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