* expr.c (store_field): Don't set MEM_ALIAS_SET for a field
[official-gcc.git] / gcc / config / fr30 / fr30.c
blobf1f63e1c324092f79dd13ee28dfa34ba03191ebf
1 /*{{{ Introduction */
3 /* FR30 specific functions.
4 Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
5 Contributed by Cygnus Solutions.
7 This file is part of GNU CC.
9 GNU CC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
14 GNU CC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GNU CC; see the file COPYING. If not, write to
21 the Free Software Foundation, 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
24 /*}}}*/
25 /*{{{ Includes */
27 #include "config.h"
28 #include "system.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 "output.h"
36 #include "insn-attr.h"
37 #include "flags.h"
38 #include "recog.h"
39 #include "tree.h"
40 #include "expr.h"
41 #include "obstack.h"
42 #include "except.h"
43 #include "function.h"
44 #include "tm_p.h"
46 /*}}}*/
47 /*{{{ Function Prologues & Epilogues */
49 /* Define the information needed to generate branch and scc insns. This is
50 stored from the compare operation. */
52 struct rtx_def * fr30_compare_op0;
53 struct rtx_def * fr30_compare_op1;
55 /* The FR30 stack looks like this:
57 Before call After call
58 FP ->| | | |
59 +-----------------------+ +-----------------------+ high
60 | | | | memory
61 | local variables, | | local variables, |
62 | reg save area, etc. | | reg save area, etc. |
63 | | | |
64 +-----------------------+ +-----------------------+
65 | | | |
66 | args to the func that | | args to this func. |
67 | is being called that | | |
68 SP ->| do not fit in regs | | |
69 +-----------------------+ +-----------------------+
70 | args that used to be | \
71 | in regs; only created | | pretend_size
72 AP-> | for vararg funcs | /
73 +-----------------------+
74 | | \
75 | register save area | |
76 | | |
77 +-----------------------+ | reg_size
78 | return address | |
79 +-----------------------+ |
80 FP ->| previous frame ptr | /
81 +-----------------------+
82 | | \
83 | local variables | | var_size
84 | | /
85 +-----------------------+
86 | | \
87 low | room for args to | |
88 memory | other funcs called | | args_size
89 | from this one | |
90 SP ->| | /
91 +-----------------------+
93 Note, AP is a fake hard register. It will be eliminated in favour of
94 SP or FP as appropriate.
96 Note, Some or all of the stack sections above may be omitted if they
97 are not needed. */
99 /* Structure to be filled in by fr30_compute_frame_size() with register
100 save masks, and offsets for the current function. */
101 struct fr30_frame_info
103 unsigned int total_size; /* # Bytes that the entire frame takes up. */
104 unsigned int pretend_size; /* # Bytes we push and pretend caller did. */
105 unsigned int args_size; /* # Bytes that outgoing arguments take up. */
106 unsigned int reg_size; /* # Bytes needed to store regs. */
107 unsigned int var_size; /* # Bytes that variables take up. */
108 unsigned int frame_size; /* # Bytes in current frame. */
109 unsigned int gmask; /* Mask of saved registers. */
110 unsigned int save_fp; /* Nonzero if frame pointer must be saved. */
111 unsigned int save_rp; /* Nonzero if return popinter must be saved. */
112 int initialised; /* Nonzero if frame size already calculated. */
115 /* Current frame information calculated by fr30_compute_frame_size(). */
116 static struct fr30_frame_info current_frame_info;
118 /* Zero structure to initialize current_frame_info. */
119 static struct fr30_frame_info zero_frame_info;
121 #define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
122 #define RETURN_POINTER_MASK (1 << (RETURN_POINTER_REGNUM))
124 /* Tell prologue and epilogue if register REGNO should be saved / restored.
125 The return address and frame pointer are treated separately.
126 Don't consider them here. */
127 #define MUST_SAVE_REGISTER(regno) \
128 ( (regno) != RETURN_POINTER_REGNUM \
129 && (regno) != FRAME_POINTER_REGNUM \
130 && regs_ever_live [regno] \
131 && ! call_used_regs [regno] )
133 #define MUST_SAVE_FRAME_POINTER (regs_ever_live [FRAME_POINTER_REGNUM] || frame_pointer_needed)
134 #define MUST_SAVE_RETURN_POINTER (regs_ever_live [RETURN_POINTER_REGNUM] || profile_flag)
136 #if UNITS_PER_WORD == 4
137 #define WORD_ALIGN(SIZE) (((SIZE) + 3) & ~3)
138 #endif
140 /* Returns the number of bytes offset between FROM_REG and TO_REG
141 for the current function. As a side effect it fills in the
142 current_frame_info structure, if the data is available. */
143 unsigned int
144 fr30_compute_frame_size (from_reg, to_reg)
145 int from_reg;
146 int to_reg;
148 int regno;
149 unsigned int return_value;
150 unsigned int var_size;
151 unsigned int args_size;
152 unsigned int pretend_size;
153 unsigned int reg_size;
154 unsigned int gmask;
156 var_size = WORD_ALIGN (get_frame_size ());
157 args_size = WORD_ALIGN (current_function_outgoing_args_size);
158 pretend_size = current_function_pretend_args_size;
160 reg_size = 0;
161 gmask = 0;
163 /* Calculate space needed for registers. */
164 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno ++)
166 if (MUST_SAVE_REGISTER (regno))
168 reg_size += UNITS_PER_WORD;
169 gmask |= 1 << regno;
173 current_frame_info.save_fp = MUST_SAVE_FRAME_POINTER;
174 current_frame_info.save_rp = MUST_SAVE_RETURN_POINTER;
176 reg_size += (current_frame_info.save_fp + current_frame_info.save_rp)
177 * UNITS_PER_WORD;
179 /* Save computed information. */
180 current_frame_info.pretend_size = pretend_size;
181 current_frame_info.var_size = var_size;
182 current_frame_info.args_size = args_size;
183 current_frame_info.reg_size = reg_size;
184 current_frame_info.frame_size = args_size + var_size;
185 current_frame_info.total_size = args_size + var_size + reg_size + pretend_size;
186 current_frame_info.gmask = gmask;
187 current_frame_info.initialised = reload_completed;
189 /* Calculate the required distance. */
190 return_value = 0;
192 if (to_reg == STACK_POINTER_REGNUM)
193 return_value += args_size + var_size;
195 if (from_reg == ARG_POINTER_REGNUM)
196 return_value += reg_size;
198 return return_value;
201 /* Called after register allocation to add any instructions needed for the
202 prologue. Using a prologue insn is favored compared to putting all of the
203 instructions in the FUNCTION_PROLOGUE macro, since it allows the scheduler
204 to intermix instructions with the saves of the caller saved registers. In
205 some cases, it might be necessary to emit a barrier instruction as the last
206 insn to prevent such scheduling. */
208 void
209 fr30_expand_prologue ()
211 int regno;
212 rtx insn;
214 if (! current_frame_info.initialised)
215 fr30_compute_frame_size (0, 0);
217 /* This cases shouldn't happen. Catch it now. */
218 if (current_frame_info.total_size == 0
219 && current_frame_info.gmask)
220 abort ();
222 /* Allocate space for register arguments if this is a variadic function. */
223 if (current_frame_info.pretend_size)
225 int regs_to_save = current_frame_info.pretend_size / UNITS_PER_WORD;
227 /* Push argument registers into the pretend arg area. */
228 for (regno = FIRST_ARG_REGNUM + FR30_NUM_ARG_REGS; regno --, regs_to_save --;)
230 insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno)));
231 RTX_FRAME_RELATED_P (insn) = 1;
235 if (current_frame_info.gmask)
237 /* Save any needed call-saved regs. */
238 for (regno = STACK_POINTER_REGNUM; regno--;)
240 if ((current_frame_info.gmask & (1 << regno)) != 0)
242 insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno)));
243 RTX_FRAME_RELATED_P (insn) = 1;
248 /* Save return address if necessary. */
249 if (current_frame_info.save_rp)
251 insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode,
252 RETURN_POINTER_REGNUM)));
253 RTX_FRAME_RELATED_P (insn) = 1;
256 /* Save old frame pointer and create new one, if necessary. */
257 if (current_frame_info.save_fp)
259 if (current_frame_info.frame_size < ((1 << 10) - UNITS_PER_WORD))
261 int enter_size = current_frame_info.frame_size + UNITS_PER_WORD;
262 rtx pattern;
264 insn = emit_insn (gen_enter_func (GEN_INT (enter_size)));
265 RTX_FRAME_RELATED_P (insn) = 1;
267 pattern = PATTERN (insn);
269 /* Also mark all 3 subexpressions as RTX_FRAME_RELATED_P. */
270 if (GET_CODE (pattern) == PARALLEL)
272 int x;
273 for (x = XVECLEN (pattern, 0); x--;)
275 rtx part = XVECEXP (pattern, 0, x);
277 /* One of the insns in the ENTER pattern updates the
278 frame pointer. If we do not actually need the frame
279 pointer in this function then this is a side effect
280 rather than a desired effect, so we do not mark that
281 insn as being related to the frame set up. Doing this
282 allows us to compile the crash66.C test file in the
283 G++ testsuite. */
284 if (! frame_pointer_needed
285 && GET_CODE (part) == SET
286 && REGNO (SET_DEST (part)) == HARD_FRAME_POINTER_REGNUM)
287 RTX_FRAME_RELATED_P (part) = 0;
288 else
289 RTX_FRAME_RELATED_P (part) = 1;
293 else
295 insn = emit_insn (gen_movsi_push (frame_pointer_rtx));
296 RTX_FRAME_RELATED_P (insn) = 1;
298 if (frame_pointer_needed)
300 insn = emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx));
301 RTX_FRAME_RELATED_P (insn) = 1;
306 /* Allocate the stack frame. */
307 if (current_frame_info.frame_size == 0)
308 ; /* Nothing to do. */
309 else if (current_frame_info.save_fp
310 && current_frame_info.frame_size < ((1 << 10) - UNITS_PER_WORD))
311 ; /* Nothing to do. */
312 else if (current_frame_info.frame_size <= 512)
314 insn = emit_insn (gen_add_to_stack (GEN_INT (- current_frame_info.frame_size)));
315 RTX_FRAME_RELATED_P (insn) = 1;
317 else
319 rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);
320 insn = emit_insn (gen_movsi (tmp, GEN_INT (current_frame_info.frame_size)));
321 RTX_FRAME_RELATED_P (insn) = 1;
322 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
323 RTX_FRAME_RELATED_P (insn) = 1;
326 if (profile_flag || profile_block_flag)
327 emit_insn (gen_blockage ());
330 /* Called after register allocation to add any instructions needed for the
331 epilogue. Using a epilogue insn is favored compared to putting all of the
332 instructions in the FUNCTION_EPILOGUE macro, since it allows the scheduler
333 to intermix instructions with the restores of the caller saved registers.
334 In some cases, it might be necessary to emit a barrier instruction as the
335 first insn to prevent such scheduling. */
336 void
337 fr30_expand_epilogue ()
339 int regno;
341 /* Perform the inversion operations of the prologue. */
342 if (! current_frame_info.initialised)
343 abort ();
345 /* Pop local variables and arguments off the stack.
346 If frame_pointer_needed is TRUE then the frame pointer register
347 has actually been used as a frame pointer, and we can recover
348 the stack pointer from it, otherwise we must unwind the stack
349 manually. */
350 if (current_frame_info.frame_size > 0)
352 if (current_frame_info.save_fp && frame_pointer_needed)
354 emit_insn (gen_leave_func ());
355 current_frame_info.save_fp = 0;
357 else if (current_frame_info.frame_size <= 508)
358 emit_insn (gen_add_to_stack
359 (GEN_INT (current_frame_info.frame_size)));
360 else
362 rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);
363 emit_insn (gen_movsi (tmp, GEN_INT (current_frame_info.frame_size)));
364 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
368 if (current_frame_info.save_fp)
369 emit_insn (gen_movsi_pop (frame_pointer_rtx));
371 /* Pop all the registers that were pushed. */
372 if (current_frame_info.save_rp)
373 emit_insn (gen_movsi_pop (gen_rtx_REG (Pmode, RETURN_POINTER_REGNUM)));
375 for (regno = 0; regno < STACK_POINTER_REGNUM; regno ++)
376 if (current_frame_info.gmask & (1 << regno))
377 emit_insn (gen_movsi_pop (gen_rtx_REG (Pmode, regno)));
379 if (current_frame_info.pretend_size)
380 emit_insn (gen_add_to_stack (GEN_INT (current_frame_info.pretend_size)));
382 /* Reset state info for each function. */
383 current_frame_info = zero_frame_info;
385 emit_jump_insn (gen_return_from_func ());
388 /* Do any needed setup for a variadic function. We must create a register
389 parameter block, and then copy any anonymous arguments, plus the last
390 named argument, from registers into memory. * copying actually done in
391 fr30_expand_prologue().
393 ARG_REGS_USED_SO_FAR has *not* been updated for the last named argument
394 which has type TYPE and mode MODE, and we rely on this fact. */
395 void
396 fr30_setup_incoming_varargs (arg_regs_used_so_far, int_mode, type, pretend_size)
397 CUMULATIVE_ARGS arg_regs_used_so_far;
398 int int_mode;
399 tree type ATTRIBUTE_UNUSED;
400 int * pretend_size;
402 enum machine_mode mode = (enum machine_mode)int_mode;
403 int size;
406 /* All BLKmode values are passed by reference. */
407 if (mode == BLKmode)
408 abort ();
410 #if STRICT_ARGUMENT_NAMING
411 /* We must treat `__builtin_va_alist' as an anonymous arg.
412 But otherwise if STRICT_ARGUMENT_NAMING is true then the
413 last named arg must not be treated as an anonymous arg. */
414 if (! current_function_varargs)
415 arg_regs_used_so_far += fr30_num_arg_regs (int_mode, type);
416 #endif
418 size = FR30_NUM_ARG_REGS - arg_regs_used_so_far;
420 if (size <= 0)
421 return;
423 * pretend_size = (size * UNITS_PER_WORD);
426 /*}}}*/
427 /*{{{ Printing operands */
429 /* Print a memory address as an operand to reference that memory location. */
431 void
432 fr30_print_operand_address (stream, address)
433 FILE * stream;
434 rtx address;
436 switch (GET_CODE (address))
438 case SYMBOL_REF:
439 output_addr_const (stream, address);
440 break;
442 default:
443 fprintf (stderr, "code = %x\n", GET_CODE (address));
444 debug_rtx (address);
445 output_operand_lossage ("fr30_print_operand_address: unhandled address");
446 break;
450 /* Print an operand. */
452 void
453 fr30_print_operand (file, x, code)
454 FILE * file;
455 rtx x;
456 int code;
458 rtx x0;
460 switch (code)
462 case '#':
463 /* Output a :D if this instruction is delayed. */
464 if (dbr_sequence_length () != 0)
465 fputs (":D", file);
466 return;
468 case 'p':
469 /* Compute the register name of the second register in a hi/lo
470 register pair. */
471 if (GET_CODE (x) != REG)
472 output_operand_lossage ("fr30_print_operand: unrecognised %p code");
473 else
474 fprintf (file, "r%d", REGNO (x) + 1);
475 return;
477 case 'b':
478 /* Convert GCC's comparison operators into FR30 comparison codes. */
479 switch (GET_CODE (x))
481 case EQ: fprintf (file, "eq"); break;
482 case NE: fprintf (file, "ne"); break;
483 case LT: fprintf (file, "lt"); break;
484 case LE: fprintf (file, "le"); break;
485 case GT: fprintf (file, "gt"); break;
486 case GE: fprintf (file, "ge"); break;
487 case LTU: fprintf (file, "c"); break;
488 case LEU: fprintf (file, "ls"); break;
489 case GTU: fprintf (file, "hi"); break;
490 case GEU: fprintf (file, "nc"); break;
491 default:
492 output_operand_lossage ("fr30_print_operand: unrecognised %b code");
493 break;
495 return;
497 case 'B':
498 /* Convert GCC's comparison operators into the complimentary FR30
499 comparison codes. */
500 switch (GET_CODE (x))
502 case EQ: fprintf (file, "ne"); break;
503 case NE: fprintf (file, "eq"); break;
504 case LT: fprintf (file, "ge"); break;
505 case LE: fprintf (file, "gt"); break;
506 case GT: fprintf (file, "le"); break;
507 case GE: fprintf (file, "lt"); break;
508 case LTU: fprintf (file, "nc"); break;
509 case LEU: fprintf (file, "hi"); break;
510 case GTU: fprintf (file, "ls"); break;
511 case GEU: fprintf (file, "c"); break;
512 default:
513 output_operand_lossage ("fr30_print_operand: unrecognised %B code");
514 break;
516 return;
518 case 'A':
519 /* Print a signed byte value as an unsigned value. */
520 if (GET_CODE (x) != CONST_INT)
521 output_operand_lossage ("fr30_print_operand: invalid operand to %A code");
522 else
524 HOST_WIDE_INT val;
526 val = INTVAL (x);
528 val &= 0xff;
530 fprintf (file, "%d", val);
532 return;
534 case 'x':
535 if (GET_CODE (x) != CONST_INT
536 || INTVAL (x) < 16
537 || INTVAL (x) > 32)
538 output_operand_lossage ("fr30_print_operand: invalid %x code");
539 else
540 fprintf (file, "%d", INTVAL (x) - 16);
541 return;
543 case 'F':
544 if (GET_CODE (x) != CONST_DOUBLE)
545 output_operand_lossage ("fr30_print_operand: invalid %F code");
546 else
548 REAL_VALUE_TYPE d;
550 REAL_VALUE_FROM_CONST_DOUBLE (d, x);
551 fprintf (file, "%.8f", d);
553 return;
555 case 0:
556 /* Handled below. */
557 break;
559 default:
560 fprintf (stderr, "unknown code = %x\n", code);
561 output_operand_lossage ("fr30_print_operand: unknown code");
562 return;
565 switch (GET_CODE (x))
567 case REG:
568 fputs (reg_names [REGNO (x)], file);
569 break;
571 case MEM:
572 x0 = XEXP (x,0);
574 switch (GET_CODE (x0))
576 case REG:
577 if ((unsigned) REGNO (x0) >= ARRAY_SIZE (reg_names))
578 abort ();
579 fprintf (file, "@%s", reg_names [REGNO (x0)]);
580 break;
582 case PLUS:
583 if (GET_CODE (XEXP (x0, 0)) != REG
584 || REGNO (XEXP (x0, 0)) < FRAME_POINTER_REGNUM
585 || REGNO (XEXP (x0, 0)) > STACK_POINTER_REGNUM
586 || GET_CODE (XEXP (x0, 1)) != CONST_INT)
588 fprintf (stderr, "bad INDEXed address:");
589 debug_rtx (x);
590 output_operand_lossage ("fr30_print_operand: unhandled MEM");
592 else if (REGNO (XEXP (x0, 0)) == FRAME_POINTER_REGNUM)
594 HOST_WIDE_INT val = INTVAL (XEXP (x0, 1));
595 if (val < -(1 << 9) || val > ((1 << 9) - 4))
597 fprintf (stderr, "frame INDEX out of range:");
598 debug_rtx (x);
599 output_operand_lossage ("fr30_print_operand: unhandled MEM");
601 fprintf (file, "@(r14, #%d)", val);
603 else
605 HOST_WIDE_INT val = INTVAL (XEXP (x0, 1));
606 if (val < 0 || val > ((1 << 6) - 4))
608 fprintf (stderr, "stack INDEX out of range:");
609 debug_rtx (x);
610 output_operand_lossage ("fr30_print_operand: unhandled MEM");
612 fprintf (file, "@(r15, #%d)", val);
614 break;
616 case SYMBOL_REF:
617 output_address (x0);
618 break;
620 default:
621 fprintf (stderr, "bad MEM code = %x\n", GET_CODE (x0));
622 debug_rtx (x);
623 output_operand_lossage ("fr30_print_operand: unhandled MEM");
624 break;
626 break;
628 case CONST_DOUBLE :
629 /* We handle SFmode constants here as output_addr_const doesn't. */
630 if (GET_MODE (x) == SFmode)
632 REAL_VALUE_TYPE d;
633 long l;
635 REAL_VALUE_FROM_CONST_DOUBLE (d, x);
636 REAL_VALUE_TO_TARGET_SINGLE (d, l);
637 fprintf (file, "0x%08lx", l);
638 break;
641 /* Fall through. Let output_addr_const deal with it. */
642 default:
643 output_addr_const (file, x);
644 break;
647 return;
650 /*}}}*/
651 /*{{{ Function arguments */
653 /* Compute the number of word sized registers needed to hold a
654 function argument of mode INT_MODE and tree type TYPE. */
656 fr30_num_arg_regs (int_mode, type)
657 int int_mode;
658 tree type;
660 enum machine_mode mode = (enum machine_mode) int_mode;
661 int size;
663 if (MUST_PASS_IN_STACK (mode, type))
664 return 0;
666 if (type && mode == BLKmode)
667 size = int_size_in_bytes (type);
668 else
669 size = GET_MODE_SIZE (mode);
671 return (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
674 /* Implements the FUNCTION_ARG_PARTIAL_NREGS macro.
675 Returns the number of argument registers required to hold *part* of
676 a parameter of machine mode MODE and tree type TYPE (which may be
677 NULL if the type is not known). If the argument fits entirly in
678 the argument registers, or entirely on the stack, then 0 is returned.
679 CUM is the number of argument registers already used by earlier
680 parameters to the function. */
683 fr30_function_arg_partial_nregs (cum, int_mode, type, named)
684 CUMULATIVE_ARGS cum;
685 int int_mode;
686 tree type;
687 int named;
689 /* Unnamed arguments, ie those that are prototyped as ...
690 are always passed on the stack.
691 Also check here to see if all the argument registers are full. */
692 if (named == 0 || cum >= FR30_NUM_ARG_REGS)
693 return 0;
695 /* Work out how many argument registers would be needed if this
696 parameter were to be passed entirely in registers. If there
697 are sufficient argument registers available (or if no registers
698 are needed because the parameter must be passed on the stack)
699 then return zero, as this parameter does not require partial
700 register, partial stack stack space. */
701 if (cum + fr30_num_arg_regs (int_mode, type) <= FR30_NUM_ARG_REGS)
702 return 0;
704 /* Otherwise return the number of registers that would be used. */
705 return FR30_NUM_ARG_REGS - cum;
708 static rtx
709 fr30_pass_by_reference (valist, type)
710 tree valist;
711 tree type;
713 tree type_ptr;
714 tree type_ptr_ptr;
715 tree t;
717 type_ptr = build_pointer_type (type);
718 type_ptr_ptr = build_pointer_type (type_ptr);
720 t = build (POSTINCREMENT_EXPR, va_list_type_node, valist, build_int_2 (UNITS_PER_WORD, 0));
721 TREE_SIDE_EFFECTS (t) = 1;
722 t = build1 (NOP_EXPR, type_ptr_ptr, t);
723 TREE_SIDE_EFFECTS (t) = 1;
724 t = build1 (INDIRECT_REF, type_ptr, t);
726 return expand_expr (t, NULL_RTX, Pmode, EXPAND_NORMAL);
729 static rtx
730 fr30_pass_by_value (valist, type)
731 tree valist;
732 tree type;
734 HOST_WIDE_INT size = int_size_in_bytes (type);
735 HOST_WIDE_INT rsize;
736 rtx addr_rtx;
737 tree t;
739 if ((size % UNITS_PER_WORD) == 0)
741 t = build (POSTINCREMENT_EXPR, va_list_type_node, valist, build_int_2 (size, 0));
742 TREE_SIDE_EFFECTS (t) = 1;
744 return expand_expr (t, NULL_RTX, Pmode, EXPAND_NORMAL);
747 rsize = (size + UNITS_PER_WORD - 1) & - UNITS_PER_WORD;
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);
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);
760 return addr_rtx;
763 /* Implement `va_arg'. */
766 fr30_va_arg (valist, type)
767 tree valist;
768 tree type;
770 HOST_WIDE_INT size;
772 if (AGGREGATE_TYPE_P (type))
773 return fr30_pass_by_reference (valist, type);
775 size = int_size_in_bytes (type);
777 if ((size % sizeof (int)) == 0
778 || size < 4)
779 return fr30_pass_by_value (valist, type);
781 return fr30_pass_by_reference (valist, type);
784 /*}}}*/
785 /*{{{ Operand predicates */
787 #ifndef Mmode
788 #define Mmode enum machine_mode
789 #endif
791 /* Returns true if OPERAND is an integer value suitable for use in
792 an ADDSP instruction. */
794 stack_add_operand (operand, mode)
795 rtx operand;
796 Mmode mode ATTRIBUTE_UNUSED;
798 return
799 (GET_CODE (operand) == CONST_INT
800 && INTVAL (operand) >= -512
801 && INTVAL (operand) <= 508
802 && ((INTVAL (operand) & 3) == 0));
805 /* Returns true if OPERAND is an integer value suitable for use in
806 an ADD por ADD2 instruction, or if it is a register. */
808 add_immediate_operand (operand, mode)
809 rtx operand;
810 Mmode mode ATTRIBUTE_UNUSED;
812 return
813 (GET_CODE (operand) == REG
814 || (GET_CODE (operand) == CONST_INT
815 && INTVAL (operand) >= -16
816 && INTVAL (operand) <= 15));
819 /* Returns true if OPERAND is hard register in the range 8 - 15. */
821 high_register_operand (operand, mode)
822 rtx operand;
823 Mmode mode ATTRIBUTE_UNUSED;
825 return
826 (GET_CODE (operand) == REG
827 && REGNO (operand) <= 15
828 && REGNO (operand) >= 8);
831 /* Returns true if OPERAND is hard register in the range 0 - 7. */
833 low_register_operand (operand, mode)
834 rtx operand;
835 Mmode mode ATTRIBUTE_UNUSED;
837 return
838 (GET_CODE (operand) == REG
839 && REGNO (operand) <= 7);
842 /* Returns true if OPERAND is suitable for use in a CALL insn. */
844 call_operand (operand, mode)
845 rtx operand;
846 Mmode mode ATTRIBUTE_UNUSED;
848 return (GET_CODE (operand) == MEM
849 && (GET_CODE (XEXP (operand, 0)) == SYMBOL_REF
850 || GET_CODE (XEXP (operand, 0)) == REG));
853 /* Returns TRUE if OP is a valid operand of a DImode operation. */
855 di_operand (op, mode)
856 rtx op;
857 Mmode mode;
859 if (register_operand (op, mode))
860 return TRUE;
862 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && GET_MODE (op) != DImode)
863 return FALSE;
865 if (GET_CODE (op) == SUBREG)
866 op = SUBREG_REG (op);
868 switch (GET_CODE (op))
870 case CONST_DOUBLE:
871 case CONST_INT:
872 return TRUE;
874 case MEM:
875 return memory_address_p (DImode, XEXP (op, 0));
877 default:
878 return FALSE;
882 /* Returns TRUE if OP is a DImode register or MEM. */
884 nonimmediate_di_operand (op, mode)
885 rtx op;
886 Mmode mode;
888 if (register_operand (op, mode))
889 return TRUE;
891 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && GET_MODE (op) != DImode)
892 return FALSE;
894 if (GET_CODE (op) == SUBREG)
895 op = SUBREG_REG (op);
897 if (GET_CODE (op) == MEM)
898 return memory_address_p (DImode, XEXP (op, 0));
900 return FALSE;
903 /* Returns true iff all the registers in the operands array
904 are in descending or ascending order. */
906 fr30_check_multiple_regs (operands, num_operands, descending)
907 rtx * operands;
908 int num_operands;
909 int descending;
911 if (descending)
913 unsigned int prev_regno = 0;
915 while (num_operands --)
917 if (GET_CODE (operands [num_operands]) != REG)
918 return 0;
920 if (REGNO (operands [num_operands]) < prev_regno)
921 return 0;
923 prev_regno = REGNO (operands [num_operands]);
926 else
928 unsigned int prev_regno = CONDITION_CODE_REGNUM;
930 while (num_operands --)
932 if (GET_CODE (operands [num_operands]) != REG)
933 return 0;
935 if (REGNO (operands [num_operands]) > prev_regno)
936 return 0;
938 prev_regno = REGNO (operands [num_operands]);
942 return 1;
945 /*}}}*/
946 /*{{{ Instruction Output Routines */
948 /* Output a double word move.
949 It must be REG<-REG, REG<-MEM, MEM<-REG or REG<-CONST.
950 On the FR30 we are contrained by the fact that it does not
951 support offsetable addresses, and so we have to load the
952 address of the secnd word into the second destination register
953 before we can use it. */
956 fr30_move_double (operands)
957 rtx * operands;
959 rtx src = operands[1];
960 rtx dest = operands[0];
961 enum rtx_code src_code = GET_CODE (src);
962 enum rtx_code dest_code = GET_CODE (dest);
963 enum machine_mode mode = GET_MODE (dest);
964 rtx val;
966 start_sequence ();
968 if (dest_code == REG)
970 if (src_code == REG)
972 int reverse = (REGNO (dest) == REGNO (src) + 1);
974 /* We normally copy the low-numbered register first. However, if
975 the first register of operand 0 is the same as the second register
976 of operand 1, we must copy in the opposite order. */
977 emit_insn (gen_rtx_SET (VOIDmode,
978 operand_subword (dest, reverse, TRUE, mode),
979 operand_subword (src, reverse, TRUE, mode)));
981 emit_insn (gen_rtx_SET (VOIDmode,
982 operand_subword (dest, !reverse, TRUE, mode),
983 operand_subword (src, !reverse, TRUE, mode)));
985 else if (src_code == MEM)
987 rtx addr = XEXP (src, 0);
988 int dregno = REGNO (dest);
989 rtx dest0;
990 rtx dest1;
991 rtx new_mem;
993 /* If the high-address word is used in the address, we
994 must load it last. Otherwise, load it first. */
995 int reverse = (refers_to_regno_p (dregno, dregno + 1, addr, 0) != 0);
997 if (GET_CODE (addr) != REG)
998 abort ();
1000 dest0 = operand_subword (dest, reverse, TRUE, mode);
1001 dest1 = operand_subword (dest, !reverse, TRUE, mode);
1003 if (reverse)
1005 emit_insn (gen_rtx_SET (VOIDmode, dest1, change_address (src, SImode, addr)));
1006 emit_insn (gen_rtx_SET (SImode, dest0, gen_rtx_REG (SImode, REGNO (addr))));
1007 emit_insn (gen_rtx_SET (SImode, dest0, plus_constant (dest0, UNITS_PER_WORD)));
1009 new_mem = gen_rtx_MEM (SImode, dest0);
1010 MEM_COPY_ATTRIBUTES (new_mem, src);
1012 emit_insn (gen_rtx_SET (VOIDmode, dest0, new_mem));
1014 else
1016 emit_insn (gen_rtx_SET (VOIDmode, dest0, change_address (src, SImode, addr)));
1017 emit_insn (gen_rtx_SET (SImode, dest1, gen_rtx_REG (SImode, REGNO (addr))));
1018 emit_insn (gen_rtx_SET (SImode, dest1, plus_constant (dest1, UNITS_PER_WORD)));
1020 new_mem = gen_rtx_MEM (SImode, dest1);
1021 MEM_COPY_ATTRIBUTES (new_mem, src);
1023 emit_insn (gen_rtx_SET (VOIDmode, dest1, new_mem));
1026 else if (src_code == CONST_INT || src_code == CONST_DOUBLE)
1028 rtx words[2];
1029 split_double (src, &words[0], &words[1]);
1030 emit_insn (gen_rtx_SET (VOIDmode,
1031 operand_subword (dest, 0, TRUE, mode),
1032 words[0]));
1034 emit_insn (gen_rtx_SET (VOIDmode,
1035 operand_subword (dest, 1, TRUE, mode),
1036 words[1]));
1039 else if (src_code == REG && dest_code == MEM)
1041 rtx addr = XEXP (dest, 0);
1042 rtx src0;
1043 rtx src1;
1045 if (GET_CODE (addr) != REG)
1046 abort ();
1048 src0 = operand_subword (src, 0, TRUE, mode);
1049 src1 = operand_subword (src, 1, TRUE, mode);
1051 emit_insn (gen_rtx_SET (VOIDmode, change_address (dest, SImode, addr), src0));
1053 if (REGNO (addr) == STACK_POINTER_REGNUM)
1054 emit_insn (gen_rtx_SET (VOIDmode, change_address (dest, SImode, plus_constant (stack_pointer_rtx, UNITS_PER_WORD)), src1));
1055 else if (REGNO (addr) == FRAME_POINTER_REGNUM)
1056 emit_insn (gen_rtx_SET (VOIDmode, change_address (dest, SImode, plus_constant (frame_pointer_rtx, UNITS_PER_WORD)), src1));
1057 else
1059 rtx new_mem;
1061 /* We need a scratch register to hold the value of 'address + 4'.
1062 We ought to allow gcc to find one for us, but for now, just
1063 push one of the source registers. */
1064 emit_insn (gen_movsi_push (src0));
1065 emit_insn (gen_movsi_internal (src0, addr));
1066 emit_insn (gen_addsi_small_int (src0, src0, GEN_INT (UNITS_PER_WORD)));
1068 new_mem = gen_rtx_MEM (SImode, src0);
1069 MEM_COPY_ATTRIBUTES (new_mem, dest);
1071 emit_insn (gen_rtx_SET (VOIDmode, new_mem, src1));
1072 emit_insn (gen_movsi_pop (src0));
1075 else
1076 /* This should have been prevented by the contraints on movdi_insn. */
1077 abort ();
1079 val = gen_sequence ();
1080 end_sequence ();
1082 return val;
1085 /*}}}*/
1087 /* Local Variables: */
1088 /* folded-file: t */
1089 /* End: */