1 /* Subroutines for insn-output.c for Motorola 88000.
2 Copyright (C) 1988, 92, 93, 94, 95, 16, 1997, 1999 Free Software
4 Contributed by Michael Tiemann (tiemann@mcc.com)
5 Currently maintained by (gcc@dg-rtp.dg.com)
7 This file is part of GNU CC.
9 GNU CC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 GNU CC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GNU CC; see the file COPYING. If not, write to
21 the Free Software Foundation, 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
27 #include <sys/types.h>
33 #include "hard-reg-set.h"
35 #include "insn-config.h"
36 #include "conditions.h"
37 #include "insn-flags.h"
39 #include "insn-attr.h"
46 extern char *version_string;
47 extern time_t time ();
48 extern char *ctime ();
49 extern int flag_traditional;
50 extern FILE *asm_out_file;
52 char *m88k_pound_sign = ""; /* Either # for SVR4 or empty for SVR3 */
53 char *m88k_short_data;
55 char m88k_volatile_code;
57 unsigned m88k_gp_threshold = 0;
58 int m88k_prologue_done = 0; /* Ln directives can now be emitted */
59 int m88k_function_number = 0; /* Counter unique to each function */
60 int m88k_fp_offset = 0; /* offset of frame pointer if used */
61 int m88k_stack_size = 0; /* size of allocated stack (including frame) */
64 rtx m88k_compare_reg; /* cmp output pseudo register */
65 rtx m88k_compare_op0; /* cmpsi operand 0 */
66 rtx m88k_compare_op1; /* cmpsi operand 1 */
68 enum processor_type m88k_cpu; /* target cpu */
70 /* Determine what instructions are needed to manufacture the integer VALUE
74 classify_integer (mode, value)
75 enum machine_mode mode;
82 else if (SMALL_INTVAL (value))
84 else if (SMALL_INTVAL (-value))
86 else if (mode == HImode)
88 else if (mode == QImode)
90 else if ((value & 0xffff) == 0)
92 else if (integer_ok_for_set (value))
98 /* Return the bit number in a compare word corresponding to CONDITION. */
101 condition_value (condition)
104 switch (GET_CODE (condition))
121 integer_ok_for_set (value)
122 register unsigned value;
124 /* All the "one" bits must be contiguous. If so, MASK + 1 will be
125 a power of two or zero. */
126 register unsigned mask = (value | (value - 1));
127 return (value && POWER_OF_2_or_0 (mask + 1));
131 output_load_const_int (mode, operands)
132 enum machine_mode mode;
135 static char *patterns[] =
143 "or.u %0,%#r0,%X1\n\tor %0,%0,%x1",
146 if (! REG_P (operands[0])
147 || GET_CODE (operands[1]) != CONST_INT)
149 return patterns[classify_integer (mode, INTVAL (operands[1]))];
152 /* These next two routines assume that floating point numbers are represented
153 in a manner which is consistent between host and target machines. */
156 output_load_const_float (operands)
159 /* These can return 0 under some circumstances when cross-compiling. */
160 operands[0] = operand_subword (operands[0], 0, 0, SFmode);
161 operands[1] = operand_subword (operands[1], 0, 0, SFmode);
163 return output_load_const_int (SImode, operands);
167 output_load_const_double (operands)
172 /* These can return zero on some cross-compilers, but there's nothing
173 we can do about it. */
174 latehalf[0] = operand_subword (operands[0], 1, 0, DFmode);
175 latehalf[1] = operand_subword (operands[1], 1, 0, DFmode);
177 operands[0] = operand_subword (operands[0], 0, 0, DFmode);
178 operands[1] = operand_subword (operands[1], 0, 0, DFmode);
180 output_asm_insn (output_load_const_int (SImode, operands), operands);
182 operands[0] = latehalf[0];
183 operands[1] = latehalf[1];
185 return output_load_const_int (SImode, operands);
189 output_load_const_dimode (operands)
194 latehalf[0] = operand_subword (operands[0], 1, 0, DImode);
195 latehalf[1] = operand_subword (operands[1], 1, 0, DImode);
197 operands[0] = operand_subword (operands[0], 0, 0, DImode);
198 operands[1] = operand_subword (operands[1], 0, 0, DImode);
200 output_asm_insn (output_load_const_int (SImode, operands), operands);
202 operands[0] = latehalf[0];
203 operands[1] = latehalf[1];
205 return output_load_const_int (SImode, operands);
208 /* Emit insns to move operands[1] into operands[0].
210 Return 1 if we have written out everything that needs to be done to
211 do the move. Otherwise, return 0 and the caller will emit the move
214 SCRATCH if non zero can be used as a scratch register for the move
215 operation. It is provided by a SECONDARY_RELOAD_* macro if needed. */
218 emit_move_sequence (operands, mode, scratch)
220 enum machine_mode mode;
223 register rtx operand0 = operands[0];
224 register rtx operand1 = operands[1];
226 if (CONSTANT_P (operand1) && flag_pic
227 && pic_address_needs_scratch (operand1))
228 operands[1] = operand1 = legitimize_address (1, operand1, 0, 0);
230 /* Handle most common case first: storing into a register. */
231 if (register_operand (operand0, mode))
233 if (register_operand (operand1, mode)
234 || (GET_CODE (operand1) == CONST_INT && SMALL_INT (operand1))
235 || GET_CODE (operand1) == HIGH
236 /* Only `general_operands' can come here, so MEM is ok. */
237 || GET_CODE (operand1) == MEM)
239 /* Run this case quickly. */
240 emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1));
244 else if (GET_CODE (operand0) == MEM)
246 if (register_operand (operand1, mode)
247 || (operand1 == const0_rtx && GET_MODE_SIZE (mode) <= UNITS_PER_WORD))
249 /* Run this case quickly. */
250 emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1));
253 if (! reload_in_progress && ! reload_completed)
255 operands[0] = validize_mem (operand0);
256 operands[1] = operand1 = force_reg (mode, operand1);
260 /* Simplify the source if we need to. */
261 if (GET_CODE (operand1) != HIGH && immediate_operand (operand1, mode))
263 if (GET_CODE (operand1) != CONST_INT
264 && GET_CODE (operand1) != CONST_DOUBLE)
266 rtx temp = ((reload_in_progress || reload_completed)
268 operands[1] = legitimize_address (flag_pic
269 && symbolic_address_p (operand1),
270 operand1, temp, scratch);
272 operands[1] = gen_rtx (SUBREG, mode, operands[1], 0);
276 /* Now have insn-emit do whatever it normally does. */
280 /* Return a legitimate reference for ORIG (either an address or a MEM)
281 using the register REG. If PIC and the address is already
282 position-independent, use ORIG. Newly generated position-independent
283 addresses go into a reg. This is REG if non zero, otherwise we
284 allocate register(s) as necessary. If this is called during reload,
285 and we need a second temp register, then we use SCRATCH, which is
286 provided via the SECONDARY_INPUT_RELOAD_CLASS mechanism. */
289 legitimize_address (pic, orig, reg, scratch)
295 rtx addr = (GET_CODE (orig) == MEM ? XEXP (orig, 0) : orig);
301 if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
305 if (reload_in_progress || reload_completed)
308 reg = gen_reg_rtx (Pmode);
313 /* If not during reload, allocate another temp reg here for
314 loading in the address, so that these instructions can be
315 optimized properly. */
316 temp = ((reload_in_progress || reload_completed)
317 ? reg : gen_reg_rtx (Pmode));
319 emit_insn (gen_rtx (SET, VOIDmode, temp,
320 gen_rtx (HIGH, SImode,
321 gen_rtx (UNSPEC, SImode,
324 emit_insn (gen_rtx (SET, VOIDmode, temp,
325 gen_rtx (LO_SUM, SImode, temp,
326 gen_rtx (UNSPEC, SImode,
331 new = gen_rtx (MEM, Pmode,
332 gen_rtx (PLUS, SImode,
333 pic_offset_table_rtx, addr));
334 current_function_uses_pic_offset_table = 1;
335 RTX_UNCHANGING_P (new) = 1;
336 insn = emit_move_insn (reg, new);
337 /* Put a REG_EQUAL note on this insn, so that it can be optimized
339 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, orig,
343 else if (GET_CODE (addr) == CONST)
347 if (GET_CODE (XEXP (addr, 0)) == PLUS
348 && XEXP (XEXP (addr, 0), 0) == pic_offset_table_rtx)
353 if (reload_in_progress || reload_completed)
356 reg = gen_reg_rtx (Pmode);
359 if (GET_CODE (XEXP (addr, 0)) != PLUS) abort ();
361 base = legitimize_address (1, XEXP (XEXP (addr, 0), 0), reg, 0);
362 addr = legitimize_address (1, XEXP (XEXP (addr, 0), 1),
363 base == reg ? 0 : reg, 0);
365 if (GET_CODE (addr) == CONST_INT)
368 return plus_constant_for_output (base, INTVAL (addr));
369 else if (! reload_in_progress && ! reload_completed)
370 addr = force_reg (Pmode, addr);
371 /* We can't create any new registers during reload, so use the
372 SCRATCH reg provided by the reload_insi pattern. */
375 emit_move_insn (scratch, addr);
379 /* If we reach here, then the SECONDARY_INPUT_RELOAD_CLASS
380 macro needs to be adjusted so that a scratch reg is provided
384 new = gen_rtx (PLUS, SImode, base, addr);
385 /* Should we set special REG_NOTEs here? */
388 else if (! SHORT_ADDRESS_P (addr, temp))
392 if (reload_in_progress || reload_completed)
395 reg = gen_reg_rtx (Pmode);
398 emit_insn (gen_rtx (SET, VOIDmode,
399 reg, gen_rtx (HIGH, SImode, addr)));
400 new = gen_rtx (LO_SUM, SImode, reg, addr);
404 && GET_CODE (orig) == MEM)
406 new = gen_rtx (MEM, GET_MODE (orig), new);
407 RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (orig);
408 MEM_COPY_ATTRIBUTES (new, orig);
413 /* Support functions for code to emit a block move. There are four methods
414 used to perform the block move:
416 + call the looping library function, e.g. __movstrSI64n8
417 + call a non-looping library function, e.g. __movstrHI15x11
418 + produce an inline sequence of ld/st instructions
420 The parameters below describe the library functions produced by
423 #define MOVSTR_LOOP 64 /* __movstrSI64n68 .. __movstrSI64n8 */
424 #define MOVSTR_QI 16 /* __movstrQI16x16 .. __movstrQI16x2 */
425 #define MOVSTR_HI 48 /* __movstrHI48x48 .. __movstrHI48x4 */
426 #define MOVSTR_SI 96 /* __movstrSI96x96 .. __movstrSI96x8 */
427 #define MOVSTR_DI 96 /* __movstrDI96x96 .. __movstrDI96x16 */
428 #define MOVSTR_ODD_HI 16 /* __movstrHI15x15 .. __movstrHI15x5 */
429 #define MOVSTR_ODD_SI 48 /* __movstrSI47x47 .. __movstrSI47x11,
430 __movstrSI46x46 .. __movstrSI46x10,
431 __movstrSI45x45 .. __movstrSI45x9 */
432 #define MOVSTR_ODD_DI 48 /* __movstrDI47x47 .. __movstrDI47x23,
433 __movstrDI46x46 .. __movstrDI46x22,
434 __movstrDI45x45 .. __movstrDI45x21,
435 __movstrDI44x44 .. __movstrDI44x20,
436 __movstrDI43x43 .. __movstrDI43x19,
437 __movstrDI42x42 .. __movstrDI42x18,
438 __movstrDI41x41 .. __movstrDI41x17 */
440 /* Limits for using the non-looping movstr functions. For the m88100
441 processor, we assume the source and destination are word aligned.
442 The QImode and HImode limits are the break even points where memcpy
443 does just as well and beyond which memcpy does better. For the
444 m88110, we tend to assume double word alignment, but also analyze
445 the word aligned cases. The analysis is complicated because memcpy
446 may use the cache control instructions for better performance. */
448 #define MOVSTR_QI_LIMIT_88100 13
449 #define MOVSTR_HI_LIMIT_88100 38
450 #define MOVSTR_SI_LIMIT_88100 MOVSTR_SI
451 #define MOVSTR_DI_LIMIT_88100 MOVSTR_SI
453 #define MOVSTR_QI_LIMIT_88000 16
454 #define MOVSTR_HI_LIMIT_88000 38
455 #define MOVSTR_SI_LIMIT_88000 72
456 #define MOVSTR_DI_LIMIT_88000 72
458 #define MOVSTR_QI_LIMIT_88110 16
459 #define MOVSTR_HI_LIMIT_88110 38
460 #define MOVSTR_SI_LIMIT_88110 72
461 #define MOVSTR_DI_LIMIT_88110 72
463 static enum machine_mode mode_from_align[] =
464 {VOIDmode, QImode, HImode, VOIDmode, SImode,
465 VOIDmode, VOIDmode, VOIDmode, DImode};
466 static int max_from_align[] = {0, MOVSTR_QI, MOVSTR_HI, 0, MOVSTR_SI,
468 static int all_from_align[] = {0, MOVSTR_QI, MOVSTR_ODD_HI, 0, MOVSTR_ODD_SI,
469 0, 0, 0, MOVSTR_ODD_DI};
471 static int best_from_align[3][9] =
472 {0, MOVSTR_QI_LIMIT_88100, MOVSTR_HI_LIMIT_88100, 0, MOVSTR_SI_LIMIT_88100,
473 0, 0, 0, MOVSTR_DI_LIMIT_88100,
474 0, MOVSTR_QI_LIMIT_88110, MOVSTR_HI_LIMIT_88110, 0, MOVSTR_SI_LIMIT_88110,
475 0, 0, 0, MOVSTR_DI_LIMIT_88110,
476 0, MOVSTR_QI_LIMIT_88000, MOVSTR_HI_LIMIT_88000, 0, MOVSTR_SI_LIMIT_88000,
477 0, 0, 0, MOVSTR_DI_LIMIT_88000};
479 static void block_move_loop ();
480 static void block_move_no_loop ();
481 static void block_move_sequence ();
483 /* Emit code to perform a block move. Choose the best method.
485 OPERANDS[0] is the destination.
486 OPERANDS[1] is the source.
487 OPERANDS[2] is the size.
488 OPERANDS[3] is the alignment safe to use. */
491 expand_block_move (dest_mem, src_mem, operands)
496 int align = INTVAL (operands[3]);
497 int constp = (GET_CODE (operands[2]) == CONST_INT);
498 int bytes = (constp ? INTVAL (operands[2]) : 0);
499 int target = (int) m88k_cpu;
501 if (! (PROCESSOR_M88100 == 0
502 && PROCESSOR_M88110 == 1
503 && PROCESSOR_M88000 == 2))
506 if (constp && bytes <= 0)
509 /* Determine machine mode to do move with. */
510 if (align > 4 && !TARGET_88110)
512 else if (align <= 0 || align == 3)
513 abort (); /* block move invalid alignment. */
515 if (constp && bytes <= 3 * align)
516 block_move_sequence (operands[0], dest_mem, operands[1], src_mem,
519 else if (constp && bytes <= best_from_align[target][align])
520 block_move_no_loop (operands[0], dest_mem, operands[1], src_mem,
523 else if (constp && align == 4 && TARGET_88100)
524 block_move_loop (operands[0], dest_mem, operands[1], src_mem,
529 #ifdef TARGET_MEM_FUNCTIONS
530 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "memcpy"), 0,
534 convert_to_mode (TYPE_MODE (sizetype), operands[2],
535 TREE_UNSIGNED (sizetype)),
536 TYPE_MODE (sizetype));
538 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "bcopy"), 0,
542 convert_to_mode (TYPE_MODE (integer_type_node),
544 TREE_UNSIGNED (integer_type_node)),
545 TYPE_MODE (integer_type_node));
550 /* Emit code to perform a block move by calling a looping movstr library
551 function. SIZE and ALIGN are known constants. DEST and SRC are
555 block_move_loop (dest, dest_mem, src, src_mem, size, align)
561 enum machine_mode mode;
570 /* Determine machine mode to do move with. */
574 /* Determine the structure of the loop. */
575 count = size / MOVSTR_LOOP;
576 units = (size - count * MOVSTR_LOOP) / align;
581 units += MOVSTR_LOOP / align;
586 block_move_no_loop (dest, dest_mem, src, src_mem, size, align);
590 remainder = size - count * MOVSTR_LOOP - units * align;
592 mode = mode_from_align[align];
593 sprintf (entry, "__movstr%s%dn%d",
594 GET_MODE_NAME (mode), MOVSTR_LOOP, units * align);
595 entry_name = get_identifier (entry);
597 offset_rtx = GEN_INT (MOVSTR_LOOP + (1 - units) * align);
599 value_rtx = gen_rtx (MEM, MEM_IN_STRUCT_P (src_mem) ? mode : BLKmode,
600 gen_rtx (PLUS, Pmode,
601 gen_rtx (REG, Pmode, 3),
603 RTX_UNCHANGING_P (value_rtx) = RTX_UNCHANGING_P (src_mem);
604 MEM_COPY_ATTRIBUTES (value_rtx, src_mem);
606 emit_insn (gen_call_movstrsi_loop
607 (gen_rtx (SYMBOL_REF, Pmode, IDENTIFIER_POINTER (entry_name)),
608 dest, src, offset_rtx, value_rtx,
609 gen_rtx (REG, mode, ((units & 1) ? 4 : 5)),
613 block_move_sequence (gen_rtx (REG, Pmode, 2), dest_mem,
614 gen_rtx (REG, Pmode, 3), src_mem,
615 remainder, align, MOVSTR_LOOP + align);
618 /* Emit code to perform a block move by calling a non-looping library
619 function. SIZE and ALIGN are known constants. DEST and SRC are
620 registers. OFFSET is the known starting point for the output pattern. */
623 block_move_no_loop (dest, dest_mem, src, src_mem, size, align)
629 enum machine_mode mode = mode_from_align[align];
630 int units = size / align;
631 int remainder = size - units * align;
639 if (remainder && size <= all_from_align[align])
641 most = all_from_align[align] - (align - remainder);
646 most = max_from_align[align];
649 sprintf (entry, "__movstr%s%dx%d",
650 GET_MODE_NAME (mode), most, size - remainder);
651 entry_name = get_identifier (entry);
653 offset_rtx = GEN_INT (most - (size - remainder));
655 value_rtx = gen_rtx (MEM, MEM_IN_STRUCT_P (src_mem) ? mode : BLKmode,
656 gen_rtx (PLUS, Pmode,
657 gen_rtx (REG, Pmode, 3),
659 RTX_UNCHANGING_P (value_rtx) = RTX_UNCHANGING_P (src_mem);
660 MEM_COPY_ATTRIBUTES (value_rtx, src_mem);
662 value_reg = ((((most - (size - remainder)) / align) & 1) == 0
663 ? (align == 8 ? 6 : 5) : 4);
665 emit_insn (gen_call_block_move
666 (gen_rtx (SYMBOL_REF, Pmode, IDENTIFIER_POINTER (entry_name)),
667 dest, src, offset_rtx, value_rtx,
668 gen_rtx (REG, mode, value_reg)));
671 block_move_sequence (gen_rtx (REG, Pmode, 2), dest_mem,
672 gen_rtx (REG, Pmode, 3), src_mem,
673 remainder, align, most);
676 /* Emit code to perform a block move with an offset sequence of ld/st
677 instructions (..., ld 0, st 1, ld 1, st 0, ...). SIZE and ALIGN are
678 known constants. DEST and SRC are registers. OFFSET is the known
679 starting point for the output pattern. */
682 block_move_sequence (dest, dest_mem, src, src_mem, size, align, offset)
690 enum machine_mode mode[2];
695 int offset_ld = offset;
696 int offset_st = offset;
698 active[0] = active[1] = FALSE;
700 /* Establish parameters for the first load and for the second load if
701 it is known to be the same mode as the first. */
702 amount[0] = amount[1] = align;
703 mode[0] = mode_from_align[align];
704 temp[0] = gen_reg_rtx (mode[0]);
705 if (size >= 2 * align)
708 temp[1] = gen_reg_rtx (mode[1]);
719 /* Change modes as the sequence tails off. */
720 if (size < amount[next])
722 amount[next] = (size >= 4 ? 4 : (size >= 2 ? 2 : 1));
723 mode[next] = mode_from_align[amount[next]];
724 temp[next] = gen_reg_rtx (mode[next]);
726 size -= amount[next];
728 MEM_IN_STRUCT_P (src_mem) ? mode[next] : BLKmode,
729 gen_rtx (PLUS, Pmode, src,
730 GEN_INT (offset_ld)));
731 RTX_UNCHANGING_P (srcp) = RTX_UNCHANGING_P (src_mem);
732 MEM_COPY_ATTRIBUTES (srcp, src_mem);
733 emit_insn (gen_rtx (SET, VOIDmode, temp[next], srcp));
734 offset_ld += amount[next];
740 active[phase] = FALSE;
742 MEM_IN_STRUCT_P (dest_mem) ? mode[phase] : BLKmode,
743 gen_rtx (PLUS, Pmode, dest,
744 GEN_INT (offset_st)));
745 RTX_UNCHANGING_P (dstp) = RTX_UNCHANGING_P (dest_mem);
746 MEM_COPY_ATTRIBUTES (dstp, dest_mem);
747 emit_insn (gen_rtx (SET, VOIDmode, dstp, temp[phase]));
748 offset_st += amount[phase];
751 while (active[next]);
754 /* Emit the code to do an AND operation. */
757 output_and (operands)
762 if (REG_P (operands[2]))
763 return "and %0,%1,%2";
765 value = INTVAL (operands[2]);
766 if (SMALL_INTVAL (value))
767 return "mask %0,%1,%2";
768 else if ((value & 0xffff0000) == 0xffff0000)
769 return "and %0,%1,%x2";
770 else if ((value & 0xffff) == 0xffff)
771 return "and.u %0,%1,%X2";
772 else if ((value & 0xffff) == 0)
773 return "mask.u %0,%1,%X2";
774 else if (integer_ok_for_set (~value))
775 return "clr %0,%1,%S2";
777 return "and.u %0,%1,%X2\n\tand %0,%0,%x2";
780 /* Emit the code to do an inclusive OR operation. */
783 output_ior (operands)
788 if (REG_P (operands[2]))
789 return "or %0,%1,%2";
791 value = INTVAL (operands[2]);
792 if (SMALL_INTVAL (value))
793 return "or %0,%1,%2";
794 else if ((value & 0xffff) == 0)
795 return "or.u %0,%1,%X2";
796 else if (integer_ok_for_set (value))
797 return "set %0,%1,%s2";
799 return "or.u %0,%1,%X2\n\tor %0,%0,%x2";
802 /* Emit the instructions for doing an XOR. */
805 output_xor (operands)
810 if (REG_P (operands[2]))
811 return "xor %0,%1,%2";
813 value = INTVAL (operands[2]);
814 if (SMALL_INTVAL (value))
815 return "xor %0,%1,%2";
816 else if ((value & 0xffff) == 0)
817 return "xor.u %0,%1,%X2";
819 return "xor.u %0,%1,%X2\n\txor %0,%0,%x2";
822 /* Output a call. Normally this is just bsr or jsr, but this also deals with
823 accomplishing a branch after the call by incrementing r1. This requires
824 that various assembler bugs be accommodated. The 4.30 DG/UX assembler
825 requires that forward references not occur when computing the difference of
826 two labels. The [version?] Motorola assembler computes a word difference.
827 No doubt there's more to come!
829 It would seem the same idea could be used to tail call, but in this case,
830 the epilogue will be non-null. */
832 static rtx sb_name = 0;
833 static rtx sb_high = 0;
834 static rtx sb_low = 0;
837 output_call (operands, addr)
847 /* This can be generalized, but there is currently no need. */
848 if (XVECLEN (final_sequence, 0) != 2)
851 /* The address of interior insns is not computed, so use the sequence. */
852 seq_insn = NEXT_INSN (PREV_INSN (XVECEXP (final_sequence, 0, 0)));
853 jump = XVECEXP (final_sequence, 0, 1);
854 if (GET_CODE (jump) == JUMP_INSN)
858 rtx dest = XEXP (SET_SRC (PATTERN (jump)), 0);
859 int delta = 4 * (insn_addresses[INSN_UID (dest)]
860 - insn_addresses[INSN_UID (seq_insn)]
862 #if (MONITOR_GCC & 0x2) /* How often do long branches happen? */
863 if ((unsigned) (delta + 0x8000) >= 0x10000)
864 warning ("Internal gcc monitor: short-branch(%x)", delta);
867 /* Delete the jump. */
868 PUT_CODE (jump, NOTE);
869 NOTE_LINE_NUMBER (jump) = NOTE_INSN_DELETED;
870 NOTE_SOURCE_FILE (jump) = 0;
872 /* We only do this optimization if -O2, modifying the value of
873 r1 in the delay slot confuses debuggers and profilers on some
876 If we loose, we must use the non-delay form. This is unlikely
877 to ever happen. If it becomes a problem, claim that a call
878 has two delay slots and only the second can be filled with
881 The 88110 can lose when a jsr.n r1 is issued and a page fault
882 occurs accessing the delay slot. So don't use jsr.n form when
885 #ifdef AS_BUG_IMMEDIATE_LABEL /* The assembler restricts immediate values. */
887 || ! ADD_INTVAL (delta * 2)
890 || ! ADD_INTVAL (delta)
892 || (REG_P (addr) && REGNO (addr) == 1))
898 ? "bsr %0#plt\n\tbr %l1"
899 : "bsr %0\n\tbr %l1"));
902 /* Output the short branch form. */
903 output_asm_insn ((REG_P (addr)
905 : (flag_pic ? "bsr.n %0#plt" : "bsr.n %0")),
910 ? "subu %#r1,%#r1,.-%l0+4"
911 : "addu %#r1,%#r1,%l0-.-4");
914 operands[0] = gen_label_rtx ();
915 operands[1] = gen_label_rtx ();
920 last = "subu %#r1,%#r1,%l0\n%l1:";
926 last = "addu %#r1,%#r1,%l0\n%l1:";
929 /* Record the values to be computed later as "def name,high-low". */
930 sb_name = gen_rtx (EXPR_LIST, VOIDmode, operands[0], sb_name);
931 sb_high = gen_rtx (EXPR_LIST, VOIDmode, high, sb_high);
932 sb_low = gen_rtx (EXPR_LIST, VOIDmode, low, sb_low);
933 #endif /* Don't USE_GAS */
940 : (flag_pic ? "bsr%. %0#plt" : "bsr%. %0"));
944 output_short_branch_defs (stream)
947 char name[256], high[256], low[256];
949 for (; sb_name && sb_high && sb_low;
950 sb_name = XEXP (sb_name, 1),
951 sb_high = XEXP (sb_high, 1),
952 sb_low = XEXP (sb_low, 1))
954 ASM_GENERATE_INTERNAL_LABEL
955 (name, "L", CODE_LABEL_NUMBER (XEXP (sb_name, 0)));
956 ASM_GENERATE_INTERNAL_LABEL
957 (high, "L", CODE_LABEL_NUMBER (XEXP (sb_high, 0)));
958 ASM_GENERATE_INTERNAL_LABEL
959 (low, "L", CODE_LABEL_NUMBER (XEXP (sb_low, 0)));
960 /* This will change as the assembler requirements become known. */
961 fprintf (stream, "\t%s\t %s,%s-%s\n",
962 SET_ASM_OP, &name[1], &high[1], &low[1]);
964 if (sb_name || sb_high || sb_low)
968 /* Return truth value of the statement that this conditional branch is likely
969 to fall through. CONDITION, is the condition that JUMP_INSN is testing. */
972 mostly_false_jump (jump_insn, condition)
973 rtx jump_insn, condition;
975 rtx target_label = JUMP_LABEL (jump_insn);
978 /* Much of this isn't computed unless we're optimizing. */
982 /* Determine if one path or the other leads to a return. */
983 for (insnt = NEXT_INSN (target_label);
985 insnt = NEXT_INSN (insnt))
987 if (GET_CODE (insnt) == JUMP_INSN)
989 else if (GET_CODE (insnt) == INSN
990 && GET_CODE (PATTERN (insnt)) == SEQUENCE
991 && GET_CODE (XVECEXP (PATTERN (insnt), 0, 0)) == JUMP_INSN)
993 insnt = XVECEXP (PATTERN (insnt), 0, 0);
998 && (GET_CODE (PATTERN (insnt)) == RETURN
999 || (GET_CODE (PATTERN (insnt)) == SET
1000 && GET_CODE (SET_SRC (PATTERN (insnt))) == REG
1001 && REGNO (SET_SRC (PATTERN (insnt))) == 1)))
1004 for (insnj = NEXT_INSN (jump_insn);
1006 insnj = NEXT_INSN (insnj))
1008 if (GET_CODE (insnj) == JUMP_INSN)
1010 else if (GET_CODE (insnj) == INSN
1011 && GET_CODE (PATTERN (insnj)) == SEQUENCE
1012 && GET_CODE (XVECEXP (PATTERN (insnj), 0, 0)) == JUMP_INSN)
1014 insnj = XVECEXP (PATTERN (insnj), 0, 0);
1019 && (GET_CODE (PATTERN (insnj)) == RETURN
1020 || (GET_CODE (PATTERN (insnj)) == SET
1021 && GET_CODE (SET_SRC (PATTERN (insnj))) == REG
1022 && REGNO (SET_SRC (PATTERN (insnj))) == 1)))
1025 /* Predict to not return. */
1026 if ((insnt == 0) != (insnj == 0))
1027 return (insnt == 0);
1029 /* Predict loops to loop. */
1030 for (insnt = PREV_INSN (target_label);
1031 insnt && GET_CODE (insnt) == NOTE;
1032 insnt = PREV_INSN (insnt))
1033 if (NOTE_LINE_NUMBER (insnt) == NOTE_INSN_LOOP_END)
1035 else if (NOTE_LINE_NUMBER (insnt) == NOTE_INSN_LOOP_BEG)
1037 else if (NOTE_LINE_NUMBER (insnt) == NOTE_INSN_LOOP_CONT)
1040 /* Predict backward branches usually take. */
1042 insnj = NEXT_INSN (PREV_INSN (XVECEXP (final_sequence, 0, 0)));
1045 if (insn_addresses[INSN_UID (insnj)]
1046 > insn_addresses[INSN_UID (target_label)])
1049 /* EQ tests are usually false and NE tests are usually true. Also,
1050 most quantities are positive, so we can make the appropriate guesses
1051 about signed comparisons against zero. Consider unsigned comparisons
1052 to be a range check and assume quantities to be in range. */
1053 switch (GET_CODE (condition))
1056 /* Unconditional branch. */
1065 case GTU: /* Must get casesi right at least. */
1066 if (XEXP (condition, 1) == const0_rtx)
1073 if (XEXP (condition, 1) == const0_rtx)
1081 /* Return true if the operand is a power of two and is a floating
1082 point type (to optimize division by power of two into multiplication). */
1085 real_power_of_2_operand (op, mode)
1087 enum machine_mode mode;
1091 int i[sizeof (REAL_VALUE_TYPE) / sizeof (int)];
1092 struct { /* IEEE double precision format */
1094 unsigned exponent : 11;
1095 unsigned mantissa1 : 20;
1098 struct { /* IEEE double format to quick check */
1099 unsigned sign : 1; /* if it fits in a float */
1100 unsigned exponent1 : 4;
1101 unsigned exponent2 : 7;
1102 unsigned mantissa1 : 20;
1107 if (GET_MODE (op) != DFmode && GET_MODE (op) != SFmode)
1110 if (GET_CODE (op) != CONST_DOUBLE)
1113 u.i[0] = CONST_DOUBLE_LOW (op);
1114 u.i[1] = CONST_DOUBLE_HIGH (op);
1116 if (u.s.mantissa1 != 0 || u.s.mantissa2 != 0 /* not a power of two */
1117 || u.s.exponent == 0 /* constant 0.0 */
1118 || u.s.exponent == 0x7ff /* NAN */
1119 || (u.s2.exponent1 != 0x8 && u.s2.exponent1 != 0x7))
1120 return 0; /* const won't fit in float */
1125 /* Make OP legitimate for mode MODE. Currently this only deals with DFmode
1126 operands, putting them in registers and making CONST_DOUBLE values
1127 SFmode where possible. */
1130 legitimize_operand (op, mode)
1132 enum machine_mode mode;
1136 union real_extract r;
1137 struct { /* IEEE double precision format */
1139 unsigned exponent : 11;
1140 unsigned mantissa1 : 20;
1143 struct { /* IEEE double format to quick check */
1144 unsigned sign : 1; /* if it fits in a float */
1145 unsigned exponent1 : 4;
1146 unsigned exponent2 : 7;
1147 unsigned mantissa1 : 20;
1152 if (GET_CODE (op) == REG || mode != DFmode)
1155 if (GET_CODE (op) == CONST_DOUBLE)
1157 bcopy (&CONST_DOUBLE_LOW (op), &u.r, sizeof u);
1158 if (u.d.exponent != 0x7ff /* NaN */
1159 && u.d.mantissa2 == 0 /* Mantissa fits */
1160 && (u.s.exponent1 == 0x8 || u.s.exponent1 == 0x7) /* Exponent fits */
1161 && (temp = simplify_unary_operation (FLOAT_TRUNCATE, SFmode,
1163 return gen_rtx (FLOAT_EXTEND, mode, force_reg (SFmode, temp));
1165 else if (register_operand (op, mode))
1168 return force_reg (mode, op);
1171 /* Return true if OP is a suitable input for a move insn. */
1174 move_operand (op, mode)
1176 enum machine_mode mode;
1178 if (register_operand (op, mode))
1180 if (GET_CODE (op) == CONST_INT)
1181 return (classify_integer (mode, INTVAL (op)) < m88k_oru_hi16);
1182 if (GET_MODE (op) != mode)
1184 if (GET_CODE (op) == SUBREG)
1185 op = SUBREG_REG (op);
1186 if (GET_CODE (op) != MEM)
1190 if (GET_CODE (op) == LO_SUM)
1191 return (REG_P (XEXP (op, 0))
1192 && symbolic_address_p (XEXP (op, 1)));
1193 return memory_address_p (mode, op);
1196 /* Return true if OP is suitable for a call insn. */
1199 call_address_operand (op, mode)
1201 enum machine_mode mode;
1203 return (REG_P (op) || symbolic_address_p (op));
1206 /* Returns true if OP is either a symbol reference or a sum of a symbol
1207 reference and a constant. */
1210 symbolic_address_p (op)
1213 switch (GET_CODE (op))
1221 return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
1222 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
1223 && GET_CODE (XEXP (op, 1)) == CONST_INT);
1230 /* Return true if OP is a register or const0_rtx. */
1233 reg_or_0_operand (op, mode)
1235 enum machine_mode mode;
1237 return (op == const0_rtx || register_operand (op, mode));
1240 /* Nonzero if OP is a valid second operand for an arithmetic insn. */
1243 arith_operand (op, mode)
1245 enum machine_mode mode;
1247 return (register_operand (op, mode)
1248 || (GET_CODE (op) == CONST_INT && SMALL_INT (op)));
1251 /* Return true if OP is a register or 5 bit integer. */
1254 arith5_operand (op, mode)
1256 enum machine_mode mode;
1258 return (register_operand (op, mode)
1259 || (GET_CODE (op) == CONST_INT && (unsigned) INTVAL (op) < 32));
1263 arith32_operand (op, mode)
1265 enum machine_mode mode;
1267 return (register_operand (op, mode) || GET_CODE (op) == CONST_INT);
1271 arith64_operand (op, mode)
1273 enum machine_mode mode;
1275 return (register_operand (op, mode)
1276 || GET_CODE (op) == CONST_INT
1277 || (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode));
1281 int5_operand (op, mode)
1283 enum machine_mode mode;
1285 return (GET_CODE (op) == CONST_INT && (unsigned) INTVAL (op) < 32);
1289 int32_operand (op, mode)
1291 enum machine_mode mode;
1293 return (GET_CODE (op) == CONST_INT);
1296 /* Return true if OP is a register or a valid immediate operand for
1300 add_operand (op, mode)
1302 enum machine_mode mode;
1304 return (register_operand (op, mode)
1305 || (GET_CODE (op) == CONST_INT && ADD_INT (op)));
1308 /* Nonzero if this is a bitmask filling the bottom bits, for optimizing and +
1309 shift left combinations into a single mak instruction. */
1315 return (value && POWER_OF_2_or_0 (value + 1));
1319 reg_or_bbx_mask_operand (op, mode)
1321 enum machine_mode mode;
1324 if (register_operand (op, mode))
1326 if (GET_CODE (op) != CONST_INT)
1329 value = INTVAL (op);
1330 if (POWER_OF_2 (value))
1336 /* Return true if OP is valid to use in the context of a floating
1337 point operation. Special case 0.0, since we can use r0. */
1340 real_or_0_operand (op, mode)
1342 enum machine_mode mode;
1344 if (mode != SFmode && mode != DFmode)
1347 return (register_operand (op, mode)
1348 || (GET_CODE (op) == CONST_DOUBLE
1349 && op == CONST0_RTX (mode)));
1352 /* Return true if OP is valid to use in the context of logic arithmetic
1353 on condition codes. */
1356 partial_ccmode_register_operand (op, mode)
1358 enum machine_mode mode;
1360 return register_operand (op, CCmode) || register_operand (op, CCEVENmode);
1363 /* Return true if OP is a relational operator. */
1368 enum machine_mode mode;
1370 switch (GET_CODE (op))
1389 even_relop (op, mode)
1391 enum machine_mode mode;
1393 switch (GET_CODE (op))
1407 odd_relop (op, mode)
1409 enum machine_mode mode;
1411 switch (GET_CODE (op))
1424 /* Return true if OP is a relational operator, and is not an unsigned
1425 relational operator. */
1428 relop_no_unsigned (op, mode)
1430 enum machine_mode mode;
1432 switch (GET_CODE (op))
1440 /* @@ What is this test doing? Why not use `mode'? */
1441 if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT
1442 || GET_MODE (op) == DImode
1443 || GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_FLOAT
1444 || GET_MODE (XEXP (op, 0)) == DImode
1445 || GET_MODE_CLASS (GET_MODE (XEXP (op, 1))) == MODE_FLOAT
1446 || GET_MODE (XEXP (op, 1)) == DImode)
1454 /* Return true if the code of this rtx pattern is EQ or NE. */
1457 equality_op (op, mode)
1459 enum machine_mode mode;
1461 return (GET_CODE (op) == EQ || GET_CODE (op) == NE);
1464 /* Return true if the code of this rtx pattern is pc or label_ref. */
1467 pc_or_label_ref (op, mode)
1469 enum machine_mode mode;
1471 return (GET_CODE (op) == PC || GET_CODE (op) == LABEL_REF);
1474 /* Output to FILE the start of the assembler file. */
1485 output_option (file, sep, type, name, indent, pos, max)
1494 if (strlen (sep) + strlen (type) + strlen (name) + pos > max)
1496 fprintf (file, indent);
1497 return fprintf (file, "%s%s", type, name);
1499 return pos + fprintf (file, "%s%s%s", sep, type, name);
1502 static struct { char *name; int value; } m_options[] = TARGET_SWITCHES;
1505 output_options (file, f_options, f_len, W_options, W_len,
1506 pos, max, sep, indent, term)
1508 struct options *f_options;
1509 struct options *W_options;
1519 pos = output_option (file, sep, "-O", "", indent, pos, max);
1520 if (write_symbols != NO_DEBUG)
1521 pos = output_option (file, sep, "-g", "", indent, pos, max);
1522 if (flag_traditional)
1523 pos = output_option (file, sep, "-traditional", "", indent, pos, max);
1525 pos = output_option (file, sep, "-p", "", indent, pos, max);
1526 if (profile_block_flag)
1527 pos = output_option (file, sep, "-a", "", indent, pos, max);
1529 for (j = 0; j < f_len; j++)
1530 if (*f_options[j].variable == f_options[j].on_value)
1531 pos = output_option (file, sep, "-f", f_options[j].string,
1534 for (j = 0; j < W_len; j++)
1535 if (*W_options[j].variable == W_options[j].on_value)
1536 pos = output_option (file, sep, "-W", W_options[j].string,
1539 for (j = 0; j < sizeof m_options / sizeof m_options[0]; j++)
1540 if (m_options[j].name[0] != '\0'
1541 && m_options[j].value > 0
1542 && ((m_options[j].value & target_flags)
1543 == m_options[j].value))
1544 pos = output_option (file, sep, "-m", m_options[j].name,
1547 if (m88k_short_data)
1548 pos = output_option (file, sep, "-mshort-data-", m88k_short_data,
1551 fprintf (file, term);
1555 output_file_start (file, f_options, f_len, W_options, W_len)
1557 struct options *f_options;
1558 struct options *W_options;
1563 ASM_FIRST_LINE (file);
1566 fprintf (file, "\t%s\n", REQUIRES_88110_ASM_OP);
1567 output_file_directive (file, main_input_filename);
1568 /* Switch to the data section so that the coffsem symbol and the
1569 gcc2_compiled. symbol aren't in the text section. */
1573 if (TARGET_IDENTIFY_REVISION)
1577 time_t now = time ((time_t *)0);
1578 sprintf (indent, "]\"\n\t%s\t \"@(#)%s [", IDENT_ASM_OP, main_input_filename);
1579 fprintf (file, indent+3);
1580 pos = fprintf (file, "gcc %s, %.24s,", version_string, ctime (&now));
1582 /* ??? It would be nice to call print_switch_values here (and thereby
1583 let us delete output_options) but this is kept in until it is known
1584 whether the change in content format matters. */
1585 output_options (file, f_options, f_len, W_options, W_len,
1586 pos, 150 - strlen (indent), " ", indent, "]\"\n\n");
1588 fprintf (file, "]\"\n");
1589 print_switch_values (file, 0, 150 - strlen (indent),
1590 indent + 3, " ", "]\"\n");
1595 /* Output an ascii string. */
1598 output_ascii (file, opcode, max, p, size)
1608 register int num = 0;
1610 fprintf (file, "\t%s\t \"", opcode);
1611 for (i = 0; i < size; i++)
1613 register int c = p[i];
1617 fprintf (file, "\"\n\t%s\t \"", opcode);
1621 if (c == '\"' || c == '\\')
1629 else if (in_escape && c >= '0' && c <= '9')
1631 /* If a digit follows an octal-escape, the Vax assembler fails
1632 to stop reading the escape after three digits. Continue to
1633 output the values as an octal-escape until a non-digit is
1635 fprintf (file, "\\%03o", c);
1638 else if ((c >= ' ' && c < 0177) || (c == '\t'))
1648 /* Some assemblers can't handle \a, \v, or \?. */
1649 case '\f': c = 'f'; goto escape;
1650 case '\b': c = 'b'; goto escape;
1651 case '\r': c = 'r'; goto escape;
1652 case '\n': c = 'n'; goto escape;
1655 fprintf (file, "\\%03o", c);
1660 fprintf (file, "\"\n");
1663 /* Output a label (allows insn-output.c to be compiled without including
1664 m88k.c or needing to include stdio.h). */
1667 output_label (label_number)
1670 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", label_number);
1673 /* Generate the assembly code for function entry.
1675 The prologue is responsible for setting up the stack frame,
1676 initializing the frame pointer register, saving registers that must be
1677 saved, and allocating SIZE additional bytes of storage for the
1678 local variables. SIZE is an integer. FILE is a stdio
1679 stream to which the assembler code should be output.
1681 The label for the beginning of the function need not be output by this
1682 macro. That has already been done when the macro is run.
1684 To determine which registers to save, the macro can refer to the array
1685 `regs_ever_live': element R is nonzero if hard register
1686 R is used anywhere within the function. This implies the
1687 function prologue should save register R, but not if it is one
1688 of the call-used registers.
1690 On machines where functions may or may not have frame-pointers, the
1691 function entry code must vary accordingly; it must set up the frame
1692 pointer if one is wanted, and not otherwise. To determine whether a
1693 frame pointer is in wanted, the macro can refer to the variable
1694 `frame_pointer_needed'. The variable's value will be 1 at run
1695 time in a function that needs a frame pointer.
1697 On machines where an argument may be passed partly in registers and
1698 partly in memory, this macro must examine the variable
1699 `current_function_pretend_args_size', and allocate that many bytes
1700 of uninitialized space on the stack just underneath the first argument
1701 arriving on the stack. (This may not be at the very end of the stack,
1702 if the calling sequence has pushed anything else since pushing the stack
1703 arguments. But usually, on such machines, nothing else has been pushed
1704 yet, because the function prologue itself does all the pushing.)
1706 If `ACCUMULATE_OUTGOING_ARGS' is defined, the variable
1707 `current_function_outgoing_args_size' contains the size in bytes
1708 required for the outgoing arguments. This macro must add that
1709 amount of uninitialized space to very bottom of the stack.
1711 The stack frame we use looks like this:
1714 |==============================================|
1716 |==============================================|
1717 | [caller's outgoing memory arguments] |
1718 |==============================================|
1719 | caller's outgoing argument area (32 bytes) |
1720 sp -> |==============================================| <- ap
1721 | [local variable space] |
1722 |----------------------------------------------|
1723 | [return address (r1)] |
1724 |----------------------------------------------|
1725 | [previous frame pointer (r30)] |
1726 |==============================================| <- fp
1727 | [preserved registers (r25..r14)] |
1728 |----------------------------------------------|
1729 | [preserved registers (x29..x22)] |
1730 |==============================================|
1731 | [dynamically allocated space (alloca)] |
1732 |==============================================|
1733 | [callee's outgoing memory arguments] |
1734 |==============================================|
1735 | [callee's outgoing argument area (32 bytes)] |
1736 |==============================================| <- sp
1740 r1 and r30 must be saved if debugging.
1742 fp (if present) is located two words down from the local
1746 static void emit_add ();
1747 static void preserve_registers ();
1748 static void emit_ldst ();
1749 static void output_tdesc ();
1753 static char save_regs[FIRST_PSEUDO_REGISTER];
1754 static int frame_laid_out;
1755 static int frame_size;
1756 static int variable_args_p;
1757 static int epilogue_marked;
1758 static int prologue_marked;
1760 #define FIRST_OCS_PRESERVE_REGISTER 14
1761 #define LAST_OCS_PRESERVE_REGISTER 30
1763 #define FIRST_OCS_EXTENDED_PRESERVE_REGISTER (32 + 22)
1764 #define LAST_OCS_EXTENDED_PRESERVE_REGISTER (32 + 31)
1766 #define STACK_UNIT_BOUNDARY (STACK_BOUNDARY / BITS_PER_UNIT)
1767 #define ROUND_CALL_BLOCK_SIZE(BYTES) \
1768 (((BYTES) + (STACK_UNIT_BOUNDARY - 1)) & ~(STACK_UNIT_BOUNDARY - 1))
1770 /* Establish the position of the FP relative to the SP. This is done
1771 either during FUNCTION_PROLOGUE or by INITIAL_ELIMINATION_OFFSET. */
1774 m88k_layout_frame ()
1780 bzero ((char *) &save_regs[0], sizeof (save_regs));
1781 sp_size = nregs = nxregs = 0;
1782 frame_size = get_frame_size ();
1784 /* Since profiling requires a call, make sure r1 is saved. */
1785 if (profile_flag || profile_block_flag)
1788 /* If we are producing debug information, store r1 and r30 where the
1789 debugger wants to find them (r30 at r30+0, r1 at r30+4). Space has
1790 already been reserved for r1/r30 in STARTING_FRAME_OFFSET. */
1791 if (write_symbols != NO_DEBUG && !TARGET_OCS_FRAME_POSITION)
1794 /* If there is a call, alloca is used, __builtin_alloca is used, or
1795 a dynamic-sized object is defined, add the 8 additional words
1796 for the callee's argument area. The common denominator is that the
1797 FP is required. may_call_alloca only gets calls to alloca;
1798 current_function_calls_alloca gets alloca and __builtin_alloca. */
1799 if (regs_ever_live[1] || frame_pointer_needed)
1802 sp_size += REG_PARM_STACK_SPACE (0);
1805 /* If we are producing PIC, save the addressing base register and r1. */
1806 if (flag_pic && current_function_uses_pic_offset_table)
1808 save_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
1812 /* If a frame is requested, save the previous FP, and the return
1813 address (r1), so that a traceback can be done without using tdesc
1814 information. Otherwise, simply save the FP if it is used as
1815 a preserve register. */
1816 if (frame_pointer_needed)
1817 save_regs[FRAME_POINTER_REGNUM] = save_regs[1] = 1;
1818 else if (regs_ever_live[FRAME_POINTER_REGNUM])
1819 save_regs[FRAME_POINTER_REGNUM] = 1;
1821 /* Figure out which extended register(s) needs to be saved. */
1822 for (regno = FIRST_EXTENDED_REGISTER + 1; regno < FIRST_PSEUDO_REGISTER;
1824 if (regs_ever_live[regno] && ! call_used_regs[regno])
1826 save_regs[regno] = 1;
1830 /* Figure out which normal register(s) needs to be saved. */
1831 for (regno = 2; regno < FRAME_POINTER_REGNUM; regno++)
1832 if (regs_ever_live[regno] && ! call_used_regs[regno])
1834 save_regs[regno] = 1;
1838 /* Achieve greatest use of double memory ops. Either we end up saving
1839 r30 or we use that slot to align the registers we do save. */
1840 if (nregs >= 2 && save_regs[1] && !save_regs[FRAME_POINTER_REGNUM])
1843 nregs += save_regs[1] + save_regs[FRAME_POINTER_REGNUM];
1844 /* if we need to align extended registers, add a word */
1845 if (nxregs > 0 && (nregs & 1) != 0)
1847 sp_size += 4 * nregs;
1848 sp_size += 8 * nxregs;
1849 sp_size += current_function_outgoing_args_size;
1851 /* The first two saved registers are placed above the new frame pointer
1852 if any. In the only case this matters, they are r1 and r30. */
1853 if (frame_pointer_needed || sp_size)
1854 m88k_fp_offset = ROUND_CALL_BLOCK_SIZE (sp_size - STARTING_FRAME_OFFSET);
1856 m88k_fp_offset = -STARTING_FRAME_OFFSET;
1857 m88k_stack_size = m88k_fp_offset + STARTING_FRAME_OFFSET;
1859 /* First, combine m88k_stack_size and size. If m88k_stack_size is
1860 non-zero, align the frame size to 8 mod 16; otherwise align the
1861 frame size to 0 mod 16. (If stacks are 8 byte aligned, this ends
1865 = ((m88k_stack_size ? STACK_UNIT_BOUNDARY - STARTING_FRAME_OFFSET : 0)
1866 - (frame_size % STACK_UNIT_BOUNDARY));
1870 need += STACK_UNIT_BOUNDARY;
1871 (void) assign_stack_local (BLKmode, need, BITS_PER_UNIT);
1872 frame_size = get_frame_size ();
1875 = ROUND_CALL_BLOCK_SIZE (m88k_stack_size + frame_size
1876 + current_function_pretend_args_size);
1880 /* Return true if this function is known to have a null prologue. */
1885 if (! reload_completed)
1887 if (! frame_laid_out)
1888 m88k_layout_frame ();
1889 return (! frame_pointer_needed
1892 && m88k_stack_size == 0);
1895 /* Determine if the current function has any references to the arg pointer.
1896 This is done indirectly by examining the DECL_ARGUMENTS' DECL_RTL.
1897 It is OK to return TRUE if there are no references, but FALSE must be
1905 if (current_function_decl == 0
1906 || current_function_varargs
1910 for (parm = DECL_ARGUMENTS (current_function_decl);
1912 parm = TREE_CHAIN (parm))
1914 if (DECL_RTL (parm) == 0
1915 || GET_CODE (DECL_RTL (parm)) == MEM)
1918 if (DECL_INCOMING_RTL (parm) == 0
1919 || GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
1926 m88k_begin_prologue (stream, size)
1930 if (TARGET_OMIT_LEAF_FRAME_POINTER && ! quiet_flag && leaf_function_p ())
1931 fprintf (stderr, "$");
1933 m88k_prologue_done = 1; /* it's ok now to put out ln directives */
1937 m88k_end_prologue (stream)
1940 if (TARGET_OCS_DEBUG_INFO && !prologue_marked)
1942 PUT_OCS_FUNCTION_START (stream);
1943 prologue_marked = 1;
1945 /* If we've already passed the start of the epilogue, say that
1946 it starts here. This marks the function as having a null body,
1947 but at a point where the return address is in a known location.
1949 Originally, I thought this couldn't happen, but the pic prologue
1950 for leaf functions ends with the instruction that restores the
1951 return address from the temporary register. If the temporary
1952 register is never used, that instruction can float all the way
1953 to the end of the function. */
1954 if (epilogue_marked)
1955 PUT_OCS_FUNCTION_END (stream);
1960 m88k_expand_prologue ()
1962 m88k_layout_frame ();
1964 if (TARGET_OPTIMIZE_ARG_AREA
1966 && ! uses_arg_area_p ())
1968 /* The incoming argument area is used for stack space if it is not
1969 used (or if -mno-optimize-arg-area is given). */
1970 if ((m88k_stack_size -= REG_PARM_STACK_SPACE (0)) < 0)
1971 m88k_stack_size = 0;
1974 if (m88k_stack_size)
1975 emit_add (stack_pointer_rtx, stack_pointer_rtx, -m88k_stack_size);
1977 if (nregs || nxregs)
1978 preserve_registers (m88k_fp_offset + 4, 1);
1980 if (frame_pointer_needed)
1981 emit_add (frame_pointer_rtx, stack_pointer_rtx, m88k_fp_offset);
1983 if (flag_pic && save_regs[PIC_OFFSET_TABLE_REGNUM])
1985 rtx return_reg = gen_rtx (REG, SImode, 1);
1986 rtx label = gen_label_rtx ();
1991 temp_reg = gen_rtx (REG, SImode, TEMP_REGNUM);
1992 emit_move_insn (temp_reg, return_reg);
1994 emit_insn (gen_locate1 (pic_offset_table_rtx, label));
1995 emit_insn (gen_locate2 (pic_offset_table_rtx, label));
1996 emit_insn (gen_addsi3 (pic_offset_table_rtx,
1997 pic_offset_table_rtx, return_reg));
1999 emit_move_insn (return_reg, temp_reg);
2001 if (profile_flag || profile_block_flag)
2002 emit_insn (gen_blockage ());
2005 /* This function generates the assembly code for function exit,
2006 on machines that need it. Args are same as for FUNCTION_PROLOGUE.
2008 The function epilogue should not depend on the current stack pointer!
2009 It should use the frame pointer only, if there is a frame pointer.
2010 This is mandatory because of alloca; we also take advantage of it to
2011 omit stack adjustments before returning. */
2014 m88k_begin_epilogue (stream)
2017 if (TARGET_OCS_DEBUG_INFO && !epilogue_marked && prologue_marked)
2019 PUT_OCS_FUNCTION_END (stream);
2021 epilogue_marked = 1;
2025 m88k_end_epilogue (stream, size)
2029 rtx insn = get_last_insn ();
2031 if (TARGET_OCS_DEBUG_INFO && !epilogue_marked)
2032 PUT_OCS_FUNCTION_END (stream);
2034 /* If the last insn isn't a BARRIER, we must write a return insn. This
2035 should only happen if the function has no prologue and no body. */
2036 if (GET_CODE (insn) == NOTE)
2037 insn = prev_nonnote_insn (insn);
2038 if (insn == 0 || GET_CODE (insn) != BARRIER)
2039 fprintf (stream, "\tjmp\t %s\n", reg_names[1]);
2041 /* If the last insn is a barrier, and the insn before that is a call,
2042 then add a nop instruction so that tdesc can walk the stack correctly
2043 even though there is no epilogue. (Otherwise, the label for the
2044 end of the tdesc region ends up at the start of the next function. */
2045 if (insn && GET_CODE (insn) == BARRIER)
2047 insn = prev_nonnote_insn (insn);
2048 if (insn && GET_CODE (insn) == CALL_INSN)
2049 fprintf (stream, "\tor\t %s,%s,%s\n",reg_names[0],reg_names[0],reg_names[0]);
2052 output_short_branch_defs (stream);
2054 fprintf (stream, "\n");
2056 if (TARGET_OCS_DEBUG_INFO)
2057 output_tdesc (stream, m88k_fp_offset + 4);
2059 m88k_function_number++;
2060 m88k_prologue_done = 0; /* don't put out ln directives */
2061 variable_args_p = 0; /* has variable args */
2063 epilogue_marked = 0;
2064 prologue_marked = 0;
2068 m88k_expand_epilogue ()
2070 #if (MONITOR_GCC & 0x4) /* What are interesting prologue/epilogue values? */
2071 fprintf (stream, "; size = %d, m88k_fp_offset = %d, m88k_stack_size = %d\n",
2072 size, m88k_fp_offset, m88k_stack_size);
2075 if (frame_pointer_needed)
2076 emit_add (stack_pointer_rtx, frame_pointer_rtx, -m88k_fp_offset);
2078 if (nregs || nxregs)
2079 preserve_registers (m88k_fp_offset + 4, 0);
2081 if (m88k_stack_size)
2082 emit_add (stack_pointer_rtx, stack_pointer_rtx, m88k_stack_size);
2085 /* Emit insns to set DSTREG to SRCREG + AMOUNT during the prologue or
2089 emit_add (dstreg, srcreg, amount)
2094 rtx incr = GEN_INT (abs (amount));
2095 if (! ADD_INTVAL (amount))
2097 rtx temp = gen_rtx (REG, SImode, TEMP_REGNUM);
2098 emit_move_insn (temp, incr);
2101 emit_insn ((amount < 0 ? gen_subsi3 : gen_addsi3) (dstreg, srcreg, incr));
2104 /* Save/restore the preserve registers. base is the highest offset from
2105 r31 at which a register is stored. store_p is true if stores are to
2106 be done; otherwise loads. */
2109 preserve_registers (base, store_p)
2118 } mem_op[FIRST_PSEUDO_REGISTER];
2119 struct mem_op *mo_ptr = mem_op;
2121 /* The 88open OCS mandates that preserved registers be stored in
2122 increasing order. For compatibility with current practice,
2123 the order is r1, r30, then the preserve registers. */
2128 /* An extra word is given in this case to make best use of double
2130 if (nregs > 2 && !save_regs[FRAME_POINTER_REGNUM])
2132 emit_ldst (store_p, 1, SImode, offset);
2137 /* Walk the registers to save recording all single memory operations. */
2138 for (regno = FRAME_POINTER_REGNUM; regno > 1; regno--)
2139 if (save_regs[regno])
2141 if ((offset & 7) != 4 || (regno & 1) != 1 || !save_regs[regno-1])
2144 mo_ptr->regno = regno;
2145 mo_ptr->offset = offset;
2156 /* Walk the registers to save recording all double memory operations.
2157 This avoids a delay in the epilogue (ld.d/ld). */
2159 for (regno = FRAME_POINTER_REGNUM; regno > 1; regno--)
2160 if (save_regs[regno])
2162 if ((offset & 7) != 4 || (regno & 1) != 1 || !save_regs[regno-1])
2169 mo_ptr->regno = regno-1;
2170 mo_ptr->offset = offset-4;
2177 /* Walk the extended registers to record all memory operations. */
2178 /* Be sure the offset is double word aligned. */
2179 offset = (offset - 1) & ~7;
2180 for (regno = FIRST_PSEUDO_REGISTER - 1; regno > FIRST_EXTENDED_REGISTER;
2182 if (save_regs[regno])
2185 mo_ptr->regno = regno;
2186 mo_ptr->offset = offset;
2193 /* Output the memory operations. */
2194 for (mo_ptr = mem_op; mo_ptr->regno; mo_ptr++)
2197 emit_ldst (store_p, mo_ptr->regno,
2198 (mo_ptr->nregs > 1 ? DImode : SImode),
2204 emit_ldst (store_p, regno, mode, offset)
2207 enum machine_mode mode;
2210 rtx reg = gen_rtx (REG, mode, regno);
2213 if (SMALL_INTVAL (offset))
2215 mem = gen_rtx (MEM, mode, plus_constant (stack_pointer_rtx, offset));
2219 /* offset is too large for immediate index must use register */
2221 rtx disp = GEN_INT (offset);
2222 rtx temp = gen_rtx (REG, SImode, TEMP_REGNUM);
2223 rtx regi = gen_rtx (PLUS, SImode, stack_pointer_rtx, temp);
2224 emit_move_insn (temp, disp);
2225 mem = gen_rtx (MEM, mode, regi);
2229 emit_move_insn (mem, reg);
2231 emit_move_insn (reg, mem);
2234 /* Convert the address expression REG to a CFA offset. */
2237 m88k_debugger_offset (reg, offset)
2239 register int offset;
2241 if (GET_CODE (reg) == PLUS)
2243 offset = INTVAL (XEXP (reg, 1));
2244 reg = XEXP (reg, 0);
2247 /* Put the offset in terms of the CFA (arg pointer). */
2248 if (reg == frame_pointer_rtx)
2249 offset += m88k_fp_offset - m88k_stack_size;
2250 else if (reg == stack_pointer_rtx)
2251 offset -= m88k_stack_size;
2252 else if (reg != arg_pointer_rtx)
2254 #if (MONITOR_GCC & 0x10) /* Watch for suspicious symbolic locations. */
2255 if (! (GET_CODE (reg) == REG
2256 && REGNO (reg) >= FIRST_PSEUDO_REGISTER))
2257 warning ("Internal gcc error: Can't express symbolic location");
2265 /* Output the 88open OCS proscribed text description information.
2268 0 22: info-byte-length (16 or 20 bytes)
2269 0 2: info-alignment (word 2)
2270 1 32: info-protocol (version 1 or 2(pic))
2271 2 32: starting-address (inclusive, not counting prologue)
2272 3 32: ending-address (exclusive, not counting epilog)
2273 4 8: info-variant (version 1 or 3(extended registers))
2274 4 17: register-save-mask (from register 14 to 30)
2276 4 1: return-address-info-discriminant
2277 4 5: frame-address-register
2278 5 32: frame-address-offset
2279 6 32: return-address-info
2280 7 32: register-save-offset
2281 8 16: extended-register-save-mask (x16 - x31)
2282 8 16: extended-register-save-offset (WORDS from register-save-offset) */
2285 output_tdesc (file, offset)
2290 long mask, return_address_info, register_save_offset;
2291 long xmask, xregister_save_offset;
2294 for (mask = 0, i = 0, regno = FIRST_OCS_PRESERVE_REGISTER;
2295 regno <= LAST_OCS_PRESERVE_REGISTER;
2299 if (save_regs[regno])
2306 for (xmask = 0, j = 0, regno = FIRST_OCS_EXTENDED_PRESERVE_REGISTER;
2307 regno <= LAST_OCS_EXTENDED_PRESERVE_REGISTER;
2311 if (save_regs[regno])
2320 if ((nxregs > 0 || nregs > 2) && !save_regs[FRAME_POINTER_REGNUM])
2322 return_address_info = - m88k_stack_size + offset;
2323 register_save_offset = return_address_info - i*4;
2327 return_address_info = 1;
2328 register_save_offset = - m88k_stack_size + offset + 4 - i*4;
2331 xregister_save_offset = - (j * 2 + ((register_save_offset >> 2) & 1));
2335 fprintf (file, "\t%s\t %d,%d", INT_ASM_OP, /* 8:0,22:(20 or 16),2:2 */
2336 (((xmask != 0) ? 20 : 16) << 2) | 2,
2339 ASM_GENERATE_INTERNAL_LABEL (buf, OCS_START_PREFIX, m88k_function_number);
2340 fprintf (file, ",%s%s", buf+1, flag_pic ? "#rel" : "");
2341 ASM_GENERATE_INTERNAL_LABEL (buf, OCS_END_PREFIX, m88k_function_number);
2342 fprintf (file, ",%s%s", buf+1, flag_pic ? "#rel" : "");
2344 fprintf (file, ",0x%x,0x%x,0x%x,0x%x",
2345 /* 8:1,17:0x%.3x,1:0,1:%d,5:%d */
2346 (((xmask ? 3 : 1) << (17+1+1+5))
2348 | ((!!save_regs[1]) << 5)
2349 | (frame_pointer_needed
2350 ? FRAME_POINTER_REGNUM
2351 : STACK_POINTER_REGNUM)),
2352 (m88k_stack_size - (frame_pointer_needed ? m88k_fp_offset : 0)),
2353 return_address_info,
2354 register_save_offset);
2356 fprintf (file, ",0x%x%04x", xmask, (0xffff & xregister_save_offset));
2362 /* Output assembler code to FILE to increment profiler label # LABELNO
2363 for profiling a function entry. NAME is the mcount function name
2364 (varies), SAVEP indicates whether the parameter registers need to
2365 be saved and restored. */
2368 output_function_profiler (file, labelno, name, savep)
2376 char *temp = (savep ? reg_names[2] : reg_names[10]);
2378 /* Remember to update FUNCTION_PROFILER_LENGTH. */
2382 fprintf (file, "\tsubu\t %s,%s,64\n", reg_names[31], reg_names[31]);
2383 fprintf (file, "\tst.d\t %s,%s,32\n", reg_names[2], reg_names[31]);
2384 fprintf (file, "\tst.d\t %s,%s,40\n", reg_names[4], reg_names[31]);
2385 fprintf (file, "\tst.d\t %s,%s,48\n", reg_names[6], reg_names[31]);
2386 fprintf (file, "\tst.d\t %s,%s,56\n", reg_names[8], reg_names[31]);
2389 ASM_GENERATE_INTERNAL_LABEL (label, "LP", labelno);
2392 fprintf (file, "\tor.u\t %s,%s,%shi16(%s#got_rel)\n",
2393 temp, reg_names[0], m88k_pound_sign, &label[1]);
2394 fprintf (file, "\tor\t %s,%s,%slo16(%s#got_rel)\n",
2395 temp, temp, m88k_pound_sign, &label[1]);
2396 sprintf (dbi, "\tld\t %s,%s,%s\n", temp,
2397 reg_names[PIC_OFFSET_TABLE_REGNUM], temp);
2401 sprintf (dbi, "\tld\t %s,%s,%s#got_rel\n", temp,
2402 reg_names[PIC_OFFSET_TABLE_REGNUM], &label[1]);
2406 fprintf (file, "\tor.u\t %s,%s,%shi16(%s)\n",
2407 temp, reg_names[0], m88k_pound_sign, &label[1]);
2408 sprintf (dbi, "\tor\t %s,%s,%slo16(%s)\n",
2409 temp, temp, m88k_pound_sign, &label[1]);
2413 fprintf (file, "\tbsr.n\t %s#plt\n", name);
2415 fprintf (file, "\tbsr.n\t %s\n", name);
2420 fprintf (file, "\tld.d\t %s,%s,32\n", reg_names[2], reg_names[31]);
2421 fprintf (file, "\tld.d\t %s,%s,40\n", reg_names[4], reg_names[31]);
2422 fprintf (file, "\tld.d\t %s,%s,48\n", reg_names[6], reg_names[31]);
2423 fprintf (file, "\tld.d\t %s,%s,56\n", reg_names[8], reg_names[31]);
2424 fprintf (file, "\taddu\t %s,%s,64\n", reg_names[31], reg_names[31]);
2428 /* Output assembler code to FILE to initialize basic-block profiling for
2429 the current module. LABELNO is unique to each instance. */
2432 output_function_block_profiler (file, labelno)
2439 /* Remember to update FUNCTION_BLOCK_PROFILER_LENGTH. */
2441 ASM_GENERATE_INTERNAL_LABEL (block, "LPBX", 0);
2442 ASM_GENERATE_INTERNAL_LABEL (label, "LPY", labelno);
2444 /* @@ Need to deal with PIC. I'm not sure what the requirements are on
2445 register usage, so I used r26/r27 to be safe. */
2446 fprintf (file, "\tor.u\t %s,%s,%shi16(%s)\n", reg_names[27], reg_names[0],
2447 m88k_pound_sign, &block[1]);
2448 fprintf (file, "\tld\t %s,%s,%slo16(%s)\n", reg_names[26], reg_names[27],
2449 m88k_pound_sign, &block[1]);
2450 fprintf (file, "\tbcnd\t %sne0,%s,%s\n",
2451 m88k_pound_sign, reg_names[26], &label[1]);
2452 fprintf (file, "\tsubu\t %s,%s,64\n", reg_names[31], reg_names[31]);
2453 fprintf (file, "\tst.d\t %s,%s,32\n", reg_names[2], reg_names[31]);
2454 fprintf (file, "\tst.d\t %s,%s,40\n", reg_names[4], reg_names[31]);
2455 fprintf (file, "\tst.d\t %s,%s,48\n", reg_names[6], reg_names[31]);
2456 fprintf (file, "\tst.d\t %s,%s,56\n", reg_names[8], reg_names[31]);
2457 fputs ("\tbsr.n\t ", file);
2458 ASM_OUTPUT_LABELREF (file, "__bb_init_func");
2460 fprintf (file, "\tor\t %s,%s,%slo16(%s)\n", reg_names[2], reg_names[27],
2461 m88k_pound_sign, &block[1]);
2462 fprintf (file, "\tld.d\t %s,%s,32\n", reg_names[2], reg_names[31]);
2463 fprintf (file, "\tld.d\t %s,%s,40\n", reg_names[4], reg_names[31]);
2464 fprintf (file, "\tld.d\t %s,%s,48\n", reg_names[6], reg_names[31]);
2465 fprintf (file, "\tld.d\t %s,%s,56\n", reg_names[8], reg_names[31]);
2466 fprintf (file, "\taddu\t %s,%s,64\n", reg_names[31], reg_names[31]);
2467 ASM_OUTPUT_INTERNAL_LABEL (file, "LPY", labelno);
2470 /* Output assembler code to FILE to increment the count associated with
2471 the basic block number BLOCKNO. */
2474 output_block_profiler (file, blockno)
2480 /* Remember to update BLOCK_PROFILER_LENGTH. */
2482 ASM_GENERATE_INTERNAL_LABEL (block, "LPBX", 2);
2484 /* @@ Need to deal with PIC. I'm not sure what the requirements are on
2485 register usage, so I used r26/r27 to be safe. */
2486 fprintf (file, "\tor.u\t %s,%s,%shi16(%s+%d)\n", reg_names[27], reg_names[0],
2487 m88k_pound_sign, &block[1], 4 * blockno);
2488 fprintf (file, "\tld\t %s,%s,%slo16(%s+%d)\n", reg_names[26], reg_names[27],
2489 m88k_pound_sign, &block[1], 4 * blockno);
2490 fprintf (file, "\taddu\t %s,%s,1\n", reg_names[26], reg_names[26]);
2491 fprintf (file, "\tst\t %s,%s,%slo16(%s+%d)\n", reg_names[26], reg_names[27],
2492 m88k_pound_sign, &block[1], 4 * blockno);
2495 /* Determine whether a function argument is passed in a register, and
2498 The arguments are CUM, which summarizes all the previous
2499 arguments; MODE, the machine mode of the argument; TYPE,
2500 the data type of the argument as a tree node or 0 if that is not known
2501 (which happens for C support library functions); and NAMED,
2502 which is 1 for an ordinary argument and 0 for nameless arguments that
2503 correspond to `...' in the called function's prototype.
2505 The value of the expression should either be a `reg' RTX for the
2506 hard register in which to pass the argument, or zero to pass the
2507 argument on the stack.
2509 On the m88000 the first eight words of args are normally in registers
2510 and the rest are pushed. Double precision floating point must be
2511 double word aligned (and if in a register, starting on an even
2512 register). Structures and unions which are not 4 byte, and word
2513 aligned are passed in memory rather than registers, even if they
2514 would fit completely in the registers under OCS rules.
2516 Note that FUNCTION_ARG and FUNCTION_INCOMING_ARG were different.
2517 For structures that are passed in memory, but could have been
2518 passed in registers, we first load the structure into the
2519 register, and then when the last argument is passed, we store
2520 the registers into the stack locations. This fixes some bugs
2521 where GCC did not expect to have register arguments, followed
2522 by stack arguments, followed by register arguments. */
2525 m88k_function_arg (args_so_far, mode, type, named)
2526 CUMULATIVE_ARGS args_so_far;
2527 enum machine_mode mode;
2533 if (type != 0 /* undo putting struct in register */
2534 && (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE))
2537 if (mode == BLKmode && TARGET_WARN_PASS_STRUCT)
2538 warning ("argument #%d is a structure", args_so_far + 1);
2540 if ((args_so_far & 1) != 0
2541 && (mode == DImode || mode == DFmode
2542 || (type != 0 && TYPE_ALIGN (type) > 32)))
2547 return (rtx) 0; /* don't put args in registers */
2550 if (type == 0 && mode == BLKmode)
2551 abort (); /* m88k_function_arg argument `type' is NULL for BLKmode. */
2553 bytes = (mode != BLKmode) ? GET_MODE_SIZE (mode) : int_size_in_bytes (type);
2554 words = (bytes + 3) / 4;
2556 if (args_so_far + words > 8)
2557 return (rtx) 0; /* args have exhausted registers */
2559 else if (mode == BLKmode
2560 && (TYPE_ALIGN (type) != BITS_PER_WORD
2561 || bytes != UNITS_PER_WORD))
2564 return gen_rtx (REG,
2565 ((mode == BLKmode) ? TYPE_MODE (type) : mode),
2569 /* Do what is necessary for `va_start'. We look at the current function
2570 to determine if stdargs or varargs is used and spill as necessary.
2571 We return a pointer to the spill area. */
2574 m88k_builtin_saveregs ()
2577 tree fntype = TREE_TYPE (current_function_decl);
2578 int argadj = ((!(TYPE_ARG_TYPES (fntype) != 0
2579 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2580 != void_type_node)))
2581 ? -UNITS_PER_WORD : 0) + UNITS_PER_WORD - 1;
2584 variable_args_p = 1;
2587 if (CONSTANT_P (current_function_arg_offset_rtx))
2589 fixed = (XINT (current_function_arg_offset_rtx, 0)
2590 + argadj) / UNITS_PER_WORD;
2593 /* Allocate the register space, and store it as the __va_reg member. */
2594 addr = assign_stack_local (BLKmode, 8 * UNITS_PER_WORD, -1);
2595 MEM_ALIAS_SET (addr) = get_varargs_alias_set ();
2596 RTX_UNCHANGING_P (addr) = 1;
2597 RTX_UNCHANGING_P (XEXP (addr, 0)) = 1;
2599 /* Now store the incoming registers. */
2602 dest = change_address (addr, Pmode,
2603 plus_constant (XEXP (addr, 0),
2604 fixed * UNITS_PER_WORD));
2605 move_block_from_reg (2 + fixed, dest, 8 - fixed,
2606 UNITS_PER_WORD * (8 - fixed));
2608 if (current_function_check_memory_usage)
2610 emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
2612 GEN_INT (UNITS_PER_WORD * (8 - fixed)),
2613 TYPE_MODE (sizetype),
2614 GEN_INT (MEMORY_USE_RW),
2615 TYPE_MODE (integer_type_node));
2619 /* Return the address of the save area, but don't put it in a
2620 register. This fails when not optimizing and produces worse code
2622 return XEXP (addr, 0);
2625 /* Define the `__builtin_va_list' type for the ABI. */
2628 m88k_build_va_list ()
2630 tree field_reg, field_stk, field_arg, int_ptr_type_node, record;
2632 int_ptr_type_node = build_pointer_type (integer_type_node);
2634 record = make_node (RECORD_TYPE);
2636 field_arg = build_decl (FIELD_DECL, get_identifier ("__va_arg"),
2638 field_stk = build_decl (FIELD_DECL, get_identifier ("__va_stk"),
2640 field_reg = build_decl (FIELD_DECL, get_identifier ("__va_reg"),
2643 DECL_FIELD_CONTEXT (field_arg) = record;
2644 DECL_FIELD_CONTEXT (field_stk) = record;
2645 DECL_FIELD_CONTEXT (field_reg) = record;
2647 TYPE_FIELDS (record) = field_arg;
2648 TREE_CHAIN (field_arg) = field_stk;
2649 TREE_CHAIN (field_stk) = field_reg;
2651 layout_type (record);
2655 /* Implement `va_start' for varargs and stdarg. */
2658 m88k_va_start (stdarg_p, valist, nextarg)
2661 rtx nextarg ATTRIBUTE_UNUSED;
2663 tree field_reg, field_stk, field_arg;
2664 tree reg, stk, arg, t;
2666 field_arg = TYPE_FIELDS (va_list_type_node);
2667 field_stk = TREE_CHAIN (field_arg);
2668 field_reg = TREE_CHAIN (field_stk);
2670 arg = build (COMPONENT_REF, TREE_TYPE (field_arg), valist, field_arg);
2671 stk = build (COMPONENT_REF, TREE_TYPE (field_stk), valist, field_stk);
2672 reg = build (COMPONENT_REF, TREE_TYPE (field_reg), valist, field_reg);
2674 /* Fill in the ARG member. */
2676 tree fntype = TREE_TYPE (current_function_decl);
2677 int argadj = ((!(TYPE_ARG_TYPES (fntype) != 0
2678 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2679 != void_type_node)))
2680 ? -UNITS_PER_WORD : 0) + UNITS_PER_WORD - 1;
2683 if (CONSTANT_P (current_function_arg_offset_rtx))
2685 int fixed = (INTVAL (current_function_arg_offset_rtx)
2686 + argadj) / UNITS_PER_WORD;
2688 argsize = build_int_2 (fixed, 0);
2692 argsize = make_tree (integer_type_node,
2693 current_function_arg_offset_rtx);
2694 argsize = fold (build (PLUS_EXPR, integer_type_node, argsize,
2695 build_int_2 (argadj, 0)));
2696 argsize = fold (build (RSHIFT_EXPR, integer_type_node, argsize,
2697 build_int_2 (2, 0)));
2700 t = build (MODIFY_EXPR, TREE_TYPE (arg), arg, argsize);
2701 TREE_SIDE_EFFECTS (t) = 1;
2702 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2705 /* Store the arg pointer in the __va_stk member. */
2706 t = make_tree (TREE_TYPE (stk), virtual_incoming_args_rtx);
2707 t = build (MODIFY_EXPR, TREE_TYPE (stk), stk, t);
2708 TREE_SIDE_EFFECTS (t) = 1;
2709 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2711 /* Tuck the return value from __builtin_saveregs into __va_reg. */
2712 t = make_tree (TREE_TYPE (reg), expand_builtin_saveregs ());
2713 t = build (MODIFY_EXPR, TREE_TYPE (reg), reg, t);
2714 TREE_SIDE_EFFECTS (t) = 1;
2715 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2718 /* Implement `va_arg'. */
2721 m88k_va_arg (valist, type)
2724 tree field_reg, field_stk, field_arg;
2725 tree reg, stk, arg, arg_align, base, t;
2726 int size, wsize, align, reg_p;
2729 field_arg = TYPE_FIELDS (va_list_type_node);
2730 field_stk = TREE_CHAIN (field_arg);
2731 field_reg = TREE_CHAIN (field_stk);
2733 arg = build (COMPONENT_REF, TREE_TYPE (field_arg), valist, field_arg);
2734 stk = build (COMPONENT_REF, TREE_TYPE (field_stk), valist, field_stk);
2735 reg = build (COMPONENT_REF, TREE_TYPE (field_reg), valist, field_reg);
2737 size = int_size_in_bytes (type);
2738 wsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
2739 align = 1 << ((TYPE_ALIGN (type) / BITS_PER_UNIT) >> 3);
2740 reg_p = (AGGREGATE_TYPE_P (type)
2741 ? size == UNITS_PER_WORD && TYPE_ALIGN (type) == BITS_PER_WORD
2742 : size <= 2*UNITS_PER_WORD);
2744 /* Align __va_arg to the (doubleword?) boundary above. */
2745 t = build (PLUS_EXPR, TREE_TYPE (arg), arg, build_int_2 (align - 1, 0));
2746 arg_align = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align, -1));
2747 arg_align = save_expr (arg_align);
2749 /* Decide if we should read from stack or regs. */
2750 t = build (LT_EXPR, integer_type_node, arg_align, build_int_2 (8, 0));
2751 base = build (COND_EXPR, TREE_TYPE (reg), t, reg, stk);
2753 /* Find the final address. */
2754 t = build (PLUS_EXPR, TREE_TYPE (base), base, arg_align);
2755 addr_rtx = expand_expr (t, NULL_RTX, Pmode, EXPAND_NORMAL);
2756 addr_rtx = copy_to_reg (addr_rtx);
2758 /* Increment __va_arg. */
2759 t = build (PLUS_EXPR, TREE_TYPE (arg), arg_align, build_int_2 (wsize, 0));
2760 t = build (MODIFY_EXPR, TREE_TYPE (arg), arg, t);
2761 TREE_SIDE_EFFECTS (t) = 1;
2762 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2767 /* If cmpsi has not been generated, emit code to do the test. Return the
2768 expression describing the test of operator OP. */
2771 emit_test (op, mode)
2773 enum machine_mode mode;
2775 if (m88k_compare_reg == 0)
2776 emit_insn (gen_test (m88k_compare_op0, m88k_compare_op1));
2777 return (gen_rtx (op, mode, m88k_compare_reg, const0_rtx));
2780 /* Determine how to best perform cmpsi/bxx, where cmpsi has a constant
2781 operand. All tests with zero (albeit swapped) and all equality tests
2782 with a constant are done with bcnd. The remaining cases are swapped
2786 emit_bcnd (op, label)
2790 if (m88k_compare_op1 == const0_rtx)
2791 emit_jump_insn( gen_bcnd (
2792 gen_rtx (op, VOIDmode,m88k_compare_op0, const0_rtx),
2794 else if (m88k_compare_op0 == const0_rtx)
2795 emit_jump_insn( gen_bcnd(
2797 swap_condition (op),
2798 VOIDmode, m88k_compare_op1, const0_rtx),
2800 else if (op != EQ && op != NE)
2801 emit_jump_insn (gen_bxx (emit_test (op, VOIDmode), label));
2804 rtx zero = gen_reg_rtx (SImode);
2808 if (GET_CODE (m88k_compare_op1) == CONST_INT)
2810 reg = force_reg (SImode, m88k_compare_op0);
2811 constant = m88k_compare_op1;
2815 reg = force_reg (SImode, m88k_compare_op1);
2816 constant = m88k_compare_op0;
2818 value = INTVAL (constant);
2820 /* Perform an arithmetic computation to make the compared-to value
2821 zero, but avoid loosing if the bcnd is later changed into sxx. */
2822 if (SMALL_INTVAL (value))
2823 emit_jump_insn (gen_bxx (emit_test (op, VOIDmode), label));
2826 if (SMALL_INTVAL (-value))
2827 emit_insn (gen_addsi3 (zero, reg,
2830 emit_insn (gen_xorsi3 (zero, reg, constant));
2832 emit_jump_insn (gen_bcnd (gen_rtx (op, VOIDmode,
2839 /* Print an operand. Recognize special options, documented below. */
2842 print_operand (file, x, code)
2847 enum rtx_code xc = (x ? GET_CODE (x) : UNKNOWN);
2848 register int value = (xc == CONST_INT ? INTVAL (x) : 0);
2849 static int sequencep;
2850 static int reversep;
2854 if (code < 'B' || code > 'E')
2855 output_operand_lossage ("%R not followed by %B/C/D/E");
2857 xc = reverse_condition (xc);
2863 case '*': /* addressing base register for PIC */
2864 fputs (reg_names[PIC_OFFSET_TABLE_REGNUM], file); return;
2866 case '#': /* SVR4 pound-sign syntax character (empty if SVR3) */
2867 fputs (m88k_pound_sign, file); return;
2869 case 'V': /* Output a serializing instruction as needed if the operand
2870 (assumed to be a MEM) is a volatile load. */
2871 case 'v': /* ditto for a volatile store. */
2872 if (MEM_VOLATILE_P (x) && TARGET_SERIALIZE_VOLATILE)
2874 /* The m88110 implements two FIFO queues, one for loads and
2875 one for stores. These queues mean that loads complete in
2876 their issue order as do stores. An interaction between the
2877 history buffer and the store reservation station ensures
2878 that a store will not bypass load. Finally, a load will not
2879 bypass store, but only when they reference the same address.
2881 To avoid this reordering (a load bypassing a store) for
2882 volatile references, a serializing instruction is output.
2883 We choose the fldcr instruction as it does not serialize on
2884 the m88100 so that -m88000 code will not be degraded.
2886 The mechanism below is completed by having CC_STATUS_INIT set
2887 the code to the unknown value. */
2891 A problem with 88110 4.1 & 4.2 makes the use of fldcr for
2892 this purpose undesirable. Instead we will use tb1, this will
2893 cause serialization on the 88100 but such is life.
2896 static rtx last_addr = 0;
2897 if (code == 'V' /* Only need to serialize before a load. */
2898 && m88k_volatile_code != 'V' /* Loads complete in FIFO order. */
2899 && !(m88k_volatile_code == 'v'
2900 && GET_CODE (XEXP (x, 0)) == LO_SUM
2901 && rtx_equal_p (XEXP (XEXP (x, 0), 1), last_addr)))
2905 "fldcr\t %s,%scr63\n\t",
2907 "fldcr\t %s,%sfcr63\n\t",
2909 reg_names[0], m88k_pound_sign);
2911 "tb1\t 1,%s,0xff\n\t", reg_names[0]);
2913 m88k_volatile_code = code;
2914 last_addr = (GET_CODE (XEXP (x, 0)) == LO_SUM
2915 ? XEXP (XEXP (x, 0), 1) : 0);
2919 case 'X': /* print the upper 16 bits... */
2921 case 'x': /* print the lower 16 bits of the integer constant in hex */
2922 if (xc != CONST_INT)
2923 output_operand_lossage ("invalid %x/X value");
2924 fprintf (file, "0x%x", value & 0xffff); return;
2926 case 'H': /* print the low 16 bits of the negated integer constant */
2927 if (xc != CONST_INT)
2928 output_operand_lossage ("invalid %H value");
2930 case 'h': /* print the register or low 16 bits of the integer constant */
2933 if (xc != CONST_INT)
2934 output_operand_lossage ("invalid %h value");
2935 fprintf (file, "%d", value & 0xffff);
2938 case 'Q': /* print the low 8 bits of the negated integer constant */
2939 if (xc != CONST_INT)
2940 output_operand_lossage ("invalid %Q value");
2942 case 'q': /* print the register or low 8 bits of the integer constant */
2945 if (xc != CONST_INT)
2946 output_operand_lossage ("invalid %q value");
2947 fprintf (file, "%d", value & 0xff);
2950 case 'w': /* print the integer constant (X == 32 ? 0 : 32 - X) */
2951 if (xc != CONST_INT)
2952 output_operand_lossage ("invalid %o value");
2953 fprintf (file, "%d", value == 32 ? 0 : 32 - value);
2956 case 'p': /* print the logarithm of the integer constant */
2958 || (value = exact_log2 (value)) < 0)
2959 output_operand_lossage ("invalid %p value");
2960 fprintf (file, "%d", value);
2963 case 'S': /* compliment the value and then... */
2965 case 's': /* print the width and offset values forming the integer
2966 constant with a SET instruction. See integer_ok_for_set. */
2968 register unsigned mask, uval = value;
2969 register int top, bottom;
2971 if (xc != CONST_INT)
2972 output_operand_lossage ("invalid %s/S value");
2973 /* All the "one" bits must be contiguous. If so, MASK will be
2974 a power of two or zero. */
2975 mask = (uval | (uval - 1)) + 1;
2976 if (!(uval && POWER_OF_2_or_0 (mask)))
2977 output_operand_lossage ("invalid %s/S value");
2978 top = mask ? exact_log2 (mask) : 32;
2979 bottom = exact_log2 (uval & ~(uval - 1));
2980 fprintf (file,"%d<%d>", top - bottom, bottom);
2984 case 'P': /* print nothing if pc_rtx; output label_ref */
2985 if (xc == LABEL_REF)
2986 output_addr_const (file, x);
2988 output_operand_lossage ("invalid %P operand");
2991 case 'L': /* print 0 or 1 if operand is label_ref and then... */
2992 fputc (xc == LABEL_REF ? '1' : '0', file);
2993 case '.': /* print .n if delay slot is used */
2994 fputs ((final_sequence
2995 && ! INSN_ANNULLED_BRANCH_P (XVECEXP (final_sequence, 0, 0)))
2996 ? ".n\t" : "\t", file);
2999 case '!': /* Reverse the following condition. */
3003 case 'R': /* reverse the condition of the next print_operand
3004 if operand is a label_ref. */
3006 reversep = (xc == LABEL_REF);
3009 case 'B': /* bcnd branch values */
3010 fputs (m88k_pound_sign, file);
3013 case EQ: fputs ("eq0", file); return;
3014 case NE: fputs ("ne0", file); return;
3015 case GT: fputs ("gt0", file); return;
3016 case LE: fputs ("le0", file); return;
3017 case LT: fputs ("lt0", file); return;
3018 case GE: fputs ("ge0", file); return;
3019 default: output_operand_lossage ("invalid %B value");
3022 case 'C': /* bb0/bb1 branch values for comparisons */
3023 fputs (m88k_pound_sign, file);
3026 case EQ: fputs ("eq", file); return;
3027 case NE: fputs ("ne", file); return;
3028 case GT: fputs ("gt", file); return;
3029 case LE: fputs ("le", file); return;
3030 case LT: fputs ("lt", file); return;
3031 case GE: fputs ("ge", file); return;
3032 case GTU: fputs ("hi", file); return;
3033 case LEU: fputs ("ls", file); return;
3034 case LTU: fputs ("lo", file); return;
3035 case GEU: fputs ("hs", file); return;
3036 default: output_operand_lossage ("invalid %C value");
3039 case 'D': /* bcnd branch values for float comparisons */
3042 case EQ: fputs ("0xa", file); return;
3043 case NE: fputs ("0x5", file); return;
3044 case GT: fputs (m88k_pound_sign, file);
3045 fputs ("gt0", file); return;
3046 case LE: fputs ("0xe", file); return;
3047 case LT: fputs ("0x4", file); return;
3048 case GE: fputs ("0xb", file); return;
3049 default: output_operand_lossage ("invalid %D value");
3052 case 'E': /* bcnd branch values for special integers */
3055 case EQ: fputs ("0x8", file); return;
3056 case NE: fputs ("0x7", file); return;
3057 default: output_operand_lossage ("invalid %E value");
3060 case 'd': /* second register of a two register pair */
3062 output_operand_lossage ("`%d' operand isn't a register");
3063 fputs (reg_names[REGNO (x) + 1], file);
3066 case 'r': /* an immediate 0 should be represented as `r0' */
3067 if (x == const0_rtx)
3069 fputs (reg_names[0], file);
3073 output_operand_lossage ("invalid %r value");
3079 if (REGNO (x) == ARG_POINTER_REGNUM)
3080 output_operand_lossage ("operand is r0");
3082 fputs (reg_names[REGNO (x)], file);
3084 else if (xc == PLUS)
3087 output_address (XEXP (x, 0));
3088 else if (flag_pic && xc == UNSPEC)
3090 output_addr_const (file, XVECEXP (x, 0, 0));
3091 fputs ("#got_rel", file);
3093 else if (xc == CONST_DOUBLE)
3094 output_operand_lossage ("operand is const_double");
3096 output_addr_const (file, x);
3099 case 'g': /* append #got_rel as needed */
3100 if (flag_pic && (xc == SYMBOL_REF || xc == LABEL_REF))
3102 output_addr_const (file, x);
3103 fputs ("#got_rel", file);
3108 case 'a': /* (standard), assume operand is an address */
3109 case 'c': /* (standard), assume operand is an immediate value */
3110 case 'l': /* (standard), assume operand is a label_ref */
3111 case 'n': /* (standard), like %c, except negate first */
3113 output_operand_lossage ("invalid code");
3118 print_operand_address (file, addr)
3122 register rtx reg0, reg1, temp;
3124 switch (GET_CODE (addr))
3127 if (REGNO (addr) == ARG_POINTER_REGNUM)
3130 fprintf (file, "%s,%s", reg_names[0], reg_names [REGNO (addr)]);
3134 fprintf (file, "%s,%slo16(",
3135 reg_names[REGNO (XEXP (addr, 0))], m88k_pound_sign);
3136 output_addr_const (file, XEXP (addr, 1));
3141 reg0 = XEXP (addr, 0);
3142 reg1 = XEXP (addr, 1);
3143 if (GET_CODE (reg0) == MULT || GET_CODE (reg0) == CONST_INT)
3150 if ((REG_P (reg0) && REGNO (reg0) == ARG_POINTER_REGNUM)
3151 || (REG_P (reg1) && REGNO (reg1) == ARG_POINTER_REGNUM))
3154 else if (REG_P (reg0))
3157 fprintf (file, "%s,%s",
3158 reg_names [REGNO (reg0)], reg_names [REGNO (reg1)]);
3160 else if (GET_CODE (reg1) == CONST_INT)
3161 fprintf (file, "%s,%d",
3162 reg_names [REGNO (reg0)], INTVAL (reg1));
3164 else if (GET_CODE (reg1) == MULT)
3166 rtx mreg = XEXP (reg1, 0);
3167 if (REGNO (mreg) == ARG_POINTER_REGNUM)
3170 fprintf (file, "%s[%s]", reg_names[REGNO (reg0)],
3171 reg_names[REGNO (mreg)]);
3174 else if (GET_CODE (reg1) == ZERO_EXTRACT)
3176 fprintf (file, "%s,%slo16(",
3177 reg_names[REGNO (reg0)], m88k_pound_sign);
3178 output_addr_const (file, XEXP (reg1, 0));
3184 fprintf (file, "%s,", reg_names[REGNO (reg0)]);
3185 output_addr_const (file, reg1);
3186 fputs ("#got_rel", file);
3196 if (REGNO (XEXP (addr, 0)) == ARG_POINTER_REGNUM)
3199 fprintf (file, "%s[%s]",
3200 reg_names[0], reg_names[REGNO (XEXP (addr, 0))]);
3204 fprintf (file, "%s,%d", reg_names[0], INTVAL (addr));
3208 fprintf (file, "%s,", reg_names[0]);
3209 if (SHORT_ADDRESS_P (addr, temp))
3211 fprintf (file, "%siw16(", m88k_pound_sign);
3212 output_addr_const (file, addr);
3216 output_addr_const (file, addr);
3220 /* Return true if X is an address which needs a temporary register when
3221 reloaded while generating PIC code. */
3224 pic_address_needs_scratch (x)
3227 /* An address which is a symbolic plus a non SMALL_INT needs a temp reg. */
3228 if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS
3229 && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
3230 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
3231 && ! ADD_INT (XEXP (XEXP (x, 0), 1)))
3237 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
3238 reference and a constant. */
3241 symbolic_operand (op, mode)
3243 enum machine_mode mode;
3245 switch (GET_CODE (op))
3253 return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
3254 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
3255 && GET_CODE (XEXP (op, 1)) == CONST_INT);
3257 /* ??? This clause seems to be irrelevant. */
3259 return GET_MODE (op) == mode;