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