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);
123 static bool fr30_can_eliminate (const int, const int);
125 #define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
126 #define RETURN_POINTER_MASK (1 << (RETURN_POINTER_REGNUM))
128 /* Tell prologue and epilogue if register REGNO should be saved / restored.
129 The return address and frame pointer are treated separately.
130 Don't consider them here. */
131 #define MUST_SAVE_REGISTER(regno) \
132 ( (regno) != RETURN_POINTER_REGNUM \
133 && (regno) != FRAME_POINTER_REGNUM \
134 && df_regs_ever_live_p (regno) \
135 && ! call_used_regs [regno] )
137 #define MUST_SAVE_FRAME_POINTER (df_regs_ever_live_p (FRAME_POINTER_REGNUM) || frame_pointer_needed)
138 #define MUST_SAVE_RETURN_POINTER (df_regs_ever_live_p (RETURN_POINTER_REGNUM) || crtl->profile)
140 #if UNITS_PER_WORD == 4
141 #define WORD_ALIGN(SIZE) (((SIZE) + 3) & ~3)
144 /* Initialize the GCC target structure. */
145 #undef TARGET_ASM_ALIGNED_HI_OP
146 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
147 #undef TARGET_ASM_ALIGNED_SI_OP
148 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
150 #undef TARGET_PROMOTE_PROTOTYPES
151 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
152 #undef TARGET_PASS_BY_REFERENCE
153 #define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_must_pass_in_stack
154 #undef TARGET_ARG_PARTIAL_BYTES
155 #define TARGET_ARG_PARTIAL_BYTES fr30_arg_partial_bytes
157 #undef TARGET_SETUP_INCOMING_VARARGS
158 #define TARGET_SETUP_INCOMING_VARARGS fr30_setup_incoming_varargs
159 #undef TARGET_MUST_PASS_IN_STACK
160 #define TARGET_MUST_PASS_IN_STACK fr30_must_pass_in_stack
162 #undef TARGET_FRAME_POINTER_REQUIRED
163 #define TARGET_FRAME_POINTER_REQUIRED fr30_frame_pointer_required
165 #undef TARGET_CAN_ELIMINATE
166 #define TARGET_CAN_ELIMINATE fr30_can_eliminate
168 struct gcc_target targetm = TARGET_INITIALIZER;
171 /* Worker function for TARGET_CAN_ELIMINATE. */
174 fr30_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
176 return (to == FRAME_POINTER_REGNUM || ! frame_pointer_needed);
179 /* Returns the number of bytes offset between FROM_REG and TO_REG
180 for the current function. As a side effect it fills in the
181 current_frame_info structure, if the data is available. */
183 fr30_compute_frame_size (int from_reg, int to_reg)
186 unsigned int return_value;
187 unsigned int var_size;
188 unsigned int args_size;
189 unsigned int pretend_size;
190 unsigned int reg_size;
193 var_size = WORD_ALIGN (get_frame_size ());
194 args_size = WORD_ALIGN (crtl->outgoing_args_size);
195 pretend_size = crtl->args.pretend_args_size;
200 /* Calculate space needed for registers. */
201 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno ++)
203 if (MUST_SAVE_REGISTER (regno))
205 reg_size += UNITS_PER_WORD;
210 current_frame_info.save_fp = MUST_SAVE_FRAME_POINTER;
211 current_frame_info.save_rp = MUST_SAVE_RETURN_POINTER;
213 reg_size += (current_frame_info.save_fp + current_frame_info.save_rp)
216 /* Save computed information. */
217 current_frame_info.pretend_size = pretend_size;
218 current_frame_info.var_size = var_size;
219 current_frame_info.args_size = args_size;
220 current_frame_info.reg_size = reg_size;
221 current_frame_info.frame_size = args_size + var_size;
222 current_frame_info.total_size = args_size + var_size + reg_size + pretend_size;
223 current_frame_info.gmask = gmask;
224 current_frame_info.initialised = reload_completed;
226 /* Calculate the required distance. */
229 if (to_reg == STACK_POINTER_REGNUM)
230 return_value += args_size + var_size;
232 if (from_reg == ARG_POINTER_REGNUM)
233 return_value += reg_size;
238 /* Called after register allocation to add any instructions needed for the
239 prologue. Using a prologue insn is favored compared to putting all of the
240 instructions in output_function_prologue(), since it allows the scheduler
241 to intermix instructions with the saves of the caller saved registers. In
242 some cases, it might be necessary to emit a barrier instruction as the last
243 insn to prevent such scheduling. */
246 fr30_expand_prologue (void)
251 if (! current_frame_info.initialised)
252 fr30_compute_frame_size (0, 0);
254 /* This cases shouldn't happen. Catch it now. */
255 gcc_assert (current_frame_info.total_size || !current_frame_info.gmask);
257 /* Allocate space for register arguments if this is a variadic function. */
258 if (current_frame_info.pretend_size)
260 int regs_to_save = current_frame_info.pretend_size / UNITS_PER_WORD;
262 /* Push argument registers into the pretend arg area. */
263 for (regno = FIRST_ARG_REGNUM + FR30_NUM_ARG_REGS; regno --, regs_to_save --;)
265 insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno)));
266 RTX_FRAME_RELATED_P (insn) = 1;
270 if (current_frame_info.gmask)
272 /* Save any needed call-saved regs. */
273 for (regno = STACK_POINTER_REGNUM; regno--;)
275 if ((current_frame_info.gmask & (1 << regno)) != 0)
277 insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno)));
278 RTX_FRAME_RELATED_P (insn) = 1;
283 /* Save return address if necessary. */
284 if (current_frame_info.save_rp)
286 insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode,
287 RETURN_POINTER_REGNUM)));
288 RTX_FRAME_RELATED_P (insn) = 1;
291 /* Save old frame pointer and create new one, if necessary. */
292 if (current_frame_info.save_fp)
294 if (current_frame_info.frame_size < ((1 << 10) - UNITS_PER_WORD))
296 int enter_size = current_frame_info.frame_size + UNITS_PER_WORD;
299 insn = emit_insn (gen_enter_func (GEN_INT (enter_size)));
300 RTX_FRAME_RELATED_P (insn) = 1;
302 pattern = PATTERN (insn);
304 /* Also mark all 3 subexpressions as RTX_FRAME_RELATED_P. */
305 if (GET_CODE (pattern) == PARALLEL)
308 for (x = XVECLEN (pattern, 0); x--;)
310 rtx part = XVECEXP (pattern, 0, x);
312 /* One of the insns in the ENTER pattern updates the
313 frame pointer. If we do not actually need the frame
314 pointer in this function then this is a side effect
315 rather than a desired effect, so we do not mark that
316 insn as being related to the frame set up. Doing this
317 allows us to compile the crash66.C test file in the
319 if (! frame_pointer_needed
320 && GET_CODE (part) == SET
321 && SET_DEST (part) == hard_frame_pointer_rtx)
322 RTX_FRAME_RELATED_P (part) = 0;
324 RTX_FRAME_RELATED_P (part) = 1;
330 insn = emit_insn (gen_movsi_push (frame_pointer_rtx));
331 RTX_FRAME_RELATED_P (insn) = 1;
333 if (frame_pointer_needed)
335 insn = emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx));
336 RTX_FRAME_RELATED_P (insn) = 1;
341 /* Allocate the stack frame. */
342 if (current_frame_info.frame_size == 0)
343 ; /* Nothing to do. */
344 else if (current_frame_info.save_fp
345 && current_frame_info.frame_size < ((1 << 10) - UNITS_PER_WORD))
346 ; /* Nothing to do. */
347 else if (current_frame_info.frame_size <= 512)
349 insn = emit_insn (gen_add_to_stack
350 (GEN_INT (- (signed) current_frame_info.frame_size)));
351 RTX_FRAME_RELATED_P (insn) = 1;
355 rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);
356 insn = emit_insn (gen_movsi (tmp, GEN_INT (current_frame_info.frame_size)));
357 RTX_FRAME_RELATED_P (insn) = 1;
358 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
359 RTX_FRAME_RELATED_P (insn) = 1;
363 emit_insn (gen_blockage ());
366 /* Called after register allocation to add any instructions needed for the
367 epilogue. Using an epilogue insn is favored compared to putting all of the
368 instructions in output_function_epilogue(), since it allows the scheduler
369 to intermix instructions with the restores of the caller saved registers.
370 In some cases, it might be necessary to emit a barrier instruction as the
371 first insn to prevent such scheduling. */
373 fr30_expand_epilogue (void)
377 /* Perform the inversion operations of the prologue. */
378 gcc_assert (current_frame_info.initialised);
380 /* Pop local variables and arguments off the stack.
381 If frame_pointer_needed is TRUE then the frame pointer register
382 has actually been used as a frame pointer, and we can recover
383 the stack pointer from it, otherwise we must unwind the stack
385 if (current_frame_info.frame_size > 0)
387 if (current_frame_info.save_fp && frame_pointer_needed)
389 emit_insn (gen_leave_func ());
390 current_frame_info.save_fp = 0;
392 else if (current_frame_info.frame_size <= 508)
393 emit_insn (gen_add_to_stack
394 (GEN_INT (current_frame_info.frame_size)));
397 rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);
398 emit_insn (gen_movsi (tmp, GEN_INT (current_frame_info.frame_size)));
399 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
403 if (current_frame_info.save_fp)
404 emit_insn (gen_movsi_pop (frame_pointer_rtx));
406 /* Pop all the registers that were pushed. */
407 if (current_frame_info.save_rp)
408 emit_insn (gen_movsi_pop (gen_rtx_REG (Pmode, RETURN_POINTER_REGNUM)));
410 for (regno = 0; regno < STACK_POINTER_REGNUM; regno ++)
411 if (current_frame_info.gmask & (1 << regno))
412 emit_insn (gen_movsi_pop (gen_rtx_REG (Pmode, regno)));
414 if (current_frame_info.pretend_size)
415 emit_insn (gen_add_to_stack (GEN_INT (current_frame_info.pretend_size)));
417 /* Reset state info for each function. */
418 current_frame_info = zero_frame_info;
420 emit_jump_insn (gen_return_from_func ());
423 /* Do any needed setup for a variadic function. We must create a register
424 parameter block, and then copy any anonymous arguments, plus the last
425 named argument, from registers into memory. * copying actually done in
426 fr30_expand_prologue().
428 ARG_REGS_USED_SO_FAR has *not* been updated for the last named argument
429 which has type TYPE and mode MODE, and we rely on this fact. */
431 fr30_setup_incoming_varargs (CUMULATIVE_ARGS *arg_regs_used_so_far,
432 enum machine_mode mode,
433 tree type ATTRIBUTE_UNUSED,
435 int second_time ATTRIBUTE_UNUSED)
439 /* All BLKmode values are passed by reference. */
440 gcc_assert (mode != BLKmode);
442 /* ??? This run-time test as well as the code inside the if
443 statement is probably unnecessary. */
444 if (targetm.calls.strict_argument_naming (arg_regs_used_so_far))
445 /* If TARGET_STRICT_ARGUMENT_NAMING returns true, then the last named
446 arg must not be treated as an anonymous arg. */
447 arg_regs_used_so_far += fr30_num_arg_regs (mode, type);
449 size = FR30_NUM_ARG_REGS - (* arg_regs_used_so_far);
454 * pretend_size = (size * UNITS_PER_WORD);
458 /*{{{ Printing operands */
460 /* Print a memory address as an operand to reference that memory location. */
463 fr30_print_operand_address (FILE *stream, rtx address)
465 switch (GET_CODE (address))
468 output_addr_const (stream, address);
472 fprintf (stderr, "code = %x\n", GET_CODE (address));
474 output_operand_lossage ("fr30_print_operand_address: unhandled address");
479 /* Print an operand. */
482 fr30_print_operand (FILE *file, rtx x, int code)
489 /* Output a :D if this instruction is delayed. */
490 if (dbr_sequence_length () != 0)
495 /* Compute the register name of the second register in a hi/lo
497 if (GET_CODE (x) != REG)
498 output_operand_lossage ("fr30_print_operand: unrecognized %%p code");
500 fprintf (file, "r%d", REGNO (x) + 1);
504 /* Convert GCC's comparison operators into FR30 comparison codes. */
505 switch (GET_CODE (x))
507 case EQ: fprintf (file, "eq"); break;
508 case NE: fprintf (file, "ne"); break;
509 case LT: fprintf (file, "lt"); break;
510 case LE: fprintf (file, "le"); break;
511 case GT: fprintf (file, "gt"); break;
512 case GE: fprintf (file, "ge"); break;
513 case LTU: fprintf (file, "c"); break;
514 case LEU: fprintf (file, "ls"); break;
515 case GTU: fprintf (file, "hi"); break;
516 case GEU: fprintf (file, "nc"); break;
518 output_operand_lossage ("fr30_print_operand: unrecognized %%b code");
524 /* Convert GCC's comparison operators into the complimentary FR30
526 switch (GET_CODE (x))
528 case EQ: fprintf (file, "ne"); break;
529 case NE: fprintf (file, "eq"); break;
530 case LT: fprintf (file, "ge"); break;
531 case LE: fprintf (file, "gt"); break;
532 case GT: fprintf (file, "le"); break;
533 case GE: fprintf (file, "lt"); break;
534 case LTU: fprintf (file, "nc"); break;
535 case LEU: fprintf (file, "hi"); break;
536 case GTU: fprintf (file, "ls"); break;
537 case GEU: fprintf (file, "c"); break;
539 output_operand_lossage ("fr30_print_operand: unrecognized %%B code");
545 /* Print a signed byte value as an unsigned value. */
546 if (GET_CODE (x) != CONST_INT)
547 output_operand_lossage ("fr30_print_operand: invalid operand to %%A code");
556 fprintf (file, HOST_WIDE_INT_PRINT_DEC, val);
561 if (GET_CODE (x) != CONST_INT
564 output_operand_lossage ("fr30_print_operand: invalid %%x code");
566 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) - 16);
570 if (GET_CODE (x) != CONST_DOUBLE)
571 output_operand_lossage ("fr30_print_operand: invalid %%F code");
576 real_to_decimal (str, CONST_DOUBLE_REAL_VALUE (x),
587 fprintf (stderr, "unknown code = %x\n", code);
588 output_operand_lossage ("fr30_print_operand: unknown code");
592 switch (GET_CODE (x))
595 fputs (reg_names [REGNO (x)], file);
601 switch (GET_CODE (x0))
604 gcc_assert ((unsigned) REGNO (x0) < ARRAY_SIZE (reg_names));
605 fprintf (file, "@%s", reg_names [REGNO (x0)]);
609 if (GET_CODE (XEXP (x0, 0)) != REG
610 || REGNO (XEXP (x0, 0)) < FRAME_POINTER_REGNUM
611 || REGNO (XEXP (x0, 0)) > STACK_POINTER_REGNUM
612 || GET_CODE (XEXP (x0, 1)) != CONST_INT)
614 fprintf (stderr, "bad INDEXed address:");
616 output_operand_lossage ("fr30_print_operand: unhandled MEM");
618 else if (REGNO (XEXP (x0, 0)) == FRAME_POINTER_REGNUM)
620 HOST_WIDE_INT val = INTVAL (XEXP (x0, 1));
621 if (val < -(1 << 9) || val > ((1 << 9) - 4))
623 fprintf (stderr, "frame INDEX out of range:");
625 output_operand_lossage ("fr30_print_operand: unhandled MEM");
627 fprintf (file, "@(r14, #" HOST_WIDE_INT_PRINT_DEC ")", val);
631 HOST_WIDE_INT val = INTVAL (XEXP (x0, 1));
632 if (val < 0 || val > ((1 << 6) - 4))
634 fprintf (stderr, "stack INDEX out of range:");
636 output_operand_lossage ("fr30_print_operand: unhandled MEM");
638 fprintf (file, "@(r15, #" HOST_WIDE_INT_PRINT_DEC ")", val);
647 fprintf (stderr, "bad MEM code = %x\n", GET_CODE (x0));
649 output_operand_lossage ("fr30_print_operand: unhandled MEM");
655 /* We handle SFmode constants here as output_addr_const doesn't. */
656 if (GET_MODE (x) == SFmode)
661 REAL_VALUE_FROM_CONST_DOUBLE (d, x);
662 REAL_VALUE_TO_TARGET_SINGLE (d, l);
663 fprintf (file, "0x%08lx", l);
667 /* Fall through. Let output_addr_const deal with it. */
669 output_addr_const (file, x);
677 /*{{{ Function arguments */
679 /* Return true if we should pass an argument on the stack rather than
683 fr30_must_pass_in_stack (enum machine_mode mode, const_tree type)
689 return AGGREGATE_TYPE_P (type);
692 /* Compute the number of word sized registers needed to hold a
693 function argument of mode INT_MODE and tree type TYPE. */
695 fr30_num_arg_regs (enum machine_mode mode, tree type)
699 if (targetm.calls.must_pass_in_stack (mode, type))
702 if (type && mode == BLKmode)
703 size = int_size_in_bytes (type);
705 size = GET_MODE_SIZE (mode);
707 return (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
710 /* Returns the number of bytes in which *part* of a parameter of machine
711 mode MODE and tree type TYPE (which may be NULL if the type is not known).
712 If the argument fits entirely in the argument registers, or entirely on
713 the stack, then 0 is returned.
714 CUM is the number of argument registers already used by earlier
715 parameters to the function. */
718 fr30_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
719 tree type, bool named)
721 /* Unnamed arguments, i.e. those that are prototyped as ...
722 are always passed on the stack.
723 Also check here to see if all the argument registers are full. */
724 if (named == 0 || *cum >= FR30_NUM_ARG_REGS)
727 /* Work out how many argument registers would be needed if this
728 parameter were to be passed entirely in registers. If there
729 are sufficient argument registers available (or if no registers
730 are needed because the parameter must be passed on the stack)
731 then return zero, as this parameter does not require partial
732 register, partial stack stack space. */
733 if (*cum + fr30_num_arg_regs (mode, type) <= FR30_NUM_ARG_REGS)
736 return (FR30_NUM_ARG_REGS - *cum) * UNITS_PER_WORD;
740 /*{{{ Operand predicates */
743 #define Mmode enum machine_mode
746 /* Returns true iff all the registers in the operands array
747 are in descending or ascending order. */
749 fr30_check_multiple_regs (rtx *operands, int num_operands, int descending)
753 unsigned int prev_regno = 0;
755 while (num_operands --)
757 if (GET_CODE (operands [num_operands]) != REG)
760 if (REGNO (operands [num_operands]) < prev_regno)
763 prev_regno = REGNO (operands [num_operands]);
768 unsigned int prev_regno = CONDITION_CODE_REGNUM;
770 while (num_operands --)
772 if (GET_CODE (operands [num_operands]) != REG)
775 if (REGNO (operands [num_operands]) > prev_regno)
778 prev_regno = REGNO (operands [num_operands]);
786 fr30_const_double_is_zero (rtx operand)
790 if (operand == NULL || GET_CODE (operand) != CONST_DOUBLE)
793 REAL_VALUE_FROM_CONST_DOUBLE (d, operand);
795 return REAL_VALUES_EQUAL (d, dconst0);
799 /*{{{ Instruction Output Routines */
801 /* Output a double word move.
802 It must be REG<-REG, REG<-MEM, MEM<-REG or REG<-CONST.
803 On the FR30 we are constrained by the fact that it does not
804 support offsetable addresses, and so we have to load the
805 address of the secnd word into the second destination register
806 before we can use it. */
809 fr30_move_double (rtx * operands)
811 rtx src = operands[1];
812 rtx dest = operands[0];
813 enum rtx_code src_code = GET_CODE (src);
814 enum rtx_code dest_code = GET_CODE (dest);
815 enum machine_mode mode = GET_MODE (dest);
820 if (dest_code == REG)
824 int reverse = (REGNO (dest) == REGNO (src) + 1);
826 /* We normally copy the low-numbered register first. However, if
827 the first register of operand 0 is the same as the second register
828 of operand 1, we must copy in the opposite order. */
829 emit_insn (gen_rtx_SET (VOIDmode,
830 operand_subword (dest, reverse, TRUE, mode),
831 operand_subword (src, reverse, TRUE, mode)));
833 emit_insn (gen_rtx_SET (VOIDmode,
834 operand_subword (dest, !reverse, TRUE, mode),
835 operand_subword (src, !reverse, TRUE, mode)));
837 else if (src_code == MEM)
839 rtx addr = XEXP (src, 0);
840 int dregno = REGNO (dest);
841 rtx dest0 = operand_subword (dest, 0, TRUE, mode);;
842 rtx dest1 = operand_subword (dest, 1, TRUE, mode);;
845 gcc_assert (GET_CODE (addr) == REG);
847 /* Copy the address before clobbering it. See PR 34174. */
848 emit_insn (gen_rtx_SET (SImode, dest1, addr));
849 emit_insn (gen_rtx_SET (VOIDmode, dest0,
850 adjust_address (src, SImode, 0)));
851 emit_insn (gen_rtx_SET (SImode, dest1,
852 plus_constant (dest1, UNITS_PER_WORD)));
854 new_mem = gen_rtx_MEM (SImode, dest1);
855 MEM_COPY_ATTRIBUTES (new_mem, src);
857 emit_insn (gen_rtx_SET (VOIDmode, dest1, new_mem));
859 else if (src_code == CONST_INT || src_code == CONST_DOUBLE)
862 split_double (src, &words[0], &words[1]);
863 emit_insn (gen_rtx_SET (VOIDmode,
864 operand_subword (dest, 0, TRUE, mode),
867 emit_insn (gen_rtx_SET (VOIDmode,
868 operand_subword (dest, 1, TRUE, mode),
872 else if (src_code == REG && dest_code == MEM)
874 rtx addr = XEXP (dest, 0);
878 gcc_assert (GET_CODE (addr) == REG);
880 src0 = operand_subword (src, 0, TRUE, mode);
881 src1 = operand_subword (src, 1, TRUE, mode);
883 emit_move_insn (adjust_address (dest, SImode, 0), src0);
885 if (REGNO (addr) == STACK_POINTER_REGNUM
886 || REGNO (addr) == FRAME_POINTER_REGNUM)
887 emit_insn (gen_rtx_SET (VOIDmode,
888 adjust_address (dest, SImode, UNITS_PER_WORD),
893 rtx scratch_reg_r0 = gen_rtx_REG (SImode, 0);
895 /* We need a scratch register to hold the value of 'address + 4'.
896 We use r0 for this purpose. It is used for example for long
897 jumps and is already marked to not be used by normal register
899 emit_insn (gen_movsi_internal (scratch_reg_r0, addr));
900 emit_insn (gen_addsi_small_int (scratch_reg_r0, scratch_reg_r0,
901 GEN_INT (UNITS_PER_WORD)));
902 new_mem = gen_rtx_MEM (SImode, scratch_reg_r0);
903 MEM_COPY_ATTRIBUTES (new_mem, dest);
904 emit_move_insn (new_mem, src1);
905 emit_insn (gen_blockage ());
909 /* This should have been prevented by the constraints on movdi_insn. */
918 /* Implement TARGET_FRAME_POINTER_REQUIRED. */
921 fr30_frame_pointer_required (void)
923 return (flag_omit_frame_pointer == 0 || crtl->args.pretend_args_size > 0);
927 /* Local Variables: */