1 /* FR30 specific functions.
2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008, 2009
3 Free Software Foundation, Inc.
4 Contributed by Cygnus Solutions.
6 This file is part of GCC.
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 3, or (at your option)
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.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
26 #include "coretypes.h"
30 #include "hard-reg-set.h"
32 #include "insn-config.h"
33 #include "conditions.h"
34 #include "insn-attr.h"
46 #include "target-def.h"
49 /*{{{ Function Prologues & Epilogues */
51 /* The FR30 stack looks like this:
53 Before call After call
55 +-----------------------+ +-----------------------+ high
57 | local variables, | | local variables, |
58 | reg save area, etc. | | reg save area, etc. |
60 +-----------------------+ +-----------------------+
62 | args to the func that | | args to this func. |
63 | is being called that | | |
64 SP ->| do not fit in regs | | |
65 +-----------------------+ +-----------------------+
66 | args that used to be | \
67 | in regs; only created | | pretend_size
68 AP-> | for vararg funcs | /
69 +-----------------------+
71 | register save area | |
73 +-----------------------+ | reg_size
75 +-----------------------+ |
76 FP ->| previous frame ptr | /
77 +-----------------------+
79 | local variables | | var_size
81 +-----------------------+
83 low | room for args to | |
84 memory | other funcs called | | args_size
87 +-----------------------+
89 Note, AP is a fake hard register. It will be eliminated in favor of
90 SP or FP as appropriate.
92 Note, Some or all of the stack sections above may be omitted if they
95 /* Structure to be filled in by fr30_compute_frame_size() with register
96 save masks, and offsets for the current function. */
97 struct fr30_frame_info
99 unsigned int total_size; /* # Bytes that the entire frame takes up. */
100 unsigned int pretend_size; /* # Bytes we push and pretend caller did. */
101 unsigned int args_size; /* # Bytes that outgoing arguments take up. */
102 unsigned int reg_size; /* # Bytes needed to store regs. */
103 unsigned int var_size; /* # Bytes that variables take up. */
104 unsigned int frame_size; /* # Bytes in current frame. */
105 unsigned int gmask; /* Mask of saved registers. */
106 unsigned int save_fp; /* Nonzero if frame pointer must be saved. */
107 unsigned int save_rp; /* Nonzero if return pointer must be saved. */
108 int initialised; /* Nonzero if frame size already calculated. */
111 /* Current frame information calculated by fr30_compute_frame_size(). */
112 static struct fr30_frame_info current_frame_info;
114 /* Zero structure to initialize current_frame_info. */
115 static struct fr30_frame_info zero_frame_info;
117 static void fr30_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
119 static bool fr30_must_pass_in_stack (enum machine_mode, const_tree);
120 static int fr30_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
122 static bool fr30_frame_pointer_required (void);
124 #define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
125 #define RETURN_POINTER_MASK (1 << (RETURN_POINTER_REGNUM))
127 /* Tell prologue and epilogue if register REGNO should be saved / restored.
128 The return address and frame pointer are treated separately.
129 Don't consider them here. */
130 #define MUST_SAVE_REGISTER(regno) \
131 ( (regno) != RETURN_POINTER_REGNUM \
132 && (regno) != FRAME_POINTER_REGNUM \
133 && df_regs_ever_live_p (regno) \
134 && ! call_used_regs [regno] )
136 #define MUST_SAVE_FRAME_POINTER (df_regs_ever_live_p (FRAME_POINTER_REGNUM) || frame_pointer_needed)
137 #define MUST_SAVE_RETURN_POINTER (df_regs_ever_live_p (RETURN_POINTER_REGNUM) || crtl->profile)
139 #if UNITS_PER_WORD == 4
140 #define WORD_ALIGN(SIZE) (((SIZE) + 3) & ~3)
143 /* Initialize the GCC target structure. */
144 #undef TARGET_ASM_ALIGNED_HI_OP
145 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
146 #undef TARGET_ASM_ALIGNED_SI_OP
147 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
149 #undef TARGET_PROMOTE_PROTOTYPES
150 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
151 #undef TARGET_PASS_BY_REFERENCE
152 #define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_must_pass_in_stack
153 #undef TARGET_ARG_PARTIAL_BYTES
154 #define TARGET_ARG_PARTIAL_BYTES fr30_arg_partial_bytes
156 #undef TARGET_SETUP_INCOMING_VARARGS
157 #define TARGET_SETUP_INCOMING_VARARGS fr30_setup_incoming_varargs
158 #undef TARGET_MUST_PASS_IN_STACK
159 #define TARGET_MUST_PASS_IN_STACK fr30_must_pass_in_stack
161 #undef TARGET_FRAME_POINTER_REQUIRED
162 #define TARGET_FRAME_POINTER_REQUIRED fr30_frame_pointer_required
164 struct gcc_target targetm = TARGET_INITIALIZER;
166 /* Returns the number of bytes offset between FROM_REG and TO_REG
167 for the current function. As a side effect it fills in the
168 current_frame_info structure, if the data is available. */
170 fr30_compute_frame_size (int from_reg, int to_reg)
173 unsigned int return_value;
174 unsigned int var_size;
175 unsigned int args_size;
176 unsigned int pretend_size;
177 unsigned int reg_size;
180 var_size = WORD_ALIGN (get_frame_size ());
181 args_size = WORD_ALIGN (crtl->outgoing_args_size);
182 pretend_size = crtl->args.pretend_args_size;
187 /* Calculate space needed for registers. */
188 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno ++)
190 if (MUST_SAVE_REGISTER (regno))
192 reg_size += UNITS_PER_WORD;
197 current_frame_info.save_fp = MUST_SAVE_FRAME_POINTER;
198 current_frame_info.save_rp = MUST_SAVE_RETURN_POINTER;
200 reg_size += (current_frame_info.save_fp + current_frame_info.save_rp)
203 /* Save computed information. */
204 current_frame_info.pretend_size = pretend_size;
205 current_frame_info.var_size = var_size;
206 current_frame_info.args_size = args_size;
207 current_frame_info.reg_size = reg_size;
208 current_frame_info.frame_size = args_size + var_size;
209 current_frame_info.total_size = args_size + var_size + reg_size + pretend_size;
210 current_frame_info.gmask = gmask;
211 current_frame_info.initialised = reload_completed;
213 /* Calculate the required distance. */
216 if (to_reg == STACK_POINTER_REGNUM)
217 return_value += args_size + var_size;
219 if (from_reg == ARG_POINTER_REGNUM)
220 return_value += reg_size;
225 /* Called after register allocation to add any instructions needed for the
226 prologue. Using a prologue insn is favored compared to putting all of the
227 instructions in output_function_prologue(), since it allows the scheduler
228 to intermix instructions with the saves of the caller saved registers. In
229 some cases, it might be necessary to emit a barrier instruction as the last
230 insn to prevent such scheduling. */
233 fr30_expand_prologue (void)
238 if (! current_frame_info.initialised)
239 fr30_compute_frame_size (0, 0);
241 /* This cases shouldn't happen. Catch it now. */
242 gcc_assert (current_frame_info.total_size || !current_frame_info.gmask);
244 /* Allocate space for register arguments if this is a variadic function. */
245 if (current_frame_info.pretend_size)
247 int regs_to_save = current_frame_info.pretend_size / UNITS_PER_WORD;
249 /* Push argument registers into the pretend arg area. */
250 for (regno = FIRST_ARG_REGNUM + FR30_NUM_ARG_REGS; regno --, regs_to_save --;)
252 insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno)));
253 RTX_FRAME_RELATED_P (insn) = 1;
257 if (current_frame_info.gmask)
259 /* Save any needed call-saved regs. */
260 for (regno = STACK_POINTER_REGNUM; regno--;)
262 if ((current_frame_info.gmask & (1 << regno)) != 0)
264 insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno)));
265 RTX_FRAME_RELATED_P (insn) = 1;
270 /* Save return address if necessary. */
271 if (current_frame_info.save_rp)
273 insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode,
274 RETURN_POINTER_REGNUM)));
275 RTX_FRAME_RELATED_P (insn) = 1;
278 /* Save old frame pointer and create new one, if necessary. */
279 if (current_frame_info.save_fp)
281 if (current_frame_info.frame_size < ((1 << 10) - UNITS_PER_WORD))
283 int enter_size = current_frame_info.frame_size + UNITS_PER_WORD;
286 insn = emit_insn (gen_enter_func (GEN_INT (enter_size)));
287 RTX_FRAME_RELATED_P (insn) = 1;
289 pattern = PATTERN (insn);
291 /* Also mark all 3 subexpressions as RTX_FRAME_RELATED_P. */
292 if (GET_CODE (pattern) == PARALLEL)
295 for (x = XVECLEN (pattern, 0); x--;)
297 rtx part = XVECEXP (pattern, 0, x);
299 /* One of the insns in the ENTER pattern updates the
300 frame pointer. If we do not actually need the frame
301 pointer in this function then this is a side effect
302 rather than a desired effect, so we do not mark that
303 insn as being related to the frame set up. Doing this
304 allows us to compile the crash66.C test file in the
306 if (! frame_pointer_needed
307 && GET_CODE (part) == SET
308 && SET_DEST (part) == hard_frame_pointer_rtx)
309 RTX_FRAME_RELATED_P (part) = 0;
311 RTX_FRAME_RELATED_P (part) = 1;
317 insn = emit_insn (gen_movsi_push (frame_pointer_rtx));
318 RTX_FRAME_RELATED_P (insn) = 1;
320 if (frame_pointer_needed)
322 insn = emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx));
323 RTX_FRAME_RELATED_P (insn) = 1;
328 /* Allocate the stack frame. */
329 if (current_frame_info.frame_size == 0)
330 ; /* Nothing to do. */
331 else if (current_frame_info.save_fp
332 && current_frame_info.frame_size < ((1 << 10) - UNITS_PER_WORD))
333 ; /* Nothing to do. */
334 else if (current_frame_info.frame_size <= 512)
336 insn = emit_insn (gen_add_to_stack
337 (GEN_INT (- (signed) current_frame_info.frame_size)));
338 RTX_FRAME_RELATED_P (insn) = 1;
342 rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);
343 insn = emit_insn (gen_movsi (tmp, GEN_INT (current_frame_info.frame_size)));
344 RTX_FRAME_RELATED_P (insn) = 1;
345 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
346 RTX_FRAME_RELATED_P (insn) = 1;
350 emit_insn (gen_blockage ());
353 /* Called after register allocation to add any instructions needed for the
354 epilogue. Using an epilogue insn is favored compared to putting all of the
355 instructions in output_function_epilogue(), since it allows the scheduler
356 to intermix instructions with the restores of the caller saved registers.
357 In some cases, it might be necessary to emit a barrier instruction as the
358 first insn to prevent such scheduling. */
360 fr30_expand_epilogue (void)
364 /* Perform the inversion operations of the prologue. */
365 gcc_assert (current_frame_info.initialised);
367 /* Pop local variables and arguments off the stack.
368 If frame_pointer_needed is TRUE then the frame pointer register
369 has actually been used as a frame pointer, and we can recover
370 the stack pointer from it, otherwise we must unwind the stack
372 if (current_frame_info.frame_size > 0)
374 if (current_frame_info.save_fp && frame_pointer_needed)
376 emit_insn (gen_leave_func ());
377 current_frame_info.save_fp = 0;
379 else if (current_frame_info.frame_size <= 508)
380 emit_insn (gen_add_to_stack
381 (GEN_INT (current_frame_info.frame_size)));
384 rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);
385 emit_insn (gen_movsi (tmp, GEN_INT (current_frame_info.frame_size)));
386 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
390 if (current_frame_info.save_fp)
391 emit_insn (gen_movsi_pop (frame_pointer_rtx));
393 /* Pop all the registers that were pushed. */
394 if (current_frame_info.save_rp)
395 emit_insn (gen_movsi_pop (gen_rtx_REG (Pmode, RETURN_POINTER_REGNUM)));
397 for (regno = 0; regno < STACK_POINTER_REGNUM; regno ++)
398 if (current_frame_info.gmask & (1 << regno))
399 emit_insn (gen_movsi_pop (gen_rtx_REG (Pmode, regno)));
401 if (current_frame_info.pretend_size)
402 emit_insn (gen_add_to_stack (GEN_INT (current_frame_info.pretend_size)));
404 /* Reset state info for each function. */
405 current_frame_info = zero_frame_info;
407 emit_jump_insn (gen_return_from_func ());
410 /* Do any needed setup for a variadic function. We must create a register
411 parameter block, and then copy any anonymous arguments, plus the last
412 named argument, from registers into memory. * copying actually done in
413 fr30_expand_prologue().
415 ARG_REGS_USED_SO_FAR has *not* been updated for the last named argument
416 which has type TYPE and mode MODE, and we rely on this fact. */
418 fr30_setup_incoming_varargs (CUMULATIVE_ARGS *arg_regs_used_so_far,
419 enum machine_mode mode,
420 tree type ATTRIBUTE_UNUSED,
422 int second_time ATTRIBUTE_UNUSED)
426 /* All BLKmode values are passed by reference. */
427 gcc_assert (mode != BLKmode);
429 /* ??? This run-time test as well as the code inside the if
430 statement is probably unnecessary. */
431 if (targetm.calls.strict_argument_naming (arg_regs_used_so_far))
432 /* If TARGET_STRICT_ARGUMENT_NAMING returns true, then the last named
433 arg must not be treated as an anonymous arg. */
434 arg_regs_used_so_far += fr30_num_arg_regs (mode, type);
436 size = FR30_NUM_ARG_REGS - (* arg_regs_used_so_far);
441 * pretend_size = (size * UNITS_PER_WORD);
445 /*{{{ Printing operands */
447 /* Print a memory address as an operand to reference that memory location. */
450 fr30_print_operand_address (FILE *stream, rtx address)
452 switch (GET_CODE (address))
455 output_addr_const (stream, address);
459 fprintf (stderr, "code = %x\n", GET_CODE (address));
461 output_operand_lossage ("fr30_print_operand_address: unhandled address");
466 /* Print an operand. */
469 fr30_print_operand (FILE *file, rtx x, int code)
476 /* Output a :D if this instruction is delayed. */
477 if (dbr_sequence_length () != 0)
482 /* Compute the register name of the second register in a hi/lo
484 if (GET_CODE (x) != REG)
485 output_operand_lossage ("fr30_print_operand: unrecognized %%p code");
487 fprintf (file, "r%d", REGNO (x) + 1);
491 /* Convert GCC's comparison operators into FR30 comparison codes. */
492 switch (GET_CODE (x))
494 case EQ: fprintf (file, "eq"); break;
495 case NE: fprintf (file, "ne"); break;
496 case LT: fprintf (file, "lt"); break;
497 case LE: fprintf (file, "le"); break;
498 case GT: fprintf (file, "gt"); break;
499 case GE: fprintf (file, "ge"); break;
500 case LTU: fprintf (file, "c"); break;
501 case LEU: fprintf (file, "ls"); break;
502 case GTU: fprintf (file, "hi"); break;
503 case GEU: fprintf (file, "nc"); break;
505 output_operand_lossage ("fr30_print_operand: unrecognized %%b code");
511 /* Convert GCC's comparison operators into the complimentary FR30
513 switch (GET_CODE (x))
515 case EQ: fprintf (file, "ne"); break;
516 case NE: fprintf (file, "eq"); break;
517 case LT: fprintf (file, "ge"); break;
518 case LE: fprintf (file, "gt"); break;
519 case GT: fprintf (file, "le"); break;
520 case GE: fprintf (file, "lt"); break;
521 case LTU: fprintf (file, "nc"); break;
522 case LEU: fprintf (file, "hi"); break;
523 case GTU: fprintf (file, "ls"); break;
524 case GEU: fprintf (file, "c"); break;
526 output_operand_lossage ("fr30_print_operand: unrecognized %%B code");
532 /* Print a signed byte value as an unsigned value. */
533 if (GET_CODE (x) != CONST_INT)
534 output_operand_lossage ("fr30_print_operand: invalid operand to %%A code");
543 fprintf (file, HOST_WIDE_INT_PRINT_DEC, val);
548 if (GET_CODE (x) != CONST_INT
551 output_operand_lossage ("fr30_print_operand: invalid %%x code");
553 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) - 16);
557 if (GET_CODE (x) != CONST_DOUBLE)
558 output_operand_lossage ("fr30_print_operand: invalid %%F code");
563 real_to_decimal (str, CONST_DOUBLE_REAL_VALUE (x),
574 fprintf (stderr, "unknown code = %x\n", code);
575 output_operand_lossage ("fr30_print_operand: unknown code");
579 switch (GET_CODE (x))
582 fputs (reg_names [REGNO (x)], file);
588 switch (GET_CODE (x0))
591 gcc_assert ((unsigned) REGNO (x0) < ARRAY_SIZE (reg_names));
592 fprintf (file, "@%s", reg_names [REGNO (x0)]);
596 if (GET_CODE (XEXP (x0, 0)) != REG
597 || REGNO (XEXP (x0, 0)) < FRAME_POINTER_REGNUM
598 || REGNO (XEXP (x0, 0)) > STACK_POINTER_REGNUM
599 || GET_CODE (XEXP (x0, 1)) != CONST_INT)
601 fprintf (stderr, "bad INDEXed address:");
603 output_operand_lossage ("fr30_print_operand: unhandled MEM");
605 else if (REGNO (XEXP (x0, 0)) == FRAME_POINTER_REGNUM)
607 HOST_WIDE_INT val = INTVAL (XEXP (x0, 1));
608 if (val < -(1 << 9) || val > ((1 << 9) - 4))
610 fprintf (stderr, "frame INDEX out of range:");
612 output_operand_lossage ("fr30_print_operand: unhandled MEM");
614 fprintf (file, "@(r14, #" HOST_WIDE_INT_PRINT_DEC ")", val);
618 HOST_WIDE_INT val = INTVAL (XEXP (x0, 1));
619 if (val < 0 || val > ((1 << 6) - 4))
621 fprintf (stderr, "stack INDEX out of range:");
623 output_operand_lossage ("fr30_print_operand: unhandled MEM");
625 fprintf (file, "@(r15, #" HOST_WIDE_INT_PRINT_DEC ")", val);
634 fprintf (stderr, "bad MEM code = %x\n", GET_CODE (x0));
636 output_operand_lossage ("fr30_print_operand: unhandled MEM");
642 /* We handle SFmode constants here as output_addr_const doesn't. */
643 if (GET_MODE (x) == SFmode)
648 REAL_VALUE_FROM_CONST_DOUBLE (d, x);
649 REAL_VALUE_TO_TARGET_SINGLE (d, l);
650 fprintf (file, "0x%08lx", l);
654 /* Fall through. Let output_addr_const deal with it. */
656 output_addr_const (file, x);
664 /*{{{ Function arguments */
666 /* Return true if we should pass an argument on the stack rather than
670 fr30_must_pass_in_stack (enum machine_mode mode, const_tree type)
676 return AGGREGATE_TYPE_P (type);
679 /* Compute the number of word sized registers needed to hold a
680 function argument of mode INT_MODE and tree type TYPE. */
682 fr30_num_arg_regs (enum machine_mode mode, tree type)
686 if (targetm.calls.must_pass_in_stack (mode, type))
689 if (type && mode == BLKmode)
690 size = int_size_in_bytes (type);
692 size = GET_MODE_SIZE (mode);
694 return (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
697 /* Returns the number of bytes in which *part* of a parameter of machine
698 mode MODE and tree type TYPE (which may be NULL if the type is not known).
699 If the argument fits entirely in the argument registers, or entirely on
700 the stack, then 0 is returned.
701 CUM is the number of argument registers already used by earlier
702 parameters to the function. */
705 fr30_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
706 tree type, bool named)
708 /* Unnamed arguments, i.e. those that are prototyped as ...
709 are always passed on the stack.
710 Also check here to see if all the argument registers are full. */
711 if (named == 0 || *cum >= FR30_NUM_ARG_REGS)
714 /* Work out how many argument registers would be needed if this
715 parameter were to be passed entirely in registers. If there
716 are sufficient argument registers available (or if no registers
717 are needed because the parameter must be passed on the stack)
718 then return zero, as this parameter does not require partial
719 register, partial stack stack space. */
720 if (*cum + fr30_num_arg_regs (mode, type) <= FR30_NUM_ARG_REGS)
723 return (FR30_NUM_ARG_REGS - *cum) * UNITS_PER_WORD;
727 /*{{{ Operand predicates */
730 #define Mmode enum machine_mode
733 /* Returns true iff all the registers in the operands array
734 are in descending or ascending order. */
736 fr30_check_multiple_regs (rtx *operands, int num_operands, int descending)
740 unsigned int prev_regno = 0;
742 while (num_operands --)
744 if (GET_CODE (operands [num_operands]) != REG)
747 if (REGNO (operands [num_operands]) < prev_regno)
750 prev_regno = REGNO (operands [num_operands]);
755 unsigned int prev_regno = CONDITION_CODE_REGNUM;
757 while (num_operands --)
759 if (GET_CODE (operands [num_operands]) != REG)
762 if (REGNO (operands [num_operands]) > prev_regno)
765 prev_regno = REGNO (operands [num_operands]);
773 fr30_const_double_is_zero (rtx operand)
777 if (operand == NULL || GET_CODE (operand) != CONST_DOUBLE)
780 REAL_VALUE_FROM_CONST_DOUBLE (d, operand);
782 return REAL_VALUES_EQUAL (d, dconst0);
786 /*{{{ Instruction Output Routines */
788 /* Output a double word move.
789 It must be REG<-REG, REG<-MEM, MEM<-REG or REG<-CONST.
790 On the FR30 we are constrained by the fact that it does not
791 support offsetable addresses, and so we have to load the
792 address of the secnd word into the second destination register
793 before we can use it. */
796 fr30_move_double (rtx * operands)
798 rtx src = operands[1];
799 rtx dest = operands[0];
800 enum rtx_code src_code = GET_CODE (src);
801 enum rtx_code dest_code = GET_CODE (dest);
802 enum machine_mode mode = GET_MODE (dest);
807 if (dest_code == REG)
811 int reverse = (REGNO (dest) == REGNO (src) + 1);
813 /* We normally copy the low-numbered register first. However, if
814 the first register of operand 0 is the same as the second register
815 of operand 1, we must copy in the opposite order. */
816 emit_insn (gen_rtx_SET (VOIDmode,
817 operand_subword (dest, reverse, TRUE, mode),
818 operand_subword (src, reverse, TRUE, mode)));
820 emit_insn (gen_rtx_SET (VOIDmode,
821 operand_subword (dest, !reverse, TRUE, mode),
822 operand_subword (src, !reverse, TRUE, mode)));
824 else if (src_code == MEM)
826 rtx addr = XEXP (src, 0);
827 int dregno = REGNO (dest);
828 rtx dest0 = operand_subword (dest, 0, TRUE, mode);;
829 rtx dest1 = operand_subword (dest, 1, TRUE, mode);;
832 gcc_assert (GET_CODE (addr) == REG);
834 /* Copy the address before clobbering it. See PR 34174. */
835 emit_insn (gen_rtx_SET (SImode, dest1, addr));
836 emit_insn (gen_rtx_SET (VOIDmode, dest0,
837 adjust_address (src, SImode, 0)));
838 emit_insn (gen_rtx_SET (SImode, dest1,
839 plus_constant (dest1, UNITS_PER_WORD)));
841 new_mem = gen_rtx_MEM (SImode, dest1);
842 MEM_COPY_ATTRIBUTES (new_mem, src);
844 emit_insn (gen_rtx_SET (VOIDmode, dest1, new_mem));
846 else if (src_code == CONST_INT || src_code == CONST_DOUBLE)
849 split_double (src, &words[0], &words[1]);
850 emit_insn (gen_rtx_SET (VOIDmode,
851 operand_subword (dest, 0, TRUE, mode),
854 emit_insn (gen_rtx_SET (VOIDmode,
855 operand_subword (dest, 1, TRUE, mode),
859 else if (src_code == REG && dest_code == MEM)
861 rtx addr = XEXP (dest, 0);
865 gcc_assert (GET_CODE (addr) == REG);
867 src0 = operand_subword (src, 0, TRUE, mode);
868 src1 = operand_subword (src, 1, TRUE, mode);
870 emit_move_insn (adjust_address (dest, SImode, 0), src0);
872 if (REGNO (addr) == STACK_POINTER_REGNUM
873 || REGNO (addr) == FRAME_POINTER_REGNUM)
874 emit_insn (gen_rtx_SET (VOIDmode,
875 adjust_address (dest, SImode, UNITS_PER_WORD),
880 rtx scratch_reg_r0 = gen_rtx_REG (SImode, 0);
882 /* We need a scratch register to hold the value of 'address + 4'.
883 We use r0 for this purpose. It is used for example for long
884 jumps and is already marked to not be used by normal register
886 emit_insn (gen_movsi_internal (scratch_reg_r0, addr));
887 emit_insn (gen_addsi_small_int (scratch_reg_r0, scratch_reg_r0,
888 GEN_INT (UNITS_PER_WORD)));
889 new_mem = gen_rtx_MEM (SImode, scratch_reg_r0);
890 MEM_COPY_ATTRIBUTES (new_mem, dest);
891 emit_move_insn (new_mem, src1);
892 emit_insn (gen_blockage ());
896 /* This should have been prevented by the constraints on movdi_insn. */
905 /* Implement TARGET_FRAME_POINTER_REQUIRED. */
908 fr30_frame_pointer_required (void)
910 return (flag_omit_frame_pointer == 0 || crtl->args.pretend_args_size > 0);
914 /* Local Variables: */