1 /* Subroutines used for code generation on ROMP.
2 Copyright (C) 1990, 1991, 1992, 1993, 1997, 1998, 1999, 2000, 2002
3 Free Software Foundation, Inc.
4 Contributed by Richard Kenner (kenner@nyu.edu)
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
28 #include "hard-reg-set.h"
30 #include "insn-config.h"
31 #include "conditions.h"
33 #include "insn-attr.h"
43 #include "target-def.h"
45 #define min(A,B) ((A) < (B) ? (A) : (B))
46 #define max(A,B) ((A) > (B) ? (A) : (B))
48 static int unsigned_comparisons_p
PARAMS ((rtx
));
49 static void output_loadsave_fpregs
PARAMS ((FILE *, enum rtx_code
, rtx
));
50 static void output_fpops
PARAMS ((FILE *));
51 static void init_fpops
PARAMS ((void));
52 static int memory_offset_in_range_p
PARAMS ((rtx
, enum machine_mode
, int, int));
53 static unsigned int hash_rtx
PARAMS ((rtx
));
54 static void romp_output_function_prologue
PARAMS ((FILE *, HOST_WIDE_INT
));
55 static void romp_output_function_epilogue
PARAMS ((FILE *, HOST_WIDE_INT
));
57 /* Initialize the GCC target structure. */
58 #undef TARGET_ASM_FUNCTION_PROLOGUE
59 #define TARGET_ASM_FUNCTION_PROLOGUE romp_output_function_prologue
60 #undef TARGET_ASM_FUNCTION_EPILOGUE
61 #define TARGET_ASM_FUNCTION_EPILOGUE romp_output_function_epilogue
63 struct gcc_target targetm
= TARGET_INITIALIZER
;
65 /* Return 1 if the insn using CC0 set by INSN does not contain
66 any unsigned tests applied to the condition codes.
68 Based on `next_insn_tests_no_inequality' in recog.c. */
71 next_insn_tests_no_unsigned (insn
)
74 register rtx next
= next_cc0_user (insn
);
78 if (find_reg_note (insn
, REG_UNUSED
, cc0_rtx
))
84 return ((GET_CODE (next
) == JUMP_INSN
85 || GET_CODE (next
) == INSN
86 || GET_CODE (next
) == CALL_INSN
)
87 && ! unsigned_comparisons_p (PATTERN (next
)));
91 unsigned_comparisons_p (x
)
94 register const char *fmt
;
96 register enum rtx_code code
= GET_CODE (x
);
114 return (XEXP (x
, 0) == cc0_rtx
|| XEXP (x
, 1) == cc0_rtx
);
119 len
= GET_RTX_LENGTH (code
);
120 fmt
= GET_RTX_FORMAT (code
);
122 for (i
= 0; i
< len
; i
++)
126 if (unsigned_comparisons_p (XEXP (x
, i
)))
129 else if (fmt
[i
] == 'E')
132 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
133 if (unsigned_comparisons_p (XVECEXP (x
, i
, j
)))
141 /* Update the condition code from the insn. Look mostly at the first
142 byte of the machine-specific insn description information.
144 cc_state.value[12] refer to two possible values that might correspond
145 to the CC. We only store register values. */
148 update_cc (body
, insn
)
149 rtx body ATTRIBUTE_UNUSED
;
152 switch (get_attr_cc (insn
))
155 /* Insn does not affect the CC at all. */
159 /* Insn doesn't affect the CC but does modify operand[0], known to be
161 if (cc_status
.value1
!= 0
162 && reg_overlap_mentioned_p (recog_data
.operand
[0], cc_status
.value1
))
163 cc_status
.value1
= 0;
165 if (cc_status
.value2
!= 0
166 && reg_overlap_mentioned_p (recog_data
.operand
[0], cc_status
.value2
))
167 cc_status
.value2
= 0;
172 /* Insn copies operand[1] to operand[0], both registers, but doesn't
174 if (cc_status
.value1
!= 0
175 && reg_overlap_mentioned_p (recog_data
.operand
[0], cc_status
.value1
))
176 cc_status
.value1
= 0;
178 if (cc_status
.value2
!= 0
179 && reg_overlap_mentioned_p (recog_data
.operand
[0], cc_status
.value2
))
180 cc_status
.value2
= 0;
182 if (cc_status
.value1
!= 0
183 && rtx_equal_p (cc_status
.value1
, recog_data
.operand
[1]))
184 cc_status
.value2
= recog_data
.operand
[0];
186 if (cc_status
.value2
!= 0
187 && rtx_equal_p (cc_status
.value2
, recog_data
.operand
[1]))
188 cc_status
.value1
= recog_data
.operand
[0];
193 /* Insn clobbers CC. */
198 /* Insn sets CC to recog_data.operand[0], but overflow is impossible. */
200 cc_status
.flags
|= CC_NO_OVERFLOW
;
201 cc_status
.value1
= recog_data
.operand
[0];
205 /* Insn is a compare which sets the CC fully. Update CC_STATUS for this
206 compare and mark whether the test will be signed or unsigned. */
208 register rtx p
= PATTERN (insn
);
212 if (GET_CODE (p
) == PARALLEL
)
213 p
= XVECEXP (p
, 0, 0);
214 cc_status
.value1
= SET_SRC (p
);
216 if (GET_CODE (SET_SRC (p
)) == REG
)
217 cc_status
.flags
|= CC_NO_OVERFLOW
;
218 if (! next_insn_tests_no_unsigned (insn
))
219 cc_status
.flags
|= CC_UNSIGNED
;
224 /* Insn sets T bit if result is non-zero. Next insn must be branch. */
226 cc_status
.flags
= CC_IN_TB
| CC_NOT_NEGATIVE
;
234 /* Return 1 if a previous compare needs to be re-issued. This will happen
235 if two compares tested the same objects, but one was signed and the
236 other unsigned. OP is the comparison operation being performed. */
239 restore_compare_p (op
)
242 enum rtx_code code
= GET_CODE (op
);
244 return (((code
== GEU
|| code
== LEU
|| code
== GTU
|| code
== LTU
)
245 && ! (cc_status
.flags
& CC_UNSIGNED
))
246 || ((code
== GE
|| code
== LE
|| code
== GT
|| code
== LT
)
247 && (cc_status
.flags
& CC_UNSIGNED
)));
250 /* Generate the (long) string corresponding to an inline multiply insn.
251 Note that `r10' does not refer to the register r10, but rather to the
252 SCR used as the MQ. */
254 output_in_line_mul ()
256 static char insns
[200];
259 strcpy (insns
, "s %0,%0\n");
260 strcat (insns
, "\tmts r10,%1\n");
261 for (i
= 0; i
< 16; i
++)
262 strcat (insns
, "\tm %0,%2\n");
263 strcat (insns
, "\tmfs r10,%0");
268 /* Returns 1 if OP is a memory reference with an offset from a register within
269 the range specified. The offset must also be a multiple of the size of the
273 memory_offset_in_range_p (op
, mode
, low
, high
)
275 enum machine_mode mode
;
280 if (! memory_operand (op
, mode
))
283 while (GET_CODE (op
) == SUBREG
)
285 offset
+= SUBREG_BYTE (op
);
286 op
= SUBREG_REG (op
);
289 /* We must now have either (mem (reg (x)), (mem (plus (reg (x)) (c))),
290 or a constant pool address. */
291 if (GET_CODE (op
) != MEM
)
294 /* Now use the actual mode and get the address. */
295 mode
= GET_MODE (op
);
297 if (GET_CODE (op
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (op
))
298 offset
= get_pool_offset (op
) + 12;
299 else if (GET_CODE (op
) == PLUS
)
301 if (GET_CODE (XEXP (op
, 1)) != CONST_INT
302 || ! register_operand (XEXP (op
, 0), Pmode
))
305 offset
+= INTVAL (XEXP (op
, 1));
308 else if (! register_operand (op
, Pmode
))
311 return (offset
>= low
&& offset
<= high
312 && (offset
% GET_MODE_SIZE (mode
) == 0));
315 /* Return 1 if OP is a valid operand for a memory reference insn that can
316 only reference indirect through a register. */
319 zero_memory_operand (op
, mode
)
321 enum machine_mode mode
;
323 return memory_offset_in_range_p (op
, mode
, 0, 0);
326 /* Return 1 if OP is a valid operand for a `short' memory reference insn. */
329 short_memory_operand (op
, mode
)
331 enum machine_mode mode
;
333 if (mode
== VOIDmode
)
334 mode
= GET_MODE (op
);
336 return memory_offset_in_range_p (op
, mode
, 0,
337 15 * min (UNITS_PER_WORD
,
338 GET_MODE_SIZE (mode
)));
341 /* Returns 1 if OP is a memory reference involving a symbolic constant
342 that is not in the constant pool. */
345 symbolic_memory_operand (op
, mode
)
347 enum machine_mode mode
;
349 if (! memory_operand (op
, mode
))
352 while (GET_CODE (op
) == SUBREG
)
353 op
= SUBREG_REG (op
);
355 if (GET_CODE (op
) != MEM
)
359 if (constant_pool_address_operand (op
, VOIDmode
))
362 return romp_symbolic_operand (op
, Pmode
)
363 || (GET_CODE (op
) == PLUS
&& register_operand (XEXP (op
, 0), Pmode
)
364 && romp_symbolic_operand (XEXP (op
, 1), Pmode
));
368 /* Returns 1 if OP is a constant pool reference to the current function. */
371 current_function_operand (op
, mode
)
373 enum machine_mode mode ATTRIBUTE_UNUSED
;
375 if (GET_CODE (op
) != MEM
|| GET_CODE (XEXP (op
, 0)) != SYMBOL_REF
376 || ! CONSTANT_POOL_ADDRESS_P (XEXP (op
, 0)))
379 op
= get_pool_constant (XEXP (op
, 0));
380 return (GET_CODE (op
) == SYMBOL_REF
381 && ! strcmp (current_function_name
, XSTR (op
, 0)));
384 /* Return non-zero if this function is known to have a null epilogue. */
389 return (reload_completed
390 && first_reg_to_save () == 16
391 && ! romp_pushes_stack ());
394 /* Returns 1 if OP is the address of a location in the constant pool. */
397 constant_pool_address_operand (op
, mode
)
399 enum machine_mode mode ATTRIBUTE_UNUSED
;
401 return ((GET_CODE (op
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (op
))
402 || (GET_CODE (op
) == CONST
&& GET_CODE (XEXP (op
, 0)) == PLUS
403 && GET_CODE (XEXP (XEXP (op
, 0), 1)) == CONST_INT
404 && GET_CODE (XEXP (XEXP (op
, 0), 0)) == SYMBOL_REF
405 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (op
, 0), 0))));
408 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
409 reference and a constant. */
412 romp_symbolic_operand (op
, mode
)
414 enum machine_mode mode ATTRIBUTE_UNUSED
;
416 switch (GET_CODE (op
))
420 return ! op
->integrated
;
424 return (GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
425 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
)
426 && GET_CODE (XEXP (op
, 1)) == CONST_INT
;
433 /* Returns 1 if OP is a valid constant for the ROMP. */
436 constant_operand (op
, mode
)
438 enum machine_mode mode
;
440 switch (GET_CODE (op
))
446 return romp_symbolic_operand (op
,mode
);
449 return (unsigned int) (INTVAL (op
) + 0x8000) < 0x10000
450 || (INTVAL (op
) & 0xffff) == 0 || (INTVAL (op
) & 0xffff0000) == 0;
457 /* Returns 1 if OP is either a constant integer valid for the ROMP or a
458 register. If a register, it must be in the proper mode unless MODE is
462 reg_or_cint_operand (op
, mode
)
464 enum machine_mode mode
;
466 if (GET_CODE (op
) == CONST_INT
)
467 return constant_operand (op
, mode
);
469 return register_operand (op
, mode
);
472 /* Return 1 is the operand is either a register or ANY constant integer. */
475 reg_or_any_cint_operand (op
, mode
)
477 enum machine_mode mode
;
479 return GET_CODE (op
) == CONST_INT
|| register_operand (op
, mode
);
482 /* Return 1 if the operand is either a register or a valid D-type operand. */
485 reg_or_D_operand (op
, mode
)
487 enum machine_mode mode
;
489 if (GET_CODE (op
) == CONST_INT
)
490 return (unsigned) (INTVAL (op
) + 0x8000) < 0x10000;
492 return register_operand (op
, mode
);
495 /* Return 1 if the operand is either a register or an item that can be
496 used as the operand of an SI add insn. */
499 reg_or_add_operand (op
, mode
)
501 enum machine_mode mode
;
503 return reg_or_D_operand (op
, mode
) || romp_symbolic_operand (op
, mode
)
504 || (GET_CODE (op
) == CONST_INT
&& (INTVAL (op
) & 0xffff) == 0);
507 /* Return 1 if the operand is either a register or an item that can be
508 used as the operand of a ROMP logical AND insn. */
511 reg_or_and_operand (op
, mode
)
513 enum machine_mode mode
;
515 if (reg_or_cint_operand (op
, mode
))
518 if (GET_CODE (op
) != CONST_INT
)
521 return (INTVAL (op
) & 0xffff) == 0xffff
522 || (INTVAL (op
) & 0xffff0000) == 0xffff0000;
525 /* Return 1 if the operand is a register or memory operand. */
528 reg_or_mem_operand (op
, mode
)
530 register enum machine_mode mode
;
532 return register_operand (op
, mode
) || memory_operand (op
, mode
);
535 /* Return 1 if the operand is either a register or a memory operand that is
539 reg_or_nonsymb_mem_operand (op
, mode
)
541 enum machine_mode mode
;
543 if (register_operand (op
, mode
))
546 if (memory_operand (op
, mode
) && ! symbolic_memory_operand (op
, mode
))
552 /* Return 1 if this operand is valid for the ROMP. This is any operand except
553 certain constant integers. */
556 romp_operand (op
, mode
)
558 enum machine_mode mode
;
560 if (GET_CODE (op
) == CONST_INT
)
561 return constant_operand (op
, mode
);
563 return general_operand (op
, mode
);
566 /* Return 1 if the operand is (reg:mode 0). */
569 reg_0_operand (op
, mode
)
571 enum machine_mode mode
;
573 return ((mode
== VOIDmode
|| mode
== GET_MODE (op
))
574 && GET_CODE (op
) == REG
&& REGNO (op
) == 0);
577 /* Return 1 if the operand is (reg:mode 15). */
580 reg_15_operand (op
, mode
)
582 enum machine_mode mode
;
584 return ((mode
== VOIDmode
|| mode
== GET_MODE (op
))
585 && GET_CODE (op
) == REG
&& REGNO (op
) == 15);
588 /* Return 1 if this is a binary floating-point operation. */
591 float_binary (op
, mode
)
593 enum machine_mode mode
;
595 if (mode
!= VOIDmode
&& mode
!= GET_MODE (op
))
598 if (GET_MODE (op
) != SFmode
&& GET_MODE (op
) != DFmode
)
601 switch (GET_CODE (op
))
607 return GET_MODE (XEXP (op
, 0)) == GET_MODE (op
)
608 && GET_MODE (XEXP (op
, 1)) == GET_MODE (op
);
615 /* Return 1 if this is a unary floating-point operation. */
618 float_unary (op
, mode
)
620 enum machine_mode mode
;
622 if (mode
!= VOIDmode
&& mode
!= GET_MODE (op
))
625 if (GET_MODE (op
) != SFmode
&& GET_MODE (op
) != DFmode
)
628 return (GET_CODE (op
) == NEG
|| GET_CODE (op
) == ABS
)
629 && GET_MODE (XEXP (op
, 0)) == GET_MODE (op
);
632 /* Return 1 if this is a valid floating-point conversion that can be done
633 as part of an operation by the RT floating-point routines. */
636 float_conversion (op
, mode
)
638 enum machine_mode mode
;
640 if (mode
!= VOIDmode
&& mode
!= GET_MODE (op
))
643 switch (GET_CODE (op
))
646 return GET_MODE (op
) == SFmode
&& GET_MODE (XEXP (op
, 0)) == DFmode
;
649 return GET_MODE (op
) == DFmode
&& GET_MODE (XEXP (op
, 0)) == SFmode
;
652 return ((GET_MODE (XEXP (op
, 0)) == SImode
653 || GET_CODE (XEXP (op
, 0)) == CONST_INT
)
654 && (GET_MODE (op
) == SFmode
|| GET_MODE (op
) == DFmode
));
657 return ((GET_MODE (op
) == SImode
658 || GET_CODE (XEXP (op
, 0)) == CONST_INT
)
659 && (GET_MODE (XEXP (op
, 0)) == SFmode
660 || GET_MODE (XEXP (op
, 0)) == DFmode
));
667 /* Print an operand. Recognize special options, documented below. */
670 print_operand (file
, x
, code
)
680 /* Byte number (const/8) */
681 if (GET_CODE (x
) != CONST_INT
)
682 output_operand_lossage ("invalid %%B value");
684 fprintf (file
, "%d", INTVAL (x
) / 8);
688 /* Low order 16 bits of constant. */
689 if (GET_CODE (x
) != CONST_INT
)
690 output_operand_lossage ("invalid %%L value");
692 fprintf (file
, "%d", INTVAL (x
) & 0xffff);
696 /* Null or "16" depending on whether the constant is greater than 16. */
697 if (GET_CODE (x
) != CONST_INT
)
698 output_operand_lossage ("invalid %%s value");
700 if (INTVAL (x
) >= 16)
701 fprintf (file
, "16");
706 /* For shifts: 's' will have given the half. Just give the amount
708 if (GET_CODE (x
) != CONST_INT
)
709 output_operand_lossage ("invalid %%S value");
711 fprintf (file
, "%d", INTVAL (x
) & 15);
715 /* The number of a single bit set or cleared, mod 16. Note that the ROMP
716 numbers bits with the high-order bit 31. */
717 if (GET_CODE (x
) != CONST_INT
)
718 output_operand_lossage ("invalid %%b value");
720 if ((i
= exact_log2 (INTVAL (x
))) >= 0)
721 fprintf (file
, "%d", (31 - i
) % 16);
722 else if ((i
= exact_log2 (~ INTVAL (x
))) >= 0)
723 fprintf (file
, "%d", (31 - i
) % 16);
725 output_operand_lossage ("invalid %%b value");
730 /* "l" or "u" depending on which half of the constant is zero. */
731 if (GET_CODE (x
) != CONST_INT
)
732 output_operand_lossage ("invalid %%h value");
734 if ((INTVAL (x
) & 0xffff0000) == 0)
736 else if ((INTVAL (x
) & 0xffff) == 0)
739 output_operand_lossage ("invalid %%h value");
744 /* Upper or lower half, depending on which half is zero. */
745 if (GET_CODE (x
) != CONST_INT
)
746 output_operand_lossage ("invalid %%H value");
748 if ((INTVAL (x
) & 0xffff0000) == 0)
749 fprintf (file
, "%d", INTVAL (x
) & 0xffff);
750 else if ((INTVAL (x
) & 0xffff) == 0)
751 fprintf (file
, "%d", (INTVAL (x
) >> 16) & 0xffff);
753 output_operand_lossage ("invalid %%H value");
758 /* Write two characters:
759 'lo' if the high order part is all ones
760 'lz' if the high order part is all zeros
761 'uo' if the low order part is all ones
762 'uz' if the low order part is all zeros
764 if (GET_CODE (x
) != CONST_INT
)
765 output_operand_lossage ("invalid %%z value");
767 if ((INTVAL (x
) & 0xffff0000) == 0)
768 fprintf (file
, "lz");
769 else if ((INTVAL (x
) & 0xffff0000) == 0xffff0000)
770 fprintf (file
, "lo");
771 else if ((INTVAL (x
) & 0xffff) == 0)
772 fprintf (file
, "uz");
773 else if ((INTVAL (x
) & 0xffff) == 0xffff)
774 fprintf (file
, "uo");
776 output_operand_lossage ("invalid %%z value");
781 /* Upper or lower half, depending on which is non-zero or not
782 all ones. Must be consistent with 'z' above. */
783 if (GET_CODE (x
) != CONST_INT
)
784 output_operand_lossage ("invalid %%Z value");
786 if ((INTVAL (x
) & 0xffff0000) == 0
787 || (INTVAL (x
) & 0xffff0000) == 0xffff0000)
788 fprintf (file
, "%d", INTVAL (x
) & 0xffff);
789 else if ((INTVAL (x
) & 0xffff) == 0 || (INTVAL (x
) & 0xffff) == 0xffff)
790 fprintf (file
, "%d", (INTVAL (x
) >> 16) & 0xffff);
792 output_operand_lossage ("invalid %%Z value");
797 /* Same as 'z', except the trailing 'o' or 'z' is not written. */
798 if (GET_CODE (x
) != CONST_INT
)
799 output_operand_lossage ("invalid %%k value");
801 if ((INTVAL (x
) & 0xffff0000) == 0
802 || (INTVAL (x
) & 0xffff0000) == 0xffff0000)
804 else if ((INTVAL (x
) & 0xffff) == 0
805 || (INTVAL (x
) & 0xffff) == 0xffff)
808 output_operand_lossage ("invalid %%k value");
813 /* Similar to 's', except that we write 'h' or 'u'. */
814 if (GET_CODE (x
) != CONST_INT
)
815 output_operand_lossage ("invalid %%k value");
824 /* For memory operations, write 's' if the operand is a short
826 if (short_memory_operand (x
, VOIDmode
))
831 /* Like 'M', but check for zero memory offset. */
832 if (zero_memory_operand (x
, VOIDmode
))
837 /* Write low-order part of DImode or DFmode. Supported for MEM
839 if (GET_CODE (x
) == REG
)
840 fprintf (file
, "%s", reg_names
[REGNO (x
) + 1]);
841 else if (GET_CODE (x
) == MEM
)
842 print_operand (file
, gen_rtx_MEM (GET_MODE (x
),
843 plus_constant (XEXP (x
, 0), 4)), 0);
849 /* Offset in constant pool for constant pool address. */
850 if (! constant_pool_address_operand (x
, VOIDmode
))
852 if (GET_CODE (x
) == SYMBOL_REF
)
853 fprintf (file
, "%d", get_pool_offset (x
) + 12);
855 /* Must be (const (plus (symbol_ref) (const_int))) */
857 (get_pool_offset (XEXP (XEXP (x
, 0), 0)) + 12
858 + INTVAL (XEXP (XEXP (x
, 0), 1))));
862 /* Branch opcode. Check for condition in test bit for eq/ne. */
863 switch (GET_CODE (x
))
866 if (cc_status
.flags
& CC_IN_TB
)
867 fprintf (file
, "ntb");
869 fprintf (file
, "eq");
873 if (cc_status
.flags
& CC_IN_TB
)
874 fprintf (file
, "tb");
876 fprintf (file
, "ne");
891 fprintf (file
, "he");
896 fprintf (file
, "le");
900 output_operand_lossage ("invalid %%j value");
905 /* Reversed branch opcode. */
906 switch (GET_CODE (x
))
909 if (cc_status
.flags
& CC_IN_TB
)
910 fprintf (file
, "tb");
912 fprintf (file
, "ne");
916 if (cc_status
.flags
& CC_IN_TB
)
917 fprintf (file
, "ntb");
919 fprintf (file
, "eq");
924 fprintf (file
, "le");
929 fprintf (file
, "he");
943 output_operand_lossage ("invalid %%j value");
948 /* Output nothing. Used as delimiter in, e.g., "mc%B1%.3 " */
952 /* Output 'x' if this insn has a delay slot, else nothing. */
953 if (dbr_sequence_length ())
958 if (GET_CODE (x
) == REG
)
959 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
960 else if (GET_CODE (x
) == MEM
)
962 if (GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
963 && current_function_operand (x
, Pmode
))
964 fprintf (file
, "r14");
966 output_address (XEXP (x
, 0));
969 output_addr_const (file
, x
);
973 output_operand_lossage ("invalid %%xn code");
977 /* This page contains routines that are used to determine what the function
978 prologue and epilogue code will do and write them out. */
980 /* Return the first register that is required to be saved. 16 if none. */
987 /* Find lowest numbered live register. */
988 for (first_reg
= 6; first_reg
<= 15; first_reg
++)
989 if (regs_ever_live
[first_reg
])
992 /* If we think that we do not have to save r14, see if it will be used
994 if (first_reg
> 14 && romp_using_r14 ())
1000 /* Compute the size of the save area in the stack, including the space for
1001 the first four incoming arguments. */
1009 /* We have the 4 words corresponding to the arguments passed in registers,
1010 4 reserved words, space for static chain, general register save area,
1011 and floating-point save area. */
1012 size
= 4 + 4 + 1 + (16 - first_reg_to_save ());
1014 /* The documentation says we have to leave 18 words in the save area if
1015 any floating-point registers at all are saved, not the three words
1016 per register you might otherwise expect. */
1017 for (i
= 2 + (TARGET_FP_REGS
!= 0); i
<= 7; i
++)
1018 if (regs_ever_live
[i
+ 17])
1027 /* Return non-zero if this function makes calls or has fp operations
1028 (which are really calls). */
1035 for (insn
= get_insns (); insn
; insn
= next_insn (insn
))
1037 if (GET_CODE (insn
) == CALL_INSN
)
1039 else if (GET_CODE (insn
) == INSN
)
1041 rtx body
= PATTERN (insn
);
1043 if (GET_CODE (body
) != USE
&& GET_CODE (body
) != CLOBBER
1044 && GET_CODE (body
) != ADDR_VEC
1045 && GET_CODE (body
) != ADDR_DIFF_VEC
1046 && get_attr_type (insn
) == TYPE_FP
)
1054 /* Return non-zero if this function will use r14 as a pointer to its
1060 /* If we are debugging, profiling, have a non-empty constant pool, or
1061 call a function, we need r14. */
1062 return (write_symbols
!= NO_DEBUG
|| current_function_profile
1063 || get_pool_size () != 0 || romp_makes_calls ());
1066 /* Return non-zero if this function needs to push space on the stack. */
1069 romp_pushes_stack ()
1071 /* We need to push the stack if a frame pointer is needed (because the
1072 stack might be dynamically adjusted), if we are debugging, if the
1073 total required size is more than 100 bytes, or if we make calls. */
1075 return (frame_pointer_needed
|| write_symbols
!= NO_DEBUG
1076 || (romp_sa_size () + get_frame_size ()) > 100
1077 || romp_makes_calls ());
1080 /* Write function prologue.
1082 We compute the size of the fixed area required as follows:
1084 We always allocate 4 words for incoming arguments, 4 word reserved, 1
1085 word for static link, as many words as required for general register
1086 save area, plus 2 words for each FP reg 2-7 that must be saved. */
1089 romp_output_function_prologue (file
, size
)
1094 int reg_save_offset
;
1095 HOST_WIDE_INT fp_save
= size
+ current_function_outgoing_args_size
;
1099 /* Add in fixed size plus output argument area. */
1100 size
+= romp_sa_size () + current_function_outgoing_args_size
;
1102 /* Compute first register to save and perform the save operation if anything
1103 needs to be saved. */
1104 first_reg
= first_reg_to_save();
1105 reg_save_offset
= - (4 + 4 + 1 + (16 - first_reg
)) * 4;
1106 if (first_reg
== 15)
1107 fprintf (file
, "\tst r15,%d(r1)\n", reg_save_offset
);
1108 else if (first_reg
< 16)
1109 fprintf (file
, "\tstm r%d,%d(r1)\n", first_reg
, reg_save_offset
);
1111 /* Set up pointer to data area if it is needed. */
1112 if (romp_using_r14 ())
1113 fprintf (file
, "\tcas r14,r0,r0\n");
1115 /* Set up frame pointer if needed. */
1116 if (frame_pointer_needed
)
1117 fprintf (file
, "\tcal r13,-%d(r1)\n", romp_sa_size () + 64);
1119 /* Push stack if neeeded. There are a couple of ways of doing this. */
1120 if (romp_pushes_stack ())
1126 fprintf (file
, "\tcau r0,%d(r0)\n", size
>> 16);
1127 fprintf (file
, "\toil r0,r0,%d\n", size
& 0xffff);
1130 fprintf (file
, "\tcal16 r0,%d(r0)\n", size
);
1131 fprintf (file
, "\ts r1,r0\n");
1134 fprintf (file
, "\tcal r1,-%d(r1)\n", size
);
1137 /* Save floating-point registers. */
1138 output_loadsave_fpregs (file
, USE
,
1139 plus_constant (stack_pointer_rtx
, fp_save
));
1142 /* Output the offset information used by debuggers.
1143 This is the exactly the total_size value of output_function_epilogue()
1144 which is added to the frame pointer. However the value in the debug
1145 table is encoded in a space-saving way as follows:
1147 The first byte contains two fields: a 2-bit size field and the first
1148 6 bits of an offset value. The 2-bit size field is in the high-order
1149 position and specifies how many subsequent bytes follow after
1150 this one. An offset value is at most 4-bytes long.
1152 The last 6 bits of the first byte initialize the offset value. In many
1153 cases where procedures have small local storage, this is enough and, in
1154 this case, the high-order size field is zero so the byte can (almost) be
1155 used as is (see below). Thus, the byte value of 0x0d is encodes an offset
1156 size of 13 words, or 52 bytes.
1158 For procedures with a local space larger than 60 bytes, the 6 bits
1159 are the high-order 6 bits. The remaining bytes follow as necessary,
1160 in Big Endian order. Thus, the short value of 16907 (= 16384+523)
1161 encodes an offset of 2092 bytes (523 words).
1163 The total offset value is in words (not bytes), so the final value has to
1164 be multiplied by 4 before it can be used in address computations by a
1168 output_encoded_offset (file
, reg_offset
)
1170 unsigned reg_offset
;
1172 /* Convert the offset value to 4-byte words rather than bytes. */
1173 reg_offset
= (reg_offset
+ 3) / 4;
1175 /* Now output 1-4 bytes in encoded form. */
1176 if (reg_offset
< (1 << 6))
1177 /* Fits into one byte */
1178 fprintf (file
, "\t.byte %d\n", reg_offset
);
1179 else if (reg_offset
< (1 << (6 + 8)))
1180 /* Fits into two bytes */
1181 fprintf (file
, "\t.short %d\n", (1 << (6 + 8)) + reg_offset
);
1182 else if (reg_offset
< (1 << (6 + 8 + 8)))
1184 /* Fits in three bytes */
1185 fprintf (file
, "\t.byte %d\n", (2 << 6) + (reg_offset
>> ( 6+ 8)));
1186 fprintf (file
, "\t.short %d\n", reg_offset
% (1 << (6 + 8)));
1191 fprintf (file
, "\t.short %d", (3 << (6 + 8)) + (reg_offset
>> (6 + 8)));
1192 fprintf (file
, "\t.short %d\n", reg_offset
% (1 << (6 + 8)));
1196 /* Write function epilogue. */
1199 romp_output_function_epilogue (file
, size
)
1203 int first_reg
= first_reg_to_save();
1204 int pushes_stack
= romp_pushes_stack ();
1205 int reg_save_offset
= - ((16 - first_reg
) + 1 + 4 + 4) * 4;
1206 HOST_WIDE_INT total_size
= (size
+ romp_sa_size ()
1207 + current_function_outgoing_args_size
);
1208 HOST_WIDE_INT fp_save
= size
+ current_function_outgoing_args_size
;
1209 int long_frame
= total_size
>= 32768;
1210 rtx insn
= get_last_insn ();
1213 int nargs
= 0; /* words of arguments */
1216 /* Compute the number of words of arguments. Since this is just for
1217 the traceback table, we ignore arguments that don't have a size or
1218 don't have a fixed size. */
1220 for (argptr
= DECL_ARGUMENTS (current_function_decl
);
1221 argptr
; argptr
= TREE_CHAIN (argptr
))
1223 int this_size
= int_size_in_bytes (TREE_TYPE (argptr
));
1226 nargs
+= (this_size
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
1229 /* If the last insn was a BARRIER, we don't have to write anything except
1231 if (GET_CODE (insn
) == NOTE
)
1232 insn
= prev_nonnote_insn (insn
);
1233 if (insn
&& GET_CODE (insn
) == BARRIER
)
1236 /* Restore floating-point registers. */
1238 output_loadsave_fpregs (file
, CLOBBER
,
1239 plus_constant (gen_rtx_REG (Pmode
, 1), fp_save
));
1241 /* If we push the stack and do not have size > 32K, adjust the register
1242 save location to the current position of sp. Otherwise, if long frame,
1243 restore sp from fp. */
1244 if (pushes_stack
&& ! long_frame
)
1245 reg_save_offset
+= total_size
;
1246 else if (long_frame
&& write_code
)
1247 fprintf (file
, "\tcal r1,%d(r13)\n", romp_sa_size () + 64);
1249 /* Restore registers. */
1250 if (first_reg
== 15 && write_code
)
1251 fprintf (file
, "\tl r15,%d(r1)\n", reg_save_offset
);
1252 else if (first_reg
< 16 && write_code
)
1253 fprintf (file
, "\tlm r%d,%d(r1)\n", first_reg
, reg_save_offset
);
1254 if (first_reg
== 16) first_reg
= 0;
1256 /* Handle popping stack, if needed and write debug table entry. */
1262 fprintf (file
, "\tbr r15\n");
1264 fprintf (file
, "\tbrx r15\n\tcal r1,%d(r1)\n", total_size
);
1267 /* Table header (0xdf), usual-type stack frame (0x07),
1268 table header (0xdf), and first register saved.
1270 The final 0x08 means that there is a byte following this one
1271 describing the number of parameter words and the register used as
1274 If GCC passed floating-point parameters in floating-point registers,
1275 it would be necessary to change the final byte from 0x08 to 0x0c.
1276 Also an additional entry byte would be need to be emitted to specify
1277 the first floating-point register.
1279 (See also Section 11 (Trace Tables) in ``IBM/4.3 Linkage Convention,''
1280 pages IBM/4.3-PSD:5-7 of Volume III of the IBM Academic Operating
1281 System Manual dated July 1987.) */
1283 fprintf (file
, "\t.long 0x%x\n", 0xdf07df08 + first_reg
* 0x10);
1285 if (nargs
> 15) nargs
= 15;
1287 /* The number of parameter words and the register used as the stack
1288 pointer (encoded here as r1).
1290 Note: The MetWare Hich C Compiler R2.1y actually gets this wrong;
1291 it erroneously lists r13 but uses r1 as the stack too. But a bug in
1292 dbx 1.5 nullifies this mistake---most of the time.
1293 (Dbx retrieves the value of r13 saved on the stack which is often
1294 the value of r1 before the call.) */
1296 fprintf (file
, "\t.byte 0x%x1\n", nargs
);
1297 output_encoded_offset (file
, total_size
);
1302 fprintf (file
, "\tbr r15\n");
1304 /* Table header (0xdf), no stack frame (0x02),
1305 table header (0xdf) and no parameters saved (0x00).
1307 If GCC passed floating-point parameters in floating-point registers,
1308 it might be necessary to change the final byte from 0x00 to 0x04.
1309 Also a byte would be needed to specify the first floating-point
1311 fprintf (file
, "\t.long 0xdf02df00\n");
1314 /* Output any pending floating-point operations. */
1315 output_fpops (file
);
1318 /* For the ROMP we need to make new SYMBOL_REFs for the actual name of a
1319 called routine. To keep them unique we maintain a hash table of all
1320 that have been created so far. */
1322 struct symref_hashent
{
1323 rtx symref
; /* Created SYMBOL_REF rtx. */
1324 struct symref_hashent
*next
; /* Next with same hash code. */
1327 #define SYMHASHSIZE 151
1328 #define HASHBITS 65535
1330 /* Define the hash table itself. */
1332 static struct symref_hashent
*symref_hash_table
[SYMHASHSIZE
];
1334 /* Given a name (allocable in temporary storage), return a SYMBOL_REF
1335 for the name. The rtx is allocated from the current rtl_obstack, while
1336 the name string is allocated from the permanent obstack. */
1339 register const char *name
;
1341 extern struct obstack permanent_obstack
;
1342 register const char *sp
= name
;
1343 unsigned int hash
= 0;
1344 struct symref_hashent
*p
, **last_p
;
1346 /* Compute the hash code for the string. */
1348 hash
= (hash
<< 4) + *sp
++;
1350 /* Search for a matching entry in the hash table, keeping track of the
1351 insertion location as we do so. */
1352 hash
= (hash
& HASHBITS
) % SYMHASHSIZE
;
1353 for (last_p
= &symref_hash_table
[hash
], p
= *last_p
;
1354 p
; last_p
= &p
->next
, p
= *last_p
)
1355 if (strcmp (name
, XSTR (p
->symref
, 0)) == 0)
1358 /* If couldn't find matching SYMBOL_REF, make a new one. */
1361 /* Ensure SYMBOL_REF will stay around. */
1362 p
= *last_p
= (struct symref_hashent
*)
1363 permalloc (sizeof (struct symref_hashent
));
1364 p
->symref
= gen_rtx_SYMBOL_REF (Pmode
,
1365 obstack_copy0 (&permanent_obstack
,
1366 name
, strlen (name
)));
1373 /* Validate the precision of a floating-point operation.
1375 We merge conversions from integers and between floating-point modes into
1376 the insn. However, this must not effect the desired precision of the
1377 insn. The RT floating-point system uses the widest of the operand modes.
1378 If this should be a double-precision insn, ensure that one operand
1379 passed to the floating-point processor has double mode.
1381 Note that since we don't check anything if the mode is single precision,
1382 it, strictly speaking, isn't necessary to call this for those insns.
1383 However, we do so in case something else needs to be checked in the
1386 This routine returns 1 if the operation is OK. */
1389 check_precision (opmode
, op1
, op2
)
1390 enum machine_mode opmode
;
1393 if (opmode
== SFmode
)
1396 /* If operand is not a conversion from an integer mode or an extension from
1397 single-precision, it must be a double-precision value. */
1398 if (GET_CODE (op1
) != FLOAT
&& GET_CODE (op1
) != FLOAT_EXTEND
)
1401 if (op2
&& GET_CODE (op2
) != FLOAT
&& GET_CODE (op2
) != FLOAT_EXTEND
)
1407 /* Floating-point on the RT is done by creating an operation block in the data
1408 area that describes the operation. If two floating-point operations are the
1409 same in a single function, they can use the same block.
1411 These routines are responsible for managing these blocks. */
1413 /* Structure to describe a floating-point operation. */
1416 struct fp_op
*next_same_hash
; /* Next op with same hash code. */
1417 struct fp_op
*next_in_mem
; /* Next op in memory. */
1418 int mem_offset
; /* Offset from data area. */
1419 short size
; /* Size of block in bytes. */
1420 short noperands
; /* Number of operands in block. */
1421 rtx ops
[3]; /* RTL for operands. */
1422 enum rtx_code opcode
; /* Operation being performed. */
1425 /* Size of hash table. */
1426 #define FP_HASH_SIZE 101
1428 /* Hash table of floating-point operation blocks. */
1429 static struct fp_op
*fp_hash_table
[FP_HASH_SIZE
];
1431 /* First floating-point block in data area. */
1432 static struct fp_op
*first_fpop
;
1434 /* Last block in data area so far. */
1435 static struct fp_op
*last_fpop_in_mem
;
1437 /* Subroutine number in file, to get unique "LF" labels. */
1438 static int subr_number
= 0;
1440 /* Current word offset in data area (includes header and any constant pool). */
1443 /* Compute hash code for an RTX used in floating-point. */
1449 register unsigned int hash
= (((int) GET_CODE (x
) << 10)
1450 + ((int) GET_MODE (x
) << 20));
1452 register const char *fmt
= GET_RTX_FORMAT (GET_CODE (x
));
1454 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (x
)); i
++)
1456 hash
+= hash_rtx (XEXP (x
, i
));
1457 else if (fmt
[i
] == 'u')
1458 hash
+= (unsigned HOST_WIDE_INT
) XEXP (x
, i
);
1459 else if (fmt
[i
] == 'i')
1460 hash
+= XINT (x
, i
);
1461 else if (fmt
[i
] == 's')
1462 hash
+= (unsigned HOST_WIDE_INT
) XSTR (x
, i
);
1467 /* Given an operation code and up to three operands, return a character string
1468 corresponding to the code to emit to branch to a floating-point operation
1469 block. INSN is provided to see if the delay slot has been filled or not.
1471 A new floating-point operation block is created if this operation has not
1472 been seen before. */
1475 output_fpop (code
, op0
, op1
, op2
, insn
)
1478 rtx insn ATTRIBUTE_UNUSED
;
1480 static char outbuf
[40];
1481 unsigned int hash
, hash0
, hash1
, hash2
;
1483 register struct fp_op
*fpop
, *last_fpop
;
1484 int dyadic
= (op2
!= 0);
1485 enum machine_mode opmode
;
1488 unsigned int tem_hash
;
1491 /* Compute hash code for each operand. If the operation is commutative,
1492 put the one with the smaller hash code first. This will make us see
1493 more operations as identical. */
1494 hash0
= op0
? hash_rtx (op0
) : 0;
1495 hash1
= op1
? hash_rtx (op1
) : 0;
1496 hash2
= op2
? hash_rtx (op2
) : 0;
1498 if (hash0
> hash1
&& code
== EQ
)
1500 tem
= op0
; op0
= op1
; op1
= tem
;
1501 tem_hash
= hash0
; hash0
= hash1
; hash1
= tem_hash
;
1503 else if (hash1
> hash2
&& (code
== PLUS
|| code
== MULT
))
1505 tem
= op1
; op1
= op2
; op2
= tem
;
1506 tem_hash
= hash1
; hash1
= hash2
; hash2
= tem_hash
;
1509 /* If operation is commutative and the first and third operands are equal,
1510 swap the second and third operands. Note that we must consider two
1511 operands equal if they are the same register even if different modes. */
1512 if (op2
&& (code
== PLUS
|| code
== MULT
)
1513 && (rtx_equal_p (op0
, op2
)
1514 || (GET_CODE (op0
) == REG
&& GET_CODE (op2
) == REG
1515 && REGNO (op0
) == REGNO (op2
))))
1517 tem
= op1
; op1
= op2
; op2
= tem
;
1518 tem_hash
= hash1
; hash1
= hash2
; hash2
= tem_hash
;
1521 /* If the first and second operands are the same, merge them. Don't do this
1522 for SFmode or SImode in general registers because this triggers a bug in
1524 if (op1
&& rtx_equal_p (op0
, op1
)
1525 && code
!= EQ
&& code
!= GE
&& code
!= SET
1526 && ((GET_MODE (op1
) != SFmode
&& GET_MODE (op1
) != SImode
)
1527 || GET_CODE (op0
) != REG
|| FP_REGNO_P (REGNO (op0
))))
1533 noperands
= 1 + (op1
!= 0) + (op2
!= 0);
1535 /* Compute hash code for entire expression and see if operation block
1537 hash
= ((int) code
<< 13) + (hash0
<< 2) + (hash1
<< 1) + hash2
;
1539 hash
%= FP_HASH_SIZE
;
1540 for (fpop
= fp_hash_table
[hash
], last_fpop
= 0;
1542 last_fpop
= fpop
, fpop
= fpop
->next_same_hash
)
1543 if (fpop
->opcode
== code
&& noperands
== fpop
->noperands
1544 && (op0
== 0 || rtx_equal_p (op0
, fpop
->ops
[0]))
1545 && (op1
== 0 || rtx_equal_p (op1
, fpop
->ops
[1]))
1546 && (op2
== 0 || rtx_equal_p (op2
, fpop
->ops
[2])))
1549 /* We have never seen this operation before. */
1550 fpop
= (struct fp_op
*) xmalloc (sizeof (struct fp_op
));
1551 fpop
->mem_offset
= data_offset
;
1552 fpop
->opcode
= code
;
1553 fpop
->noperands
= noperands
;
1558 /* Compute the size using the rules in Appendix A of the RT Linkage
1559 Convention (4.3/RT-PSD:5) manual. These rules are a bit ambiguous,
1560 but if we guess wrong, it will effect only efficiency, not correctness. */
1562 /* Size = 24 + 32 for each non-fp (or fr7) */
1564 if (op0
&& (GET_CODE (op0
) != REG
1565 || ! FP_REGNO_P (REGNO (op0
)) || REGNO (op0
) == 23))
1568 if (op1
&& (GET_CODE (op1
) != REG
1569 || ! FP_REGNO_P (REGNO (op1
)) || REGNO (op1
) == 23))
1572 if (op2
&& (GET_CODE (op2
) != REG
1573 || ! FP_REGNO_P (REGNO (op2
)) || REGNO (op2
) == 23))
1576 /* Size + 12 for each conversion. First get operation mode. */
1577 if ((op0
&& GET_MODE (op0
) == DFmode
)
1578 || (op1
&& GET_MODE (op1
) == DFmode
)
1579 || (op2
&& GET_MODE (op2
) == DFmode
))
1584 if (op0
&& GET_MODE (op0
) != opmode
)
1586 if (op1
&& GET_MODE (op1
) != opmode
)
1588 if (op2
&& GET_MODE (op2
) != opmode
)
1591 /* 12 more if first and third operand types not the same. */
1592 if (op2
&& GET_MODE (op0
) != GET_MODE (op2
))
1595 /* CMP and CMPT need additional. Also, compute size of save/restore here. */
1598 else if (code
== GE
)
1600 else if (code
== USE
|| code
== CLOBBER
)
1602 /* 34 + 24 for each additional register plus 8 if fr7 saved. (We
1603 call it 36 because we need to keep the block length a multiple
1606 for (i
= 0; i
<= 7; i
++)
1607 if (INTVAL (op0
) & (1 << (7-i
)))
1608 size
+= 24 + 8 * (i
== 7);
1611 /* We provide no general-purpose scratch registers. */
1614 /* No floating-point scratch registers are provided. Compute extra
1615 length due to this. This logic is that shown in the referenced
1619 if (op0
&& GET_CODE (op0
) == REG
&& FP_REGNO_P (REGNO (op0
)))
1621 if (op1
&& GET_CODE (op1
) == REG
&& FP_REGNO_P (REGNO (op1
)))
1623 if (op2
&& GET_CODE (op2
) == REG
&& FP_REGNO_P (REGNO (op2
)))
1626 if ((op0
== 0 || GET_CODE (op0
) != REG
|| REGNO(op0
) != 17)
1627 && (op1
== 0 || GET_CODE (op1
) != REG
|| REGNO(op1
) != 17)
1628 && (op2
== 0 || GET_CODE (op2
) != REG
|| REGNO(op2
) != 17))
1634 size
+= fr0_avail
? 64 : 112;
1635 else if (fpop
->noperands
== 2 && i
== 1)
1636 size
+= fr0_avail
? 0 : 64;
1637 else if (fpop
->noperands
== 3)
1639 if (GET_CODE (op0
) == REG
&& FP_REGNO_P (REGNO (op0
))
1640 && GET_CODE (op2
) == REG
&& FP_REGNO_P (REGNO (op2
)))
1642 if (REGNO (op0
) == REGNO (op2
))
1644 /* This triggers a bug on the RT. */
1647 size
+= fr0_avail
? 0 : 64;
1653 if (GET_CODE (op0
) == REG
&& FP_REGNO_P (REGNO (op0
)))
1655 if (GET_CODE (op2
) == REG
&& FP_REGNO_P (REGNO (op2
)))
1658 size
+= fr0_avail
? 64 : 112;
1660 size
+= fr0_avail
? 0 : 64;
1664 else if (code
!= USE
&& code
!= CLOBBER
1665 && (GET_CODE (op0
) != REG
|| ! FP_REGNO_P (REGNO (op0
))))
1668 if (! TARGET_FULL_FP_BLOCKS
)
1670 /* If we are not to pad the blocks, just compute its actual length. */
1671 size
= 12; /* Header + opcode */
1672 if (code
== USE
|| code
== CLOBBER
)
1681 /* If in the middle of a word, round. */
1682 if (size
% UNITS_PER_WORD
)
1685 /* Handle any immediates. */
1686 if (code
!= USE
&& code
!= CLOBBER
&& op0
&& GET_CODE (op0
) != REG
)
1688 if (op1
&& GET_CODE (op1
) != REG
)
1690 if (op2
&& GET_CODE (op2
) != REG
)
1693 if (code
!= USE
&& code
!= CLOBBER
&&
1694 op0
&& GET_CODE (op0
) == CONST_DOUBLE
&& GET_MODE (op0
) == DFmode
)
1696 if (op1
&& GET_CODE (op1
) == CONST_DOUBLE
&& GET_MODE (op1
) == DFmode
)
1698 if (op2
&& GET_CODE (op2
) == CONST_DOUBLE
&& GET_MODE (op2
) == DFmode
)
1702 /* Done with size computation! Chain this in. */
1704 data_offset
+= size
/ UNITS_PER_WORD
;
1705 fpop
->next_in_mem
= 0;
1706 fpop
->next_same_hash
= 0;
1708 if (last_fpop_in_mem
)
1709 last_fpop_in_mem
->next_in_mem
= fpop
;
1712 last_fpop_in_mem
= fpop
;
1715 last_fpop
->next_same_hash
= fpop
;
1717 fp_hash_table
[hash
] = fpop
;
1720 /* FPOP describes the operation to be performed. Return a string to branch
1722 if (fpop
->mem_offset
< 32768 / UNITS_PER_WORD
)
1723 sprintf (outbuf
, "cal r15,%d(r14)\n\tbalr%s r15,r15",
1724 fpop
->mem_offset
* UNITS_PER_WORD
,
1725 dbr_sequence_length () ? "x" : "");
1727 sprintf (outbuf
, "get r15,$L%dF%d\n\tbalr%s r15,r15",
1728 subr_number
, fpop
->mem_offset
* UNITS_PER_WORD
,
1729 dbr_sequence_length () ? "x" : "");
1733 /* If necessary, output a floating-point operation to save or restore all
1734 floating-point registers.
1736 file is the file to write the operation to, CODE is USE for save, CLOBBER
1737 for restore, and ADDR is the address of the same area, as RTL. */
1740 output_loadsave_fpregs (file
, code
, addr
)
1746 register int mask
= 0;
1748 for (i
= 2 + (TARGET_FP_REGS
!= 0); i
<= 7; i
++)
1749 if (regs_ever_live
[i
+ 17])
1750 mask
|= 1 << (7 - i
);
1753 fprintf (file
, "\t%s\n",
1754 output_fpop (code
, GEN_INT (mask
), gen_rtx_MEM (Pmode
, addr
),
1759 /* Output any floating-point operations at the end of the routine. */
1765 register struct fp_op
*fpop
;
1766 register int size_so_far
;
1770 if (first_fpop
== 0)
1775 ASM_OUTPUT_ALIGN (file
, 2);
1777 for (fpop
= first_fpop
; fpop
; fpop
= fpop
->next_in_mem
)
1779 if (fpop
->mem_offset
< 32768 / UNITS_PER_WORD
)
1780 fprintf (file
, "# data area offset = %d\n",
1781 fpop
->mem_offset
* UNITS_PER_WORD
);
1783 fprintf (file
, "L%dF%d:\n",
1784 subr_number
, fpop
->mem_offset
* UNITS_PER_WORD
);
1786 fprintf (file
, "\tcas r0,r15,r0\n");
1787 fprintf (file
, "\t.long FPGLUE\n");
1788 switch (fpop
->opcode
)
1791 fprintf (file
, "\t.byte 0x1d\t# STOREM\n");
1794 fprintf (file
, "\t.byte 0x0f\t# LOADM\n");
1797 fprintf (file
, "\t.byte 0x00\t# ABS\n");
1800 fprintf (file
, "\t.byte 0x02\t# ADD\n");
1803 fprintf (file
, "\t.byte 0x07\t# CMP\n");
1806 fprintf (file
, "\t.byte 0x08\t# CMPT\n");
1809 fprintf (file
, "\t.byte 0x0c\t# DIV\n");
1812 fprintf (file
, "\t.byte 0x14\t# MOVE\n");
1815 fprintf (file
, "\t.byte 0x15\t# MUL\n");
1818 fprintf (file
, "\t.byte 0x16\t# NEG\n");
1821 fprintf (file
, "\t.byte 0x1c\t# SQRT\n");
1824 fprintf (file
, "\t.byte 0x1e\t# SUB\n");
1830 fprintf (file
, "\t.byte %d\n", fpop
->noperands
);
1831 fprintf (file
, "\t.short 0x8001\n");
1833 if ((fpop
->ops
[0] == 0
1834 || GET_CODE (fpop
->ops
[0]) != REG
|| REGNO(fpop
->ops
[0]) != 17)
1835 && (fpop
->ops
[1] == 0 || GET_CODE (fpop
->ops
[1]) != REG
1836 || REGNO(fpop
->ops
[1]) != 17)
1837 && (fpop
->ops
[2] == 0 || GET_CODE (fpop
->ops
[2]) != REG
1838 || REGNO(fpop
->ops
[2]) != 17))
1839 fprintf (file
, "\t.byte %d, 0x80\n", fpop
->size
);
1841 fprintf (file
, "\t.byte %d, 0\n", fpop
->size
);
1843 for (i
= 0; i
< fpop
->noperands
; i
++)
1846 register int opbyte
;
1847 register const char *desc0
;
1851 switch (GET_MODE (fpop
->ops
[i
]))
1870 switch (GET_CODE (fpop
->ops
[i
]))
1873 strcpy(desc1
, reg_names
[REGNO (fpop
->ops
[i
])]);
1874 if (FP_REGNO_P (REGNO (fpop
->ops
[i
])))
1877 opbyte
= REGNO (fpop
->ops
[i
]) - 17;
1882 opbyte
= REGNO (fpop
->ops
[i
]);
1884 opbyte
= (opbyte
<< 4) + opbyte
+ 1;
1890 if (GET_CODE (XEXP (fpop
->ops
[i
], 0)) == PLUS
)
1892 immed
[i
] = XEXP (XEXP (fpop
->ops
[i
], 0), 1);
1893 opbyte
= REGNO (XEXP (XEXP (fpop
->ops
[i
], 0), 0));
1894 if (GET_CODE (immed
[i
]) == CONST_INT
)
1895 sprintf (desc1
, "%d(%s)", INTVAL (immed
[i
]),
1898 sprintf (desc1
, "<memory> (%s)", reg_names
[opbyte
]);
1900 else if (GET_CODE (XEXP (fpop
->ops
[i
], 0)) == REG
)
1902 opbyte
= REGNO (XEXP (fpop
->ops
[i
], 0));
1903 immed
[i
] = const0_rtx
;
1904 sprintf (desc1
, "(%s)", reg_names
[opbyte
]);
1908 immed
[i
] = XEXP (fpop
->ops
[i
], 0);
1910 sprintf(desc1
, "<memory>");
1921 immed
[i
] = fpop
->ops
[i
];
1930 /* Save/restore is special. */
1931 if (i
== 0 && (fpop
->opcode
== USE
|| fpop
->opcode
== CLOBBER
))
1932 type
= 0xff, opbyte
= INTVAL (fpop
->ops
[0]), immed
[i
] = 0;
1934 fprintf (file
, "\t.byte 0x%x,0x%x # (%s) %s\n",
1935 type
, opbyte
, desc0
, desc1
);
1940 /* If in the middle of a word, round. */
1941 if (size_so_far
% UNITS_PER_WORD
)
1943 fprintf (file
, "\t.space 2\n");
1947 for (i
= 0; i
< fpop
->noperands
; i
++)
1949 switch (GET_MODE (immed
[i
]))
1954 fprintf (file
, "\t.long ");
1955 output_addr_const (file
, immed
[i
]);
1956 fprintf (file
, "\n");
1963 if (GET_CODE (immed
[i
]) == CONST_DOUBLE
)
1966 REAL_VALUE_FROM_CONST_DOUBLE (r
, immed
[i
]);
1967 assemble_real (r
, GET_MODE (immed
[i
]),
1968 GET_MODE_ALIGNMENT (GET_MODE (immed
[i
])));
1978 if (size_so_far
!= fpop
->size
)
1980 if (TARGET_FULL_FP_BLOCKS
)
1981 fprintf (file
, "\t.space %d\n", fpop
->size
- size_so_far
);
1987 /* Update for next subroutine. */
1992 /* Initialize floating-point operation table. */
1999 first_fpop
= last_fpop_in_mem
= 0;
2000 for (i
= 0; i
< FP_HASH_SIZE
; i
++)
2001 fp_hash_table
[i
] = 0;
2004 /* Return the offset value of an automatic variable (N_LSYM) having
2005 the given offset. Basically, we correct by going from a frame pointer to
2006 stack pointer value.
2010 romp_debugger_auto_correction(offset
)
2015 /* We really want to go from STACK_POINTER_REGNUM to
2016 FRAME_POINTER_REGNUM, but this isn't defined. So go the other
2017 direction and negate. */
2018 INITIAL_ELIMINATION_OFFSET (FRAME_POINTER_REGNUM
, STACK_POINTER_REGNUM
,
2021 /* The offset value points somewhere between the frame pointer and
2022 the stack pointer. What is up from the frame pointer is down from the
2023 stack pointer. Therefore the negation in the offset value too. */
2025 return -(offset
+fp_to_sp
+4);
2028 /* Return the offset value of an argument having
2029 the given offset. Basically, we correct by going from an arg pointer to
2030 stack pointer value. */
2033 romp_debugger_arg_correction (offset
)
2038 INITIAL_ELIMINATION_OFFSET (ARG_POINTER_REGNUM
, FRAME_POINTER_REGNUM
,
2041 /* Actually, something different happens if offset is from a floating-point
2042 register argument, but we don't handle it here. */
2044 return (offset
- fp_to_argp
);
2048 romp_initialize_trampoline (tramp
, fnaddr
, cxt
)
2049 rtx tramp
, fnaddr
, cxt
;
2051 rtx addr
, temp
, val
;
2053 temp
= expand_simple_binop (SImode
, PLUS
, tramp
, GEN_INT (4),
2054 0, 1, OPTAB_LIB_WIDEN
);
2055 emit_move_insn (gen_rtx_MEM (SImode
, memory_address (SImode
, tramp
)), temp
);
2057 val
= force_reg (SImode
, cxt
);
2058 addr
= memory_address (HImode
, plus_constant (tramp
, 10));
2059 emit_move_insn (gen_rtx_MEM (HImode
, addr
), gen_lowpart (HImode
, val
));
2060 temp
= expand_shift (RSHIFT_EXPR
, SImode
, val
, build_int_2 (16, 0), 0, 1);
2061 addr
= memory_address (HImode
, plus_constant (tramp
, 6));
2062 emit_move_insn (gen_rtx_MEM (HImode
, addr
), gen_lowpart (HImode
, temp
));
2064 val
= force_reg (SImode
, fnaddr
);
2065 addr
= memory_address (HImode
, plus_constant (tramp
, 24));
2066 emit_move_insn (gen_rtx_MEM (HImode
, addr
), gen_lowpart (HImode
, val
));
2067 temp
= expand_shift (RSHIFT_EXPR
, SImode
, val
, build_int_2 (16, 0), 0, 1);
2068 addr
= memory_address (HImode
, plus_constant (tramp
, 20));
2069 emit_move_insn (gen_rtx_MEM (HImode
, addr
), gen_lowpart (HImode
, temp
));