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