]> gcc.gnu.org Git - gcc.git/blame - gcc/config/romp/romp.c
(bdn/bdz): Fix typo in checking for when we need to split.
[gcc.git] / gcc / config / romp / romp.c
CommitLineData
e6ee5154 1/* Subroutines used for code generation on ROMP.
d49debfe 2 Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
e6ee5154
RK
3 Contributed by Richard Kenner (kenner@nyu.edu)
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
19the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21
22#include <stdio.h>
23#include "config.h"
24#include "rtl.h"
25#include "regs.h"
26#include "hard-reg-set.h"
27#include "real.h"
28#include "insn-config.h"
29#include "conditions.h"
30#include "insn-flags.h"
31#include "output.h"
32#include "insn-attr.h"
33#include "flags.h"
34#include "recog.h"
35#include "expr.h"
36#include "obstack.h"
37#include "tree.h"
38
39#define min(A,B) ((A) < (B) ? (A) : (B))
40#define max(A,B) ((A) > (B) ? (A) : (B))
41
42static int unsigned_comparisons_p ();
43static void output_loadsave_fpregs ();
44static void output_fpops ();
45static void init_fpops ();
46\f
47/* Return 1 if the insn using CC0 set by INSN does not contain
48 any unsigned tests applied to the condition codes.
49
50 Based on `next_insn_tests_no_inequality' in recog.c. */
51
52int
53next_insn_tests_no_unsigned (insn)
54 rtx insn;
55{
56 register rtx next = next_cc0_user (insn);
57
58 if (next == 0)
59 {
60 if (find_reg_note (insn, REG_UNUSED, cc0_rtx))
61 return 1;
62 else
63 abort ();
64 }
65
66 return ((GET_CODE (next) == JUMP_INSN
67 || GET_CODE (next) == INSN
68 || GET_CODE (next) == CALL_INSN)
69 && ! unsigned_comparisons_p (PATTERN (next)));
70}
71
72static int
73unsigned_comparisons_p (x)
74 rtx x;
75{
76 register char *fmt;
77 register int len, i;
78 register enum rtx_code code = GET_CODE (x);
79
80 switch (code)
81 {
82 case REG:
83 case PC:
84 case CC0:
85 case CONST_INT:
86 case CONST_DOUBLE:
87 case CONST:
88 case LABEL_REF:
89 case SYMBOL_REF:
90 return 0;
91
92 case LTU:
93 case GTU:
94 case LEU:
95 case GEU:
96 return (XEXP (x, 0) == cc0_rtx || XEXP (x, 1) == cc0_rtx);
97 }
98
99 len = GET_RTX_LENGTH (code);
100 fmt = GET_RTX_FORMAT (code);
101
102 for (i = 0; i < len; i++)
103 {
104 if (fmt[i] == 'e')
105 {
106 if (unsigned_comparisons_p (XEXP (x, i)))
107 return 1;
108 }
109 else if (fmt[i] == 'E')
110 {
111 register int j;
112 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
113 if (unsigned_comparisons_p (XVECEXP (x, i, j)))
114 return 1;
115 }
116 }
117
118 return 0;
119}
120\f
121/* Update the condition code from the insn. Look mostly at the first
122 byte of the machine-specific insn description information.
123
124 cc_state.value[12] refer to two possible values that might correspond
125 to the CC. We only store register values. */
126
127update_cc (body, insn)
128 rtx body;
129 rtx insn;
130{
131 switch (get_attr_cc (insn))
132 {
133 case CC_NONE:
134 /* Insn does not affect the CC at all. */
135 break;
136
137 case CC_CHANGE0:
138 /* Insn doesn't affect the CC but does modify operand[0], known to be
139 a register. */
140 if (cc_status.value1 != 0
141 && reg_overlap_mentioned_p (recog_operand[0], cc_status.value1))
142 cc_status.value1 = 0;
143
144 if (cc_status.value2 != 0
145 && reg_overlap_mentioned_p (recog_operand[0], cc_status.value2))
146 cc_status.value2 = 0;
147
148 break;
149
150 case CC_COPY1TO0:
151 /* Insn copies operand[1] to operand[0], both registers, but doesn't
152 affect the CC. */
153 if (cc_status.value1 != 0
154 && reg_overlap_mentioned_p (recog_operand[0], cc_status.value1))
155 cc_status.value1 = 0;
156
157 if (cc_status.value2 != 0
158 && reg_overlap_mentioned_p (recog_operand[0], cc_status.value2))
159 cc_status.value2 = 0;
160
161 if (cc_status.value1 != 0
162 && rtx_equal_p (cc_status.value1, recog_operand[1]))
163 cc_status.value2 = recog_operand[0];
164
165 if (cc_status.value2 != 0
166 && rtx_equal_p (cc_status.value2, recog_operand[1]))
167 cc_status.value1 = recog_operand[0];
168
169 break;
170
171 case CC_CLOBBER:
172 /* Insn clobbers CC. */
173 CC_STATUS_INIT;
174 break;
175
176 case CC_SETS:
177 /* Insn sets CC to recog_operand[0], but overflow is impossible. */
178 CC_STATUS_INIT;
179 cc_status.flags |= CC_NO_OVERFLOW;
180 cc_status.value1 = recog_operand[0];
181 break;
182
183 case CC_COMPARE:
184 /* Insn is a compare which sets the CC fully. Update CC_STATUS for this
185 compare and mark whether the test will be signed or unsigned. */
186 {
187 register rtx p = PATTERN (insn);
188
189 CC_STATUS_INIT;
190
191 if (GET_CODE (p) == PARALLEL)
192 p = XVECEXP (p, 0, 0);
193 cc_status.value1 = SET_SRC (p);
194
195 if (GET_CODE (SET_SRC (p)) == REG)
196 cc_status.flags |= CC_NO_OVERFLOW;
197 if (! next_insn_tests_no_unsigned (insn))
198 cc_status.flags |= CC_UNSIGNED;
199 }
200 break;
201
202 case CC_TBIT:
203 /* Insn sets T bit if result is non-zero. Next insn must be branch. */
204 CC_STATUS_INIT;
205 cc_status.flags = CC_IN_TB | CC_NOT_NEGATIVE;
206 break;
207
208 default:
209 abort ();
210 }
211}
212
213/* Return 1 if a previous compare needs to be re-issued. This will happen
214 if two compares tested the same objects, but one was signed and the
215 other unsigned. OP is the comparison operation being performed. */
216
217int
218restore_compare_p (op)
219 rtx op;
220{
221 enum rtx_code code = GET_CODE (op);
222
223 return (((code == GEU || code == LEU || code == GTU || code == LTU)
224 && ! (cc_status.flags & CC_UNSIGNED))
225 || ((code == GE || code == LE || code == GT || code == LT)
226 && (cc_status.flags & CC_UNSIGNED)));
227}
228\f
229/* Generate the (long) string corresponding to an inline multiply insn.
230 Note that `r10' does not refer to the register r10, but rather to the
231 SCR used as the MQ. */
232char *
233output_in_line_mul ()
234{
235 static char insns[200];
236 int i;
237
238 strcpy (insns, "s %0,%0\n");
239 strcat (insns, "\tmts r10,%1\n");
240 for (i = 0; i < 16; i++)
241 strcat (insns, "\tm %0,%2\n");
242 strcat (insns, "\tmfs r10,%0");
243
244 return insns;
245}
246\f
247/* Returns 1 if OP is a memory reference with an offset from a register within
248 the range specified. The offset must also be a multiple of the size of the
249 mode. */
250
251static int
252memory_offset_in_range_p (op, mode, low, high)
253 register rtx op;
254 enum machine_mode mode;
255 int low, high;
256{
257 int offset = 0;
258
259 if (! memory_operand (op, mode))
260 return 0;
261
262 while (GET_CODE (op) == SUBREG)
263 {
264 offset += SUBREG_WORD (op) * UNITS_PER_WORD;
265#if BYTES_BIG_ENDIAN
266 offset -= (min (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (op)))
267 - min (UNITS_PER_WORD,
268 GET_MODE_SIZE (GET_MODE (SUBREG_REG (op)))));
269#endif
270 op = SUBREG_REG (op);
271 }
272
273 /* We must now have either (mem (reg (x)), (mem (plus (reg (x)) (c))),
274 or a constant pool address. */
275 if (GET_CODE (op) != MEM)
276 abort ();
277
278 /* Now use the actual mode and get the address. */
279 mode = GET_MODE (op);
280 op = XEXP (op, 0);
281 if (GET_CODE (op) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (op))
282 offset = get_pool_offset (op) + 12;
283 else if (GET_CODE (op) == PLUS)
284 {
285 if (GET_CODE (XEXP (op, 1)) != CONST_INT
286 || ! register_operand (XEXP (op, 0), Pmode))
287 return 0;
288
289 offset += INTVAL (XEXP (op, 1));
290 }
291
292 else if (! register_operand (op, Pmode))
293 return 0;
294
295 return (offset >= low && offset <= high
296 && (offset % GET_MODE_SIZE (mode) == 0));
297}
298
299/* Return 1 if OP is a valid operand for a memory reference insn that can
300 only reference indirect through a register. */
301
302int
303zero_memory_operand (op, mode)
304 rtx op;
305 enum machine_mode mode;
306{
307 return memory_offset_in_range_p (op, mode, 0, 0);
308}
309
310/* Return 1 if OP is a valid operand for a `short' memory reference insn. */
311
312int
313short_memory_operand (op, mode)
314 rtx op;
315 enum machine_mode mode;
316{
317 if (mode == VOIDmode)
318 mode = GET_MODE (op);
319
320 return memory_offset_in_range_p (op, mode, 0,
321 15 * min (UNITS_PER_WORD,
322 GET_MODE_SIZE (mode)));
323}
324
325/* Returns 1 if OP is a memory reference involving a symbolic constant
326 that is not in the constant pool. */
327
328int
329symbolic_memory_operand (op, mode)
330 register rtx op;
331 enum machine_mode mode;
332{
333 if (! memory_operand (op, mode))
334 return 0;
335
336 while (GET_CODE (op) == SUBREG)
337 op = SUBREG_REG (op);
338
339 if (GET_CODE (op) != MEM)
340 abort ();
341
342 op = XEXP (op, 0);
343 if (constant_pool_address_operand (op, VOIDmode))
344 return 0;
345 else
346 return romp_symbolic_operand (op, Pmode)
347 || (GET_CODE (op) == PLUS && register_operand (XEXP (op, 0), Pmode)
348 && romp_symbolic_operand (XEXP (op, 1), Pmode));
349}
350
351
352/* Returns 1 if OP is a constant pool reference to the current function. */
353
354int
355current_function_operand (op, mode)
356 rtx op;
357 enum machine_mode mode;
358{
359 if (GET_CODE (op) != MEM || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
360 || ! CONSTANT_POOL_ADDRESS_P (XEXP (op, 0)))
361 return 0;
362
363 op = get_pool_constant (XEXP (op, 0));
364 return (GET_CODE (op) == SYMBOL_REF
365 && ! strcmp (current_function_name, XSTR (op, 0)));
366}
367
368/* Return non-zero if this function is known to have a null epilogue. */
369
370int
371null_epilogue ()
372{
373 return (reload_completed
374 && first_reg_to_save () == 16
375 && ! romp_pushes_stack ());
376}
377\f
378/* Returns 1 if OP is the address of a location in the constant pool. */
379
380int
381constant_pool_address_operand (op, mode)
382 rtx op;
383 enum machine_mode mode;
384{
385 return ((GET_CODE (op) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (op))
386 || (GET_CODE (op) == CONST && GET_CODE (XEXP (op, 0)) == PLUS
387 && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
388 && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
389 && CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (op, 0), 0))));
390}
391
392/* Returns 1 if OP is either a symbol reference or a sum of a symbol
393 reference and a constant. */
394
395int
396romp_symbolic_operand (op, mode)
397 register rtx op;
398 enum machine_mode mode;
399{
400 switch (GET_CODE (op))
401 {
402 case SYMBOL_REF:
403 case LABEL_REF:
404 return ! op->integrated;
405
406 case CONST:
407 op = XEXP (op, 0);
408 return (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
409 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
410 && GET_CODE (XEXP (op, 1)) == CONST_INT;
411
412 default:
413 return 0;
414 }
415}
416
417/* Returns 1 if OP is a valid constant for the ROMP. */
418
419int
420constant_operand (op, mode)
421 register rtx op;
422 enum machine_mode mode;
423{
424 switch (GET_CODE (op))
425 {
426 case LABEL_REF:
427 case SYMBOL_REF:
428 case PLUS:
429 case CONST:
430 return romp_symbolic_operand (op,mode);
431
432 case CONST_INT:
433 return (unsigned int) (INTVAL (op) + 0x8000) < 0x10000
434 || (INTVAL (op) & 0xffff) == 0 || (INTVAL (op) & 0xffff0000) == 0;
435
436 default:
437 return 0;
438 }
439}
440
441/* Returns 1 if OP is either a constant integer valid for the ROMP or a
442 register. If a register, it must be in the proper mode unless MODE is
443 VOIDmode. */
444
445int
446reg_or_cint_operand (op, mode)
447 register rtx op;
448 enum machine_mode mode;
449{
450 if (GET_CODE (op) == CONST_INT)
451 return constant_operand (op, mode);
452
453 return register_operand (op, mode);
454}
455
456/* Return 1 is the operand is either a register or ANY constant integer. */
457
458int
459reg_or_any_cint_operand (op, mode)
460 register rtx op;
461 enum machine_mode mode;
462{
463 return GET_CODE (op) == CONST_INT || register_operand (op, mode);
464}
465
466/* Return 1 if the operand is either a register or a valid D-type operand. */
467
468int
469reg_or_D_operand (op, mode)
470 register rtx op;
471 enum machine_mode mode;
472{
473 if (GET_CODE (op) == CONST_INT)
474 return (unsigned) (INTVAL (op) + 0x8000) < 0x10000;
475
476 return register_operand (op, mode);
477}
478
479/* Return 1 if the operand is either a register or an item that can be
480 used as the operand of an SI add insn. */
481
482int
483reg_or_add_operand (op, mode)
484 register rtx op;
485 enum machine_mode mode;
486{
487 return reg_or_D_operand (op, mode) || romp_symbolic_operand (op, mode)
488 || (GET_CODE (op) == CONST_INT && (INTVAL (op) & 0xffff) == 0);
489}
490
491/* Return 1 if the operand is either a register or an item that can be
492 used as the operand of a ROMP logical AND insn. */
493
494int
495reg_or_and_operand (op, mode)
496 register rtx op;
497 enum machine_mode mode;
498{
499 if (reg_or_cint_operand (op, mode))
500 return 1;
501
502 if (GET_CODE (op) != CONST_INT)
503 return 0;
504
505 return (INTVAL (op) & 0xffff) == 0xffff
506 || (INTVAL (op) & 0xffff0000) == 0xffff0000;
507}
508
509/* Return 1 if the operand is a register or memory operand. */
510
511int
512reg_or_mem_operand (op, mode)
513 register rtx op;
514 register enum machine_mode mode;
515{
516 return register_operand (op, mode) || memory_operand (op, mode);
517}
518
519/* Return 1 if the operand is either a register or a memory operand that is
520 not symbolic. */
521
522int
523reg_or_nonsymb_mem_operand (op, mode)
524 register rtx op;
525 enum machine_mode mode;
526{
527 if (register_operand (op, mode))
528 return 1;
529
530 if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode))
531 return 1;
532
533 return 0;
534}
535
536/* Return 1 if this operand is valid for the ROMP. This is any operand except
537 certain constant integers. */
538
539int
540romp_operand (op, mode)
541 register rtx op;
542 enum machine_mode mode;
543{
544 if (GET_CODE (op) == CONST_INT)
545 return constant_operand (op, mode);
546
547 return general_operand (op, mode);
548}
549
550/* Return 1 if the operand is (reg:mode 0). */
551
552int
553reg_0_operand (op, mode)
554 rtx op;
555 enum machine_mode mode;
556{
557 return ((mode == VOIDmode || mode == GET_MODE (op))
558 && GET_CODE (op) == REG && REGNO (op) == 0);
559}
560
561/* Return 1 if the operand is (reg:mode 15). */
562
563int
564reg_15_operand (op, mode)
565 rtx op;
566 enum machine_mode mode;
567{
568 return ((mode == VOIDmode || mode == GET_MODE (op))
569 && GET_CODE (op) == REG && REGNO (op) == 15);
570}
571\f
572/* Return 1 if this is a binary floating-point operation. */
573
574int
575float_binary (op, mode)
576 register rtx op;
577 enum machine_mode mode;
578{
579 if (mode != VOIDmode && mode != GET_MODE (op))
580 return 0;
581
582 if (GET_MODE (op) != SFmode && GET_MODE (op) != DFmode)
583 return 0;
584
585 switch (GET_CODE (op))
586 {
587 case PLUS:
588 case MINUS:
589 case MULT:
590 case DIV:
591 return GET_MODE (XEXP (op, 0)) == GET_MODE (op)
592 && GET_MODE (XEXP (op, 1)) == GET_MODE (op);
593
594 default:
595 return 0;
596 }
597}
598
599/* Return 1 if this is a unary floating-point operation. */
600
601int
602float_unary (op, mode)
603 register rtx op;
604 enum machine_mode mode;
605{
606 if (mode != VOIDmode && mode != GET_MODE (op))
607 return 0;
608
609 if (GET_MODE (op) != SFmode && GET_MODE (op) != DFmode)
610 return 0;
611
612 return (GET_CODE (op) == NEG || GET_CODE (op) == ABS)
613 && GET_MODE (XEXP (op, 0)) == GET_MODE (op);
614}
615
b4ac57ab 616/* Return 1 if this is a valid floating-point conversion that can be done
e6ee5154
RK
617 as part of an operation by the RT floating-point routines. */
618
619int
620float_conversion (op, mode)
621 register rtx op;
622 enum machine_mode mode;
623{
624 if (mode != VOIDmode && mode != GET_MODE (op))
625 return 0;
626
627 switch (GET_CODE (op))
628 {
629 case FLOAT_TRUNCATE:
630 return GET_MODE (op) == SFmode && GET_MODE (XEXP (op, 0)) == DFmode;
631
632 case FLOAT_EXTEND:
633 return GET_MODE (op) == DFmode && GET_MODE (XEXP (op, 0)) == SFmode;
634
635 case FLOAT:
636 return ((GET_MODE (XEXP (op, 0)) == SImode
637 || GET_CODE (XEXP (op, 0)) == CONST_INT)
638 && (GET_MODE (op) == SFmode || GET_MODE (op) == DFmode));
639
640 case FIX:
641 return ((GET_MODE (op) == SImode
642 || GET_CODE (XEXP (op, 0)) == CONST_INT)
643 && (GET_MODE (XEXP (op, 0)) == SFmode
644 || GET_MODE (XEXP (op, 0)) == DFmode));
645
646 default:
647 return 0;
648 }
649}
650\f
651/* Print an operand. Recognize special options, documented below. */
652
653void
654print_operand (file, x, code)
655 FILE *file;
656 rtx x;
657 char code;
658{
659 int i;
660
661 switch (code)
662 {
663 case 'B':
664 /* Byte number (const/8) */
665 if (GET_CODE (x) != CONST_INT)
666 output_operand_lossage ("invalid %%B value");
667
668 fprintf (file, "%d", INTVAL (x) / 8);
669 break;
670
671 case 'L':
672 /* Low order 16 bits of constant. */
673 if (GET_CODE (x) != CONST_INT)
674 output_operand_lossage ("invalid %%L value");
675
676 fprintf (file, "%d", INTVAL (x) & 0xffff);
677 break;
678
679 case 's':
680 /* Null or "16" depending on whether the constant is greater than 16. */
681 if (GET_CODE (x) != CONST_INT)
682 output_operand_lossage ("invalid %%s value");
683
684 if (INTVAL (x) >= 16)
685 fprintf (file, "16");
686
687 break;
688
689 case 'S':
690 /* For shifts: 's' will have given the half. Just give the amount
691 within 16. */
692 if (GET_CODE (x) != CONST_INT)
693 output_operand_lossage ("invalid %%S value");
694
695 fprintf (file, "%d", INTVAL (x) & 15);
696 break;
697
698 case 'b':
699 /* The number of a single bit set or cleared, mod 16. Note that the ROMP
700 numbers bits with the high-order bit 31. */
701 if (GET_CODE (x) != CONST_INT)
702 output_operand_lossage ("invalid %%b value");
703
704 if ((i = exact_log2 (INTVAL (x))) >= 0)
705 fprintf (file, "%d", (31 - i) % 16);
706 else if ((i = exact_log2 (~ INTVAL (x))) >= 0)
707 fprintf (file, "%d", (31 - i) % 16);
708 else
709 output_operand_lossage ("invalid %%b value");
710
711 break;
712
713 case 'h':
714 /* "l" or "u" depending on which half of the constant is zero. */
715 if (GET_CODE (x) != CONST_INT)
716 output_operand_lossage ("invalid %%h value");
717
718 if ((INTVAL (x) & 0xffff0000) == 0)
719 fprintf (file, "l");
720 else if ((INTVAL (x) & 0xffff) == 0)
721 fprintf (file, "u");
722 else
723 output_operand_lossage ("invalid %%h value");
724
725 break;
726
727 case 'H':
728 /* Upper or lower half, depending on which half is zero. */
729 if (GET_CODE (x) != CONST_INT)
730 output_operand_lossage ("invalid %%H value");
731
732 if ((INTVAL (x) & 0xffff0000) == 0)
733 fprintf (file, "%d", INTVAL (x) & 0xffff);
734 else if ((INTVAL (x) & 0xffff) == 0)
735 fprintf (file, "%d", (INTVAL (x) >> 16) & 0xffff);
736 else
737 output_operand_lossage ("invalid %%H value");
738
739 break;
740
741 case 'z':
742 /* Write two characters:
743 'lo' if the high order part is all ones
744 'lz' if the high order part is all zeros
745 'uo' if the low order part is all ones
746 'uz' if the low order part is all zeros
747 */
748 if (GET_CODE (x) != CONST_INT)
749 output_operand_lossage ("invalid %%z value");
750
751 if ((INTVAL (x) & 0xffff0000) == 0)
752 fprintf (file, "lz");
753 else if ((INTVAL (x) & 0xffff0000) == 0xffff0000)
754 fprintf (file, "lo");
755 else if ((INTVAL (x) & 0xffff) == 0)
756 fprintf (file, "uz");
757 else if ((INTVAL (x) & 0xffff) == 0xffff)
758 fprintf (file, "uo");
759 else
760 output_operand_lossage ("invalid %%z value");
761
762 break;
763
764 case 'Z':
765 /* Upper or lower half, depending on which is non-zero or not
766 all ones. Must be consistent with 'z' above. */
767 if (GET_CODE (x) != CONST_INT)
768 output_operand_lossage ("invalid %%Z value");
769
770 if ((INTVAL (x) & 0xffff0000) == 0
771 || (INTVAL (x) & 0xffff0000) == 0xffff0000)
772 fprintf (file, "%d", INTVAL (x) & 0xffff);
773 else if ((INTVAL (x) & 0xffff) == 0 || (INTVAL (x) & 0xffff) == 0xffff)
774 fprintf (file, "%d", (INTVAL (x) >> 16) & 0xffff);
775 else
776 output_operand_lossage ("invalid %%Z value");
777
778 break;
779
780 case 'k':
781 /* Same as 'z', except the trailing 'o' or 'z' is not written. */
782 if (GET_CODE (x) != CONST_INT)
783 output_operand_lossage ("invalid %%k value");
784
785 if ((INTVAL (x) & 0xffff0000) == 0
786 || (INTVAL (x) & 0xffff0000) == 0xffff0000)
787 fprintf (file, "l");
788 else if ((INTVAL (x) & 0xffff) == 0
789 || (INTVAL (x) & 0xffff) == 0xffff)
790 fprintf (file, "u");
791 else
792 output_operand_lossage ("invalid %%k value");
793
794 break;
795
796 case 't':
797 /* Similar to 's', except that we write 'h' or 'u'. */
798 if (GET_CODE (x) != CONST_INT)
799 output_operand_lossage ("invalid %%k value");
800
801 if (INTVAL (x) < 16)
802 fprintf (file, "u");
803 else
804 fprintf (file, "l");
805 break;
806
807 case 'M':
808 /* For memory operations, write 's' if the operand is a short
809 memory operand. */
810 if (short_memory_operand (x, VOIDmode))
811 fprintf (file, "s");
812 break;
813
814 case 'N':
815 /* Like 'M', but check for zero memory offset. */
816 if (zero_memory_operand (x, VOIDmode))
817 fprintf (file, "s");
818 break;
819
820 case 'O':
821 /* Write low-order part of DImode or DFmode. Supported for MEM
822 and REG only. */
823 if (GET_CODE (x) == REG)
824 fprintf (file, "%s", reg_names[REGNO (x) + 1]);
825 else if (GET_CODE (x) == MEM)
826 print_operand (file, gen_rtx (MEM, GET_MODE (x),
827 plus_constant (XEXP (x, 0), 4)), 0);
828 else
829 abort ();
830 break;
831
832 case 'C':
833 /* Offset in constant pool for constant pool address. */
834 if (! constant_pool_address_operand (x, VOIDmode))
835 abort ();
836 if (GET_CODE (x) == SYMBOL_REF)
837 fprintf (file, "%d", get_pool_offset (x) + 12);
838 else
839 /* Must be (const (plus (symbol_ref) (const_int))) */
840 fprintf (file, "%d",
841 (get_pool_offset (XEXP (XEXP (x, 0), 0)) + 12
842 + INTVAL (XEXP (XEXP (x, 0), 1))));
843 break;
844
845 case 'j':
846 /* Branch opcode. Check for condition in test bit for eq/ne. */
847 switch (GET_CODE (x))
848 {
849 case EQ:
850 if (cc_status.flags & CC_IN_TB)
851 fprintf (file, "ntb");
852 else
853 fprintf (file, "eq");
854 break;
855
856 case NE:
857 if (cc_status.flags & CC_IN_TB)
858 fprintf (file, "tb");
859 else
860 fprintf (file, "ne");
861 break;
862
863 case GT:
864 case GTU:
865 fprintf (file, "h");
866 break;
867
868 case LT:
869 case LTU:
870 fprintf (file, "l");
871 break;
872
873 case GE:
874 case GEU:
875 fprintf (file, "he");
876 break;
877
878 case LE:
879 case LEU:
880 fprintf (file, "le");
881 break;
882
883 default:
884 output_operand_lossage ("invalid %%j value");
885 }
886 break;
887
888 case 'J':
889 /* Reversed branch opcode. */
890 switch (GET_CODE (x))
891 {
892 case EQ:
893 if (cc_status.flags & CC_IN_TB)
894 fprintf (file, "tb");
895 else
896 fprintf (file, "ne");
897 break;
898
899 case NE:
900 if (cc_status.flags & CC_IN_TB)
901 fprintf (file, "ntb");
902 else
903 fprintf (file, "eq");
904 break;
905
906 case GT:
907 case GTU:
908 fprintf (file, "le");
909 break;
910
911 case LT:
912 case LTU:
913 fprintf (file, "he");
914 break;
915
916 case GE:
917 case GEU:
918 fprintf (file, "l");
919 break;
920
921 case LE:
922 case LEU:
923 fprintf (file, "h");
924 break;
925
926 default:
927 output_operand_lossage ("invalid %%j value");
928 }
929 break;
930
931 case '.':
b4ac57ab 932 /* Output nothing. Used as delimiter in, e.g., "mc%B1%.3 " */
e6ee5154
RK
933 break;
934
935 case '#':
936 /* Output 'x' if this insn has a delay slot, else nothing. */
937 if (dbr_sequence_length ())
938 fprintf (file, "x");
939 break;
940
941 case 0:
942 if (GET_CODE (x) == REG)
943 fprintf (file, "%s", reg_names[REGNO (x)]);
944 else if (GET_CODE (x) == MEM)
945 {
946 if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
947 && current_function_operand (x, Pmode))
948 fprintf (file, "r14");
949 else
950 output_address (XEXP (x, 0));
951 }
952 else
953 output_addr_const (file, x);
954 break;
955
956 default:
957 output_operand_lossage ("invalid %%xn code");
958 }
959}
960\f
961/* This page contains routines that are used to determine what the function
962 prologue and epilogue code will do and write them out. */
963
964/* Return the first register that is required to be saved. 16 if none. */
965
966int
967first_reg_to_save()
968{
969 int first_reg;
970
971 /* Find lowest numbered live register. */
972 for (first_reg = 6; first_reg <= 15; first_reg++)
973 if (regs_ever_live[first_reg])
974 break;
975
976 /* If we think that we do not have to save r14, see if it will be used
977 to be sure. */
978 if (first_reg > 14 && romp_using_r14 ())
979 first_reg = 14;
980
981 return first_reg;
982}
983
984/* Compute the size of the save area in the stack, including the space for
985 the first four incoming arguments. */
986
987int
988romp_sa_size ()
989{
990 int size;
991 int i;
992
993 /* We have the 4 words corresponding to the arguments passed in registers,
994 4 reserved words, space for static chain, general register save area,
995 and floating-point save area. */
996 size = 4 + 4 + 1 + (16 - first_reg_to_save ());
997
998 /* The documentation says we have to leave 18 words in the save area if
999 any floating-point registers at all are saved, not the three words
1000 per register you might otherwise expect. */
1001 for (i = 2 + (TARGET_FP_REGS != 0); i <= 7; i++)
1002 if (regs_ever_live[i + 17])
1003 {
1004 size += 18;
1005 break;
1006 }
1007
1008 return size * 4;
1009}
1010
1011/* Return non-zero if this function makes calls or has fp operations
1012 (which are really calls). */
1013
1014int
1015romp_makes_calls ()
1016{
1017 rtx insn;
1018
1019 for (insn = get_insns (); insn; insn = next_insn (insn))
1020 {
1021 if (GET_CODE (insn) == CALL_INSN)
1022 return 1;
1023 else if (GET_CODE (insn) == INSN)
1024 {
1025 rtx body = PATTERN (insn);
1026
1027 if (GET_CODE (body) != USE && GET_CODE (body) != CLOBBER
1028 && GET_CODE (body) != ADDR_VEC
1029 && GET_CODE (body) != ADDR_DIFF_VEC
1030 && get_attr_type (insn) == TYPE_FP)
1031 return 1;
1032 }
1033 }
1034
1035 return 0;
1036}
1037
1038/* Return non-zero if this function will use r14 as a pointer to its
1039 constant pool. */
1040
1041int
1042romp_using_r14 ()
1043{
1044 /* If we are debugging, profiling, have a non-empty constant pool, or
1045 call a function, we need r14. */
1046 return (write_symbols != NO_DEBUG || profile_flag || get_pool_size () != 0
1047 || romp_makes_calls ());
1048}
1049
1050/* Return non-zero if this function needs to push space on the stack. */
1051
1052int
1053romp_pushes_stack ()
1054{
1055 /* We need to push the stack if a frame pointer is needed (because the
1056 stack might be dynamically adjusted), if we are debugging, if the
1057 total required size is more than 100 bytes, or if we make calls. */
1058
1059 return (frame_pointer_needed || write_symbols != NO_DEBUG
1060 || (romp_sa_size () + get_frame_size ()) > 100
1061 || romp_makes_calls ());
1062}
1063
1064/* Write function prologue.
1065
1066 We compute the size of the fixed area required as follows:
1067
1068 We always allocate 4 words for incoming arguments, 4 word reserved, 1
1069 word for static link, as many words as required for general register
1070 save area, plus 2 words for each FP reg 2-7 that must be saved. */
1071
1072void
1073output_prolog (file, size)
1074 FILE *file;
1075 int size;
1076{
1077 int first_reg;
1078 int reg_save_offset;
e6ee5154
RK
1079 int fp_save = size + current_function_outgoing_args_size;
1080
1081 init_fpops ();
1082
1083 /* Add in fixed size plus output argument area. */
1084 size += romp_sa_size () + current_function_outgoing_args_size;
1085
1086 /* Compute first register to save and perform the save operation if anything
1087 needs to be saved. */
1088 first_reg = first_reg_to_save();
1089 reg_save_offset = - (4 + 4 + 1 + (16 - first_reg)) * 4;
1090 if (first_reg == 15)
1091 fprintf (file, "\tst r15,%d(r1)\n", reg_save_offset);
1092 else if (first_reg < 16)
1093 fprintf (file, "\tstm r%d,%d(r1)\n", first_reg, reg_save_offset);
1094
1095 /* Set up pointer to data area if it is needed. */
1096 if (romp_using_r14 ())
1097 fprintf (file, "\tcas r14,r0,r0\n");
1098
1099 /* Set up frame pointer if needed. */
1100 if (frame_pointer_needed)
1101 fprintf (file, "\tcal r13,-%d(r1)\n", romp_sa_size () + 64);
1102
1103 /* Push stack if neeeded. There are a couple of ways of doing this. */
1104 if (romp_pushes_stack ())
1105 {
1106 if (size >= 32768)
1107 {
1108 if (size >= 65536)
1109 {
1110 fprintf (file, "\tcau r0,%d(r0)\n", size >> 16);
1111 fprintf (file, "\toil r0,r0,%d\n", size & 0xffff);
1112 }
1113 else
1114 fprintf (file, "\tcal16 r0,%d(r0)\n", size);
1115 fprintf (file, "\ts r1,r0\n");
1116 }
1117 else
1118 fprintf (file, "\tcal r1,-%d(r1)\n", size);
1119 }
1120
1121 /* Save floating-point registers. */
1122 output_loadsave_fpregs (file, USE,
1123 plus_constant (stack_pointer_rtx, fp_save));
1124}
d1abe602
RK
1125\f
1126/* Output the offset information used by debuggers.
1127 This is the exactly the total_size value of output_epilog
1128 which is added to the frame pointer. However the value in the debug
1129 table is encoded in a space-saving way as follows:
1130
1131 The first byte contains two fields: a 2-bit size field and the first
1132 6 bits of an offset value. The 2-bit size field is in the high-order
1133 position and specifies how many subsequent bytes follow after
1134 this one. An offset value is at most 4-bytes long.
1135
1136 The last 6 bits of the first byte initialize the offset value. In many
1137 cases where procedures have small local storage, this is enough and, in
1138 this case, the high-order size field is zero so the byte can (almost) be
1139 used as is (see below). Thus, the byte value of 0x0d is encodes a offset
1140 size of 13 words, or 52 bytes.
1141
1142 For procedures with a local space larger than 60 bytes, the 6 bits
1143 are the high-order 6 bits. The remaining bytes follow as necessary,
1144 in Big Endian order. Thus, the short value of 16907 (= 16384+523)
1145 encodes an offset of 2092 bytes (523 words).
1146
1147 The total offset value is in words (not bytes), so the final value has to
1148 be multiplied by 4 before it can be used in address computations by a
1149 debugger. */
e6ee5154 1150
d1abe602
RK
1151void
1152output_encoded_offset (file, reg_offset)
1153 FILE *file;
1154 unsigned reg_offset;
1155{
1156 /* Convert the offset value to 4-byte words rather than bytes. */
1157 reg_offset = (reg_offset + 3) / 4;
1158
1159 /* Now output 1-4 bytes in encoded form. */
1160 if (reg_offset < (1 << 6))
1161 /* Fits into one byte */
1162 fprintf (file, "\t.byte %d\n", reg_offset);
1163 else if (reg_offset < (1 << (6 + 8)))
1164 /* Fits into two bytes */
1165 fprintf (file, "\t.short %d\n", (1 << (6 + 8)) + reg_offset);
1166 else if (reg_offset < (1 << (6 + 8 + 8)))
1167 {
1168 /* Fits in three bytes */
1169 fprintf (file, "\t.byte %d\n", (2 << 6) + (reg_offset >> ( 6+ 8)));
1170 fprintf (file, "\t.short %d\n", reg_offset % (1 << (6 + 8)));
1171 }
1172 else
1173 {
1174 /* Use 4 bytes. */
1175 fprintf (file, "\t.short %d", (3 << (6 + 8)) + (reg_offset >> (6 + 8)));
1176 fprintf (file, "\t.short %d\n", reg_offset % (1 << (6 + 8)));
1177 }
1178}
1179\f
e6ee5154
RK
1180/* Write function epilogue. */
1181
1182void
1183output_epilog (file, size)
1184 FILE *file;
1185 int size;
1186{
1187 int first_reg = first_reg_to_save();
1188 int pushes_stack = romp_pushes_stack ();
1189 int reg_save_offset = - ((16 - first_reg) + 1 + 4 + 4) * 4;
1190 int total_size = (size + romp_sa_size ()
1191 + current_function_outgoing_args_size);
1192 int fp_save = size + current_function_outgoing_args_size;
1193 int long_frame = total_size >= 32768;
1194 rtx insn = get_last_insn ();
1195 int write_code = 1;
1196
1197 int nargs = 0; /* words of arguments */
1198 tree argptr;
1199
d49debfe
RK
1200 /* Compute the number of words of arguments. Since this is just for
1201 the traceback table, we ignore arguments that don't have a size or
1202 don't have a fixed size. */
1203
e6ee5154
RK
1204 for (argptr = DECL_ARGUMENTS (current_function_decl);
1205 argptr; argptr = TREE_CHAIN (argptr))
d49debfe
RK
1206 {
1207 int this_size = int_size_in_bytes (TREE_TYPE (argptr));
1208
1209 if (this_size > 0)
1210 nargs += (this_size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
1211 }
e6ee5154
RK
1212
1213 /* If the last insn was a BARRIER, we don't have to write anything except
1214 the trace table. */
1215 if (GET_CODE (insn) == NOTE)
1216 insn = prev_nonnote_insn (insn);
1217 if (insn && GET_CODE (insn) == BARRIER)
1218 write_code = 0;
1219
1220 /* Restore floating-point registers. */
1221 if (write_code)
1222 output_loadsave_fpregs (file, CLOBBER,
1223 gen_rtx (PLUS, Pmode, gen_rtx (REG, Pmode, 1),
1224 gen_rtx (CONST_INT, VOIDmode, fp_save)));
1225
1226 /* If we push the stack and do not have size > 32K, adjust the register
1227 save location to the current position of sp. Otherwise, if long frame,
1228 restore sp from fp. */
1229 if (pushes_stack && ! long_frame)
1230 reg_save_offset += total_size;
1231 else if (long_frame && write_code)
1232 fprintf (file, "\tcal r1,%d(r13)\n", romp_sa_size () + 64);
1233
1234 /* Restore registers. */
1235 if (first_reg == 15 && write_code)
1236 fprintf (file, "\tl r15,%d(r1)\n", reg_save_offset);
1237 else if (first_reg < 16 && write_code)
1238 fprintf (file, "\tlm r%d,%d(r1)\n", first_reg, reg_save_offset);
1239 if (first_reg == 16) first_reg = 0;
1240
1241 /* Handle popping stack, if needed and write debug table entry. */
1242 if (pushes_stack)
1243 {
1244 if (write_code)
1245 {
1246 if (long_frame)
1247 fprintf (file, "\tbr r15\n");
1248 else
1249 fprintf (file, "\tbrx r15\n\tcal r1,%d(r1)\n", total_size);
1250 }
d1abe602
RK
1251
1252 /* Table header (0xdf), usual-type stack frame (0x07),
1253 table header (0xdf), and first register saved.
1254
1255 The final 0x08 means that there is a byte following this one
1256 describing the number of parameter words and the register used as
1257 stack pointer.
1258
1259 If GCC passed floating-point parameters in floating-point registers,
1260 it would be necessary to change the final byte from 0x08 to 0x0c.
1261 Also an additional entry byte would be need to be emitted to specify
1262 the first floating-point register.
1263
1264 (See also Section 11 (Trace Tables) in ``IBM/4.3 Linkage Convention,''
1265 pages IBM/4.3-PSD:5-7 of Volume III of the IBM Academic Operating
1266 System Manual dated July 1987.) */
1267
e6ee5154
RK
1268 fprintf (file, "\t.long 0x%x\n", 0xdf07df08 + first_reg * 0x10);
1269
1270 if (nargs > 15) nargs = 15;
d1abe602
RK
1271
1272 /* The number of parameter words and the register used as the stack
1273 pointer (encoded here as r1).
1274
1275 Note: The MetWare Hich C Compiler R2.1y actually gets this wrong;
1276 it erroneously lists r13 but uses r1 as the stack too. But a bug in
1277 dbx 1.5 nullifies this mistake---most of the time.
1278 (Dbx retrieves the value of r13 saved on the stack which is often
1279 the value of r1 before the call.) */
1280
1281 fprintf (file, "\t.byte 0x%x1\n", nargs);
1282 output_encoded_offset (file, total_size);
e6ee5154
RK
1283 }
1284 else
1285 {
1286 if (write_code)
1287 fprintf (file, "\tbr r15\n");
d1abe602
RK
1288
1289 /* Table header (0xdf), no stack frame (0x02),
1290 table header (0xdf) and no parameters saved (0x00).
1291
1292 If GCC passed floating-point parameters in floating-point registers,
1293 it might be necessary to change the final byte from 0x00 to 0x04.
1294 Also a byte would be needed to specify the first floating-point
1295 register. */
e6ee5154
RK
1296 fprintf (file, "\t.long 0xdf02df00\n");
1297 }
1298
1299 /* Output any pending floating-point operations. */
ad59df7d 1300 output_fpops (file);
e6ee5154
RK
1301}
1302\f
1303/* For the ROMP we need to make new SYMBOL_REFs for the actual name of a
1304 called routine. To keep them unique we maintain a hash table of all
1305 that have been created so far. */
1306
1307struct symref_hashent {
1308 rtx symref; /* Created SYMBOL_REF rtx. */
1309 struct symref_hashent *next; /* Next with same hash code. */
1310};
1311
1312#define SYMHASHSIZE 151
1313#define HASHBITS 65535
1314
1315/* Define the hash table itself. */
1316
1317static struct symref_hashent *symref_hash_table[SYMHASHSIZE];
1318
1319/* Given a name (allocatable in temporary storage), return a SYMBOL_REF
1320 for the name. The rtx is allocated from the current rtl_obstack, while
1321 the name string is allocated from the permanent obstack. */
1322rtx
1323get_symref (name)
1324 register char *name;
1325{
1326 extern struct obstack permanent_obstack;
1327 register char *sp = name;
1328 unsigned int hash = 0;
1329 struct symref_hashent *p, **last_p;
1330
1331 /* Compute the hash code for the string. */
1332 while (*sp)
1333 hash = (hash << 4) + *sp++;
1334
1335 /* Search for a matching entry in the hash table, keeping track of the
1336 insertion location as we do so. */
1337 hash = (hash & HASHBITS) % SYMHASHSIZE;
1338 for (last_p = &symref_hash_table[hash], p = *last_p;
1339 p; last_p = &p->next, p = *last_p)
1340 if (strcmp (name, XSTR (p->symref, 0)) == 0)
1341 break;
1342
1343 /* If couldn't find matching SYMBOL_REF, make a new one. */
1344 if (p == 0)
1345 {
1346 /* Ensure SYMBOL_REF will stay around. */
1347 end_temporary_allocation ();
1348 p = *last_p = (struct symref_hashent *)
1349 permalloc (sizeof (struct symref_hashent));
1350 p->symref = gen_rtx (SYMBOL_REF, Pmode,
1351 obstack_copy0 (&permanent_obstack,
1352 name, strlen (name)));
1353 p->next = 0;
1354 resume_temporary_allocation ();
1355 }
1356
1357 return p->symref;
1358}
1359\f
1360/* Validate the precision of a floating-point operation.
1361
1362 We merge conversions from integers and between floating-point modes into
1363 the insn. However, this must not effect the desired precision of the
1364 insn. The RT floating-point system uses the widest of the operand modes.
1365 If this should be a double-precision insn, ensure that one operand
1366 passed to the floating-point processor has double mode.
1367
1368 Note that since we don't check anything if the mode is single precision,
1369 it, strictly speaking, isn't necessary to call this for those insns.
1370 However, we do so in case something else needs to be checked in the
1371 future.
1372
1373 This routine returns 1 if the operation is OK. */
1374
1375int
1376check_precision (opmode, op1, op2)
1377 enum machine_mode opmode;
1378 rtx op1, op2;
1379{
1380 if (opmode == SFmode)
1381 return 1;
1382
1383 /* If operand is not a conversion from an integer mode or an extension from
1384 single-precision, it must be a double-precision value. */
1385 if (GET_CODE (op1) != FLOAT && GET_CODE (op1) != FLOAT_EXTEND)
1386 return 1;
1387
1388 if (op2 && GET_CODE (op2) != FLOAT && GET_CODE (op2) != FLOAT_EXTEND)
1389 return 1;
1390
1391 return 0;
1392}
1393\f
1394/* Floating-point on the RT is done by creating an operation block in the data
1395 area that describes the operation. If two floating-point operations are the
1396 same in a single function, they can use the same block.
1397
1398 These routines are responsible for managing these blocks. */
1399
1400/* Structure to describe a floating-point operation. */
1401
1402struct fp_op {
1403 struct fp_op *next_same_hash; /* Next op with same hash code. */
1404 struct fp_op *next_in_mem; /* Next op in memory. */
1405 int mem_offset; /* Offset from data area. */
1406 short size; /* Size of block in bytes. */
1407 short noperands; /* Number of operands in block. */
1408 rtx ops[3]; /* RTL for operands. */
1409 enum rtx_code opcode; /* Operation being performed. */
1410};
1411
1412/* Size of hash table. */
1413#define FP_HASH_SIZE 101
1414
1415/* Hash table of floating-point operation blocks. */
1416static struct fp_op *fp_hash_table[FP_HASH_SIZE];
1417
1418/* First floating-point block in data area. */
1419static struct fp_op *first_fpop;
1420
1421/* Last block in data area so far. */
1422static struct fp_op *last_fpop_in_mem;
1423
1424/* Subroutine number in file, to get unique "LF" labels. */
1425static int subr_number = 0;
1426
1427/* Current word offset in data area (includes header and any constant pool). */
1428int data_offset;
1429
1430/* Compute hash code for an RTX used in floating-point. */
1431
1432static unsigned int
1433hash_rtx (x)
1434 register rtx x;
1435{
1436 register unsigned int hash = (((int) GET_CODE (x) << 10)
1437 + ((int) GET_MODE (x) << 20));
1438 register int i;
1439 register char *fmt = GET_RTX_FORMAT (GET_CODE (x));
1440
1441 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (x)); i++)
1442 if (fmt[i] == 'e')
1443 hash += hash_rtx (XEXP (x, i));
1444 else if (fmt[i] == 'u')
1445 hash += (int) XEXP (x, i);
1446 else if (fmt[i] == 'i')
1447 hash += XINT (x, i);
1448 else if (fmt[i] == 's')
1449 hash += (int) XSTR (x, i);
1450
1451 return hash;
1452}
1453\f
1454/* Given an operation code and up to three operands, return a character string
1455 corresponding to the code to emit to branch to a floating-point operation
1456 block. INSN is provided to see if the delay slot has been filled or not.
1457
1458 A new floating-point operation block is created if this operation has not
1459 been seen before. */
1460
1461char *
1462output_fpop (code, op0, op1, op2, insn)
1463 enum rtx_code code;
1464 rtx op0, op1, op2;
1465 rtx insn;
1466{
1467 static char outbuf[40];
1468 unsigned int hash, hash0, hash1, hash2;
1469 int size, i;
1470 register struct fp_op *fpop, *last_fpop;
1471 int dyadic = (op2 != 0);
1472 enum machine_mode opmode;
1473 int noperands;
1474 rtx tem;
1475 unsigned int tem_hash;
1476 int fr0_avail = 0;
1477
1478 /* Compute hash code for each operand. If the operation is commutative,
1479 put the one with the smaller hash code first. This will make us see
1480 more operations as identical. */
1481 hash0 = op0 ? hash_rtx (op0) : 0;
1482 hash1 = op1 ? hash_rtx (op1) : 0;
1483 hash2 = op2 ? hash_rtx (op2) : 0;
1484
1485 if (hash0 > hash1 && code == EQ)
1486 {
1487 tem = op0; op0 = op1; op1 = tem;
1488 tem_hash = hash0; hash0 = hash1; hash1 = tem_hash;
1489 }
1490 else if (hash1 > hash2 && (code == PLUS || code == MULT))
1491 {
1492 tem = op1; op1 = op2; op2 = tem;
1493 tem_hash = hash1; hash1 = hash2; hash2 = tem_hash;
1494 }
1495
1496 /* If operation is commutative and the first and third operands are equal,
1497 swap the second and third operands. Note that we must consider two
1498 operands equal if they are the same register even if different modes. */
1499 if (op2 && (code == PLUS || code == MULT)
1500 && (rtx_equal_p (op0, op2)
1501 || (GET_CODE (op0) == REG && GET_CODE (op2) == REG
1502 && REGNO (op0) == REGNO (op2))))
1503 {
1504 tem = op1; op1 = op2; op2 = tem;
1505 tem_hash = hash1; hash1 = hash2; hash2 = tem_hash;
1506 }
1507
1508 /* If the first and second operands are the same, merge them. Don't do this
913c6f09
RK
1509 for SFmode or SImode in general registers because this triggers a bug in
1510 the RT fp code. */
e6ee5154
RK
1511 if (op1 && rtx_equal_p (op0, op1)
1512 && code != EQ && code != GE && code != SET
913c6f09
RK
1513 && ((GET_MODE (op1) != SFmode && GET_MODE (op1) != SImode)
1514 || GET_CODE (op0) != REG || FP_REGNO_P (REGNO (op0))))
e6ee5154
RK
1515 {
1516 op1 = op2;
1517 op2 = 0;
1518 }
1519
1520 noperands = 1 + (op1 != 0) + (op2 != 0);
1521
1522 /* Compute hash code for entire expression and see if operation block
1523 already exists. */
1524 hash = ((int) code << 13) + (hash0 << 2) + (hash1 << 1) + hash2;
1525
1526 hash %= FP_HASH_SIZE;
1527 for (fpop = fp_hash_table[hash], last_fpop = 0;
1528 fpop;
1529 last_fpop = fpop, fpop = fpop->next_same_hash)
1530 if (fpop->opcode == code && noperands == fpop->noperands
1531 && (op0 == 0 || rtx_equal_p (op0, fpop->ops[0]))
1532 && (op1 == 0 || rtx_equal_p (op1, fpop->ops[1]))
1533 && (op2 == 0 || rtx_equal_p (op2, fpop->ops[2])))
1534 goto win;
1535
1536 /* We have never seen this operation before. */
1537 fpop = (struct fp_op *) oballoc (sizeof (struct fp_op));
1538 fpop->mem_offset = data_offset;
1539 fpop->opcode = code;
1540 fpop->noperands = noperands;
1541 fpop->ops[0] = op0;
1542 fpop->ops[1] = op1;
1543 fpop->ops[2] = op2;
1544
1545 /* Compute the size using the rules in Appendix A of the RT Linkage
1546 Convention (4.3/RT-PSD:5) manual. These rules are a bit ambiguous,
1547 but if we guess wrong, it will effect only efficiency, not correctness. */
1548
1549 /* Size = 24 + 32 for each non-fp (or fr7) */
1550 size = 24;
1551 if (op0 && (GET_CODE (op0) != REG
1552 || ! FP_REGNO_P (REGNO (op0)) || REGNO (op0) == 23))
1553 size += 32;
1554
1555 if (op1 && (GET_CODE (op1) != REG
1556 || ! FP_REGNO_P (REGNO (op1)) || REGNO (op1) == 23))
1557 size += 32;
1558
1559 if (op2 && (GET_CODE (op2) != REG
1560 || ! FP_REGNO_P (REGNO (op2)) || REGNO (op2) == 23))
1561 size += 32;
1562
1563 /* Size + 12 for each conversion. First get operation mode. */
1564 if ((op0 && GET_MODE (op0) == DFmode)
1565 || (op1 && GET_MODE (op1) == DFmode)
1566 || (op2 && GET_MODE (op2) == DFmode))
1567 opmode = DFmode;
1568 else
1569 opmode = SFmode;
1570
1571 if (op0 && GET_MODE (op0) != opmode)
1572 size += 12;
1573 if (op1 && GET_MODE (op1) != opmode)
1574 size += 12;
1575 if (op2 && GET_MODE (op2) != opmode)
1576 size += 12;
1577
1578 /* 12 more if first and third operand types not the same. */
1579 if (op2 && GET_MODE (op0) != GET_MODE (op2))
1580 size += 12;
1581
1582 /* CMP and CMPT need additional. Also, compute size of save/restore here. */
1583 if (code == EQ)
1584 size += 32;
1585 else if (code == GE)
1586 size += 64;
1587 else if (code == USE || code == CLOBBER)
1588 {
1589 /* 34 + 24 for each additional register plus 8 if fr7 saved. (We
1590 call it 36 because we need to keep the block length a multiple
1591 of four. */
1592 size = 36 - 24;
1593 for (i = 0; i <= 7; i++)
1594 if (INTVAL (op0) & (1 << (7-i)))
1595 size += 24 + 8 * (i == 7);
1596 }
1597
1598 /* We provide no general-purpose scratch registers. */
1599 size +=16;
1600
1601 /* No floating-point scratch registers are provided. Compute extra
1602 length due to this. This logic is that shown in the referenced
1603 appendix. */
1604
1605 i = 0;
1606 if (op0 && GET_CODE (op0) == REG && FP_REGNO_P (REGNO (op0)))
1607 i++;
1608 if (op1 && GET_CODE (op1) == REG && FP_REGNO_P (REGNO (op1)))
1609 i++;
1610 if (op2 && GET_CODE (op2) == REG && FP_REGNO_P (REGNO (op2)))
1611 i++;
1612
1613 if ((op0 == 0 || GET_CODE (op0) != REG || REGNO(op0) != 17)
1614 && (op1 == 0 || GET_CODE (op1) != REG || REGNO(op1) != 17)
1615 && (op2 == 0 || GET_CODE (op2) != REG || REGNO(op2) != 17))
1616 fr0_avail = 1;
1617
1618 if (dyadic)
1619 {
1620 if (i == 0)
1621 size += fr0_avail ? 64 : 112;
1622 else if (fpop->noperands == 2 && i == 1)
1623 size += fr0_avail ? 0 : 64;
1624 else if (fpop->noperands == 3)
1625 {
1626 if (GET_CODE (op0) == REG && FP_REGNO_P (REGNO (op0))
1627 && GET_CODE (op2) == REG && FP_REGNO_P (REGNO (op2)))
1628 {
1629 if (REGNO (op0) == REGNO (op2))
1630#if 1
1631 /* This triggers a bug on the RT. */
1632 abort ();
1633#else
1634 size += fr0_avail ? 0 : 64;
1635#endif
1636 }
1637 else
1638 {
1639 i = 0;
1640 if (GET_CODE (op0) == REG && FP_REGNO_P (REGNO (op0)))
1641 i++;
1642 if (GET_CODE (op2) == REG && FP_REGNO_P (REGNO (op2)))
1643 i++;
1644 if (i == 0)
1645 size += fr0_avail ? 64 : 112;
1646 else if (i == 1)
1647 size += fr0_avail ? 0 : 64;
1648 }
1649 }
1650 }
1651 else if (code != USE && code != CLOBBER
1652 && (GET_CODE (op0) != REG || ! FP_REGNO_P (REGNO (op0))))
1653 size += 64;
1654
1655 if (! TARGET_FULL_FP_BLOCKS)
1656 {
1657 /* If we are not to pad the blocks, just compute its actual length. */
1658 size = 12; /* Header + opcode */
1659 if (code == USE || code == CLOBBER)
1660 size += 2;
1661 else
1662 {
1663 if (op0) size += 2;
1664 if (op1) size += 2;
1665 if (op2) size += 2;
1666 }
1667
1668 /* If in the middle of a word, round. */
1669 if (size % UNITS_PER_WORD)
1670 size += 2;
1671
1672 /* Handle any immediates. */
1673 if (code != USE && code != CLOBBER && op0 && GET_CODE (op0) != REG)
1674 size += 4;
1675 if (op1 && GET_CODE (op1) != REG)
1676 size += 4;
1677 if (op2 && GET_CODE (op2) != REG)
1678 size += 4;
1679
1680 if (code != USE && code != CLOBBER &&
1681 op0 && GET_CODE (op0) == CONST_DOUBLE && GET_MODE (op0) == DFmode)
1682 size += 4;
1683 if (op1 && GET_CODE (op1) == CONST_DOUBLE && GET_MODE (op1) == DFmode)
1684 size += 4;
1685 if (op2 && GET_CODE (op2) == CONST_DOUBLE && GET_MODE (op2) == DFmode)
1686 size += 4;
1687 }
1688
1689 /* Done with size computation! Chain this in. */
1690 fpop->size = size;
1691 data_offset += size / UNITS_PER_WORD;
1692 fpop->next_in_mem = 0;
1693 fpop->next_same_hash = 0;
1694
1695 if (last_fpop_in_mem)
1696 last_fpop_in_mem->next_in_mem = fpop;
1697 else
1698 first_fpop = fpop;
1699 last_fpop_in_mem = fpop;
1700
1701 if (last_fpop)
1702 last_fpop->next_same_hash = fpop;
1703 else
1704 fp_hash_table[hash] = fpop;
1705
1706win:
1707 /* FPOP describes the operation to be performed. Return a string to branch
1708 to it. */
1709 if (fpop->mem_offset < 32768 / UNITS_PER_WORD)
1710 sprintf (outbuf, "cal r15,%d(r14)\n\tbalr%s r15,r15",
1711 fpop->mem_offset * UNITS_PER_WORD,
1712 dbr_sequence_length () ? "x" : "");
1713 else
1714 sprintf (outbuf, "get r15,$L%dF%d\n\tbalr%s r15,r15",
1715 subr_number, fpop->mem_offset * UNITS_PER_WORD,
1716 dbr_sequence_length () ? "x" : "");
1717 return outbuf;
1718}
1719\f
1720/* If necessary, output a floating-point operation to save or restore all
1721 floating-point registers.
1722
1723 file is the file to write the operation to, CODE is USE for save, CLOBBER
1724 for restore, and ADDR is the address of the same area, as RTL. */
1725
1726static void
1727output_loadsave_fpregs (file, code, addr)
1728 FILE *file;
1729 enum rtx_code code;
1730 rtx addr;
1731{
1732 register int i;
1733 register int mask = 0;
1734
1735 for (i = 2 + (TARGET_FP_REGS != 0); i <= 7; i++)
1736 if (regs_ever_live[i + 17])
1737 mask |= 1 << (7 - i);
1738
1739 if (mask)
1740 fprintf (file, "\t%s\n",
1741 output_fpop (code, gen_rtx (CONST_INT, VOIDmode, mask),
1742 gen_rtx (MEM, Pmode, addr),
1743 0, const0_rtx));
1744
1745}
1746\f
1747/* Output any floating-point operations at the end of the routine. */
1748
1749static void
1750output_fpops (file)
1751 FILE *file;
1752{
1753 register struct fp_op *fpop;
1754 register int size_so_far;
1755 register int i;
1756 rtx immed[3];
1757
1758 if (first_fpop == 0)
1759 return;
1760
1761 data_section ();
1762
1763 ASM_OUTPUT_ALIGN (file, 2);
1764
1765 for (fpop = first_fpop; fpop; fpop = fpop->next_in_mem)
1766 {
1767 if (fpop->mem_offset < 32768 / UNITS_PER_WORD)
1768 fprintf (file, "# data area offset = %d\n",
1769 fpop->mem_offset * UNITS_PER_WORD);
1770 else
1771 fprintf (file, "L%dF%d:\n",
1772 subr_number, fpop->mem_offset * UNITS_PER_WORD);
1773
1774 fprintf (file, "\tcas r0,r15,r0\n");
1775 fprintf (file, "\t.long FPGLUE\n");
1776 switch (fpop->opcode)
1777 {
1778 case USE:
1779 fprintf (file, "\t.byte 0x1d\t# STOREM\n");
1780 break;
1781 case CLOBBER:
1782 fprintf (file, "\t.byte 0x0f\t# LOADM\n");
1783 break;
1784 case ABS:
1785 fprintf (file, "\t.byte 0x00\t# ABS\n");
1786 break;
1787 case PLUS:
1788 fprintf (file, "\t.byte 0x02\t# ADD\n");
1789 break;
1790 case EQ:
1791 fprintf (file, "\t.byte 0x07\t# CMP\n");
1792 break;
1793 case GE:
1794 fprintf (file, "\t.byte 0x08\t# CMPT\n");
1795 break;
1796 case DIV:
1797 fprintf (file, "\t.byte 0x0c\t# DIV\n");
1798 break;
1799 case SET:
1800 fprintf (file, "\t.byte 0x14\t# MOVE\n");
1801 break;
1802 case MULT:
1803 fprintf (file, "\t.byte 0x15\t# MUL\n");
1804 break;
1805 case NEG:
1806 fprintf (file, "\t.byte 0x16\t# NEG\n");
1807 break;
1808 case SQRT:
1809 fprintf (file, "\t.byte 0x1c\t# SQRT\n");
1810 break;
1811 case MINUS:
1812 fprintf (file, "\t.byte 0x1e\t# SUB\n");
1813 break;
1814 default:
1815 abort ();
1816 }
1817
1818 fprintf (file, "\t.byte %d\n", fpop->noperands);
1819 fprintf (file, "\t.short 0x8001\n");
1820
1821 if ((fpop->ops[0] == 0
1822 || GET_CODE (fpop->ops[0]) != REG || REGNO(fpop->ops[0]) != 17)
1823 && (fpop->ops[1] == 0 || GET_CODE (fpop->ops[1]) != REG
1824 || REGNO(fpop->ops[1]) != 17)
1825 && (fpop->ops[2] == 0 || GET_CODE (fpop->ops[2]) != REG
1826 || REGNO(fpop->ops[2]) != 17))
1827 fprintf (file, "\t.byte %d, 0x80\n", fpop->size);
1828 else
1829 fprintf (file, "\t.byte %d, 0\n", fpop->size);
1830 size_so_far = 12;
1831 for (i = 0; i < fpop->noperands; i++)
1832 {
1833 register int type;
1834 register int opbyte;
1835 register char *desc0;
1836 char desc1[50];
1837
1838 immed[i] = 0;
1839 switch (GET_MODE (fpop->ops[i]))
1840 {
1841 case SImode:
1842 case VOIDmode:
1843 desc0 = "int";
1844 type = 0;
1845 break;
1846 case SFmode:
1847 desc0 = "float";
1848 type = 2;
1849 break;
1850 case DFmode:
1851 desc0 = "double";
1852 type = 3;
1853 break;
1854 default:
1855 abort ();
1856 }
1857
1858 switch (GET_CODE (fpop->ops[i]))
1859 {
1860 case REG:
1861 strcpy(desc1, reg_names[REGNO (fpop->ops[i])]);
1862 if (FP_REGNO_P (REGNO (fpop->ops[i])))
1863 {
1864 type += 0x10;
1865 opbyte = REGNO (fpop->ops[i]) - 17;
1866 }
1867 else
1868 {
1869 type += 0x00;
1870 opbyte = REGNO (fpop->ops[i]);
1871 if (type == 3)
1872 opbyte = (opbyte << 4) + opbyte + 1;
1873 }
1874 break;
1875
1876 case MEM:
1877 type += 0x30;
1878 if (GET_CODE (XEXP (fpop->ops[i], 0)) == PLUS)
1879 {
1880 immed[i] = XEXP (XEXP (fpop->ops[i], 0), 1);
1881 opbyte = REGNO (XEXP (XEXP (fpop->ops[i], 0), 0));
1882 if (GET_CODE (immed[i]) == CONST_INT)
1883 sprintf (desc1, "%d(%s)", INTVAL (immed[i]),
1884 reg_names[opbyte]);
1885 else
1886 sprintf (desc1, "<memory> (%s)", reg_names[opbyte]);
1887 }
1888 else if (GET_CODE (XEXP (fpop->ops[i], 0)) == REG)
1889 {
1890 opbyte = REGNO (XEXP (fpop->ops[i], 0));
1891 immed[i] = const0_rtx;
1892 sprintf (desc1, "(%s)", reg_names[opbyte]);
1893 }
1894 else
1895 {
1896 immed[i] = XEXP (fpop->ops[i], 0);
1897 opbyte = 0;
1898 sprintf(desc1, "<memory>");
1899 }
1900 break;
1901
1902 case CONST_INT:
1903 case CONST_DOUBLE:
1904 case CONST:
5187794f
RK
1905 case SYMBOL_REF:
1906 case LABEL_REF:
e6ee5154
RK
1907 type += 0x20;
1908 opbyte = 0;
1909 immed[i] = fpop->ops[i];
1910 desc1[0] = '$';
1911 desc1[1] = '\0';
1912 break;
1913
1914 default:
1915 abort ();
1916 }
1917
1918 /* Save/restore is special. */
1919 if (i == 0 && (fpop->opcode == USE || fpop->opcode == CLOBBER))
1920 type = 0xff, opbyte = INTVAL (fpop->ops[0]), immed[i] = 0;
1921
1922 fprintf (file, "\t.byte 0x%x,0x%x # (%s) %s\n",
1923 type, opbyte, desc0, desc1);
1924
1925 size_so_far += 2;
1926 }
1927
1928 /* If in the middle of a word, round. */
1929 if (size_so_far % UNITS_PER_WORD)
1930 {
1931 fprintf (file, "\t.space 2\n");
1932 size_so_far += 2;
1933 }
1934
1935 for (i = 0; i < fpop->noperands; i++)
1936 if (immed[i])
1937 switch (GET_MODE (immed[i]))
1938 {
1939 case SImode:
1940 case VOIDmode:
1941 size_so_far += 4;
1942 fprintf (file, "\t.long ");
1943 output_addr_const (file, immed[i]);
1944 fprintf (file, "\n");
1945 break;
1946
1947 case DFmode:
1948 size_so_far += 4;
1949 case SFmode:
1950 size_so_far += 4;
1951 if (GET_CODE (immed[i]) == CONST_DOUBLE)
1952 {
1953 union real_extract u;
1954
1955 bcopy (&CONST_DOUBLE_LOW (immed[i]), &u, sizeof u);
1956 if (GET_MODE (immed[i]) == DFmode)
1957 ASM_OUTPUT_DOUBLE (file, u.d);
1958 else
1959 ASM_OUTPUT_FLOAT (file, u.d);
1960 }
1961 else
1962 abort ();
1963 break;
1964
1965 default:
1966 abort ();
1967 }
1968
1969 if (size_so_far != fpop->size)
1970 {
1971 if (TARGET_FULL_FP_BLOCKS)
1972 fprintf (file, "\t.space %d\n", fpop->size - size_so_far);
1973 else
1974 abort ();
1975 }
1976 }
1977
1978 /* Update for next subroutine. */
1979 subr_number++;
1980 text_section ();
1981}
1982
1983 /* Initialize floating-point operation table. */
1984
1985static void
1986init_fpops()
1987{
1988 register int i;
1989
1990 first_fpop = last_fpop_in_mem = 0;
1991 for (i = 0; i < FP_HASH_SIZE; i++)
1992 fp_hash_table[i] = 0;
1993}
d1abe602
RK
1994\f
1995/* Return the offset value of an automatic variable (N_LSYM) having
1996 the given offset. Basically, we correct by going from a frame pointer to
1997 stack pointer value.
1998*/
1999
2000int
2001romp_debugger_auto_correction(offset)
2002 int offset;
2003{
2004 int fp_to_sp;
2005
2006 /* We really want to go from STACK_POINTER_REGNUM to
2007 FRAME_POINTER_REGNUM, but this isn't defined. So go the other
2008 direction and negate. */
2009 INITIAL_ELIMINATION_OFFSET (FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM,
2010 fp_to_sp);
2011
2012 /* The offset value points somewhere between the frame pointer and
2013 the stack pointer. What is up from the frame pointer is down from the
2014 stack pointer. Therefore the negation in the offset value too. */
2015
2016 return -(offset+fp_to_sp+4);
2017}
2018
2019/* Return the offset value of an argument having
2020 the given offset. Basically, we correct by going from a arg pointer to
2021 stack pointer value. */
2022
2023int
2024romp_debugger_arg_correction (offset)
2025 int offset;
2026{
2027 int fp_to_argp;
2028
2029 INITIAL_ELIMINATION_OFFSET (ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM,
2030 fp_to_argp);
2031
2032 /* Actually, something different happens if offset is from a floating-point
2033 register argument, but we don't handle it here. */
2034
2035 return (offset - fp_to_argp);
2036}
This page took 0.340143 seconds and 5 git commands to generate.