* config/nios2/nios2.c (nios2_label_align): Update for recent
[official-gcc.git] / gcc / config / nios2 / nios2.c
blob344181a496bb2db0d88924119c24b8b31f8ae714
1 /* Target machine subroutines for Altera Nios II.
2 Copyright (C) 2012-2018 Free Software Foundation, Inc.
3 Contributed by Jonah Graham (jgraham@altera.com),
4 Will Reece (wreece@altera.com), and Jeff DaSilva (jdasilva@altera.com).
5 Contributed by Mentor Graphics, Inc.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published
11 by the Free Software Foundation; either version 3, or (at your
12 option) any later version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 #define IN_TARGET_CODE 1
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "backend.h"
29 #include "target.h"
30 #include "rtl.h"
31 #include "tree.h"
32 #include "stringpool.h"
33 #include "attribs.h"
34 #include "df.h"
35 #include "memmodel.h"
36 #include "tm_p.h"
37 #include "optabs.h"
38 #include "regs.h"
39 #include "emit-rtl.h"
40 #include "recog.h"
41 #include "diagnostic-core.h"
42 #include "output.h"
43 #include "insn-attr.h"
44 #include "flags.h"
45 #include "explow.h"
46 #include "calls.h"
47 #include "varasm.h"
48 #include "expr.h"
49 #include "toplev.h"
50 #include "langhooks.h"
51 #include "stor-layout.h"
52 #include "builtins.h"
53 #include "tree-pass.h"
54 #include "xregex.h"
56 /* This file should be included last. */
57 #include "target-def.h"
59 /* Forward function declarations. */
60 static bool nios2_symbolic_constant_p (rtx);
61 static bool prologue_saved_reg_p (unsigned);
62 static void nios2_load_pic_register (void);
63 static void nios2_register_custom_code (unsigned int, enum nios2_ccs_code, int);
64 static const char *nios2_unspec_reloc_name (int);
65 static void nios2_register_builtin_fndecl (unsigned, tree);
66 static rtx nios2_ldst_parallel (bool, bool, bool, rtx, int,
67 unsigned HOST_WIDE_INT, bool);
68 static int nios2_address_cost (rtx, machine_mode, addr_space_t, bool);
70 /* Threshold for data being put into the small data/bss area, instead
71 of the normal data area (references to the small data/bss area take
72 1 instruction, and use the global pointer, references to the normal
73 data area takes 2 instructions). */
74 unsigned HOST_WIDE_INT nios2_section_threshold = NIOS2_DEFAULT_GVALUE;
76 struct GTY (()) machine_function
78 /* Current frame information, to be filled in by nios2_compute_frame_layout
79 with register save masks, and offsets for the current function. */
81 /* Mask of registers to save. */
82 unsigned int save_mask;
83 /* Number of bytes that the entire frame takes up. */
84 int total_size;
85 /* Number of bytes that variables take up. */
86 int var_size;
87 /* Number of bytes that outgoing arguments take up. */
88 int args_size;
89 /* Number of bytes needed to store registers in frame. */
90 int save_reg_size;
91 /* Number of bytes used to store callee-saved registers. */
92 int callee_save_reg_size;
93 /* Offset from new stack pointer to store registers. */
94 int save_regs_offset;
95 /* Offset from save_regs_offset to store frame pointer register. */
96 int fp_save_offset;
97 /* != 0 if function has a variable argument list. */
98 int uses_anonymous_args;
99 /* != 0 if frame layout already calculated. */
100 int initialized;
103 /* State to track the assignment of custom codes to FPU/custom builtins. */
104 static enum nios2_ccs_code custom_code_status[256];
105 static int custom_code_index[256];
106 /* Set to true if any conflicts (re-use of a code between 0-255) are found. */
107 static bool custom_code_conflict = false;
109 /* State for command-line options. */
110 regex_t nios2_gprel_sec_regex;
111 regex_t nios2_r0rel_sec_regex;
114 /* Definition of builtin function types for nios2. */
116 #define N2_FTYPES \
117 N2_FTYPE(1, (SF)) \
118 N2_FTYPE(1, (VOID)) \
119 N2_FTYPE(2, (DF, DF)) \
120 N2_FTYPE(3, (DF, DF, DF)) \
121 N2_FTYPE(2, (DF, SF)) \
122 N2_FTYPE(2, (DF, SI)) \
123 N2_FTYPE(2, (DF, UI)) \
124 N2_FTYPE(2, (SF, DF)) \
125 N2_FTYPE(2, (SF, SF)) \
126 N2_FTYPE(3, (SF, SF, SF)) \
127 N2_FTYPE(2, (SF, SI)) \
128 N2_FTYPE(2, (SF, UI)) \
129 N2_FTYPE(2, (SI, CVPTR)) \
130 N2_FTYPE(2, (SI, DF)) \
131 N2_FTYPE(3, (SI, DF, DF)) \
132 N2_FTYPE(2, (SI, SF)) \
133 N2_FTYPE(3, (SI, SF, SF)) \
134 N2_FTYPE(2, (SI, SI)) \
135 N2_FTYPE(3, (SI, SI, SI)) \
136 N2_FTYPE(3, (SI, VPTR, SI)) \
137 N2_FTYPE(2, (UI, CVPTR)) \
138 N2_FTYPE(2, (UI, DF)) \
139 N2_FTYPE(2, (UI, SF)) \
140 N2_FTYPE(2, (VOID, DF)) \
141 N2_FTYPE(2, (VOID, SF)) \
142 N2_FTYPE(2, (VOID, SI)) \
143 N2_FTYPE(3, (VOID, SI, SI)) \
144 N2_FTYPE(2, (VOID, VPTR)) \
145 N2_FTYPE(3, (VOID, VPTR, SI))
147 #define N2_FTYPE_OP1(R) N2_FTYPE_ ## R ## _VOID
148 #define N2_FTYPE_OP2(R, A1) N2_FTYPE_ ## R ## _ ## A1
149 #define N2_FTYPE_OP3(R, A1, A2) N2_FTYPE_ ## R ## _ ## A1 ## _ ## A2
151 /* Expand ftcode enumeration. */
152 enum nios2_ftcode {
153 #define N2_FTYPE(N,ARGS) N2_FTYPE_OP ## N ARGS,
154 N2_FTYPES
155 #undef N2_FTYPE
156 N2_FTYPE_MAX
159 /* Return the tree function type, based on the ftcode. */
160 static tree
161 nios2_ftype (enum nios2_ftcode ftcode)
163 static tree types[(int) N2_FTYPE_MAX];
165 tree N2_TYPE_SF = float_type_node;
166 tree N2_TYPE_DF = double_type_node;
167 tree N2_TYPE_SI = integer_type_node;
168 tree N2_TYPE_UI = unsigned_type_node;
169 tree N2_TYPE_VOID = void_type_node;
171 static const_tree N2_TYPE_CVPTR, N2_TYPE_VPTR;
172 if (!N2_TYPE_CVPTR)
174 /* const volatile void *. */
175 N2_TYPE_CVPTR
176 = build_pointer_type (build_qualified_type (void_type_node,
177 (TYPE_QUAL_CONST
178 | TYPE_QUAL_VOLATILE)));
179 /* volatile void *. */
180 N2_TYPE_VPTR
181 = build_pointer_type (build_qualified_type (void_type_node,
182 TYPE_QUAL_VOLATILE));
184 if (types[(int) ftcode] == NULL_TREE)
185 switch (ftcode)
187 #define N2_FTYPE_ARGS1(R) N2_TYPE_ ## R
188 #define N2_FTYPE_ARGS2(R,A1) N2_TYPE_ ## R, N2_TYPE_ ## A1
189 #define N2_FTYPE_ARGS3(R,A1,A2) N2_TYPE_ ## R, N2_TYPE_ ## A1, N2_TYPE_ ## A2
190 #define N2_FTYPE(N,ARGS) \
191 case N2_FTYPE_OP ## N ARGS: \
192 types[(int) ftcode] \
193 = build_function_type_list (N2_FTYPE_ARGS ## N ARGS, NULL_TREE); \
194 break;
195 N2_FTYPES
196 #undef N2_FTYPE
197 default: gcc_unreachable ();
199 return types[(int) ftcode];
203 /* Definition of FPU instruction descriptions. */
205 struct nios2_fpu_insn_info
207 const char *name;
208 int num_operands, *optvar;
209 int opt, no_opt;
210 #define N2F_DF 0x1
211 #define N2F_DFREQ 0x2
212 #define N2F_UNSAFE 0x4
213 #define N2F_FINITE 0x8
214 #define N2F_NO_ERRNO 0x10
215 unsigned int flags;
216 enum insn_code icode;
217 enum nios2_ftcode ftcode;
220 /* Base macro for defining FPU instructions. */
221 #define N2FPU_INSN_DEF_BASE(insn, nop, flags, icode, args) \
222 { #insn, nop, &nios2_custom_ ## insn, OPT_mcustom_##insn##_, \
223 OPT_mno_custom_##insn, flags, CODE_FOR_ ## icode, \
224 N2_FTYPE_OP ## nop args }
226 /* Arithmetic and math functions; 2 or 3 operand FP operations. */
227 #define N2FPU_OP2(mode) (mode, mode)
228 #define N2FPU_OP3(mode) (mode, mode, mode)
229 #define N2FPU_INSN_DEF(code, icode, nop, flags, m, M) \
230 N2FPU_INSN_DEF_BASE (f ## code ## m, nop, flags, \
231 icode ## m ## f ## nop, N2FPU_OP ## nop (M ## F))
232 #define N2FPU_INSN_SF(code, nop, flags) \
233 N2FPU_INSN_DEF (code, code, nop, flags, s, S)
234 #define N2FPU_INSN_DF(code, nop, flags) \
235 N2FPU_INSN_DEF (code, code, nop, flags | N2F_DF, d, D)
237 /* Compare instructions, 3 operand FP operation with a SI result. */
238 #define N2FPU_CMP_DEF(code, flags, m, M) \
239 N2FPU_INSN_DEF_BASE (fcmp ## code ## m, 3, flags, \
240 nios2_s ## code ## m ## f, (SI, M ## F, M ## F))
241 #define N2FPU_CMP_SF(code) N2FPU_CMP_DEF (code, 0, s, S)
242 #define N2FPU_CMP_DF(code) N2FPU_CMP_DEF (code, N2F_DF, d, D)
244 /* The order of definition needs to be maintained consistent with
245 enum n2fpu_code in nios2-opts.h. */
246 struct nios2_fpu_insn_info nios2_fpu_insn[] =
248 /* Single precision instructions. */
249 N2FPU_INSN_SF (add, 3, 0),
250 N2FPU_INSN_SF (sub, 3, 0),
251 N2FPU_INSN_SF (mul, 3, 0),
252 N2FPU_INSN_SF (div, 3, 0),
253 /* Due to textual difference between min/max and smin/smax. */
254 N2FPU_INSN_DEF (min, smin, 3, N2F_FINITE, s, S),
255 N2FPU_INSN_DEF (max, smax, 3, N2F_FINITE, s, S),
256 N2FPU_INSN_SF (neg, 2, 0),
257 N2FPU_INSN_SF (abs, 2, 0),
258 N2FPU_INSN_SF (sqrt, 2, 0),
259 N2FPU_INSN_SF (sin, 2, N2F_UNSAFE),
260 N2FPU_INSN_SF (cos, 2, N2F_UNSAFE),
261 N2FPU_INSN_SF (tan, 2, N2F_UNSAFE),
262 N2FPU_INSN_SF (atan, 2, N2F_UNSAFE),
263 N2FPU_INSN_SF (exp, 2, N2F_UNSAFE),
264 N2FPU_INSN_SF (log, 2, N2F_UNSAFE),
265 /* Single precision compares. */
266 N2FPU_CMP_SF (eq), N2FPU_CMP_SF (ne),
267 N2FPU_CMP_SF (lt), N2FPU_CMP_SF (le),
268 N2FPU_CMP_SF (gt), N2FPU_CMP_SF (ge),
270 /* Double precision instructions. */
271 N2FPU_INSN_DF (add, 3, 0),
272 N2FPU_INSN_DF (sub, 3, 0),
273 N2FPU_INSN_DF (mul, 3, 0),
274 N2FPU_INSN_DF (div, 3, 0),
275 /* Due to textual difference between min/max and smin/smax. */
276 N2FPU_INSN_DEF (min, smin, 3, N2F_FINITE, d, D),
277 N2FPU_INSN_DEF (max, smax, 3, N2F_FINITE, d, D),
278 N2FPU_INSN_DF (neg, 2, 0),
279 N2FPU_INSN_DF (abs, 2, 0),
280 N2FPU_INSN_DF (sqrt, 2, 0),
281 N2FPU_INSN_DF (sin, 2, N2F_UNSAFE),
282 N2FPU_INSN_DF (cos, 2, N2F_UNSAFE),
283 N2FPU_INSN_DF (tan, 2, N2F_UNSAFE),
284 N2FPU_INSN_DF (atan, 2, N2F_UNSAFE),
285 N2FPU_INSN_DF (exp, 2, N2F_UNSAFE),
286 N2FPU_INSN_DF (log, 2, N2F_UNSAFE),
287 /* Double precision compares. */
288 N2FPU_CMP_DF (eq), N2FPU_CMP_DF (ne),
289 N2FPU_CMP_DF (lt), N2FPU_CMP_DF (le),
290 N2FPU_CMP_DF (gt), N2FPU_CMP_DF (ge),
292 /* Conversion instructions. */
293 N2FPU_INSN_DEF_BASE (floatis, 2, 0, floatsisf2, (SF, SI)),
294 N2FPU_INSN_DEF_BASE (floatus, 2, 0, floatunssisf2, (SF, UI)),
295 N2FPU_INSN_DEF_BASE (floatid, 2, 0, floatsidf2, (DF, SI)),
296 N2FPU_INSN_DEF_BASE (floatud, 2, 0, floatunssidf2, (DF, UI)),
297 N2FPU_INSN_DEF_BASE (round, 2, N2F_NO_ERRNO, lroundsfsi2, (SI, SF)),
298 N2FPU_INSN_DEF_BASE (fixsi, 2, 0, fix_truncsfsi2, (SI, SF)),
299 N2FPU_INSN_DEF_BASE (fixsu, 2, 0, fixuns_truncsfsi2, (UI, SF)),
300 N2FPU_INSN_DEF_BASE (fixdi, 2, 0, fix_truncdfsi2, (SI, DF)),
301 N2FPU_INSN_DEF_BASE (fixdu, 2, 0, fixuns_truncdfsi2, (UI, DF)),
302 N2FPU_INSN_DEF_BASE (fextsd, 2, 0, extendsfdf2, (DF, SF)),
303 N2FPU_INSN_DEF_BASE (ftruncds, 2, 0, truncdfsf2, (SF, DF)),
305 /* X, Y access instructions. */
306 N2FPU_INSN_DEF_BASE (fwrx, 2, N2F_DFREQ, nios2_fwrx, (VOID, DF)),
307 N2FPU_INSN_DEF_BASE (fwry, 2, N2F_DFREQ, nios2_fwry, (VOID, SF)),
308 N2FPU_INSN_DEF_BASE (frdxlo, 1, N2F_DFREQ, nios2_frdxlo, (SF)),
309 N2FPU_INSN_DEF_BASE (frdxhi, 1, N2F_DFREQ, nios2_frdxhi, (SF)),
310 N2FPU_INSN_DEF_BASE (frdy, 1, N2F_DFREQ, nios2_frdy, (SF))
313 /* Some macros for ease of access. */
314 #define N2FPU(code) nios2_fpu_insn[(int) code]
315 #define N2FPU_ENABLED_P(code) (N2FPU_N(code) >= 0)
316 #define N2FPU_N(code) (*N2FPU(code).optvar)
317 #define N2FPU_NAME(code) (N2FPU(code).name)
318 #define N2FPU_ICODE(code) (N2FPU(code).icode)
319 #define N2FPU_FTCODE(code) (N2FPU(code).ftcode)
320 #define N2FPU_FINITE_P(code) (N2FPU(code).flags & N2F_FINITE)
321 #define N2FPU_UNSAFE_P(code) (N2FPU(code).flags & N2F_UNSAFE)
322 #define N2FPU_NO_ERRNO_P(code) (N2FPU(code).flags & N2F_NO_ERRNO)
323 #define N2FPU_DOUBLE_P(code) (N2FPU(code).flags & N2F_DF)
324 #define N2FPU_DOUBLE_REQUIRED_P(code) (N2FPU(code).flags & N2F_DFREQ)
326 /* Same as above, but for cases where using only the op part is shorter. */
327 #define N2FPU_OP(op) N2FPU(n2fpu_ ## op)
328 #define N2FPU_OP_NAME(op) N2FPU_NAME(n2fpu_ ## op)
329 #define N2FPU_OP_ENABLED_P(op) N2FPU_ENABLED_P(n2fpu_ ## op)
331 /* Export the FPU insn enabled predicate to nios2.md. */
332 bool
333 nios2_fpu_insn_enabled (enum n2fpu_code code)
335 return N2FPU_ENABLED_P (code);
338 /* Return true if COND comparison for mode MODE is enabled under current
339 settings. */
341 static bool
342 nios2_fpu_compare_enabled (enum rtx_code cond, machine_mode mode)
344 if (mode == SFmode)
345 switch (cond)
347 case EQ: return N2FPU_OP_ENABLED_P (fcmpeqs);
348 case NE: return N2FPU_OP_ENABLED_P (fcmpnes);
349 case GT: return N2FPU_OP_ENABLED_P (fcmpgts);
350 case GE: return N2FPU_OP_ENABLED_P (fcmpges);
351 case LT: return N2FPU_OP_ENABLED_P (fcmplts);
352 case LE: return N2FPU_OP_ENABLED_P (fcmples);
353 default: break;
355 else if (mode == DFmode)
356 switch (cond)
358 case EQ: return N2FPU_OP_ENABLED_P (fcmpeqd);
359 case NE: return N2FPU_OP_ENABLED_P (fcmpned);
360 case GT: return N2FPU_OP_ENABLED_P (fcmpgtd);
361 case GE: return N2FPU_OP_ENABLED_P (fcmpged);
362 case LT: return N2FPU_OP_ENABLED_P (fcmpltd);
363 case LE: return N2FPU_OP_ENABLED_P (fcmpled);
364 default: break;
366 return false;
369 /* Stack layout and calling conventions. */
371 #define NIOS2_STACK_ALIGN(LOC) \
372 (((LOC) + ((PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT) - 1)) \
373 & ~((PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT) - 1))
375 /* Return the bytes needed to compute the frame pointer from the current
376 stack pointer. */
377 static int
378 nios2_compute_frame_layout (void)
380 unsigned int regno;
381 unsigned int save_mask = 0;
382 int total_size;
383 int var_size;
384 int out_args_size;
385 int save_reg_size;
386 int callee_save_reg_size;
388 if (cfun->machine->initialized)
389 return cfun->machine->total_size;
391 /* Calculate space needed for gp registers. */
392 save_reg_size = 0;
393 for (regno = 0; regno <= LAST_GP_REG; regno++)
394 if (prologue_saved_reg_p (regno))
396 save_mask |= 1 << regno;
397 save_reg_size += 4;
400 /* If we are saving any callee-save register, then assume
401 push.n/pop.n should be used. Make sure RA is saved, and
402 contiguous registers starting from r16-- are all saved. */
403 if (TARGET_HAS_CDX && save_reg_size != 0)
405 if ((save_mask & (1 << RA_REGNO)) == 0)
407 save_mask |= 1 << RA_REGNO;
408 save_reg_size += 4;
411 for (regno = 23; regno >= 16; regno--)
412 if ((save_mask & (1 << regno)) != 0)
414 /* Starting from highest numbered callee-saved
415 register that is used, make sure all regs down
416 to r16 is saved, to maintain contiguous range
417 for push.n/pop.n. */
418 unsigned int i;
419 for (i = regno - 1; i >= 16; i--)
420 if ((save_mask & (1 << i)) == 0)
422 save_mask |= 1 << i;
423 save_reg_size += 4;
425 break;
429 callee_save_reg_size = save_reg_size;
431 /* If we call eh_return, we need to save the EH data registers. */
432 if (crtl->calls_eh_return)
434 unsigned i;
435 unsigned r;
437 for (i = 0; (r = EH_RETURN_DATA_REGNO (i)) != INVALID_REGNUM; i++)
438 if (!(save_mask & (1 << r)))
440 save_mask |= 1 << r;
441 save_reg_size += 4;
445 cfun->machine->fp_save_offset = 0;
446 if (save_mask & (1 << HARD_FRAME_POINTER_REGNUM))
448 int fp_save_offset = 0;
449 for (regno = 0; regno < HARD_FRAME_POINTER_REGNUM; regno++)
450 if (save_mask & (1 << regno))
451 fp_save_offset += 4;
453 cfun->machine->fp_save_offset = fp_save_offset;
456 var_size = NIOS2_STACK_ALIGN (get_frame_size ());
457 out_args_size = NIOS2_STACK_ALIGN (crtl->outgoing_args_size);
458 total_size = var_size + out_args_size;
460 save_reg_size = NIOS2_STACK_ALIGN (save_reg_size);
461 total_size += save_reg_size;
462 total_size += NIOS2_STACK_ALIGN (crtl->args.pretend_args_size);
464 /* Save other computed information. */
465 cfun->machine->save_mask = save_mask;
466 cfun->machine->total_size = total_size;
467 cfun->machine->var_size = var_size;
468 cfun->machine->args_size = out_args_size;
469 cfun->machine->save_reg_size = save_reg_size;
470 cfun->machine->callee_save_reg_size = callee_save_reg_size;
471 cfun->machine->initialized = reload_completed;
472 cfun->machine->save_regs_offset = out_args_size + var_size;
474 return total_size;
477 /* Generate save/restore of register REGNO at SP + OFFSET. Used by the
478 prologue/epilogue expand routines. */
479 static void
480 save_reg (int regno, unsigned offset)
482 rtx reg = gen_rtx_REG (SImode, regno);
483 rtx addr = plus_constant (Pmode, stack_pointer_rtx, offset, false);
484 rtx_insn *insn = emit_move_insn (gen_frame_mem (Pmode, addr), reg);
485 RTX_FRAME_RELATED_P (insn) = 1;
488 static void
489 restore_reg (int regno, unsigned offset)
491 rtx reg = gen_rtx_REG (SImode, regno);
492 rtx addr = plus_constant (Pmode, stack_pointer_rtx, offset, false);
493 rtx_insn *insn = emit_move_insn (reg, gen_frame_mem (Pmode, addr));
494 /* Tag epilogue unwind note. */
495 add_reg_note (insn, REG_CFA_RESTORE, reg);
496 RTX_FRAME_RELATED_P (insn) = 1;
499 /* This routine tests for the base register update SET in load/store
500 multiple RTL insns, used in pop_operation_p and ldstwm_operation_p. */
501 static bool
502 base_reg_adjustment_p (rtx set, rtx *base_reg, rtx *offset)
504 if (GET_CODE (set) == SET
505 && REG_P (SET_DEST (set))
506 && GET_CODE (SET_SRC (set)) == PLUS
507 && REG_P (XEXP (SET_SRC (set), 0))
508 && rtx_equal_p (SET_DEST (set), XEXP (SET_SRC (set), 0))
509 && CONST_INT_P (XEXP (SET_SRC (set), 1)))
511 *base_reg = XEXP (SET_SRC (set), 0);
512 *offset = XEXP (SET_SRC (set), 1);
513 return true;
515 return false;
518 /* Does the CFA note work for push/pop prologue/epilogue instructions. */
519 static void
520 nios2_create_cfa_notes (rtx_insn *insn, bool epilogue_p)
522 int i = 0;
523 rtx base_reg, offset, elt, pat = PATTERN (insn);
524 if (epilogue_p)
526 elt = XVECEXP (pat, 0, 0);
527 if (GET_CODE (elt) == RETURN)
528 i++;
529 elt = XVECEXP (pat, 0, i);
530 if (base_reg_adjustment_p (elt, &base_reg, &offset))
532 add_reg_note (insn, REG_CFA_ADJUST_CFA, copy_rtx (elt));
533 i++;
535 for (; i < XVECLEN (pat, 0); i++)
537 elt = SET_DEST (XVECEXP (pat, 0, i));
538 gcc_assert (REG_P (elt));
539 add_reg_note (insn, REG_CFA_RESTORE, elt);
542 else
544 /* Tag each of the prologue sets. */
545 for (i = 0; i < XVECLEN (pat, 0); i++)
546 RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1;
550 /* Temp regno used inside prologue/epilogue. */
551 #define TEMP_REG_NUM 8
553 /* Emit conditional trap for checking stack limit. SIZE is the number of
554 additional bytes required.
556 GDB prologue analysis depends on this generating a direct comparison
557 to the SP register, so the adjustment to add SIZE needs to be done on
558 the other operand to the comparison. Use TEMP_REG_NUM as a temporary,
559 if necessary. */
560 static void
561 nios2_emit_stack_limit_check (int size)
563 rtx sum = NULL_RTX;
565 if (GET_CODE (stack_limit_rtx) == SYMBOL_REF)
567 /* This generates a %hiadj/%lo pair with the constant size
568 add handled by the relocations. */
569 sum = gen_rtx_REG (Pmode, TEMP_REG_NUM);
570 emit_move_insn (sum, plus_constant (Pmode, stack_limit_rtx, size));
572 else if (!REG_P (stack_limit_rtx))
573 sorry ("Unknown form for stack limit expression");
574 else if (size == 0)
575 sum = stack_limit_rtx;
576 else if (SMALL_INT (size))
578 sum = gen_rtx_REG (Pmode, TEMP_REG_NUM);
579 emit_move_insn (sum, plus_constant (Pmode, stack_limit_rtx, size));
581 else
583 sum = gen_rtx_REG (Pmode, TEMP_REG_NUM);
584 emit_move_insn (sum, gen_int_mode (size, Pmode));
585 emit_insn (gen_add2_insn (sum, stack_limit_rtx));
588 emit_insn (gen_ctrapsi4 (gen_rtx_LTU (VOIDmode, stack_pointer_rtx, sum),
589 stack_pointer_rtx, sum, GEN_INT (3)));
592 static rtx_insn *
593 nios2_emit_add_constant (rtx reg, HOST_WIDE_INT immed)
595 rtx_insn *insn;
596 if (SMALL_INT (immed))
597 insn = emit_insn (gen_add2_insn (reg, gen_int_mode (immed, Pmode)));
598 else
600 rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM);
601 emit_move_insn (tmp, gen_int_mode (immed, Pmode));
602 insn = emit_insn (gen_add2_insn (reg, tmp));
604 return insn;
607 static rtx_insn *
608 nios2_adjust_stack (int sp_adjust, bool epilogue_p)
610 enum reg_note note_kind = REG_NOTE_MAX;
611 rtx_insn *insn = NULL;
612 if (sp_adjust)
614 if (SMALL_INT (sp_adjust))
615 insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
616 gen_int_mode (sp_adjust, Pmode)));
617 else
619 rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM);
620 emit_move_insn (tmp, gen_int_mode (sp_adjust, Pmode));
621 insn = emit_insn (gen_add2_insn (stack_pointer_rtx, tmp));
622 /* Attach a note indicating what happened. */
623 if (!epilogue_p)
624 note_kind = REG_FRAME_RELATED_EXPR;
626 if (epilogue_p)
627 note_kind = REG_CFA_ADJUST_CFA;
628 if (note_kind != REG_NOTE_MAX)
630 rtx cfa_adj = gen_rtx_SET (stack_pointer_rtx,
631 plus_constant (Pmode, stack_pointer_rtx,
632 sp_adjust));
633 add_reg_note (insn, note_kind, cfa_adj);
635 RTX_FRAME_RELATED_P (insn) = 1;
637 return insn;
640 void
641 nios2_expand_prologue (void)
643 unsigned int regno;
644 int total_frame_size, save_offset;
645 int sp_offset; /* offset from base_reg to final stack value. */
646 int save_regs_base; /* offset from base_reg to register save area. */
647 rtx_insn *insn;
649 total_frame_size = nios2_compute_frame_layout ();
651 if (flag_stack_usage_info)
652 current_function_static_stack_size = total_frame_size;
654 /* When R2 CDX push.n/stwm is available, arrange for stack frame to be built
655 using them. */
656 if (TARGET_HAS_CDX
657 && (cfun->machine->save_reg_size != 0
658 || cfun->machine->uses_anonymous_args))
660 unsigned int regmask = cfun->machine->save_mask;
661 unsigned int callee_save_regs = regmask & 0xffff0000;
662 unsigned int caller_save_regs = regmask & 0x0000ffff;
663 int push_immed = 0;
664 int pretend_args_size = NIOS2_STACK_ALIGN (crtl->args.pretend_args_size);
665 rtx stack_mem =
666 gen_frame_mem (SImode, plus_constant (Pmode, stack_pointer_rtx, -4));
668 /* Check that there is room for the entire stack frame before doing
669 any SP adjustments or pushes. */
670 if (crtl->limit_stack)
671 nios2_emit_stack_limit_check (total_frame_size);
673 if (pretend_args_size)
675 if (cfun->machine->uses_anonymous_args)
677 /* Emit a stwm to push copy of argument registers onto
678 the stack for va_arg processing. */
679 unsigned int r, mask = 0, n = pretend_args_size / 4;
680 for (r = LAST_ARG_REGNO - n + 1; r <= LAST_ARG_REGNO; r++)
681 mask |= (1 << r);
682 insn = emit_insn (nios2_ldst_parallel
683 (false, false, false, stack_mem,
684 -pretend_args_size, mask, false));
685 /* Tag first SP adjustment as frame-related. */
686 RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, 0)) = 1;
687 RTX_FRAME_RELATED_P (insn) = 1;
689 else
690 nios2_adjust_stack (-pretend_args_size, false);
692 if (callee_save_regs)
694 /* Emit a push.n to save registers and optionally allocate
695 push_immed extra bytes on the stack. */
696 int sp_adjust;
697 if (caller_save_regs)
698 /* Can't allocate extra stack space yet. */
699 push_immed = 0;
700 else if (cfun->machine->save_regs_offset <= 60)
701 /* Stack adjustment fits entirely in the push.n. */
702 push_immed = cfun->machine->save_regs_offset;
703 else if (frame_pointer_needed
704 && cfun->machine->fp_save_offset == 0)
705 /* Deferring the entire stack adjustment until later
706 allows us to use a mov.n instead of a 32-bit addi
707 instruction to set the frame pointer. */
708 push_immed = 0;
709 else
710 /* Splitting the stack adjustment between the push.n
711 and an explicit adjustment makes it more likely that
712 we can use spdeci.n for the explicit part. */
713 push_immed = 60;
714 sp_adjust = -(cfun->machine->callee_save_reg_size + push_immed);
715 insn = emit_insn (nios2_ldst_parallel (false, false, false,
716 stack_mem, sp_adjust,
717 callee_save_regs, false));
718 nios2_create_cfa_notes (insn, false);
719 RTX_FRAME_RELATED_P (insn) = 1;
722 if (caller_save_regs)
724 /* Emit a stwm to save the EH data regs, r4-r7. */
725 int caller_save_size = (cfun->machine->save_reg_size
726 - cfun->machine->callee_save_reg_size);
727 gcc_assert ((caller_save_regs & ~0xf0) == 0);
728 insn = emit_insn (nios2_ldst_parallel
729 (false, false, false, stack_mem,
730 -caller_save_size, caller_save_regs, false));
731 nios2_create_cfa_notes (insn, false);
732 RTX_FRAME_RELATED_P (insn) = 1;
735 save_regs_base = push_immed;
736 sp_offset = -(cfun->machine->save_regs_offset - push_immed);
738 /* The non-CDX cases decrement the stack pointer, to prepare for individual
739 register saves to the stack. */
740 else if (!SMALL_INT (total_frame_size))
742 /* We need an intermediary point, this will point at the spill block. */
743 nios2_adjust_stack (cfun->machine->save_regs_offset - total_frame_size,
744 false);
745 save_regs_base = 0;
746 sp_offset = -cfun->machine->save_regs_offset;
747 if (crtl->limit_stack)
748 nios2_emit_stack_limit_check (cfun->machine->save_regs_offset);
750 else if (total_frame_size)
752 nios2_adjust_stack (-total_frame_size, false);
753 save_regs_base = cfun->machine->save_regs_offset;
754 sp_offset = 0;
755 if (crtl->limit_stack)
756 nios2_emit_stack_limit_check (0);
758 else
759 save_regs_base = sp_offset = 0;
761 /* Save the registers individually in the non-CDX case. */
762 if (!TARGET_HAS_CDX)
764 save_offset = save_regs_base + cfun->machine->save_reg_size;
766 for (regno = LAST_GP_REG; regno > 0; regno--)
767 if (cfun->machine->save_mask & (1 << regno))
769 save_offset -= 4;
770 save_reg (regno, save_offset);
774 /* Set the hard frame pointer. */
775 if (frame_pointer_needed)
777 int fp_save_offset = save_regs_base + cfun->machine->fp_save_offset;
778 insn =
779 (fp_save_offset == 0
780 ? emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx)
781 : emit_insn (gen_add3_insn (hard_frame_pointer_rtx,
782 stack_pointer_rtx,
783 gen_int_mode (fp_save_offset, Pmode))));
784 RTX_FRAME_RELATED_P (insn) = 1;
787 /* Allocate sp_offset more bytes in the stack frame. */
788 nios2_adjust_stack (sp_offset, false);
790 /* Load the PIC register if needed. */
791 if (crtl->uses_pic_offset_table)
792 nios2_load_pic_register ();
794 /* If we are profiling, make sure no instructions are scheduled before
795 the call to mcount. */
796 if (crtl->profile)
797 emit_insn (gen_blockage ());
800 void
801 nios2_expand_epilogue (bool sibcall_p)
803 rtx_insn *insn;
804 rtx cfa_adj;
805 int total_frame_size;
806 int sp_adjust, save_offset;
807 unsigned int regno;
809 if (!sibcall_p && nios2_can_use_return_insn ())
811 emit_jump_insn (gen_return ());
812 return;
815 emit_insn (gen_blockage ());
817 total_frame_size = nios2_compute_frame_layout ();
818 if (frame_pointer_needed)
820 /* Recover the stack pointer. */
821 insn =
822 (cfun->machine->fp_save_offset == 0
823 ? emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx)
824 : emit_insn (gen_add3_insn
825 (stack_pointer_rtx, hard_frame_pointer_rtx,
826 gen_int_mode (-cfun->machine->fp_save_offset, Pmode))));
827 cfa_adj = plus_constant (Pmode, stack_pointer_rtx,
828 (total_frame_size
829 - cfun->machine->save_regs_offset));
830 add_reg_note (insn, REG_CFA_DEF_CFA, cfa_adj);
831 RTX_FRAME_RELATED_P (insn) = 1;
833 save_offset = 0;
834 sp_adjust = total_frame_size - cfun->machine->save_regs_offset;
836 else if (!SMALL_INT (total_frame_size))
838 nios2_adjust_stack (cfun->machine->save_regs_offset, true);
839 save_offset = 0;
840 sp_adjust = total_frame_size - cfun->machine->save_regs_offset;
842 else
844 save_offset = cfun->machine->save_regs_offset;
845 sp_adjust = total_frame_size;
848 if (!TARGET_HAS_CDX)
850 /* Generate individual register restores. */
851 save_offset += cfun->machine->save_reg_size;
853 for (regno = LAST_GP_REG; regno > 0; regno--)
854 if (cfun->machine->save_mask & (1 << regno))
856 save_offset -= 4;
857 restore_reg (regno, save_offset);
859 nios2_adjust_stack (sp_adjust, true);
861 else if (cfun->machine->save_reg_size == 0)
863 /* Nothing to restore, just recover the stack position. */
864 nios2_adjust_stack (sp_adjust, true);
866 else
868 /* Emit CDX pop.n/ldwm to restore registers and optionally return. */
869 unsigned int regmask = cfun->machine->save_mask;
870 unsigned int callee_save_regs = regmask & 0xffff0000;
871 unsigned int caller_save_regs = regmask & 0x0000ffff;
872 int callee_save_size = cfun->machine->callee_save_reg_size;
873 int caller_save_size = cfun->machine->save_reg_size - callee_save_size;
874 int pretend_args_size = NIOS2_STACK_ALIGN (crtl->args.pretend_args_size);
875 bool ret_p = (!pretend_args_size && !crtl->calls_eh_return
876 && !sibcall_p);
878 if (!ret_p || caller_save_size > 0)
879 sp_adjust = save_offset;
880 else
881 sp_adjust = (save_offset > 60 ? save_offset - 60 : 0);
883 save_offset -= sp_adjust;
885 nios2_adjust_stack (sp_adjust, true);
887 if (caller_save_regs)
889 /* Emit a ldwm to restore EH data regs. */
890 rtx stack_mem = gen_frame_mem (SImode, stack_pointer_rtx);
891 insn = emit_insn (nios2_ldst_parallel
892 (true, true, true, stack_mem,
893 caller_save_size, caller_save_regs, false));
894 RTX_FRAME_RELATED_P (insn) = 1;
895 nios2_create_cfa_notes (insn, true);
898 if (callee_save_regs)
900 int sp_adjust = save_offset + callee_save_size;
901 rtx stack_mem;
902 if (ret_p)
904 /* Emit a pop.n to restore regs and return. */
905 stack_mem =
906 gen_frame_mem (SImode,
907 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
908 gen_int_mode (sp_adjust - 4,
909 Pmode)));
910 insn =
911 emit_jump_insn (nios2_ldst_parallel (true, false, false,
912 stack_mem, sp_adjust,
913 callee_save_regs, ret_p));
914 RTX_FRAME_RELATED_P (insn) = 1;
915 /* No need to attach CFA notes since we cannot step over
916 a return. */
917 return;
919 else
921 /* If no return, we have to use the ldwm form. */
922 stack_mem = gen_frame_mem (SImode, stack_pointer_rtx);
923 insn =
924 emit_insn (nios2_ldst_parallel (true, true, true,
925 stack_mem, sp_adjust,
926 callee_save_regs, ret_p));
927 RTX_FRAME_RELATED_P (insn) = 1;
928 nios2_create_cfa_notes (insn, true);
932 if (pretend_args_size)
933 nios2_adjust_stack (pretend_args_size, true);
936 /* Add in the __builtin_eh_return stack adjustment. */
937 if (crtl->calls_eh_return)
938 emit_insn (gen_add2_insn (stack_pointer_rtx, EH_RETURN_STACKADJ_RTX));
940 if (!sibcall_p)
941 emit_jump_insn (gen_simple_return ());
944 bool
945 nios2_expand_return (void)
947 /* If CDX is available, generate a pop.n instruction to do both
948 the stack pop and return. */
949 if (TARGET_HAS_CDX)
951 int total_frame_size = nios2_compute_frame_layout ();
952 int sp_adjust = (cfun->machine->save_regs_offset
953 + cfun->machine->callee_save_reg_size);
954 gcc_assert (sp_adjust == total_frame_size);
955 if (sp_adjust != 0)
957 rtx mem =
958 gen_frame_mem (SImode,
959 plus_constant (Pmode, stack_pointer_rtx,
960 sp_adjust - 4, false));
961 rtx_insn *insn =
962 emit_jump_insn (nios2_ldst_parallel (true, false, false,
963 mem, sp_adjust,
964 cfun->machine->save_mask,
965 true));
966 RTX_FRAME_RELATED_P (insn) = 1;
967 /* No need to create CFA notes since we can't step over
968 a return. */
969 return true;
972 return false;
975 /* Implement RETURN_ADDR_RTX. Note, we do not support moving
976 back to a previous frame. */
978 nios2_get_return_address (int count)
980 if (count != 0)
981 return const0_rtx;
983 return get_hard_reg_initial_val (Pmode, RA_REGNO);
986 /* Emit code to change the current function's return address to
987 ADDRESS. SCRATCH is available as a scratch register, if needed.
988 ADDRESS and SCRATCH are both word-mode GPRs. */
989 void
990 nios2_set_return_address (rtx address, rtx scratch)
992 nios2_compute_frame_layout ();
993 if (cfun->machine->save_mask & (1 << RA_REGNO))
995 unsigned offset = cfun->machine->save_reg_size - 4;
996 rtx base;
998 if (frame_pointer_needed)
999 base = hard_frame_pointer_rtx;
1000 else
1002 base = stack_pointer_rtx;
1003 offset += cfun->machine->save_regs_offset;
1005 if (!SMALL_INT (offset))
1007 emit_move_insn (scratch, gen_int_mode (offset, Pmode));
1008 emit_insn (gen_add2_insn (scratch, base));
1009 base = scratch;
1010 offset = 0;
1013 if (offset)
1014 base = plus_constant (Pmode, base, offset);
1015 emit_move_insn (gen_rtx_MEM (Pmode, base), address);
1017 else
1018 emit_move_insn (gen_rtx_REG (Pmode, RA_REGNO), address);
1021 /* Implement FUNCTION_PROFILER macro. */
1022 void
1023 nios2_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
1025 fprintf (file, "\tmov\tr8, ra\n");
1026 if (flag_pic == 1)
1028 fprintf (file, "\tnextpc\tr2\n");
1029 fprintf (file, "\t1: movhi\tr3, %%hiadj(_gp_got - 1b)\n");
1030 fprintf (file, "\taddi\tr3, r3, %%lo(_gp_got - 1b)\n");
1031 fprintf (file, "\tadd\tr2, r2, r3\n");
1032 fprintf (file, "\tldw\tr2, %%call(_mcount)(r2)\n");
1033 fprintf (file, "\tcallr\tr2\n");
1035 else if (flag_pic == 2)
1037 fprintf (file, "\tnextpc\tr2\n");
1038 fprintf (file, "\t1: movhi\tr3, %%hiadj(_gp_got - 1b)\n");
1039 fprintf (file, "\taddi\tr3, r3, %%lo(_gp_got - 1b)\n");
1040 fprintf (file, "\tadd\tr2, r2, r3\n");
1041 fprintf (file, "\tmovhi\tr3, %%call_hiadj(_mcount)\n");
1042 fprintf (file, "\taddi\tr3, r3, %%call_lo(_mcount)\n");
1043 fprintf (file, "\tadd\tr3, r2, r3\n");
1044 fprintf (file, "\tldw\tr2, 0(r3)\n");
1045 fprintf (file, "\tcallr\tr2\n");
1047 else
1048 fprintf (file, "\tcall\t_mcount\n");
1049 fprintf (file, "\tmov\tra, r8\n");
1052 /* Dump stack layout. */
1053 static void
1054 nios2_dump_frame_layout (FILE *file)
1056 fprintf (file, "\t%s Current Frame Info\n", ASM_COMMENT_START);
1057 fprintf (file, "\t%s total_size = %d\n", ASM_COMMENT_START,
1058 cfun->machine->total_size);
1059 fprintf (file, "\t%s var_size = %d\n", ASM_COMMENT_START,
1060 cfun->machine->var_size);
1061 fprintf (file, "\t%s args_size = %d\n", ASM_COMMENT_START,
1062 cfun->machine->args_size);
1063 fprintf (file, "\t%s save_reg_size = %d\n", ASM_COMMENT_START,
1064 cfun->machine->save_reg_size);
1065 fprintf (file, "\t%s initialized = %d\n", ASM_COMMENT_START,
1066 cfun->machine->initialized);
1067 fprintf (file, "\t%s save_regs_offset = %d\n", ASM_COMMENT_START,
1068 cfun->machine->save_regs_offset);
1069 fprintf (file, "\t%s is_leaf = %d\n", ASM_COMMENT_START,
1070 crtl->is_leaf);
1071 fprintf (file, "\t%s frame_pointer_needed = %d\n", ASM_COMMENT_START,
1072 frame_pointer_needed);
1073 fprintf (file, "\t%s pretend_args_size = %d\n", ASM_COMMENT_START,
1074 crtl->args.pretend_args_size);
1077 /* Return true if REGNO should be saved in the prologue. */
1078 static bool
1079 prologue_saved_reg_p (unsigned regno)
1081 gcc_assert (GP_REG_P (regno));
1083 if (df_regs_ever_live_p (regno) && !call_used_regs[regno])
1084 return true;
1086 if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
1087 return true;
1089 if (regno == PIC_OFFSET_TABLE_REGNUM && crtl->uses_pic_offset_table)
1090 return true;
1092 if (regno == RA_REGNO && df_regs_ever_live_p (RA_REGNO))
1093 return true;
1095 return false;
1098 /* Implement TARGET_CAN_ELIMINATE. */
1099 static bool
1100 nios2_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
1102 if (to == STACK_POINTER_REGNUM)
1103 return !frame_pointer_needed;
1104 return true;
1107 /* Implement INITIAL_ELIMINATION_OFFSET macro. */
1109 nios2_initial_elimination_offset (int from, int to)
1111 int offset;
1113 nios2_compute_frame_layout ();
1115 /* Set OFFSET to the offset from the stack pointer. */
1116 switch (from)
1118 case FRAME_POINTER_REGNUM:
1119 /* This is the high end of the local variable storage, not the
1120 hard frame pointer. */
1121 offset = cfun->machine->args_size + cfun->machine->var_size;
1122 break;
1124 case ARG_POINTER_REGNUM:
1125 offset = cfun->machine->total_size;
1126 offset -= crtl->args.pretend_args_size;
1127 break;
1129 default:
1130 gcc_unreachable ();
1133 /* If we are asked for the frame pointer offset, then adjust OFFSET
1134 by the offset from the frame pointer to the stack pointer. */
1135 if (to == HARD_FRAME_POINTER_REGNUM)
1136 offset -= (cfun->machine->save_regs_offset
1137 + cfun->machine->fp_save_offset);
1139 return offset;
1142 /* Return nonzero if this function is known to have a null epilogue.
1143 This allows the optimizer to omit jumps to jumps if no stack
1144 was created. */
1146 nios2_can_use_return_insn (void)
1148 int total_frame_size;
1150 if (!reload_completed || crtl->profile)
1151 return 0;
1153 total_frame_size = nios2_compute_frame_layout ();
1155 /* If CDX is available, check if we can return using a
1156 single pop.n instruction. */
1157 if (TARGET_HAS_CDX
1158 && !frame_pointer_needed
1159 && cfun->machine->save_regs_offset <= 60
1160 && (cfun->machine->save_mask & 0x80000000) != 0
1161 && (cfun->machine->save_mask & 0xffff) == 0
1162 && crtl->args.pretend_args_size == 0)
1163 return true;
1165 return total_frame_size == 0;
1169 /* Check and signal some warnings/errors on FPU insn options. */
1170 static void
1171 nios2_custom_check_insns (void)
1173 unsigned int i, j;
1174 bool errors = false;
1176 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
1177 if (N2FPU_ENABLED_P (i) && N2FPU_DOUBLE_P (i))
1179 for (j = 0; j < ARRAY_SIZE (nios2_fpu_insn); j++)
1180 if (N2FPU_DOUBLE_REQUIRED_P (j) && ! N2FPU_ENABLED_P (j))
1182 error ("switch %<-mcustom-%s%> is required for double "
1183 "precision floating point", N2FPU_NAME (j));
1184 errors = true;
1186 break;
1189 /* Warn if the user has certain exotic operations that won't get used
1190 without -funsafe-math-optimizations. See expand_builtin () in
1191 builtins.c. */
1192 if (!flag_unsafe_math_optimizations)
1193 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
1194 if (N2FPU_ENABLED_P (i) && N2FPU_UNSAFE_P (i))
1195 warning (0, "switch %<-mcustom-%s%> has no effect unless "
1196 "-funsafe-math-optimizations is specified", N2FPU_NAME (i));
1198 /* Warn if the user is trying to use -mcustom-fmins et. al, that won't
1199 get used without -ffinite-math-only. See fold_builtin_fmin_fmax ()
1200 in builtins.c. */
1201 if (!flag_finite_math_only)
1202 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
1203 if (N2FPU_ENABLED_P (i) && N2FPU_FINITE_P (i))
1204 warning (0, "switch %<-mcustom-%s%> has no effect unless "
1205 "-ffinite-math-only is specified", N2FPU_NAME (i));
1207 /* Warn if the user is trying to use a custom rounding instruction
1208 that won't get used without -fno-math-errno. See
1209 expand_builtin_int_roundingfn_2 () in builtins.c. */
1210 if (flag_errno_math)
1211 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
1212 if (N2FPU_ENABLED_P (i) && N2FPU_NO_ERRNO_P (i))
1213 warning (0, "switch %<-mcustom-%s%> has no effect unless "
1214 "-fno-math-errno is specified", N2FPU_NAME (i));
1216 if (errors || custom_code_conflict)
1217 fatal_error (input_location,
1218 "conflicting use of -mcustom switches, target attributes, "
1219 "and/or __builtin_custom_ functions");
1222 static void
1223 nios2_set_fpu_custom_code (enum n2fpu_code code, int n, bool override_p)
1225 if (override_p || N2FPU_N (code) == -1)
1226 N2FPU_N (code) = n;
1227 nios2_register_custom_code (n, CCS_FPU, (int) code);
1230 /* Type to represent a standard FPU config. */
1231 struct nios2_fpu_config
1233 const char *name;
1234 bool set_sp_constants;
1235 int code[n2fpu_code_num];
1238 #define NIOS2_FPU_CONFIG_NUM 3
1239 static struct nios2_fpu_config custom_fpu_config[NIOS2_FPU_CONFIG_NUM];
1241 static void
1242 nios2_init_fpu_configs (void)
1244 struct nios2_fpu_config* cfg;
1245 int i = 0;
1246 #define NEXT_FPU_CONFIG \
1247 do { \
1248 cfg = &custom_fpu_config[i++]; \
1249 memset (cfg, -1, sizeof (struct nios2_fpu_config));\
1250 } while (0)
1252 NEXT_FPU_CONFIG;
1253 cfg->name = "60-1";
1254 cfg->set_sp_constants = true;
1255 cfg->code[n2fpu_fmuls] = 252;
1256 cfg->code[n2fpu_fadds] = 253;
1257 cfg->code[n2fpu_fsubs] = 254;
1259 NEXT_FPU_CONFIG;
1260 cfg->name = "60-2";
1261 cfg->set_sp_constants = true;
1262 cfg->code[n2fpu_fmuls] = 252;
1263 cfg->code[n2fpu_fadds] = 253;
1264 cfg->code[n2fpu_fsubs] = 254;
1265 cfg->code[n2fpu_fdivs] = 255;
1267 NEXT_FPU_CONFIG;
1268 cfg->name = "72-3";
1269 cfg->set_sp_constants = true;
1270 cfg->code[n2fpu_floatus] = 243;
1271 cfg->code[n2fpu_fixsi] = 244;
1272 cfg->code[n2fpu_floatis] = 245;
1273 cfg->code[n2fpu_fcmpgts] = 246;
1274 cfg->code[n2fpu_fcmples] = 249;
1275 cfg->code[n2fpu_fcmpeqs] = 250;
1276 cfg->code[n2fpu_fcmpnes] = 251;
1277 cfg->code[n2fpu_fmuls] = 252;
1278 cfg->code[n2fpu_fadds] = 253;
1279 cfg->code[n2fpu_fsubs] = 254;
1280 cfg->code[n2fpu_fdivs] = 255;
1282 #undef NEXT_FPU_CONFIG
1283 gcc_assert (i == NIOS2_FPU_CONFIG_NUM);
1286 static struct nios2_fpu_config *
1287 nios2_match_custom_fpu_cfg (const char *cfgname, const char *endp)
1289 int i;
1290 for (i = 0; i < NIOS2_FPU_CONFIG_NUM; i++)
1292 bool match = !(endp != NULL
1293 ? strncmp (custom_fpu_config[i].name, cfgname,
1294 endp - cfgname)
1295 : strcmp (custom_fpu_config[i].name, cfgname));
1296 if (match)
1297 return &custom_fpu_config[i];
1299 return NULL;
1302 /* Use CFGNAME to lookup FPU config, ENDP if not NULL marks end of string.
1303 OVERRIDE is true if loaded config codes should overwrite current state. */
1304 static void
1305 nios2_handle_custom_fpu_cfg (const char *cfgname, const char *endp,
1306 bool override)
1308 struct nios2_fpu_config *cfg = nios2_match_custom_fpu_cfg (cfgname, endp);
1309 if (cfg)
1311 unsigned int i;
1312 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
1313 if (cfg->code[i] >= 0)
1314 nios2_set_fpu_custom_code ((enum n2fpu_code) i, cfg->code[i],
1315 override);
1316 if (cfg->set_sp_constants)
1317 flag_single_precision_constant = 1;
1319 else
1320 warning (0, "ignoring unrecognized switch %<-mcustom-fpu-cfg%> "
1321 "value %<%s%>", cfgname);
1323 /* Guard against errors in the standard configurations. */
1324 nios2_custom_check_insns ();
1327 /* Check individual FPU insn options, and register custom code. */
1328 static void
1329 nios2_handle_custom_fpu_insn_option (int fpu_insn_index)
1331 int param = N2FPU_N (fpu_insn_index);
1333 if (param >= 0 && param <= 255)
1334 nios2_register_custom_code (param, CCS_FPU, fpu_insn_index);
1336 /* Valid values are 0-255, but also allow -1 so that the
1337 -mno-custom-<opt> switches work. */
1338 else if (param != -1)
1339 error ("switch %<-mcustom-%s%> value %d must be between 0 and 255",
1340 N2FPU_NAME (fpu_insn_index), param);
1343 /* Allocate a chunk of memory for per-function machine-dependent data. */
1344 static struct machine_function *
1345 nios2_init_machine_status (void)
1347 return ggc_cleared_alloc<machine_function> ();
1350 /* Implement TARGET_OPTION_OVERRIDE. */
1351 static void
1352 nios2_option_override (void)
1354 unsigned int i;
1356 #ifdef SUBTARGET_OVERRIDE_OPTIONS
1357 SUBTARGET_OVERRIDE_OPTIONS;
1358 #endif
1360 /* Check for unsupported options. */
1361 if (flag_pic && !TARGET_LINUX_ABI)
1362 sorry ("position-independent code requires the Linux ABI");
1363 if (flag_pic && stack_limit_rtx
1364 && GET_CODE (stack_limit_rtx) == SYMBOL_REF)
1365 sorry ("PIC support for -fstack-limit-symbol");
1367 /* Function to allocate machine-dependent function status. */
1368 init_machine_status = &nios2_init_machine_status;
1370 nios2_section_threshold
1371 = (global_options_set.x_g_switch_value
1372 ? g_switch_value : NIOS2_DEFAULT_GVALUE);
1374 if (nios2_gpopt_option == gpopt_unspecified)
1376 /* Default to -mgpopt unless -fpic or -fPIC. */
1377 if (flag_pic)
1378 nios2_gpopt_option = gpopt_none;
1379 else
1380 nios2_gpopt_option = gpopt_local;
1383 /* GP-relative and r0-relative addressing don't make sense for PIC. */
1384 if (flag_pic)
1386 if (nios2_gpopt_option != gpopt_none)
1387 error ("-mgpopt not supported with PIC.");
1388 if (nios2_gprel_sec)
1389 error ("-mgprel-sec= not supported with PIC.");
1390 if (nios2_r0rel_sec)
1391 error ("-mr0rel-sec= not supported with PIC.");
1394 /* Process -mgprel-sec= and -m0rel-sec=. */
1395 if (nios2_gprel_sec)
1397 if (regcomp (&nios2_gprel_sec_regex, nios2_gprel_sec,
1398 REG_EXTENDED | REG_NOSUB))
1399 error ("-mgprel-sec= argument is not a valid regular expression.");
1401 if (nios2_r0rel_sec)
1403 if (regcomp (&nios2_r0rel_sec_regex, nios2_r0rel_sec,
1404 REG_EXTENDED | REG_NOSUB))
1405 error ("-mr0rel-sec= argument is not a valid regular expression.");
1408 /* If we don't have mul, we don't have mulx either! */
1409 if (!TARGET_HAS_MUL && TARGET_HAS_MULX)
1410 target_flags &= ~MASK_HAS_MULX;
1412 /* Optional BMX and CDX instructions only make sense for R2. */
1413 if (!TARGET_ARCH_R2)
1415 if (TARGET_HAS_BMX)
1416 error ("BMX instructions are only supported with R2 architecture");
1417 if (TARGET_HAS_CDX)
1418 error ("CDX instructions are only supported with R2 architecture");
1421 /* R2 is little-endian only. */
1422 if (TARGET_ARCH_R2 && TARGET_BIG_ENDIAN)
1423 error ("R2 architecture is little-endian only");
1425 /* Initialize default FPU configurations. */
1426 nios2_init_fpu_configs ();
1428 /* Set up default handling for floating point custom instructions.
1430 Putting things in this order means that the -mcustom-fpu-cfg=
1431 switch will always be overridden by individual -mcustom-fadds=
1432 switches, regardless of the order in which they were specified
1433 on the command line.
1435 This behavior of prioritization of individual -mcustom-<insn>=
1436 options before the -mcustom-fpu-cfg= switch is maintained for
1437 compatibility. */
1438 if (nios2_custom_fpu_cfg_string && *nios2_custom_fpu_cfg_string)
1439 nios2_handle_custom_fpu_cfg (nios2_custom_fpu_cfg_string, NULL, false);
1441 /* Handle options for individual FPU insns. */
1442 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
1443 nios2_handle_custom_fpu_insn_option (i);
1445 nios2_custom_check_insns ();
1447 /* Save the initial options in case the user does function specific
1448 options. */
1449 target_option_default_node = target_option_current_node
1450 = build_target_option_node (&global_options);
1454 /* Return true if CST is a constant within range of movi/movui/movhi. */
1455 static bool
1456 nios2_simple_const_p (const_rtx cst)
1458 if (!CONST_INT_P (cst))
1459 return false;
1460 HOST_WIDE_INT val = INTVAL (cst);
1461 return SMALL_INT (val) || SMALL_INT_UNSIGNED (val) || UPPER16_INT (val);
1464 /* Compute a (partial) cost for rtx X. Return true if the complete
1465 cost has been computed, and false if subexpressions should be
1466 scanned. In either case, *TOTAL contains the cost result. */
1467 static bool
1468 nios2_rtx_costs (rtx x, machine_mode mode,
1469 int outer_code,
1470 int opno,
1471 int *total, bool speed)
1473 int code = GET_CODE (x);
1475 switch (code)
1477 case CONST_INT:
1478 if (INTVAL (x) == 0 || nios2_simple_const_p (x))
1480 *total = COSTS_N_INSNS (0);
1481 return true;
1483 else
1485 /* High + lo_sum. */
1486 *total = COSTS_N_INSNS (1);
1487 return true;
1490 case LABEL_REF:
1491 case SYMBOL_REF:
1492 case CONST:
1493 case CONST_DOUBLE:
1494 if (gprel_constant_p (x) || r0rel_constant_p (x))
1496 *total = COSTS_N_INSNS (1);
1497 return true;
1499 else
1501 /* High + lo_sum. */
1502 *total = COSTS_N_INSNS (1);
1503 return true;
1506 case HIGH:
1508 /* This is essentially a constant. */
1509 *total = COSTS_N_INSNS (0);
1510 return true;
1513 case LO_SUM:
1515 *total = COSTS_N_INSNS (0);
1516 return true;
1519 case AND:
1521 /* Recognize 'nor' insn pattern. */
1522 if (GET_CODE (XEXP (x, 0)) == NOT
1523 && GET_CODE (XEXP (x, 1)) == NOT)
1525 *total = COSTS_N_INSNS (1);
1526 return true;
1528 return false;
1531 /* For insns that have an execution latency (3 cycles), don't
1532 penalize by the full amount since we can often schedule
1533 to avoid it. */
1534 case MULT:
1536 if (!TARGET_HAS_MUL)
1537 *total = COSTS_N_INSNS (5); /* Guess? */
1538 else if (speed)
1539 *total = COSTS_N_INSNS (2); /* Latency adjustment. */
1540 else
1541 *total = COSTS_N_INSNS (1);
1542 return false;
1545 case DIV:
1547 if (!TARGET_HAS_DIV)
1548 *total = COSTS_N_INSNS (5); /* Guess? */
1549 else if (speed)
1550 *total = COSTS_N_INSNS (2); /* Latency adjustment. */
1551 else
1552 *total = COSTS_N_INSNS (1);
1553 return false;
1556 case ASHIFT:
1557 case ASHIFTRT:
1558 case LSHIFTRT:
1559 case ROTATE:
1561 if (!speed)
1562 *total = COSTS_N_INSNS (1);
1563 else
1564 *total = COSTS_N_INSNS (2); /* Latency adjustment. */
1565 return false;
1568 case ZERO_EXTRACT:
1569 if (TARGET_HAS_BMX)
1571 *total = COSTS_N_INSNS (1);
1572 return true;
1574 return false;
1576 case SIGN_EXTEND:
1578 if (MEM_P (XEXP (x, 0)))
1579 *total = COSTS_N_INSNS (1);
1580 else
1581 *total = COSTS_N_INSNS (3);
1582 return false;
1585 case MEM:
1587 rtx addr = XEXP (x, 0);
1589 /* Account for cost of different addressing modes. */
1590 *total = nios2_address_cost (addr, mode, ADDR_SPACE_GENERIC, speed);
1592 if (outer_code == SET && opno == 0)
1593 /* Stores execute in 1 cycle accounted for by
1594 the outer SET. */
1596 else if (outer_code == SET || outer_code == SIGN_EXTEND
1597 || outer_code == ZERO_EXTEND)
1598 /* Latency adjustment. */
1600 if (speed)
1601 *total += COSTS_N_INSNS (1);
1603 else
1604 /* This is going to have to be split into a load. */
1605 *total += COSTS_N_INSNS (speed ? 2 : 1);
1606 return true;
1609 default:
1610 return false;
1614 /* Implement TARGET_PREFERRED_RELOAD_CLASS. */
1615 static reg_class_t
1616 nios2_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, reg_class_t regclass)
1618 return regclass == NO_REGS ? GENERAL_REGS : regclass;
1621 /* Emit a call to __tls_get_addr. TI is the argument to this function.
1622 RET is an RTX for the return value location. The entire insn sequence
1623 is returned. */
1624 static GTY(()) rtx nios2_tls_symbol;
1626 static rtx
1627 nios2_call_tls_get_addr (rtx ti)
1629 rtx arg = gen_rtx_REG (Pmode, FIRST_ARG_REGNO);
1630 rtx ret = gen_rtx_REG (Pmode, FIRST_RETVAL_REGNO);
1631 rtx fn;
1632 rtx_insn *insn;
1634 if (!nios2_tls_symbol)
1635 nios2_tls_symbol = init_one_libfunc ("__tls_get_addr");
1637 emit_move_insn (arg, ti);
1638 fn = gen_rtx_MEM (QImode, nios2_tls_symbol);
1639 insn = emit_call_insn (gen_call_value (ret, fn, const0_rtx));
1640 RTL_CONST_CALL_P (insn) = 1;
1641 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), ret);
1642 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), arg);
1644 return ret;
1647 /* Return true for large offsets requiring hiadj/lo relocation pairs. */
1648 static bool
1649 nios2_large_offset_p (int unspec)
1651 gcc_assert (nios2_unspec_reloc_name (unspec) != NULL);
1653 if (flag_pic == 2
1654 /* FIXME: TLS GOT offset relocations will eventually also get this
1655 treatment, after binutils support for those are also completed. */
1656 && (unspec == UNSPEC_PIC_SYM || unspec == UNSPEC_PIC_CALL_SYM))
1657 return true;
1659 /* 'gotoff' offsets are always hiadj/lo. */
1660 if (unspec == UNSPEC_PIC_GOTOFF_SYM)
1661 return true;
1663 return false;
1666 /* Return true for conforming unspec relocations. Also used in
1667 constraints.md and predicates.md. */
1668 bool
1669 nios2_unspec_reloc_p (rtx op)
1671 return (GET_CODE (op) == CONST
1672 && GET_CODE (XEXP (op, 0)) == UNSPEC
1673 && ! nios2_large_offset_p (XINT (XEXP (op, 0), 1)));
1676 static bool
1677 nios2_large_unspec_reloc_p (rtx op)
1679 return (GET_CODE (op) == CONST
1680 && GET_CODE (XEXP (op, 0)) == UNSPEC
1681 && nios2_large_offset_p (XINT (XEXP (op, 0), 1)));
1684 /* Helper to generate unspec constant. */
1685 static rtx
1686 nios2_unspec_offset (rtx loc, int unspec)
1688 return gen_rtx_CONST (Pmode, gen_rtx_UNSPEC (Pmode, gen_rtvec (1, loc),
1689 unspec));
1692 /* Generate GOT pointer based address with large offset. */
1693 static rtx
1694 nios2_large_got_address (rtx offset, rtx tmp)
1696 if (!tmp)
1697 tmp = gen_reg_rtx (Pmode);
1698 emit_move_insn (tmp, offset);
1699 return gen_rtx_PLUS (Pmode, tmp, pic_offset_table_rtx);
1702 /* Generate a GOT pointer based address. */
1703 static rtx
1704 nios2_got_address (rtx loc, int unspec)
1706 rtx offset = nios2_unspec_offset (loc, unspec);
1707 crtl->uses_pic_offset_table = 1;
1709 if (nios2_large_offset_p (unspec))
1710 return force_reg (Pmode, nios2_large_got_address (offset, NULL_RTX));
1712 return gen_rtx_PLUS (Pmode, pic_offset_table_rtx, offset);
1715 /* Generate the code to access LOC, a thread local SYMBOL_REF. The
1716 return value will be a valid address and move_operand (either a REG
1717 or a LO_SUM). */
1718 static rtx
1719 nios2_legitimize_tls_address (rtx loc)
1721 rtx tmp, mem, tp;
1722 enum tls_model model = SYMBOL_REF_TLS_MODEL (loc);
1724 switch (model)
1726 case TLS_MODEL_GLOBAL_DYNAMIC:
1727 tmp = gen_reg_rtx (Pmode);
1728 emit_move_insn (tmp, nios2_got_address (loc, UNSPEC_ADD_TLS_GD));
1729 return nios2_call_tls_get_addr (tmp);
1731 case TLS_MODEL_LOCAL_DYNAMIC:
1732 tmp = gen_reg_rtx (Pmode);
1733 emit_move_insn (tmp, nios2_got_address (loc, UNSPEC_ADD_TLS_LDM));
1734 return gen_rtx_PLUS (Pmode, nios2_call_tls_get_addr (tmp),
1735 nios2_unspec_offset (loc, UNSPEC_ADD_TLS_LDO));
1737 case TLS_MODEL_INITIAL_EXEC:
1738 tmp = gen_reg_rtx (Pmode);
1739 mem = gen_const_mem (Pmode, nios2_got_address (loc, UNSPEC_LOAD_TLS_IE));
1740 emit_move_insn (tmp, mem);
1741 tp = gen_rtx_REG (Pmode, TP_REGNO);
1742 return gen_rtx_PLUS (Pmode, tp, tmp);
1744 case TLS_MODEL_LOCAL_EXEC:
1745 tp = gen_rtx_REG (Pmode, TP_REGNO);
1746 return gen_rtx_PLUS (Pmode, tp,
1747 nios2_unspec_offset (loc, UNSPEC_ADD_TLS_LE));
1748 default:
1749 gcc_unreachable ();
1753 /* Divide Support
1755 If -O3 is used, we want to output a table lookup for
1756 divides between small numbers (both num and den >= 0
1757 and < 0x10). The overhead of this method in the worst
1758 case is 40 bytes in the text section (10 insns) and
1759 256 bytes in the data section. Additional divides do
1760 not incur additional penalties in the data section.
1762 Code speed is improved for small divides by about 5x
1763 when using this method in the worse case (~9 cycles
1764 vs ~45). And in the worst case divides not within the
1765 table are penalized by about 10% (~5 cycles vs ~45).
1766 However in the typical case the penalty is not as bad
1767 because doing the long divide in only 45 cycles is
1768 quite optimistic.
1770 ??? would be nice to have some benchmarks other
1771 than Dhrystone to back this up.
1773 This bit of expansion is to create this instruction
1774 sequence as rtl.
1775 or $8, $4, $5
1776 slli $9, $4, 4
1777 cmpgeui $3, $8, 16
1778 beq $3, $0, .L3
1779 or $10, $9, $5
1780 add $12, $11, divide_table
1781 ldbu $2, 0($12)
1782 br .L1
1783 .L3:
1784 call slow_div
1785 .L1:
1786 # continue here with result in $2
1788 ??? Ideally I would like the libcall block to contain all
1789 of this code, but I don't know how to do that. What it
1790 means is that if the divide can be eliminated, it may not
1791 completely disappear.
1793 ??? The __divsi3_table label should ideally be moved out
1794 of this block and into a global. If it is placed into the
1795 sdata section we can save even more cycles by doing things
1796 gp relative. */
1797 void
1798 nios2_emit_expensive_div (rtx *operands, machine_mode mode)
1800 rtx or_result, shift_left_result;
1801 rtx lookup_value;
1802 rtx_code_label *lab1, *lab3;
1803 rtx_insn *insns;
1804 rtx libfunc;
1805 rtx final_result;
1806 rtx_insn *tmp;
1807 rtx table;
1809 /* It may look a little generic, but only SImode is supported for now. */
1810 gcc_assert (mode == SImode);
1811 libfunc = optab_libfunc (sdiv_optab, SImode);
1813 lab1 = gen_label_rtx ();
1814 lab3 = gen_label_rtx ();
1816 or_result = expand_simple_binop (SImode, IOR,
1817 operands[1], operands[2],
1818 0, 0, OPTAB_LIB_WIDEN);
1820 emit_cmp_and_jump_insns (or_result, GEN_INT (15), GTU, 0,
1821 GET_MODE (or_result), 0, lab3);
1822 JUMP_LABEL (get_last_insn ()) = lab3;
1824 shift_left_result = expand_simple_binop (SImode, ASHIFT,
1825 operands[1], GEN_INT (4),
1826 0, 0, OPTAB_LIB_WIDEN);
1828 lookup_value = expand_simple_binop (SImode, IOR,
1829 shift_left_result, operands[2],
1830 0, 0, OPTAB_LIB_WIDEN);
1831 table = gen_rtx_PLUS (SImode, lookup_value,
1832 gen_rtx_SYMBOL_REF (SImode, "__divsi3_table"));
1833 convert_move (operands[0], gen_rtx_MEM (QImode, table), 1);
1835 tmp = emit_jump_insn (gen_jump (lab1));
1836 JUMP_LABEL (tmp) = lab1;
1837 emit_barrier ();
1839 emit_label (lab3);
1840 LABEL_NUSES (lab3) = 1;
1842 start_sequence ();
1843 final_result = emit_library_call_value (libfunc, NULL_RTX,
1844 LCT_CONST, SImode,
1845 operands[1], SImode,
1846 operands[2], SImode);
1848 insns = get_insns ();
1849 end_sequence ();
1850 emit_libcall_block (insns, operands[0], final_result,
1851 gen_rtx_DIV (SImode, operands[1], operands[2]));
1853 emit_label (lab1);
1854 LABEL_NUSES (lab1) = 1;
1858 /* Branches and compares. */
1860 /* Return in *ALT_CODE and *ALT_OP, an alternate equivalent constant
1861 comparison, e.g. >= 1 into > 0. */
1862 static void
1863 nios2_alternate_compare_const (enum rtx_code code, rtx op,
1864 enum rtx_code *alt_code, rtx *alt_op,
1865 machine_mode mode)
1867 gcc_assert (CONST_INT_P (op));
1869 HOST_WIDE_INT opval = INTVAL (op);
1870 enum rtx_code scode = signed_condition (code);
1871 bool dec_p = (scode == LT || scode == GE);
1873 if (code == EQ || code == NE)
1875 *alt_code = code;
1876 *alt_op = op;
1877 return;
1880 *alt_op = (dec_p
1881 ? gen_int_mode (opval - 1, mode)
1882 : gen_int_mode (opval + 1, mode));
1884 /* The required conversion between [>,>=] and [<,<=] is captured
1885 by a reverse + swap of condition codes. */
1886 *alt_code = reverse_condition (swap_condition (code));
1889 /* Test if the incremented/decremented value crosses the over/underflow
1890 boundary. Supposedly, such boundary cases should already be transformed
1891 into always-true/false or EQ conditions, so use an assertion here. */
1892 unsigned HOST_WIDE_INT alt_opval = INTVAL (*alt_op);
1893 if (code == scode)
1894 alt_opval ^= (1 << (GET_MODE_BITSIZE (mode) - 1));
1895 alt_opval &= GET_MODE_MASK (mode);
1896 gcc_assert (dec_p ? alt_opval != GET_MODE_MASK (mode) : alt_opval != 0);
1900 /* Return true if the constant comparison is supported by nios2. */
1901 static bool
1902 nios2_valid_compare_const_p (enum rtx_code code, rtx op)
1904 gcc_assert (CONST_INT_P (op));
1905 switch (code)
1907 case EQ: case NE: case GE: case LT:
1908 return SMALL_INT (INTVAL (op));
1909 case GEU: case LTU:
1910 return SMALL_INT_UNSIGNED (INTVAL (op));
1911 default:
1912 return false;
1916 /* Checks if the FPU comparison in *CMP, *OP1, and *OP2 can be supported in
1917 the current configuration. Perform modifications if MODIFY_P is true.
1918 Returns true if FPU compare can be done. */
1920 bool
1921 nios2_validate_fpu_compare (machine_mode mode, rtx *cmp, rtx *op1, rtx *op2,
1922 bool modify_p)
1924 bool rev_p = false;
1925 enum rtx_code code = GET_CODE (*cmp);
1927 if (!nios2_fpu_compare_enabled (code, mode))
1929 code = swap_condition (code);
1930 if (nios2_fpu_compare_enabled (code, mode))
1931 rev_p = true;
1932 else
1933 return false;
1936 if (modify_p)
1938 if (rev_p)
1940 rtx tmp = *op1;
1941 *op1 = *op2;
1942 *op2 = tmp;
1944 *op1 = force_reg (mode, *op1);
1945 *op2 = force_reg (mode, *op2);
1946 *cmp = gen_rtx_fmt_ee (code, mode, *op1, *op2);
1948 return true;
1951 /* Checks and modifies the comparison in *CMP, *OP1, and *OP2 into valid
1952 nios2 supported form. Returns true if success. */
1953 bool
1954 nios2_validate_compare (machine_mode mode, rtx *cmp, rtx *op1, rtx *op2)
1956 enum rtx_code code = GET_CODE (*cmp);
1957 enum rtx_code alt_code;
1958 rtx alt_op2;
1960 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
1961 return nios2_validate_fpu_compare (mode, cmp, op1, op2, true);
1963 if (CONST_INT_P (*op2) && *op2 != const0_rtx)
1965 /* Create alternate constant compare. */
1966 nios2_alternate_compare_const (code, *op2, &alt_code, &alt_op2, mode);
1968 /* If alterate op2 is zero(0), we can use it directly, possibly
1969 swapping the compare code. */
1970 if (alt_op2 == const0_rtx)
1972 code = alt_code;
1973 *op2 = alt_op2;
1974 goto check_rebuild_cmp;
1977 /* Check if either constant compare can be used. */
1978 if (nios2_valid_compare_const_p (code, *op2))
1979 return true;
1980 else if (nios2_valid_compare_const_p (alt_code, alt_op2))
1982 code = alt_code;
1983 *op2 = alt_op2;
1984 goto rebuild_cmp;
1987 /* We have to force op2 into a register now. Try to pick one
1988 with a lower cost. */
1989 if (! nios2_simple_const_p (*op2)
1990 && nios2_simple_const_p (alt_op2))
1992 code = alt_code;
1993 *op2 = alt_op2;
1995 *op2 = force_reg (mode, *op2);
1997 else if (!reg_or_0_operand (*op2, mode))
1998 *op2 = force_reg (mode, *op2);
2000 check_rebuild_cmp:
2001 if (code == GT || code == GTU || code == LE || code == LEU)
2003 rtx t = *op1; *op1 = *op2; *op2 = t;
2004 code = swap_condition (code);
2006 rebuild_cmp:
2007 *cmp = gen_rtx_fmt_ee (code, mode, *op1, *op2);
2008 return true;
2012 /* Addressing modes and constants. */
2014 /* Symbol references and other 32-bit constants are split into
2015 high/lo_sum pairs during the split1 pass. After that, they are not
2016 considered legitimate addresses.
2017 This function returns true if in a pre-split context where these
2018 constants are allowed. */
2019 static bool
2020 nios2_large_constant_allowed (void)
2022 /* The reload_completed check is for the benefit of
2023 nios2_asm_output_mi_thunk and perhaps other places that try to
2024 emulate a post-reload pass. */
2025 return !(cfun->curr_properties & PROP_rtl_split_insns) && !reload_completed;
2028 /* Return true if X is constant expression with a reference to an
2029 "ordinary" symbol; not GOT-relative, not GP-relative, not TLS. */
2030 static bool
2031 nios2_symbolic_constant_p (rtx x)
2033 rtx base, offset;
2035 if (flag_pic)
2036 return false;
2037 if (GET_CODE (x) == LABEL_REF)
2038 return true;
2039 else if (CONSTANT_P (x))
2041 split_const (x, &base, &offset);
2042 return (SYMBOL_REF_P (base)
2043 && !SYMBOL_REF_TLS_MODEL (base)
2044 && !gprel_constant_p (base)
2045 && !r0rel_constant_p (base)
2046 && SMALL_INT (INTVAL (offset)));
2048 return false;
2051 /* Return true if X is an expression of the form
2052 (PLUS reg large_constant). */
2053 static bool
2054 nios2_plus_large_constant_p (rtx x)
2056 return (GET_CODE (x) == PLUS
2057 && REG_P (XEXP (x, 0))
2058 && nios2_large_constant_p (XEXP (x, 1)));
2061 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
2062 static bool
2063 nios2_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
2065 rtx base, offset;
2066 split_const (x, &base, &offset);
2067 return GET_CODE (base) != SYMBOL_REF || !SYMBOL_REF_TLS_MODEL (base);
2070 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
2071 static bool
2072 nios2_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
2074 return nios2_legitimate_constant_p (mode, x) == false;
2077 /* Return true if register REGNO is a valid base register.
2078 STRICT_P is true if REG_OK_STRICT is in effect. */
2080 bool
2081 nios2_regno_ok_for_base_p (int regno, bool strict_p)
2083 if (!HARD_REGISTER_NUM_P (regno))
2085 if (!strict_p)
2086 return true;
2088 if (!reg_renumber)
2089 return false;
2091 regno = reg_renumber[regno];
2094 /* The fake registers will be eliminated to either the stack or
2095 hard frame pointer, both of which are usually valid base registers.
2096 Reload deals with the cases where the eliminated form isn't valid. */
2097 return (GP_REG_P (regno)
2098 || regno == FRAME_POINTER_REGNUM
2099 || regno == ARG_POINTER_REGNUM);
2102 /* Return true if OFFSET is permitted in a load/store address expression.
2103 Normally any 16-bit value is permitted, but on R2 if we may be emitting
2104 the IO forms of these instructions we must restrict the offset to fit
2105 in a 12-bit field instead. */
2107 static bool
2108 nios2_valid_addr_offset_p (rtx offset)
2110 return (CONST_INT_P (offset)
2111 && ((TARGET_ARCH_R2 && (TARGET_BYPASS_CACHE
2112 || TARGET_BYPASS_CACHE_VOLATILE))
2113 ? SMALL_INT12 (INTVAL (offset))
2114 : SMALL_INT (INTVAL (offset))));
2117 /* Return true if the address expression formed by BASE + OFFSET is
2118 valid. */
2119 static bool
2120 nios2_valid_addr_expr_p (rtx base, rtx offset, bool strict_p)
2122 if (!strict_p && GET_CODE (base) == SUBREG)
2123 base = SUBREG_REG (base);
2124 return (REG_P (base)
2125 && nios2_regno_ok_for_base_p (REGNO (base), strict_p)
2126 && (offset == NULL_RTX
2127 || nios2_valid_addr_offset_p (offset)
2128 || (nios2_large_constant_allowed ()
2129 && nios2_symbolic_constant_p (offset))
2130 || nios2_unspec_reloc_p (offset)));
2133 /* Implement TARGET_LEGITIMATE_ADDRESS_P. */
2134 static bool
2135 nios2_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
2136 rtx operand, bool strict_p)
2138 switch (GET_CODE (operand))
2140 /* Direct. */
2141 case SYMBOL_REF:
2142 if (SYMBOL_REF_TLS_MODEL (operand))
2143 return false;
2145 /* Else, fall through. */
2146 case CONST:
2147 if (gprel_constant_p (operand) || r0rel_constant_p (operand))
2148 return true;
2150 /* Else, fall through. */
2151 case LABEL_REF:
2152 if (nios2_large_constant_allowed ()
2153 && nios2_symbolic_constant_p (operand))
2154 return true;
2155 return false;
2157 case CONST_INT:
2158 if (r0rel_constant_p (operand))
2159 return true;
2160 return nios2_large_constant_allowed ();
2162 case CONST_DOUBLE:
2163 return false;
2165 /* Register indirect. */
2166 case REG:
2167 return nios2_regno_ok_for_base_p (REGNO (operand), strict_p);
2169 /* Register indirect with displacement. */
2170 case PLUS:
2172 rtx op0 = XEXP (operand, 0);
2173 rtx op1 = XEXP (operand, 1);
2175 if (nios2_valid_addr_expr_p (op0, op1, strict_p)
2176 || nios2_valid_addr_expr_p (op1, op0, strict_p))
2177 return true;
2179 break;
2181 /* %lo(constant)(reg)
2182 This requires a 16-bit relocation and isn't valid with R2
2183 io-variant load/stores. */
2184 case LO_SUM:
2185 if (TARGET_ARCH_R2
2186 && (TARGET_BYPASS_CACHE || TARGET_BYPASS_CACHE_VOLATILE))
2187 return false;
2188 else
2190 rtx op0 = XEXP (operand, 0);
2191 rtx op1 = XEXP (operand, 1);
2193 return (REG_P (op0)
2194 && nios2_regno_ok_for_base_p (REGNO (op0), strict_p)
2195 && nios2_large_constant_p (op1));
2198 default:
2199 break;
2201 return false;
2204 /* Implement TARGET_ADDRESS_COST.
2205 Experimentation has shown that we get better code by penalizing the
2206 the (plus reg symbolic_constant) and (plus reg (const ...)) forms
2207 but giving (plus reg symbol_ref) address modes the same cost as those
2208 that don't require splitting. Also, from a theoretical point of view:
2209 - This is in line with the recommendation in the GCC internals
2210 documentation to make address forms involving multiple
2211 registers more expensive than single-register forms.
2212 - OTOH it still encourages fwprop1 to propagate constants into
2213 address expressions more aggressively.
2214 - We should discourage splitting (symbol + offset) into hi/lo pairs
2215 to allow CSE'ing the symbol when it's used with more than one offset,
2216 but not so heavily as to avoid this addressing mode at all. */
2217 static int
2218 nios2_address_cost (rtx address,
2219 machine_mode mode ATTRIBUTE_UNUSED,
2220 addr_space_t as ATTRIBUTE_UNUSED,
2221 bool speed ATTRIBUTE_UNUSED)
2223 if (nios2_plus_large_constant_p (address))
2224 return COSTS_N_INSNS (1);
2225 if (nios2_large_constant_p (address))
2227 if (GET_CODE (address) == CONST)
2228 return COSTS_N_INSNS (1);
2229 else
2230 return COSTS_N_INSNS (0);
2232 return COSTS_N_INSNS (0);
2235 /* Return true if X is a MEM whose address expression involves a large (32-bit)
2236 constant. */
2237 bool
2238 nios2_large_constant_memory_operand_p (rtx x)
2240 rtx addr;
2242 if (GET_CODE (x) != MEM)
2243 return false;
2244 addr = XEXP (x, 0);
2246 return (nios2_large_constant_p (addr)
2247 || nios2_plus_large_constant_p (addr));
2251 /* Return true if X is something that needs to be split into a
2252 high/lo_sum pair. */
2253 bool
2254 nios2_large_constant_p (rtx x)
2256 return (nios2_symbolic_constant_p (x)
2257 || nios2_large_unspec_reloc_p (x)
2258 || (CONST_INT_P (x) && !SMALL_INT (INTVAL (x))));
2261 /* Given an RTX X that satisfies nios2_large_constant_p, split it into
2262 high and lo_sum parts using TEMP as a scratch register. Emit the high
2263 instruction and return the lo_sum expression.
2264 Also handle special cases involving constant integers. */
2266 nios2_split_large_constant (rtx x, rtx temp)
2268 if (CONST_INT_P (x))
2270 HOST_WIDE_INT val = INTVAL (x);
2271 if (SMALL_INT (val))
2272 return x;
2273 else if (SMALL_INT_UNSIGNED (val) || UPPER16_INT (val))
2275 emit_move_insn (temp, x);
2276 return temp;
2278 else
2280 HOST_WIDE_INT high = (val + 0x8000) & ~0xffff;
2281 HOST_WIDE_INT low = val - high;
2282 emit_move_insn (temp, gen_int_mode (high, Pmode));
2283 return gen_rtx_PLUS (Pmode, temp, gen_int_mode (low, Pmode));
2287 emit_insn (gen_rtx_SET (temp, gen_rtx_HIGH (Pmode, copy_rtx (x))));
2288 return gen_rtx_LO_SUM (Pmode, temp, copy_rtx (x));
2291 /* Split an RTX of the form
2292 (plus op0 op1)
2293 where op1 is a large constant into
2294 (set temp (high op1))
2295 (set temp (plus op0 temp))
2296 (lo_sum temp op1)
2297 returning the lo_sum expression as the value. */
2298 static rtx
2299 nios2_split_plus_large_constant (rtx op0, rtx op1)
2301 rtx temp = gen_reg_rtx (Pmode);
2302 op0 = force_reg (Pmode, op0);
2304 emit_insn (gen_rtx_SET (temp, gen_rtx_HIGH (Pmode, copy_rtx (op1))));
2305 emit_insn (gen_rtx_SET (temp, gen_rtx_PLUS (Pmode, op0, temp)));
2306 return gen_rtx_LO_SUM (Pmode, temp, copy_rtx (op1));
2309 /* Given a MEM OP with an address that includes a splittable symbol or
2310 other large constant, emit some instructions to do the split and
2311 return a new MEM. */
2313 nios2_split_large_constant_memory_operand (rtx op)
2315 rtx addr = XEXP (op, 0);
2317 if (nios2_large_constant_p (addr))
2318 addr = nios2_split_large_constant (addr, gen_reg_rtx (Pmode));
2319 else if (nios2_plus_large_constant_p (addr))
2320 addr = nios2_split_plus_large_constant (XEXP (addr, 0), XEXP (addr, 1));
2321 else
2322 gcc_unreachable ();
2323 return replace_equiv_address (op, addr, false);
2326 /* Return true if SECTION is a small section name. */
2327 static bool
2328 nios2_small_section_name_p (const char *section)
2330 return (strcmp (section, ".sbss") == 0
2331 || strncmp (section, ".sbss.", 6) == 0
2332 || strcmp (section, ".sdata") == 0
2333 || strncmp (section, ".sdata.", 7) == 0
2334 || (nios2_gprel_sec
2335 && regexec (&nios2_gprel_sec_regex, section, 0, NULL, 0) == 0));
2338 /* Return true if SECTION is a r0-relative section name. */
2339 static bool
2340 nios2_r0rel_section_name_p (const char *section)
2342 return (nios2_r0rel_sec
2343 && regexec (&nios2_r0rel_sec_regex, section, 0, NULL, 0) == 0);
2346 /* Return true if EXP should be placed in the small data section. */
2347 static bool
2348 nios2_in_small_data_p (const_tree exp)
2350 /* We want to merge strings, so we never consider them small data. */
2351 if (TREE_CODE (exp) == STRING_CST)
2352 return false;
2354 if (TREE_CODE (exp) == VAR_DECL)
2356 if (DECL_SECTION_NAME (exp))
2358 const char *section = DECL_SECTION_NAME (exp);
2359 if (nios2_small_section_name_p (section))
2360 return true;
2362 else
2364 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
2366 /* If this is an incomplete type with size 0, then we can't put it
2367 in sdata because it might be too big when completed. */
2368 if (size > 0
2369 && (unsigned HOST_WIDE_INT) size <= nios2_section_threshold)
2370 return true;
2374 return false;
2377 /* Return true if symbol is in small data section. */
2379 static bool
2380 nios2_symbol_ref_in_small_data_p (rtx sym)
2382 tree decl;
2384 gcc_assert (GET_CODE (sym) == SYMBOL_REF);
2385 decl = SYMBOL_REF_DECL (sym);
2387 /* TLS variables are not accessed through the GP. */
2388 if (SYMBOL_REF_TLS_MODEL (sym) != 0)
2389 return false;
2391 /* On Nios II R2, there is no GP-relative relocation that can be
2392 used with "io" instructions. So, if we are implicitly generating
2393 those instructions, we cannot emit GP-relative accesses. */
2394 if (TARGET_ARCH_R2
2395 && (TARGET_BYPASS_CACHE || TARGET_BYPASS_CACHE_VOLATILE))
2396 return false;
2398 /* If the user has explicitly placed the symbol in a small data section
2399 via an attribute, generate gp-relative addressing even if the symbol
2400 is external, weak, or larger than we'd automatically put in the
2401 small data section. OTOH, if the symbol is located in some
2402 non-small-data section, we can't use gp-relative accesses on it
2403 unless the user has requested gpopt_data or gpopt_all. */
2405 switch (nios2_gpopt_option)
2407 case gpopt_none:
2408 /* Don't generate a gp-relative addressing mode if that's been
2409 disabled. */
2410 return false;
2412 case gpopt_local:
2413 /* Use GP-relative addressing for small data symbols that are
2414 not external or weak or uninitialized common, plus any symbols
2415 that have explicitly been placed in a small data section. */
2416 if (decl && DECL_SECTION_NAME (decl))
2417 return nios2_small_section_name_p (DECL_SECTION_NAME (decl));
2418 return (SYMBOL_REF_SMALL_P (sym)
2419 && !SYMBOL_REF_EXTERNAL_P (sym)
2420 && !(decl && DECL_WEAK (decl))
2421 && !(decl && DECL_COMMON (decl)
2422 && (DECL_INITIAL (decl) == NULL
2423 || (!in_lto_p
2424 && DECL_INITIAL (decl) == error_mark_node))));
2426 case gpopt_global:
2427 /* Use GP-relative addressing for small data symbols, even if
2428 they are external or weak. Note that SYMBOL_REF_SMALL_P
2429 is also true of symbols that have explicitly been placed
2430 in a small data section. */
2431 return SYMBOL_REF_SMALL_P (sym);
2433 case gpopt_data:
2434 /* Use GP-relative addressing for all data symbols regardless
2435 of the object size, but not for code symbols. This option
2436 is equivalent to the user asserting that the entire data
2437 section is accessible from the GP. */
2438 return !SYMBOL_REF_FUNCTION_P (sym);
2440 case gpopt_all:
2441 /* Use GP-relative addressing for everything, including code.
2442 Effectively, the user has asserted that the entire program
2443 fits within the 64K range of the GP offset. */
2444 return true;
2446 default:
2447 /* We shouldn't get here. */
2448 return false;
2452 /* Likewise for r0-relative addressing. */
2453 static bool
2454 nios2_symbol_ref_in_r0rel_data_p (rtx sym)
2456 tree decl;
2458 gcc_assert (GET_CODE (sym) == SYMBOL_REF);
2459 decl = SYMBOL_REF_DECL (sym);
2461 /* TLS variables are not accessed through r0. */
2462 if (SYMBOL_REF_TLS_MODEL (sym) != 0)
2463 return false;
2465 /* On Nios II R2, there is no r0-relative relocation that can be
2466 used with "io" instructions. So, if we are implicitly generating
2467 those instructions, we cannot emit r0-relative accesses. */
2468 if (TARGET_ARCH_R2
2469 && (TARGET_BYPASS_CACHE || TARGET_BYPASS_CACHE_VOLATILE))
2470 return false;
2472 /* If the user has explicitly placed the symbol in a r0rel section
2473 via an attribute, generate r0-relative addressing. */
2474 if (decl && DECL_SECTION_NAME (decl))
2475 return nios2_r0rel_section_name_p (DECL_SECTION_NAME (decl));
2476 return false;
2479 /* Implement TARGET_SECTION_TYPE_FLAGS. */
2481 static unsigned int
2482 nios2_section_type_flags (tree decl, const char *name, int reloc)
2484 unsigned int flags;
2486 flags = default_section_type_flags (decl, name, reloc);
2488 if (nios2_small_section_name_p (name))
2489 flags |= SECTION_SMALL;
2491 return flags;
2494 /* Return true if SYMBOL_REF X binds locally. */
2496 static bool
2497 nios2_symbol_binds_local_p (const_rtx x)
2499 return (SYMBOL_REF_DECL (x)
2500 ? targetm.binds_local_p (SYMBOL_REF_DECL (x))
2501 : SYMBOL_REF_LOCAL_P (x));
2504 /* Position independent code related. */
2506 /* Emit code to load the PIC register. */
2507 static void
2508 nios2_load_pic_register (void)
2510 rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM);
2512 emit_insn (gen_load_got_register (pic_offset_table_rtx, tmp));
2513 emit_insn (gen_add3_insn (pic_offset_table_rtx, pic_offset_table_rtx, tmp));
2516 /* Generate a PIC address as a MEM rtx. */
2517 static rtx
2518 nios2_load_pic_address (rtx sym, int unspec, rtx tmp)
2520 if (flag_pic == 2
2521 && GET_CODE (sym) == SYMBOL_REF
2522 && nios2_symbol_binds_local_p (sym))
2523 /* Under -fPIC, generate a GOTOFF address for local symbols. */
2525 rtx offset = nios2_unspec_offset (sym, UNSPEC_PIC_GOTOFF_SYM);
2526 crtl->uses_pic_offset_table = 1;
2527 return nios2_large_got_address (offset, tmp);
2530 return gen_const_mem (Pmode, nios2_got_address (sym, unspec));
2533 /* Nonzero if the constant value X is a legitimate general operand
2534 when generating PIC code. It is given that flag_pic is on and
2535 that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
2536 bool
2537 nios2_legitimate_pic_operand_p (rtx x)
2539 if (nios2_large_unspec_reloc_p (x))
2540 return true;
2542 return ! (GET_CODE (x) == SYMBOL_REF
2543 || GET_CODE (x) == LABEL_REF || GET_CODE (x) == CONST);
2546 /* Return TRUE if X is a thread-local symbol. */
2547 static bool
2548 nios2_tls_symbol_p (rtx x)
2550 return (targetm.have_tls && GET_CODE (x) == SYMBOL_REF
2551 && SYMBOL_REF_TLS_MODEL (x) != 0);
2554 /* Legitimize addresses that are CONSTANT_P expressions. */
2555 static rtx
2556 nios2_legitimize_constant_address (rtx addr)
2558 rtx base, offset;
2559 split_const (addr, &base, &offset);
2561 if (nios2_tls_symbol_p (base))
2562 base = nios2_legitimize_tls_address (base);
2563 else if (flag_pic)
2564 base = nios2_load_pic_address (base, UNSPEC_PIC_SYM, NULL_RTX);
2565 else if (!nios2_large_constant_allowed ()
2566 && nios2_symbolic_constant_p (addr))
2567 return nios2_split_large_constant (addr, gen_reg_rtx (Pmode));
2568 else if (CONST_INT_P (addr))
2570 HOST_WIDE_INT val = INTVAL (addr);
2571 if (SMALL_INT (val))
2572 /* Use r0-relative addressing. */
2573 return addr;
2574 else if (!nios2_large_constant_allowed ())
2575 /* Split into high/lo pair. */
2576 return nios2_split_large_constant (addr, gen_reg_rtx (Pmode));
2578 else
2579 return addr;
2581 if (offset != const0_rtx)
2583 gcc_assert (can_create_pseudo_p ());
2584 return gen_rtx_PLUS (Pmode, force_reg (Pmode, base),
2585 (CONST_INT_P (offset)
2586 ? (SMALL_INT (INTVAL (offset))
2587 ? offset : force_reg (Pmode, offset))
2588 : offset));
2590 return base;
2593 /* Implement TARGET_LEGITIMIZE_ADDRESS. */
2594 static rtx
2595 nios2_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
2596 machine_mode mode ATTRIBUTE_UNUSED)
2598 rtx op0, op1;
2600 if (CONSTANT_P (x))
2601 return nios2_legitimize_constant_address (x);
2603 /* Remaining cases all involve something + a constant. */
2604 if (GET_CODE (x) != PLUS)
2605 return x;
2607 op0 = XEXP (x, 0);
2608 op1 = XEXP (x, 1);
2610 /* Target-independent code turns (exp + constant) into plain
2611 register indirect. Although subsequent optimization passes will
2612 eventually sort that out, ivopts uses the unoptimized form for
2613 computing its cost model, so we get better results by generating
2614 the correct form from the start. */
2615 if (nios2_valid_addr_offset_p (op1))
2616 return gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), copy_rtx (op1));
2618 /* We may need to split symbolic constants now. */
2619 else if (nios2_symbolic_constant_p (op1))
2621 if (nios2_large_constant_allowed ())
2622 return gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), copy_rtx (op1));
2623 else
2624 return nios2_split_plus_large_constant (op0, op1);
2627 /* For the TLS LE (Local Exec) model, the compiler may try to
2628 combine constant offsets with unspec relocs, creating address RTXs
2629 looking like this:
2630 (plus:SI (reg:SI 23 r23)
2631 (const:SI
2632 (plus:SI
2633 (unspec:SI [(symbol_ref:SI ("var"))] UNSPEC_ADD_TLS_LE)
2634 (const_int 48 [0x30]))))
2636 This usually happens when 'var' is a thread-local struct variable,
2637 and access of a field in var causes the addend.
2639 We typically want this combining, so transform the above into this
2640 form, which is allowed:
2641 (plus:SI (reg:SI 23 r23)
2642 (const:SI
2643 (unspec:SI
2644 [(const:SI
2645 (plus:SI (symbol_ref:SI ("var"))
2646 (const_int 48 [0x30])))] UNSPEC_ADD_TLS_LE)))
2648 Which will be output as '%tls_le(var+48)(r23)' in assembly. */
2649 else if (GET_CODE (op1) == CONST)
2651 rtx unspec, offset;
2652 split_const (op1, &unspec, &offset);
2653 if (GET_CODE (unspec) == UNSPEC
2654 && !nios2_large_offset_p (XINT (unspec, 1))
2655 && offset != const0_rtx)
2657 rtx reg = force_reg (Pmode, op0);
2658 unspec = copy_rtx (unspec);
2659 XVECEXP (unspec, 0, 0)
2660 = plus_constant (Pmode, XVECEXP (unspec, 0, 0), INTVAL (offset));
2661 return gen_rtx_PLUS (Pmode, reg, gen_rtx_CONST (Pmode, unspec));
2665 return x;
2668 static rtx
2669 nios2_delegitimize_address (rtx x)
2671 x = delegitimize_mem_from_attrs (x);
2673 if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == UNSPEC)
2675 switch (XINT (XEXP (x, 0), 1))
2677 case UNSPEC_PIC_SYM:
2678 case UNSPEC_PIC_CALL_SYM:
2679 case UNSPEC_PIC_GOTOFF_SYM:
2680 case UNSPEC_ADD_TLS_GD:
2681 case UNSPEC_ADD_TLS_LDM:
2682 case UNSPEC_LOAD_TLS_IE:
2683 case UNSPEC_ADD_TLS_LE:
2684 x = XVECEXP (XEXP (x, 0), 0, 0);
2685 gcc_assert (CONSTANT_P (x));
2686 break;
2689 return x;
2692 /* Main expander function for RTL moves. */
2693 bool
2694 nios2_emit_move_sequence (rtx *operands, machine_mode mode)
2696 rtx to = operands[0];
2697 rtx from = operands[1];
2699 if (!register_operand (to, mode) && !reg_or_0_operand (from, mode))
2701 gcc_assert (can_create_pseudo_p ());
2702 from = copy_to_mode_reg (mode, from);
2705 if (CONSTANT_P (from))
2707 if (CONST_INT_P (from))
2709 if (!SMALL_INT (INTVAL (from))
2710 && !SMALL_INT_UNSIGNED (INTVAL (from))
2711 && !UPPER16_INT (INTVAL (from)))
2713 HOST_WIDE_INT high = (INTVAL (from) + 0x8000) & ~0xffff;
2714 HOST_WIDE_INT low = INTVAL (from) & 0xffff;
2715 emit_move_insn (to, gen_int_mode (high, SImode));
2716 emit_insn (gen_add2_insn (to, gen_int_mode (low, HImode)));
2717 set_unique_reg_note (get_last_insn (), REG_EQUAL,
2718 copy_rtx (from));
2719 return true;
2722 else if (gprel_constant_p (from) || r0rel_constant_p (from))
2723 /* Handled directly by movsi_internal as gp + offset
2724 or r0 + offset. */
2726 else if (nios2_large_constant_p (from))
2727 /* This case covers either a regular symbol reference or an UNSPEC
2728 representing a 32-bit offset. We split the former
2729 only conditionally and the latter always. */
2731 if (!nios2_large_constant_allowed ()
2732 || nios2_large_unspec_reloc_p (from))
2734 rtx lo = nios2_split_large_constant (from, to);
2735 emit_insn (gen_rtx_SET (to, lo));
2736 set_unique_reg_note (get_last_insn (), REG_EQUAL,
2737 copy_rtx (operands[1]));
2738 return true;
2741 else
2742 /* This is a TLS or PIC symbol. */
2744 from = nios2_legitimize_constant_address (from);
2745 if (CONSTANT_P (from))
2747 emit_insn (gen_rtx_SET (to,
2748 gen_rtx_HIGH (Pmode, copy_rtx (from))));
2749 emit_insn (gen_rtx_SET (to, gen_rtx_LO_SUM (Pmode, to, from)));
2750 set_unique_reg_note (get_last_insn (), REG_EQUAL,
2751 copy_rtx (operands[1]));
2752 return true;
2757 operands[0] = to;
2758 operands[1] = from;
2759 return false;
2762 /* The function with address *ADDR is being called. If the address
2763 needs to be loaded from the GOT, emit the instruction to do so and
2764 update *ADDR to point to the rtx for the loaded value.
2765 If REG != NULL_RTX, it is used as the target/scratch register in the
2766 GOT address calculation. */
2767 void
2768 nios2_adjust_call_address (rtx *call_op, rtx reg)
2770 if (MEM_P (*call_op))
2771 call_op = &XEXP (*call_op, 0);
2773 rtx addr = *call_op;
2774 if (flag_pic && CONSTANT_P (addr))
2776 rtx tmp = reg ? reg : NULL_RTX;
2777 if (!reg)
2778 reg = gen_reg_rtx (Pmode);
2779 addr = nios2_load_pic_address (addr, UNSPEC_PIC_CALL_SYM, tmp);
2780 emit_insn (gen_rtx_SET (reg, addr));
2781 *call_op = reg;
2786 /* Output assembly language related definitions. */
2788 /* Implement TARGET_PRINT_OPERAND_PUNCT_VALID_P. */
2789 static bool
2790 nios2_print_operand_punct_valid_p (unsigned char code)
2792 return (code == '.' || code == '!');
2796 /* Print the operand OP to file stream FILE modified by LETTER.
2797 LETTER can be one of:
2799 i: print i/hi/ui suffixes (used for mov instruction variants),
2800 when OP is the appropriate immediate operand.
2802 u: like 'i', except without "ui" suffix case (used for cmpgeu/cmpltu)
2804 o: print "io" if OP needs volatile access (due to TARGET_BYPASS_CACHE
2805 or TARGET_BYPASS_CACHE_VOLATILE).
2807 x: print i/hi/ci/chi suffixes for the and instruction,
2808 when OP is the appropriate immediate operand.
2810 z: prints the third register immediate operand in assembly
2811 instructions. Outputs const0_rtx as the 'zero' register
2812 instead of '0'.
2814 y: same as 'z', but for specifically for logical instructions,
2815 where the processing for immediates are slightly different.
2817 H: for %hiadj
2818 L: for %lo
2819 D: for the upper 32-bits of a 64-bit double value
2820 R: prints reverse condition.
2821 A: prints (reg) operand for ld[s]ex and st[s]ex.
2823 .: print .n suffix for 16-bit instructions.
2824 !: print r.n suffix for 16-bit instructions. Used for jmpr.n.
2826 static void
2827 nios2_print_operand (FILE *file, rtx op, int letter)
2830 /* First take care of the format letters that just insert a string
2831 into the output stream. */
2832 switch (letter)
2834 case '.':
2835 if (current_output_insn && get_attr_length (current_output_insn) == 2)
2836 fprintf (file, ".n");
2837 return;
2839 case '!':
2840 if (current_output_insn && get_attr_length (current_output_insn) == 2)
2841 fprintf (file, "r.n");
2842 return;
2844 case 'x':
2845 if (CONST_INT_P (op))
2847 HOST_WIDE_INT val = INTVAL (op);
2848 HOST_WIDE_INT low = val & 0xffff;
2849 HOST_WIDE_INT high = (val >> 16) & 0xffff;
2851 if (val != 0)
2853 if (high != 0)
2855 if (low != 0)
2857 gcc_assert (TARGET_ARCH_R2);
2858 if (high == 0xffff)
2859 fprintf (file, "c");
2860 else if (low == 0xffff)
2861 fprintf (file, "ch");
2862 else
2863 gcc_unreachable ();
2865 else
2866 fprintf (file, "h");
2868 fprintf (file, "i");
2871 return;
2873 case 'u':
2874 case 'i':
2875 if (CONST_INT_P (op))
2877 HOST_WIDE_INT val = INTVAL (op);
2878 HOST_WIDE_INT low = val & 0xffff;
2879 HOST_WIDE_INT high = (val >> 16) & 0xffff;
2880 if (val != 0)
2882 if (low == 0 && high != 0)
2883 fprintf (file, "h");
2884 else if (high == 0 && (low & 0x8000) != 0 && letter != 'u')
2885 fprintf (file, "u");
2888 if (CONSTANT_P (op) && op != const0_rtx)
2889 fprintf (file, "i");
2890 return;
2892 case 'o':
2893 if (GET_CODE (op) == MEM
2894 && ((MEM_VOLATILE_P (op) && TARGET_BYPASS_CACHE_VOLATILE)
2895 || TARGET_BYPASS_CACHE))
2897 gcc_assert (current_output_insn
2898 && get_attr_length (current_output_insn) == 4);
2899 fprintf (file, "io");
2901 return;
2903 default:
2904 break;
2907 /* Handle comparison operator names. */
2908 if (comparison_operator (op, VOIDmode))
2910 enum rtx_code cond = GET_CODE (op);
2911 if (letter == 0)
2913 fprintf (file, "%s", GET_RTX_NAME (cond));
2914 return;
2916 if (letter == 'R')
2918 fprintf (file, "%s", GET_RTX_NAME (reverse_condition (cond)));
2919 return;
2923 /* Now handle the cases where we actually need to format an operand. */
2924 switch (GET_CODE (op))
2926 case REG:
2927 if (letter == 0 || letter == 'z' || letter == 'y')
2929 fprintf (file, "%s", reg_names[REGNO (op)]);
2930 return;
2932 else if (letter == 'D')
2934 fprintf (file, "%s", reg_names[REGNO (op)+1]);
2935 return;
2937 break;
2939 case CONST_INT:
2941 rtx int_rtx = op;
2942 HOST_WIDE_INT val = INTVAL (int_rtx);
2943 HOST_WIDE_INT low = val & 0xffff;
2944 HOST_WIDE_INT high = (val >> 16) & 0xffff;
2946 if (letter == 'y')
2948 if (val == 0)
2949 fprintf (file, "zero");
2950 else
2952 if (high != 0)
2954 if (low != 0)
2956 gcc_assert (TARGET_ARCH_R2);
2957 if (high == 0xffff)
2958 /* andci. */
2959 int_rtx = gen_int_mode (low, SImode);
2960 else if (low == 0xffff)
2961 /* andchi. */
2962 int_rtx = gen_int_mode (high, SImode);
2963 else
2964 gcc_unreachable ();
2966 else
2967 /* andhi. */
2968 int_rtx = gen_int_mode (high, SImode);
2970 else
2971 /* andi. */
2972 int_rtx = gen_int_mode (low, SImode);
2973 output_addr_const (file, int_rtx);
2975 return;
2977 else if (letter == 'z')
2979 if (val == 0)
2980 fprintf (file, "zero");
2981 else
2983 if (low == 0 && high != 0)
2984 int_rtx = gen_int_mode (high, SImode);
2985 else if (low != 0)
2987 gcc_assert (high == 0 || high == 0xffff);
2988 int_rtx = gen_int_mode (low, high == 0 ? SImode : HImode);
2990 else
2991 gcc_unreachable ();
2992 output_addr_const (file, int_rtx);
2994 return;
2998 /* Else, fall through. */
3000 case CONST:
3001 case LABEL_REF:
3002 case SYMBOL_REF:
3003 case CONST_DOUBLE:
3004 if (letter == 0 || letter == 'z')
3006 output_addr_const (file, op);
3007 return;
3009 else if (letter == 'H' || letter == 'L')
3011 fprintf (file, "%%");
3012 if (GET_CODE (op) == CONST
3013 && GET_CODE (XEXP (op, 0)) == UNSPEC)
3015 rtx unspec = XEXP (op, 0);
3016 int unspec_reloc = XINT (unspec, 1);
3017 gcc_assert (nios2_large_offset_p (unspec_reloc));
3018 fprintf (file, "%s_", nios2_unspec_reloc_name (unspec_reloc));
3019 op = XVECEXP (unspec, 0, 0);
3021 fprintf (file, letter == 'H' ? "hiadj(" : "lo(");
3022 output_addr_const (file, op);
3023 fprintf (file, ")");
3024 return;
3026 break;
3028 case SUBREG:
3029 case MEM:
3030 if (letter == 'A')
3032 /* Address of '(reg)' form, with no index. */
3033 fprintf (file, "(%s)", reg_names[REGNO (XEXP (op, 0))]);
3034 return;
3036 if (letter == 0)
3038 output_address (VOIDmode, op);
3039 return;
3041 break;
3043 case CODE_LABEL:
3044 if (letter == 0)
3046 output_addr_const (file, op);
3047 return;
3049 break;
3051 default:
3052 break;
3055 debug_rtx (op);
3056 output_operand_lossage ("Unsupported operand for code '%c'", letter);
3057 gcc_unreachable ();
3060 /* Return true if this is a GP-relative accessible reference. */
3061 bool
3062 gprel_constant_p (rtx op)
3064 if (GET_CODE (op) == SYMBOL_REF
3065 && nios2_symbol_ref_in_small_data_p (op))
3066 return true;
3067 else if (GET_CODE (op) == CONST
3068 && GET_CODE (XEXP (op, 0)) == PLUS)
3069 return gprel_constant_p (XEXP (XEXP (op, 0), 0));
3071 return false;
3074 /* Likewise if this is a zero-relative accessible reference. */
3075 bool
3076 r0rel_constant_p (rtx op)
3078 if (GET_CODE (op) == SYMBOL_REF
3079 && nios2_symbol_ref_in_r0rel_data_p (op))
3080 return true;
3081 else if (GET_CODE (op) == CONST
3082 && GET_CODE (XEXP (op, 0)) == PLUS)
3083 return r0rel_constant_p (XEXP (XEXP (op, 0), 0));
3084 else if (GET_CODE (op) == CONST_INT
3085 && SMALL_INT (INTVAL (op)))
3086 return true;
3088 return false;
3091 /* Return the name string for a supported unspec reloc offset. */
3092 static const char *
3093 nios2_unspec_reloc_name (int unspec)
3095 switch (unspec)
3097 case UNSPEC_PIC_SYM:
3098 return "got";
3099 case UNSPEC_PIC_CALL_SYM:
3100 return "call";
3101 case UNSPEC_PIC_GOTOFF_SYM:
3102 return "gotoff";
3103 case UNSPEC_LOAD_TLS_IE:
3104 return "tls_ie";
3105 case UNSPEC_ADD_TLS_LE:
3106 return "tls_le";
3107 case UNSPEC_ADD_TLS_GD:
3108 return "tls_gd";
3109 case UNSPEC_ADD_TLS_LDM:
3110 return "tls_ldm";
3111 case UNSPEC_ADD_TLS_LDO:
3112 return "tls_ldo";
3113 default:
3114 return NULL;
3118 /* Implement TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */
3119 static bool
3120 nios2_output_addr_const_extra (FILE *file, rtx op)
3122 const char *name;
3123 gcc_assert (GET_CODE (op) == UNSPEC);
3125 /* Support for printing out const unspec relocations. */
3126 name = nios2_unspec_reloc_name (XINT (op, 1));
3127 if (name)
3129 fprintf (file, "%%%s(", name);
3130 output_addr_const (file, XVECEXP (op, 0, 0));
3131 fprintf (file, ")");
3132 return true;
3134 return false;
3137 /* Implement TARGET_PRINT_OPERAND_ADDRESS. */
3138 static void
3139 nios2_print_operand_address (FILE *file, machine_mode mode, rtx op)
3141 switch (GET_CODE (op))
3143 case CONST:
3144 case CONST_INT:
3145 case LABEL_REF:
3146 case CONST_DOUBLE:
3147 case SYMBOL_REF:
3148 if (gprel_constant_p (op))
3150 fprintf (file, "%%gprel(");
3151 output_addr_const (file, op);
3152 fprintf (file, ")(%s)", reg_names[GP_REGNO]);
3153 return;
3155 else if (r0rel_constant_p (op))
3157 if (CONST_INT_P (op))
3159 output_addr_const (file, op);
3160 fprintf (file, "(r0)");
3161 return;
3163 else
3165 fprintf (file, "%%lo(");
3166 output_addr_const (file, op);
3167 fprintf (file, ")(r0)");
3168 return;
3171 break;
3173 case PLUS:
3175 rtx op0 = XEXP (op, 0);
3176 rtx op1 = XEXP (op, 1);
3178 if (REG_P (op0) && CONSTANT_P (op1))
3180 output_addr_const (file, op1);
3181 fprintf (file, "(%s)", reg_names[REGNO (op0)]);
3182 return;
3184 else if (REG_P (op1) && CONSTANT_P (op0))
3186 output_addr_const (file, op0);
3187 fprintf (file, "(%s)", reg_names[REGNO (op1)]);
3188 return;
3191 break;
3193 case LO_SUM:
3195 rtx op0 = XEXP (op, 0);
3196 rtx op1 = XEXP (op, 1);
3198 if (REG_P (op0) && CONSTANT_P (op1))
3200 nios2_print_operand (file, op1, 'L');
3201 fprintf (file, "(%s)", reg_names[REGNO (op0)]);
3202 return;
3205 break;
3207 case REG:
3208 fprintf (file, "0(%s)", reg_names[REGNO (op)]);
3209 return;
3211 case MEM:
3213 rtx base = XEXP (op, 0);
3214 nios2_print_operand_address (file, mode, base);
3215 return;
3217 default:
3218 break;
3221 fprintf (stderr, "Missing way to print address\n");
3222 debug_rtx (op);
3223 gcc_unreachable ();
3226 /* Implement TARGET_ASM_OUTPUT_DWARF_DTPREL. */
3227 static void
3228 nios2_output_dwarf_dtprel (FILE *file, int size, rtx x)
3230 gcc_assert (size == 4);
3231 fprintf (file, "\t.4byte\t%%tls_ldo(");
3232 output_addr_const (file, x);
3233 fprintf (file, ")");
3236 /* Implemet TARGET_ASM_FILE_END. */
3238 static void
3239 nios2_asm_file_end (void)
3241 /* The Nios II Linux stack is mapped non-executable by default, so add a
3242 .note.GNU-stack section for switching to executable stacks only when
3243 trampolines are generated. */
3244 if (TARGET_LINUX_ABI && trampolines_created)
3245 file_end_indicate_exec_stack ();
3248 /* Implement TARGET_ASM_FUNCTION_PROLOGUE. */
3249 static void
3250 nios2_asm_function_prologue (FILE *file)
3252 if (flag_verbose_asm || flag_debug_asm)
3254 nios2_compute_frame_layout ();
3255 nios2_dump_frame_layout (file);
3259 /* Emit assembly of custom FPU instructions. */
3260 const char *
3261 nios2_fpu_insn_asm (enum n2fpu_code code)
3263 static char buf[256];
3264 const char *op1, *op2, *op3;
3265 int ln = 256, n = 0;
3267 int N = N2FPU_N (code);
3268 int num_operands = N2FPU (code).num_operands;
3269 const char *insn_name = N2FPU_NAME (code);
3270 tree ftype = nios2_ftype (N2FPU_FTCODE (code));
3271 machine_mode dst_mode = TYPE_MODE (TREE_TYPE (ftype));
3272 machine_mode src_mode = TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (ftype)));
3274 /* Prepare X register for DF input operands. */
3275 if (GET_MODE_SIZE (src_mode) == 8 && num_operands == 3)
3276 n = snprintf (buf, ln, "custom\t%d, zero, %%1, %%D1 # fwrx %%1\n\t",
3277 N2FPU_N (n2fpu_fwrx));
3279 if (src_mode == SFmode)
3281 if (dst_mode == VOIDmode)
3283 /* The fwry case. */
3284 op1 = op3 = "zero";
3285 op2 = "%0";
3286 num_operands -= 1;
3288 else
3290 op1 = (dst_mode == DFmode ? "%D0" : "%0");
3291 op2 = "%1";
3292 op3 = (num_operands == 2 ? "zero" : "%2");
3295 else if (src_mode == DFmode)
3297 if (dst_mode == VOIDmode)
3299 /* The fwrx case. */
3300 op1 = "zero";
3301 op2 = "%0";
3302 op3 = "%D0";
3303 num_operands -= 1;
3305 else
3307 op1 = (dst_mode == DFmode ? "%D0" : "%0");
3308 op2 = (num_operands == 2 ? "%1" : "%2");
3309 op3 = (num_operands == 2 ? "%D1" : "%D2");
3312 else if (src_mode == VOIDmode)
3314 /* frdxlo, frdxhi, frdy cases. */
3315 gcc_assert (dst_mode == SFmode);
3316 op1 = "%0";
3317 op2 = op3 = "zero";
3319 else if (src_mode == SImode)
3321 /* Conversion operators. */
3322 gcc_assert (num_operands == 2);
3323 op1 = (dst_mode == DFmode ? "%D0" : "%0");
3324 op2 = "%1";
3325 op3 = "zero";
3327 else
3328 gcc_unreachable ();
3330 /* Main instruction string. */
3331 n += snprintf (buf + n, ln - n, "custom\t%d, %s, %s, %s # %s %%0%s%s",
3332 N, op1, op2, op3, insn_name,
3333 (num_operands >= 2 ? ", %1" : ""),
3334 (num_operands == 3 ? ", %2" : ""));
3336 /* Extraction of Y register for DF results. */
3337 if (dst_mode == DFmode)
3338 snprintf (buf + n, ln - n, "\n\tcustom\t%d, %%0, zero, zero # frdy %%0",
3339 N2FPU_N (n2fpu_frdy));
3340 return buf;
3345 /* Function argument related. */
3347 /* Define where to put the arguments to a function. Value is zero to
3348 push the argument on the stack, or a hard register in which to
3349 store the argument.
3351 MODE is the argument's machine mode.
3352 TYPE is the data type of the argument (as a tree).
3353 This is null for libcalls where that information may
3354 not be available.
3355 CUM is a variable of type CUMULATIVE_ARGS which gives info about
3356 the preceding args and about the function being called.
3357 NAMED is nonzero if this argument is a named parameter
3358 (otherwise it is an extra parameter matching an ellipsis). */
3360 static rtx
3361 nios2_function_arg (cumulative_args_t cum_v, machine_mode mode,
3362 const_tree type ATTRIBUTE_UNUSED,
3363 bool named ATTRIBUTE_UNUSED)
3365 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
3366 rtx return_rtx = NULL_RTX;
3368 if (cum->regs_used < NUM_ARG_REGS)
3369 return_rtx = gen_rtx_REG (mode, FIRST_ARG_REGNO + cum->regs_used);
3371 return return_rtx;
3374 /* Return number of bytes, at the beginning of the argument, that must be
3375 put in registers. 0 is the argument is entirely in registers or entirely
3376 in memory. */
3378 static int
3379 nios2_arg_partial_bytes (cumulative_args_t cum_v,
3380 machine_mode mode, tree type ATTRIBUTE_UNUSED,
3381 bool named ATTRIBUTE_UNUSED)
3383 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
3384 HOST_WIDE_INT param_size;
3386 if (mode == BLKmode)
3388 param_size = int_size_in_bytes (type);
3389 gcc_assert (param_size >= 0);
3391 else
3392 param_size = GET_MODE_SIZE (mode);
3394 /* Convert to words (round up). */
3395 param_size = (UNITS_PER_WORD - 1 + param_size) / UNITS_PER_WORD;
3397 if (cum->regs_used < NUM_ARG_REGS
3398 && cum->regs_used + param_size > NUM_ARG_REGS)
3399 return (NUM_ARG_REGS - cum->regs_used) * UNITS_PER_WORD;
3401 return 0;
3404 /* Update the data in CUM to advance over an argument of mode MODE
3405 and data type TYPE; TYPE is null for libcalls where that information
3406 may not be available. */
3408 static void
3409 nios2_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
3410 const_tree type ATTRIBUTE_UNUSED,
3411 bool named ATTRIBUTE_UNUSED)
3413 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
3414 HOST_WIDE_INT param_size;
3416 if (mode == BLKmode)
3418 param_size = int_size_in_bytes (type);
3419 gcc_assert (param_size >= 0);
3421 else
3422 param_size = GET_MODE_SIZE (mode);
3424 /* Convert to words (round up). */
3425 param_size = (UNITS_PER_WORD - 1 + param_size) / UNITS_PER_WORD;
3427 if (cum->regs_used + param_size > NUM_ARG_REGS)
3428 cum->regs_used = NUM_ARG_REGS;
3429 else
3430 cum->regs_used += param_size;
3433 static pad_direction
3434 nios2_function_arg_padding (machine_mode mode, const_tree type)
3436 /* On little-endian targets, the first byte of every stack argument
3437 is passed in the first byte of the stack slot. */
3438 if (!BYTES_BIG_ENDIAN)
3439 return PAD_UPWARD;
3441 /* Otherwise, integral types are padded downward: the last byte of a
3442 stack argument is passed in the last byte of the stack slot. */
3443 if (type != 0
3444 ? INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)
3445 : GET_MODE_CLASS (mode) == MODE_INT)
3446 return PAD_DOWNWARD;
3448 /* Arguments smaller than a stack slot are padded downward. */
3449 if (mode != BLKmode)
3450 return (GET_MODE_BITSIZE (mode) >= PARM_BOUNDARY
3451 ? PAD_UPWARD : PAD_DOWNWARD);
3453 return ((int_size_in_bytes (type) >= (PARM_BOUNDARY / BITS_PER_UNIT))
3454 ? PAD_UPWARD : PAD_DOWNWARD);
3457 pad_direction
3458 nios2_block_reg_padding (machine_mode mode, tree type,
3459 int first ATTRIBUTE_UNUSED)
3461 return nios2_function_arg_padding (mode, type);
3464 /* Emit RTL insns to initialize the variable parts of a trampoline.
3465 FNADDR is an RTX for the address of the function's pure code.
3466 CXT is an RTX for the static chain value for the function.
3467 On Nios II, we handle this by a library call. */
3468 static void
3469 nios2_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
3471 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
3472 rtx ctx_reg = force_reg (Pmode, cxt);
3473 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
3475 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
3476 LCT_NORMAL, VOIDmode, addr, Pmode, fnaddr, Pmode,
3477 ctx_reg, Pmode);
3480 /* Implement TARGET_FUNCTION_VALUE. */
3481 static rtx
3482 nios2_function_value (const_tree ret_type, const_tree fn ATTRIBUTE_UNUSED,
3483 bool outgoing ATTRIBUTE_UNUSED)
3485 return gen_rtx_REG (TYPE_MODE (ret_type), FIRST_RETVAL_REGNO);
3488 /* Implement TARGET_LIBCALL_VALUE. */
3489 static rtx
3490 nios2_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
3492 return gen_rtx_REG (mode, FIRST_RETVAL_REGNO);
3495 /* Implement TARGET_FUNCTION_VALUE_REGNO_P. */
3496 static bool
3497 nios2_function_value_regno_p (const unsigned int regno)
3499 return regno == FIRST_RETVAL_REGNO;
3502 /* Implement TARGET_RETURN_IN_MEMORY. */
3503 static bool
3504 nios2_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
3506 return (int_size_in_bytes (type) > (2 * UNITS_PER_WORD)
3507 || int_size_in_bytes (type) == -1);
3510 /* TODO: It may be possible to eliminate the copyback and implement
3511 own va_arg type. */
3512 static void
3513 nios2_setup_incoming_varargs (cumulative_args_t cum_v,
3514 machine_mode mode, tree type,
3515 int *pretend_size, int second_time)
3517 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
3518 CUMULATIVE_ARGS local_cum;
3519 cumulative_args_t local_cum_v = pack_cumulative_args (&local_cum);
3520 int regs_to_push;
3521 int pret_size;
3523 cfun->machine->uses_anonymous_args = 1;
3524 local_cum = *cum;
3525 nios2_function_arg_advance (local_cum_v, mode, type, true);
3527 regs_to_push = NUM_ARG_REGS - local_cum.regs_used;
3529 /* If we can use CDX stwm to push the arguments on the stack,
3530 nios2_expand_prologue will do that instead. */
3531 if (!TARGET_HAS_CDX && !second_time && regs_to_push > 0)
3533 rtx ptr = virtual_incoming_args_rtx;
3534 rtx mem = gen_rtx_MEM (BLKmode, ptr);
3535 emit_insn (gen_blockage ());
3536 move_block_from_reg (local_cum.regs_used + FIRST_ARG_REGNO, mem,
3537 regs_to_push);
3538 emit_insn (gen_blockage ());
3541 pret_size = regs_to_push * UNITS_PER_WORD;
3542 if (pret_size)
3543 *pretend_size = pret_size;
3548 /* Init FPU builtins. */
3549 static void
3550 nios2_init_fpu_builtins (int start_code)
3552 tree fndecl;
3553 char builtin_name[64] = "__builtin_custom_";
3554 unsigned int i, n = strlen ("__builtin_custom_");
3556 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
3558 snprintf (builtin_name + n, sizeof (builtin_name) - n,
3559 "%s", N2FPU_NAME (i));
3560 fndecl =
3561 add_builtin_function (builtin_name, nios2_ftype (N2FPU_FTCODE (i)),
3562 start_code + i, BUILT_IN_MD, NULL, NULL_TREE);
3563 nios2_register_builtin_fndecl (start_code + i, fndecl);
3567 /* Helper function for expanding FPU builtins. */
3568 static rtx
3569 nios2_expand_fpu_builtin (tree exp, unsigned int code, rtx target)
3571 struct expand_operand ops[MAX_RECOG_OPERANDS];
3572 enum insn_code icode = N2FPU_ICODE (code);
3573 int nargs, argno, opno = 0;
3574 int num_operands = N2FPU (code).num_operands;
3575 machine_mode dst_mode = TYPE_MODE (TREE_TYPE (exp));
3576 bool has_target_p = (dst_mode != VOIDmode);
3578 if (N2FPU_N (code) < 0)
3579 fatal_error (input_location,
3580 "Cannot call %<__builtin_custom_%s%> without specifying switch"
3581 " %<-mcustom-%s%>", N2FPU_NAME (code), N2FPU_NAME (code));
3582 if (has_target_p)
3583 create_output_operand (&ops[opno++], target, dst_mode);
3584 else
3585 /* Subtract away the count of the VOID return, mainly for fwrx/fwry. */
3586 num_operands -= 1;
3587 nargs = call_expr_nargs (exp);
3588 for (argno = 0; argno < nargs; argno++)
3590 tree arg = CALL_EXPR_ARG (exp, argno);
3591 create_input_operand (&ops[opno++], expand_normal (arg),
3592 TYPE_MODE (TREE_TYPE (arg)));
3594 if (!maybe_expand_insn (icode, num_operands, ops))
3596 error ("invalid argument to built-in function");
3597 return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx;
3599 return has_target_p ? ops[0].value : const0_rtx;
3602 /* Nios II has custom instruction built-in functions of the forms:
3603 __builtin_custom_n
3604 __builtin_custom_nX
3605 __builtin_custom_nXX
3606 __builtin_custom_Xn
3607 __builtin_custom_XnX
3608 __builtin_custom_XnXX
3610 where each X could be either 'i' (int), 'f' (float), or 'p' (void*).
3611 Therefore with 0-1 return values, and 0-2 arguments, we have a
3612 total of (3 + 1) * (1 + 3 + 9) == 52 custom builtin functions.
3614 #define NUM_CUSTOM_BUILTINS ((3 + 1) * (1 + 3 + 9))
3615 static char custom_builtin_name[NUM_CUSTOM_BUILTINS][5];
3617 static void
3618 nios2_init_custom_builtins (int start_code)
3620 tree builtin_ftype, ret_type, fndecl;
3621 char builtin_name[32] = "__builtin_custom_";
3622 int n = strlen ("__builtin_custom_");
3623 int builtin_code = 0;
3624 int lhs, rhs1, rhs2;
3626 struct { tree type; const char *c; } op[4];
3627 /* z */ op[0].c = ""; op[0].type = NULL_TREE;
3628 /* f */ op[1].c = "f"; op[1].type = float_type_node;
3629 /* i */ op[2].c = "i"; op[2].type = integer_type_node;
3630 /* p */ op[3].c = "p"; op[3].type = ptr_type_node;
3632 /* We enumerate through the possible operand types to create all the
3633 __builtin_custom_XnXX function tree types. Note that these may slightly
3634 overlap with the function types created for other fixed builtins. */
3636 for (lhs = 0; lhs < 4; lhs++)
3637 for (rhs1 = 0; rhs1 < 4; rhs1++)
3638 for (rhs2 = 0; rhs2 < 4; rhs2++)
3640 if (rhs1 == 0 && rhs2 != 0)
3641 continue;
3642 ret_type = (op[lhs].type ? op[lhs].type : void_type_node);
3643 builtin_ftype
3644 = build_function_type_list (ret_type, integer_type_node,
3645 op[rhs1].type, op[rhs2].type,
3646 NULL_TREE);
3647 snprintf (builtin_name + n, 32 - n, "%sn%s%s",
3648 op[lhs].c, op[rhs1].c, op[rhs2].c);
3649 /* Save copy of parameter string into custom_builtin_name[]. */
3650 strncpy (custom_builtin_name[builtin_code], builtin_name + n, 5);
3651 fndecl =
3652 add_builtin_function (builtin_name, builtin_ftype,
3653 start_code + builtin_code,
3654 BUILT_IN_MD, NULL, NULL_TREE);
3655 nios2_register_builtin_fndecl (start_code + builtin_code, fndecl);
3656 builtin_code += 1;
3660 /* Helper function for expanding custom builtins. */
3661 static rtx
3662 nios2_expand_custom_builtin (tree exp, unsigned int index, rtx target)
3664 bool has_target_p = (TREE_TYPE (exp) != void_type_node);
3665 machine_mode tmode = VOIDmode;
3666 int nargs, argno;
3667 rtx value, insn, unspec_args[3];
3668 tree arg;
3670 /* XnXX form. */
3671 if (has_target_p)
3673 tmode = TYPE_MODE (TREE_TYPE (exp));
3674 if (!target || GET_MODE (target) != tmode
3675 || !REG_P (target))
3676 target = gen_reg_rtx (tmode);
3679 nargs = call_expr_nargs (exp);
3680 for (argno = 0; argno < nargs; argno++)
3682 arg = CALL_EXPR_ARG (exp, argno);
3683 value = expand_normal (arg);
3684 unspec_args[argno] = value;
3685 if (argno == 0)
3687 if (!custom_insn_opcode (value, VOIDmode))
3688 error ("custom instruction opcode must be compile time "
3689 "constant in the range 0-255 for __builtin_custom_%s",
3690 custom_builtin_name[index]);
3692 else
3693 /* For other arguments, force into a register. */
3694 unspec_args[argno] = force_reg (TYPE_MODE (TREE_TYPE (arg)),
3695 unspec_args[argno]);
3697 /* Fill remaining unspec operands with zero. */
3698 for (; argno < 3; argno++)
3699 unspec_args[argno] = const0_rtx;
3701 insn = (has_target_p
3702 ? gen_rtx_SET (target,
3703 gen_rtx_UNSPEC_VOLATILE (tmode,
3704 gen_rtvec_v (3, unspec_args),
3705 UNSPECV_CUSTOM_XNXX))
3706 : gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec_v (3, unspec_args),
3707 UNSPECV_CUSTOM_NXX));
3708 emit_insn (insn);
3709 return has_target_p ? target : const0_rtx;
3715 /* Main definition of built-in functions. Nios II has a small number of fixed
3716 builtins, plus a large number of FPU insn builtins, and builtins for
3717 generating custom instructions. */
3719 struct nios2_builtin_desc
3721 enum insn_code icode;
3722 enum nios2_arch_type arch;
3723 enum nios2_ftcode ftype;
3724 const char *name;
3727 #define N2_BUILTINS \
3728 N2_BUILTIN_DEF (sync, R1, N2_FTYPE_VOID_VOID) \
3729 N2_BUILTIN_DEF (ldbio, R1, N2_FTYPE_SI_CVPTR) \
3730 N2_BUILTIN_DEF (ldbuio, R1, N2_FTYPE_UI_CVPTR) \
3731 N2_BUILTIN_DEF (ldhio, R1, N2_FTYPE_SI_CVPTR) \
3732 N2_BUILTIN_DEF (ldhuio, R1, N2_FTYPE_UI_CVPTR) \
3733 N2_BUILTIN_DEF (ldwio, R1, N2_FTYPE_SI_CVPTR) \
3734 N2_BUILTIN_DEF (stbio, R1, N2_FTYPE_VOID_VPTR_SI) \
3735 N2_BUILTIN_DEF (sthio, R1, N2_FTYPE_VOID_VPTR_SI) \
3736 N2_BUILTIN_DEF (stwio, R1, N2_FTYPE_VOID_VPTR_SI) \
3737 N2_BUILTIN_DEF (rdctl, R1, N2_FTYPE_SI_SI) \
3738 N2_BUILTIN_DEF (wrctl, R1, N2_FTYPE_VOID_SI_SI) \
3739 N2_BUILTIN_DEF (rdprs, R1, N2_FTYPE_SI_SI_SI) \
3740 N2_BUILTIN_DEF (flushd, R1, N2_FTYPE_VOID_VPTR) \
3741 N2_BUILTIN_DEF (flushda, R1, N2_FTYPE_VOID_VPTR) \
3742 N2_BUILTIN_DEF (wrpie, R2, N2_FTYPE_SI_SI) \
3743 N2_BUILTIN_DEF (eni, R2, N2_FTYPE_VOID_SI) \
3744 N2_BUILTIN_DEF (ldex, R2, N2_FTYPE_SI_CVPTR) \
3745 N2_BUILTIN_DEF (ldsex, R2, N2_FTYPE_SI_CVPTR) \
3746 N2_BUILTIN_DEF (stex, R2, N2_FTYPE_SI_VPTR_SI) \
3747 N2_BUILTIN_DEF (stsex, R2, N2_FTYPE_SI_VPTR_SI)
3749 enum nios2_builtin_code {
3750 #define N2_BUILTIN_DEF(name, arch, ftype) NIOS2_BUILTIN_ ## name,
3751 N2_BUILTINS
3752 #undef N2_BUILTIN_DEF
3753 NUM_FIXED_NIOS2_BUILTINS
3756 static const struct nios2_builtin_desc nios2_builtins[] = {
3757 #define N2_BUILTIN_DEF(name, arch, ftype) \
3758 { CODE_FOR_ ## name, ARCH_ ## arch, ftype, "__builtin_" #name },
3759 N2_BUILTINS
3760 #undef N2_BUILTIN_DEF
3763 /* Start/ends of FPU/custom insn builtin index ranges. */
3764 static unsigned int nios2_fpu_builtin_base;
3765 static unsigned int nios2_custom_builtin_base;
3766 static unsigned int nios2_custom_builtin_end;
3768 /* Implement TARGET_INIT_BUILTINS. */
3769 static void
3770 nios2_init_builtins (void)
3772 unsigned int i;
3774 /* Initialize fixed builtins. */
3775 for (i = 0; i < ARRAY_SIZE (nios2_builtins); i++)
3777 const struct nios2_builtin_desc *d = &nios2_builtins[i];
3778 tree fndecl =
3779 add_builtin_function (d->name, nios2_ftype (d->ftype), i,
3780 BUILT_IN_MD, NULL, NULL);
3781 nios2_register_builtin_fndecl (i, fndecl);
3784 /* Initialize FPU builtins. */
3785 nios2_fpu_builtin_base = ARRAY_SIZE (nios2_builtins);
3786 nios2_init_fpu_builtins (nios2_fpu_builtin_base);
3788 /* Initialize custom insn builtins. */
3789 nios2_custom_builtin_base
3790 = nios2_fpu_builtin_base + ARRAY_SIZE (nios2_fpu_insn);
3791 nios2_custom_builtin_end
3792 = nios2_custom_builtin_base + NUM_CUSTOM_BUILTINS;
3793 nios2_init_custom_builtins (nios2_custom_builtin_base);
3796 /* Array of fndecls for TARGET_BUILTIN_DECL. */
3797 #define NIOS2_NUM_BUILTINS \
3798 (ARRAY_SIZE (nios2_builtins) + ARRAY_SIZE (nios2_fpu_insn) + NUM_CUSTOM_BUILTINS)
3799 static GTY(()) tree nios2_builtin_decls[NIOS2_NUM_BUILTINS];
3801 static void
3802 nios2_register_builtin_fndecl (unsigned code, tree fndecl)
3804 nios2_builtin_decls[code] = fndecl;
3807 /* Implement TARGET_BUILTIN_DECL. */
3808 static tree
3809 nios2_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
3811 gcc_assert (nios2_custom_builtin_end == ARRAY_SIZE (nios2_builtin_decls));
3813 if (code >= nios2_custom_builtin_end)
3814 return error_mark_node;
3816 if (code >= nios2_fpu_builtin_base
3817 && code < nios2_custom_builtin_base
3818 && ! N2FPU_ENABLED_P (code - nios2_fpu_builtin_base))
3819 return error_mark_node;
3821 return nios2_builtin_decls[code];
3825 /* Low-level built-in expand routine. */
3826 static rtx
3827 nios2_expand_builtin_insn (const struct nios2_builtin_desc *d, int n,
3828 struct expand_operand *ops, bool has_target_p)
3830 if (maybe_expand_insn (d->icode, n, ops))
3831 return has_target_p ? ops[0].value : const0_rtx;
3832 else
3834 error ("invalid argument to built-in function %s", d->name);
3835 return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx;
3839 /* Expand ldio/stio and ldex/ldsex/stex/stsex form load-store
3840 instruction builtins. */
3841 static rtx
3842 nios2_expand_ldst_builtin (tree exp, rtx target,
3843 const struct nios2_builtin_desc *d)
3845 bool has_target_p;
3846 rtx addr, mem, val;
3847 struct expand_operand ops[MAX_RECOG_OPERANDS];
3848 machine_mode mode = insn_data[d->icode].operand[0].mode;
3850 addr = expand_normal (CALL_EXPR_ARG (exp, 0));
3851 mem = gen_rtx_MEM (mode, addr);
3853 if (insn_data[d->icode].operand[0].allows_mem)
3855 /* stxio/stex/stsex. */
3856 val = expand_normal (CALL_EXPR_ARG (exp, 1));
3857 if (CONST_INT_P (val))
3858 val = force_reg (mode, gen_int_mode (INTVAL (val), mode));
3859 val = simplify_gen_subreg (mode, val, GET_MODE (val), 0);
3860 create_output_operand (&ops[0], mem, mode);
3861 create_input_operand (&ops[1], val, mode);
3862 if (insn_data[d->icode].n_operands == 3)
3864 /* stex/stsex status value, returned as result of function. */
3865 create_output_operand (&ops[2], target, mode);
3866 has_target_p = true;
3868 else
3869 has_target_p = false;
3871 else
3873 /* ldxio. */
3874 create_output_operand (&ops[0], target, mode);
3875 create_input_operand (&ops[1], mem, mode);
3876 has_target_p = true;
3878 return nios2_expand_builtin_insn (d, insn_data[d->icode].n_operands, ops,
3879 has_target_p);
3882 /* Expand rdctl/wrctl builtins. */
3883 static rtx
3884 nios2_expand_rdwrctl_builtin (tree exp, rtx target,
3885 const struct nios2_builtin_desc *d)
3887 bool has_target_p = (insn_data[d->icode].operand[0].predicate
3888 == register_operand);
3889 rtx ctlcode = expand_normal (CALL_EXPR_ARG (exp, 0));
3890 struct expand_operand ops[MAX_RECOG_OPERANDS];
3891 if (!rdwrctl_operand (ctlcode, VOIDmode))
3893 error ("Control register number must be in range 0-31 for %s",
3894 d->name);
3895 return has_target_p ? gen_reg_rtx (SImode) : const0_rtx;
3897 if (has_target_p)
3899 create_output_operand (&ops[0], target, SImode);
3900 create_integer_operand (&ops[1], INTVAL (ctlcode));
3902 else
3904 rtx val = expand_normal (CALL_EXPR_ARG (exp, 1));
3905 create_integer_operand (&ops[0], INTVAL (ctlcode));
3906 create_input_operand (&ops[1], val, SImode);
3908 return nios2_expand_builtin_insn (d, 2, ops, has_target_p);
3911 static rtx
3912 nios2_expand_rdprs_builtin (tree exp, rtx target,
3913 const struct nios2_builtin_desc *d)
3915 rtx reg = expand_normal (CALL_EXPR_ARG (exp, 0));
3916 rtx imm = expand_normal (CALL_EXPR_ARG (exp, 1));
3917 struct expand_operand ops[MAX_RECOG_OPERANDS];
3919 if (!rdwrctl_operand (reg, VOIDmode))
3921 error ("Register number must be in range 0-31 for %s",
3922 d->name);
3923 return gen_reg_rtx (SImode);
3926 if (!rdprs_dcache_operand (imm, VOIDmode))
3928 error ("The immediate value must fit into a %d-bit integer for %s",
3929 (TARGET_ARCH_R2) ? 12 : 16, d->name);
3930 return gen_reg_rtx (SImode);
3933 create_output_operand (&ops[0], target, SImode);
3934 create_input_operand (&ops[1], reg, SImode);
3935 create_integer_operand (&ops[2], INTVAL (imm));
3937 return nios2_expand_builtin_insn (d, 3, ops, true);
3940 static rtx
3941 nios2_expand_cache_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
3942 const struct nios2_builtin_desc *d)
3944 rtx mem, addr;
3945 struct expand_operand ops[MAX_RECOG_OPERANDS];
3947 addr = expand_normal (CALL_EXPR_ARG (exp, 0));
3948 mem = gen_rtx_MEM (SImode, addr);
3950 create_input_operand (&ops[0], mem, SImode);
3952 return nios2_expand_builtin_insn (d, 1, ops, false);
3955 static rtx
3956 nios2_expand_wrpie_builtin (tree exp, rtx target,
3957 const struct nios2_builtin_desc *d)
3959 rtx val;
3960 struct expand_operand ops[MAX_RECOG_OPERANDS];
3962 val = expand_normal (CALL_EXPR_ARG (exp, 0));
3963 create_input_operand (&ops[1], val, SImode);
3964 create_output_operand (&ops[0], target, SImode);
3966 return nios2_expand_builtin_insn (d, 2, ops, true);
3969 static rtx
3970 nios2_expand_eni_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
3971 const struct nios2_builtin_desc *d)
3973 rtx imm = expand_normal (CALL_EXPR_ARG (exp, 0));
3974 struct expand_operand ops[MAX_RECOG_OPERANDS];
3976 if (INTVAL (imm) != 0 && INTVAL (imm) != 1)
3978 error ("The ENI instruction operand must be either 0 or 1");
3979 return const0_rtx;
3981 create_integer_operand (&ops[0], INTVAL (imm));
3983 return nios2_expand_builtin_insn (d, 1, ops, false);
3986 /* Implement TARGET_EXPAND_BUILTIN. Expand an expression EXP that calls
3987 a built-in function, with result going to TARGET if that's convenient
3988 (and in mode MODE if that's convenient).
3989 SUBTARGET may be used as the target for computing one of EXP's operands.
3990 IGNORE is nonzero if the value is to be ignored. */
3992 static rtx
3993 nios2_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
3994 machine_mode mode ATTRIBUTE_UNUSED,
3995 int ignore ATTRIBUTE_UNUSED)
3997 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
3998 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4000 if (fcode < nios2_fpu_builtin_base)
4002 const struct nios2_builtin_desc *d = &nios2_builtins[fcode];
4004 if (d->arch > nios2_arch_option)
4006 error ("Builtin function %s requires Nios II R%d",
4007 d->name, (int) d->arch);
4008 /* Given it is invalid, just generate a normal call. */
4009 return expand_call (exp, target, ignore);
4012 switch (fcode)
4014 case NIOS2_BUILTIN_sync:
4015 emit_insn (gen_sync ());
4016 return const0_rtx;
4018 case NIOS2_BUILTIN_ldbio:
4019 case NIOS2_BUILTIN_ldbuio:
4020 case NIOS2_BUILTIN_ldhio:
4021 case NIOS2_BUILTIN_ldhuio:
4022 case NIOS2_BUILTIN_ldwio:
4023 case NIOS2_BUILTIN_stbio:
4024 case NIOS2_BUILTIN_sthio:
4025 case NIOS2_BUILTIN_stwio:
4026 case NIOS2_BUILTIN_ldex:
4027 case NIOS2_BUILTIN_ldsex:
4028 case NIOS2_BUILTIN_stex:
4029 case NIOS2_BUILTIN_stsex:
4030 return nios2_expand_ldst_builtin (exp, target, d);
4032 case NIOS2_BUILTIN_rdctl:
4033 case NIOS2_BUILTIN_wrctl:
4034 return nios2_expand_rdwrctl_builtin (exp, target, d);
4036 case NIOS2_BUILTIN_rdprs:
4037 return nios2_expand_rdprs_builtin (exp, target, d);
4039 case NIOS2_BUILTIN_flushd:
4040 case NIOS2_BUILTIN_flushda:
4041 return nios2_expand_cache_builtin (exp, target, d);
4043 case NIOS2_BUILTIN_wrpie:
4044 return nios2_expand_wrpie_builtin (exp, target, d);
4046 case NIOS2_BUILTIN_eni:
4047 return nios2_expand_eni_builtin (exp, target, d);
4049 default:
4050 gcc_unreachable ();
4053 else if (fcode < nios2_custom_builtin_base)
4054 /* FPU builtin range. */
4055 return nios2_expand_fpu_builtin (exp, fcode - nios2_fpu_builtin_base,
4056 target);
4057 else if (fcode < nios2_custom_builtin_end)
4058 /* Custom insn builtin range. */
4059 return nios2_expand_custom_builtin (exp, fcode - nios2_custom_builtin_base,
4060 target);
4061 else
4062 gcc_unreachable ();
4065 /* Implement TARGET_INIT_LIBFUNCS. */
4066 static void ATTRIBUTE_UNUSED
4067 nios2_init_libfuncs (void)
4069 init_sync_libfuncs (UNITS_PER_WORD);
4074 /* Register a custom code use, and signal error if a conflict was found. */
4075 static void
4076 nios2_register_custom_code (unsigned int N, enum nios2_ccs_code status,
4077 int index)
4079 gcc_assert (N <= 255);
4081 if (status == CCS_FPU)
4083 if (custom_code_status[N] == CCS_FPU && index != custom_code_index[N])
4085 custom_code_conflict = true;
4086 error ("switch %<-mcustom-%s%> conflicts with switch %<-mcustom-%s%>",
4087 N2FPU_NAME (custom_code_index[N]), N2FPU_NAME (index));
4089 else if (custom_code_status[N] == CCS_BUILTIN_CALL)
4091 custom_code_conflict = true;
4092 error ("call to %<__builtin_custom_%s%> conflicts with switch "
4093 "%<-mcustom-%s%>", custom_builtin_name[custom_code_index[N]],
4094 N2FPU_NAME (index));
4097 else if (status == CCS_BUILTIN_CALL)
4099 if (custom_code_status[N] == CCS_FPU)
4101 custom_code_conflict = true;
4102 error ("call to %<__builtin_custom_%s%> conflicts with switch "
4103 "%<-mcustom-%s%>", custom_builtin_name[index],
4104 N2FPU_NAME (custom_code_index[N]));
4106 else
4108 /* Note that code conflicts between different __builtin_custom_xnxx
4109 calls are not checked. */
4112 else
4113 gcc_unreachable ();
4115 custom_code_status[N] = status;
4116 custom_code_index[N] = index;
4119 /* Mark a custom code as not in use. */
4120 static void
4121 nios2_deregister_custom_code (unsigned int N)
4123 if (N <= 255)
4125 custom_code_status[N] = CCS_UNUSED;
4126 custom_code_index[N] = 0;
4130 /* Target attributes can affect per-function option state, so we need to
4131 save/restore the custom code tracking info using the
4132 TARGET_OPTION_SAVE/TARGET_OPTION_RESTORE hooks. */
4134 static void
4135 nios2_option_save (struct cl_target_option *ptr,
4136 struct gcc_options *opts ATTRIBUTE_UNUSED)
4138 unsigned int i;
4139 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
4140 ptr->saved_fpu_custom_code[i] = N2FPU_N (i);
4141 memcpy (ptr->saved_custom_code_status, custom_code_status,
4142 sizeof (custom_code_status));
4143 memcpy (ptr->saved_custom_code_index, custom_code_index,
4144 sizeof (custom_code_index));
4147 static void
4148 nios2_option_restore (struct gcc_options *opts ATTRIBUTE_UNUSED,
4149 struct cl_target_option *ptr)
4151 unsigned int i;
4152 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
4153 N2FPU_N (i) = ptr->saved_fpu_custom_code[i];
4154 memcpy (custom_code_status, ptr->saved_custom_code_status,
4155 sizeof (custom_code_status));
4156 memcpy (custom_code_index, ptr->saved_custom_code_index,
4157 sizeof (custom_code_index));
4160 /* Inner function to process the attribute((target(...))), take an argument and
4161 set the current options from the argument. If we have a list, recursively
4162 go over the list. */
4164 static bool
4165 nios2_valid_target_attribute_rec (tree args)
4167 if (TREE_CODE (args) == TREE_LIST)
4169 bool ret = true;
4170 for (; args; args = TREE_CHAIN (args))
4171 if (TREE_VALUE (args)
4172 && !nios2_valid_target_attribute_rec (TREE_VALUE (args)))
4173 ret = false;
4174 return ret;
4176 else if (TREE_CODE (args) == STRING_CST)
4178 char *argstr = ASTRDUP (TREE_STRING_POINTER (args));
4179 while (argstr && *argstr != '\0')
4181 bool no_opt = false, end_p = false;
4182 char *eq = NULL, *p;
4183 while (ISSPACE (*argstr))
4184 argstr++;
4185 p = argstr;
4186 while (*p != '\0' && *p != ',')
4188 if (!eq && *p == '=')
4189 eq = p;
4190 ++p;
4192 if (*p == '\0')
4193 end_p = true;
4194 else
4195 *p = '\0';
4196 if (eq) *eq = '\0';
4198 if (!strncmp (argstr, "no-", 3))
4200 no_opt = true;
4201 argstr += 3;
4203 if (!strncmp (argstr, "custom-fpu-cfg", 14))
4205 char *end_eq = p;
4206 if (no_opt)
4208 error ("custom-fpu-cfg option does not support %<no-%>");
4209 return false;
4211 if (!eq)
4213 error ("custom-fpu-cfg option requires configuration"
4214 " argument");
4215 return false;
4217 /* Increment and skip whitespace. */
4218 while (ISSPACE (*(++eq))) ;
4219 /* Decrement and skip to before any trailing whitespace. */
4220 while (ISSPACE (*(--end_eq))) ;
4222 nios2_handle_custom_fpu_cfg (eq, end_eq + 1, true);
4224 else if (!strncmp (argstr, "custom-", 7))
4226 int code = -1;
4227 unsigned int i;
4228 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
4229 if (!strncmp (argstr + 7, N2FPU_NAME (i),
4230 strlen (N2FPU_NAME (i))))
4232 /* Found insn. */
4233 code = i;
4234 break;
4236 if (code >= 0)
4238 if (no_opt)
4240 if (eq)
4242 error ("%<no-custom-%s%> does not accept arguments",
4243 N2FPU_NAME (code));
4244 return false;
4246 /* Disable option by setting to -1. */
4247 nios2_deregister_custom_code (N2FPU_N (code));
4248 N2FPU_N (code) = -1;
4250 else
4252 char *t;
4253 if (eq)
4254 while (ISSPACE (*(++eq))) ;
4255 if (!eq || eq == p)
4257 error ("%<custom-%s=%> requires argument",
4258 N2FPU_NAME (code));
4259 return false;
4261 for (t = eq; t != p; ++t)
4263 if (ISSPACE (*t))
4264 continue;
4265 if (!ISDIGIT (*t))
4267 error ("`custom-%s=' argument requires "
4268 "numeric digits", N2FPU_NAME (code));
4269 return false;
4272 /* Set option to argument. */
4273 N2FPU_N (code) = atoi (eq);
4274 nios2_handle_custom_fpu_insn_option (code);
4277 else
4279 error ("%<custom-%s=%> is not recognized as FPU instruction",
4280 argstr + 7);
4281 return false;
4284 else
4286 error ("%<%s%> is unknown", argstr);
4287 return false;
4290 if (end_p)
4291 break;
4292 else
4293 argstr = p + 1;
4295 return true;
4297 else
4298 gcc_unreachable ();
4301 /* Return a TARGET_OPTION_NODE tree of the target options listed or NULL. */
4303 static tree
4304 nios2_valid_target_attribute_tree (tree args)
4306 if (!nios2_valid_target_attribute_rec (args))
4307 return NULL_TREE;
4308 nios2_custom_check_insns ();
4309 return build_target_option_node (&global_options);
4312 /* Hook to validate attribute((target("string"))). */
4314 static bool
4315 nios2_valid_target_attribute_p (tree fndecl, tree ARG_UNUSED (name),
4316 tree args, int ARG_UNUSED (flags))
4318 struct cl_target_option cur_target;
4319 bool ret = true;
4320 tree old_optimize = build_optimization_node (&global_options);
4321 tree new_target, new_optimize;
4322 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
4324 /* If the function changed the optimization levels as well as setting target
4325 options, start with the optimizations specified. */
4326 if (func_optimize && func_optimize != old_optimize)
4327 cl_optimization_restore (&global_options,
4328 TREE_OPTIMIZATION (func_optimize));
4330 /* The target attributes may also change some optimization flags, so update
4331 the optimization options if necessary. */
4332 cl_target_option_save (&cur_target, &global_options);
4333 new_target = nios2_valid_target_attribute_tree (args);
4334 new_optimize = build_optimization_node (&global_options);
4336 if (!new_target)
4337 ret = false;
4339 else if (fndecl)
4341 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
4343 if (old_optimize != new_optimize)
4344 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
4347 cl_target_option_restore (&global_options, &cur_target);
4349 if (old_optimize != new_optimize)
4350 cl_optimization_restore (&global_options,
4351 TREE_OPTIMIZATION (old_optimize));
4352 return ret;
4355 /* Remember the last target of nios2_set_current_function. */
4356 static GTY(()) tree nios2_previous_fndecl;
4358 /* Establish appropriate back-end context for processing the function
4359 FNDECL. The argument might be NULL to indicate processing at top
4360 level, outside of any function scope. */
4361 static void
4362 nios2_set_current_function (tree fndecl)
4364 tree old_tree = (nios2_previous_fndecl
4365 ? DECL_FUNCTION_SPECIFIC_TARGET (nios2_previous_fndecl)
4366 : NULL_TREE);
4368 tree new_tree = (fndecl
4369 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
4370 : NULL_TREE);
4372 if (fndecl && fndecl != nios2_previous_fndecl)
4374 nios2_previous_fndecl = fndecl;
4375 if (old_tree == new_tree)
4378 else if (new_tree)
4380 cl_target_option_restore (&global_options,
4381 TREE_TARGET_OPTION (new_tree));
4382 target_reinit ();
4385 else if (old_tree)
4387 struct cl_target_option *def
4388 = TREE_TARGET_OPTION (target_option_current_node);
4390 cl_target_option_restore (&global_options, def);
4391 target_reinit ();
4396 /* Hook to validate the current #pragma GCC target and set the FPU custom
4397 code option state. If ARGS is NULL, then POP_TARGET is used to reset
4398 the options. */
4399 static bool
4400 nios2_pragma_target_parse (tree args, tree pop_target)
4402 tree cur_tree;
4403 if (! args)
4405 cur_tree = ((pop_target)
4406 ? pop_target
4407 : target_option_default_node);
4408 cl_target_option_restore (&global_options,
4409 TREE_TARGET_OPTION (cur_tree));
4411 else
4413 cur_tree = nios2_valid_target_attribute_tree (args);
4414 if (!cur_tree)
4415 return false;
4418 target_option_current_node = cur_tree;
4419 return true;
4422 /* Implement TARGET_MERGE_DECL_ATTRIBUTES.
4423 We are just using this hook to add some additional error checking to
4424 the default behavior. GCC does not provide a target hook for merging
4425 the target options, and only correctly handles merging empty vs non-empty
4426 option data; see merge_decls() in c-decl.c.
4427 So here we require either that at least one of the decls has empty
4428 target options, or that the target options/data be identical. */
4429 static tree
4430 nios2_merge_decl_attributes (tree olddecl, tree newdecl)
4432 tree oldopts = lookup_attribute ("target", DECL_ATTRIBUTES (olddecl));
4433 tree newopts = lookup_attribute ("target", DECL_ATTRIBUTES (newdecl));
4434 if (newopts && oldopts && newopts != oldopts)
4436 tree oldtree = DECL_FUNCTION_SPECIFIC_TARGET (olddecl);
4437 tree newtree = DECL_FUNCTION_SPECIFIC_TARGET (newdecl);
4438 if (oldtree && newtree && oldtree != newtree)
4440 struct cl_target_option *olddata = TREE_TARGET_OPTION (oldtree);
4441 struct cl_target_option *newdata = TREE_TARGET_OPTION (newtree);
4442 if (olddata != newdata
4443 && memcmp (olddata, newdata, sizeof (struct cl_target_option)))
4444 error ("%qE redeclared with conflicting %qs attributes",
4445 DECL_NAME (newdecl), "target");
4448 return merge_attributes (DECL_ATTRIBUTES (olddecl),
4449 DECL_ATTRIBUTES (newdecl));
4452 /* Implement TARGET_ASM_OUTPUT_MI_THUNK. */
4453 static void
4454 nios2_asm_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
4455 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
4456 tree function)
4458 rtx this_rtx, funexp;
4459 rtx_insn *insn;
4461 /* Pretend to be a post-reload pass while generating rtl. */
4462 reload_completed = 1;
4464 if (flag_pic)
4465 nios2_load_pic_register ();
4467 /* Mark the end of the (empty) prologue. */
4468 emit_note (NOTE_INSN_PROLOGUE_END);
4470 /* Find the "this" pointer. If the function returns a structure,
4471 the structure return pointer is in $5. */
4472 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
4473 this_rtx = gen_rtx_REG (Pmode, FIRST_ARG_REGNO + 1);
4474 else
4475 this_rtx = gen_rtx_REG (Pmode, FIRST_ARG_REGNO);
4477 /* Add DELTA to THIS_RTX. */
4478 nios2_emit_add_constant (this_rtx, delta);
4480 /* If needed, add *(*THIS_RTX + VCALL_OFFSET) to THIS_RTX. */
4481 if (vcall_offset)
4483 rtx tmp;
4485 tmp = gen_rtx_REG (Pmode, 2);
4486 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
4487 nios2_emit_add_constant (tmp, vcall_offset);
4488 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
4489 emit_insn (gen_add2_insn (this_rtx, tmp));
4492 /* Generate a tail call to the target function. */
4493 if (!TREE_USED (function))
4495 assemble_external (function);
4496 TREE_USED (function) = 1;
4498 funexp = XEXP (DECL_RTL (function), 0);
4499 /* Function address needs to be constructed under PIC,
4500 provide r2 to use here. */
4501 nios2_adjust_call_address (&funexp, gen_rtx_REG (Pmode, 2));
4502 insn = emit_call_insn (gen_sibcall_internal (funexp, const0_rtx));
4503 SIBLING_CALL_P (insn) = 1;
4505 /* Run just enough of rest_of_compilation to get the insns emitted.
4506 There's not really enough bulk here to make other passes such as
4507 instruction scheduling worth while. Note that use_thunk calls
4508 assemble_start_function and assemble_end_function. */
4509 insn = get_insns ();
4510 shorten_branches (insn);
4511 final_start_function (insn, file, 1);
4512 final (insn, file, 1);
4513 final_end_function ();
4515 /* Stop pretending to be a post-reload pass. */
4516 reload_completed = 0;
4520 /* Utility function to break a memory address into
4521 base register + constant offset. Return false if something
4522 unexpected is seen. */
4523 static bool
4524 split_mem_address (rtx addr, rtx *base_reg, rtx *offset)
4526 if (REG_P (addr))
4528 *base_reg = addr;
4529 *offset = const0_rtx;
4530 return true;
4532 else if (GET_CODE (addr) == PLUS)
4534 *base_reg = XEXP (addr, 0);
4535 *offset = XEXP (addr, 1);
4536 return true;
4538 return false;
4541 /* Splits out the operands of an ALU insn, places them in *LHS, *RHS1, *RHS2. */
4542 static void
4543 split_alu_insn (rtx_insn *insn, rtx *lhs, rtx *rhs1, rtx *rhs2)
4545 rtx pat = PATTERN (insn);
4546 gcc_assert (GET_CODE (pat) == SET);
4547 *lhs = SET_DEST (pat);
4548 *rhs1 = XEXP (SET_SRC (pat), 0);
4549 if (GET_RTX_CLASS (GET_CODE (SET_SRC (pat))) != RTX_UNARY)
4550 *rhs2 = XEXP (SET_SRC (pat), 1);
4551 return;
4554 /* Returns true if OP is a REG and assigned a CDX reg. */
4555 static bool
4556 cdxreg (rtx op)
4558 return REG_P (op) && (!reload_completed || CDX_REG_P (REGNO (op)));
4561 /* Returns true if OP is within range of CDX addi.n immediates. */
4562 static bool
4563 cdx_add_immed (rtx op)
4565 if (CONST_INT_P (op))
4567 HOST_WIDE_INT ival = INTVAL (op);
4568 return ival <= 128 && ival > 0 && (ival & (ival - 1)) == 0;
4570 return false;
4573 /* Returns true if OP is within range of CDX andi.n immediates. */
4574 static bool
4575 cdx_and_immed (rtx op)
4577 if (CONST_INT_P (op))
4579 HOST_WIDE_INT ival = INTVAL (op);
4580 return (ival == 1 || ival == 2 || ival == 3 || ival == 4
4581 || ival == 8 || ival == 0xf || ival == 0x10
4582 || ival == 0x1f || ival == 0x20
4583 || ival == 0x3f || ival == 0x7f
4584 || ival == 0x80 || ival == 0xff || ival == 0x7ff
4585 || ival == 0xff00 || ival == 0xffff);
4587 return false;
4590 /* Returns true if OP is within range of CDX movi.n immediates. */
4591 static bool
4592 cdx_mov_immed (rtx op)
4594 if (CONST_INT_P (op))
4596 HOST_WIDE_INT ival = INTVAL (op);
4597 return ((ival >= 0 && ival <= 124)
4598 || ival == 0xff || ival == -2 || ival == -1);
4600 return false;
4603 /* Returns true if OP is within range of CDX slli.n/srli.n immediates. */
4604 static bool
4605 cdx_shift_immed (rtx op)
4607 if (CONST_INT_P (op))
4609 HOST_WIDE_INT ival = INTVAL (op);
4610 return (ival == 1 || ival == 2 || ival == 3 || ival == 8
4611 || ival == 12 || ival == 16 || ival == 24
4612 || ival == 31);
4614 return false;
4619 /* Classification of different kinds of add instructions. */
4620 enum nios2_add_insn_kind {
4621 nios2_add_n_kind,
4622 nios2_addi_n_kind,
4623 nios2_subi_n_kind,
4624 nios2_spaddi_n_kind,
4625 nios2_spinci_n_kind,
4626 nios2_spdeci_n_kind,
4627 nios2_add_kind,
4628 nios2_addi_kind
4631 static const char *nios2_add_insn_names[] = {
4632 "add.n", "addi.n", "subi.n", "spaddi.n", "spinci.n", "spdeci.n",
4633 "add", "addi" };
4634 static bool nios2_add_insn_narrow[] = {
4635 true, true, true, true, true, true,
4636 false, false};
4638 /* Function to classify kinds of add instruction patterns. */
4639 static enum nios2_add_insn_kind
4640 nios2_add_insn_classify (rtx_insn *insn ATTRIBUTE_UNUSED,
4641 rtx lhs, rtx rhs1, rtx rhs2)
4643 if (TARGET_HAS_CDX)
4645 if (cdxreg (lhs) && cdxreg (rhs1))
4647 if (cdxreg (rhs2))
4648 return nios2_add_n_kind;
4649 if (CONST_INT_P (rhs2))
4651 HOST_WIDE_INT ival = INTVAL (rhs2);
4652 if (ival > 0 && cdx_add_immed (rhs2))
4653 return nios2_addi_n_kind;
4654 if (ival < 0 && cdx_add_immed (GEN_INT (-ival)))
4655 return nios2_subi_n_kind;
4658 else if (rhs1 == stack_pointer_rtx
4659 && CONST_INT_P (rhs2))
4661 HOST_WIDE_INT imm7 = INTVAL (rhs2) >> 2;
4662 HOST_WIDE_INT rem = INTVAL (rhs2) & 3;
4663 if (rem == 0 && (imm7 & ~0x7f) == 0)
4665 if (cdxreg (lhs))
4666 return nios2_spaddi_n_kind;
4667 if (lhs == stack_pointer_rtx)
4668 return nios2_spinci_n_kind;
4670 imm7 = -INTVAL(rhs2) >> 2;
4671 rem = -INTVAL (rhs2) & 3;
4672 if (lhs == stack_pointer_rtx
4673 && rem == 0 && (imm7 & ~0x7f) == 0)
4674 return nios2_spdeci_n_kind;
4677 return ((REG_P (rhs2) || rhs2 == const0_rtx)
4678 ? nios2_add_kind : nios2_addi_kind);
4681 /* Emit assembly language for the different kinds of add instructions. */
4682 const char*
4683 nios2_add_insn_asm (rtx_insn *insn, rtx *operands)
4685 static char buf[256];
4686 int ln = 256;
4687 enum nios2_add_insn_kind kind
4688 = nios2_add_insn_classify (insn, operands[0], operands[1], operands[2]);
4689 if (kind == nios2_subi_n_kind)
4690 snprintf (buf, ln, "subi.n\t%%0, %%1, %d", (int) -INTVAL (operands[2]));
4691 else if (kind == nios2_spaddi_n_kind)
4692 snprintf (buf, ln, "spaddi.n\t%%0, %%2");
4693 else if (kind == nios2_spinci_n_kind)
4694 snprintf (buf, ln, "spinci.n\t%%2");
4695 else if (kind == nios2_spdeci_n_kind)
4696 snprintf (buf, ln, "spdeci.n\t%d", (int) -INTVAL (operands[2]));
4697 else
4698 snprintf (buf, ln, "%s\t%%0, %%1, %%z2", nios2_add_insn_names[(int)kind]);
4699 return buf;
4702 /* This routine, which the default "length" attribute computation is
4703 based on, encapsulates information about all the cases where CDX
4704 provides a narrow 2-byte instruction form. */
4705 bool
4706 nios2_cdx_narrow_form_p (rtx_insn *insn)
4708 rtx pat, lhs, rhs1, rhs2;
4709 enum attr_type type;
4710 if (!TARGET_HAS_CDX)
4711 return false;
4712 type = get_attr_type (insn);
4713 pat = PATTERN (insn);
4714 gcc_assert (reload_completed);
4715 switch (type)
4717 case TYPE_CONTROL:
4718 if (GET_CODE (pat) == SIMPLE_RETURN)
4719 return true;
4720 if (GET_CODE (pat) == PARALLEL)
4721 pat = XVECEXP (pat, 0, 0);
4722 if (GET_CODE (pat) == SET)
4723 pat = SET_SRC (pat);
4724 if (GET_CODE (pat) == IF_THEN_ELSE)
4726 /* Conditional branch patterns; for these we
4727 only check the comparison to find beqz.n/bnez.n cases.
4728 For the 'nios2_cbranch' pattern, we cannot also check
4729 the branch range here. That will be done at the md
4730 pattern "length" attribute computation. */
4731 rtx cmp = XEXP (pat, 0);
4732 return ((GET_CODE (cmp) == EQ || GET_CODE (cmp) == NE)
4733 && cdxreg (XEXP (cmp, 0))
4734 && XEXP (cmp, 1) == const0_rtx);
4736 if (GET_CODE (pat) == TRAP_IF)
4737 /* trap.n is always usable. */
4738 return true;
4739 if (GET_CODE (pat) == CALL)
4740 pat = XEXP (XEXP (pat, 0), 0);
4741 if (REG_P (pat))
4742 /* Control instructions taking a register operand are indirect
4743 jumps and calls. The CDX instructions have a 5-bit register
4744 field so any reg is valid. */
4745 return true;
4746 else
4748 gcc_assert (!insn_variable_length_p (insn));
4749 return false;
4751 case TYPE_ADD:
4753 enum nios2_add_insn_kind kind;
4754 split_alu_insn (insn, &lhs, &rhs1, &rhs2);
4755 kind = nios2_add_insn_classify (insn, lhs, rhs1, rhs2);
4756 return nios2_add_insn_narrow[(int)kind];
4758 case TYPE_LD:
4760 bool ret;
4761 HOST_WIDE_INT offset, rem = 0;
4762 rtx addr, reg = SET_DEST (pat), mem = SET_SRC (pat);
4763 if (GET_CODE (mem) == SIGN_EXTEND)
4764 /* No CDX form for sign-extended load. */
4765 return false;
4766 if (GET_CODE (mem) == ZERO_EXTEND)
4767 /* The load alternatives in the zero_extend* patterns. */
4768 mem = XEXP (mem, 0);
4769 if (MEM_P (mem))
4771 /* ldxio. */
4772 if ((MEM_VOLATILE_P (mem) && TARGET_BYPASS_CACHE_VOLATILE)
4773 || TARGET_BYPASS_CACHE)
4774 return false;
4775 addr = XEXP (mem, 0);
4776 /* GP-based and R0-based references are never narrow. */
4777 if (gprel_constant_p (addr) || r0rel_constant_p (addr))
4778 return false;
4779 /* %lo requires a 16-bit relocation and is never narrow. */
4780 if (GET_CODE (addr) == LO_SUM)
4781 return false;
4782 ret = split_mem_address (addr, &rhs1, &rhs2);
4783 gcc_assert (ret);
4785 else
4786 return false;
4788 offset = INTVAL (rhs2);
4789 if (GET_MODE (mem) == SImode)
4791 rem = offset & 3;
4792 offset >>= 2;
4793 /* ldwsp.n case. */
4794 if (rtx_equal_p (rhs1, stack_pointer_rtx)
4795 && rem == 0 && (offset & ~0x1f) == 0)
4796 return true;
4798 else if (GET_MODE (mem) == HImode)
4800 rem = offset & 1;
4801 offset >>= 1;
4803 /* ldbu.n, ldhu.n, ldw.n cases. */
4804 return (cdxreg (reg) && cdxreg (rhs1)
4805 && rem == 0 && (offset & ~0xf) == 0);
4807 case TYPE_ST:
4808 if (GET_CODE (pat) == PARALLEL)
4809 /* stex, stsex. */
4810 return false;
4811 else
4813 bool ret;
4814 HOST_WIDE_INT offset, rem = 0;
4815 rtx addr, reg = SET_SRC (pat), mem = SET_DEST (pat);
4816 if (!MEM_P (mem))
4817 return false;
4818 /* stxio. */
4819 if ((MEM_VOLATILE_P (mem) && TARGET_BYPASS_CACHE_VOLATILE)
4820 || TARGET_BYPASS_CACHE)
4821 return false;
4822 addr = XEXP (mem, 0);
4823 /* GP-based and r0-based references are never narrow. */
4824 if (gprel_constant_p (addr) || r0rel_constant_p (addr))
4825 return false;
4826 /* %lo requires a 16-bit relocation and is never narrow. */
4827 if (GET_CODE (addr) == LO_SUM)
4828 return false;
4829 ret = split_mem_address (addr, &rhs1, &rhs2);
4830 gcc_assert (ret);
4831 offset = INTVAL (rhs2);
4832 if (GET_MODE (mem) == SImode)
4834 rem = offset & 3;
4835 offset >>= 2;
4836 /* stwsp.n case. */
4837 if (rtx_equal_p (rhs1, stack_pointer_rtx)
4838 && rem == 0 && (offset & ~0x1f) == 0)
4839 return true;
4840 /* stwz.n case. */
4841 else if (reg == const0_rtx && cdxreg (rhs1)
4842 && rem == 0 && (offset & ~0x3f) == 0)
4843 return true;
4845 else if (GET_MODE (mem) == HImode)
4847 rem = offset & 1;
4848 offset >>= 1;
4850 else
4852 gcc_assert (GET_MODE (mem) == QImode);
4853 /* stbz.n case. */
4854 if (reg == const0_rtx && cdxreg (rhs1)
4855 && (offset & ~0x3f) == 0)
4856 return true;
4859 /* stbu.n, sthu.n, stw.n cases. */
4860 return (cdxreg (reg) && cdxreg (rhs1)
4861 && rem == 0 && (offset & ~0xf) == 0);
4863 case TYPE_MOV:
4864 lhs = SET_DEST (pat);
4865 rhs1 = SET_SRC (pat);
4866 if (CONST_INT_P (rhs1))
4867 return (cdxreg (lhs) && cdx_mov_immed (rhs1));
4868 gcc_assert (REG_P (lhs) && REG_P (rhs1));
4869 return true;
4871 case TYPE_AND:
4872 /* Some zero_extend* alternatives are and insns. */
4873 if (GET_CODE (SET_SRC (pat)) == ZERO_EXTEND)
4874 return (cdxreg (SET_DEST (pat))
4875 && cdxreg (XEXP (SET_SRC (pat), 0)));
4876 split_alu_insn (insn, &lhs, &rhs1, &rhs2);
4877 if (CONST_INT_P (rhs2))
4878 return (cdxreg (lhs) && cdxreg (rhs1) && cdx_and_immed (rhs2));
4879 return (cdxreg (lhs) && cdxreg (rhs2)
4880 && (!reload_completed || rtx_equal_p (lhs, rhs1)));
4882 case TYPE_OR:
4883 case TYPE_XOR:
4884 /* Note the two-address limitation for CDX form. */
4885 split_alu_insn (insn, &lhs, &rhs1, &rhs2);
4886 return (cdxreg (lhs) && cdxreg (rhs2)
4887 && (!reload_completed || rtx_equal_p (lhs, rhs1)));
4889 case TYPE_SUB:
4890 split_alu_insn (insn, &lhs, &rhs1, &rhs2);
4891 return (cdxreg (lhs) && cdxreg (rhs1) && cdxreg (rhs2));
4893 case TYPE_NEG:
4894 case TYPE_NOT:
4895 split_alu_insn (insn, &lhs, &rhs1, NULL);
4896 return (cdxreg (lhs) && cdxreg (rhs1));
4898 case TYPE_SLL:
4899 case TYPE_SRL:
4900 split_alu_insn (insn, &lhs, &rhs1, &rhs2);
4901 return (cdxreg (lhs)
4902 && ((cdxreg (rhs1) && cdx_shift_immed (rhs2))
4903 || (cdxreg (rhs2)
4904 && (!reload_completed || rtx_equal_p (lhs, rhs1)))));
4905 case TYPE_NOP:
4906 case TYPE_PUSH:
4907 case TYPE_POP:
4908 return true;
4909 default:
4910 break;
4912 return false;
4915 /* Main function to implement the pop_operation predicate that
4916 check pop.n insn pattern integrity. The CDX pop.n patterns mostly
4917 hardcode the restored registers, so the main checking is for the
4918 SP offsets. */
4919 bool
4920 pop_operation_p (rtx op)
4922 int i;
4923 HOST_WIDE_INT last_offset = -1, len = XVECLEN (op, 0);
4924 rtx base_reg, offset;
4926 if (len < 3 /* At least has a return, SP-update, and RA restore. */
4927 || GET_CODE (XVECEXP (op, 0, 0)) != RETURN
4928 || !base_reg_adjustment_p (XVECEXP (op, 0, 1), &base_reg, &offset)
4929 || !rtx_equal_p (base_reg, stack_pointer_rtx)
4930 || !CONST_INT_P (offset)
4931 || (INTVAL (offset) & 3) != 0)
4932 return false;
4934 for (i = len - 1; i > 1; i--)
4936 rtx set = XVECEXP (op, 0, i);
4937 rtx curr_base_reg, curr_offset;
4939 if (GET_CODE (set) != SET || !MEM_P (SET_SRC (set))
4940 || !split_mem_address (XEXP (SET_SRC (set), 0),
4941 &curr_base_reg, &curr_offset)
4942 || !rtx_equal_p (base_reg, curr_base_reg)
4943 || !CONST_INT_P (curr_offset))
4944 return false;
4945 if (i == len - 1)
4947 last_offset = INTVAL (curr_offset);
4948 if ((last_offset & 3) != 0 || last_offset > 60)
4949 return false;
4951 else
4953 last_offset += 4;
4954 if (INTVAL (curr_offset) != last_offset)
4955 return false;
4958 if (last_offset < 0 || last_offset + 4 != INTVAL (offset))
4959 return false;
4961 return true;
4965 /* Masks of registers that are valid for CDX ldwm/stwm instructions.
4966 The instruction can encode subsets drawn from either R2-R13 or
4967 R14-R23 + FP + RA. */
4968 #define CDX_LDSTWM_VALID_REGS_0 0x00003ffc
4969 #define CDX_LDSTWM_VALID_REGS_1 0x90ffc000
4971 static bool
4972 nios2_ldstwm_regset_p (unsigned int regno, unsigned int *regset)
4974 if (*regset == 0)
4976 if (CDX_LDSTWM_VALID_REGS_0 & (1 << regno))
4977 *regset = CDX_LDSTWM_VALID_REGS_0;
4978 else if (CDX_LDSTWM_VALID_REGS_1 & (1 << regno))
4979 *regset = CDX_LDSTWM_VALID_REGS_1;
4980 else
4981 return false;
4982 return true;
4984 else
4985 return (*regset & (1 << regno)) != 0;
4988 /* Main function to implement ldwm_operation/stwm_operation
4989 predicates that check ldwm/stwm insn pattern integrity. */
4990 bool
4991 ldstwm_operation_p (rtx op, bool load_p)
4993 int start, i, end = XVECLEN (op, 0) - 1, last_regno = -1;
4994 unsigned int regset = 0;
4995 rtx base_reg, offset;
4996 rtx first_elt = XVECEXP (op, 0, 0);
4997 bool inc_p = true;
4998 bool wb_p = base_reg_adjustment_p (first_elt, &base_reg, &offset);
4999 if (GET_CODE (XVECEXP (op, 0, end)) == RETURN)
5000 end--;
5001 start = wb_p ? 1 : 0;
5002 for (i = start; i <= end; i++)
5004 int regno;
5005 rtx reg, mem, elt = XVECEXP (op, 0, i);
5006 /* Return early if not a SET at all. */
5007 if (GET_CODE (elt) != SET)
5008 return false;
5009 reg = load_p ? SET_DEST (elt) : SET_SRC (elt);
5010 mem = load_p ? SET_SRC (elt) : SET_DEST (elt);
5011 if (!REG_P (reg) || !MEM_P (mem))
5012 return false;
5013 regno = REGNO (reg);
5014 if (!nios2_ldstwm_regset_p (regno, &regset))
5015 return false;
5016 /* If no writeback to determine direction, use offset of first MEM. */
5017 if (wb_p)
5018 inc_p = INTVAL (offset) > 0;
5019 else if (i == start)
5021 rtx first_base, first_offset;
5022 if (!split_mem_address (XEXP (mem, 0),
5023 &first_base, &first_offset))
5024 return false;
5025 if (!REG_P (first_base) || !CONST_INT_P (first_offset))
5026 return false;
5027 base_reg = first_base;
5028 inc_p = INTVAL (first_offset) >= 0;
5030 /* Ensure that the base register is not loaded into. */
5031 if (load_p && regno == (int) REGNO (base_reg))
5032 return false;
5033 /* Check for register order inc/dec integrity. */
5034 if (last_regno >= 0)
5036 if (inc_p && last_regno >= regno)
5037 return false;
5038 if (!inc_p && last_regno <= regno)
5039 return false;
5041 last_regno = regno;
5043 return true;
5046 /* Helper for nios2_ldst_parallel, for generating a parallel vector
5047 SET element. */
5048 static rtx
5049 gen_ldst (bool load_p, int regno, rtx base_mem, int offset)
5051 rtx reg = gen_rtx_REG (SImode, regno);
5052 rtx mem = adjust_address_nv (base_mem, SImode, offset);
5053 return gen_rtx_SET (load_p ? reg : mem,
5054 load_p ? mem : reg);
5057 /* A general routine for creating the body RTL pattern of
5058 ldwm/stwm/push.n/pop.n insns.
5059 LOAD_P: true/false for load/store direction.
5060 REG_INC_P: whether registers are incrementing/decrementing in the
5061 *RTL vector* (not necessarily the order defined in the ISA specification).
5062 OFFSET_INC_P: Same as REG_INC_P, but for the memory offset order.
5063 BASE_MEM: starting MEM.
5064 BASE_UPDATE: amount to update base register; zero means no writeback.
5065 REGMASK: register mask to load/store.
5066 RET_P: true if to tag a (return) element at the end.
5068 Note that this routine does not do any checking. It's the job of the
5069 caller to do the right thing, and the insn patterns to do the
5070 safe-guarding. */
5071 static rtx
5072 nios2_ldst_parallel (bool load_p, bool reg_inc_p, bool offset_inc_p,
5073 rtx base_mem, int base_update,
5074 unsigned HOST_WIDE_INT regmask, bool ret_p)
5076 rtvec p;
5077 int regno, b = 0, i = 0, n = 0, len = popcount_hwi (regmask);
5078 if (ret_p) len++, i++, b++;
5079 if (base_update != 0) len++, i++;
5080 p = rtvec_alloc (len);
5081 for (regno = (reg_inc_p ? 0 : 31);
5082 regno != (reg_inc_p ? 32 : -1);
5083 regno += (reg_inc_p ? 1 : -1))
5084 if ((regmask & (1 << regno)) != 0)
5086 int offset = (offset_inc_p ? 4 : -4) * n++;
5087 RTVEC_ELT (p, i++) = gen_ldst (load_p, regno, base_mem, offset);
5089 if (ret_p)
5090 RTVEC_ELT (p, 0) = ret_rtx;
5091 if (base_update != 0)
5093 rtx reg, offset;
5094 if (!split_mem_address (XEXP (base_mem, 0), &reg, &offset))
5095 gcc_unreachable ();
5096 RTVEC_ELT (p, b) =
5097 gen_rtx_SET (reg, plus_constant (Pmode, reg, base_update));
5099 return gen_rtx_PARALLEL (VOIDmode, p);
5102 /* CDX ldwm/stwm peephole optimization pattern related routines. */
5104 /* Data structure and sorting function for ldwm/stwm peephole optimizers. */
5105 struct ldstwm_operand
5107 int offset; /* Offset from base register. */
5108 rtx reg; /* Register to store at this offset. */
5109 rtx mem; /* Original mem. */
5110 bool bad; /* True if this load/store can't be combined. */
5111 bool rewrite; /* True if we should rewrite using scratch. */
5114 static int
5115 compare_ldstwm_operands (const void *arg1, const void *arg2)
5117 const struct ldstwm_operand *op1 = (const struct ldstwm_operand *) arg1;
5118 const struct ldstwm_operand *op2 = (const struct ldstwm_operand *) arg2;
5119 if (op1->bad)
5120 return op2->bad ? 0 : 1;
5121 else if (op2->bad)
5122 return -1;
5123 else
5124 return op1->offset - op2->offset;
5127 /* Helper function: return true if a load/store using REGNO with address
5128 BASEREG and offset OFFSET meets the constraints for a 2-byte CDX ldw.n,
5129 stw.n, ldwsp.n, or stwsp.n instruction. */
5130 static bool
5131 can_use_cdx_ldstw (int regno, int basereg, int offset)
5133 if (CDX_REG_P (regno) && CDX_REG_P (basereg)
5134 && (offset & 0x3) == 0 && offset >= 0 && offset < 0x40)
5135 return true;
5136 else if (basereg == SP_REGNO
5137 && offset >= 0 && offset < 0x80 && (offset & 0x3) == 0)
5138 return true;
5139 return false;
5142 /* This function is called from peephole2 optimizers to try to merge
5143 a series of individual loads and stores into a ldwm or stwm. It
5144 can also rewrite addresses inside the individual loads and stores
5145 using a common base register using a scratch register and smaller
5146 offsets if that allows them to use CDX ldw.n or stw.n instructions
5147 instead of 4-byte loads or stores.
5148 N is the number of insns we are trying to merge. SCRATCH is non-null
5149 if there is a scratch register available. The OPERANDS array contains
5150 alternating REG (even) and MEM (odd) operands. */
5151 bool
5152 gen_ldstwm_peep (bool load_p, int n, rtx scratch, rtx *operands)
5154 /* CDX ldwm/stwm instructions allow a maximum of 12 registers to be
5155 specified. */
5156 #define MAX_LDSTWM_OPS 12
5157 struct ldstwm_operand sort[MAX_LDSTWM_OPS];
5158 int basereg = -1;
5159 int baseoffset;
5160 int i, m, lastoffset, lastreg;
5161 unsigned int regmask = 0, usemask = 0, regset;
5162 bool needscratch;
5163 int newbasereg;
5164 int nbytes;
5166 if (!TARGET_HAS_CDX)
5167 return false;
5168 if (n < 2 || n > MAX_LDSTWM_OPS)
5169 return false;
5171 /* Check all the operands for validity and initialize the sort array.
5172 The places where we return false here are all situations that aren't
5173 expected to ever happen -- invalid patterns, invalid registers, etc. */
5174 for (i = 0; i < n; i++)
5176 rtx base, offset;
5177 rtx reg = operands[i];
5178 rtx mem = operands[i + n];
5179 int r, o, regno;
5180 bool bad = false;
5182 if (!REG_P (reg) || !MEM_P (mem))
5183 return false;
5185 regno = REGNO (reg);
5186 if (regno > 31)
5187 return false;
5188 if (load_p && (regmask & (1 << regno)) != 0)
5189 return false;
5190 regmask |= 1 << regno;
5192 if (!split_mem_address (XEXP (mem, 0), &base, &offset))
5193 return false;
5194 r = REGNO (base);
5195 o = INTVAL (offset);
5197 if (basereg == -1)
5198 basereg = r;
5199 else if (r != basereg)
5200 bad = true;
5201 usemask |= 1 << r;
5203 sort[i].bad = bad;
5204 sort[i].rewrite = false;
5205 sort[i].offset = o;
5206 sort[i].reg = reg;
5207 sort[i].mem = mem;
5210 /* If we are doing a series of register loads, we can't safely reorder
5211 them if any of the regs used in addr expressions are also being set. */
5212 if (load_p && (regmask & usemask))
5213 return false;
5215 /* Sort the array by increasing mem offset order, then check that
5216 offsets are valid and register order matches mem order. At the
5217 end of this loop, m is the number of loads/stores we will try to
5218 combine; the rest are leftovers. */
5219 qsort (sort, n, sizeof (struct ldstwm_operand), compare_ldstwm_operands);
5221 baseoffset = sort[0].offset;
5222 needscratch = baseoffset != 0;
5223 if (needscratch && !scratch)
5224 return false;
5226 lastreg = regmask = regset = 0;
5227 lastoffset = baseoffset;
5228 for (m = 0; m < n && !sort[m].bad; m++)
5230 int thisreg = REGNO (sort[m].reg);
5231 if (sort[m].offset != lastoffset
5232 || (m > 0 && lastreg >= thisreg)
5233 || !nios2_ldstwm_regset_p (thisreg, &regset))
5234 break;
5235 lastoffset += 4;
5236 lastreg = thisreg;
5237 regmask |= (1 << thisreg);
5240 /* For loads, make sure we are not overwriting the scratch reg.
5241 The peephole2 pattern isn't supposed to match unless the register is
5242 unused all the way through, so this isn't supposed to happen anyway. */
5243 if (load_p
5244 && needscratch
5245 && ((1 << REGNO (scratch)) & regmask) != 0)
5246 return false;
5247 newbasereg = needscratch ? (int) REGNO (scratch) : basereg;
5249 /* We may be able to combine only the first m of the n total loads/stores
5250 into a single instruction. If m < 2, there's no point in emitting
5251 a ldwm/stwm at all, but we might be able to do further optimizations
5252 if we have a scratch. We will count the instruction lengths of the
5253 old and new patterns and store the savings in nbytes. */
5254 if (m < 2)
5256 if (!needscratch)
5257 return false;
5258 m = 0;
5259 nbytes = 0;
5261 else
5262 nbytes = -4; /* Size of ldwm/stwm. */
5263 if (needscratch)
5265 int bo = baseoffset > 0 ? baseoffset : -baseoffset;
5266 if (CDX_REG_P (newbasereg)
5267 && CDX_REG_P (basereg)
5268 && bo <= 128 && bo > 0 && (bo & (bo - 1)) == 0)
5269 nbytes -= 2; /* Size of addi.n/subi.n. */
5270 else
5271 nbytes -= 4; /* Size of non-CDX addi. */
5274 /* Count the size of the input load/store instructions being replaced. */
5275 for (i = 0; i < m; i++)
5276 if (can_use_cdx_ldstw (REGNO (sort[i].reg), basereg, sort[i].offset))
5277 nbytes += 2;
5278 else
5279 nbytes += 4;
5281 /* We may also be able to save a bit if we can rewrite non-CDX
5282 load/stores that can't be combined into the ldwm/stwm into CDX
5283 load/stores using the scratch reg. For example, this might happen
5284 if baseoffset is large, by bringing in the offsets in the load/store
5285 instructions within the range that fits in the CDX instruction. */
5286 if (needscratch && CDX_REG_P (newbasereg))
5287 for (i = m; i < n && !sort[i].bad; i++)
5288 if (!can_use_cdx_ldstw (REGNO (sort[i].reg), basereg, sort[i].offset)
5289 && can_use_cdx_ldstw (REGNO (sort[i].reg), newbasereg,
5290 sort[i].offset - baseoffset))
5292 sort[i].rewrite = true;
5293 nbytes += 2;
5296 /* Are we good to go? */
5297 if (nbytes <= 0)
5298 return false;
5300 /* Emit the scratch load. */
5301 if (needscratch)
5302 emit_insn (gen_rtx_SET (scratch, XEXP (sort[0].mem, 0)));
5304 /* Emit the ldwm/stwm insn. */
5305 if (m > 0)
5307 rtvec p = rtvec_alloc (m);
5308 for (i = 0; i < m; i++)
5310 int offset = sort[i].offset;
5311 rtx mem, reg = sort[i].reg;
5312 rtx base_reg = gen_rtx_REG (Pmode, newbasereg);
5313 if (needscratch)
5314 offset -= baseoffset;
5315 mem = gen_rtx_MEM (SImode, plus_constant (Pmode, base_reg, offset));
5316 if (load_p)
5317 RTVEC_ELT (p, i) = gen_rtx_SET (reg, mem);
5318 else
5319 RTVEC_ELT (p, i) = gen_rtx_SET (mem, reg);
5321 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
5324 /* Emit any leftover load/stores as individual instructions, doing
5325 the previously-noted rewrites to use the scratch reg. */
5326 for (i = m; i < n; i++)
5328 rtx reg = sort[i].reg;
5329 rtx mem = sort[i].mem;
5330 if (sort[i].rewrite)
5332 int offset = sort[i].offset - baseoffset;
5333 mem = gen_rtx_MEM (SImode, plus_constant (Pmode, scratch, offset));
5335 if (load_p)
5336 emit_move_insn (reg, mem);
5337 else
5338 emit_move_insn (mem, reg);
5340 return true;
5343 /* Implement TARGET_MACHINE_DEPENDENT_REORG:
5344 We use this hook when emitting CDX code to enforce the 4-byte
5345 alignment requirement for labels that are used as the targets of
5346 jmpi instructions. CDX code can otherwise contain a mix of 16-bit
5347 and 32-bit instructions aligned on any 16-bit boundary, but functions
5348 and jmpi labels have to be 32-bit aligned because of the way the address
5349 is encoded in the instruction. */
5351 static unsigned char *label_align;
5352 static int min_labelno, max_labelno;
5354 static void
5355 nios2_reorg (void)
5357 bool changed = true;
5358 rtx_insn *insn;
5360 if (!TARGET_HAS_CDX)
5361 return;
5363 /* Initialize the data structures. */
5364 if (label_align)
5365 free (label_align);
5366 max_labelno = max_label_num ();
5367 min_labelno = get_first_label_num ();
5368 label_align = XCNEWVEC (unsigned char, max_labelno - min_labelno + 1);
5370 /* Iterate on inserting alignment and adjusting branch lengths until
5371 no more changes. */
5372 while (changed)
5374 changed = false;
5375 shorten_branches (get_insns ());
5377 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
5378 if (JUMP_P (insn) && insn_variable_length_p (insn))
5380 rtx label = JUMP_LABEL (insn);
5381 /* We use the current fact that all cases of 'jmpi'
5382 doing the actual branch in the machine description
5383 has a computed length of 6 or 8. Length 4 and below
5384 are all PC-relative 'br' branches without the jump-align
5385 problem. */
5386 if (label && LABEL_P (label) && get_attr_length (insn) > 4)
5388 int index = CODE_LABEL_NUMBER (label) - min_labelno;
5389 if (label_align[index] != 2)
5391 label_align[index] = 2;
5392 changed = true;
5399 /* Implement LABEL_ALIGN, using the information gathered in nios2_reorg. */
5401 nios2_label_align (rtx label)
5403 int n = CODE_LABEL_NUMBER (label);
5405 if (label_align && n >= min_labelno && n <= max_labelno)
5406 return MAX (label_align[n - min_labelno], align_labels.levels[0].log);
5407 return align_labels.levels[0].log;
5410 /* Implement ADJUST_REG_ALLOC_ORDER. We use the default ordering
5411 for R1 and non-CDX R2 code; for CDX we tweak thing to prefer
5412 the registers that can be used as operands to instructions that
5413 have 3-bit register fields. */
5414 void
5415 nios2_adjust_reg_alloc_order (void)
5417 const int cdx_reg_alloc_order[] =
5419 /* Call-clobbered GPRs within CDX 3-bit encoded range. */
5420 2, 3, 4, 5, 6, 7,
5421 /* Call-saved GPRs within CDX 3-bit encoded range. */
5422 16, 17,
5423 /* Other call-clobbered GPRs. */
5424 8, 9, 10, 11, 12, 13, 14, 15,
5425 /* Other call-saved GPRs. RA placed first since it is always saved. */
5426 31, 18, 19, 20, 21, 22, 23, 28,
5427 /* Fixed GPRs, not used by the register allocator. */
5428 0, 1, 24, 25, 26, 27, 29, 30, 32, 33, 34, 35, 36, 37, 38, 39
5431 if (TARGET_HAS_CDX)
5432 memcpy (reg_alloc_order, cdx_reg_alloc_order,
5433 sizeof (int) * FIRST_PSEUDO_REGISTER);
5437 /* Initialize the GCC target structure. */
5438 #undef TARGET_ASM_FUNCTION_PROLOGUE
5439 #define TARGET_ASM_FUNCTION_PROLOGUE nios2_asm_function_prologue
5441 #undef TARGET_IN_SMALL_DATA_P
5442 #define TARGET_IN_SMALL_DATA_P nios2_in_small_data_p
5444 #undef TARGET_SECTION_TYPE_FLAGS
5445 #define TARGET_SECTION_TYPE_FLAGS nios2_section_type_flags
5447 #undef TARGET_INIT_BUILTINS
5448 #define TARGET_INIT_BUILTINS nios2_init_builtins
5449 #undef TARGET_EXPAND_BUILTIN
5450 #define TARGET_EXPAND_BUILTIN nios2_expand_builtin
5451 #undef TARGET_BUILTIN_DECL
5452 #define TARGET_BUILTIN_DECL nios2_builtin_decl
5454 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
5455 #define TARGET_FUNCTION_OK_FOR_SIBCALL hook_bool_tree_tree_true
5457 #undef TARGET_CAN_ELIMINATE
5458 #define TARGET_CAN_ELIMINATE nios2_can_eliminate
5460 #undef TARGET_FUNCTION_ARG
5461 #define TARGET_FUNCTION_ARG nios2_function_arg
5463 #undef TARGET_FUNCTION_ARG_ADVANCE
5464 #define TARGET_FUNCTION_ARG_ADVANCE nios2_function_arg_advance
5466 #undef TARGET_FUNCTION_ARG_PADDING
5467 #define TARGET_FUNCTION_ARG_PADDING nios2_function_arg_padding
5469 #undef TARGET_ARG_PARTIAL_BYTES
5470 #define TARGET_ARG_PARTIAL_BYTES nios2_arg_partial_bytes
5472 #undef TARGET_TRAMPOLINE_INIT
5473 #define TARGET_TRAMPOLINE_INIT nios2_trampoline_init
5475 #undef TARGET_FUNCTION_VALUE
5476 #define TARGET_FUNCTION_VALUE nios2_function_value
5478 #undef TARGET_LIBCALL_VALUE
5479 #define TARGET_LIBCALL_VALUE nios2_libcall_value
5481 #undef TARGET_FUNCTION_VALUE_REGNO_P
5482 #define TARGET_FUNCTION_VALUE_REGNO_P nios2_function_value_regno_p
5484 #undef TARGET_RETURN_IN_MEMORY
5485 #define TARGET_RETURN_IN_MEMORY nios2_return_in_memory
5487 #undef TARGET_PROMOTE_PROTOTYPES
5488 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
5490 #undef TARGET_SETUP_INCOMING_VARARGS
5491 #define TARGET_SETUP_INCOMING_VARARGS nios2_setup_incoming_varargs
5493 #undef TARGET_MUST_PASS_IN_STACK
5494 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
5496 #undef TARGET_LEGITIMATE_CONSTANT_P
5497 #define TARGET_LEGITIMATE_CONSTANT_P nios2_legitimate_constant_p
5499 #undef TARGET_LEGITIMIZE_ADDRESS
5500 #define TARGET_LEGITIMIZE_ADDRESS nios2_legitimize_address
5502 #undef TARGET_DELEGITIMIZE_ADDRESS
5503 #define TARGET_DELEGITIMIZE_ADDRESS nios2_delegitimize_address
5505 #undef TARGET_LEGITIMATE_ADDRESS_P
5506 #define TARGET_LEGITIMATE_ADDRESS_P nios2_legitimate_address_p
5508 #undef TARGET_PREFERRED_RELOAD_CLASS
5509 #define TARGET_PREFERRED_RELOAD_CLASS nios2_preferred_reload_class
5511 #undef TARGET_RTX_COSTS
5512 #define TARGET_RTX_COSTS nios2_rtx_costs
5514 #undef TARGET_ADDRESS_COST
5515 #define TARGET_ADDRESS_COST nios2_address_cost
5517 #undef TARGET_HAVE_TLS
5518 #define TARGET_HAVE_TLS TARGET_LINUX_ABI
5520 #undef TARGET_CANNOT_FORCE_CONST_MEM
5521 #define TARGET_CANNOT_FORCE_CONST_MEM nios2_cannot_force_const_mem
5523 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
5524 #define TARGET_ASM_OUTPUT_DWARF_DTPREL nios2_output_dwarf_dtprel
5526 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
5527 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P nios2_print_operand_punct_valid_p
5529 #undef TARGET_PRINT_OPERAND
5530 #define TARGET_PRINT_OPERAND nios2_print_operand
5532 #undef TARGET_PRINT_OPERAND_ADDRESS
5533 #define TARGET_PRINT_OPERAND_ADDRESS nios2_print_operand_address
5535 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
5536 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA nios2_output_addr_const_extra
5538 #undef TARGET_ASM_FILE_END
5539 #define TARGET_ASM_FILE_END nios2_asm_file_end
5541 #undef TARGET_OPTION_OVERRIDE
5542 #define TARGET_OPTION_OVERRIDE nios2_option_override
5544 #undef TARGET_OPTION_SAVE
5545 #define TARGET_OPTION_SAVE nios2_option_save
5547 #undef TARGET_OPTION_RESTORE
5548 #define TARGET_OPTION_RESTORE nios2_option_restore
5550 #undef TARGET_SET_CURRENT_FUNCTION
5551 #define TARGET_SET_CURRENT_FUNCTION nios2_set_current_function
5553 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
5554 #define TARGET_OPTION_VALID_ATTRIBUTE_P nios2_valid_target_attribute_p
5556 #undef TARGET_OPTION_PRAGMA_PARSE
5557 #define TARGET_OPTION_PRAGMA_PARSE nios2_pragma_target_parse
5559 #undef TARGET_MERGE_DECL_ATTRIBUTES
5560 #define TARGET_MERGE_DECL_ATTRIBUTES nios2_merge_decl_attributes
5562 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
5563 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK \
5564 hook_bool_const_tree_hwi_hwi_const_tree_true
5566 #undef TARGET_ASM_OUTPUT_MI_THUNK
5567 #define TARGET_ASM_OUTPUT_MI_THUNK nios2_asm_output_mi_thunk
5569 #undef TARGET_MACHINE_DEPENDENT_REORG
5570 #define TARGET_MACHINE_DEPENDENT_REORG nios2_reorg
5572 #undef TARGET_CONSTANT_ALIGNMENT
5573 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
5575 struct gcc_target targetm = TARGET_INITIALIZER;
5577 #include "gt-nios2.h"