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