1 /* Subroutines used for code generation on ROMP.
2 Copyright (C) 1990, 91, 92, 93, 97, 98, 1999 Free Software Foundation, Inc.
3 Contributed by Richard Kenner (kenner@nyu.edu)
5 This file is part of GNU CC.
7 GNU CC 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 2, or (at your option)
12 GNU CC 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.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
27 #include "hard-reg-set.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "insn-flags.h"
33 #include "insn-attr.h"
41 #define min(A,B) ((A) < (B) ? (A) : (B))
42 #define max(A,B) ((A) > (B) ? (A) : (B))
44 static int unsigned_comparisons_p ();
45 static void output_loadsave_fpregs ();
46 static void output_fpops ();
47 static void init_fpops ();
49 /* Return 1 if the insn using CC0 set by INSN does not contain
50 any unsigned tests applied to the condition codes.
52 Based on `next_insn_tests_no_inequality' in recog.c. */
55 next_insn_tests_no_unsigned (insn)
58 register rtx next = next_cc0_user (insn);
62 if (find_reg_note (insn, REG_UNUSED, cc0_rtx))
68 return ((GET_CODE (next) == JUMP_INSN
69 || GET_CODE (next) == INSN
70 || GET_CODE (next) == CALL_INSN)
71 && ! unsigned_comparisons_p (PATTERN (next)));
75 unsigned_comparisons_p (x)
78 register const char *fmt;
80 register enum rtx_code code = GET_CODE (x);
98 return (XEXP (x, 0) == cc0_rtx || XEXP (x, 1) == cc0_rtx);
101 len = GET_RTX_LENGTH (code);
102 fmt = GET_RTX_FORMAT (code);
104 for (i = 0; i < len; i++)
108 if (unsigned_comparisons_p (XEXP (x, i)))
111 else if (fmt[i] == 'E')
114 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
115 if (unsigned_comparisons_p (XVECEXP (x, i, j)))
123 /* Update the condition code from the insn. Look mostly at the first
124 byte of the machine-specific insn description information.
126 cc_state.value[12] refer to two possible values that might correspond
127 to the CC. We only store register values. */
129 update_cc (body, insn)
133 switch (get_attr_cc (insn))
136 /* Insn does not affect the CC at all. */
140 /* Insn doesn't affect the CC but does modify operand[0], known to be
142 if (cc_status.value1 != 0
143 && reg_overlap_mentioned_p (recog_operand[0], cc_status.value1))
144 cc_status.value1 = 0;
146 if (cc_status.value2 != 0
147 && reg_overlap_mentioned_p (recog_operand[0], cc_status.value2))
148 cc_status.value2 = 0;
153 /* Insn copies operand[1] to operand[0], both registers, but doesn't
155 if (cc_status.value1 != 0
156 && reg_overlap_mentioned_p (recog_operand[0], cc_status.value1))
157 cc_status.value1 = 0;
159 if (cc_status.value2 != 0
160 && reg_overlap_mentioned_p (recog_operand[0], cc_status.value2))
161 cc_status.value2 = 0;
163 if (cc_status.value1 != 0
164 && rtx_equal_p (cc_status.value1, recog_operand[1]))
165 cc_status.value2 = recog_operand[0];
167 if (cc_status.value2 != 0
168 && rtx_equal_p (cc_status.value2, recog_operand[1]))
169 cc_status.value1 = recog_operand[0];
174 /* Insn clobbers CC. */
179 /* Insn sets CC to recog_operand[0], but overflow is impossible. */
181 cc_status.flags |= CC_NO_OVERFLOW;
182 cc_status.value1 = recog_operand[0];
186 /* Insn is a compare which sets the CC fully. Update CC_STATUS for this
187 compare and mark whether the test will be signed or unsigned. */
189 register rtx p = PATTERN (insn);
193 if (GET_CODE (p) == PARALLEL)
194 p = XVECEXP (p, 0, 0);
195 cc_status.value1 = SET_SRC (p);
197 if (GET_CODE (SET_SRC (p)) == REG)
198 cc_status.flags |= CC_NO_OVERFLOW;
199 if (! next_insn_tests_no_unsigned (insn))
200 cc_status.flags |= CC_UNSIGNED;
205 /* Insn sets T bit if result is non-zero. Next insn must be branch. */
207 cc_status.flags = CC_IN_TB | CC_NOT_NEGATIVE;
215 /* Return 1 if a previous compare needs to be re-issued. This will happen
216 if two compares tested the same objects, but one was signed and the
217 other unsigned. OP is the comparison operation being performed. */
220 restore_compare_p (op)
223 enum rtx_code code = GET_CODE (op);
225 return (((code == GEU || code == LEU || code == GTU || code == LTU)
226 && ! (cc_status.flags & CC_UNSIGNED))
227 || ((code == GE || code == LE || code == GT || code == LT)
228 && (cc_status.flags & CC_UNSIGNED)));
231 /* Generate the (long) string corresponding to an inline multiply insn.
232 Note that `r10' does not refer to the register r10, but rather to the
233 SCR used as the MQ. */
235 output_in_line_mul ()
237 static char insns[200];
240 strcpy (insns, "s %0,%0\n");
241 strcat (insns, "\tmts r10,%1\n");
242 for (i = 0; i < 16; i++)
243 strcat (insns, "\tm %0,%2\n");
244 strcat (insns, "\tmfs r10,%0");
249 /* Returns 1 if OP is a memory reference with an offset from a register within
250 the range specified. The offset must also be a multiple of the size of the
254 memory_offset_in_range_p (op, mode, low, high)
256 enum machine_mode mode;
261 if (! memory_operand (op, mode))
264 while (GET_CODE (op) == SUBREG)
266 offset += SUBREG_WORD (op) * UNITS_PER_WORD;
268 offset -= (min (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (op)))
269 - min (UNITS_PER_WORD,
270 GET_MODE_SIZE (GET_MODE (SUBREG_REG (op)))));
272 op = SUBREG_REG (op);
275 /* We must now have either (mem (reg (x)), (mem (plus (reg (x)) (c))),
276 or a constant pool address. */
277 if (GET_CODE (op) != MEM)
280 /* Now use the actual mode and get the address. */
281 mode = GET_MODE (op);
283 if (GET_CODE (op) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (op))
284 offset = get_pool_offset (op) + 12;
285 else if (GET_CODE (op) == PLUS)
287 if (GET_CODE (XEXP (op, 1)) != CONST_INT
288 || ! register_operand (XEXP (op, 0), Pmode))
291 offset += INTVAL (XEXP (op, 1));
294 else if (! register_operand (op, Pmode))
297 return (offset >= low && offset <= high
298 && (offset % GET_MODE_SIZE (mode) == 0));
301 /* Return 1 if OP is a valid operand for a memory reference insn that can
302 only reference indirect through a register. */
305 zero_memory_operand (op, mode)
307 enum machine_mode mode;
309 return memory_offset_in_range_p (op, mode, 0, 0);
312 /* Return 1 if OP is a valid operand for a `short' memory reference insn. */
315 short_memory_operand (op, mode)
317 enum machine_mode mode;
319 if (mode == VOIDmode)
320 mode = GET_MODE (op);
322 return memory_offset_in_range_p (op, mode, 0,
323 15 * min (UNITS_PER_WORD,
324 GET_MODE_SIZE (mode)));
327 /* Returns 1 if OP is a memory reference involving a symbolic constant
328 that is not in the constant pool. */
331 symbolic_memory_operand (op, mode)
333 enum machine_mode mode;
335 if (! memory_operand (op, mode))
338 while (GET_CODE (op) == SUBREG)
339 op = SUBREG_REG (op);
341 if (GET_CODE (op) != MEM)
345 if (constant_pool_address_operand (op, VOIDmode))
348 return romp_symbolic_operand (op, Pmode)
349 || (GET_CODE (op) == PLUS && register_operand (XEXP (op, 0), Pmode)
350 && romp_symbolic_operand (XEXP (op, 1), Pmode));
354 /* Returns 1 if OP is a constant pool reference to the current function. */
357 current_function_operand (op, mode)
359 enum machine_mode mode;
361 if (GET_CODE (op) != MEM || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
362 || ! CONSTANT_POOL_ADDRESS_P (XEXP (op, 0)))
365 op = get_pool_constant (XEXP (op, 0));
366 return (GET_CODE (op) == SYMBOL_REF
367 && ! strcmp (current_function_name, XSTR (op, 0)));
370 /* Return non-zero if this function is known to have a null epilogue. */
375 return (reload_completed
376 && first_reg_to_save () == 16
377 && ! romp_pushes_stack ());
380 /* Returns 1 if OP is the address of a location in the constant pool. */
383 constant_pool_address_operand (op, mode)
385 enum machine_mode mode;
387 return ((GET_CODE (op) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (op))
388 || (GET_CODE (op) == CONST && GET_CODE (XEXP (op, 0)) == PLUS
389 && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
390 && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
391 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (op, 0), 0))));
394 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
395 reference and a constant. */
398 romp_symbolic_operand (op, mode)
400 enum machine_mode mode;
402 switch (GET_CODE (op))
406 return ! op->integrated;
410 return (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
411 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
412 && GET_CODE (XEXP (op, 1)) == CONST_INT;
419 /* Returns 1 if OP is a valid constant for the ROMP. */
422 constant_operand (op, mode)
424 enum machine_mode mode;
426 switch (GET_CODE (op))
432 return romp_symbolic_operand (op,mode);
435 return (unsigned int) (INTVAL (op) + 0x8000) < 0x10000
436 || (INTVAL (op) & 0xffff) == 0 || (INTVAL (op) & 0xffff0000) == 0;
443 /* Returns 1 if OP is either a constant integer valid for the ROMP or a
444 register. If a register, it must be in the proper mode unless MODE is
448 reg_or_cint_operand (op, mode)
450 enum machine_mode mode;
452 if (GET_CODE (op) == CONST_INT)
453 return constant_operand (op, mode);
455 return register_operand (op, mode);
458 /* Return 1 is the operand is either a register or ANY constant integer. */
461 reg_or_any_cint_operand (op, mode)
463 enum machine_mode mode;
465 return GET_CODE (op) == CONST_INT || register_operand (op, mode);
468 /* Return 1 if the operand is either a register or a valid D-type operand. */
471 reg_or_D_operand (op, mode)
473 enum machine_mode mode;
475 if (GET_CODE (op) == CONST_INT)
476 return (unsigned) (INTVAL (op) + 0x8000) < 0x10000;
478 return register_operand (op, mode);
481 /* Return 1 if the operand is either a register or an item that can be
482 used as the operand of an SI add insn. */
485 reg_or_add_operand (op, mode)
487 enum machine_mode mode;
489 return reg_or_D_operand (op, mode) || romp_symbolic_operand (op, mode)
490 || (GET_CODE (op) == CONST_INT && (INTVAL (op) & 0xffff) == 0);
493 /* Return 1 if the operand is either a register or an item that can be
494 used as the operand of a ROMP logical AND insn. */
497 reg_or_and_operand (op, mode)
499 enum machine_mode mode;
501 if (reg_or_cint_operand (op, mode))
504 if (GET_CODE (op) != CONST_INT)
507 return (INTVAL (op) & 0xffff) == 0xffff
508 || (INTVAL (op) & 0xffff0000) == 0xffff0000;
511 /* Return 1 if the operand is a register or memory operand. */
514 reg_or_mem_operand (op, mode)
516 register enum machine_mode mode;
518 return register_operand (op, mode) || memory_operand (op, mode);
521 /* Return 1 if the operand is either a register or a memory operand that is
525 reg_or_nonsymb_mem_operand (op, mode)
527 enum machine_mode mode;
529 if (register_operand (op, mode))
532 if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode))
538 /* Return 1 if this operand is valid for the ROMP. This is any operand except
539 certain constant integers. */
542 romp_operand (op, mode)
544 enum machine_mode mode;
546 if (GET_CODE (op) == CONST_INT)
547 return constant_operand (op, mode);
549 return general_operand (op, mode);
552 /* Return 1 if the operand is (reg:mode 0). */
555 reg_0_operand (op, mode)
557 enum machine_mode mode;
559 return ((mode == VOIDmode || mode == GET_MODE (op))
560 && GET_CODE (op) == REG && REGNO (op) == 0);
563 /* Return 1 if the operand is (reg:mode 15). */
566 reg_15_operand (op, mode)
568 enum machine_mode mode;
570 return ((mode == VOIDmode || mode == GET_MODE (op))
571 && GET_CODE (op) == REG && REGNO (op) == 15);
574 /* Return 1 if this is a binary floating-point operation. */
577 float_binary (op, mode)
579 enum machine_mode mode;
581 if (mode != VOIDmode && mode != GET_MODE (op))
584 if (GET_MODE (op) != SFmode && GET_MODE (op) != DFmode)
587 switch (GET_CODE (op))
593 return GET_MODE (XEXP (op, 0)) == GET_MODE (op)
594 && GET_MODE (XEXP (op, 1)) == GET_MODE (op);
601 /* Return 1 if this is a unary floating-point operation. */
604 float_unary (op, mode)
606 enum machine_mode mode;
608 if (mode != VOIDmode && mode != GET_MODE (op))
611 if (GET_MODE (op) != SFmode && GET_MODE (op) != DFmode)
614 return (GET_CODE (op) == NEG || GET_CODE (op) == ABS)
615 && GET_MODE (XEXP (op, 0)) == GET_MODE (op);
618 /* Return 1 if this is a valid floating-point conversion that can be done
619 as part of an operation by the RT floating-point routines. */
622 float_conversion (op, mode)
624 enum machine_mode mode;
626 if (mode != VOIDmode && mode != GET_MODE (op))
629 switch (GET_CODE (op))
632 return GET_MODE (op) == SFmode && GET_MODE (XEXP (op, 0)) == DFmode;
635 return GET_MODE (op) == DFmode && GET_MODE (XEXP (op, 0)) == SFmode;
638 return ((GET_MODE (XEXP (op, 0)) == SImode
639 || GET_CODE (XEXP (op, 0)) == CONST_INT)
640 && (GET_MODE (op) == SFmode || GET_MODE (op) == DFmode));
643 return ((GET_MODE (op) == SImode
644 || GET_CODE (XEXP (op, 0)) == CONST_INT)
645 && (GET_MODE (XEXP (op, 0)) == SFmode
646 || GET_MODE (XEXP (op, 0)) == DFmode));
653 /* Print an operand. Recognize special options, documented below. */
656 print_operand (file, x, code)
666 /* Byte number (const/8) */
667 if (GET_CODE (x) != CONST_INT)
668 output_operand_lossage ("invalid %%B value");
670 fprintf (file, "%d", INTVAL (x) / 8);
674 /* Low order 16 bits of constant. */
675 if (GET_CODE (x) != CONST_INT)
676 output_operand_lossage ("invalid %%L value");
678 fprintf (file, "%d", INTVAL (x) & 0xffff);
682 /* Null or "16" depending on whether the constant is greater than 16. */
683 if (GET_CODE (x) != CONST_INT)
684 output_operand_lossage ("invalid %%s value");
686 if (INTVAL (x) >= 16)
687 fprintf (file, "16");
692 /* For shifts: 's' will have given the half. Just give the amount
694 if (GET_CODE (x) != CONST_INT)
695 output_operand_lossage ("invalid %%S value");
697 fprintf (file, "%d", INTVAL (x) & 15);
701 /* The number of a single bit set or cleared, mod 16. Note that the ROMP
702 numbers bits with the high-order bit 31. */
703 if (GET_CODE (x) != CONST_INT)
704 output_operand_lossage ("invalid %%b value");
706 if ((i = exact_log2 (INTVAL (x))) >= 0)
707 fprintf (file, "%d", (31 - i) % 16);
708 else if ((i = exact_log2 (~ INTVAL (x))) >= 0)
709 fprintf (file, "%d", (31 - i) % 16);
711 output_operand_lossage ("invalid %%b value");
716 /* "l" or "u" depending on which half of the constant is zero. */
717 if (GET_CODE (x) != CONST_INT)
718 output_operand_lossage ("invalid %%h value");
720 if ((INTVAL (x) & 0xffff0000) == 0)
722 else if ((INTVAL (x) & 0xffff) == 0)
725 output_operand_lossage ("invalid %%h value");
730 /* Upper or lower half, depending on which half is zero. */
731 if (GET_CODE (x) != CONST_INT)
732 output_operand_lossage ("invalid %%H value");
734 if ((INTVAL (x) & 0xffff0000) == 0)
735 fprintf (file, "%d", INTVAL (x) & 0xffff);
736 else if ((INTVAL (x) & 0xffff) == 0)
737 fprintf (file, "%d", (INTVAL (x) >> 16) & 0xffff);
739 output_operand_lossage ("invalid %%H value");
744 /* Write two characters:
745 'lo' if the high order part is all ones
746 'lz' if the high order part is all zeros
747 'uo' if the low order part is all ones
748 'uz' if the low order part is all zeros
750 if (GET_CODE (x) != CONST_INT)
751 output_operand_lossage ("invalid %%z value");
753 if ((INTVAL (x) & 0xffff0000) == 0)
754 fprintf (file, "lz");
755 else if ((INTVAL (x) & 0xffff0000) == 0xffff0000)
756 fprintf (file, "lo");
757 else if ((INTVAL (x) & 0xffff) == 0)
758 fprintf (file, "uz");
759 else if ((INTVAL (x) & 0xffff) == 0xffff)
760 fprintf (file, "uo");
762 output_operand_lossage ("invalid %%z value");
767 /* Upper or lower half, depending on which is non-zero or not
768 all ones. Must be consistent with 'z' above. */
769 if (GET_CODE (x) != CONST_INT)
770 output_operand_lossage ("invalid %%Z value");
772 if ((INTVAL (x) & 0xffff0000) == 0
773 || (INTVAL (x) & 0xffff0000) == 0xffff0000)
774 fprintf (file, "%d", INTVAL (x) & 0xffff);
775 else if ((INTVAL (x) & 0xffff) == 0 || (INTVAL (x) & 0xffff) == 0xffff)
776 fprintf (file, "%d", (INTVAL (x) >> 16) & 0xffff);
778 output_operand_lossage ("invalid %%Z value");
783 /* Same as 'z', except the trailing 'o' or 'z' is not written. */
784 if (GET_CODE (x) != CONST_INT)
785 output_operand_lossage ("invalid %%k value");
787 if ((INTVAL (x) & 0xffff0000) == 0
788 || (INTVAL (x) & 0xffff0000) == 0xffff0000)
790 else if ((INTVAL (x) & 0xffff) == 0
791 || (INTVAL (x) & 0xffff) == 0xffff)
794 output_operand_lossage ("invalid %%k value");
799 /* Similar to 's', except that we write 'h' or 'u'. */
800 if (GET_CODE (x) != CONST_INT)
801 output_operand_lossage ("invalid %%k value");
810 /* For memory operations, write 's' if the operand is a short
812 if (short_memory_operand (x, VOIDmode))
817 /* Like 'M', but check for zero memory offset. */
818 if (zero_memory_operand (x, VOIDmode))
823 /* Write low-order part of DImode or DFmode. Supported for MEM
825 if (GET_CODE (x) == REG)
826 fprintf (file, "%s", reg_names[REGNO (x) + 1]);
827 else if (GET_CODE (x) == MEM)
828 print_operand (file, gen_rtx_MEM (GET_MODE (x),
829 plus_constant (XEXP (x, 0), 4)), 0);
835 /* Offset in constant pool for constant pool address. */
836 if (! constant_pool_address_operand (x, VOIDmode))
838 if (GET_CODE (x) == SYMBOL_REF)
839 fprintf (file, "%d", get_pool_offset (x) + 12);
841 /* Must be (const (plus (symbol_ref) (const_int))) */
843 (get_pool_offset (XEXP (XEXP (x, 0), 0)) + 12
844 + INTVAL (XEXP (XEXP (x, 0), 1))));
848 /* Branch opcode. Check for condition in test bit for eq/ne. */
849 switch (GET_CODE (x))
852 if (cc_status.flags & CC_IN_TB)
853 fprintf (file, "ntb");
855 fprintf (file, "eq");
859 if (cc_status.flags & CC_IN_TB)
860 fprintf (file, "tb");
862 fprintf (file, "ne");
877 fprintf (file, "he");
882 fprintf (file, "le");
886 output_operand_lossage ("invalid %%j value");
891 /* Reversed branch opcode. */
892 switch (GET_CODE (x))
895 if (cc_status.flags & CC_IN_TB)
896 fprintf (file, "tb");
898 fprintf (file, "ne");
902 if (cc_status.flags & CC_IN_TB)
903 fprintf (file, "ntb");
905 fprintf (file, "eq");
910 fprintf (file, "le");
915 fprintf (file, "he");
929 output_operand_lossage ("invalid %%j value");
934 /* Output nothing. Used as delimiter in, e.g., "mc%B1%.3 " */
938 /* Output 'x' if this insn has a delay slot, else nothing. */
939 if (dbr_sequence_length ())
944 if (GET_CODE (x) == REG)
945 fprintf (file, "%s", reg_names[REGNO (x)]);
946 else if (GET_CODE (x) == MEM)
948 if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
949 && current_function_operand (x, Pmode))
950 fprintf (file, "r14");
952 output_address (XEXP (x, 0));
955 output_addr_const (file, x);
959 output_operand_lossage ("invalid %%xn code");
963 /* This page contains routines that are used to determine what the function
964 prologue and epilogue code will do and write them out. */
966 /* Return the first register that is required to be saved. 16 if none. */
973 /* Find lowest numbered live register. */
974 for (first_reg = 6; first_reg <= 15; first_reg++)
975 if (regs_ever_live[first_reg])
978 /* If we think that we do not have to save r14, see if it will be used
980 if (first_reg > 14 && romp_using_r14 ())
986 /* Compute the size of the save area in the stack, including the space for
987 the first four incoming arguments. */
995 /* We have the 4 words corresponding to the arguments passed in registers,
996 4 reserved words, space for static chain, general register save area,
997 and floating-point save area. */
998 size = 4 + 4 + 1 + (16 - first_reg_to_save ());
1000 /* The documentation says we have to leave 18 words in the save area if
1001 any floating-point registers at all are saved, not the three words
1002 per register you might otherwise expect. */
1003 for (i = 2 + (TARGET_FP_REGS != 0); i <= 7; i++)
1004 if (regs_ever_live[i + 17])
1013 /* Return non-zero if this function makes calls or has fp operations
1014 (which are really calls). */
1021 for (insn = get_insns (); insn; insn = next_insn (insn))
1023 if (GET_CODE (insn) == CALL_INSN)
1025 else if (GET_CODE (insn) == INSN)
1027 rtx body = PATTERN (insn);
1029 if (GET_CODE (body) != USE && GET_CODE (body) != CLOBBER
1030 && GET_CODE (body) != ADDR_VEC
1031 && GET_CODE (body) != ADDR_DIFF_VEC
1032 && get_attr_type (insn) == TYPE_FP)
1040 /* Return non-zero if this function will use r14 as a pointer to its
1046 /* If we are debugging, profiling, have a non-empty constant pool, or
1047 call a function, we need r14. */
1048 return (write_symbols != NO_DEBUG || profile_flag || get_pool_size () != 0
1049 || romp_makes_calls ());
1052 /* Return non-zero if this function needs to push space on the stack. */
1055 romp_pushes_stack ()
1057 /* We need to push the stack if a frame pointer is needed (because the
1058 stack might be dynamically adjusted), if we are debugging, if the
1059 total required size is more than 100 bytes, or if we make calls. */
1061 return (frame_pointer_needed || write_symbols != NO_DEBUG
1062 || (romp_sa_size () + get_frame_size ()) > 100
1063 || romp_makes_calls ());
1066 /* Write function prologue.
1068 We compute the size of the fixed area required as follows:
1070 We always allocate 4 words for incoming arguments, 4 word reserved, 1
1071 word for static link, as many words as required for general register
1072 save area, plus 2 words for each FP reg 2-7 that must be saved. */
1075 output_prolog (file, size)
1080 int reg_save_offset;
1081 int fp_save = size + current_function_outgoing_args_size;
1085 /* Add in fixed size plus output argument area. */
1086 size += romp_sa_size () + current_function_outgoing_args_size;
1088 /* Compute first register to save and perform the save operation if anything
1089 needs to be saved. */
1090 first_reg = first_reg_to_save();
1091 reg_save_offset = - (4 + 4 + 1 + (16 - first_reg)) * 4;
1092 if (first_reg == 15)
1093 fprintf (file, "\tst r15,%d(r1)\n", reg_save_offset);
1094 else if (first_reg < 16)
1095 fprintf (file, "\tstm r%d,%d(r1)\n", first_reg, reg_save_offset);
1097 /* Set up pointer to data area if it is needed. */
1098 if (romp_using_r14 ())
1099 fprintf (file, "\tcas r14,r0,r0\n");
1101 /* Set up frame pointer if needed. */
1102 if (frame_pointer_needed)
1103 fprintf (file, "\tcal r13,-%d(r1)\n", romp_sa_size () + 64);
1105 /* Push stack if neeeded. There are a couple of ways of doing this. */
1106 if (romp_pushes_stack ())
1112 fprintf (file, "\tcau r0,%d(r0)\n", size >> 16);
1113 fprintf (file, "\toil r0,r0,%d\n", size & 0xffff);
1116 fprintf (file, "\tcal16 r0,%d(r0)\n", size);
1117 fprintf (file, "\ts r1,r0\n");
1120 fprintf (file, "\tcal r1,-%d(r1)\n", size);
1123 /* Save floating-point registers. */
1124 output_loadsave_fpregs (file, USE,
1125 plus_constant (stack_pointer_rtx, fp_save));
1128 /* Output the offset information used by debuggers.
1129 This is the exactly the total_size value of output_epilog
1130 which is added to the frame pointer. However the value in the debug
1131 table is encoded in a space-saving way as follows:
1133 The first byte contains two fields: a 2-bit size field and the first
1134 6 bits of an offset value. The 2-bit size field is in the high-order
1135 position and specifies how many subsequent bytes follow after
1136 this one. An offset value is at most 4-bytes long.
1138 The last 6 bits of the first byte initialize the offset value. In many
1139 cases where procedures have small local storage, this is enough and, in
1140 this case, the high-order size field is zero so the byte can (almost) be
1141 used as is (see below). Thus, the byte value of 0x0d is encodes a offset
1142 size of 13 words, or 52 bytes.
1144 For procedures with a local space larger than 60 bytes, the 6 bits
1145 are the high-order 6 bits. The remaining bytes follow as necessary,
1146 in Big Endian order. Thus, the short value of 16907 (= 16384+523)
1147 encodes an offset of 2092 bytes (523 words).
1149 The total offset value is in words (not bytes), so the final value has to
1150 be multiplied by 4 before it can be used in address computations by a
1154 output_encoded_offset (file, reg_offset)
1156 unsigned reg_offset;
1158 /* Convert the offset value to 4-byte words rather than bytes. */
1159 reg_offset = (reg_offset + 3) / 4;
1161 /* Now output 1-4 bytes in encoded form. */
1162 if (reg_offset < (1 << 6))
1163 /* Fits into one byte */
1164 fprintf (file, "\t.byte %d\n", reg_offset);
1165 else if (reg_offset < (1 << (6 + 8)))
1166 /* Fits into two bytes */
1167 fprintf (file, "\t.short %d\n", (1 << (6 + 8)) + reg_offset);
1168 else if (reg_offset < (1 << (6 + 8 + 8)))
1170 /* Fits in three bytes */
1171 fprintf (file, "\t.byte %d\n", (2 << 6) + (reg_offset >> ( 6+ 8)));
1172 fprintf (file, "\t.short %d\n", reg_offset % (1 << (6 + 8)));
1177 fprintf (file, "\t.short %d", (3 << (6 + 8)) + (reg_offset >> (6 + 8)));
1178 fprintf (file, "\t.short %d\n", reg_offset % (1 << (6 + 8)));
1182 /* Write function epilogue. */
1185 output_epilog (file, size)
1189 int first_reg = first_reg_to_save();
1190 int pushes_stack = romp_pushes_stack ();
1191 int reg_save_offset = - ((16 - first_reg) + 1 + 4 + 4) * 4;
1192 int total_size = (size + romp_sa_size ()
1193 + current_function_outgoing_args_size);
1194 int fp_save = size + current_function_outgoing_args_size;
1195 int long_frame = total_size >= 32768;
1196 rtx insn = get_last_insn ();
1199 int nargs = 0; /* words of arguments */
1202 /* Compute the number of words of arguments. Since this is just for
1203 the traceback table, we ignore arguments that don't have a size or
1204 don't have a fixed size. */
1206 for (argptr = DECL_ARGUMENTS (current_function_decl);
1207 argptr; argptr = TREE_CHAIN (argptr))
1209 int this_size = int_size_in_bytes (TREE_TYPE (argptr));
1212 nargs += (this_size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
1215 /* If the last insn was a BARRIER, we don't have to write anything except
1217 if (GET_CODE (insn) == NOTE)
1218 insn = prev_nonnote_insn (insn);
1219 if (insn && GET_CODE (insn) == BARRIER)
1222 /* Restore floating-point registers. */
1224 output_loadsave_fpregs (file, CLOBBER,
1225 plus_constant (gen_rtx_REG (Pmode, 1), fp_save));
1227 /* If we push the stack and do not have size > 32K, adjust the register
1228 save location to the current position of sp. Otherwise, if long frame,
1229 restore sp from fp. */
1230 if (pushes_stack && ! long_frame)
1231 reg_save_offset += total_size;
1232 else if (long_frame && write_code)
1233 fprintf (file, "\tcal r1,%d(r13)\n", romp_sa_size () + 64);
1235 /* Restore registers. */
1236 if (first_reg == 15 && write_code)
1237 fprintf (file, "\tl r15,%d(r1)\n", reg_save_offset);
1238 else if (first_reg < 16 && write_code)
1239 fprintf (file, "\tlm r%d,%d(r1)\n", first_reg, reg_save_offset);
1240 if (first_reg == 16) first_reg = 0;
1242 /* Handle popping stack, if needed and write debug table entry. */
1248 fprintf (file, "\tbr r15\n");
1250 fprintf (file, "\tbrx r15\n\tcal r1,%d(r1)\n", total_size);
1253 /* Table header (0xdf), usual-type stack frame (0x07),
1254 table header (0xdf), and first register saved.
1256 The final 0x08 means that there is a byte following this one
1257 describing the number of parameter words and the register used as
1260 If GCC passed floating-point parameters in floating-point registers,
1261 it would be necessary to change the final byte from 0x08 to 0x0c.
1262 Also an additional entry byte would be need to be emitted to specify
1263 the first floating-point register.
1265 (See also Section 11 (Trace Tables) in ``IBM/4.3 Linkage Convention,''
1266 pages IBM/4.3-PSD:5-7 of Volume III of the IBM Academic Operating
1267 System Manual dated July 1987.) */
1269 fprintf (file, "\t.long 0x%x\n", 0xdf07df08 + first_reg * 0x10);
1271 if (nargs > 15) nargs = 15;
1273 /* The number of parameter words and the register used as the stack
1274 pointer (encoded here as r1).
1276 Note: The MetWare Hich C Compiler R2.1y actually gets this wrong;
1277 it erroneously lists r13 but uses r1 as the stack too. But a bug in
1278 dbx 1.5 nullifies this mistake---most of the time.
1279 (Dbx retrieves the value of r13 saved on the stack which is often
1280 the value of r1 before the call.) */
1282 fprintf (file, "\t.byte 0x%x1\n", nargs);
1283 output_encoded_offset (file, total_size);
1288 fprintf (file, "\tbr r15\n");
1290 /* Table header (0xdf), no stack frame (0x02),
1291 table header (0xdf) and no parameters saved (0x00).
1293 If GCC passed floating-point parameters in floating-point registers,
1294 it might be necessary to change the final byte from 0x00 to 0x04.
1295 Also a byte would be needed to specify the first floating-point
1297 fprintf (file, "\t.long 0xdf02df00\n");
1300 /* Output any pending floating-point operations. */
1301 output_fpops (file);
1304 /* For the ROMP we need to make new SYMBOL_REFs for the actual name of a
1305 called routine. To keep them unique we maintain a hash table of all
1306 that have been created so far. */
1308 struct symref_hashent {
1309 rtx symref; /* Created SYMBOL_REF rtx. */
1310 struct symref_hashent *next; /* Next with same hash code. */
1313 #define SYMHASHSIZE 151
1314 #define HASHBITS 65535
1316 /* Define the hash table itself. */
1318 static struct symref_hashent *symref_hash_table[SYMHASHSIZE];
1320 /* Given a name (allocable in temporary storage), return a SYMBOL_REF
1321 for the name. The rtx is allocated from the current rtl_obstack, while
1322 the name string is allocated from the permanent obstack. */
1325 register char *name;
1327 extern struct obstack permanent_obstack;
1328 register char *sp = name;
1329 unsigned int hash = 0;
1330 struct symref_hashent *p, **last_p;
1332 /* Compute the hash code for the string. */
1334 hash = (hash << 4) + *sp++;
1336 /* Search for a matching entry in the hash table, keeping track of the
1337 insertion location as we do so. */
1338 hash = (hash & HASHBITS) % SYMHASHSIZE;
1339 for (last_p = &symref_hash_table[hash], p = *last_p;
1340 p; last_p = &p->next, p = *last_p)
1341 if (strcmp (name, XSTR (p->symref, 0)) == 0)
1344 /* If couldn't find matching SYMBOL_REF, make a new one. */
1347 /* Ensure SYMBOL_REF will stay around. */
1348 end_temporary_allocation ();
1349 p = *last_p = (struct symref_hashent *)
1350 permalloc (sizeof (struct symref_hashent));
1351 p->symref = gen_rtx_SYMBOL_REF (Pmode,
1352 obstack_copy0 (&permanent_obstack,
1353 name, strlen (name)));
1355 resume_temporary_allocation ();
1361 /* Validate the precision of a floating-point operation.
1363 We merge conversions from integers and between floating-point modes into
1364 the insn. However, this must not effect the desired precision of the
1365 insn. The RT floating-point system uses the widest of the operand modes.
1366 If this should be a double-precision insn, ensure that one operand
1367 passed to the floating-point processor has double mode.
1369 Note that since we don't check anything if the mode is single precision,
1370 it, strictly speaking, isn't necessary to call this for those insns.
1371 However, we do so in case something else needs to be checked in the
1374 This routine returns 1 if the operation is OK. */
1377 check_precision (opmode, op1, op2)
1378 enum machine_mode opmode;
1381 if (opmode == SFmode)
1384 /* If operand is not a conversion from an integer mode or an extension from
1385 single-precision, it must be a double-precision value. */
1386 if (GET_CODE (op1) != FLOAT && GET_CODE (op1) != FLOAT_EXTEND)
1389 if (op2 && GET_CODE (op2) != FLOAT && GET_CODE (op2) != FLOAT_EXTEND)
1395 /* Floating-point on the RT is done by creating an operation block in the data
1396 area that describes the operation. If two floating-point operations are the
1397 same in a single function, they can use the same block.
1399 These routines are responsible for managing these blocks. */
1401 /* Structure to describe a floating-point operation. */
1404 struct fp_op *next_same_hash; /* Next op with same hash code. */
1405 struct fp_op *next_in_mem; /* Next op in memory. */
1406 int mem_offset; /* Offset from data area. */
1407 short size; /* Size of block in bytes. */
1408 short noperands; /* Number of operands in block. */
1409 rtx ops[3]; /* RTL for operands. */
1410 enum rtx_code opcode; /* Operation being performed. */
1413 /* Size of hash table. */
1414 #define FP_HASH_SIZE 101
1416 /* Hash table of floating-point operation blocks. */
1417 static struct fp_op *fp_hash_table[FP_HASH_SIZE];
1419 /* First floating-point block in data area. */
1420 static struct fp_op *first_fpop;
1422 /* Last block in data area so far. */
1423 static struct fp_op *last_fpop_in_mem;
1425 /* Subroutine number in file, to get unique "LF" labels. */
1426 static int subr_number = 0;
1428 /* Current word offset in data area (includes header and any constant pool). */
1431 /* Compute hash code for an RTX used in floating-point. */
1437 register unsigned int hash = (((int) GET_CODE (x) << 10)
1438 + ((int) GET_MODE (x) << 20));
1440 register const char *fmt = GET_RTX_FORMAT (GET_CODE (x));
1442 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (x)); i++)
1444 hash += hash_rtx (XEXP (x, i));
1445 else if (fmt[i] == 'u')
1446 hash += (unsigned HOST_WIDE_INT) XEXP (x, i);
1447 else if (fmt[i] == 'i')
1448 hash += XINT (x, i);
1449 else if (fmt[i] == 's')
1450 hash += (unsigned HOST_WIDE_INT) XSTR (x, i);
1455 /* Given an operation code and up to three operands, return a character string
1456 corresponding to the code to emit to branch to a floating-point operation
1457 block. INSN is provided to see if the delay slot has been filled or not.
1459 A new floating-point operation block is created if this operation has not
1460 been seen before. */
1463 output_fpop (code, op0, op1, op2, insn)
1468 static char outbuf[40];
1469 unsigned int hash, hash0, hash1, hash2;
1471 register struct fp_op *fpop, *last_fpop;
1472 int dyadic = (op2 != 0);
1473 enum machine_mode opmode;
1476 unsigned int tem_hash;
1479 /* Compute hash code for each operand. If the operation is commutative,
1480 put the one with the smaller hash code first. This will make us see
1481 more operations as identical. */
1482 hash0 = op0 ? hash_rtx (op0) : 0;
1483 hash1 = op1 ? hash_rtx (op1) : 0;
1484 hash2 = op2 ? hash_rtx (op2) : 0;
1486 if (hash0 > hash1 && code == EQ)
1488 tem = op0; op0 = op1; op1 = tem;
1489 tem_hash = hash0; hash0 = hash1; hash1 = tem_hash;
1491 else if (hash1 > hash2 && (code == PLUS || code == MULT))
1493 tem = op1; op1 = op2; op2 = tem;
1494 tem_hash = hash1; hash1 = hash2; hash2 = tem_hash;
1497 /* If operation is commutative and the first and third operands are equal,
1498 swap the second and third operands. Note that we must consider two
1499 operands equal if they are the same register even if different modes. */
1500 if (op2 && (code == PLUS || code == MULT)
1501 && (rtx_equal_p (op0, op2)
1502 || (GET_CODE (op0) == REG && GET_CODE (op2) == REG
1503 && REGNO (op0) == REGNO (op2))))
1505 tem = op1; op1 = op2; op2 = tem;
1506 tem_hash = hash1; hash1 = hash2; hash2 = tem_hash;
1509 /* If the first and second operands are the same, merge them. Don't do this
1510 for SFmode or SImode in general registers because this triggers a bug in
1512 if (op1 && rtx_equal_p (op0, op1)
1513 && code != EQ && code != GE && code != SET
1514 && ((GET_MODE (op1) != SFmode && GET_MODE (op1) != SImode)
1515 || GET_CODE (op0) != REG || FP_REGNO_P (REGNO (op0))))
1521 noperands = 1 + (op1 != 0) + (op2 != 0);
1523 /* Compute hash code for entire expression and see if operation block
1525 hash = ((int) code << 13) + (hash0 << 2) + (hash1 << 1) + hash2;
1527 hash %= FP_HASH_SIZE;
1528 for (fpop = fp_hash_table[hash], last_fpop = 0;
1530 last_fpop = fpop, fpop = fpop->next_same_hash)
1531 if (fpop->opcode == code && noperands == fpop->noperands
1532 && (op0 == 0 || rtx_equal_p (op0, fpop->ops[0]))
1533 && (op1 == 0 || rtx_equal_p (op1, fpop->ops[1]))
1534 && (op2 == 0 || rtx_equal_p (op2, fpop->ops[2])))
1537 /* We have never seen this operation before. */
1538 fpop = (struct fp_op *) oballoc (sizeof (struct fp_op));
1539 fpop->mem_offset = data_offset;
1540 fpop->opcode = code;
1541 fpop->noperands = noperands;
1546 /* Compute the size using the rules in Appendix A of the RT Linkage
1547 Convention (4.3/RT-PSD:5) manual. These rules are a bit ambiguous,
1548 but if we guess wrong, it will effect only efficiency, not correctness. */
1550 /* Size = 24 + 32 for each non-fp (or fr7) */
1552 if (op0 && (GET_CODE (op0) != REG
1553 || ! FP_REGNO_P (REGNO (op0)) || REGNO (op0) == 23))
1556 if (op1 && (GET_CODE (op1) != REG
1557 || ! FP_REGNO_P (REGNO (op1)) || REGNO (op1) == 23))
1560 if (op2 && (GET_CODE (op2) != REG
1561 || ! FP_REGNO_P (REGNO (op2)) || REGNO (op2) == 23))
1564 /* Size + 12 for each conversion. First get operation mode. */
1565 if ((op0 && GET_MODE (op0) == DFmode)
1566 || (op1 && GET_MODE (op1) == DFmode)
1567 || (op2 && GET_MODE (op2) == DFmode))
1572 if (op0 && GET_MODE (op0) != opmode)
1574 if (op1 && GET_MODE (op1) != opmode)
1576 if (op2 && GET_MODE (op2) != opmode)
1579 /* 12 more if first and third operand types not the same. */
1580 if (op2 && GET_MODE (op0) != GET_MODE (op2))
1583 /* CMP and CMPT need additional. Also, compute size of save/restore here. */
1586 else if (code == GE)
1588 else if (code == USE || code == CLOBBER)
1590 /* 34 + 24 for each additional register plus 8 if fr7 saved. (We
1591 call it 36 because we need to keep the block length a multiple
1594 for (i = 0; i <= 7; i++)
1595 if (INTVAL (op0) & (1 << (7-i)))
1596 size += 24 + 8 * (i == 7);
1599 /* We provide no general-purpose scratch registers. */
1602 /* No floating-point scratch registers are provided. Compute extra
1603 length due to this. This logic is that shown in the referenced
1607 if (op0 && GET_CODE (op0) == REG && FP_REGNO_P (REGNO (op0)))
1609 if (op1 && GET_CODE (op1) == REG && FP_REGNO_P (REGNO (op1)))
1611 if (op2 && GET_CODE (op2) == REG && FP_REGNO_P (REGNO (op2)))
1614 if ((op0 == 0 || GET_CODE (op0) != REG || REGNO(op0) != 17)
1615 && (op1 == 0 || GET_CODE (op1) != REG || REGNO(op1) != 17)
1616 && (op2 == 0 || GET_CODE (op2) != REG || REGNO(op2) != 17))
1622 size += fr0_avail ? 64 : 112;
1623 else if (fpop->noperands == 2 && i == 1)
1624 size += fr0_avail ? 0 : 64;
1625 else if (fpop->noperands == 3)
1627 if (GET_CODE (op0) == REG && FP_REGNO_P (REGNO (op0))
1628 && GET_CODE (op2) == REG && FP_REGNO_P (REGNO (op2)))
1630 if (REGNO (op0) == REGNO (op2))
1632 /* This triggers a bug on the RT. */
1635 size += fr0_avail ? 0 : 64;
1641 if (GET_CODE (op0) == REG && FP_REGNO_P (REGNO (op0)))
1643 if (GET_CODE (op2) == REG && FP_REGNO_P (REGNO (op2)))
1646 size += fr0_avail ? 64 : 112;
1648 size += fr0_avail ? 0 : 64;
1652 else if (code != USE && code != CLOBBER
1653 && (GET_CODE (op0) != REG || ! FP_REGNO_P (REGNO (op0))))
1656 if (! TARGET_FULL_FP_BLOCKS)
1658 /* If we are not to pad the blocks, just compute its actual length. */
1659 size = 12; /* Header + opcode */
1660 if (code == USE || code == CLOBBER)
1669 /* If in the middle of a word, round. */
1670 if (size % UNITS_PER_WORD)
1673 /* Handle any immediates. */
1674 if (code != USE && code != CLOBBER && op0 && GET_CODE (op0) != REG)
1676 if (op1 && GET_CODE (op1) != REG)
1678 if (op2 && GET_CODE (op2) != REG)
1681 if (code != USE && code != CLOBBER &&
1682 op0 && GET_CODE (op0) == CONST_DOUBLE && GET_MODE (op0) == DFmode)
1684 if (op1 && GET_CODE (op1) == CONST_DOUBLE && GET_MODE (op1) == DFmode)
1686 if (op2 && GET_CODE (op2) == CONST_DOUBLE && GET_MODE (op2) == DFmode)
1690 /* Done with size computation! Chain this in. */
1692 data_offset += size / UNITS_PER_WORD;
1693 fpop->next_in_mem = 0;
1694 fpop->next_same_hash = 0;
1696 if (last_fpop_in_mem)
1697 last_fpop_in_mem->next_in_mem = fpop;
1700 last_fpop_in_mem = fpop;
1703 last_fpop->next_same_hash = fpop;
1705 fp_hash_table[hash] = fpop;
1708 /* FPOP describes the operation to be performed. Return a string to branch
1710 if (fpop->mem_offset < 32768 / UNITS_PER_WORD)
1711 sprintf (outbuf, "cal r15,%d(r14)\n\tbalr%s r15,r15",
1712 fpop->mem_offset * UNITS_PER_WORD,
1713 dbr_sequence_length () ? "x" : "");
1715 sprintf (outbuf, "get r15,$L%dF%d\n\tbalr%s r15,r15",
1716 subr_number, fpop->mem_offset * UNITS_PER_WORD,
1717 dbr_sequence_length () ? "x" : "");
1721 /* If necessary, output a floating-point operation to save or restore all
1722 floating-point registers.
1724 file is the file to write the operation to, CODE is USE for save, CLOBBER
1725 for restore, and ADDR is the address of the same area, as RTL. */
1728 output_loadsave_fpregs (file, code, addr)
1734 register int mask = 0;
1736 for (i = 2 + (TARGET_FP_REGS != 0); i <= 7; i++)
1737 if (regs_ever_live[i + 17])
1738 mask |= 1 << (7 - i);
1741 fprintf (file, "\t%s\n",
1742 output_fpop (code, GEN_INT (mask), gen_rtx_MEM (Pmode, addr),
1747 /* Output any floating-point operations at the end of the routine. */
1753 register struct fp_op *fpop;
1754 register int size_so_far;
1758 if (first_fpop == 0)
1763 ASM_OUTPUT_ALIGN (file, 2);
1765 for (fpop = first_fpop; fpop; fpop = fpop->next_in_mem)
1767 if (fpop->mem_offset < 32768 / UNITS_PER_WORD)
1768 fprintf (file, "# data area offset = %d\n",
1769 fpop->mem_offset * UNITS_PER_WORD);
1771 fprintf (file, "L%dF%d:\n",
1772 subr_number, fpop->mem_offset * UNITS_PER_WORD);
1774 fprintf (file, "\tcas r0,r15,r0\n");
1775 fprintf (file, "\t.long FPGLUE\n");
1776 switch (fpop->opcode)
1779 fprintf (file, "\t.byte 0x1d\t# STOREM\n");
1782 fprintf (file, "\t.byte 0x0f\t# LOADM\n");
1785 fprintf (file, "\t.byte 0x00\t# ABS\n");
1788 fprintf (file, "\t.byte 0x02\t# ADD\n");
1791 fprintf (file, "\t.byte 0x07\t# CMP\n");
1794 fprintf (file, "\t.byte 0x08\t# CMPT\n");
1797 fprintf (file, "\t.byte 0x0c\t# DIV\n");
1800 fprintf (file, "\t.byte 0x14\t# MOVE\n");
1803 fprintf (file, "\t.byte 0x15\t# MUL\n");
1806 fprintf (file, "\t.byte 0x16\t# NEG\n");
1809 fprintf (file, "\t.byte 0x1c\t# SQRT\n");
1812 fprintf (file, "\t.byte 0x1e\t# SUB\n");
1818 fprintf (file, "\t.byte %d\n", fpop->noperands);
1819 fprintf (file, "\t.short 0x8001\n");
1821 if ((fpop->ops[0] == 0
1822 || GET_CODE (fpop->ops[0]) != REG || REGNO(fpop->ops[0]) != 17)
1823 && (fpop->ops[1] == 0 || GET_CODE (fpop->ops[1]) != REG
1824 || REGNO(fpop->ops[1]) != 17)
1825 && (fpop->ops[2] == 0 || GET_CODE (fpop->ops[2]) != REG
1826 || REGNO(fpop->ops[2]) != 17))
1827 fprintf (file, "\t.byte %d, 0x80\n", fpop->size);
1829 fprintf (file, "\t.byte %d, 0\n", fpop->size);
1831 for (i = 0; i < fpop->noperands; i++)
1834 register int opbyte;
1835 register char *desc0;
1839 switch (GET_MODE (fpop->ops[i]))
1858 switch (GET_CODE (fpop->ops[i]))
1861 strcpy(desc1, reg_names[REGNO (fpop->ops[i])]);
1862 if (FP_REGNO_P (REGNO (fpop->ops[i])))
1865 opbyte = REGNO (fpop->ops[i]) - 17;
1870 opbyte = REGNO (fpop->ops[i]);
1872 opbyte = (opbyte << 4) + opbyte + 1;
1878 if (GET_CODE (XEXP (fpop->ops[i], 0)) == PLUS)
1880 immed[i] = XEXP (XEXP (fpop->ops[i], 0), 1);
1881 opbyte = REGNO (XEXP (XEXP (fpop->ops[i], 0), 0));
1882 if (GET_CODE (immed[i]) == CONST_INT)
1883 sprintf (desc1, "%d(%s)", INTVAL (immed[i]),
1886 sprintf (desc1, "<memory> (%s)", reg_names[opbyte]);
1888 else if (GET_CODE (XEXP (fpop->ops[i], 0)) == REG)
1890 opbyte = REGNO (XEXP (fpop->ops[i], 0));
1891 immed[i] = const0_rtx;
1892 sprintf (desc1, "(%s)", reg_names[opbyte]);
1896 immed[i] = XEXP (fpop->ops[i], 0);
1898 sprintf(desc1, "<memory>");
1909 immed[i] = fpop->ops[i];
1918 /* Save/restore is special. */
1919 if (i == 0 && (fpop->opcode == USE || fpop->opcode == CLOBBER))
1920 type = 0xff, opbyte = INTVAL (fpop->ops[0]), immed[i] = 0;
1922 fprintf (file, "\t.byte 0x%x,0x%x # (%s) %s\n",
1923 type, opbyte, desc0, desc1);
1928 /* If in the middle of a word, round. */
1929 if (size_so_far % UNITS_PER_WORD)
1931 fprintf (file, "\t.space 2\n");
1935 for (i = 0; i < fpop->noperands; i++)
1937 switch (GET_MODE (immed[i]))
1942 fprintf (file, "\t.long ");
1943 output_addr_const (file, immed[i]);
1944 fprintf (file, "\n");
1951 if (GET_CODE (immed[i]) == CONST_DOUBLE)
1953 union real_extract u;
1955 bcopy ((char *) &CONST_DOUBLE_LOW (immed[i]),
1956 (char *) &u, sizeof u);
1957 if (GET_MODE (immed[i]) == DFmode)
1958 ASM_OUTPUT_DOUBLE (file, u.d);
1960 ASM_OUTPUT_FLOAT (file, u.d);
1970 if (size_so_far != fpop->size)
1972 if (TARGET_FULL_FP_BLOCKS)
1973 fprintf (file, "\t.space %d\n", fpop->size - size_so_far);
1979 /* Update for next subroutine. */
1984 /* Initialize floating-point operation table. */
1991 first_fpop = last_fpop_in_mem = 0;
1992 for (i = 0; i < FP_HASH_SIZE; i++)
1993 fp_hash_table[i] = 0;
1996 /* Return the offset value of an automatic variable (N_LSYM) having
1997 the given offset. Basically, we correct by going from a frame pointer to
1998 stack pointer value.
2002 romp_debugger_auto_correction(offset)
2007 /* We really want to go from STACK_POINTER_REGNUM to
2008 FRAME_POINTER_REGNUM, but this isn't defined. So go the other
2009 direction and negate. */
2010 INITIAL_ELIMINATION_OFFSET (FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM,
2013 /* The offset value points somewhere between the frame pointer and
2014 the stack pointer. What is up from the frame pointer is down from the
2015 stack pointer. Therefore the negation in the offset value too. */
2017 return -(offset+fp_to_sp+4);
2020 /* Return the offset value of an argument having
2021 the given offset. Basically, we correct by going from a arg pointer to
2022 stack pointer value. */
2025 romp_debugger_arg_correction (offset)
2030 INITIAL_ELIMINATION_OFFSET (ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM,
2033 /* Actually, something different happens if offset is from a floating-point
2034 register argument, but we don't handle it here. */
2036 return (offset - fp_to_argp);