Move ISR impelentation to nds32-isr.c module.
[official-gcc.git] / gcc / config / nds32 / nds32.c
blob746a5e193875ebd86196a4edcbbfb61a07bf3330
1 /* Subroutines used for code generation of Andes NDS32 cpu for GNU compiler
2 Copyright (C) 2012-2014 Free Software Foundation, Inc.
3 Contributed by Andes Technology Corporation.
5 This file is part of GCC.
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.
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.
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/>. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "tree.h"
28 #include "stor-layout.h"
29 #include "varasm.h"
30 #include "calls.h"
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"
41 #include "function.h"
42 #include "expr.h"
43 #include "recog.h"
44 #include "diagnostic-core.h"
45 #include "df.h"
46 #include "tm_p.h"
47 #include "tm-constrs.h"
48 #include "optabs.h" /* For GEN_FCN. */
49 #include "target.h"
50 #include "target-def.h"
51 #include "langhooks.h" /* For add_builtin_function(). */
52 #include "ggc.h"
53 #include "builtins.h"
55 /* ------------------------------------------------------------------------ */
57 /* This file is divided into five parts:
59 PART 1: Auxiliary static variable definitions and
60 target hook static variable definitions.
62 PART 2: Auxiliary static function definitions.
64 PART 3: Implement target hook stuff definitions.
66 PART 4: Implemet extern function definitions,
67 the prototype is in nds32-protos.h.
69 PART 5: Initialize target hook structure and definitions. */
71 /* ------------------------------------------------------------------------ */
73 /* PART 1: Auxiliary static variable definitions and
74 target hook static variable definitions. */
76 /* Define intrinsic register names.
77 Please refer to nds32_intrinsic.h file, the index is corresponding to
78 'enum nds32_intrinsic_registers' data type values.
79 NOTE that the base value starting from 1024. */
80 static const char * const nds32_intrinsic_register_names[] =
82 "$PSW", "$IPSW", "$ITYPE", "$IPC"
85 /* Defining target-specific uses of __attribute__. */
86 static const struct attribute_spec nds32_attribute_table[] =
88 /* Syntax: { name, min_len, max_len, decl_required, type_required,
89 function_type_required, handler, affects_type_identity } */
91 /* The interrupt vid: [0-63]+ (actual vector number starts from 9 to 72). */
92 { "interrupt", 1, 64, false, false, false, NULL, false },
93 /* The exception vid: [1-8]+ (actual vector number starts from 1 to 8). */
94 { "exception", 1, 8, false, false, false, NULL, false },
95 /* Argument is user's interrupt numbers. The vector number is always 0. */
96 { "reset", 1, 1, false, false, false, NULL, false },
98 /* The attributes describing isr nested type. */
99 { "nested", 0, 0, false, false, false, NULL, false },
100 { "not_nested", 0, 0, false, false, false, NULL, false },
101 { "nested_ready", 0, 0, false, false, false, NULL, false },
103 /* The attributes describing isr register save scheme. */
104 { "save_all", 0, 0, false, false, false, NULL, false },
105 { "partial_save", 0, 0, false, false, false, NULL, false },
107 /* The attributes used by reset attribute. */
108 { "nmi", 1, 1, false, false, false, NULL, false },
109 { "warm", 1, 1, false, false, false, NULL, false },
111 /* The attribute telling no prologue/epilogue. */
112 { "naked", 0, 0, false, false, false, NULL, false },
114 /* The last attribute spec is set to be NULL. */
115 { NULL, 0, 0, false, false, false, NULL, false }
119 /* ------------------------------------------------------------------------ */
121 /* PART 2: Auxiliary static function definitions. */
123 /* Function to save and restore machine-specific function data. */
124 static struct machine_function *
125 nds32_init_machine_status (void)
127 struct machine_function *machine;
128 machine = ggc_cleared_alloc<machine_function> ();
130 /* Initially assume this function needs prologue/epilogue. */
131 machine->naked_p = 0;
133 /* Initially assume this function does NOT use fp_as_gp optimization. */
134 machine->fp_as_gp_p = 0;
136 return machine;
139 /* Function to compute stack frame size and
140 store into cfun->machine structure. */
141 static void
142 nds32_compute_stack_frame (void)
144 int r;
145 int block_size;
147 /* Because nds32_compute_stack_frame() will be called from different place,
148 everytime we enter this function, we have to assume this function
149 needs prologue/epilogue. */
150 cfun->machine->naked_p = 0;
152 /* Get variadic arguments size to prepare pretend arguments and
153 push them into stack at prologue.
154 Currently, we do not push variadic arguments by ourself.
155 We have GCC handle all the works.
156 The caller will push all corresponding nameless arguments into stack,
157 and the callee is able to retrieve them without problems.
158 These variables are still preserved in case one day
159 we would like caller passing arguments with registers. */
160 cfun->machine->va_args_size = 0;
161 cfun->machine->va_args_first_regno = SP_REGNUM;
162 cfun->machine->va_args_last_regno = SP_REGNUM;
164 /* Get local variables, incoming variables, and temporary variables size.
165 Note that we need to make sure it is 8-byte alignment because
166 there may be no padding bytes if we are using LRA. */
167 cfun->machine->local_size = NDS32_ROUND_UP_DOUBLE_WORD (get_frame_size ());
169 /* Get outgoing arguments size. */
170 cfun->machine->out_args_size = crtl->outgoing_args_size;
172 /* If $fp value is required to be saved on stack, it needs 4 bytes space.
173 Check whether $fp is ever live. */
174 cfun->machine->fp_size = (df_regs_ever_live_p (FP_REGNUM)) ? 4 : 0;
176 /* If $gp value is required to be saved on stack, it needs 4 bytes space.
177 Check whether we are using PIC code genration. */
178 cfun->machine->gp_size = (flag_pic) ? 4 : 0;
180 /* If $lp value is required to be saved on stack, it needs 4 bytes space.
181 Check whether $lp is ever live. */
182 cfun->machine->lp_size = (df_regs_ever_live_p (LP_REGNUM)) ? 4 : 0;
184 /* Initially there is no padding bytes. */
185 cfun->machine->callee_saved_area_padding_bytes = 0;
187 /* Calculate the bytes of saving callee-saved registers on stack. */
188 cfun->machine->callee_saved_regs_size = 0;
189 cfun->machine->callee_saved_regs_first_regno = SP_REGNUM;
190 cfun->machine->callee_saved_regs_last_regno = SP_REGNUM;
191 /* Currently, there is no need to check $r28~$r31
192 because we will save them in another way. */
193 for (r = 0; r < 28; r++)
195 if (NDS32_REQUIRED_CALLEE_SAVED_P (r))
197 /* Mark the first required callee-saved register
198 (only need to set it once).
199 If first regno == SP_REGNUM, we can tell that
200 it is the first time to be here. */
201 if (cfun->machine->callee_saved_regs_first_regno == SP_REGNUM)
202 cfun->machine->callee_saved_regs_first_regno = r;
203 /* Mark the last required callee-saved register. */
204 cfun->machine->callee_saved_regs_last_regno = r;
208 /* Check if this function can omit prologue/epilogue code fragment.
209 If there is 'naked' attribute in this function,
210 we can set 'naked_p' flag to indicate that
211 we do not have to generate prologue/epilogue.
212 Or, if all the following conditions succeed,
213 we can set this function 'naked_p' as well:
214 condition 1: first_regno == last_regno == SP_REGNUM,
215 which means we do not have to save
216 any callee-saved registers.
217 condition 2: Both $lp and $fp are NOT live in this function,
218 which means we do not need to save them.
219 condition 3: There is no local_size, which means
220 we do not need to adjust $sp. */
221 if (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl))
222 || (cfun->machine->callee_saved_regs_first_regno == SP_REGNUM
223 && cfun->machine->callee_saved_regs_last_regno == SP_REGNUM
224 && !df_regs_ever_live_p (FP_REGNUM)
225 && !df_regs_ever_live_p (LP_REGNUM)
226 && cfun->machine->local_size == 0))
228 /* Set this function 'naked_p' and
229 other functions can check this flag. */
230 cfun->machine->naked_p = 1;
232 /* No need to save $fp, $gp, and $lp.
233 We should set these value to be zero
234 so that nds32_initial_elimination_offset() can work properly. */
235 cfun->machine->fp_size = 0;
236 cfun->machine->gp_size = 0;
237 cfun->machine->lp_size = 0;
239 /* If stack usage computation is required,
240 we need to provide the static stack size. */
241 if (flag_stack_usage_info)
242 current_function_static_stack_size = 0;
244 /* No need to do following adjustment, return immediately. */
245 return;
248 /* Adjustment for v3push instructions:
249 If we are using v3push (push25/pop25) instructions,
250 we need to make sure Rb is $r6 and Re is
251 located on $r6, $r8, $r10, or $r14.
252 Some results above will be discarded and recomputed.
253 Note that it is only available under V3/V3M ISA. */
254 if (TARGET_V3PUSH)
256 /* Recompute:
257 cfun->machine->fp_size
258 cfun->machine->gp_size
259 cfun->machine->lp_size
260 cfun->machine->callee_saved_regs_first_regno
261 cfun->machine->callee_saved_regs_last_regno */
263 /* For v3push instructions, $fp, $gp, and $lp are always saved. */
264 cfun->machine->fp_size = 4;
265 cfun->machine->gp_size = 4;
266 cfun->machine->lp_size = 4;
268 /* Remember to set Rb = $r6. */
269 cfun->machine->callee_saved_regs_first_regno = 6;
271 if (cfun->machine->callee_saved_regs_last_regno <= 6)
273 /* Re = $r6 */
274 cfun->machine->callee_saved_regs_last_regno = 6;
276 else if (cfun->machine->callee_saved_regs_last_regno <= 8)
278 /* Re = $r8 */
279 cfun->machine->callee_saved_regs_last_regno = 8;
281 else if (cfun->machine->callee_saved_regs_last_regno <= 10)
283 /* Re = $r10 */
284 cfun->machine->callee_saved_regs_last_regno = 10;
286 else if (cfun->machine->callee_saved_regs_last_regno <= 14)
288 /* Re = $r14 */
289 cfun->machine->callee_saved_regs_last_regno = 14;
291 else if (cfun->machine->callee_saved_regs_last_regno == SP_REGNUM)
293 /* If last_regno is SP_REGNUM, which means
294 it is never changed, so set it to Re = $r6. */
295 cfun->machine->callee_saved_regs_last_regno = 6;
297 else
299 /* The program flow should not go here. */
300 gcc_unreachable ();
304 /* We have correctly set callee_saved_regs_first_regno
305 and callee_saved_regs_last_regno.
306 Initially, the callee_saved_regs_size is supposed to be 0.
307 As long as callee_saved_regs_last_regno is not SP_REGNUM,
308 we can update callee_saved_regs_size with new size. */
309 if (cfun->machine->callee_saved_regs_last_regno != SP_REGNUM)
311 /* Compute pushed size of callee-saved registers. */
312 cfun->machine->callee_saved_regs_size
313 = 4 * (cfun->machine->callee_saved_regs_last_regno
314 - cfun->machine->callee_saved_regs_first_regno
315 + 1);
318 /* Important: We need to make sure that
319 (va_args_size + fp_size + gp_size
320 + lp_size + callee_saved_regs_size)
321 is 8-byte alignment.
322 If it is not, calculate the padding bytes. */
323 block_size = cfun->machine->va_args_size
324 + cfun->machine->fp_size
325 + cfun->machine->gp_size
326 + cfun->machine->lp_size
327 + cfun->machine->callee_saved_regs_size;
328 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size))
330 cfun->machine->callee_saved_area_padding_bytes
331 = NDS32_ROUND_UP_DOUBLE_WORD (block_size) - block_size;
334 /* If stack usage computation is required,
335 we need to provide the static stack size. */
336 if (flag_stack_usage_info)
338 current_function_static_stack_size
339 = NDS32_ROUND_UP_DOUBLE_WORD (block_size)
340 + cfun->machine->local_size
341 + cfun->machine->out_args_size;
345 /* Function to create a parallel rtx pattern
346 which presents stack push multiple behavior.
347 The overall concept are:
348 "push registers to memory",
349 "adjust stack pointer". */
350 static rtx
351 nds32_gen_stack_push_multiple (rtx Rb, rtx Re,
352 rtx En4 ATTRIBUTE_UNUSED)
354 int regno;
355 int extra_count;
356 int num_use_regs;
357 int par_index;
358 int offset;
360 rtx reg;
361 rtx mem;
362 rtx push_rtx;
363 rtx adjust_sp_rtx;
364 rtx parallel_insn;
366 /* We need to provide a customized rtx which contains
367 necessary information for data analysis,
368 so we create a parallel rtx like this:
369 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
370 (reg:SI Rb))
371 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
372 (reg:SI Rb+1))
374 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
375 (reg:SI Re))
376 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
377 (reg:SI FP_REGNUM))
378 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
379 (reg:SI GP_REGNUM))
380 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
381 (reg:SI LP_REGNUM))
382 (set (reg:SI SP_REGNUM)
383 (plus (reg:SI SP_REGNUM) (const_int -32)))]) */
385 /* Calculate the number of registers that will be pushed. */
386 extra_count = 0;
387 if (cfun->machine->fp_size)
388 extra_count++;
389 if (cfun->machine->gp_size)
390 extra_count++;
391 if (cfun->machine->lp_size)
392 extra_count++;
393 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
394 if (REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM)
395 num_use_regs = extra_count;
396 else
397 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + extra_count;
399 /* In addition to used registers,
400 we need one more space for (set sp sp-x) rtx. */
401 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
402 rtvec_alloc (num_use_regs + 1));
403 par_index = 0;
405 /* Initialize offset and start to create push behavior. */
406 offset = -(num_use_regs * 4);
408 /* Create (set mem regX) from Rb, Rb+1 up to Re. */
409 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
411 /* Rb and Re may be SP_REGNUM.
412 We need to break this loop immediately. */
413 if (regno == SP_REGNUM)
414 break;
416 reg = gen_rtx_REG (SImode, regno);
417 mem = gen_frame_mem (SImode, plus_constant (Pmode,
418 stack_pointer_rtx,
419 offset));
420 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
421 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
422 RTX_FRAME_RELATED_P (push_rtx) = 1;
423 offset = offset + 4;
424 par_index++;
427 /* Create (set mem fp), (set mem gp), and (set mem lp) if necessary. */
428 if (cfun->machine->fp_size)
430 reg = gen_rtx_REG (SImode, FP_REGNUM);
431 mem = gen_frame_mem (SImode, plus_constant (Pmode,
432 stack_pointer_rtx,
433 offset));
434 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
435 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
436 RTX_FRAME_RELATED_P (push_rtx) = 1;
437 offset = offset + 4;
438 par_index++;
440 if (cfun->machine->gp_size)
442 reg = gen_rtx_REG (SImode, GP_REGNUM);
443 mem = gen_frame_mem (SImode, plus_constant (Pmode,
444 stack_pointer_rtx,
445 offset));
446 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
447 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
448 RTX_FRAME_RELATED_P (push_rtx) = 1;
449 offset = offset + 4;
450 par_index++;
452 if (cfun->machine->lp_size)
454 reg = gen_rtx_REG (SImode, LP_REGNUM);
455 mem = gen_frame_mem (SImode, plus_constant (Pmode,
456 stack_pointer_rtx,
457 offset));
458 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
459 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
460 RTX_FRAME_RELATED_P (push_rtx) = 1;
461 offset = offset + 4;
462 par_index++;
465 /* Create (set sp sp-x). */
467 /* We need to re-calculate the offset value again for adjustment. */
468 offset = -(num_use_regs * 4);
469 adjust_sp_rtx
470 = gen_rtx_SET (VOIDmode,
471 stack_pointer_rtx,
472 plus_constant (Pmode, stack_pointer_rtx, offset));
473 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
474 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
476 return parallel_insn;
479 /* Function to create a parallel rtx pattern
480 which presents stack pop multiple behavior.
481 The overall concept are:
482 "pop registers from memory",
483 "adjust stack pointer". */
484 static rtx
485 nds32_gen_stack_pop_multiple (rtx Rb, rtx Re,
486 rtx En4 ATTRIBUTE_UNUSED)
488 int regno;
489 int extra_count;
490 int num_use_regs;
491 int par_index;
492 int offset;
494 rtx reg;
495 rtx mem;
496 rtx pop_rtx;
497 rtx adjust_sp_rtx;
498 rtx parallel_insn;
500 /* We need to provide a customized rtx which contains
501 necessary information for data analysis,
502 so we create a parallel rtx like this:
503 (parallel [(set (reg:SI Rb)
504 (mem (reg:SI SP_REGNUM)))
505 (set (reg:SI Rb+1)
506 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
508 (set (reg:SI Re)
509 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
510 (set (reg:SI FP_REGNUM)
511 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
512 (set (reg:SI GP_REGNUM)
513 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
514 (set (reg:SI LP_REGNUM)
515 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
516 (set (reg:SI SP_REGNUM)
517 (plus (reg:SI SP_REGNUM) (const_int 32)))]) */
519 /* Calculate the number of registers that will be poped. */
520 extra_count = 0;
521 if (cfun->machine->fp_size)
522 extra_count++;
523 if (cfun->machine->gp_size)
524 extra_count++;
525 if (cfun->machine->lp_size)
526 extra_count++;
527 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
528 if (REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM)
529 num_use_regs = extra_count;
530 else
531 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + extra_count;
533 /* In addition to used registers,
534 we need one more space for (set sp sp+x) rtx. */
535 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
536 rtvec_alloc (num_use_regs + 1));
537 par_index = 0;
539 /* Initialize offset and start to create pop behavior. */
540 offset = 0;
542 /* Create (set regX mem) from Rb, Rb+1 up to Re. */
543 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
545 /* Rb and Re may be SP_REGNUM.
546 We need to break this loop immediately. */
547 if (regno == SP_REGNUM)
548 break;
550 reg = gen_rtx_REG (SImode, regno);
551 mem = gen_frame_mem (SImode, plus_constant (Pmode,
552 stack_pointer_rtx,
553 offset));
554 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
555 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
556 RTX_FRAME_RELATED_P (pop_rtx) = 1;
557 offset = offset + 4;
558 par_index++;
561 /* Create (set fp mem), (set gp mem), and (set lp mem) if necessary. */
562 if (cfun->machine->fp_size)
564 reg = gen_rtx_REG (SImode, FP_REGNUM);
565 mem = gen_frame_mem (SImode, plus_constant (Pmode,
566 stack_pointer_rtx,
567 offset));
568 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
569 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
570 RTX_FRAME_RELATED_P (pop_rtx) = 1;
571 offset = offset + 4;
572 par_index++;
574 if (cfun->machine->gp_size)
576 reg = gen_rtx_REG (SImode, GP_REGNUM);
577 mem = gen_frame_mem (SImode, plus_constant (Pmode,
578 stack_pointer_rtx,
579 offset));
580 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
581 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
582 RTX_FRAME_RELATED_P (pop_rtx) = 1;
583 offset = offset + 4;
584 par_index++;
586 if (cfun->machine->lp_size)
588 reg = gen_rtx_REG (SImode, LP_REGNUM);
589 mem = gen_frame_mem (SImode, plus_constant (Pmode,
590 stack_pointer_rtx,
591 offset));
592 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
593 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
594 RTX_FRAME_RELATED_P (pop_rtx) = 1;
595 offset = offset + 4;
596 par_index++;
599 /* Create (set sp sp+x). */
601 /* The offset value is already in place. No need to re-calculate it. */
602 adjust_sp_rtx
603 = gen_rtx_SET (VOIDmode,
604 stack_pointer_rtx,
605 plus_constant (Pmode, stack_pointer_rtx, offset));
606 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
607 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
609 return parallel_insn;
612 /* Function to create a parallel rtx pattern
613 which presents stack v3push behavior.
614 The overall concept are:
615 "push registers to memory",
616 "adjust stack pointer". */
617 static rtx
618 nds32_gen_stack_v3push (rtx Rb,
619 rtx Re,
620 rtx En4 ATTRIBUTE_UNUSED,
621 rtx imm8u)
623 int regno;
624 int num_use_regs;
625 int par_index;
626 int offset;
628 rtx reg;
629 rtx mem;
630 rtx push_rtx;
631 rtx adjust_sp_rtx;
632 rtx parallel_insn;
634 /* We need to provide a customized rtx which contains
635 necessary information for data analysis,
636 so we create a parallel rtx like this:
637 (parallel [
638 (set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
639 (reg:SI Rb))
640 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
641 (reg:SI Rb+1))
643 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
644 (reg:SI Re))
645 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
646 (reg:SI FP_REGNUM))
647 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
648 (reg:SI GP_REGNUM))
649 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
650 (reg:SI LP_REGNUM))
651 (set (reg:SI SP_REGNUM)
652 (plus (reg:SI SP_REGNUM) (const_int -32-imm8u)))]) */
654 /* Calculate the number of registers that will be pushed.
655 Since $fp, $gp, and $lp is always pushed with v3push instruction,
656 we need to count these three registers.
657 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
658 So there is no need to worry about Rb=Re=SP_REGNUM case. */
659 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + 3;
661 /* In addition to used registers,
662 we need one more space for (set sp sp-x-imm8u) rtx. */
663 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
664 rtvec_alloc (num_use_regs + 1));
665 par_index = 0;
667 /* Initialize offset and start to create push behavior. */
668 offset = -(num_use_regs * 4);
670 /* Create (set mem regX) from Rb, Rb+1 up to Re.
671 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
672 So there is no need to worry about Rb=Re=SP_REGNUM case. */
673 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
675 reg = gen_rtx_REG (SImode, regno);
676 mem = gen_frame_mem (SImode, plus_constant (Pmode,
677 stack_pointer_rtx,
678 offset));
679 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
680 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
681 RTX_FRAME_RELATED_P (push_rtx) = 1;
682 offset = offset + 4;
683 par_index++;
686 /* Create (set mem fp). */
687 reg = gen_rtx_REG (SImode, FP_REGNUM);
688 mem = gen_frame_mem (SImode, plus_constant (Pmode,
689 stack_pointer_rtx,
690 offset));
691 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
692 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
693 RTX_FRAME_RELATED_P (push_rtx) = 1;
694 offset = offset + 4;
695 par_index++;
696 /* Create (set mem gp). */
697 reg = gen_rtx_REG (SImode, GP_REGNUM);
698 mem = gen_frame_mem (SImode, plus_constant (Pmode,
699 stack_pointer_rtx,
700 offset));
701 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
702 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
703 RTX_FRAME_RELATED_P (push_rtx) = 1;
704 offset = offset + 4;
705 par_index++;
706 /* Create (set mem lp). */
707 reg = gen_rtx_REG (SImode, LP_REGNUM);
708 mem = gen_frame_mem (SImode, plus_constant (Pmode,
709 stack_pointer_rtx,
710 offset));
711 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
712 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
713 RTX_FRAME_RELATED_P (push_rtx) = 1;
714 offset = offset + 4;
715 par_index++;
717 /* Create (set sp sp-x-imm8u). */
719 /* We need to re-calculate the offset value again for adjustment. */
720 offset = -(num_use_regs * 4);
721 adjust_sp_rtx
722 = gen_rtx_SET (VOIDmode,
723 stack_pointer_rtx,
724 plus_constant (Pmode,
725 stack_pointer_rtx,
726 offset - INTVAL (imm8u)));
727 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
728 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
730 return parallel_insn;
733 /* Function to create a parallel rtx pattern
734 which presents stack v3pop behavior.
735 The overall concept are:
736 "pop registers from memory",
737 "adjust stack pointer". */
738 static rtx
739 nds32_gen_stack_v3pop (rtx Rb,
740 rtx Re,
741 rtx En4 ATTRIBUTE_UNUSED,
742 rtx imm8u)
744 int regno;
745 int num_use_regs;
746 int par_index;
747 int offset;
749 rtx reg;
750 rtx mem;
751 rtx pop_rtx;
752 rtx adjust_sp_rtx;
753 rtx parallel_insn;
755 /* We need to provide a customized rtx which contains
756 necessary information for data analysis,
757 so we create a parallel rtx like this:
758 (parallel [(set (reg:SI Rb)
759 (mem (reg:SI SP_REGNUM)))
760 (set (reg:SI Rb+1)
761 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
763 (set (reg:SI Re)
764 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
765 (set (reg:SI FP_REGNUM)
766 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
767 (set (reg:SI GP_REGNUM)
768 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
769 (set (reg:SI LP_REGNUM)
770 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
771 (set (reg:SI SP_REGNUM)
772 (plus (reg:SI SP_REGNUM) (const_int 32+imm8u)))]) */
774 /* Calculate the number of registers that will be poped.
775 Since $fp, $gp, and $lp is always poped with v3pop instruction,
776 we need to count these three registers.
777 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
778 So there is no need to worry about Rb=Re=SP_REGNUM case. */
779 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + 3;
781 /* In addition to used registers,
782 we need one more space for (set sp sp+x+imm8u) rtx. */
783 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
784 rtvec_alloc (num_use_regs + 1));
785 par_index = 0;
787 /* Initialize offset and start to create pop behavior. */
788 offset = 0;
790 /* Create (set regX mem) from Rb, Rb+1 up to Re.
791 Under v3pop, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
792 So there is no need to worry about Rb=Re=SP_REGNUM case. */
793 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
795 reg = gen_rtx_REG (SImode, regno);
796 mem = gen_frame_mem (SImode, plus_constant (Pmode,
797 stack_pointer_rtx,
798 offset));
799 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
800 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
801 RTX_FRAME_RELATED_P (pop_rtx) = 1;
802 offset = offset + 4;
803 par_index++;
806 /* Create (set fp mem). */
807 reg = gen_rtx_REG (SImode, FP_REGNUM);
808 mem = gen_frame_mem (SImode, plus_constant (Pmode,
809 stack_pointer_rtx,
810 offset));
811 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
812 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
813 RTX_FRAME_RELATED_P (pop_rtx) = 1;
814 offset = offset + 4;
815 par_index++;
816 /* Create (set gp mem). */
817 reg = gen_rtx_REG (SImode, GP_REGNUM);
818 mem = gen_frame_mem (SImode, plus_constant (Pmode,
819 stack_pointer_rtx,
820 offset));
821 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
822 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
823 RTX_FRAME_RELATED_P (pop_rtx) = 1;
824 offset = offset + 4;
825 par_index++;
826 /* Create (set lp mem ). */
827 reg = gen_rtx_REG (SImode, LP_REGNUM);
828 mem = gen_frame_mem (SImode, plus_constant (Pmode,
829 stack_pointer_rtx,
830 offset));
831 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
832 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
833 RTX_FRAME_RELATED_P (pop_rtx) = 1;
834 offset = offset + 4;
835 par_index++;
837 /* Create (set sp sp+x+imm8u). */
839 /* The offset value is already in place. No need to re-calculate it. */
840 adjust_sp_rtx
841 = gen_rtx_SET (VOIDmode,
842 stack_pointer_rtx,
843 plus_constant (Pmode,
844 stack_pointer_rtx,
845 offset + INTVAL (imm8u)));
846 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
847 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
849 return parallel_insn;
852 /* A subroutine that checks multiple load and store
853 using consecutive registers.
854 OP is a parallel rtx we would like to check.
855 LOAD_P indicates whether we are checking load operation.
856 PAR_INDEX is starting element of parallel rtx.
857 FIRST_ELT_REGNO is used to tell starting register number.
858 COUNT helps us to check consecutive register numbers. */
859 static bool
860 nds32_consecutive_registers_load_store_p (rtx op,
861 bool load_p,
862 int par_index,
863 int first_elt_regno,
864 int count)
866 int i;
867 int check_regno;
868 rtx elt;
869 rtx elt_reg;
870 rtx elt_mem;
872 for (i = 0; i < count; i++)
874 /* Pick up each element from parallel rtx. */
875 elt = XVECEXP (op, 0, i + par_index);
877 /* If this element is not a 'set' rtx, return false immediately. */
878 if (GET_CODE (elt) != SET)
879 return false;
881 /* Pick up reg and mem of this element. */
882 elt_reg = load_p ? SET_DEST (elt) : SET_SRC (elt);
883 elt_mem = load_p ? SET_SRC (elt) : SET_DEST (elt);
885 /* If elt_reg is not a expected reg rtx, return false. */
886 if (GET_CODE (elt_reg) != REG || GET_MODE (elt_reg) != SImode)
887 return false;
888 /* If elt_mem is not a expected mem rtx, return false. */
889 if (GET_CODE (elt_mem) != MEM || GET_MODE (elt_mem) != SImode)
890 return false;
892 /* The consecutive registers should be in (Rb,Rb+1...Re) order. */
893 check_regno = first_elt_regno + i;
895 /* If the register number is not continuous, return false. */
896 if (REGNO (elt_reg) != (unsigned int) check_regno)
897 return false;
900 return true;
903 /* Function that may creates more instructions
904 for large value on adjusting stack pointer.
906 In nds32 target, 'addi' can be used for stack pointer
907 adjustment in prologue/epilogue stage.
908 However, sometimes there are too many local variables so that
909 the adjustment value is not able to be fit in the 'addi' instruction.
910 One solution is to move value into a register
911 and then use 'add' instruction.
912 In practice, we use TA_REGNUM ($r15) to accomplish this purpose.
913 Also, we need to return zero for sp adjustment so that
914 proglogue/epilogue knows there is no need to create 'addi' instruction. */
915 static int
916 nds32_force_addi_stack_int (int full_value)
918 int adjust_value;
920 rtx tmp_reg;
921 rtx sp_adjust_insn;
923 if (!satisfies_constraint_Is15 (GEN_INT (full_value)))
925 /* The value is not able to fit in single addi instruction.
926 Create more instructions of moving value into a register
927 and then add stack pointer with it. */
929 /* $r15 is going to be temporary register to hold the value. */
930 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
932 /* Create one more instruction to move value
933 into the temporary register. */
934 emit_move_insn (tmp_reg, GEN_INT (full_value));
936 /* Create new 'add' rtx. */
937 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
938 stack_pointer_rtx,
939 tmp_reg);
940 /* Emit rtx into insn list and receive its transformed insn rtx. */
941 sp_adjust_insn = emit_insn (sp_adjust_insn);
943 /* At prologue, we need to tell GCC that this is frame related insn,
944 so that we can consider this instruction to output debug information.
945 If full_value is NEGATIVE, it means this function
946 is invoked by expand_prologue. */
947 if (full_value < 0)
949 /* Because (tmp_reg <- full_value) may be split into two
950 rtl patterns, we can not set its RTX_FRAME_RELATED_P.
951 We need to construct another (sp <- sp + full_value)
952 and then insert it into sp_adjust_insn's reg note to
953 represent a frame related expression.
954 GCC knows how to refer it and output debug information. */
956 rtx plus_rtx;
957 rtx set_rtx;
959 plus_rtx = plus_constant (Pmode, stack_pointer_rtx, full_value);
960 set_rtx = gen_rtx_SET (VOIDmode, stack_pointer_rtx, plus_rtx);
961 add_reg_note (sp_adjust_insn, REG_FRAME_RELATED_EXPR, set_rtx);
963 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
966 /* We have used alternative way to adjust stack pointer value.
967 Return zero so that prologue/epilogue
968 will not generate other instructions. */
969 return 0;
971 else
973 /* The value is able to fit in addi instruction.
974 However, remember to make it to be positive value
975 because we want to return 'adjustment' result. */
976 adjust_value = (full_value < 0) ? (-full_value) : (full_value);
978 return adjust_value;
982 /* Return true if MODE/TYPE need double word alignment. */
983 static bool
984 nds32_needs_double_word_align (enum machine_mode mode, const_tree type)
986 unsigned int align;
988 /* Pick up the alignment according to the mode or type. */
989 align = NDS32_MODE_TYPE_ALIGN (mode, type);
991 return (align > PARM_BOUNDARY);
994 /* Return true if FUNC is a naked function. */
995 static bool
996 nds32_naked_function_p (tree func)
998 tree t;
1000 if (TREE_CODE (func) != FUNCTION_DECL)
1001 abort ();
1003 t = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
1005 return (t != NULL_TREE);
1008 /* Function that check if 'X' is a valid address register.
1009 The variable 'STRICT' is very important to
1010 make decision for register number.
1012 STRICT : true
1013 => We are in reload pass or after reload pass.
1014 The register number should be strictly limited in general registers.
1016 STRICT : false
1017 => Before reload pass, we are free to use any register number. */
1018 static bool
1019 nds32_address_register_rtx_p (rtx x, bool strict)
1021 int regno;
1023 if (GET_CODE (x) != REG)
1024 return false;
1026 regno = REGNO (x);
1028 if (strict)
1029 return REGNO_OK_FOR_BASE_P (regno);
1030 else
1031 return true;
1034 /* Function that check if 'INDEX' is valid to be a index rtx for address.
1036 OUTER_MODE : Machine mode of outer address rtx.
1037 INDEX : Check if this rtx is valid to be a index for address.
1038 STRICT : If it is true, we are in reload pass or after reload pass. */
1039 static bool
1040 nds32_legitimate_index_p (enum machine_mode outer_mode,
1041 rtx index,
1042 bool strict)
1044 int regno;
1045 rtx op0;
1046 rtx op1;
1048 switch (GET_CODE (index))
1050 case REG:
1051 regno = REGNO (index);
1052 /* If we are in reload pass or after reload pass,
1053 we need to limit it to general register. */
1054 if (strict)
1055 return REGNO_OK_FOR_INDEX_P (regno);
1056 else
1057 return true;
1059 case CONST_INT:
1060 /* The alignment of the integer value is determined by 'outer_mode'. */
1061 if (GET_MODE_SIZE (outer_mode) == 1)
1063 /* Further check if the value is legal for the 'outer_mode'. */
1064 if (!satisfies_constraint_Is15 (index))
1065 return false;
1067 /* Pass all test, the value is valid, return true. */
1068 return true;
1070 if (GET_MODE_SIZE (outer_mode) == 2
1071 && NDS32_HALF_WORD_ALIGN_P (INTVAL (index)))
1073 /* Further check if the value is legal for the 'outer_mode'. */
1074 if (!satisfies_constraint_Is16 (index))
1075 return false;
1077 /* Pass all test, the value is valid, return true. */
1078 return true;
1080 if (GET_MODE_SIZE (outer_mode) == 4
1081 && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index)))
1083 /* Further check if the value is legal for the 'outer_mode'. */
1084 if (!satisfies_constraint_Is17 (index))
1085 return false;
1087 /* Pass all test, the value is valid, return true. */
1088 return true;
1090 if (GET_MODE_SIZE (outer_mode) == 8
1091 && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index)))
1093 /* Further check if the value is legal for the 'outer_mode'. */
1094 if (!satisfies_constraint_Is17 (gen_int_mode (INTVAL (index) + 4,
1095 SImode)))
1096 return false;
1098 /* Pass all test, the value is valid, return true. */
1099 return true;
1102 return false;
1104 case MULT:
1105 op0 = XEXP (index, 0);
1106 op1 = XEXP (index, 1);
1108 if (REG_P (op0) && CONST_INT_P (op1))
1110 int multiplier;
1111 multiplier = INTVAL (op1);
1113 /* We only allow (mult reg const_int_1)
1114 or (mult reg const_int_2) or (mult reg const_int_4). */
1115 if (multiplier != 1 && multiplier != 2 && multiplier != 4)
1116 return false;
1118 regno = REGNO (op0);
1119 /* Limit it in general registers if we are
1120 in reload pass or after reload pass. */
1121 if(strict)
1122 return REGNO_OK_FOR_INDEX_P (regno);
1123 else
1124 return true;
1127 return false;
1129 case ASHIFT:
1130 op0 = XEXP (index, 0);
1131 op1 = XEXP (index, 1);
1133 if (REG_P (op0) && CONST_INT_P (op1))
1135 int sv;
1136 /* op1 is already the sv value for use to do left shift. */
1137 sv = INTVAL (op1);
1139 /* We only allow (ashift reg const_int_0)
1140 or (ashift reg const_int_1) or (ashift reg const_int_2). */
1141 if (sv != 0 && sv != 1 && sv !=2)
1142 return false;
1144 regno = REGNO (op0);
1145 /* Limit it in general registers if we are
1146 in reload pass or after reload pass. */
1147 if(strict)
1148 return REGNO_OK_FOR_INDEX_P (regno);
1149 else
1150 return true;
1153 return false;
1155 default:
1156 return false;
1160 /* Function to expand builtin function for
1161 '[(unspec_volatile [(reg)])]'. */
1162 static rtx
1163 nds32_expand_builtin_null_ftype_reg (enum insn_code icode,
1164 tree exp, rtx target)
1166 /* Mapping:
1167 ops[0] <--> value0 <--> arg0 */
1168 struct expand_operand ops[1];
1169 tree arg0;
1170 rtx value0;
1172 /* Grab the incoming arguments and extract its rtx. */
1173 arg0 = CALL_EXPR_ARG (exp, 0);
1174 value0 = expand_normal (arg0);
1176 /* Create operands. */
1177 create_input_operand (&ops[0], value0, TYPE_MODE (TREE_TYPE (arg0)));
1179 /* Emit new instruction. */
1180 if (!maybe_expand_insn (icode, 1, ops))
1181 error ("invalid argument to built-in function");
1183 return target;
1186 /* Function to expand builtin function for
1187 '[(set (reg) (unspec_volatile [(imm)]))]'. */
1188 static rtx
1189 nds32_expand_builtin_reg_ftype_imm (enum insn_code icode,
1190 tree exp, rtx target)
1192 /* Mapping:
1193 ops[0] <--> target <--> exp
1194 ops[1] <--> value0 <--> arg0 */
1195 struct expand_operand ops[2];
1196 tree arg0;
1197 rtx value0;
1199 /* Grab the incoming arguments and extract its rtx. */
1200 arg0 = CALL_EXPR_ARG (exp, 0);
1201 value0 = expand_normal (arg0);
1203 /* Create operands. */
1204 create_output_operand (&ops[0], target, TYPE_MODE (TREE_TYPE (exp)));
1205 create_input_operand (&ops[1], value0, TYPE_MODE (TREE_TYPE (arg0)));
1207 /* Emit new instruction. */
1208 if (!maybe_expand_insn (icode, 2, ops))
1209 error ("invalid argument to built-in function");
1211 return target;
1214 /* Function to expand builtin function for
1215 '[(unspec_volatile [(reg) (imm)])]' pattern. */
1216 static rtx
1217 nds32_expand_builtin_null_ftype_reg_imm (enum insn_code icode,
1218 tree exp, rtx target)
1220 /* Mapping:
1221 ops[0] <--> value0 <--> arg0
1222 ops[1] <--> value1 <--> arg1 */
1223 struct expand_operand ops[2];
1224 tree arg0, arg1;
1225 rtx value0, value1;
1227 /* Grab the incoming arguments and extract its rtx. */
1228 arg0 = CALL_EXPR_ARG (exp, 0);
1229 arg1 = CALL_EXPR_ARG (exp, 1);
1230 value0 = expand_normal (arg0);
1231 value1 = expand_normal (arg1);
1233 /* Create operands. */
1234 create_input_operand (&ops[0], value0, TYPE_MODE (TREE_TYPE (arg0)));
1235 create_input_operand (&ops[1], value1, TYPE_MODE (TREE_TYPE (arg1)));
1237 /* Emit new instruction. */
1238 if (!maybe_expand_insn (icode, 2, ops))
1239 error ("invalid argument to built-in function");
1241 return target;
1244 /* A helper function to return character based on byte size. */
1245 static char
1246 nds32_byte_to_size (int byte)
1248 switch (byte)
1250 case 4:
1251 return 'w';
1252 case 2:
1253 return 'h';
1254 case 1:
1255 return 'b';
1256 default:
1257 /* Normally it should not be here. */
1258 gcc_unreachable ();
1262 /* A helper function to check if this function should contain prologue. */
1263 static int
1264 nds32_have_prologue_p (void)
1266 int i;
1268 for (i = 0; i < 28; i++)
1269 if (NDS32_REQUIRED_CALLEE_SAVED_P (i))
1270 return 1;
1272 return (flag_pic
1273 || NDS32_REQUIRED_CALLEE_SAVED_P (FP_REGNUM)
1274 || NDS32_REQUIRED_CALLEE_SAVED_P (LP_REGNUM));
1277 /* ------------------------------------------------------------------------ */
1279 /* PART 3: Implement target hook stuff definitions. */
1281 /* Register Classes. */
1283 static unsigned char
1284 nds32_class_max_nregs (reg_class_t rclass ATTRIBUTE_UNUSED,
1285 enum machine_mode mode)
1287 /* Return the maximum number of consecutive registers
1288 needed to represent "mode" in a register of "rclass". */
1289 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1292 static int
1293 nds32_register_priority (int hard_regno)
1295 /* Encourage to use r0-r7 for LRA when optimize for size. */
1296 if (optimize_size && hard_regno < 8)
1297 return 4;
1298 return 3;
1302 /* Stack Layout and Calling Conventions. */
1304 /* There are three kinds of pointer concepts using in GCC compiler:
1306 frame pointer: A pointer to the first location of local variables.
1307 stack pointer: A pointer to the top of a stack frame.
1308 argument pointer: A pointer to the incoming arguments.
1310 In nds32 target calling convention, we are using 8-byte alignment.
1311 Besides, we would like to have each stack frame of a function includes:
1313 [Block A]
1314 1. previous hard frame pointer
1315 2. return address
1316 3. callee-saved registers
1317 4. <padding bytes> (we will calculte in nds32_compute_stack_frame()
1318 and save it at
1319 cfun->machine->callee_saved_area_padding_bytes)
1321 [Block B]
1322 1. local variables
1323 2. spilling location
1324 3. <padding bytes> (it will be calculated by GCC itself)
1325 4. incoming arguments
1326 5. <padding bytes> (it will be calculated by GCC itself)
1328 [Block C]
1329 1. <padding bytes> (it will be calculated by GCC itself)
1330 2. outgoing arguments
1332 We 'wrap' these blocks together with
1333 hard frame pointer ($r28) and stack pointer ($r31).
1334 By applying the basic frame/stack/argument pointers concept,
1335 the layout of a stack frame shoule be like this:
1338 old stack pointer -> ----
1339 | | \
1340 | | saved arguments for
1341 | | vararg functions
1342 | | /
1343 hard frame pointer -> --
1344 & argument pointer | | \
1345 | | previous hardware frame pointer
1346 | | return address
1347 | | callee-saved registers
1348 | | /
1349 frame pointer -> --
1350 | | \
1351 | | local variables
1352 | | and incoming arguments
1353 | | /
1355 | | \
1356 | | outgoing
1357 | | arguments
1358 | | /
1359 stack pointer -> ----
1361 $SFP and $AP are used to represent frame pointer and arguments pointer,
1362 which will be both eliminated as hard frame pointer. */
1364 /* -- Eliminating Frame Pointer and Arg Pointer. */
1366 static bool nds32_can_eliminate (const int from_reg, const int to_reg)
1368 if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
1369 return true;
1371 if (from_reg == ARG_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM)
1372 return true;
1374 if (from_reg == FRAME_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
1375 return true;
1377 if (from_reg == FRAME_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM)
1378 return true;
1380 return false;
1383 /* -- Passing Arguments in Registers. */
1385 static rtx
1386 nds32_function_arg (cumulative_args_t ca, enum machine_mode mode,
1387 const_tree type, bool named)
1389 CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
1391 /* The last time this hook is called,
1392 it is called with MODE == VOIDmode. */
1393 if (mode == VOIDmode)
1394 return NULL_RTX;
1396 /* For nameless arguments, they are passed on the stack. */
1397 if (!named)
1398 return NULL_RTX;
1400 /* If there are still registers available, return it. */
1401 if (NDS32_ARG_PASS_IN_REG_P (cum->reg_offset, mode, type))
1403 /* Pick up the next available register number. */
1404 unsigned int regno;
1406 regno = NDS32_AVAILABLE_REGNUM_FOR_ARG (cum->reg_offset, mode, type);
1407 return gen_rtx_REG (mode, regno);
1409 else
1411 /* No register available, return NULL_RTX.
1412 The compiler will use stack to pass argument instead. */
1413 return NULL_RTX;
1417 static void
1418 nds32_function_arg_advance (cumulative_args_t ca, enum machine_mode mode,
1419 const_tree type, bool named)
1421 CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
1423 /* Advance next register for use.
1424 Only named argument could be advanced. */
1425 if (named)
1427 cum->reg_offset
1428 = NDS32_AVAILABLE_REGNUM_FOR_ARG (cum->reg_offset, mode, type)
1429 - NDS32_GPR_ARG_FIRST_REGNUM
1430 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1434 static unsigned int
1435 nds32_function_arg_boundary (enum machine_mode mode, const_tree type)
1437 return (nds32_needs_double_word_align (mode, type)
1438 ? NDS32_DOUBLE_WORD_ALIGNMENT
1439 : PARM_BOUNDARY);
1442 /* -- How Scalar Function Values Are Returned. */
1444 static rtx
1445 nds32_function_value (const_tree ret_type,
1446 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
1447 bool outgoing ATTRIBUTE_UNUSED)
1449 enum machine_mode mode;
1450 int unsignedp;
1452 mode = TYPE_MODE (ret_type);
1453 unsignedp = TYPE_UNSIGNED (ret_type);
1455 mode = promote_mode (ret_type, mode, &unsignedp);
1457 return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM);
1460 static rtx
1461 nds32_libcall_value (enum machine_mode mode,
1462 const_rtx fun ATTRIBUTE_UNUSED)
1464 return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM);
1467 static bool
1468 nds32_function_value_regno_p (const unsigned int regno)
1470 return (regno == NDS32_GPR_RET_FIRST_REGNUM);
1473 /* -- Function Entry and Exit. */
1475 /* The content produced from this function
1476 will be placed before prologue body. */
1477 static void
1478 nds32_asm_function_prologue (FILE *file,
1479 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
1481 int r;
1482 const char *func_name;
1483 tree attrs;
1484 tree name;
1486 /* All stack frame information is supposed to be
1487 already computed when expanding prologue.
1488 The result is in cfun->machine.
1489 DO NOT call nds32_compute_stack_frame() here
1490 because it may corrupt the essential information. */
1492 fprintf (file, "\t! BEGIN PROLOGUE\n");
1493 fprintf (file, "\t! fp needed: %d\n", frame_pointer_needed);
1494 fprintf (file, "\t! pretend_args: %d\n", cfun->machine->va_args_size);
1495 fprintf (file, "\t! local_size: %d\n", cfun->machine->local_size);
1496 fprintf (file, "\t! out_args_size: %d\n", cfun->machine->out_args_size);
1498 /* Use df_regs_ever_live_p() to detect if the register
1499 is ever used in the current function. */
1500 fprintf (file, "\t! registers ever_live: ");
1501 for (r = 0; r < 32; r++)
1503 if (df_regs_ever_live_p (r))
1504 fprintf (file, "%s, ", reg_names[r]);
1506 fputc ('\n', file);
1508 /* Display the attributes of this function. */
1509 fprintf (file, "\t! function attributes: ");
1510 /* Get the attributes tree list.
1511 Note that GCC builds attributes list with reverse order. */
1512 attrs = DECL_ATTRIBUTES (current_function_decl);
1514 /* If there is no any attribute, print out "None". */
1515 if (!attrs)
1516 fprintf (file, "None");
1518 /* If there are some attributes, try if we need to
1519 construct isr vector information. */
1520 func_name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
1521 nds32_construct_isr_vectors_information (attrs, func_name);
1523 /* Display all attributes of this function. */
1524 while (attrs)
1526 name = TREE_PURPOSE (attrs);
1527 fprintf (file, "%s ", IDENTIFIER_POINTER (name));
1529 /* Pick up the next attribute. */
1530 attrs = TREE_CHAIN (attrs);
1532 fputc ('\n', file);
1535 /* After rtl prologue has been expanded, this function is used. */
1536 static void
1537 nds32_asm_function_end_prologue (FILE *file)
1539 fprintf (file, "\t! END PROLOGUE\n");
1541 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
1542 we can generate special directive: ".omit_fp_begin"
1543 to guide linker doing fp-as-gp optimization.
1544 However, for a naked function, which means
1545 it should not have prologue/epilogue,
1546 using fp-as-gp still requires saving $fp by push/pop behavior and
1547 there is no benefit to use fp-as-gp on such small function.
1548 So we need to make sure this function is NOT naked as well. */
1549 if (!frame_pointer_needed
1550 && !cfun->machine->naked_p
1551 && cfun->machine->fp_as_gp_p)
1553 fprintf (file, "\t! ----------------------------------------\n");
1554 fprintf (file, "\t! Guide linker to do "
1555 "link time optimization: fp-as-gp\n");
1556 fprintf (file, "\t! We add one more instruction to "
1557 "initialize $fp near to $gp location.\n");
1558 fprintf (file, "\t! If linker fails to use fp-as-gp transformation,\n");
1559 fprintf (file, "\t! this extra instruction should be "
1560 "eliminated at link stage.\n");
1561 fprintf (file, "\t.omit_fp_begin\n");
1562 fprintf (file, "\tla\t$fp,_FP_BASE_\n");
1563 fprintf (file, "\t! ----------------------------------------\n");
1567 /* Before rtl epilogue has been expanded, this function is used. */
1568 static void
1569 nds32_asm_function_begin_epilogue (FILE *file)
1571 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
1572 we can generate special directive: ".omit_fp_end"
1573 to claim fp-as-gp optimization range.
1574 However, for a naked function,
1575 which means it should not have prologue/epilogue,
1576 using fp-as-gp still requires saving $fp by push/pop behavior and
1577 there is no benefit to use fp-as-gp on such small function.
1578 So we need to make sure this function is NOT naked as well. */
1579 if (!frame_pointer_needed
1580 && !cfun->machine->naked_p
1581 && cfun->machine->fp_as_gp_p)
1583 fprintf (file, "\t! ----------------------------------------\n");
1584 fprintf (file, "\t! Claim the range of fp-as-gp "
1585 "link time optimization\n");
1586 fprintf (file, "\t.omit_fp_end\n");
1587 fprintf (file, "\t! ----------------------------------------\n");
1590 fprintf (file, "\t! BEGIN EPILOGUE\n");
1593 /* The content produced from this function
1594 will be placed after epilogue body. */
1595 static void
1596 nds32_asm_function_epilogue (FILE *file,
1597 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
1599 fprintf (file, "\t! END EPILOGUE\n");
1602 static void
1603 nds32_asm_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
1604 HOST_WIDE_INT delta,
1605 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
1606 tree function)
1608 int this_regno;
1610 /* Make sure unwind info is emitted for the thunk if needed. */
1611 final_start_function (emit_barrier (), file, 1);
1613 this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function)
1615 : 0);
1617 if (delta != 0)
1619 if (satisfies_constraint_Is15 (GEN_INT (delta)))
1621 fprintf (file, "\taddi\t$r%d, $r%d, %ld\n",
1622 this_regno, this_regno, delta);
1624 else if (satisfies_constraint_Is20 (GEN_INT (delta)))
1626 fprintf (file, "\tmovi\t$ta, %ld\n", delta);
1627 fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno);
1629 else
1631 fprintf (file, "\tsethi\t$ta, hi20(%ld)\n", delta);
1632 fprintf (file, "\tori\t$ta, $ta, lo12(%ld)\n", delta);
1633 fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno);
1637 fprintf (file, "\tb\t");
1638 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
1639 fprintf (file, "\n");
1641 final_end_function ();
1644 /* -- Permitting tail calls. */
1646 /* Determine whether we need to enable warning for function return check. */
1647 static bool
1648 nds32_warn_func_return (tree decl)
1650 /* Naked functions are implemented entirely in assembly, including the
1651 return sequence, so suppress warnings about this. */
1652 return !nds32_naked_function_p (decl);
1656 /* Implementing the Varargs Macros. */
1658 static bool
1659 nds32_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED)
1661 /* Return true so that all the named arguments for FUNCTION_ARG have named=1.
1662 If return false, for the variadic function, all named arguments EXCEPT
1663 the last are treated as named. */
1664 return true;
1668 /* Trampolines for Nested Functions. */
1670 static void
1671 nds32_asm_trampoline_template (FILE *f)
1673 if (TARGET_REDUCED_REGS)
1675 /* Trampoline is not supported on reduced-set registers yet. */
1676 sorry ("a nested function is not supported for reduced registers");
1678 else
1680 asm_fprintf (f, "\t! Trampoline code template\n");
1681 asm_fprintf (f, "\t! This code fragment will be copied "
1682 "into stack on demand\n");
1684 asm_fprintf (f, "\tmfusr\t$r16,$pc\n");
1685 asm_fprintf (f, "\tlwi\t$r15,[$r16 + 20] "
1686 "! load nested function address\n");
1687 asm_fprintf (f, "\tlwi\t$r16,[$r16 + 16] "
1688 "! load chain_value\n");
1689 asm_fprintf (f, "\tjr\t$r15\n");
1692 /* Preserve space ($pc + 16) for saving chain_value,
1693 nds32_trampoline_init will fill the value in this slot. */
1694 asm_fprintf (f, "\t! space for saving chain_value\n");
1695 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
1697 /* Preserve space ($pc + 20) for saving nested function address,
1698 nds32_trampoline_init will fill the value in this slot. */
1699 asm_fprintf (f, "\t! space for saving nested function address\n");
1700 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
1703 /* Emit RTL insns to initialize the variable parts of a trampoline. */
1704 static void
1705 nds32_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
1707 int i;
1709 /* Nested function address. */
1710 rtx fnaddr;
1711 /* The memory rtx that is going to
1712 be filled with chain_value. */
1713 rtx chain_value_mem;
1714 /* The memory rtx that is going to
1715 be filled with nested function address. */
1716 rtx nested_func_mem;
1718 /* Start address of trampoline code in stack, for doing cache sync. */
1719 rtx sync_cache_addr;
1720 /* Temporary register for sync instruction. */
1721 rtx tmp_reg;
1722 /* Instruction-cache sync instruction,
1723 requesting an argument as starting address. */
1724 rtx isync_insn;
1725 /* For convenience reason of doing comparison. */
1726 int tramp_align_in_bytes;
1728 /* Trampoline is not supported on reduced-set registers yet. */
1729 if (TARGET_REDUCED_REGS)
1730 sorry ("a nested function is not supported for reduced registers");
1732 /* STEP 1: Copy trampoline code template into stack,
1733 fill up essential data into stack. */
1735 /* Extract nested function address rtx. */
1736 fnaddr = XEXP (DECL_RTL (fndecl), 0);
1738 /* m_tramp is memory rtx that is going to be filled with trampoline code.
1739 We have nds32_asm_trampoline_template() to emit template pattern. */
1740 emit_block_move (m_tramp, assemble_trampoline_template (),
1741 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
1743 /* After copying trampoline code into stack,
1744 fill chain_value into stack. */
1745 chain_value_mem = adjust_address (m_tramp, SImode, 16);
1746 emit_move_insn (chain_value_mem, chain_value);
1747 /* After copying trampoline code int stack,
1748 fill nested function address into stack. */
1749 nested_func_mem = adjust_address (m_tramp, SImode, 20);
1750 emit_move_insn (nested_func_mem, fnaddr);
1752 /* STEP 2: Sync instruction-cache. */
1754 /* We have successfully filled trampoline code into stack.
1755 However, in order to execute code in stack correctly,
1756 we must sync instruction cache. */
1757 sync_cache_addr = XEXP (m_tramp, 0);
1758 tmp_reg = gen_reg_rtx (SImode);
1759 isync_insn = gen_unspec_volatile_isync (tmp_reg);
1761 /* Because nds32_cache_block_size is in bytes,
1762 we get trampoline alignment in bytes for convenient comparison. */
1763 tramp_align_in_bytes = TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT;
1765 if (tramp_align_in_bytes >= nds32_cache_block_size
1766 && (tramp_align_in_bytes % nds32_cache_block_size) == 0)
1768 /* Under this condition, the starting address of trampoline
1769 must be aligned to the starting address of each cache block
1770 and we do not have to worry about cross-boundary issue. */
1771 for (i = 0;
1772 i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1)
1773 / nds32_cache_block_size;
1774 i++)
1776 emit_move_insn (tmp_reg,
1777 plus_constant (Pmode, sync_cache_addr,
1778 nds32_cache_block_size * i));
1779 emit_insn (isync_insn);
1782 else if (TRAMPOLINE_SIZE > nds32_cache_block_size)
1784 /* The starting address of trampoline code
1785 may not be aligned to the cache block,
1786 so the trampoline code may be across two cache block.
1787 We need to sync the last element, which is 4-byte size,
1788 of trampoline template. */
1789 for (i = 0;
1790 i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1)
1791 / nds32_cache_block_size;
1792 i++)
1794 emit_move_insn (tmp_reg,
1795 plus_constant (Pmode, sync_cache_addr,
1796 nds32_cache_block_size * i));
1797 emit_insn (isync_insn);
1800 /* The last element of trampoline template is 4-byte size. */
1801 emit_move_insn (tmp_reg,
1802 plus_constant (Pmode, sync_cache_addr,
1803 TRAMPOLINE_SIZE - 4));
1804 emit_insn (isync_insn);
1806 else
1808 /* This is the simplest case.
1809 Because TRAMPOLINE_SIZE is less than or
1810 equal to nds32_cache_block_size,
1811 we can just sync start address and
1812 the last element of trampoline code. */
1814 /* Sync starting address of tampoline code. */
1815 emit_move_insn (tmp_reg, sync_cache_addr);
1816 emit_insn (isync_insn);
1817 /* Sync the last element, which is 4-byte size,
1818 of trampoline template. */
1819 emit_move_insn (tmp_reg,
1820 plus_constant (Pmode, sync_cache_addr,
1821 TRAMPOLINE_SIZE - 4));
1822 emit_insn (isync_insn);
1825 /* Set instruction serialization barrier
1826 to guarantee the correct operations. */
1827 emit_insn (gen_unspec_volatile_isb ());
1831 /* Addressing Modes. */
1833 static bool
1834 nds32_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
1836 /* For (mem:DI addr) or (mem:DF addr) case,
1837 we only allow 'addr' to be [reg], [symbol_ref],
1838 [const], or [reg + const_int] pattern. */
1839 if (mode == DImode || mode == DFmode)
1841 /* Allow [Reg + const_int] addressing mode. */
1842 if (GET_CODE (x) == PLUS)
1844 if (nds32_address_register_rtx_p (XEXP (x, 0), strict)
1845 && nds32_legitimate_index_p (mode, XEXP (x, 1), strict)
1846 && CONST_INT_P (XEXP (x, 1)))
1847 return true;
1849 else if (nds32_address_register_rtx_p (XEXP (x, 1), strict)
1850 && nds32_legitimate_index_p (mode, XEXP (x, 0), strict)
1851 && CONST_INT_P (XEXP (x, 0)))
1852 return true;
1855 /* Now check [reg], [symbol_ref], and [const]. */
1856 if (GET_CODE (x) != REG
1857 && GET_CODE (x) != SYMBOL_REF
1858 && GET_CODE (x) != CONST)
1859 return false;
1862 /* Check if 'x' is a valid address. */
1863 switch (GET_CODE (x))
1865 case REG:
1866 /* (mem (reg A)) => [Ra] */
1867 return nds32_address_register_rtx_p (x, strict);
1869 case SYMBOL_REF:
1871 if (!TARGET_GP_DIRECT
1872 && (reload_completed
1873 || reload_in_progress
1874 || lra_in_progress))
1875 return false;
1877 /* (mem (symbol_ref A)) => [symbol_ref] */
1878 return !currently_expanding_to_rtl;
1880 case CONST:
1882 if (!TARGET_GP_DIRECT
1883 && (reload_completed
1884 || reload_in_progress
1885 || lra_in_progress))
1886 return false;
1888 /* (mem (const (...)))
1889 => [ + const_addr ], where const_addr = symbol_ref + const_int */
1890 if (GET_CODE (XEXP (x, 0)) == PLUS)
1892 rtx plus_op = XEXP (x, 0);
1894 rtx op0 = XEXP (plus_op, 0);
1895 rtx op1 = XEXP (plus_op, 1);
1897 if (GET_CODE (op0) == SYMBOL_REF && CONST_INT_P (op1))
1898 return true;
1899 else
1900 return false;
1903 return false;
1905 case POST_MODIFY:
1906 /* (mem (post_modify (reg) (plus (reg) (reg))))
1907 => [Ra], Rb */
1908 /* (mem (post_modify (reg) (plus (reg) (const_int))))
1909 => [Ra], const_int */
1910 if (GET_CODE (XEXP (x, 0)) == REG
1911 && GET_CODE (XEXP (x, 1)) == PLUS)
1913 rtx plus_op = XEXP (x, 1);
1915 rtx op0 = XEXP (plus_op, 0);
1916 rtx op1 = XEXP (plus_op, 1);
1918 if (nds32_address_register_rtx_p (op0, strict)
1919 && nds32_legitimate_index_p (mode, op1, strict))
1920 return true;
1921 else
1922 return false;
1925 return false;
1927 case POST_INC:
1928 case POST_DEC:
1929 /* (mem (post_inc reg)) => [Ra], 1/2/4 */
1930 /* (mem (post_dec reg)) => [Ra], -1/-2/-4 */
1931 /* The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
1932 We only need to deal with register Ra. */
1933 if (nds32_address_register_rtx_p (XEXP (x, 0), strict))
1934 return true;
1935 else
1936 return false;
1938 case PLUS:
1939 /* (mem (plus reg const_int))
1940 => [Ra + imm] */
1941 /* (mem (plus reg reg))
1942 => [Ra + Rb] */
1943 /* (mem (plus (mult reg const_int) reg))
1944 => [Ra + Rb << sv] */
1945 if (nds32_address_register_rtx_p (XEXP (x, 0), strict)
1946 && nds32_legitimate_index_p (mode, XEXP (x, 1), strict))
1947 return true;
1948 else if (nds32_address_register_rtx_p (XEXP (x, 1), strict)
1949 && nds32_legitimate_index_p (mode, XEXP (x, 0), strict))
1950 return true;
1951 else
1952 return false;
1954 case LO_SUM:
1955 if (!TARGET_GP_DIRECT)
1956 return true;
1958 default:
1959 return false;
1964 /* Describing Relative Costs of Operations. */
1966 static int nds32_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
1967 reg_class_t from,
1968 reg_class_t to)
1970 if (from == HIGH_REGS || to == HIGH_REGS)
1971 return 6;
1973 return 2;
1976 static int nds32_memory_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
1977 reg_class_t rclass ATTRIBUTE_UNUSED,
1978 bool in ATTRIBUTE_UNUSED)
1980 return 8;
1983 /* This target hook describes the relative costs of RTL expressions.
1984 Return 'true' when all subexpressions of x have been processed.
1985 Return 'false' to sum the costs of sub-rtx, plus cost of this operation.
1986 Refer to gcc/rtlanal.c for more information. */
1987 static bool
1988 nds32_rtx_costs (rtx x,
1989 int code,
1990 int outer_code,
1991 int opno ATTRIBUTE_UNUSED,
1992 int *total,
1993 bool speed)
1995 /* According to 'speed', goto suitable cost model section. */
1996 if (speed)
1997 goto performance_cost;
1998 else
1999 goto size_cost;
2002 performance_cost:
2003 /* This is section for performance cost model. */
2005 /* In gcc/rtl.h, the default value of COSTS_N_INSNS(N) is N*4.
2006 We treat it as 4-cycle cost for each instruction
2007 under performance consideration. */
2008 switch (code)
2010 case SET:
2011 /* For 'SET' rtx, we need to return false
2012 so that it can recursively calculate costs. */
2013 return false;
2015 case USE:
2016 /* Used in combine.c as a marker. */
2017 *total = 0;
2018 break;
2020 case MULT:
2021 *total = COSTS_N_INSNS (1);
2022 break;
2024 case DIV:
2025 case UDIV:
2026 case MOD:
2027 case UMOD:
2028 *total = COSTS_N_INSNS (7);
2029 break;
2031 default:
2032 *total = COSTS_N_INSNS (1);
2033 break;
2036 return true;
2039 size_cost:
2040 /* This is section for size cost model. */
2042 /* In gcc/rtl.h, the default value of COSTS_N_INSNS(N) is N*4.
2043 We treat it as 4-byte cost for each instruction
2044 under code size consideration. */
2045 switch (code)
2047 case SET:
2048 /* For 'SET' rtx, we need to return false
2049 so that it can recursively calculate costs. */
2050 return false;
2052 case USE:
2053 /* Used in combine.c as a marker. */
2054 *total = 0;
2055 break;
2057 case CONST_INT:
2058 /* All instructions involving constant operation
2059 need to be considered for cost evaluation. */
2060 if (outer_code == SET)
2062 /* (set X imm5s), use movi55, 2-byte cost.
2063 (set X imm20s), use movi, 4-byte cost.
2064 (set X BIG_INT), use sethi/ori, 8-byte cost. */
2065 if (satisfies_constraint_Is05 (x))
2066 *total = COSTS_N_INSNS (1) - 2;
2067 else if (satisfies_constraint_Is20 (x))
2068 *total = COSTS_N_INSNS (1);
2069 else
2070 *total = COSTS_N_INSNS (2);
2072 else if (outer_code == PLUS || outer_code == MINUS)
2074 /* Possible addi333/subi333 or subi45/addi45, 2-byte cost.
2075 General case, cost 1 instruction with 4-byte. */
2076 if (satisfies_constraint_Iu05 (x))
2077 *total = COSTS_N_INSNS (1) - 2;
2078 else
2079 *total = COSTS_N_INSNS (1);
2081 else if (outer_code == ASHIFT)
2083 /* Possible slli333, 2-byte cost.
2084 General case, cost 1 instruction with 4-byte. */
2085 if (satisfies_constraint_Iu03 (x))
2086 *total = COSTS_N_INSNS (1) - 2;
2087 else
2088 *total = COSTS_N_INSNS (1);
2090 else if (outer_code == ASHIFTRT || outer_code == LSHIFTRT)
2092 /* Possible srai45 or srli45, 2-byte cost.
2093 General case, cost 1 instruction with 4-byte. */
2094 if (satisfies_constraint_Iu05 (x))
2095 *total = COSTS_N_INSNS (1) - 2;
2096 else
2097 *total = COSTS_N_INSNS (1);
2099 else
2101 /* For other cases, simply set it 4-byte cost. */
2102 *total = COSTS_N_INSNS (1);
2104 break;
2106 case CONST_DOUBLE:
2107 /* It requires high part and low part processing, set it 8-byte cost. */
2108 *total = COSTS_N_INSNS (2);
2109 break;
2111 default:
2112 /* For other cases, generally we set it 4-byte cost
2113 and stop resurively traversing. */
2114 *total = COSTS_N_INSNS (1);
2115 break;
2118 return true;
2121 static int nds32_address_cost (rtx address,
2122 enum machine_mode mode ATTRIBUTE_UNUSED,
2123 addr_space_t as ATTRIBUTE_UNUSED,
2124 bool speed)
2126 rtx plus0, plus1;
2127 enum rtx_code code;
2129 code = GET_CODE (address);
2131 /* According to 'speed', goto suitable cost model section. */
2132 if (speed)
2133 goto performance_cost;
2134 else
2135 goto size_cost;
2137 performance_cost:
2138 /* This is section for performance cost model. */
2140 /* FALLTHRU, currently we use same cost model as size_cost. */
2142 size_cost:
2143 /* This is section for size cost model. */
2145 switch (code)
2147 case POST_MODIFY:
2148 case POST_INC:
2149 case POST_DEC:
2150 /* We encourage that rtx contains
2151 POST_MODIFY/POST_INC/POST_DEC behavior. */
2152 return 0;
2154 case SYMBOL_REF:
2155 /* We can have gp-relative load/store for symbol_ref.
2156 Have it 4-byte cost. */
2157 return COSTS_N_INSNS (1);
2159 case CONST:
2160 /* It is supposed to be the pattern (const (plus symbol_ref const_int)).
2161 Have it 4-byte cost. */
2162 return COSTS_N_INSNS (1);
2164 case REG:
2165 /* Simply return 4-byte costs. */
2166 return COSTS_N_INSNS (1);
2168 case PLUS:
2169 /* We do not need to check if the address is a legitimate address,
2170 because this hook is never called with an invalid address.
2171 But we better check the range of
2172 const_int value for cost, if it exists. */
2173 plus0 = XEXP (address, 0);
2174 plus1 = XEXP (address, 1);
2176 if (REG_P (plus0) && CONST_INT_P (plus1))
2178 /* If it is possible to be lwi333/swi333 form,
2179 make it 2-byte cost. */
2180 if (satisfies_constraint_Iu05 (plus1))
2181 return (COSTS_N_INSNS (1) - 2);
2182 else
2183 return COSTS_N_INSNS (1);
2186 /* For other 'plus' situation, make it cost 4-byte. */
2187 return COSTS_N_INSNS (1);
2189 default:
2190 break;
2193 return COSTS_N_INSNS (4);
2197 /* Defining the Output Assembler Language. */
2199 /* -- The Overall Framework of an Assembler File. */
2201 static void
2202 nds32_asm_file_start (void)
2204 default_file_start ();
2206 /* Tell assembler which ABI we are using. */
2207 fprintf (asm_out_file, "\t! ABI version\n");
2208 fprintf (asm_out_file, "\t.abi_2\n");
2210 /* Tell assembler that this asm code is generated by compiler. */
2211 fprintf (asm_out_file, "\t! This asm file is generated by compiler\n");
2212 fprintf (asm_out_file, "\t.flag\tverbatim\n");
2213 /* Give assembler the size of each vector for interrupt handler. */
2214 fprintf (asm_out_file, "\t! This vector size directive is required "
2215 "for checking inconsistency on interrupt handler\n");
2216 fprintf (asm_out_file, "\t.vec_size\t%d\n", nds32_isr_vector_size);
2218 /* If user enables '-mforce-fp-as-gp' or compiles programs with -Os,
2219 the compiler may produce 'la $fp,_FP_BASE_' instruction
2220 at prologue for fp-as-gp optimization.
2221 We should emit weak reference of _FP_BASE_ to avoid undefined reference
2222 in case user does not pass '--relax' option to linker. */
2223 if (TARGET_FORCE_FP_AS_GP || optimize_size)
2225 fprintf (asm_out_file, "\t! This weak reference is required to do "
2226 "fp-as-gp link time optimization\n");
2227 fprintf (asm_out_file, "\t.weak\t_FP_BASE_\n");
2229 /* If user enables '-mex9', we should emit relaxation directive
2230 to tell linker that this file is allowed to do ex9 optimization. */
2231 if (TARGET_EX9)
2233 fprintf (asm_out_file, "\t! This relaxation directive is required "
2234 "to do ex9 link time optimization\n");
2235 fprintf (asm_out_file, "\t.relax\tex9\n");
2238 fprintf (asm_out_file, "\t! ------------------------------------\n");
2240 if (TARGET_ISA_V2)
2241 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V2");
2242 if (TARGET_ISA_V3)
2243 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3");
2244 if (TARGET_ISA_V3M)
2245 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3M");
2247 fprintf (asm_out_file, "\t! Endian setting\t: %s\n",
2248 ((TARGET_BIG_ENDIAN) ? "big-endian"
2249 : "little-endian"));
2251 fprintf (asm_out_file, "\t! ------------------------------------\n");
2253 fprintf (asm_out_file, "\t! Use conditional move\t\t: %s\n",
2254 ((TARGET_CMOV) ? "Yes"
2255 : "No"));
2256 fprintf (asm_out_file, "\t! Use performance extension\t: %s\n",
2257 ((TARGET_PERF_EXT) ? "Yes"
2258 : "No"));
2260 fprintf (asm_out_file, "\t! ------------------------------------\n");
2262 fprintf (asm_out_file, "\t! V3PUSH instructions\t: %s\n",
2263 ((TARGET_V3PUSH) ? "Yes"
2264 : "No"));
2265 fprintf (asm_out_file, "\t! 16-bit instructions\t: %s\n",
2266 ((TARGET_16_BIT) ? "Yes"
2267 : "No"));
2268 fprintf (asm_out_file, "\t! GP base access\t: %s\n",
2269 ((TARGET_GP_DIRECT) ? "Yes"
2270 : "No"));
2271 fprintf (asm_out_file, "\t! Reduced registers set\t: %s\n",
2272 ((TARGET_REDUCED_REGS) ? "Yes"
2273 : "No"));
2275 fprintf (asm_out_file, "\t! ------------------------------------\n");
2277 if (optimize_size)
2278 fprintf (asm_out_file, "\t! Optimization level\t: -Os\n");
2279 else
2280 fprintf (asm_out_file, "\t! Optimization level\t: -O%d\n", optimize);
2282 fprintf (asm_out_file, "\t! ------------------------------------\n");
2284 fprintf (asm_out_file, "\t! Cache block size\t: %d\n",
2285 nds32_cache_block_size);
2287 fprintf (asm_out_file, "\t! ------------------------------------\n");
2289 nds32_asm_file_start_for_isr ();
2292 static void
2293 nds32_asm_file_end (void)
2295 nds32_asm_file_end_for_isr ();
2297 fprintf (asm_out_file, "\t! ------------------------------------\n");
2300 /* -- Output and Generation of Labels. */
2302 static void
2303 nds32_asm_globalize_label (FILE *stream, const char *name)
2305 fputs ("\t.global\t", stream);
2306 assemble_name (stream, name);
2307 fputs ("\n", stream);
2310 /* -- Output of Assembler Instructions. */
2312 static void
2313 nds32_print_operand (FILE *stream, rtx x, int code)
2315 int op_value;
2317 switch (code)
2319 case 0 :
2320 /* Do nothing special. */
2321 break;
2323 case 'V':
2324 /* 'x' is supposed to be CONST_INT, get the value. */
2325 gcc_assert (CONST_INT_P (x));
2326 op_value = INTVAL (x);
2328 /* According to the Andes architecture,
2329 the system/user register index range is 0 ~ 1023.
2330 In order to avoid conflict between user-specified-integer value
2331 and enum-specified-register value,
2332 the 'enum nds32_intrinsic_registers' value
2333 in nds32_intrinsic.h starts from 1024. */
2334 if (op_value < 1024 && op_value >= 0)
2336 /* If user gives integer value directly (0~1023),
2337 we just print out the value. */
2338 fprintf (stream, "%d", op_value);
2340 else if (op_value < 0
2341 || op_value >= ((int) ARRAY_SIZE (nds32_intrinsic_register_names)
2342 + 1024))
2344 /* The enum index value for array size is out of range. */
2345 error ("intrinsic register index is out of range");
2347 else
2349 /* If user applies normal way with __NDS32_REG_XXX__ enum data,
2350 we can print out register name. Remember to substract 1024. */
2351 fprintf (stream, "%s",
2352 nds32_intrinsic_register_names[op_value - 1024]);
2355 /* No need to handle following process, so return immediately. */
2356 return;
2358 default :
2359 /* Unknown flag. */
2360 output_operand_lossage ("invalid operand output code");
2361 break;
2364 switch (GET_CODE (x))
2366 case LABEL_REF:
2367 case SYMBOL_REF:
2368 output_addr_const (stream, x);
2369 break;
2371 case REG:
2372 /* Forbid using static chain register ($r16)
2373 on reduced-set registers configuration. */
2374 if (TARGET_REDUCED_REGS
2375 && REGNO (x) == STATIC_CHAIN_REGNUM)
2376 sorry ("a nested function is not supported for reduced registers");
2378 /* Normal cases, print out register name. */
2379 fputs (reg_names[REGNO (x)], stream);
2380 break;
2382 case MEM:
2383 output_address (XEXP (x, 0));
2384 break;
2386 case CODE_LABEL:
2387 case CONST_INT:
2388 case CONST:
2389 output_addr_const (stream, x);
2390 break;
2392 default:
2393 /* Generally, output_addr_const () is able to handle most cases.
2394 We want to see what CODE could appear,
2395 so we use gcc_unreachable() to stop it. */
2396 debug_rtx (x);
2397 gcc_unreachable ();
2398 break;
2402 static void
2403 nds32_print_operand_address (FILE *stream, rtx x)
2405 rtx op0, op1;
2407 switch (GET_CODE (x))
2409 case SYMBOL_REF:
2410 case CONST:
2411 /* [ + symbol_ref] */
2412 /* [ + const_addr], where const_addr = symbol_ref + const_int */
2413 fputs ("[ + ", stream);
2414 output_addr_const (stream, x);
2415 fputs ("]", stream);
2416 break;
2418 case REG:
2419 /* Forbid using static chain register ($r16)
2420 on reduced-set registers configuration. */
2421 if (TARGET_REDUCED_REGS
2422 && REGNO (x) == STATIC_CHAIN_REGNUM)
2423 sorry ("a nested function is not supported for reduced registers");
2425 /* [Ra] */
2426 fprintf (stream, "[%s]", reg_names[REGNO (x)]);
2427 break;
2429 case PLUS:
2430 op0 = XEXP (x, 0);
2431 op1 = XEXP (x, 1);
2433 /* Checking op0, forbid using static chain register ($r16)
2434 on reduced-set registers configuration. */
2435 if (TARGET_REDUCED_REGS
2436 && REG_P (op0)
2437 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2438 sorry ("a nested function is not supported for reduced registers");
2439 /* Checking op1, forbid using static chain register ($r16)
2440 on reduced-set registers configuration. */
2441 if (TARGET_REDUCED_REGS
2442 && REG_P (op1)
2443 && REGNO (op1) == STATIC_CHAIN_REGNUM)
2444 sorry ("a nested function is not supported for reduced registers");
2446 if (REG_P (op0) && CONST_INT_P (op1))
2448 /* [Ra + imm] */
2449 fprintf (stream, "[%s + (%d)]",
2450 reg_names[REGNO (op0)], (int)INTVAL (op1));
2452 else if (REG_P (op0) && REG_P (op1))
2454 /* [Ra + Rb] */
2455 fprintf (stream, "[%s + %s]",
2456 reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
2458 else if (GET_CODE (op0) == MULT && REG_P (op1))
2460 /* [Ra + Rb << sv]
2461 From observation, the pattern looks like:
2462 (plus:SI (mult:SI (reg:SI 58)
2463 (const_int 4 [0x4]))
2464 (reg/f:SI 57)) */
2465 int sv;
2467 /* We need to set sv to output shift value. */
2468 if (INTVAL (XEXP (op0, 1)) == 1)
2469 sv = 0;
2470 else if (INTVAL (XEXP (op0, 1)) == 2)
2471 sv = 1;
2472 else if (INTVAL (XEXP (op0, 1)) == 4)
2473 sv = 2;
2474 else
2475 gcc_unreachable ();
2477 fprintf (stream, "[%s + %s << %d]",
2478 reg_names[REGNO (op1)],
2479 reg_names[REGNO (XEXP (op0, 0))],
2480 sv);
2482 else
2484 /* The control flow is not supposed to be here. */
2485 debug_rtx (x);
2486 gcc_unreachable ();
2489 break;
2491 case POST_MODIFY:
2492 /* (post_modify (regA) (plus (regA) (regB)))
2493 (post_modify (regA) (plus (regA) (const_int)))
2494 We would like to extract
2495 regA and regB (or const_int) from plus rtx. */
2496 op0 = XEXP (XEXP (x, 1), 0);
2497 op1 = XEXP (XEXP (x, 1), 1);
2499 /* Checking op0, forbid using static chain register ($r16)
2500 on reduced-set registers configuration. */
2501 if (TARGET_REDUCED_REGS
2502 && REG_P (op0)
2503 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2504 sorry ("a nested function is not supported for reduced registers");
2505 /* Checking op1, forbid using static chain register ($r16)
2506 on reduced-set registers configuration. */
2507 if (TARGET_REDUCED_REGS
2508 && REG_P (op1)
2509 && REGNO (op1) == STATIC_CHAIN_REGNUM)
2510 sorry ("a nested function is not supported for reduced registers");
2512 if (REG_P (op0) && REG_P (op1))
2514 /* [Ra], Rb */
2515 fprintf (stream, "[%s], %s",
2516 reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
2518 else if (REG_P (op0) && CONST_INT_P (op1))
2520 /* [Ra], imm */
2521 fprintf (stream, "[%s], %d",
2522 reg_names[REGNO (op0)], (int)INTVAL (op1));
2524 else
2526 /* The control flow is not supposed to be here. */
2527 debug_rtx (x);
2528 gcc_unreachable ();
2531 break;
2533 case POST_INC:
2534 case POST_DEC:
2535 op0 = XEXP (x, 0);
2537 /* Checking op0, forbid using static chain register ($r16)
2538 on reduced-set registers configuration. */
2539 if (TARGET_REDUCED_REGS
2540 && REG_P (op0)
2541 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2542 sorry ("a nested function is not supported for reduced registers");
2544 if (REG_P (op0))
2546 /* "[Ra], 1/2/4" or "[Ra], -1/-2/-4"
2547 The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
2548 We only need to deal with register Ra. */
2549 fprintf (stream, "[%s]", reg_names[REGNO (op0)]);
2551 else
2553 /* The control flow is not supposed to be here. */
2554 debug_rtx (x);
2555 gcc_unreachable ();
2558 break;
2560 default :
2561 /* Generally, output_addr_const () is able to handle most cases.
2562 We want to see what CODE could appear,
2563 so we use gcc_unreachable() to stop it. */
2564 debug_rtx (x);
2565 gcc_unreachable ();
2566 break;
2571 /* Defining target-specific uses of __attribute__. */
2573 /* Add some checking after merging attributes. */
2574 static tree
2575 nds32_merge_decl_attributes (tree olddecl, tree newdecl)
2577 tree combined_attrs;
2579 /* Create combined attributes. */
2580 combined_attrs = merge_attributes (DECL_ATTRIBUTES (olddecl),
2581 DECL_ATTRIBUTES (newdecl));
2583 /* Since newdecl is acutally a duplicate of olddecl,
2584 we can take olddecl for some operations. */
2585 if (TREE_CODE (olddecl) == FUNCTION_DECL)
2587 /* Check isr-specific attributes conflict. */
2588 nds32_check_isr_attrs_conflict (olddecl, combined_attrs);
2591 return combined_attrs;
2594 /* Add some checking when inserting attributes. */
2595 static void
2596 nds32_insert_attributes (tree decl, tree *attributes)
2598 /* For function declaration, we need to check isr-specific attributes:
2599 1. Call nds32_check_isr_attrs_conflict() to check any conflict.
2600 2. Check valid integer value for interrupt/exception.
2601 3. Check valid integer value for reset.
2602 4. Check valid function for nmi/warm. */
2603 if (TREE_CODE (decl) == FUNCTION_DECL)
2605 tree func_attrs;
2606 tree intr, excp, reset;
2608 /* Pick up function attributes. */
2609 func_attrs = *attributes;
2611 /* 1. Call nds32_check_isr_attrs_conflict() to check any conflict. */
2612 nds32_check_isr_attrs_conflict (decl, func_attrs);
2614 /* Now we are starting to check valid id value
2615 for interrupt/exception/reset.
2616 Note that we ONLY check its validity here.
2617 To construct isr vector information, it is still performed
2618 by nds32_construct_isr_vectors_information(). */
2619 intr = lookup_attribute ("interrupt", func_attrs);
2620 excp = lookup_attribute ("exception", func_attrs);
2621 reset = lookup_attribute ("reset", func_attrs);
2623 if (intr || excp)
2625 /* Deal with interrupt/exception. */
2626 tree id_list;
2627 unsigned int lower_bound, upper_bound;
2629 /* The way to handle interrupt or exception is the same,
2630 we just need to take care of actual vector number.
2631 For interrupt(0..63), the actual vector number is (9..72).
2632 For exception(1..8), the actual vector number is (1..8). */
2633 lower_bound = (intr) ? (0) : (1);
2634 upper_bound = (intr) ? (63) : (8);
2636 /* Prepare id list so that we can traverse id value. */
2637 id_list = (intr) ? (TREE_VALUE (intr)) : (TREE_VALUE (excp));
2639 /* 2. Check valid integer value for interrupt/exception. */
2640 while (id_list)
2642 tree id;
2644 /* Pick up each vector id value. */
2645 id = TREE_VALUE (id_list);
2646 /* Issue error if it is not a valid integer value. */
2647 if (TREE_CODE (id) != INTEGER_CST
2648 || wi::ltu_p (id, lower_bound)
2649 || wi::gtu_p (id, upper_bound))
2650 error ("invalid id value for interrupt/exception attribute");
2652 /* Advance to next id. */
2653 id_list = TREE_CHAIN (id_list);
2656 else if (reset)
2658 /* Deal with reset. */
2659 tree id_list;
2660 tree id;
2661 tree nmi, warm;
2662 unsigned int lower_bound;
2663 unsigned int upper_bound;
2665 /* Prepare id_list and identify id value so that
2666 we can check if total number of vectors is valid. */
2667 id_list = TREE_VALUE (reset);
2668 id = TREE_VALUE (id_list);
2670 /* The maximum numbers for user's interrupt is 64. */
2671 lower_bound = 0;
2672 upper_bound = 64;
2674 /* 3. Check valid integer value for reset. */
2675 if (TREE_CODE (id) != INTEGER_CST
2676 || wi::ltu_p (id, lower_bound)
2677 || wi::gtu_p (id, upper_bound))
2678 error ("invalid id value for reset attribute");
2680 /* 4. Check valid function for nmi/warm. */
2681 nmi = lookup_attribute ("nmi", func_attrs);
2682 warm = lookup_attribute ("warm", func_attrs);
2684 if (nmi != NULL_TREE)
2686 tree nmi_func_list;
2687 tree nmi_func;
2689 nmi_func_list = TREE_VALUE (nmi);
2690 nmi_func = TREE_VALUE (nmi_func_list);
2692 /* Issue error if it is not a valid nmi function. */
2693 if (TREE_CODE (nmi_func) != IDENTIFIER_NODE)
2694 error ("invalid nmi function for reset attribute");
2697 if (warm != NULL_TREE)
2699 tree warm_func_list;
2700 tree warm_func;
2702 warm_func_list = TREE_VALUE (warm);
2703 warm_func = TREE_VALUE (warm_func_list);
2705 /* Issue error if it is not a valid warm function. */
2706 if (TREE_CODE (warm_func) != IDENTIFIER_NODE)
2707 error ("invalid warm function for reset attribute");
2710 else
2712 /* No interrupt, exception, or reset attribute is set. */
2713 return;
2718 static bool
2719 nds32_option_pragma_parse (tree args ATTRIBUTE_UNUSED,
2720 tree pop_target ATTRIBUTE_UNUSED)
2722 /* Currently, we do not parse any pragma target by ourself,
2723 so just simply return false. */
2724 return false;
2727 static void
2728 nds32_option_override (void)
2730 /* After all the command options have been parsed,
2731 we shall deal with some flags for changing compiler settings. */
2733 /* At first, we check if we have to strictly
2734 set some flags based on ISA family. */
2735 if (TARGET_ISA_V2)
2737 /* Under V2 ISA, we need to strictly disable TARGET_V3PUSH. */
2738 target_flags &= ~MASK_V3PUSH;
2740 if (TARGET_ISA_V3)
2742 /* Under V3 ISA, currently nothing should be strictly set. */
2744 if (TARGET_ISA_V3M)
2746 /* Under V3M ISA, we need to strictly enable TARGET_REDUCED_REGS. */
2747 target_flags |= MASK_REDUCED_REGS;
2748 /* Under V3M ISA, we need to strictly disable TARGET_PERF_EXT. */
2749 target_flags &= ~MASK_PERF_EXT;
2752 /* See if we are using reduced-set registers:
2753 $r0~$r5, $r6~$r10, $r15, $r28, $r29, $r30, $r31
2754 If so, we must forbid using $r11~$r14, $r16~$r27. */
2755 if (TARGET_REDUCED_REGS)
2757 int r;
2759 /* Prevent register allocator from
2760 choosing it as doing register allocation. */
2761 for (r = 11; r <= 14; r++)
2762 fixed_regs[r] = call_used_regs[r] = 1;
2763 for (r = 16; r <= 27; r++)
2764 fixed_regs[r] = call_used_regs[r] = 1;
2767 /* See if user explicitly would like to use fp-as-gp optimization.
2768 If so, we must prevent $fp from being allocated
2769 during register allocation. */
2770 if (TARGET_FORCE_FP_AS_GP)
2771 fixed_regs[FP_REGNUM] = call_used_regs[FP_REGNUM] = 1;
2773 if (!TARGET_16_BIT)
2775 /* Under no 16 bit ISA, we need to strictly disable TARGET_V3PUSH. */
2776 target_flags &= ~MASK_V3PUSH;
2779 /* Currently, we don't support PIC code generation yet. */
2780 if (flag_pic)
2781 sorry ("not support -fpic");
2785 /* Miscellaneous Parameters. */
2787 static void
2788 nds32_init_builtins (void)
2790 tree pointer_type_node = build_pointer_type (integer_type_node);
2792 tree void_ftype_void = build_function_type (void_type_node,
2793 void_list_node);
2795 tree void_ftype_pint = build_function_type_list (void_type_node,
2796 pointer_type_node,
2797 NULL_TREE);
2799 tree int_ftype_int = build_function_type_list (integer_type_node,
2800 integer_type_node,
2801 NULL_TREE);
2803 tree void_ftype_int_int = build_function_type_list (void_type_node,
2804 integer_type_node,
2805 integer_type_node,
2806 NULL_TREE);
2808 /* Cache. */
2809 add_builtin_function ("__builtin_nds32_isync", void_ftype_pint,
2810 NDS32_BUILTIN_ISYNC,
2811 BUILT_IN_MD, NULL, NULL_TREE);
2812 add_builtin_function ("__builtin_nds32_isb", void_ftype_void,
2813 NDS32_BUILTIN_ISB,
2814 BUILT_IN_MD, NULL, NULL_TREE);
2816 /* Register Transfer. */
2817 add_builtin_function ("__builtin_nds32_mfsr", int_ftype_int,
2818 NDS32_BUILTIN_MFSR,
2819 BUILT_IN_MD, NULL, NULL_TREE);
2820 add_builtin_function ("__builtin_nds32_mfusr", int_ftype_int,
2821 NDS32_BUILTIN_MFUSR,
2822 BUILT_IN_MD, NULL, NULL_TREE);
2823 add_builtin_function ("__builtin_nds32_mtsr", void_ftype_int_int,
2824 NDS32_BUILTIN_MTSR,
2825 BUILT_IN_MD, NULL, NULL_TREE);
2826 add_builtin_function ("__builtin_nds32_mtusr", void_ftype_int_int,
2827 NDS32_BUILTIN_MTUSR,
2828 BUILT_IN_MD, NULL, NULL_TREE);
2830 /* Interrupt. */
2831 add_builtin_function ("__builtin_nds32_setgie_en", void_ftype_void,
2832 NDS32_BUILTIN_SETGIE_EN,
2833 BUILT_IN_MD, NULL, NULL_TREE);
2834 add_builtin_function ("__builtin_nds32_setgie_dis", void_ftype_void,
2835 NDS32_BUILTIN_SETGIE_DIS,
2836 BUILT_IN_MD, NULL, NULL_TREE);
2839 static rtx
2840 nds32_expand_builtin (tree exp,
2841 rtx target,
2842 rtx subtarget ATTRIBUTE_UNUSED,
2843 enum machine_mode mode ATTRIBUTE_UNUSED,
2844 int ignore ATTRIBUTE_UNUSED)
2846 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2848 int fcode = DECL_FUNCTION_CODE (fndecl);
2850 switch (fcode)
2852 /* Cache. */
2853 case NDS32_BUILTIN_ISYNC:
2854 return nds32_expand_builtin_null_ftype_reg
2855 (CODE_FOR_unspec_volatile_isync, exp, target);
2856 case NDS32_BUILTIN_ISB:
2857 /* Since there are no result and operands for isb instruciton,
2858 we can simply emit this rtx. */
2859 emit_insn (gen_unspec_volatile_isb ());
2860 return target;
2862 /* Register Transfer. */
2863 case NDS32_BUILTIN_MFSR:
2864 return nds32_expand_builtin_reg_ftype_imm
2865 (CODE_FOR_unspec_volatile_mfsr, exp, target);
2866 case NDS32_BUILTIN_MFUSR:
2867 return nds32_expand_builtin_reg_ftype_imm
2868 (CODE_FOR_unspec_volatile_mfusr, exp, target);
2869 case NDS32_BUILTIN_MTSR:
2870 return nds32_expand_builtin_null_ftype_reg_imm
2871 (CODE_FOR_unspec_volatile_mtsr, exp, target);
2872 case NDS32_BUILTIN_MTUSR:
2873 return nds32_expand_builtin_null_ftype_reg_imm
2874 (CODE_FOR_unspec_volatile_mtusr, exp, target);
2876 /* Interrupt. */
2877 case NDS32_BUILTIN_SETGIE_EN:
2878 /* Since there are no result and operands for setgie.e instruciton,
2879 we can simply emit this rtx. */
2880 emit_insn (gen_unspec_volatile_setgie_en ());
2881 return target;
2882 case NDS32_BUILTIN_SETGIE_DIS:
2883 /* Since there are no result and operands for setgie.d instruciton,
2884 we can simply emit this rtx. */
2885 emit_insn (gen_unspec_volatile_setgie_dis ());
2886 return target;
2888 default:
2889 gcc_unreachable ();
2892 return NULL_RTX;
2896 /* ------------------------------------------------------------------------ */
2898 /* PART 4: Implemet extern function definitions,
2899 the prototype is in nds32-protos.h. */
2901 /* Defining Data Structures for Per-function Information. */
2903 void
2904 nds32_init_expanders (void)
2906 /* Arrange to initialize and mark the machine per-function status. */
2907 init_machine_status = nds32_init_machine_status;
2911 /* Register Usage. */
2913 /* -- How Values Fit in Registers. */
2916 nds32_hard_regno_nregs (int regno ATTRIBUTE_UNUSED,
2917 enum machine_mode mode)
2919 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
2923 nds32_hard_regno_mode_ok (int regno, enum machine_mode mode)
2925 /* Restrict double-word quantities to even register pairs. */
2926 if (HARD_REGNO_NREGS (regno, mode) == 1
2927 || !((regno) & 1))
2928 return 1;
2930 return 0;
2934 /* Register Classes. */
2936 enum reg_class
2937 nds32_regno_reg_class (int regno)
2939 /* Refer to nds32.h for more register class details. */
2941 if (regno >= 0 && regno <= 7)
2942 return LOW_REGS;
2943 else if (regno >= 8 && regno <= 11)
2944 return MIDDLE_REGS;
2945 else if (regno >= 12 && regno <= 14)
2946 return HIGH_REGS;
2947 else if (regno == 15)
2948 return R15_TA_REG;
2949 else if (regno >= 16 && regno <= 19)
2950 return MIDDLE_REGS;
2951 else if (regno >= 20 && regno <= 31)
2952 return HIGH_REGS;
2953 else if (regno == 32 || regno == 33)
2954 return FRAME_REGS;
2955 else
2956 return NO_REGS;
2960 /* Stack Layout and Calling Conventions. */
2962 /* -- Basic Stack Layout. */
2965 nds32_return_addr_rtx (int count,
2966 rtx frameaddr ATTRIBUTE_UNUSED)
2968 /* There is no way to determine the return address
2969 if frameaddr is the frame that has 'count' steps
2970 up from current frame. */
2971 if (count != 0)
2972 return NULL_RTX;
2974 /* If count == 0, it means we are at current frame,
2975 the return address is $r30 ($lp). */
2976 return get_hard_reg_initial_val (Pmode, LP_REGNUM);
2979 /* -- Eliminating Frame Pointer and Arg Pointer. */
2981 HOST_WIDE_INT
2982 nds32_initial_elimination_offset (unsigned int from_reg, unsigned int to_reg)
2984 HOST_WIDE_INT offset;
2986 /* Compute and setup stack frame size.
2987 The result will be in cfun->machine. */
2988 nds32_compute_stack_frame ();
2990 /* Remember to consider
2991 cfun->machine->callee_saved_area_padding_bytes
2992 when calculating offset. */
2993 if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
2995 offset = (cfun->machine->fp_size
2996 + cfun->machine->gp_size
2997 + cfun->machine->lp_size
2998 + cfun->machine->callee_saved_regs_size
2999 + cfun->machine->callee_saved_area_padding_bytes
3000 + cfun->machine->local_size
3001 + cfun->machine->out_args_size);
3003 else if (from_reg == ARG_POINTER_REGNUM
3004 && to_reg == HARD_FRAME_POINTER_REGNUM)
3006 offset = 0;
3008 else if (from_reg == FRAME_POINTER_REGNUM
3009 && to_reg == STACK_POINTER_REGNUM)
3011 offset = (cfun->machine->local_size + cfun->machine->out_args_size);
3013 else if (from_reg == FRAME_POINTER_REGNUM
3014 && to_reg == HARD_FRAME_POINTER_REGNUM)
3016 offset = (-1) * (cfun->machine->fp_size
3017 + cfun->machine->gp_size
3018 + cfun->machine->lp_size
3019 + cfun->machine->callee_saved_regs_size
3020 + cfun->machine->callee_saved_area_padding_bytes);
3022 else
3024 gcc_unreachable ();
3027 return offset;
3030 /* -- Passing Arguments in Registers. */
3032 void
3033 nds32_init_cumulative_args (CUMULATIVE_ARGS *cum,
3034 tree fntype ATTRIBUTE_UNUSED,
3035 rtx libname ATTRIBUTE_UNUSED,
3036 tree fndecl ATTRIBUTE_UNUSED,
3037 int n_named_args ATTRIBUTE_UNUSED)
3039 /* Initial available registers
3040 (in offset, corresponding to NDS32_GPR_ARG_FIRST_REGNUM)
3041 for passing arguments. */
3042 cum->reg_offset = 0;
3045 /* -- Function Entry and Exit. */
3047 /* Function for normal multiple push prologue. */
3048 void
3049 nds32_expand_prologue (void)
3051 int fp_adjust;
3052 int sp_adjust;
3053 int en4_const;
3055 rtx Rb, Re;
3056 rtx push_insn;
3057 rtx fp_adjust_insn, sp_adjust_insn;
3059 /* Before computing everything for stack frame size,
3060 we check if it is still worth to use fp_as_gp optimization.
3061 If it is, the 'df_regs_ever_live_p (FP_REGNUM)' will be set
3062 so that $fp will be saved on stack. */
3063 cfun->machine->fp_as_gp_p = nds32_fp_as_gp_check_available ();
3065 /* Compute and setup stack frame size.
3066 The result will be in cfun->machine. */
3067 nds32_compute_stack_frame ();
3069 /* If the function is 'naked',
3070 we do not have to generate prologue code fragment. */
3071 if (cfun->machine->naked_p)
3072 return;
3074 /* Get callee_first_regno and callee_last_regno. */
3075 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
3076 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
3078 /* push_insn = gen_stack_push_multiple(first_regno, last_regno),
3079 the pattern 'stack_push_multiple' is implemented in nds32.md.
3080 For En4 field, we have to calculate its constant value.
3081 Refer to Andes ISA for more information. */
3082 en4_const = 0;
3083 if (cfun->machine->fp_size)
3084 en4_const += 8;
3085 if (cfun->machine->gp_size)
3086 en4_const += 4;
3087 if (cfun->machine->lp_size)
3088 en4_const += 2;
3090 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
3091 to be saved, we don't have to create multiple push instruction.
3092 Otherwise, a multiple push instruction is needed. */
3093 if (!(REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM && en4_const == 0))
3095 /* Create multiple push instruction rtx. */
3096 push_insn = nds32_gen_stack_push_multiple (Rb, Re, GEN_INT (en4_const));
3097 /* Emit rtx into instructions list and receive INSN rtx form. */
3098 push_insn = emit_insn (push_insn);
3100 /* The insn rtx 'push_insn' will change frame layout.
3101 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3102 generate CFI (Call Frame Information) stuff. */
3103 RTX_FRAME_RELATED_P (push_insn) = 1;
3106 /* Check frame_pointer_needed to see
3107 if we shall emit fp adjustment instruction. */
3108 if (frame_pointer_needed)
3110 /* adjust $fp = $sp + ($fp size) + ($gp size) + ($lp size)
3111 + (4 * callee-saved-registers)
3112 Note: No need to adjust
3113 cfun->machine->callee_saved_area_padding_bytes,
3114 because, at this point, stack pointer is just
3115 at the position after push instruction. */
3116 fp_adjust = cfun->machine->fp_size
3117 + cfun->machine->gp_size
3118 + cfun->machine->lp_size
3119 + cfun->machine->callee_saved_regs_size;
3120 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
3121 stack_pointer_rtx,
3122 GEN_INT (fp_adjust));
3123 /* Emit rtx into instructions list and receive INSN rtx form. */
3124 fp_adjust_insn = emit_insn (fp_adjust_insn);
3127 /* Adjust $sp = $sp - local_size - out_args_size
3128 - callee_saved_area_padding_bytes. */
3129 sp_adjust = cfun->machine->local_size
3130 + cfun->machine->out_args_size
3131 + cfun->machine->callee_saved_area_padding_bytes;
3132 /* sp_adjust value may be out of range of the addi instruction,
3133 create alternative add behavior with TA_REGNUM if necessary,
3134 using NEGATIVE value to tell that we are decreasing address. */
3135 sp_adjust = nds32_force_addi_stack_int ( (-1) * sp_adjust);
3136 if (sp_adjust)
3138 /* Generate sp adjustment instruction if and only if sp_adjust != 0. */
3139 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3140 stack_pointer_rtx,
3141 GEN_INT (-1 * sp_adjust));
3142 /* Emit rtx into instructions list and receive INSN rtx form. */
3143 sp_adjust_insn = emit_insn (sp_adjust_insn);
3145 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3146 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3147 generate CFI (Call Frame Information) stuff. */
3148 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3151 /* Prevent the instruction scheduler from
3152 moving instructions across the boundary. */
3153 emit_insn (gen_blockage ());
3156 /* Function for normal multiple pop epilogue. */
3157 void
3158 nds32_expand_epilogue (void)
3160 int sp_adjust;
3161 int en4_const;
3163 rtx Rb, Re;
3164 rtx pop_insn;
3165 rtx sp_adjust_insn;
3167 /* Compute and setup stack frame size.
3168 The result will be in cfun->machine. */
3169 nds32_compute_stack_frame ();
3171 /* Prevent the instruction scheduler from
3172 moving instructions across the boundary. */
3173 emit_insn (gen_blockage ());
3175 /* If the function is 'naked', we do not have to generate
3176 epilogue code fragment BUT 'ret' instruction. */
3177 if (cfun->machine->naked_p)
3179 /* Generate return instruction by using
3180 unspec_volatile_func_return pattern.
3181 Make sure this instruction is after gen_blockage().
3182 NOTE that $lp will become 'live'
3183 after this instruction has been emitted. */
3184 emit_insn (gen_unspec_volatile_func_return ());
3185 return;
3188 if (frame_pointer_needed)
3190 /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size)
3191 - (4 * callee-saved-registers)
3192 Note: No need to adjust
3193 cfun->machine->callee_saved_area_padding_bytes,
3194 because we want to adjust stack pointer
3195 to the position for pop instruction. */
3196 sp_adjust = cfun->machine->fp_size
3197 + cfun->machine->gp_size
3198 + cfun->machine->lp_size
3199 + cfun->machine->callee_saved_regs_size;
3200 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3201 hard_frame_pointer_rtx,
3202 GEN_INT (-1 * sp_adjust));
3203 /* Emit rtx into instructions list and receive INSN rtx form. */
3204 sp_adjust_insn = emit_insn (sp_adjust_insn);
3206 else
3208 /* If frame pointer is NOT needed,
3209 we cannot calculate the sp adjustment from frame pointer.
3210 Instead, we calculate the adjustment by local_size,
3211 out_args_size, and callee_saved_area_padding_bytes.
3212 Notice that such sp adjustment value may be out of range,
3213 so we have to deal with it as well. */
3215 /* Adjust $sp = $sp + local_size + out_args_size
3216 + callee_saved_area_padding_bytes. */
3217 sp_adjust = cfun->machine->local_size
3218 + cfun->machine->out_args_size
3219 + cfun->machine->callee_saved_area_padding_bytes;
3220 /* sp_adjust value may be out of range of the addi instruction,
3221 create alternative add behavior with TA_REGNUM if necessary,
3222 using POSITIVE value to tell that we are increasing address. */
3223 sp_adjust = nds32_force_addi_stack_int (sp_adjust);
3224 if (sp_adjust)
3226 /* Generate sp adjustment instruction
3227 if and only if sp_adjust != 0. */
3228 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3229 stack_pointer_rtx,
3230 GEN_INT (sp_adjust));
3231 /* Emit rtx into instructions list and receive INSN rtx form. */
3232 sp_adjust_insn = emit_insn (sp_adjust_insn);
3236 /* Get callee_first_regno and callee_last_regno. */
3237 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
3238 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
3240 /* pop_insn = gen_stack_pop_multiple(first_regno, last_regno),
3241 the pattern 'stack_pop_multiple' is implementad in nds32.md.
3242 For En4 field, we have to calculate its constant value.
3243 Refer to Andes ISA for more information. */
3244 en4_const = 0;
3245 if (cfun->machine->fp_size)
3246 en4_const += 8;
3247 if (cfun->machine->gp_size)
3248 en4_const += 4;
3249 if (cfun->machine->lp_size)
3250 en4_const += 2;
3252 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
3253 to be saved, we don't have to create multiple pop instruction.
3254 Otherwise, a multiple pop instruction is needed. */
3255 if (!(REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM && en4_const == 0))
3257 /* Create multiple pop instruction rtx. */
3258 pop_insn = nds32_gen_stack_pop_multiple (Rb, Re, GEN_INT (en4_const));
3259 /* Emit pop instruction. */
3260 emit_insn (pop_insn);
3263 /* Generate return instruction by using
3264 unspec_volatile_func_return pattern. */
3265 emit_insn (gen_unspec_volatile_func_return ());
3268 /* Function for v3push prologue. */
3269 void
3270 nds32_expand_prologue_v3push (void)
3272 int fp_adjust;
3273 int sp_adjust;
3275 rtx Rb, Re;
3276 rtx push_insn;
3277 rtx fp_adjust_insn, sp_adjust_insn;
3279 /* Before computing everything for stack frame size,
3280 we check if it is still worth to use fp_as_gp optimization.
3281 If it is, the 'df_regs_ever_live_p (FP_REGNUM)' will be set
3282 so that $fp will be saved on stack. */
3283 cfun->machine->fp_as_gp_p = nds32_fp_as_gp_check_available ();
3285 /* Compute and setup stack frame size.
3286 The result will be in cfun->machine. */
3287 nds32_compute_stack_frame ();
3289 /* If the function is 'naked',
3290 we do not have to generate prologue code fragment. */
3291 if (cfun->machine->naked_p)
3292 return;
3294 /* Get callee_first_regno and callee_last_regno. */
3295 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
3296 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
3298 /* Calculate sp_adjust first to test if 'push25 Re,imm8u' is available,
3299 where imm8u has to be 8-byte alignment. */
3300 sp_adjust = cfun->machine->local_size
3301 + cfun->machine->out_args_size
3302 + cfun->machine->callee_saved_area_padding_bytes;
3304 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
3305 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust))
3307 /* We can use 'push25 Re,imm8u'. */
3309 /* push_insn = gen_stack_v3push(last_regno, sp_adjust),
3310 the pattern 'stack_v3push' is implemented in nds32.md.
3311 The (const_int 14) means v3push always push { $fp $gp $lp }. */
3312 push_insn = nds32_gen_stack_v3push (Rb, Re,
3313 GEN_INT (14), GEN_INT (sp_adjust));
3314 /* emit rtx into instructions list and receive INSN rtx form */
3315 push_insn = emit_insn (push_insn);
3317 /* The insn rtx 'push_insn' will change frame layout.
3318 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3319 generate CFI (Call Frame Information) stuff. */
3320 RTX_FRAME_RELATED_P (push_insn) = 1;
3322 /* Check frame_pointer_needed to see
3323 if we shall emit fp adjustment instruction. */
3324 if (frame_pointer_needed)
3326 /* adjust $fp = $sp + 4 ($fp size)
3327 + 4 ($gp size)
3328 + 4 ($lp size)
3329 + (4 * n) (callee-saved registers)
3330 + sp_adjust ('push25 Re,imm8u')
3331 Note: Since we use 'push25 Re,imm8u',
3332 the position of stack pointer is further
3333 changed after push instruction.
3334 Hence, we need to take sp_adjust value
3335 into consideration. */
3336 fp_adjust = cfun->machine->fp_size
3337 + cfun->machine->gp_size
3338 + cfun->machine->lp_size
3339 + cfun->machine->callee_saved_regs_size
3340 + sp_adjust;
3341 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
3342 stack_pointer_rtx,
3343 GEN_INT (fp_adjust));
3344 /* Emit rtx into instructions list and receive INSN rtx form. */
3345 fp_adjust_insn = emit_insn (fp_adjust_insn);
3348 else
3350 /* We have to use 'push25 Re,0' and
3351 expand one more instruction to adjust $sp later. */
3353 /* push_insn = gen_stack_v3push(last_regno, sp_adjust),
3354 the pattern 'stack_v3push' is implemented in nds32.md.
3355 The (const_int 14) means v3push always push { $fp $gp $lp }. */
3356 push_insn = nds32_gen_stack_v3push (Rb, Re,
3357 GEN_INT (14), GEN_INT (0));
3358 /* Emit rtx into instructions list and receive INSN rtx form. */
3359 push_insn = emit_insn (push_insn);
3361 /* The insn rtx 'push_insn' will change frame layout.
3362 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3363 generate CFI (Call Frame Information) stuff. */
3364 RTX_FRAME_RELATED_P (push_insn) = 1;
3366 /* Check frame_pointer_needed to see
3367 if we shall emit fp adjustment instruction. */
3368 if (frame_pointer_needed)
3370 /* adjust $fp = $sp + 4 ($fp size)
3371 + 4 ($gp size)
3372 + 4 ($lp size)
3373 + (4 * n) (callee-saved registers)
3374 Note: Since we use 'push25 Re,0',
3375 the stack pointer is just at the position
3376 after push instruction.
3377 No need to take sp_adjust into consideration. */
3378 fp_adjust = cfun->machine->fp_size
3379 + cfun->machine->gp_size
3380 + cfun->machine->lp_size
3381 + cfun->machine->callee_saved_regs_size;
3382 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
3383 stack_pointer_rtx,
3384 GEN_INT (fp_adjust));
3385 /* Emit rtx into instructions list and receive INSN rtx form. */
3386 fp_adjust_insn = emit_insn (fp_adjust_insn);
3389 /* Because we use 'push25 Re,0',
3390 we need to expand one more instruction to adjust $sp.
3391 However, sp_adjust value may be out of range of the addi instruction,
3392 create alternative add behavior with TA_REGNUM if necessary,
3393 using NEGATIVE value to tell that we are decreasing address. */
3394 sp_adjust = nds32_force_addi_stack_int ( (-1) * sp_adjust);
3395 if (sp_adjust)
3397 /* Generate sp adjustment instruction
3398 if and only if sp_adjust != 0. */
3399 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3400 stack_pointer_rtx,
3401 GEN_INT (-1 * sp_adjust));
3402 /* Emit rtx into instructions list and receive INSN rtx form. */
3403 sp_adjust_insn = emit_insn (sp_adjust_insn);
3405 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3406 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3407 generate CFI (Call Frame Information) stuff. */
3408 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3412 /* Prevent the instruction scheduler from
3413 moving instructions across the boundary. */
3414 emit_insn (gen_blockage ());
3417 /* Function for v3pop epilogue. */
3418 void
3419 nds32_expand_epilogue_v3pop (void)
3421 int sp_adjust;
3423 rtx Rb, Re;
3424 rtx pop_insn;
3425 rtx sp_adjust_insn;
3427 /* Compute and setup stack frame size.
3428 The result will be in cfun->machine. */
3429 nds32_compute_stack_frame ();
3431 /* Prevent the instruction scheduler from
3432 moving instructions across the boundary. */
3433 emit_insn (gen_blockage ());
3435 /* If the function is 'naked', we do not have to generate
3436 epilogue code fragment BUT 'ret' instruction. */
3437 if (cfun->machine->naked_p)
3439 /* Generate return instruction by using
3440 unspec_volatile_func_return pattern.
3441 Make sure this instruction is after gen_blockage().
3442 NOTE that $lp will become 'live'
3443 after this instruction has been emitted. */
3444 emit_insn (gen_unspec_volatile_func_return ());
3445 return;
3448 /* Get callee_first_regno and callee_last_regno. */
3449 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
3450 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
3452 /* Calculate sp_adjust first to test if 'pop25 Re,imm8u' is available,
3453 where imm8u has to be 8-byte alignment. */
3454 sp_adjust = cfun->machine->local_size
3455 + cfun->machine->out_args_size
3456 + cfun->machine->callee_saved_area_padding_bytes;
3458 /* We have to consider alloca issue as well.
3459 If the function does call alloca(), the stack pointer is not fixed.
3460 In that case, we cannot use 'pop25 Re,imm8u' directly.
3461 We have to caculate stack pointer from frame pointer
3462 and then use 'pop25 Re,0'.
3463 Of course, the frame_pointer_needed should be nonzero
3464 if the function calls alloca(). */
3465 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
3466 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust)
3467 && !cfun->calls_alloca)
3469 /* We can use 'pop25 Re,imm8u'. */
3471 /* pop_insn = gen_stack_v3pop(last_regno, sp_adjust),
3472 the pattern 'stack_v3pop' is implementad in nds32.md.
3473 The (const_int 14) means v3pop always pop { $fp $gp $lp }. */
3474 pop_insn = nds32_gen_stack_v3pop (Rb, Re,
3475 GEN_INT (14), GEN_INT (sp_adjust));
3477 /* Emit pop instruction. */
3478 emit_insn (pop_insn);
3480 else
3482 /* We have to use 'pop25 Re,0', and prior to it,
3483 we must expand one more instruction to adjust $sp. */
3485 if (frame_pointer_needed)
3487 /* adjust $sp = $fp - 4 ($fp size)
3488 - 4 ($gp size)
3489 - 4 ($lp size)
3490 - (4 * n) (callee-saved registers)
3491 Note: No need to adjust
3492 cfun->machine->callee_saved_area_padding_bytes,
3493 because we want to adjust stack pointer
3494 to the position for pop instruction. */
3495 sp_adjust = cfun->machine->fp_size
3496 + cfun->machine->gp_size
3497 + cfun->machine->lp_size
3498 + cfun->machine->callee_saved_regs_size;
3499 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3500 hard_frame_pointer_rtx,
3501 GEN_INT (-1 * sp_adjust));
3502 /* Emit rtx into instructions list and receive INSN rtx form. */
3503 sp_adjust_insn = emit_insn (sp_adjust_insn);
3505 else
3507 /* If frame pointer is NOT needed,
3508 we cannot calculate the sp adjustment from frame pointer.
3509 Instead, we calculate the adjustment by local_size,
3510 out_args_size, and callee_saved_area_padding_bytes.
3511 Notice that such sp adjustment value may be out of range,
3512 so we have to deal with it as well. */
3514 /* Adjust $sp = $sp + local_size + out_args_size
3515 + callee_saved_area_padding_bytes. */
3516 sp_adjust = cfun->machine->local_size
3517 + cfun->machine->out_args_size
3518 + cfun->machine->callee_saved_area_padding_bytes;
3519 /* sp_adjust value may be out of range of the addi instruction,
3520 create alternative add behavior with TA_REGNUM if necessary,
3521 using POSITIVE value to tell that we are increasing address. */
3522 sp_adjust = nds32_force_addi_stack_int (sp_adjust);
3523 if (sp_adjust)
3525 /* Generate sp adjustment instruction
3526 if and only if sp_adjust != 0. */
3527 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3528 stack_pointer_rtx,
3529 GEN_INT (sp_adjust));
3530 /* Emit rtx into instructions list and receive INSN rtx form. */
3531 sp_adjust_insn = emit_insn (sp_adjust_insn);
3535 /* pop_insn = gen_stack_v3pop(last_regno, sp_adjust),
3536 the pattern 'stack_v3pop' is implementad in nds32.md. */
3537 /* The (const_int 14) means v3pop always pop { $fp $gp $lp }. */
3538 pop_insn = nds32_gen_stack_v3pop (Rb, Re,
3539 GEN_INT (14), GEN_INT (0));
3541 /* Emit pop instruction. */
3542 emit_insn (pop_insn);
3546 /* ------------------------------------------------------------------------ */
3548 /* Function to test 333-form for load/store instructions.
3549 This is auxiliary extern function for auxiliary macro in nds32.h.
3550 Because it is a little complicated, we use function instead of macro. */
3551 bool
3552 nds32_ls_333_p (rtx rt, rtx ra, rtx imm, enum machine_mode mode)
3554 if (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS
3555 && REGNO_REG_CLASS (REGNO (ra)) == LOW_REGS)
3557 if (GET_MODE_SIZE (mode) == 4)
3558 return satisfies_constraint_Iu05 (imm);
3560 if (GET_MODE_SIZE (mode) == 2)
3561 return satisfies_constraint_Iu04 (imm);
3563 if (GET_MODE_SIZE (mode) == 1)
3564 return satisfies_constraint_Iu03 (imm);
3567 return false;
3571 /* Functions to expand load_multiple and store_multiple.
3572 They are auxiliary extern functions to help create rtx template.
3573 Check nds32-multiple.md file for the patterns. */
3575 nds32_expand_load_multiple (int base_regno, int count,
3576 rtx base_addr, rtx basemem)
3578 int par_index;
3579 int offset;
3580 rtx result;
3581 rtx new_addr, mem, reg;
3583 /* Create the pattern that is presented in nds32-multiple.md. */
3585 result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
3587 for (par_index = 0; par_index < count; par_index++)
3589 offset = par_index * 4;
3590 /* 4-byte for loading data to each register. */
3591 new_addr = plus_constant (Pmode, base_addr, offset);
3592 mem = adjust_automodify_address_nv (basemem, SImode,
3593 new_addr, offset);
3594 reg = gen_rtx_REG (SImode, base_regno + par_index);
3596 XVECEXP (result, 0, par_index) = gen_rtx_SET (VOIDmode, reg, mem);
3599 return result;
3603 nds32_expand_store_multiple (int base_regno, int count,
3604 rtx base_addr, rtx basemem)
3606 int par_index;
3607 int offset;
3608 rtx result;
3609 rtx new_addr, mem, reg;
3611 /* Create the pattern that is presented in nds32-multiple.md. */
3613 result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
3615 for (par_index = 0; par_index < count; par_index++)
3617 offset = par_index * 4;
3618 /* 4-byte for storing data to memory. */
3619 new_addr = plus_constant (Pmode, base_addr, offset);
3620 mem = adjust_automodify_address_nv (basemem, SImode,
3621 new_addr, offset);
3622 reg = gen_rtx_REG (SImode, base_regno + par_index);
3624 XVECEXP (result, 0, par_index) = gen_rtx_SET (VOIDmode, mem, reg);
3627 return result;
3630 /* Function to move block memory content by
3631 using load_multiple and store_multiple.
3632 This is auxiliary extern function to help create rtx template.
3633 Check nds32-multiple.md file for the patterns. */
3635 nds32_expand_movmemqi (rtx dstmem, rtx srcmem, rtx total_bytes, rtx alignment)
3637 HOST_WIDE_INT in_words, out_words;
3638 rtx dst_base_reg, src_base_reg;
3639 int maximum_bytes;
3641 /* Because reduced-set regsiters has few registers
3642 (r0~r5, r6~10, r15, r28~r31, where 'r15' and 'r28~r31'
3643 cannot be used for register allocation),
3644 using 8 registers (32 bytes) for moving memory block
3645 may easily consume all of them.
3646 It makes register allocation/spilling hard to work.
3647 So we only allow maximum=4 registers (16 bytes) for
3648 moving memory block under reduced-set registers. */
3649 if (TARGET_REDUCED_REGS)
3650 maximum_bytes = 16;
3651 else
3652 maximum_bytes = 32;
3654 /* 1. Total_bytes is integer for sure.
3655 2. Alignment is integer for sure.
3656 3. Maximum 4 or 8 registers, 4 * 4 = 16 bytes, 8 * 4 = 32 bytes.
3657 4. Requires (n * 4) block size.
3658 5. Requires 4-byte alignment. */
3659 if (GET_CODE (total_bytes) != CONST_INT
3660 || GET_CODE (alignment) != CONST_INT
3661 || INTVAL (total_bytes) > maximum_bytes
3662 || INTVAL (total_bytes) & 3
3663 || INTVAL (alignment) & 3)
3664 return 0;
3666 dst_base_reg = copy_to_mode_reg (SImode, XEXP (dstmem, 0));
3667 src_base_reg = copy_to_mode_reg (SImode, XEXP (srcmem, 0));
3669 out_words = in_words = INTVAL (total_bytes) / UNITS_PER_WORD;
3671 emit_insn (nds32_expand_load_multiple (0, in_words, src_base_reg, srcmem));
3672 emit_insn (nds32_expand_store_multiple (0, out_words, dst_base_reg, dstmem));
3674 /* Successfully create patterns, return 1. */
3675 return 1;
3678 /* Function to check whether the OP is a valid load/store operation.
3679 This is a helper function for the predicates:
3680 'nds32_load_multiple_operation' and 'nds32_store_multiple_operation'
3681 in predicates.md file.
3683 The OP is supposed to be a parallel rtx.
3684 For each element within this parallel rtx:
3685 (set (reg) (mem addr)) is the form for load operation.
3686 (set (mem addr) (reg)) is the form for store operation.
3687 We have to extract reg and mem of every element and
3688 check if the information is valid for multiple load/store operation. */
3689 bool
3690 nds32_valid_multiple_load_store (rtx op, bool load_p)
3692 int count;
3693 int first_elt_regno;
3694 rtx elt;
3696 /* Get the counts of elements in the parallel rtx. */
3697 count = XVECLEN (op, 0);
3698 /* Pick up the first element. */
3699 elt = XVECEXP (op, 0, 0);
3701 /* Perform some quick check for the first element in the parallel rtx. */
3702 if (GET_CODE (elt) != SET
3703 || count <= 1
3704 || count > 8)
3705 return false;
3707 /* Pick up regno of first element for further detail checking.
3708 Note that the form is different between load and store operation. */
3709 if (load_p)
3711 if (GET_CODE (SET_DEST (elt)) != REG
3712 || GET_CODE (SET_SRC (elt)) != MEM)
3713 return false;
3715 first_elt_regno = REGNO (SET_DEST (elt));
3717 else
3719 if (GET_CODE (SET_SRC (elt)) != REG
3720 || GET_CODE (SET_DEST (elt)) != MEM)
3721 return false;
3723 first_elt_regno = REGNO (SET_SRC (elt));
3726 /* Perform detail check for each element.
3727 Refer to nds32-multiple.md for more information
3728 about following checking.
3729 The starting element of parallel rtx is index 0. */
3730 if (!nds32_consecutive_registers_load_store_p (op, load_p, 0,
3731 first_elt_regno,
3732 count))
3733 return false;
3735 /* Pass all test, this is a valid rtx. */
3736 return true;
3739 /* Function to check whether the OP is a valid stack push/pop operation.
3740 For a valid stack operation, it must satisfy following conditions:
3741 1. Consecutive registers push/pop operations.
3742 2. Valid $fp/$gp/$lp push/pop operations.
3743 3. The last element must be stack adjustment rtx.
3744 See the prologue/epilogue implementation for details. */
3745 bool
3746 nds32_valid_stack_push_pop (rtx op, bool push_p)
3748 int index;
3749 int total_count;
3750 int rest_count;
3751 int first_regno;
3752 rtx elt;
3753 rtx elt_reg;
3754 rtx elt_mem;
3755 rtx elt_plus;
3757 /* Get the counts of elements in the parallel rtx. */
3758 total_count = XVECLEN (op, 0);
3760 /* Perform some quick check for that every element should be 'set'. */
3761 for (index = 0; index < total_count; index++)
3763 elt = XVECEXP (op, 0, index);
3764 if (GET_CODE (elt) != SET)
3765 return false;
3768 /* For push operation, the parallel rtx looks like:
3769 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
3770 (reg:SI Rb))
3771 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
3772 (reg:SI Rb+1))
3774 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
3775 (reg:SI Re))
3776 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
3777 (reg:SI FP_REGNUM))
3778 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
3779 (reg:SI GP_REGNUM))
3780 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
3781 (reg:SI LP_REGNUM))
3782 (set (reg:SI SP_REGNUM)
3783 (plus (reg:SI SP_REGNUM) (const_int -32)))])
3785 For pop operation, the parallel rtx looks like:
3786 (parallel [(set (reg:SI Rb)
3787 (mem (reg:SI SP_REGNUM)))
3788 (set (reg:SI Rb+1)
3789 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
3791 (set (reg:SI Re)
3792 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
3793 (set (reg:SI FP_REGNUM)
3794 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
3795 (set (reg:SI GP_REGNUM)
3796 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
3797 (set (reg:SI LP_REGNUM)
3798 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
3799 (set (reg:SI SP_REGNUM)
3800 (plus (reg:SI SP_REGNUM) (const_int 32)))]) */
3802 /* 1. Consecutive registers push/pop operations.
3803 We need to calculate how many registers should be consecutive.
3804 The $sp adjustment rtx, $fp push rtx, $gp push rtx,
3805 and $lp push rtx are excluded. */
3807 /* Exclude last $sp adjustment rtx. */
3808 rest_count = total_count - 1;
3809 /* Exclude $fp, $gp, and $lp if they are in the parallel rtx. */
3810 if (cfun->machine->fp_size)
3811 rest_count--;
3812 if (cfun->machine->gp_size)
3813 rest_count--;
3814 if (cfun->machine->lp_size)
3815 rest_count--;
3817 if (rest_count > 0)
3819 elt = XVECEXP (op, 0, 0);
3820 /* Pick up register element. */
3821 elt_reg = push_p ? SET_SRC (elt) : SET_DEST (elt);
3822 first_regno = REGNO (elt_reg);
3824 /* The 'push' operation is a kind of store operation.
3825 The 'pop' operation is a kind of load operation.
3826 Pass corresponding false/true as second argument (bool load_p).
3827 The par_index is supposed to start with index 0. */
3828 if (!nds32_consecutive_registers_load_store_p (op,
3829 !push_p ? true : false,
3831 first_regno,
3832 rest_count))
3833 return false;
3836 /* 2. Valid $fp/$gp/$lp push/pop operations.
3837 Remember to set start index for checking them. */
3839 /* The rest_count is the start index for checking $fp/$gp/$lp. */
3840 index = rest_count;
3841 /* If index < 0, this parallel rtx is definitely
3842 not a valid stack push/pop operation. */
3843 if (index < 0)
3844 return false;
3846 /* Check $fp/$gp/$lp one by one.
3847 We use 'push_p' to pick up reg rtx and mem rtx. */
3848 if (cfun->machine->fp_size)
3850 elt = XVECEXP (op, 0, index);
3851 elt_mem = push_p ? SET_DEST (elt) : SET_SRC (elt);
3852 elt_reg = push_p ? SET_SRC (elt) : SET_DEST (elt);
3853 index++;
3855 if (GET_CODE (elt_mem) != MEM
3856 || GET_CODE (elt_reg) != REG
3857 || REGNO (elt_reg) != FP_REGNUM)
3858 return false;
3860 if (cfun->machine->gp_size)
3862 elt = XVECEXP (op, 0, index);
3863 elt_mem = push_p ? SET_DEST (elt) : SET_SRC (elt);
3864 elt_reg = push_p ? SET_SRC (elt) : SET_DEST (elt);
3865 index++;
3867 if (GET_CODE (elt_mem) != MEM
3868 || GET_CODE (elt_reg) != REG
3869 || REGNO (elt_reg) != GP_REGNUM)
3870 return false;
3872 if (cfun->machine->lp_size)
3874 elt = XVECEXP (op, 0, index);
3875 elt_mem = push_p ? SET_DEST (elt) : SET_SRC (elt);
3876 elt_reg = push_p ? SET_SRC (elt) : SET_DEST (elt);
3877 index++;
3879 if (GET_CODE (elt_mem) != MEM
3880 || GET_CODE (elt_reg) != REG
3881 || REGNO (elt_reg) != LP_REGNUM)
3882 return false;
3885 /* 3. The last element must be stack adjustment rtx.
3886 Its form of rtx should be:
3887 (set (reg:SI SP_REGNUM)
3888 (plus (reg:SI SP_REGNUM) (const_int X)))
3889 The X could be positive or negative value. */
3891 /* Pick up the last element. */
3892 elt = XVECEXP (op, 0, total_count - 1);
3894 /* Extract its destination and source rtx. */
3895 elt_reg = SET_DEST (elt);
3896 elt_plus = SET_SRC (elt);
3898 /* Check this is (set (stack_reg) (plus stack_reg const)) pattern. */
3899 if (GET_CODE (elt_reg) != REG
3900 || GET_CODE (elt_plus) != PLUS
3901 || REGNO (elt_reg) != SP_REGNUM)
3902 return false;
3904 /* Pass all test, this is a valid rtx. */
3905 return true;
3908 /* Computing the Length of an Insn.
3909 Modifies the length assigned to instruction INSN.
3910 LEN is the initially computed length of the insn. */
3912 nds32_adjust_insn_length (rtx insn, int length)
3914 rtx src, dst;
3916 switch (recog_memoized (insn))
3918 case CODE_FOR_move_df:
3919 case CODE_FOR_move_di:
3920 /* Adjust length of movd44 to 2. */
3921 src = XEXP (PATTERN (insn), 1);
3922 dst = XEXP (PATTERN (insn), 0);
3924 if (REG_P (src)
3925 && REG_P (dst)
3926 && (REGNO (src) % 2) == 0
3927 && (REGNO (dst) % 2) == 0)
3928 length = 2;
3929 break;
3931 default:
3932 break;
3935 return length;
3939 /* Function to check if 'bclr' instruction can be used with IVAL. */
3941 nds32_can_use_bclr_p (int ival)
3943 int one_bit_count;
3945 /* Calculate the number of 1-bit of (~ival), if there is only one 1-bit,
3946 it means the original ival has only one 0-bit,
3947 So it is ok to perform 'bclr' operation. */
3949 one_bit_count = popcount_hwi ((unsigned HOST_WIDE_INT) (~ival));
3951 /* 'bclr' is a performance extension instruction. */
3952 return (TARGET_PERF_EXT && (one_bit_count == 1));
3955 /* Function to check if 'bset' instruction can be used with IVAL. */
3957 nds32_can_use_bset_p (int ival)
3959 int one_bit_count;
3961 /* Caculate the number of 1-bit of ival, if there is only one 1-bit,
3962 it is ok to perform 'bset' operation. */
3964 one_bit_count = popcount_hwi ((unsigned HOST_WIDE_INT) (ival));
3966 /* 'bset' is a performance extension instruction. */
3967 return (TARGET_PERF_EXT && (one_bit_count == 1));
3970 /* Function to check if 'btgl' instruction can be used with IVAL. */
3972 nds32_can_use_btgl_p (int ival)
3974 int one_bit_count;
3976 /* Caculate the number of 1-bit of ival, if there is only one 1-bit,
3977 it is ok to perform 'btgl' operation. */
3979 one_bit_count = popcount_hwi ((unsigned HOST_WIDE_INT) (ival));
3981 /* 'btgl' is a performance extension instruction. */
3982 return (TARGET_PERF_EXT && (one_bit_count == 1));
3985 /* Function to check if 'bitci' instruction can be used with IVAL. */
3987 nds32_can_use_bitci_p (int ival)
3989 /* If we are using V3 ISA, we have 'bitci' instruction.
3990 Try to see if we can present 'andi' semantic with
3991 such 'bit-clear-immediate' operation.
3992 For example, 'andi $r0,$r0,0xfffffffc' can be
3993 presented with 'bitci $r0,$r0,3'. */
3994 return (TARGET_ISA_V3
3995 && (ival < 0)
3996 && satisfies_constraint_Iu15 (gen_int_mode (~ival, SImode)));
4000 /* Return true if is load/store with SYMBOL_REF addressing mode
4001 and memory mode is SImode. */
4002 bool
4003 nds32_symbol_load_store_p (rtx insn)
4005 rtx mem_src = NULL_RTX;
4007 switch (get_attr_type (insn))
4009 case TYPE_LOAD:
4010 mem_src = SET_SRC (PATTERN (insn));
4011 break;
4012 case TYPE_STORE:
4013 mem_src = SET_DEST (PATTERN (insn));
4014 break;
4015 default:
4016 break;
4019 /* Find load/store insn with addressing mode is SYMBOL_REF. */
4020 if (mem_src != NULL_RTX)
4022 if ((GET_CODE (mem_src) == ZERO_EXTEND)
4023 || (GET_CODE (mem_src) == SIGN_EXTEND))
4024 mem_src = XEXP (mem_src, 0);
4026 if ((GET_CODE (XEXP (mem_src, 0)) == SYMBOL_REF)
4027 || (GET_CODE (XEXP (mem_src, 0)) == LO_SUM))
4028 return true;
4031 return false;
4034 /* Function to determine whether it is worth to do fp_as_gp optimization.
4035 Return 0: It is NOT worth to do fp_as_gp optimization.
4036 Return 1: It is APPROXIMATELY worth to do fp_as_gp optimization.
4037 Note that if it is worth to do fp_as_gp optimization,
4038 we MUST set FP_REGNUM ever live in this function. */
4040 nds32_fp_as_gp_check_available (void)
4042 /* If there exists ANY of following conditions,
4043 we DO NOT perform fp_as_gp optimization:
4044 1. TARGET_FORBID_FP_AS_GP is set
4045 regardless of the TARGET_FORCE_FP_AS_GP.
4046 2. User explicitly uses 'naked' attribute.
4047 3. Not optimize for size.
4048 4. Need frame pointer.
4049 5. If $fp is already required to be saved,
4050 it means $fp is already choosen by register allocator.
4051 Thus we better not to use it for fp_as_gp optimization.
4052 6. This function is a vararg function.
4053 DO NOT apply fp_as_gp optimization on this function
4054 because it may change and break stack frame.
4055 7. The epilogue is empty.
4056 This happens when the function uses exit()
4057 or its attribute is no_return.
4058 In that case, compiler will not expand epilogue
4059 so that we have no chance to output .omit_fp_end directive. */
4060 if (TARGET_FORBID_FP_AS_GP
4061 || lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl))
4062 || !optimize_size
4063 || frame_pointer_needed
4064 || NDS32_REQUIRED_CALLEE_SAVED_P (FP_REGNUM)
4065 || (cfun->stdarg == 1)
4066 || (find_fallthru_edge (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) == NULL))
4067 return 0;
4069 /* Now we can check the possibility of using fp_as_gp optimization. */
4070 if (TARGET_FORCE_FP_AS_GP)
4072 /* User explicitly issues -mforce-fp-as-gp option. */
4073 df_set_regs_ever_live (FP_REGNUM, 1);
4074 return 1;
4076 else
4078 /* In the following we are going to evaluate whether
4079 it is worth to do fp_as_gp optimization. */
4080 int good_gain = 0;
4081 int symbol_count = 0;
4083 int threshold;
4084 rtx insn;
4086 /* We check if there already requires prologue.
4087 Note that $gp will be saved in prologue for PIC code generation.
4088 After that, we can set threshold by the existence of prologue.
4089 Each fp-implied instruction will gain 2-byte code size
4090 from gp-aware instruction, so we have following heuristics. */
4091 if (flag_pic
4092 || nds32_have_prologue_p ())
4094 /* Have-prologue:
4095 Compiler already intends to generate prologue content,
4096 so the fp_as_gp optimization will only insert
4097 'la $fp,_FP_BASE_' instruction, which will be
4098 converted into 4-byte instruction at link time.
4099 The threshold is "3" symbol accesses, 2 + 2 + 2 > 4. */
4100 threshold = 3;
4102 else
4104 /* None-prologue:
4105 Compiler originally does not generate prologue content,
4106 so the fp_as_gp optimization will NOT ONLY insert
4107 'la $fp,_FP_BASE' instruction, but also causes
4108 push/pop instructions.
4109 If we are using v3push (push25/pop25),
4110 the threshold is "5" symbol accesses, 5*2 > 4 + 2 + 2;
4111 If we are using normal push (smw/lmw),
4112 the threshold is "5+2" symbol accesses 7*2 > 4 + 4 + 4. */
4113 threshold = 5 + (TARGET_V3PUSH ? 0 : 2);
4116 /* We would like to traverse every instruction in this function.
4117 So we need to have push_topmost_sequence()/pop_topmost_sequence()
4118 surrounding our for-loop evaluation. */
4119 push_topmost_sequence ();
4120 /* Counting the insn number which the addressing mode is symbol. */
4121 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4123 if (single_set (insn) && nds32_symbol_load_store_p (insn))
4124 symbol_count++;
4126 if (symbol_count == threshold)
4128 good_gain = 1;
4129 break;
4132 pop_topmost_sequence ();
4134 /* Enable fp_as_gp optimization when potential gain is good enough. */
4135 if (good_gain)
4137 df_set_regs_ever_live (FP_REGNUM, 1);
4138 return 1;
4142 /* By default we return 0. */
4143 return 0;
4147 /* Function to generate PC relative jump table.
4148 Refer to nds32.md for more details.
4150 The following is the sample for the case that diff value
4151 can be presented in '.short' size.
4153 addi $r1, $r1, -(case_lower_bound)
4154 slti $ta, $r1, (case_number)
4155 beqz $ta, .L_skip_label
4157 la $ta, .L35 ! get jump table address
4158 lh $r1, [$ta + $r1 << 1] ! load symbol diff from jump table entry
4159 addi $ta, $r1, $ta
4160 jr5 $ta
4162 ! jump table entry
4163 L35:
4164 .short .L25-.L35
4165 .short .L26-.L35
4166 .short .L27-.L35
4167 .short .L28-.L35
4168 .short .L29-.L35
4169 .short .L30-.L35
4170 .short .L31-.L35
4171 .short .L32-.L35
4172 .short .L33-.L35
4173 .short .L34-.L35 */
4174 const char *
4175 nds32_output_casesi_pc_relative (rtx *operands)
4177 enum machine_mode mode;
4178 rtx diff_vec;
4180 diff_vec = PATTERN (NEXT_INSN (operands[1]));
4182 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
4184 /* Step C: "t <-- operands[1]". */
4185 output_asm_insn ("la\t$ta, %l1", operands);
4187 /* Get the mode of each element in the difference vector. */
4188 mode = GET_MODE (diff_vec);
4190 /* Step D: "z <-- (mem (plus (operands[0] << m) t))",
4191 where m is 0, 1, or 2 to load address-diff value from table. */
4192 switch (mode)
4194 case QImode:
4195 output_asm_insn ("lb\t%2, [$ta + %0 << 0]", operands);
4196 break;
4197 case HImode:
4198 output_asm_insn ("lh\t%2, [$ta + %0 << 1]", operands);
4199 break;
4200 case SImode:
4201 output_asm_insn ("lw\t%2, [$ta + %0 << 2]", operands);
4202 break;
4203 default:
4204 gcc_unreachable ();
4207 /* Step E: "t <-- z + t".
4208 Add table label_ref with address-diff value to
4209 obtain target case address. */
4210 output_asm_insn ("add\t$ta, %2, $ta", operands);
4212 /* Step F: jump to target with register t. */
4213 if (TARGET_16_BIT)
4214 return "jr5\t$ta";
4215 else
4216 return "jr\t$ta";
4219 /* Function to generate normal jump table. */
4220 const char *
4221 nds32_output_casesi (rtx *operands)
4223 /* Step C: "t <-- operands[1]". */
4224 output_asm_insn ("la\t$ta, %l1", operands);
4226 /* Step D: "z <-- (mem (plus (operands[0] << 2) t))". */
4227 output_asm_insn ("lw\t%2, [$ta + %0 << 2]", operands);
4229 /* No need to perform Step E, which is only used for
4230 pc relative jump table. */
4232 /* Step F: jump to target with register z. */
4233 if (TARGET_16_BIT)
4234 return "jr5\t%2";
4235 else
4236 return "jr\t%2";
4240 /* Function to return memory format. */
4241 enum nds32_16bit_address_type
4242 nds32_mem_format (rtx op)
4244 enum machine_mode mode_test;
4245 int val;
4246 int regno;
4248 if (!TARGET_16_BIT)
4249 return ADDRESS_NOT_16BIT_FORMAT;
4251 mode_test = GET_MODE (op);
4253 op = XEXP (op, 0);
4255 /* 45 format. */
4256 if (GET_CODE (op) == REG && (mode_test == SImode))
4257 return ADDRESS_REG;
4259 /* 333 format for QI/HImode. */
4260 if (GET_CODE (op) == REG && (REGNO (op) < R8_REGNUM))
4261 return ADDRESS_LO_REG_IMM3U;
4263 /* post_inc 333 format. */
4264 if ((GET_CODE (op) == POST_INC) && (mode_test == SImode))
4266 regno = REGNO(XEXP (op, 0));
4268 if (regno < 8)
4269 return ADDRESS_POST_INC_LO_REG_IMM3U;
4272 /* post_inc 333 format. */
4273 if ((GET_CODE (op) == POST_MODIFY)
4274 && (mode_test == SImode)
4275 && (REG_P (XEXP (XEXP (op, 1), 0)))
4276 && (CONST_INT_P (XEXP (XEXP (op, 1), 1))))
4278 regno = REGNO (XEXP (XEXP (op, 1), 0));
4279 val = INTVAL (XEXP (XEXP (op, 1), 1));
4280 if (regno < 8 && val < 32)
4281 return ADDRESS_POST_INC_LO_REG_IMM3U;
4284 if ((GET_CODE (op) == PLUS)
4285 && (GET_CODE (XEXP (op, 0)) == REG)
4286 && (GET_CODE (XEXP (op, 1)) == CONST_INT))
4288 val = INTVAL (XEXP (op, 1));
4290 regno = REGNO(XEXP (op, 0));
4292 if (regno > 7
4293 && regno != SP_REGNUM
4294 && regno != FP_REGNUM)
4295 return ADDRESS_NOT_16BIT_FORMAT;
4297 switch (mode_test)
4299 case QImode:
4300 /* 333 format. */
4301 if (val >= 0 && val < 8 && regno < 8)
4302 return ADDRESS_LO_REG_IMM3U;
4303 break;
4305 case HImode:
4306 /* 333 format. */
4307 if (val >= 0 && val < 16 && (val % 2 == 0) && regno < 8)
4308 return ADDRESS_LO_REG_IMM3U;
4309 break;
4311 case SImode:
4312 case SFmode:
4313 case DFmode:
4314 /* fp imply 37 format. */
4315 if ((regno == FP_REGNUM) &&
4316 (val >= 0 && val < 512 && (val % 4 == 0)))
4317 return ADDRESS_FP_IMM7U;
4318 /* sp imply 37 format. */
4319 else if ((regno == SP_REGNUM) &&
4320 (val >= 0 && val < 512 && (val % 4 == 0)))
4321 return ADDRESS_SP_IMM7U;
4322 /* 333 format. */
4323 else if (val >= 0 && val < 32 && (val % 4 == 0) && regno < 8)
4324 return ADDRESS_LO_REG_IMM3U;
4325 break;
4327 default:
4328 break;
4332 return ADDRESS_NOT_16BIT_FORMAT;
4335 /* Output 16-bit store. */
4336 const char *
4337 nds32_output_16bit_store (rtx *operands, int byte)
4339 char pattern[100];
4340 char size;
4341 rtx code = XEXP (operands[0], 0);
4343 size = nds32_byte_to_size (byte);
4345 switch (nds32_mem_format (operands[0]))
4347 case ADDRESS_REG:
4348 operands[0] = code;
4349 output_asm_insn ("swi450\t%1, [%0]", operands);
4350 break;
4351 case ADDRESS_LO_REG_IMM3U:
4352 snprintf (pattern, sizeof (pattern), "s%ci333\t%%1, %%0", size);
4353 output_asm_insn (pattern, operands);
4354 break;
4355 case ADDRESS_POST_INC_LO_REG_IMM3U:
4356 snprintf (pattern, sizeof (pattern), "s%ci333.bi\t%%1, %%0", size);
4357 output_asm_insn (pattern, operands);
4358 break;
4359 case ADDRESS_FP_IMM7U:
4360 output_asm_insn ("swi37\t%1, %0", operands);
4361 break;
4362 case ADDRESS_SP_IMM7U:
4363 /* Get immediate value and set back to operands[1]. */
4364 operands[0] = XEXP (code, 1);
4365 output_asm_insn ("swi37.sp\t%1, [ + (%0)]", operands);
4366 break;
4367 default:
4368 break;
4371 return "";
4374 /* Output 16-bit load. */
4375 const char *
4376 nds32_output_16bit_load (rtx *operands, int byte)
4378 char pattern[100];
4379 unsigned char size;
4380 rtx code = XEXP (operands[1], 0);
4382 size = nds32_byte_to_size (byte);
4384 switch (nds32_mem_format (operands[1]))
4386 case ADDRESS_REG:
4387 operands[1] = code;
4388 output_asm_insn ("lwi450\t%0, [%1]", operands);
4389 break;
4390 case ADDRESS_LO_REG_IMM3U:
4391 snprintf (pattern, sizeof (pattern), "l%ci333\t%%0, %%1", size);
4392 output_asm_insn (pattern, operands);
4393 break;
4394 case ADDRESS_POST_INC_LO_REG_IMM3U:
4395 snprintf (pattern, sizeof (pattern), "l%ci333.bi\t%%0, %%1", size);
4396 output_asm_insn (pattern, operands);
4397 break;
4398 case ADDRESS_FP_IMM7U:
4399 output_asm_insn ("lwi37\t%0, %1", operands);
4400 break;
4401 case ADDRESS_SP_IMM7U:
4402 /* Get immediate value and set back to operands[0]. */
4403 operands[1] = XEXP (code, 1);
4404 output_asm_insn ("lwi37.sp\t%0, [ + (%1)]", operands);
4405 break;
4406 default:
4407 break;
4410 return "";
4413 /* Output 32-bit store. */
4414 const char *
4415 nds32_output_32bit_store (rtx *operands, int byte)
4417 char pattern[100];
4418 unsigned char size;
4419 rtx code = XEXP (operands[0], 0);
4421 size = nds32_byte_to_size (byte);
4423 switch (GET_CODE (code))
4425 case REG:
4426 /* (mem (reg X))
4427 => access location by using register,
4428 use "sbi / shi / swi" */
4429 snprintf (pattern, sizeof (pattern), "s%ci\t%%1, %%0", size);
4430 break;
4432 case SYMBOL_REF:
4433 case CONST:
4434 /* (mem (symbol_ref X))
4435 (mem (const (...)))
4436 => access global variables,
4437 use "sbi.gp / shi.gp / swi.gp" */
4438 operands[0] = XEXP (operands[0], 0);
4439 snprintf (pattern, sizeof (pattern), "s%ci.gp\t%%1, [ + %%0]", size);
4440 break;
4442 case POST_INC:
4443 /* (mem (post_inc reg))
4444 => access location by using register which will be post increment,
4445 use "sbi.bi / shi.bi / swi.bi" */
4446 snprintf (pattern, sizeof (pattern),
4447 "s%ci.bi\t%%1, %%0, %d", size, byte);
4448 break;
4450 case POST_DEC:
4451 /* (mem (post_dec reg))
4452 => access location by using register which will be post decrement,
4453 use "sbi.bi / shi.bi / swi.bi" */
4454 snprintf (pattern, sizeof (pattern),
4455 "s%ci.bi\t%%1, %%0, -%d", size, byte);
4456 break;
4458 case POST_MODIFY:
4459 switch (GET_CODE (XEXP (XEXP (code, 1), 1)))
4461 case REG:
4462 case SUBREG:
4463 /* (mem (post_modify (reg) (plus (reg) (reg))))
4464 => access location by using register which will be
4465 post modified with reg,
4466 use "sb.bi/ sh.bi / sw.bi" */
4467 snprintf (pattern, sizeof (pattern), "s%c.bi\t%%1, %%0", size);
4468 break;
4469 case CONST_INT:
4470 /* (mem (post_modify (reg) (plus (reg) (const_int))))
4471 => access location by using register which will be
4472 post modified with const_int,
4473 use "sbi.bi/ shi.bi / swi.bi" */
4474 snprintf (pattern, sizeof (pattern), "s%ci.bi\t%%1, %%0", size);
4475 break;
4476 default:
4477 abort ();
4479 break;
4481 case PLUS:
4482 switch (GET_CODE (XEXP (code, 1)))
4484 case REG:
4485 case SUBREG:
4486 /* (mem (plus reg reg)) or (mem (plus (mult reg const_int) reg))
4487 => access location by adding two registers,
4488 use "sb / sh / sw" */
4489 snprintf (pattern, sizeof (pattern), "s%c\t%%1, %%0", size);
4490 break;
4491 case CONST_INT:
4492 /* (mem (plus reg const_int))
4493 => access location by adding one register with const_int,
4494 use "sbi / shi / swi" */
4495 snprintf (pattern, sizeof (pattern), "s%ci\t%%1, %%0", size);
4496 break;
4497 default:
4498 abort ();
4500 break;
4502 case LO_SUM:
4503 operands[2] = XEXP (code, 1);
4504 operands[0] = XEXP (code, 0);
4505 snprintf (pattern, sizeof (pattern),
4506 "s%ci\t%%1, [%%0 + lo12(%%2)]", size);
4507 break;
4509 default:
4510 abort ();
4513 output_asm_insn (pattern, operands);
4514 return "";
4517 /* Output 32-bit load. */
4518 const char *
4519 nds32_output_32bit_load (rtx *operands, int byte)
4521 char pattern[100];
4522 unsigned char size;
4523 rtx code;
4525 code = XEXP (operands[1], 0);
4527 size = nds32_byte_to_size (byte);
4529 switch (GET_CODE (code))
4531 case REG:
4532 /* (mem (reg X))
4533 => access location by using register,
4534 use "lbi / lhi / lwi" */
4535 snprintf (pattern, sizeof (pattern), "l%ci\t%%0, %%1", size);
4536 break;
4538 case SYMBOL_REF:
4539 case CONST:
4540 /* (mem (symbol_ref X))
4541 (mem (const (...)))
4542 => access global variables,
4543 use "lbi.gp / lhi.gp / lwi.gp" */
4544 operands[1] = XEXP (operands[1], 0);
4545 snprintf (pattern, sizeof (pattern), "l%ci.gp\t%%0, [ + %%1]", size);
4546 break;
4548 case POST_INC:
4549 /* (mem (post_inc reg))
4550 => access location by using register which will be post increment,
4551 use "lbi.bi / lhi.bi / lwi.bi" */
4552 snprintf (pattern, sizeof (pattern),
4553 "l%ci.bi\t%%0, %%1, %d", size, byte);
4554 break;
4556 case POST_DEC:
4557 /* (mem (post_dec reg))
4558 => access location by using register which will be post decrement,
4559 use "lbi.bi / lhi.bi / lwi.bi" */
4560 snprintf (pattern, sizeof (pattern),
4561 "l%ci.bi\t%%0, %%1, -%d", size, byte);
4562 break;
4564 case POST_MODIFY:
4565 switch (GET_CODE (XEXP (XEXP (code, 1), 1)))
4567 case REG:
4568 case SUBREG:
4569 /* (mem (post_modify (reg) (plus (reg) (reg))))
4570 => access location by using register which will be
4571 post modified with reg,
4572 use "lb.bi/ lh.bi / lw.bi" */
4573 snprintf (pattern, sizeof (pattern), "l%c.bi\t%%0, %%1", size);
4574 break;
4575 case CONST_INT:
4576 /* (mem (post_modify (reg) (plus (reg) (const_int))))
4577 => access location by using register which will be
4578 post modified with const_int,
4579 use "lbi.bi/ lhi.bi / lwi.bi" */
4580 snprintf (pattern, sizeof (pattern), "l%ci.bi\t%%0, %%1", size);
4581 break;
4582 default:
4583 abort ();
4585 break;
4587 case PLUS:
4588 switch (GET_CODE (XEXP (code, 1)))
4590 case REG:
4591 case SUBREG:
4592 /* (mem (plus reg reg)) or (mem (plus (mult reg const_int) reg))
4593 use "lb / lh / lw" */
4594 snprintf (pattern, sizeof (pattern), "l%c\t%%0, %%1", size);
4595 break;
4596 case CONST_INT:
4597 /* (mem (plus reg const_int))
4598 => access location by adding one register with const_int,
4599 use "lbi / lhi / lwi" */
4600 snprintf (pattern, sizeof (pattern), "l%ci\t%%0, %%1", size);
4601 break;
4602 default:
4603 abort ();
4605 break;
4607 case LO_SUM:
4608 operands[2] = XEXP (code, 1);
4609 operands[1] = XEXP (code, 0);
4610 snprintf (pattern, sizeof (pattern),
4611 "l%ci\t%%0, [%%1 + lo12(%%2)]", size);
4612 break;
4614 default:
4615 abort ();
4618 output_asm_insn (pattern, operands);
4619 return "";
4622 /* Output 32-bit load with signed extension. */
4623 const char *
4624 nds32_output_32bit_load_s (rtx *operands, int byte)
4626 char pattern[100];
4627 unsigned char size;
4628 rtx code;
4630 code = XEXP (operands[1], 0);
4632 size = nds32_byte_to_size (byte);
4634 switch (GET_CODE (code))
4636 case REG:
4637 /* (mem (reg X))
4638 => access location by using register,
4639 use "lbsi / lhsi" */
4640 snprintf (pattern, sizeof (pattern), "l%csi\t%%0, %%1", size);
4641 break;
4643 case SYMBOL_REF:
4644 case CONST:
4645 /* (mem (symbol_ref X))
4646 (mem (const (...)))
4647 => access global variables,
4648 use "lbsi.gp / lhsi.gp" */
4649 operands[1] = XEXP (operands[1], 0);
4650 snprintf (pattern, sizeof (pattern), "l%csi.gp\t%%0, [ + %%1]", size);
4651 break;
4653 case POST_INC:
4654 /* (mem (post_inc reg))
4655 => access location by using register which will be post increment,
4656 use "lbsi.bi / lhsi.bi" */
4657 snprintf (pattern, sizeof (pattern),
4658 "l%csi.bi\t%%0, %%1, %d", size, byte);
4659 break;
4661 case POST_DEC:
4662 /* (mem (post_dec reg))
4663 => access location by using register which will be post decrement,
4664 use "lbsi.bi / lhsi.bi" */
4665 snprintf (pattern, sizeof (pattern),
4666 "l%csi.bi\t%%0, %%1, -%d", size, byte);
4667 break;
4669 case POST_MODIFY:
4670 switch (GET_CODE (XEXP (XEXP (code, 1), 1)))
4672 case REG:
4673 case SUBREG:
4674 /* (mem (post_modify (reg) (plus (reg) (reg))))
4675 => access location by using register which will be
4676 post modified with reg,
4677 use "lbs.bi/ lhs.bi" */
4678 snprintf (pattern, sizeof (pattern), "l%cs.bi\t%%0, %%1", size);
4679 break;
4680 case CONST_INT:
4681 /* (mem (post_modify (reg) (plus (reg) (const_int))))
4682 => access location by using register which will be
4683 post modified with const_int,
4684 use "lbsi.bi/ lhsi.bi" */
4685 snprintf (pattern, sizeof (pattern), "l%csi.bi\t%%0, %%1", size);
4686 break;
4687 default:
4688 abort ();
4690 break;
4692 case PLUS:
4693 switch (GET_CODE (XEXP (code, 1)))
4695 case REG:
4696 case SUBREG:
4697 /* (mem (plus reg reg)) or (mem (plus (mult reg const_int) reg))
4698 use "lbs / lhs" */
4699 snprintf (pattern, sizeof (pattern), "l%cs\t%%0, %%1", size);
4700 break;
4701 case CONST_INT:
4702 /* (mem (plus reg const_int))
4703 => access location by adding one register with const_int,
4704 use "lbsi / lhsi" */
4705 snprintf (pattern, sizeof (pattern), "l%csi\t%%0, %%1", size);
4706 break;
4707 default:
4708 abort ();
4710 break;
4712 case LO_SUM:
4713 operands[2] = XEXP (code, 1);
4714 operands[1] = XEXP (code, 0);
4715 snprintf (pattern, sizeof (pattern),
4716 "l%csi\t%%0, [%%1 + lo12(%%2)]", size);
4717 break;
4719 default:
4720 abort ();
4723 output_asm_insn (pattern, operands);
4724 return "";
4727 /* Function to output stack push operation.
4728 We need to deal with normal stack push multiple or stack v3push. */
4729 const char *
4730 nds32_output_stack_push (void)
4732 /* A string pattern for output_asm_insn(). */
4733 char pattern[100];
4734 /* The operands array which will be used in output_asm_insn(). */
4735 rtx operands[3];
4736 /* Pick up callee-saved first regno and last regno for further use. */
4737 int rb_regno = cfun->machine->callee_saved_regs_first_regno;
4738 int re_regno = cfun->machine->callee_saved_regs_last_regno;
4740 if (TARGET_V3PUSH)
4742 /* For stack v3push:
4743 operands[0]: Re
4744 operands[1]: imm8u */
4746 /* This variable is to check if 'push25 Re,imm8u' is available. */
4747 int sp_adjust;
4749 /* Set operands[0]. */
4750 operands[0] = gen_rtx_REG (SImode, re_regno);
4752 /* Check if we can generate 'push25 Re,imm8u',
4753 otherwise, generate 'push25 Re,0'. */
4754 sp_adjust = cfun->machine->local_size
4755 + cfun->machine->out_args_size
4756 + cfun->machine->callee_saved_area_padding_bytes;
4757 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
4758 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust))
4759 operands[1] = GEN_INT (sp_adjust);
4760 else
4761 operands[1] = GEN_INT (0);
4763 /* Create assembly code pattern. */
4764 snprintf (pattern, sizeof (pattern), "push25\t%%0, %%1");
4766 else
4768 /* For normal stack push multiple:
4769 operands[0]: Rb
4770 operands[1]: Re
4771 operands[2]: En4 */
4773 /* This variable is used to check if we only need to generate En4 field.
4774 As long as Rb==Re=SP_REGNUM, we set this variable to 1. */
4775 int push_en4_only_p = 0;
4777 /* Set operands[0] and operands[1]. */
4778 operands[0] = gen_rtx_REG (SImode, rb_regno);
4779 operands[1] = gen_rtx_REG (SImode, re_regno);
4781 /* 'smw.adm $sp,[$sp],$sp,0' means push nothing. */
4782 if (!cfun->machine->fp_size
4783 && !cfun->machine->gp_size
4784 && !cfun->machine->lp_size
4785 && REGNO (operands[0]) == SP_REGNUM
4786 && REGNO (operands[1]) == SP_REGNUM)
4788 /* No need to generate instruction. */
4789 return "";
4791 else
4793 /* If Rb==Re=SP_REGNUM, we only need to generate En4 field. */
4794 if (REGNO (operands[0]) == SP_REGNUM
4795 && REGNO (operands[1]) == SP_REGNUM)
4796 push_en4_only_p = 1;
4798 /* Create assembly code pattern.
4799 We need to handle the form: "Rb, Re, { $fp $gp $lp }". */
4800 snprintf (pattern, sizeof (pattern),
4801 "push.s\t%s{%s%s%s }",
4802 push_en4_only_p ? "" : "%0, %1, ",
4803 cfun->machine->fp_size ? " $fp" : "",
4804 cfun->machine->gp_size ? " $gp" : "",
4805 cfun->machine->lp_size ? " $lp" : "");
4809 /* We use output_asm_insn() to output assembly code by ourself. */
4810 output_asm_insn (pattern, operands);
4811 return "";
4814 /* Function to output stack pop operation.
4815 We need to deal with normal stack pop multiple or stack v3pop. */
4816 const char *
4817 nds32_output_stack_pop (void)
4819 /* A string pattern for output_asm_insn(). */
4820 char pattern[100];
4821 /* The operands array which will be used in output_asm_insn(). */
4822 rtx operands[3];
4823 /* Pick up callee-saved first regno and last regno for further use. */
4824 int rb_regno = cfun->machine->callee_saved_regs_first_regno;
4825 int re_regno = cfun->machine->callee_saved_regs_last_regno;
4827 if (TARGET_V3PUSH)
4829 /* For stack v3pop:
4830 operands[0]: Re
4831 operands[1]: imm8u */
4833 /* This variable is to check if 'pop25 Re,imm8u' is available. */
4834 int sp_adjust;
4836 /* Set operands[0]. */
4837 operands[0] = gen_rtx_REG (SImode, re_regno);
4839 /* Check if we can generate 'pop25 Re,imm8u',
4840 otherwise, generate 'pop25 Re,0'.
4841 We have to consider alloca issue as well.
4842 If the function does call alloca(), the stack pointer is not fixed.
4843 In that case, we cannot use 'pop25 Re,imm8u' directly.
4844 We have to caculate stack pointer from frame pointer
4845 and then use 'pop25 Re,0'. */
4846 sp_adjust = cfun->machine->local_size
4847 + cfun->machine->out_args_size
4848 + cfun->machine->callee_saved_area_padding_bytes;
4849 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
4850 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust)
4851 && !cfun->calls_alloca)
4852 operands[1] = GEN_INT (sp_adjust);
4853 else
4854 operands[1] = GEN_INT (0);
4856 /* Create assembly code pattern. */
4857 snprintf (pattern, sizeof (pattern), "pop25\t%%0, %%1");
4859 else
4861 /* For normal stack pop multiple:
4862 operands[0]: Rb
4863 operands[1]: Re
4864 operands[2]: En4 */
4866 /* This variable is used to check if we only need to generate En4 field.
4867 As long as Rb==Re=SP_REGNUM, we set this variable to 1. */
4868 int pop_en4_only_p = 0;
4870 /* Set operands[0] and operands[1]. */
4871 operands[0] = gen_rtx_REG (SImode, rb_regno);
4872 operands[1] = gen_rtx_REG (SImode, re_regno);
4874 /* 'lmw.bim $sp,[$sp],$sp,0' means pop nothing. */
4875 if (!cfun->machine->fp_size
4876 && !cfun->machine->gp_size
4877 && !cfun->machine->lp_size
4878 && REGNO (operands[0]) == SP_REGNUM
4879 && REGNO (operands[1]) == SP_REGNUM)
4881 /* No need to generate instruction. */
4882 return "";
4884 else
4886 /* If Rb==Re=SP_REGNUM, we only need to generate En4 field. */
4887 if (REGNO (operands[0]) == SP_REGNUM
4888 && REGNO (operands[1]) == SP_REGNUM)
4889 pop_en4_only_p = 1;
4891 /* Create assembly code pattern.
4892 We need to handle the form: "Rb, Re, { $fp $gp $lp }". */
4893 snprintf (pattern, sizeof (pattern),
4894 "pop.s\t%s{%s%s%s }",
4895 pop_en4_only_p ? "" : "%0, %1, ",
4896 cfun->machine->fp_size ? " $fp" : "",
4897 cfun->machine->gp_size ? " $gp" : "",
4898 cfun->machine->lp_size ? " $lp" : "");
4902 /* We use output_asm_insn() to output assembly code by ourself. */
4903 output_asm_insn (pattern, operands);
4904 return "";
4907 /* Return align 2 (log base 2) if the next instruction of LABEL is 4 byte. */
4909 nds32_target_alignment (rtx label)
4911 rtx insn;
4913 if (optimize_size)
4914 return 0;
4916 insn = next_active_insn (label);
4918 if (insn == 0)
4919 return 0;
4920 else if ((get_attr_length (insn) % 4) == 0)
4921 return 2;
4922 else
4923 return 0;
4926 /* ------------------------------------------------------------------------ */
4928 /* PART 5: Initialize target hook structure and definitions. */
4930 /* Controlling the Compilation Driver. */
4933 /* Run-time Target Specification. */
4936 /* Defining Data Structures for Per-function Information. */
4939 /* Storage Layout. */
4941 #undef TARGET_PROMOTE_FUNCTION_MODE
4942 #define TARGET_PROMOTE_FUNCTION_MODE \
4943 default_promote_function_mode_always_promote
4946 /* Layout of Source Language Data Types. */
4949 /* Register Usage. */
4951 /* -- Basic Characteristics of Registers. */
4953 /* -- Order of Allocation of Registers. */
4955 /* -- How Values Fit in Registers. */
4957 /* -- Handling Leaf Functions. */
4959 /* -- Registers That Form a Stack. */
4962 /* Register Classes. */
4964 #undef TARGET_CLASS_MAX_NREGS
4965 #define TARGET_CLASS_MAX_NREGS nds32_class_max_nregs
4967 #undef TARGET_LRA_P
4968 #define TARGET_LRA_P hook_bool_void_true
4970 #undef TARGET_REGISTER_PRIORITY
4971 #define TARGET_REGISTER_PRIORITY nds32_register_priority
4974 /* Obsolete Macros for Defining Constraints. */
4977 /* Stack Layout and Calling Conventions. */
4979 /* -- Basic Stack Layout. */
4981 /* -- Exception Handling Support. */
4983 /* -- Specifying How Stack Checking is Done. */
4985 /* -- Registers That Address the Stack Frame. */
4987 /* -- Eliminating Frame Pointer and Arg Pointer. */
4989 #undef TARGET_CAN_ELIMINATE
4990 #define TARGET_CAN_ELIMINATE nds32_can_eliminate
4992 /* -- Passing Function Arguments on the Stack. */
4994 /* -- Passing Arguments in Registers. */
4996 #undef TARGET_FUNCTION_ARG
4997 #define TARGET_FUNCTION_ARG nds32_function_arg
4999 #undef TARGET_FUNCTION_ARG_ADVANCE
5000 #define TARGET_FUNCTION_ARG_ADVANCE nds32_function_arg_advance
5002 #undef TARGET_FUNCTION_ARG_BOUNDARY
5003 #define TARGET_FUNCTION_ARG_BOUNDARY nds32_function_arg_boundary
5005 /* -- How Scalar Function Values Are Returned. */
5007 #undef TARGET_FUNCTION_VALUE
5008 #define TARGET_FUNCTION_VALUE nds32_function_value
5010 #undef TARGET_LIBCALL_VALUE
5011 #define TARGET_LIBCALL_VALUE nds32_libcall_value
5013 #undef TARGET_FUNCTION_VALUE_REGNO_P
5014 #define TARGET_FUNCTION_VALUE_REGNO_P nds32_function_value_regno_p
5016 /* -- How Large Values Are Returned. */
5018 /* -- Caller-Saves Register Allocation. */
5020 /* -- Function Entry and Exit. */
5022 #undef TARGET_ASM_FUNCTION_PROLOGUE
5023 #define TARGET_ASM_FUNCTION_PROLOGUE nds32_asm_function_prologue
5025 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
5026 #define TARGET_ASM_FUNCTION_END_PROLOGUE nds32_asm_function_end_prologue
5028 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
5029 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE nds32_asm_function_begin_epilogue
5031 #undef TARGET_ASM_FUNCTION_EPILOGUE
5032 #define TARGET_ASM_FUNCTION_EPILOGUE nds32_asm_function_epilogue
5034 #undef TARGET_ASM_OUTPUT_MI_THUNK
5035 #define TARGET_ASM_OUTPUT_MI_THUNK nds32_asm_output_mi_thunk
5037 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
5038 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
5040 /* -- Generating Code for Profiling. */
5042 /* -- Permitting tail calls. */
5044 #undef TARGET_WARN_FUNC_RETURN
5045 #define TARGET_WARN_FUNC_RETURN nds32_warn_func_return
5047 /* Stack smashing protection. */
5050 /* Implementing the Varargs Macros. */
5052 #undef TARGET_STRICT_ARGUMENT_NAMING
5053 #define TARGET_STRICT_ARGUMENT_NAMING nds32_strict_argument_naming
5056 /* Trampolines for Nested Functions. */
5058 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
5059 #define TARGET_ASM_TRAMPOLINE_TEMPLATE nds32_asm_trampoline_template
5061 #undef TARGET_TRAMPOLINE_INIT
5062 #define TARGET_TRAMPOLINE_INIT nds32_trampoline_init
5065 /* Implicit Calls to Library Routines. */
5068 /* Addressing Modes. */
5070 #undef TARGET_LEGITIMATE_ADDRESS_P
5071 #define TARGET_LEGITIMATE_ADDRESS_P nds32_legitimate_address_p
5074 /* Anchored Addresses. */
5077 /* Condition Code Status. */
5079 /* -- Representation of condition codes using (cc0). */
5081 /* -- Representation of condition codes using registers. */
5083 /* -- Macros to control conditional execution. */
5086 /* Describing Relative Costs of Operations. */
5088 #undef TARGET_REGISTER_MOVE_COST
5089 #define TARGET_REGISTER_MOVE_COST nds32_register_move_cost
5091 #undef TARGET_MEMORY_MOVE_COST
5092 #define TARGET_MEMORY_MOVE_COST nds32_memory_move_cost
5094 #undef TARGET_RTX_COSTS
5095 #define TARGET_RTX_COSTS nds32_rtx_costs
5097 #undef TARGET_ADDRESS_COST
5098 #define TARGET_ADDRESS_COST nds32_address_cost
5101 /* Adjusting the Instruction Scheduler. */
5104 /* Dividing the Output into Sections (Texts, Data, . . . ). */
5107 /* Position Independent Code. */
5110 /* Defining the Output Assembler Language. */
5112 /* -- The Overall Framework of an Assembler File. */
5114 #undef TARGET_ASM_FILE_START
5115 #define TARGET_ASM_FILE_START nds32_asm_file_start
5116 #undef TARGET_ASM_FILE_END
5117 #define TARGET_ASM_FILE_END nds32_asm_file_end
5119 /* -- Output of Data. */
5121 #undef TARGET_ASM_ALIGNED_HI_OP
5122 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
5124 #undef TARGET_ASM_ALIGNED_SI_OP
5125 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
5127 /* -- Output of Uninitialized Variables. */
5129 /* -- Output and Generation of Labels. */
5131 #undef TARGET_ASM_GLOBALIZE_LABEL
5132 #define TARGET_ASM_GLOBALIZE_LABEL nds32_asm_globalize_label
5134 /* -- How Initialization Functions Are Handled. */
5136 /* -- Macros Controlling Initialization Routines. */
5138 /* -- Output of Assembler Instructions. */
5140 #undef TARGET_PRINT_OPERAND
5141 #define TARGET_PRINT_OPERAND nds32_print_operand
5142 #undef TARGET_PRINT_OPERAND_ADDRESS
5143 #define TARGET_PRINT_OPERAND_ADDRESS nds32_print_operand_address
5145 /* -- Output of Dispatch Tables. */
5147 /* -- Assembler Commands for Exception Regions. */
5149 /* -- Assembler Commands for Alignment. */
5152 /* Controlling Debugging Information Format. */
5154 /* -- Macros Affecting All Debugging Formats. */
5156 /* -- Specific Options for DBX Output. */
5158 /* -- Open-Ended Hooks for DBX Format. */
5160 /* -- File Names in DBX Format. */
5162 /* -- Macros for SDB and DWARF Output. */
5164 /* -- Macros for VMS Debug Format. */
5167 /* Cross Compilation and Floating Point. */
5170 /* Mode Switching Instructions. */
5173 /* Defining target-specific uses of __attribute__. */
5175 #undef TARGET_ATTRIBUTE_TABLE
5176 #define TARGET_ATTRIBUTE_TABLE nds32_attribute_table
5178 #undef TARGET_MERGE_DECL_ATTRIBUTES
5179 #define TARGET_MERGE_DECL_ATTRIBUTES nds32_merge_decl_attributes
5181 #undef TARGET_INSERT_ATTRIBUTES
5182 #define TARGET_INSERT_ATTRIBUTES nds32_insert_attributes
5184 #undef TARGET_OPTION_PRAGMA_PARSE
5185 #define TARGET_OPTION_PRAGMA_PARSE nds32_option_pragma_parse
5187 #undef TARGET_OPTION_OVERRIDE
5188 #define TARGET_OPTION_OVERRIDE nds32_option_override
5191 /* Emulating TLS. */
5194 /* Defining coprocessor specifics for MIPS targets. */
5197 /* Parameters for Precompiled Header Validity Checking. */
5200 /* C++ ABI parameters. */
5203 /* Adding support for named address spaces. */
5206 /* Miscellaneous Parameters. */
5208 #undef TARGET_INIT_BUILTINS
5209 #define TARGET_INIT_BUILTINS nds32_init_builtins
5211 #undef TARGET_EXPAND_BUILTIN
5212 #define TARGET_EXPAND_BUILTIN nds32_expand_builtin
5215 /* ------------------------------------------------------------------------ */
5217 /* Initialize the GCC target structure. */
5219 struct gcc_target targetm = TARGET_INITIALIZER;
5221 /* ------------------------------------------------------------------------ */