]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/nios2/nios2.c
Use function_arg_info for TARGET_FUNCTION_(INCOMING_)ARG
[thirdparty/gcc.git] / gcc / config / nios2 / nios2.c
CommitLineData
e430824f 1/* Target machine subroutines for Altera Nios II.
a5544970 2 Copyright (C) 2012-2019 Free Software Foundation, Inc.
e430824f
CLT
3 Contributed by Jonah Graham (jgraham@altera.com),
4 Will Reece (wreece@altera.com), and Jeff DaSilva (jdasilva@altera.com).
5 Contributed by Mentor Graphics, Inc.
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published
11 by the Free Software Foundation; either version 3, or (at your
12 option) any later version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
22
8fcc61f8
RS
23#define IN_TARGET_CODE 1
24
e430824f
CLT
25#include "config.h"
26#include "system.h"
27#include "coretypes.h"
c7131fb2 28#include "backend.h"
e11c4407 29#include "target.h"
e430824f 30#include "rtl.h"
e11c4407 31#include "tree.h"
314e6352
ML
32#include "stringpool.h"
33#include "attribs.h"
c7131fb2 34#include "df.h"
4d0cdd0c 35#include "memmodel.h"
e11c4407
AM
36#include "tm_p.h"
37#include "optabs.h"
e430824f 38#include "regs.h"
e11c4407
AM
39#include "emit-rtl.h"
40#include "recog.h"
41#include "diagnostic-core.h"
e430824f
CLT
42#include "output.h"
43#include "insn-attr.h"
44#include "flags.h"
36566b39
PK
45#include "explow.h"
46#include "calls.h"
36566b39 47#include "varasm.h"
e430824f 48#include "expr.h"
e430824f 49#include "toplev.h"
e430824f 50#include "langhooks.h"
e430824f 51#include "stor-layout.h"
47657153 52#include "builtins.h"
82348675 53#include "tree-pass.h"
de10fca0 54#include "xregex.h"
e430824f 55
994c5d85 56/* This file should be included last. */
d58627a0
RS
57#include "target-def.h"
58
e430824f 59/* Forward function declarations. */
82348675 60static bool nios2_symbolic_constant_p (rtx);
e430824f
CLT
61static bool prologue_saved_reg_p (unsigned);
62static void nios2_load_pic_register (void);
63static void nios2_register_custom_code (unsigned int, enum nios2_ccs_code, int);
64static const char *nios2_unspec_reloc_name (int);
65static void nios2_register_builtin_fndecl (unsigned, tree);
aa32db37
SL
66static rtx nios2_ldst_parallel (bool, bool, bool, rtx, int,
67 unsigned HOST_WIDE_INT, bool);
efd5897c 68static int nios2_address_cost (rtx, machine_mode, addr_space_t, bool);
e430824f
CLT
69
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). */
74unsigned HOST_WIDE_INT nios2_section_threshold = NIOS2_DEFAULT_GVALUE;
75
76struct GTY (()) machine_function
77{
78 /* Current frame information, to be filled in by nios2_compute_frame_layout
79 with register save masks, and offsets for the current function. */
80
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;
c3ff2812
SL
91 /* Number of bytes used to store callee-saved registers. */
92 int callee_save_reg_size;
747425d0 93 /* Offset from new stack pointer to store registers. */
e430824f 94 int save_regs_offset;
747425d0
CLT
95 /* Offset from save_regs_offset to store frame pointer register. */
96 int fp_save_offset;
c3ff2812
SL
97 /* != 0 if function has a variable argument list. */
98 int uses_anonymous_args;
e430824f
CLT
99 /* != 0 if frame layout already calculated. */
100 int initialized;
101};
102
103/* State to track the assignment of custom codes to FPU/custom builtins. */
104static enum nios2_ccs_code custom_code_status[256];
105static int custom_code_index[256];
106/* Set to true if any conflicts (re-use of a code between 0-255) are found. */
107static bool custom_code_conflict = false;
108
de10fca0
SL
109/* State for command-line options. */
110regex_t nios2_gprel_sec_regex;
1cef1159 111regex_t nios2_r0rel_sec_regex;
de10fca0 112
e430824f
CLT
113\f
114/* Definition of builtin function types for nios2. */
115
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)) \
524d2e49
SL
135 N2_FTYPE(3, (SI, SI, SI)) \
136 N2_FTYPE(3, (SI, VPTR, SI)) \
e430824f
CLT
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)) \
524d2e49 142 N2_FTYPE(2, (VOID, SI)) \
e430824f 143 N2_FTYPE(3, (VOID, SI, SI)) \
524d2e49 144 N2_FTYPE(2, (VOID, VPTR)) \
e430824f
CLT
145 N2_FTYPE(3, (VOID, VPTR, SI))
146
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
150
151/* Expand ftcode enumeration. */
152enum nios2_ftcode {
153#define N2_FTYPE(N,ARGS) N2_FTYPE_OP ## N ARGS,
154N2_FTYPES
155#undef N2_FTYPE
156N2_FTYPE_MAX
157};
158
159/* Return the tree function type, based on the ftcode. */
160static tree
161nios2_ftype (enum nios2_ftcode ftcode)
162{
163 static tree types[(int) N2_FTYPE_MAX];
164
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;
170
171 static const_tree N2_TYPE_CVPTR, N2_TYPE_VPTR;
172 if (!N2_TYPE_CVPTR)
173 {
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));
183 }
184 if (types[(int) ftcode] == NULL_TREE)
185 switch (ftcode)
186 {
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 ();
198 }
199 return types[(int) ftcode];
200}
201
202\f
203/* Definition of FPU instruction descriptions. */
204
205struct nios2_fpu_insn_info
206{
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
aa221564 214#define N2F_NO_ERRNO 0x10
e430824f
CLT
215 unsigned int flags;
216 enum insn_code icode;
217 enum nios2_ftcode ftcode;
218};
219
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 }
225
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)
236
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)
243
244/* The order of definition needs to be maintained consistent with
245 enum n2fpu_code in nios2-opts.h. */
246struct nios2_fpu_insn_info nios2_fpu_insn[] =
247 {
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),
269
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),
291
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)),
aa221564 297 N2FPU_INSN_DEF_BASE (round, 2, N2F_NO_ERRNO, lroundsfsi2, (SI, SF)),
e430824f
CLT
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)),
304
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))
311 };
312
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)
aa221564 322#define N2FPU_NO_ERRNO_P(code) (N2FPU(code).flags & N2F_NO_ERRNO)
e430824f
CLT
323#define N2FPU_DOUBLE_P(code) (N2FPU(code).flags & N2F_DF)
324#define N2FPU_DOUBLE_REQUIRED_P(code) (N2FPU(code).flags & N2F_DFREQ)
325
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)
330
331/* Export the FPU insn enabled predicate to nios2.md. */
332bool
333nios2_fpu_insn_enabled (enum n2fpu_code code)
334{
335 return N2FPU_ENABLED_P (code);
336}
337
338/* Return true if COND comparison for mode MODE is enabled under current
339 settings. */
340
341static bool
ef4bddc2 342nios2_fpu_compare_enabled (enum rtx_code cond, machine_mode mode)
e430824f
CLT
343{
344 if (mode == SFmode)
345 switch (cond)
346 {
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;
354 }
355 else if (mode == DFmode)
356 switch (cond)
357 {
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;
365 }
366 return false;
367}
368
369/* Stack layout and calling conventions. */
370
371#define NIOS2_STACK_ALIGN(LOC) \
372 (((LOC) + ((PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT) - 1)) \
373 & ~((PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT) - 1))
374
375/* Return the bytes needed to compute the frame pointer from the current
376 stack pointer. */
377static int
378nios2_compute_frame_layout (void)
379{
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;
c3ff2812 386 int callee_save_reg_size;
e430824f
CLT
387
388 if (cfun->machine->initialized)
389 return cfun->machine->total_size;
390
e430824f
CLT
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))
395 {
396 save_mask |= 1 << regno;
397 save_reg_size += 4;
398 }
399
c3ff2812
SL
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)
404 {
405 if ((save_mask & (1 << RA_REGNO)) == 0)
406 {
407 save_mask |= 1 << RA_REGNO;
408 save_reg_size += 4;
409 }
410
411 for (regno = 23; regno >= 16; regno--)
412 if ((save_mask & (1 << regno)) != 0)
413 {
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)
421 {
422 save_mask |= 1 << i;
423 save_reg_size += 4;
424 }
425 break;
426 }
427 }
428
429 callee_save_reg_size = save_reg_size;
430
e430824f
CLT
431 /* If we call eh_return, we need to save the EH data registers. */
432 if (crtl->calls_eh_return)
433 {
434 unsigned i;
435 unsigned r;
436
437 for (i = 0; (r = EH_RETURN_DATA_REGNO (i)) != INVALID_REGNUM; i++)
438 if (!(save_mask & (1 << r)))
439 {
440 save_mask |= 1 << r;
441 save_reg_size += 4;
442 }
443 }
444
747425d0
CLT
445 cfun->machine->fp_save_offset = 0;
446 if (save_mask & (1 << HARD_FRAME_POINTER_REGNUM))
447 {
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;
452
453 cfun->machine->fp_save_offset = fp_save_offset;
454 }
455
c3ff2812
SL
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;
459
e430824f
CLT
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);
463
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;
c3ff2812 470 cfun->machine->callee_save_reg_size = callee_save_reg_size;
e430824f
CLT
471 cfun->machine->initialized = reload_completed;
472 cfun->machine->save_regs_offset = out_args_size + var_size;
473
474 return total_size;
475}
476
477/* Generate save/restore of register REGNO at SP + OFFSET. Used by the
478 prologue/epilogue expand routines. */
479static void
480save_reg (int regno, unsigned offset)
481{
482 rtx reg = gen_rtx_REG (SImode, regno);
9d07490f
SL
483 rtx addr = plus_constant (Pmode, stack_pointer_rtx, offset, false);
484 rtx_insn *insn = emit_move_insn (gen_frame_mem (Pmode, addr), reg);
e430824f
CLT
485 RTX_FRAME_RELATED_P (insn) = 1;
486}
487
488static void
489restore_reg (int regno, unsigned offset)
490{
491 rtx reg = gen_rtx_REG (SImode, regno);
9d07490f
SL
492 rtx addr = plus_constant (Pmode, stack_pointer_rtx, offset, false);
493 rtx_insn *insn = emit_move_insn (reg, gen_frame_mem (Pmode, addr));
e430824f
CLT
494 /* Tag epilogue unwind note. */
495 add_reg_note (insn, REG_CFA_RESTORE, reg);
496 RTX_FRAME_RELATED_P (insn) = 1;
497}
498
aa32db37
SL
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. */
501static bool
502base_reg_adjustment_p (rtx set, rtx *base_reg, rtx *offset)
503{
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)))
510 {
511 *base_reg = XEXP (SET_SRC (set), 0);
512 *offset = XEXP (SET_SRC (set), 1);
513 return true;
514 }
515 return false;
516}
517
c3ff2812
SL
518/* Does the CFA note work for push/pop prologue/epilogue instructions. */
519static void
520nios2_create_cfa_notes (rtx_insn *insn, bool epilogue_p)
521{
522 int i = 0;
523 rtx base_reg, offset, elt, pat = PATTERN (insn);
524 if (epilogue_p)
525 {
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))
531 {
532 add_reg_note (insn, REG_CFA_ADJUST_CFA, copy_rtx (elt));
533 i++;
534 }
535 for (; i < XVECLEN (pat, 0); i++)
536 {
537 elt = SET_DEST (XVECEXP (pat, 0, i));
538 gcc_assert (REG_P (elt));
539 add_reg_note (insn, REG_CFA_RESTORE, elt);
540 }
541 }
542 else
543 {
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;
547 }
548}
549
5faebb89
SL
550/* Temp regno used inside prologue/epilogue. */
551#define TEMP_REG_NUM 8
552
553/* Emit conditional trap for checking stack limit. SIZE is the number of
554 additional bytes required.
555
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. */
e430824f 560static void
5faebb89 561nios2_emit_stack_limit_check (int size)
e430824f 562{
a6885f12 563 rtx sum = NULL_RTX;
5faebb89
SL
564
565 if (GET_CODE (stack_limit_rtx) == SYMBOL_REF)
566 {
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));
571 }
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))
577 {
578 sum = gen_rtx_REG (Pmode, TEMP_REG_NUM);
579 emit_move_insn (sum, plus_constant (Pmode, stack_limit_rtx, size));
580 }
e430824f 581 else
5faebb89
SL
582 {
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));
586 }
e430824f 587
5faebb89
SL
588 emit_insn (gen_ctrapsi4 (gen_rtx_LTU (VOIDmode, stack_pointer_rtx, sum),
589 stack_pointer_rtx, sum, GEN_INT (3)));
590}
e430824f 591
9d07490f 592static rtx_insn *
a866d527
CLT
593nios2_emit_add_constant (rtx reg, HOST_WIDE_INT immed)
594{
9d07490f 595 rtx_insn *insn;
a866d527
CLT
596 if (SMALL_INT (immed))
597 insn = emit_insn (gen_add2_insn (reg, gen_int_mode (immed, Pmode)));
598 else
599 {
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));
603 }
604 return insn;
605}
606
c3ff2812
SL
607static rtx_insn *
608nios2_adjust_stack (int sp_adjust, bool epilogue_p)
609{
610 enum reg_note note_kind = REG_NOTE_MAX;
611 rtx_insn *insn = NULL;
612 if (sp_adjust)
613 {
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
618 {
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;
625 }
626 if (epilogue_p)
627 note_kind = REG_CFA_ADJUST_CFA;
628 if (note_kind != REG_NOTE_MAX)
629 {
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);
634 }
635 RTX_FRAME_RELATED_P (insn) = 1;
636 }
637 return insn;
638}
639
e430824f
CLT
640void
641nios2_expand_prologue (void)
642{
643 unsigned int regno;
644 int total_frame_size, save_offset;
747425d0
CLT
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. */
9d07490f 647 rtx_insn *insn;
e430824f
CLT
648
649 total_frame_size = nios2_compute_frame_layout ();
650
651 if (flag_stack_usage_info)
652 current_function_static_stack_size = total_frame_size;
653
c3ff2812
SL
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))
659 {
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));
667
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);
672
673 if (pretend_args_size)
674 {
675 if (cfun->machine->uses_anonymous_args)
676 {
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;
688 }
689 else
690 nios2_adjust_stack (-pretend_args_size, false);
691 }
692 if (callee_save_regs)
693 {
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;
720 }
721
722 if (caller_save_regs)
723 {
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;
733 }
734
735 save_regs_base = push_immed;
736 sp_offset = -(cfun->machine->save_regs_offset - push_immed);
737 }
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))
e430824f
CLT
741 {
742 /* We need an intermediary point, this will point at the spill block. */
c3ff2812
SL
743 nios2_adjust_stack (cfun->machine->save_regs_offset - total_frame_size,
744 false);
747425d0 745 save_regs_base = 0;
e430824f 746 sp_offset = -cfun->machine->save_regs_offset;
5faebb89
SL
747 if (crtl->limit_stack)
748 nios2_emit_stack_limit_check (cfun->machine->save_regs_offset);
e430824f
CLT
749 }
750 else if (total_frame_size)
751 {
c3ff2812 752 nios2_adjust_stack (-total_frame_size, false);
747425d0 753 save_regs_base = cfun->machine->save_regs_offset;
e430824f 754 sp_offset = 0;
5faebb89
SL
755 if (crtl->limit_stack)
756 nios2_emit_stack_limit_check (0);
e430824f
CLT
757 }
758 else
747425d0 759 save_regs_base = sp_offset = 0;
e430824f 760
c3ff2812
SL
761 /* Save the registers individually in the non-CDX case. */
762 if (!TARGET_HAS_CDX)
763 {
764 save_offset = save_regs_base + cfun->machine->save_reg_size;
e430824f 765
c3ff2812
SL
766 for (regno = LAST_GP_REG; regno > 0; regno--)
767 if (cfun->machine->save_mask & (1 << regno))
768 {
769 save_offset -= 4;
770 save_reg (regno, save_offset);
771 }
772 }
e430824f 773
c3ff2812 774 /* Set the hard frame pointer. */
e430824f
CLT
775 if (frame_pointer_needed)
776 {
747425d0 777 int fp_save_offset = save_regs_base + cfun->machine->fp_save_offset;
c3ff2812
SL
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))));
e430824f
CLT
784 RTX_FRAME_RELATED_P (insn) = 1;
785 }
786
c3ff2812
SL
787 /* Allocate sp_offset more bytes in the stack frame. */
788 nios2_adjust_stack (sp_offset, false);
e430824f
CLT
789
790 /* Load the PIC register if needed. */
791 if (crtl->uses_pic_offset_table)
792 nios2_load_pic_register ();
793
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 ());
798}
799
800void
801nios2_expand_epilogue (bool sibcall_p)
802{
9d07490f
SL
803 rtx_insn *insn;
804 rtx cfa_adj;
e430824f
CLT
805 int total_frame_size;
806 int sp_adjust, save_offset;
807 unsigned int regno;
808
809 if (!sibcall_p && nios2_can_use_return_insn ())
810 {
811 emit_jump_insn (gen_return ());
812 return;
813 }
814
815 emit_insn (gen_blockage ());
816
817 total_frame_size = nios2_compute_frame_layout ();
818 if (frame_pointer_needed)
819 {
820 /* Recover the stack pointer. */
c3ff2812
SL
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))));
e430824f
CLT
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;
832
833 save_offset = 0;
834 sp_adjust = total_frame_size - cfun->machine->save_regs_offset;
835 }
836 else if (!SMALL_INT (total_frame_size))
837 {
c3ff2812 838 nios2_adjust_stack (cfun->machine->save_regs_offset, true);
e430824f
CLT
839 save_offset = 0;
840 sp_adjust = total_frame_size - cfun->machine->save_regs_offset;
841 }
842 else
843 {
844 save_offset = cfun->machine->save_regs_offset;
845 sp_adjust = total_frame_size;
846 }
e430824f 847
c3ff2812
SL
848 if (!TARGET_HAS_CDX)
849 {
850 /* Generate individual register restores. */
851 save_offset += cfun->machine->save_reg_size;
e430824f 852
c3ff2812
SL
853 for (regno = LAST_GP_REG; regno > 0; regno--)
854 if (cfun->machine->save_mask & (1 << regno))
855 {
856 save_offset -= 4;
857 restore_reg (regno, save_offset);
858 }
859 nios2_adjust_stack (sp_adjust, true);
860 }
861 else if (cfun->machine->save_reg_size == 0)
e430824f 862 {
c3ff2812
SL
863 /* Nothing to restore, just recover the stack position. */
864 nios2_adjust_stack (sp_adjust, true);
865 }
866 else
867 {
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);
877
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);
882
883 save_offset -= sp_adjust;
884
885 nios2_adjust_stack (sp_adjust, true);
886
887 if (caller_save_regs)
888 {
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);
896 }
897
898 if (callee_save_regs)
899 {
900 int sp_adjust = save_offset + callee_save_size;
901 rtx stack_mem;
902 if (ret_p)
903 {
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;
918 }
919 else
920 {
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);
929 }
930 }
931
932 if (pretend_args_size)
933 nios2_adjust_stack (pretend_args_size, true);
e430824f
CLT
934 }
935
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));
939
940 if (!sibcall_p)
941 emit_jump_insn (gen_simple_return ());
942}
943
c3ff2812
SL
944bool
945nios2_expand_return (void)
946{
947 /* If CDX is available, generate a pop.n instruction to do both
948 the stack pop and return. */
949 if (TARGET_HAS_CDX)
950 {
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)
956 {
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;
970 }
971 }
972 return false;
973}
974
e430824f
CLT
975/* Implement RETURN_ADDR_RTX. Note, we do not support moving
976 back to a previous frame. */
977rtx
978nios2_get_return_address (int count)
979{
980 if (count != 0)
981 return const0_rtx;
982
983 return get_hard_reg_initial_val (Pmode, RA_REGNO);
984}
985
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. */
989void
990nios2_set_return_address (rtx address, rtx scratch)
991{
992 nios2_compute_frame_layout ();
993 if (cfun->machine->save_mask & (1 << RA_REGNO))
994 {
995 unsigned offset = cfun->machine->save_reg_size - 4;
996 rtx base;
997
998 if (frame_pointer_needed)
999 base = hard_frame_pointer_rtx;
1000 else
1001 {
1002 base = stack_pointer_rtx;
1003 offset += cfun->machine->save_regs_offset;
1004
1005 if (!SMALL_INT (offset))
1006 {
1007 emit_move_insn (scratch, gen_int_mode (offset, Pmode));
1008 emit_insn (gen_add2_insn (scratch, base));
1009 base = scratch;
1010 offset = 0;
1011 }
1012 }
1013 if (offset)
1014 base = plus_constant (Pmode, base, offset);
1015 emit_move_insn (gen_rtx_MEM (Pmode, base), address);
1016 }
1017 else
1018 emit_move_insn (gen_rtx_REG (Pmode, RA_REGNO), address);
1019}
1020
1021/* Implement FUNCTION_PROFILER macro. */
1022void
1023nios2_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
1024{
1025 fprintf (file, "\tmov\tr8, ra\n");
95ce7613 1026 if (flag_pic == 1)
e430824f
CLT
1027 {
1028 fprintf (file, "\tnextpc\tr2\n");
02b67731
SL
1029 fprintf (file, "\t1: movhi\tr3, %%hiadj(_gp_got - 1b)\n");
1030 fprintf (file, "\taddi\tr3, r3, %%lo(_gp_got - 1b)\n");
e430824f
CLT
1031 fprintf (file, "\tadd\tr2, r2, r3\n");
1032 fprintf (file, "\tldw\tr2, %%call(_mcount)(r2)\n");
1033 fprintf (file, "\tcallr\tr2\n");
1034 }
95ce7613
CLT
1035 else if (flag_pic == 2)
1036 {
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");
98e8dd4d 1042 fprintf (file, "\taddi\tr3, r3, %%call_lo(_mcount)\n");
95ce7613
CLT
1043 fprintf (file, "\tadd\tr3, r2, r3\n");
1044 fprintf (file, "\tldw\tr2, 0(r3)\n");
1045 fprintf (file, "\tcallr\tr2\n");
1046 }
e430824f
CLT
1047 else
1048 fprintf (file, "\tcall\t_mcount\n");
1049 fprintf (file, "\tmov\tra, r8\n");
1050}
1051
1052/* Dump stack layout. */
1053static void
1054nios2_dump_frame_layout (FILE *file)
1055{
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);
1075}
1076
1077/* Return true if REGNO should be saved in the prologue. */
1078static bool
1079prologue_saved_reg_p (unsigned regno)
1080{
1081 gcc_assert (GP_REG_P (regno));
1082
1083 if (df_regs_ever_live_p (regno) && !call_used_regs[regno])
1084 return true;
1085
1086 if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
1087 return true;
1088
1089 if (regno == PIC_OFFSET_TABLE_REGNUM && crtl->uses_pic_offset_table)
1090 return true;
1091
1092 if (regno == RA_REGNO && df_regs_ever_live_p (RA_REGNO))
1093 return true;
1094
1095 return false;
1096}
1097
1098/* Implement TARGET_CAN_ELIMINATE. */
1099static bool
1100nios2_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
1101{
1102 if (to == STACK_POINTER_REGNUM)
1103 return !frame_pointer_needed;
1104 return true;
1105}
1106
1107/* Implement INITIAL_ELIMINATION_OFFSET macro. */
1108int
1109nios2_initial_elimination_offset (int from, int to)
1110{
1111 int offset;
1112
1113 nios2_compute_frame_layout ();
1114
1115 /* Set OFFSET to the offset from the stack pointer. */
1116 switch (from)
1117 {
1118 case FRAME_POINTER_REGNUM:
9bba3b25
SL
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;
e430824f
CLT
1122 break;
1123
1124 case ARG_POINTER_REGNUM:
1125 offset = cfun->machine->total_size;
1126 offset -= crtl->args.pretend_args_size;
1127 break;
1128
1129 default:
1130 gcc_unreachable ();
1131 }
1132
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)
747425d0
CLT
1136 offset -= (cfun->machine->save_regs_offset
1137 + cfun->machine->fp_save_offset);
e430824f
CLT
1138
1139 return offset;
1140}
1141
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. */
1145int
1146nios2_can_use_return_insn (void)
1147{
c3ff2812
SL
1148 int total_frame_size;
1149
e430824f
CLT
1150 if (!reload_completed || crtl->profile)
1151 return 0;
1152
c3ff2812
SL
1153 total_frame_size = nios2_compute_frame_layout ();
1154
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;
1164
1165 return total_frame_size == 0;
e430824f
CLT
1166}
1167
1168\f
1169/* Check and signal some warnings/errors on FPU insn options. */
1170static void
1171nios2_custom_check_insns (void)
1172{
1173 unsigned int i, j;
1174 bool errors = false;
1175
1176 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
1177 if (N2FPU_ENABLED_P (i) && N2FPU_DOUBLE_P (i))
1178 {
1179 for (j = 0; j < ARRAY_SIZE (nios2_fpu_insn); j++)
1180 if (N2FPU_DOUBLE_REQUIRED_P (j) && ! N2FPU_ENABLED_P (j))
1181 {
1182 error ("switch %<-mcustom-%s%> is required for double "
1183 "precision floating point", N2FPU_NAME (j));
1184 errors = true;
1185 }
1186 break;
1187 }
1188
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 "
a3f9f006
ML
1196 "%<-funsafe-math-optimizations%> is specified",
1197 N2FPU_NAME (i));
e430824f
CLT
1198
1199 /* Warn if the user is trying to use -mcustom-fmins et. al, that won't
1200 get used without -ffinite-math-only. See fold_builtin_fmin_fmax ()
1201 in builtins.c. */
1202 if (!flag_finite_math_only)
1203 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
1204 if (N2FPU_ENABLED_P (i) && N2FPU_FINITE_P (i))
1205 warning (0, "switch %<-mcustom-%s%> has no effect unless "
a3f9f006 1206 "%<-ffinite-math-only%> is specified", N2FPU_NAME (i));
e430824f 1207
aa221564
SL
1208 /* Warn if the user is trying to use a custom rounding instruction
1209 that won't get used without -fno-math-errno. See
1210 expand_builtin_int_roundingfn_2 () in builtins.c. */
1211 if (flag_errno_math)
1212 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
1213 if (N2FPU_ENABLED_P (i) && N2FPU_NO_ERRNO_P (i))
1214 warning (0, "switch %<-mcustom-%s%> has no effect unless "
a3f9f006 1215 "%<-fno-math-errno%> is specified", N2FPU_NAME (i));
aa221564 1216
e430824f 1217 if (errors || custom_code_conflict)
40fecdd6 1218 fatal_error (input_location,
a3f9f006
ML
1219 "conflicting use of %<-mcustom%> switches, target attributes, "
1220 "and/or %<__builtin_custom_%> functions");
e430824f
CLT
1221}
1222
1223static void
1224nios2_set_fpu_custom_code (enum n2fpu_code code, int n, bool override_p)
1225{
1226 if (override_p || N2FPU_N (code) == -1)
1227 N2FPU_N (code) = n;
1228 nios2_register_custom_code (n, CCS_FPU, (int) code);
1229}
1230
1231/* Type to represent a standard FPU config. */
1232struct nios2_fpu_config
1233{
1234 const char *name;
1235 bool set_sp_constants;
1236 int code[n2fpu_code_num];
1237};
1238
1239#define NIOS2_FPU_CONFIG_NUM 3
1240static struct nios2_fpu_config custom_fpu_config[NIOS2_FPU_CONFIG_NUM];
1241
1242static void
1243nios2_init_fpu_configs (void)
1244{
1245 struct nios2_fpu_config* cfg;
1246 int i = 0;
1247#define NEXT_FPU_CONFIG \
1248 do { \
1249 cfg = &custom_fpu_config[i++]; \
1250 memset (cfg, -1, sizeof (struct nios2_fpu_config));\
1251 } while (0)
1252
1253 NEXT_FPU_CONFIG;
1254 cfg->name = "60-1";
1255 cfg->set_sp_constants = true;
1256 cfg->code[n2fpu_fmuls] = 252;
1257 cfg->code[n2fpu_fadds] = 253;
1258 cfg->code[n2fpu_fsubs] = 254;
1259
1260 NEXT_FPU_CONFIG;
1261 cfg->name = "60-2";
1262 cfg->set_sp_constants = true;
1263 cfg->code[n2fpu_fmuls] = 252;
1264 cfg->code[n2fpu_fadds] = 253;
1265 cfg->code[n2fpu_fsubs] = 254;
1266 cfg->code[n2fpu_fdivs] = 255;
1267
1268 NEXT_FPU_CONFIG;
1269 cfg->name = "72-3";
1270 cfg->set_sp_constants = true;
1271 cfg->code[n2fpu_floatus] = 243;
1272 cfg->code[n2fpu_fixsi] = 244;
1273 cfg->code[n2fpu_floatis] = 245;
1274 cfg->code[n2fpu_fcmpgts] = 246;
1275 cfg->code[n2fpu_fcmples] = 249;
1276 cfg->code[n2fpu_fcmpeqs] = 250;
1277 cfg->code[n2fpu_fcmpnes] = 251;
1278 cfg->code[n2fpu_fmuls] = 252;
1279 cfg->code[n2fpu_fadds] = 253;
1280 cfg->code[n2fpu_fsubs] = 254;
1281 cfg->code[n2fpu_fdivs] = 255;
1282
1283#undef NEXT_FPU_CONFIG
1284 gcc_assert (i == NIOS2_FPU_CONFIG_NUM);
1285}
1286
1287static struct nios2_fpu_config *
1288nios2_match_custom_fpu_cfg (const char *cfgname, const char *endp)
1289{
1290 int i;
1291 for (i = 0; i < NIOS2_FPU_CONFIG_NUM; i++)
1292 {
1293 bool match = !(endp != NULL
1294 ? strncmp (custom_fpu_config[i].name, cfgname,
1295 endp - cfgname)
1296 : strcmp (custom_fpu_config[i].name, cfgname));
1297 if (match)
1298 return &custom_fpu_config[i];
1299 }
1300 return NULL;
1301}
1302
1303/* Use CFGNAME to lookup FPU config, ENDP if not NULL marks end of string.
1304 OVERRIDE is true if loaded config codes should overwrite current state. */
1305static void
1306nios2_handle_custom_fpu_cfg (const char *cfgname, const char *endp,
1307 bool override)
1308{
1309 struct nios2_fpu_config *cfg = nios2_match_custom_fpu_cfg (cfgname, endp);
1310 if (cfg)
1311 {
1312 unsigned int i;
1313 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
1314 if (cfg->code[i] >= 0)
1315 nios2_set_fpu_custom_code ((enum n2fpu_code) i, cfg->code[i],
1316 override);
1317 if (cfg->set_sp_constants)
1318 flag_single_precision_constant = 1;
1319 }
1320 else
1321 warning (0, "ignoring unrecognized switch %<-mcustom-fpu-cfg%> "
95ce7613 1322 "value %<%s%>", cfgname);
e430824f
CLT
1323
1324 /* Guard against errors in the standard configurations. */
1325 nios2_custom_check_insns ();
1326}
1327
1328/* Check individual FPU insn options, and register custom code. */
1329static void
1330nios2_handle_custom_fpu_insn_option (int fpu_insn_index)
1331{
1332 int param = N2FPU_N (fpu_insn_index);
1333
01512446 1334 if (param >= 0 && param <= 255)
e430824f
CLT
1335 nios2_register_custom_code (param, CCS_FPU, fpu_insn_index);
1336
1337 /* Valid values are 0-255, but also allow -1 so that the
1338 -mno-custom-<opt> switches work. */
1339 else if (param != -1)
1340 error ("switch %<-mcustom-%s%> value %d must be between 0 and 255",
1341 N2FPU_NAME (fpu_insn_index), param);
1342}
1343
1344/* Allocate a chunk of memory for per-function machine-dependent data. */
1345static struct machine_function *
1346nios2_init_machine_status (void)
1347{
766090c2 1348 return ggc_cleared_alloc<machine_function> ();
e430824f
CLT
1349}
1350
1351/* Implement TARGET_OPTION_OVERRIDE. */
1352static void
1353nios2_option_override (void)
1354{
1355 unsigned int i;
1356
1357#ifdef SUBTARGET_OVERRIDE_OPTIONS
1358 SUBTARGET_OVERRIDE_OPTIONS;
1359#endif
1360
1361 /* Check for unsupported options. */
1362 if (flag_pic && !TARGET_LINUX_ABI)
1363 sorry ("position-independent code requires the Linux ABI");
5faebb89
SL
1364 if (flag_pic && stack_limit_rtx
1365 && GET_CODE (stack_limit_rtx) == SYMBOL_REF)
a3f9f006 1366 sorry ("PIC support for %<-fstack-limit-symbol%>");
e430824f
CLT
1367
1368 /* Function to allocate machine-dependent function status. */
1369 init_machine_status = &nios2_init_machine_status;
1370
1371 nios2_section_threshold
1372 = (global_options_set.x_g_switch_value
1373 ? g_switch_value : NIOS2_DEFAULT_GVALUE);
1374
56314783
SL
1375 if (nios2_gpopt_option == gpopt_unspecified)
1376 {
1377 /* Default to -mgpopt unless -fpic or -fPIC. */
1378 if (flag_pic)
1379 nios2_gpopt_option = gpopt_none;
1380 else
1381 nios2_gpopt_option = gpopt_local;
1382 }
e430824f 1383
1cef1159 1384 /* GP-relative and r0-relative addressing don't make sense for PIC. */
de10fca0 1385 if (flag_pic)
1cef1159 1386 {
de10fca0 1387 if (nios2_gpopt_option != gpopt_none)
a3f9f006 1388 error ("%<-mgpopt%> not supported with PIC.");
de10fca0 1389 if (nios2_gprel_sec)
a3f9f006 1390 error ("%<-mgprel-sec=%> not supported with PIC.");
1cef1159 1391 if (nios2_r0rel_sec)
a3f9f006 1392 error ("%<-mr0rel-sec=%> not supported with PIC.");
de10fca0
SL
1393 }
1394
1cef1159 1395 /* Process -mgprel-sec= and -m0rel-sec=. */
de10fca0
SL
1396 if (nios2_gprel_sec)
1397 {
1398 if (regcomp (&nios2_gprel_sec_regex, nios2_gprel_sec,
1399 REG_EXTENDED | REG_NOSUB))
a3f9f006 1400 error ("%<-mgprel-sec=%> argument is not a valid regular expression.");
de10fca0 1401 }
1cef1159
SL
1402 if (nios2_r0rel_sec)
1403 {
1404 if (regcomp (&nios2_r0rel_sec_regex, nios2_r0rel_sec,
1405 REG_EXTENDED | REG_NOSUB))
a3f9f006 1406 error ("%<-mr0rel-sec=%> argument is not a valid regular expression.");
1cef1159 1407 }
de10fca0 1408
e430824f
CLT
1409 /* If we don't have mul, we don't have mulx either! */
1410 if (!TARGET_HAS_MUL && TARGET_HAS_MULX)
1411 target_flags &= ~MASK_HAS_MULX;
1412
77c50d73
SL
1413 /* Optional BMX and CDX instructions only make sense for R2. */
1414 if (!TARGET_ARCH_R2)
1415 {
1416 if (TARGET_HAS_BMX)
1417 error ("BMX instructions are only supported with R2 architecture");
1418 if (TARGET_HAS_CDX)
1419 error ("CDX instructions are only supported with R2 architecture");
1420 }
1421
1422 /* R2 is little-endian only. */
1423 if (TARGET_ARCH_R2 && TARGET_BIG_ENDIAN)
1424 error ("R2 architecture is little-endian only");
1425
e430824f
CLT
1426 /* Initialize default FPU configurations. */
1427 nios2_init_fpu_configs ();
1428
1429 /* Set up default handling for floating point custom instructions.
1430
1431 Putting things in this order means that the -mcustom-fpu-cfg=
1432 switch will always be overridden by individual -mcustom-fadds=
1433 switches, regardless of the order in which they were specified
1434 on the command line.
1435
1436 This behavior of prioritization of individual -mcustom-<insn>=
1437 options before the -mcustom-fpu-cfg= switch is maintained for
1438 compatibility. */
1439 if (nios2_custom_fpu_cfg_string && *nios2_custom_fpu_cfg_string)
1440 nios2_handle_custom_fpu_cfg (nios2_custom_fpu_cfg_string, NULL, false);
1441
1442 /* Handle options for individual FPU insns. */
1443 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
1444 nios2_handle_custom_fpu_insn_option (i);
1445
1446 nios2_custom_check_insns ();
1447
1448 /* Save the initial options in case the user does function specific
1449 options. */
1450 target_option_default_node = target_option_current_node
1451 = build_target_option_node (&global_options);
1452}
1453
1454\f
1455/* Return true if CST is a constant within range of movi/movui/movhi. */
1456static bool
1457nios2_simple_const_p (const_rtx cst)
1458{
039f4db9
SB
1459 if (!CONST_INT_P (cst))
1460 return false;
e430824f
CLT
1461 HOST_WIDE_INT val = INTVAL (cst);
1462 return SMALL_INT (val) || SMALL_INT_UNSIGNED (val) || UPPER16_INT (val);
1463}
1464
1465/* Compute a (partial) cost for rtx X. Return true if the complete
1466 cost has been computed, and false if subexpressions should be
1467 scanned. In either case, *TOTAL contains the cost result. */
1468static bool
efd5897c
SL
1469nios2_rtx_costs (rtx x, machine_mode mode,
1470 int outer_code,
1471 int opno,
1472 int *total, bool speed)
e430824f 1473{
e548c9df
AM
1474 int code = GET_CODE (x);
1475
e430824f
CLT
1476 switch (code)
1477 {
1478 case CONST_INT:
efd5897c 1479 if (INTVAL (x) == 0 || nios2_simple_const_p (x))
e430824f
CLT
1480 {
1481 *total = COSTS_N_INSNS (0);
1482 return true;
1483 }
e430824f
CLT
1484 else
1485 {
efd5897c
SL
1486 /* High + lo_sum. */
1487 *total = COSTS_N_INSNS (1);
e430824f
CLT
1488 return true;
1489 }
1490
1491 case LABEL_REF:
1492 case SYMBOL_REF:
1493 case CONST:
1494 case CONST_DOUBLE:
1cef1159 1495 if (gprel_constant_p (x) || r0rel_constant_p (x))
efd5897c
SL
1496 {
1497 *total = COSTS_N_INSNS (1);
1498 return true;
1499 }
1500 else
1501 {
1502 /* High + lo_sum. */
1503 *total = COSTS_N_INSNS (1);
1504 return true;
1505 }
1506
1507 case HIGH:
1508 {
1509 /* This is essentially a constant. */
1510 *total = COSTS_N_INSNS (0);
1511 return true;
1512 }
1513
1514 case LO_SUM:
1515 {
1516 *total = COSTS_N_INSNS (0);
1517 return true;
1518 }
e430824f
CLT
1519
1520 case AND:
1521 {
1522 /* Recognize 'nor' insn pattern. */
1523 if (GET_CODE (XEXP (x, 0)) == NOT
1524 && GET_CODE (XEXP (x, 1)) == NOT)
1525 {
1526 *total = COSTS_N_INSNS (1);
1527 return true;
1528 }
1529 return false;
1530 }
1531
efd5897c
SL
1532 /* For insns that have an execution latency (3 cycles), don't
1533 penalize by the full amount since we can often schedule
1534 to avoid it. */
e430824f
CLT
1535 case MULT:
1536 {
efd5897c
SL
1537 if (!TARGET_HAS_MUL)
1538 *total = COSTS_N_INSNS (5); /* Guess? */
1539 else if (speed)
1540 *total = COSTS_N_INSNS (2); /* Latency adjustment. */
1541 else
1542 *total = COSTS_N_INSNS (1);
2eae232f
SL
1543 if (TARGET_HAS_MULX && GET_MODE (x) == DImode)
1544 {
1545 enum rtx_code c0 = GET_CODE (XEXP (x, 0));
1546 enum rtx_code c1 = GET_CODE (XEXP (x, 1));
1547 if ((c0 == SIGN_EXTEND && c1 == SIGN_EXTEND)
1548 || (c0 == ZERO_EXTEND && c1 == ZERO_EXTEND))
1549 /* This is the <mul>sidi3 pattern, which expands into 4 insns,
1550 2 multiplies and 2 moves. */
1551 {
1552 *total = *total * 2 + COSTS_N_INSNS (2);
1553 return true;
1554 }
1555 }
e430824f
CLT
1556 return false;
1557 }
efd5897c
SL
1558
1559 case DIV:
e430824f 1560 {
efd5897c
SL
1561 if (!TARGET_HAS_DIV)
1562 *total = COSTS_N_INSNS (5); /* Guess? */
1563 else if (speed)
1564 *total = COSTS_N_INSNS (2); /* Latency adjustment. */
1565 else
1566 *total = COSTS_N_INSNS (1);
e430824f
CLT
1567 return false;
1568 }
efd5897c
SL
1569
1570 case ASHIFT:
1571 case ASHIFTRT:
1572 case LSHIFTRT:
1573 case ROTATE:
e430824f 1574 {
efd5897c
SL
1575 if (!speed)
1576 *total = COSTS_N_INSNS (1);
1577 else
1578 *total = COSTS_N_INSNS (2); /* Latency adjustment. */
e430824f
CLT
1579 return false;
1580 }
efd5897c
SL
1581
1582 case ZERO_EXTRACT:
1583 if (TARGET_HAS_BMX)
1584 {
1585 *total = COSTS_N_INSNS (1);
1586 return true;
1587 }
1588 return false;
e430824f 1589
efd5897c
SL
1590 case SIGN_EXTEND:
1591 {
1592 if (MEM_P (XEXP (x, 0)))
1593 *total = COSTS_N_INSNS (1);
1594 else
1595 *total = COSTS_N_INSNS (3);
1596 return false;
1597 }
1598
1599 case MEM:
3bbbe009 1600 {
efd5897c
SL
1601 rtx addr = XEXP (x, 0);
1602
1603 /* Account for cost of different addressing modes. */
1604 *total = nios2_address_cost (addr, mode, ADDR_SPACE_GENERIC, speed);
1605
1606 if (outer_code == SET && opno == 0)
1607 /* Stores execute in 1 cycle accounted for by
1608 the outer SET. */
1609 ;
1610 else if (outer_code == SET || outer_code == SIGN_EXTEND
1611 || outer_code == ZERO_EXTEND)
1612 /* Latency adjustment. */
1613 {
1614 if (speed)
1615 *total += COSTS_N_INSNS (1);
1616 }
1617 else
1618 /* This is going to have to be split into a load. */
1619 *total += COSTS_N_INSNS (speed ? 2 : 1);
1620 return true;
3bbbe009
SL
1621 }
1622
e430824f
CLT
1623 default:
1624 return false;
1625 }
1626}
1627
1628/* Implement TARGET_PREFERRED_RELOAD_CLASS. */
1629static reg_class_t
1630nios2_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, reg_class_t regclass)
1631{
1632 return regclass == NO_REGS ? GENERAL_REGS : regclass;
1633}
1634
1635/* Emit a call to __tls_get_addr. TI is the argument to this function.
1636 RET is an RTX for the return value location. The entire insn sequence
1637 is returned. */
1638static GTY(()) rtx nios2_tls_symbol;
1639
1640static rtx
1641nios2_call_tls_get_addr (rtx ti)
1642{
1643 rtx arg = gen_rtx_REG (Pmode, FIRST_ARG_REGNO);
1644 rtx ret = gen_rtx_REG (Pmode, FIRST_RETVAL_REGNO);
9d07490f
SL
1645 rtx fn;
1646 rtx_insn *insn;
e430824f
CLT
1647
1648 if (!nios2_tls_symbol)
1649 nios2_tls_symbol = init_one_libfunc ("__tls_get_addr");
1650
1651 emit_move_insn (arg, ti);
1652 fn = gen_rtx_MEM (QImode, nios2_tls_symbol);
1653 insn = emit_call_insn (gen_call_value (ret, fn, const0_rtx));
1654 RTL_CONST_CALL_P (insn) = 1;
1655 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), ret);
1656 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), arg);
1657
1658 return ret;
1659}
1660
95ce7613
CLT
1661/* Return true for large offsets requiring hiadj/lo relocation pairs. */
1662static bool
1663nios2_large_offset_p (int unspec)
1664{
1665 gcc_assert (nios2_unspec_reloc_name (unspec) != NULL);
1666
1667 if (flag_pic == 2
1668 /* FIXME: TLS GOT offset relocations will eventually also get this
1669 treatment, after binutils support for those are also completed. */
1670 && (unspec == UNSPEC_PIC_SYM || unspec == UNSPEC_PIC_CALL_SYM))
1671 return true;
1672
1673 /* 'gotoff' offsets are always hiadj/lo. */
1674 if (unspec == UNSPEC_PIC_GOTOFF_SYM)
1675 return true;
1676
1677 return false;
1678}
1679
1680/* Return true for conforming unspec relocations. Also used in
1681 constraints.md and predicates.md. */
1682bool
1683nios2_unspec_reloc_p (rtx op)
1684{
1685 return (GET_CODE (op) == CONST
1686 && GET_CODE (XEXP (op, 0)) == UNSPEC
1687 && ! nios2_large_offset_p (XINT (XEXP (op, 0), 1)));
1688}
1689
3bbbe009
SL
1690static bool
1691nios2_large_unspec_reloc_p (rtx op)
1692{
1693 return (GET_CODE (op) == CONST
1694 && GET_CODE (XEXP (op, 0)) == UNSPEC
1695 && nios2_large_offset_p (XINT (XEXP (op, 0), 1)));
1696}
1697
95ce7613
CLT
1698/* Helper to generate unspec constant. */
1699static rtx
1700nios2_unspec_offset (rtx loc, int unspec)
1701{
1702 return gen_rtx_CONST (Pmode, gen_rtx_UNSPEC (Pmode, gen_rtvec (1, loc),
1703 unspec));
1704}
1705
1706/* Generate GOT pointer based address with large offset. */
e430824f 1707static rtx
a866d527 1708nios2_large_got_address (rtx offset, rtx tmp)
e430824f 1709{
a866d527
CLT
1710 if (!tmp)
1711 tmp = gen_reg_rtx (Pmode);
1712 emit_move_insn (tmp, offset);
1713 return gen_rtx_PLUS (Pmode, tmp, pic_offset_table_rtx);
e430824f
CLT
1714}
1715
95ce7613 1716/* Generate a GOT pointer based address. */
e430824f
CLT
1717static rtx
1718nios2_got_address (rtx loc, int unspec)
1719{
95ce7613 1720 rtx offset = nios2_unspec_offset (loc, unspec);
e430824f 1721 crtl->uses_pic_offset_table = 1;
95ce7613
CLT
1722
1723 if (nios2_large_offset_p (unspec))
a866d527 1724 return force_reg (Pmode, nios2_large_got_address (offset, NULL_RTX));
95ce7613
CLT
1725
1726 return gen_rtx_PLUS (Pmode, pic_offset_table_rtx, offset);
e430824f
CLT
1727}
1728
1729/* Generate the code to access LOC, a thread local SYMBOL_REF. The
1730 return value will be a valid address and move_operand (either a REG
1731 or a LO_SUM). */
1732static rtx
1733nios2_legitimize_tls_address (rtx loc)
1734{
1735 rtx tmp, mem, tp;
1736 enum tls_model model = SYMBOL_REF_TLS_MODEL (loc);
1737
1738 switch (model)
1739 {
1740 case TLS_MODEL_GLOBAL_DYNAMIC:
1741 tmp = gen_reg_rtx (Pmode);
1742 emit_move_insn (tmp, nios2_got_address (loc, UNSPEC_ADD_TLS_GD));
1743 return nios2_call_tls_get_addr (tmp);
1744
1745 case TLS_MODEL_LOCAL_DYNAMIC:
1746 tmp = gen_reg_rtx (Pmode);
1747 emit_move_insn (tmp, nios2_got_address (loc, UNSPEC_ADD_TLS_LDM));
95ce7613
CLT
1748 return gen_rtx_PLUS (Pmode, nios2_call_tls_get_addr (tmp),
1749 nios2_unspec_offset (loc, UNSPEC_ADD_TLS_LDO));
e430824f
CLT
1750
1751 case TLS_MODEL_INITIAL_EXEC:
1752 tmp = gen_reg_rtx (Pmode);
1753 mem = gen_const_mem (Pmode, nios2_got_address (loc, UNSPEC_LOAD_TLS_IE));
1754 emit_move_insn (tmp, mem);
1755 tp = gen_rtx_REG (Pmode, TP_REGNO);
1756 return gen_rtx_PLUS (Pmode, tp, tmp);
1757
1758 case TLS_MODEL_LOCAL_EXEC:
1759 tp = gen_rtx_REG (Pmode, TP_REGNO);
95ce7613
CLT
1760 return gen_rtx_PLUS (Pmode, tp,
1761 nios2_unspec_offset (loc, UNSPEC_ADD_TLS_LE));
e430824f
CLT
1762 default:
1763 gcc_unreachable ();
1764 }
1765}
1766
1767/* Divide Support
1768
1769 If -O3 is used, we want to output a table lookup for
1770 divides between small numbers (both num and den >= 0
1771 and < 0x10). The overhead of this method in the worst
1772 case is 40 bytes in the text section (10 insns) and
1773 256 bytes in the data section. Additional divides do
1774 not incur additional penalties in the data section.
1775
1776 Code speed is improved for small divides by about 5x
1777 when using this method in the worse case (~9 cycles
1778 vs ~45). And in the worst case divides not within the
1779 table are penalized by about 10% (~5 cycles vs ~45).
1780 However in the typical case the penalty is not as bad
1781 because doing the long divide in only 45 cycles is
1782 quite optimistic.
1783
1784 ??? would be nice to have some benchmarks other
1785 than Dhrystone to back this up.
1786
1787 This bit of expansion is to create this instruction
1788 sequence as rtl.
1789 or $8, $4, $5
1790 slli $9, $4, 4
1791 cmpgeui $3, $8, 16
1792 beq $3, $0, .L3
1793 or $10, $9, $5
1794 add $12, $11, divide_table
1795 ldbu $2, 0($12)
1796 br .L1
1797.L3:
1798 call slow_div
1799.L1:
1800# continue here with result in $2
1801
1802 ??? Ideally I would like the libcall block to contain all
1803 of this code, but I don't know how to do that. What it
1804 means is that if the divide can be eliminated, it may not
1805 completely disappear.
1806
1807 ??? The __divsi3_table label should ideally be moved out
1808 of this block and into a global. If it is placed into the
1809 sdata section we can save even more cycles by doing things
1810 gp relative. */
1811void
ef4bddc2 1812nios2_emit_expensive_div (rtx *operands, machine_mode mode)
e430824f
CLT
1813{
1814 rtx or_result, shift_left_result;
1815 rtx lookup_value;
19f8b229 1816 rtx_code_label *lab1, *lab3;
9d07490f 1817 rtx_insn *insns;
e430824f
CLT
1818 rtx libfunc;
1819 rtx final_result;
9d07490f 1820 rtx_insn *tmp;
e430824f
CLT
1821 rtx table;
1822
1823 /* It may look a little generic, but only SImode is supported for now. */
1824 gcc_assert (mode == SImode);
1825 libfunc = optab_libfunc (sdiv_optab, SImode);
1826
1827 lab1 = gen_label_rtx ();
1828 lab3 = gen_label_rtx ();
1829
1830 or_result = expand_simple_binop (SImode, IOR,
1831 operands[1], operands[2],
1832 0, 0, OPTAB_LIB_WIDEN);
1833
1834 emit_cmp_and_jump_insns (or_result, GEN_INT (15), GTU, 0,
1835 GET_MODE (or_result), 0, lab3);
1836 JUMP_LABEL (get_last_insn ()) = lab3;
1837
1838 shift_left_result = expand_simple_binop (SImode, ASHIFT,
1839 operands[1], GEN_INT (4),
1840 0, 0, OPTAB_LIB_WIDEN);
1841
1842 lookup_value = expand_simple_binop (SImode, IOR,
1843 shift_left_result, operands[2],
1844 0, 0, OPTAB_LIB_WIDEN);
1845 table = gen_rtx_PLUS (SImode, lookup_value,
1846 gen_rtx_SYMBOL_REF (SImode, "__divsi3_table"));
1847 convert_move (operands[0], gen_rtx_MEM (QImode, table), 1);
1848
1849 tmp = emit_jump_insn (gen_jump (lab1));
1850 JUMP_LABEL (tmp) = lab1;
1851 emit_barrier ();
1852
1853 emit_label (lab3);
1854 LABEL_NUSES (lab3) = 1;
1855
1856 start_sequence ();
1857 final_result = emit_library_call_value (libfunc, NULL_RTX,
db69559b 1858 LCT_CONST, SImode,
e430824f
CLT
1859 operands[1], SImode,
1860 operands[2], SImode);
1861
1862 insns = get_insns ();
1863 end_sequence ();
1864 emit_libcall_block (insns, operands[0], final_result,
1865 gen_rtx_DIV (SImode, operands[1], operands[2]));
1866
1867 emit_label (lab1);
1868 LABEL_NUSES (lab1) = 1;
1869}
1870
1871\f
1872/* Branches and compares. */
1873
1874/* Return in *ALT_CODE and *ALT_OP, an alternate equivalent constant
1875 comparison, e.g. >= 1 into > 0. */
1876static void
1877nios2_alternate_compare_const (enum rtx_code code, rtx op,
1878 enum rtx_code *alt_code, rtx *alt_op,
ef4bddc2 1879 machine_mode mode)
e430824f 1880{
039f4db9
SB
1881 gcc_assert (CONST_INT_P (op));
1882
e430824f
CLT
1883 HOST_WIDE_INT opval = INTVAL (op);
1884 enum rtx_code scode = signed_condition (code);
1885 bool dec_p = (scode == LT || scode == GE);
1886
1887 if (code == EQ || code == NE)
1888 {
1889 *alt_code = code;
1890 *alt_op = op;
1891 return;
1892 }
1893
1894 *alt_op = (dec_p
1895 ? gen_int_mode (opval - 1, mode)
1896 : gen_int_mode (opval + 1, mode));
1897
1898 /* The required conversion between [>,>=] and [<,<=] is captured
1899 by a reverse + swap of condition codes. */
1900 *alt_code = reverse_condition (swap_condition (code));
1901
1902 {
1903 /* Test if the incremented/decremented value crosses the over/underflow
1904 boundary. Supposedly, such boundary cases should already be transformed
1905 into always-true/false or EQ conditions, so use an assertion here. */
1906 unsigned HOST_WIDE_INT alt_opval = INTVAL (*alt_op);
1907 if (code == scode)
1908 alt_opval ^= (1 << (GET_MODE_BITSIZE (mode) - 1));
1909 alt_opval &= GET_MODE_MASK (mode);
1910 gcc_assert (dec_p ? alt_opval != GET_MODE_MASK (mode) : alt_opval != 0);
1911 }
1912}
1913
1914/* Return true if the constant comparison is supported by nios2. */
1915static bool
1916nios2_valid_compare_const_p (enum rtx_code code, rtx op)
1917{
039f4db9 1918 gcc_assert (CONST_INT_P (op));
e430824f
CLT
1919 switch (code)
1920 {
1921 case EQ: case NE: case GE: case LT:
1922 return SMALL_INT (INTVAL (op));
1923 case GEU: case LTU:
1924 return SMALL_INT_UNSIGNED (INTVAL (op));
1925 default:
1926 return false;
1927 }
1928}
1929
1930/* Checks if the FPU comparison in *CMP, *OP1, and *OP2 can be supported in
1931 the current configuration. Perform modifications if MODIFY_P is true.
1932 Returns true if FPU compare can be done. */
1933
1934bool
ef4bddc2 1935nios2_validate_fpu_compare (machine_mode mode, rtx *cmp, rtx *op1, rtx *op2,
e430824f
CLT
1936 bool modify_p)
1937{
1938 bool rev_p = false;
1939 enum rtx_code code = GET_CODE (*cmp);
1940
1941 if (!nios2_fpu_compare_enabled (code, mode))
1942 {
1943 code = swap_condition (code);
1944 if (nios2_fpu_compare_enabled (code, mode))
1945 rev_p = true;
1946 else
1947 return false;
1948 }
1949
1950 if (modify_p)
1951 {
1952 if (rev_p)
1953 {
1954 rtx tmp = *op1;
1955 *op1 = *op2;
1956 *op2 = tmp;
1957 }
1958 *op1 = force_reg (mode, *op1);
1959 *op2 = force_reg (mode, *op2);
1960 *cmp = gen_rtx_fmt_ee (code, mode, *op1, *op2);
1961 }
1962 return true;
1963}
1964
1965/* Checks and modifies the comparison in *CMP, *OP1, and *OP2 into valid
1966 nios2 supported form. Returns true if success. */
1967bool
ef4bddc2 1968nios2_validate_compare (machine_mode mode, rtx *cmp, rtx *op1, rtx *op2)
e430824f
CLT
1969{
1970 enum rtx_code code = GET_CODE (*cmp);
1971 enum rtx_code alt_code;
1972 rtx alt_op2;
1973
1974 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
1975 return nios2_validate_fpu_compare (mode, cmp, op1, op2, true);
1976
039f4db9 1977 if (CONST_INT_P (*op2) && *op2 != const0_rtx)
e430824f
CLT
1978 {
1979 /* Create alternate constant compare. */
1980 nios2_alternate_compare_const (code, *op2, &alt_code, &alt_op2, mode);
1981
1982 /* If alterate op2 is zero(0), we can use it directly, possibly
1983 swapping the compare code. */
1984 if (alt_op2 == const0_rtx)
1985 {
1986 code = alt_code;
1987 *op2 = alt_op2;
1988 goto check_rebuild_cmp;
1989 }
1990
1991 /* Check if either constant compare can be used. */
1992 if (nios2_valid_compare_const_p (code, *op2))
1993 return true;
1994 else if (nios2_valid_compare_const_p (alt_code, alt_op2))
1995 {
1996 code = alt_code;
1997 *op2 = alt_op2;
1998 goto rebuild_cmp;
1999 }
2000
2001 /* We have to force op2 into a register now. Try to pick one
2002 with a lower cost. */
2003 if (! nios2_simple_const_p (*op2)
2004 && nios2_simple_const_p (alt_op2))
2005 {
2006 code = alt_code;
2007 *op2 = alt_op2;
2008 }
039f4db9 2009 *op2 = force_reg (mode, *op2);
e430824f 2010 }
039f4db9
SB
2011 else if (!reg_or_0_operand (*op2, mode))
2012 *op2 = force_reg (mode, *op2);
2013
e430824f
CLT
2014 check_rebuild_cmp:
2015 if (code == GT || code == GTU || code == LE || code == LEU)
2016 {
2017 rtx t = *op1; *op1 = *op2; *op2 = t;
2018 code = swap_condition (code);
2019 }
2020 rebuild_cmp:
2021 *cmp = gen_rtx_fmt_ee (code, mode, *op1, *op2);
2022 return true;
2023}
2024
2025
82348675
SL
2026/* Addressing modes and constants. */
2027
df8ceba6
SL
2028/* Symbol references and other 32-bit constants are split into
2029 high/lo_sum pairs during the split1 pass. After that, they are not
2030 considered legitimate addresses.
82348675
SL
2031 This function returns true if in a pre-split context where these
2032 constants are allowed. */
2033static bool
df8ceba6 2034nios2_large_constant_allowed (void)
82348675
SL
2035{
2036 /* The reload_completed check is for the benefit of
2037 nios2_asm_output_mi_thunk and perhaps other places that try to
2038 emulate a post-reload pass. */
2039 return !(cfun->curr_properties & PROP_rtl_split_insns) && !reload_completed;
2040}
2041
2042/* Return true if X is constant expression with a reference to an
2043 "ordinary" symbol; not GOT-relative, not GP-relative, not TLS. */
2044static bool
2045nios2_symbolic_constant_p (rtx x)
2046{
2047 rtx base, offset;
2048
2049 if (flag_pic)
2050 return false;
2051 if (GET_CODE (x) == LABEL_REF)
2052 return true;
2053 else if (CONSTANT_P (x))
2054 {
2055 split_const (x, &base, &offset);
2056 return (SYMBOL_REF_P (base)
2057 && !SYMBOL_REF_TLS_MODEL (base)
2058 && !gprel_constant_p (base)
1cef1159 2059 && !r0rel_constant_p (base)
82348675
SL
2060 && SMALL_INT (INTVAL (offset)));
2061 }
2062 return false;
2063}
2064
2065/* Return true if X is an expression of the form
df8ceba6 2066 (PLUS reg large_constant). */
82348675 2067static bool
df8ceba6 2068nios2_plus_large_constant_p (rtx x)
82348675
SL
2069{
2070 return (GET_CODE (x) == PLUS
2071 && REG_P (XEXP (x, 0))
df8ceba6 2072 && nios2_large_constant_p (XEXP (x, 1)));
82348675 2073}
e430824f
CLT
2074
2075/* Implement TARGET_LEGITIMATE_CONSTANT_P. */
2076static bool
ef4bddc2 2077nios2_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
e430824f
CLT
2078{
2079 rtx base, offset;
2080 split_const (x, &base, &offset);
2081 return GET_CODE (base) != SYMBOL_REF || !SYMBOL_REF_TLS_MODEL (base);
2082}
2083
2084/* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
2085static bool
ef4bddc2 2086nios2_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
e430824f
CLT
2087{
2088 return nios2_legitimate_constant_p (mode, x) == false;
2089}
2090
2091/* Return true if register REGNO is a valid base register.
2092 STRICT_P is true if REG_OK_STRICT is in effect. */
2093
2094bool
2095nios2_regno_ok_for_base_p (int regno, bool strict_p)
2096{
2097 if (!HARD_REGISTER_NUM_P (regno))
2098 {
2099 if (!strict_p)
2100 return true;
2101
2102 if (!reg_renumber)
2103 return false;
2104
2105 regno = reg_renumber[regno];
2106 }
2107
2108 /* The fake registers will be eliminated to either the stack or
2109 hard frame pointer, both of which are usually valid base registers.
2110 Reload deals with the cases where the eliminated form isn't valid. */
2111 return (GP_REG_P (regno)
2112 || regno == FRAME_POINTER_REGNUM
2113 || regno == ARG_POINTER_REGNUM);
2114}
2115
42e6ab74
SL
2116/* Return true if OFFSET is permitted in a load/store address expression.
2117 Normally any 16-bit value is permitted, but on R2 if we may be emitting
2118 the IO forms of these instructions we must restrict the offset to fit
2119 in a 12-bit field instead. */
2120
2121static bool
2122nios2_valid_addr_offset_p (rtx offset)
2123{
2124 return (CONST_INT_P (offset)
2125 && ((TARGET_ARCH_R2 && (TARGET_BYPASS_CACHE
2126 || TARGET_BYPASS_CACHE_VOLATILE))
2127 ? SMALL_INT12 (INTVAL (offset))
2128 : SMALL_INT (INTVAL (offset))));
2129}
2130
e430824f
CLT
2131/* Return true if the address expression formed by BASE + OFFSET is
2132 valid. */
2133static bool
2134nios2_valid_addr_expr_p (rtx base, rtx offset, bool strict_p)
2135{
2136 if (!strict_p && GET_CODE (base) == SUBREG)
2137 base = SUBREG_REG (base);
2138 return (REG_P (base)
2139 && nios2_regno_ok_for_base_p (REGNO (base), strict_p)
2140 && (offset == NULL_RTX
42e6ab74 2141 || nios2_valid_addr_offset_p (offset)
df8ceba6 2142 || (nios2_large_constant_allowed ()
82348675 2143 && nios2_symbolic_constant_p (offset))
e430824f
CLT
2144 || nios2_unspec_reloc_p (offset)));
2145}
2146
2147/* Implement TARGET_LEGITIMATE_ADDRESS_P. */
2148static bool
ef4bddc2 2149nios2_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
e430824f
CLT
2150 rtx operand, bool strict_p)
2151{
2152 switch (GET_CODE (operand))
2153 {
2154 /* Direct. */
2155 case SYMBOL_REF:
2156 if (SYMBOL_REF_TLS_MODEL (operand))
2157 return false;
7dcc7195
CLT
2158
2159 /* Else, fall through. */
2160 case CONST:
1cef1159 2161 if (gprel_constant_p (operand) || r0rel_constant_p (operand))
e430824f
CLT
2162 return true;
2163
2164 /* Else, fall through. */
2165 case LABEL_REF:
df8ceba6 2166 if (nios2_large_constant_allowed ()
82348675
SL
2167 && nios2_symbolic_constant_p (operand))
2168 return true;
df8ceba6 2169 return false;
82348675 2170
e430824f 2171 case CONST_INT:
df8ceba6
SL
2172 if (r0rel_constant_p (operand))
2173 return true;
2174 return nios2_large_constant_allowed ();
2175
e430824f
CLT
2176 case CONST_DOUBLE:
2177 return false;
2178
2179 /* Register indirect. */
2180 case REG:
2181 return nios2_regno_ok_for_base_p (REGNO (operand), strict_p);
2182
2183 /* Register indirect with displacement. */
2184 case PLUS:
2185 {
2186 rtx op0 = XEXP (operand, 0);
2187 rtx op1 = XEXP (operand, 1);
2188
82348675
SL
2189 if (nios2_valid_addr_expr_p (op0, op1, strict_p)
2190 || nios2_valid_addr_expr_p (op1, op0, strict_p))
2191 return true;
e430824f 2192 }
82348675
SL
2193 break;
2194
2195 /* %lo(constant)(reg)
2196 This requires a 16-bit relocation and isn't valid with R2
2197 io-variant load/stores. */
2198 case LO_SUM:
2199 if (TARGET_ARCH_R2
2200 && (TARGET_BYPASS_CACHE || TARGET_BYPASS_CACHE_VOLATILE))
2201 return false;
2202 else
2203 {
2204 rtx op0 = XEXP (operand, 0);
2205 rtx op1 = XEXP (operand, 1);
2206
2207 return (REG_P (op0)
2208 && nios2_regno_ok_for_base_p (REGNO (op0), strict_p)
2209 && nios2_large_constant_p (op1));
2210 }
e430824f
CLT
2211
2212 default:
2213 break;
2214 }
2215 return false;
2216}
2217
efd5897c
SL
2218/* Implement TARGET_ADDRESS_COST.
2219 Experimentation has shown that we get better code by penalizing the
2220 the (plus reg symbolic_constant) and (plus reg (const ...)) forms
2221 but giving (plus reg symbol_ref) address modes the same cost as those
2222 that don't require splitting. Also, from a theoretical point of view:
2223 - This is in line with the recommendation in the GCC internals
2224 documentation to make address forms involving multiple
2225 registers more expensive than single-register forms.
2226 - OTOH it still encourages fwprop1 to propagate constants into
2227 address expressions more aggressively.
2228 - We should discourage splitting (symbol + offset) into hi/lo pairs
2229 to allow CSE'ing the symbol when it's used with more than one offset,
2230 but not so heavily as to avoid this addressing mode at all. */
2231static int
2232nios2_address_cost (rtx address,
2233 machine_mode mode ATTRIBUTE_UNUSED,
2234 addr_space_t as ATTRIBUTE_UNUSED,
2235 bool speed ATTRIBUTE_UNUSED)
2236{
df8ceba6 2237 if (nios2_plus_large_constant_p (address))
efd5897c 2238 return COSTS_N_INSNS (1);
df8ceba6 2239 if (nios2_large_constant_p (address))
efd5897c
SL
2240 {
2241 if (GET_CODE (address) == CONST)
2242 return COSTS_N_INSNS (1);
2243 else
2244 return COSTS_N_INSNS (0);
2245 }
2246 return COSTS_N_INSNS (0);
2247}
2248
df8ceba6 2249/* Return true if X is a MEM whose address expression involves a large (32-bit)
82348675
SL
2250 constant. */
2251bool
df8ceba6 2252nios2_large_constant_memory_operand_p (rtx x)
82348675
SL
2253{
2254 rtx addr;
2255
2256 if (GET_CODE (x) != MEM)
2257 return false;
2258 addr = XEXP (x, 0);
2259
df8ceba6
SL
2260 return (nios2_large_constant_p (addr)
2261 || nios2_plus_large_constant_p (addr));
82348675
SL
2262}
2263
2264
2265/* Return true if X is something that needs to be split into a
2266 high/lo_sum pair. */
2267bool
2268nios2_large_constant_p (rtx x)
2269{
2270 return (nios2_symbolic_constant_p (x)
df8ceba6
SL
2271 || nios2_large_unspec_reloc_p (x)
2272 || (CONST_INT_P (x) && !SMALL_INT (INTVAL (x))));
82348675
SL
2273}
2274
2275/* Given an RTX X that satisfies nios2_large_constant_p, split it into
2276 high and lo_sum parts using TEMP as a scratch register. Emit the high
df8ceba6
SL
2277 instruction and return the lo_sum expression.
2278 Also handle special cases involving constant integers. */
82348675
SL
2279rtx
2280nios2_split_large_constant (rtx x, rtx temp)
2281{
df8ceba6
SL
2282 if (CONST_INT_P (x))
2283 {
2284 HOST_WIDE_INT val = INTVAL (x);
2285 if (SMALL_INT (val))
2286 return x;
2287 else if (SMALL_INT_UNSIGNED (val) || UPPER16_INT (val))
2288 {
2289 emit_move_insn (temp, x);
2290 return temp;
2291 }
2292 else
2293 {
2294 HOST_WIDE_INT high = (val + 0x8000) & ~0xffff;
2295 HOST_WIDE_INT low = val - high;
2296 emit_move_insn (temp, gen_int_mode (high, Pmode));
2297 return gen_rtx_PLUS (Pmode, temp, gen_int_mode (low, Pmode));
2298 }
2299 }
2300
82348675
SL
2301 emit_insn (gen_rtx_SET (temp, gen_rtx_HIGH (Pmode, copy_rtx (x))));
2302 return gen_rtx_LO_SUM (Pmode, temp, copy_rtx (x));
2303}
2304
2305/* Split an RTX of the form
2306 (plus op0 op1)
2307 where op1 is a large constant into
2308 (set temp (high op1))
2309 (set temp (plus op0 temp))
2310 (lo_sum temp op1)
2311 returning the lo_sum expression as the value. */
2312static rtx
2313nios2_split_plus_large_constant (rtx op0, rtx op1)
2314{
2315 rtx temp = gen_reg_rtx (Pmode);
2316 op0 = force_reg (Pmode, op0);
2317
2318 emit_insn (gen_rtx_SET (temp, gen_rtx_HIGH (Pmode, copy_rtx (op1))));
2319 emit_insn (gen_rtx_SET (temp, gen_rtx_PLUS (Pmode, op0, temp)));
2320 return gen_rtx_LO_SUM (Pmode, temp, copy_rtx (op1));
2321}
2322
df8ceba6
SL
2323/* Given a MEM OP with an address that includes a splittable symbol or
2324 other large constant, emit some instructions to do the split and
2325 return a new MEM. */
82348675 2326rtx
df8ceba6 2327nios2_split_large_constant_memory_operand (rtx op)
82348675
SL
2328{
2329 rtx addr = XEXP (op, 0);
2330
df8ceba6 2331 if (nios2_large_constant_p (addr))
82348675 2332 addr = nios2_split_large_constant (addr, gen_reg_rtx (Pmode));
df8ceba6 2333 else if (nios2_plus_large_constant_p (addr))
82348675
SL
2334 addr = nios2_split_plus_large_constant (XEXP (addr, 0), XEXP (addr, 1));
2335 else
2336 gcc_unreachable ();
2337 return replace_equiv_address (op, addr, false);
2338}
2339
e430824f
CLT
2340/* Return true if SECTION is a small section name. */
2341static bool
2342nios2_small_section_name_p (const char *section)
2343{
2344 return (strcmp (section, ".sbss") == 0
2345 || strncmp (section, ".sbss.", 6) == 0
2346 || strcmp (section, ".sdata") == 0
de10fca0
SL
2347 || strncmp (section, ".sdata.", 7) == 0
2348 || (nios2_gprel_sec
2349 && regexec (&nios2_gprel_sec_regex, section, 0, NULL, 0) == 0));
e430824f
CLT
2350}
2351
1cef1159
SL
2352/* Return true if SECTION is a r0-relative section name. */
2353static bool
2354nios2_r0rel_section_name_p (const char *section)
2355{
2356 return (nios2_r0rel_sec
2357 && regexec (&nios2_r0rel_sec_regex, section, 0, NULL, 0) == 0);
2358}
2359
e430824f
CLT
2360/* Return true if EXP should be placed in the small data section. */
2361static bool
2362nios2_in_small_data_p (const_tree exp)
2363{
2364 /* We want to merge strings, so we never consider them small data. */
2365 if (TREE_CODE (exp) == STRING_CST)
2366 return false;
2367
2368 if (TREE_CODE (exp) == VAR_DECL)
2369 {
2370 if (DECL_SECTION_NAME (exp))
2371 {
f961457f 2372 const char *section = DECL_SECTION_NAME (exp);
56314783 2373 if (nios2_small_section_name_p (section))
e430824f
CLT
2374 return true;
2375 }
2376 else
2377 {
2378 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
2379
2380 /* If this is an incomplete type with size 0, then we can't put it
2381 in sdata because it might be too big when completed. */
2382 if (size > 0
2383 && (unsigned HOST_WIDE_INT) size <= nios2_section_threshold)
2384 return true;
2385 }
2386 }
2387
2388 return false;
2389}
2390
2391/* Return true if symbol is in small data section. */
2392
7dcc7195 2393static bool
e430824f
CLT
2394nios2_symbol_ref_in_small_data_p (rtx sym)
2395{
56314783
SL
2396 tree decl;
2397
e430824f 2398 gcc_assert (GET_CODE (sym) == SYMBOL_REF);
56314783
SL
2399 decl = SYMBOL_REF_DECL (sym);
2400
2401 /* TLS variables are not accessed through the GP. */
2402 if (SYMBOL_REF_TLS_MODEL (sym) != 0)
2403 return false;
2404
42e6ab74
SL
2405 /* On Nios II R2, there is no GP-relative relocation that can be
2406 used with "io" instructions. So, if we are implicitly generating
2407 those instructions, we cannot emit GP-relative accesses. */
2408 if (TARGET_ARCH_R2
2409 && (TARGET_BYPASS_CACHE || TARGET_BYPASS_CACHE_VOLATILE))
2410 return false;
2411
56314783
SL
2412 /* If the user has explicitly placed the symbol in a small data section
2413 via an attribute, generate gp-relative addressing even if the symbol
2414 is external, weak, or larger than we'd automatically put in the
2415 small data section. OTOH, if the symbol is located in some
2416 non-small-data section, we can't use gp-relative accesses on it
2417 unless the user has requested gpopt_data or gpopt_all. */
e430824f 2418
56314783
SL
2419 switch (nios2_gpopt_option)
2420 {
2421 case gpopt_none:
2422 /* Don't generate a gp-relative addressing mode if that's been
2423 disabled. */
2424 return false;
2425
2426 case gpopt_local:
2427 /* Use GP-relative addressing for small data symbols that are
ce9f2dc5
SL
2428 not external or weak or uninitialized common, plus any symbols
2429 that have explicitly been placed in a small data section. */
56314783
SL
2430 if (decl && DECL_SECTION_NAME (decl))
2431 return nios2_small_section_name_p (DECL_SECTION_NAME (decl));
2432 return (SYMBOL_REF_SMALL_P (sym)
2433 && !SYMBOL_REF_EXTERNAL_P (sym)
ce9f2dc5
SL
2434 && !(decl && DECL_WEAK (decl))
2435 && !(decl && DECL_COMMON (decl)
2436 && (DECL_INITIAL (decl) == NULL
2437 || (!in_lto_p
2438 && DECL_INITIAL (decl) == error_mark_node))));
56314783
SL
2439
2440 case gpopt_global:
2441 /* Use GP-relative addressing for small data symbols, even if
2442 they are external or weak. Note that SYMBOL_REF_SMALL_P
2443 is also true of symbols that have explicitly been placed
2444 in a small data section. */
2445 return SYMBOL_REF_SMALL_P (sym);
2446
2447 case gpopt_data:
2448 /* Use GP-relative addressing for all data symbols regardless
2449 of the object size, but not for code symbols. This option
2450 is equivalent to the user asserting that the entire data
2451 section is accessible from the GP. */
2452 return !SYMBOL_REF_FUNCTION_P (sym);
2453
2454 case gpopt_all:
2455 /* Use GP-relative addressing for everything, including code.
2456 Effectively, the user has asserted that the entire program
2457 fits within the 64K range of the GP offset. */
2458 return true;
2459
2460 default:
2461 /* We shouldn't get here. */
2462 return false;
2463 }
e430824f
CLT
2464}
2465
1cef1159
SL
2466/* Likewise for r0-relative addressing. */
2467static bool
2468nios2_symbol_ref_in_r0rel_data_p (rtx sym)
2469{
2470 tree decl;
2471
2472 gcc_assert (GET_CODE (sym) == SYMBOL_REF);
2473 decl = SYMBOL_REF_DECL (sym);
2474
2475 /* TLS variables are not accessed through r0. */
2476 if (SYMBOL_REF_TLS_MODEL (sym) != 0)
2477 return false;
2478
2479 /* On Nios II R2, there is no r0-relative relocation that can be
2480 used with "io" instructions. So, if we are implicitly generating
2481 those instructions, we cannot emit r0-relative accesses. */
2482 if (TARGET_ARCH_R2
2483 && (TARGET_BYPASS_CACHE || TARGET_BYPASS_CACHE_VOLATILE))
2484 return false;
2485
2486 /* If the user has explicitly placed the symbol in a r0rel section
2487 via an attribute, generate r0-relative addressing. */
2488 if (decl && DECL_SECTION_NAME (decl))
2489 return nios2_r0rel_section_name_p (DECL_SECTION_NAME (decl));
2490 return false;
2491}
2492
e430824f
CLT
2493/* Implement TARGET_SECTION_TYPE_FLAGS. */
2494
2495static unsigned int
2496nios2_section_type_flags (tree decl, const char *name, int reloc)
2497{
2498 unsigned int flags;
2499
2500 flags = default_section_type_flags (decl, name, reloc);
2501
2502 if (nios2_small_section_name_p (name))
2503 flags |= SECTION_SMALL;
2504
2505 return flags;
2506}
2507
95ce7613
CLT
2508/* Return true if SYMBOL_REF X binds locally. */
2509
2510static bool
2511nios2_symbol_binds_local_p (const_rtx x)
2512{
2513 return (SYMBOL_REF_DECL (x)
2514 ? targetm.binds_local_p (SYMBOL_REF_DECL (x))
2515 : SYMBOL_REF_LOCAL_P (x));
2516}
e430824f
CLT
2517
2518/* Position independent code related. */
2519
2520/* Emit code to load the PIC register. */
2521static void
2522nios2_load_pic_register (void)
2523{
2524 rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM);
2525
2526 emit_insn (gen_load_got_register (pic_offset_table_rtx, tmp));
2527 emit_insn (gen_add3_insn (pic_offset_table_rtx, pic_offset_table_rtx, tmp));
2528}
2529
2530/* Generate a PIC address as a MEM rtx. */
2531static rtx
a866d527 2532nios2_load_pic_address (rtx sym, int unspec, rtx tmp)
e430824f 2533{
95ce7613
CLT
2534 if (flag_pic == 2
2535 && GET_CODE (sym) == SYMBOL_REF
2536 && nios2_symbol_binds_local_p (sym))
2537 /* Under -fPIC, generate a GOTOFF address for local symbols. */
a866d527
CLT
2538 {
2539 rtx offset = nios2_unspec_offset (sym, UNSPEC_PIC_GOTOFF_SYM);
2540 crtl->uses_pic_offset_table = 1;
2541 return nios2_large_got_address (offset, tmp);
2542 }
95ce7613
CLT
2543
2544 return gen_const_mem (Pmode, nios2_got_address (sym, unspec));
e430824f
CLT
2545}
2546
2547/* Nonzero if the constant value X is a legitimate general operand
2548 when generating PIC code. It is given that flag_pic is on and
2549 that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
2550bool
2551nios2_legitimate_pic_operand_p (rtx x)
2552{
3bbbe009 2553 if (nios2_large_unspec_reloc_p (x))
95ce7613
CLT
2554 return true;
2555
e430824f
CLT
2556 return ! (GET_CODE (x) == SYMBOL_REF
2557 || GET_CODE (x) == LABEL_REF || GET_CODE (x) == CONST);
2558}
2559
2560/* Return TRUE if X is a thread-local symbol. */
2561static bool
2562nios2_tls_symbol_p (rtx x)
2563{
2564 return (targetm.have_tls && GET_CODE (x) == SYMBOL_REF
2565 && SYMBOL_REF_TLS_MODEL (x) != 0);
2566}
2567
2568/* Legitimize addresses that are CONSTANT_P expressions. */
2569static rtx
2570nios2_legitimize_constant_address (rtx addr)
2571{
2572 rtx base, offset;
2573 split_const (addr, &base, &offset);
2574
2575 if (nios2_tls_symbol_p (base))
2576 base = nios2_legitimize_tls_address (base);
2577 else if (flag_pic)
a866d527 2578 base = nios2_load_pic_address (base, UNSPEC_PIC_SYM, NULL_RTX);
df8ceba6 2579 else if (!nios2_large_constant_allowed ()
82348675
SL
2580 && nios2_symbolic_constant_p (addr))
2581 return nios2_split_large_constant (addr, gen_reg_rtx (Pmode));
df8ceba6
SL
2582 else if (CONST_INT_P (addr))
2583 {
2584 HOST_WIDE_INT val = INTVAL (addr);
2585 if (SMALL_INT (val))
2586 /* Use r0-relative addressing. */
2587 return addr;
2588 else if (!nios2_large_constant_allowed ())
2589 /* Split into high/lo pair. */
2590 return nios2_split_large_constant (addr, gen_reg_rtx (Pmode));
2591 }
e430824f
CLT
2592 else
2593 return addr;
2594
2595 if (offset != const0_rtx)
2596 {
2597 gcc_assert (can_create_pseudo_p ());
2598 return gen_rtx_PLUS (Pmode, force_reg (Pmode, base),
2599 (CONST_INT_P (offset)
2600 ? (SMALL_INT (INTVAL (offset))
2601 ? offset : force_reg (Pmode, offset))
2602 : offset));
2603 }
2604 return base;
2605}
2606
2607/* Implement TARGET_LEGITIMIZE_ADDRESS. */
2608static rtx
2609nios2_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
ef4bddc2 2610 machine_mode mode ATTRIBUTE_UNUSED)
e430824f 2611{
82348675
SL
2612 rtx op0, op1;
2613
e430824f
CLT
2614 if (CONSTANT_P (x))
2615 return nios2_legitimize_constant_address (x);
2616
82348675
SL
2617 /* Remaining cases all involve something + a constant. */
2618 if (GET_CODE (x) != PLUS)
2619 return x;
2620
2621 op0 = XEXP (x, 0);
2622 op1 = XEXP (x, 1);
2623
efd5897c
SL
2624 /* Target-independent code turns (exp + constant) into plain
2625 register indirect. Although subsequent optimization passes will
2626 eventually sort that out, ivopts uses the unoptimized form for
2627 computing its cost model, so we get better results by generating
2628 the correct form from the start. */
2629 if (nios2_valid_addr_offset_p (op1))
2630 return gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), copy_rtx (op1));
2631
82348675 2632 /* We may need to split symbolic constants now. */
efd5897c 2633 else if (nios2_symbolic_constant_p (op1))
82348675 2634 {
df8ceba6 2635 if (nios2_large_constant_allowed ())
82348675
SL
2636 return gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), copy_rtx (op1));
2637 else
2638 return nios2_split_plus_large_constant (op0, op1);
2639 }
2640
e430824f
CLT
2641 /* For the TLS LE (Local Exec) model, the compiler may try to
2642 combine constant offsets with unspec relocs, creating address RTXs
2643 looking like this:
2644 (plus:SI (reg:SI 23 r23)
2645 (const:SI
2646 (plus:SI
2647 (unspec:SI [(symbol_ref:SI ("var"))] UNSPEC_ADD_TLS_LE)
2648 (const_int 48 [0x30]))))
2649
2650 This usually happens when 'var' is a thread-local struct variable,
2651 and access of a field in var causes the addend.
2652
2653 We typically want this combining, so transform the above into this
2654 form, which is allowed:
2655 (plus:SI (reg:SI 23 r23)
2656 (const:SI
2657 (unspec:SI
2658 [(const:SI
2659 (plus:SI (symbol_ref:SI ("var"))
2660 (const_int 48 [0x30])))] UNSPEC_ADD_TLS_LE)))
2661
2662 Which will be output as '%tls_le(var+48)(r23)' in assembly. */
82348675 2663 else if (GET_CODE (op1) == CONST)
e430824f 2664 {
b062ae05 2665 rtx unspec, offset;
82348675 2666 split_const (op1, &unspec, &offset);
e430824f 2667 if (GET_CODE (unspec) == UNSPEC
95ce7613 2668 && !nios2_large_offset_p (XINT (unspec, 1))
e430824f
CLT
2669 && offset != const0_rtx)
2670 {
82348675 2671 rtx reg = force_reg (Pmode, op0);
e430824f
CLT
2672 unspec = copy_rtx (unspec);
2673 XVECEXP (unspec, 0, 0)
2674 = plus_constant (Pmode, XVECEXP (unspec, 0, 0), INTVAL (offset));
82348675 2675 return gen_rtx_PLUS (Pmode, reg, gen_rtx_CONST (Pmode, unspec));
e430824f
CLT
2676 }
2677 }
2678
2679 return x;
2680}
2681
98e8dd4d
CLT
2682static rtx
2683nios2_delegitimize_address (rtx x)
2684{
2685 x = delegitimize_mem_from_attrs (x);
2686
2687 if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == UNSPEC)
2688 {
2689 switch (XINT (XEXP (x, 0), 1))
2690 {
2691 case UNSPEC_PIC_SYM:
2692 case UNSPEC_PIC_CALL_SYM:
2693 case UNSPEC_PIC_GOTOFF_SYM:
2694 case UNSPEC_ADD_TLS_GD:
2695 case UNSPEC_ADD_TLS_LDM:
2696 case UNSPEC_LOAD_TLS_IE:
2697 case UNSPEC_ADD_TLS_LE:
2698 x = XVECEXP (XEXP (x, 0), 0, 0);
030b9d90 2699 gcc_assert (CONSTANT_P (x));
98e8dd4d
CLT
2700 break;
2701 }
2702 }
2703 return x;
2704}
2705
e430824f 2706/* Main expander function for RTL moves. */
9d07490f 2707bool
ef4bddc2 2708nios2_emit_move_sequence (rtx *operands, machine_mode mode)
e430824f
CLT
2709{
2710 rtx to = operands[0];
2711 rtx from = operands[1];
2712
2713 if (!register_operand (to, mode) && !reg_or_0_operand (from, mode))
2714 {
2715 gcc_assert (can_create_pseudo_p ());
2716 from = copy_to_mode_reg (mode, from);
2717 }
2718
3bbbe009
SL
2719 if (CONSTANT_P (from))
2720 {
2721 if (CONST_INT_P (from))
2722 {
2723 if (!SMALL_INT (INTVAL (from))
2724 && !SMALL_INT_UNSIGNED (INTVAL (from))
2725 && !UPPER16_INT (INTVAL (from)))
2726 {
2727 HOST_WIDE_INT high = (INTVAL (from) + 0x8000) & ~0xffff;
2728 HOST_WIDE_INT low = INTVAL (from) & 0xffff;
2729 emit_move_insn (to, gen_int_mode (high, SImode));
2730 emit_insn (gen_add2_insn (to, gen_int_mode (low, HImode)));
2731 set_unique_reg_note (get_last_insn (), REG_EQUAL,
2732 copy_rtx (from));
2733 return true;
2734 }
2735 }
1cef1159
SL
2736 else if (gprel_constant_p (from) || r0rel_constant_p (from))
2737 /* Handled directly by movsi_internal as gp + offset
2738 or r0 + offset. */
82348675
SL
2739 ;
2740 else if (nios2_large_constant_p (from))
2741 /* This case covers either a regular symbol reference or an UNSPEC
2742 representing a 32-bit offset. We split the former
2743 only conditionally and the latter always. */
3bbbe009 2744 {
df8ceba6 2745 if (!nios2_large_constant_allowed ()
82348675
SL
2746 || nios2_large_unspec_reloc_p (from))
2747 {
2748 rtx lo = nios2_split_large_constant (from, to);
2749 emit_insn (gen_rtx_SET (to, lo));
2750 set_unique_reg_note (get_last_insn (), REG_EQUAL,
2751 copy_rtx (operands[1]));
2752 return true;
2753 }
2754 }
2755 else
2756 /* This is a TLS or PIC symbol. */
2757 {
2758 from = nios2_legitimize_constant_address (from);
3bbbe009
SL
2759 if (CONSTANT_P (from))
2760 {
1cf4526c
SL
2761 emit_insn (gen_rtx_SET (to,
2762 gen_rtx_HIGH (Pmode, copy_rtx (from))));
3bbbe009
SL
2763 emit_insn (gen_rtx_SET (to, gen_rtx_LO_SUM (Pmode, to, from)));
2764 set_unique_reg_note (get_last_insn (), REG_EQUAL,
2765 copy_rtx (operands[1]));
2766 return true;
2767 }
2768 }
2769 }
e430824f
CLT
2770
2771 operands[0] = to;
2772 operands[1] = from;
9d07490f 2773 return false;
e430824f
CLT
2774}
2775
2776/* The function with address *ADDR is being called. If the address
2777 needs to be loaded from the GOT, emit the instruction to do so and
a866d527
CLT
2778 update *ADDR to point to the rtx for the loaded value.
2779 If REG != NULL_RTX, it is used as the target/scratch register in the
2780 GOT address calculation. */
e430824f 2781void
a866d527 2782nios2_adjust_call_address (rtx *call_op, rtx reg)
e430824f 2783{
a866d527
CLT
2784 if (MEM_P (*call_op))
2785 call_op = &XEXP (*call_op, 0);
2786
2787 rtx addr = *call_op;
e430824f
CLT
2788 if (flag_pic && CONSTANT_P (addr))
2789 {
a866d527
CLT
2790 rtx tmp = reg ? reg : NULL_RTX;
2791 if (!reg)
2792 reg = gen_reg_rtx (Pmode);
2793 addr = nios2_load_pic_address (addr, UNSPEC_PIC_CALL_SYM, tmp);
f7df4a84 2794 emit_insn (gen_rtx_SET (reg, addr));
a866d527 2795 *call_op = reg;
e430824f
CLT
2796 }
2797}
2798
2799\f
2800/* Output assembly language related definitions. */
2801
3bbbe009
SL
2802/* Implement TARGET_PRINT_OPERAND_PUNCT_VALID_P. */
2803static bool
2804nios2_print_operand_punct_valid_p (unsigned char code)
2805{
2806 return (code == '.' || code == '!');
2807}
2808
2809
e430824f
CLT
2810/* Print the operand OP to file stream FILE modified by LETTER.
2811 LETTER can be one of:
2812
3bbbe009
SL
2813 i: print i/hi/ui suffixes (used for mov instruction variants),
2814 when OP is the appropriate immediate operand.
2815
2816 u: like 'i', except without "ui" suffix case (used for cmpgeu/cmpltu)
2817
2818 o: print "io" if OP needs volatile access (due to TARGET_BYPASS_CACHE
2819 or TARGET_BYPASS_CACHE_VOLATILE).
2820
2821 x: print i/hi/ci/chi suffixes for the and instruction,
2822 when OP is the appropriate immediate operand.
2823
2824 z: prints the third register immediate operand in assembly
2825 instructions. Outputs const0_rtx as the 'zero' register
2826 instead of '0'.
2827
2828 y: same as 'z', but for specifically for logical instructions,
2829 where the processing for immediates are slightly different.
2830
e430824f
CLT
2831 H: for %hiadj
2832 L: for %lo
e430824f
CLT
2833 D: for the upper 32-bits of a 64-bit double value
2834 R: prints reverse condition.
3bbbe009
SL
2835 A: prints (reg) operand for ld[s]ex and st[s]ex.
2836
2837 .: print .n suffix for 16-bit instructions.
2838 !: print r.n suffix for 16-bit instructions. Used for jmpr.n.
e430824f
CLT
2839*/
2840static void
2841nios2_print_operand (FILE *file, rtx op, int letter)
2842{
2843
3bbbe009
SL
2844 /* First take care of the format letters that just insert a string
2845 into the output stream. */
e430824f
CLT
2846 switch (letter)
2847 {
3bbbe009
SL
2848 case '.':
2849 if (current_output_insn && get_attr_length (current_output_insn) == 2)
2850 fprintf (file, ".n");
2851 return;
2852
2853 case '!':
2854 if (current_output_insn && get_attr_length (current_output_insn) == 2)
2855 fprintf (file, "r.n");
2856 return;
2857
2858 case 'x':
2859 if (CONST_INT_P (op))
2860 {
2861 HOST_WIDE_INT val = INTVAL (op);
2862 HOST_WIDE_INT low = val & 0xffff;
2863 HOST_WIDE_INT high = (val >> 16) & 0xffff;
2864
2865 if (val != 0)
2866 {
2867 if (high != 0)
2868 {
2869 if (low != 0)
2870 {
2871 gcc_assert (TARGET_ARCH_R2);
2872 if (high == 0xffff)
2873 fprintf (file, "c");
2874 else if (low == 0xffff)
2875 fprintf (file, "ch");
2876 else
2877 gcc_unreachable ();
2878 }
2879 else
2880 fprintf (file, "h");
2881 }
2882 fprintf (file, "i");
2883 }
2884 }
2885 return;
2886
2887 case 'u':
e430824f 2888 case 'i':
3bbbe009
SL
2889 if (CONST_INT_P (op))
2890 {
2891 HOST_WIDE_INT val = INTVAL (op);
2892 HOST_WIDE_INT low = val & 0xffff;
2893 HOST_WIDE_INT high = (val >> 16) & 0xffff;
2894 if (val != 0)
2895 {
2896 if (low == 0 && high != 0)
2897 fprintf (file, "h");
2898 else if (high == 0 && (low & 0x8000) != 0 && letter != 'u')
2899 fprintf (file, "u");
2900 }
2901 }
e430824f
CLT
2902 if (CONSTANT_P (op) && op != const0_rtx)
2903 fprintf (file, "i");
2904 return;
2905
2906 case 'o':
2907 if (GET_CODE (op) == MEM
2908 && ((MEM_VOLATILE_P (op) && TARGET_BYPASS_CACHE_VOLATILE)
2909 || TARGET_BYPASS_CACHE))
3bbbe009
SL
2910 {
2911 gcc_assert (current_output_insn
2912 && get_attr_length (current_output_insn) == 4);
2913 fprintf (file, "io");
2914 }
e430824f
CLT
2915 return;
2916
2917 default:
2918 break;
2919 }
2920
3bbbe009 2921 /* Handle comparison operator names. */
e430824f
CLT
2922 if (comparison_operator (op, VOIDmode))
2923 {
2924 enum rtx_code cond = GET_CODE (op);
2925 if (letter == 0)
2926 {
2927 fprintf (file, "%s", GET_RTX_NAME (cond));
2928 return;
2929 }
2930 if (letter == 'R')
2931 {
2932 fprintf (file, "%s", GET_RTX_NAME (reverse_condition (cond)));
2933 return;
2934 }
2935 }
2936
3bbbe009 2937 /* Now handle the cases where we actually need to format an operand. */
e430824f
CLT
2938 switch (GET_CODE (op))
2939 {
2940 case REG:
3bbbe009 2941 if (letter == 0 || letter == 'z' || letter == 'y')
e430824f
CLT
2942 {
2943 fprintf (file, "%s", reg_names[REGNO (op)]);
2944 return;
2945 }
2946 else if (letter == 'D')
2947 {
2948 fprintf (file, "%s", reg_names[REGNO (op)+1]);
2949 return;
2950 }
2951 break;
2952
2953 case CONST_INT:
3bbbe009
SL
2954 {
2955 rtx int_rtx = op;
2956 HOST_WIDE_INT val = INTVAL (int_rtx);
2957 HOST_WIDE_INT low = val & 0xffff;
2958 HOST_WIDE_INT high = (val >> 16) & 0xffff;
2959
2960 if (letter == 'y')
2961 {
2962 if (val == 0)
2963 fprintf (file, "zero");
2964 else
2965 {
2966 if (high != 0)
2967 {
2968 if (low != 0)
2969 {
2970 gcc_assert (TARGET_ARCH_R2);
2971 if (high == 0xffff)
2972 /* andci. */
2973 int_rtx = gen_int_mode (low, SImode);
2974 else if (low == 0xffff)
2975 /* andchi. */
2976 int_rtx = gen_int_mode (high, SImode);
2977 else
2978 gcc_unreachable ();
2979 }
2980 else
2981 /* andhi. */
2982 int_rtx = gen_int_mode (high, SImode);
2983 }
2984 else
2985 /* andi. */
2986 int_rtx = gen_int_mode (low, SImode);
2987 output_addr_const (file, int_rtx);
2988 }
2989 return;
2990 }
2991 else if (letter == 'z')
2992 {
2993 if (val == 0)
2994 fprintf (file, "zero");
2995 else
2996 {
2997 if (low == 0 && high != 0)
2998 int_rtx = gen_int_mode (high, SImode);
2999 else if (low != 0)
3000 {
3001 gcc_assert (high == 0 || high == 0xffff);
3002 int_rtx = gen_int_mode (low, high == 0 ? SImode : HImode);
3003 }
3004 else
3005 gcc_unreachable ();
3006 output_addr_const (file, int_rtx);
3007 }
3008 return;
3009 }
3010 }
e430824f 3011
e430824f
CLT
3012 /* Else, fall through. */
3013
3014 case CONST:
3015 case LABEL_REF:
3016 case SYMBOL_REF:
3017 case CONST_DOUBLE:
3018 if (letter == 0 || letter == 'z')
3019 {
3020 output_addr_const (file, op);
3021 return;
3022 }
95ce7613
CLT
3023 else if (letter == 'H' || letter == 'L')
3024 {
3025 fprintf (file, "%%");
3026 if (GET_CODE (op) == CONST
3027 && GET_CODE (XEXP (op, 0)) == UNSPEC)
3028 {
3029 rtx unspec = XEXP (op, 0);
3030 int unspec_reloc = XINT (unspec, 1);
3031 gcc_assert (nios2_large_offset_p (unspec_reloc));
3032 fprintf (file, "%s_", nios2_unspec_reloc_name (unspec_reloc));
3033 op = XVECEXP (unspec, 0, 0);
3034 }
3035 fprintf (file, letter == 'H' ? "hiadj(" : "lo(");
e430824f
CLT
3036 output_addr_const (file, op);
3037 fprintf (file, ")");
3038 return;
95ce7613 3039 }
e430824f
CLT
3040 break;
3041
3042 case SUBREG:
3043 case MEM:
3bbbe009
SL
3044 if (letter == 'A')
3045 {
3046 /* Address of '(reg)' form, with no index. */
3047 fprintf (file, "(%s)", reg_names[REGNO (XEXP (op, 0))]);
3048 return;
3049 }
e430824f
CLT
3050 if (letter == 0)
3051 {
cc8ca59e 3052 output_address (VOIDmode, op);
e430824f
CLT
3053 return;
3054 }
3055 break;
3056
3057 case CODE_LABEL:
3058 if (letter == 0)
3059 {
3060 output_addr_const (file, op);
3061 return;
3062 }
3063 break;
3064
3065 default:
3066 break;
3067 }
3068
82348675 3069 debug_rtx (op);
e430824f
CLT
3070 output_operand_lossage ("Unsupported operand for code '%c'", letter);
3071 gcc_unreachable ();
3072}
3073
3074/* Return true if this is a GP-relative accessible reference. */
7dcc7195 3075bool
e430824f
CLT
3076gprel_constant_p (rtx op)
3077{
3078 if (GET_CODE (op) == SYMBOL_REF
3079 && nios2_symbol_ref_in_small_data_p (op))
3080 return true;
3081 else if (GET_CODE (op) == CONST
3082 && GET_CODE (XEXP (op, 0)) == PLUS)
3083 return gprel_constant_p (XEXP (XEXP (op, 0), 0));
3084
3085 return false;
3086}
3087
1cef1159
SL
3088/* Likewise if this is a zero-relative accessible reference. */
3089bool
3090r0rel_constant_p (rtx op)
3091{
3092 if (GET_CODE (op) == SYMBOL_REF
3093 && nios2_symbol_ref_in_r0rel_data_p (op))
3094 return true;
3095 else if (GET_CODE (op) == CONST
3096 && GET_CODE (XEXP (op, 0)) == PLUS)
3097 return r0rel_constant_p (XEXP (XEXP (op, 0), 0));
df8ceba6
SL
3098 else if (GET_CODE (op) == CONST_INT
3099 && SMALL_INT (INTVAL (op)))
3100 return true;
1cef1159
SL
3101
3102 return false;
3103}
3104
e430824f
CLT
3105/* Return the name string for a supported unspec reloc offset. */
3106static const char *
3107nios2_unspec_reloc_name (int unspec)
3108{
3109 switch (unspec)
3110 {
3111 case UNSPEC_PIC_SYM:
3112 return "got";
3113 case UNSPEC_PIC_CALL_SYM:
3114 return "call";
95ce7613
CLT
3115 case UNSPEC_PIC_GOTOFF_SYM:
3116 return "gotoff";
e430824f
CLT
3117 case UNSPEC_LOAD_TLS_IE:
3118 return "tls_ie";
3119 case UNSPEC_ADD_TLS_LE:
3120 return "tls_le";
3121 case UNSPEC_ADD_TLS_GD:
3122 return "tls_gd";
3123 case UNSPEC_ADD_TLS_LDM:
3124 return "tls_ldm";
3125 case UNSPEC_ADD_TLS_LDO:
3126 return "tls_ldo";
3127 default:
3128 return NULL;
3129 }
3130}
3131
e430824f
CLT
3132/* Implement TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */
3133static bool
3134nios2_output_addr_const_extra (FILE *file, rtx op)
3135{
3136 const char *name;
3137 gcc_assert (GET_CODE (op) == UNSPEC);
3138
3139 /* Support for printing out const unspec relocations. */
3140 name = nios2_unspec_reloc_name (XINT (op, 1));
3141 if (name)
3142 {
3143 fprintf (file, "%%%s(", name);
3144 output_addr_const (file, XVECEXP (op, 0, 0));
3145 fprintf (file, ")");
3146 return true;
3147 }
3148 return false;
3149}
3150
3151/* Implement TARGET_PRINT_OPERAND_ADDRESS. */
3152static void
cc8ca59e 3153nios2_print_operand_address (FILE *file, machine_mode mode, rtx op)
e430824f
CLT
3154{
3155 switch (GET_CODE (op))
3156 {
3157 case CONST:
3158 case CONST_INT:
3159 case LABEL_REF:
3160 case CONST_DOUBLE:
3161 case SYMBOL_REF:
3162 if (gprel_constant_p (op))
3163 {
3164 fprintf (file, "%%gprel(");
3165 output_addr_const (file, op);
3166 fprintf (file, ")(%s)", reg_names[GP_REGNO]);
3167 return;
3168 }
1cef1159
SL
3169 else if (r0rel_constant_p (op))
3170 {
df8ceba6
SL
3171 if (CONST_INT_P (op))
3172 {
3173 output_addr_const (file, op);
3174 fprintf (file, "(r0)");
3175 return;
3176 }
3177 else
3178 {
3179 fprintf (file, "%%lo(");
3180 output_addr_const (file, op);
3181 fprintf (file, ")(r0)");
3182 return;
3183 }
3184 }
e430824f
CLT
3185 break;
3186
3187 case PLUS:
3188 {
3189 rtx op0 = XEXP (op, 0);
3190 rtx op1 = XEXP (op, 1);
3191
3192 if (REG_P (op0) && CONSTANT_P (op1))
3193 {
3194 output_addr_const (file, op1);
3195 fprintf (file, "(%s)", reg_names[REGNO (op0)]);
3196 return;
3197 }
3198 else if (REG_P (op1) && CONSTANT_P (op0))
3199 {
3200 output_addr_const (file, op0);
3201 fprintf (file, "(%s)", reg_names[REGNO (op1)]);
3202 return;
3203 }
3204 }
3205 break;
3206
82348675
SL
3207 case LO_SUM:
3208 {
3209 rtx op0 = XEXP (op, 0);
3210 rtx op1 = XEXP (op, 1);
3211
3212 if (REG_P (op0) && CONSTANT_P (op1))
3213 {
3214 nios2_print_operand (file, op1, 'L');
3215 fprintf (file, "(%s)", reg_names[REGNO (op0)]);
3216 return;
3217 }
3218 }
3219 break;
3220
e430824f
CLT
3221 case REG:
3222 fprintf (file, "0(%s)", reg_names[REGNO (op)]);
3223 return;
3224
3225 case MEM:
3226 {
3227 rtx base = XEXP (op, 0);
cc8ca59e 3228 nios2_print_operand_address (file, mode, base);
e430824f
CLT
3229 return;
3230 }
3231 default:
3232 break;
3233 }
3234
3235 fprintf (stderr, "Missing way to print address\n");
3236 debug_rtx (op);
3237 gcc_unreachable ();
3238}
3239
3240/* Implement TARGET_ASM_OUTPUT_DWARF_DTPREL. */
3241static void
3242nios2_output_dwarf_dtprel (FILE *file, int size, rtx x)
3243{
3244 gcc_assert (size == 4);
3245 fprintf (file, "\t.4byte\t%%tls_ldo(");
3246 output_addr_const (file, x);
3247 fprintf (file, ")");
3248}
3249
a9ce4e4a
CLT
3250/* Implemet TARGET_ASM_FILE_END. */
3251
3252static void
3253nios2_asm_file_end (void)
3254{
3255 /* The Nios II Linux stack is mapped non-executable by default, so add a
3256 .note.GNU-stack section for switching to executable stacks only when
3257 trampolines are generated. */
3258 if (TARGET_LINUX_ABI && trampolines_created)
3259 file_end_indicate_exec_stack ();
3260}
3261
e430824f
CLT
3262/* Implement TARGET_ASM_FUNCTION_PROLOGUE. */
3263static void
42776416 3264nios2_asm_function_prologue (FILE *file)
e430824f
CLT
3265{
3266 if (flag_verbose_asm || flag_debug_asm)
3267 {
3268 nios2_compute_frame_layout ();
3269 nios2_dump_frame_layout (file);
3270 }
3271}
3272
3273/* Emit assembly of custom FPU instructions. */
3274const char *
3275nios2_fpu_insn_asm (enum n2fpu_code code)
3276{
3277 static char buf[256];
3278 const char *op1, *op2, *op3;
3279 int ln = 256, n = 0;
3280
3281 int N = N2FPU_N (code);
3282 int num_operands = N2FPU (code).num_operands;
3283 const char *insn_name = N2FPU_NAME (code);
3284 tree ftype = nios2_ftype (N2FPU_FTCODE (code));
ef4bddc2
RS
3285 machine_mode dst_mode = TYPE_MODE (TREE_TYPE (ftype));
3286 machine_mode src_mode = TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (ftype)));
e430824f
CLT
3287
3288 /* Prepare X register for DF input operands. */
3289 if (GET_MODE_SIZE (src_mode) == 8 && num_operands == 3)
3290 n = snprintf (buf, ln, "custom\t%d, zero, %%1, %%D1 # fwrx %%1\n\t",
3291 N2FPU_N (n2fpu_fwrx));
3292
3293 if (src_mode == SFmode)
3294 {
3295 if (dst_mode == VOIDmode)
3296 {
3297 /* The fwry case. */
3298 op1 = op3 = "zero";
3299 op2 = "%0";
3300 num_operands -= 1;
3301 }
3302 else
3303 {
aad8816f
SZ
3304 op1 = (dst_mode == DFmode ? "%D0" : "%0");
3305 op2 = "%1";
e430824f
CLT
3306 op3 = (num_operands == 2 ? "zero" : "%2");
3307 }
3308 }
3309 else if (src_mode == DFmode)
3310 {
3311 if (dst_mode == VOIDmode)
3312 {
3313 /* The fwrx case. */
3314 op1 = "zero";
3315 op2 = "%0";
3316 op3 = "%D0";
3317 num_operands -= 1;
3318 }
3319 else
3320 {
3321 op1 = (dst_mode == DFmode ? "%D0" : "%0");
3322 op2 = (num_operands == 2 ? "%1" : "%2");
3323 op3 = (num_operands == 2 ? "%D1" : "%D2");
3324 }
3325 }
3326 else if (src_mode == VOIDmode)
3327 {
3328 /* frdxlo, frdxhi, frdy cases. */
3329 gcc_assert (dst_mode == SFmode);
3330 op1 = "%0";
3331 op2 = op3 = "zero";
3332 }
3333 else if (src_mode == SImode)
3334 {
3335 /* Conversion operators. */
3336 gcc_assert (num_operands == 2);
3337 op1 = (dst_mode == DFmode ? "%D0" : "%0");
3338 op2 = "%1";
3339 op3 = "zero";
3340 }
3341 else
3342 gcc_unreachable ();
3343
3344 /* Main instruction string. */
3345 n += snprintf (buf + n, ln - n, "custom\t%d, %s, %s, %s # %s %%0%s%s",
3346 N, op1, op2, op3, insn_name,
3347 (num_operands >= 2 ? ", %1" : ""),
3348 (num_operands == 3 ? ", %2" : ""));
3349
3350 /* Extraction of Y register for DF results. */
3351 if (dst_mode == DFmode)
3352 snprintf (buf + n, ln - n, "\n\tcustom\t%d, %%0, zero, zero # frdy %%0",
3353 N2FPU_N (n2fpu_frdy));
3354 return buf;
3355}
3356
3357\f
3358
3359/* Function argument related. */
3360
3361/* Define where to put the arguments to a function. Value is zero to
3362 push the argument on the stack, or a hard register in which to
3363 store the argument.
3364
e430824f
CLT
3365 CUM is a variable of type CUMULATIVE_ARGS which gives info about
3366 the preceding args and about the function being called.
6783fdb7 3367 ARG is a description of the argument. */
e430824f
CLT
3368
3369static rtx
6783fdb7 3370nios2_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
e430824f
CLT
3371{
3372 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
3373 rtx return_rtx = NULL_RTX;
3374
3375 if (cum->regs_used < NUM_ARG_REGS)
6783fdb7 3376 return_rtx = gen_rtx_REG (arg.mode, FIRST_ARG_REGNO + cum->regs_used);
e430824f
CLT
3377
3378 return return_rtx;
3379}
3380
3381/* Return number of bytes, at the beginning of the argument, that must be
3382 put in registers. 0 is the argument is entirely in registers or entirely
3383 in memory. */
3384
3385static int
a7c81bc1 3386nios2_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
e430824f
CLT
3387{
3388 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
a7c81bc1
RS
3389 HOST_WIDE_INT param_size = arg.promoted_size_in_bytes ();
3390 gcc_assert (param_size >= 0);
e430824f
CLT
3391
3392 /* Convert to words (round up). */
3393 param_size = (UNITS_PER_WORD - 1 + param_size) / UNITS_PER_WORD;
3394
3395 if (cum->regs_used < NUM_ARG_REGS
3396 && cum->regs_used + param_size > NUM_ARG_REGS)
3397 return (NUM_ARG_REGS - cum->regs_used) * UNITS_PER_WORD;
3398
3399 return 0;
3400}
3401
3402/* Update the data in CUM to advance over an argument of mode MODE
3403 and data type TYPE; TYPE is null for libcalls where that information
3404 may not be available. */
3405
3406static void
ef4bddc2 3407nios2_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
e430824f
CLT
3408 const_tree type ATTRIBUTE_UNUSED,
3409 bool named ATTRIBUTE_UNUSED)
3410{
3411 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
3412 HOST_WIDE_INT param_size;
3413
3414 if (mode == BLKmode)
3415 {
3416 param_size = int_size_in_bytes (type);
3417 gcc_assert (param_size >= 0);
3418 }
3419 else
3420 param_size = GET_MODE_SIZE (mode);
3421
3422 /* Convert to words (round up). */
3423 param_size = (UNITS_PER_WORD - 1 + param_size) / UNITS_PER_WORD;
3424
3425 if (cum->regs_used + param_size > NUM_ARG_REGS)
3426 cum->regs_used = NUM_ARG_REGS;
3427 else
3428 cum->regs_used += param_size;
3429}
3430
76b0cbf8 3431static pad_direction
ef4bddc2 3432nios2_function_arg_padding (machine_mode mode, const_tree type)
e430824f
CLT
3433{
3434 /* On little-endian targets, the first byte of every stack argument
3435 is passed in the first byte of the stack slot. */
3436 if (!BYTES_BIG_ENDIAN)
76b0cbf8 3437 return PAD_UPWARD;
e430824f
CLT
3438
3439 /* Otherwise, integral types are padded downward: the last byte of a
3440 stack argument is passed in the last byte of the stack slot. */
3441 if (type != 0
3442 ? INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)
3443 : GET_MODE_CLASS (mode) == MODE_INT)
76b0cbf8 3444 return PAD_DOWNWARD;
e430824f
CLT
3445
3446 /* Arguments smaller than a stack slot are padded downward. */
3447 if (mode != BLKmode)
76b0cbf8
RS
3448 return (GET_MODE_BITSIZE (mode) >= PARM_BOUNDARY
3449 ? PAD_UPWARD : PAD_DOWNWARD);
e430824f
CLT
3450
3451 return ((int_size_in_bytes (type) >= (PARM_BOUNDARY / BITS_PER_UNIT))
76b0cbf8 3452 ? PAD_UPWARD : PAD_DOWNWARD);
e430824f
CLT
3453}
3454
76b0cbf8 3455pad_direction
ef4bddc2 3456nios2_block_reg_padding (machine_mode mode, tree type,
e430824f
CLT
3457 int first ATTRIBUTE_UNUSED)
3458{
3459 return nios2_function_arg_padding (mode, type);
3460}
3461
3462/* Emit RTL insns to initialize the variable parts of a trampoline.
3463 FNADDR is an RTX for the address of the function's pure code.
3464 CXT is an RTX for the static chain value for the function.
3465 On Nios II, we handle this by a library call. */
3466static void
3467nios2_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
3468{
3469 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
3470 rtx ctx_reg = force_reg (Pmode, cxt);
3471 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
3472
3473 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
db69559b 3474 LCT_NORMAL, VOIDmode, addr, Pmode, fnaddr, Pmode,
e430824f
CLT
3475 ctx_reg, Pmode);
3476}
3477
3478/* Implement TARGET_FUNCTION_VALUE. */
3479static rtx
3480nios2_function_value (const_tree ret_type, const_tree fn ATTRIBUTE_UNUSED,
3481 bool outgoing ATTRIBUTE_UNUSED)
3482{
3483 return gen_rtx_REG (TYPE_MODE (ret_type), FIRST_RETVAL_REGNO);
3484}
3485
3486/* Implement TARGET_LIBCALL_VALUE. */
3487static rtx
ef4bddc2 3488nios2_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
e430824f
CLT
3489{
3490 return gen_rtx_REG (mode, FIRST_RETVAL_REGNO);
3491}
3492
3493/* Implement TARGET_FUNCTION_VALUE_REGNO_P. */
3494static bool
3495nios2_function_value_regno_p (const unsigned int regno)
3496{
3497 return regno == FIRST_RETVAL_REGNO;
3498}
3499
3500/* Implement TARGET_RETURN_IN_MEMORY. */
3501static bool
3502nios2_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
3503{
3504 return (int_size_in_bytes (type) > (2 * UNITS_PER_WORD)
3505 || int_size_in_bytes (type) == -1);
3506}
3507
3508/* TODO: It may be possible to eliminate the copyback and implement
3509 own va_arg type. */
3510static void
3511nios2_setup_incoming_varargs (cumulative_args_t cum_v,
e7056ca4
RS
3512 const function_arg_info &arg,
3513 int *pretend_size, int second_time)
e430824f
CLT
3514{
3515 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
3516 CUMULATIVE_ARGS local_cum;
3517 cumulative_args_t local_cum_v = pack_cumulative_args (&local_cum);
3518 int regs_to_push;
3519 int pret_size;
3520
c3ff2812 3521 cfun->machine->uses_anonymous_args = 1;
e430824f 3522 local_cum = *cum;
e7056ca4 3523 nios2_function_arg_advance (local_cum_v, arg.mode, arg.type, arg.named);
e430824f
CLT
3524
3525 regs_to_push = NUM_ARG_REGS - local_cum.regs_used;
3526
c3ff2812
SL
3527 /* If we can use CDX stwm to push the arguments on the stack,
3528 nios2_expand_prologue will do that instead. */
3529 if (!TARGET_HAS_CDX && !second_time && regs_to_push > 0)
e430824f
CLT
3530 {
3531 rtx ptr = virtual_incoming_args_rtx;
3532 rtx mem = gen_rtx_MEM (BLKmode, ptr);
3533 emit_insn (gen_blockage ());
3534 move_block_from_reg (local_cum.regs_used + FIRST_ARG_REGNO, mem,
3535 regs_to_push);
3536 emit_insn (gen_blockage ());
3537 }
3538
3539 pret_size = regs_to_push * UNITS_PER_WORD;
3540 if (pret_size)
3541 *pretend_size = pret_size;
3542}
3543
3544\f
3545
3546/* Init FPU builtins. */
3547static void
3548nios2_init_fpu_builtins (int start_code)
3549{
3550 tree fndecl;
3551 char builtin_name[64] = "__builtin_custom_";
3552 unsigned int i, n = strlen ("__builtin_custom_");
3553
3554 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
3555 {
3556 snprintf (builtin_name + n, sizeof (builtin_name) - n,
3557 "%s", N2FPU_NAME (i));
3558 fndecl =
3559 add_builtin_function (builtin_name, nios2_ftype (N2FPU_FTCODE (i)),
3560 start_code + i, BUILT_IN_MD, NULL, NULL_TREE);
3561 nios2_register_builtin_fndecl (start_code + i, fndecl);
3562 }
3563}
3564
3565/* Helper function for expanding FPU builtins. */
3566static rtx
3567nios2_expand_fpu_builtin (tree exp, unsigned int code, rtx target)
3568{
3569 struct expand_operand ops[MAX_RECOG_OPERANDS];
3570 enum insn_code icode = N2FPU_ICODE (code);
3571 int nargs, argno, opno = 0;
3572 int num_operands = N2FPU (code).num_operands;
ef4bddc2 3573 machine_mode dst_mode = TYPE_MODE (TREE_TYPE (exp));
e430824f
CLT
3574 bool has_target_p = (dst_mode != VOIDmode);
3575
3576 if (N2FPU_N (code) < 0)
40fecdd6
JM
3577 fatal_error (input_location,
3578 "Cannot call %<__builtin_custom_%s%> without specifying switch"
e430824f
CLT
3579 " %<-mcustom-%s%>", N2FPU_NAME (code), N2FPU_NAME (code));
3580 if (has_target_p)
3581 create_output_operand (&ops[opno++], target, dst_mode);
3582 else
3583 /* Subtract away the count of the VOID return, mainly for fwrx/fwry. */
3584 num_operands -= 1;
3585 nargs = call_expr_nargs (exp);
3586 for (argno = 0; argno < nargs; argno++)
3587 {
3588 tree arg = CALL_EXPR_ARG (exp, argno);
3589 create_input_operand (&ops[opno++], expand_normal (arg),
3590 TYPE_MODE (TREE_TYPE (arg)));
3591 }
3592 if (!maybe_expand_insn (icode, num_operands, ops))
3593 {
3594 error ("invalid argument to built-in function");
3595 return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx;
3596 }
3597 return has_target_p ? ops[0].value : const0_rtx;
3598}
3599
3600/* Nios II has custom instruction built-in functions of the forms:
3601 __builtin_custom_n
3602 __builtin_custom_nX
3603 __builtin_custom_nXX
3604 __builtin_custom_Xn
3605 __builtin_custom_XnX
3606 __builtin_custom_XnXX
3607
3608 where each X could be either 'i' (int), 'f' (float), or 'p' (void*).
3609 Therefore with 0-1 return values, and 0-2 arguments, we have a
3610 total of (3 + 1) * (1 + 3 + 9) == 52 custom builtin functions.
3611*/
3612#define NUM_CUSTOM_BUILTINS ((3 + 1) * (1 + 3 + 9))
3613static char custom_builtin_name[NUM_CUSTOM_BUILTINS][5];
3614
3615static void
3616nios2_init_custom_builtins (int start_code)
3617{
3618 tree builtin_ftype, ret_type, fndecl;
3619 char builtin_name[32] = "__builtin_custom_";
3620 int n = strlen ("__builtin_custom_");
3621 int builtin_code = 0;
3622 int lhs, rhs1, rhs2;
3623
3624 struct { tree type; const char *c; } op[4];
3625 /* z */ op[0].c = ""; op[0].type = NULL_TREE;
3626 /* f */ op[1].c = "f"; op[1].type = float_type_node;
3627 /* i */ op[2].c = "i"; op[2].type = integer_type_node;
3628 /* p */ op[3].c = "p"; op[3].type = ptr_type_node;
3629
3630 /* We enumerate through the possible operand types to create all the
3631 __builtin_custom_XnXX function tree types. Note that these may slightly
3632 overlap with the function types created for other fixed builtins. */
3633
3634 for (lhs = 0; lhs < 4; lhs++)
3635 for (rhs1 = 0; rhs1 < 4; rhs1++)
3636 for (rhs2 = 0; rhs2 < 4; rhs2++)
3637 {
3638 if (rhs1 == 0 && rhs2 != 0)
3639 continue;
3640 ret_type = (op[lhs].type ? op[lhs].type : void_type_node);
3641 builtin_ftype
3642 = build_function_type_list (ret_type, integer_type_node,
3643 op[rhs1].type, op[rhs2].type,
3644 NULL_TREE);
3645 snprintf (builtin_name + n, 32 - n, "%sn%s%s",
3646 op[lhs].c, op[rhs1].c, op[rhs2].c);
3647 /* Save copy of parameter string into custom_builtin_name[]. */
3648 strncpy (custom_builtin_name[builtin_code], builtin_name + n, 5);
3649 fndecl =
3650 add_builtin_function (builtin_name, builtin_ftype,
3651 start_code + builtin_code,
3652 BUILT_IN_MD, NULL, NULL_TREE);
3653 nios2_register_builtin_fndecl (start_code + builtin_code, fndecl);
3654 builtin_code += 1;
3655 }
3656}
3657
3658/* Helper function for expanding custom builtins. */
3659static rtx
3660nios2_expand_custom_builtin (tree exp, unsigned int index, rtx target)
3661{
3662 bool has_target_p = (TREE_TYPE (exp) != void_type_node);
ef4bddc2 3663 machine_mode tmode = VOIDmode;
e430824f
CLT
3664 int nargs, argno;
3665 rtx value, insn, unspec_args[3];
3666 tree arg;
3667
3668 /* XnXX form. */
3669 if (has_target_p)
3670 {
3671 tmode = TYPE_MODE (TREE_TYPE (exp));
3672 if (!target || GET_MODE (target) != tmode
3673 || !REG_P (target))
3674 target = gen_reg_rtx (tmode);
3675 }
3676
3677 nargs = call_expr_nargs (exp);
3678 for (argno = 0; argno < nargs; argno++)
3679 {
3680 arg = CALL_EXPR_ARG (exp, argno);
3681 value = expand_normal (arg);
3682 unspec_args[argno] = value;
3683 if (argno == 0)
3684 {
3685 if (!custom_insn_opcode (value, VOIDmode))
3686 error ("custom instruction opcode must be compile time "
a3f9f006 3687 "constant in the range 0-255 for %<__builtin_custom_%s%>",
e430824f
CLT
3688 custom_builtin_name[index]);
3689 }
3690 else
3691 /* For other arguments, force into a register. */
3692 unspec_args[argno] = force_reg (TYPE_MODE (TREE_TYPE (arg)),
3693 unspec_args[argno]);
3694 }
3695 /* Fill remaining unspec operands with zero. */
3696 for (; argno < 3; argno++)
3697 unspec_args[argno] = const0_rtx;
3698
3699 insn = (has_target_p
f7df4a84 3700 ? gen_rtx_SET (target,
e430824f
CLT
3701 gen_rtx_UNSPEC_VOLATILE (tmode,
3702 gen_rtvec_v (3, unspec_args),
3703 UNSPECV_CUSTOM_XNXX))
3704 : gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec_v (3, unspec_args),
3705 UNSPECV_CUSTOM_NXX));
3706 emit_insn (insn);
3707 return has_target_p ? target : const0_rtx;
3708}
3709
3710
3711\f
3712
3713/* Main definition of built-in functions. Nios II has a small number of fixed
3714 builtins, plus a large number of FPU insn builtins, and builtins for
3715 generating custom instructions. */
3716
3717struct nios2_builtin_desc
3718{
3719 enum insn_code icode;
524d2e49 3720 enum nios2_arch_type arch;
e430824f
CLT
3721 enum nios2_ftcode ftype;
3722 const char *name;
3723};
3724
3725#define N2_BUILTINS \
524d2e49
SL
3726 N2_BUILTIN_DEF (sync, R1, N2_FTYPE_VOID_VOID) \
3727 N2_BUILTIN_DEF (ldbio, R1, N2_FTYPE_SI_CVPTR) \
3728 N2_BUILTIN_DEF (ldbuio, R1, N2_FTYPE_UI_CVPTR) \
3729 N2_BUILTIN_DEF (ldhio, R1, N2_FTYPE_SI_CVPTR) \
3730 N2_BUILTIN_DEF (ldhuio, R1, N2_FTYPE_UI_CVPTR) \
3731 N2_BUILTIN_DEF (ldwio, R1, N2_FTYPE_SI_CVPTR) \
3732 N2_BUILTIN_DEF (stbio, R1, N2_FTYPE_VOID_VPTR_SI) \
3733 N2_BUILTIN_DEF (sthio, R1, N2_FTYPE_VOID_VPTR_SI) \
3734 N2_BUILTIN_DEF (stwio, R1, N2_FTYPE_VOID_VPTR_SI) \
3735 N2_BUILTIN_DEF (rdctl, R1, N2_FTYPE_SI_SI) \
3736 N2_BUILTIN_DEF (wrctl, R1, N2_FTYPE_VOID_SI_SI) \
3737 N2_BUILTIN_DEF (rdprs, R1, N2_FTYPE_SI_SI_SI) \
3738 N2_BUILTIN_DEF (flushd, R1, N2_FTYPE_VOID_VPTR) \
3739 N2_BUILTIN_DEF (flushda, R1, N2_FTYPE_VOID_VPTR) \
3740 N2_BUILTIN_DEF (wrpie, R2, N2_FTYPE_SI_SI) \
3741 N2_BUILTIN_DEF (eni, R2, N2_FTYPE_VOID_SI) \
3742 N2_BUILTIN_DEF (ldex, R2, N2_FTYPE_SI_CVPTR) \
3743 N2_BUILTIN_DEF (ldsex, R2, N2_FTYPE_SI_CVPTR) \
3744 N2_BUILTIN_DEF (stex, R2, N2_FTYPE_SI_VPTR_SI) \
3745 N2_BUILTIN_DEF (stsex, R2, N2_FTYPE_SI_VPTR_SI)
e430824f
CLT
3746
3747enum nios2_builtin_code {
524d2e49 3748#define N2_BUILTIN_DEF(name, arch, ftype) NIOS2_BUILTIN_ ## name,
e430824f
CLT
3749 N2_BUILTINS
3750#undef N2_BUILTIN_DEF
3751 NUM_FIXED_NIOS2_BUILTINS
3752};
3753
3754static const struct nios2_builtin_desc nios2_builtins[] = {
524d2e49
SL
3755#define N2_BUILTIN_DEF(name, arch, ftype) \
3756 { CODE_FOR_ ## name, ARCH_ ## arch, ftype, "__builtin_" #name },
e430824f
CLT
3757 N2_BUILTINS
3758#undef N2_BUILTIN_DEF
3759};
3760
3761/* Start/ends of FPU/custom insn builtin index ranges. */
3762static unsigned int nios2_fpu_builtin_base;
3763static unsigned int nios2_custom_builtin_base;
3764static unsigned int nios2_custom_builtin_end;
3765
3766/* Implement TARGET_INIT_BUILTINS. */
3767static void
3768nios2_init_builtins (void)
3769{
3770 unsigned int i;
3771
3772 /* Initialize fixed builtins. */
3773 for (i = 0; i < ARRAY_SIZE (nios2_builtins); i++)
3774 {
3775 const struct nios2_builtin_desc *d = &nios2_builtins[i];
3776 tree fndecl =
3777 add_builtin_function (d->name, nios2_ftype (d->ftype), i,
3778 BUILT_IN_MD, NULL, NULL);
3779 nios2_register_builtin_fndecl (i, fndecl);
3780 }
3781
3782 /* Initialize FPU builtins. */
3783 nios2_fpu_builtin_base = ARRAY_SIZE (nios2_builtins);
3784 nios2_init_fpu_builtins (nios2_fpu_builtin_base);
3785
3786 /* Initialize custom insn builtins. */
3787 nios2_custom_builtin_base
3788 = nios2_fpu_builtin_base + ARRAY_SIZE (nios2_fpu_insn);
3789 nios2_custom_builtin_end
3790 = nios2_custom_builtin_base + NUM_CUSTOM_BUILTINS;
3791 nios2_init_custom_builtins (nios2_custom_builtin_base);
3792}
3793
3794/* Array of fndecls for TARGET_BUILTIN_DECL. */
3795#define NIOS2_NUM_BUILTINS \
3796 (ARRAY_SIZE (nios2_builtins) + ARRAY_SIZE (nios2_fpu_insn) + NUM_CUSTOM_BUILTINS)
3797static GTY(()) tree nios2_builtin_decls[NIOS2_NUM_BUILTINS];
3798
3799static void
3800nios2_register_builtin_fndecl (unsigned code, tree fndecl)
3801{
3802 nios2_builtin_decls[code] = fndecl;
3803}
3804
3805/* Implement TARGET_BUILTIN_DECL. */
3806static tree
3807nios2_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
3808{
3809 gcc_assert (nios2_custom_builtin_end == ARRAY_SIZE (nios2_builtin_decls));
3810
3811 if (code >= nios2_custom_builtin_end)
3812 return error_mark_node;
3813
3814 if (code >= nios2_fpu_builtin_base
3815 && code < nios2_custom_builtin_base
3816 && ! N2FPU_ENABLED_P (code - nios2_fpu_builtin_base))
3817 return error_mark_node;
3818
3819 return nios2_builtin_decls[code];
3820}
3821
3822\f
3823/* Low-level built-in expand routine. */
3824static rtx
3825nios2_expand_builtin_insn (const struct nios2_builtin_desc *d, int n,
3826 struct expand_operand *ops, bool has_target_p)
3827{
3828 if (maybe_expand_insn (d->icode, n, ops))
3829 return has_target_p ? ops[0].value : const0_rtx;
3830 else
3831 {
3832 error ("invalid argument to built-in function %s", d->name);
3833 return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx;
3834 }
3835}
3836
524d2e49
SL
3837/* Expand ldio/stio and ldex/ldsex/stex/stsex form load-store
3838 instruction builtins. */
e430824f 3839static rtx
524d2e49
SL
3840nios2_expand_ldst_builtin (tree exp, rtx target,
3841 const struct nios2_builtin_desc *d)
e430824f
CLT
3842{
3843 bool has_target_p;
3844 rtx addr, mem, val;
3845 struct expand_operand ops[MAX_RECOG_OPERANDS];
ef4bddc2 3846 machine_mode mode = insn_data[d->icode].operand[0].mode;
e430824f
CLT
3847
3848 addr = expand_normal (CALL_EXPR_ARG (exp, 0));
3849 mem = gen_rtx_MEM (mode, addr);
3850
3851 if (insn_data[d->icode].operand[0].allows_mem)
3852 {
524d2e49 3853 /* stxio/stex/stsex. */
e430824f
CLT
3854 val = expand_normal (CALL_EXPR_ARG (exp, 1));
3855 if (CONST_INT_P (val))
3856 val = force_reg (mode, gen_int_mode (INTVAL (val), mode));
3857 val = simplify_gen_subreg (mode, val, GET_MODE (val), 0);
3858 create_output_operand (&ops[0], mem, mode);
3859 create_input_operand (&ops[1], val, mode);
524d2e49
SL
3860 if (insn_data[d->icode].n_operands == 3)
3861 {
3862 /* stex/stsex status value, returned as result of function. */
3863 create_output_operand (&ops[2], target, mode);
3864 has_target_p = true;
3865 }
3866 else
3867 has_target_p = false;
e430824f
CLT
3868 }
3869 else
3870 {
3871 /* ldxio. */
3872 create_output_operand (&ops[0], target, mode);
3873 create_input_operand (&ops[1], mem, mode);
3874 has_target_p = true;
3875 }
524d2e49
SL
3876 return nios2_expand_builtin_insn (d, insn_data[d->icode].n_operands, ops,
3877 has_target_p);
e430824f
CLT
3878}
3879
3880/* Expand rdctl/wrctl builtins. */
3881static rtx
3882nios2_expand_rdwrctl_builtin (tree exp, rtx target,
3883 const struct nios2_builtin_desc *d)
3884{
3885 bool has_target_p = (insn_data[d->icode].operand[0].predicate
3886 == register_operand);
3887 rtx ctlcode = expand_normal (CALL_EXPR_ARG (exp, 0));
3888 struct expand_operand ops[MAX_RECOG_OPERANDS];
3889 if (!rdwrctl_operand (ctlcode, VOIDmode))
3890 {
3891 error ("Control register number must be in range 0-31 for %s",
3892 d->name);
3893 return has_target_p ? gen_reg_rtx (SImode) : const0_rtx;
3894 }
3895 if (has_target_p)
3896 {
3897 create_output_operand (&ops[0], target, SImode);
3898 create_integer_operand (&ops[1], INTVAL (ctlcode));
3899 }
3900 else
3901 {
3902 rtx val = expand_normal (CALL_EXPR_ARG (exp, 1));
3903 create_integer_operand (&ops[0], INTVAL (ctlcode));
3904 create_input_operand (&ops[1], val, SImode);
3905 }
3906 return nios2_expand_builtin_insn (d, 2, ops, has_target_p);
3907}
3908
524d2e49
SL
3909static rtx
3910nios2_expand_rdprs_builtin (tree exp, rtx target,
3911 const struct nios2_builtin_desc *d)
3912{
3913 rtx reg = expand_normal (CALL_EXPR_ARG (exp, 0));
3914 rtx imm = expand_normal (CALL_EXPR_ARG (exp, 1));
3915 struct expand_operand ops[MAX_RECOG_OPERANDS];
3916
3917 if (!rdwrctl_operand (reg, VOIDmode))
3918 {
3919 error ("Register number must be in range 0-31 for %s",
3920 d->name);
3921 return gen_reg_rtx (SImode);
3922 }
3923
3924 if (!rdprs_dcache_operand (imm, VOIDmode))
3925 {
3926 error ("The immediate value must fit into a %d-bit integer for %s",
3927 (TARGET_ARCH_R2) ? 12 : 16, d->name);
3928 return gen_reg_rtx (SImode);
3929 }
3930
3931 create_output_operand (&ops[0], target, SImode);
3932 create_input_operand (&ops[1], reg, SImode);
3933 create_integer_operand (&ops[2], INTVAL (imm));
3934
3935 return nios2_expand_builtin_insn (d, 3, ops, true);
3936}
3937
3938static rtx
3939nios2_expand_cache_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
3940 const struct nios2_builtin_desc *d)
3941{
3942 rtx mem, addr;
3943 struct expand_operand ops[MAX_RECOG_OPERANDS];
3944
3945 addr = expand_normal (CALL_EXPR_ARG (exp, 0));
3946 mem = gen_rtx_MEM (SImode, addr);
3947
3948 create_input_operand (&ops[0], mem, SImode);
3949
3950 return nios2_expand_builtin_insn (d, 1, ops, false);
3951}
3952
3953static rtx
3954nios2_expand_wrpie_builtin (tree exp, rtx target,
3955 const struct nios2_builtin_desc *d)
3956{
3957 rtx val;
3958 struct expand_operand ops[MAX_RECOG_OPERANDS];
3959
3960 val = expand_normal (CALL_EXPR_ARG (exp, 0));
3961 create_input_operand (&ops[1], val, SImode);
3962 create_output_operand (&ops[0], target, SImode);
3963
3964 return nios2_expand_builtin_insn (d, 2, ops, true);
3965}
3966
3967static rtx
3968nios2_expand_eni_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
3969 const struct nios2_builtin_desc *d)
3970{
3971 rtx imm = expand_normal (CALL_EXPR_ARG (exp, 0));
3972 struct expand_operand ops[MAX_RECOG_OPERANDS];
3973
3974 if (INTVAL (imm) != 0 && INTVAL (imm) != 1)
3975 {
3976 error ("The ENI instruction operand must be either 0 or 1");
3977 return const0_rtx;
3978 }
3979 create_integer_operand (&ops[0], INTVAL (imm));
3980
3981 return nios2_expand_builtin_insn (d, 1, ops, false);
3982}
3983
e430824f
CLT
3984/* Implement TARGET_EXPAND_BUILTIN. Expand an expression EXP that calls
3985 a built-in function, with result going to TARGET if that's convenient
3986 (and in mode MODE if that's convenient).
3987 SUBTARGET may be used as the target for computing one of EXP's operands.
3988 IGNORE is nonzero if the value is to be ignored. */
3989
3990static rtx
3991nios2_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
ef4bddc2 3992 machine_mode mode ATTRIBUTE_UNUSED,
e430824f
CLT
3993 int ignore ATTRIBUTE_UNUSED)
3994{
3995 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
4d732405 3996 unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
e430824f
CLT
3997
3998 if (fcode < nios2_fpu_builtin_base)
3999 {
4000 const struct nios2_builtin_desc *d = &nios2_builtins[fcode];
4001
524d2e49
SL
4002 if (d->arch > nios2_arch_option)
4003 {
4004 error ("Builtin function %s requires Nios II R%d",
4005 d->name, (int) d->arch);
4006 /* Given it is invalid, just generate a normal call. */
4007 return expand_call (exp, target, ignore);
4008 }
4009
e430824f
CLT
4010 switch (fcode)
4011 {
4012 case NIOS2_BUILTIN_sync:
4013 emit_insn (gen_sync ());
4014 return const0_rtx;
4015
4016 case NIOS2_BUILTIN_ldbio:
4017 case NIOS2_BUILTIN_ldbuio:
4018 case NIOS2_BUILTIN_ldhio:
4019 case NIOS2_BUILTIN_ldhuio:
4020 case NIOS2_BUILTIN_ldwio:
4021 case NIOS2_BUILTIN_stbio:
4022 case NIOS2_BUILTIN_sthio:
4023 case NIOS2_BUILTIN_stwio:
524d2e49
SL
4024 case NIOS2_BUILTIN_ldex:
4025 case NIOS2_BUILTIN_ldsex:
4026 case NIOS2_BUILTIN_stex:
4027 case NIOS2_BUILTIN_stsex:
4028 return nios2_expand_ldst_builtin (exp, target, d);
e430824f
CLT
4029
4030 case NIOS2_BUILTIN_rdctl:
4031 case NIOS2_BUILTIN_wrctl:
4032 return nios2_expand_rdwrctl_builtin (exp, target, d);
4033
524d2e49
SL
4034 case NIOS2_BUILTIN_rdprs:
4035 return nios2_expand_rdprs_builtin (exp, target, d);
4036
4037 case NIOS2_BUILTIN_flushd:
4038 case NIOS2_BUILTIN_flushda:
4039 return nios2_expand_cache_builtin (exp, target, d);
4040
4041 case NIOS2_BUILTIN_wrpie:
4042 return nios2_expand_wrpie_builtin (exp, target, d);
4043
4044 case NIOS2_BUILTIN_eni:
4045 return nios2_expand_eni_builtin (exp, target, d);
4046
e430824f
CLT
4047 default:
4048 gcc_unreachable ();
4049 }
4050 }
4051 else if (fcode < nios2_custom_builtin_base)
4052 /* FPU builtin range. */
4053 return nios2_expand_fpu_builtin (exp, fcode - nios2_fpu_builtin_base,
4054 target);
4055 else if (fcode < nios2_custom_builtin_end)
4056 /* Custom insn builtin range. */
4057 return nios2_expand_custom_builtin (exp, fcode - nios2_custom_builtin_base,
4058 target);
4059 else
4060 gcc_unreachable ();
4061}
4062
4063/* Implement TARGET_INIT_LIBFUNCS. */
665ad37b 4064static void ATTRIBUTE_UNUSED
e430824f
CLT
4065nios2_init_libfuncs (void)
4066{
9bd99cce 4067 init_sync_libfuncs (UNITS_PER_WORD);
e430824f
CLT
4068}
4069
4070\f
4071
4072/* Register a custom code use, and signal error if a conflict was found. */
4073static void
4074nios2_register_custom_code (unsigned int N, enum nios2_ccs_code status,
4075 int index)
4076{
4077 gcc_assert (N <= 255);
4078
4079 if (status == CCS_FPU)
4080 {
4081 if (custom_code_status[N] == CCS_FPU && index != custom_code_index[N])
4082 {
4083 custom_code_conflict = true;
4084 error ("switch %<-mcustom-%s%> conflicts with switch %<-mcustom-%s%>",
4085 N2FPU_NAME (custom_code_index[N]), N2FPU_NAME (index));
4086 }
4087 else if (custom_code_status[N] == CCS_BUILTIN_CALL)
4088 {
4089 custom_code_conflict = true;
4090 error ("call to %<__builtin_custom_%s%> conflicts with switch "
4091 "%<-mcustom-%s%>", custom_builtin_name[custom_code_index[N]],
4092 N2FPU_NAME (index));
4093 }
4094 }
4095 else if (status == CCS_BUILTIN_CALL)
4096 {
4097 if (custom_code_status[N] == CCS_FPU)
4098 {
4099 custom_code_conflict = true;
4100 error ("call to %<__builtin_custom_%s%> conflicts with switch "
4101 "%<-mcustom-%s%>", custom_builtin_name[index],
4102 N2FPU_NAME (custom_code_index[N]));
4103 }
4104 else
4105 {
4106 /* Note that code conflicts between different __builtin_custom_xnxx
4107 calls are not checked. */
4108 }
4109 }
4110 else
4111 gcc_unreachable ();
4112
4113 custom_code_status[N] = status;
4114 custom_code_index[N] = index;
4115}
4116
4117/* Mark a custom code as not in use. */
4118static void
4119nios2_deregister_custom_code (unsigned int N)
4120{
4121 if (N <= 255)
4122 {
4123 custom_code_status[N] = CCS_UNUSED;
4124 custom_code_index[N] = 0;
4125 }
4126}
4127
4128/* Target attributes can affect per-function option state, so we need to
4129 save/restore the custom code tracking info using the
4130 TARGET_OPTION_SAVE/TARGET_OPTION_RESTORE hooks. */
4131
4132static void
4133nios2_option_save (struct cl_target_option *ptr,
4134 struct gcc_options *opts ATTRIBUTE_UNUSED)
4135{
4136 unsigned int i;
4137 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
4138 ptr->saved_fpu_custom_code[i] = N2FPU_N (i);
4139 memcpy (ptr->saved_custom_code_status, custom_code_status,
4140 sizeof (custom_code_status));
4141 memcpy (ptr->saved_custom_code_index, custom_code_index,
4142 sizeof (custom_code_index));
4143}
4144
4145static void
4146nios2_option_restore (struct gcc_options *opts ATTRIBUTE_UNUSED,
4147 struct cl_target_option *ptr)
4148{
4149 unsigned int i;
4150 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
4151 N2FPU_N (i) = ptr->saved_fpu_custom_code[i];
4152 memcpy (custom_code_status, ptr->saved_custom_code_status,
4153 sizeof (custom_code_status));
4154 memcpy (custom_code_index, ptr->saved_custom_code_index,
4155 sizeof (custom_code_index));
4156}
4157
4158/* Inner function to process the attribute((target(...))), take an argument and
4159 set the current options from the argument. If we have a list, recursively
4160 go over the list. */
4161
4162static bool
4163nios2_valid_target_attribute_rec (tree args)
4164{
4165 if (TREE_CODE (args) == TREE_LIST)
4166 {
4167 bool ret = true;
4168 for (; args; args = TREE_CHAIN (args))
4169 if (TREE_VALUE (args)
4170 && !nios2_valid_target_attribute_rec (TREE_VALUE (args)))
4171 ret = false;
4172 return ret;
4173 }
4174 else if (TREE_CODE (args) == STRING_CST)
4175 {
4176 char *argstr = ASTRDUP (TREE_STRING_POINTER (args));
4177 while (argstr && *argstr != '\0')
4178 {
4179 bool no_opt = false, end_p = false;
4180 char *eq = NULL, *p;
4181 while (ISSPACE (*argstr))
4182 argstr++;
4183 p = argstr;
4184 while (*p != '\0' && *p != ',')
4185 {
4186 if (!eq && *p == '=')
4187 eq = p;
4188 ++p;
4189 }
4190 if (*p == '\0')
4191 end_p = true;
4192 else
4193 *p = '\0';
4194 if (eq) *eq = '\0';
4195
4196 if (!strncmp (argstr, "no-", 3))
4197 {
4198 no_opt = true;
4199 argstr += 3;
4200 }
4201 if (!strncmp (argstr, "custom-fpu-cfg", 14))
4202 {
4203 char *end_eq = p;
4204 if (no_opt)
4205 {
4206 error ("custom-fpu-cfg option does not support %<no-%>");
4207 return false;
4208 }
4209 if (!eq)
4210 {
4211 error ("custom-fpu-cfg option requires configuration"
4212 " argument");
4213 return false;
4214 }
4215 /* Increment and skip whitespace. */
4216 while (ISSPACE (*(++eq))) ;
4217 /* Decrement and skip to before any trailing whitespace. */
4218 while (ISSPACE (*(--end_eq))) ;
4219
4220 nios2_handle_custom_fpu_cfg (eq, end_eq + 1, true);
4221 }
4222 else if (!strncmp (argstr, "custom-", 7))
4223 {
4224 int code = -1;
4225 unsigned int i;
4226 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
4227 if (!strncmp (argstr + 7, N2FPU_NAME (i),
4228 strlen (N2FPU_NAME (i))))
4229 {
4230 /* Found insn. */
4231 code = i;
4232 break;
4233 }
4234 if (code >= 0)
4235 {
4236 if (no_opt)
4237 {
4238 if (eq)
4239 {
4240 error ("%<no-custom-%s%> does not accept arguments",
4241 N2FPU_NAME (code));
4242 return false;
4243 }
4244 /* Disable option by setting to -1. */
4245 nios2_deregister_custom_code (N2FPU_N (code));
4246 N2FPU_N (code) = -1;
4247 }
4248 else
4249 {
4250 char *t;
4251 if (eq)
4252 while (ISSPACE (*(++eq))) ;
4253 if (!eq || eq == p)
4254 {
4255 error ("%<custom-%s=%> requires argument",
4256 N2FPU_NAME (code));
4257 return false;
4258 }
4259 for (t = eq; t != p; ++t)
4260 {
4261 if (ISSPACE (*t))
4262 continue;
4263 if (!ISDIGIT (*t))
4264 {
6e0686e1
SL
4265 error ("%<custom-%s=%> argument should be "
4266 "a non-negative integer", N2FPU_NAME (code));
e430824f
CLT
4267 return false;
4268 }
4269 }
4270 /* Set option to argument. */
4271 N2FPU_N (code) = atoi (eq);
4272 nios2_handle_custom_fpu_insn_option (code);
4273 }
4274 }
4275 else
4276 {
bd2c6270 4277 error ("%<custom-%s=%> is not recognized as FPU instruction",
e430824f
CLT
4278 argstr + 7);
4279 return false;
4280 }
4281 }
4282 else
4283 {
4284 error ("%<%s%> is unknown", argstr);
4285 return false;
4286 }
4287
4288 if (end_p)
4289 break;
4290 else
4291 argstr = p + 1;
4292 }
4293 return true;
4294 }
4295 else
4296 gcc_unreachable ();
4297}
4298
4299/* Return a TARGET_OPTION_NODE tree of the target options listed or NULL. */
4300
4301static tree
4302nios2_valid_target_attribute_tree (tree args)
4303{
4304 if (!nios2_valid_target_attribute_rec (args))
4305 return NULL_TREE;
4306 nios2_custom_check_insns ();
4307 return build_target_option_node (&global_options);
4308}
4309
4310/* Hook to validate attribute((target("string"))). */
4311
4312static bool
4313nios2_valid_target_attribute_p (tree fndecl, tree ARG_UNUSED (name),
4314 tree args, int ARG_UNUSED (flags))
4315{
4316 struct cl_target_option cur_target;
4317 bool ret = true;
4318 tree old_optimize = build_optimization_node (&global_options);
4319 tree new_target, new_optimize;
4320 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
4321
4322 /* If the function changed the optimization levels as well as setting target
4323 options, start with the optimizations specified. */
4324 if (func_optimize && func_optimize != old_optimize)
4325 cl_optimization_restore (&global_options,
4326 TREE_OPTIMIZATION (func_optimize));
4327
4328 /* The target attributes may also change some optimization flags, so update
4329 the optimization options if necessary. */
4330 cl_target_option_save (&cur_target, &global_options);
4331 new_target = nios2_valid_target_attribute_tree (args);
4332 new_optimize = build_optimization_node (&global_options);
4333
4334 if (!new_target)
4335 ret = false;
4336
4337 else if (fndecl)
4338 {
4339 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
4340
4341 if (old_optimize != new_optimize)
4342 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
4343 }
4344
4345 cl_target_option_restore (&global_options, &cur_target);
4346
4347 if (old_optimize != new_optimize)
4348 cl_optimization_restore (&global_options,
4349 TREE_OPTIMIZATION (old_optimize));
4350 return ret;
4351}
4352
4353/* Remember the last target of nios2_set_current_function. */
4354static GTY(()) tree nios2_previous_fndecl;
4355
4356/* Establish appropriate back-end context for processing the function
4357 FNDECL. The argument might be NULL to indicate processing at top
4358 level, outside of any function scope. */
4359static void
4360nios2_set_current_function (tree fndecl)
4361{
4362 tree old_tree = (nios2_previous_fndecl
4363 ? DECL_FUNCTION_SPECIFIC_TARGET (nios2_previous_fndecl)
4364 : NULL_TREE);
4365
4366 tree new_tree = (fndecl
4367 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
4368 : NULL_TREE);
4369
4370 if (fndecl && fndecl != nios2_previous_fndecl)
4371 {
4372 nios2_previous_fndecl = fndecl;
4373 if (old_tree == new_tree)
4374 ;
4375
4376 else if (new_tree)
4377 {
4378 cl_target_option_restore (&global_options,
4379 TREE_TARGET_OPTION (new_tree));
4380 target_reinit ();
4381 }
4382
4383 else if (old_tree)
4384 {
4385 struct cl_target_option *def
4386 = TREE_TARGET_OPTION (target_option_current_node);
4387
4388 cl_target_option_restore (&global_options, def);
4389 target_reinit ();
4390 }
4391 }
4392}
4393
4394/* Hook to validate the current #pragma GCC target and set the FPU custom
4395 code option state. If ARGS is NULL, then POP_TARGET is used to reset
4396 the options. */
4397static bool
4398nios2_pragma_target_parse (tree args, tree pop_target)
4399{
4400 tree cur_tree;
4401 if (! args)
4402 {
4403 cur_tree = ((pop_target)
4404 ? pop_target
4405 : target_option_default_node);
4406 cl_target_option_restore (&global_options,
4407 TREE_TARGET_OPTION (cur_tree));
4408 }
4409 else
4410 {
4411 cur_tree = nios2_valid_target_attribute_tree (args);
4412 if (!cur_tree)
4413 return false;
4414 }
4415
4416 target_option_current_node = cur_tree;
4417 return true;
4418}
4419
4420/* Implement TARGET_MERGE_DECL_ATTRIBUTES.
4421 We are just using this hook to add some additional error checking to
4422 the default behavior. GCC does not provide a target hook for merging
4423 the target options, and only correctly handles merging empty vs non-empty
4424 option data; see merge_decls() in c-decl.c.
4425 So here we require either that at least one of the decls has empty
4426 target options, or that the target options/data be identical. */
4427static tree
4428nios2_merge_decl_attributes (tree olddecl, tree newdecl)
4429{
4430 tree oldopts = lookup_attribute ("target", DECL_ATTRIBUTES (olddecl));
4431 tree newopts = lookup_attribute ("target", DECL_ATTRIBUTES (newdecl));
4432 if (newopts && oldopts && newopts != oldopts)
4433 {
4434 tree oldtree = DECL_FUNCTION_SPECIFIC_TARGET (olddecl);
4435 tree newtree = DECL_FUNCTION_SPECIFIC_TARGET (newdecl);
4436 if (oldtree && newtree && oldtree != newtree)
4437 {
4438 struct cl_target_option *olddata = TREE_TARGET_OPTION (oldtree);
4439 struct cl_target_option *newdata = TREE_TARGET_OPTION (newtree);
4440 if (olddata != newdata
4441 && memcmp (olddata, newdata, sizeof (struct cl_target_option)))
4442 error ("%qE redeclared with conflicting %qs attributes",
4443 DECL_NAME (newdecl), "target");
4444 }
4445 }
4446 return merge_attributes (DECL_ATTRIBUTES (olddecl),
4447 DECL_ATTRIBUTES (newdecl));
4448}
4449
a866d527
CLT
4450/* Implement TARGET_ASM_OUTPUT_MI_THUNK. */
4451static void
4452nios2_asm_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
4453 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
4454 tree function)
4455{
f7430263 4456 const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
a866d527
CLT
4457 rtx this_rtx, funexp;
4458 rtx_insn *insn;
4459
4460 /* Pretend to be a post-reload pass while generating rtl. */
4461 reload_completed = 1;
4462
4463 if (flag_pic)
4464 nios2_load_pic_register ();
4465
4466 /* Mark the end of the (empty) prologue. */
4467 emit_note (NOTE_INSN_PROLOGUE_END);
4468
4469 /* Find the "this" pointer. If the function returns a structure,
4470 the structure return pointer is in $5. */
4471 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
4472 this_rtx = gen_rtx_REG (Pmode, FIRST_ARG_REGNO + 1);
4473 else
4474 this_rtx = gen_rtx_REG (Pmode, FIRST_ARG_REGNO);
4475
4476 /* Add DELTA to THIS_RTX. */
4477 nios2_emit_add_constant (this_rtx, delta);
4478
4479 /* If needed, add *(*THIS_RTX + VCALL_OFFSET) to THIS_RTX. */
4480 if (vcall_offset)
4481 {
4482 rtx tmp;
4483
4484 tmp = gen_rtx_REG (Pmode, 2);
4485 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
4486 nios2_emit_add_constant (tmp, vcall_offset);
4487 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
4488 emit_insn (gen_add2_insn (this_rtx, tmp));
4489 }
4490
4491 /* Generate a tail call to the target function. */
4492 if (!TREE_USED (function))
4493 {
4494 assemble_external (function);
4495 TREE_USED (function) = 1;
4496 }
4497 funexp = XEXP (DECL_RTL (function), 0);
4498 /* Function address needs to be constructed under PIC,
4499 provide r2 to use here. */
4500 nios2_adjust_call_address (&funexp, gen_rtx_REG (Pmode, 2));
4501 insn = emit_call_insn (gen_sibcall_internal (funexp, const0_rtx));
4502 SIBLING_CALL_P (insn) = 1;
4503
4504 /* Run just enough of rest_of_compilation to get the insns emitted.
4505 There's not really enough bulk here to make other passes such as
8b4e7143 4506 instruction scheduling worth while. */
a866d527
CLT
4507 insn = get_insns ();
4508 shorten_branches (insn);
f7430263 4509 assemble_start_function (thunk_fndecl, fnname);
a866d527
CLT
4510 final_start_function (insn, file, 1);
4511 final (insn, file, 1);
4512 final_end_function ();
f7430263 4513 assemble_end_function (thunk_fndecl, fnname);
a866d527
CLT
4514
4515 /* Stop pretending to be a post-reload pass. */
4516 reload_completed = 0;
4517}
4518
3bbbe009
SL
4519
4520/* Utility function to break a memory address into
4521 base register + constant offset. Return false if something
4522 unexpected is seen. */
4523static bool
4524split_mem_address (rtx addr, rtx *base_reg, rtx *offset)
4525{
4526 if (REG_P (addr))
4527 {
4528 *base_reg = addr;
4529 *offset = const0_rtx;
4530 return true;
4531 }
4532 else if (GET_CODE (addr) == PLUS)
4533 {
4534 *base_reg = XEXP (addr, 0);
4535 *offset = XEXP (addr, 1);
4536 return true;
4537 }
4538 return false;
4539}
4540
4541/* Splits out the operands of an ALU insn, places them in *LHS, *RHS1, *RHS2. */
4542static void
4543split_alu_insn (rtx_insn *insn, rtx *lhs, rtx *rhs1, rtx *rhs2)
4544{
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;
4552}
4553
4554/* Returns true if OP is a REG and assigned a CDX reg. */
4555static bool
4556cdxreg (rtx op)
4557{
4558 return REG_P (op) && (!reload_completed || CDX_REG_P (REGNO (op)));
4559}
4560
4561/* Returns true if OP is within range of CDX addi.n immediates. */
4562static bool
4563cdx_add_immed (rtx op)
4564{
4565 if (CONST_INT_P (op))
4566 {
4567 HOST_WIDE_INT ival = INTVAL (op);
4568 return ival <= 128 && ival > 0 && (ival & (ival - 1)) == 0;
4569 }
4570 return false;
4571}
4572
4573/* Returns true if OP is within range of CDX andi.n immediates. */
4574static bool
4575cdx_and_immed (rtx op)
4576{
4577 if (CONST_INT_P (op))
4578 {
4579 HOST_WIDE_INT ival = INTVAL (op);
4580 return (ival == 1 || ival == 2 || ival == 3 || ival == 4
4581 || ival == 8 || ival == 0xf || ival == 0x10
231f6e09
SL
4582 || ival == 0x1f || ival == 0x20
4583 || ival == 0x3f || ival == 0x7f
3bbbe009
SL
4584 || ival == 0x80 || ival == 0xff || ival == 0x7ff
4585 || ival == 0xff00 || ival == 0xffff);
4586 }
4587 return false;
4588}
4589
4590/* Returns true if OP is within range of CDX movi.n immediates. */
4591static bool
4592cdx_mov_immed (rtx op)
4593{
4594 if (CONST_INT_P (op))
4595 {
4596 HOST_WIDE_INT ival = INTVAL (op);
4597 return ((ival >= 0 && ival <= 124)
4598 || ival == 0xff || ival == -2 || ival == -1);
4599 }
4600 return false;
4601}
4602
4603/* Returns true if OP is within range of CDX slli.n/srli.n immediates. */
4604static bool
4605cdx_shift_immed (rtx op)
4606{
4607 if (CONST_INT_P (op))
4608 {
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);
4613 }
4614 return false;
4615}
4616
4617
4618
4619/* Classification of different kinds of add instructions. */
4620enum 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
4629};
4630
4631static const char *nios2_add_insn_names[] = {
4632 "add.n", "addi.n", "subi.n", "spaddi.n", "spinci.n", "spdeci.n",
4633 "add", "addi" };
4634static bool nios2_add_insn_narrow[] = {
4635 true, true, true, true, true, true,
4636 false, false};
4637
4638/* Function to classify kinds of add instruction patterns. */
4639static enum nios2_add_insn_kind
4640nios2_add_insn_classify (rtx_insn *insn ATTRIBUTE_UNUSED,
4641 rtx lhs, rtx rhs1, rtx rhs2)
4642{
4643 if (TARGET_HAS_CDX)
4644 {
4645 if (cdxreg (lhs) && cdxreg (rhs1))
4646 {
4647 if (cdxreg (rhs2))
4648 return nios2_add_n_kind;
4649 if (CONST_INT_P (rhs2))
4650 {
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;
4656 }
4657 }
4658 else if (rhs1 == stack_pointer_rtx
4659 && CONST_INT_P (rhs2))
4660 {
4661 HOST_WIDE_INT imm7 = INTVAL (rhs2) >> 2;
4662 HOST_WIDE_INT rem = INTVAL (rhs2) & 3;
4663 if (rem == 0 && (imm7 & ~0x7f) == 0)
4664 {
4665 if (cdxreg (lhs))
4666 return nios2_spaddi_n_kind;
4667 if (lhs == stack_pointer_rtx)
4668 return nios2_spinci_n_kind;
4669 }
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;
4675 }
4676 }
4677 return ((REG_P (rhs2) || rhs2 == const0_rtx)
4678 ? nios2_add_kind : nios2_addi_kind);
4679}
4680
4681/* Emit assembly language for the different kinds of add instructions. */
4682const char*
4683nios2_add_insn_asm (rtx_insn *insn, rtx *operands)
4684{
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;
4700}
4701
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. */
4705bool
4706nios2_cdx_narrow_form_p (rtx_insn *insn)
4707{
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)
4716 {
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)
4725 {
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);
4735 }
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
4747 {
4748 gcc_assert (!insn_variable_length_p (insn));
4749 return false;
4750 }
4751 case TYPE_ADD:
4752 {
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];
4757 }
4758 case TYPE_LD:
4759 {
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))
4770 {
4771 /* ldxio. */
4772 if ((MEM_VOLATILE_P (mem) && TARGET_BYPASS_CACHE_VOLATILE)
4773 || TARGET_BYPASS_CACHE)
4774 return false;
4775 addr = XEXP (mem, 0);
1cef1159
SL
4776 /* GP-based and R0-based references are never narrow. */
4777 if (gprel_constant_p (addr) || r0rel_constant_p (addr))
3bbbe009 4778 return false;
82348675
SL
4779 /* %lo requires a 16-bit relocation and is never narrow. */
4780 if (GET_CODE (addr) == LO_SUM)
4781 return false;
3bbbe009
SL
4782 ret = split_mem_address (addr, &rhs1, &rhs2);
4783 gcc_assert (ret);
4784 }
4785 else
4786 return false;
4787
4788 offset = INTVAL (rhs2);
4789 if (GET_MODE (mem) == SImode)
4790 {
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;
4797 }
4798 else if (GET_MODE (mem) == HImode)
4799 {
4800 rem = offset & 1;
4801 offset >>= 1;
4802 }
4803 /* ldbu.n, ldhu.n, ldw.n cases. */
4804 return (cdxreg (reg) && cdxreg (rhs1)
4805 && rem == 0 && (offset & ~0xf) == 0);
4806 }
4807 case TYPE_ST:
4808 if (GET_CODE (pat) == PARALLEL)
4809 /* stex, stsex. */
4810 return false;
4811 else
4812 {
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);
1cef1159
SL
4823 /* GP-based and r0-based references are never narrow. */
4824 if (gprel_constant_p (addr) || r0rel_constant_p (addr))
3bbbe009 4825 return false;
82348675
SL
4826 /* %lo requires a 16-bit relocation and is never narrow. */
4827 if (GET_CODE (addr) == LO_SUM)
4828 return false;
3bbbe009
SL
4829 ret = split_mem_address (addr, &rhs1, &rhs2);
4830 gcc_assert (ret);
4831 offset = INTVAL (rhs2);
4832 if (GET_MODE (mem) == SImode)
4833 {
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;
4844 }
4845 else if (GET_MODE (mem) == HImode)
4846 {
4847 rem = offset & 1;
4848 offset >>= 1;
4849 }
4850 else
4851 {
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;
4857 }
4858
4859 /* stbu.n, sthu.n, stw.n cases. */
4860 return (cdxreg (reg) && cdxreg (rhs1)
4861 && rem == 0 && (offset & ~0xf) == 0);
4862 }
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;
4870
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)));
4881
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)));
4888
4889 case TYPE_SUB:
4890 split_alu_insn (insn, &lhs, &rhs1, &rhs2);
4891 return (cdxreg (lhs) && cdxreg (rhs1) && cdxreg (rhs2));
4892
4893 case TYPE_NEG:
4894 case TYPE_NOT:
4895 split_alu_insn (insn, &lhs, &rhs1, NULL);
4896 return (cdxreg (lhs) && cdxreg (rhs1));
4897
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;
4911 }
4912 return false;
4913}
4914
aa32db37
SL
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. */
4919bool
4920pop_operation_p (rtx op)
4921{
4922 int i;
4923 HOST_WIDE_INT last_offset = -1, len = XVECLEN (op, 0);
4924 rtx base_reg, offset;
4925
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;
4933
4934 for (i = len - 1; i > 1; i--)
4935 {
4936 rtx set = XVECEXP (op, 0, i);
4937 rtx curr_base_reg, curr_offset;
4938
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)
4946 {
4947 last_offset = INTVAL (curr_offset);
4948 if ((last_offset & 3) != 0 || last_offset > 60)
4949 return false;
4950 }
4951 else
4952 {
4953 last_offset += 4;
4954 if (INTVAL (curr_offset) != last_offset)
4955 return false;
4956 }
4957 }
4958 if (last_offset < 0 || last_offset + 4 != INTVAL (offset))
4959 return false;
4960
4961 return true;
4962}
4963
4964
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
4970
4971static bool
4972nios2_ldstwm_regset_p (unsigned int regno, unsigned int *regset)
4973{
4974 if (*regset == 0)
4975 {
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;
4983 }
4984 else
4985 return (*regset & (1 << regno)) != 0;
4986}
4987
4988/* Main function to implement ldwm_operation/stwm_operation
4989 predicates that check ldwm/stwm insn pattern integrity. */
4990bool
4991ldstwm_operation_p (rtx op, bool load_p)
4992{
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++)
5003 {
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)
5020 {
5021 rtx first_base, first_offset;
5022 if (!split_mem_address (XEXP (mem, 0),
5023 &first_base, &first_offset))
5024 return false;
039f4db9
SB
5025 if (!REG_P (first_base) || !CONST_INT_P (first_offset))
5026 return false;
aa32db37
SL
5027 base_reg = first_base;
5028 inc_p = INTVAL (first_offset) >= 0;
5029 }
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)
5035 {
5036 if (inc_p && last_regno >= regno)
5037 return false;
5038 if (!inc_p && last_regno <= regno)
5039 return false;
5040 }
5041 last_regno = regno;
5042 }
5043 return true;
5044}
5045
5046/* Helper for nios2_ldst_parallel, for generating a parallel vector
5047 SET element. */
5048static rtx
5049gen_ldst (bool load_p, int regno, rtx base_mem, int offset)
5050{
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);
5055}
5056
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.
5067
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. */
5071static rtx
5072nios2_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)
5075{
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)
5085 {
5086 int offset = (offset_inc_p ? 4 : -4) * n++;
5087 RTVEC_ELT (p, i++) = gen_ldst (load_p, regno, base_mem, offset);
5088 }
5089 if (ret_p)
5090 RTVEC_ELT (p, 0) = ret_rtx;
5091 if (base_update != 0)
5092 {
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));
5098 }
5099 return gen_rtx_PARALLEL (VOIDmode, p);
5100}
5101
5102/* CDX ldwm/stwm peephole optimization pattern related routines. */
5103
5104/* Data structure and sorting function for ldwm/stwm peephole optimizers. */
5105struct ldstwm_operand
5106{
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. */
5112};
5113
5114static int
5115compare_ldstwm_operands (const void *arg1, const void *arg2)
5116{
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;
5125}
5126
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. */
5130static bool
5131can_use_cdx_ldstw (int regno, int basereg, int offset)
5132{
5133 if (CDX_REG_P (regno) && CDX_REG_P (basereg)
01512446 5134 && (offset & 0x3) == 0 && offset >= 0 && offset < 0x40)
aa32db37
SL
5135 return true;
5136 else if (basereg == SP_REGNO
5137 && offset >= 0 && offset < 0x80 && (offset & 0x3) == 0)
5138 return true;
5139 return false;
5140}
5141
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. */
5151bool
5152gen_ldstwm_peep (bool load_p, int n, rtx scratch, rtx *operands)
5153{
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;
5165
5166 if (!TARGET_HAS_CDX)
5167 return false;
5168 if (n < 2 || n > MAX_LDSTWM_OPS)
5169 return false;
5170
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++)
5175 {
5176 rtx base, offset;
5177 rtx reg = operands[i];
5178 rtx mem = operands[i + n];
5179 int r, o, regno;
5180 bool bad = false;
5181
5182 if (!REG_P (reg) || !MEM_P (mem))
5183 return false;
5184
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;
5191
5192 if (!split_mem_address (XEXP (mem, 0), &base, &offset))
5193 return false;
5194 r = REGNO (base);
5195 o = INTVAL (offset);
5196
5197 if (basereg == -1)
5198 basereg = r;
5199 else if (r != basereg)
5200 bad = true;
5201 usemask |= 1 << r;
5202
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;
5208 }
5209
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;
5214
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);
5220
5221 baseoffset = sort[0].offset;
5222 needscratch = baseoffset != 0;
5223 if (needscratch && !scratch)
5224 return false;
5225
5226 lastreg = regmask = regset = 0;
5227 lastoffset = baseoffset;
5228 for (m = 0; m < n && !sort[m].bad; m++)
5229 {
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);
5238 }
5239
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;
5248
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)
5255 {
5256 if (!needscratch)
5257 return false;
5258 m = 0;
5259 nbytes = 0;
5260 }
5261 else
5262 nbytes = -4; /* Size of ldwm/stwm. */
5263 if (needscratch)
5264 {
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. */
5272 }
5273
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;
5280
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))
5291 {
5292 sort[i].rewrite = true;
5293 nbytes += 2;
5294 }
5295
5296 /* Are we good to go? */
5297 if (nbytes <= 0)
5298 return false;
5299
5300 /* Emit the scratch load. */
5301 if (needscratch)
5302 emit_insn (gen_rtx_SET (scratch, XEXP (sort[0].mem, 0)));
5303
5304 /* Emit the ldwm/stwm insn. */
5305 if (m > 0)
5306 {
5307 rtvec p = rtvec_alloc (m);
5308 for (i = 0; i < m; i++)
5309 {
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);
5320 }
5321 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
5322 }
5323
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++)
5327 {
5328 rtx reg = sort[i].reg;
5329 rtx mem = sort[i].mem;
5330 if (sort[i].rewrite)
5331 {
5332 int offset = sort[i].offset - baseoffset;
5333 mem = gen_rtx_MEM (SImode, plus_constant (Pmode, scratch, offset));
5334 }
5335 if (load_p)
5336 emit_move_insn (reg, mem);
5337 else
5338 emit_move_insn (mem, reg);
5339 }
5340 return true;
5341}
5342
3bbbe009
SL
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. */
5350
5351static unsigned char *label_align;
5352static int min_labelno, max_labelno;
5353
5354static void
5355nios2_reorg (void)
5356{
5357 bool changed = true;
5358 rtx_insn *insn;
5359
5360 if (!TARGET_HAS_CDX)
5361 return;
5362
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);
5369
5370 /* Iterate on inserting alignment and adjusting branch lengths until
5371 no more changes. */
5372 while (changed)
5373 {
5374 changed = false;
5375 shorten_branches (get_insns ());
5376
5377 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
5378 if (JUMP_P (insn) && insn_variable_length_p (insn))
5379 {
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)
5387 {
5388 int index = CODE_LABEL_NUMBER (label) - min_labelno;
5389 if (label_align[index] != 2)
5390 {
5391 label_align[index] = 2;
5392 changed = true;
5393 }
5394 }
5395 }
5396 }
5397}
5398
5399/* Implement LABEL_ALIGN, using the information gathered in nios2_reorg. */
5400int
5401nios2_label_align (rtx label)
5402{
5403 int n = CODE_LABEL_NUMBER (label);
5404
5405 if (label_align && n >= min_labelno && n <= max_labelno)
d84916bd
JL
5406 return MAX (label_align[n - min_labelno], align_labels.levels[0].log);
5407 return align_labels.levels[0].log;
3bbbe009
SL
5408}
5409
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. */
5414void
5415nios2_adjust_reg_alloc_order (void)
5416{
5417 const int cdx_reg_alloc_order[] =
5418 {
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
5429 };
5430
5431 if (TARGET_HAS_CDX)
5432 memcpy (reg_alloc_order, cdx_reg_alloc_order,
5433 sizeof (int) * FIRST_PSEUDO_REGISTER);
5434}
5435
e430824f
CLT
5436\f
5437/* Initialize the GCC target structure. */
5438#undef TARGET_ASM_FUNCTION_PROLOGUE
5439#define TARGET_ASM_FUNCTION_PROLOGUE nios2_asm_function_prologue
5440
5441#undef TARGET_IN_SMALL_DATA_P
5442#define TARGET_IN_SMALL_DATA_P nios2_in_small_data_p
5443
5444#undef TARGET_SECTION_TYPE_FLAGS
5445#define TARGET_SECTION_TYPE_FLAGS nios2_section_type_flags
5446
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
5453
e430824f
CLT
5454#undef TARGET_FUNCTION_OK_FOR_SIBCALL
5455#define TARGET_FUNCTION_OK_FOR_SIBCALL hook_bool_tree_tree_true
5456
5457#undef TARGET_CAN_ELIMINATE
5458#define TARGET_CAN_ELIMINATE nios2_can_eliminate
5459
5460#undef TARGET_FUNCTION_ARG
5461#define TARGET_FUNCTION_ARG nios2_function_arg
5462
5463#undef TARGET_FUNCTION_ARG_ADVANCE
5464#define TARGET_FUNCTION_ARG_ADVANCE nios2_function_arg_advance
5465
76b0cbf8
RS
5466#undef TARGET_FUNCTION_ARG_PADDING
5467#define TARGET_FUNCTION_ARG_PADDING nios2_function_arg_padding
5468
e430824f
CLT
5469#undef TARGET_ARG_PARTIAL_BYTES
5470#define TARGET_ARG_PARTIAL_BYTES nios2_arg_partial_bytes
5471
5472#undef TARGET_TRAMPOLINE_INIT
5473#define TARGET_TRAMPOLINE_INIT nios2_trampoline_init
5474
5475#undef TARGET_FUNCTION_VALUE
5476#define TARGET_FUNCTION_VALUE nios2_function_value
5477
5478#undef TARGET_LIBCALL_VALUE
5479#define TARGET_LIBCALL_VALUE nios2_libcall_value
5480
5481#undef TARGET_FUNCTION_VALUE_REGNO_P
5482#define TARGET_FUNCTION_VALUE_REGNO_P nios2_function_value_regno_p
5483
5484#undef TARGET_RETURN_IN_MEMORY
5485#define TARGET_RETURN_IN_MEMORY nios2_return_in_memory
5486
5487#undef TARGET_PROMOTE_PROTOTYPES
5488#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
5489
5490#undef TARGET_SETUP_INCOMING_VARARGS
5491#define TARGET_SETUP_INCOMING_VARARGS nios2_setup_incoming_varargs
5492
5493#undef TARGET_MUST_PASS_IN_STACK
5494#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
5495
5496#undef TARGET_LEGITIMATE_CONSTANT_P
5497#define TARGET_LEGITIMATE_CONSTANT_P nios2_legitimate_constant_p
5498
5499#undef TARGET_LEGITIMIZE_ADDRESS
5500#define TARGET_LEGITIMIZE_ADDRESS nios2_legitimize_address
5501
98e8dd4d
CLT
5502#undef TARGET_DELEGITIMIZE_ADDRESS
5503#define TARGET_DELEGITIMIZE_ADDRESS nios2_delegitimize_address
5504
e430824f
CLT
5505#undef TARGET_LEGITIMATE_ADDRESS_P
5506#define TARGET_LEGITIMATE_ADDRESS_P nios2_legitimate_address_p
5507
5508#undef TARGET_PREFERRED_RELOAD_CLASS
5509#define TARGET_PREFERRED_RELOAD_CLASS nios2_preferred_reload_class
5510
5511#undef TARGET_RTX_COSTS
5512#define TARGET_RTX_COSTS nios2_rtx_costs
5513
efd5897c
SL
5514#undef TARGET_ADDRESS_COST
5515#define TARGET_ADDRESS_COST nios2_address_cost
5516
e430824f
CLT
5517#undef TARGET_HAVE_TLS
5518#define TARGET_HAVE_TLS TARGET_LINUX_ABI
5519
5520#undef TARGET_CANNOT_FORCE_CONST_MEM
5521#define TARGET_CANNOT_FORCE_CONST_MEM nios2_cannot_force_const_mem
5522
5523#undef TARGET_ASM_OUTPUT_DWARF_DTPREL
5524#define TARGET_ASM_OUTPUT_DWARF_DTPREL nios2_output_dwarf_dtprel
5525
3bbbe009
SL
5526#undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
5527#define TARGET_PRINT_OPERAND_PUNCT_VALID_P nios2_print_operand_punct_valid_p
5528
e430824f
CLT
5529#undef TARGET_PRINT_OPERAND
5530#define TARGET_PRINT_OPERAND nios2_print_operand
5531
5532#undef TARGET_PRINT_OPERAND_ADDRESS
5533#define TARGET_PRINT_OPERAND_ADDRESS nios2_print_operand_address
5534
5535#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
5536#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA nios2_output_addr_const_extra
5537
a9ce4e4a
CLT
5538#undef TARGET_ASM_FILE_END
5539#define TARGET_ASM_FILE_END nios2_asm_file_end
5540
e430824f
CLT
5541#undef TARGET_OPTION_OVERRIDE
5542#define TARGET_OPTION_OVERRIDE nios2_option_override
5543
5544#undef TARGET_OPTION_SAVE
5545#define TARGET_OPTION_SAVE nios2_option_save
5546
5547#undef TARGET_OPTION_RESTORE
5548#define TARGET_OPTION_RESTORE nios2_option_restore
5549
5550#undef TARGET_SET_CURRENT_FUNCTION
5551#define TARGET_SET_CURRENT_FUNCTION nios2_set_current_function
5552
5553#undef TARGET_OPTION_VALID_ATTRIBUTE_P
5554#define TARGET_OPTION_VALID_ATTRIBUTE_P nios2_valid_target_attribute_p
5555
5556#undef TARGET_OPTION_PRAGMA_PARSE
5557#define TARGET_OPTION_PRAGMA_PARSE nios2_pragma_target_parse
5558
5559#undef TARGET_MERGE_DECL_ATTRIBUTES
5560#define TARGET_MERGE_DECL_ATTRIBUTES nios2_merge_decl_attributes
5561
a866d527
CLT
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
5565
5566#undef TARGET_ASM_OUTPUT_MI_THUNK
5567#define TARGET_ASM_OUTPUT_MI_THUNK nios2_asm_output_mi_thunk
5568
3bbbe009
SL
5569#undef TARGET_MACHINE_DEPENDENT_REORG
5570#define TARGET_MACHINE_DEPENDENT_REORG nios2_reorg
5571
58e17cf8
RS
5572#undef TARGET_CONSTANT_ALIGNMENT
5573#define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
5574
e23f3619
SL
5575#undef TARGET_HAVE_SPECULATION_SAFE_VALUE
5576#define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
5577
e430824f
CLT
5578struct gcc_target targetm = TARGET_INITIALIZER;
5579
5580#include "gt-nios2.h"