4b729e8e819e33585c0b87c649c99e9c5f51446f
[gcc.git] / gcc / config / fr30 / fr30.c
1 /* FR30 specific functions.
2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004
3 Free Software Foundation, Inc.
4 Contributed by Cygnus Solutions.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
22
23 /*{{{ Includes */
24
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "tm.h"
29 #include "rtl.h"
30 #include "regs.h"
31 #include "hard-reg-set.h"
32 #include "real.h"
33 #include "insn-config.h"
34 #include "conditions.h"
35 #include "insn-attr.h"
36 #include "flags.h"
37 #include "recog.h"
38 #include "tree.h"
39 #include "output.h"
40 #include "expr.h"
41 #include "obstack.h"
42 #include "except.h"
43 #include "function.h"
44 #include "toplev.h"
45 #include "tm_p.h"
46 #include "target.h"
47 #include "target-def.h"
48
49 /*}}}*/
50 /*{{{ Function Prologues & Epilogues */
51
52 /* Define the information needed to generate branch and scc insns. This is
53 stored from the compare operation. */
54
55 struct rtx_def * fr30_compare_op0;
56 struct rtx_def * fr30_compare_op1;
57
58 /* The FR30 stack looks like this:
59
60 Before call After call
61 FP ->| | | |
62 +-----------------------+ +-----------------------+ high
63 | | | | memory
64 | local variables, | | local variables, |
65 | reg save area, etc. | | reg save area, etc. |
66 | | | |
67 +-----------------------+ +-----------------------+
68 | | | |
69 | args to the func that | | args to this func. |
70 | is being called that | | |
71 SP ->| do not fit in regs | | |
72 +-----------------------+ +-----------------------+
73 | args that used to be | \
74 | in regs; only created | | pretend_size
75 AP-> | for vararg funcs | /
76 +-----------------------+
77 | | \
78 | register save area | |
79 | | |
80 +-----------------------+ | reg_size
81 | return address | |
82 +-----------------------+ |
83 FP ->| previous frame ptr | /
84 +-----------------------+
85 | | \
86 | local variables | | var_size
87 | | /
88 +-----------------------+
89 | | \
90 low | room for args to | |
91 memory | other funcs called | | args_size
92 | from this one | |
93 SP ->| | /
94 +-----------------------+
95
96 Note, AP is a fake hard register. It will be eliminated in favor of
97 SP or FP as appropriate.
98
99 Note, Some or all of the stack sections above may be omitted if they
100 are not needed. */
101
102 /* Structure to be filled in by fr30_compute_frame_size() with register
103 save masks, and offsets for the current function. */
104 struct fr30_frame_info
105 {
106 unsigned int total_size; /* # Bytes that the entire frame takes up. */
107 unsigned int pretend_size; /* # Bytes we push and pretend caller did. */
108 unsigned int args_size; /* # Bytes that outgoing arguments take up. */
109 unsigned int reg_size; /* # Bytes needed to store regs. */
110 unsigned int var_size; /* # Bytes that variables take up. */
111 unsigned int frame_size; /* # Bytes in current frame. */
112 unsigned int gmask; /* Mask of saved registers. */
113 unsigned int save_fp; /* Nonzero if frame pointer must be saved. */
114 unsigned int save_rp; /* Nonzero if return pointer must be saved. */
115 int initialised; /* Nonzero if frame size already calculated. */
116 };
117
118 /* Current frame information calculated by fr30_compute_frame_size(). */
119 static struct fr30_frame_info current_frame_info;
120
121 /* Zero structure to initialize current_frame_info. */
122 static struct fr30_frame_info zero_frame_info;
123
124 static rtx fr30_pass_by_reference (tree, tree);
125 static rtx fr30_pass_by_value (tree, tree);
126
127 #define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
128 #define RETURN_POINTER_MASK (1 << (RETURN_POINTER_REGNUM))
129
130 /* Tell prologue and epilogue if register REGNO should be saved / restored.
131 The return address and frame pointer are treated separately.
132 Don't consider them here. */
133 #define MUST_SAVE_REGISTER(regno) \
134 ( (regno) != RETURN_POINTER_REGNUM \
135 && (regno) != FRAME_POINTER_REGNUM \
136 && regs_ever_live [regno] \
137 && ! call_used_regs [regno] )
138
139 #define MUST_SAVE_FRAME_POINTER (regs_ever_live [FRAME_POINTER_REGNUM] || frame_pointer_needed)
140 #define MUST_SAVE_RETURN_POINTER (regs_ever_live [RETURN_POINTER_REGNUM] || current_function_profile)
141
142 #if UNITS_PER_WORD == 4
143 #define WORD_ALIGN(SIZE) (((SIZE) + 3) & ~3)
144 #endif
145 \f
146 /* Initialize the GCC target structure. */
147 #undef TARGET_ASM_ALIGNED_HI_OP
148 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
149 #undef TARGET_ASM_ALIGNED_SI_OP
150 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
151
152 #undef TARGET_PROMOTE_PROTOTYPES
153 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
154
155 struct gcc_target targetm = TARGET_INITIALIZER;
156 \f
157 /* Returns the number of bytes offset between FROM_REG and TO_REG
158 for the current function. As a side effect it fills in the
159 current_frame_info structure, if the data is available. */
160 unsigned int
161 fr30_compute_frame_size (int from_reg, int to_reg)
162 {
163 int regno;
164 unsigned int return_value;
165 unsigned int var_size;
166 unsigned int args_size;
167 unsigned int pretend_size;
168 unsigned int reg_size;
169 unsigned int gmask;
170
171 var_size = WORD_ALIGN (get_frame_size ());
172 args_size = WORD_ALIGN (current_function_outgoing_args_size);
173 pretend_size = current_function_pretend_args_size;
174
175 reg_size = 0;
176 gmask = 0;
177
178 /* Calculate space needed for registers. */
179 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno ++)
180 {
181 if (MUST_SAVE_REGISTER (regno))
182 {
183 reg_size += UNITS_PER_WORD;
184 gmask |= 1 << regno;
185 }
186 }
187
188 current_frame_info.save_fp = MUST_SAVE_FRAME_POINTER;
189 current_frame_info.save_rp = MUST_SAVE_RETURN_POINTER;
190
191 reg_size += (current_frame_info.save_fp + current_frame_info.save_rp)
192 * UNITS_PER_WORD;
193
194 /* Save computed information. */
195 current_frame_info.pretend_size = pretend_size;
196 current_frame_info.var_size = var_size;
197 current_frame_info.args_size = args_size;
198 current_frame_info.reg_size = reg_size;
199 current_frame_info.frame_size = args_size + var_size;
200 current_frame_info.total_size = args_size + var_size + reg_size + pretend_size;
201 current_frame_info.gmask = gmask;
202 current_frame_info.initialised = reload_completed;
203
204 /* Calculate the required distance. */
205 return_value = 0;
206
207 if (to_reg == STACK_POINTER_REGNUM)
208 return_value += args_size + var_size;
209
210 if (from_reg == ARG_POINTER_REGNUM)
211 return_value += reg_size;
212
213 return return_value;
214 }
215
216 /* Called after register allocation to add any instructions needed for the
217 prologue. Using a prologue insn is favored compared to putting all of the
218 instructions in output_function_prologue(), since it allows the scheduler
219 to intermix instructions with the saves of the caller saved registers. In
220 some cases, it might be necessary to emit a barrier instruction as the last
221 insn to prevent such scheduling. */
222
223 void
224 fr30_expand_prologue (void)
225 {
226 int regno;
227 rtx insn;
228
229 if (! current_frame_info.initialised)
230 fr30_compute_frame_size (0, 0);
231
232 /* This cases shouldn't happen. Catch it now. */
233 if (current_frame_info.total_size == 0
234 && current_frame_info.gmask)
235 abort ();
236
237 /* Allocate space for register arguments if this is a variadic function. */
238 if (current_frame_info.pretend_size)
239 {
240 int regs_to_save = current_frame_info.pretend_size / UNITS_PER_WORD;
241
242 /* Push argument registers into the pretend arg area. */
243 for (regno = FIRST_ARG_REGNUM + FR30_NUM_ARG_REGS; regno --, regs_to_save --;)
244 {
245 insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno)));
246 RTX_FRAME_RELATED_P (insn) = 1;
247 }
248 }
249
250 if (current_frame_info.gmask)
251 {
252 /* Save any needed call-saved regs. */
253 for (regno = STACK_POINTER_REGNUM; regno--;)
254 {
255 if ((current_frame_info.gmask & (1 << regno)) != 0)
256 {
257 insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno)));
258 RTX_FRAME_RELATED_P (insn) = 1;
259 }
260 }
261 }
262
263 /* Save return address if necessary. */
264 if (current_frame_info.save_rp)
265 {
266 insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode,
267 RETURN_POINTER_REGNUM)));
268 RTX_FRAME_RELATED_P (insn) = 1;
269 }
270
271 /* Save old frame pointer and create new one, if necessary. */
272 if (current_frame_info.save_fp)
273 {
274 if (current_frame_info.frame_size < ((1 << 10) - UNITS_PER_WORD))
275 {
276 int enter_size = current_frame_info.frame_size + UNITS_PER_WORD;
277 rtx pattern;
278
279 insn = emit_insn (gen_enter_func (GEN_INT (enter_size)));
280 RTX_FRAME_RELATED_P (insn) = 1;
281
282 pattern = PATTERN (insn);
283
284 /* Also mark all 3 subexpressions as RTX_FRAME_RELATED_P. */
285 if (GET_CODE (pattern) == PARALLEL)
286 {
287 int x;
288 for (x = XVECLEN (pattern, 0); x--;)
289 {
290 rtx part = XVECEXP (pattern, 0, x);
291
292 /* One of the insns in the ENTER pattern updates the
293 frame pointer. If we do not actually need the frame
294 pointer in this function then this is a side effect
295 rather than a desired effect, so we do not mark that
296 insn as being related to the frame set up. Doing this
297 allows us to compile the crash66.C test file in the
298 G++ testsuite. */
299 if (! frame_pointer_needed
300 && GET_CODE (part) == SET
301 && REGNO (SET_DEST (part)) == HARD_FRAME_POINTER_REGNUM)
302 RTX_FRAME_RELATED_P (part) = 0;
303 else
304 RTX_FRAME_RELATED_P (part) = 1;
305 }
306 }
307 }
308 else
309 {
310 insn = emit_insn (gen_movsi_push (frame_pointer_rtx));
311 RTX_FRAME_RELATED_P (insn) = 1;
312
313 if (frame_pointer_needed)
314 {
315 insn = emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx));
316 RTX_FRAME_RELATED_P (insn) = 1;
317 }
318 }
319 }
320
321 /* Allocate the stack frame. */
322 if (current_frame_info.frame_size == 0)
323 ; /* Nothing to do. */
324 else if (current_frame_info.save_fp
325 && current_frame_info.frame_size < ((1 << 10) - UNITS_PER_WORD))
326 ; /* Nothing to do. */
327 else if (current_frame_info.frame_size <= 512)
328 {
329 insn = emit_insn (gen_add_to_stack (GEN_INT (- current_frame_info.frame_size)));
330 RTX_FRAME_RELATED_P (insn) = 1;
331 }
332 else
333 {
334 rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);
335 insn = emit_insn (gen_movsi (tmp, GEN_INT (current_frame_info.frame_size)));
336 RTX_FRAME_RELATED_P (insn) = 1;
337 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
338 RTX_FRAME_RELATED_P (insn) = 1;
339 }
340
341 if (current_function_profile)
342 emit_insn (gen_blockage ());
343 }
344
345 /* Called after register allocation to add any instructions needed for the
346 epilogue. Using an epilogue insn is favored compared to putting all of the
347 instructions in output_function_epilogue(), since it allows the scheduler
348 to intermix instructions with the restores of the caller saved registers.
349 In some cases, it might be necessary to emit a barrier instruction as the
350 first insn to prevent such scheduling. */
351 void
352 fr30_expand_epilogue (void)
353 {
354 int regno;
355
356 /* Perform the inversion operations of the prologue. */
357 if (! current_frame_info.initialised)
358 abort ();
359
360 /* Pop local variables and arguments off the stack.
361 If frame_pointer_needed is TRUE then the frame pointer register
362 has actually been used as a frame pointer, and we can recover
363 the stack pointer from it, otherwise we must unwind the stack
364 manually. */
365 if (current_frame_info.frame_size > 0)
366 {
367 if (current_frame_info.save_fp && frame_pointer_needed)
368 {
369 emit_insn (gen_leave_func ());
370 current_frame_info.save_fp = 0;
371 }
372 else if (current_frame_info.frame_size <= 508)
373 emit_insn (gen_add_to_stack
374 (GEN_INT (current_frame_info.frame_size)));
375 else
376 {
377 rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);
378 emit_insn (gen_movsi (tmp, GEN_INT (current_frame_info.frame_size)));
379 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
380 }
381 }
382
383 if (current_frame_info.save_fp)
384 emit_insn (gen_movsi_pop (frame_pointer_rtx));
385
386 /* Pop all the registers that were pushed. */
387 if (current_frame_info.save_rp)
388 emit_insn (gen_movsi_pop (gen_rtx_REG (Pmode, RETURN_POINTER_REGNUM)));
389
390 for (regno = 0; regno < STACK_POINTER_REGNUM; regno ++)
391 if (current_frame_info.gmask & (1 << regno))
392 emit_insn (gen_movsi_pop (gen_rtx_REG (Pmode, regno)));
393
394 if (current_frame_info.pretend_size)
395 emit_insn (gen_add_to_stack (GEN_INT (current_frame_info.pretend_size)));
396
397 /* Reset state info for each function. */
398 current_frame_info = zero_frame_info;
399
400 emit_jump_insn (gen_return_from_func ());
401 }
402
403 /* Do any needed setup for a variadic function. We must create a register
404 parameter block, and then copy any anonymous arguments, plus the last
405 named argument, from registers into memory. * copying actually done in
406 fr30_expand_prologue().
407
408 ARG_REGS_USED_SO_FAR has *not* been updated for the last named argument
409 which has type TYPE and mode MODE, and we rely on this fact. */
410 void
411 fr30_setup_incoming_varargs (CUMULATIVE_ARGS arg_regs_used_so_far,
412 int int_mode,
413 tree type ATTRIBUTE_UNUSED,
414 int *pretend_size)
415 {
416 enum machine_mode mode = (enum machine_mode)int_mode;
417 int size;
418
419
420 /* All BLKmode values are passed by reference. */
421 if (mode == BLKmode)
422 abort ();
423
424 /* ??? This run-time test as well as the code inside the if
425 statement is probably unnecessary. */
426 if (targetm.calls.strict_argument_naming (&arg_regs_used_so_far))
427 /* If TARGET_STRICT_ARGUMENT_NAMING returns true, then the last named
428 arg must not be treated as an anonymous arg. */
429 arg_regs_used_so_far += fr30_num_arg_regs (int_mode, type);
430
431 size = FR30_NUM_ARG_REGS - arg_regs_used_so_far;
432
433 if (size <= 0)
434 return;
435
436 * pretend_size = (size * UNITS_PER_WORD);
437 }
438
439 /*}}}*/
440 /*{{{ Printing operands */
441
442 /* Print a memory address as an operand to reference that memory location. */
443
444 void
445 fr30_print_operand_address (FILE *stream, rtx address)
446 {
447 switch (GET_CODE (address))
448 {
449 case SYMBOL_REF:
450 output_addr_const (stream, address);
451 break;
452
453 default:
454 fprintf (stderr, "code = %x\n", GET_CODE (address));
455 debug_rtx (address);
456 output_operand_lossage ("fr30_print_operand_address: unhandled address");
457 break;
458 }
459 }
460
461 /* Print an operand. */
462
463 void
464 fr30_print_operand (FILE *file, rtx x, int code)
465 {
466 rtx x0;
467
468 switch (code)
469 {
470 case '#':
471 /* Output a :D if this instruction is delayed. */
472 if (dbr_sequence_length () != 0)
473 fputs (":D", file);
474 return;
475
476 case 'p':
477 /* Compute the register name of the second register in a hi/lo
478 register pair. */
479 if (GET_CODE (x) != REG)
480 output_operand_lossage ("fr30_print_operand: unrecognized %%p code");
481 else
482 fprintf (file, "r%d", REGNO (x) + 1);
483 return;
484
485 case 'b':
486 /* Convert GCC's comparison operators into FR30 comparison codes. */
487 switch (GET_CODE (x))
488 {
489 case EQ: fprintf (file, "eq"); break;
490 case NE: fprintf (file, "ne"); break;
491 case LT: fprintf (file, "lt"); break;
492 case LE: fprintf (file, "le"); break;
493 case GT: fprintf (file, "gt"); break;
494 case GE: fprintf (file, "ge"); break;
495 case LTU: fprintf (file, "c"); break;
496 case LEU: fprintf (file, "ls"); break;
497 case GTU: fprintf (file, "hi"); break;
498 case GEU: fprintf (file, "nc"); break;
499 default:
500 output_operand_lossage ("fr30_print_operand: unrecognized %%b code");
501 break;
502 }
503 return;
504
505 case 'B':
506 /* Convert GCC's comparison operators into the complimentary FR30
507 comparison codes. */
508 switch (GET_CODE (x))
509 {
510 case EQ: fprintf (file, "ne"); break;
511 case NE: fprintf (file, "eq"); break;
512 case LT: fprintf (file, "ge"); break;
513 case LE: fprintf (file, "gt"); break;
514 case GT: fprintf (file, "le"); break;
515 case GE: fprintf (file, "lt"); break;
516 case LTU: fprintf (file, "nc"); break;
517 case LEU: fprintf (file, "hi"); break;
518 case GTU: fprintf (file, "ls"); break;
519 case GEU: fprintf (file, "c"); break;
520 default:
521 output_operand_lossage ("fr30_print_operand: unrecognized %%B code");
522 break;
523 }
524 return;
525
526 case 'A':
527 /* Print a signed byte value as an unsigned value. */
528 if (GET_CODE (x) != CONST_INT)
529 output_operand_lossage ("fr30_print_operand: invalid operand to %%A code");
530 else
531 {
532 HOST_WIDE_INT val;
533
534 val = INTVAL (x);
535
536 val &= 0xff;
537
538 fprintf (file, HOST_WIDE_INT_PRINT_DEC, val);
539 }
540 return;
541
542 case 'x':
543 if (GET_CODE (x) != CONST_INT
544 || INTVAL (x) < 16
545 || INTVAL (x) > 32)
546 output_operand_lossage ("fr30_print_operand: invalid %%x code");
547 else
548 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) - 16);
549 return;
550
551 case 'F':
552 if (GET_CODE (x) != CONST_DOUBLE)
553 output_operand_lossage ("fr30_print_operand: invalid %%F code");
554 else
555 {
556 char str[30];
557
558 real_to_decimal (str, CONST_DOUBLE_REAL_VALUE (x),
559 sizeof (str), 0, 1);
560 fputs (str, file);
561 }
562 return;
563
564 case 0:
565 /* Handled below. */
566 break;
567
568 default:
569 fprintf (stderr, "unknown code = %x\n", code);
570 output_operand_lossage ("fr30_print_operand: unknown code");
571 return;
572 }
573
574 switch (GET_CODE (x))
575 {
576 case REG:
577 fputs (reg_names [REGNO (x)], file);
578 break;
579
580 case MEM:
581 x0 = XEXP (x,0);
582
583 switch (GET_CODE (x0))
584 {
585 case REG:
586 if ((unsigned) REGNO (x0) >= ARRAY_SIZE (reg_names))
587 abort ();
588 fprintf (file, "@%s", reg_names [REGNO (x0)]);
589 break;
590
591 case PLUS:
592 if (GET_CODE (XEXP (x0, 0)) != REG
593 || REGNO (XEXP (x0, 0)) < FRAME_POINTER_REGNUM
594 || REGNO (XEXP (x0, 0)) > STACK_POINTER_REGNUM
595 || GET_CODE (XEXP (x0, 1)) != CONST_INT)
596 {
597 fprintf (stderr, "bad INDEXed address:");
598 debug_rtx (x);
599 output_operand_lossage ("fr30_print_operand: unhandled MEM");
600 }
601 else if (REGNO (XEXP (x0, 0)) == FRAME_POINTER_REGNUM)
602 {
603 HOST_WIDE_INT val = INTVAL (XEXP (x0, 1));
604 if (val < -(1 << 9) || val > ((1 << 9) - 4))
605 {
606 fprintf (stderr, "frame INDEX out of range:");
607 debug_rtx (x);
608 output_operand_lossage ("fr30_print_operand: unhandled MEM");
609 }
610 fprintf (file, "@(r14, #" HOST_WIDE_INT_PRINT_DEC ")", val);
611 }
612 else
613 {
614 HOST_WIDE_INT val = INTVAL (XEXP (x0, 1));
615 if (val < 0 || val > ((1 << 6) - 4))
616 {
617 fprintf (stderr, "stack INDEX out of range:");
618 debug_rtx (x);
619 output_operand_lossage ("fr30_print_operand: unhandled MEM");
620 }
621 fprintf (file, "@(r15, #" HOST_WIDE_INT_PRINT_DEC ")", val);
622 }
623 break;
624
625 case SYMBOL_REF:
626 output_address (x0);
627 break;
628
629 default:
630 fprintf (stderr, "bad MEM code = %x\n", GET_CODE (x0));
631 debug_rtx (x);
632 output_operand_lossage ("fr30_print_operand: unhandled MEM");
633 break;
634 }
635 break;
636
637 case CONST_DOUBLE :
638 /* We handle SFmode constants here as output_addr_const doesn't. */
639 if (GET_MODE (x) == SFmode)
640 {
641 REAL_VALUE_TYPE d;
642 long l;
643
644 REAL_VALUE_FROM_CONST_DOUBLE (d, x);
645 REAL_VALUE_TO_TARGET_SINGLE (d, l);
646 fprintf (file, "0x%08lx", l);
647 break;
648 }
649
650 /* Fall through. Let output_addr_const deal with it. */
651 default:
652 output_addr_const (file, x);
653 break;
654 }
655
656 return;
657 }
658
659 /*}}}*/
660 /*{{{ Function arguments */
661
662 /* Compute the number of word sized registers needed to hold a
663 function argument of mode INT_MODE and tree type TYPE. */
664 int
665 fr30_num_arg_regs (int int_mode, tree type)
666 {
667 enum machine_mode mode = (enum machine_mode) int_mode;
668 int size;
669
670 if (MUST_PASS_IN_STACK (mode, type))
671 return 0;
672
673 if (type && mode == BLKmode)
674 size = int_size_in_bytes (type);
675 else
676 size = GET_MODE_SIZE (mode);
677
678 return (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
679 }
680
681 /* Implements the FUNCTION_ARG_PARTIAL_NREGS macro.
682 Returns the number of argument registers required to hold *part* of
683 a parameter of machine mode MODE and tree type TYPE (which may be
684 NULL if the type is not known). If the argument fits entirely in
685 the argument registers, or entirely on the stack, then 0 is returned.
686 CUM is the number of argument registers already used by earlier
687 parameters to the function. */
688
689 int
690 fr30_function_arg_partial_nregs (CUMULATIVE_ARGS cum, int int_mode,
691 tree type, int named)
692 {
693 /* Unnamed arguments, ie those that are prototyped as ...
694 are always passed on the stack.
695 Also check here to see if all the argument registers are full. */
696 if (named == 0 || cum >= FR30_NUM_ARG_REGS)
697 return 0;
698
699 /* Work out how many argument registers would be needed if this
700 parameter were to be passed entirely in registers. If there
701 are sufficient argument registers available (or if no registers
702 are needed because the parameter must be passed on the stack)
703 then return zero, as this parameter does not require partial
704 register, partial stack stack space. */
705 if (cum + fr30_num_arg_regs (int_mode, type) <= FR30_NUM_ARG_REGS)
706 return 0;
707
708 /* Otherwise return the number of registers that would be used. */
709 return FR30_NUM_ARG_REGS - cum;
710 }
711
712 static rtx
713 fr30_pass_by_reference (tree valist, tree type)
714 {
715 tree type_ptr;
716 tree type_ptr_ptr;
717 tree t;
718
719 type_ptr = build_pointer_type (type);
720 type_ptr_ptr = build_pointer_type (type_ptr);
721
722 t = build (POSTINCREMENT_EXPR, va_list_type_node, valist, build_int_2 (UNITS_PER_WORD, 0));
723 TREE_SIDE_EFFECTS (t) = 1;
724 t = build1 (NOP_EXPR, type_ptr_ptr, t);
725 TREE_SIDE_EFFECTS (t) = 1;
726 t = build1 (INDIRECT_REF, type_ptr, t);
727
728 return expand_expr (t, NULL_RTX, Pmode, EXPAND_NORMAL);
729 }
730
731 static rtx
732 fr30_pass_by_value (tree valist, tree type)
733 {
734 HOST_WIDE_INT size = int_size_in_bytes (type);
735 HOST_WIDE_INT rsize;
736 rtx addr_rtx;
737 tree t;
738
739 if ((size % UNITS_PER_WORD) == 0)
740 {
741 t = build (POSTINCREMENT_EXPR, va_list_type_node, valist, build_int_2 (size, 0));
742 TREE_SIDE_EFFECTS (t) = 1;
743
744 return expand_expr (t, NULL_RTX, Pmode, EXPAND_NORMAL);
745 }
746
747 rsize = (size + UNITS_PER_WORD - 1) & - UNITS_PER_WORD;
748
749 /* Care for bigendian correction on the aligned address. */
750 t = build (PLUS_EXPR, ptr_type_node, valist, build_int_2 (rsize - size, 0));
751 addr_rtx = expand_expr (t, NULL_RTX, Pmode, EXPAND_NORMAL);
752 addr_rtx = copy_to_reg (addr_rtx);
753
754 /* Increment AP. */
755 t = build (PLUS_EXPR, va_list_type_node, valist, build_int_2 (rsize, 0));
756 t = build (MODIFY_EXPR, va_list_type_node, valist, t);
757 TREE_SIDE_EFFECTS (t) = 1;
758 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
759
760 return addr_rtx;
761 }
762
763 /* Implement `va_arg'. */
764
765 rtx
766 fr30_va_arg (tree valist, tree type)
767 {
768 HOST_WIDE_INT size;
769
770 if (AGGREGATE_TYPE_P (type))
771 return fr30_pass_by_reference (valist, type);
772
773 size = int_size_in_bytes (type);
774
775 if ((size % sizeof (int)) == 0
776 || size < 4)
777 return fr30_pass_by_value (valist, type);
778
779 return fr30_pass_by_reference (valist, type);
780 }
781
782 /*}}}*/
783 /*{{{ Operand predicates */
784
785 #ifndef Mmode
786 #define Mmode enum machine_mode
787 #endif
788
789 /* Returns true if OPERAND is an integer value suitable for use in
790 an ADDSP instruction. */
791 int
792 stack_add_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED)
793 {
794 return
795 (GET_CODE (operand) == CONST_INT
796 && INTVAL (operand) >= -512
797 && INTVAL (operand) <= 508
798 && ((INTVAL (operand) & 3) == 0));
799 }
800
801 /* Returns true if OPERAND is an integer value suitable for use in
802 an ADD por ADD2 instruction, or if it is a register. */
803 int
804 add_immediate_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED)
805 {
806 return
807 (GET_CODE (operand) == REG
808 || (GET_CODE (operand) == CONST_INT
809 && INTVAL (operand) >= -16
810 && INTVAL (operand) <= 15));
811 }
812
813 /* Returns true if OPERAND is hard register in the range 8 - 15. */
814 int
815 high_register_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED)
816 {
817 return
818 (GET_CODE (operand) == REG
819 && REGNO (operand) <= 15
820 && REGNO (operand) >= 8);
821 }
822
823 /* Returns true if OPERAND is hard register in the range 0 - 7. */
824 int
825 low_register_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED)
826 {
827 return
828 (GET_CODE (operand) == REG
829 && REGNO (operand) <= 7);
830 }
831
832 /* Returns true if OPERAND is suitable for use in a CALL insn. */
833 int
834 call_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED)
835 {
836 return (GET_CODE (operand) == MEM
837 && (GET_CODE (XEXP (operand, 0)) == SYMBOL_REF
838 || GET_CODE (XEXP (operand, 0)) == REG));
839 }
840
841 /* Returns TRUE if OP is a valid operand of a DImode operation. */
842 int
843 di_operand (rtx op, Mmode mode)
844 {
845 if (register_operand (op, mode))
846 return TRUE;
847
848 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && GET_MODE (op) != DImode)
849 return FALSE;
850
851 if (GET_CODE (op) == SUBREG)
852 op = SUBREG_REG (op);
853
854 switch (GET_CODE (op))
855 {
856 case CONST_DOUBLE:
857 case CONST_INT:
858 return TRUE;
859
860 case MEM:
861 return memory_address_p (DImode, XEXP (op, 0));
862
863 default:
864 return FALSE;
865 }
866 }
867
868 /* Returns TRUE if OP is a DImode register or MEM. */
869 int
870 nonimmediate_di_operand (rtx op, Mmode mode)
871 {
872 if (register_operand (op, mode))
873 return TRUE;
874
875 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && GET_MODE (op) != DImode)
876 return FALSE;
877
878 if (GET_CODE (op) == SUBREG)
879 op = SUBREG_REG (op);
880
881 if (GET_CODE (op) == MEM)
882 return memory_address_p (DImode, XEXP (op, 0));
883
884 return FALSE;
885 }
886
887 /* Returns true iff all the registers in the operands array
888 are in descending or ascending order. */
889 int
890 fr30_check_multiple_regs (rtx *operands, int num_operands, int descending)
891 {
892 if (descending)
893 {
894 unsigned int prev_regno = 0;
895
896 while (num_operands --)
897 {
898 if (GET_CODE (operands [num_operands]) != REG)
899 return 0;
900
901 if (REGNO (operands [num_operands]) < prev_regno)
902 return 0;
903
904 prev_regno = REGNO (operands [num_operands]);
905 }
906 }
907 else
908 {
909 unsigned int prev_regno = CONDITION_CODE_REGNUM;
910
911 while (num_operands --)
912 {
913 if (GET_CODE (operands [num_operands]) != REG)
914 return 0;
915
916 if (REGNO (operands [num_operands]) > prev_regno)
917 return 0;
918
919 prev_regno = REGNO (operands [num_operands]);
920 }
921 }
922
923 return 1;
924 }
925
926 int
927 fr30_const_double_is_zero (rtx operand)
928 {
929 REAL_VALUE_TYPE d;
930
931 if (operand == NULL || GET_CODE (operand) != CONST_DOUBLE)
932 return 0;
933
934 REAL_VALUE_FROM_CONST_DOUBLE (d, operand);
935
936 return REAL_VALUES_EQUAL (d, dconst0);
937 }
938
939 /*}}}*/
940 /*{{{ Instruction Output Routines */
941
942 /* Output a double word move.
943 It must be REG<-REG, REG<-MEM, MEM<-REG or REG<-CONST.
944 On the FR30 we are constrained by the fact that it does not
945 support offsetable addresses, and so we have to load the
946 address of the secnd word into the second destination register
947 before we can use it. */
948
949 rtx
950 fr30_move_double (rtx * operands)
951 {
952 rtx src = operands[1];
953 rtx dest = operands[0];
954 enum rtx_code src_code = GET_CODE (src);
955 enum rtx_code dest_code = GET_CODE (dest);
956 enum machine_mode mode = GET_MODE (dest);
957 rtx val;
958
959 start_sequence ();
960
961 if (dest_code == REG)
962 {
963 if (src_code == REG)
964 {
965 int reverse = (REGNO (dest) == REGNO (src) + 1);
966
967 /* We normally copy the low-numbered register first. However, if
968 the first register of operand 0 is the same as the second register
969 of operand 1, we must copy in the opposite order. */
970 emit_insn (gen_rtx_SET (VOIDmode,
971 operand_subword (dest, reverse, TRUE, mode),
972 operand_subword (src, reverse, TRUE, mode)));
973
974 emit_insn (gen_rtx_SET (VOIDmode,
975 operand_subword (dest, !reverse, TRUE, mode),
976 operand_subword (src, !reverse, TRUE, mode)));
977 }
978 else if (src_code == MEM)
979 {
980 rtx addr = XEXP (src, 0);
981 int dregno = REGNO (dest);
982 rtx dest0;
983 rtx dest1;
984 rtx new_mem;
985
986 /* If the high-address word is used in the address, we
987 must load it last. Otherwise, load it first. */
988 int reverse = (refers_to_regno_p (dregno, dregno + 1, addr, 0) != 0);
989
990 if (GET_CODE (addr) != REG)
991 abort ();
992
993 dest0 = operand_subword (dest, reverse, TRUE, mode);
994 dest1 = operand_subword (dest, !reverse, TRUE, mode);
995
996 if (reverse)
997 {
998 emit_insn (gen_rtx_SET (VOIDmode, dest1,
999 adjust_address (src, SImode, 0)));
1000 emit_insn (gen_rtx_SET (SImode, dest0,
1001 gen_rtx_REG (SImode, REGNO (addr))));
1002 emit_insn (gen_rtx_SET (SImode, dest0,
1003 plus_constant (dest0, UNITS_PER_WORD)));
1004
1005 new_mem = gen_rtx_MEM (SImode, dest0);
1006 MEM_COPY_ATTRIBUTES (new_mem, src);
1007
1008 emit_insn (gen_rtx_SET (VOIDmode, dest0, new_mem));
1009 }
1010 else
1011 {
1012 emit_insn (gen_rtx_SET (VOIDmode, dest0,
1013 adjust_address (src, SImode, 0)));
1014 emit_insn (gen_rtx_SET (SImode, dest1,
1015 gen_rtx_REG (SImode, REGNO (addr))));
1016 emit_insn (gen_rtx_SET (SImode, dest1,
1017 plus_constant (dest1, UNITS_PER_WORD)));
1018
1019 new_mem = gen_rtx_MEM (SImode, dest1);
1020 MEM_COPY_ATTRIBUTES (new_mem, src);
1021
1022 emit_insn (gen_rtx_SET (VOIDmode, dest1, new_mem));
1023 }
1024 }
1025 else if (src_code == CONST_INT || src_code == CONST_DOUBLE)
1026 {
1027 rtx words[2];
1028 split_double (src, &words[0], &words[1]);
1029 emit_insn (gen_rtx_SET (VOIDmode,
1030 operand_subword (dest, 0, TRUE, mode),
1031 words[0]));
1032
1033 emit_insn (gen_rtx_SET (VOIDmode,
1034 operand_subword (dest, 1, TRUE, mode),
1035 words[1]));
1036 }
1037 }
1038 else if (src_code == REG && dest_code == MEM)
1039 {
1040 rtx addr = XEXP (dest, 0);
1041 rtx src0;
1042 rtx src1;
1043
1044 if (GET_CODE (addr) != REG)
1045 abort ();
1046
1047 src0 = operand_subword (src, 0, TRUE, mode);
1048 src1 = operand_subword (src, 1, TRUE, mode);
1049
1050 emit_insn (gen_rtx_SET (VOIDmode, adjust_address (dest, SImode, 0),
1051 src0));
1052
1053 if (REGNO (addr) == STACK_POINTER_REGNUM
1054 || REGNO (addr) == FRAME_POINTER_REGNUM)
1055 emit_insn (gen_rtx_SET (VOIDmode,
1056 adjust_address (dest, SImode, UNITS_PER_WORD),
1057 src1));
1058 else
1059 {
1060 rtx new_mem;
1061
1062 /* We need a scratch register to hold the value of 'address + 4'.
1063 We ought to allow gcc to find one for us, but for now, just
1064 push one of the source registers. */
1065 emit_insn (gen_movsi_push (src0));
1066 emit_insn (gen_movsi_internal (src0, addr));
1067 emit_insn (gen_addsi_small_int (src0, src0, GEN_INT (UNITS_PER_WORD)));
1068
1069 new_mem = gen_rtx_MEM (SImode, src0);
1070 MEM_COPY_ATTRIBUTES (new_mem, dest);
1071
1072 emit_insn (gen_rtx_SET (VOIDmode, new_mem, src1));
1073 emit_insn (gen_movsi_pop (src0));
1074 }
1075 }
1076 else
1077 /* This should have been prevented by the constraints on movdi_insn. */
1078 abort ();
1079
1080 val = get_insns ();
1081 end_sequence ();
1082
1083 return val;
1084 }
1085 /*}}}*/
1086 /* Local Variables: */
1087 /* folded-file: t */
1088 /* End: */