OSDN Git Service

Add NIOS2 support. Code from SourceyG++.
[pf3gnuchains/gcc-fork.git] / gcc / config / nios2 / nios2.c
1 /* Target machine subroutines for Altera Nios II.
2    Copyright (C) 2012 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 #include <stdio.h>
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "regs.h"
31 #include "hard-reg-set.h"
32 #include "insn-config.h"
33 #include "conditions.h"
34 #include "output.h"
35 #include "insn-attr.h"
36 #include "flags.h"
37 #include "recog.h"
38 #include "expr.h"
39 #include "optabs.h"
40 #include "function.h"
41 #include "ggc.h"
42 #include "basic-block.h"
43 #include "diagnostic-core.h"
44 #include "toplev.h"
45 #include "target.h"
46 #include "target-def.h"
47 #include "tm_p.h"
48 #include "langhooks.h"
49 #include "df.h"
50 #include "debug.h"
51 #include "real.h"
52 #include "integrate.h"
53 #include "reload.h"
54
55 /* Local prototypes.  */
56 static bool nios2_rtx_costs (rtx, int, int, int, int *, bool);
57 static reg_class_t nios2_preferred_reload_class (rtx, reg_class_t);
58 static void nios2_print_operand (FILE *, rtx, int);
59 static void nios2_print_operand_address (FILE *, rtx);
60 static void nios2_asm_function_prologue (FILE *, HOST_WIDE_INT);
61 static int nios2_issue_rate (void);
62 static struct machine_function *nios2_init_machine_status (void);
63 static bool nios2_in_small_data_p (const_tree);
64 static void dump_frame_size (FILE *);
65 static HOST_WIDE_INT compute_frame_size (void);
66 static void save_reg (int, unsigned);
67 static void restore_reg (int, unsigned);
68 static unsigned int nios2_section_type_flags (tree, const char *, int);
69 static bool nios2_can_eliminate (const int, const int);
70 static void nios2_load_pic_register (void);
71 static bool nios2_cannot_force_const_mem (enum machine_mode, rtx);
72 static rtx nios2_legitimize_pic_address (rtx orig, enum machine_mode mode,
73                                          rtx reg);
74 static bool nios2_legitimate_constant_p (enum machine_mode, rtx);
75 static rtx nios2_legitimize_address (rtx x, rtx orig_x, enum machine_mode mode);
76 static bool nios2_legitimate_address_p (enum machine_mode mode, rtx, bool);
77 static void nios2_init_builtins (void);
78 static rtx nios2_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
79 static void nios2_init_libfuncs (void);
80 static rtx nios2_function_arg (cumulative_args_t, enum machine_mode,
81                                const_tree, bool);
82 static void nios2_function_arg_advance (cumulative_args_t, enum machine_mode,
83                                         const_tree, bool);
84 static void nios2_setup_incoming_varargs (cumulative_args_t, enum machine_mode, 
85                                           tree, int *, int);
86 static int nios2_arg_partial_bytes (cumulative_args_t,
87                                     enum machine_mode, tree, bool);
88 static void nios2_trampoline_init (rtx, tree, rtx);
89 static rtx nios2_function_value (const_tree, const_tree, bool);
90 static rtx nios2_libcall_value (enum machine_mode, const_rtx);
91 static bool nios2_function_value_regno_p (const unsigned int);
92 static bool nios2_return_in_memory (const_tree, const_tree);
93 static void nios2_encode_section_info (tree, rtx, int);
94 static void nios2_output_dwarf_dtprel (FILE *fuke, int size, rtx x);
95 static void nios2_option_override (void);
96 static void nios2_option_save (struct cl_target_option*);
97 static void nios2_option_restore (struct cl_target_option*);
98 static void nios2_set_current_function (tree);
99 static bool nios2_valid_target_attribute_p (tree, tree, tree, int);
100 static bool nios2_pragma_target_parse (tree, tree);
101 static tree nios2_merge_decl_attributes (tree, tree);
102 static void nios2_custom_check_insns (void);
103 static void nios2_handle_custom_fpu_cfg (const char*, bool);
104 static void nios2_handle_custom_fpu_insn_option (int);
105 static void nios2_register_custom_code (unsigned int, enum nios2_ccs_code, int);
106 static void nios2_deregister_custom_code (unsigned int);
107
108 /* Initialize the GCC target structure.  */
109 #undef TARGET_ASM_FUNCTION_PROLOGUE
110 #define TARGET_ASM_FUNCTION_PROLOGUE nios2_asm_function_prologue
111
112 #undef TARGET_SCHED_ISSUE_RATE
113 #define TARGET_SCHED_ISSUE_RATE nios2_issue_rate
114 #undef TARGET_IN_SMALL_DATA_P
115 #define TARGET_IN_SMALL_DATA_P nios2_in_small_data_p
116 #undef  TARGET_ENCODE_SECTION_INFO
117 #define TARGET_ENCODE_SECTION_INFO nios2_encode_section_info
118 #undef  TARGET_SECTION_TYPE_FLAGS
119 #define TARGET_SECTION_TYPE_FLAGS  nios2_section_type_flags
120
121 #undef TARGET_INIT_BUILTINS
122 #define TARGET_INIT_BUILTINS nios2_init_builtins
123 #undef TARGET_EXPAND_BUILTIN
124 #define TARGET_EXPAND_BUILTIN nios2_expand_builtin
125
126 #undef TARGET_INIT_LIBFUNCS
127 #define TARGET_INIT_LIBFUNCS nios2_init_libfuncs
128
129 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
130 #define TARGET_FUNCTION_OK_FOR_SIBCALL hook_bool_tree_tree_true
131
132 #undef TARGET_CAN_ELIMINATE
133 #define TARGET_CAN_ELIMINATE nios2_can_eliminate
134
135 #undef TARGET_FUNCTION_ARG
136 #define TARGET_FUNCTION_ARG nios2_function_arg
137
138 #undef TARGET_FUNCTION_ARG_ADVANCE
139 #define TARGET_FUNCTION_ARG_ADVANCE nios2_function_arg_advance
140
141 #undef TARGET_ARG_PARTIAL_BYTES
142 #define TARGET_ARG_PARTIAL_BYTES nios2_arg_partial_bytes
143
144 #undef TARGET_TRAMPOLINE_INIT
145 #define TARGET_TRAMPOLINE_INIT nios2_trampoline_init
146
147 #undef TARGET_FUNCTION_VALUE
148 #define TARGET_FUNCTION_VALUE nios2_function_value
149
150 #undef TARGET_LIBCALL_VALUE
151 #define TARGET_LIBCALL_VALUE nios2_libcall_value
152
153 #undef TARGET_FUNCTION_VALUE_REGNO_P
154 #define TARGET_FUNCTION_VALUE_REGNO_P nios2_function_value_regno_p
155
156 #undef TARGET_RETURN_IN_MEMORY
157 #define TARGET_RETURN_IN_MEMORY nios2_return_in_memory
158
159 #undef TARGET_PROMOTE_PROTOTYPES
160 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
161
162 #undef TARGET_SETUP_INCOMING_VARARGS
163 #define TARGET_SETUP_INCOMING_VARARGS nios2_setup_incoming_varargs
164
165 #undef TARGET_MUST_PASS_IN_STACK
166 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
167
168 #undef TARGET_LEGITIMATE_CONSTANT_P
169 #define TARGET_LEGITIMATE_CONSTANT_P nios2_legitimate_constant_p
170
171 #undef TARGET_LEGITIMIZE_ADDRESS
172 #define TARGET_LEGITIMIZE_ADDRESS nios2_legitimize_address
173
174 #undef TARGET_LEGITIMATE_ADDRESS_P
175 #define TARGET_LEGITIMATE_ADDRESS_P nios2_legitimate_address_p
176
177 #undef TARGET_PREFERRED_RELOAD_CLASS
178 #define TARGET_PREFERRED_RELOAD_CLASS nios2_preferred_reload_class
179
180 #undef TARGET_RTX_COSTS
181 #define TARGET_RTX_COSTS nios2_rtx_costs
182
183 #undef TARGET_HAVE_TLS
184 #define TARGET_HAVE_TLS TARGET_LINUX_ABI
185
186 #undef TARGET_CANNOT_FORCE_CONST_MEM
187 #define TARGET_CANNOT_FORCE_CONST_MEM nios2_cannot_force_const_mem
188
189 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
190 #define TARGET_ASM_OUTPUT_DWARF_DTPREL nios2_output_dwarf_dtprel
191
192 #undef TARGET_PRINT_OPERAND
193 #define TARGET_PRINT_OPERAND nios2_print_operand
194
195 #undef TARGET_PRINT_OPERAND_ADDRESS
196 #define TARGET_PRINT_OPERAND_ADDRESS nios2_print_operand_address
197
198 #undef TARGET_OPTION_OVERRIDE
199 #define TARGET_OPTION_OVERRIDE nios2_option_override
200
201 #undef TARGET_OPTION_SAVE
202 #define TARGET_OPTION_SAVE nios2_option_save
203
204 #undef TARGET_OPTION_RESTORE
205 #define TARGET_OPTION_RESTORE nios2_option_restore
206
207 #undef TARGET_SET_CURRENT_FUNCTION
208 #define TARGET_SET_CURRENT_FUNCTION nios2_set_current_function
209
210 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
211 #define TARGET_OPTION_VALID_ATTRIBUTE_P nios2_valid_target_attribute_p
212
213 #undef TARGET_OPTION_PRAGMA_PARSE
214 #define TARGET_OPTION_PRAGMA_PARSE nios2_pragma_target_parse
215
216 #undef TARGET_MERGE_DECL_ATTRIBUTES
217 #define TARGET_MERGE_DECL_ATTRIBUTES nios2_merge_decl_attributes
218
219 /* ??? Might want to redefine TARGET_RETURN_IN_MSB here to handle
220    big-endian case; depends on what ABI we choose.  */
221
222 struct gcc_target targetm = TARGET_INITIALIZER;
223 \f
224
225 /* Threshold for data being put into the small data/bss area, instead
226    of the normal data area (references to the small data/bss area take
227    1 instruction, and use the global pointer, references to the normal
228    data area takes 2 instructions).  */
229 unsigned HOST_WIDE_INT nios2_section_threshold = NIOS2_DEFAULT_GVALUE;
230
231 struct GTY (()) machine_function
232 {
233   /* Current frame information, to be filled in by compute_frame_size
234      with register save masks, and offsets for the current function.  */
235
236   unsigned HOST_WIDE_INT save_mask; /* Mask of registers to save.  */
237   long total_size;       /* # bytes that the entire frame takes up.  */
238   long var_size;         /* # bytes that variables take up.  */
239   long args_size;        /* # bytes that outgoing arguments take up.  */
240   int save_reg_size;     /* # bytes needed to store gp regs.  */
241   long save_regs_offset; /* Offset from new sp to store gp registers.  */
242   int initialized;       /* != 0 if frame size already calculated.  */
243 };
244
245 /* State to track the assignment of custom codes to FPU/custom builtins.  */
246 static enum nios2_ccs_code custom_code_status[256];
247 static int custom_code_index[256];
248 /* Set to true if any conflicts (re-use of a code between 0-255) are found.  */
249 static bool custom_code_conflict = false;
250
251 \f
252
253 /* Definition of builtin function types for nios2.  */
254
255 #define N2_FTYPES                               \
256   N2_FTYPE(1, (SF))                             \
257   N2_FTYPE(1, (VOID))                           \
258   N2_FTYPE(2, (DF, DF))                         \
259   N2_FTYPE(3, (DF, DF, DF))                     \
260   N2_FTYPE(2, (DF, SF))                         \
261   N2_FTYPE(2, (DF, SI))                         \
262   N2_FTYPE(2, (DF, UI))                         \
263   N2_FTYPE(2, (SF, DF))                         \
264   N2_FTYPE(2, (SF, SF))                         \
265   N2_FTYPE(3, (SF, SF, SF))                     \
266   N2_FTYPE(2, (SF, SI))                         \
267   N2_FTYPE(2, (SF, UI))                         \
268   N2_FTYPE(2, (SI, CVPTR))                      \
269   N2_FTYPE(2, (SI, DF))                         \
270   N2_FTYPE(3, (SI, DF, DF))                     \
271   N2_FTYPE(2, (SI, SF))                         \
272   N2_FTYPE(3, (SI, SF, SF))                     \
273   N2_FTYPE(2, (SI, SI))                         \
274   N2_FTYPE(2, (UI, CVPTR))                      \
275   N2_FTYPE(2, (UI, DF))                         \
276   N2_FTYPE(2, (UI, SF))                         \
277   N2_FTYPE(2, (VOID, DF))                       \
278   N2_FTYPE(2, (VOID, SF))                       \
279   N2_FTYPE(3, (VOID, SI, SI))                   \
280   N2_FTYPE(3, (VOID, VPTR, SI))
281
282 #define N2_FTYPE_OP1(R)         N2_FTYPE_ ## R ## _VOID
283 #define N2_FTYPE_OP2(R, A1)     N2_FTYPE_ ## R ## _ ## A1
284 #define N2_FTYPE_OP3(R, A1, A2) N2_FTYPE_ ## R ## _ ## A1 ## _ ## A2
285
286 /* Expand ftcode enumeration.  */
287 enum nios2_ftcode {
288 #define N2_FTYPE(N,ARGS) N2_FTYPE_OP ## N ARGS,
289 N2_FTYPES
290 #undef N2_FTYPE
291 N2_FTYPE_MAX
292 };
293
294 /* Return the tree function type, based on the ftcode.  */
295 static tree
296 nios2_ftype (enum nios2_ftcode ftcode)
297 {
298   static tree types[(int) N2_FTYPE_MAX];
299
300   tree N2_TYPE_SF = float_type_node;
301   tree N2_TYPE_DF = double_type_node;
302   tree N2_TYPE_SI = integer_type_node;
303   tree N2_TYPE_UI = unsigned_type_node;
304   tree N2_TYPE_VOID = void_type_node;
305
306   static const_tree N2_TYPE_CVPTR, N2_TYPE_VPTR;
307   if (!N2_TYPE_CVPTR)
308     {
309       /* const volatile void * */
310       N2_TYPE_CVPTR
311         = build_pointer_type (build_qualified_type (void_type_node,
312                                                     (TYPE_QUAL_CONST
313                                                      | TYPE_QUAL_VOLATILE)));
314       /* volatile void * */
315       N2_TYPE_VPTR
316         = build_pointer_type (build_qualified_type (void_type_node,
317                                                     TYPE_QUAL_VOLATILE));
318     }
319   if (types[(int) ftcode] == NULL_TREE)
320     switch (ftcode)
321       {
322 #define N2_FTYPE_ARGS1(R) N2_TYPE_ ## R
323 #define N2_FTYPE_ARGS2(R,A1) N2_TYPE_ ## R, N2_TYPE_ ## A1
324 #define N2_FTYPE_ARGS3(R,A1,A2) N2_TYPE_ ## R, N2_TYPE_ ## A1, N2_TYPE_ ## A2
325 #define N2_FTYPE(N,ARGS)                                                \
326   case N2_FTYPE_OP ## N ARGS:                                           \
327     types[(int) ftcode]                                                 \
328       = build_function_type_list (N2_FTYPE_ARGS ## N ARGS, NULL_TREE); \
329     break;
330         N2_FTYPES
331 #undef N2_FTYPE
332       default: gcc_unreachable ();
333       }
334   return types[(int) ftcode];
335 }
336
337
338 \f
339 /* Definition of FPU instruction descriptions.  */
340
341 struct nios2_fpu_insn_info
342 {
343   const char *name;
344   int num_operands, *optvar;
345   int opt, no_opt;
346 #define N2F_DF            0x1
347 #define N2F_DFREQ         0x2
348 #define N2F_UNSAFE        0x4
349 #define N2F_FINITE        0x8
350   unsigned int flags;
351   enum insn_code icode;
352   enum nios2_ftcode ftcode;
353 };
354
355 /* Base macro for defining FPU instructions.  */
356 #define N2FPU_INSN_DEF_BASE(insn, nop, flags, icode, args)      \
357   { #insn, nop, &nios2_custom_ ## insn, OPT_mcustom_##insn##_,  \
358     OPT_mno_custom_##insn, flags, CODE_FOR_ ## icode,           \
359     N2_FTYPE_OP ## nop args }
360
361 /* Arithmetic and math functions; 2 or 3 operand FP operations.  */
362 #define N2FPU_OP2(mode) (mode, mode)
363 #define N2FPU_OP3(mode) (mode, mode, mode)
364 #define N2FPU_INSN_DEF(code, icode, nop, flags, m, M)                   \
365   N2FPU_INSN_DEF_BASE (f ## code ## m, nop, flags,                      \
366                        icode ## m ## f ## nop, N2FPU_OP ## nop (M ## F))
367 #define N2FPU_INSN_SF(code, nop, flags)         \
368   N2FPU_INSN_DEF (code, code, nop, flags, s, S)
369 #define N2FPU_INSN_DF(code, nop, flags)         \
370   N2FPU_INSN_DEF (code, code, nop, flags | N2F_DF, d, D)
371
372 /* Compare instructions, 3 operand FP operation with a SI result.  */
373 #define N2FPU_CMP_DEF(code, flags, m, M)                                \
374   N2FPU_INSN_DEF_BASE (fcmp ## code ## m, 3, flags,                     \
375                        nios2_s ## code ## m ## f, (SI, M ## F, M ## F))
376 #define N2FPU_CMP_SF(code) N2FPU_CMP_DEF (code, 0, s, S)
377 #define N2FPU_CMP_DF(code) N2FPU_CMP_DEF (code, N2F_DF, d, D)
378
379 /* The order of definition needs to be maintained consistent with
380    enum n2fpu_code in nios2-opts.h.  */
381 struct nios2_fpu_insn_info nios2_fpu_insn[] =
382   {
383     /* Single precision instructions.  */
384     N2FPU_INSN_SF (add, 3, 0),
385     N2FPU_INSN_SF (sub, 3, 0),
386     N2FPU_INSN_SF (mul, 3, 0),
387     N2FPU_INSN_SF (div, 3, 0),
388     /* Due to textual difference between min/max and smin/smax.  */
389     N2FPU_INSN_DEF (min, smin, 3, N2F_FINITE, s, S),
390     N2FPU_INSN_DEF (max, smax, 3, N2F_FINITE, s, S),
391     N2FPU_INSN_SF (neg, 2, 0),
392     N2FPU_INSN_SF (abs, 2, 0),
393     N2FPU_INSN_SF (sqrt, 2, 0),
394     N2FPU_INSN_SF (sin, 2, N2F_UNSAFE),
395     N2FPU_INSN_SF (cos, 2, N2F_UNSAFE),
396     N2FPU_INSN_SF (tan, 2, N2F_UNSAFE),
397     N2FPU_INSN_SF (atan, 2, N2F_UNSAFE),
398     N2FPU_INSN_SF (exp, 2, N2F_UNSAFE),
399     N2FPU_INSN_SF (log, 2, N2F_UNSAFE),
400     /* Single precision compares.  */
401     N2FPU_CMP_SF (eq), N2FPU_CMP_SF (ne),
402     N2FPU_CMP_SF (lt), N2FPU_CMP_SF (le),
403     N2FPU_CMP_SF (gt), N2FPU_CMP_SF (ge),
404
405     /* Double precision instructions.  */
406     N2FPU_INSN_DF (add, 3, 0),
407     N2FPU_INSN_DF (sub, 3, 0),
408     N2FPU_INSN_DF (mul, 3, 0),
409     N2FPU_INSN_DF (div, 3, 0),
410     /* Due to textual difference between min/max and smin/smax.  */
411     N2FPU_INSN_DEF (min, smin, 3, N2F_FINITE, d, D),
412     N2FPU_INSN_DEF (max, smax, 3, N2F_FINITE, d, D),
413     N2FPU_INSN_DF (neg, 2, 0),
414     N2FPU_INSN_DF (abs, 2, 0),
415     N2FPU_INSN_DF (sqrt, 2, 0),
416     N2FPU_INSN_DF (sin, 2, N2F_UNSAFE),
417     N2FPU_INSN_DF (cos, 2, N2F_UNSAFE),
418     N2FPU_INSN_DF (tan, 2, N2F_UNSAFE),
419     N2FPU_INSN_DF (atan, 2, N2F_UNSAFE),
420     N2FPU_INSN_DF (exp, 2, N2F_UNSAFE),
421     N2FPU_INSN_DF (log, 2, N2F_UNSAFE),
422     /* Double precision compares.  */
423     N2FPU_CMP_DF (eq), N2FPU_CMP_DF (ne),
424     N2FPU_CMP_DF (lt), N2FPU_CMP_DF (le),
425     N2FPU_CMP_DF (gt), N2FPU_CMP_DF (ge),
426
427     /* Conversion instructions.  */
428     N2FPU_INSN_DEF_BASE (floatis,  2, 0, floatsisf2,    (SF, SI)),
429     N2FPU_INSN_DEF_BASE (floatus,  2, 0, floatunssisf2, (SF, UI)),
430     N2FPU_INSN_DEF_BASE (floatid,  2, 0, floatsidf2,    (DF, SI)),
431     N2FPU_INSN_DEF_BASE (floatud,  2, 0, floatunssidf2, (DF, UI)),
432     N2FPU_INSN_DEF_BASE (fixsi,    2, 0, fix_truncsfsi2,      (SI, SF)),
433     N2FPU_INSN_DEF_BASE (fixsu,    2, 0, fixuns_truncsfsi2,   (UI, SF)),
434     N2FPU_INSN_DEF_BASE (fixdi,    2, 0, fix_truncdfsi2,      (SI, DF)),
435     N2FPU_INSN_DEF_BASE (fixdu,    2, 0, fixuns_truncdfsi2,   (UI, DF)),
436     N2FPU_INSN_DEF_BASE (fextsd,   2, 0, extendsfdf2,   (DF, SF)),
437     N2FPU_INSN_DEF_BASE (ftruncds, 2, 0, truncdfsf2,    (SF, DF)),
438
439     /* X, Y access instructions.  */
440     N2FPU_INSN_DEF_BASE (fwrx,     2, N2F_DFREQ, nios2_fwrx,   (VOID, DF)),
441     N2FPU_INSN_DEF_BASE (fwry,     2, N2F_DFREQ, nios2_fwry,   (VOID, SF)),
442     N2FPU_INSN_DEF_BASE (frdxlo,   1, N2F_DFREQ, nios2_frdxlo, (SF)),
443     N2FPU_INSN_DEF_BASE (frdxhi,   1, N2F_DFREQ, nios2_frdxhi, (SF)),
444     N2FPU_INSN_DEF_BASE (frdy,     1, N2F_DFREQ, nios2_frdy,   (SF))
445   };
446
447 /* Some macros for ease of access.  */
448 #define N2FPU(code) nios2_fpu_insn[(int) code]
449 #define N2FPU_ENABLED_P(code) (N2FPU_N(code) >= 0)
450 #define N2FPU_N(code) (*N2FPU(code).optvar)
451 #define N2FPU_NAME(code) (N2FPU(code).name)
452 #define N2FPU_ICODE(code) (N2FPU(code).icode)
453 #define N2FPU_FTCODE(code) (N2FPU(code).ftcode)
454 #define N2FPU_FINITE_P(code) (N2FPU(code).flags & N2F_FINITE)
455 #define N2FPU_UNSAFE_P(code) (N2FPU(code).flags & N2F_UNSAFE)
456 #define N2FPU_DOUBLE_P(code) (N2FPU(code).flags & N2F_DF)
457 #define N2FPU_DOUBLE_REQUIRED_P(code) (N2FPU(code).flags & N2F_DFREQ)
458
459 /* Same as above, but for cases where using only the op part is shorter.  */
460 #define N2FPU_OP(op) N2FPU(n2fpu_ ## op)
461 #define N2FPU_OP_NAME(op) N2FPU_NAME(n2fpu_ ## op)
462 #define N2FPU_OP_ENABLED_P(op) N2FPU_ENABLED_P(n2fpu_ ## op)
463
464 /* Export the FPU insn enabled predicate to nios2.md.  */
465 bool
466 nios2_fpu_insn_enabled (enum n2fpu_code code)
467 {
468   return N2FPU_ENABLED_P (code);
469 }
470
471 static bool
472 nios2_fpu_compare_enabled (enum rtx_code cond, enum machine_mode mode)
473 {
474   if (mode == SFmode)
475     switch (cond) 
476       {
477       case EQ: return N2FPU_OP_ENABLED_P (fcmpeqs);
478       case NE: return N2FPU_OP_ENABLED_P (fcmpnes);
479       case GT: return N2FPU_OP_ENABLED_P (fcmpgts);
480       case GE: return N2FPU_OP_ENABLED_P (fcmpges);
481       case LT: return N2FPU_OP_ENABLED_P (fcmplts);
482       case LE: return N2FPU_OP_ENABLED_P (fcmples);
483       default: break;
484       }
485   else if (mode == DFmode)
486     switch (cond) 
487       {
488       case EQ: return N2FPU_OP_ENABLED_P (fcmpeqd);
489       case NE: return N2FPU_OP_ENABLED_P (fcmpned);
490       case GT: return N2FPU_OP_ENABLED_P (fcmpgtd);
491       case GE: return N2FPU_OP_ENABLED_P (fcmpged);
492       case LT: return N2FPU_OP_ENABLED_P (fcmpltd);
493       case LE: return N2FPU_OP_ENABLED_P (fcmpled);
494       default: break;
495       }
496   return false;
497 }
498
499 #define IS_UNSPEC_TLS(x) ((x) >= UNSPEC_TLS && (x) <= UNSPEC_ADD_TLS_LDO)
500
501
502 /* Stack Layout and Calling Conventions */
503
504 #define TOO_BIG_OFFSET(X) ((X) > ((1 << 15) - 1))
505 #define TEMP_REG_NUM 8
506
507 static void
508 save_reg (int regno, unsigned offset)
509 {
510   rtx reg = gen_rtx_REG (SImode, regno);
511   rtx addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
512                            gen_int_mode (offset, Pmode));
513
514   rtx pattern = gen_rtx_SET (SImode, gen_frame_mem (Pmode, addr), reg);
515   rtx insn = emit_insn (pattern);
516   RTX_FRAME_RELATED_P (insn) = 1;
517 }
518
519 static void
520 restore_reg (int regno, unsigned offset)
521 {
522   rtx reg = gen_rtx_REG (SImode, regno);
523   rtx addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
524                            gen_int_mode (offset, Pmode));
525
526   rtx pattern = gen_rtx_SET (SImode, reg, gen_frame_mem (Pmode, addr));
527   emit_insn (pattern);
528 }
529
530 void
531 expand_prologue (void)
532 {
533   int ix;
534   HOST_WIDE_INT total_frame_size = compute_frame_size ();
535   int sp_offset;        /* offset from base_reg to final stack value.  */
536   int fp_offset;        /* offset from base_reg to final fp value.  */
537   int save_offset;
538   rtx insn;
539   unsigned HOST_WIDE_INT save_mask;
540
541   total_frame_size = compute_frame_size ();
542   if (flag_stack_usage_info)
543     current_function_static_stack_size = total_frame_size;
544
545   /* Decrement the stack pointer */
546   if (TOO_BIG_OFFSET (total_frame_size))
547     {
548       /* We need an intermediary point, this will point at the spill
549          block.  */
550       insn = emit_insn
551         (gen_add3_insn (stack_pointer_rtx,
552                         stack_pointer_rtx,
553                         gen_int_mode (cfun->machine->save_regs_offset
554                                       - total_frame_size, Pmode)));
555       RTX_FRAME_RELATED_P (insn) = 1;
556
557       fp_offset = 0;
558       sp_offset = -cfun->machine->save_regs_offset;
559     }
560   else if (total_frame_size)
561     {
562       insn = emit_insn (gen_add3_insn (stack_pointer_rtx,
563                                        stack_pointer_rtx,
564                                        gen_int_mode (-total_frame_size,
565                                                      Pmode)));
566       RTX_FRAME_RELATED_P (insn) = 1;
567       fp_offset = cfun->machine->save_regs_offset;
568       sp_offset = 0;
569     }
570   else
571     fp_offset = sp_offset = 0;
572
573   if (crtl->limit_stack)
574     emit_insn (gen_stack_overflow_detect_and_trap ());
575
576   save_offset = fp_offset + cfun->machine->save_reg_size;
577   save_mask = cfun->machine->save_mask;
578   
579   for (ix = 32; ix--;)
580     if (save_mask & ((unsigned HOST_WIDE_INT)1 << ix))
581       {
582         save_offset -= 4;
583         save_reg (ix, save_offset);
584       }
585
586   if (frame_pointer_needed)
587     {
588       insn = emit_insn (gen_add3_insn (hard_frame_pointer_rtx,
589                                        stack_pointer_rtx,
590                                        gen_int_mode (fp_offset, Pmode)));
591       RTX_FRAME_RELATED_P (insn) = 1;
592     }
593
594   if (sp_offset)
595     {
596       rtx sp_adjust
597         = gen_rtx_SET (Pmode, stack_pointer_rtx,
598                        gen_rtx_PLUS (Pmode, stack_pointer_rtx,
599                                      gen_int_mode (sp_offset, Pmode)));
600       if (SMALL_INT (sp_offset))
601         insn = emit_insn (sp_adjust);
602       else
603         {
604           rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM);
605           emit_insn (gen_rtx_SET (Pmode, tmp, gen_int_mode (sp_offset, Pmode)));
606           insn = emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
607                                            tmp));
608           /* Attach the sp_adjust as a note indicating what happened.  */
609           REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
610                                               sp_adjust, REG_NOTES (insn));
611         }
612       RTX_FRAME_RELATED_P (insn) = 1;
613
614       if (crtl->limit_stack)
615         emit_insn (gen_stack_overflow_detect_and_trap ());
616     }
617
618   /* Load the PIC register if needed.  */
619   if (crtl->uses_pic_offset_table)
620     nios2_load_pic_register ();
621
622   /* If we are profiling, make sure no instructions are scheduled before
623      the call to mcount.  */
624   if (crtl->profile)
625     emit_insn (gen_blockage ());
626 }
627
628 void
629 expand_epilogue (bool sibcall_p)
630 {
631   int ix;
632   HOST_WIDE_INT total_frame_size = compute_frame_size ();
633   unsigned HOST_WIDE_INT save_mask;
634   int sp_adjust;
635   int save_offset;
636  
637   if (!sibcall_p && nios2_can_use_return_insn ())
638     {
639       emit_jump_insn (gen_return ());
640       return;
641     }
642
643   emit_insn (gen_blockage ());
644
645   if (frame_pointer_needed)
646     {
647       /* Recover the stack pointer.  */
648       emit_insn (gen_rtx_SET (Pmode, stack_pointer_rtx,
649                               hard_frame_pointer_rtx));
650       save_offset = 0;
651       sp_adjust = total_frame_size - cfun->machine->save_regs_offset;
652     }
653   else if (TOO_BIG_OFFSET (total_frame_size))
654     {
655       rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM);
656
657       emit_insn
658         (gen_rtx_SET (Pmode, tmp,
659                       gen_int_mode (cfun->machine->save_regs_offset,
660                                     Pmode)));
661       emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, tmp));
662       save_offset = 0;
663       sp_adjust = total_frame_size - cfun->machine->save_regs_offset;
664     }
665   else
666     {
667       save_offset = cfun->machine->save_regs_offset;
668       sp_adjust = total_frame_size;
669     }
670   
671   save_mask = cfun->machine->save_mask;
672   save_offset += cfun->machine->save_reg_size;
673   
674   for (ix = 32; ix--;)
675     if (save_mask & ((unsigned HOST_WIDE_INT)1 << ix))
676       {
677         save_offset -= 4;
678         restore_reg (ix, save_offset);
679       }
680
681   if (sp_adjust)
682     emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
683                               gen_int_mode (sp_adjust, Pmode)));
684
685   /* Add in the __builtin_eh_return stack adjustment.  */
686   if (crtl->calls_eh_return)
687     emit_insn (gen_add3_insn (stack_pointer_rtx,
688                               stack_pointer_rtx,
689                               EH_RETURN_STACKADJ_RTX));
690
691   if (!sibcall_p)
692     emit_jump_insn (gen_return_from_epilogue (gen_rtx_REG (Pmode, RA_REGNO)));
693 }
694
695 /* Implement RETURN_ADDR_RTX.  Note, we do not support moving
696    back to a previous frame.  */
697 rtx
698 nios2_get_return_address (int count)
699 {
700   if (count != 0)
701     return const0_rtx;
702
703   return get_hard_reg_initial_val (Pmode, RA_REGNO);
704 }
705
706 /* Emit code to change the current function's return address to
707    ADDRESS.  SCRATCH is available as a scratch register, if needed.
708    ADDRESS and SCRATCH are both word-mode GPRs.  */
709 void
710 nios2_set_return_address (rtx address, rtx scratch)
711 {
712   compute_frame_size ();
713   if ((cfun->machine->save_mask >> RA_REGNO) & 1)
714     {
715       unsigned offset = cfun->machine->save_reg_size - 4;
716       rtx base;
717       
718       if (frame_pointer_needed)
719         base = hard_frame_pointer_rtx;
720       else
721         {
722           base = stack_pointer_rtx;
723           offset += cfun->machine->save_regs_offset;
724           
725           if (TOO_BIG_OFFSET (offset))
726             {
727               emit_insn (gen_rtx_SET (Pmode, scratch,
728                                       gen_int_mode (offset, Pmode)));
729               emit_insn (gen_add3_insn (scratch, scratch, base));
730               base = scratch;
731               offset = 0;
732             }
733         }
734       if (offset)
735         base = gen_rtx_PLUS (Pmode, base, gen_int_mode (offset, Pmode));
736       emit_insn (gen_rtx_SET (Pmode, gen_rtx_MEM (Pmode, base), address));
737     }
738   else
739     emit_insn (gen_rtx_SET (Pmode, gen_rtx_REG (Pmode, RA_REGNO), address));
740 }
741
742 \f
743 /* Profiling.  */
744
745 void
746 nios2_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
747 {
748   fprintf (file, "\tmov\tr8, ra\n");
749   if (flag_pic)
750     {
751       fprintf (file, "\tnextpc\tr2\n");
752       fprintf (file, "\t1: movhi\tr3, %%hiadj(_GLOBAL_OFFSET_TABLE_ - 1b)\n");
753       fprintf (file, "\taddi\tr3, r3, %%lo(_GLOBAL_OFFSET_TABLE_ - 1b)\n");
754       fprintf (file, "\tadd\tr2, r2, r3\n");
755       fprintf (file, "\tldw\tr2, %%call(_mcount)(r2)\n");
756       fprintf (file, "\tcallr\tr2\n");
757     }
758   else
759     fprintf (file, "\tcall\t_mcount\n");
760   fprintf (file, "\tmov\tra, r8\n");
761 }
762
763 /* Stack Layout.  */
764 static void
765 dump_frame_size (FILE *file)
766 {
767   fprintf (file, "\t%s Current Frame Info\n", ASM_COMMENT_START);
768
769   fprintf (file, "\t%s total_size = %ld\n", ASM_COMMENT_START,
770            cfun->machine->total_size);
771   fprintf (file, "\t%s var_size = %ld\n", ASM_COMMENT_START,
772            cfun->machine->var_size);
773   fprintf (file, "\t%s args_size = %ld\n", ASM_COMMENT_START,
774            cfun->machine->args_size);
775   fprintf (file, "\t%s save_reg_size = %d\n", ASM_COMMENT_START,
776            cfun->machine->save_reg_size);
777   fprintf (file, "\t%s initialized = %d\n", ASM_COMMENT_START,
778            cfun->machine->initialized);
779   fprintf (file, "\t%s save_regs_offset = %ld\n", ASM_COMMENT_START,
780            cfun->machine->save_regs_offset);
781   fprintf (file, "\t%s current_function_is_leaf = %d\n", ASM_COMMENT_START,
782            current_function_is_leaf);
783   fprintf (file, "\t%s frame_pointer_needed = %d\n", ASM_COMMENT_START,
784            frame_pointer_needed);
785   fprintf (file, "\t%s pretend_args_size = %d\n", ASM_COMMENT_START,
786            crtl->args.pretend_args_size);
787
788 }
789
790 /* Return true if REGNO should be saved in a prologue.  */
791 static bool
792 save_reg_p (unsigned regno)
793 {
794   gcc_assert (GP_REGNO_P (regno));
795   
796   if (df_regs_ever_live_p (regno) && !call_used_regs[regno])
797     return true;
798
799   if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
800     return true;
801
802   if (regno == PIC_OFFSET_TABLE_REGNUM && crtl->uses_pic_offset_table)
803     return true;
804
805   if (regno == RA_REGNO && df_regs_ever_live_p (RA_REGNO))
806     return true;
807
808   return false;
809 }
810
811 /* Return the bytes needed to compute the frame pointer from the current
812    stack pointer.  */
813 static HOST_WIDE_INT
814 compute_frame_size (void)
815 {
816   unsigned int regno;
817   HOST_WIDE_INT var_size;       /* # of var. bytes allocated.  */
818   HOST_WIDE_INT total_size;     /* # bytes that the entire frame takes up.  */
819   HOST_WIDE_INT save_reg_size;  /* # bytes needed to store callee save regs.  */
820   HOST_WIDE_INT out_args_size;  /* # bytes needed for outgoing args. */
821   unsigned HOST_WIDE_INT save_mask = 0;
822
823   if (cfun->machine->initialized)
824     return cfun->machine->total_size;
825   
826   save_reg_size = 0;
827   var_size = STACK_ALIGN (get_frame_size ());
828   out_args_size = STACK_ALIGN (crtl->outgoing_args_size);
829
830   total_size = var_size + out_args_size;
831
832   /* Calculate space needed for gp registers.  */
833   for (regno = 0; GP_REGNO_P (regno); regno++)
834     if (save_reg_p (regno))
835       {
836         save_mask |= (unsigned HOST_WIDE_INT)1 << regno;
837         save_reg_size += 4;
838       }
839
840   /* If we call eh_return, we need to save the EH data registers.  */
841   if (crtl->calls_eh_return)
842     {
843       unsigned i;
844       unsigned r;
845       
846       for (i = 0; (r = EH_RETURN_DATA_REGNO (i)) != INVALID_REGNUM; i++)
847         if (!(save_mask & (1 << r)))
848           {
849             save_mask |= 1 << r;
850             save_reg_size += 4;
851           }
852     }
853
854   save_reg_size = STACK_ALIGN (save_reg_size);
855   total_size += save_reg_size;
856
857   total_size += STACK_ALIGN (crtl->args.pretend_args_size);
858
859   /* Save other computed information.  */
860   cfun->machine->save_mask = save_mask;
861   cfun->machine->total_size = total_size;
862   cfun->machine->var_size = var_size;
863   cfun->machine->args_size = out_args_size;
864   cfun->machine->save_reg_size = save_reg_size;
865   cfun->machine->initialized = reload_completed;
866   cfun->machine->save_regs_offset = out_args_size + var_size;
867
868   return total_size;
869 }
870
871 /* Implement TARGET_CAN_ELIMINATE.  */
872 static bool
873 nios2_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
874 {
875   if (to == STACK_POINTER_REGNUM)
876     return !frame_pointer_needed;
877   return true;
878 }
879
880 int
881 nios2_initial_elimination_offset (int from, int to)
882 {
883   int offset;
884
885   compute_frame_size ();
886
887   /* Set OFFSET to the offset from the stack pointer.  */
888   switch (from)
889     {
890     case FRAME_POINTER_REGNUM:
891       offset = cfun->machine->args_size;
892       break;
893
894     case ARG_POINTER_REGNUM:
895       offset = cfun->machine->total_size;
896       offset -= crtl->args.pretend_args_size;
897       break;
898
899     default:
900       gcc_unreachable ();
901     }
902
903     /* If we are asked for the frame pointer offset, then adjust OFFSET
904        by the offset from the frame pointer to the stack pointer.  */
905     if (to == HARD_FRAME_POINTER_REGNUM)
906       offset -= cfun->machine->save_regs_offset;
907
908     return offset;
909 }
910
911 /* Return nonzero if this function is known to have a null epilogue.
912    This allows the optimizer to omit jumps to jumps if no stack
913    was created.  */
914 int
915 nios2_can_use_return_insn (void)
916 {
917   if (!reload_completed)
918     return 0;
919
920   if (df_regs_ever_live_p (RA_REGNO) || crtl->profile)
921     return 0;
922
923   if (cfun->machine->initialized)
924     return cfun->machine->total_size == 0;
925
926   return compute_frame_size () == 0;
927 }
928
929
930 \f
931 /* Check and signal some warnings/errors on FPU insn options.  */
932 static void
933 nios2_custom_check_insns (void)
934 {
935   unsigned int i, j;
936   bool errors = false;
937
938   for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
939     if (N2FPU_ENABLED_P (i) && N2FPU_DOUBLE_P (i))
940       {
941         for (j = 0; j < ARRAY_SIZE (nios2_fpu_insn); j++)
942           if (N2FPU_DOUBLE_REQUIRED_P (j) && ! N2FPU_ENABLED_P (j))
943             {
944               error ("switch `-mcustom-%s' is required for double precision "
945                      "floating point", N2FPU_NAME (j));
946               errors = true;
947             }
948         break;
949       }
950
951   /* Warn if the user has certain exotic operations that won't get used
952      without -funsafe-math-optimizations.  See expand_builtin () in
953      builtins.c.  */
954   if (!flag_unsafe_math_optimizations)
955     for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
956       if (N2FPU_ENABLED_P (i) && N2FPU_UNSAFE_P (i))
957         warning (0, "switch `-mcustom-%s' has no effect unless "
958                  "-funsafe-math-optimizations is specified", N2FPU_NAME (i));
959
960   /* Warn if the user is trying to use -mcustom-fmins et. al, that won't
961      get used without -ffinite-math-only.  See fold_builtin_fmin_fmax ()
962      in builtins.c.  */
963   if (!flag_finite_math_only)
964     for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
965       if (N2FPU_ENABLED_P (i) && N2FPU_FINITE_P (i))
966         warning (0, "switch `-mcustom-%s' has no effect unless "
967                  "-ffinite-math-only is specified", N2FPU_NAME (i));
968
969   if (errors || custom_code_conflict)
970     fatal_error ("conflicting use of -mcustom switches, target attributes, "
971                  "and/or __builtin_custom_ functions");
972 }
973
974 static void
975 nios2_set_fpu_custom_code (enum n2fpu_code code, int N, bool override_p)
976 {
977   if (override_p || N2FPU_N (code) == -1)
978     N2FPU_N (code) = N;
979   nios2_register_custom_code (N, CCS_FPU, (int) code);
980 }
981
982 static void
983 nios2_handle_custom_fpu_cfg (const char *cfg, bool override_p)
984 {
985   if (!strncasecmp (cfg, "60-1", 4))
986     {
987       nios2_set_fpu_custom_code (n2fpu_fmuls, 252, override_p);
988       nios2_set_fpu_custom_code (n2fpu_fadds, 253, override_p);
989       nios2_set_fpu_custom_code (n2fpu_fsubs, 254, override_p);
990       flag_single_precision_constant = 1;
991     }
992   else if (!strncasecmp (cfg, "60-2", 4))
993     {
994       nios2_set_fpu_custom_code (n2fpu_fmuls, 252, override_p);
995       nios2_set_fpu_custom_code (n2fpu_fadds, 253, override_p);
996       nios2_set_fpu_custom_code (n2fpu_fsubs, 254, override_p);
997       nios2_set_fpu_custom_code (n2fpu_fdivs, 255, override_p);
998       flag_single_precision_constant = 1;
999     }
1000   else if (!strncasecmp (cfg, "72-3", 4))
1001     {
1002       nios2_set_fpu_custom_code (n2fpu_floatus, 243, override_p);
1003       nios2_set_fpu_custom_code (n2fpu_fixsi, 244, override_p);
1004       nios2_set_fpu_custom_code (n2fpu_floatis, 245, override_p);
1005       nios2_set_fpu_custom_code (n2fpu_fcmpgts, 246, override_p);
1006       nios2_set_fpu_custom_code (n2fpu_fcmples, 249, override_p);
1007       nios2_set_fpu_custom_code (n2fpu_fcmpeqs, 250, override_p);
1008       nios2_set_fpu_custom_code (n2fpu_fcmpnes, 251, override_p);
1009       nios2_set_fpu_custom_code (n2fpu_fmuls, 252, override_p);
1010       nios2_set_fpu_custom_code (n2fpu_fadds, 253, override_p);
1011       nios2_set_fpu_custom_code (n2fpu_fsubs, 254, override_p);
1012       nios2_set_fpu_custom_code (n2fpu_fdivs, 255, override_p);
1013       flag_single_precision_constant = 1;
1014     }
1015   else
1016     warning (0, "ignoring unrecognized switch `-mcustom-fpu-cfg' value `%s'",
1017              cfg);
1018
1019   /* Guard against errors in the standard configurations.  */
1020   nios2_custom_check_insns ();
1021 }
1022
1023 /* Check individual FPU insn options, and register custom code.  */
1024 static void
1025 nios2_handle_custom_fpu_insn_option (int fpu_insn_index)
1026 {
1027   int param = N2FPU_N (fpu_insn_index);
1028
1029   if (0 <= param && param <= 255)
1030     nios2_register_custom_code (param, CCS_FPU, fpu_insn_index);
1031
1032   /* Valid values are 0-255, but also allow -1 so that the
1033      -mno-custom-<opt> switches work.  */
1034   else if (param != -1)
1035     error ("switch `-mcustom-%s' value %d must be between 0 and 255",
1036            N2FPU_NAME (fpu_insn_index), param);
1037 }
1038
1039 /* Implement TARGET_OPTION_OVERRIDE.  */
1040 static void
1041 nios2_option_override (void)
1042 {
1043   unsigned int i;
1044
1045 #ifdef SUBTARGET_OVERRIDE_OPTIONS
1046   SUBTARGET_OVERRIDE_OPTIONS;
1047 #endif
1048
1049   /* Check for unsupported options.  */
1050   if (flag_pic && !TARGET_LINUX_ABI)
1051     error ("position-independent code requires the Linux ABI");
1052
1053   /* Function to allocate machine-dependent function status.  */
1054   init_machine_status = &nios2_init_machine_status;
1055
1056   nios2_section_threshold
1057     = (global_options_set.x_g_switch_value
1058        ? g_switch_value : NIOS2_DEFAULT_GVALUE);
1059
1060   /* If we don't have mul, we don't have mulx either!  */
1061   if (!TARGET_HAS_MUL && TARGET_HAS_MULX)
1062     target_flags &= ~MASK_HAS_MULX;
1063
1064   /* Set up default handling for floating point custom instructions.
1065
1066      Putting things in this order means that the -mcustom-fpu-cfg=
1067      switch will always be overridden by individual -mcustom-fadds=
1068      switches, regardless of the order in which they were specified
1069      on the command line.
1070
1071      This behavior of prioritization of individual -mcustom-<insn>=
1072      options before the -mcustom-fpu-cfg= switch is maintained for
1073      compatibility.  */
1074   if (nios2_custom_fpu_cfg_string && *nios2_custom_fpu_cfg_string)
1075     nios2_handle_custom_fpu_cfg (nios2_custom_fpu_cfg_string, false);
1076
1077   /* Handle options for individual FPU insns.  */
1078   for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
1079     nios2_handle_custom_fpu_insn_option (i);
1080
1081   nios2_custom_check_insns ();
1082
1083   /* Save the initial options in case the user does function specific options */
1084   target_option_default_node = target_option_current_node
1085     = build_target_option_node ();
1086 }
1087
1088 /* Allocate a chunk of memory for per-function machine-dependent data.  */
1089 static struct machine_function *
1090 nios2_init_machine_status (void)
1091 {
1092   return ggc_alloc_cleared_machine_function ();
1093 }
1094
1095 \f
1096 /* Return true if CST is a constant within range of movi/movui/movhi.  */
1097 static bool
1098 nios2_simple_const_p (const_rtx cst)
1099 {
1100   HOST_WIDE_INT val = INTVAL (cst);
1101   return (SMALL_INT (val) || SMALL_INT_UNSIGNED (val) || UPPER16_INT (val));
1102 }
1103
1104 /* Compute a (partial) cost for rtx X.  Return true if the complete
1105    cost has been computed, and false if subexpressions should be
1106    scanned.  In either case, *TOTAL contains the cost result.  */
1107 static bool
1108 nios2_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
1109                  int opno ATTRIBUTE_UNUSED,
1110                  int *total, bool speed ATTRIBUTE_UNUSED)
1111 {
1112   switch (code)
1113     {
1114       case CONST_INT:
1115         if (INTVAL (x) == 0)
1116           {
1117             *total = COSTS_N_INSNS (0);
1118             return true;
1119           }
1120         else if (nios2_simple_const_p (x))
1121           {
1122             *total = COSTS_N_INSNS (2);
1123             return true;
1124           }
1125         else
1126           {
1127             *total = COSTS_N_INSNS (4);
1128             return true;
1129           }
1130
1131       case LABEL_REF:
1132       case SYMBOL_REF:
1133         /* ??? gp relative stuff will fit in here.  */
1134         /* fall through */
1135       case CONST:
1136       case CONST_DOUBLE:
1137         {
1138           *total = COSTS_N_INSNS (4);
1139           return true;
1140         }
1141
1142       case AND:
1143         {
1144           /* Recognize 'nor' insn pattern.  */
1145           if (GET_CODE (XEXP (x, 0)) == NOT
1146               && GET_CODE (XEXP (x, 1)) == NOT)
1147             {
1148               *total = COSTS_N_INSNS (1);
1149               return true;
1150             }
1151           return false;
1152         }
1153
1154       case MULT:
1155         {
1156           *total = COSTS_N_INSNS (1);
1157           return false;
1158         }
1159       case SIGN_EXTEND:
1160         {
1161           *total = COSTS_N_INSNS (3);
1162           return false;
1163         }
1164       case ZERO_EXTEND:
1165         {
1166           *total = COSTS_N_INSNS (1);
1167           return false;
1168         }
1169
1170       default:
1171         return false;
1172     }
1173 }
1174
1175 /* Implement TARGET_PREFERRED_RELOAD_CLASS.  */
1176
1177 static reg_class_t
1178 nios2_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, reg_class_t regclass)
1179 {
1180   return (regclass == NO_REGS ? GENERAL_REGS : regclass);
1181 }
1182
1183 /* Instruction support:
1184    These functions are used within the machine description to
1185    handle common or complicated output and expansions from
1186    instructions.  */
1187
1188 /* Return TRUE if X references a SYMBOL_REF.  */
1189 static int
1190 symbol_mentioned_p (rtx x)
1191 {
1192   const char * fmt;
1193   int i;
1194
1195   if (GET_CODE (x) == SYMBOL_REF)
1196     return 1;
1197
1198   /* UNSPEC_TLS entries for a symbol include the SYMBOL_REF, but they
1199      are constant offsets, not symbols.  */
1200   if (GET_CODE (x) == UNSPEC && IS_UNSPEC_TLS (XINT (x, 1)))
1201     return 0;
1202
1203   fmt = GET_RTX_FORMAT (GET_CODE (x));
1204
1205   for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
1206     if (fmt[i] == 'E')
1207       {
1208         int j;
1209         
1210         for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1211           if (symbol_mentioned_p (XVECEXP (x, i, j)))
1212             return 1;
1213       }
1214     else if (fmt[i] == 'e' && symbol_mentioned_p (XEXP (x, i)))
1215       return 1;
1216
1217   return 0;
1218 }
1219
1220 /* Return TRUE if X references a LABEL_REF.  */
1221 static int
1222 label_mentioned_p (rtx x)
1223 {
1224   const char * fmt;
1225   int i;
1226
1227   if (GET_CODE (x) == LABEL_REF)
1228     return 1;
1229
1230   /* UNSPEC_TLS entries for a symbol include a LABEL_REF for the referencing
1231      instruction, but they are constant offsets, not symbols.  */
1232   if (GET_CODE (x) == UNSPEC && IS_UNSPEC_TLS (XINT (x, 1)))
1233     return 0;
1234
1235   fmt = GET_RTX_FORMAT (GET_CODE (x));
1236   for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
1237     if (fmt[i] == 'E')
1238       {
1239         int j;
1240         
1241         for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1242           if (label_mentioned_p (XVECEXP (x, i, j)))
1243             return 1;
1244       }
1245     else if (fmt[i] == 'e' && label_mentioned_p (XEXP (x, i)))
1246       return 1;
1247
1248   return 0;
1249 }
1250
1251 static int
1252 tls_mentioned_p (rtx x)
1253 {
1254   switch (GET_CODE (x))
1255     {
1256     case CONST:
1257       return tls_mentioned_p (XEXP (x, 0));
1258
1259     case UNSPEC:
1260       if (IS_UNSPEC_TLS (XINT (x, 1)))
1261         return 1;
1262
1263     default:
1264       return 0;
1265     }
1266 }
1267
1268 /* Helper for nios2_tls_referenced_p.  */
1269 static int
1270 nios2_tls_operand_p_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
1271 {
1272   if (GET_CODE (*x) == SYMBOL_REF)
1273     return SYMBOL_REF_TLS_MODEL (*x) != 0;
1274
1275   /* Don't recurse into UNSPEC_TLS looking for TLS symbols; these are
1276      TLS offsets, not real symbol references.  */
1277   if (GET_CODE (*x) == UNSPEC
1278       && IS_UNSPEC_TLS (XINT (*x, 1)))
1279     return -1;
1280
1281   return 0;
1282 }
1283
1284 /* Return TRUE if X contains any TLS symbol references.  */
1285 static bool
1286 nios2_tls_referenced_p (rtx x)
1287 {
1288   if (! TARGET_HAVE_TLS)
1289     return false;
1290
1291   return for_each_rtx (&x, nios2_tls_operand_p_1, NULL);
1292 }
1293
1294 static bool
1295 nios2_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
1296 {
1297   return nios2_tls_referenced_p (x);
1298 }
1299
1300 /* Emit a call to __tls_get_addr.  TI is the argument to this function.  RET is
1301    an RTX for the return value location.  The entire insn sequence is
1302    returned.  */
1303 static GTY(()) rtx nios2_tls_symbol;
1304
1305 static rtx
1306 nios2_call_tls_get_addr (rtx ti)
1307 {
1308   rtx arg = gen_rtx_REG (Pmode, FIRST_ARG_REGNO);
1309   rtx ret = gen_rtx_REG (Pmode, FIRST_RETVAL_REGNO);
1310   rtx fn, insn;
1311   
1312   if (!nios2_tls_symbol)
1313     nios2_tls_symbol = init_one_libfunc ("__tls_get_addr");
1314
1315   emit_insn (gen_rtx_SET (Pmode, arg, ti));
1316   fn = gen_rtx_MEM (QImode, nios2_tls_symbol);
1317   insn = emit_call_insn (gen_call_value (ret, fn, const0_rtx));
1318   RTL_CONST_CALL_P (insn) = 1;
1319   use_reg (&CALL_INSN_FUNCTION_USAGE (insn), ret);
1320   use_reg (&CALL_INSN_FUNCTION_USAGE (insn), arg);
1321
1322   return ret;
1323 }
1324
1325 /* Generate the code to access LOC, a thread local SYMBOL_REF.  The
1326    return value will be a valid address and move_operand (either a REG
1327    or a LO_SUM).  */
1328 static rtx
1329 nios2_legitimize_tls_address (rtx loc)
1330 {
1331   rtx dest = gen_reg_rtx (Pmode);
1332   rtx ret, tmp1;
1333   enum tls_model model = SYMBOL_REF_TLS_MODEL (loc);
1334
1335   switch (model)
1336     {
1337     case TLS_MODEL_GLOBAL_DYNAMIC:
1338       tmp1 = gen_reg_rtx (Pmode);
1339       emit_insn (gen_add_tls_gd (tmp1, pic_offset_table_rtx, loc));
1340       crtl->uses_pic_offset_table = 1;
1341       ret = nios2_call_tls_get_addr (tmp1);
1342       emit_insn (gen_rtx_SET (Pmode, dest, ret));
1343       break;
1344
1345     case TLS_MODEL_LOCAL_DYNAMIC:
1346       tmp1 = gen_reg_rtx (Pmode);
1347       emit_insn (gen_add_tls_ldm (tmp1, pic_offset_table_rtx, loc));
1348       crtl->uses_pic_offset_table = 1;
1349       ret = nios2_call_tls_get_addr (tmp1);
1350
1351       emit_insn (gen_add_tls_ldo (dest, ret, loc));
1352
1353       break;
1354
1355     case TLS_MODEL_INITIAL_EXEC:
1356       tmp1 = gen_reg_rtx (Pmode);
1357       emit_insn (gen_load_tls_ie (tmp1, pic_offset_table_rtx, loc));
1358       crtl->uses_pic_offset_table = 1;
1359       emit_insn (gen_add3_insn (dest,
1360                                 gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM),
1361                                 tmp1));
1362       break;
1363
1364     case TLS_MODEL_LOCAL_EXEC:
1365       emit_insn (gen_add_tls_le (dest,
1366                                  gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM),
1367                                  loc));
1368       break;
1369
1370     default:
1371       gcc_unreachable ();
1372     }
1373
1374   return dest;
1375 }
1376
1377 int
1378 nios2_emit_move_sequence (rtx *operands, enum machine_mode mode)
1379 {
1380   rtx to = operands[0];
1381   rtx from = operands[1];
1382
1383   if (!register_operand (to, mode) && !reg_or_0_operand (from, mode))
1384     {
1385       gcc_assert (can_create_pseudo_p ());
1386       from = copy_to_mode_reg (mode, from);
1387     }
1388
1389   /* Recognize the case where from is a reference to thread-local
1390      data and load its address to a register.  */
1391   if (nios2_tls_referenced_p (from))
1392     {
1393       rtx tmp = from;
1394       rtx addend = NULL;
1395
1396       if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
1397         {
1398           addend = XEXP (XEXP (tmp, 0), 1);
1399           tmp = XEXP (XEXP (tmp, 0), 0);
1400         }
1401
1402       gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
1403       gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
1404
1405       tmp = nios2_legitimize_tls_address (tmp);
1406       if (addend)
1407         {
1408           tmp = gen_rtx_PLUS (SImode, tmp, addend);
1409           tmp = force_operand (tmp, to);
1410         }
1411       from = tmp;
1412     }
1413   else if (flag_pic && (CONSTANT_P (from) || symbol_mentioned_p (from) ||
1414                         label_mentioned_p (from)))
1415     from = nios2_legitimize_pic_address (from, SImode,
1416                                          (can_create_pseudo_p () ? 0 : to));
1417
1418   operands[0] = to;
1419   operands[1] = from;
1420   return 0;
1421 }
1422
1423 /* Divide Support */
1424
1425 /*
1426   If -O3 is used, we want to output a table lookup for
1427   divides between small numbers (both num and den >= 0
1428   and < 0x10).  The overhead of this method in the worse
1429   case is 40 bytes in the text section (10 insns) and
1430   256 bytes in the data section.  Additional divides do
1431   not incur additional penalties in the data section.
1432
1433   Code speed is improved for small divides by about 5x
1434   when using this method in the worse case (~9 cycles
1435   vs ~45).  And in the worse case divides not within the
1436   table are penalized by about 10% (~5 cycles vs ~45).
1437   However in the typical case the penalty is not as bad
1438   because doing the long divide in only 45 cycles is
1439   quite optimistic.
1440
1441   ??? It would be nice to have some benchmarks other
1442   than Dhrystone to back this up.
1443
1444   This bit of expansion is to create this instruction
1445   sequence as rtl.
1446         or      $8, $4, $5
1447         slli    $9, $4, 4
1448         cmpgeui $3, $8, 16
1449         beq     $3, $0, .L3
1450         or      $10, $9, $5
1451         add     $12, $11, divide_table
1452         ldbu    $2, 0($12)
1453         br      .L1
1454 .L3:
1455         call    slow_div
1456 .L1:
1457 #       continue here with result in $2
1458
1459   ??? Ideally I would like the emit libcall block to contain
1460   all of this code, but I don't know how to do that.  What it
1461   means is that if the divide can be eliminated, it may not
1462   completely disappear.
1463
1464   ??? The __divsi3_table label should ideally be moved out
1465   of this block and into a global.  If it is placed into the
1466   sdata section we can save even more cycles by doing things
1467   gp relative.
1468 */
1469 int
1470 nios2_emit_expensive_div (rtx *operands, enum machine_mode mode)
1471 {
1472   rtx or_result, shift_left_result;
1473   rtx lookup_value;
1474   rtx lab1, lab3;
1475   rtx insns;
1476   rtx libfunc;
1477   rtx final_result;
1478   rtx tmp;
1479   rtx table;
1480
1481   /* It may look a little generic, but only SImode
1482      is supported for now.  */
1483   gcc_assert (mode == SImode);
1484   libfunc = optab_libfunc (sdiv_optab, SImode);
1485
1486   lab1 = gen_label_rtx ();
1487   lab3 = gen_label_rtx ();
1488
1489   or_result = expand_simple_binop (SImode, IOR,
1490                                    operands[1], operands[2],
1491                                    0, 0, OPTAB_LIB_WIDEN);
1492
1493   emit_cmp_and_jump_insns (or_result, GEN_INT (15), GTU, 0,
1494                            GET_MODE (or_result), 0, lab3);
1495   JUMP_LABEL (get_last_insn ()) = lab3;
1496
1497   shift_left_result = expand_simple_binop (SImode, ASHIFT,
1498                                            operands[1], GEN_INT (4),
1499                                            0, 0, OPTAB_LIB_WIDEN);
1500
1501   lookup_value = expand_simple_binop (SImode, IOR,
1502                                       shift_left_result, operands[2],
1503                                       0, 0, OPTAB_LIB_WIDEN);
1504   table = gen_rtx_PLUS (SImode, lookup_value,
1505                         gen_rtx_SYMBOL_REF (SImode, "__divsi3_table"));
1506   convert_move (operands[0], gen_rtx_MEM (QImode, table), 1);
1507
1508   tmp = emit_jump_insn (gen_jump (lab1));
1509   JUMP_LABEL (tmp) = lab1;
1510   emit_barrier ();
1511
1512   emit_label (lab3);
1513   LABEL_NUSES (lab3) = 1;
1514
1515   start_sequence ();
1516   final_result = emit_library_call_value (libfunc, NULL_RTX,
1517                                           LCT_CONST, SImode, 2,
1518                                           operands[1], SImode,
1519                                           operands[2], SImode);
1520
1521
1522   insns = get_insns ();
1523   end_sequence ();
1524   emit_libcall_block (insns, operands[0], final_result,
1525                       gen_rtx_DIV (SImode, operands[1], operands[2]));
1526
1527   emit_label (lab1);
1528   LABEL_NUSES (lab1) = 1;
1529   return 1;
1530 }
1531
1532 /* The function with address *ADDR is being called.  If the address
1533    needs to be loaded from the GOT, emit the instruction to do so and
1534    update *ADDR to point to the rtx for the loaded value.  */
1535 void
1536 nios2_adjust_call_address (rtx *addr)
1537 {
1538   if (flag_pic
1539       && (GET_CODE (*addr) == SYMBOL_REF || GET_CODE (*addr) == LABEL_REF))
1540     {
1541       rtx addr_orig;
1542       crtl->uses_pic_offset_table = 1;
1543       addr_orig = *addr;
1544       *addr = gen_reg_rtx (GET_MODE (addr_orig));
1545       emit_insn (gen_pic_load_call_addr (*addr,
1546                                          pic_offset_table_rtx, addr_orig));
1547     }
1548 }
1549
1550
1551 \f
1552 /* Branches/Compares.  */
1553
1554 /* Return in *ALT_CODE and *ALT_OP, an alternate equivalent constant
1555    comparision, e.g. >= 1 into > 0.  */
1556 static void
1557 nios2_alternate_compare_const (enum rtx_code code, rtx op,
1558                                enum rtx_code *alt_code, rtx *alt_op,
1559                                enum machine_mode mode)
1560 {
1561   HOST_WIDE_INT opval = INTVAL (op);
1562   enum rtx_code scode = signed_condition (code);
1563   *alt_code = ((code == EQ || code == NE) ? code
1564                /* The required conversion between [>,>=] and [<,<=] is captured
1565                   by a reverse + swap of condition codes.  */
1566                : reverse_condition (swap_condition (code)));
1567   *alt_op = ((scode == LT || scode == GE) ? gen_int_mode (opval - 1, mode)
1568              : (scode == LE || scode == GT) ? gen_int_mode (opval + 1, mode)
1569              : gen_int_mode (opval, mode));
1570 }
1571
1572 /* Return true if the constant comparison is supported by nios2.  */
1573 static bool
1574 nios2_valid_compare_const_p (enum rtx_code code, rtx op)
1575 {
1576   switch (code)
1577     {
1578     case EQ: case NE: case GE: case LT:
1579       return SMALL_INT (INTVAL (op));
1580     case GEU: case LTU:
1581       return SMALL_INT_UNSIGNED (INTVAL (op));
1582     default:
1583       return false;
1584     }
1585 }
1586
1587 /* Return true if compares in MODE is supported, mainly for floating-point
1588    modes.  */
1589 bool
1590 nios2_supported_compare_p (enum machine_mode mode)
1591 {
1592   switch (mode)
1593     {
1594     case SFmode:
1595       return (N2FPU_OP_ENABLED_P (fcmpeqs) && N2FPU_OP_ENABLED_P (fcmpnes)
1596               && (N2FPU_OP_ENABLED_P (fcmplts) || N2FPU_OP_ENABLED_P (fcmpgts))
1597               && (N2FPU_OP_ENABLED_P (fcmpges) || N2FPU_OP_ENABLED_P (fcmples)));
1598
1599     case DFmode:
1600       return (N2FPU_OP_ENABLED_P (fcmpeqd) && N2FPU_OP_ENABLED_P (fcmpned)
1601               && (N2FPU_OP_ENABLED_P (fcmpltd) || N2FPU_OP_ENABLED_P (fcmpgtd))
1602               && (N2FPU_OP_ENABLED_P (fcmpged) || N2FPU_OP_ENABLED_P (fcmpled)));
1603     default:
1604       return true;
1605     }
1606 }
1607
1608 /* Checks and modifies the comparison in *CMP, *OP1, and *OP2 into valid
1609    nios2 supported form. Returns true if success.  */
1610 bool
1611 nios2_validate_compare (enum machine_mode mode, rtx *cmp, rtx *op1, rtx *op2)
1612 {
1613   enum rtx_code code = GET_CODE (*cmp);
1614   enum rtx_code alt_code;
1615   rtx alt_op2;
1616
1617   if (GET_MODE_CLASS (mode) == MODE_FLOAT)
1618     {
1619       if (nios2_fpu_compare_enabled (code, mode))
1620         {
1621           *op1 = force_reg (mode, *op1);
1622           *op2 = force_reg (mode, *op2);
1623           goto rebuild_cmp;
1624         }
1625       else
1626         {
1627           enum rtx_code rev_code = swap_condition (code);
1628           if (nios2_fpu_compare_enabled (rev_code, mode))
1629             {
1630               rtx tmp = *op1;
1631               *op1 = force_reg (mode, *op2);
1632               *op2 = force_reg (mode, tmp);
1633               code = rev_code;
1634               goto rebuild_cmp;
1635             }
1636           else
1637             return false;
1638         }
1639     }
1640
1641   if (!reg_or_0_operand (*op2, mode))
1642     {
1643       /* Create alternate constant compare.  */
1644       nios2_alternate_compare_const (code, *op2, &alt_code, &alt_op2, mode);
1645
1646       /* If alterate op2 is zero(0), we can use it directly, possibly
1647          swapping the compare code.  */
1648       if (alt_op2 == const0_rtx)
1649         {
1650           code = alt_code;
1651           *op2 = alt_op2;
1652           goto check_rebuild_cmp;
1653         }
1654
1655       /* Check if either constant compare can be used.  */
1656       if (nios2_valid_compare_const_p (code, *op2))
1657         return true;
1658       else if (nios2_valid_compare_const_p (alt_code, alt_op2))
1659         {
1660           code = alt_code;
1661           *op2 = alt_op2;
1662           goto rebuild_cmp;
1663         }
1664
1665       /* We have to force op2 into a register now. Try to pick one
1666          with a lower cost.  */
1667       if (! nios2_simple_const_p (*op2)
1668           && nios2_simple_const_p (alt_op2))
1669         {
1670           code = alt_code;
1671           *op2 = alt_op2;
1672         }
1673       *op2 = force_reg (SImode, *op2);
1674     }
1675  check_rebuild_cmp:
1676   if (code == GT || code == GTU || code == LE || code == LEU)
1677     {
1678       rtx t = *op1; *op1 = *op2; *op2 = t;
1679       code = swap_condition (code);
1680     }
1681  rebuild_cmp:
1682   *cmp = gen_rtx_fmt_ee (code, mode, *op1, *op2);
1683   return true;
1684 }
1685
1686
1687 /* Addressing Modes.  */
1688
1689 /* Implement TARGET_LEGITIMATE_CONSTANT_P.  */
1690 static bool
1691 nios2_legitimate_constant_p (enum machine_mode mode, rtx x)
1692 {
1693   switch (GET_CODE (x))
1694     {
1695     case SYMBOL_REF:
1696       return !SYMBOL_REF_TLS_MODEL (x);
1697     case CONST:
1698       {
1699         rtx op = XEXP (x, 0);
1700         if (GET_CODE (op) != PLUS)
1701           return false;
1702         return (nios2_legitimate_constant_p (mode, XEXP (op, 0))
1703                 && nios2_legitimate_constant_p (mode, XEXP (op, 1)));
1704       }
1705     default:
1706       return true;
1707     }
1708 }
1709
1710 /* Implement TARGET_LEGITIMATE_ADDRESS_P.  */
1711 static bool
1712 nios2_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
1713                             rtx operand, bool strict)
1714 {
1715   int ret_val = 0;
1716
1717   switch (GET_CODE (operand))
1718     {
1719       /* Direct.  */
1720     case SYMBOL_REF:
1721       if (SYMBOL_REF_TLS_MODEL (operand))
1722         break;
1723       
1724       if (SYMBOL_REF_IN_NIOS2_SMALL_DATA_P (operand))
1725         {
1726           ret_val = 1;
1727           break;
1728         }
1729       /* Else, fall through.  */
1730     case LABEL_REF:
1731     case CONST_INT:
1732     case CONST:
1733     case CONST_DOUBLE:
1734       /* ??? In here I need to add gp addressing.  */
1735       ret_val = 0;
1736
1737       break;
1738
1739       /* Register indirect.  */
1740     case REG:
1741       ret_val = REG_OK_FOR_BASE_P2 (operand, strict);
1742       break;
1743
1744       /* Register indirect with displacement.  */
1745     case PLUS:
1746       {
1747         rtx op0 = XEXP (operand, 0);
1748         rtx op1 = XEXP (operand, 1);
1749
1750         if (REG_P (op0) && REG_P (op1))
1751           ret_val = 0;
1752         else if (REG_P (op0) && GET_CODE (op1) == CONST_INT)
1753           ret_val = (REG_OK_FOR_BASE_P2 (op0, strict)
1754                      && SMALL_INT (INTVAL (op1)));
1755         else if (REG_P (op1) && GET_CODE (op0) == CONST_INT)
1756           ret_val = (REG_OK_FOR_BASE_P2 (op1, strict)
1757                      && SMALL_INT (INTVAL (op0)));
1758         else
1759           ret_val = 0;
1760       }
1761       break;
1762
1763     default:
1764       ret_val = 0;
1765       break;
1766     }
1767
1768   return ret_val;
1769 }
1770
1771 /* Return true if EXP should be placed in the small data section.  */
1772 static bool
1773 nios2_in_small_data_p (const_tree exp)
1774 {
1775   /* We want to merge strings, so we never consider them small data.  */
1776   if (TREE_CODE (exp) == STRING_CST)
1777     return false;
1778
1779   if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
1780     {
1781       const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
1782       /* ??? these string names need moving into
1783          an array in some header file */
1784       if (nios2_section_threshold > 0
1785           && (strcmp (section, ".sbss") == 0
1786               || strncmp (section, ".sbss.", 6) == 0
1787               || strcmp (section, ".sdata") == 0
1788               || strncmp (section, ".sdata.", 7) == 0))
1789         return true;
1790     }
1791   else if (TREE_CODE (exp) == VAR_DECL)
1792     {
1793       HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
1794
1795       /* If this is an incomplete type with size 0, then we can't put it
1796          in sdata because it might be too big when completed.  */
1797       if (size > 0 && (unsigned HOST_WIDE_INT)size <= nios2_section_threshold)
1798         return true;
1799     }
1800
1801   return false;
1802 }
1803
1804 static void
1805 nios2_encode_section_info (tree decl, rtx rtl, int first)
1806 {
1807   rtx symbol;
1808   int flags;
1809
1810   default_encode_section_info (decl, rtl, first);
1811
1812   /* Careful not to prod global register variables.  */
1813   if (GET_CODE (rtl) != MEM)
1814     return;
1815   symbol = XEXP (rtl, 0);
1816   if (GET_CODE (symbol) != SYMBOL_REF)
1817     return;
1818
1819   flags = SYMBOL_REF_FLAGS (symbol);
1820
1821   /* We don't want weak variables to be addressed with gp in case they end up 
1822      with value 0 which is not within 2^15 of $gp.  */
1823   if (DECL_P (decl) && DECL_WEAK (decl))
1824     flags |= SYMBOL_FLAG_WEAK_DECL;
1825
1826   SYMBOL_REF_FLAGS (symbol) = flags;
1827 }
1828
1829 static unsigned int
1830 nios2_section_type_flags (tree decl, const char *name, int reloc)
1831 {
1832   unsigned int flags;
1833
1834   flags = default_section_type_flags (decl, name, reloc);
1835
1836   if (strcmp (name, ".sbss") == 0
1837       || strncmp (name, ".sbss.", 6) == 0
1838       || strcmp (name, ".sdata") == 0
1839       || strncmp (name, ".sdata.", 7) == 0)
1840     flags |= SECTION_SMALL;
1841
1842   return flags;
1843 }
1844
1845
1846 /* Position Independent Code related.  */
1847
1848 /* Emit code to load the PIC register.  */
1849 static void
1850 nios2_load_pic_register (void)
1851 {
1852   rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM);
1853
1854   emit_insn (gen_load_got_register (pic_offset_table_rtx, tmp));
1855   emit_insn (gen_add3_insn (pic_offset_table_rtx, pic_offset_table_rtx, tmp));
1856 }
1857
1858 /* Nonzero if the constant value X is a legitimate general operand
1859    when generating PIC code.  It is given that flag_pic is on and
1860    that X satisfies CONSTANT_P or is a CONST_DOUBLE.  */
1861 bool
1862 nios2_legitimate_pic_operand_p (rtx x)
1863 {
1864   rtx inner;
1865
1866   /* UNSPEC_TLS is always PIC.  */
1867   if (tls_mentioned_p (x))
1868     return true;
1869
1870   if (GET_CODE (x) == SYMBOL_REF)
1871     return false;
1872   if (GET_CODE (x) == LABEL_REF)
1873     return false;
1874   if (GET_CODE (x) == CONST)
1875     {
1876       inner = XEXP (x, 0);
1877       if (GET_CODE (inner) == PLUS
1878           && GET_CODE (XEXP (inner, 0)) == SYMBOL_REF)
1879         return false;
1880     }
1881   return true;
1882 }
1883
1884 rtx
1885 nios2_legitimize_pic_address (rtx orig,
1886                               enum machine_mode mode ATTRIBUTE_UNUSED, rtx reg)
1887 {
1888   if (GET_CODE (orig) == SYMBOL_REF
1889       || GET_CODE (orig) == LABEL_REF)
1890     {
1891       if (reg == 0)
1892         {
1893           gcc_assert (can_create_pseudo_p ());
1894           reg = gen_reg_rtx (Pmode);
1895         }
1896
1897       emit_insn (gen_pic_load_addr (reg, pic_offset_table_rtx, orig));
1898
1899       crtl->uses_pic_offset_table = 1;
1900
1901       return reg;
1902     }
1903   else if (GET_CODE (orig) == CONST)
1904     {
1905       rtx base, offset;
1906
1907       if (GET_CODE (XEXP (orig, 0)) == PLUS
1908           && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
1909         return orig;
1910
1911       if (GET_CODE (XEXP (orig, 0)) == UNSPEC
1912           && IS_UNSPEC_TLS (XINT (XEXP (orig, 0), 1)))
1913         return orig;
1914
1915       if (reg == 0)
1916         {
1917           gcc_assert (can_create_pseudo_p ());
1918           reg = gen_reg_rtx (Pmode);
1919         }
1920
1921       gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
1922
1923       base = nios2_legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode,
1924                                            reg);
1925       offset = nios2_legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
1926                                              base == reg ? 0 : reg);
1927
1928       if (CONST_INT_P (offset))
1929         {
1930           if (SMALL_INT (INTVAL (offset)))
1931             return plus_constant (base, INTVAL (offset));
1932           else
1933             offset = force_reg (Pmode, offset);
1934         }
1935
1936       return gen_rtx_PLUS (Pmode, base, offset);
1937     }
1938
1939   return orig;
1940 }
1941
1942 /* Test for various thread-local symbols.  */
1943
1944 /* Return TRUE if X is a thread-local symbol.  */
1945 static bool
1946 nios2_tls_symbol_p (rtx x)
1947 {
1948   return (TARGET_HAVE_TLS && GET_CODE (x) == SYMBOL_REF
1949           && SYMBOL_REF_TLS_MODEL (x) != 0);
1950 }
1951
1952 /* Implement TARGET_LEGITIMIZE_ADDRESS.  */
1953 static rtx
1954 nios2_legitimize_address (rtx x, rtx orig_x, enum machine_mode mode)
1955 {
1956   if (nios2_tls_symbol_p (x))
1957     return nios2_legitimize_tls_address (x);
1958
1959   if (flag_pic)
1960     {
1961       /* We need to find and carefully transform any SYMBOL and LABEL
1962          references; so go back to the original address expression.  */
1963       rtx new_x = nios2_legitimize_pic_address (orig_x, mode, NULL_RTX);
1964
1965       if (new_x != orig_x)
1966         x = new_x;
1967     }
1968
1969   return x;
1970 }
1971
1972
1973 /* Output assembly language related definitions.  */
1974
1975 /* Print the operand OP to file stream
1976    FILE modified by LETTER. LETTER
1977    can be one of:
1978      i: print "i" if OP is an immediate, except 0
1979      o: print "io" if OP is volatile
1980
1981      z: for const0_rtx print $0 instead of 0
1982      H: for %hiadj
1983      L: for %lo
1984      U: for upper half of 32 bit value
1985      D: for the upper 32-bits of a 64-bit double value
1986      R: prints reverse condition.  */
1987 static void
1988 nios2_print_operand (FILE *file, rtx op, int letter)
1989 {
1990
1991   switch (letter)
1992     {
1993     case 'i':
1994       if (CONSTANT_P (op) && (op != const0_rtx))
1995         fprintf (file, "i");
1996       return;
1997
1998     case 'o':
1999       if (GET_CODE (op) == MEM
2000           && ((MEM_VOLATILE_P (op) && TARGET_BYPASS_CACHE_VOLATILE)
2001               || TARGET_BYPASS_CACHE))
2002         fprintf (file, "io");
2003       return;
2004
2005     default:
2006       break;
2007     }
2008
2009   if (comparison_operator (op, VOIDmode))
2010     {
2011       enum rtx_code cond = GET_CODE (op);
2012       if (letter == 0)
2013         {
2014           fprintf (file, "%s", GET_RTX_NAME (cond));
2015           return;
2016         }
2017       if (letter == 'R')
2018         {
2019           fprintf (file, "%s", GET_RTX_NAME (reverse_condition (cond)));
2020           return;
2021         }
2022     }
2023
2024   switch (GET_CODE (op))
2025     {
2026     case REG:
2027       if (letter == 0 || letter == 'z')
2028         {
2029           fprintf (file, "%s", reg_names[REGNO (op)]);
2030           return;
2031         }
2032       else if (letter == 'D')
2033         {
2034           fprintf (file, "%s", reg_names[REGNO (op)+1]);
2035           return;
2036         }
2037       break;
2038
2039     case CONST_INT:
2040       if (INTVAL (op) == 0 && letter == 'z')
2041         {
2042           fprintf (file, "zero");
2043           return;
2044         }
2045       else if (letter == 'U')
2046         {
2047           HOST_WIDE_INT val = INTVAL (op);
2048           rtx new_op;
2049           val = (val / 65536) & 0xFFFF;
2050           new_op = gen_int_mode (val, SImode);
2051           output_addr_const (file, new_op);
2052           return;
2053         }
2054       /* Else, fall through.  */
2055
2056     case CONST:
2057     case LABEL_REF:
2058     case SYMBOL_REF:
2059     case CONST_DOUBLE:
2060       if (letter == 0 || letter == 'z')
2061         {
2062           output_addr_const (file, op);
2063           return;
2064         }
2065       else if (letter == 'H')
2066         {
2067           fprintf (file, "%%hiadj(");
2068           output_addr_const (file, op);
2069           fprintf (file, ")");
2070           return;
2071         }
2072       else if (letter == 'L')
2073         {
2074           fprintf (file, "%%lo(");
2075           output_addr_const (file, op);
2076           fprintf (file, ")");
2077           return;
2078         }
2079       break;
2080
2081
2082     case SUBREG:
2083     case MEM:
2084       if (letter == 0)
2085         {
2086           output_address (op);
2087           return;
2088         }
2089       break;
2090
2091     case CODE_LABEL:
2092       if (letter == 0)
2093         {
2094           output_addr_const (file, op);
2095           return;
2096         }
2097       break;
2098
2099     default:
2100       break;
2101     }
2102
2103   fprintf (stderr, "Missing way to print (%c) ", letter);
2104   debug_rtx (op);
2105   gcc_unreachable ();
2106 }
2107
2108 static int
2109 gprel_constant (rtx op)
2110 {
2111   if (GET_CODE (op) == SYMBOL_REF
2112       && SYMBOL_REF_IN_NIOS2_SMALL_DATA_P (op))
2113     return 1;
2114   else if (GET_CODE (op) == CONST
2115            && GET_CODE (XEXP (op, 0)) == PLUS)
2116     return gprel_constant (XEXP (XEXP (op, 0), 0));
2117   else
2118     return 0;
2119 }
2120
2121 static void
2122 nios2_print_operand_address (FILE *file, rtx op)
2123 {
2124   switch (GET_CODE (op))
2125     {
2126     case CONST:
2127     case CONST_INT:
2128     case LABEL_REF:
2129     case CONST_DOUBLE:
2130     case SYMBOL_REF:
2131       if (gprel_constant (op))
2132         {
2133           fprintf (file, "%%gprel(");
2134           output_addr_const (file, op);
2135           fprintf (file, ")(%s)", reg_names[GP_REGNO]);
2136           return;
2137         }
2138
2139       break;
2140
2141     case PLUS:
2142       {
2143         rtx op0 = XEXP (op, 0);
2144         rtx op1 = XEXP (op, 1);
2145
2146         if (REG_P (op0) && CONSTANT_P (op1))
2147           {
2148             output_addr_const (file, op1);
2149             fprintf (file, "(%s)", reg_names[REGNO (op0)]);
2150             return;
2151           }
2152         else if (REG_P (op1) && CONSTANT_P (op0))
2153           {
2154             output_addr_const (file, op0);
2155             fprintf (file, "(%s)", reg_names[REGNO (op1)]);
2156             return;
2157           }
2158       }
2159       break;
2160
2161     case REG:
2162       fprintf (file, "0(%s)", reg_names[REGNO (op)]);
2163       return;
2164
2165     case MEM:
2166       {
2167         rtx base = XEXP (op, 0);
2168         nios2_print_operand_address (file, base);
2169         return;
2170       }
2171     default:
2172       break;
2173     }
2174
2175   fprintf (stderr, "Missing way to print address\n");
2176   debug_rtx (op);
2177   gcc_unreachable ();
2178 }
2179
2180 static void
2181 nios2_output_dwarf_dtprel (FILE *file, int size, rtx x)
2182 {
2183   gcc_assert (size == 4);
2184   fprintf (file, "\t.4byte\t%%tls_ldo(");
2185   output_addr_const (file, x);
2186   fprintf (file, ")");
2187 }
2188
2189 static void
2190 nios2_asm_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
2191 {
2192   if (flag_verbose_asm || flag_debug_asm)
2193     {
2194       compute_frame_size ();
2195       dump_frame_size (file);
2196     }
2197 }
2198
2199 /* Emit assembly of custom FPU instructions.  */
2200 const char*
2201 nios2_fpu_insn_asm (enum n2fpu_code code)
2202 {
2203   static char buf[256];
2204   const char *op1, *op2, *op3;
2205   int ln = 256, n = 0;
2206   
2207   int N = N2FPU_N (code);
2208   int num_operands = N2FPU (code).num_operands;
2209   const char* insn_name = N2FPU_NAME (code);
2210   tree ftype = nios2_ftype (N2FPU_FTCODE (code));
2211   enum machine_mode dst_mode = TYPE_MODE (TREE_TYPE (ftype));
2212   enum machine_mode src_mode = TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (ftype)));
2213
2214   /* Prepare X register for DF input operands.  */
2215   if (GET_MODE_SIZE (src_mode) == 8 && num_operands == 3)
2216     n = snprintf (buf, ln, "custom\t%d, zero, %%1, %%D1 # fwrx %%1\n\t",
2217                   N2FPU_N (n2fpu_fwrx));
2218
2219   if (src_mode == SFmode)
2220     {
2221       if (dst_mode == VOIDmode)
2222         {
2223           /* The fwry case.  */
2224           op1 = op3 = "zero";
2225           op2 = "%0";
2226           num_operands -= 1;
2227         }
2228       else
2229         {
2230           op1 = "%0"; op2 = "%1";
2231           op3 = (num_operands == 2 ? "zero" : "%2");
2232         }
2233     }
2234   else if (src_mode == DFmode)
2235     {
2236       if (dst_mode == VOIDmode)
2237         {
2238           /* The fwrx case.  */
2239           op1 = "zero";
2240           op2 = "%0";
2241           op3 = "%D0";
2242           num_operands -= 1;
2243         }
2244       else
2245         {
2246           op1 = (dst_mode == DFmode ? "%D0" : "%0");
2247           op2 = (num_operands == 2 ? "%1" : "%2");
2248           op3 = (num_operands == 2 ? "%D1" : "%D2");
2249         }
2250     }
2251   else if (src_mode == VOIDmode)
2252     {
2253       /* frdxlo, frdxhi, frdy cases.  */
2254       gcc_assert (dst_mode == SFmode);
2255       op1 = "%0";
2256       op2 = op3 = "zero";
2257     }
2258   else if (src_mode == SImode)
2259     {
2260       /* Conversion operators.  */
2261       gcc_assert (num_operands == 2);
2262       op1 = (dst_mode == DFmode ? "%D0" : "%0");
2263       op2 = "%1";
2264       op3 = "zero";
2265     }
2266   else
2267     gcc_unreachable ();
2268
2269   /* Main instruction string.  */
2270   n += snprintf (buf + n, ln - n, "custom\t%d, %s, %s, %s # %s %%0%s%s",
2271                  N, op1, op2, op3, insn_name,
2272                  (num_operands >= 2 ? ", %1" : ""),
2273                  (num_operands == 3 ? ", %2" : ""));
2274
2275   /* Extraction of Y register for DF results.  */
2276   if (dst_mode == DFmode)
2277     snprintf (buf + n, ln - n, "\n\tcustom\t%d, %%0, zero, zero # frdy %%0",
2278               N2FPU_N (n2fpu_frdy));
2279   return buf;
2280 }
2281
2282
2283 \f
2284 /* Instruction scheduler related.  */
2285
2286 static int
2287 nios2_issue_rate (void)
2288 {
2289 #ifdef MAX_DFA_ISSUE_RATE
2290   return MAX_DFA_ISSUE_RATE;
2291 #else
2292   return 1;
2293 #endif
2294 }
2295
2296 \f
2297
2298 /* Function argument related.  */
2299
2300 void
2301 nios2_init_cumulative_args (CUMULATIVE_ARGS *cum,
2302                             tree fntype ATTRIBUTE_UNUSED,
2303                             rtx libname ATTRIBUTE_UNUSED,
2304                             tree fndecl ATTRIBUTE_UNUSED,
2305                             int n_named_args ATTRIBUTE_UNUSED)
2306 {
2307   cum->regs_used = 0;
2308 }
2309
2310 /* Define where to put the arguments to a function.  Value is zero to
2311    push the argument on the stack, or a hard register in which to
2312    store the argument.
2313
2314    MODE is the argument's machine mode.
2315    TYPE is the data type of the argument (as a tree).
2316    This is null for libcalls where that information may
2317    not be available.
2318    CUM is a variable of type CUMULATIVE_ARGS which gives info about
2319    the preceding args and about the function being called.
2320    NAMED is nonzero if this argument is a named parameter
2321    (otherwise it is an extra parameter matching an ellipsis).  */
2322
2323 static rtx
2324 nios2_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
2325                     const_tree type ATTRIBUTE_UNUSED,
2326                     bool named ATTRIBUTE_UNUSED)
2327 {
2328   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 
2329   rtx return_rtx = NULL_RTX;
2330
2331   if (cum->regs_used < NUM_ARG_REGS)
2332     return_rtx = gen_rtx_REG (mode, FIRST_ARG_REGNO + cum->regs_used);
2333
2334   return return_rtx;
2335 }
2336
2337 /* Return number of bytes, at the beginning of the argument, that must be
2338    put in registers.  0 is the argument is entirely in registers or entirely
2339    in memory.  */
2340
2341 static int
2342 nios2_arg_partial_bytes (cumulative_args_t cum_v,
2343                          enum machine_mode mode, tree type,
2344                          bool named ATTRIBUTE_UNUSED)
2345 {
2346   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 
2347   HOST_WIDE_INT param_size;
2348
2349   if (mode == BLKmode)
2350     {
2351       param_size = int_size_in_bytes (type);
2352       if (param_size < 0)
2353         internal_error
2354           ("Do not know how to handle large structs or variable length types");
2355     }
2356   else
2357     param_size = GET_MODE_SIZE (mode);
2358
2359   /* Convert to words (round up).  */
2360   param_size = (3 + param_size) / 4;
2361
2362   if (cum->regs_used < NUM_ARG_REGS
2363       && cum->regs_used + param_size > NUM_ARG_REGS)
2364     return (NUM_ARG_REGS - cum->regs_used) * UNITS_PER_WORD;
2365   else
2366     return 0;
2367 }
2368
2369 /* Update the data in CUM to advance over an argument
2370    of mode MODE and data type TYPE.
2371    (TYPE is null for libcalls where that information may not be available.)  */
2372
2373 static void
2374 nios2_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
2375                             const_tree type ATTRIBUTE_UNUSED,
2376                             bool named ATTRIBUTE_UNUSED)
2377 {
2378   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 
2379   HOST_WIDE_INT param_size;
2380
2381   if (mode == BLKmode)
2382     {
2383       param_size = int_size_in_bytes (type);
2384       if (param_size < 0)
2385         internal_error
2386           ("Do not know how to handle large structs or variable length types");
2387     }
2388   else
2389     param_size = GET_MODE_SIZE (mode);
2390
2391   /* Convert to words (round up).  */
2392   param_size = (3 + param_size) / 4;
2393
2394   if (cum->regs_used + param_size > NUM_ARG_REGS)
2395     cum->regs_used = NUM_ARG_REGS;
2396   else
2397     cum->regs_used += param_size;
2398
2399   return;
2400 }
2401
2402 enum direction
2403 nios2_function_arg_padding (enum machine_mode mode, const_tree type)
2404 {
2405   /* On little-endian targets, the first byte of every stack argument
2406      is passed in the first byte of the stack slot.  */
2407   if (!BYTES_BIG_ENDIAN)
2408     return upward;
2409
2410   /* Otherwise, integral types are padded downward: the last byte of a
2411      stack argument is passed in the last byte of the stack slot.  */
2412   if (type != 0
2413       ? INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)
2414       : GET_MODE_CLASS (mode) == MODE_INT)
2415     return downward;
2416
2417   /* Arguments smaller than a stack slot are padded downward.  */
2418   if (mode != BLKmode)
2419     return (GET_MODE_BITSIZE (mode) >= PARM_BOUNDARY) ? upward : downward;
2420   else
2421     return ((int_size_in_bytes (type) >= (PARM_BOUNDARY / BITS_PER_UNIT))
2422             ? upward : downward);
2423 }
2424
2425 enum direction
2426 nios2_block_reg_padding (enum machine_mode mode, tree type,
2427                          int first ATTRIBUTE_UNUSED)
2428 {
2429   /* ??? Do we need to treat floating point specially, ala MIPS?  */
2430   return nios2_function_arg_padding (mode, type);
2431 }
2432
2433
2434 /* Emit RTL insns to initialize the variable parts of a trampoline.
2435    FNADDR is an RTX for the address of the function's pure code.
2436    CXT is an RTX for the static chain value for the function.
2437    On Nios II, we handle this by a library call.  */
2438 static void
2439 nios2_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
2440 {
2441   rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
2442   rtx ctx_reg = force_reg (Pmode, cxt);
2443   rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
2444
2445   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
2446                      LCT_NORMAL, VOIDmode, 3,
2447                      addr, Pmode,
2448                      fnaddr, Pmode,
2449                      ctx_reg, Pmode);
2450 }
2451
2452 static rtx
2453 nios2_function_value (const_tree ret_type, const_tree fn ATTRIBUTE_UNUSED,
2454                       bool outgoing ATTRIBUTE_UNUSED)
2455 {
2456   return gen_rtx_REG (TYPE_MODE (ret_type), FIRST_RETVAL_REGNO);
2457 }
2458
2459 static rtx
2460 nios2_libcall_value (enum machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
2461 {
2462   return gen_rtx_REG (mode, FIRST_RETVAL_REGNO);
2463 }
2464
2465 static bool
2466 nios2_function_value_regno_p (const unsigned int regno)
2467 {
2468   return (regno == FIRST_RETVAL_REGNO);
2469 }
2470
2471 static bool
2472 nios2_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
2473 {
2474   return (int_size_in_bytes (type) > (2 * UNITS_PER_WORD)
2475           || int_size_in_bytes (type) == -1);
2476 }
2477
2478 /* ??? It may be possible to eliminate the copyback and implement
2479    my own va_arg type, but that is more work for now.  */
2480 static void
2481 nios2_setup_incoming_varargs (cumulative_args_t cum_v,
2482                               enum machine_mode mode, tree type,
2483                               int *pretend_size, int second_time)
2484 {
2485   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 
2486   CUMULATIVE_ARGS local_cum;
2487   cumulative_args_t local_cum_v = pack_cumulative_args (&local_cum);
2488   int regs_to_push;
2489   int pret_size;
2490
2491   local_cum = *cum;
2492   nios2_function_arg_advance (local_cum_v, mode, type, 1);
2493
2494   regs_to_push = NUM_ARG_REGS - local_cum.regs_used;
2495
2496   if (!second_time && regs_to_push > 0)
2497     {
2498       rtx ptr = virtual_incoming_args_rtx;
2499       rtx mem = gen_rtx_MEM (BLKmode, ptr);
2500       emit_insn (gen_blockage ());
2501       move_block_from_reg (local_cum.regs_used + FIRST_ARG_REGNO, mem,
2502                            regs_to_push);
2503       emit_insn (gen_blockage ());
2504     }
2505
2506   pret_size = regs_to_push * UNITS_PER_WORD;
2507
2508   if (pret_size)
2509     *pretend_size = pret_size;
2510 }
2511
2512
2513 \f
2514 /* Init FPU builtins.  */
2515 static void
2516 nios2_init_fpu_builtins (int start_code)
2517 {
2518   char builtin_name[64] = "__builtin_custom_";
2519   unsigned int i, n = strlen ("__builtin_custom_");
2520
2521   for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
2522     {
2523       snprintf (builtin_name + n, sizeof (builtin_name) - n,
2524                 "%s", N2FPU_NAME (i));
2525       add_builtin_function (builtin_name, nios2_ftype (N2FPU_FTCODE (i)),
2526                             start_code + i, BUILT_IN_MD, NULL, NULL_TREE);
2527     }
2528 }
2529
2530 static rtx
2531 nios2_expand_fpu_builtin (tree exp, unsigned int code, rtx target)
2532 {
2533   struct expand_operand ops[MAX_RECOG_OPERANDS];
2534   enum insn_code icode = N2FPU_ICODE (code);
2535   int nargs, argno, opno = 0;
2536   int num_operands = N2FPU (code).num_operands;
2537   enum machine_mode dst_mode = TYPE_MODE (TREE_TYPE (exp));
2538   bool has_target_p = (dst_mode != VOIDmode);
2539
2540   if (N2FPU_N (code) < 0)
2541     fatal_error ("Cannot call `__builtin_custom_%s' without specifying switch"
2542                  " `-mcustom-%s'", N2FPU_NAME (code), N2FPU_NAME (code));
2543   if (has_target_p)
2544     create_output_operand (&ops[opno++], target, dst_mode);
2545   else
2546     /* Subtract away the count of the VOID return, mainly for fwrx/fwry.   */
2547     num_operands -= 1;
2548   nargs = call_expr_nargs (exp);
2549   for (argno = 0; argno < nargs; argno++)
2550     {
2551       tree arg = CALL_EXPR_ARG (exp, argno);
2552       create_input_operand (&ops[opno++], expand_normal (arg),
2553                             TYPE_MODE (TREE_TYPE (arg)));
2554     }
2555   if (!maybe_expand_insn (icode, num_operands, ops))
2556     {
2557       error ("invalid argument to built-in function");
2558       return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx;
2559     }
2560   return has_target_p ? ops[0].value : const0_rtx;
2561 }
2562
2563
2564 /* Nios II has custom instruction built-in functions of the forms:
2565    __builtin_custom_n
2566    __builtin_custom_nX
2567    __builtin_custom_nXX
2568    __builtin_custom_Xn
2569    __builtin_custom_XnX
2570    __builtin_custom_XnXX
2571
2572    where each X could be either 'i' (int), 'f' (float), or 'p' (void*).
2573    Therefore with 0-1 return values, and 0-2 arguments, we have a
2574    total of (3 + 1) * (1 + 3 + 9) == 52 custom builtin functions.
2575 */
2576 #define NUM_CUSTOM_BUILTINS ((3 + 1) * (1 + 3 + 9))
2577 static char custom_builtin_name[NUM_CUSTOM_BUILTINS][5];
2578
2579 static void
2580 nios2_init_custom_builtins (int start_code)
2581 {
2582   tree builtin_ftype, ret_type;
2583   char builtin_name[32] = "__builtin_custom_";
2584   int n = strlen ("__builtin_custom_");
2585   int builtin_code = 0;
2586   int lhs, rhs1, rhs2;
2587
2588   struct { tree type; const char* c; } op[4];
2589   /* z */ op[0].c = "";  op[0].type = NULL_TREE;
2590   /* f */ op[1].c = "f"; op[1].type = float_type_node;
2591   /* i */ op[2].c = "i"; op[2].type = integer_type_node;
2592   /* p */ op[3].c = "p"; op[3].type = ptr_type_node;
2593
2594   /* This way of constructing the function tree types will slightly 
2595      overlap with the N2_FTYPES list used by other builtins.  */
2596
2597   for (lhs = 0; lhs < 4; lhs++)
2598     for (rhs1 = 0; rhs1 < 4; rhs1++)
2599       for (rhs2 = 0; rhs2 < 4; rhs2++)
2600         {
2601           if (rhs1 == 0 && rhs2 != 0)
2602             continue;
2603           ret_type = (op[lhs].type ? op[lhs].type : void_type_node);
2604           builtin_ftype
2605             = build_function_type_list (ret_type, integer_type_node,
2606                                         op[rhs1].type, op[rhs2].type,
2607                                         NULL_TREE);
2608           snprintf (builtin_name + n, 32 - n, "%sn%s%s",
2609                     op[lhs].c, op[rhs1].c, op[rhs2].c);
2610           /* Save copy of parameter string into custom_builtin_name[].  */
2611           strncpy (custom_builtin_name[builtin_code], builtin_name + n, 5);
2612           add_builtin_function (builtin_name, builtin_ftype,
2613                                 start_code + builtin_code,
2614                                 BUILT_IN_MD, NULL, NULL_TREE);
2615           builtin_code += 1;
2616         }
2617 }
2618
2619 static rtx
2620 nios2_expand_custom_builtin (tree exp, unsigned int index, rtx target)
2621 {
2622   bool has_target_p = (TREE_TYPE (exp) != void_type_node);
2623   enum machine_mode tmode = VOIDmode;
2624   int nargs, argno;
2625   rtx value, insn, unspec_args[3];
2626   tree arg;
2627
2628   /* XnXX form.  */
2629   if (has_target_p)
2630     {
2631       tmode = TYPE_MODE (TREE_TYPE (exp));
2632       if (!target || GET_MODE (target) != tmode
2633           || !REG_P (target))
2634         target = gen_reg_rtx (tmode);
2635     }
2636
2637   nargs = call_expr_nargs (exp);
2638   for (argno = 0; argno < nargs; argno++)
2639     {
2640       arg = CALL_EXPR_ARG (exp, argno);
2641       value = expand_normal (arg);
2642       unspec_args[argno] = value;
2643       if (argno == 0)
2644         {
2645           if (!custom_insn_opcode (value, VOIDmode))
2646             error ("Custom instruction opcode must be compile time "
2647                    "constant in the range 0-255 for __builtin_custom_%s",
2648                    custom_builtin_name[index]);
2649         }
2650       else
2651         /* For other arguments, force into a register.  */
2652         unspec_args[argno] = force_reg (TYPE_MODE (TREE_TYPE (arg)),
2653                                         unspec_args[argno]);
2654     }
2655   /* Fill remaining unspec operands with zero.  */
2656   for (; argno < 3; argno++)
2657     unspec_args[argno] = const0_rtx;
2658
2659   insn = (has_target_p
2660           ? gen_rtx_SET (VOIDmode, target,
2661                          gen_rtx_UNSPEC_VOLATILE (tmode,
2662                                                   gen_rtvec_v (3, unspec_args),
2663                                                   UNSPECV_CUSTOM_XNXX))
2664           : gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec_v (3, unspec_args),
2665                                      UNSPECV_CUSTOM_NXX));
2666   emit_insn (insn);
2667   return has_target_p ? target : const0_rtx;
2668 }
2669
2670
2671 \f
2672
2673 /* Main definition of built-in functions. Nios II has a small number of fixed
2674    builtins, plus a large number of FPU insn builtins, and builtins for
2675    generating custom instructions.  */
2676
2677 struct nios2_builtin_desc
2678 {
2679   enum insn_code icode;
2680   enum nios2_ftcode ftype;
2681   const char* name;
2682 };
2683
2684 #define N2_BUILTINS                                     \
2685   N2_BUILTIN_DEF (sync,   N2_FTYPE_VOID_VOID)           \
2686   N2_BUILTIN_DEF (ldbio,  N2_FTYPE_SI_CVPTR)            \
2687   N2_BUILTIN_DEF (ldbuio, N2_FTYPE_UI_CVPTR)            \
2688   N2_BUILTIN_DEF (ldhio,  N2_FTYPE_SI_CVPTR)            \
2689   N2_BUILTIN_DEF (ldhuio, N2_FTYPE_UI_CVPTR)            \
2690   N2_BUILTIN_DEF (ldwio,  N2_FTYPE_SI_CVPTR)            \
2691   N2_BUILTIN_DEF (stbio,  N2_FTYPE_VOID_VPTR_SI)        \
2692   N2_BUILTIN_DEF (sthio,  N2_FTYPE_VOID_VPTR_SI)        \
2693   N2_BUILTIN_DEF (stwio,  N2_FTYPE_VOID_VPTR_SI)        \
2694   N2_BUILTIN_DEF (rdctl,  N2_FTYPE_SI_SI)               \
2695   N2_BUILTIN_DEF (wrctl,  N2_FTYPE_VOID_SI_SI)
2696
2697 enum nios2_builtin_code {
2698 #define N2_BUILTIN_DEF(name, ftype) NIOS2_BUILTIN_ ## name,
2699   N2_BUILTINS
2700 #undef N2_BUILTIN_DEF
2701   NUM_FIXED_NIOS2_BUILTINS
2702 };
2703
2704 static const struct nios2_builtin_desc nios2_builtins[] = {
2705 #define N2_BUILTIN_DEF(name, ftype)                     \
2706   { CODE_FOR_ ## name, ftype, "__builtin_" #name },
2707   N2_BUILTINS
2708 #undef N2_BUILTIN_DEF
2709 };
2710
2711 /* Start/ends of FPU/custom insn builtin index ranges.  */
2712 static unsigned int nios2_fpu_builtin_base;
2713 static unsigned int nios2_custom_builtin_base;
2714 static unsigned int nios2_custom_builtin_end;
2715
2716 static void
2717 nios2_init_builtins (void)
2718 {
2719   unsigned int i;
2720
2721   /* Initialize fixed builtins.  */
2722   for (i = 0; i < ARRAY_SIZE (nios2_builtins); i++)
2723     {
2724       const struct nios2_builtin_desc *d = &nios2_builtins[i];
2725       add_builtin_function (d->name, nios2_ftype (d->ftype), i,
2726                             BUILT_IN_MD, NULL, NULL);
2727     }
2728
2729   /* Initialize FPU builtins.  */
2730   nios2_fpu_builtin_base = ARRAY_SIZE (nios2_builtins);
2731   nios2_init_fpu_builtins (nios2_fpu_builtin_base);
2732
2733   /* Initialize custom insn builtins.  */
2734   nios2_custom_builtin_base
2735     = nios2_fpu_builtin_base + ARRAY_SIZE (nios2_fpu_insn);
2736   nios2_custom_builtin_end
2737     = nios2_custom_builtin_base + NUM_CUSTOM_BUILTINS;
2738   nios2_init_custom_builtins (nios2_custom_builtin_base);
2739 }
2740
2741 static rtx
2742 nios2_expand_builtin_insn (const struct nios2_builtin_desc *d, int n,
2743                            struct expand_operand* ops, bool has_target_p)
2744 {
2745   if (maybe_expand_insn (d->icode, n, ops))
2746     return has_target_p ? ops[0].value : const0_rtx;
2747   else
2748     {
2749       error ("invalid argument to built-in function %s", d->name);
2750       return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx;       
2751     } 
2752 }
2753
2754 static rtx
2755 nios2_expand_ldstio_builtin  (tree exp, rtx target,
2756                               const struct nios2_builtin_desc *d)
2757 {
2758   bool has_target_p;
2759   rtx addr, mem, val;
2760   struct expand_operand ops[MAX_RECOG_OPERANDS];
2761   enum machine_mode mode = insn_data[d->icode].operand[0].mode;
2762
2763   addr = expand_normal (CALL_EXPR_ARG (exp, 0));
2764   mem = gen_rtx_MEM (mode, addr);
2765
2766   if (insn_data[d->icode].operand[0].allows_mem)
2767     {
2768       /* stxio  */
2769       val = force_reg (mode, expand_normal (CALL_EXPR_ARG (exp, 1)));
2770       val = simplify_gen_subreg (mode, val, GET_MODE (val), 0);
2771       create_output_operand (&ops[0], mem, mode);
2772       create_input_operand (&ops[1], val, mode);
2773       has_target_p = false;
2774     }
2775   else
2776     {
2777       /* ldxio */
2778       create_output_operand (&ops[0], target, mode);
2779       create_input_operand (&ops[1], mem, mode);
2780       has_target_p = true;
2781     }
2782   return nios2_expand_builtin_insn (d, 2, ops, has_target_p);
2783 }
2784
2785 static rtx
2786 nios2_expand_rdwrctl_builtin (tree exp, rtx target,
2787                              const struct nios2_builtin_desc *d)
2788 {
2789   bool has_target_p = (insn_data[d->icode].operand[0].predicate
2790                        == register_operand);
2791   rtx ctlcode = expand_normal (CALL_EXPR_ARG (exp, 0));
2792   struct expand_operand ops[MAX_RECOG_OPERANDS];
2793   if (!rdwrctl_operand (ctlcode, VOIDmode))
2794     {
2795       error ("Control register number must be in range 0-31 for %s",
2796              d->name);
2797       return has_target_p ? gen_reg_rtx (SImode) : const0_rtx;
2798     }
2799   if (has_target_p)
2800     {
2801       create_output_operand (&ops[0], target, SImode);
2802       create_integer_operand (&ops[1], INTVAL (ctlcode));
2803     }
2804   else
2805     {
2806       rtx val = expand_normal (CALL_EXPR_ARG (exp, 1));
2807       create_integer_operand (&ops[0], INTVAL (ctlcode));
2808       create_input_operand (&ops[1], val, SImode);
2809     }
2810   return nios2_expand_builtin_insn (d, 2, ops, has_target_p);
2811 }
2812
2813 /* Expand an expression EXP that calls a built-in function,
2814    with result going to TARGET if that's convenient
2815    (and in mode MODE if that's convenient).
2816    SUBTARGET may be used as the target for computing one of EXP's operands.
2817    IGNORE is nonzero if the value is to be ignored.  */
2818
2819 static rtx
2820 nios2_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
2821                       enum machine_mode mode ATTRIBUTE_UNUSED,
2822                       int ignore ATTRIBUTE_UNUSED)
2823 {
2824   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2825   unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
2826
2827   if (fcode < nios2_fpu_builtin_base)
2828     {
2829       const struct nios2_builtin_desc *d = &nios2_builtins[fcode];
2830
2831       switch (fcode)
2832         {
2833         case NIOS2_BUILTIN_sync:
2834           emit_insn (gen_sync ());
2835           return const0_rtx;
2836
2837         case NIOS2_BUILTIN_ldbio:
2838         case NIOS2_BUILTIN_ldbuio:
2839         case NIOS2_BUILTIN_ldhio:
2840         case NIOS2_BUILTIN_ldhuio:
2841         case NIOS2_BUILTIN_ldwio:
2842         case NIOS2_BUILTIN_stbio:
2843         case NIOS2_BUILTIN_sthio:
2844         case NIOS2_BUILTIN_stwio:
2845           return nios2_expand_ldstio_builtin (exp, target, d);
2846
2847         case NIOS2_BUILTIN_rdctl:
2848         case NIOS2_BUILTIN_wrctl:
2849           return nios2_expand_rdwrctl_builtin (exp, target, d);
2850
2851         default:
2852           gcc_unreachable ();
2853         }
2854     }
2855   else if (fcode < nios2_custom_builtin_base)
2856     /* FPU builtin range.  */
2857     return nios2_expand_fpu_builtin (exp, fcode - nios2_fpu_builtin_base,
2858                                      target);
2859   else if (fcode < nios2_custom_builtin_end)
2860     /* Custom insn builtin range.  */
2861     return nios2_expand_custom_builtin (exp, fcode - nios2_custom_builtin_base,
2862                                         target);
2863   else
2864     gcc_unreachable ();
2865 }
2866
2867 static void
2868 nios2_init_libfuncs (void)
2869 {
2870   /* For Linux, we have access to kernel support for atomic operations.  */
2871   if (TARGET_LINUX_ABI)
2872     init_sync_libfuncs (UNITS_PER_WORD);
2873 }
2874
2875 \f
2876
2877
2878 /* Register a custom code use, and signal error if a conflict was found.  */
2879 static void
2880 nios2_register_custom_code (unsigned int N, enum nios2_ccs_code status,
2881                             int index)
2882 {
2883   gcc_assert (N <= 255);
2884
2885   if (status == CCS_FPU)
2886     {
2887       if (custom_code_status[N] == CCS_FPU && index != custom_code_index[N])
2888         {
2889           custom_code_conflict = true;
2890           error ("switch `-mcustom-%s' conflicts with switch `-mcustom-%s'",
2891                  N2FPU_NAME (custom_code_index[N]), N2FPU_NAME (index));
2892         }
2893       else if (custom_code_status[N] == CCS_BUILTIN_CALL)
2894         {
2895           custom_code_conflict = true;
2896           error ("call to `__builtin_custom_%s' conflicts with switch "
2897                  "`-mcustom-%s'", custom_builtin_name[custom_code_index[N]],
2898                  N2FPU_NAME (index));
2899         }
2900     }
2901   else if (status == CCS_BUILTIN_CALL)
2902     {
2903       if (custom_code_status[N] == CCS_FPU)
2904         {
2905           custom_code_conflict = true;
2906           error ("call to `__builtin_custom_%s' conflicts with switch "
2907                  "`-mcustom-%s'", custom_builtin_name[index],
2908                  N2FPU_NAME (custom_code_index[N]));
2909         }
2910           /* Code conflicts between different __builtin_custom_xnxx calls
2911              do not seem to be checked. ???  */
2912     }
2913   else
2914     gcc_unreachable ();
2915
2916   custom_code_status[N] = status;
2917   custom_code_index[N] = index;
2918 }
2919
2920 /* Mark a custom code as not in use.  */
2921 static void
2922 nios2_deregister_custom_code (unsigned int N)
2923 {
2924   if (N <= 255)
2925     {
2926       custom_code_status[N] = CCS_UNUSED;
2927       custom_code_index[N] = 0;
2928     }
2929 }
2930
2931 /* Target attributes can affect per-function option state, so we need to
2932    save/restore the custom code tracking info using the
2933    TARGET_OPTION_SAVE/TARGET_OPTION_RESTORE hooks.  */
2934
2935 static void
2936 nios2_option_save (struct cl_target_option *ptr)
2937 {
2938   unsigned int i;
2939   for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
2940     ptr->saved_fpu_custom_code[i] = N2FPU_N (i);
2941   memcpy (ptr->saved_custom_code_status, custom_code_status,
2942           sizeof (custom_code_status));
2943   memcpy (ptr->saved_custom_code_index, custom_code_index,
2944           sizeof (custom_code_index));
2945 }
2946
2947 static void
2948 nios2_option_restore (struct cl_target_option *ptr)
2949 {
2950   unsigned int i;
2951   for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
2952     N2FPU_N (i) = ptr->saved_fpu_custom_code[i];
2953   memcpy (custom_code_status, ptr->saved_custom_code_status,
2954           sizeof (custom_code_status));
2955   memcpy (custom_code_index, ptr->saved_custom_code_index,
2956           sizeof (custom_code_index));
2957 }
2958
2959 /* Inner function to process the attribute((target(...))), take an argument and
2960    set the current options from the argument. If we have a list, recursively go
2961    over the list.  */
2962
2963 static bool
2964 nios2_valid_target_attribute_rec (tree args)
2965 {
2966   if (TREE_CODE (args) == TREE_LIST)
2967     {
2968       bool ret = true;
2969       for (; args; args = TREE_CHAIN (args))
2970         if (TREE_VALUE (args)
2971             && !nios2_valid_target_attribute_rec (TREE_VALUE (args)))
2972           ret = false;
2973       return ret;
2974     }
2975   else if (TREE_CODE (args) == STRING_CST)
2976     {
2977       char *argstr = ASTRDUP (TREE_STRING_POINTER (args));
2978       while (argstr && *argstr != '\0')
2979         {
2980           bool no_opt = false, end_p = false;
2981           char *eq = NULL, *p;
2982           while (ISSPACE (*argstr))
2983             argstr++;
2984           p = argstr;
2985           while (*p != '\0' && *p != ',')
2986             {
2987               if (!eq && *p == '=')
2988                 eq = p;
2989               ++p;
2990             }
2991           if (*p == '\0')
2992             end_p = true;
2993           else
2994             *p = '\0';
2995           if (eq) *eq = '\0';
2996
2997           if (!strncmp (argstr, "no-", 3))
2998             {
2999               no_opt = true;
3000               argstr += 3;
3001             }
3002           if (!strncmp (argstr, "custom-fpu-cfg", 14))
3003             {
3004               if (no_opt)
3005                 {
3006                   error ("custom-fpu-cfg option does not support `no-'");
3007                   return false;
3008                 }
3009               if (!eq)
3010                 {
3011                   error ("custom-fpu-cfg option requires configuration"
3012                          " argument");
3013                   return false;
3014                 }
3015               /* Increment and skip whitespace.  */
3016               while (ISSPACE (*(++eq))) ;
3017               nios2_handle_custom_fpu_cfg (eq, true);
3018             }
3019           else if (!strncmp (argstr, "custom-", 7))
3020             {
3021               int code = -1;
3022               unsigned int i;
3023               for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
3024                 if (!strncmp (argstr + 7, N2FPU_NAME (i),
3025                               strlen (N2FPU_NAME (i))))
3026                   {
3027                     /* Found insn.  */
3028                     code = i;
3029                     break;
3030                   }
3031               if (code >= 0)
3032                 {
3033                   if (no_opt)
3034                     {
3035                       if (eq)
3036                         {
3037                           error ("`no-custom-%s' does not accept arguments",
3038                                  N2FPU_NAME (code));
3039                           return false;
3040                         }
3041                       /* Disable option by setting to -1.  */
3042                       nios2_deregister_custom_code (N2FPU_N (code));
3043                       N2FPU_N (code) = -1;
3044                     }
3045                   else
3046                     {
3047                       char *t;
3048                       if (eq)
3049                         while (ISSPACE (*(++eq))) ;
3050                       if (!eq || eq == p)
3051                         {
3052                           error ("`custom-%s=' requires argument",
3053                                  N2FPU_NAME (code));
3054                           return false;
3055                         }
3056                       for (t = eq; t != p; ++t)
3057                         {
3058                           if (ISSPACE (*t))
3059                             continue;
3060                           if (!ISDIGIT (*t))
3061                             {                    
3062                               error ("`custom-%s=' argument requires "
3063                                      "numeric digits", N2FPU_NAME (code));
3064                               return false;
3065                             }
3066                         }
3067                       /* Set option to argument.  */
3068                       N2FPU_N (code) = atoi (eq);
3069                       nios2_handle_custom_fpu_insn_option (code);
3070                     }
3071                 }
3072               else
3073                 {
3074                   error ("`custom-%s=' is not recognised as FPU instruction",
3075                          argstr + 7);
3076                   return false;
3077                 }               
3078             }
3079           else
3080             {
3081               error ("`%s' is unknown", argstr);
3082               return false;
3083             }
3084
3085           if (end_p)
3086             break;
3087           else
3088             argstr = p + 1;
3089         }
3090       return true;
3091     }
3092   else
3093     gcc_unreachable ();
3094 }
3095
3096 /* Return a TARGET_OPTION_NODE tree of the target options listed or NULL.  */
3097
3098 static tree
3099 nios2_valid_target_attribute_tree (tree args)
3100 {
3101   if (!nios2_valid_target_attribute_rec (args))
3102     return NULL_TREE;
3103   nios2_custom_check_insns ();
3104   return build_target_option_node ();
3105 }
3106
3107 /* Hook to validate attribute((target("string"))).  */
3108
3109 static bool
3110 nios2_valid_target_attribute_p (tree fndecl,
3111                                 tree ARG_UNUSED (name),
3112                                 tree args,
3113                                 int ARG_UNUSED (flags))
3114 {
3115   struct cl_target_option cur_target;
3116   bool ret = true;
3117   tree old_optimize = build_optimization_node ();
3118   tree new_target, new_optimize;
3119   tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
3120
3121   /* If the function changed the optimization levels as well as setting target
3122      options, start with the optimizations specified.  */
3123   if (func_optimize && func_optimize != old_optimize)
3124     cl_optimization_restore (&global_options,
3125                              TREE_OPTIMIZATION (func_optimize));
3126
3127   /* The target attributes may also change some optimization flags, so update
3128      the optimization options if necessary.  */
3129   cl_target_option_save (&cur_target, &global_options);
3130   new_target = nios2_valid_target_attribute_tree (args);
3131   new_optimize = build_optimization_node ();
3132
3133   if (!new_target)
3134     ret = false;
3135
3136   else if (fndecl)
3137     {
3138       DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
3139
3140       if (old_optimize != new_optimize)
3141         DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
3142     }
3143
3144   cl_target_option_restore (&global_options, &cur_target);
3145
3146   if (old_optimize != new_optimize)
3147     cl_optimization_restore (&global_options,
3148                              TREE_OPTIMIZATION (old_optimize));
3149   return ret;
3150 }
3151
3152 /* Remember the last target of nios2_set_current_function.  */
3153 static GTY(()) tree nios2_previous_fndecl;
3154
3155 /* Establish appropriate back-end context for processing the function
3156    FNDECL.  The argument might be NULL to indicate processing at top
3157    level, outside of any function scope.  */
3158 static void
3159 nios2_set_current_function (tree fndecl)
3160 {
3161   tree old_tree = (nios2_previous_fndecl
3162                    ? DECL_FUNCTION_SPECIFIC_TARGET (nios2_previous_fndecl)
3163                    : NULL_TREE);
3164
3165   tree new_tree = (fndecl
3166                    ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
3167                    : NULL_TREE);
3168
3169   if (fndecl && fndecl != nios2_previous_fndecl)
3170     {
3171       nios2_previous_fndecl = fndecl;
3172       if (old_tree == new_tree)
3173         ;
3174
3175       else if (new_tree)
3176         {
3177           cl_target_option_restore (&global_options,
3178                                     TREE_TARGET_OPTION (new_tree));
3179           target_reinit ();
3180         }
3181
3182       else if (old_tree)
3183         {
3184           struct cl_target_option *def
3185             = TREE_TARGET_OPTION (target_option_current_node);
3186
3187           cl_target_option_restore (&global_options, def);
3188           target_reinit ();
3189         }
3190     }
3191 }
3192
3193 /* Hook to validate the current #pragma GCC target and set the FPU custom
3194    code option state.  If ARGS is NULL, then POP_TARGET is used to reset
3195    the options.  */
3196
3197 static bool
3198 nios2_pragma_target_parse (tree args, tree pop_target)
3199 {
3200   tree cur_tree;
3201   if (! args)
3202     {
3203       cur_tree = ((pop_target)
3204                   ? pop_target
3205                   : target_option_default_node);
3206       cl_target_option_restore (&global_options,
3207                                 TREE_TARGET_OPTION (cur_tree));
3208     }
3209   else
3210     {
3211       cur_tree = nios2_valid_target_attribute_tree (args);
3212       if (!cur_tree)
3213         return false;
3214     }
3215
3216   target_option_current_node = cur_tree;
3217   return true;
3218 }
3219
3220 /* Implement TARGET_MERGE_DECL_ATTRIBUTES.
3221    We are just using this hook to add some additional error checking to
3222    the default behavior.  GCC does not provide a target hook for merging
3223    the target options, and only correctly handles merging empty vs non-empty
3224    option data; see merge_decls() in c-decl.c.
3225    So here we require either that at least one of the decls has empty
3226    target options, or that the target options/data be identical.  */
3227 static tree
3228 nios2_merge_decl_attributes (tree olddecl, tree newdecl)
3229 {
3230   tree oldopts = lookup_attribute ("target", DECL_ATTRIBUTES (olddecl));
3231   tree newopts = lookup_attribute ("target", DECL_ATTRIBUTES (newdecl));
3232   if (newopts && oldopts && newopts != oldopts)
3233     {
3234       tree oldtree = DECL_FUNCTION_SPECIFIC_TARGET (olddecl);
3235       tree newtree = DECL_FUNCTION_SPECIFIC_TARGET (newdecl);
3236       if (oldtree && newtree && oldtree != newtree)
3237         {
3238           struct cl_target_option *olddata = TREE_TARGET_OPTION (oldtree);
3239           struct cl_target_option *newdata = TREE_TARGET_OPTION (newtree);
3240           if (olddata != newdata
3241               && memcmp (olddata, newdata, sizeof (struct cl_target_option)))
3242             error ("%qE redeclared with conflicting %qs attributes",
3243                    DECL_NAME (newdecl), "target");
3244         }
3245     }
3246   return merge_attributes (DECL_ATTRIBUTES (olddecl),
3247                            DECL_ATTRIBUTES (newdecl));
3248 }
3249
3250 #include "gt-nios2.h"