]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/nios2/nios2.cc
Merge remote-tracking branch 'origin/master' into devel/c++-contracts
[thirdparty/gcc.git] / gcc / config / nios2 / nios2.cc
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 2554
b01c075e
JM
2555 if (unspec == UNSPEC_PIC_CALL_SYM)
2556 return gen_rtx_MEM (Pmode, nios2_got_address (sym, unspec));
2557 else
2558 return gen_const_mem (Pmode, nios2_got_address (sym, unspec));
e430824f
CLT
2559}
2560
2561/* Nonzero if the constant value X is a legitimate general operand
2562 when generating PIC code. It is given that flag_pic is on and
2563 that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
2564bool
2565nios2_legitimate_pic_operand_p (rtx x)
2566{
3bbbe009 2567 if (nios2_large_unspec_reloc_p (x))
95ce7613
CLT
2568 return true;
2569
e430824f
CLT
2570 return ! (GET_CODE (x) == SYMBOL_REF
2571 || GET_CODE (x) == LABEL_REF || GET_CODE (x) == CONST);
2572}
2573
2574/* Return TRUE if X is a thread-local symbol. */
2575static bool
2576nios2_tls_symbol_p (rtx x)
2577{
2578 return (targetm.have_tls && GET_CODE (x) == SYMBOL_REF
2579 && SYMBOL_REF_TLS_MODEL (x) != 0);
2580}
2581
2582/* Legitimize addresses that are CONSTANT_P expressions. */
2583static rtx
2584nios2_legitimize_constant_address (rtx addr)
2585{
2586 rtx base, offset;
2587 split_const (addr, &base, &offset);
2588
2589 if (nios2_tls_symbol_p (base))
2590 base = nios2_legitimize_tls_address (base);
2591 else if (flag_pic)
a866d527 2592 base = nios2_load_pic_address (base, UNSPEC_PIC_SYM, NULL_RTX);
df8ceba6 2593 else if (!nios2_large_constant_allowed ()
82348675
SL
2594 && nios2_symbolic_constant_p (addr))
2595 return nios2_split_large_constant (addr, gen_reg_rtx (Pmode));
df8ceba6
SL
2596 else if (CONST_INT_P (addr))
2597 {
2598 HOST_WIDE_INT val = INTVAL (addr);
2599 if (SMALL_INT (val))
2600 /* Use r0-relative addressing. */
2601 return addr;
2602 else if (!nios2_large_constant_allowed ())
2603 /* Split into high/lo pair. */
2604 return nios2_split_large_constant (addr, gen_reg_rtx (Pmode));
2605 }
e430824f
CLT
2606 else
2607 return addr;
2608
2609 if (offset != const0_rtx)
2610 {
2611 gcc_assert (can_create_pseudo_p ());
2612 return gen_rtx_PLUS (Pmode, force_reg (Pmode, base),
2613 (CONST_INT_P (offset)
2614 ? (SMALL_INT (INTVAL (offset))
2615 ? offset : force_reg (Pmode, offset))
2616 : offset));
2617 }
2618 return base;
2619}
2620
2621/* Implement TARGET_LEGITIMIZE_ADDRESS. */
2622static rtx
2623nios2_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
ef4bddc2 2624 machine_mode mode ATTRIBUTE_UNUSED)
e430824f 2625{
82348675
SL
2626 rtx op0, op1;
2627
e430824f
CLT
2628 if (CONSTANT_P (x))
2629 return nios2_legitimize_constant_address (x);
2630
82348675
SL
2631 /* Remaining cases all involve something + a constant. */
2632 if (GET_CODE (x) != PLUS)
2633 return x;
2634
2635 op0 = XEXP (x, 0);
2636 op1 = XEXP (x, 1);
2637
efd5897c
SL
2638 /* Target-independent code turns (exp + constant) into plain
2639 register indirect. Although subsequent optimization passes will
2640 eventually sort that out, ivopts uses the unoptimized form for
2641 computing its cost model, so we get better results by generating
2642 the correct form from the start. */
2643 if (nios2_valid_addr_offset_p (op1))
2644 return gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), copy_rtx (op1));
2645
82348675 2646 /* We may need to split symbolic constants now. */
efd5897c 2647 else if (nios2_symbolic_constant_p (op1))
82348675 2648 {
df8ceba6 2649 if (nios2_large_constant_allowed ())
82348675
SL
2650 return gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), copy_rtx (op1));
2651 else
2652 return nios2_split_plus_large_constant (op0, op1);
2653 }
2654
e430824f
CLT
2655 /* For the TLS LE (Local Exec) model, the compiler may try to
2656 combine constant offsets with unspec relocs, creating address RTXs
2657 looking like this:
2658 (plus:SI (reg:SI 23 r23)
2659 (const:SI
2660 (plus:SI
2661 (unspec:SI [(symbol_ref:SI ("var"))] UNSPEC_ADD_TLS_LE)
2662 (const_int 48 [0x30]))))
2663
2664 This usually happens when 'var' is a thread-local struct variable,
2665 and access of a field in var causes the addend.
2666
2667 We typically want this combining, so transform the above into this
2668 form, which is allowed:
2669 (plus:SI (reg:SI 23 r23)
2670 (const:SI
2671 (unspec:SI
2672 [(const:SI
2673 (plus:SI (symbol_ref:SI ("var"))
2674 (const_int 48 [0x30])))] UNSPEC_ADD_TLS_LE)))
2675
2676 Which will be output as '%tls_le(var+48)(r23)' in assembly. */
82348675 2677 else if (GET_CODE (op1) == CONST)
e430824f 2678 {
b062ae05 2679 rtx unspec, offset;
82348675 2680 split_const (op1, &unspec, &offset);
e430824f 2681 if (GET_CODE (unspec) == UNSPEC
95ce7613 2682 && !nios2_large_offset_p (XINT (unspec, 1))
e430824f
CLT
2683 && offset != const0_rtx)
2684 {
82348675 2685 rtx reg = force_reg (Pmode, op0);
e430824f
CLT
2686 unspec = copy_rtx (unspec);
2687 XVECEXP (unspec, 0, 0)
2688 = plus_constant (Pmode, XVECEXP (unspec, 0, 0), INTVAL (offset));
82348675 2689 return gen_rtx_PLUS (Pmode, reg, gen_rtx_CONST (Pmode, unspec));
e430824f
CLT
2690 }
2691 }
2692
2693 return x;
2694}
2695
98e8dd4d
CLT
2696static rtx
2697nios2_delegitimize_address (rtx x)
2698{
2699 x = delegitimize_mem_from_attrs (x);
2700
2701 if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == UNSPEC)
2702 {
2703 switch (XINT (XEXP (x, 0), 1))
2704 {
2705 case UNSPEC_PIC_SYM:
2706 case UNSPEC_PIC_CALL_SYM:
2707 case UNSPEC_PIC_GOTOFF_SYM:
2708 case UNSPEC_ADD_TLS_GD:
2709 case UNSPEC_ADD_TLS_LDM:
2710 case UNSPEC_LOAD_TLS_IE:
2711 case UNSPEC_ADD_TLS_LE:
2712 x = XVECEXP (XEXP (x, 0), 0, 0);
030b9d90 2713 gcc_assert (CONSTANT_P (x));
98e8dd4d
CLT
2714 break;
2715 }
2716 }
2717 return x;
2718}
2719
e430824f 2720/* Main expander function for RTL moves. */
9d07490f 2721bool
ef4bddc2 2722nios2_emit_move_sequence (rtx *operands, machine_mode mode)
e430824f
CLT
2723{
2724 rtx to = operands[0];
2725 rtx from = operands[1];
2726
2727 if (!register_operand (to, mode) && !reg_or_0_operand (from, mode))
2728 {
2729 gcc_assert (can_create_pseudo_p ());
2730 from = copy_to_mode_reg (mode, from);
2731 }
2732
3bbbe009
SL
2733 if (CONSTANT_P (from))
2734 {
2735 if (CONST_INT_P (from))
2736 {
2737 if (!SMALL_INT (INTVAL (from))
2738 && !SMALL_INT_UNSIGNED (INTVAL (from))
2739 && !UPPER16_INT (INTVAL (from)))
2740 {
2741 HOST_WIDE_INT high = (INTVAL (from) + 0x8000) & ~0xffff;
2742 HOST_WIDE_INT low = INTVAL (from) & 0xffff;
2743 emit_move_insn (to, gen_int_mode (high, SImode));
2744 emit_insn (gen_add2_insn (to, gen_int_mode (low, HImode)));
2745 set_unique_reg_note (get_last_insn (), REG_EQUAL,
2746 copy_rtx (from));
2747 return true;
2748 }
2749 }
1cef1159
SL
2750 else if (gprel_constant_p (from) || r0rel_constant_p (from))
2751 /* Handled directly by movsi_internal as gp + offset
2752 or r0 + offset. */
82348675
SL
2753 ;
2754 else if (nios2_large_constant_p (from))
2755 /* This case covers either a regular symbol reference or an UNSPEC
2756 representing a 32-bit offset. We split the former
2757 only conditionally and the latter always. */
3bbbe009 2758 {
df8ceba6 2759 if (!nios2_large_constant_allowed ()
82348675
SL
2760 || nios2_large_unspec_reloc_p (from))
2761 {
2762 rtx lo = nios2_split_large_constant (from, to);
2763 emit_insn (gen_rtx_SET (to, lo));
2764 set_unique_reg_note (get_last_insn (), REG_EQUAL,
2765 copy_rtx (operands[1]));
2766 return true;
2767 }
2768 }
2769 else
2770 /* This is a TLS or PIC symbol. */
2771 {
2772 from = nios2_legitimize_constant_address (from);
3bbbe009
SL
2773 if (CONSTANT_P (from))
2774 {
1cf4526c
SL
2775 emit_insn (gen_rtx_SET (to,
2776 gen_rtx_HIGH (Pmode, copy_rtx (from))));
3bbbe009
SL
2777 emit_insn (gen_rtx_SET (to, gen_rtx_LO_SUM (Pmode, to, from)));
2778 set_unique_reg_note (get_last_insn (), REG_EQUAL,
2779 copy_rtx (operands[1]));
2780 return true;
2781 }
2782 }
2783 }
e430824f
CLT
2784
2785 operands[0] = to;
2786 operands[1] = from;
9d07490f 2787 return false;
e430824f
CLT
2788}
2789
2790/* The function with address *ADDR is being called. If the address
2791 needs to be loaded from the GOT, emit the instruction to do so and
a866d527
CLT
2792 update *ADDR to point to the rtx for the loaded value.
2793 If REG != NULL_RTX, it is used as the target/scratch register in the
2794 GOT address calculation. */
e430824f 2795void
a866d527 2796nios2_adjust_call_address (rtx *call_op, rtx reg)
e430824f 2797{
a866d527
CLT
2798 if (MEM_P (*call_op))
2799 call_op = &XEXP (*call_op, 0);
2800
2801 rtx addr = *call_op;
e430824f
CLT
2802 if (flag_pic && CONSTANT_P (addr))
2803 {
a866d527
CLT
2804 rtx tmp = reg ? reg : NULL_RTX;
2805 if (!reg)
2806 reg = gen_reg_rtx (Pmode);
2807 addr = nios2_load_pic_address (addr, UNSPEC_PIC_CALL_SYM, tmp);
f7df4a84 2808 emit_insn (gen_rtx_SET (reg, addr));
a866d527 2809 *call_op = reg;
e430824f
CLT
2810 }
2811}
2812
2813\f
2814/* Output assembly language related definitions. */
2815
3bbbe009
SL
2816/* Implement TARGET_PRINT_OPERAND_PUNCT_VALID_P. */
2817static bool
2818nios2_print_operand_punct_valid_p (unsigned char code)
2819{
2820 return (code == '.' || code == '!');
2821}
2822
2823
e430824f
CLT
2824/* Print the operand OP to file stream FILE modified by LETTER.
2825 LETTER can be one of:
2826
3bbbe009
SL
2827 i: print i/hi/ui suffixes (used for mov instruction variants),
2828 when OP is the appropriate immediate operand.
2829
2830 u: like 'i', except without "ui" suffix case (used for cmpgeu/cmpltu)
2831
2832 o: print "io" if OP needs volatile access (due to TARGET_BYPASS_CACHE
2833 or TARGET_BYPASS_CACHE_VOLATILE).
2834
2835 x: print i/hi/ci/chi suffixes for the and instruction,
2836 when OP is the appropriate immediate operand.
2837
2838 z: prints the third register immediate operand in assembly
2839 instructions. Outputs const0_rtx as the 'zero' register
2840 instead of '0'.
2841
2842 y: same as 'z', but for specifically for logical instructions,
2843 where the processing for immediates are slightly different.
2844
e430824f
CLT
2845 H: for %hiadj
2846 L: for %lo
e430824f
CLT
2847 D: for the upper 32-bits of a 64-bit double value
2848 R: prints reverse condition.
3bbbe009
SL
2849 A: prints (reg) operand for ld[s]ex and st[s]ex.
2850
2851 .: print .n suffix for 16-bit instructions.
2852 !: print r.n suffix for 16-bit instructions. Used for jmpr.n.
e430824f
CLT
2853*/
2854static void
2855nios2_print_operand (FILE *file, rtx op, int letter)
2856{
2857
3bbbe009
SL
2858 /* First take care of the format letters that just insert a string
2859 into the output stream. */
e430824f
CLT
2860 switch (letter)
2861 {
3bbbe009
SL
2862 case '.':
2863 if (current_output_insn && get_attr_length (current_output_insn) == 2)
2864 fprintf (file, ".n");
2865 return;
2866
2867 case '!':
2868 if (current_output_insn && get_attr_length (current_output_insn) == 2)
2869 fprintf (file, "r.n");
2870 return;
2871
2872 case 'x':
2873 if (CONST_INT_P (op))
2874 {
2875 HOST_WIDE_INT val = INTVAL (op);
2876 HOST_WIDE_INT low = val & 0xffff;
2877 HOST_WIDE_INT high = (val >> 16) & 0xffff;
2878
2879 if (val != 0)
2880 {
2881 if (high != 0)
2882 {
2883 if (low != 0)
2884 {
2885 gcc_assert (TARGET_ARCH_R2);
2886 if (high == 0xffff)
2887 fprintf (file, "c");
2888 else if (low == 0xffff)
2889 fprintf (file, "ch");
2890 else
2891 gcc_unreachable ();
2892 }
2893 else
2894 fprintf (file, "h");
2895 }
2896 fprintf (file, "i");
2897 }
2898 }
2899 return;
2900
2901 case 'u':
e430824f 2902 case 'i':
3bbbe009
SL
2903 if (CONST_INT_P (op))
2904 {
2905 HOST_WIDE_INT val = INTVAL (op);
2906 HOST_WIDE_INT low = val & 0xffff;
2907 HOST_WIDE_INT high = (val >> 16) & 0xffff;
2908 if (val != 0)
2909 {
2910 if (low == 0 && high != 0)
2911 fprintf (file, "h");
2912 else if (high == 0 && (low & 0x8000) != 0 && letter != 'u')
2913 fprintf (file, "u");
2914 }
2915 }
e430824f
CLT
2916 if (CONSTANT_P (op) && op != const0_rtx)
2917 fprintf (file, "i");
2918 return;
2919
2920 case 'o':
2921 if (GET_CODE (op) == MEM
2922 && ((MEM_VOLATILE_P (op) && TARGET_BYPASS_CACHE_VOLATILE)
2923 || TARGET_BYPASS_CACHE))
3bbbe009
SL
2924 {
2925 gcc_assert (current_output_insn
2926 && get_attr_length (current_output_insn) == 4);
2927 fprintf (file, "io");
2928 }
e430824f
CLT
2929 return;
2930
2931 default:
2932 break;
2933 }
2934
3bbbe009 2935 /* Handle comparison operator names. */
e430824f
CLT
2936 if (comparison_operator (op, VOIDmode))
2937 {
2938 enum rtx_code cond = GET_CODE (op);
2939 if (letter == 0)
2940 {
2941 fprintf (file, "%s", GET_RTX_NAME (cond));
2942 return;
2943 }
2944 if (letter == 'R')
2945 {
2946 fprintf (file, "%s", GET_RTX_NAME (reverse_condition (cond)));
2947 return;
2948 }
2949 }
2950
3bbbe009 2951 /* Now handle the cases where we actually need to format an operand. */
e430824f
CLT
2952 switch (GET_CODE (op))
2953 {
2954 case REG:
3bbbe009 2955 if (letter == 0 || letter == 'z' || letter == 'y')
e430824f
CLT
2956 {
2957 fprintf (file, "%s", reg_names[REGNO (op)]);
2958 return;
2959 }
2960 else if (letter == 'D')
2961 {
2962 fprintf (file, "%s", reg_names[REGNO (op)+1]);
2963 return;
2964 }
2965 break;
2966
2967 case CONST_INT:
3bbbe009
SL
2968 {
2969 rtx int_rtx = op;
2970 HOST_WIDE_INT val = INTVAL (int_rtx);
2971 HOST_WIDE_INT low = val & 0xffff;
2972 HOST_WIDE_INT high = (val >> 16) & 0xffff;
2973
2974 if (letter == 'y')
2975 {
2976 if (val == 0)
2977 fprintf (file, "zero");
2978 else
2979 {
2980 if (high != 0)
2981 {
2982 if (low != 0)
2983 {
2984 gcc_assert (TARGET_ARCH_R2);
2985 if (high == 0xffff)
2986 /* andci. */
2987 int_rtx = gen_int_mode (low, SImode);
2988 else if (low == 0xffff)
2989 /* andchi. */
2990 int_rtx = gen_int_mode (high, SImode);
2991 else
2992 gcc_unreachable ();
2993 }
2994 else
2995 /* andhi. */
2996 int_rtx = gen_int_mode (high, SImode);
2997 }
2998 else
2999 /* andi. */
3000 int_rtx = gen_int_mode (low, SImode);
3001 output_addr_const (file, int_rtx);
3002 }
3003 return;
3004 }
3005 else if (letter == 'z')
3006 {
3007 if (val == 0)
3008 fprintf (file, "zero");
3009 else
3010 {
3011 if (low == 0 && high != 0)
3012 int_rtx = gen_int_mode (high, SImode);
3013 else if (low != 0)
3014 {
3015 gcc_assert (high == 0 || high == 0xffff);
3016 int_rtx = gen_int_mode (low, high == 0 ? SImode : HImode);
3017 }
3018 else
3019 gcc_unreachable ();
3020 output_addr_const (file, int_rtx);
3021 }
3022 return;
3023 }
3024 }
e430824f 3025
e430824f
CLT
3026 /* Else, fall through. */
3027
3028 case CONST:
3029 case LABEL_REF:
3030 case SYMBOL_REF:
3031 case CONST_DOUBLE:
3032 if (letter == 0 || letter == 'z')
3033 {
3034 output_addr_const (file, op);
3035 return;
3036 }
95ce7613
CLT
3037 else if (letter == 'H' || letter == 'L')
3038 {
3039 fprintf (file, "%%");
3040 if (GET_CODE (op) == CONST
3041 && GET_CODE (XEXP (op, 0)) == UNSPEC)
3042 {
3043 rtx unspec = XEXP (op, 0);
3044 int unspec_reloc = XINT (unspec, 1);
3045 gcc_assert (nios2_large_offset_p (unspec_reloc));
3046 fprintf (file, "%s_", nios2_unspec_reloc_name (unspec_reloc));
3047 op = XVECEXP (unspec, 0, 0);
3048 }
3049 fprintf (file, letter == 'H' ? "hiadj(" : "lo(");
e430824f
CLT
3050 output_addr_const (file, op);
3051 fprintf (file, ")");
3052 return;
95ce7613 3053 }
e430824f
CLT
3054 break;
3055
3056 case SUBREG:
3057 case MEM:
3bbbe009
SL
3058 if (letter == 'A')
3059 {
3060 /* Address of '(reg)' form, with no index. */
3061 fprintf (file, "(%s)", reg_names[REGNO (XEXP (op, 0))]);
3062 return;
3063 }
e430824f
CLT
3064 if (letter == 0)
3065 {
cc8ca59e 3066 output_address (VOIDmode, op);
e430824f
CLT
3067 return;
3068 }
3069 break;
3070
3071 case CODE_LABEL:
3072 if (letter == 0)
3073 {
3074 output_addr_const (file, op);
3075 return;
3076 }
3077 break;
3078
3079 default:
3080 break;
3081 }
3082
82348675 3083 debug_rtx (op);
e430824f
CLT
3084 output_operand_lossage ("Unsupported operand for code '%c'", letter);
3085 gcc_unreachable ();
3086}
3087
3088/* Return true if this is a GP-relative accessible reference. */
7dcc7195 3089bool
e430824f
CLT
3090gprel_constant_p (rtx op)
3091{
3092 if (GET_CODE (op) == SYMBOL_REF
3093 && nios2_symbol_ref_in_small_data_p (op))
3094 return true;
3095 else if (GET_CODE (op) == CONST
3096 && GET_CODE (XEXP (op, 0)) == PLUS)
3097 return gprel_constant_p (XEXP (XEXP (op, 0), 0));
3098
3099 return false;
3100}
3101
1cef1159
SL
3102/* Likewise if this is a zero-relative accessible reference. */
3103bool
3104r0rel_constant_p (rtx op)
3105{
3106 if (GET_CODE (op) == SYMBOL_REF
3107 && nios2_symbol_ref_in_r0rel_data_p (op))
3108 return true;
3109 else if (GET_CODE (op) == CONST
3110 && GET_CODE (XEXP (op, 0)) == PLUS)
3111 return r0rel_constant_p (XEXP (XEXP (op, 0), 0));
df8ceba6
SL
3112 else if (GET_CODE (op) == CONST_INT
3113 && SMALL_INT (INTVAL (op)))
3114 return true;
1cef1159
SL
3115
3116 return false;
3117}
3118
e430824f
CLT
3119/* Return the name string for a supported unspec reloc offset. */
3120static const char *
3121nios2_unspec_reloc_name (int unspec)
3122{
3123 switch (unspec)
3124 {
3125 case UNSPEC_PIC_SYM:
3126 return "got";
3127 case UNSPEC_PIC_CALL_SYM:
3128 return "call";
95ce7613
CLT
3129 case UNSPEC_PIC_GOTOFF_SYM:
3130 return "gotoff";
e430824f
CLT
3131 case UNSPEC_LOAD_TLS_IE:
3132 return "tls_ie";
3133 case UNSPEC_ADD_TLS_LE:
3134 return "tls_le";
3135 case UNSPEC_ADD_TLS_GD:
3136 return "tls_gd";
3137 case UNSPEC_ADD_TLS_LDM:
3138 return "tls_ldm";
3139 case UNSPEC_ADD_TLS_LDO:
3140 return "tls_ldo";
3141 default:
3142 return NULL;
3143 }
3144}
3145
e430824f
CLT
3146/* Implement TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */
3147static bool
3148nios2_output_addr_const_extra (FILE *file, rtx op)
3149{
3150 const char *name;
3151 gcc_assert (GET_CODE (op) == UNSPEC);
3152
3153 /* Support for printing out const unspec relocations. */
3154 name = nios2_unspec_reloc_name (XINT (op, 1));
3155 if (name)
3156 {
3157 fprintf (file, "%%%s(", name);
3158 output_addr_const (file, XVECEXP (op, 0, 0));
3159 fprintf (file, ")");
3160 return true;
3161 }
3162 return false;
3163}
3164
3165/* Implement TARGET_PRINT_OPERAND_ADDRESS. */
3166static void
cc8ca59e 3167nios2_print_operand_address (FILE *file, machine_mode mode, rtx op)
e430824f
CLT
3168{
3169 switch (GET_CODE (op))
3170 {
3171 case CONST:
3172 case CONST_INT:
3173 case LABEL_REF:
3174 case CONST_DOUBLE:
3175 case SYMBOL_REF:
3176 if (gprel_constant_p (op))
3177 {
3178 fprintf (file, "%%gprel(");
3179 output_addr_const (file, op);
3180 fprintf (file, ")(%s)", reg_names[GP_REGNO]);
3181 return;
3182 }
1cef1159
SL
3183 else if (r0rel_constant_p (op))
3184 {
df8ceba6
SL
3185 if (CONST_INT_P (op))
3186 {
3187 output_addr_const (file, op);
3188 fprintf (file, "(r0)");
3189 return;
3190 }
3191 else
3192 {
3193 fprintf (file, "%%lo(");
3194 output_addr_const (file, op);
3195 fprintf (file, ")(r0)");
3196 return;
3197 }
3198 }
e430824f
CLT
3199 break;
3200
3201 case PLUS:
3202 {
3203 rtx op0 = XEXP (op, 0);
3204 rtx op1 = XEXP (op, 1);
3205
3206 if (REG_P (op0) && CONSTANT_P (op1))
3207 {
3208 output_addr_const (file, op1);
3209 fprintf (file, "(%s)", reg_names[REGNO (op0)]);
3210 return;
3211 }
3212 else if (REG_P (op1) && CONSTANT_P (op0))
3213 {
3214 output_addr_const (file, op0);
3215 fprintf (file, "(%s)", reg_names[REGNO (op1)]);
3216 return;
3217 }
3218 }
3219 break;
3220
82348675
SL
3221 case LO_SUM:
3222 {
3223 rtx op0 = XEXP (op, 0);
3224 rtx op1 = XEXP (op, 1);
3225
3226 if (REG_P (op0) && CONSTANT_P (op1))
3227 {
3228 nios2_print_operand (file, op1, 'L');
3229 fprintf (file, "(%s)", reg_names[REGNO (op0)]);
3230 return;
3231 }
3232 }
3233 break;
3234
e430824f
CLT
3235 case REG:
3236 fprintf (file, "0(%s)", reg_names[REGNO (op)]);
3237 return;
3238
3239 case MEM:
3240 {
3241 rtx base = XEXP (op, 0);
cc8ca59e 3242 nios2_print_operand_address (file, mode, base);
e430824f
CLT
3243 return;
3244 }
3245 default:
3246 break;
3247 }
3248
3249 fprintf (stderr, "Missing way to print address\n");
3250 debug_rtx (op);
3251 gcc_unreachable ();
3252}
3253
3254/* Implement TARGET_ASM_OUTPUT_DWARF_DTPREL. */
3255static void
3256nios2_output_dwarf_dtprel (FILE *file, int size, rtx x)
3257{
3258 gcc_assert (size == 4);
3259 fprintf (file, "\t.4byte\t%%tls_ldo(");
3260 output_addr_const (file, x);
3261 fprintf (file, ")");
3262}
3263
a9ce4e4a
CLT
3264/* Implemet TARGET_ASM_FILE_END. */
3265
3266static void
3267nios2_asm_file_end (void)
3268{
3269 /* The Nios II Linux stack is mapped non-executable by default, so add a
3270 .note.GNU-stack section for switching to executable stacks only when
3271 trampolines are generated. */
3272 if (TARGET_LINUX_ABI && trampolines_created)
3273 file_end_indicate_exec_stack ();
3274}
3275
e430824f
CLT
3276/* Implement TARGET_ASM_FUNCTION_PROLOGUE. */
3277static void
42776416 3278nios2_asm_function_prologue (FILE *file)
e430824f
CLT
3279{
3280 if (flag_verbose_asm || flag_debug_asm)
3281 {
3282 nios2_compute_frame_layout ();
3283 nios2_dump_frame_layout (file);
3284 }
3285}
3286
3287/* Emit assembly of custom FPU instructions. */
3288const char *
3289nios2_fpu_insn_asm (enum n2fpu_code code)
3290{
3291 static char buf[256];
3292 const char *op1, *op2, *op3;
3293 int ln = 256, n = 0;
3294
3295 int N = N2FPU_N (code);
3296 int num_operands = N2FPU (code).num_operands;
3297 const char *insn_name = N2FPU_NAME (code);
3298 tree ftype = nios2_ftype (N2FPU_FTCODE (code));
ef4bddc2
RS
3299 machine_mode dst_mode = TYPE_MODE (TREE_TYPE (ftype));
3300 machine_mode src_mode = TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (ftype)));
e430824f
CLT
3301
3302 /* Prepare X register for DF input operands. */
3303 if (GET_MODE_SIZE (src_mode) == 8 && num_operands == 3)
3304 n = snprintf (buf, ln, "custom\t%d, zero, %%1, %%D1 # fwrx %%1\n\t",
3305 N2FPU_N (n2fpu_fwrx));
3306
3307 if (src_mode == SFmode)
3308 {
3309 if (dst_mode == VOIDmode)
3310 {
3311 /* The fwry case. */
3312 op1 = op3 = "zero";
3313 op2 = "%0";
3314 num_operands -= 1;
3315 }
3316 else
3317 {
aad8816f
SZ
3318 op1 = (dst_mode == DFmode ? "%D0" : "%0");
3319 op2 = "%1";
e430824f
CLT
3320 op3 = (num_operands == 2 ? "zero" : "%2");
3321 }
3322 }
3323 else if (src_mode == DFmode)
3324 {
3325 if (dst_mode == VOIDmode)
3326 {
3327 /* The fwrx case. */
3328 op1 = "zero";
3329 op2 = "%0";
3330 op3 = "%D0";
3331 num_operands -= 1;
3332 }
3333 else
3334 {
3335 op1 = (dst_mode == DFmode ? "%D0" : "%0");
3336 op2 = (num_operands == 2 ? "%1" : "%2");
3337 op3 = (num_operands == 2 ? "%D1" : "%D2");
3338 }
3339 }
3340 else if (src_mode == VOIDmode)
3341 {
3342 /* frdxlo, frdxhi, frdy cases. */
3343 gcc_assert (dst_mode == SFmode);
3344 op1 = "%0";
3345 op2 = op3 = "zero";
3346 }
3347 else if (src_mode == SImode)
3348 {
3349 /* Conversion operators. */
3350 gcc_assert (num_operands == 2);
3351 op1 = (dst_mode == DFmode ? "%D0" : "%0");
3352 op2 = "%1";
3353 op3 = "zero";
3354 }
3355 else
3356 gcc_unreachable ();
3357
3358 /* Main instruction string. */
3359 n += snprintf (buf + n, ln - n, "custom\t%d, %s, %s, %s # %s %%0%s%s",
3360 N, op1, op2, op3, insn_name,
3361 (num_operands >= 2 ? ", %1" : ""),
3362 (num_operands == 3 ? ", %2" : ""));
3363
3364 /* Extraction of Y register for DF results. */
3365 if (dst_mode == DFmode)
3366 snprintf (buf + n, ln - n, "\n\tcustom\t%d, %%0, zero, zero # frdy %%0",
3367 N2FPU_N (n2fpu_frdy));
3368 return buf;
3369}
3370
3371\f
3372
3373/* Function argument related. */
3374
3375/* Define where to put the arguments to a function. Value is zero to
3376 push the argument on the stack, or a hard register in which to
3377 store the argument.
3378
e430824f
CLT
3379 CUM is a variable of type CUMULATIVE_ARGS which gives info about
3380 the preceding args and about the function being called.
6783fdb7 3381 ARG is a description of the argument. */
e430824f
CLT
3382
3383static rtx
6783fdb7 3384nios2_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
e430824f
CLT
3385{
3386 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
3387 rtx return_rtx = NULL_RTX;
3388
3389 if (cum->regs_used < NUM_ARG_REGS)
6783fdb7 3390 return_rtx = gen_rtx_REG (arg.mode, FIRST_ARG_REGNO + cum->regs_used);
e430824f
CLT
3391
3392 return return_rtx;
3393}
3394
3395/* Return number of bytes, at the beginning of the argument, that must be
3396 put in registers. 0 is the argument is entirely in registers or entirely
3397 in memory. */
3398
3399static int
a7c81bc1 3400nios2_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
e430824f
CLT
3401{
3402 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
a7c81bc1
RS
3403 HOST_WIDE_INT param_size = arg.promoted_size_in_bytes ();
3404 gcc_assert (param_size >= 0);
e430824f
CLT
3405
3406 /* Convert to words (round up). */
3407 param_size = (UNITS_PER_WORD - 1 + param_size) / UNITS_PER_WORD;
3408
3409 if (cum->regs_used < NUM_ARG_REGS
3410 && cum->regs_used + param_size > NUM_ARG_REGS)
3411 return (NUM_ARG_REGS - cum->regs_used) * UNITS_PER_WORD;
3412
3413 return 0;
3414}
3415
6930c98c 3416/* Update the data in CUM to advance over argument ARG. */
e430824f
CLT
3417
3418static void
6930c98c
RS
3419nios2_function_arg_advance (cumulative_args_t cum_v,
3420 const function_arg_info &arg)
e430824f
CLT
3421{
3422 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
6930c98c
RS
3423 HOST_WIDE_INT param_size = arg.promoted_size_in_bytes ();
3424 gcc_assert (param_size >= 0);
e430824f
CLT
3425
3426 /* Convert to words (round up). */
3427 param_size = (UNITS_PER_WORD - 1 + param_size) / UNITS_PER_WORD;
3428
3429 if (cum->regs_used + param_size > NUM_ARG_REGS)
3430 cum->regs_used = NUM_ARG_REGS;
3431 else
3432 cum->regs_used += param_size;
3433}
3434
76b0cbf8 3435static pad_direction
ef4bddc2 3436nios2_function_arg_padding (machine_mode mode, const_tree type)
e430824f
CLT
3437{
3438 /* On little-endian targets, the first byte of every stack argument
3439 is passed in the first byte of the stack slot. */
3440 if (!BYTES_BIG_ENDIAN)
76b0cbf8 3441 return PAD_UPWARD;
e430824f
CLT
3442
3443 /* Otherwise, integral types are padded downward: the last byte of a
3444 stack argument is passed in the last byte of the stack slot. */
3445 if (type != 0
3446 ? INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)
3447 : GET_MODE_CLASS (mode) == MODE_INT)
76b0cbf8 3448 return PAD_DOWNWARD;
e430824f
CLT
3449
3450 /* Arguments smaller than a stack slot are padded downward. */
3451 if (mode != BLKmode)
76b0cbf8
RS
3452 return (GET_MODE_BITSIZE (mode) >= PARM_BOUNDARY
3453 ? PAD_UPWARD : PAD_DOWNWARD);
e430824f
CLT
3454
3455 return ((int_size_in_bytes (type) >= (PARM_BOUNDARY / BITS_PER_UNIT))
76b0cbf8 3456 ? PAD_UPWARD : PAD_DOWNWARD);
e430824f
CLT
3457}
3458
76b0cbf8 3459pad_direction
ef4bddc2 3460nios2_block_reg_padding (machine_mode mode, tree type,
e430824f
CLT
3461 int first ATTRIBUTE_UNUSED)
3462{
3463 return nios2_function_arg_padding (mode, type);
3464}
3465
3466/* Emit RTL insns to initialize the variable parts of a trampoline.
3467 FNADDR is an RTX for the address of the function's pure code.
3468 CXT is an RTX for the static chain value for the function.
3469 On Nios II, we handle this by a library call. */
3470static void
3471nios2_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
3472{
3473 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
3474 rtx ctx_reg = force_reg (Pmode, cxt);
3475 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
3476
3477 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
db69559b 3478 LCT_NORMAL, VOIDmode, addr, Pmode, fnaddr, Pmode,
e430824f
CLT
3479 ctx_reg, Pmode);
3480}
3481
3482/* Implement TARGET_FUNCTION_VALUE. */
3483static rtx
3484nios2_function_value (const_tree ret_type, const_tree fn ATTRIBUTE_UNUSED,
3485 bool outgoing ATTRIBUTE_UNUSED)
3486{
3487 return gen_rtx_REG (TYPE_MODE (ret_type), FIRST_RETVAL_REGNO);
3488}
3489
3490/* Implement TARGET_LIBCALL_VALUE. */
3491static rtx
ef4bddc2 3492nios2_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
e430824f
CLT
3493{
3494 return gen_rtx_REG (mode, FIRST_RETVAL_REGNO);
3495}
3496
3497/* Implement TARGET_FUNCTION_VALUE_REGNO_P. */
3498static bool
3499nios2_function_value_regno_p (const unsigned int regno)
3500{
3501 return regno == FIRST_RETVAL_REGNO;
3502}
3503
3504/* Implement TARGET_RETURN_IN_MEMORY. */
3505static bool
3506nios2_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
3507{
3508 return (int_size_in_bytes (type) > (2 * UNITS_PER_WORD)
3509 || int_size_in_bytes (type) == -1);
3510}
3511
3512/* TODO: It may be possible to eliminate the copyback and implement
3513 own va_arg type. */
3514static void
3515nios2_setup_incoming_varargs (cumulative_args_t cum_v,
e7056ca4
RS
3516 const function_arg_info &arg,
3517 int *pretend_size, int second_time)
e430824f
CLT
3518{
3519 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
3520 CUMULATIVE_ARGS local_cum;
3521 cumulative_args_t local_cum_v = pack_cumulative_args (&local_cum);
3522 int regs_to_push;
3523 int pret_size;
3524
c3ff2812 3525 cfun->machine->uses_anonymous_args = 1;
e430824f 3526 local_cum = *cum;
4fe34cdc
JM
3527 if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
3528 nios2_function_arg_advance (local_cum_v, arg);
e430824f
CLT
3529
3530 regs_to_push = NUM_ARG_REGS - local_cum.regs_used;
3531
c3ff2812
SL
3532 /* If we can use CDX stwm to push the arguments on the stack,
3533 nios2_expand_prologue will do that instead. */
3534 if (!TARGET_HAS_CDX && !second_time && regs_to_push > 0)
e430824f
CLT
3535 {
3536 rtx ptr = virtual_incoming_args_rtx;
3537 rtx mem = gen_rtx_MEM (BLKmode, ptr);
3538 emit_insn (gen_blockage ());
3539 move_block_from_reg (local_cum.regs_used + FIRST_ARG_REGNO, mem,
3540 regs_to_push);
3541 emit_insn (gen_blockage ());
3542 }
3543
3544 pret_size = regs_to_push * UNITS_PER_WORD;
3545 if (pret_size)
3546 *pretend_size = pret_size;
3547}
3548
3549\f
3550
3551/* Init FPU builtins. */
3552static void
3553nios2_init_fpu_builtins (int start_code)
3554{
3555 tree fndecl;
3556 char builtin_name[64] = "__builtin_custom_";
3557 unsigned int i, n = strlen ("__builtin_custom_");
3558
3559 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
3560 {
3561 snprintf (builtin_name + n, sizeof (builtin_name) - n,
3562 "%s", N2FPU_NAME (i));
3563 fndecl =
3564 add_builtin_function (builtin_name, nios2_ftype (N2FPU_FTCODE (i)),
3565 start_code + i, BUILT_IN_MD, NULL, NULL_TREE);
3566 nios2_register_builtin_fndecl (start_code + i, fndecl);
3567 }
3568}
3569
3570/* Helper function for expanding FPU builtins. */
3571static rtx
3572nios2_expand_fpu_builtin (tree exp, unsigned int code, rtx target)
3573{
3574 struct expand_operand ops[MAX_RECOG_OPERANDS];
3575 enum insn_code icode = N2FPU_ICODE (code);
3576 int nargs, argno, opno = 0;
3577 int num_operands = N2FPU (code).num_operands;
ef4bddc2 3578 machine_mode dst_mode = TYPE_MODE (TREE_TYPE (exp));
e430824f
CLT
3579 bool has_target_p = (dst_mode != VOIDmode);
3580
3581 if (N2FPU_N (code) < 0)
40fecdd6 3582 fatal_error (input_location,
5074c6fa
SL
3583 "cannot call %<__builtin_custom_%s%> without specifying "
3584 "switch %<-mcustom-%s%>",
3585 N2FPU_NAME (code), N2FPU_NAME (code));
e430824f
CLT
3586 if (has_target_p)
3587 create_output_operand (&ops[opno++], target, dst_mode);
3588 else
3589 /* Subtract away the count of the VOID return, mainly for fwrx/fwry. */
3590 num_operands -= 1;
3591 nargs = call_expr_nargs (exp);
3592 for (argno = 0; argno < nargs; argno++)
3593 {
3594 tree arg = CALL_EXPR_ARG (exp, argno);
3595 create_input_operand (&ops[opno++], expand_normal (arg),
3596 TYPE_MODE (TREE_TYPE (arg)));
3597 }
3598 if (!maybe_expand_insn (icode, num_operands, ops))
3599 {
3600 error ("invalid argument to built-in function");
3601 return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx;
3602 }
3603 return has_target_p ? ops[0].value : const0_rtx;
3604}
3605
3606/* Nios II has custom instruction built-in functions of the forms:
3607 __builtin_custom_n
3608 __builtin_custom_nX
3609 __builtin_custom_nXX
3610 __builtin_custom_Xn
3611 __builtin_custom_XnX
3612 __builtin_custom_XnXX
3613
3614 where each X could be either 'i' (int), 'f' (float), or 'p' (void*).
3615 Therefore with 0-1 return values, and 0-2 arguments, we have a
3616 total of (3 + 1) * (1 + 3 + 9) == 52 custom builtin functions.
3617*/
3618#define NUM_CUSTOM_BUILTINS ((3 + 1) * (1 + 3 + 9))
3619static char custom_builtin_name[NUM_CUSTOM_BUILTINS][5];
3620
3621static void
3622nios2_init_custom_builtins (int start_code)
3623{
3624 tree builtin_ftype, ret_type, fndecl;
3625 char builtin_name[32] = "__builtin_custom_";
3626 int n = strlen ("__builtin_custom_");
3627 int builtin_code = 0;
3628 int lhs, rhs1, rhs2;
3629
3630 struct { tree type; const char *c; } op[4];
3631 /* z */ op[0].c = ""; op[0].type = NULL_TREE;
3632 /* f */ op[1].c = "f"; op[1].type = float_type_node;
3633 /* i */ op[2].c = "i"; op[2].type = integer_type_node;
3634 /* p */ op[3].c = "p"; op[3].type = ptr_type_node;
3635
3636 /* We enumerate through the possible operand types to create all the
3637 __builtin_custom_XnXX function tree types. Note that these may slightly
3638 overlap with the function types created for other fixed builtins. */
3639
3640 for (lhs = 0; lhs < 4; lhs++)
3641 for (rhs1 = 0; rhs1 < 4; rhs1++)
3642 for (rhs2 = 0; rhs2 < 4; rhs2++)
3643 {
3644 if (rhs1 == 0 && rhs2 != 0)
3645 continue;
3646 ret_type = (op[lhs].type ? op[lhs].type : void_type_node);
3647 builtin_ftype
3648 = build_function_type_list (ret_type, integer_type_node,
3649 op[rhs1].type, op[rhs2].type,
3650 NULL_TREE);
e430824f 3651 /* Save copy of parameter string into custom_builtin_name[]. */
5074c6fa
SL
3652 snprintf (custom_builtin_name[builtin_code], 5, "%sn%s%s",
3653 op[lhs].c, op[rhs1].c, op[rhs2].c);
3654 strncpy (builtin_name + n, custom_builtin_name[builtin_code], 5);
e430824f
CLT
3655 fndecl =
3656 add_builtin_function (builtin_name, builtin_ftype,
3657 start_code + builtin_code,
3658 BUILT_IN_MD, NULL, NULL_TREE);
3659 nios2_register_builtin_fndecl (start_code + builtin_code, fndecl);
3660 builtin_code += 1;
3661 }
3662}
3663
3664/* Helper function for expanding custom builtins. */
3665static rtx
3666nios2_expand_custom_builtin (tree exp, unsigned int index, rtx target)
3667{
3668 bool has_target_p = (TREE_TYPE (exp) != void_type_node);
ef4bddc2 3669 machine_mode tmode = VOIDmode;
e430824f
CLT
3670 int nargs, argno;
3671 rtx value, insn, unspec_args[3];
3672 tree arg;
3673
3674 /* XnXX form. */
3675 if (has_target_p)
3676 {
3677 tmode = TYPE_MODE (TREE_TYPE (exp));
3678 if (!target || GET_MODE (target) != tmode
3679 || !REG_P (target))
3680 target = gen_reg_rtx (tmode);
3681 }
3682
3683 nargs = call_expr_nargs (exp);
3684 for (argno = 0; argno < nargs; argno++)
3685 {
3686 arg = CALL_EXPR_ARG (exp, argno);
3687 value = expand_normal (arg);
3688 unspec_args[argno] = value;
3689 if (argno == 0)
3690 {
3691 if (!custom_insn_opcode (value, VOIDmode))
5074c6fa 3692 error ("custom instruction opcode must be a compile-time "
a3f9f006 3693 "constant in the range 0-255 for %<__builtin_custom_%s%>",
e430824f
CLT
3694 custom_builtin_name[index]);
3695 }
3696 else
3697 /* For other arguments, force into a register. */
3698 unspec_args[argno] = force_reg (TYPE_MODE (TREE_TYPE (arg)),
3699 unspec_args[argno]);
3700 }
3701 /* Fill remaining unspec operands with zero. */
3702 for (; argno < 3; argno++)
3703 unspec_args[argno] = const0_rtx;
3704
3705 insn = (has_target_p
f7df4a84 3706 ? gen_rtx_SET (target,
e430824f
CLT
3707 gen_rtx_UNSPEC_VOLATILE (tmode,
3708 gen_rtvec_v (3, unspec_args),
3709 UNSPECV_CUSTOM_XNXX))
3710 : gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec_v (3, unspec_args),
3711 UNSPECV_CUSTOM_NXX));
3712 emit_insn (insn);
3713 return has_target_p ? target : const0_rtx;
3714}
3715
3716
3717\f
3718
3719/* Main definition of built-in functions. Nios II has a small number of fixed
3720 builtins, plus a large number of FPU insn builtins, and builtins for
3721 generating custom instructions. */
3722
3723struct nios2_builtin_desc
3724{
3725 enum insn_code icode;
524d2e49 3726 enum nios2_arch_type arch;
e430824f
CLT
3727 enum nios2_ftcode ftype;
3728 const char *name;
3729};
3730
3731#define N2_BUILTINS \
524d2e49
SL
3732 N2_BUILTIN_DEF (sync, R1, N2_FTYPE_VOID_VOID) \
3733 N2_BUILTIN_DEF (ldbio, R1, N2_FTYPE_SI_CVPTR) \
3734 N2_BUILTIN_DEF (ldbuio, R1, N2_FTYPE_UI_CVPTR) \
3735 N2_BUILTIN_DEF (ldhio, R1, N2_FTYPE_SI_CVPTR) \
3736 N2_BUILTIN_DEF (ldhuio, R1, N2_FTYPE_UI_CVPTR) \
3737 N2_BUILTIN_DEF (ldwio, R1, N2_FTYPE_SI_CVPTR) \
3738 N2_BUILTIN_DEF (stbio, R1, N2_FTYPE_VOID_VPTR_SI) \
3739 N2_BUILTIN_DEF (sthio, R1, N2_FTYPE_VOID_VPTR_SI) \
3740 N2_BUILTIN_DEF (stwio, R1, N2_FTYPE_VOID_VPTR_SI) \
3741 N2_BUILTIN_DEF (rdctl, R1, N2_FTYPE_SI_SI) \
3742 N2_BUILTIN_DEF (wrctl, R1, N2_FTYPE_VOID_SI_SI) \
3743 N2_BUILTIN_DEF (rdprs, R1, N2_FTYPE_SI_SI_SI) \
3744 N2_BUILTIN_DEF (flushd, R1, N2_FTYPE_VOID_VPTR) \
3745 N2_BUILTIN_DEF (flushda, R1, N2_FTYPE_VOID_VPTR) \
3746 N2_BUILTIN_DEF (wrpie, R2, N2_FTYPE_SI_SI) \
3747 N2_BUILTIN_DEF (eni, R2, N2_FTYPE_VOID_SI) \
3748 N2_BUILTIN_DEF (ldex, R2, N2_FTYPE_SI_CVPTR) \
3749 N2_BUILTIN_DEF (ldsex, R2, N2_FTYPE_SI_CVPTR) \
3750 N2_BUILTIN_DEF (stex, R2, N2_FTYPE_SI_VPTR_SI) \
3751 N2_BUILTIN_DEF (stsex, R2, N2_FTYPE_SI_VPTR_SI)
e430824f
CLT
3752
3753enum nios2_builtin_code {
524d2e49 3754#define N2_BUILTIN_DEF(name, arch, ftype) NIOS2_BUILTIN_ ## name,
e430824f
CLT
3755 N2_BUILTINS
3756#undef N2_BUILTIN_DEF
3757 NUM_FIXED_NIOS2_BUILTINS
3758};
3759
3760static const struct nios2_builtin_desc nios2_builtins[] = {
524d2e49
SL
3761#define N2_BUILTIN_DEF(name, arch, ftype) \
3762 { CODE_FOR_ ## name, ARCH_ ## arch, ftype, "__builtin_" #name },
e430824f
CLT
3763 N2_BUILTINS
3764#undef N2_BUILTIN_DEF
3765};
3766
3767/* Start/ends of FPU/custom insn builtin index ranges. */
3768static unsigned int nios2_fpu_builtin_base;
3769static unsigned int nios2_custom_builtin_base;
3770static unsigned int nios2_custom_builtin_end;
3771
3772/* Implement TARGET_INIT_BUILTINS. */
3773static void
3774nios2_init_builtins (void)
3775{
3776 unsigned int i;
3777
3778 /* Initialize fixed builtins. */
3779 for (i = 0; i < ARRAY_SIZE (nios2_builtins); i++)
3780 {
3781 const struct nios2_builtin_desc *d = &nios2_builtins[i];
3782 tree fndecl =
3783 add_builtin_function (d->name, nios2_ftype (d->ftype), i,
3784 BUILT_IN_MD, NULL, NULL);
3785 nios2_register_builtin_fndecl (i, fndecl);
3786 }
3787
3788 /* Initialize FPU builtins. */
3789 nios2_fpu_builtin_base = ARRAY_SIZE (nios2_builtins);
3790 nios2_init_fpu_builtins (nios2_fpu_builtin_base);
3791
3792 /* Initialize custom insn builtins. */
3793 nios2_custom_builtin_base
3794 = nios2_fpu_builtin_base + ARRAY_SIZE (nios2_fpu_insn);
3795 nios2_custom_builtin_end
3796 = nios2_custom_builtin_base + NUM_CUSTOM_BUILTINS;
3797 nios2_init_custom_builtins (nios2_custom_builtin_base);
3798}
3799
3800/* Array of fndecls for TARGET_BUILTIN_DECL. */
3801#define NIOS2_NUM_BUILTINS \
3802 (ARRAY_SIZE (nios2_builtins) + ARRAY_SIZE (nios2_fpu_insn) + NUM_CUSTOM_BUILTINS)
3803static GTY(()) tree nios2_builtin_decls[NIOS2_NUM_BUILTINS];
3804
3805static void
3806nios2_register_builtin_fndecl (unsigned code, tree fndecl)
3807{
3808 nios2_builtin_decls[code] = fndecl;
3809}
3810
3811/* Implement TARGET_BUILTIN_DECL. */
3812static tree
3813nios2_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
3814{
3815 gcc_assert (nios2_custom_builtin_end == ARRAY_SIZE (nios2_builtin_decls));
3816
3817 if (code >= nios2_custom_builtin_end)
3818 return error_mark_node;
3819
3820 if (code >= nios2_fpu_builtin_base
3821 && code < nios2_custom_builtin_base
3822 && ! N2FPU_ENABLED_P (code - nios2_fpu_builtin_base))
3823 return error_mark_node;
3824
3825 return nios2_builtin_decls[code];
3826}
3827
3828\f
3829/* Low-level built-in expand routine. */
3830static rtx
3831nios2_expand_builtin_insn (const struct nios2_builtin_desc *d, int n,
3832 struct expand_operand *ops, bool has_target_p)
3833{
3834 if (maybe_expand_insn (d->icode, n, ops))
3835 return has_target_p ? ops[0].value : const0_rtx;
3836 else
3837 {
3838 error ("invalid argument to built-in function %s", d->name);
3839 return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx;
3840 }
3841}
3842
524d2e49
SL
3843/* Expand ldio/stio and ldex/ldsex/stex/stsex form load-store
3844 instruction builtins. */
e430824f 3845static rtx
524d2e49
SL
3846nios2_expand_ldst_builtin (tree exp, rtx target,
3847 const struct nios2_builtin_desc *d)
e430824f
CLT
3848{
3849 bool has_target_p;
3850 rtx addr, mem, val;
3851 struct expand_operand ops[MAX_RECOG_OPERANDS];
ef4bddc2 3852 machine_mode mode = insn_data[d->icode].operand[0].mode;
e430824f
CLT
3853
3854 addr = expand_normal (CALL_EXPR_ARG (exp, 0));
3855 mem = gen_rtx_MEM (mode, addr);
3856
3857 if (insn_data[d->icode].operand[0].allows_mem)
3858 {
524d2e49 3859 /* stxio/stex/stsex. */
e430824f
CLT
3860 val = expand_normal (CALL_EXPR_ARG (exp, 1));
3861 if (CONST_INT_P (val))
3862 val = force_reg (mode, gen_int_mode (INTVAL (val), mode));
3863 val = simplify_gen_subreg (mode, val, GET_MODE (val), 0);
3864 create_output_operand (&ops[0], mem, mode);
3865 create_input_operand (&ops[1], val, mode);
524d2e49
SL
3866 if (insn_data[d->icode].n_operands == 3)
3867 {
3868 /* stex/stsex status value, returned as result of function. */
3869 create_output_operand (&ops[2], target, mode);
3870 has_target_p = true;
3871 }
3872 else
3873 has_target_p = false;
e430824f
CLT
3874 }
3875 else
3876 {
3877 /* ldxio. */
3878 create_output_operand (&ops[0], target, mode);
3879 create_input_operand (&ops[1], mem, mode);
3880 has_target_p = true;
3881 }
524d2e49
SL
3882 return nios2_expand_builtin_insn (d, insn_data[d->icode].n_operands, ops,
3883 has_target_p);
e430824f
CLT
3884}
3885
3886/* Expand rdctl/wrctl builtins. */
3887static rtx
3888nios2_expand_rdwrctl_builtin (tree exp, rtx target,
3889 const struct nios2_builtin_desc *d)
3890{
3891 bool has_target_p = (insn_data[d->icode].operand[0].predicate
3892 == register_operand);
3893 rtx ctlcode = expand_normal (CALL_EXPR_ARG (exp, 0));
3894 struct expand_operand ops[MAX_RECOG_OPERANDS];
3895 if (!rdwrctl_operand (ctlcode, VOIDmode))
3896 {
5074c6fa 3897 error ("control register number must be in range 0-31 for %s",
e430824f
CLT
3898 d->name);
3899 return has_target_p ? gen_reg_rtx (SImode) : const0_rtx;
3900 }
3901 if (has_target_p)
3902 {
3903 create_output_operand (&ops[0], target, SImode);
3904 create_integer_operand (&ops[1], INTVAL (ctlcode));
3905 }
3906 else
3907 {
3908 rtx val = expand_normal (CALL_EXPR_ARG (exp, 1));
3909 create_integer_operand (&ops[0], INTVAL (ctlcode));
3910 create_input_operand (&ops[1], val, SImode);
3911 }
3912 return nios2_expand_builtin_insn (d, 2, ops, has_target_p);
3913}
3914
524d2e49
SL
3915static rtx
3916nios2_expand_rdprs_builtin (tree exp, rtx target,
3917 const struct nios2_builtin_desc *d)
3918{
3919 rtx reg = expand_normal (CALL_EXPR_ARG (exp, 0));
3920 rtx imm = expand_normal (CALL_EXPR_ARG (exp, 1));
3921 struct expand_operand ops[MAX_RECOG_OPERANDS];
3922
3923 if (!rdwrctl_operand (reg, VOIDmode))
3924 {
5074c6fa 3925 error ("register number must be in range 0-31 for %s",
524d2e49
SL
3926 d->name);
3927 return gen_reg_rtx (SImode);
3928 }
3929
3930 if (!rdprs_dcache_operand (imm, VOIDmode))
3931 {
5074c6fa 3932 error ("immediate value must fit into a %d-bit integer for %s",
524d2e49
SL
3933 (TARGET_ARCH_R2) ? 12 : 16, d->name);
3934 return gen_reg_rtx (SImode);
3935 }
3936
3937 create_output_operand (&ops[0], target, SImode);
3938 create_input_operand (&ops[1], reg, SImode);
3939 create_integer_operand (&ops[2], INTVAL (imm));
3940
3941 return nios2_expand_builtin_insn (d, 3, ops, true);
3942}
3943
3944static rtx
3945nios2_expand_cache_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
3946 const struct nios2_builtin_desc *d)
3947{
3948 rtx mem, addr;
3949 struct expand_operand ops[MAX_RECOG_OPERANDS];
3950
3951 addr = expand_normal (CALL_EXPR_ARG (exp, 0));
3952 mem = gen_rtx_MEM (SImode, addr);
3953
3954 create_input_operand (&ops[0], mem, SImode);
3955
3956 return nios2_expand_builtin_insn (d, 1, ops, false);
3957}
3958
3959static rtx
3960nios2_expand_wrpie_builtin (tree exp, rtx target,
3961 const struct nios2_builtin_desc *d)
3962{
3963 rtx val;
3964 struct expand_operand ops[MAX_RECOG_OPERANDS];
3965
3966 val = expand_normal (CALL_EXPR_ARG (exp, 0));
3967 create_input_operand (&ops[1], val, SImode);
3968 create_output_operand (&ops[0], target, SImode);
3969
3970 return nios2_expand_builtin_insn (d, 2, ops, true);
3971}
3972
3973static rtx
3974nios2_expand_eni_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
3975 const struct nios2_builtin_desc *d)
3976{
3977 rtx imm = expand_normal (CALL_EXPR_ARG (exp, 0));
3978 struct expand_operand ops[MAX_RECOG_OPERANDS];
3979
3980 if (INTVAL (imm) != 0 && INTVAL (imm) != 1)
3981 {
5074c6fa 3982 error ("the ENI instruction operand must be either 0 or 1");
524d2e49
SL
3983 return const0_rtx;
3984 }
3985 create_integer_operand (&ops[0], INTVAL (imm));
3986
3987 return nios2_expand_builtin_insn (d, 1, ops, false);
3988}
3989
e430824f
CLT
3990/* Implement TARGET_EXPAND_BUILTIN. Expand an expression EXP that calls
3991 a built-in function, with result going to TARGET if that's convenient
3992 (and in mode MODE if that's convenient).
3993 SUBTARGET may be used as the target for computing one of EXP's operands.
3994 IGNORE is nonzero if the value is to be ignored. */
3995
3996static rtx
3997nios2_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
ef4bddc2 3998 machine_mode mode ATTRIBUTE_UNUSED,
e430824f
CLT
3999 int ignore ATTRIBUTE_UNUSED)
4000{
4001 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
4d732405 4002 unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
e430824f
CLT
4003
4004 if (fcode < nios2_fpu_builtin_base)
4005 {
4006 const struct nios2_builtin_desc *d = &nios2_builtins[fcode];
4007
524d2e49
SL
4008 if (d->arch > nios2_arch_option)
4009 {
5074c6fa 4010 error ("built-in function %s requires Nios II R%d",
524d2e49
SL
4011 d->name, (int) d->arch);
4012 /* Given it is invalid, just generate a normal call. */
4013 return expand_call (exp, target, ignore);
4014 }
4015
e430824f
CLT
4016 switch (fcode)
4017 {
4018 case NIOS2_BUILTIN_sync:
4019 emit_insn (gen_sync ());
4020 return const0_rtx;
4021
4022 case NIOS2_BUILTIN_ldbio:
4023 case NIOS2_BUILTIN_ldbuio:
4024 case NIOS2_BUILTIN_ldhio:
4025 case NIOS2_BUILTIN_ldhuio:
4026 case NIOS2_BUILTIN_ldwio:
4027 case NIOS2_BUILTIN_stbio:
4028 case NIOS2_BUILTIN_sthio:
4029 case NIOS2_BUILTIN_stwio:
524d2e49
SL
4030 case NIOS2_BUILTIN_ldex:
4031 case NIOS2_BUILTIN_ldsex:
4032 case NIOS2_BUILTIN_stex:
4033 case NIOS2_BUILTIN_stsex:
4034 return nios2_expand_ldst_builtin (exp, target, d);
e430824f
CLT
4035
4036 case NIOS2_BUILTIN_rdctl:
4037 case NIOS2_BUILTIN_wrctl:
4038 return nios2_expand_rdwrctl_builtin (exp, target, d);
4039
524d2e49
SL
4040 case NIOS2_BUILTIN_rdprs:
4041 return nios2_expand_rdprs_builtin (exp, target, d);
4042
4043 case NIOS2_BUILTIN_flushd:
4044 case NIOS2_BUILTIN_flushda:
4045 return nios2_expand_cache_builtin (exp, target, d);
4046
4047 case NIOS2_BUILTIN_wrpie:
4048 return nios2_expand_wrpie_builtin (exp, target, d);
4049
4050 case NIOS2_BUILTIN_eni:
4051 return nios2_expand_eni_builtin (exp, target, d);
4052
e430824f
CLT
4053 default:
4054 gcc_unreachable ();
4055 }
4056 }
4057 else if (fcode < nios2_custom_builtin_base)
4058 /* FPU builtin range. */
4059 return nios2_expand_fpu_builtin (exp, fcode - nios2_fpu_builtin_base,
4060 target);
4061 else if (fcode < nios2_custom_builtin_end)
4062 /* Custom insn builtin range. */
4063 return nios2_expand_custom_builtin (exp, fcode - nios2_custom_builtin_base,
4064 target);
4065 else
4066 gcc_unreachable ();
4067}
4068
4069/* Implement TARGET_INIT_LIBFUNCS. */
665ad37b 4070static void ATTRIBUTE_UNUSED
e430824f
CLT
4071nios2_init_libfuncs (void)
4072{
9bd99cce 4073 init_sync_libfuncs (UNITS_PER_WORD);
e430824f
CLT
4074}
4075
4076\f
4077
4078/* Register a custom code use, and signal error if a conflict was found. */
4079static void
4080nios2_register_custom_code (unsigned int N, enum nios2_ccs_code status,
4081 int index)
4082{
4083 gcc_assert (N <= 255);
4084
4085 if (status == CCS_FPU)
4086 {
4087 if (custom_code_status[N] == CCS_FPU && index != custom_code_index[N])
4088 {
4089 custom_code_conflict = true;
5074c6fa
SL
4090 error ("switch %<-mcustom-%s%> conflicts with "
4091 "switch %<-mcustom-%s%>",
e430824f
CLT
4092 N2FPU_NAME (custom_code_index[N]), N2FPU_NAME (index));
4093 }
4094 else if (custom_code_status[N] == CCS_BUILTIN_CALL)
4095 {
4096 custom_code_conflict = true;
5074c6fa
SL
4097 error ("call to %<__builtin_custom_%s%> conflicts with "
4098 "switch %<-mcustom-%s%>",
4099 custom_builtin_name[custom_code_index[N]],
e430824f
CLT
4100 N2FPU_NAME (index));
4101 }
4102 }
4103 else if (status == CCS_BUILTIN_CALL)
4104 {
4105 if (custom_code_status[N] == CCS_FPU)
4106 {
4107 custom_code_conflict = true;
5074c6fa
SL
4108 error ("call to %<__builtin_custom_%s%> conflicts with "
4109 "switch %<-mcustom-%s%>",
4110 custom_builtin_name[index],
e430824f
CLT
4111 N2FPU_NAME (custom_code_index[N]));
4112 }
4113 else
4114 {
4115 /* Note that code conflicts between different __builtin_custom_xnxx
4116 calls are not checked. */
4117 }
4118 }
4119 else
4120 gcc_unreachable ();
4121
4122 custom_code_status[N] = status;
4123 custom_code_index[N] = index;
4124}
4125
4126/* Mark a custom code as not in use. */
4127static void
4128nios2_deregister_custom_code (unsigned int N)
4129{
4130 if (N <= 255)
4131 {
4132 custom_code_status[N] = CCS_UNUSED;
4133 custom_code_index[N] = 0;
4134 }
4135}
4136
4137/* Target attributes can affect per-function option state, so we need to
4138 save/restore the custom code tracking info using the
4139 TARGET_OPTION_SAVE/TARGET_OPTION_RESTORE hooks. */
4140
4141static void
4142nios2_option_save (struct cl_target_option *ptr,
ba948b37
JJ
4143 struct gcc_options *opts ATTRIBUTE_UNUSED,
4144 struct gcc_options *opts_set ATTRIBUTE_UNUSED)
e430824f
CLT
4145{
4146 unsigned int i;
4147 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
4148 ptr->saved_fpu_custom_code[i] = N2FPU_N (i);
4149 memcpy (ptr->saved_custom_code_status, custom_code_status,
4150 sizeof (custom_code_status));
4151 memcpy (ptr->saved_custom_code_index, custom_code_index,
4152 sizeof (custom_code_index));
4153}
4154
4155static void
4156nios2_option_restore (struct gcc_options *opts ATTRIBUTE_UNUSED,
ba948b37 4157 struct gcc_options *opts_set ATTRIBUTE_UNUSED,
e430824f
CLT
4158 struct cl_target_option *ptr)
4159{
4160 unsigned int i;
4161 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
4162 N2FPU_N (i) = ptr->saved_fpu_custom_code[i];
4163 memcpy (custom_code_status, ptr->saved_custom_code_status,
4164 sizeof (custom_code_status));
4165 memcpy (custom_code_index, ptr->saved_custom_code_index,
4166 sizeof (custom_code_index));
4167}
4168
d581cf9c
SL
4169static bool
4170nios2_can_inline_p (tree caller, tree callee)
4171{
4172 tree callee_opts = DECL_FUNCTION_SPECIFIC_TARGET (callee);
4173 tree caller_opts = DECL_FUNCTION_SPECIFIC_TARGET (caller);
4174 struct cl_target_option *callee_ptr, *caller_ptr;
4175 unsigned int i;
4176
4177 if (! callee_opts)
4178 callee_opts = target_option_default_node;
4179 if (! caller_opts)
4180 caller_opts = target_option_default_node;
4181
4182 /* If both caller and callee have attributes, assume that if the
4183 pointer is different, the two functions have different target
4184 options since build_target_option_node uses a hash table for the
4185 options. */
4186 if (callee_opts == caller_opts)
4187 return true;
4188
4189 /* The only target options we recognize via function attributes are
4190 those related to custom instructions. If we failed the above test,
4191 check that any custom instructions enabled in the callee are also
4192 enabled with the same value in the caller. */
4193 callee_ptr = TREE_TARGET_OPTION (callee_opts);
4194 caller_ptr = TREE_TARGET_OPTION (caller_opts);
4195 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
4196 if (callee_ptr->saved_fpu_custom_code[i] != -1
4197 && (callee_ptr->saved_fpu_custom_code[i]
4198 != caller_ptr->saved_fpu_custom_code[i]))
4199 return false;
4200 return true;
4201}
4202
e430824f
CLT
4203/* Inner function to process the attribute((target(...))), take an argument and
4204 set the current options from the argument. If we have a list, recursively
4205 go over the list. */
4206
4207static bool
4208nios2_valid_target_attribute_rec (tree args)
4209{
4210 if (TREE_CODE (args) == TREE_LIST)
4211 {
4212 bool ret = true;
4213 for (; args; args = TREE_CHAIN (args))
4214 if (TREE_VALUE (args)
4215 && !nios2_valid_target_attribute_rec (TREE_VALUE (args)))
4216 ret = false;
4217 return ret;
4218 }
4219 else if (TREE_CODE (args) == STRING_CST)
4220 {
4221 char *argstr = ASTRDUP (TREE_STRING_POINTER (args));
4222 while (argstr && *argstr != '\0')
4223 {
4224 bool no_opt = false, end_p = false;
4225 char *eq = NULL, *p;
4226 while (ISSPACE (*argstr))
4227 argstr++;
4228 p = argstr;
4229 while (*p != '\0' && *p != ',')
4230 {
4231 if (!eq && *p == '=')
4232 eq = p;
4233 ++p;
4234 }
4235 if (*p == '\0')
4236 end_p = true;
4237 else
4238 *p = '\0';
4239 if (eq) *eq = '\0';
4240
c0129e2d 4241 if (startswith (argstr, "no-"))
e430824f
CLT
4242 {
4243 no_opt = true;
4244 argstr += 3;
4245 }
c0129e2d 4246 if (startswith (argstr, "custom-fpu-cfg"))
e430824f
CLT
4247 {
4248 char *end_eq = p;
4249 if (no_opt)
4250 {
5074c6fa 4251 error ("%<custom-fpu-cfg%> option does not support %<no-%>");
e430824f
CLT
4252 return false;
4253 }
4254 if (!eq)
4255 {
5074c6fa
SL
4256 error ("%<custom-fpu-cfg%> option requires configuration "
4257 "argument");
e430824f
CLT
4258 return false;
4259 }
4260 /* Increment and skip whitespace. */
4261 while (ISSPACE (*(++eq))) ;
4262 /* Decrement and skip to before any trailing whitespace. */
4263 while (ISSPACE (*(--end_eq))) ;
4264
4265 nios2_handle_custom_fpu_cfg (eq, end_eq + 1, true);
4266 }
c0129e2d 4267 else if (startswith (argstr, "custom-"))
e430824f
CLT
4268 {
4269 int code = -1;
4270 unsigned int i;
4271 for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
c0129e2d 4272 if (startswith (argstr + 7, N2FPU_NAME (i)))
e430824f
CLT
4273 {
4274 /* Found insn. */
4275 code = i;
4276 break;
4277 }
4278 if (code >= 0)
4279 {
4280 if (no_opt)
4281 {
4282 if (eq)
4283 {
4284 error ("%<no-custom-%s%> does not accept arguments",
4285 N2FPU_NAME (code));
4286 return false;
4287 }
4288 /* Disable option by setting to -1. */
4289 nios2_deregister_custom_code (N2FPU_N (code));
4290 N2FPU_N (code) = -1;
4291 }
4292 else
4293 {
4294 char *t;
4295 if (eq)
4296 while (ISSPACE (*(++eq))) ;
4297 if (!eq || eq == p)
4298 {
4299 error ("%<custom-%s=%> requires argument",
4300 N2FPU_NAME (code));
4301 return false;
4302 }
4303 for (t = eq; t != p; ++t)
4304 {
4305 if (ISSPACE (*t))
4306 continue;
4307 if (!ISDIGIT (*t))
4308 {
6e0686e1
SL
4309 error ("%<custom-%s=%> argument should be "
4310 "a non-negative integer", N2FPU_NAME (code));
e430824f
CLT
4311 return false;
4312 }
4313 }
4314 /* Set option to argument. */
4315 N2FPU_N (code) = atoi (eq);
4316 nios2_handle_custom_fpu_insn_option (code);
4317 }
4318 }
4319 else
4320 {
bd2c6270 4321 error ("%<custom-%s=%> is not recognized as FPU instruction",
e430824f
CLT
4322 argstr + 7);
4323 return false;
4324 }
4325 }
4326 else
4327 {
5074c6fa 4328 error ("invalid custom instruction option %qs", argstr);
e430824f
CLT
4329 return false;
4330 }
4331
4332 if (end_p)
4333 break;
4334 else
4335 argstr = p + 1;
4336 }
4337 return true;
4338 }
4339 else
4340 gcc_unreachable ();
4341}
4342
4343/* Return a TARGET_OPTION_NODE tree of the target options listed or NULL. */
4344
4345static tree
4346nios2_valid_target_attribute_tree (tree args)
4347{
4348 if (!nios2_valid_target_attribute_rec (args))
4349 return NULL_TREE;
4350 nios2_custom_check_insns ();
ba948b37 4351 return build_target_option_node (&global_options, &global_options_set);
e430824f
CLT
4352}
4353
4354/* Hook to validate attribute((target("string"))). */
4355
4356static bool
4357nios2_valid_target_attribute_p (tree fndecl, tree ARG_UNUSED (name),
4358 tree args, int ARG_UNUSED (flags))
4359{
4360 struct cl_target_option cur_target;
4361 bool ret = true;
ba948b37
JJ
4362 tree old_optimize
4363 = build_optimization_node (&global_options, &global_options_set);
e430824f
CLT
4364 tree new_target, new_optimize;
4365 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
4366
4367 /* If the function changed the optimization levels as well as setting target
4368 options, start with the optimizations specified. */
4369 if (func_optimize && func_optimize != old_optimize)
ba948b37 4370 cl_optimization_restore (&global_options, &global_options_set,
e430824f
CLT
4371 TREE_OPTIMIZATION (func_optimize));
4372
4373 /* The target attributes may also change some optimization flags, so update
4374 the optimization options if necessary. */
ba948b37 4375 cl_target_option_save (&cur_target, &global_options, &global_options_set);
e430824f 4376 new_target = nios2_valid_target_attribute_tree (args);
ba948b37 4377 new_optimize = build_optimization_node (&global_options, &global_options_set);
e430824f
CLT
4378
4379 if (!new_target)
4380 ret = false;
4381
4382 else if (fndecl)
4383 {
4384 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
4385
4386 if (old_optimize != new_optimize)
4387 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
4388 }
4389
ba948b37 4390 cl_target_option_restore (&global_options, &global_options_set, &cur_target);
e430824f
CLT
4391
4392 if (old_optimize != new_optimize)
ba948b37 4393 cl_optimization_restore (&global_options, &global_options_set,
e430824f
CLT
4394 TREE_OPTIMIZATION (old_optimize));
4395 return ret;
4396}
4397
4398/* Remember the last target of nios2_set_current_function. */
4399static GTY(()) tree nios2_previous_fndecl;
4400
4401/* Establish appropriate back-end context for processing the function
4402 FNDECL. The argument might be NULL to indicate processing at top
4403 level, outside of any function scope. */
4404static void
4405nios2_set_current_function (tree fndecl)
4406{
4407 tree old_tree = (nios2_previous_fndecl
4408 ? DECL_FUNCTION_SPECIFIC_TARGET (nios2_previous_fndecl)
4409 : NULL_TREE);
4410
4411 tree new_tree = (fndecl
4412 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
4413 : NULL_TREE);
4414
4415 if (fndecl && fndecl != nios2_previous_fndecl)
4416 {
4417 nios2_previous_fndecl = fndecl;
4418 if (old_tree == new_tree)
4419 ;
4420
4421 else if (new_tree)
4422 {
ba948b37 4423 cl_target_option_restore (&global_options, &global_options_set,
e430824f
CLT
4424 TREE_TARGET_OPTION (new_tree));
4425 target_reinit ();
4426 }
4427
4428 else if (old_tree)
4429 {
4430 struct cl_target_option *def
4431 = TREE_TARGET_OPTION (target_option_current_node);
4432
ba948b37 4433 cl_target_option_restore (&global_options, &global_options_set, def);
e430824f
CLT
4434 target_reinit ();
4435 }
4436 }
4437}
4438
4439/* Hook to validate the current #pragma GCC target and set the FPU custom
4440 code option state. If ARGS is NULL, then POP_TARGET is used to reset
4441 the options. */
4442static bool
4443nios2_pragma_target_parse (tree args, tree pop_target)
4444{
4445 tree cur_tree;
4446 if (! args)
4447 {
4448 cur_tree = ((pop_target)
4449 ? pop_target
4450 : target_option_default_node);
ba948b37 4451 cl_target_option_restore (&global_options, &global_options_set,
e430824f
CLT
4452 TREE_TARGET_OPTION (cur_tree));
4453 }
4454 else
4455 {
4456 cur_tree = nios2_valid_target_attribute_tree (args);
4457 if (!cur_tree)
4458 return false;
4459 }
4460
4461 target_option_current_node = cur_tree;
4462 return true;
4463}
4464
4465/* Implement TARGET_MERGE_DECL_ATTRIBUTES.
4466 We are just using this hook to add some additional error checking to
4467 the default behavior. GCC does not provide a target hook for merging
4468 the target options, and only correctly handles merging empty vs non-empty
e53b6e56 4469 option data; see merge_decls() in c-decl.cc.
e430824f
CLT
4470 So here we require either that at least one of the decls has empty
4471 target options, or that the target options/data be identical. */
4472static tree
4473nios2_merge_decl_attributes (tree olddecl, tree newdecl)
4474{
4475 tree oldopts = lookup_attribute ("target", DECL_ATTRIBUTES (olddecl));
4476 tree newopts = lookup_attribute ("target", DECL_ATTRIBUTES (newdecl));
4477 if (newopts && oldopts && newopts != oldopts)
4478 {
4479 tree oldtree = DECL_FUNCTION_SPECIFIC_TARGET (olddecl);
4480 tree newtree = DECL_FUNCTION_SPECIFIC_TARGET (newdecl);
4481 if (oldtree && newtree && oldtree != newtree)
4482 {
4483 struct cl_target_option *olddata = TREE_TARGET_OPTION (oldtree);
4484 struct cl_target_option *newdata = TREE_TARGET_OPTION (newtree);
4485 if (olddata != newdata
4486 && memcmp (olddata, newdata, sizeof (struct cl_target_option)))
4487 error ("%qE redeclared with conflicting %qs attributes",
4488 DECL_NAME (newdecl), "target");
4489 }
4490 }
4491 return merge_attributes (DECL_ATTRIBUTES (olddecl),
4492 DECL_ATTRIBUTES (newdecl));
4493}
4494
a866d527
CLT
4495/* Implement TARGET_ASM_OUTPUT_MI_THUNK. */
4496static void
4497nios2_asm_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
4498 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
4499 tree function)
4500{
f7430263 4501 const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
a866d527
CLT
4502 rtx this_rtx, funexp;
4503 rtx_insn *insn;
4504
4505 /* Pretend to be a post-reload pass while generating rtl. */
4506 reload_completed = 1;
4507
4508 if (flag_pic)
4509 nios2_load_pic_register ();
4510
4511 /* Mark the end of the (empty) prologue. */
4512 emit_note (NOTE_INSN_PROLOGUE_END);
4513
4514 /* Find the "this" pointer. If the function returns a structure,
4515 the structure return pointer is in $5. */
4516 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
4517 this_rtx = gen_rtx_REG (Pmode, FIRST_ARG_REGNO + 1);
4518 else
4519 this_rtx = gen_rtx_REG (Pmode, FIRST_ARG_REGNO);
4520
4521 /* Add DELTA to THIS_RTX. */
4522 nios2_emit_add_constant (this_rtx, delta);
4523
4524 /* If needed, add *(*THIS_RTX + VCALL_OFFSET) to THIS_RTX. */
4525 if (vcall_offset)
4526 {
4527 rtx tmp;
4528
4529 tmp = gen_rtx_REG (Pmode, 2);
4530 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
4531 nios2_emit_add_constant (tmp, vcall_offset);
4532 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
4533 emit_insn (gen_add2_insn (this_rtx, tmp));
4534 }
4535
4536 /* Generate a tail call to the target function. */
4537 if (!TREE_USED (function))
4538 {
4539 assemble_external (function);
4540 TREE_USED (function) = 1;
4541 }
4542 funexp = XEXP (DECL_RTL (function), 0);
4543 /* Function address needs to be constructed under PIC,
4544 provide r2 to use here. */
4545 nios2_adjust_call_address (&funexp, gen_rtx_REG (Pmode, 2));
4546 insn = emit_call_insn (gen_sibcall_internal (funexp, const0_rtx));
4547 SIBLING_CALL_P (insn) = 1;
4548
4549 /* Run just enough of rest_of_compilation to get the insns emitted.
4550 There's not really enough bulk here to make other passes such as
8b4e7143 4551 instruction scheduling worth while. */
a866d527
CLT
4552 insn = get_insns ();
4553 shorten_branches (insn);
f7430263 4554 assemble_start_function (thunk_fndecl, fnname);
a866d527
CLT
4555 final_start_function (insn, file, 1);
4556 final (insn, file, 1);
4557 final_end_function ();
f7430263 4558 assemble_end_function (thunk_fndecl, fnname);
a866d527
CLT
4559
4560 /* Stop pretending to be a post-reload pass. */
4561 reload_completed = 0;
4562}
4563
3bbbe009
SL
4564
4565/* Utility function to break a memory address into
4566 base register + constant offset. Return false if something
4567 unexpected is seen. */
4568static bool
4569split_mem_address (rtx addr, rtx *base_reg, rtx *offset)
4570{
4571 if (REG_P (addr))
4572 {
4573 *base_reg = addr;
4574 *offset = const0_rtx;
4575 return true;
4576 }
4577 else if (GET_CODE (addr) == PLUS)
4578 {
4579 *base_reg = XEXP (addr, 0);
4580 *offset = XEXP (addr, 1);
4581 return true;
4582 }
4583 return false;
4584}
4585
4586/* Splits out the operands of an ALU insn, places them in *LHS, *RHS1, *RHS2. */
4587static void
4588split_alu_insn (rtx_insn *insn, rtx *lhs, rtx *rhs1, rtx *rhs2)
4589{
4590 rtx pat = PATTERN (insn);
4591 gcc_assert (GET_CODE (pat) == SET);
4592 *lhs = SET_DEST (pat);
4593 *rhs1 = XEXP (SET_SRC (pat), 0);
4594 if (GET_RTX_CLASS (GET_CODE (SET_SRC (pat))) != RTX_UNARY)
4595 *rhs2 = XEXP (SET_SRC (pat), 1);
4596 return;
4597}
4598
4599/* Returns true if OP is a REG and assigned a CDX reg. */
4600static bool
4601cdxreg (rtx op)
4602{
4603 return REG_P (op) && (!reload_completed || CDX_REG_P (REGNO (op)));
4604}
4605
4606/* Returns true if OP is within range of CDX addi.n immediates. */
4607static bool
4608cdx_add_immed (rtx op)
4609{
4610 if (CONST_INT_P (op))
4611 {
4612 HOST_WIDE_INT ival = INTVAL (op);
4613 return ival <= 128 && ival > 0 && (ival & (ival - 1)) == 0;
4614 }
4615 return false;
4616}
4617
4618/* Returns true if OP is within range of CDX andi.n immediates. */
4619static bool
4620cdx_and_immed (rtx op)
4621{
4622 if (CONST_INT_P (op))
4623 {
4624 HOST_WIDE_INT ival = INTVAL (op);
4625 return (ival == 1 || ival == 2 || ival == 3 || ival == 4
4626 || ival == 8 || ival == 0xf || ival == 0x10
231f6e09
SL
4627 || ival == 0x1f || ival == 0x20
4628 || ival == 0x3f || ival == 0x7f
3bbbe009
SL
4629 || ival == 0x80 || ival == 0xff || ival == 0x7ff
4630 || ival == 0xff00 || ival == 0xffff);
4631 }
4632 return false;
4633}
4634
4635/* Returns true if OP is within range of CDX movi.n immediates. */
4636static bool
4637cdx_mov_immed (rtx op)
4638{
4639 if (CONST_INT_P (op))
4640 {
4641 HOST_WIDE_INT ival = INTVAL (op);
4642 return ((ival >= 0 && ival <= 124)
4643 || ival == 0xff || ival == -2 || ival == -1);
4644 }
4645 return false;
4646}
4647
4648/* Returns true if OP is within range of CDX slli.n/srli.n immediates. */
4649static bool
4650cdx_shift_immed (rtx op)
4651{
4652 if (CONST_INT_P (op))
4653 {
4654 HOST_WIDE_INT ival = INTVAL (op);
4655 return (ival == 1 || ival == 2 || ival == 3 || ival == 8
4656 || ival == 12 || ival == 16 || ival == 24
4657 || ival == 31);
4658 }
4659 return false;
4660}
4661
4662
4663
4664/* Classification of different kinds of add instructions. */
4665enum nios2_add_insn_kind {
4666 nios2_add_n_kind,
4667 nios2_addi_n_kind,
4668 nios2_subi_n_kind,
4669 nios2_spaddi_n_kind,
4670 nios2_spinci_n_kind,
4671 nios2_spdeci_n_kind,
4672 nios2_add_kind,
4673 nios2_addi_kind
4674};
4675
4676static const char *nios2_add_insn_names[] = {
4677 "add.n", "addi.n", "subi.n", "spaddi.n", "spinci.n", "spdeci.n",
4678 "add", "addi" };
4679static bool nios2_add_insn_narrow[] = {
4680 true, true, true, true, true, true,
4681 false, false};
4682
4683/* Function to classify kinds of add instruction patterns. */
4684static enum nios2_add_insn_kind
4685nios2_add_insn_classify (rtx_insn *insn ATTRIBUTE_UNUSED,
4686 rtx lhs, rtx rhs1, rtx rhs2)
4687{
4688 if (TARGET_HAS_CDX)
4689 {
4690 if (cdxreg (lhs) && cdxreg (rhs1))
4691 {
4692 if (cdxreg (rhs2))
4693 return nios2_add_n_kind;
4694 if (CONST_INT_P (rhs2))
4695 {
4696 HOST_WIDE_INT ival = INTVAL (rhs2);
4697 if (ival > 0 && cdx_add_immed (rhs2))
4698 return nios2_addi_n_kind;
4699 if (ival < 0 && cdx_add_immed (GEN_INT (-ival)))
4700 return nios2_subi_n_kind;
4701 }
4702 }
4703 else if (rhs1 == stack_pointer_rtx
4704 && CONST_INT_P (rhs2))
4705 {
4706 HOST_WIDE_INT imm7 = INTVAL (rhs2) >> 2;
4707 HOST_WIDE_INT rem = INTVAL (rhs2) & 3;
4708 if (rem == 0 && (imm7 & ~0x7f) == 0)
4709 {
4710 if (cdxreg (lhs))
4711 return nios2_spaddi_n_kind;
4712 if (lhs == stack_pointer_rtx)
4713 return nios2_spinci_n_kind;
4714 }
4715 imm7 = -INTVAL(rhs2) >> 2;
4716 rem = -INTVAL (rhs2) & 3;
4717 if (lhs == stack_pointer_rtx
4718 && rem == 0 && (imm7 & ~0x7f) == 0)
4719 return nios2_spdeci_n_kind;
4720 }
4721 }
4722 return ((REG_P (rhs2) || rhs2 == const0_rtx)
4723 ? nios2_add_kind : nios2_addi_kind);
4724}
4725
4726/* Emit assembly language for the different kinds of add instructions. */
4727const char*
4728nios2_add_insn_asm (rtx_insn *insn, rtx *operands)
4729{
4730 static char buf[256];
4731 int ln = 256;
4732 enum nios2_add_insn_kind kind
4733 = nios2_add_insn_classify (insn, operands[0], operands[1], operands[2]);
4734 if (kind == nios2_subi_n_kind)
4735 snprintf (buf, ln, "subi.n\t%%0, %%1, %d", (int) -INTVAL (operands[2]));
4736 else if (kind == nios2_spaddi_n_kind)
4737 snprintf (buf, ln, "spaddi.n\t%%0, %%2");
4738 else if (kind == nios2_spinci_n_kind)
4739 snprintf (buf, ln, "spinci.n\t%%2");
4740 else if (kind == nios2_spdeci_n_kind)
4741 snprintf (buf, ln, "spdeci.n\t%d", (int) -INTVAL (operands[2]));
4742 else
4743 snprintf (buf, ln, "%s\t%%0, %%1, %%z2", nios2_add_insn_names[(int)kind]);
4744 return buf;
4745}
4746
4747/* This routine, which the default "length" attribute computation is
4748 based on, encapsulates information about all the cases where CDX
4749 provides a narrow 2-byte instruction form. */
4750bool
4751nios2_cdx_narrow_form_p (rtx_insn *insn)
4752{
5074c6fa 4753 rtx pat, lhs, rhs1 = NULL_RTX, rhs2 = NULL_RTX;
3bbbe009
SL
4754 enum attr_type type;
4755 if (!TARGET_HAS_CDX)
4756 return false;
4757 type = get_attr_type (insn);
4758 pat = PATTERN (insn);
4759 gcc_assert (reload_completed);
4760 switch (type)
4761 {
4762 case TYPE_CONTROL:
4763 if (GET_CODE (pat) == SIMPLE_RETURN)
4764 return true;
4765 if (GET_CODE (pat) == PARALLEL)
4766 pat = XVECEXP (pat, 0, 0);
4767 if (GET_CODE (pat) == SET)
4768 pat = SET_SRC (pat);
4769 if (GET_CODE (pat) == IF_THEN_ELSE)
4770 {
4771 /* Conditional branch patterns; for these we
4772 only check the comparison to find beqz.n/bnez.n cases.
4773 For the 'nios2_cbranch' pattern, we cannot also check
4774 the branch range here. That will be done at the md
4775 pattern "length" attribute computation. */
4776 rtx cmp = XEXP (pat, 0);
4777 return ((GET_CODE (cmp) == EQ || GET_CODE (cmp) == NE)
4778 && cdxreg (XEXP (cmp, 0))
4779 && XEXP (cmp, 1) == const0_rtx);
4780 }
4781 if (GET_CODE (pat) == TRAP_IF)
4782 /* trap.n is always usable. */
4783 return true;
4784 if (GET_CODE (pat) == CALL)
4785 pat = XEXP (XEXP (pat, 0), 0);
4786 if (REG_P (pat))
4787 /* Control instructions taking a register operand are indirect
4788 jumps and calls. The CDX instructions have a 5-bit register
4789 field so any reg is valid. */
4790 return true;
4791 else
4792 {
4793 gcc_assert (!insn_variable_length_p (insn));
4794 return false;
4795 }
4796 case TYPE_ADD:
4797 {
4798 enum nios2_add_insn_kind kind;
4799 split_alu_insn (insn, &lhs, &rhs1, &rhs2);
4800 kind = nios2_add_insn_classify (insn, lhs, rhs1, rhs2);
4801 return nios2_add_insn_narrow[(int)kind];
4802 }
4803 case TYPE_LD:
4804 {
4805 bool ret;
4806 HOST_WIDE_INT offset, rem = 0;
4807 rtx addr, reg = SET_DEST (pat), mem = SET_SRC (pat);
4808 if (GET_CODE (mem) == SIGN_EXTEND)
4809 /* No CDX form for sign-extended load. */
4810 return false;
4811 if (GET_CODE (mem) == ZERO_EXTEND)
4812 /* The load alternatives in the zero_extend* patterns. */
4813 mem = XEXP (mem, 0);
4814 if (MEM_P (mem))
4815 {
4816 /* ldxio. */
4817 if ((MEM_VOLATILE_P (mem) && TARGET_BYPASS_CACHE_VOLATILE)
4818 || TARGET_BYPASS_CACHE)
4819 return false;
4820 addr = XEXP (mem, 0);
1cef1159
SL
4821 /* GP-based and R0-based references are never narrow. */
4822 if (gprel_constant_p (addr) || r0rel_constant_p (addr))
3bbbe009 4823 return false;
82348675
SL
4824 /* %lo requires a 16-bit relocation and is never narrow. */
4825 if (GET_CODE (addr) == LO_SUM)
4826 return false;
3bbbe009
SL
4827 ret = split_mem_address (addr, &rhs1, &rhs2);
4828 gcc_assert (ret);
4829 }
4830 else
4831 return false;
4832
4833 offset = INTVAL (rhs2);
4834 if (GET_MODE (mem) == SImode)
4835 {
4836 rem = offset & 3;
4837 offset >>= 2;
4838 /* ldwsp.n case. */
4839 if (rtx_equal_p (rhs1, stack_pointer_rtx)
4840 && rem == 0 && (offset & ~0x1f) == 0)
4841 return true;
4842 }
4843 else if (GET_MODE (mem) == HImode)
4844 {
4845 rem = offset & 1;
4846 offset >>= 1;
4847 }
4848 /* ldbu.n, ldhu.n, ldw.n cases. */
4849 return (cdxreg (reg) && cdxreg (rhs1)
4850 && rem == 0 && (offset & ~0xf) == 0);
4851 }
4852 case TYPE_ST:
4853 if (GET_CODE (pat) == PARALLEL)
4854 /* stex, stsex. */
4855 return false;
4856 else
4857 {
4858 bool ret;
4859 HOST_WIDE_INT offset, rem = 0;
4860 rtx addr, reg = SET_SRC (pat), mem = SET_DEST (pat);
4861 if (!MEM_P (mem))
4862 return false;
4863 /* stxio. */
4864 if ((MEM_VOLATILE_P (mem) && TARGET_BYPASS_CACHE_VOLATILE)
4865 || TARGET_BYPASS_CACHE)
4866 return false;
4867 addr = XEXP (mem, 0);
1cef1159
SL
4868 /* GP-based and r0-based references are never narrow. */
4869 if (gprel_constant_p (addr) || r0rel_constant_p (addr))
3bbbe009 4870 return false;
82348675
SL
4871 /* %lo requires a 16-bit relocation and is never narrow. */
4872 if (GET_CODE (addr) == LO_SUM)
4873 return false;
3bbbe009
SL
4874 ret = split_mem_address (addr, &rhs1, &rhs2);
4875 gcc_assert (ret);
4876 offset = INTVAL (rhs2);
4877 if (GET_MODE (mem) == SImode)
4878 {
4879 rem = offset & 3;
4880 offset >>= 2;
4881 /* stwsp.n case. */
4882 if (rtx_equal_p (rhs1, stack_pointer_rtx)
4883 && rem == 0 && (offset & ~0x1f) == 0)
4884 return true;
4885 /* stwz.n case. */
4886 else if (reg == const0_rtx && cdxreg (rhs1)
4887 && rem == 0 && (offset & ~0x3f) == 0)
4888 return true;
4889 }
4890 else if (GET_MODE (mem) == HImode)
4891 {
4892 rem = offset & 1;
4893 offset >>= 1;
4894 }
4895 else
4896 {
4897 gcc_assert (GET_MODE (mem) == QImode);
4898 /* stbz.n case. */
4899 if (reg == const0_rtx && cdxreg (rhs1)
4900 && (offset & ~0x3f) == 0)
4901 return true;
4902 }
4903
4904 /* stbu.n, sthu.n, stw.n cases. */
4905 return (cdxreg (reg) && cdxreg (rhs1)
4906 && rem == 0 && (offset & ~0xf) == 0);
4907 }
4908 case TYPE_MOV:
4909 lhs = SET_DEST (pat);
4910 rhs1 = SET_SRC (pat);
4911 if (CONST_INT_P (rhs1))
4912 return (cdxreg (lhs) && cdx_mov_immed (rhs1));
4913 gcc_assert (REG_P (lhs) && REG_P (rhs1));
4914 return true;
4915
4916 case TYPE_AND:
4917 /* Some zero_extend* alternatives are and insns. */
4918 if (GET_CODE (SET_SRC (pat)) == ZERO_EXTEND)
4919 return (cdxreg (SET_DEST (pat))
4920 && cdxreg (XEXP (SET_SRC (pat), 0)));
4921 split_alu_insn (insn, &lhs, &rhs1, &rhs2);
4922 if (CONST_INT_P (rhs2))
4923 return (cdxreg (lhs) && cdxreg (rhs1) && cdx_and_immed (rhs2));
4924 return (cdxreg (lhs) && cdxreg (rhs2)
4925 && (!reload_completed || rtx_equal_p (lhs, rhs1)));
4926
4927 case TYPE_OR:
4928 case TYPE_XOR:
4929 /* Note the two-address limitation for CDX form. */
4930 split_alu_insn (insn, &lhs, &rhs1, &rhs2);
4931 return (cdxreg (lhs) && cdxreg (rhs2)
4932 && (!reload_completed || rtx_equal_p (lhs, rhs1)));
4933
4934 case TYPE_SUB:
4935 split_alu_insn (insn, &lhs, &rhs1, &rhs2);
4936 return (cdxreg (lhs) && cdxreg (rhs1) && cdxreg (rhs2));
4937
4938 case TYPE_NEG:
4939 case TYPE_NOT:
4940 split_alu_insn (insn, &lhs, &rhs1, NULL);
4941 return (cdxreg (lhs) && cdxreg (rhs1));
4942
4943 case TYPE_SLL:
4944 case TYPE_SRL:
4945 split_alu_insn (insn, &lhs, &rhs1, &rhs2);
4946 return (cdxreg (lhs)
4947 && ((cdxreg (rhs1) && cdx_shift_immed (rhs2))
4948 || (cdxreg (rhs2)
4949 && (!reload_completed || rtx_equal_p (lhs, rhs1)))));
4950 case TYPE_NOP:
4951 case TYPE_PUSH:
4952 case TYPE_POP:
4953 return true;
4954 default:
4955 break;
4956 }
4957 return false;
4958}
4959
aa32db37
SL
4960/* Main function to implement the pop_operation predicate that
4961 check pop.n insn pattern integrity. The CDX pop.n patterns mostly
4962 hardcode the restored registers, so the main checking is for the
4963 SP offsets. */
4964bool
4965pop_operation_p (rtx op)
4966{
4967 int i;
4968 HOST_WIDE_INT last_offset = -1, len = XVECLEN (op, 0);
4969 rtx base_reg, offset;
4970
4971 if (len < 3 /* At least has a return, SP-update, and RA restore. */
4972 || GET_CODE (XVECEXP (op, 0, 0)) != RETURN
4973 || !base_reg_adjustment_p (XVECEXP (op, 0, 1), &base_reg, &offset)
4974 || !rtx_equal_p (base_reg, stack_pointer_rtx)
4975 || !CONST_INT_P (offset)
4976 || (INTVAL (offset) & 3) != 0)
4977 return false;
4978
4979 for (i = len - 1; i > 1; i--)
4980 {
4981 rtx set = XVECEXP (op, 0, i);
4982 rtx curr_base_reg, curr_offset;
4983
4984 if (GET_CODE (set) != SET || !MEM_P (SET_SRC (set))
4985 || !split_mem_address (XEXP (SET_SRC (set), 0),
4986 &curr_base_reg, &curr_offset)
4987 || !rtx_equal_p (base_reg, curr_base_reg)
4988 || !CONST_INT_P (curr_offset))
4989 return false;
4990 if (i == len - 1)
4991 {
4992 last_offset = INTVAL (curr_offset);
4993 if ((last_offset & 3) != 0 || last_offset > 60)
4994 return false;
4995 }
4996 else
4997 {
4998 last_offset += 4;
4999 if (INTVAL (curr_offset) != last_offset)
5000 return false;
5001 }
5002 }
5003 if (last_offset < 0 || last_offset + 4 != INTVAL (offset))
5004 return false;
5005
5006 return true;
5007}
5008
5009
5010/* Masks of registers that are valid for CDX ldwm/stwm instructions.
5011 The instruction can encode subsets drawn from either R2-R13 or
5012 R14-R23 + FP + RA. */
5013#define CDX_LDSTWM_VALID_REGS_0 0x00003ffc
5014#define CDX_LDSTWM_VALID_REGS_1 0x90ffc000
5015
5016static bool
5017nios2_ldstwm_regset_p (unsigned int regno, unsigned int *regset)
5018{
5019 if (*regset == 0)
5020 {
5021 if (CDX_LDSTWM_VALID_REGS_0 & (1 << regno))
5022 *regset = CDX_LDSTWM_VALID_REGS_0;
5023 else if (CDX_LDSTWM_VALID_REGS_1 & (1 << regno))
5024 *regset = CDX_LDSTWM_VALID_REGS_1;
5025 else
5026 return false;
5027 return true;
5028 }
5029 else
5030 return (*regset & (1 << regno)) != 0;
5031}
5032
5033/* Main function to implement ldwm_operation/stwm_operation
5034 predicates that check ldwm/stwm insn pattern integrity. */
5035bool
5036ldstwm_operation_p (rtx op, bool load_p)
5037{
5038 int start, i, end = XVECLEN (op, 0) - 1, last_regno = -1;
5039 unsigned int regset = 0;
5040 rtx base_reg, offset;
5041 rtx first_elt = XVECEXP (op, 0, 0);
5042 bool inc_p = true;
5043 bool wb_p = base_reg_adjustment_p (first_elt, &base_reg, &offset);
5044 if (GET_CODE (XVECEXP (op, 0, end)) == RETURN)
5045 end--;
5046 start = wb_p ? 1 : 0;
5047 for (i = start; i <= end; i++)
5048 {
5049 int regno;
5050 rtx reg, mem, elt = XVECEXP (op, 0, i);
5051 /* Return early if not a SET at all. */
5052 if (GET_CODE (elt) != SET)
5053 return false;
5054 reg = load_p ? SET_DEST (elt) : SET_SRC (elt);
5055 mem = load_p ? SET_SRC (elt) : SET_DEST (elt);
5056 if (!REG_P (reg) || !MEM_P (mem))
5057 return false;
5058 regno = REGNO (reg);
5059 if (!nios2_ldstwm_regset_p (regno, &regset))
5060 return false;
5061 /* If no writeback to determine direction, use offset of first MEM. */
5062 if (wb_p)
5063 inc_p = INTVAL (offset) > 0;
5064 else if (i == start)
5065 {
5066 rtx first_base, first_offset;
5067 if (!split_mem_address (XEXP (mem, 0),
5068 &first_base, &first_offset))
5069 return false;
039f4db9
SB
5070 if (!REG_P (first_base) || !CONST_INT_P (first_offset))
5071 return false;
aa32db37
SL
5072 base_reg = first_base;
5073 inc_p = INTVAL (first_offset) >= 0;
5074 }
5075 /* Ensure that the base register is not loaded into. */
5076 if (load_p && regno == (int) REGNO (base_reg))
5077 return false;
5078 /* Check for register order inc/dec integrity. */
5079 if (last_regno >= 0)
5080 {
5081 if (inc_p && last_regno >= regno)
5082 return false;
5083 if (!inc_p && last_regno <= regno)
5084 return false;
5085 }
5086 last_regno = regno;
5087 }
5088 return true;
5089}
5090
5091/* Helper for nios2_ldst_parallel, for generating a parallel vector
5092 SET element. */
5093static rtx
5094gen_ldst (bool load_p, int regno, rtx base_mem, int offset)
5095{
5096 rtx reg = gen_rtx_REG (SImode, regno);
5097 rtx mem = adjust_address_nv (base_mem, SImode, offset);
5098 return gen_rtx_SET (load_p ? reg : mem,
5099 load_p ? mem : reg);
5100}
5101
5102/* A general routine for creating the body RTL pattern of
5103 ldwm/stwm/push.n/pop.n insns.
5104 LOAD_P: true/false for load/store direction.
5105 REG_INC_P: whether registers are incrementing/decrementing in the
5106 *RTL vector* (not necessarily the order defined in the ISA specification).
5107 OFFSET_INC_P: Same as REG_INC_P, but for the memory offset order.
5108 BASE_MEM: starting MEM.
5109 BASE_UPDATE: amount to update base register; zero means no writeback.
5110 REGMASK: register mask to load/store.
5111 RET_P: true if to tag a (return) element at the end.
5112
5113 Note that this routine does not do any checking. It's the job of the
5114 caller to do the right thing, and the insn patterns to do the
5115 safe-guarding. */
5116static rtx
5117nios2_ldst_parallel (bool load_p, bool reg_inc_p, bool offset_inc_p,
5118 rtx base_mem, int base_update,
5119 unsigned HOST_WIDE_INT regmask, bool ret_p)
5120{
5121 rtvec p;
5122 int regno, b = 0, i = 0, n = 0, len = popcount_hwi (regmask);
5123 if (ret_p) len++, i++, b++;
5124 if (base_update != 0) len++, i++;
5125 p = rtvec_alloc (len);
5126 for (regno = (reg_inc_p ? 0 : 31);
5127 regno != (reg_inc_p ? 32 : -1);
5128 regno += (reg_inc_p ? 1 : -1))
5129 if ((regmask & (1 << regno)) != 0)
5130 {
5131 int offset = (offset_inc_p ? 4 : -4) * n++;
5132 RTVEC_ELT (p, i++) = gen_ldst (load_p, regno, base_mem, offset);
5133 }
5134 if (ret_p)
5135 RTVEC_ELT (p, 0) = ret_rtx;
5136 if (base_update != 0)
5137 {
5138 rtx reg, offset;
5139 if (!split_mem_address (XEXP (base_mem, 0), &reg, &offset))
5140 gcc_unreachable ();
5141 RTVEC_ELT (p, b) =
5142 gen_rtx_SET (reg, plus_constant (Pmode, reg, base_update));
5143 }
5144 return gen_rtx_PARALLEL (VOIDmode, p);
5145}
5146
5147/* CDX ldwm/stwm peephole optimization pattern related routines. */
5148
5149/* Data structure and sorting function for ldwm/stwm peephole optimizers. */
5150struct ldstwm_operand
5151{
5152 int offset; /* Offset from base register. */
5153 rtx reg; /* Register to store at this offset. */
5154 rtx mem; /* Original mem. */
5155 bool bad; /* True if this load/store can't be combined. */
5156 bool rewrite; /* True if we should rewrite using scratch. */
5157};
5158
5159static int
5160compare_ldstwm_operands (const void *arg1, const void *arg2)
5161{
5162 const struct ldstwm_operand *op1 = (const struct ldstwm_operand *) arg1;
5163 const struct ldstwm_operand *op2 = (const struct ldstwm_operand *) arg2;
5164 if (op1->bad)
5165 return op2->bad ? 0 : 1;
5166 else if (op2->bad)
5167 return -1;
5168 else
5169 return op1->offset - op2->offset;
5170}
5171
5172/* Helper function: return true if a load/store using REGNO with address
5173 BASEREG and offset OFFSET meets the constraints for a 2-byte CDX ldw.n,
5174 stw.n, ldwsp.n, or stwsp.n instruction. */
5175static bool
5176can_use_cdx_ldstw (int regno, int basereg, int offset)
5177{
5178 if (CDX_REG_P (regno) && CDX_REG_P (basereg)
01512446 5179 && (offset & 0x3) == 0 && offset >= 0 && offset < 0x40)
aa32db37
SL
5180 return true;
5181 else if (basereg == SP_REGNO
5182 && offset >= 0 && offset < 0x80 && (offset & 0x3) == 0)
5183 return true;
5184 return false;
5185}
5186
5187/* This function is called from peephole2 optimizers to try to merge
5188 a series of individual loads and stores into a ldwm or stwm. It
5189 can also rewrite addresses inside the individual loads and stores
5190 using a common base register using a scratch register and smaller
5191 offsets if that allows them to use CDX ldw.n or stw.n instructions
5192 instead of 4-byte loads or stores.
5193 N is the number of insns we are trying to merge. SCRATCH is non-null
5194 if there is a scratch register available. The OPERANDS array contains
5195 alternating REG (even) and MEM (odd) operands. */
5196bool
5197gen_ldstwm_peep (bool load_p, int n, rtx scratch, rtx *operands)
5198{
5199 /* CDX ldwm/stwm instructions allow a maximum of 12 registers to be
5200 specified. */
5201#define MAX_LDSTWM_OPS 12
5202 struct ldstwm_operand sort[MAX_LDSTWM_OPS];
5203 int basereg = -1;
5204 int baseoffset;
5205 int i, m, lastoffset, lastreg;
5206 unsigned int regmask = 0, usemask = 0, regset;
5207 bool needscratch;
5208 int newbasereg;
5209 int nbytes;
5210
5211 if (!TARGET_HAS_CDX)
5212 return false;
5213 if (n < 2 || n > MAX_LDSTWM_OPS)
5214 return false;
5215
5216 /* Check all the operands for validity and initialize the sort array.
5217 The places where we return false here are all situations that aren't
5218 expected to ever happen -- invalid patterns, invalid registers, etc. */
5219 for (i = 0; i < n; i++)
5220 {
5221 rtx base, offset;
5222 rtx reg = operands[i];
5223 rtx mem = operands[i + n];
5224 int r, o, regno;
5225 bool bad = false;
5226
5227 if (!REG_P (reg) || !MEM_P (mem))
5228 return false;
5229
5230 regno = REGNO (reg);
5231 if (regno > 31)
5232 return false;
5233 if (load_p && (regmask & (1 << regno)) != 0)
5234 return false;
5235 regmask |= 1 << regno;
5236
5237 if (!split_mem_address (XEXP (mem, 0), &base, &offset))
5238 return false;
5239 r = REGNO (base);
5240 o = INTVAL (offset);
5241
5242 if (basereg == -1)
5243 basereg = r;
5244 else if (r != basereg)
5245 bad = true;
5246 usemask |= 1 << r;
5247
5248 sort[i].bad = bad;
5249 sort[i].rewrite = false;
5250 sort[i].offset = o;
5251 sort[i].reg = reg;
5252 sort[i].mem = mem;
5253 }
5254
5255 /* If we are doing a series of register loads, we can't safely reorder
5256 them if any of the regs used in addr expressions are also being set. */
5257 if (load_p && (regmask & usemask))
5258 return false;
5259
5260 /* Sort the array by increasing mem offset order, then check that
5261 offsets are valid and register order matches mem order. At the
5262 end of this loop, m is the number of loads/stores we will try to
5263 combine; the rest are leftovers. */
5264 qsort (sort, n, sizeof (struct ldstwm_operand), compare_ldstwm_operands);
5265
5266 baseoffset = sort[0].offset;
5267 needscratch = baseoffset != 0;
5268 if (needscratch && !scratch)
5269 return false;
5270
5271 lastreg = regmask = regset = 0;
5272 lastoffset = baseoffset;
5273 for (m = 0; m < n && !sort[m].bad; m++)
5274 {
5275 int thisreg = REGNO (sort[m].reg);
5276 if (sort[m].offset != lastoffset
5277 || (m > 0 && lastreg >= thisreg)
5278 || !nios2_ldstwm_regset_p (thisreg, &regset))
5279 break;
5280 lastoffset += 4;
5281 lastreg = thisreg;
5282 regmask |= (1 << thisreg);
5283 }
5284
5285 /* For loads, make sure we are not overwriting the scratch reg.
5286 The peephole2 pattern isn't supposed to match unless the register is
5287 unused all the way through, so this isn't supposed to happen anyway. */
5288 if (load_p
5289 && needscratch
5290 && ((1 << REGNO (scratch)) & regmask) != 0)
5291 return false;
5292 newbasereg = needscratch ? (int) REGNO (scratch) : basereg;
5293
5294 /* We may be able to combine only the first m of the n total loads/stores
5295 into a single instruction. If m < 2, there's no point in emitting
5296 a ldwm/stwm at all, but we might be able to do further optimizations
5297 if we have a scratch. We will count the instruction lengths of the
5298 old and new patterns and store the savings in nbytes. */
5299 if (m < 2)
5300 {
5301 if (!needscratch)
5302 return false;
5303 m = 0;
5304 nbytes = 0;
5305 }
5306 else
5307 nbytes = -4; /* Size of ldwm/stwm. */
5308 if (needscratch)
5309 {
5310 int bo = baseoffset > 0 ? baseoffset : -baseoffset;
5311 if (CDX_REG_P (newbasereg)
5312 && CDX_REG_P (basereg)
5313 && bo <= 128 && bo > 0 && (bo & (bo - 1)) == 0)
5314 nbytes -= 2; /* Size of addi.n/subi.n. */
5315 else
5316 nbytes -= 4; /* Size of non-CDX addi. */
5317 }
5318
5319 /* Count the size of the input load/store instructions being replaced. */
5320 for (i = 0; i < m; i++)
5321 if (can_use_cdx_ldstw (REGNO (sort[i].reg), basereg, sort[i].offset))
5322 nbytes += 2;
5323 else
5324 nbytes += 4;
5325
5326 /* We may also be able to save a bit if we can rewrite non-CDX
5327 load/stores that can't be combined into the ldwm/stwm into CDX
5328 load/stores using the scratch reg. For example, this might happen
5329 if baseoffset is large, by bringing in the offsets in the load/store
5330 instructions within the range that fits in the CDX instruction. */
5331 if (needscratch && CDX_REG_P (newbasereg))
5332 for (i = m; i < n && !sort[i].bad; i++)
5333 if (!can_use_cdx_ldstw (REGNO (sort[i].reg), basereg, sort[i].offset)
5334 && can_use_cdx_ldstw (REGNO (sort[i].reg), newbasereg,
5335 sort[i].offset - baseoffset))
5336 {
5337 sort[i].rewrite = true;
5338 nbytes += 2;
5339 }
5340
5341 /* Are we good to go? */
5342 if (nbytes <= 0)
5343 return false;
5344
5345 /* Emit the scratch load. */
5346 if (needscratch)
5347 emit_insn (gen_rtx_SET (scratch, XEXP (sort[0].mem, 0)));
5348
5349 /* Emit the ldwm/stwm insn. */
5350 if (m > 0)
5351 {
5352 rtvec p = rtvec_alloc (m);
5353 for (i = 0; i < m; i++)
5354 {
5355 int offset = sort[i].offset;
5356 rtx mem, reg = sort[i].reg;
5357 rtx base_reg = gen_rtx_REG (Pmode, newbasereg);
5358 if (needscratch)
5359 offset -= baseoffset;
5360 mem = gen_rtx_MEM (SImode, plus_constant (Pmode, base_reg, offset));
5361 if (load_p)
5362 RTVEC_ELT (p, i) = gen_rtx_SET (reg, mem);
5363 else
5364 RTVEC_ELT (p, i) = gen_rtx_SET (mem, reg);
5365 }
5366 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
5367 }
5368
5369 /* Emit any leftover load/stores as individual instructions, doing
5370 the previously-noted rewrites to use the scratch reg. */
5371 for (i = m; i < n; i++)
5372 {
5373 rtx reg = sort[i].reg;
5374 rtx mem = sort[i].mem;
5375 if (sort[i].rewrite)
5376 {
5377 int offset = sort[i].offset - baseoffset;
5378 mem = gen_rtx_MEM (SImode, plus_constant (Pmode, scratch, offset));
5379 }
5380 if (load_p)
5381 emit_move_insn (reg, mem);
5382 else
5383 emit_move_insn (mem, reg);
5384 }
5385 return true;
5386}
5387
3bbbe009
SL
5388/* Implement TARGET_MACHINE_DEPENDENT_REORG:
5389 We use this hook when emitting CDX code to enforce the 4-byte
5390 alignment requirement for labels that are used as the targets of
5391 jmpi instructions. CDX code can otherwise contain a mix of 16-bit
5392 and 32-bit instructions aligned on any 16-bit boundary, but functions
5393 and jmpi labels have to be 32-bit aligned because of the way the address
5394 is encoded in the instruction. */
5395
5396static unsigned char *label_align;
5397static int min_labelno, max_labelno;
5398
5399static void
5400nios2_reorg (void)
5401{
5402 bool changed = true;
5403 rtx_insn *insn;
5404
5405 if (!TARGET_HAS_CDX)
5406 return;
5407
5408 /* Initialize the data structures. */
5409 if (label_align)
5410 free (label_align);
5411 max_labelno = max_label_num ();
5412 min_labelno = get_first_label_num ();
5413 label_align = XCNEWVEC (unsigned char, max_labelno - min_labelno + 1);
5414
5415 /* Iterate on inserting alignment and adjusting branch lengths until
5416 no more changes. */
5417 while (changed)
5418 {
5419 changed = false;
5420 shorten_branches (get_insns ());
5421
5422 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
5423 if (JUMP_P (insn) && insn_variable_length_p (insn))
5424 {
5425 rtx label = JUMP_LABEL (insn);
5426 /* We use the current fact that all cases of 'jmpi'
5427 doing the actual branch in the machine description
5428 has a computed length of 6 or 8. Length 4 and below
5429 are all PC-relative 'br' branches without the jump-align
5430 problem. */
5431 if (label && LABEL_P (label) && get_attr_length (insn) > 4)
5432 {
5433 int index = CODE_LABEL_NUMBER (label) - min_labelno;
5434 if (label_align[index] != 2)
5435 {
5436 label_align[index] = 2;
5437 changed = true;
5438 }
5439 }
5440 }
5441 }
5442}
5443
5444/* Implement LABEL_ALIGN, using the information gathered in nios2_reorg. */
5445int
5446nios2_label_align (rtx label)
5447{
5448 int n = CODE_LABEL_NUMBER (label);
5449
5450 if (label_align && n >= min_labelno && n <= max_labelno)
d84916bd
JL
5451 return MAX (label_align[n - min_labelno], align_labels.levels[0].log);
5452 return align_labels.levels[0].log;
3bbbe009
SL
5453}
5454
5455/* Implement ADJUST_REG_ALLOC_ORDER. We use the default ordering
5456 for R1 and non-CDX R2 code; for CDX we tweak thing to prefer
5457 the registers that can be used as operands to instructions that
5458 have 3-bit register fields. */
5459void
5460nios2_adjust_reg_alloc_order (void)
5461{
5462 const int cdx_reg_alloc_order[] =
5463 {
5464 /* Call-clobbered GPRs within CDX 3-bit encoded range. */
5465 2, 3, 4, 5, 6, 7,
5466 /* Call-saved GPRs within CDX 3-bit encoded range. */
5467 16, 17,
5468 /* Other call-clobbered GPRs. */
5469 8, 9, 10, 11, 12, 13, 14, 15,
5470 /* Other call-saved GPRs. RA placed first since it is always saved. */
5471 31, 18, 19, 20, 21, 22, 23, 28,
5472 /* Fixed GPRs, not used by the register allocator. */
5473 0, 1, 24, 25, 26, 27, 29, 30, 32, 33, 34, 35, 36, 37, 38, 39
5474 };
5475
5476 if (TARGET_HAS_CDX)
5477 memcpy (reg_alloc_order, cdx_reg_alloc_order,
5478 sizeof (int) * FIRST_PSEUDO_REGISTER);
5479}
5480
e430824f
CLT
5481\f
5482/* Initialize the GCC target structure. */
5483#undef TARGET_ASM_FUNCTION_PROLOGUE
5484#define TARGET_ASM_FUNCTION_PROLOGUE nios2_asm_function_prologue
5485
5486#undef TARGET_IN_SMALL_DATA_P
5487#define TARGET_IN_SMALL_DATA_P nios2_in_small_data_p
5488
5489#undef TARGET_SECTION_TYPE_FLAGS
5490#define TARGET_SECTION_TYPE_FLAGS nios2_section_type_flags
5491
5492#undef TARGET_INIT_BUILTINS
5493#define TARGET_INIT_BUILTINS nios2_init_builtins
5494#undef TARGET_EXPAND_BUILTIN
5495#define TARGET_EXPAND_BUILTIN nios2_expand_builtin
5496#undef TARGET_BUILTIN_DECL
5497#define TARGET_BUILTIN_DECL nios2_builtin_decl
5498
e430824f
CLT
5499#undef TARGET_FUNCTION_OK_FOR_SIBCALL
5500#define TARGET_FUNCTION_OK_FOR_SIBCALL hook_bool_tree_tree_true
5501
5502#undef TARGET_CAN_ELIMINATE
5503#define TARGET_CAN_ELIMINATE nios2_can_eliminate
5504
5505#undef TARGET_FUNCTION_ARG
5506#define TARGET_FUNCTION_ARG nios2_function_arg
5507
5508#undef TARGET_FUNCTION_ARG_ADVANCE
5509#define TARGET_FUNCTION_ARG_ADVANCE nios2_function_arg_advance
5510
76b0cbf8
RS
5511#undef TARGET_FUNCTION_ARG_PADDING
5512#define TARGET_FUNCTION_ARG_PADDING nios2_function_arg_padding
5513
e430824f
CLT
5514#undef TARGET_ARG_PARTIAL_BYTES
5515#define TARGET_ARG_PARTIAL_BYTES nios2_arg_partial_bytes
5516
5517#undef TARGET_TRAMPOLINE_INIT
5518#define TARGET_TRAMPOLINE_INIT nios2_trampoline_init
5519
5520#undef TARGET_FUNCTION_VALUE
5521#define TARGET_FUNCTION_VALUE nios2_function_value
5522
5523#undef TARGET_LIBCALL_VALUE
5524#define TARGET_LIBCALL_VALUE nios2_libcall_value
5525
5526#undef TARGET_FUNCTION_VALUE_REGNO_P
5527#define TARGET_FUNCTION_VALUE_REGNO_P nios2_function_value_regno_p
5528
5529#undef TARGET_RETURN_IN_MEMORY
5530#define TARGET_RETURN_IN_MEMORY nios2_return_in_memory
5531
5532#undef TARGET_PROMOTE_PROTOTYPES
5533#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
5534
5535#undef TARGET_SETUP_INCOMING_VARARGS
5536#define TARGET_SETUP_INCOMING_VARARGS nios2_setup_incoming_varargs
5537
5538#undef TARGET_MUST_PASS_IN_STACK
5539#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
5540
5541#undef TARGET_LEGITIMATE_CONSTANT_P
5542#define TARGET_LEGITIMATE_CONSTANT_P nios2_legitimate_constant_p
5543
5544#undef TARGET_LEGITIMIZE_ADDRESS
5545#define TARGET_LEGITIMIZE_ADDRESS nios2_legitimize_address
5546
98e8dd4d
CLT
5547#undef TARGET_DELEGITIMIZE_ADDRESS
5548#define TARGET_DELEGITIMIZE_ADDRESS nios2_delegitimize_address
5549
e430824f
CLT
5550#undef TARGET_LEGITIMATE_ADDRESS_P
5551#define TARGET_LEGITIMATE_ADDRESS_P nios2_legitimate_address_p
5552
5553#undef TARGET_PREFERRED_RELOAD_CLASS
5554#define TARGET_PREFERRED_RELOAD_CLASS nios2_preferred_reload_class
5555
5556#undef TARGET_RTX_COSTS
5557#define TARGET_RTX_COSTS nios2_rtx_costs
5558
efd5897c
SL
5559#undef TARGET_ADDRESS_COST
5560#define TARGET_ADDRESS_COST nios2_address_cost
5561
e430824f
CLT
5562#undef TARGET_HAVE_TLS
5563#define TARGET_HAVE_TLS TARGET_LINUX_ABI
5564
5565#undef TARGET_CANNOT_FORCE_CONST_MEM
5566#define TARGET_CANNOT_FORCE_CONST_MEM nios2_cannot_force_const_mem
5567
5568#undef TARGET_ASM_OUTPUT_DWARF_DTPREL
5569#define TARGET_ASM_OUTPUT_DWARF_DTPREL nios2_output_dwarf_dtprel
5570
3bbbe009
SL
5571#undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
5572#define TARGET_PRINT_OPERAND_PUNCT_VALID_P nios2_print_operand_punct_valid_p
5573
e430824f
CLT
5574#undef TARGET_PRINT_OPERAND
5575#define TARGET_PRINT_OPERAND nios2_print_operand
5576
5577#undef TARGET_PRINT_OPERAND_ADDRESS
5578#define TARGET_PRINT_OPERAND_ADDRESS nios2_print_operand_address
5579
5580#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
5581#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA nios2_output_addr_const_extra
5582
a9ce4e4a
CLT
5583#undef TARGET_ASM_FILE_END
5584#define TARGET_ASM_FILE_END nios2_asm_file_end
5585
e430824f
CLT
5586#undef TARGET_OPTION_OVERRIDE
5587#define TARGET_OPTION_OVERRIDE nios2_option_override
5588
5589#undef TARGET_OPTION_SAVE
5590#define TARGET_OPTION_SAVE nios2_option_save
5591
5592#undef TARGET_OPTION_RESTORE
5593#define TARGET_OPTION_RESTORE nios2_option_restore
5594
d581cf9c
SL
5595#undef TARGET_CAN_INLINE_P
5596#define TARGET_CAN_INLINE_P nios2_can_inline_p
5597
e430824f
CLT
5598#undef TARGET_SET_CURRENT_FUNCTION
5599#define TARGET_SET_CURRENT_FUNCTION nios2_set_current_function
5600
5601#undef TARGET_OPTION_VALID_ATTRIBUTE_P
5602#define TARGET_OPTION_VALID_ATTRIBUTE_P nios2_valid_target_attribute_p
5603
5604#undef TARGET_OPTION_PRAGMA_PARSE
5605#define TARGET_OPTION_PRAGMA_PARSE nios2_pragma_target_parse
5606
5607#undef TARGET_MERGE_DECL_ATTRIBUTES
5608#define TARGET_MERGE_DECL_ATTRIBUTES nios2_merge_decl_attributes
5609
a866d527
CLT
5610#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
5611#define TARGET_ASM_CAN_OUTPUT_MI_THUNK \
5612 hook_bool_const_tree_hwi_hwi_const_tree_true
5613
5614#undef TARGET_ASM_OUTPUT_MI_THUNK
5615#define TARGET_ASM_OUTPUT_MI_THUNK nios2_asm_output_mi_thunk
5616
3bbbe009
SL
5617#undef TARGET_MACHINE_DEPENDENT_REORG
5618#define TARGET_MACHINE_DEPENDENT_REORG nios2_reorg
5619
58e17cf8
RS
5620#undef TARGET_CONSTANT_ALIGNMENT
5621#define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
5622
e23f3619
SL
5623#undef TARGET_HAVE_SPECULATION_SAFE_VALUE
5624#define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
5625
e430824f
CLT
5626struct gcc_target targetm = TARGET_INITIALIZER;
5627
5628#include "gt-nios2.h"