1 /* FR30 specific functions.
2 Copyright (C) 1998-2020 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. */
154 #undef TARGET_ASM_ALIGNED_HI_OP
155 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
156 #undef TARGET_ASM_ALIGNED_SI_OP
157 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
158
159 #undef TARGET_PROMOTE_PROTOTYPES
160 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
161 #undef TARGET_PASS_BY_REFERENCE
162 #define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_must_pass_in_stack
163 #undef TARGET_ARG_PARTIAL_BYTES
164 #define TARGET_ARG_PARTIAL_BYTES fr30_arg_partial_bytes
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
169
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
177 #undef TARGET_SETUP_INCOMING_VARARGS
178 #define TARGET_SETUP_INCOMING_VARARGS fr30_setup_incoming_varargs
179 #undef TARGET_MUST_PASS_IN_STACK
180 #define TARGET_MUST_PASS_IN_STACK fr30_must_pass_in_stack
181
182 #undef TARGET_FRAME_POINTER_REQUIRED
183 #define TARGET_FRAME_POINTER_REQUIRED fr30_frame_pointer_required
184
185 #undef TARGET_CAN_ELIMINATE
186 #define TARGET_CAN_ELIMINATE fr30_can_eliminate
187
188 #undef TARGET_LRA_P
189 #define TARGET_LRA_P hook_bool_void_false
190
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
196 #undef TARGET_CONSTANT_ALIGNMENT
197 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
198
199 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
200 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
201
202 struct gcc_target targetm = TARGET_INITIALIZER;
203
204
205 /* Worker function for TARGET_CAN_ELIMINATE. */
206
207 bool
fr30_can_eliminate(const int from ATTRIBUTE_UNUSED,const int to)208 fr30_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
209 {
210 return (to == FRAME_POINTER_REGNUM || ! frame_pointer_needed);
211 }
212
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. */
216 unsigned int
fr30_compute_frame_size(int from_reg,int to_reg)217 fr30_compute_frame_size (int from_reg, int to_reg)
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 ());
228 args_size = WORD_ALIGN (crtl->outgoing_args_size);
229 pretend_size = crtl->args.pretend_args_size;
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
274 instructions in output_function_prologue(), since it allows the scheduler
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
279 void
fr30_expand_prologue(void)280 fr30_expand_prologue (void)
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. */
289 gcc_assert (current_frame_info.total_size || !current_frame_info.gmask);
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
355 && SET_DEST (part) == hard_frame_pointer_rtx)
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 {
383 insn = emit_insn (gen_add_to_stack
384 (GEN_INT (- (signed) current_frame_info.frame_size)));
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
396 if (crtl->profile)
397 emit_insn (gen_blockage ());
398 }
399
400 /* Called after register allocation to add any instructions needed for the
401 epilogue. Using an epilogue insn is favored compared to putting all of the
402 instructions in output_function_epilogue(), since it allows the scheduler
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. */
406 void
fr30_expand_epilogue(void)407 fr30_expand_epilogue (void)
408 {
409 int regno;
410
411 /* Perform the inversion operations of the prologue. */
412 gcc_assert (current_frame_info.initialised);
413
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))
446 emit_insn (gen_movsi_pop (gen_rtx_REG (Pmode, regno)));
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
454 emit_jump_insn (gen_return_from_func ());
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
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. */
464 void
fr30_setup_incoming_varargs(cumulative_args_t arg_regs_used_so_far_v,const function_arg_info & arg,int * pretend_size,int second_time ATTRIBUTE_UNUSED)465 fr30_setup_incoming_varargs (cumulative_args_t arg_regs_used_so_far_v,
466 const function_arg_info &arg,
467 int *pretend_size,
468 int second_time ATTRIBUTE_UNUSED)
469 {
470 CUMULATIVE_ARGS *arg_regs_used_so_far
471 = get_cumulative_args (arg_regs_used_so_far_v);
472 int size;
473
474 /* All BLKmode values are passed by reference. */
475 gcc_assert (arg.mode != BLKmode);
476
477 /* ??? This run-time test as well as the code inside the if
478 statement is probably unnecessary. */
479 if (targetm.calls.strict_argument_naming (arg_regs_used_so_far_v))
480 /* If TARGET_STRICT_ARGUMENT_NAMING returns true, then the last named
481 arg must not be treated as an anonymous arg. */
482 /* ??? This is a pointer increment, which makes no sense. */
483 arg_regs_used_so_far += fr30_num_arg_regs (arg);
484
485 size = FR30_NUM_ARG_REGS - (* arg_regs_used_so_far);
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
498 void
fr30_print_operand_address(FILE * stream,rtx address)499 fr30_print_operand_address (FILE *stream, rtx address)
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
517 void
fr30_print_operand(FILE * file,rtx x,int code)518 fr30_print_operand (FILE *file, rtx x, int code)
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)
534 output_operand_lossage ("fr30_print_operand: unrecognized %%p code");
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:
554 output_operand_lossage ("fr30_print_operand: unrecognized %%b code");
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:
575 output_operand_lossage ("fr30_print_operand: unrecognized %%B code");
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)
583 output_operand_lossage ("fr30_print_operand: invalid operand to %%A code");
584 else
585 {
586 HOST_WIDE_INT val;
587
588 val = INTVAL (x);
589
590 val &= 0xff;
591
592 fprintf (file, HOST_WIDE_INT_PRINT_DEC, val);
593 }
594 return;
595
596 case 'x':
597 if (GET_CODE (x) != CONST_INT
598 || INTVAL (x) < 16
599 || INTVAL (x) > 32)
600 output_operand_lossage ("fr30_print_operand: invalid %%x code");
601 else
602 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) - 16);
603 return;
604
605 case 'F':
606 if (GET_CODE (x) != CONST_DOUBLE)
607 output_operand_lossage ("fr30_print_operand: invalid %%F code");
608 else
609 {
610 char str[30];
611
612 real_to_decimal (str, CONST_DOUBLE_REAL_VALUE (x),
613 sizeof (str), 0, 1);
614 fputs (str, file);
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:
640 gcc_assert ((unsigned) REGNO (x0) < ARRAY_SIZE (reg_names));
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 }
663 fprintf (file, "@(r14, #" HOST_WIDE_INT_PRINT_DEC ")", val);
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 }
674 fprintf (file, "@(r15, #" HOST_WIDE_INT_PRINT_DEC ")", val);
675 }
676 break;
677
678 case SYMBOL_REF:
679 output_address (VOIDmode, x0);
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 {
694 long l;
695
696 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
697 fprintf (file, "0x%08lx", l);
698 break;
699 }
700
701 /* FALLTHRU */
702 /* Let output_addr_const deal with it. */
703 default:
704 output_addr_const (file, x);
705 break;
706 }
707
708 return;
709 }
710
711 /*}}}*/
712
713 /* Implements TARGET_FUNCTION_VALUE. */
714
715 static rtx
fr30_function_value(const_tree valtype,const_tree fntype_or_decli ATTRIBUTE_UNUSED,bool outgoing ATTRIBUTE_UNUSED)716 fr30_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
725 static rtx
fr30_libcall_value(machine_mode mode,const_rtx fun ATTRIBUTE_UNUSED)726 fr30_libcall_value (machine_mode mode,
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
734 static bool
fr30_function_value_regno_p(const unsigned int regno)735 fr30_function_value_regno_p (const unsigned int regno)
736 {
737 return (regno == RETURN_VALUE_REGNUM);
738 }
739
740 /*{{{ Function arguments */
741
742 /* Return true if we should pass an argument on the stack rather than
743 in registers. */
744
745 static bool
fr30_must_pass_in_stack(const function_arg_info & arg)746 fr30_must_pass_in_stack (const function_arg_info &arg)
747 {
748 return arg.mode == BLKmode || arg.aggregate_type_p ();
749 }
750
751 /* Compute the number of word sized registers needed to hold function
752 argument ARG. */
753 static int
fr30_num_arg_regs(const function_arg_info & arg)754 fr30_num_arg_regs (const function_arg_info &arg)
755 {
756 if (targetm.calls.must_pass_in_stack (arg))
757 return 0;
758
759 int size = arg.promoted_size_in_bytes ();
760 return (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
761 }
762
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. */
767
768 static int
fr30_arg_partial_bytes(cumulative_args_t cum_v,const function_arg_info & arg)769 fr30_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
770 {
771 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
772
773 /* Unnamed arguments, i.e. those that are prototyped as ...
774 are always passed on the stack.
775 Also check here to see if all the argument registers are full. */
776 if (!arg.named || *cum >= FR30_NUM_ARG_REGS)
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 space. */
785 if (*cum + fr30_num_arg_regs (arg) <= FR30_NUM_ARG_REGS)
786 return 0;
787
788 return (FR30_NUM_ARG_REGS - *cum) * UNITS_PER_WORD;
789 }
790
791 static rtx
fr30_function_arg(cumulative_args_t cum_v,const function_arg_info & arg)792 fr30_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
793 {
794 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
795
796 if (!arg.named
797 || fr30_must_pass_in_stack (arg)
798 || *cum >= FR30_NUM_ARG_REGS)
799 return NULL_RTX;
800 else
801 return gen_rtx_REG (arg.mode, *cum + FIRST_ARG_REGNUM);
802 }
803
804 /* Implement TARGET_FUNCTION_ARG_ADVANCE. */
805 static void
fr30_function_arg_advance(cumulative_args_t cum,const function_arg_info & arg)806 fr30_function_arg_advance (cumulative_args_t cum,
807 const function_arg_info &arg)
808 {
809 if (arg.named)
810 *get_cumulative_args (cum) += fr30_num_arg_regs (arg);
811 }
812
813 /*}}}*/
814 /*{{{ Operand predicates */
815
816 #ifndef Mmode
817 #define Mmode machine_mode
818 #endif
819
820 /* Returns true iff all the registers in the operands array
821 are in descending or ascending order. */
822 int
fr30_check_multiple_regs(rtx * operands,int num_operands,int descending)823 fr30_check_multiple_regs (rtx *operands, int num_operands, int descending)
824 {
825 if (descending)
826 {
827 unsigned int prev_regno = 0;
828
829 while (num_operands --)
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 {
842 unsigned int prev_regno = CONDITION_CODE_REGNUM;
843
844 while (num_operands --)
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
859 int
fr30_const_double_is_zero(rtx operand)860 fr30_const_double_is_zero (rtx operand)
861 {
862 if (operand == NULL || GET_CODE (operand) != CONST_DOUBLE)
863 return 0;
864
865 return real_equal (CONST_DOUBLE_REAL_VALUE (operand), &dconst0);
866 }
867
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.
873 On the FR30 we are constrained by the fact that it does not
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
878 rtx
fr30_move_double(rtx * operands)879 fr30_move_double (rtx * operands)
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);
885 machine_mode mode = GET_MODE (dest);
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. */
899 emit_insn (gen_rtx_SET (operand_subword (dest, reverse, TRUE, mode),
900 operand_subword (src, reverse, TRUE, mode)));
901
902 emit_insn
903 (gen_rtx_SET (operand_subword (dest, !reverse, TRUE, mode),
904 operand_subword (src, !reverse, TRUE, mode)));
905 }
906 else if (src_code == MEM)
907 {
908 rtx addr = XEXP (src, 0);
909 rtx dest0 = operand_subword (dest, 0, TRUE, mode);
910 rtx dest1 = operand_subword (dest, 1, TRUE, mode);
911 rtx new_mem;
912
913 gcc_assert (GET_CODE (addr) == REG);
914
915 /* Copy the address before clobbering it. See PR 34174. */
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)));
920
921 new_mem = gen_rtx_MEM (SImode, dest1);
922 MEM_COPY_ATTRIBUTES (new_mem, src);
923
924 emit_insn (gen_rtx_SET (dest1, new_mem));
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]);
930 emit_insn (gen_rtx_SET (operand_subword (dest, 0, TRUE, mode),
931 words[0]));
932
933 emit_insn (gen_rtx_SET (operand_subword (dest, 1, TRUE, mode),
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
943 gcc_assert (GET_CODE (addr) == REG);
944
945 src0 = operand_subword (src, 0, TRUE, mode);
946 src1 = operand_subword (src, 1, TRUE, mode);
947
948 emit_move_insn (adjust_address (dest, SImode, 0), src0);
949
950 if (REGNO (addr) == STACK_POINTER_REGNUM
951 || REGNO (addr) == FRAME_POINTER_REGNUM)
952 emit_insn (gen_rtx_SET (adjust_address (dest, SImode, UNITS_PER_WORD),
953 src1));
954 else
955 {
956 rtx new_mem;
957 rtx scratch_reg_r0 = gen_rtx_REG (SImode, 0);
958
959 /* We need a scratch register to hold the value of 'address + 4'.
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);
967 MEM_COPY_ATTRIBUTES (new_mem, dest);
968 emit_move_insn (new_mem, src1);
969 emit_insn (gen_blockage ());
970 }
971 }
972 else
973 /* This should have been prevented by the constraints on movdi_insn. */
974 gcc_unreachable ();
975
976 val = get_insns ();
977 end_sequence ();
978
979 return val;
980 }
981
982 /* Implement TARGET_FRAME_POINTER_REQUIRED. */
983
984 bool
fr30_frame_pointer_required(void)985 fr30_frame_pointer_required (void)
986 {
987 return (flag_omit_frame_pointer == 0 || crtl->args.pretend_args_size > 0);
988 }
989
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
1007 static void
fr30_asm_trampoline_template(FILE * f)1008 fr30_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
1019 static void
fr30_trampoline_init(rtx m_tramp,tree fndecl,rtx chain_value)1020 fr30_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
1034 /*}}}*/
1035 /* Local Variables: */
1036 /* folded-file: t */
1037 /* End: */
1038