Initial revision
[official-gcc.git] / gcc / config / romp / romp.c
blob5926b74dce7961fdd16a784974408860b9185942
1 /* Subroutines used for code generation on ROMP.
2 Copyright (C) 1990, 1991, 1992, 1993 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)
10 any later version.
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. */
23 #include <stdio.h>
24 #include "config.h"
25 #include "rtl.h"
26 #include "regs.h"
27 #include "hard-reg-set.h"
28 #include "real.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "insn-flags.h"
32 #include "output.h"
33 #include "insn-attr.h"
34 #include "flags.h"
35 #include "recog.h"
36 #include "expr.h"
37 #include "obstack.h"
38 #include "tree.h"
40 #define min(A,B) ((A) < (B) ? (A) : (B))
41 #define max(A,B) ((A) > (B) ? (A) : (B))
43 static int unsigned_comparisons_p ();
44 static void output_loadsave_fpregs ();
45 static void output_fpops ();
46 static void init_fpops ();
48 /* Return 1 if the insn using CC0 set by INSN does not contain
49 any unsigned tests applied to the condition codes.
51 Based on `next_insn_tests_no_inequality' in recog.c. */
53 int
54 next_insn_tests_no_unsigned (insn)
55 rtx insn;
57 register rtx next = next_cc0_user (insn);
59 if (next == 0)
61 if (find_reg_note (insn, REG_UNUSED, cc0_rtx))
62 return 1;
63 else
64 abort ();
67 return ((GET_CODE (next) == JUMP_INSN
68 || GET_CODE (next) == INSN
69 || GET_CODE (next) == CALL_INSN)
70 && ! unsigned_comparisons_p (PATTERN (next)));
73 static int
74 unsigned_comparisons_p (x)
75 rtx x;
77 register char *fmt;
78 register int len, i;
79 register enum rtx_code code = GET_CODE (x);
81 switch (code)
83 case REG:
84 case PC:
85 case CC0:
86 case CONST_INT:
87 case CONST_DOUBLE:
88 case CONST:
89 case LABEL_REF:
90 case SYMBOL_REF:
91 return 0;
93 case LTU:
94 case GTU:
95 case LEU:
96 case GEU:
97 return (XEXP (x, 0) == cc0_rtx || XEXP (x, 1) == cc0_rtx);
100 len = GET_RTX_LENGTH (code);
101 fmt = GET_RTX_FORMAT (code);
103 for (i = 0; i < len; i++)
105 if (fmt[i] == 'e')
107 if (unsigned_comparisons_p (XEXP (x, i)))
108 return 1;
110 else if (fmt[i] == 'E')
112 register int j;
113 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
114 if (unsigned_comparisons_p (XVECEXP (x, i, j)))
115 return 1;
119 return 0;
122 /* Update the condition code from the insn. Look mostly at the first
123 byte of the machine-specific insn description information.
125 cc_state.value[12] refer to two possible values that might correspond
126 to the CC. We only store register values. */
128 update_cc (body, insn)
129 rtx body;
130 rtx insn;
132 switch (get_attr_cc (insn))
134 case CC_NONE:
135 /* Insn does not affect the CC at all. */
136 break;
138 case CC_CHANGE0:
139 /* Insn doesn't affect the CC but does modify operand[0], known to be
140 a register. */
141 if (cc_status.value1 != 0
142 && reg_overlap_mentioned_p (recog_operand[0], cc_status.value1))
143 cc_status.value1 = 0;
145 if (cc_status.value2 != 0
146 && reg_overlap_mentioned_p (recog_operand[0], cc_status.value2))
147 cc_status.value2 = 0;
149 break;
151 case CC_COPY1TO0:
152 /* Insn copies operand[1] to operand[0], both registers, but doesn't
153 affect the CC. */
154 if (cc_status.value1 != 0
155 && reg_overlap_mentioned_p (recog_operand[0], cc_status.value1))
156 cc_status.value1 = 0;
158 if (cc_status.value2 != 0
159 && reg_overlap_mentioned_p (recog_operand[0], cc_status.value2))
160 cc_status.value2 = 0;
162 if (cc_status.value1 != 0
163 && rtx_equal_p (cc_status.value1, recog_operand[1]))
164 cc_status.value2 = recog_operand[0];
166 if (cc_status.value2 != 0
167 && rtx_equal_p (cc_status.value2, recog_operand[1]))
168 cc_status.value1 = recog_operand[0];
170 break;
172 case CC_CLOBBER:
173 /* Insn clobbers CC. */
174 CC_STATUS_INIT;
175 break;
177 case CC_SETS:
178 /* Insn sets CC to recog_operand[0], but overflow is impossible. */
179 CC_STATUS_INIT;
180 cc_status.flags |= CC_NO_OVERFLOW;
181 cc_status.value1 = recog_operand[0];
182 break;
184 case CC_COMPARE:
185 /* Insn is a compare which sets the CC fully. Update CC_STATUS for this
186 compare and mark whether the test will be signed or unsigned. */
188 register rtx p = PATTERN (insn);
190 CC_STATUS_INIT;
192 if (GET_CODE (p) == PARALLEL)
193 p = XVECEXP (p, 0, 0);
194 cc_status.value1 = SET_SRC (p);
196 if (GET_CODE (SET_SRC (p)) == REG)
197 cc_status.flags |= CC_NO_OVERFLOW;
198 if (! next_insn_tests_no_unsigned (insn))
199 cc_status.flags |= CC_UNSIGNED;
201 break;
203 case CC_TBIT:
204 /* Insn sets T bit if result is non-zero. Next insn must be branch. */
205 CC_STATUS_INIT;
206 cc_status.flags = CC_IN_TB | CC_NOT_NEGATIVE;
207 break;
209 default:
210 abort ();
214 /* Return 1 if a previous compare needs to be re-issued. This will happen
215 if two compares tested the same objects, but one was signed and the
216 other unsigned. OP is the comparison operation being performed. */
219 restore_compare_p (op)
220 rtx op;
222 enum rtx_code code = GET_CODE (op);
224 return (((code == GEU || code == LEU || code == GTU || code == LTU)
225 && ! (cc_status.flags & CC_UNSIGNED))
226 || ((code == GE || code == LE || code == GT || code == LT)
227 && (cc_status.flags & CC_UNSIGNED)));
230 /* Generate the (long) string corresponding to an inline multiply insn.
231 Note that `r10' does not refer to the register r10, but rather to the
232 SCR used as the MQ. */
233 char *
234 output_in_line_mul ()
236 static char insns[200];
237 int i;
239 strcpy (insns, "s %0,%0\n");
240 strcat (insns, "\tmts r10,%1\n");
241 for (i = 0; i < 16; i++)
242 strcat (insns, "\tm %0,%2\n");
243 strcat (insns, "\tmfs r10,%0");
245 return insns;
248 /* Returns 1 if OP is a memory reference with an offset from a register within
249 the range specified. The offset must also be a multiple of the size of the
250 mode. */
252 static int
253 memory_offset_in_range_p (op, mode, low, high)
254 register rtx op;
255 enum machine_mode mode;
256 int low, high;
258 int offset = 0;
260 if (! memory_operand (op, mode))
261 return 0;
263 while (GET_CODE (op) == SUBREG)
265 offset += SUBREG_WORD (op) * UNITS_PER_WORD;
266 #if BYTES_BIG_ENDIAN
267 offset -= (min (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (op)))
268 - min (UNITS_PER_WORD,
269 GET_MODE_SIZE (GET_MODE (SUBREG_REG (op)))));
270 #endif
271 op = SUBREG_REG (op);
274 /* We must now have either (mem (reg (x)), (mem (plus (reg (x)) (c))),
275 or a constant pool address. */
276 if (GET_CODE (op) != MEM)
277 abort ();
279 /* Now use the actual mode and get the address. */
280 mode = GET_MODE (op);
281 op = XEXP (op, 0);
282 if (GET_CODE (op) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (op))
283 offset = get_pool_offset (op) + 12;
284 else if (GET_CODE (op) == PLUS)
286 if (GET_CODE (XEXP (op, 1)) != CONST_INT
287 || ! register_operand (XEXP (op, 0), Pmode))
288 return 0;
290 offset += INTVAL (XEXP (op, 1));
293 else if (! register_operand (op, Pmode))
294 return 0;
296 return (offset >= low && offset <= high
297 && (offset % GET_MODE_SIZE (mode) == 0));
300 /* Return 1 if OP is a valid operand for a memory reference insn that can
301 only reference indirect through a register. */
304 zero_memory_operand (op, mode)
305 rtx op;
306 enum machine_mode mode;
308 return memory_offset_in_range_p (op, mode, 0, 0);
311 /* Return 1 if OP is a valid operand for a `short' memory reference insn. */
314 short_memory_operand (op, mode)
315 rtx op;
316 enum machine_mode mode;
318 if (mode == VOIDmode)
319 mode = GET_MODE (op);
321 return memory_offset_in_range_p (op, mode, 0,
322 15 * min (UNITS_PER_WORD,
323 GET_MODE_SIZE (mode)));
326 /* Returns 1 if OP is a memory reference involving a symbolic constant
327 that is not in the constant pool. */
330 symbolic_memory_operand (op, mode)
331 register rtx op;
332 enum machine_mode mode;
334 if (! memory_operand (op, mode))
335 return 0;
337 while (GET_CODE (op) == SUBREG)
338 op = SUBREG_REG (op);
340 if (GET_CODE (op) != MEM)
341 abort ();
343 op = XEXP (op, 0);
344 if (constant_pool_address_operand (op, VOIDmode))
345 return 0;
346 else
347 return romp_symbolic_operand (op, Pmode)
348 || (GET_CODE (op) == PLUS && register_operand (XEXP (op, 0), Pmode)
349 && romp_symbolic_operand (XEXP (op, 1), Pmode));
353 /* Returns 1 if OP is a constant pool reference to the current function. */
356 current_function_operand (op, mode)
357 rtx op;
358 enum machine_mode mode;
360 if (GET_CODE (op) != MEM || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
361 || ! CONSTANT_POOL_ADDRESS_P (XEXP (op, 0)))
362 return 0;
364 op = get_pool_constant (XEXP (op, 0));
365 return (GET_CODE (op) == SYMBOL_REF
366 && ! strcmp (current_function_name, XSTR (op, 0)));
369 /* Return non-zero if this function is known to have a null epilogue. */
372 null_epilogue ()
374 return (reload_completed
375 && first_reg_to_save () == 16
376 && ! romp_pushes_stack ());
379 /* Returns 1 if OP is the address of a location in the constant pool. */
382 constant_pool_address_operand (op, mode)
383 rtx op;
384 enum machine_mode mode;
386 return ((GET_CODE (op) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (op))
387 || (GET_CODE (op) == CONST && GET_CODE (XEXP (op, 0)) == PLUS
388 && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
389 && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
390 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (op, 0), 0))));
393 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
394 reference and a constant. */
397 romp_symbolic_operand (op, mode)
398 register rtx op;
399 enum machine_mode mode;
401 switch (GET_CODE (op))
403 case SYMBOL_REF:
404 case LABEL_REF:
405 return ! op->integrated;
407 case CONST:
408 op = XEXP (op, 0);
409 return (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
410 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
411 && GET_CODE (XEXP (op, 1)) == CONST_INT;
413 default:
414 return 0;
418 /* Returns 1 if OP is a valid constant for the ROMP. */
421 constant_operand (op, mode)
422 register rtx op;
423 enum machine_mode mode;
425 switch (GET_CODE (op))
427 case LABEL_REF:
428 case SYMBOL_REF:
429 case PLUS:
430 case CONST:
431 return romp_symbolic_operand (op,mode);
433 case CONST_INT:
434 return (unsigned int) (INTVAL (op) + 0x8000) < 0x10000
435 || (INTVAL (op) & 0xffff) == 0 || (INTVAL (op) & 0xffff0000) == 0;
437 default:
438 return 0;
442 /* Returns 1 if OP is either a constant integer valid for the ROMP or a
443 register. If a register, it must be in the proper mode unless MODE is
444 VOIDmode. */
447 reg_or_cint_operand (op, mode)
448 register rtx op;
449 enum machine_mode mode;
451 if (GET_CODE (op) == CONST_INT)
452 return constant_operand (op, mode);
454 return register_operand (op, mode);
457 /* Return 1 is the operand is either a register or ANY constant integer. */
460 reg_or_any_cint_operand (op, mode)
461 register rtx op;
462 enum machine_mode mode;
464 return GET_CODE (op) == CONST_INT || register_operand (op, mode);
467 /* Return 1 if the operand is either a register or a valid D-type operand. */
470 reg_or_D_operand (op, mode)
471 register rtx op;
472 enum machine_mode mode;
474 if (GET_CODE (op) == CONST_INT)
475 return (unsigned) (INTVAL (op) + 0x8000) < 0x10000;
477 return register_operand (op, mode);
480 /* Return 1 if the operand is either a register or an item that can be
481 used as the operand of an SI add insn. */
484 reg_or_add_operand (op, mode)
485 register rtx op;
486 enum machine_mode mode;
488 return reg_or_D_operand (op, mode) || romp_symbolic_operand (op, mode)
489 || (GET_CODE (op) == CONST_INT && (INTVAL (op) & 0xffff) == 0);
492 /* Return 1 if the operand is either a register or an item that can be
493 used as the operand of a ROMP logical AND insn. */
496 reg_or_and_operand (op, mode)
497 register rtx op;
498 enum machine_mode mode;
500 if (reg_or_cint_operand (op, mode))
501 return 1;
503 if (GET_CODE (op) != CONST_INT)
504 return 0;
506 return (INTVAL (op) & 0xffff) == 0xffff
507 || (INTVAL (op) & 0xffff0000) == 0xffff0000;
510 /* Return 1 if the operand is a register or memory operand. */
513 reg_or_mem_operand (op, mode)
514 register rtx op;
515 register enum machine_mode mode;
517 return register_operand (op, mode) || memory_operand (op, mode);
520 /* Return 1 if the operand is either a register or a memory operand that is
521 not symbolic. */
524 reg_or_nonsymb_mem_operand (op, mode)
525 register rtx op;
526 enum machine_mode mode;
528 if (register_operand (op, mode))
529 return 1;
531 if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode))
532 return 1;
534 return 0;
537 /* Return 1 if this operand is valid for the ROMP. This is any operand except
538 certain constant integers. */
541 romp_operand (op, mode)
542 register rtx op;
543 enum machine_mode mode;
545 if (GET_CODE (op) == CONST_INT)
546 return constant_operand (op, mode);
548 return general_operand (op, mode);
551 /* Return 1 if the operand is (reg:mode 0). */
554 reg_0_operand (op, mode)
555 rtx op;
556 enum machine_mode mode;
558 return ((mode == VOIDmode || mode == GET_MODE (op))
559 && GET_CODE (op) == REG && REGNO (op) == 0);
562 /* Return 1 if the operand is (reg:mode 15). */
565 reg_15_operand (op, mode)
566 rtx op;
567 enum machine_mode mode;
569 return ((mode == VOIDmode || mode == GET_MODE (op))
570 && GET_CODE (op) == REG && REGNO (op) == 15);
573 /* Return 1 if this is a binary floating-point operation. */
576 float_binary (op, mode)
577 register rtx op;
578 enum machine_mode mode;
580 if (mode != VOIDmode && mode != GET_MODE (op))
581 return 0;
583 if (GET_MODE (op) != SFmode && GET_MODE (op) != DFmode)
584 return 0;
586 switch (GET_CODE (op))
588 case PLUS:
589 case MINUS:
590 case MULT:
591 case DIV:
592 return GET_MODE (XEXP (op, 0)) == GET_MODE (op)
593 && GET_MODE (XEXP (op, 1)) == GET_MODE (op);
595 default:
596 return 0;
600 /* Return 1 if this is a unary floating-point operation. */
603 float_unary (op, mode)
604 register rtx op;
605 enum machine_mode mode;
607 if (mode != VOIDmode && mode != GET_MODE (op))
608 return 0;
610 if (GET_MODE (op) != SFmode && GET_MODE (op) != DFmode)
611 return 0;
613 return (GET_CODE (op) == NEG || GET_CODE (op) == ABS)
614 && GET_MODE (XEXP (op, 0)) == GET_MODE (op);
617 /* Return 1 if this is a valid floating-point conversion that can be done
618 as part of an operation by the RT floating-point routines. */
621 float_conversion (op, mode)
622 register rtx op;
623 enum machine_mode mode;
625 if (mode != VOIDmode && mode != GET_MODE (op))
626 return 0;
628 switch (GET_CODE (op))
630 case FLOAT_TRUNCATE:
631 return GET_MODE (op) == SFmode && GET_MODE (XEXP (op, 0)) == DFmode;
633 case FLOAT_EXTEND:
634 return GET_MODE (op) == DFmode && GET_MODE (XEXP (op, 0)) == SFmode;
636 case FLOAT:
637 return ((GET_MODE (XEXP (op, 0)) == SImode
638 || GET_CODE (XEXP (op, 0)) == CONST_INT)
639 && (GET_MODE (op) == SFmode || GET_MODE (op) == DFmode));
641 case FIX:
642 return ((GET_MODE (op) == SImode
643 || GET_CODE (XEXP (op, 0)) == CONST_INT)
644 && (GET_MODE (XEXP (op, 0)) == SFmode
645 || GET_MODE (XEXP (op, 0)) == DFmode));
647 default:
648 return 0;
652 /* Print an operand. Recognize special options, documented below. */
654 void
655 print_operand (file, x, code)
656 FILE *file;
657 rtx x;
658 char code;
660 int i;
662 switch (code)
664 case 'B':
665 /* Byte number (const/8) */
666 if (GET_CODE (x) != CONST_INT)
667 output_operand_lossage ("invalid %%B value");
669 fprintf (file, "%d", INTVAL (x) / 8);
670 break;
672 case 'L':
673 /* Low order 16 bits of constant. */
674 if (GET_CODE (x) != CONST_INT)
675 output_operand_lossage ("invalid %%L value");
677 fprintf (file, "%d", INTVAL (x) & 0xffff);
678 break;
680 case 's':
681 /* Null or "16" depending on whether the constant is greater than 16. */
682 if (GET_CODE (x) != CONST_INT)
683 output_operand_lossage ("invalid %%s value");
685 if (INTVAL (x) >= 16)
686 fprintf (file, "16");
688 break;
690 case 'S':
691 /* For shifts: 's' will have given the half. Just give the amount
692 within 16. */
693 if (GET_CODE (x) != CONST_INT)
694 output_operand_lossage ("invalid %%S value");
696 fprintf (file, "%d", INTVAL (x) & 15);
697 break;
699 case 'b':
700 /* The number of a single bit set or cleared, mod 16. Note that the ROMP
701 numbers bits with the high-order bit 31. */
702 if (GET_CODE (x) != CONST_INT)
703 output_operand_lossage ("invalid %%b value");
705 if ((i = exact_log2 (INTVAL (x))) >= 0)
706 fprintf (file, "%d", (31 - i) % 16);
707 else if ((i = exact_log2 (~ INTVAL (x))) >= 0)
708 fprintf (file, "%d", (31 - i) % 16);
709 else
710 output_operand_lossage ("invalid %%b value");
712 break;
714 case 'h':
715 /* "l" or "u" depending on which half of the constant is zero. */
716 if (GET_CODE (x) != CONST_INT)
717 output_operand_lossage ("invalid %%h value");
719 if ((INTVAL (x) & 0xffff0000) == 0)
720 fprintf (file, "l");
721 else if ((INTVAL (x) & 0xffff) == 0)
722 fprintf (file, "u");
723 else
724 output_operand_lossage ("invalid %%h value");
726 break;
728 case 'H':
729 /* Upper or lower half, depending on which half is zero. */
730 if (GET_CODE (x) != CONST_INT)
731 output_operand_lossage ("invalid %%H value");
733 if ((INTVAL (x) & 0xffff0000) == 0)
734 fprintf (file, "%d", INTVAL (x) & 0xffff);
735 else if ((INTVAL (x) & 0xffff) == 0)
736 fprintf (file, "%d", (INTVAL (x) >> 16) & 0xffff);
737 else
738 output_operand_lossage ("invalid %%H value");
740 break;
742 case 'z':
743 /* Write two characters:
744 'lo' if the high order part is all ones
745 'lz' if the high order part is all zeros
746 'uo' if the low order part is all ones
747 'uz' if the low order part is all zeros
749 if (GET_CODE (x) != CONST_INT)
750 output_operand_lossage ("invalid %%z value");
752 if ((INTVAL (x) & 0xffff0000) == 0)
753 fprintf (file, "lz");
754 else if ((INTVAL (x) & 0xffff0000) == 0xffff0000)
755 fprintf (file, "lo");
756 else if ((INTVAL (x) & 0xffff) == 0)
757 fprintf (file, "uz");
758 else if ((INTVAL (x) & 0xffff) == 0xffff)
759 fprintf (file, "uo");
760 else
761 output_operand_lossage ("invalid %%z value");
763 break;
765 case 'Z':
766 /* Upper or lower half, depending on which is non-zero or not
767 all ones. Must be consistent with 'z' above. */
768 if (GET_CODE (x) != CONST_INT)
769 output_operand_lossage ("invalid %%Z value");
771 if ((INTVAL (x) & 0xffff0000) == 0
772 || (INTVAL (x) & 0xffff0000) == 0xffff0000)
773 fprintf (file, "%d", INTVAL (x) & 0xffff);
774 else if ((INTVAL (x) & 0xffff) == 0 || (INTVAL (x) & 0xffff) == 0xffff)
775 fprintf (file, "%d", (INTVAL (x) >> 16) & 0xffff);
776 else
777 output_operand_lossage ("invalid %%Z value");
779 break;
781 case 'k':
782 /* Same as 'z', except the trailing 'o' or 'z' is not written. */
783 if (GET_CODE (x) != CONST_INT)
784 output_operand_lossage ("invalid %%k value");
786 if ((INTVAL (x) & 0xffff0000) == 0
787 || (INTVAL (x) & 0xffff0000) == 0xffff0000)
788 fprintf (file, "l");
789 else if ((INTVAL (x) & 0xffff) == 0
790 || (INTVAL (x) & 0xffff) == 0xffff)
791 fprintf (file, "u");
792 else
793 output_operand_lossage ("invalid %%k value");
795 break;
797 case 't':
798 /* Similar to 's', except that we write 'h' or 'u'. */
799 if (GET_CODE (x) != CONST_INT)
800 output_operand_lossage ("invalid %%k value");
802 if (INTVAL (x) < 16)
803 fprintf (file, "u");
804 else
805 fprintf (file, "l");
806 break;
808 case 'M':
809 /* For memory operations, write 's' if the operand is a short
810 memory operand. */
811 if (short_memory_operand (x, VOIDmode))
812 fprintf (file, "s");
813 break;
815 case 'N':
816 /* Like 'M', but check for zero memory offset. */
817 if (zero_memory_operand (x, VOIDmode))
818 fprintf (file, "s");
819 break;
821 case 'O':
822 /* Write low-order part of DImode or DFmode. Supported for MEM
823 and REG only. */
824 if (GET_CODE (x) == REG)
825 fprintf (file, "%s", reg_names[REGNO (x) + 1]);
826 else if (GET_CODE (x) == MEM)
827 print_operand (file, gen_rtx (MEM, GET_MODE (x),
828 plus_constant (XEXP (x, 0), 4)), 0);
829 else
830 abort ();
831 break;
833 case 'C':
834 /* Offset in constant pool for constant pool address. */
835 if (! constant_pool_address_operand (x, VOIDmode))
836 abort ();
837 if (GET_CODE (x) == SYMBOL_REF)
838 fprintf (file, "%d", get_pool_offset (x) + 12);
839 else
840 /* Must be (const (plus (symbol_ref) (const_int))) */
841 fprintf (file, "%d",
842 (get_pool_offset (XEXP (XEXP (x, 0), 0)) + 12
843 + INTVAL (XEXP (XEXP (x, 0), 1))));
844 break;
846 case 'j':
847 /* Branch opcode. Check for condition in test bit for eq/ne. */
848 switch (GET_CODE (x))
850 case EQ:
851 if (cc_status.flags & CC_IN_TB)
852 fprintf (file, "ntb");
853 else
854 fprintf (file, "eq");
855 break;
857 case NE:
858 if (cc_status.flags & CC_IN_TB)
859 fprintf (file, "tb");
860 else
861 fprintf (file, "ne");
862 break;
864 case GT:
865 case GTU:
866 fprintf (file, "h");
867 break;
869 case LT:
870 case LTU:
871 fprintf (file, "l");
872 break;
874 case GE:
875 case GEU:
876 fprintf (file, "he");
877 break;
879 case LE:
880 case LEU:
881 fprintf (file, "le");
882 break;
884 default:
885 output_operand_lossage ("invalid %%j value");
887 break;
889 case 'J':
890 /* Reversed branch opcode. */
891 switch (GET_CODE (x))
893 case EQ:
894 if (cc_status.flags & CC_IN_TB)
895 fprintf (file, "tb");
896 else
897 fprintf (file, "ne");
898 break;
900 case NE:
901 if (cc_status.flags & CC_IN_TB)
902 fprintf (file, "ntb");
903 else
904 fprintf (file, "eq");
905 break;
907 case GT:
908 case GTU:
909 fprintf (file, "le");
910 break;
912 case LT:
913 case LTU:
914 fprintf (file, "he");
915 break;
917 case GE:
918 case GEU:
919 fprintf (file, "l");
920 break;
922 case LE:
923 case LEU:
924 fprintf (file, "h");
925 break;
927 default:
928 output_operand_lossage ("invalid %%j value");
930 break;
932 case '.':
933 /* Output nothing. Used as delimiter in, e.g., "mc%B1%.3 " */
934 break;
936 case '#':
937 /* Output 'x' if this insn has a delay slot, else nothing. */
938 if (dbr_sequence_length ())
939 fprintf (file, "x");
940 break;
942 case 0:
943 if (GET_CODE (x) == REG)
944 fprintf (file, "%s", reg_names[REGNO (x)]);
945 else if (GET_CODE (x) == MEM)
947 if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
948 && current_function_operand (x, Pmode))
949 fprintf (file, "r14");
950 else
951 output_address (XEXP (x, 0));
953 else
954 output_addr_const (file, x);
955 break;
957 default:
958 output_operand_lossage ("invalid %%xn code");
962 /* This page contains routines that are used to determine what the function
963 prologue and epilogue code will do and write them out. */
965 /* Return the first register that is required to be saved. 16 if none. */
968 first_reg_to_save()
970 int first_reg;
972 /* Find lowest numbered live register. */
973 for (first_reg = 6; first_reg <= 15; first_reg++)
974 if (regs_ever_live[first_reg])
975 break;
977 /* If we think that we do not have to save r14, see if it will be used
978 to be sure. */
979 if (first_reg > 14 && romp_using_r14 ())
980 first_reg = 14;
982 return first_reg;
985 /* Compute the size of the save area in the stack, including the space for
986 the first four incoming arguments. */
989 romp_sa_size ()
991 int size;
992 int i;
994 /* We have the 4 words corresponding to the arguments passed in registers,
995 4 reserved words, space for static chain, general register save area,
996 and floating-point save area. */
997 size = 4 + 4 + 1 + (16 - first_reg_to_save ());
999 /* The documentation says we have to leave 18 words in the save area if
1000 any floating-point registers at all are saved, not the three words
1001 per register you might otherwise expect. */
1002 for (i = 2 + (TARGET_FP_REGS != 0); i <= 7; i++)
1003 if (regs_ever_live[i + 17])
1005 size += 18;
1006 break;
1009 return size * 4;
1012 /* Return non-zero if this function makes calls or has fp operations
1013 (which are really calls). */
1016 romp_makes_calls ()
1018 rtx insn;
1020 for (insn = get_insns (); insn; insn = next_insn (insn))
1022 if (GET_CODE (insn) == CALL_INSN)
1023 return 1;
1024 else if (GET_CODE (insn) == INSN)
1026 rtx body = PATTERN (insn);
1028 if (GET_CODE (body) != USE && GET_CODE (body) != CLOBBER
1029 && GET_CODE (body) != ADDR_VEC
1030 && GET_CODE (body) != ADDR_DIFF_VEC
1031 && get_attr_type (insn) == TYPE_FP)
1032 return 1;
1036 return 0;
1039 /* Return non-zero if this function will use r14 as a pointer to its
1040 constant pool. */
1043 romp_using_r14 ()
1045 /* If we are debugging, profiling, have a non-empty constant pool, or
1046 call a function, we need r14. */
1047 return (write_symbols != NO_DEBUG || profile_flag || get_pool_size () != 0
1048 || romp_makes_calls ());
1051 /* Return non-zero if this function needs to push space on the stack. */
1054 romp_pushes_stack ()
1056 /* We need to push the stack if a frame pointer is needed (because the
1057 stack might be dynamically adjusted), if we are debugging, if the
1058 total required size is more than 100 bytes, or if we make calls. */
1060 return (frame_pointer_needed || write_symbols != NO_DEBUG
1061 || (romp_sa_size () + get_frame_size ()) > 100
1062 || romp_makes_calls ());
1065 /* Write function prologue.
1067 We compute the size of the fixed area required as follows:
1069 We always allocate 4 words for incoming arguments, 4 word reserved, 1
1070 word for static link, as many words as required for general register
1071 save area, plus 2 words for each FP reg 2-7 that must be saved. */
1073 void
1074 output_prolog (file, size)
1075 FILE *file;
1076 int size;
1078 int first_reg;
1079 int reg_save_offset;
1080 int fp_save = size + current_function_outgoing_args_size;
1082 init_fpops ();
1084 /* Add in fixed size plus output argument area. */
1085 size += romp_sa_size () + current_function_outgoing_args_size;
1087 /* Compute first register to save and perform the save operation if anything
1088 needs to be saved. */
1089 first_reg = first_reg_to_save();
1090 reg_save_offset = - (4 + 4 + 1 + (16 - first_reg)) * 4;
1091 if (first_reg == 15)
1092 fprintf (file, "\tst r15,%d(r1)\n", reg_save_offset);
1093 else if (first_reg < 16)
1094 fprintf (file, "\tstm r%d,%d(r1)\n", first_reg, reg_save_offset);
1096 /* Set up pointer to data area if it is needed. */
1097 if (romp_using_r14 ())
1098 fprintf (file, "\tcas r14,r0,r0\n");
1100 /* Set up frame pointer if needed. */
1101 if (frame_pointer_needed)
1102 fprintf (file, "\tcal r13,-%d(r1)\n", romp_sa_size () + 64);
1104 /* Push stack if neeeded. There are a couple of ways of doing this. */
1105 if (romp_pushes_stack ())
1107 if (size >= 32768)
1109 if (size >= 65536)
1111 fprintf (file, "\tcau r0,%d(r0)\n", size >> 16);
1112 fprintf (file, "\toil r0,r0,%d\n", size & 0xffff);
1114 else
1115 fprintf (file, "\tcal16 r0,%d(r0)\n", size);
1116 fprintf (file, "\ts r1,r0\n");
1118 else
1119 fprintf (file, "\tcal r1,-%d(r1)\n", size);
1122 /* Save floating-point registers. */
1123 output_loadsave_fpregs (file, USE,
1124 plus_constant (stack_pointer_rtx, fp_save));
1127 /* Output the offset information used by debuggers.
1128 This is the exactly the total_size value of output_epilog
1129 which is added to the frame pointer. However the value in the debug
1130 table is encoded in a space-saving way as follows:
1132 The first byte contains two fields: a 2-bit size field and the first
1133 6 bits of an offset value. The 2-bit size field is in the high-order
1134 position and specifies how many subsequent bytes follow after
1135 this one. An offset value is at most 4-bytes long.
1137 The last 6 bits of the first byte initialize the offset value. In many
1138 cases where procedures have small local storage, this is enough and, in
1139 this case, the high-order size field is zero so the byte can (almost) be
1140 used as is (see below). Thus, the byte value of 0x0d is encodes a offset
1141 size of 13 words, or 52 bytes.
1143 For procedures with a local space larger than 60 bytes, the 6 bits
1144 are the high-order 6 bits. The remaining bytes follow as necessary,
1145 in Big Endian order. Thus, the short value of 16907 (= 16384+523)
1146 encodes an offset of 2092 bytes (523 words).
1148 The total offset value is in words (not bytes), so the final value has to
1149 be multiplied by 4 before it can be used in address computations by a
1150 debugger. */
1152 void
1153 output_encoded_offset (file, reg_offset)
1154 FILE *file;
1155 unsigned reg_offset;
1157 /* Convert the offset value to 4-byte words rather than bytes. */
1158 reg_offset = (reg_offset + 3) / 4;
1160 /* Now output 1-4 bytes in encoded form. */
1161 if (reg_offset < (1 << 6))
1162 /* Fits into one byte */
1163 fprintf (file, "\t.byte %d\n", reg_offset);
1164 else if (reg_offset < (1 << (6 + 8)))
1165 /* Fits into two bytes */
1166 fprintf (file, "\t.short %d\n", (1 << (6 + 8)) + reg_offset);
1167 else if (reg_offset < (1 << (6 + 8 + 8)))
1169 /* Fits in three bytes */
1170 fprintf (file, "\t.byte %d\n", (2 << 6) + (reg_offset >> ( 6+ 8)));
1171 fprintf (file, "\t.short %d\n", reg_offset % (1 << (6 + 8)));
1173 else
1175 /* Use 4 bytes. */
1176 fprintf (file, "\t.short %d", (3 << (6 + 8)) + (reg_offset >> (6 + 8)));
1177 fprintf (file, "\t.short %d\n", reg_offset % (1 << (6 + 8)));
1181 /* Write function epilogue. */
1183 void
1184 output_epilog (file, size)
1185 FILE *file;
1186 int size;
1188 int first_reg = first_reg_to_save();
1189 int pushes_stack = romp_pushes_stack ();
1190 int reg_save_offset = - ((16 - first_reg) + 1 + 4 + 4) * 4;
1191 int total_size = (size + romp_sa_size ()
1192 + current_function_outgoing_args_size);
1193 int fp_save = size + current_function_outgoing_args_size;
1194 int long_frame = total_size >= 32768;
1195 rtx insn = get_last_insn ();
1196 int write_code = 1;
1198 int nargs = 0; /* words of arguments */
1199 tree argptr;
1201 /* Compute the number of words of arguments. Since this is just for
1202 the traceback table, we ignore arguments that don't have a size or
1203 don't have a fixed size. */
1205 for (argptr = DECL_ARGUMENTS (current_function_decl);
1206 argptr; argptr = TREE_CHAIN (argptr))
1208 int this_size = int_size_in_bytes (TREE_TYPE (argptr));
1210 if (this_size > 0)
1211 nargs += (this_size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
1214 /* If the last insn was a BARRIER, we don't have to write anything except
1215 the trace table. */
1216 if (GET_CODE (insn) == NOTE)
1217 insn = prev_nonnote_insn (insn);
1218 if (insn && GET_CODE (insn) == BARRIER)
1219 write_code = 0;
1221 /* Restore floating-point registers. */
1222 if (write_code)
1223 output_loadsave_fpregs (file, CLOBBER,
1224 gen_rtx (PLUS, Pmode, gen_rtx (REG, Pmode, 1),
1225 gen_rtx (CONST_INT, VOIDmode, 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. */
1243 if (pushes_stack)
1245 if (write_code)
1247 if (long_frame)
1248 fprintf (file, "\tbr r15\n");
1249 else
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
1258 stack pointer.
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);
1285 else
1287 if (write_code)
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
1296 register. */
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 (allocatable 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. */
1324 get_symref (name)
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. */
1333 while (*sp)
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)
1342 break;
1344 /* If couldn't find matching SYMBOL_REF, make a new one. */
1345 if (p == 0)
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)));
1354 p->next = 0;
1355 resume_temporary_allocation ();
1358 return p->symref;
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
1372 future.
1374 This routine returns 1 if the operation is OK. */
1377 check_precision (opmode, op1, op2)
1378 enum machine_mode opmode;
1379 rtx op1, op2;
1381 if (opmode == SFmode)
1382 return 1;
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)
1387 return 1;
1389 if (op2 && GET_CODE (op2) != FLOAT && GET_CODE (op2) != FLOAT_EXTEND)
1390 return 1;
1392 return 0;
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. */
1403 struct fp_op {
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). */
1429 int data_offset;
1431 /* Compute hash code for an RTX used in floating-point. */
1433 static unsigned int
1434 hash_rtx (x)
1435 register rtx x;
1437 register unsigned int hash = (((int) GET_CODE (x) << 10)
1438 + ((int) GET_MODE (x) << 20));
1439 register int i;
1440 register char *fmt = GET_RTX_FORMAT (GET_CODE (x));
1442 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (x)); i++)
1443 if (fmt[i] == 'e')
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);
1452 return hash;
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. */
1462 char *
1463 output_fpop (code, op0, op1, op2, insn)
1464 enum rtx_code code;
1465 rtx op0, op1, op2;
1466 rtx insn;
1468 static char outbuf[40];
1469 unsigned int hash, hash0, hash1, hash2;
1470 int size, i;
1471 register struct fp_op *fpop, *last_fpop;
1472 int dyadic = (op2 != 0);
1473 enum machine_mode opmode;
1474 int noperands;
1475 rtx tem;
1476 unsigned int tem_hash;
1477 int fr0_avail = 0;
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
1511 the RT fp code. */
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))))
1517 op1 = op2;
1518 op2 = 0;
1521 noperands = 1 + (op1 != 0) + (op2 != 0);
1523 /* Compute hash code for entire expression and see if operation block
1524 already exists. */
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;
1529 fpop;
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])))
1535 goto win;
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;
1542 fpop->ops[0] = op0;
1543 fpop->ops[1] = op1;
1544 fpop->ops[2] = op2;
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) */
1551 size = 24;
1552 if (op0 && (GET_CODE (op0) != REG
1553 || ! FP_REGNO_P (REGNO (op0)) || REGNO (op0) == 23))
1554 size += 32;
1556 if (op1 && (GET_CODE (op1) != REG
1557 || ! FP_REGNO_P (REGNO (op1)) || REGNO (op1) == 23))
1558 size += 32;
1560 if (op2 && (GET_CODE (op2) != REG
1561 || ! FP_REGNO_P (REGNO (op2)) || REGNO (op2) == 23))
1562 size += 32;
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))
1568 opmode = DFmode;
1569 else
1570 opmode = SFmode;
1572 if (op0 && GET_MODE (op0) != opmode)
1573 size += 12;
1574 if (op1 && GET_MODE (op1) != opmode)
1575 size += 12;
1576 if (op2 && GET_MODE (op2) != opmode)
1577 size += 12;
1579 /* 12 more if first and third operand types not the same. */
1580 if (op2 && GET_MODE (op0) != GET_MODE (op2))
1581 size += 12;
1583 /* CMP and CMPT need additional. Also, compute size of save/restore here. */
1584 if (code == EQ)
1585 size += 32;
1586 else if (code == GE)
1587 size += 64;
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
1592 of four. */
1593 size = 36 - 24;
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. */
1600 size +=16;
1602 /* No floating-point scratch registers are provided. Compute extra
1603 length due to this. This logic is that shown in the referenced
1604 appendix. */
1606 i = 0;
1607 if (op0 && GET_CODE (op0) == REG && FP_REGNO_P (REGNO (op0)))
1608 i++;
1609 if (op1 && GET_CODE (op1) == REG && FP_REGNO_P (REGNO (op1)))
1610 i++;
1611 if (op2 && GET_CODE (op2) == REG && FP_REGNO_P (REGNO (op2)))
1612 i++;
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))
1617 fr0_avail = 1;
1619 if (dyadic)
1621 if (i == 0)
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))
1631 #if 1
1632 /* This triggers a bug on the RT. */
1633 abort ();
1634 #else
1635 size += fr0_avail ? 0 : 64;
1636 #endif
1638 else
1640 i = 0;
1641 if (GET_CODE (op0) == REG && FP_REGNO_P (REGNO (op0)))
1642 i++;
1643 if (GET_CODE (op2) == REG && FP_REGNO_P (REGNO (op2)))
1644 i++;
1645 if (i == 0)
1646 size += fr0_avail ? 64 : 112;
1647 else if (i == 1)
1648 size += fr0_avail ? 0 : 64;
1652 else if (code != USE && code != CLOBBER
1653 && (GET_CODE (op0) != REG || ! FP_REGNO_P (REGNO (op0))))
1654 size += 64;
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)
1661 size += 2;
1662 else
1664 if (op0) size += 2;
1665 if (op1) size += 2;
1666 if (op2) size += 2;
1669 /* If in the middle of a word, round. */
1670 if (size % UNITS_PER_WORD)
1671 size += 2;
1673 /* Handle any immediates. */
1674 if (code != USE && code != CLOBBER && op0 && GET_CODE (op0) != REG)
1675 size += 4;
1676 if (op1 && GET_CODE (op1) != REG)
1677 size += 4;
1678 if (op2 && GET_CODE (op2) != REG)
1679 size += 4;
1681 if (code != USE && code != CLOBBER &&
1682 op0 && GET_CODE (op0) == CONST_DOUBLE && GET_MODE (op0) == DFmode)
1683 size += 4;
1684 if (op1 && GET_CODE (op1) == CONST_DOUBLE && GET_MODE (op1) == DFmode)
1685 size += 4;
1686 if (op2 && GET_CODE (op2) == CONST_DOUBLE && GET_MODE (op2) == DFmode)
1687 size += 4;
1690 /* Done with size computation! Chain this in. */
1691 fpop->size = size;
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;
1698 else
1699 first_fpop = fpop;
1700 last_fpop_in_mem = fpop;
1702 if (last_fpop)
1703 last_fpop->next_same_hash = fpop;
1704 else
1705 fp_hash_table[hash] = fpop;
1707 win:
1708 /* FPOP describes the operation to be performed. Return a string to branch
1709 to it. */
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" : "");
1714 else
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" : "");
1718 return outbuf;
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. */
1727 static void
1728 output_loadsave_fpregs (file, code, addr)
1729 FILE *file;
1730 enum rtx_code code;
1731 rtx addr;
1733 register int i;
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);
1740 if (mask)
1741 fprintf (file, "\t%s\n",
1742 output_fpop (code, gen_rtx (CONST_INT, VOIDmode, mask),
1743 gen_rtx (MEM, Pmode, addr),
1744 0, const0_rtx));
1748 /* Output any floating-point operations at the end of the routine. */
1750 static void
1751 output_fpops (file)
1752 FILE *file;
1754 register struct fp_op *fpop;
1755 register int size_so_far;
1756 register int i;
1757 rtx immed[3];
1759 if (first_fpop == 0)
1760 return;
1762 data_section ();
1764 ASM_OUTPUT_ALIGN (file, 2);
1766 for (fpop = first_fpop; fpop; fpop = fpop->next_in_mem)
1768 if (fpop->mem_offset < 32768 / UNITS_PER_WORD)
1769 fprintf (file, "# data area offset = %d\n",
1770 fpop->mem_offset * UNITS_PER_WORD);
1771 else
1772 fprintf (file, "L%dF%d:\n",
1773 subr_number, fpop->mem_offset * UNITS_PER_WORD);
1775 fprintf (file, "\tcas r0,r15,r0\n");
1776 fprintf (file, "\t.long FPGLUE\n");
1777 switch (fpop->opcode)
1779 case USE:
1780 fprintf (file, "\t.byte 0x1d\t# STOREM\n");
1781 break;
1782 case CLOBBER:
1783 fprintf (file, "\t.byte 0x0f\t# LOADM\n");
1784 break;
1785 case ABS:
1786 fprintf (file, "\t.byte 0x00\t# ABS\n");
1787 break;
1788 case PLUS:
1789 fprintf (file, "\t.byte 0x02\t# ADD\n");
1790 break;
1791 case EQ:
1792 fprintf (file, "\t.byte 0x07\t# CMP\n");
1793 break;
1794 case GE:
1795 fprintf (file, "\t.byte 0x08\t# CMPT\n");
1796 break;
1797 case DIV:
1798 fprintf (file, "\t.byte 0x0c\t# DIV\n");
1799 break;
1800 case SET:
1801 fprintf (file, "\t.byte 0x14\t# MOVE\n");
1802 break;
1803 case MULT:
1804 fprintf (file, "\t.byte 0x15\t# MUL\n");
1805 break;
1806 case NEG:
1807 fprintf (file, "\t.byte 0x16\t# NEG\n");
1808 break;
1809 case SQRT:
1810 fprintf (file, "\t.byte 0x1c\t# SQRT\n");
1811 break;
1812 case MINUS:
1813 fprintf (file, "\t.byte 0x1e\t# SUB\n");
1814 break;
1815 default:
1816 abort ();
1819 fprintf (file, "\t.byte %d\n", fpop->noperands);
1820 fprintf (file, "\t.short 0x8001\n");
1822 if ((fpop->ops[0] == 0
1823 || GET_CODE (fpop->ops[0]) != REG || REGNO(fpop->ops[0]) != 17)
1824 && (fpop->ops[1] == 0 || GET_CODE (fpop->ops[1]) != REG
1825 || REGNO(fpop->ops[1]) != 17)
1826 && (fpop->ops[2] == 0 || GET_CODE (fpop->ops[2]) != REG
1827 || REGNO(fpop->ops[2]) != 17))
1828 fprintf (file, "\t.byte %d, 0x80\n", fpop->size);
1829 else
1830 fprintf (file, "\t.byte %d, 0\n", fpop->size);
1831 size_so_far = 12;
1832 for (i = 0; i < fpop->noperands; i++)
1834 register int type;
1835 register int opbyte;
1836 register char *desc0;
1837 char desc1[50];
1839 immed[i] = 0;
1840 switch (GET_MODE (fpop->ops[i]))
1842 case SImode:
1843 case VOIDmode:
1844 desc0 = "int";
1845 type = 0;
1846 break;
1847 case SFmode:
1848 desc0 = "float";
1849 type = 2;
1850 break;
1851 case DFmode:
1852 desc0 = "double";
1853 type = 3;
1854 break;
1855 default:
1856 abort ();
1859 switch (GET_CODE (fpop->ops[i]))
1861 case REG:
1862 strcpy(desc1, reg_names[REGNO (fpop->ops[i])]);
1863 if (FP_REGNO_P (REGNO (fpop->ops[i])))
1865 type += 0x10;
1866 opbyte = REGNO (fpop->ops[i]) - 17;
1868 else
1870 type += 0x00;
1871 opbyte = REGNO (fpop->ops[i]);
1872 if (type == 3)
1873 opbyte = (opbyte << 4) + opbyte + 1;
1875 break;
1877 case MEM:
1878 type += 0x30;
1879 if (GET_CODE (XEXP (fpop->ops[i], 0)) == PLUS)
1881 immed[i] = XEXP (XEXP (fpop->ops[i], 0), 1);
1882 opbyte = REGNO (XEXP (XEXP (fpop->ops[i], 0), 0));
1883 if (GET_CODE (immed[i]) == CONST_INT)
1884 sprintf (desc1, "%d(%s)", INTVAL (immed[i]),
1885 reg_names[opbyte]);
1886 else
1887 sprintf (desc1, "<memory> (%s)", reg_names[opbyte]);
1889 else if (GET_CODE (XEXP (fpop->ops[i], 0)) == REG)
1891 opbyte = REGNO (XEXP (fpop->ops[i], 0));
1892 immed[i] = const0_rtx;
1893 sprintf (desc1, "(%s)", reg_names[opbyte]);
1895 else
1897 immed[i] = XEXP (fpop->ops[i], 0);
1898 opbyte = 0;
1899 sprintf(desc1, "<memory>");
1901 break;
1903 case CONST_INT:
1904 case CONST_DOUBLE:
1905 case CONST:
1906 case SYMBOL_REF:
1907 case LABEL_REF:
1908 type += 0x20;
1909 opbyte = 0;
1910 immed[i] = fpop->ops[i];
1911 desc1[0] = '$';
1912 desc1[1] = '\0';
1913 break;
1915 default:
1916 abort ();
1919 /* Save/restore is special. */
1920 if (i == 0 && (fpop->opcode == USE || fpop->opcode == CLOBBER))
1921 type = 0xff, opbyte = INTVAL (fpop->ops[0]), immed[i] = 0;
1923 fprintf (file, "\t.byte 0x%x,0x%x # (%s) %s\n",
1924 type, opbyte, desc0, desc1);
1926 size_so_far += 2;
1929 /* If in the middle of a word, round. */
1930 if (size_so_far % UNITS_PER_WORD)
1932 fprintf (file, "\t.space 2\n");
1933 size_so_far += 2;
1936 for (i = 0; i < fpop->noperands; i++)
1937 if (immed[i])
1938 switch (GET_MODE (immed[i]))
1940 case SImode:
1941 case VOIDmode:
1942 size_so_far += 4;
1943 fprintf (file, "\t.long ");
1944 output_addr_const (file, immed[i]);
1945 fprintf (file, "\n");
1946 break;
1948 case DFmode:
1949 size_so_far += 4;
1950 case SFmode:
1951 size_so_far += 4;
1952 if (GET_CODE (immed[i]) == CONST_DOUBLE)
1954 union real_extract u;
1956 bcopy ((char *) &CONST_DOUBLE_LOW (immed[i]),
1957 (char *) &u, sizeof u);
1958 if (GET_MODE (immed[i]) == DFmode)
1959 ASM_OUTPUT_DOUBLE (file, u.d);
1960 else
1961 ASM_OUTPUT_FLOAT (file, u.d);
1963 else
1964 abort ();
1965 break;
1967 default:
1968 abort ();
1971 if (size_so_far != fpop->size)
1973 if (TARGET_FULL_FP_BLOCKS)
1974 fprintf (file, "\t.space %d\n", fpop->size - size_so_far);
1975 else
1976 abort ();
1980 /* Update for next subroutine. */
1981 subr_number++;
1982 text_section ();
1985 /* Initialize floating-point operation table. */
1987 static void
1988 init_fpops()
1990 register int i;
1992 first_fpop = last_fpop_in_mem = 0;
1993 for (i = 0; i < FP_HASH_SIZE; i++)
1994 fp_hash_table[i] = 0;
1997 /* Return the offset value of an automatic variable (N_LSYM) having
1998 the given offset. Basically, we correct by going from a frame pointer to
1999 stack pointer value.
2003 romp_debugger_auto_correction(offset)
2004 int offset;
2006 int fp_to_sp;
2008 /* We really want to go from STACK_POINTER_REGNUM to
2009 FRAME_POINTER_REGNUM, but this isn't defined. So go the other
2010 direction and negate. */
2011 INITIAL_ELIMINATION_OFFSET (FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM,
2012 fp_to_sp);
2014 /* The offset value points somewhere between the frame pointer and
2015 the stack pointer. What is up from the frame pointer is down from the
2016 stack pointer. Therefore the negation in the offset value too. */
2018 return -(offset+fp_to_sp+4);
2021 /* Return the offset value of an argument having
2022 the given offset. Basically, we correct by going from a arg pointer to
2023 stack pointer value. */
2026 romp_debugger_arg_correction (offset)
2027 int offset;
2029 int fp_to_argp;
2031 INITIAL_ELIMINATION_OFFSET (ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM,
2032 fp_to_argp);
2034 /* Actually, something different happens if offset is from a floating-point
2035 register argument, but we don't handle it here. */
2037 return (offset - fp_to_argp);