]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/nds32/nds32.c
New jit API entrypoint: gcc_jit_context_new_rvalue_from_long
[thirdparty/gcc.git] / gcc / config / nds32 / nds32.c
CommitLineData
9304f876 1/* Subroutines used for code generation of Andes NDS32 cpu for GNU compiler
5624e564 2 Copyright (C) 2012-2015 Free Software Foundation, Inc.
9304f876
CJW
3 Contributed by Andes Technology Corporation.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published
9 by the Free Software Foundation; either version 3, or (at your
10 option) any later version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
20
19ac960a 21/* ------------------------------------------------------------------------ */
9304f876
CJW
22
23#include "config.h"
24#include "system.h"
25#include "coretypes.h"
26#include "tm.h"
27#include "tree.h"
d8a2d370
DN
28#include "stor-layout.h"
29#include "varasm.h"
30#include "calls.h"
9304f876
CJW
31#include "rtl.h"
32#include "regs.h"
33#include "hard-reg-set.h"
34#include "insn-config.h" /* Required by recog.h. */
35#include "conditions.h"
36#include "output.h"
37#include "insn-attr.h" /* For DFA state_t. */
38#include "insn-codes.h" /* For CODE_FOR_xxx. */
39#include "reload.h" /* For push_reload(). */
40#include "flags.h"
83685514
AM
41#include "hashtab.h"
42#include "hash-set.h"
43#include "vec.h"
44#include "machmode.h"
45#include "input.h"
9304f876
CJW
46#include "function.h"
47#include "expr.h"
48#include "recog.h"
49#include "diagnostic-core.h"
60393bbc
AM
50#include "dominance.h"
51#include "cfg.h"
52#include "cfgrtl.h"
53#include "cfganal.h"
54#include "lcm.h"
55#include "cfgbuild.h"
56#include "cfgcleanup.h"
57#include "predict.h"
58#include "basic-block.h"
9304f876
CJW
59#include "df.h"
60#include "tm_p.h"
61#include "tm-constrs.h"
62#include "optabs.h" /* For GEN_FCN. */
63#include "target.h"
64#include "target-def.h"
65#include "langhooks.h" /* For add_builtin_function(). */
66#include "ggc.h"
9b2b7279 67#include "builtins.h"
9304f876
CJW
68
69/* ------------------------------------------------------------------------ */
70
71/* This file is divided into five parts:
72
73 PART 1: Auxiliary static variable definitions and
74 target hook static variable definitions.
75
76 PART 2: Auxiliary static function definitions.
77
78 PART 3: Implement target hook stuff definitions.
79
80 PART 4: Implemet extern function definitions,
81 the prototype is in nds32-protos.h.
82
83 PART 5: Initialize target hook structure and definitions. */
84
85/* ------------------------------------------------------------------------ */
86
87/* PART 1: Auxiliary static variable definitions and
88 target hook static variable definitions. */
89
9304f876
CJW
90/* Define intrinsic register names.
91 Please refer to nds32_intrinsic.h file, the index is corresponding to
92 'enum nds32_intrinsic_registers' data type values.
93 NOTE that the base value starting from 1024. */
94static const char * const nds32_intrinsic_register_names[] =
95{
96 "$PSW", "$IPSW", "$ITYPE", "$IPC"
97};
98
99/* Defining target-specific uses of __attribute__. */
100static const struct attribute_spec nds32_attribute_table[] =
101{
102 /* Syntax: { name, min_len, max_len, decl_required, type_required,
103 function_type_required, handler, affects_type_identity } */
104
105 /* The interrupt vid: [0-63]+ (actual vector number starts from 9 to 72). */
106 { "interrupt", 1, 64, false, false, false, NULL, false },
107 /* The exception vid: [1-8]+ (actual vector number starts from 1 to 8). */
108 { "exception", 1, 8, false, false, false, NULL, false },
109 /* Argument is user's interrupt numbers. The vector number is always 0. */
110 { "reset", 1, 1, false, false, false, NULL, false },
111
112 /* The attributes describing isr nested type. */
113 { "nested", 0, 0, false, false, false, NULL, false },
114 { "not_nested", 0, 0, false, false, false, NULL, false },
115 { "nested_ready", 0, 0, false, false, false, NULL, false },
116
117 /* The attributes describing isr register save scheme. */
118 { "save_all", 0, 0, false, false, false, NULL, false },
119 { "partial_save", 0, 0, false, false, false, NULL, false },
120
121 /* The attributes used by reset attribute. */
122 { "nmi", 1, 1, false, false, false, NULL, false },
123 { "warm", 1, 1, false, false, false, NULL, false },
124
125 /* The attribute telling no prologue/epilogue. */
126 { "naked", 0, 0, false, false, false, NULL, false },
127
128 /* The last attribute spec is set to be NULL. */
129 { NULL, 0, 0, false, false, false, NULL, false }
130};
131
132
133/* ------------------------------------------------------------------------ */
134
135/* PART 2: Auxiliary static function definitions. */
136
137/* Function to save and restore machine-specific function data. */
138static struct machine_function *
139nds32_init_machine_status (void)
140{
141 struct machine_function *machine;
766090c2 142 machine = ggc_cleared_alloc<machine_function> ();
9304f876
CJW
143
144 /* Initially assume this function needs prologue/epilogue. */
145 machine->naked_p = 0;
146
147 /* Initially assume this function does NOT use fp_as_gp optimization. */
148 machine->fp_as_gp_p = 0;
149
150 return machine;
151}
152
153/* Function to compute stack frame size and
154 store into cfun->machine structure. */
155static void
156nds32_compute_stack_frame (void)
157{
158 int r;
159 int block_size;
160
161 /* Because nds32_compute_stack_frame() will be called from different place,
162 everytime we enter this function, we have to assume this function
163 needs prologue/epilogue. */
164 cfun->machine->naked_p = 0;
165
166 /* Get variadic arguments size to prepare pretend arguments and
35da54a6
CJW
167 we will push them into stack at prologue by ourself. */
168 cfun->machine->va_args_size = crtl->args.pretend_args_size;
169 if (cfun->machine->va_args_size != 0)
170 {
171 cfun->machine->va_args_first_regno
172 = NDS32_GPR_ARG_FIRST_REGNUM
173 + NDS32_MAX_GPR_REGS_FOR_ARGS
174 - (crtl->args.pretend_args_size / UNITS_PER_WORD);
175 cfun->machine->va_args_last_regno
176 = NDS32_GPR_ARG_FIRST_REGNUM + NDS32_MAX_GPR_REGS_FOR_ARGS - 1;
177 }
178 else
179 {
180 cfun->machine->va_args_first_regno = SP_REGNUM;
181 cfun->machine->va_args_last_regno = SP_REGNUM;
182 }
183
184 /* Important: We need to make sure that varargs area is 8-byte alignment. */
185 block_size = cfun->machine->va_args_size;
186 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size))
187 {
188 cfun->machine->va_args_area_padding_bytes
189 = NDS32_ROUND_UP_DOUBLE_WORD (block_size) - block_size;
190 }
9304f876
CJW
191
192 /* Get local variables, incoming variables, and temporary variables size.
193 Note that we need to make sure it is 8-byte alignment because
194 there may be no padding bytes if we are using LRA. */
195 cfun->machine->local_size = NDS32_ROUND_UP_DOUBLE_WORD (get_frame_size ());
196
197 /* Get outgoing arguments size. */
198 cfun->machine->out_args_size = crtl->outgoing_args_size;
199
200 /* If $fp value is required to be saved on stack, it needs 4 bytes space.
201 Check whether $fp is ever live. */
202 cfun->machine->fp_size = (df_regs_ever_live_p (FP_REGNUM)) ? 4 : 0;
203
204 /* If $gp value is required to be saved on stack, it needs 4 bytes space.
205 Check whether we are using PIC code genration. */
206 cfun->machine->gp_size = (flag_pic) ? 4 : 0;
207
208 /* If $lp value is required to be saved on stack, it needs 4 bytes space.
209 Check whether $lp is ever live. */
210 cfun->machine->lp_size = (df_regs_ever_live_p (LP_REGNUM)) ? 4 : 0;
211
212 /* Initially there is no padding bytes. */
213 cfun->machine->callee_saved_area_padding_bytes = 0;
214
215 /* Calculate the bytes of saving callee-saved registers on stack. */
216 cfun->machine->callee_saved_regs_size = 0;
217 cfun->machine->callee_saved_regs_first_regno = SP_REGNUM;
218 cfun->machine->callee_saved_regs_last_regno = SP_REGNUM;
219 /* Currently, there is no need to check $r28~$r31
220 because we will save them in another way. */
221 for (r = 0; r < 28; r++)
222 {
223 if (NDS32_REQUIRED_CALLEE_SAVED_P (r))
224 {
225 /* Mark the first required callee-saved register
226 (only need to set it once).
227 If first regno == SP_REGNUM, we can tell that
228 it is the first time to be here. */
229 if (cfun->machine->callee_saved_regs_first_regno == SP_REGNUM)
230 cfun->machine->callee_saved_regs_first_regno = r;
231 /* Mark the last required callee-saved register. */
232 cfun->machine->callee_saved_regs_last_regno = r;
233 }
234 }
235
236 /* Check if this function can omit prologue/epilogue code fragment.
237 If there is 'naked' attribute in this function,
238 we can set 'naked_p' flag to indicate that
239 we do not have to generate prologue/epilogue.
240 Or, if all the following conditions succeed,
241 we can set this function 'naked_p' as well:
242 condition 1: first_regno == last_regno == SP_REGNUM,
243 which means we do not have to save
244 any callee-saved registers.
245 condition 2: Both $lp and $fp are NOT live in this function,
2da1e7c0
CJW
246 which means we do not need to save them and there
247 is no outgoing size.
9304f876
CJW
248 condition 3: There is no local_size, which means
249 we do not need to adjust $sp. */
250 if (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl))
251 || (cfun->machine->callee_saved_regs_first_regno == SP_REGNUM
252 && cfun->machine->callee_saved_regs_last_regno == SP_REGNUM
253 && !df_regs_ever_live_p (FP_REGNUM)
254 && !df_regs_ever_live_p (LP_REGNUM)
255 && cfun->machine->local_size == 0))
256 {
2da1e7c0
CJW
257 /* Set this function 'naked_p' and other functions can check this flag.
258 Note that in nds32 port, the 'naked_p = 1' JUST means there is no
259 callee-saved, local size, and outgoing size.
260 The varargs space and ret instruction may still present in
261 the prologue/epilogue expanding. */
9304f876
CJW
262 cfun->machine->naked_p = 1;
263
264 /* No need to save $fp, $gp, and $lp.
265 We should set these value to be zero
266 so that nds32_initial_elimination_offset() can work properly. */
267 cfun->machine->fp_size = 0;
268 cfun->machine->gp_size = 0;
269 cfun->machine->lp_size = 0;
270
271 /* If stack usage computation is required,
272 we need to provide the static stack size. */
273 if (flag_stack_usage_info)
274 current_function_static_stack_size = 0;
275
276 /* No need to do following adjustment, return immediately. */
277 return;
278 }
279
280 /* Adjustment for v3push instructions:
281 If we are using v3push (push25/pop25) instructions,
282 we need to make sure Rb is $r6 and Re is
283 located on $r6, $r8, $r10, or $r14.
284 Some results above will be discarded and recomputed.
2da1e7c0
CJW
285 Note that it is only available under V3/V3M ISA and we
286 DO NOT setup following stuff for isr or variadic function. */
287 if (TARGET_V3PUSH
288 && !nds32_isr_function_p (current_function_decl)
289 && (cfun->machine->va_args_size == 0))
9304f876
CJW
290 {
291 /* Recompute:
292 cfun->machine->fp_size
293 cfun->machine->gp_size
294 cfun->machine->lp_size
295 cfun->machine->callee_saved_regs_first_regno
296 cfun->machine->callee_saved_regs_last_regno */
297
298 /* For v3push instructions, $fp, $gp, and $lp are always saved. */
299 cfun->machine->fp_size = 4;
300 cfun->machine->gp_size = 4;
301 cfun->machine->lp_size = 4;
302
303 /* Remember to set Rb = $r6. */
304 cfun->machine->callee_saved_regs_first_regno = 6;
305
306 if (cfun->machine->callee_saved_regs_last_regno <= 6)
307 {
308 /* Re = $r6 */
309 cfun->machine->callee_saved_regs_last_regno = 6;
310 }
311 else if (cfun->machine->callee_saved_regs_last_regno <= 8)
312 {
313 /* Re = $r8 */
314 cfun->machine->callee_saved_regs_last_regno = 8;
315 }
316 else if (cfun->machine->callee_saved_regs_last_regno <= 10)
317 {
318 /* Re = $r10 */
319 cfun->machine->callee_saved_regs_last_regno = 10;
320 }
321 else if (cfun->machine->callee_saved_regs_last_regno <= 14)
322 {
323 /* Re = $r14 */
324 cfun->machine->callee_saved_regs_last_regno = 14;
325 }
326 else if (cfun->machine->callee_saved_regs_last_regno == SP_REGNUM)
327 {
328 /* If last_regno is SP_REGNUM, which means
329 it is never changed, so set it to Re = $r6. */
330 cfun->machine->callee_saved_regs_last_regno = 6;
331 }
332 else
333 {
334 /* The program flow should not go here. */
335 gcc_unreachable ();
336 }
337 }
338
339 /* We have correctly set callee_saved_regs_first_regno
340 and callee_saved_regs_last_regno.
341 Initially, the callee_saved_regs_size is supposed to be 0.
342 As long as callee_saved_regs_last_regno is not SP_REGNUM,
343 we can update callee_saved_regs_size with new size. */
344 if (cfun->machine->callee_saved_regs_last_regno != SP_REGNUM)
345 {
346 /* Compute pushed size of callee-saved registers. */
347 cfun->machine->callee_saved_regs_size
348 = 4 * (cfun->machine->callee_saved_regs_last_regno
349 - cfun->machine->callee_saved_regs_first_regno
350 + 1);
351 }
352
353 /* Important: We need to make sure that
35da54a6 354 (fp_size + gp_size + lp_size + callee_saved_regs_size)
9304f876
CJW
355 is 8-byte alignment.
356 If it is not, calculate the padding bytes. */
35da54a6 357 block_size = cfun->machine->fp_size
9304f876
CJW
358 + cfun->machine->gp_size
359 + cfun->machine->lp_size
360 + cfun->machine->callee_saved_regs_size;
361 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size))
362 {
363 cfun->machine->callee_saved_area_padding_bytes
364 = NDS32_ROUND_UP_DOUBLE_WORD (block_size) - block_size;
365 }
366
367 /* If stack usage computation is required,
368 we need to provide the static stack size. */
369 if (flag_stack_usage_info)
370 {
371 current_function_static_stack_size
372 = NDS32_ROUND_UP_DOUBLE_WORD (block_size)
373 + cfun->machine->local_size
374 + cfun->machine->out_args_size;
375 }
376}
377
378/* Function to create a parallel rtx pattern
379 which presents stack push multiple behavior.
380 The overall concept are:
381 "push registers to memory",
382 "adjust stack pointer". */
4e9a2848 383static void
47e0e7d2 384nds32_emit_stack_push_multiple (rtx Rb, rtx Re, rtx En4, bool vaarg_p)
9304f876
CJW
385{
386 int regno;
387 int extra_count;
388 int num_use_regs;
389 int par_index;
390 int offset;
4e9a2848 391 int save_fp, save_gp, save_lp;
9304f876
CJW
392
393 rtx reg;
394 rtx mem;
395 rtx push_rtx;
396 rtx adjust_sp_rtx;
397 rtx parallel_insn;
47e0e7d2 398 rtx dwarf;
9304f876
CJW
399
400 /* We need to provide a customized rtx which contains
401 necessary information for data analysis,
402 so we create a parallel rtx like this:
403 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
404 (reg:SI Rb))
405 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
406 (reg:SI Rb+1))
407 ...
408 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
409 (reg:SI Re))
410 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
411 (reg:SI FP_REGNUM))
412 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
413 (reg:SI GP_REGNUM))
414 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
415 (reg:SI LP_REGNUM))
416 (set (reg:SI SP_REGNUM)
417 (plus (reg:SI SP_REGNUM) (const_int -32)))]) */
418
4e9a2848
CJW
419 /* Determine whether we need to save $fp, $gp, or $lp. */
420 save_fp = INTVAL (En4) & 0x8;
421 save_gp = INTVAL (En4) & 0x4;
422 save_lp = INTVAL (En4) & 0x2;
423
9304f876
CJW
424 /* Calculate the number of registers that will be pushed. */
425 extra_count = 0;
4e9a2848 426 if (save_fp)
9304f876 427 extra_count++;
4e9a2848 428 if (save_gp)
9304f876 429 extra_count++;
4e9a2848 430 if (save_lp)
9304f876
CJW
431 extra_count++;
432 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
433 if (REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM)
434 num_use_regs = extra_count;
435 else
436 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + extra_count;
437
438 /* In addition to used registers,
439 we need one more space for (set sp sp-x) rtx. */
440 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
441 rtvec_alloc (num_use_regs + 1));
442 par_index = 0;
443
444 /* Initialize offset and start to create push behavior. */
445 offset = -(num_use_regs * 4);
446
447 /* Create (set mem regX) from Rb, Rb+1 up to Re. */
448 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
449 {
450 /* Rb and Re may be SP_REGNUM.
451 We need to break this loop immediately. */
452 if (regno == SP_REGNUM)
4e9a2848 453 break;
9304f876
CJW
454
455 reg = gen_rtx_REG (SImode, regno);
456 mem = gen_frame_mem (SImode, plus_constant (Pmode,
457 stack_pointer_rtx,
458 offset));
459 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
460 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
461 RTX_FRAME_RELATED_P (push_rtx) = 1;
462 offset = offset + 4;
463 par_index++;
464 }
465
466 /* Create (set mem fp), (set mem gp), and (set mem lp) if necessary. */
4e9a2848 467 if (save_fp)
9304f876
CJW
468 {
469 reg = gen_rtx_REG (SImode, FP_REGNUM);
470 mem = gen_frame_mem (SImode, plus_constant (Pmode,
471 stack_pointer_rtx,
472 offset));
473 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
474 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
475 RTX_FRAME_RELATED_P (push_rtx) = 1;
476 offset = offset + 4;
477 par_index++;
478 }
4e9a2848 479 if (save_gp)
9304f876
CJW
480 {
481 reg = gen_rtx_REG (SImode, GP_REGNUM);
482 mem = gen_frame_mem (SImode, plus_constant (Pmode,
483 stack_pointer_rtx,
484 offset));
485 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
486 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
487 RTX_FRAME_RELATED_P (push_rtx) = 1;
488 offset = offset + 4;
489 par_index++;
490 }
4e9a2848 491 if (save_lp)
9304f876
CJW
492 {
493 reg = gen_rtx_REG (SImode, LP_REGNUM);
494 mem = gen_frame_mem (SImode, plus_constant (Pmode,
495 stack_pointer_rtx,
496 offset));
497 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
498 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
499 RTX_FRAME_RELATED_P (push_rtx) = 1;
500 offset = offset + 4;
501 par_index++;
502 }
503
504 /* Create (set sp sp-x). */
505
506 /* We need to re-calculate the offset value again for adjustment. */
507 offset = -(num_use_regs * 4);
508 adjust_sp_rtx
509 = gen_rtx_SET (VOIDmode,
510 stack_pointer_rtx,
511 plus_constant (Pmode, stack_pointer_rtx, offset));
512 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
513 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
514
4e9a2848
CJW
515 parallel_insn = emit_insn (parallel_insn);
516
517 /* The insn rtx 'parallel_insn' will change frame layout.
518 We need to use RTX_FRAME_RELATED_P so that GCC is able to
519 generate CFI (Call Frame Information) stuff. */
520 RTX_FRAME_RELATED_P (parallel_insn) = 1;
47e0e7d2
CJW
521
522 /* Don't use GCC's logic for CFI info if we are generate a push for VAARG
523 since we will not restore those register at epilogue. */
524 if (vaarg_p)
525 {
526 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA,
527 copy_rtx (adjust_sp_rtx), NULL_RTX);
528 REG_NOTES (parallel_insn) = dwarf;
529 }
9304f876
CJW
530}
531
532/* Function to create a parallel rtx pattern
533 which presents stack pop multiple behavior.
534 The overall concept are:
535 "pop registers from memory",
536 "adjust stack pointer". */
4e9a2848
CJW
537static void
538nds32_emit_stack_pop_multiple (rtx Rb, rtx Re, rtx En4)
9304f876
CJW
539{
540 int regno;
541 int extra_count;
542 int num_use_regs;
543 int par_index;
544 int offset;
4e9a2848 545 int save_fp, save_gp, save_lp;
9304f876
CJW
546
547 rtx reg;
548 rtx mem;
549 rtx pop_rtx;
550 rtx adjust_sp_rtx;
551 rtx parallel_insn;
4e9a2848 552 rtx dwarf = NULL_RTX;
9304f876
CJW
553
554 /* We need to provide a customized rtx which contains
555 necessary information for data analysis,
556 so we create a parallel rtx like this:
557 (parallel [(set (reg:SI Rb)
558 (mem (reg:SI SP_REGNUM)))
559 (set (reg:SI Rb+1)
560 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
561 ...
562 (set (reg:SI Re)
563 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
564 (set (reg:SI FP_REGNUM)
565 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
566 (set (reg:SI GP_REGNUM)
567 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
568 (set (reg:SI LP_REGNUM)
569 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
570 (set (reg:SI SP_REGNUM)
571 (plus (reg:SI SP_REGNUM) (const_int 32)))]) */
572
4e9a2848
CJW
573 /* Determine whether we need to restore $fp, $gp, or $lp. */
574 save_fp = INTVAL (En4) & 0x8;
575 save_gp = INTVAL (En4) & 0x4;
576 save_lp = INTVAL (En4) & 0x2;
577
9304f876
CJW
578 /* Calculate the number of registers that will be poped. */
579 extra_count = 0;
4e9a2848 580 if (save_fp)
9304f876 581 extra_count++;
4e9a2848 582 if (save_gp)
9304f876 583 extra_count++;
4e9a2848 584 if (save_lp)
9304f876
CJW
585 extra_count++;
586 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
587 if (REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM)
588 num_use_regs = extra_count;
589 else
590 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + extra_count;
591
592 /* In addition to used registers,
593 we need one more space for (set sp sp+x) rtx. */
594 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
595 rtvec_alloc (num_use_regs + 1));
596 par_index = 0;
597
598 /* Initialize offset and start to create pop behavior. */
599 offset = 0;
600
601 /* Create (set regX mem) from Rb, Rb+1 up to Re. */
602 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
603 {
604 /* Rb and Re may be SP_REGNUM.
605 We need to break this loop immediately. */
606 if (regno == SP_REGNUM)
4e9a2848 607 break;
9304f876
CJW
608
609 reg = gen_rtx_REG (SImode, regno);
610 mem = gen_frame_mem (SImode, plus_constant (Pmode,
611 stack_pointer_rtx,
612 offset));
613 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
614 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
615 RTX_FRAME_RELATED_P (pop_rtx) = 1;
616 offset = offset + 4;
617 par_index++;
4e9a2848
CJW
618
619 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
9304f876
CJW
620 }
621
622 /* Create (set fp mem), (set gp mem), and (set lp mem) if necessary. */
4e9a2848 623 if (save_fp)
9304f876
CJW
624 {
625 reg = gen_rtx_REG (SImode, FP_REGNUM);
626 mem = gen_frame_mem (SImode, plus_constant (Pmode,
627 stack_pointer_rtx,
628 offset));
629 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
630 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
631 RTX_FRAME_RELATED_P (pop_rtx) = 1;
632 offset = offset + 4;
633 par_index++;
4e9a2848
CJW
634
635 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
9304f876 636 }
4e9a2848 637 if (save_gp)
9304f876
CJW
638 {
639 reg = gen_rtx_REG (SImode, GP_REGNUM);
640 mem = gen_frame_mem (SImode, plus_constant (Pmode,
641 stack_pointer_rtx,
642 offset));
643 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
644 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
645 RTX_FRAME_RELATED_P (pop_rtx) = 1;
646 offset = offset + 4;
647 par_index++;
4e9a2848
CJW
648
649 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
9304f876 650 }
4e9a2848 651 if (save_lp)
9304f876
CJW
652 {
653 reg = gen_rtx_REG (SImode, LP_REGNUM);
654 mem = gen_frame_mem (SImode, plus_constant (Pmode,
655 stack_pointer_rtx,
656 offset));
657 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
658 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
659 RTX_FRAME_RELATED_P (pop_rtx) = 1;
660 offset = offset + 4;
661 par_index++;
4e9a2848
CJW
662
663 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
9304f876
CJW
664 }
665
666 /* Create (set sp sp+x). */
667
668 /* The offset value is already in place. No need to re-calculate it. */
669 adjust_sp_rtx
670 = gen_rtx_SET (VOIDmode,
671 stack_pointer_rtx,
672 plus_constant (Pmode, stack_pointer_rtx, offset));
673 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
9304f876 674
4e9a2848
CJW
675 /* Tell gcc we adjust SP in this insn. */
676 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, copy_rtx (adjust_sp_rtx), dwarf);
677
678 parallel_insn = emit_insn (parallel_insn);
679
680 /* The insn rtx 'parallel_insn' will change frame layout.
681 We need to use RTX_FRAME_RELATED_P so that GCC is able to
682 generate CFI (Call Frame Information) stuff. */
683 RTX_FRAME_RELATED_P (parallel_insn) = 1;
684
685 /* Add CFI info by manual. */
686 REG_NOTES (parallel_insn) = dwarf;
9304f876
CJW
687}
688
689/* Function to create a parallel rtx pattern
690 which presents stack v3push behavior.
691 The overall concept are:
692 "push registers to memory",
693 "adjust stack pointer". */
88437f39
CJW
694static void
695nds32_emit_stack_v3push (rtx Rb,
696 rtx Re,
697 rtx En4 ATTRIBUTE_UNUSED,
698 rtx imm8u)
9304f876
CJW
699{
700 int regno;
701 int num_use_regs;
702 int par_index;
703 int offset;
704
705 rtx reg;
706 rtx mem;
707 rtx push_rtx;
708 rtx adjust_sp_rtx;
709 rtx parallel_insn;
710
711 /* We need to provide a customized rtx which contains
712 necessary information for data analysis,
713 so we create a parallel rtx like this:
88437f39 714 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
9304f876
CJW
715 (reg:SI Rb))
716 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
717 (reg:SI Rb+1))
718 ...
719 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
720 (reg:SI Re))
721 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
722 (reg:SI FP_REGNUM))
723 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
724 (reg:SI GP_REGNUM))
725 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
726 (reg:SI LP_REGNUM))
727 (set (reg:SI SP_REGNUM)
728 (plus (reg:SI SP_REGNUM) (const_int -32-imm8u)))]) */
729
730 /* Calculate the number of registers that will be pushed.
731 Since $fp, $gp, and $lp is always pushed with v3push instruction,
732 we need to count these three registers.
733 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
734 So there is no need to worry about Rb=Re=SP_REGNUM case. */
735 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + 3;
736
737 /* In addition to used registers,
738 we need one more space for (set sp sp-x-imm8u) rtx. */
739 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
740 rtvec_alloc (num_use_regs + 1));
741 par_index = 0;
742
743 /* Initialize offset and start to create push behavior. */
744 offset = -(num_use_regs * 4);
745
746 /* Create (set mem regX) from Rb, Rb+1 up to Re.
747 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
748 So there is no need to worry about Rb=Re=SP_REGNUM case. */
749 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
750 {
751 reg = gen_rtx_REG (SImode, regno);
752 mem = gen_frame_mem (SImode, plus_constant (Pmode,
753 stack_pointer_rtx,
754 offset));
755 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
756 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
757 RTX_FRAME_RELATED_P (push_rtx) = 1;
758 offset = offset + 4;
759 par_index++;
760 }
761
762 /* Create (set mem fp). */
763 reg = gen_rtx_REG (SImode, FP_REGNUM);
764 mem = gen_frame_mem (SImode, plus_constant (Pmode,
765 stack_pointer_rtx,
766 offset));
767 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
768 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
769 RTX_FRAME_RELATED_P (push_rtx) = 1;
770 offset = offset + 4;
771 par_index++;
772 /* Create (set mem gp). */
773 reg = gen_rtx_REG (SImode, GP_REGNUM);
774 mem = gen_frame_mem (SImode, plus_constant (Pmode,
775 stack_pointer_rtx,
776 offset));
777 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
778 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
779 RTX_FRAME_RELATED_P (push_rtx) = 1;
780 offset = offset + 4;
781 par_index++;
782 /* Create (set mem lp). */
783 reg = gen_rtx_REG (SImode, LP_REGNUM);
784 mem = gen_frame_mem (SImode, plus_constant (Pmode,
785 stack_pointer_rtx,
786 offset));
787 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
788 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
789 RTX_FRAME_RELATED_P (push_rtx) = 1;
790 offset = offset + 4;
791 par_index++;
792
793 /* Create (set sp sp-x-imm8u). */
794
795 /* We need to re-calculate the offset value again for adjustment. */
796 offset = -(num_use_regs * 4);
797 adjust_sp_rtx
798 = gen_rtx_SET (VOIDmode,
799 stack_pointer_rtx,
800 plus_constant (Pmode,
801 stack_pointer_rtx,
802 offset - INTVAL (imm8u)));
803 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
804 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
805
88437f39
CJW
806 parallel_insn = emit_insn (parallel_insn);
807
808 /* The insn rtx 'parallel_insn' will change frame layout.
809 We need to use RTX_FRAME_RELATED_P so that GCC is able to
810 generate CFI (Call Frame Information) stuff. */
811 RTX_FRAME_RELATED_P (parallel_insn) = 1;
9304f876
CJW
812}
813
814/* Function to create a parallel rtx pattern
815 which presents stack v3pop behavior.
816 The overall concept are:
817 "pop registers from memory",
818 "adjust stack pointer". */
88437f39
CJW
819static void
820nds32_emit_stack_v3pop (rtx Rb,
821 rtx Re,
822 rtx En4 ATTRIBUTE_UNUSED,
823 rtx imm8u)
9304f876
CJW
824{
825 int regno;
826 int num_use_regs;
827 int par_index;
828 int offset;
829
830 rtx reg;
831 rtx mem;
832 rtx pop_rtx;
833 rtx adjust_sp_rtx;
834 rtx parallel_insn;
88437f39 835 rtx dwarf = NULL_RTX;
9304f876
CJW
836
837 /* We need to provide a customized rtx which contains
838 necessary information for data analysis,
839 so we create a parallel rtx like this:
840 (parallel [(set (reg:SI Rb)
841 (mem (reg:SI SP_REGNUM)))
842 (set (reg:SI Rb+1)
843 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
844 ...
845 (set (reg:SI Re)
846 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
847 (set (reg:SI FP_REGNUM)
848 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
849 (set (reg:SI GP_REGNUM)
850 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
851 (set (reg:SI LP_REGNUM)
852 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
853 (set (reg:SI SP_REGNUM)
854 (plus (reg:SI SP_REGNUM) (const_int 32+imm8u)))]) */
855
856 /* Calculate the number of registers that will be poped.
857 Since $fp, $gp, and $lp is always poped with v3pop instruction,
858 we need to count these three registers.
859 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
860 So there is no need to worry about Rb=Re=SP_REGNUM case. */
861 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + 3;
862
863 /* In addition to used registers,
864 we need one more space for (set sp sp+x+imm8u) rtx. */
865 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
866 rtvec_alloc (num_use_regs + 1));
867 par_index = 0;
868
869 /* Initialize offset and start to create pop behavior. */
870 offset = 0;
871
872 /* Create (set regX mem) from Rb, Rb+1 up to Re.
873 Under v3pop, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
874 So there is no need to worry about Rb=Re=SP_REGNUM case. */
875 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
876 {
877 reg = gen_rtx_REG (SImode, regno);
878 mem = gen_frame_mem (SImode, plus_constant (Pmode,
879 stack_pointer_rtx,
880 offset));
881 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
882 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
883 RTX_FRAME_RELATED_P (pop_rtx) = 1;
884 offset = offset + 4;
885 par_index++;
88437f39
CJW
886
887 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
9304f876
CJW
888 }
889
890 /* Create (set fp mem). */
891 reg = gen_rtx_REG (SImode, FP_REGNUM);
892 mem = gen_frame_mem (SImode, plus_constant (Pmode,
893 stack_pointer_rtx,
894 offset));
895 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
896 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
897 RTX_FRAME_RELATED_P (pop_rtx) = 1;
898 offset = offset + 4;
899 par_index++;
88437f39
CJW
900 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
901
9304f876
CJW
902 /* Create (set gp mem). */
903 reg = gen_rtx_REG (SImode, GP_REGNUM);
904 mem = gen_frame_mem (SImode, plus_constant (Pmode,
905 stack_pointer_rtx,
906 offset));
907 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
908 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
909 RTX_FRAME_RELATED_P (pop_rtx) = 1;
910 offset = offset + 4;
911 par_index++;
88437f39
CJW
912 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
913
9304f876
CJW
914 /* Create (set lp mem ). */
915 reg = gen_rtx_REG (SImode, LP_REGNUM);
916 mem = gen_frame_mem (SImode, plus_constant (Pmode,
917 stack_pointer_rtx,
918 offset));
919 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
920 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
921 RTX_FRAME_RELATED_P (pop_rtx) = 1;
922 offset = offset + 4;
923 par_index++;
88437f39 924 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
9304f876
CJW
925
926 /* Create (set sp sp+x+imm8u). */
927
928 /* The offset value is already in place. No need to re-calculate it. */
929 adjust_sp_rtx
930 = gen_rtx_SET (VOIDmode,
931 stack_pointer_rtx,
932 plus_constant (Pmode,
933 stack_pointer_rtx,
934 offset + INTVAL (imm8u)));
935 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
9304f876 936
88437f39
CJW
937 /* Tell gcc we adjust SP in this insn. */
938 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, copy_rtx (adjust_sp_rtx), dwarf);
939
940 parallel_insn = emit_insn (parallel_insn);
941
942 /* The insn rtx 'parallel_insn' will change frame layout.
943 We need to use RTX_FRAME_RELATED_P so that GCC is able to
944 generate CFI (Call Frame Information) stuff. */
945 RTX_FRAME_RELATED_P (parallel_insn) = 1;
946
947 /* Add CFI info by manual. */
948 REG_NOTES (parallel_insn) = dwarf;
9304f876
CJW
949}
950
9304f876
CJW
951/* Function that may creates more instructions
952 for large value on adjusting stack pointer.
953
954 In nds32 target, 'addi' can be used for stack pointer
955 adjustment in prologue/epilogue stage.
956 However, sometimes there are too many local variables so that
957 the adjustment value is not able to be fit in the 'addi' instruction.
958 One solution is to move value into a register
959 and then use 'add' instruction.
960 In practice, we use TA_REGNUM ($r15) to accomplish this purpose.
961 Also, we need to return zero for sp adjustment so that
962 proglogue/epilogue knows there is no need to create 'addi' instruction. */
963static int
964nds32_force_addi_stack_int (int full_value)
965{
966 int adjust_value;
967
968 rtx tmp_reg;
969 rtx sp_adjust_insn;
970
971 if (!satisfies_constraint_Is15 (GEN_INT (full_value)))
972 {
973 /* The value is not able to fit in single addi instruction.
974 Create more instructions of moving value into a register
975 and then add stack pointer with it. */
976
977 /* $r15 is going to be temporary register to hold the value. */
978 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
979
980 /* Create one more instruction to move value
981 into the temporary register. */
982 emit_move_insn (tmp_reg, GEN_INT (full_value));
983
984 /* Create new 'add' rtx. */
985 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
986 stack_pointer_rtx,
987 tmp_reg);
988 /* Emit rtx into insn list and receive its transformed insn rtx. */
989 sp_adjust_insn = emit_insn (sp_adjust_insn);
990
991 /* At prologue, we need to tell GCC that this is frame related insn,
992 so that we can consider this instruction to output debug information.
993 If full_value is NEGATIVE, it means this function
994 is invoked by expand_prologue. */
995 if (full_value < 0)
996 {
997 /* Because (tmp_reg <- full_value) may be split into two
998 rtl patterns, we can not set its RTX_FRAME_RELATED_P.
999 We need to construct another (sp <- sp + full_value)
1000 and then insert it into sp_adjust_insn's reg note to
1001 represent a frame related expression.
1002 GCC knows how to refer it and output debug information. */
1003
1004 rtx plus_rtx;
1005 rtx set_rtx;
1006
1007 plus_rtx = plus_constant (Pmode, stack_pointer_rtx, full_value);
1008 set_rtx = gen_rtx_SET (VOIDmode, stack_pointer_rtx, plus_rtx);
1009 add_reg_note (sp_adjust_insn, REG_FRAME_RELATED_EXPR, set_rtx);
1010
1011 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
1012 }
1013
1014 /* We have used alternative way to adjust stack pointer value.
1015 Return zero so that prologue/epilogue
1016 will not generate other instructions. */
1017 return 0;
1018 }
1019 else
1020 {
1021 /* The value is able to fit in addi instruction.
1022 However, remember to make it to be positive value
1023 because we want to return 'adjustment' result. */
1024 adjust_value = (full_value < 0) ? (-full_value) : (full_value);
1025
1026 return adjust_value;
1027 }
1028}
1029
1030/* Return true if MODE/TYPE need double word alignment. */
1031static bool
ef4bddc2 1032nds32_needs_double_word_align (machine_mode mode, const_tree type)
9304f876
CJW
1033{
1034 unsigned int align;
1035
634bdae9
CJW
1036 /* Pick up the alignment according to the mode or type. */
1037 align = NDS32_MODE_TYPE_ALIGN (mode, type);
9304f876
CJW
1038
1039 return (align > PARM_BOUNDARY);
1040}
1041
1042/* Return true if FUNC is a naked function. */
810f736f
CJW
1043static bool
1044nds32_naked_function_p (tree func)
9304f876
CJW
1045{
1046 tree t;
1047
1048 if (TREE_CODE (func) != FUNCTION_DECL)
1049 abort ();
1050
1051 t = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
1052
1053 return (t != NULL_TREE);
1054}
1055
1056/* Function that check if 'X' is a valid address register.
1057 The variable 'STRICT' is very important to
1058 make decision for register number.
1059
1060 STRICT : true
1061 => We are in reload pass or after reload pass.
1062 The register number should be strictly limited in general registers.
1063
1064 STRICT : false
1065 => Before reload pass, we are free to use any register number. */
1066static bool
1067nds32_address_register_rtx_p (rtx x, bool strict)
1068{
1069 int regno;
1070
1071 if (GET_CODE (x) != REG)
1072 return false;
1073
1074 regno = REGNO (x);
1075
1076 if (strict)
1077 return REGNO_OK_FOR_BASE_P (regno);
1078 else
1079 return true;
1080}
1081
1082/* Function that check if 'INDEX' is valid to be a index rtx for address.
1083
1084 OUTER_MODE : Machine mode of outer address rtx.
1085 INDEX : Check if this rtx is valid to be a index for address.
1086 STRICT : If it is true, we are in reload pass or after reload pass. */
1087static bool
ef4bddc2 1088nds32_legitimate_index_p (machine_mode outer_mode,
9304f876
CJW
1089 rtx index,
1090 bool strict)
1091{
1092 int regno;
1093 rtx op0;
1094 rtx op1;
1095
1096 switch (GET_CODE (index))
1097 {
1098 case REG:
1099 regno = REGNO (index);
1100 /* If we are in reload pass or after reload pass,
1101 we need to limit it to general register. */
1102 if (strict)
1103 return REGNO_OK_FOR_INDEX_P (regno);
1104 else
1105 return true;
1106
1107 case CONST_INT:
1108 /* The alignment of the integer value is determined by 'outer_mode'. */
1109 if (GET_MODE_SIZE (outer_mode) == 1)
1110 {
1111 /* Further check if the value is legal for the 'outer_mode'. */
1112 if (!satisfies_constraint_Is15 (index))
1113 return false;
1114
1115 /* Pass all test, the value is valid, return true. */
1116 return true;
1117 }
1118 if (GET_MODE_SIZE (outer_mode) == 2
1119 && NDS32_HALF_WORD_ALIGN_P (INTVAL (index)))
1120 {
1121 /* Further check if the value is legal for the 'outer_mode'. */
1122 if (!satisfies_constraint_Is16 (index))
1123 return false;
1124
1125 /* Pass all test, the value is valid, return true. */
1126 return true;
1127 }
1128 if (GET_MODE_SIZE (outer_mode) == 4
1129 && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index)))
1130 {
1131 /* Further check if the value is legal for the 'outer_mode'. */
1132 if (!satisfies_constraint_Is17 (index))
1133 return false;
1134
1135 /* Pass all test, the value is valid, return true. */
1136 return true;
1137 }
1138 if (GET_MODE_SIZE (outer_mode) == 8
1139 && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index)))
1140 {
1141 /* Further check if the value is legal for the 'outer_mode'. */
1142 if (!satisfies_constraint_Is17 (gen_int_mode (INTVAL (index) + 4,
1143 SImode)))
1144 return false;
1145
1146 /* Pass all test, the value is valid, return true. */
1147 return true;
1148 }
1149
1150 return false;
1151
1152 case MULT:
1153 op0 = XEXP (index, 0);
1154 op1 = XEXP (index, 1);
1155
1156 if (REG_P (op0) && CONST_INT_P (op1))
1157 {
1158 int multiplier;
1159 multiplier = INTVAL (op1);
1160
1161 /* We only allow (mult reg const_int_1)
1162 or (mult reg const_int_2) or (mult reg const_int_4). */
1163 if (multiplier != 1 && multiplier != 2 && multiplier != 4)
1164 return false;
1165
1166 regno = REGNO (op0);
1167 /* Limit it in general registers if we are
1168 in reload pass or after reload pass. */
1169 if(strict)
1170 return REGNO_OK_FOR_INDEX_P (regno);
1171 else
1172 return true;
1173 }
1174
1175 return false;
1176
1177 case ASHIFT:
1178 op0 = XEXP (index, 0);
1179 op1 = XEXP (index, 1);
1180
1181 if (REG_P (op0) && CONST_INT_P (op1))
1182 {
1183 int sv;
1184 /* op1 is already the sv value for use to do left shift. */
1185 sv = INTVAL (op1);
1186
1187 /* We only allow (ashift reg const_int_0)
1188 or (ashift reg const_int_1) or (ashift reg const_int_2). */
1189 if (sv != 0 && sv != 1 && sv !=2)
1190 return false;
1191
1192 regno = REGNO (op0);
1193 /* Limit it in general registers if we are
1194 in reload pass or after reload pass. */
1195 if(strict)
1196 return REGNO_OK_FOR_INDEX_P (regno);
1197 else
1198 return true;
1199 }
1200
1201 return false;
1202
1203 default:
1204 return false;
1205 }
1206}
1207
9304f876
CJW
1208/* ------------------------------------------------------------------------ */
1209
1210/* PART 3: Implement target hook stuff definitions. */
1211\f
1212/* Register Classes. */
1213
1214static unsigned char
1215nds32_class_max_nregs (reg_class_t rclass ATTRIBUTE_UNUSED,
ef4bddc2 1216 machine_mode mode)
9304f876
CJW
1217{
1218 /* Return the maximum number of consecutive registers
1219 needed to represent "mode" in a register of "rclass". */
1220 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1221}
1222
1223static int
1224nds32_register_priority (int hard_regno)
1225{
1226 /* Encourage to use r0-r7 for LRA when optimize for size. */
1227 if (optimize_size && hard_regno < 8)
1228 return 4;
1229 return 3;
1230}
1231
1232\f
1233/* Stack Layout and Calling Conventions. */
1234
1235/* There are three kinds of pointer concepts using in GCC compiler:
1236
1237 frame pointer: A pointer to the first location of local variables.
1238 stack pointer: A pointer to the top of a stack frame.
1239 argument pointer: A pointer to the incoming arguments.
1240
1241 In nds32 target calling convention, we are using 8-byte alignment.
1242 Besides, we would like to have each stack frame of a function includes:
1243
1244 [Block A]
1245 1. previous hard frame pointer
1246 2. return address
1247 3. callee-saved registers
1248 4. <padding bytes> (we will calculte in nds32_compute_stack_frame()
1249 and save it at
1250 cfun->machine->callee_saved_area_padding_bytes)
1251
1252 [Block B]
1253 1. local variables
1254 2. spilling location
1255 3. <padding bytes> (it will be calculated by GCC itself)
1256 4. incoming arguments
1257 5. <padding bytes> (it will be calculated by GCC itself)
1258
1259 [Block C]
1260 1. <padding bytes> (it will be calculated by GCC itself)
1261 2. outgoing arguments
1262
1263 We 'wrap' these blocks together with
1264 hard frame pointer ($r28) and stack pointer ($r31).
1265 By applying the basic frame/stack/argument pointers concept,
1266 the layout of a stack frame shoule be like this:
1267
1268 | |
1269 old stack pointer -> ----
1270 | | \
1271 | | saved arguments for
1272 | | vararg functions
1273 | | /
1274 hard frame pointer -> --
1275 & argument pointer | | \
1276 | | previous hardware frame pointer
1277 | | return address
1278 | | callee-saved registers
1279 | | /
1280 frame pointer -> --
1281 | | \
1282 | | local variables
1283 | | and incoming arguments
1284 | | /
1285 --
1286 | | \
1287 | | outgoing
1288 | | arguments
1289 | | /
1290 stack pointer -> ----
1291
1292 $SFP and $AP are used to represent frame pointer and arguments pointer,
1293 which will be both eliminated as hard frame pointer. */
1294
1295/* -- Eliminating Frame Pointer and Arg Pointer. */
1296
19ac960a
CJW
1297static bool
1298nds32_can_eliminate (const int from_reg, const int to_reg)
9304f876
CJW
1299{
1300 if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
1301 return true;
1302
1303 if (from_reg == ARG_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM)
1304 return true;
1305
1306 if (from_reg == FRAME_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
1307 return true;
1308
1309 if (from_reg == FRAME_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM)
1310 return true;
1311
1312 return false;
1313}
1314
1315/* -- Passing Arguments in Registers. */
1316
1317static rtx
ef4bddc2 1318nds32_function_arg (cumulative_args_t ca, machine_mode mode,
9304f876
CJW
1319 const_tree type, bool named)
1320{
7f6cd86b 1321 unsigned int regno;
9304f876
CJW
1322 CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
1323
1324 /* The last time this hook is called,
1325 it is called with MODE == VOIDmode. */
1326 if (mode == VOIDmode)
1327 return NULL_RTX;
1328
7f6cd86b 1329 /* For nameless arguments, we need to take care it individually. */
9304f876 1330 if (!named)
9304f876 1331 {
7f6cd86b
CJW
1332 /* If we are under hard float abi, we have arguments passed on the
1333 stack and all situation can be handled by GCC itself. */
1334 if (TARGET_HARD_FLOAT)
1335 return NULL_RTX;
1336
1337 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum->gpr_offset, mode, type))
1338 {
1339 /* If we still have enough registers to pass argument, pick up
1340 next available register number. */
1341 regno
1342 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type);
1343 return gen_rtx_REG (mode, regno);
1344 }
634bdae9 1345
9304f876
CJW
1346 /* No register available, return NULL_RTX.
1347 The compiler will use stack to pass argument instead. */
1348 return NULL_RTX;
1349 }
7f6cd86b
CJW
1350
1351 /* The following is to handle named argument.
1352 Note that the strategies of TARGET_HARD_FLOAT and !TARGET_HARD_FLOAT
1353 are different. */
1354 if (TARGET_HARD_FLOAT)
1355 {
1356 /* Currently we have not implemented hard float yet. */
1357 gcc_unreachable ();
1358 }
1359 else
1360 {
1361 /* For !TARGET_HARD_FLOAT calling convention, we always use GPR to pass
1362 argument. Since we allow to pass argument partially in registers,
1363 we can just return it if there are still registers available. */
1364 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum->gpr_offset, mode, type))
1365 {
1366 /* Pick up the next available register number. */
1367 regno
1368 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type);
1369 return gen_rtx_REG (mode, regno);
1370 }
1371
1372 }
1373
1374 /* No register available, return NULL_RTX.
1375 The compiler will use stack to pass argument instead. */
1376 return NULL_RTX;
9304f876
CJW
1377}
1378
d40f3c40 1379static bool
ef4bddc2 1380nds32_must_pass_in_stack (machine_mode mode, const_tree type)
d40f3c40
CJW
1381{
1382 /* Return true if a type must be passed in memory.
1383 If it is NOT using hard float abi, small aggregates can be
1384 passed in a register even we are calling a variadic function.
1385 So there is no need to take padding into consideration. */
1386 if (TARGET_HARD_FLOAT)
1387 return must_pass_in_stack_var_size_or_pad (mode, type);
1388 else
1389 return must_pass_in_stack_var_size (mode, type);
1390}
1391
650fc469 1392static int
ef4bddc2 1393nds32_arg_partial_bytes (cumulative_args_t ca, machine_mode mode,
650fc469
CJW
1394 tree type, bool named ATTRIBUTE_UNUSED)
1395{
1396 /* Returns the number of bytes at the beginning of an argument that
1397 must be put in registers. The value must be zero for arguments that are
1398 passed entirely in registers or that are entirely pushed on the stack.
1399 Besides, TARGET_FUNCTION_ARG for these arguments should return the
1400 first register to be used by the caller for this argument. */
1401 unsigned int needed_reg_count;
1402 unsigned int remaining_reg_count;
1403 CUMULATIVE_ARGS *cum;
1404
1405 cum = get_cumulative_args (ca);
1406
1407 /* Under hard float abi, we better have argument entirely passed in
1408 registers or pushed on the stack so that we can reduce the complexity
1409 of dealing with cum->gpr_offset and cum->fpr_offset. */
1410 if (TARGET_HARD_FLOAT)
1411 return 0;
1412
1413 /* If we have already runned out of argument registers, return zero
1414 so that the argument will be entirely pushed on the stack. */
1415 if (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1416 >= NDS32_GPR_ARG_FIRST_REGNUM + NDS32_MAX_GPR_REGS_FOR_ARGS)
1417 return 0;
1418
1419 /* Calculate how many registers do we need for this argument. */
1420 needed_reg_count = NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1421
1422 /* Calculate how many argument registers have left for passing argument.
1423 Note that we should count it from next available register number. */
1424 remaining_reg_count
1425 = NDS32_MAX_GPR_REGS_FOR_ARGS
1426 - (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1427 - NDS32_GPR_ARG_FIRST_REGNUM);
1428
1429 /* Note that we have to return the nubmer of bytes, not registers count. */
1430 if (needed_reg_count > remaining_reg_count)
1431 return remaining_reg_count * UNITS_PER_WORD;
1432
1433 return 0;
1434}
1435
9304f876 1436static void
ef4bddc2 1437nds32_function_arg_advance (cumulative_args_t ca, machine_mode mode,
9304f876
CJW
1438 const_tree type, bool named)
1439{
ef4bddc2 1440 machine_mode sub_mode;
9304f876
CJW
1441 CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
1442
9304f876
CJW
1443 if (named)
1444 {
7f6cd86b
CJW
1445 /* We need to further check TYPE and MODE so that we can determine
1446 which kind of register we shall advance. */
1447 if (type && TREE_CODE (type) == COMPLEX_TYPE)
1448 sub_mode = TYPE_MODE (TREE_TYPE (type));
1449 else
1450 sub_mode = mode;
1451
1452 /* Under hard float abi, we may advance FPR registers. */
1453 if (TARGET_HARD_FLOAT && GET_MODE_CLASS (sub_mode) == MODE_FLOAT)
1454 {
1455 /* Currently we have not implemented hard float yet. */
1456 gcc_unreachable ();
1457 }
1458 else
1459 {
1460 cum->gpr_offset
1461 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1462 - NDS32_GPR_ARG_FIRST_REGNUM
1463 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1464 }
1465 }
1466 else
1467 {
1468 /* If this nameless argument is NOT under TARGET_HARD_FLOAT,
1469 we can advance next register as well so that caller is
1470 able to pass arguments in registers and callee must be
1471 in charge of pushing all of them into stack. */
1472 if (!TARGET_HARD_FLOAT)
1473 {
1474 cum->gpr_offset
1475 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1476 - NDS32_GPR_ARG_FIRST_REGNUM
1477 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1478 }
9304f876
CJW
1479 }
1480}
1481
1482static unsigned int
ef4bddc2 1483nds32_function_arg_boundary (machine_mode mode, const_tree type)
9304f876
CJW
1484{
1485 return (nds32_needs_double_word_align (mode, type)
1486 ? NDS32_DOUBLE_WORD_ALIGNMENT
1487 : PARM_BOUNDARY);
1488}
1489
1490/* -- How Scalar Function Values Are Returned. */
1491
1492static rtx
1493nds32_function_value (const_tree ret_type,
1494 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
1495 bool outgoing ATTRIBUTE_UNUSED)
1496{
ef4bddc2 1497 machine_mode mode;
9304f876
CJW
1498 int unsignedp;
1499
1500 mode = TYPE_MODE (ret_type);
1501 unsignedp = TYPE_UNSIGNED (ret_type);
1502
1503 mode = promote_mode (ret_type, mode, &unsignedp);
1504
1505 return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM);
1506}
1507
1508static rtx
ef4bddc2 1509nds32_libcall_value (machine_mode mode,
9304f876
CJW
1510 const_rtx fun ATTRIBUTE_UNUSED)
1511{
1512 return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM);
1513}
1514
1515static bool
1516nds32_function_value_regno_p (const unsigned int regno)
1517{
1518 return (regno == NDS32_GPR_RET_FIRST_REGNUM);
1519}
1520
1521/* -- Function Entry and Exit. */
1522
1523/* The content produced from this function
1524 will be placed before prologue body. */
1525static void
1526nds32_asm_function_prologue (FILE *file,
1527 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
1528{
1529 int r;
1530 const char *func_name;
1531 tree attrs;
1532 tree name;
1533
1534 /* All stack frame information is supposed to be
1535 already computed when expanding prologue.
1536 The result is in cfun->machine.
1537 DO NOT call nds32_compute_stack_frame() here
1538 because it may corrupt the essential information. */
1539
1540 fprintf (file, "\t! BEGIN PROLOGUE\n");
1541 fprintf (file, "\t! fp needed: %d\n", frame_pointer_needed);
1542 fprintf (file, "\t! pretend_args: %d\n", cfun->machine->va_args_size);
1543 fprintf (file, "\t! local_size: %d\n", cfun->machine->local_size);
1544 fprintf (file, "\t! out_args_size: %d\n", cfun->machine->out_args_size);
1545
1546 /* Use df_regs_ever_live_p() to detect if the register
1547 is ever used in the current function. */
1548 fprintf (file, "\t! registers ever_live: ");
1549 for (r = 0; r < 32; r++)
1550 {
1551 if (df_regs_ever_live_p (r))
1552 fprintf (file, "%s, ", reg_names[r]);
1553 }
1554 fputc ('\n', file);
1555
1556 /* Display the attributes of this function. */
1557 fprintf (file, "\t! function attributes: ");
f2dafb91
CJW
1558 /* Get the attributes tree list.
1559 Note that GCC builds attributes list with reverse order. */
1560 attrs = DECL_ATTRIBUTES (current_function_decl);
9304f876
CJW
1561
1562 /* If there is no any attribute, print out "None". */
1563 if (!attrs)
1564 fprintf (file, "None");
1565
1566 /* If there are some attributes, try if we need to
1567 construct isr vector information. */
1568 func_name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
1569 nds32_construct_isr_vectors_information (attrs, func_name);
1570
1571 /* Display all attributes of this function. */
1572 while (attrs)
1573 {
1574 name = TREE_PURPOSE (attrs);
1575 fprintf (file, "%s ", IDENTIFIER_POINTER (name));
1576
1577 /* Pick up the next attribute. */
1578 attrs = TREE_CHAIN (attrs);
1579 }
1580 fputc ('\n', file);
1581}
1582
1583/* After rtl prologue has been expanded, this function is used. */
1584static void
1585nds32_asm_function_end_prologue (FILE *file)
1586{
1587 fprintf (file, "\t! END PROLOGUE\n");
1588
1589 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
1590 we can generate special directive: ".omit_fp_begin"
1591 to guide linker doing fp-as-gp optimization.
1592 However, for a naked function, which means
1593 it should not have prologue/epilogue,
1594 using fp-as-gp still requires saving $fp by push/pop behavior and
1595 there is no benefit to use fp-as-gp on such small function.
1596 So we need to make sure this function is NOT naked as well. */
1597 if (!frame_pointer_needed
1598 && !cfun->machine->naked_p
1599 && cfun->machine->fp_as_gp_p)
1600 {
1601 fprintf (file, "\t! ----------------------------------------\n");
1602 fprintf (file, "\t! Guide linker to do "
1603 "link time optimization: fp-as-gp\n");
1604 fprintf (file, "\t! We add one more instruction to "
1605 "initialize $fp near to $gp location.\n");
1606 fprintf (file, "\t! If linker fails to use fp-as-gp transformation,\n");
1607 fprintf (file, "\t! this extra instruction should be "
1608 "eliminated at link stage.\n");
1609 fprintf (file, "\t.omit_fp_begin\n");
1610 fprintf (file, "\tla\t$fp,_FP_BASE_\n");
1611 fprintf (file, "\t! ----------------------------------------\n");
1612 }
1613}
1614
1615/* Before rtl epilogue has been expanded, this function is used. */
1616static void
1617nds32_asm_function_begin_epilogue (FILE *file)
1618{
1619 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
1620 we can generate special directive: ".omit_fp_end"
1621 to claim fp-as-gp optimization range.
1622 However, for a naked function,
1623 which means it should not have prologue/epilogue,
1624 using fp-as-gp still requires saving $fp by push/pop behavior and
1625 there is no benefit to use fp-as-gp on such small function.
1626 So we need to make sure this function is NOT naked as well. */
1627 if (!frame_pointer_needed
1628 && !cfun->machine->naked_p
1629 && cfun->machine->fp_as_gp_p)
1630 {
1631 fprintf (file, "\t! ----------------------------------------\n");
1632 fprintf (file, "\t! Claim the range of fp-as-gp "
1633 "link time optimization\n");
1634 fprintf (file, "\t.omit_fp_end\n");
1635 fprintf (file, "\t! ----------------------------------------\n");
1636 }
1637
1638 fprintf (file, "\t! BEGIN EPILOGUE\n");
1639}
1640
1641/* The content produced from this function
1642 will be placed after epilogue body. */
1643static void
1644nds32_asm_function_epilogue (FILE *file,
1645 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
1646{
1647 fprintf (file, "\t! END EPILOGUE\n");
1648}
1649
1650static void
1651nds32_asm_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
1652 HOST_WIDE_INT delta,
1653 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
1654 tree function)
1655{
1656 int this_regno;
1657
1658 /* Make sure unwind info is emitted for the thunk if needed. */
1659 final_start_function (emit_barrier (), file, 1);
1660
1661 this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function)
1662 ? 1
1663 : 0);
1664
1665 if (delta != 0)
1666 {
1667 if (satisfies_constraint_Is15 (GEN_INT (delta)))
1668 {
1669 fprintf (file, "\taddi\t$r%d, $r%d, %ld\n",
1670 this_regno, this_regno, delta);
1671 }
1672 else if (satisfies_constraint_Is20 (GEN_INT (delta)))
1673 {
1674 fprintf (file, "\tmovi\t$ta, %ld\n", delta);
1675 fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno);
1676 }
1677 else
1678 {
1679 fprintf (file, "\tsethi\t$ta, hi20(%ld)\n", delta);
1680 fprintf (file, "\tori\t$ta, $ta, lo12(%ld)\n", delta);
1681 fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno);
1682 }
1683 }
1684
1685 fprintf (file, "\tb\t");
1686 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
1687 fprintf (file, "\n");
1688
1689 final_end_function ();
1690}
1691
1692/* -- Permitting tail calls. */
1693
1694/* Determine whether we need to enable warning for function return check. */
1695static bool
1696nds32_warn_func_return (tree decl)
1697{
1698/* Naked functions are implemented entirely in assembly, including the
1699 return sequence, so suppress warnings about this. */
1700 return !nds32_naked_function_p (decl);
1701}
1702
1703\f
1704/* Implementing the Varargs Macros. */
1705
d4a6a4d9
CJW
1706static void
1707nds32_setup_incoming_varargs (cumulative_args_t ca,
ef4bddc2 1708 machine_mode mode,
d4a6a4d9
CJW
1709 tree type,
1710 int *pretend_args_size,
1711 int second_time ATTRIBUTE_UNUSED)
1712{
1713 unsigned int total_args_regs;
1714 unsigned int num_of_used_regs;
1715 unsigned int remaining_reg_count;
1716 CUMULATIVE_ARGS *cum;
1717
1718 /* If we are under hard float abi, we do not need to set *pretend_args_size.
1719 So that all nameless arguments are pushed by caller and all situation
1720 can be handled by GCC itself. */
1721 if (TARGET_HARD_FLOAT)
1722 return;
1723
1724 /* We are using NDS32_MAX_GPR_REGS_FOR_ARGS registers,
1725 counting from NDS32_GPR_ARG_FIRST_REGNUM, for saving incoming arguments.
1726 However, for nameless(anonymous) arguments, we should push them on the
1727 stack so that all the nameless arguments appear to have been passed
1728 consecutively in the memory for accessing. Hence, we need to check and
1729 exclude the registers that are used for named arguments. */
1730
1731 cum = get_cumulative_args (ca);
1732
1733 /* The MODE and TYPE describe the last argument.
1734 We need those information to determine the remaining registers
1735 for varargs. */
1736 total_args_regs
1737 = NDS32_MAX_GPR_REGS_FOR_ARGS + NDS32_GPR_ARG_FIRST_REGNUM;
1738 num_of_used_regs
1739 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1740 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1741
1742 remaining_reg_count = total_args_regs - num_of_used_regs;
1743 *pretend_args_size = remaining_reg_count * UNITS_PER_WORD;
1744
1745 return;
1746}
1747
9304f876
CJW
1748static bool
1749nds32_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED)
1750{
d4a6a4d9
CJW
1751 /* If this hook returns true, the named argument of FUNCTION_ARG is always
1752 true for named arguments, and false for unnamed arguments. */
9304f876
CJW
1753 return true;
1754}
1755
1756\f
1757/* Trampolines for Nested Functions. */
1758
1759static void
1760nds32_asm_trampoline_template (FILE *f)
1761{
1762 if (TARGET_REDUCED_REGS)
1763 {
1764 /* Trampoline is not supported on reduced-set registers yet. */
1765 sorry ("a nested function is not supported for reduced registers");
1766 }
1767 else
1768 {
1769 asm_fprintf (f, "\t! Trampoline code template\n");
1770 asm_fprintf (f, "\t! This code fragment will be copied "
1771 "into stack on demand\n");
1772
1773 asm_fprintf (f, "\tmfusr\t$r16,$pc\n");
1774 asm_fprintf (f, "\tlwi\t$r15,[$r16 + 20] "
1775 "! load nested function address\n");
1776 asm_fprintf (f, "\tlwi\t$r16,[$r16 + 16] "
1777 "! load chain_value\n");
1778 asm_fprintf (f, "\tjr\t$r15\n");
1779 }
1780
1781 /* Preserve space ($pc + 16) for saving chain_value,
1782 nds32_trampoline_init will fill the value in this slot. */
1783 asm_fprintf (f, "\t! space for saving chain_value\n");
1784 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
1785
1786 /* Preserve space ($pc + 20) for saving nested function address,
1787 nds32_trampoline_init will fill the value in this slot. */
1788 asm_fprintf (f, "\t! space for saving nested function address\n");
1789 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
1790}
1791
1792/* Emit RTL insns to initialize the variable parts of a trampoline. */
1793static void
1794nds32_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
1795{
1796 int i;
1797
1798 /* Nested function address. */
1799 rtx fnaddr;
1800 /* The memory rtx that is going to
1801 be filled with chain_value. */
1802 rtx chain_value_mem;
1803 /* The memory rtx that is going to
1804 be filled with nested function address. */
1805 rtx nested_func_mem;
1806
1807 /* Start address of trampoline code in stack, for doing cache sync. */
1808 rtx sync_cache_addr;
1809 /* Temporary register for sync instruction. */
1810 rtx tmp_reg;
1811 /* Instruction-cache sync instruction,
1812 requesting an argument as starting address. */
1813 rtx isync_insn;
1814 /* For convenience reason of doing comparison. */
1815 int tramp_align_in_bytes;
1816
1817 /* Trampoline is not supported on reduced-set registers yet. */
1818 if (TARGET_REDUCED_REGS)
1819 sorry ("a nested function is not supported for reduced registers");
1820
1821 /* STEP 1: Copy trampoline code template into stack,
1822 fill up essential data into stack. */
1823
1824 /* Extract nested function address rtx. */
1825 fnaddr = XEXP (DECL_RTL (fndecl), 0);
1826
1827 /* m_tramp is memory rtx that is going to be filled with trampoline code.
1828 We have nds32_asm_trampoline_template() to emit template pattern. */
1829 emit_block_move (m_tramp, assemble_trampoline_template (),
1830 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
1831
1832 /* After copying trampoline code into stack,
1833 fill chain_value into stack. */
1834 chain_value_mem = adjust_address (m_tramp, SImode, 16);
1835 emit_move_insn (chain_value_mem, chain_value);
1836 /* After copying trampoline code int stack,
1837 fill nested function address into stack. */
1838 nested_func_mem = adjust_address (m_tramp, SImode, 20);
1839 emit_move_insn (nested_func_mem, fnaddr);
1840
1841 /* STEP 2: Sync instruction-cache. */
1842
1843 /* We have successfully filled trampoline code into stack.
1844 However, in order to execute code in stack correctly,
1845 we must sync instruction cache. */
1846 sync_cache_addr = XEXP (m_tramp, 0);
1847 tmp_reg = gen_reg_rtx (SImode);
1848 isync_insn = gen_unspec_volatile_isync (tmp_reg);
1849
1850 /* Because nds32_cache_block_size is in bytes,
1851 we get trampoline alignment in bytes for convenient comparison. */
1852 tramp_align_in_bytes = TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT;
1853
1854 if (tramp_align_in_bytes >= nds32_cache_block_size
1855 && (tramp_align_in_bytes % nds32_cache_block_size) == 0)
1856 {
1857 /* Under this condition, the starting address of trampoline
1858 must be aligned to the starting address of each cache block
1859 and we do not have to worry about cross-boundary issue. */
1860 for (i = 0;
1861 i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1)
1862 / nds32_cache_block_size;
1863 i++)
1864 {
1865 emit_move_insn (tmp_reg,
1866 plus_constant (Pmode, sync_cache_addr,
1867 nds32_cache_block_size * i));
1868 emit_insn (isync_insn);
1869 }
1870 }
1871 else if (TRAMPOLINE_SIZE > nds32_cache_block_size)
1872 {
1873 /* The starting address of trampoline code
1874 may not be aligned to the cache block,
1875 so the trampoline code may be across two cache block.
1876 We need to sync the last element, which is 4-byte size,
1877 of trampoline template. */
1878 for (i = 0;
1879 i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1)
1880 / nds32_cache_block_size;
1881 i++)
1882 {
1883 emit_move_insn (tmp_reg,
1884 plus_constant (Pmode, sync_cache_addr,
1885 nds32_cache_block_size * i));
1886 emit_insn (isync_insn);
1887 }
1888
1889 /* The last element of trampoline template is 4-byte size. */
1890 emit_move_insn (tmp_reg,
1891 plus_constant (Pmode, sync_cache_addr,
1892 TRAMPOLINE_SIZE - 4));
1893 emit_insn (isync_insn);
1894 }
1895 else
1896 {
1897 /* This is the simplest case.
1898 Because TRAMPOLINE_SIZE is less than or
1899 equal to nds32_cache_block_size,
1900 we can just sync start address and
1901 the last element of trampoline code. */
1902
1903 /* Sync starting address of tampoline code. */
1904 emit_move_insn (tmp_reg, sync_cache_addr);
1905 emit_insn (isync_insn);
1906 /* Sync the last element, which is 4-byte size,
1907 of trampoline template. */
1908 emit_move_insn (tmp_reg,
1909 plus_constant (Pmode, sync_cache_addr,
1910 TRAMPOLINE_SIZE - 4));
1911 emit_insn (isync_insn);
1912 }
1913
1914 /* Set instruction serialization barrier
1915 to guarantee the correct operations. */
1916 emit_insn (gen_unspec_volatile_isb ());
1917}
1918
1919\f
1920/* Addressing Modes. */
1921
1922static bool
ef4bddc2 1923nds32_legitimate_address_p (machine_mode mode, rtx x, bool strict)
9304f876
CJW
1924{
1925 /* For (mem:DI addr) or (mem:DF addr) case,
1926 we only allow 'addr' to be [reg], [symbol_ref],
1927 [const], or [reg + const_int] pattern. */
1928 if (mode == DImode || mode == DFmode)
1929 {
1930 /* Allow [Reg + const_int] addressing mode. */
1931 if (GET_CODE (x) == PLUS)
1932 {
1933 if (nds32_address_register_rtx_p (XEXP (x, 0), strict)
1934 && nds32_legitimate_index_p (mode, XEXP (x, 1), strict)
1935 && CONST_INT_P (XEXP (x, 1)))
1936 return true;
1937
1938 else if (nds32_address_register_rtx_p (XEXP (x, 1), strict)
1939 && nds32_legitimate_index_p (mode, XEXP (x, 0), strict)
1940 && CONST_INT_P (XEXP (x, 0)))
1941 return true;
1942 }
1943
1944 /* Now check [reg], [symbol_ref], and [const]. */
1945 if (GET_CODE (x) != REG
1946 && GET_CODE (x) != SYMBOL_REF
1947 && GET_CODE (x) != CONST)
1948 return false;
1949 }
1950
1951 /* Check if 'x' is a valid address. */
1952 switch (GET_CODE (x))
1953 {
1954 case REG:
1955 /* (mem (reg A)) => [Ra] */
1956 return nds32_address_register_rtx_p (x, strict);
1957
1958 case SYMBOL_REF:
1959
1960 if (!TARGET_GP_DIRECT
1961 && (reload_completed
1962 || reload_in_progress
1963 || lra_in_progress))
1964 return false;
1965
1966 /* (mem (symbol_ref A)) => [symbol_ref] */
1967 return !currently_expanding_to_rtl;
1968
1969 case CONST:
1970
1971 if (!TARGET_GP_DIRECT
1972 && (reload_completed
1973 || reload_in_progress
1974 || lra_in_progress))
1975 return false;
1976
1977 /* (mem (const (...)))
1978 => [ + const_addr ], where const_addr = symbol_ref + const_int */
1979 if (GET_CODE (XEXP (x, 0)) == PLUS)
1980 {
1981 rtx plus_op = XEXP (x, 0);
1982
1983 rtx op0 = XEXP (plus_op, 0);
1984 rtx op1 = XEXP (plus_op, 1);
1985
1986 if (GET_CODE (op0) == SYMBOL_REF && CONST_INT_P (op1))
1987 return true;
1988 else
1989 return false;
1990 }
1991
1992 return false;
1993
1994 case POST_MODIFY:
1995 /* (mem (post_modify (reg) (plus (reg) (reg))))
1996 => [Ra], Rb */
1997 /* (mem (post_modify (reg) (plus (reg) (const_int))))
1998 => [Ra], const_int */
1999 if (GET_CODE (XEXP (x, 0)) == REG
2000 && GET_CODE (XEXP (x, 1)) == PLUS)
2001 {
2002 rtx plus_op = XEXP (x, 1);
2003
2004 rtx op0 = XEXP (plus_op, 0);
2005 rtx op1 = XEXP (plus_op, 1);
2006
2007 if (nds32_address_register_rtx_p (op0, strict)
2008 && nds32_legitimate_index_p (mode, op1, strict))
2009 return true;
2010 else
2011 return false;
2012 }
2013
2014 return false;
2015
2016 case POST_INC:
2017 case POST_DEC:
2018 /* (mem (post_inc reg)) => [Ra], 1/2/4 */
2019 /* (mem (post_dec reg)) => [Ra], -1/-2/-4 */
2020 /* The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
2021 We only need to deal with register Ra. */
2022 if (nds32_address_register_rtx_p (XEXP (x, 0), strict))
2023 return true;
2024 else
2025 return false;
2026
2027 case PLUS:
2028 /* (mem (plus reg const_int))
2029 => [Ra + imm] */
2030 /* (mem (plus reg reg))
2031 => [Ra + Rb] */
2032 /* (mem (plus (mult reg const_int) reg))
2033 => [Ra + Rb << sv] */
2034 if (nds32_address_register_rtx_p (XEXP (x, 0), strict)
2035 && nds32_legitimate_index_p (mode, XEXP (x, 1), strict))
2036 return true;
2037 else if (nds32_address_register_rtx_p (XEXP (x, 1), strict)
2038 && nds32_legitimate_index_p (mode, XEXP (x, 0), strict))
2039 return true;
2040 else
2041 return false;
2042
2043 case LO_SUM:
34425025
CJW
2044 /* (mem (lo_sum (reg) (symbol_ref))) */
2045 /* (mem (lo_sum (reg) (const))) */
2046 gcc_assert (REG_P (XEXP (x, 0)));
2047 if (GET_CODE (XEXP (x, 1)) == SYMBOL_REF
2048 || GET_CODE (XEXP (x, 1)) == CONST)
2049 return nds32_legitimate_address_p (mode, XEXP (x, 1), strict);
2050 else
2051 return false;
9304f876
CJW
2052
2053 default:
2054 return false;
2055 }
2056}
2057
2058\f
2059/* Describing Relative Costs of Operations. */
2060
19ac960a 2061static int
ef4bddc2 2062nds32_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
19ac960a
CJW
2063 reg_class_t from,
2064 reg_class_t to)
9304f876
CJW
2065{
2066 if (from == HIGH_REGS || to == HIGH_REGS)
2067 return 6;
2068
2069 return 2;
2070}
2071
19ac960a 2072static int
ef4bddc2 2073nds32_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
19ac960a
CJW
2074 reg_class_t rclass ATTRIBUTE_UNUSED,
2075 bool in ATTRIBUTE_UNUSED)
9304f876
CJW
2076{
2077 return 8;
2078}
2079
2080/* This target hook describes the relative costs of RTL expressions.
2081 Return 'true' when all subexpressions of x have been processed.
2082 Return 'false' to sum the costs of sub-rtx, plus cost of this operation.
2083 Refer to gcc/rtlanal.c for more information. */
2084static bool
2085nds32_rtx_costs (rtx x,
2086 int code,
2087 int outer_code,
89a4b547 2088 int opno,
9304f876
CJW
2089 int *total,
2090 bool speed)
2091{
89a4b547 2092 return nds32_rtx_costs_impl (x, code, outer_code, opno, total, speed);
9304f876
CJW
2093}
2094
19ac960a
CJW
2095static int
2096nds32_address_cost (rtx address,
ef4bddc2 2097 machine_mode mode,
19ac960a
CJW
2098 addr_space_t as,
2099 bool speed)
9304f876 2100{
89a4b547 2101 return nds32_address_cost_impl (address, mode, as, speed);
9304f876
CJW
2102}
2103
2104\f
2105/* Defining the Output Assembler Language. */
2106
2107/* -- The Overall Framework of an Assembler File. */
2108
2109static void
2110nds32_asm_file_start (void)
2111{
9304f876
CJW
2112 default_file_start ();
2113
2114 /* Tell assembler which ABI we are using. */
2115 fprintf (asm_out_file, "\t! ABI version\n");
2116 fprintf (asm_out_file, "\t.abi_2\n");
2117
2118 /* Tell assembler that this asm code is generated by compiler. */
2119 fprintf (asm_out_file, "\t! This asm file is generated by compiler\n");
2120 fprintf (asm_out_file, "\t.flag\tverbatim\n");
2121 /* Give assembler the size of each vector for interrupt handler. */
2122 fprintf (asm_out_file, "\t! This vector size directive is required "
2123 "for checking inconsistency on interrupt handler\n");
2124 fprintf (asm_out_file, "\t.vec_size\t%d\n", nds32_isr_vector_size);
2125
2126 /* If user enables '-mforce-fp-as-gp' or compiles programs with -Os,
2127 the compiler may produce 'la $fp,_FP_BASE_' instruction
2128 at prologue for fp-as-gp optimization.
2129 We should emit weak reference of _FP_BASE_ to avoid undefined reference
2130 in case user does not pass '--relax' option to linker. */
2131 if (TARGET_FORCE_FP_AS_GP || optimize_size)
2132 {
2133 fprintf (asm_out_file, "\t! This weak reference is required to do "
2134 "fp-as-gp link time optimization\n");
2135 fprintf (asm_out_file, "\t.weak\t_FP_BASE_\n");
2136 }
2137 /* If user enables '-mex9', we should emit relaxation directive
2138 to tell linker that this file is allowed to do ex9 optimization. */
2139 if (TARGET_EX9)
2140 {
2141 fprintf (asm_out_file, "\t! This relaxation directive is required "
2142 "to do ex9 link time optimization\n");
2143 fprintf (asm_out_file, "\t.relax\tex9\n");
2144 }
2145
2146 fprintf (asm_out_file, "\t! ------------------------------------\n");
2147
2148 if (TARGET_ISA_V2)
2149 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V2");
2150 if (TARGET_ISA_V3)
2151 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3");
2152 if (TARGET_ISA_V3M)
2153 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3M");
2154
2155 fprintf (asm_out_file, "\t! Endian setting\t: %s\n",
2156 ((TARGET_BIG_ENDIAN) ? "big-endian"
2157 : "little-endian"));
2158
2159 fprintf (asm_out_file, "\t! ------------------------------------\n");
2160
2161 fprintf (asm_out_file, "\t! Use conditional move\t\t: %s\n",
2162 ((TARGET_CMOV) ? "Yes"
2163 : "No"));
2164 fprintf (asm_out_file, "\t! Use performance extension\t: %s\n",
2165 ((TARGET_PERF_EXT) ? "Yes"
2166 : "No"));
2167
2168 fprintf (asm_out_file, "\t! ------------------------------------\n");
2169
2170 fprintf (asm_out_file, "\t! V3PUSH instructions\t: %s\n",
2171 ((TARGET_V3PUSH) ? "Yes"
2172 : "No"));
2173 fprintf (asm_out_file, "\t! 16-bit instructions\t: %s\n",
2174 ((TARGET_16_BIT) ? "Yes"
2175 : "No"));
2176 fprintf (asm_out_file, "\t! GP base access\t: %s\n",
2177 ((TARGET_GP_DIRECT) ? "Yes"
2178 : "No"));
2179 fprintf (asm_out_file, "\t! Reduced registers set\t: %s\n",
2180 ((TARGET_REDUCED_REGS) ? "Yes"
2181 : "No"));
2182
2183 fprintf (asm_out_file, "\t! ------------------------------------\n");
2184
2185 if (optimize_size)
2186 fprintf (asm_out_file, "\t! Optimization level\t: -Os\n");
2187 else
2188 fprintf (asm_out_file, "\t! Optimization level\t: -O%d\n", optimize);
2189
2190 fprintf (asm_out_file, "\t! ------------------------------------\n");
2191
2192 fprintf (asm_out_file, "\t! Cache block size\t: %d\n",
2193 nds32_cache_block_size);
2194
2195 fprintf (asm_out_file, "\t! ------------------------------------\n");
2196
c23a919b 2197 nds32_asm_file_start_for_isr ();
9304f876
CJW
2198}
2199
2200static void
2201nds32_asm_file_end (void)
2202{
c23a919b 2203 nds32_asm_file_end_for_isr ();
9304f876
CJW
2204
2205 fprintf (asm_out_file, "\t! ------------------------------------\n");
2206}
2207
2208/* -- Output and Generation of Labels. */
2209
2210static void
2211nds32_asm_globalize_label (FILE *stream, const char *name)
2212{
2213 fputs ("\t.global\t", stream);
2214 assemble_name (stream, name);
2215 fputs ("\n", stream);
2216}
2217
2218/* -- Output of Assembler Instructions. */
2219
2220static void
2221nds32_print_operand (FILE *stream, rtx x, int code)
2222{
2223 int op_value;
2224
2225 switch (code)
2226 {
2227 case 0 :
2228 /* Do nothing special. */
2229 break;
2230
2231 case 'V':
2232 /* 'x' is supposed to be CONST_INT, get the value. */
2233 gcc_assert (CONST_INT_P (x));
2234 op_value = INTVAL (x);
2235
2236 /* According to the Andes architecture,
2237 the system/user register index range is 0 ~ 1023.
2238 In order to avoid conflict between user-specified-integer value
2239 and enum-specified-register value,
2240 the 'enum nds32_intrinsic_registers' value
2241 in nds32_intrinsic.h starts from 1024. */
2242 if (op_value < 1024 && op_value >= 0)
2243 {
2244 /* If user gives integer value directly (0~1023),
2245 we just print out the value. */
2246 fprintf (stream, "%d", op_value);
2247 }
2248 else if (op_value < 0
2249 || op_value >= ((int) ARRAY_SIZE (nds32_intrinsic_register_names)
2250 + 1024))
2251 {
2252 /* The enum index value for array size is out of range. */
2253 error ("intrinsic register index is out of range");
2254 }
2255 else
2256 {
2257 /* If user applies normal way with __NDS32_REG_XXX__ enum data,
2258 we can print out register name. Remember to substract 1024. */
2259 fprintf (stream, "%s",
2260 nds32_intrinsic_register_names[op_value - 1024]);
2261 }
2262
2263 /* No need to handle following process, so return immediately. */
2264 return;
2265
2266 default :
2267 /* Unknown flag. */
2268 output_operand_lossage ("invalid operand output code");
2269 break;
2270 }
2271
2272 switch (GET_CODE (x))
2273 {
2274 case LABEL_REF:
2275 case SYMBOL_REF:
2276 output_addr_const (stream, x);
2277 break;
2278
2279 case REG:
2280 /* Forbid using static chain register ($r16)
2281 on reduced-set registers configuration. */
2282 if (TARGET_REDUCED_REGS
2283 && REGNO (x) == STATIC_CHAIN_REGNUM)
2284 sorry ("a nested function is not supported for reduced registers");
2285
2286 /* Normal cases, print out register name. */
2287 fputs (reg_names[REGNO (x)], stream);
2288 break;
2289
2290 case MEM:
2291 output_address (XEXP (x, 0));
2292 break;
2293
2294 case CODE_LABEL:
2295 case CONST_INT:
2296 case CONST:
2297 output_addr_const (stream, x);
2298 break;
2299
2300 default:
2301 /* Generally, output_addr_const () is able to handle most cases.
2302 We want to see what CODE could appear,
2303 so we use gcc_unreachable() to stop it. */
2304 debug_rtx (x);
2305 gcc_unreachable ();
2306 break;
2307 }
2308}
2309
2310static void
2311nds32_print_operand_address (FILE *stream, rtx x)
2312{
2313 rtx op0, op1;
2314
2315 switch (GET_CODE (x))
2316 {
2317 case SYMBOL_REF:
2318 case CONST:
2319 /* [ + symbol_ref] */
2320 /* [ + const_addr], where const_addr = symbol_ref + const_int */
2321 fputs ("[ + ", stream);
2322 output_addr_const (stream, x);
2323 fputs ("]", stream);
2324 break;
2325
2326 case REG:
2327 /* Forbid using static chain register ($r16)
2328 on reduced-set registers configuration. */
2329 if (TARGET_REDUCED_REGS
2330 && REGNO (x) == STATIC_CHAIN_REGNUM)
2331 sorry ("a nested function is not supported for reduced registers");
2332
2333 /* [Ra] */
2334 fprintf (stream, "[%s]", reg_names[REGNO (x)]);
2335 break;
2336
2337 case PLUS:
2338 op0 = XEXP (x, 0);
2339 op1 = XEXP (x, 1);
2340
2341 /* Checking op0, forbid using static chain register ($r16)
2342 on reduced-set registers configuration. */
2343 if (TARGET_REDUCED_REGS
2344 && REG_P (op0)
2345 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2346 sorry ("a nested function is not supported for reduced registers");
2347 /* Checking op1, forbid using static chain register ($r16)
2348 on reduced-set registers configuration. */
2349 if (TARGET_REDUCED_REGS
2350 && REG_P (op1)
2351 && REGNO (op1) == STATIC_CHAIN_REGNUM)
2352 sorry ("a nested function is not supported for reduced registers");
2353
2354 if (REG_P (op0) && CONST_INT_P (op1))
2355 {
2356 /* [Ra + imm] */
2357 fprintf (stream, "[%s + (%d)]",
2358 reg_names[REGNO (op0)], (int)INTVAL (op1));
2359 }
2360 else if (REG_P (op0) && REG_P (op1))
2361 {
2362 /* [Ra + Rb] */
2363 fprintf (stream, "[%s + %s]",
2364 reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
2365 }
2366 else if (GET_CODE (op0) == MULT && REG_P (op1))
2367 {
2368 /* [Ra + Rb << sv]
2369 From observation, the pattern looks like:
2370 (plus:SI (mult:SI (reg:SI 58)
2371 (const_int 4 [0x4]))
2372 (reg/f:SI 57)) */
2373 int sv;
2374
2375 /* We need to set sv to output shift value. */
2376 if (INTVAL (XEXP (op0, 1)) == 1)
2377 sv = 0;
2378 else if (INTVAL (XEXP (op0, 1)) == 2)
2379 sv = 1;
2380 else if (INTVAL (XEXP (op0, 1)) == 4)
2381 sv = 2;
2382 else
2383 gcc_unreachable ();
2384
2385 fprintf (stream, "[%s + %s << %d]",
2386 reg_names[REGNO (op1)],
2387 reg_names[REGNO (XEXP (op0, 0))],
2388 sv);
2389 }
2390 else
2391 {
2392 /* The control flow is not supposed to be here. */
2393 debug_rtx (x);
2394 gcc_unreachable ();
2395 }
2396
2397 break;
2398
2399 case POST_MODIFY:
2400 /* (post_modify (regA) (plus (regA) (regB)))
2401 (post_modify (regA) (plus (regA) (const_int)))
2402 We would like to extract
2403 regA and regB (or const_int) from plus rtx. */
2404 op0 = XEXP (XEXP (x, 1), 0);
2405 op1 = XEXP (XEXP (x, 1), 1);
2406
2407 /* Checking op0, forbid using static chain register ($r16)
2408 on reduced-set registers configuration. */
2409 if (TARGET_REDUCED_REGS
2410 && REG_P (op0)
2411 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2412 sorry ("a nested function is not supported for reduced registers");
2413 /* Checking op1, forbid using static chain register ($r16)
2414 on reduced-set registers configuration. */
2415 if (TARGET_REDUCED_REGS
2416 && REG_P (op1)
2417 && REGNO (op1) == STATIC_CHAIN_REGNUM)
2418 sorry ("a nested function is not supported for reduced registers");
2419
2420 if (REG_P (op0) && REG_P (op1))
2421 {
2422 /* [Ra], Rb */
2423 fprintf (stream, "[%s], %s",
2424 reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
2425 }
2426 else if (REG_P (op0) && CONST_INT_P (op1))
2427 {
2428 /* [Ra], imm */
2429 fprintf (stream, "[%s], %d",
2430 reg_names[REGNO (op0)], (int)INTVAL (op1));
2431 }
2432 else
2433 {
2434 /* The control flow is not supposed to be here. */
2435 debug_rtx (x);
2436 gcc_unreachable ();
2437 }
2438
2439 break;
2440
2441 case POST_INC:
2442 case POST_DEC:
2443 op0 = XEXP (x, 0);
2444
2445 /* Checking op0, forbid using static chain register ($r16)
2446 on reduced-set registers configuration. */
2447 if (TARGET_REDUCED_REGS
2448 && REG_P (op0)
2449 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2450 sorry ("a nested function is not supported for reduced registers");
2451
2452 if (REG_P (op0))
2453 {
2454 /* "[Ra], 1/2/4" or "[Ra], -1/-2/-4"
2455 The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
2456 We only need to deal with register Ra. */
2457 fprintf (stream, "[%s]", reg_names[REGNO (op0)]);
2458 }
2459 else
2460 {
2461 /* The control flow is not supposed to be here. */
2462 debug_rtx (x);
2463 gcc_unreachable ();
2464 }
2465
2466 break;
2467
2468 default :
2469 /* Generally, output_addr_const () is able to handle most cases.
2470 We want to see what CODE could appear,
2471 so we use gcc_unreachable() to stop it. */
2472 debug_rtx (x);
2473 gcc_unreachable ();
2474 break;
2475 }
2476}
2477
2478\f
2479/* Defining target-specific uses of __attribute__. */
2480
2481/* Add some checking after merging attributes. */
2482static tree
2483nds32_merge_decl_attributes (tree olddecl, tree newdecl)
2484{
2485 tree combined_attrs;
2486
2487 /* Create combined attributes. */
2488 combined_attrs = merge_attributes (DECL_ATTRIBUTES (olddecl),
2489 DECL_ATTRIBUTES (newdecl));
2490
59043e75 2491 /* Since newdecl is acutally a duplicate of olddecl,
9304f876
CJW
2492 we can take olddecl for some operations. */
2493 if (TREE_CODE (olddecl) == FUNCTION_DECL)
2494 {
2495 /* Check isr-specific attributes conflict. */
2496 nds32_check_isr_attrs_conflict (olddecl, combined_attrs);
2497 }
2498
2499 return combined_attrs;
2500}
2501
2502/* Add some checking when inserting attributes. */
2503static void
2504nds32_insert_attributes (tree decl, tree *attributes)
2505{
2506 /* For function declaration, we need to check isr-specific attributes:
2507 1. Call nds32_check_isr_attrs_conflict() to check any conflict.
2508 2. Check valid integer value for interrupt/exception.
2509 3. Check valid integer value for reset.
2510 4. Check valid function for nmi/warm. */
2511 if (TREE_CODE (decl) == FUNCTION_DECL)
2512 {
2513 tree func_attrs;
2514 tree intr, excp, reset;
2515
2516 /* Pick up function attributes. */
2517 func_attrs = *attributes;
2518
2519 /* 1. Call nds32_check_isr_attrs_conflict() to check any conflict. */
2520 nds32_check_isr_attrs_conflict (decl, func_attrs);
2521
2522 /* Now we are starting to check valid id value
2523 for interrupt/exception/reset.
2524 Note that we ONLY check its validity here.
2525 To construct isr vector information, it is still performed
2526 by nds32_construct_isr_vectors_information(). */
2527 intr = lookup_attribute ("interrupt", func_attrs);
2528 excp = lookup_attribute ("exception", func_attrs);
2529 reset = lookup_attribute ("reset", func_attrs);
2530
2531 if (intr || excp)
2532 {
2533 /* Deal with interrupt/exception. */
2534 tree id_list;
2535 unsigned int lower_bound, upper_bound;
2536
2537 /* The way to handle interrupt or exception is the same,
2538 we just need to take care of actual vector number.
2539 For interrupt(0..63), the actual vector number is (9..72).
2540 For exception(1..8), the actual vector number is (1..8). */
2541 lower_bound = (intr) ? (0) : (1);
2542 upper_bound = (intr) ? (63) : (8);
2543
2544 /* Prepare id list so that we can traverse id value. */
2545 id_list = (intr) ? (TREE_VALUE (intr)) : (TREE_VALUE (excp));
2546
2547 /* 2. Check valid integer value for interrupt/exception. */
2548 while (id_list)
2549 {
2550 tree id;
2551
2552 /* Pick up each vector id value. */
2553 id = TREE_VALUE (id_list);
2554 /* Issue error if it is not a valid integer value. */
2555 if (TREE_CODE (id) != INTEGER_CST
807e902e
KZ
2556 || wi::ltu_p (id, lower_bound)
2557 || wi::gtu_p (id, upper_bound))
9304f876
CJW
2558 error ("invalid id value for interrupt/exception attribute");
2559
2560 /* Advance to next id. */
2561 id_list = TREE_CHAIN (id_list);
2562 }
2563 }
2564 else if (reset)
2565 {
2566 /* Deal with reset. */
2567 tree id_list;
2568 tree id;
2569 tree nmi, warm;
2570 unsigned int lower_bound;
2571 unsigned int upper_bound;
2572
2573 /* Prepare id_list and identify id value so that
2574 we can check if total number of vectors is valid. */
2575 id_list = TREE_VALUE (reset);
2576 id = TREE_VALUE (id_list);
2577
2578 /* The maximum numbers for user's interrupt is 64. */
2579 lower_bound = 0;
2580 upper_bound = 64;
2581
2582 /* 3. Check valid integer value for reset. */
2583 if (TREE_CODE (id) != INTEGER_CST
807e902e
KZ
2584 || wi::ltu_p (id, lower_bound)
2585 || wi::gtu_p (id, upper_bound))
9304f876
CJW
2586 error ("invalid id value for reset attribute");
2587
2588 /* 4. Check valid function for nmi/warm. */
2589 nmi = lookup_attribute ("nmi", func_attrs);
2590 warm = lookup_attribute ("warm", func_attrs);
2591
2592 if (nmi != NULL_TREE)
2593 {
2594 tree nmi_func_list;
2595 tree nmi_func;
2596
2597 nmi_func_list = TREE_VALUE (nmi);
2598 nmi_func = TREE_VALUE (nmi_func_list);
2599
2600 /* Issue error if it is not a valid nmi function. */
2601 if (TREE_CODE (nmi_func) != IDENTIFIER_NODE)
2602 error ("invalid nmi function for reset attribute");
2603 }
2604
2605 if (warm != NULL_TREE)
2606 {
2607 tree warm_func_list;
2608 tree warm_func;
2609
2610 warm_func_list = TREE_VALUE (warm);
2611 warm_func = TREE_VALUE (warm_func_list);
2612
2613 /* Issue error if it is not a valid warm function. */
2614 if (TREE_CODE (warm_func) != IDENTIFIER_NODE)
2615 error ("invalid warm function for reset attribute");
2616 }
2617 }
2618 else
2619 {
2620 /* No interrupt, exception, or reset attribute is set. */
2621 return;
2622 }
2623 }
2624}
2625
2626static bool
2627nds32_option_pragma_parse (tree args ATTRIBUTE_UNUSED,
2628 tree pop_target ATTRIBUTE_UNUSED)
2629{
2630 /* Currently, we do not parse any pragma target by ourself,
2631 so just simply return false. */
2632 return false;
2633}
2634
2635static void
2636nds32_option_override (void)
2637{
2638 /* After all the command options have been parsed,
2639 we shall deal with some flags for changing compiler settings. */
2640
2641 /* At first, we check if we have to strictly
2642 set some flags based on ISA family. */
2643 if (TARGET_ISA_V2)
2644 {
2645 /* Under V2 ISA, we need to strictly disable TARGET_V3PUSH. */
2646 target_flags &= ~MASK_V3PUSH;
2647 }
2648 if (TARGET_ISA_V3)
2649 {
2650 /* Under V3 ISA, currently nothing should be strictly set. */
2651 }
2652 if (TARGET_ISA_V3M)
2653 {
2654 /* Under V3M ISA, we need to strictly enable TARGET_REDUCED_REGS. */
2655 target_flags |= MASK_REDUCED_REGS;
2656 /* Under V3M ISA, we need to strictly disable TARGET_PERF_EXT. */
2657 target_flags &= ~MASK_PERF_EXT;
2658 }
2659
2660 /* See if we are using reduced-set registers:
2661 $r0~$r5, $r6~$r10, $r15, $r28, $r29, $r30, $r31
2662 If so, we must forbid using $r11~$r14, $r16~$r27. */
2663 if (TARGET_REDUCED_REGS)
2664 {
2665 int r;
2666
2667 /* Prevent register allocator from
2668 choosing it as doing register allocation. */
2669 for (r = 11; r <= 14; r++)
2670 fixed_regs[r] = call_used_regs[r] = 1;
2671 for (r = 16; r <= 27; r++)
2672 fixed_regs[r] = call_used_regs[r] = 1;
2673 }
2674
2675 /* See if user explicitly would like to use fp-as-gp optimization.
2676 If so, we must prevent $fp from being allocated
2677 during register allocation. */
2678 if (TARGET_FORCE_FP_AS_GP)
2679 fixed_regs[FP_REGNUM] = call_used_regs[FP_REGNUM] = 1;
2680
2681 if (!TARGET_16_BIT)
2682 {
2683 /* Under no 16 bit ISA, we need to strictly disable TARGET_V3PUSH. */
2684 target_flags &= ~MASK_V3PUSH;
2685 }
2686
2687 /* Currently, we don't support PIC code generation yet. */
2688 if (flag_pic)
2689 sorry ("not support -fpic");
2690}
2691
2692\f
2693/* Miscellaneous Parameters. */
2694
2695static void
2696nds32_init_builtins (void)
2697{
aaa44d2d 2698 nds32_init_builtins_impl ();
9304f876
CJW
2699}
2700
2701static rtx
2702nds32_expand_builtin (tree exp,
2703 rtx target,
aaa44d2d 2704 rtx subtarget,
ef4bddc2 2705 machine_mode mode,
aaa44d2d 2706 int ignore)
9304f876 2707{
aaa44d2d 2708 return nds32_expand_builtin_impl (exp, target, subtarget, mode, ignore);
9304f876
CJW
2709}
2710
2711
2712/* ------------------------------------------------------------------------ */
2713
2714/* PART 4: Implemet extern function definitions,
2715 the prototype is in nds32-protos.h. */
2716\f
2717/* Defining Data Structures for Per-function Information. */
2718
2719void
2720nds32_init_expanders (void)
2721{
2722 /* Arrange to initialize and mark the machine per-function status. */
2723 init_machine_status = nds32_init_machine_status;
2724}
2725
2726\f
2727/* Register Usage. */
2728
2729/* -- How Values Fit in Registers. */
2730
2731int
2732nds32_hard_regno_nregs (int regno ATTRIBUTE_UNUSED,
ef4bddc2 2733 machine_mode mode)
9304f876
CJW
2734{
2735 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
2736}
2737
2738int
ef4bddc2 2739nds32_hard_regno_mode_ok (int regno, machine_mode mode)
9304f876
CJW
2740{
2741 /* Restrict double-word quantities to even register pairs. */
2742 if (HARD_REGNO_NREGS (regno, mode) == 1
2743 || !((regno) & 1))
2744 return 1;
2745
2746 return 0;
2747}
2748
2749\f
2750/* Register Classes. */
2751
2752enum reg_class
2753nds32_regno_reg_class (int regno)
2754{
2755 /* Refer to nds32.h for more register class details. */
2756
2757 if (regno >= 0 && regno <= 7)
2758 return LOW_REGS;
2759 else if (regno >= 8 && regno <= 11)
2760 return MIDDLE_REGS;
2761 else if (regno >= 12 && regno <= 14)
2762 return HIGH_REGS;
2763 else if (regno == 15)
2764 return R15_TA_REG;
2765 else if (regno >= 16 && regno <= 19)
2766 return MIDDLE_REGS;
2767 else if (regno >= 20 && regno <= 31)
2768 return HIGH_REGS;
2769 else if (regno == 32 || regno == 33)
2770 return FRAME_REGS;
2771 else
2772 return NO_REGS;
2773}
2774
2775\f
2776/* Stack Layout and Calling Conventions. */
2777
2778/* -- Basic Stack Layout. */
2779
2780rtx
2781nds32_return_addr_rtx (int count,
2782 rtx frameaddr ATTRIBUTE_UNUSED)
2783{
2784 /* There is no way to determine the return address
2785 if frameaddr is the frame that has 'count' steps
2786 up from current frame. */
2787 if (count != 0)
2788 return NULL_RTX;
2789
2790 /* If count == 0, it means we are at current frame,
2791 the return address is $r30 ($lp). */
2792 return get_hard_reg_initial_val (Pmode, LP_REGNUM);
2793}
2794
2795/* -- Eliminating Frame Pointer and Arg Pointer. */
2796
2797HOST_WIDE_INT
2798nds32_initial_elimination_offset (unsigned int from_reg, unsigned int to_reg)
2799{
2800 HOST_WIDE_INT offset;
2801
2802 /* Compute and setup stack frame size.
2803 The result will be in cfun->machine. */
2804 nds32_compute_stack_frame ();
2805
2806 /* Remember to consider
2807 cfun->machine->callee_saved_area_padding_bytes
2808 when calculating offset. */
2809 if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
2810 {
2811 offset = (cfun->machine->fp_size
2812 + cfun->machine->gp_size
2813 + cfun->machine->lp_size
2814 + cfun->machine->callee_saved_regs_size
2815 + cfun->machine->callee_saved_area_padding_bytes
2816 + cfun->machine->local_size
2817 + cfun->machine->out_args_size);
2818 }
2819 else if (from_reg == ARG_POINTER_REGNUM
2820 && to_reg == HARD_FRAME_POINTER_REGNUM)
2821 {
2822 offset = 0;
2823 }
2824 else if (from_reg == FRAME_POINTER_REGNUM
2825 && to_reg == STACK_POINTER_REGNUM)
2826 {
2827 offset = (cfun->machine->local_size + cfun->machine->out_args_size);
2828 }
2829 else if (from_reg == FRAME_POINTER_REGNUM
2830 && to_reg == HARD_FRAME_POINTER_REGNUM)
2831 {
2832 offset = (-1) * (cfun->machine->fp_size
2833 + cfun->machine->gp_size
2834 + cfun->machine->lp_size
2835 + cfun->machine->callee_saved_regs_size
2836 + cfun->machine->callee_saved_area_padding_bytes);
2837 }
2838 else
2839 {
2840 gcc_unreachable ();
2841 }
2842
2843 return offset;
2844}
2845
2846/* -- Passing Arguments in Registers. */
2847
2848void
2849nds32_init_cumulative_args (CUMULATIVE_ARGS *cum,
2850 tree fntype ATTRIBUTE_UNUSED,
2851 rtx libname ATTRIBUTE_UNUSED,
2852 tree fndecl ATTRIBUTE_UNUSED,
2853 int n_named_args ATTRIBUTE_UNUSED)
2854{
2855 /* Initial available registers
2856 (in offset, corresponding to NDS32_GPR_ARG_FIRST_REGNUM)
2857 for passing arguments. */
9d93cc24 2858 cum->gpr_offset = 0;
9304f876
CJW
2859}
2860
2861/* -- Function Entry and Exit. */
2862
2863/* Function for normal multiple push prologue. */
2864void
2865nds32_expand_prologue (void)
2866{
2867 int fp_adjust;
2868 int sp_adjust;
2869 int en4_const;
2870
2871 rtx Rb, Re;
9304f876
CJW
2872 rtx fp_adjust_insn, sp_adjust_insn;
2873
9304f876
CJW
2874 /* Compute and setup stack frame size.
2875 The result will be in cfun->machine. */
2876 nds32_compute_stack_frame ();
2877
557430f1
CJW
2878 /* If this is a variadic function, first we need to push argument
2879 registers that hold the unnamed argument value. */
2880 if (cfun->machine->va_args_size != 0)
2881 {
2882 Rb = gen_rtx_REG (SImode, cfun->machine->va_args_first_regno);
2883 Re = gen_rtx_REG (SImode, cfun->machine->va_args_last_regno);
2884 /* No need to push $fp, $gp, or $lp, so use GEN_INT(0). */
47e0e7d2 2885 nds32_emit_stack_push_multiple (Rb, Re, GEN_INT (0), true);
557430f1
CJW
2886
2887 /* We may also need to adjust stack pointer for padding bytes
2888 because varargs may cause $sp not 8-byte aligned. */
2889 if (cfun->machine->va_args_area_padding_bytes)
2890 {
2891 /* Generate sp adjustment instruction. */
2892 sp_adjust = cfun->machine->va_args_area_padding_bytes;
2893 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
2894 stack_pointer_rtx,
2895 GEN_INT (-1 * sp_adjust));
2896
2897 /* Emit rtx into instructions list and receive INSN rtx form. */
2898 sp_adjust_insn = emit_insn (sp_adjust_insn);
2899
2900 /* The insn rtx 'sp_adjust_insn' will change frame layout.
2901 We need to use RTX_FRAME_RELATED_P so that GCC is able to
2902 generate CFI (Call Frame Information) stuff. */
2903 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
2904 }
2905 }
2906
9304f876
CJW
2907 /* If the function is 'naked',
2908 we do not have to generate prologue code fragment. */
2909 if (cfun->machine->naked_p)
2910 return;
2911
2912 /* Get callee_first_regno and callee_last_regno. */
2913 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
2914 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
2915
4e9a2848 2916 /* nds32_emit_stack_push_multiple(first_regno, last_regno),
9304f876
CJW
2917 the pattern 'stack_push_multiple' is implemented in nds32.md.
2918 For En4 field, we have to calculate its constant value.
2919 Refer to Andes ISA for more information. */
2920 en4_const = 0;
2921 if (cfun->machine->fp_size)
2922 en4_const += 8;
2923 if (cfun->machine->gp_size)
2924 en4_const += 4;
2925 if (cfun->machine->lp_size)
2926 en4_const += 2;
2927
2928 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
2929 to be saved, we don't have to create multiple push instruction.
2930 Otherwise, a multiple push instruction is needed. */
2931 if (!(REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM && en4_const == 0))
2932 {
2933 /* Create multiple push instruction rtx. */
47e0e7d2 2934 nds32_emit_stack_push_multiple (Rb, Re, GEN_INT (en4_const), false);
9304f876
CJW
2935 }
2936
2937 /* Check frame_pointer_needed to see
2938 if we shall emit fp adjustment instruction. */
2939 if (frame_pointer_needed)
2940 {
2941 /* adjust $fp = $sp + ($fp size) + ($gp size) + ($lp size)
2942 + (4 * callee-saved-registers)
2943 Note: No need to adjust
2944 cfun->machine->callee_saved_area_padding_bytes,
2945 because, at this point, stack pointer is just
2946 at the position after push instruction. */
2947 fp_adjust = cfun->machine->fp_size
2948 + cfun->machine->gp_size
2949 + cfun->machine->lp_size
2950 + cfun->machine->callee_saved_regs_size;
2951 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
2952 stack_pointer_rtx,
2953 GEN_INT (fp_adjust));
2954 /* Emit rtx into instructions list and receive INSN rtx form. */
2955 fp_adjust_insn = emit_insn (fp_adjust_insn);
7064dcad
CJW
2956
2957 /* The insn rtx 'fp_adjust_insn' will change frame layout. */
2958 RTX_FRAME_RELATED_P (fp_adjust_insn) = 1;
9304f876
CJW
2959 }
2960
2961 /* Adjust $sp = $sp - local_size - out_args_size
2962 - callee_saved_area_padding_bytes. */
2963 sp_adjust = cfun->machine->local_size
2964 + cfun->machine->out_args_size
2965 + cfun->machine->callee_saved_area_padding_bytes;
2966 /* sp_adjust value may be out of range of the addi instruction,
2967 create alternative add behavior with TA_REGNUM if necessary,
2968 using NEGATIVE value to tell that we are decreasing address. */
2969 sp_adjust = nds32_force_addi_stack_int ( (-1) * sp_adjust);
2970 if (sp_adjust)
2971 {
2972 /* Generate sp adjustment instruction if and only if sp_adjust != 0. */
2973 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
2974 stack_pointer_rtx,
2975 GEN_INT (-1 * sp_adjust));
2976 /* Emit rtx into instructions list and receive INSN rtx form. */
2977 sp_adjust_insn = emit_insn (sp_adjust_insn);
2978
2979 /* The insn rtx 'sp_adjust_insn' will change frame layout.
2980 We need to use RTX_FRAME_RELATED_P so that GCC is able to
2981 generate CFI (Call Frame Information) stuff. */
2982 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
2983 }
2984
2985 /* Prevent the instruction scheduler from
2986 moving instructions across the boundary. */
2987 emit_insn (gen_blockage ());
2988}
2989
2990/* Function for normal multiple pop epilogue. */
2991void
2992nds32_expand_epilogue (void)
2993{
2994 int sp_adjust;
2995 int en4_const;
2996
2997 rtx Rb, Re;
9304f876
CJW
2998 rtx sp_adjust_insn;
2999
3000 /* Compute and setup stack frame size.
3001 The result will be in cfun->machine. */
3002 nds32_compute_stack_frame ();
3003
3004 /* Prevent the instruction scheduler from
3005 moving instructions across the boundary. */
3006 emit_insn (gen_blockage ());
3007
3008 /* If the function is 'naked', we do not have to generate
557430f1
CJW
3009 epilogue code fragment BUT 'ret' instruction.
3010 However, if this function is also a variadic function,
3011 we need to create adjust stack pointer before 'ret' instruction. */
9304f876
CJW
3012 if (cfun->machine->naked_p)
3013 {
557430f1
CJW
3014 /* If this is a variadic function, we do not have to restore argument
3015 registers but need to adjust stack pointer back to previous stack
3016 frame location before return. */
3017 if (cfun->machine->va_args_size != 0)
3018 {
3019 /* Generate sp adjustment instruction.
3020 We need to consider padding bytes here. */
3021 sp_adjust = cfun->machine->va_args_size
3022 + cfun->machine->va_args_area_padding_bytes;
3023 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3024 stack_pointer_rtx,
3025 GEN_INT (sp_adjust));
3026 /* Emit rtx into instructions list and receive INSN rtx form. */
3027 sp_adjust_insn = emit_insn (sp_adjust_insn);
3028
3029 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3030 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3031 generate CFI (Call Frame Information) stuff. */
3032 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3033 }
3034
9304f876
CJW
3035 /* Generate return instruction by using
3036 unspec_volatile_func_return pattern.
3037 Make sure this instruction is after gen_blockage().
3038 NOTE that $lp will become 'live'
3039 after this instruction has been emitted. */
3040 emit_insn (gen_unspec_volatile_func_return ());
3041 return;
3042 }
3043
3044 if (frame_pointer_needed)
3045 {
3046 /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size)
3047 - (4 * callee-saved-registers)
3048 Note: No need to adjust
3049 cfun->machine->callee_saved_area_padding_bytes,
3050 because we want to adjust stack pointer
3051 to the position for pop instruction. */
3052 sp_adjust = cfun->machine->fp_size
3053 + cfun->machine->gp_size
3054 + cfun->machine->lp_size
3055 + cfun->machine->callee_saved_regs_size;
3056 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3057 hard_frame_pointer_rtx,
3058 GEN_INT (-1 * sp_adjust));
3059 /* Emit rtx into instructions list and receive INSN rtx form. */
3060 sp_adjust_insn = emit_insn (sp_adjust_insn);
557430f1
CJW
3061
3062 /* The insn rtx 'sp_adjust_insn' will change frame layout. */
3063 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
9304f876
CJW
3064 }
3065 else
3066 {
3067 /* If frame pointer is NOT needed,
3068 we cannot calculate the sp adjustment from frame pointer.
3069 Instead, we calculate the adjustment by local_size,
3070 out_args_size, and callee_saved_area_padding_bytes.
3071 Notice that such sp adjustment value may be out of range,
3072 so we have to deal with it as well. */
3073
3074 /* Adjust $sp = $sp + local_size + out_args_size
3075 + callee_saved_area_padding_bytes. */
3076 sp_adjust = cfun->machine->local_size
3077 + cfun->machine->out_args_size
3078 + cfun->machine->callee_saved_area_padding_bytes;
3079 /* sp_adjust value may be out of range of the addi instruction,
3080 create alternative add behavior with TA_REGNUM if necessary,
3081 using POSITIVE value to tell that we are increasing address. */
3082 sp_adjust = nds32_force_addi_stack_int (sp_adjust);
3083 if (sp_adjust)
3084 {
3085 /* Generate sp adjustment instruction
3086 if and only if sp_adjust != 0. */
3087 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3088 stack_pointer_rtx,
3089 GEN_INT (sp_adjust));
3090 /* Emit rtx into instructions list and receive INSN rtx form. */
3091 sp_adjust_insn = emit_insn (sp_adjust_insn);
557430f1
CJW
3092
3093 /* The insn rtx 'sp_adjust_insn' will change frame layout. */
3094 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
9304f876
CJW
3095 }
3096 }
3097
3098 /* Get callee_first_regno and callee_last_regno. */
3099 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
3100 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
3101
4e9a2848 3102 /* nds32_emit_stack_pop_multiple(first_regno, last_regno),
9304f876
CJW
3103 the pattern 'stack_pop_multiple' is implementad in nds32.md.
3104 For En4 field, we have to calculate its constant value.
3105 Refer to Andes ISA for more information. */
3106 en4_const = 0;
3107 if (cfun->machine->fp_size)
3108 en4_const += 8;
3109 if (cfun->machine->gp_size)
3110 en4_const += 4;
3111 if (cfun->machine->lp_size)
3112 en4_const += 2;
3113
3114 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
3115 to be saved, we don't have to create multiple pop instruction.
3116 Otherwise, a multiple pop instruction is needed. */
3117 if (!(REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM && en4_const == 0))
3118 {
3119 /* Create multiple pop instruction rtx. */
4e9a2848 3120 nds32_emit_stack_pop_multiple (Rb, Re, GEN_INT (en4_const));
9304f876
CJW
3121 }
3122
557430f1
CJW
3123 /* If this is a variadic function, we do not have to restore argument
3124 registers but need to adjust stack pointer back to previous stack
3125 frame location before return. */
3126 if (cfun->machine->va_args_size != 0)
3127 {
3128 /* Generate sp adjustment instruction.
3129 We need to consider padding bytes here. */
3130 sp_adjust = cfun->machine->va_args_size
3131 + cfun->machine->va_args_area_padding_bytes;
3132 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3133 stack_pointer_rtx,
3134 GEN_INT (sp_adjust));
3135 /* Emit rtx into instructions list and receive INSN rtx form. */
3136 sp_adjust_insn = emit_insn (sp_adjust_insn);
3137
3138 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3139 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3140 generate CFI (Call Frame Information) stuff. */
3141 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3142 }
3143
9304f876
CJW
3144 /* Generate return instruction by using
3145 unspec_volatile_func_return pattern. */
3146 emit_insn (gen_unspec_volatile_func_return ());
3147}
3148
3149/* Function for v3push prologue. */
3150void
3151nds32_expand_prologue_v3push (void)
3152{
3153 int fp_adjust;
3154 int sp_adjust;
3155
3156 rtx Rb, Re;
9304f876
CJW
3157 rtx fp_adjust_insn, sp_adjust_insn;
3158
9304f876
CJW
3159 /* Compute and setup stack frame size.
3160 The result will be in cfun->machine. */
3161 nds32_compute_stack_frame ();
3162
3163 /* If the function is 'naked',
3164 we do not have to generate prologue code fragment. */
3165 if (cfun->machine->naked_p)
3166 return;
3167
3168 /* Get callee_first_regno and callee_last_regno. */
3169 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
3170 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
3171
3172 /* Calculate sp_adjust first to test if 'push25 Re,imm8u' is available,
3173 where imm8u has to be 8-byte alignment. */
3174 sp_adjust = cfun->machine->local_size
3175 + cfun->machine->out_args_size
3176 + cfun->machine->callee_saved_area_padding_bytes;
3177
3178 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
3179 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust))
3180 {
3181 /* We can use 'push25 Re,imm8u'. */
3182
88437f39 3183 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
9304f876
CJW
3184 the pattern 'stack_v3push' is implemented in nds32.md.
3185 The (const_int 14) means v3push always push { $fp $gp $lp }. */
88437f39
CJW
3186 nds32_emit_stack_v3push (Rb, Re,
3187 GEN_INT (14), GEN_INT (sp_adjust));
9304f876
CJW
3188
3189 /* Check frame_pointer_needed to see
3190 if we shall emit fp adjustment instruction. */
3191 if (frame_pointer_needed)
3192 {
3193 /* adjust $fp = $sp + 4 ($fp size)
3194 + 4 ($gp size)
3195 + 4 ($lp size)
3196 + (4 * n) (callee-saved registers)
3197 + sp_adjust ('push25 Re,imm8u')
3198 Note: Since we use 'push25 Re,imm8u',
3199 the position of stack pointer is further
3200 changed after push instruction.
3201 Hence, we need to take sp_adjust value
3202 into consideration. */
3203 fp_adjust = cfun->machine->fp_size
3204 + cfun->machine->gp_size
3205 + cfun->machine->lp_size
3206 + cfun->machine->callee_saved_regs_size
3207 + sp_adjust;
3208 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
3209 stack_pointer_rtx,
3210 GEN_INT (fp_adjust));
3211 /* Emit rtx into instructions list and receive INSN rtx form. */
3212 fp_adjust_insn = emit_insn (fp_adjust_insn);
3213 }
3214 }
3215 else
3216 {
3217 /* We have to use 'push25 Re,0' and
3218 expand one more instruction to adjust $sp later. */
3219
88437f39 3220 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
9304f876
CJW
3221 the pattern 'stack_v3push' is implemented in nds32.md.
3222 The (const_int 14) means v3push always push { $fp $gp $lp }. */
88437f39
CJW
3223 nds32_emit_stack_v3push (Rb, Re,
3224 GEN_INT (14), GEN_INT (0));
9304f876
CJW
3225
3226 /* Check frame_pointer_needed to see
3227 if we shall emit fp adjustment instruction. */
3228 if (frame_pointer_needed)
3229 {
3230 /* adjust $fp = $sp + 4 ($fp size)
3231 + 4 ($gp size)
3232 + 4 ($lp size)
3233 + (4 * n) (callee-saved registers)
3234 Note: Since we use 'push25 Re,0',
3235 the stack pointer is just at the position
3236 after push instruction.
3237 No need to take sp_adjust into consideration. */
3238 fp_adjust = cfun->machine->fp_size
3239 + cfun->machine->gp_size
3240 + cfun->machine->lp_size
3241 + cfun->machine->callee_saved_regs_size;
3242 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
3243 stack_pointer_rtx,
3244 GEN_INT (fp_adjust));
3245 /* Emit rtx into instructions list and receive INSN rtx form. */
3246 fp_adjust_insn = emit_insn (fp_adjust_insn);
3247 }
3248
3249 /* Because we use 'push25 Re,0',
3250 we need to expand one more instruction to adjust $sp.
3251 However, sp_adjust value may be out of range of the addi instruction,
3252 create alternative add behavior with TA_REGNUM if necessary,
3253 using NEGATIVE value to tell that we are decreasing address. */
3254 sp_adjust = nds32_force_addi_stack_int ( (-1) * sp_adjust);
3255 if (sp_adjust)
3256 {
3257 /* Generate sp adjustment instruction
3258 if and only if sp_adjust != 0. */
3259 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3260 stack_pointer_rtx,
3261 GEN_INT (-1 * sp_adjust));
3262 /* Emit rtx into instructions list and receive INSN rtx form. */
3263 sp_adjust_insn = emit_insn (sp_adjust_insn);
3264
3265 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3266 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3267 generate CFI (Call Frame Information) stuff. */
3268 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3269 }
3270 }
3271
3272 /* Prevent the instruction scheduler from
3273 moving instructions across the boundary. */
3274 emit_insn (gen_blockage ());
3275}
3276
3277/* Function for v3pop epilogue. */
3278void
3279nds32_expand_epilogue_v3pop (void)
3280{
3281 int sp_adjust;
3282
3283 rtx Rb, Re;
9304f876
CJW
3284 rtx sp_adjust_insn;
3285
3286 /* Compute and setup stack frame size.
3287 The result will be in cfun->machine. */
3288 nds32_compute_stack_frame ();
3289
3290 /* Prevent the instruction scheduler from
3291 moving instructions across the boundary. */
3292 emit_insn (gen_blockage ());
3293
3294 /* If the function is 'naked', we do not have to generate
3295 epilogue code fragment BUT 'ret' instruction. */
3296 if (cfun->machine->naked_p)
3297 {
3298 /* Generate return instruction by using
3299 unspec_volatile_func_return pattern.
3300 Make sure this instruction is after gen_blockage().
3301 NOTE that $lp will become 'live'
3302 after this instruction has been emitted. */
3303 emit_insn (gen_unspec_volatile_func_return ());
3304 return;
3305 }
3306
3307 /* Get callee_first_regno and callee_last_regno. */
3308 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
3309 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
3310
3311 /* Calculate sp_adjust first to test if 'pop25 Re,imm8u' is available,
3312 where imm8u has to be 8-byte alignment. */
3313 sp_adjust = cfun->machine->local_size
3314 + cfun->machine->out_args_size
3315 + cfun->machine->callee_saved_area_padding_bytes;
3316
3317 /* We have to consider alloca issue as well.
3318 If the function does call alloca(), the stack pointer is not fixed.
3319 In that case, we cannot use 'pop25 Re,imm8u' directly.
3320 We have to caculate stack pointer from frame pointer
3321 and then use 'pop25 Re,0'.
3322 Of course, the frame_pointer_needed should be nonzero
3323 if the function calls alloca(). */
3324 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
3325 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust)
3326 && !cfun->calls_alloca)
3327 {
3328 /* We can use 'pop25 Re,imm8u'. */
3329
88437f39 3330 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
9304f876
CJW
3331 the pattern 'stack_v3pop' is implementad in nds32.md.
3332 The (const_int 14) means v3pop always pop { $fp $gp $lp }. */
88437f39
CJW
3333 nds32_emit_stack_v3pop (Rb, Re,
3334 GEN_INT (14), GEN_INT (sp_adjust));
9304f876
CJW
3335 }
3336 else
3337 {
3338 /* We have to use 'pop25 Re,0', and prior to it,
3339 we must expand one more instruction to adjust $sp. */
3340
3341 if (frame_pointer_needed)
3342 {
3343 /* adjust $sp = $fp - 4 ($fp size)
3344 - 4 ($gp size)
3345 - 4 ($lp size)
3346 - (4 * n) (callee-saved registers)
3347 Note: No need to adjust
3348 cfun->machine->callee_saved_area_padding_bytes,
3349 because we want to adjust stack pointer
3350 to the position for pop instruction. */
3351 sp_adjust = cfun->machine->fp_size
3352 + cfun->machine->gp_size
3353 + cfun->machine->lp_size
3354 + cfun->machine->callee_saved_regs_size;
3355 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3356 hard_frame_pointer_rtx,
3357 GEN_INT (-1 * sp_adjust));
3358 /* Emit rtx into instructions list and receive INSN rtx form. */
3359 sp_adjust_insn = emit_insn (sp_adjust_insn);
3360 }
3361 else
3362 {
3363 /* If frame pointer is NOT needed,
3364 we cannot calculate the sp adjustment from frame pointer.
3365 Instead, we calculate the adjustment by local_size,
3366 out_args_size, and callee_saved_area_padding_bytes.
3367 Notice that such sp adjustment value may be out of range,
3368 so we have to deal with it as well. */
3369
3370 /* Adjust $sp = $sp + local_size + out_args_size
3371 + callee_saved_area_padding_bytes. */
3372 sp_adjust = cfun->machine->local_size
3373 + cfun->machine->out_args_size
3374 + cfun->machine->callee_saved_area_padding_bytes;
3375 /* sp_adjust value may be out of range of the addi instruction,
3376 create alternative add behavior with TA_REGNUM if necessary,
3377 using POSITIVE value to tell that we are increasing address. */
3378 sp_adjust = nds32_force_addi_stack_int (sp_adjust);
3379 if (sp_adjust)
3380 {
3381 /* Generate sp adjustment instruction
3382 if and only if sp_adjust != 0. */
3383 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3384 stack_pointer_rtx,
3385 GEN_INT (sp_adjust));
3386 /* Emit rtx into instructions list and receive INSN rtx form. */
3387 sp_adjust_insn = emit_insn (sp_adjust_insn);
3388 }
3389 }
3390
88437f39 3391 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
9304f876
CJW
3392 the pattern 'stack_v3pop' is implementad in nds32.md. */
3393 /* The (const_int 14) means v3pop always pop { $fp $gp $lp }. */
88437f39
CJW
3394 nds32_emit_stack_v3pop (Rb, Re,
3395 GEN_INT (14), GEN_INT (0));
9304f876
CJW
3396 }
3397}
3398
3399/* ------------------------------------------------------------------------ */
3400
3401/* Function to test 333-form for load/store instructions.
3402 This is auxiliary extern function for auxiliary macro in nds32.h.
3403 Because it is a little complicated, we use function instead of macro. */
3404bool
ef4bddc2 3405nds32_ls_333_p (rtx rt, rtx ra, rtx imm, machine_mode mode)
9304f876
CJW
3406{
3407 if (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS
3408 && REGNO_REG_CLASS (REGNO (ra)) == LOW_REGS)
3409 {
3410 if (GET_MODE_SIZE (mode) == 4)
3411 return satisfies_constraint_Iu05 (imm);
3412
3413 if (GET_MODE_SIZE (mode) == 2)
3414 return satisfies_constraint_Iu04 (imm);
3415
3416 if (GET_MODE_SIZE (mode) == 1)
3417 return satisfies_constraint_Iu03 (imm);
3418 }
3419
3420 return false;
3421}
3422
3423
9304f876
CJW
3424/* Computing the Length of an Insn.
3425 Modifies the length assigned to instruction INSN.
3426 LEN is the initially computed length of the insn. */
3427int
ca009aee 3428nds32_adjust_insn_length (rtx_insn *insn, int length)
9304f876
CJW
3429{
3430 rtx src, dst;
3431
3432 switch (recog_memoized (insn))
3433 {
3434 case CODE_FOR_move_df:
3435 case CODE_FOR_move_di:
3436 /* Adjust length of movd44 to 2. */
3437 src = XEXP (PATTERN (insn), 1);
3438 dst = XEXP (PATTERN (insn), 0);
3439
3440 if (REG_P (src)
3441 && REG_P (dst)
3442 && (REGNO (src) % 2) == 0
3443 && (REGNO (dst) % 2) == 0)
3444 length = 2;
3445 break;
3446
3447 default:
3448 break;
3449 }
3450
3451 return length;
3452}
3453
3454
9304f876
CJW
3455/* Return align 2 (log base 2) if the next instruction of LABEL is 4 byte. */
3456int
3457nds32_target_alignment (rtx label)
3458{
84034c69 3459 rtx_insn *insn;
9304f876
CJW
3460
3461 if (optimize_size)
3462 return 0;
3463
3464 insn = next_active_insn (label);
3465
3466 if (insn == 0)
3467 return 0;
3468 else if ((get_attr_length (insn) % 4) == 0)
3469 return 2;
3470 else
3471 return 0;
3472}
3473
3474/* ------------------------------------------------------------------------ */
3475
3476/* PART 5: Initialize target hook structure and definitions. */
3477\f
3478/* Controlling the Compilation Driver. */
3479
3480\f
3481/* Run-time Target Specification. */
3482
3483\f
3484/* Defining Data Structures for Per-function Information. */
3485
3486\f
3487/* Storage Layout. */
3488
3489#undef TARGET_PROMOTE_FUNCTION_MODE
3490#define TARGET_PROMOTE_FUNCTION_MODE \
3491 default_promote_function_mode_always_promote
3492
3493\f
3494/* Layout of Source Language Data Types. */
3495
3496\f
3497/* Register Usage. */
3498
3499/* -- Basic Characteristics of Registers. */
3500
3501/* -- Order of Allocation of Registers. */
3502
3503/* -- How Values Fit in Registers. */
3504
3505/* -- Handling Leaf Functions. */
3506
3507/* -- Registers That Form a Stack. */
3508
3509\f
3510/* Register Classes. */
3511
3512#undef TARGET_CLASS_MAX_NREGS
3513#define TARGET_CLASS_MAX_NREGS nds32_class_max_nregs
3514
3515#undef TARGET_LRA_P
3516#define TARGET_LRA_P hook_bool_void_true
3517
3518#undef TARGET_REGISTER_PRIORITY
3519#define TARGET_REGISTER_PRIORITY nds32_register_priority
3520
3521\f
3522/* Obsolete Macros for Defining Constraints. */
3523
3524\f
3525/* Stack Layout and Calling Conventions. */
3526
3527/* -- Basic Stack Layout. */
3528
3529/* -- Exception Handling Support. */
3530
3531/* -- Specifying How Stack Checking is Done. */
3532
3533/* -- Registers That Address the Stack Frame. */
3534
3535/* -- Eliminating Frame Pointer and Arg Pointer. */
3536
3537#undef TARGET_CAN_ELIMINATE
3538#define TARGET_CAN_ELIMINATE nds32_can_eliminate
3539
3540/* -- Passing Function Arguments on the Stack. */
3541
3542/* -- Passing Arguments in Registers. */
3543
3544#undef TARGET_FUNCTION_ARG
3545#define TARGET_FUNCTION_ARG nds32_function_arg
3546
d40f3c40
CJW
3547#undef TARGET_MUST_PASS_IN_STACK
3548#define TARGET_MUST_PASS_IN_STACK nds32_must_pass_in_stack
3549
650fc469
CJW
3550#undef TARGET_ARG_PARTIAL_BYTES
3551#define TARGET_ARG_PARTIAL_BYTES nds32_arg_partial_bytes
3552
9304f876
CJW
3553#undef TARGET_FUNCTION_ARG_ADVANCE
3554#define TARGET_FUNCTION_ARG_ADVANCE nds32_function_arg_advance
3555
3556#undef TARGET_FUNCTION_ARG_BOUNDARY
3557#define TARGET_FUNCTION_ARG_BOUNDARY nds32_function_arg_boundary
3558
3559/* -- How Scalar Function Values Are Returned. */
3560
3561#undef TARGET_FUNCTION_VALUE
3562#define TARGET_FUNCTION_VALUE nds32_function_value
3563
3564#undef TARGET_LIBCALL_VALUE
3565#define TARGET_LIBCALL_VALUE nds32_libcall_value
3566
3567#undef TARGET_FUNCTION_VALUE_REGNO_P
3568#define TARGET_FUNCTION_VALUE_REGNO_P nds32_function_value_regno_p
3569
3570/* -- How Large Values Are Returned. */
3571
3572/* -- Caller-Saves Register Allocation. */
3573
3574/* -- Function Entry and Exit. */
3575
3576#undef TARGET_ASM_FUNCTION_PROLOGUE
3577#define TARGET_ASM_FUNCTION_PROLOGUE nds32_asm_function_prologue
3578
3579#undef TARGET_ASM_FUNCTION_END_PROLOGUE
3580#define TARGET_ASM_FUNCTION_END_PROLOGUE nds32_asm_function_end_prologue
3581
3582#undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
3583#define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE nds32_asm_function_begin_epilogue
3584
3585#undef TARGET_ASM_FUNCTION_EPILOGUE
3586#define TARGET_ASM_FUNCTION_EPILOGUE nds32_asm_function_epilogue
3587
3588#undef TARGET_ASM_OUTPUT_MI_THUNK
3589#define TARGET_ASM_OUTPUT_MI_THUNK nds32_asm_output_mi_thunk
3590
3591#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
3592#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
3593
3594/* -- Generating Code for Profiling. */
3595
3596/* -- Permitting tail calls. */
3597
3598#undef TARGET_WARN_FUNC_RETURN
3599#define TARGET_WARN_FUNC_RETURN nds32_warn_func_return
3600
3601/* Stack smashing protection. */
3602
3603\f
3604/* Implementing the Varargs Macros. */
3605
d4a6a4d9
CJW
3606#undef TARGET_SETUP_INCOMING_VARARGS
3607#define TARGET_SETUP_INCOMING_VARARGS nds32_setup_incoming_varargs
3608
9304f876
CJW
3609#undef TARGET_STRICT_ARGUMENT_NAMING
3610#define TARGET_STRICT_ARGUMENT_NAMING nds32_strict_argument_naming
3611
3612\f
3613/* Trampolines for Nested Functions. */
3614
3615#undef TARGET_ASM_TRAMPOLINE_TEMPLATE
3616#define TARGET_ASM_TRAMPOLINE_TEMPLATE nds32_asm_trampoline_template
3617
3618#undef TARGET_TRAMPOLINE_INIT
3619#define TARGET_TRAMPOLINE_INIT nds32_trampoline_init
3620
3621\f
3622/* Implicit Calls to Library Routines. */
3623
3624\f
3625/* Addressing Modes. */
3626
3627#undef TARGET_LEGITIMATE_ADDRESS_P
3628#define TARGET_LEGITIMATE_ADDRESS_P nds32_legitimate_address_p
3629
3630\f
3631/* Anchored Addresses. */
3632
3633\f
3634/* Condition Code Status. */
3635
3636/* -- Representation of condition codes using (cc0). */
3637
3638/* -- Representation of condition codes using registers. */
3639
3640/* -- Macros to control conditional execution. */
3641
3642\f
3643/* Describing Relative Costs of Operations. */
3644
3645#undef TARGET_REGISTER_MOVE_COST
3646#define TARGET_REGISTER_MOVE_COST nds32_register_move_cost
3647
3648#undef TARGET_MEMORY_MOVE_COST
3649#define TARGET_MEMORY_MOVE_COST nds32_memory_move_cost
3650
3651#undef TARGET_RTX_COSTS
3652#define TARGET_RTX_COSTS nds32_rtx_costs
3653
3654#undef TARGET_ADDRESS_COST
3655#define TARGET_ADDRESS_COST nds32_address_cost
3656
3657\f
3658/* Adjusting the Instruction Scheduler. */
3659
3660\f
3661/* Dividing the Output into Sections (Texts, Data, . . . ). */
3662
3663\f
3664/* Position Independent Code. */
3665
3666\f
3667/* Defining the Output Assembler Language. */
3668
3669/* -- The Overall Framework of an Assembler File. */
3670
3671#undef TARGET_ASM_FILE_START
3672#define TARGET_ASM_FILE_START nds32_asm_file_start
3673#undef TARGET_ASM_FILE_END
3674#define TARGET_ASM_FILE_END nds32_asm_file_end
3675
3676/* -- Output of Data. */
3677
3678#undef TARGET_ASM_ALIGNED_HI_OP
3679#define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
3680
3681#undef TARGET_ASM_ALIGNED_SI_OP
3682#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
3683
3684/* -- Output of Uninitialized Variables. */
3685
3686/* -- Output and Generation of Labels. */
3687
3688#undef TARGET_ASM_GLOBALIZE_LABEL
3689#define TARGET_ASM_GLOBALIZE_LABEL nds32_asm_globalize_label
3690
3691/* -- How Initialization Functions Are Handled. */
3692
3693/* -- Macros Controlling Initialization Routines. */
3694
3695/* -- Output of Assembler Instructions. */
3696
3697#undef TARGET_PRINT_OPERAND
3698#define TARGET_PRINT_OPERAND nds32_print_operand
3699#undef TARGET_PRINT_OPERAND_ADDRESS
3700#define TARGET_PRINT_OPERAND_ADDRESS nds32_print_operand_address
3701
3702/* -- Output of Dispatch Tables. */
3703
3704/* -- Assembler Commands for Exception Regions. */
3705
3706/* -- Assembler Commands for Alignment. */
3707
3708\f
3709/* Controlling Debugging Information Format. */
3710
3711/* -- Macros Affecting All Debugging Formats. */
3712
3713/* -- Specific Options for DBX Output. */
3714
3715/* -- Open-Ended Hooks for DBX Format. */
3716
3717/* -- File Names in DBX Format. */
3718
3719/* -- Macros for SDB and DWARF Output. */
3720
3721/* -- Macros for VMS Debug Format. */
3722
3723\f
3724/* Cross Compilation and Floating Point. */
3725
3726\f
3727/* Mode Switching Instructions. */
3728
3729\f
3730/* Defining target-specific uses of __attribute__. */
3731
3732#undef TARGET_ATTRIBUTE_TABLE
3733#define TARGET_ATTRIBUTE_TABLE nds32_attribute_table
3734
3735#undef TARGET_MERGE_DECL_ATTRIBUTES
3736#define TARGET_MERGE_DECL_ATTRIBUTES nds32_merge_decl_attributes
3737
3738#undef TARGET_INSERT_ATTRIBUTES
3739#define TARGET_INSERT_ATTRIBUTES nds32_insert_attributes
3740
3741#undef TARGET_OPTION_PRAGMA_PARSE
3742#define TARGET_OPTION_PRAGMA_PARSE nds32_option_pragma_parse
3743
3744#undef TARGET_OPTION_OVERRIDE
3745#define TARGET_OPTION_OVERRIDE nds32_option_override
3746
3747\f
3748/* Emulating TLS. */
3749
3750\f
3751/* Defining coprocessor specifics for MIPS targets. */
3752
3753\f
3754/* Parameters for Precompiled Header Validity Checking. */
3755
3756\f
3757/* C++ ABI parameters. */
3758
3759\f
3760/* Adding support for named address spaces. */
3761
3762\f
3763/* Miscellaneous Parameters. */
3764
3765#undef TARGET_INIT_BUILTINS
3766#define TARGET_INIT_BUILTINS nds32_init_builtins
3767
3768#undef TARGET_EXPAND_BUILTIN
3769#define TARGET_EXPAND_BUILTIN nds32_expand_builtin
3770
3771\f
3772/* ------------------------------------------------------------------------ */
3773
3774/* Initialize the GCC target structure. */
3775
3776struct gcc_target targetm = TARGET_INITIALIZER;
3777
3778/* ------------------------------------------------------------------------ */