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