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