]> gcc.gnu.org Git - gcc.git/blob - gcc/config/romp/romp.c
entered into RCS
[gcc.git] / gcc / config / romp / romp.c
1 /* Subroutines used for code generation on ROMP.
2 Copyright (C) 1990, 1991 Free Software Foundation, Inc.
3 Contributed by Richard Kenner (kenner@nyu.edu)
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 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
42 static int unsigned_comparisons_p ();
43 static void output_loadsave_fpregs ();
44 static void output_fpops ();
45 static 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
52 int
53 next_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
72 static int
73 unsigned_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
127 update_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
217 int
218 restore_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. */
232 char *
233 output_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
251 static int
252 memory_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
302 int
303 zero_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
312 int
313 short_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
328 int
329 symbolic_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
354 int
355 current_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
370 int
371 null_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
380 int
381 constant_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
395 int
396 romp_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
419 int
420 constant_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
445 int
446 reg_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
458 int
459 reg_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
468 int
469 reg_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
482 int
483 reg_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
494 int
495 reg_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
511 int
512 reg_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
522 int
523 reg_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
539 int
540 romp_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
552 int
553 reg_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
563 int
564 reg_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
574 int
575 float_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
601 int
602 float_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
616 /* Return 1 if this is a valid floating-point conversion that can be done
617 as part of an operation by the RT floating-point routines. */
618
619 int
620 float_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
653 void
654 print_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 '.':
932 /* Output nothing. Used as delimiter in, e.g., "mc%B1%.3 " */
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
966 int
967 first_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
987 int
988 romp_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
1014 int
1015 romp_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
1041 int
1042 romp_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
1052 int
1053 romp_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
1072 void
1073 output_prolog (file, size)
1074 FILE *file;
1075 int size;
1076 {
1077 int first_reg;
1078 int reg_save_offset;
1079 rtx insn;
1080 int fp_save = size + current_function_outgoing_args_size;
1081
1082 init_fpops ();
1083
1084 /* Add in fixed size plus output argument area. */
1085 size += romp_sa_size () + current_function_outgoing_args_size;
1086
1087 /* Compute first register to save and perform the save operation if anything
1088 needs to be saved. */
1089 first_reg = first_reg_to_save();
1090 reg_save_offset = - (4 + 4 + 1 + (16 - first_reg)) * 4;
1091 if (first_reg == 15)
1092 fprintf (file, "\tst r15,%d(r1)\n", reg_save_offset);
1093 else if (first_reg < 16)
1094 fprintf (file, "\tstm r%d,%d(r1)\n", first_reg, reg_save_offset);
1095
1096 /* Set up pointer to data area if it is needed. */
1097 if (romp_using_r14 ())
1098 fprintf (file, "\tcas r14,r0,r0\n");
1099
1100 /* Set up frame pointer if needed. */
1101 if (frame_pointer_needed)
1102 fprintf (file, "\tcal r13,-%d(r1)\n", romp_sa_size () + 64);
1103
1104 /* Push stack if neeeded. There are a couple of ways of doing this. */
1105 if (romp_pushes_stack ())
1106 {
1107 if (size >= 32768)
1108 {
1109 if (size >= 65536)
1110 {
1111 fprintf (file, "\tcau r0,%d(r0)\n", size >> 16);
1112 fprintf (file, "\toil r0,r0,%d\n", size & 0xffff);
1113 }
1114 else
1115 fprintf (file, "\tcal16 r0,%d(r0)\n", size);
1116 fprintf (file, "\ts r1,r0\n");
1117 }
1118 else
1119 fprintf (file, "\tcal r1,-%d(r1)\n", size);
1120 }
1121
1122 /* Save floating-point registers. */
1123 output_loadsave_fpregs (file, USE,
1124 plus_constant (stack_pointer_rtx, fp_save));
1125 }
1126
1127 /* Write function epilogue. */
1128
1129 void
1130 output_epilog (file, size)
1131 FILE *file;
1132 int size;
1133 {
1134 int first_reg = first_reg_to_save();
1135 int pushes_stack = romp_pushes_stack ();
1136 int reg_save_offset = - ((16 - first_reg) + 1 + 4 + 4) * 4;
1137 int total_size = (size + romp_sa_size ()
1138 + current_function_outgoing_args_size);
1139 int fp_save = size + current_function_outgoing_args_size;
1140 int long_frame = total_size >= 32768;
1141 rtx insn = get_last_insn ();
1142 int write_code = 1;
1143
1144 int nargs = 0; /* words of arguments */
1145 tree argptr;
1146
1147 for (argptr = DECL_ARGUMENTS (current_function_decl);
1148 argptr; argptr = TREE_CHAIN (argptr))
1149 nargs += ((TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (argptr)))
1150 + BITS_PER_WORD - 1) / BITS_PER_WORD);
1151
1152 /* If the last insn was a BARRIER, we don't have to write anything except
1153 the trace table. */
1154 if (GET_CODE (insn) == NOTE)
1155 insn = prev_nonnote_insn (insn);
1156 if (insn && GET_CODE (insn) == BARRIER)
1157 write_code = 0;
1158
1159 /* Restore floating-point registers. */
1160 if (write_code)
1161 output_loadsave_fpregs (file, CLOBBER,
1162 gen_rtx (PLUS, Pmode, gen_rtx (REG, Pmode, 1),
1163 gen_rtx (CONST_INT, VOIDmode, fp_save)));
1164
1165 /* If we push the stack and do not have size > 32K, adjust the register
1166 save location to the current position of sp. Otherwise, if long frame,
1167 restore sp from fp. */
1168 if (pushes_stack && ! long_frame)
1169 reg_save_offset += total_size;
1170 else if (long_frame && write_code)
1171 fprintf (file, "\tcal r1,%d(r13)\n", romp_sa_size () + 64);
1172
1173 /* Restore registers. */
1174 if (first_reg == 15 && write_code)
1175 fprintf (file, "\tl r15,%d(r1)\n", reg_save_offset);
1176 else if (first_reg < 16 && write_code)
1177 fprintf (file, "\tlm r%d,%d(r1)\n", first_reg, reg_save_offset);
1178 if (first_reg == 16) first_reg = 0;
1179
1180 /* Handle popping stack, if needed and write debug table entry. */
1181 if (pushes_stack)
1182 {
1183 if (write_code)
1184 {
1185 if (long_frame)
1186 fprintf (file, "\tbr r15\n");
1187 else
1188 fprintf (file, "\tbrx r15\n\tcal r1,%d(r1)\n", total_size);
1189 }
1190 fprintf (file, "\t.long 0x%x\n", 0xdf07df08 + first_reg * 0x10);
1191
1192 if (nargs > 15) nargs = 15;
1193 if (frame_pointer_needed)
1194 fprintf (file, "\t.byte 0x%xd, 53\n", nargs);
1195 else
1196 fprintf (file, "\t.short 0x%x100\n", nargs);
1197 }
1198 else
1199 {
1200 if (write_code)
1201 fprintf (file, "\tbr r15\n");
1202 fprintf (file, "\t.long 0xdf02df00\n");
1203 }
1204
1205 /* Output any pending floating-point operations. */
1206 if (write_code)
1207 output_fpops (file);
1208 }
1209 \f
1210 /* For the ROMP we need to make new SYMBOL_REFs for the actual name of a
1211 called routine. To keep them unique we maintain a hash table of all
1212 that have been created so far. */
1213
1214 struct symref_hashent {
1215 rtx symref; /* Created SYMBOL_REF rtx. */
1216 struct symref_hashent *next; /* Next with same hash code. */
1217 };
1218
1219 #define SYMHASHSIZE 151
1220 #define HASHBITS 65535
1221
1222 /* Define the hash table itself. */
1223
1224 static struct symref_hashent *symref_hash_table[SYMHASHSIZE];
1225
1226 /* Given a name (allocatable in temporary storage), return a SYMBOL_REF
1227 for the name. The rtx is allocated from the current rtl_obstack, while
1228 the name string is allocated from the permanent obstack. */
1229 rtx
1230 get_symref (name)
1231 register char *name;
1232 {
1233 extern struct obstack permanent_obstack;
1234 register char *sp = name;
1235 unsigned int hash = 0;
1236 struct symref_hashent *p, **last_p;
1237
1238 /* Compute the hash code for the string. */
1239 while (*sp)
1240 hash = (hash << 4) + *sp++;
1241
1242 /* Search for a matching entry in the hash table, keeping track of the
1243 insertion location as we do so. */
1244 hash = (hash & HASHBITS) % SYMHASHSIZE;
1245 for (last_p = &symref_hash_table[hash], p = *last_p;
1246 p; last_p = &p->next, p = *last_p)
1247 if (strcmp (name, XSTR (p->symref, 0)) == 0)
1248 break;
1249
1250 /* If couldn't find matching SYMBOL_REF, make a new one. */
1251 if (p == 0)
1252 {
1253 /* Ensure SYMBOL_REF will stay around. */
1254 end_temporary_allocation ();
1255 p = *last_p = (struct symref_hashent *)
1256 permalloc (sizeof (struct symref_hashent));
1257 p->symref = gen_rtx (SYMBOL_REF, Pmode,
1258 obstack_copy0 (&permanent_obstack,
1259 name, strlen (name)));
1260 p->next = 0;
1261 resume_temporary_allocation ();
1262 }
1263
1264 return p->symref;
1265 }
1266 \f
1267 /* Validate the precision of a floating-point operation.
1268
1269 We merge conversions from integers and between floating-point modes into
1270 the insn. However, this must not effect the desired precision of the
1271 insn. The RT floating-point system uses the widest of the operand modes.
1272 If this should be a double-precision insn, ensure that one operand
1273 passed to the floating-point processor has double mode.
1274
1275 Note that since we don't check anything if the mode is single precision,
1276 it, strictly speaking, isn't necessary to call this for those insns.
1277 However, we do so in case something else needs to be checked in the
1278 future.
1279
1280 This routine returns 1 if the operation is OK. */
1281
1282 int
1283 check_precision (opmode, op1, op2)
1284 enum machine_mode opmode;
1285 rtx op1, op2;
1286 {
1287 if (opmode == SFmode)
1288 return 1;
1289
1290 /* If operand is not a conversion from an integer mode or an extension from
1291 single-precision, it must be a double-precision value. */
1292 if (GET_CODE (op1) != FLOAT && GET_CODE (op1) != FLOAT_EXTEND)
1293 return 1;
1294
1295 if (op2 && GET_CODE (op2) != FLOAT && GET_CODE (op2) != FLOAT_EXTEND)
1296 return 1;
1297
1298 return 0;
1299 }
1300 \f
1301 /* Floating-point on the RT is done by creating an operation block in the data
1302 area that describes the operation. If two floating-point operations are the
1303 same in a single function, they can use the same block.
1304
1305 These routines are responsible for managing these blocks. */
1306
1307 /* Structure to describe a floating-point operation. */
1308
1309 struct fp_op {
1310 struct fp_op *next_same_hash; /* Next op with same hash code. */
1311 struct fp_op *next_in_mem; /* Next op in memory. */
1312 int mem_offset; /* Offset from data area. */
1313 short size; /* Size of block in bytes. */
1314 short noperands; /* Number of operands in block. */
1315 rtx ops[3]; /* RTL for operands. */
1316 enum rtx_code opcode; /* Operation being performed. */
1317 };
1318
1319 /* Size of hash table. */
1320 #define FP_HASH_SIZE 101
1321
1322 /* Hash table of floating-point operation blocks. */
1323 static struct fp_op *fp_hash_table[FP_HASH_SIZE];
1324
1325 /* First floating-point block in data area. */
1326 static struct fp_op *first_fpop;
1327
1328 /* Last block in data area so far. */
1329 static struct fp_op *last_fpop_in_mem;
1330
1331 /* Subroutine number in file, to get unique "LF" labels. */
1332 static int subr_number = 0;
1333
1334 /* Current word offset in data area (includes header and any constant pool). */
1335 int data_offset;
1336
1337 /* Compute hash code for an RTX used in floating-point. */
1338
1339 static unsigned int
1340 hash_rtx (x)
1341 register rtx x;
1342 {
1343 register unsigned int hash = (((int) GET_CODE (x) << 10)
1344 + ((int) GET_MODE (x) << 20));
1345 register int i;
1346 register char *fmt = GET_RTX_FORMAT (GET_CODE (x));
1347
1348 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (x)); i++)
1349 if (fmt[i] == 'e')
1350 hash += hash_rtx (XEXP (x, i));
1351 else if (fmt[i] == 'u')
1352 hash += (int) XEXP (x, i);
1353 else if (fmt[i] == 'i')
1354 hash += XINT (x, i);
1355 else if (fmt[i] == 's')
1356 hash += (int) XSTR (x, i);
1357
1358 return hash;
1359 }
1360 \f
1361 /* Given an operation code and up to three operands, return a character string
1362 corresponding to the code to emit to branch to a floating-point operation
1363 block. INSN is provided to see if the delay slot has been filled or not.
1364
1365 A new floating-point operation block is created if this operation has not
1366 been seen before. */
1367
1368 char *
1369 output_fpop (code, op0, op1, op2, insn)
1370 enum rtx_code code;
1371 rtx op0, op1, op2;
1372 rtx insn;
1373 {
1374 static char outbuf[40];
1375 unsigned int hash, hash0, hash1, hash2;
1376 int size, i;
1377 register struct fp_op *fpop, *last_fpop;
1378 int dyadic = (op2 != 0);
1379 enum machine_mode opmode;
1380 int noperands;
1381 rtx tem;
1382 unsigned int tem_hash;
1383 int fr0_avail = 0;
1384
1385 /* Compute hash code for each operand. If the operation is commutative,
1386 put the one with the smaller hash code first. This will make us see
1387 more operations as identical. */
1388 hash0 = op0 ? hash_rtx (op0) : 0;
1389 hash1 = op1 ? hash_rtx (op1) : 0;
1390 hash2 = op2 ? hash_rtx (op2) : 0;
1391
1392 if (hash0 > hash1 && code == EQ)
1393 {
1394 tem = op0; op0 = op1; op1 = tem;
1395 tem_hash = hash0; hash0 = hash1; hash1 = tem_hash;
1396 }
1397 else if (hash1 > hash2 && (code == PLUS || code == MULT))
1398 {
1399 tem = op1; op1 = op2; op2 = tem;
1400 tem_hash = hash1; hash1 = hash2; hash2 = tem_hash;
1401 }
1402
1403 /* If operation is commutative and the first and third operands are equal,
1404 swap the second and third operands. Note that we must consider two
1405 operands equal if they are the same register even if different modes. */
1406 if (op2 && (code == PLUS || code == MULT)
1407 && (rtx_equal_p (op0, op2)
1408 || (GET_CODE (op0) == REG && GET_CODE (op2) == REG
1409 && REGNO (op0) == REGNO (op2))))
1410 {
1411 tem = op1; op1 = op2; op2 = tem;
1412 tem_hash = hash1; hash1 = hash2; hash2 = tem_hash;
1413 }
1414
1415 /* If the first and second operands are the same, merge them. Don't do this
1416 for SFmode or SImode in general registers because this triggers a bug in
1417 the RT fp code. */
1418 if (op1 && rtx_equal_p (op0, op1)
1419 && code != EQ && code != GE && code != SET
1420 && ((GET_MODE (op1) != SFmode && GET_MODE (op1) != SImode)
1421 || GET_CODE (op0) != REG || FP_REGNO_P (REGNO (op0))))
1422 {
1423 op1 = op2;
1424 op2 = 0;
1425 }
1426
1427 noperands = 1 + (op1 != 0) + (op2 != 0);
1428
1429 /* Compute hash code for entire expression and see if operation block
1430 already exists. */
1431 hash = ((int) code << 13) + (hash0 << 2) + (hash1 << 1) + hash2;
1432
1433 hash %= FP_HASH_SIZE;
1434 for (fpop = fp_hash_table[hash], last_fpop = 0;
1435 fpop;
1436 last_fpop = fpop, fpop = fpop->next_same_hash)
1437 if (fpop->opcode == code && noperands == fpop->noperands
1438 && (op0 == 0 || rtx_equal_p (op0, fpop->ops[0]))
1439 && (op1 == 0 || rtx_equal_p (op1, fpop->ops[1]))
1440 && (op2 == 0 || rtx_equal_p (op2, fpop->ops[2])))
1441 goto win;
1442
1443 /* We have never seen this operation before. */
1444 fpop = (struct fp_op *) oballoc (sizeof (struct fp_op));
1445 fpop->mem_offset = data_offset;
1446 fpop->opcode = code;
1447 fpop->noperands = noperands;
1448 fpop->ops[0] = op0;
1449 fpop->ops[1] = op1;
1450 fpop->ops[2] = op2;
1451
1452 /* Compute the size using the rules in Appendix A of the RT Linkage
1453 Convention (4.3/RT-PSD:5) manual. These rules are a bit ambiguous,
1454 but if we guess wrong, it will effect only efficiency, not correctness. */
1455
1456 /* Size = 24 + 32 for each non-fp (or fr7) */
1457 size = 24;
1458 if (op0 && (GET_CODE (op0) != REG
1459 || ! FP_REGNO_P (REGNO (op0)) || REGNO (op0) == 23))
1460 size += 32;
1461
1462 if (op1 && (GET_CODE (op1) != REG
1463 || ! FP_REGNO_P (REGNO (op1)) || REGNO (op1) == 23))
1464 size += 32;
1465
1466 if (op2 && (GET_CODE (op2) != REG
1467 || ! FP_REGNO_P (REGNO (op2)) || REGNO (op2) == 23))
1468 size += 32;
1469
1470 /* Size + 12 for each conversion. First get operation mode. */
1471 if ((op0 && GET_MODE (op0) == DFmode)
1472 || (op1 && GET_MODE (op1) == DFmode)
1473 || (op2 && GET_MODE (op2) == DFmode))
1474 opmode = DFmode;
1475 else
1476 opmode = SFmode;
1477
1478 if (op0 && GET_MODE (op0) != opmode)
1479 size += 12;
1480 if (op1 && GET_MODE (op1) != opmode)
1481 size += 12;
1482 if (op2 && GET_MODE (op2) != opmode)
1483 size += 12;
1484
1485 /* 12 more if first and third operand types not the same. */
1486 if (op2 && GET_MODE (op0) != GET_MODE (op2))
1487 size += 12;
1488
1489 /* CMP and CMPT need additional. Also, compute size of save/restore here. */
1490 if (code == EQ)
1491 size += 32;
1492 else if (code == GE)
1493 size += 64;
1494 else if (code == USE || code == CLOBBER)
1495 {
1496 /* 34 + 24 for each additional register plus 8 if fr7 saved. (We
1497 call it 36 because we need to keep the block length a multiple
1498 of four. */
1499 size = 36 - 24;
1500 for (i = 0; i <= 7; i++)
1501 if (INTVAL (op0) & (1 << (7-i)))
1502 size += 24 + 8 * (i == 7);
1503 }
1504
1505 /* We provide no general-purpose scratch registers. */
1506 size +=16;
1507
1508 /* No floating-point scratch registers are provided. Compute extra
1509 length due to this. This logic is that shown in the referenced
1510 appendix. */
1511
1512 i = 0;
1513 if (op0 && GET_CODE (op0) == REG && FP_REGNO_P (REGNO (op0)))
1514 i++;
1515 if (op1 && GET_CODE (op1) == REG && FP_REGNO_P (REGNO (op1)))
1516 i++;
1517 if (op2 && GET_CODE (op2) == REG && FP_REGNO_P (REGNO (op2)))
1518 i++;
1519
1520 if ((op0 == 0 || GET_CODE (op0) != REG || REGNO(op0) != 17)
1521 && (op1 == 0 || GET_CODE (op1) != REG || REGNO(op1) != 17)
1522 && (op2 == 0 || GET_CODE (op2) != REG || REGNO(op2) != 17))
1523 fr0_avail = 1;
1524
1525 if (dyadic)
1526 {
1527 if (i == 0)
1528 size += fr0_avail ? 64 : 112;
1529 else if (fpop->noperands == 2 && i == 1)
1530 size += fr0_avail ? 0 : 64;
1531 else if (fpop->noperands == 3)
1532 {
1533 if (GET_CODE (op0) == REG && FP_REGNO_P (REGNO (op0))
1534 && GET_CODE (op2) == REG && FP_REGNO_P (REGNO (op2)))
1535 {
1536 if (REGNO (op0) == REGNO (op2))
1537 #if 1
1538 /* This triggers a bug on the RT. */
1539 abort ();
1540 #else
1541 size += fr0_avail ? 0 : 64;
1542 #endif
1543 }
1544 else
1545 {
1546 i = 0;
1547 if (GET_CODE (op0) == REG && FP_REGNO_P (REGNO (op0)))
1548 i++;
1549 if (GET_CODE (op2) == REG && FP_REGNO_P (REGNO (op2)))
1550 i++;
1551 if (i == 0)
1552 size += fr0_avail ? 64 : 112;
1553 else if (i == 1)
1554 size += fr0_avail ? 0 : 64;
1555 }
1556 }
1557 }
1558 else if (code != USE && code != CLOBBER
1559 && (GET_CODE (op0) != REG || ! FP_REGNO_P (REGNO (op0))))
1560 size += 64;
1561
1562 if (! TARGET_FULL_FP_BLOCKS)
1563 {
1564 /* If we are not to pad the blocks, just compute its actual length. */
1565 size = 12; /* Header + opcode */
1566 if (code == USE || code == CLOBBER)
1567 size += 2;
1568 else
1569 {
1570 if (op0) size += 2;
1571 if (op1) size += 2;
1572 if (op2) size += 2;
1573 }
1574
1575 /* If in the middle of a word, round. */
1576 if (size % UNITS_PER_WORD)
1577 size += 2;
1578
1579 /* Handle any immediates. */
1580 if (code != USE && code != CLOBBER && op0 && GET_CODE (op0) != REG)
1581 size += 4;
1582 if (op1 && GET_CODE (op1) != REG)
1583 size += 4;
1584 if (op2 && GET_CODE (op2) != REG)
1585 size += 4;
1586
1587 if (code != USE && code != CLOBBER &&
1588 op0 && GET_CODE (op0) == CONST_DOUBLE && GET_MODE (op0) == DFmode)
1589 size += 4;
1590 if (op1 && GET_CODE (op1) == CONST_DOUBLE && GET_MODE (op1) == DFmode)
1591 size += 4;
1592 if (op2 && GET_CODE (op2) == CONST_DOUBLE && GET_MODE (op2) == DFmode)
1593 size += 4;
1594 }
1595
1596 /* Done with size computation! Chain this in. */
1597 fpop->size = size;
1598 data_offset += size / UNITS_PER_WORD;
1599 fpop->next_in_mem = 0;
1600 fpop->next_same_hash = 0;
1601
1602 if (last_fpop_in_mem)
1603 last_fpop_in_mem->next_in_mem = fpop;
1604 else
1605 first_fpop = fpop;
1606 last_fpop_in_mem = fpop;
1607
1608 if (last_fpop)
1609 last_fpop->next_same_hash = fpop;
1610 else
1611 fp_hash_table[hash] = fpop;
1612
1613 win:
1614 /* FPOP describes the operation to be performed. Return a string to branch
1615 to it. */
1616 if (fpop->mem_offset < 32768 / UNITS_PER_WORD)
1617 sprintf (outbuf, "cal r15,%d(r14)\n\tbalr%s r15,r15",
1618 fpop->mem_offset * UNITS_PER_WORD,
1619 dbr_sequence_length () ? "x" : "");
1620 else
1621 sprintf (outbuf, "get r15,$L%dF%d\n\tbalr%s r15,r15",
1622 subr_number, fpop->mem_offset * UNITS_PER_WORD,
1623 dbr_sequence_length () ? "x" : "");
1624 return outbuf;
1625 }
1626 \f
1627 /* If necessary, output a floating-point operation to save or restore all
1628 floating-point registers.
1629
1630 file is the file to write the operation to, CODE is USE for save, CLOBBER
1631 for restore, and ADDR is the address of the same area, as RTL. */
1632
1633 static void
1634 output_loadsave_fpregs (file, code, addr)
1635 FILE *file;
1636 enum rtx_code code;
1637 rtx addr;
1638 {
1639 register int i;
1640 register int mask = 0;
1641
1642 for (i = 2 + (TARGET_FP_REGS != 0); i <= 7; i++)
1643 if (regs_ever_live[i + 17])
1644 mask |= 1 << (7 - i);
1645
1646 if (mask)
1647 fprintf (file, "\t%s\n",
1648 output_fpop (code, gen_rtx (CONST_INT, VOIDmode, mask),
1649 gen_rtx (MEM, Pmode, addr),
1650 0, const0_rtx));
1651
1652 }
1653 \f
1654 /* Output any floating-point operations at the end of the routine. */
1655
1656 static void
1657 output_fpops (file)
1658 FILE *file;
1659 {
1660 register struct fp_op *fpop;
1661 register int size_so_far;
1662 register int i;
1663 rtx immed[3];
1664
1665 if (first_fpop == 0)
1666 return;
1667
1668 data_section ();
1669
1670 ASM_OUTPUT_ALIGN (file, 2);
1671
1672 for (fpop = first_fpop; fpop; fpop = fpop->next_in_mem)
1673 {
1674 if (fpop->mem_offset < 32768 / UNITS_PER_WORD)
1675 fprintf (file, "# data area offset = %d\n",
1676 fpop->mem_offset * UNITS_PER_WORD);
1677 else
1678 fprintf (file, "L%dF%d:\n",
1679 subr_number, fpop->mem_offset * UNITS_PER_WORD);
1680
1681 fprintf (file, "\tcas r0,r15,r0\n");
1682 fprintf (file, "\t.long FPGLUE\n");
1683 switch (fpop->opcode)
1684 {
1685 case USE:
1686 fprintf (file, "\t.byte 0x1d\t# STOREM\n");
1687 break;
1688 case CLOBBER:
1689 fprintf (file, "\t.byte 0x0f\t# LOADM\n");
1690 break;
1691 case ABS:
1692 fprintf (file, "\t.byte 0x00\t# ABS\n");
1693 break;
1694 case PLUS:
1695 fprintf (file, "\t.byte 0x02\t# ADD\n");
1696 break;
1697 case EQ:
1698 fprintf (file, "\t.byte 0x07\t# CMP\n");
1699 break;
1700 case GE:
1701 fprintf (file, "\t.byte 0x08\t# CMPT\n");
1702 break;
1703 case DIV:
1704 fprintf (file, "\t.byte 0x0c\t# DIV\n");
1705 break;
1706 case SET:
1707 fprintf (file, "\t.byte 0x14\t# MOVE\n");
1708 break;
1709 case MULT:
1710 fprintf (file, "\t.byte 0x15\t# MUL\n");
1711 break;
1712 case NEG:
1713 fprintf (file, "\t.byte 0x16\t# NEG\n");
1714 break;
1715 case SQRT:
1716 fprintf (file, "\t.byte 0x1c\t# SQRT\n");
1717 break;
1718 case MINUS:
1719 fprintf (file, "\t.byte 0x1e\t# SUB\n");
1720 break;
1721 default:
1722 abort ();
1723 }
1724
1725 fprintf (file, "\t.byte %d\n", fpop->noperands);
1726 fprintf (file, "\t.short 0x8001\n");
1727
1728 if ((fpop->ops[0] == 0
1729 || GET_CODE (fpop->ops[0]) != REG || REGNO(fpop->ops[0]) != 17)
1730 && (fpop->ops[1] == 0 || GET_CODE (fpop->ops[1]) != REG
1731 || REGNO(fpop->ops[1]) != 17)
1732 && (fpop->ops[2] == 0 || GET_CODE (fpop->ops[2]) != REG
1733 || REGNO(fpop->ops[2]) != 17))
1734 fprintf (file, "\t.byte %d, 0x80\n", fpop->size);
1735 else
1736 fprintf (file, "\t.byte %d, 0\n", fpop->size);
1737 size_so_far = 12;
1738 for (i = 0; i < fpop->noperands; i++)
1739 {
1740 register int type;
1741 register int opbyte;
1742 register char *desc0;
1743 char desc1[50];
1744
1745 immed[i] = 0;
1746 switch (GET_MODE (fpop->ops[i]))
1747 {
1748 case SImode:
1749 case VOIDmode:
1750 desc0 = "int";
1751 type = 0;
1752 break;
1753 case SFmode:
1754 desc0 = "float";
1755 type = 2;
1756 break;
1757 case DFmode:
1758 desc0 = "double";
1759 type = 3;
1760 break;
1761 default:
1762 abort ();
1763 }
1764
1765 switch (GET_CODE (fpop->ops[i]))
1766 {
1767 case REG:
1768 strcpy(desc1, reg_names[REGNO (fpop->ops[i])]);
1769 if (FP_REGNO_P (REGNO (fpop->ops[i])))
1770 {
1771 type += 0x10;
1772 opbyte = REGNO (fpop->ops[i]) - 17;
1773 }
1774 else
1775 {
1776 type += 0x00;
1777 opbyte = REGNO (fpop->ops[i]);
1778 if (type == 3)
1779 opbyte = (opbyte << 4) + opbyte + 1;
1780 }
1781 break;
1782
1783 case MEM:
1784 type += 0x30;
1785 if (GET_CODE (XEXP (fpop->ops[i], 0)) == PLUS)
1786 {
1787 immed[i] = XEXP (XEXP (fpop->ops[i], 0), 1);
1788 opbyte = REGNO (XEXP (XEXP (fpop->ops[i], 0), 0));
1789 if (GET_CODE (immed[i]) == CONST_INT)
1790 sprintf (desc1, "%d(%s)", INTVAL (immed[i]),
1791 reg_names[opbyte]);
1792 else
1793 sprintf (desc1, "<memory> (%s)", reg_names[opbyte]);
1794 }
1795 else if (GET_CODE (XEXP (fpop->ops[i], 0)) == REG)
1796 {
1797 opbyte = REGNO (XEXP (fpop->ops[i], 0));
1798 immed[i] = const0_rtx;
1799 sprintf (desc1, "(%s)", reg_names[opbyte]);
1800 }
1801 else
1802 {
1803 immed[i] = XEXP (fpop->ops[i], 0);
1804 opbyte = 0;
1805 sprintf(desc1, "<memory>");
1806 }
1807 break;
1808
1809 case CONST_INT:
1810 case CONST_DOUBLE:
1811 case CONST:
1812 type += 0x20;
1813 opbyte = 0;
1814 immed[i] = fpop->ops[i];
1815 desc1[0] = '$';
1816 desc1[1] = '\0';
1817 break;
1818
1819 default:
1820 abort ();
1821 }
1822
1823 /* Save/restore is special. */
1824 if (i == 0 && (fpop->opcode == USE || fpop->opcode == CLOBBER))
1825 type = 0xff, opbyte = INTVAL (fpop->ops[0]), immed[i] = 0;
1826
1827 fprintf (file, "\t.byte 0x%x,0x%x # (%s) %s\n",
1828 type, opbyte, desc0, desc1);
1829
1830 size_so_far += 2;
1831 }
1832
1833 /* If in the middle of a word, round. */
1834 if (size_so_far % UNITS_PER_WORD)
1835 {
1836 fprintf (file, "\t.space 2\n");
1837 size_so_far += 2;
1838 }
1839
1840 for (i = 0; i < fpop->noperands; i++)
1841 if (immed[i])
1842 switch (GET_MODE (immed[i]))
1843 {
1844 case SImode:
1845 case VOIDmode:
1846 size_so_far += 4;
1847 fprintf (file, "\t.long ");
1848 output_addr_const (file, immed[i]);
1849 fprintf (file, "\n");
1850 break;
1851
1852 case DFmode:
1853 size_so_far += 4;
1854 case SFmode:
1855 size_so_far += 4;
1856 if (GET_CODE (immed[i]) == CONST_DOUBLE)
1857 {
1858 union real_extract u;
1859
1860 bcopy (&CONST_DOUBLE_LOW (immed[i]), &u, sizeof u);
1861 if (GET_MODE (immed[i]) == DFmode)
1862 ASM_OUTPUT_DOUBLE (file, u.d);
1863 else
1864 ASM_OUTPUT_FLOAT (file, u.d);
1865 }
1866 else
1867 abort ();
1868 break;
1869
1870 default:
1871 abort ();
1872 }
1873
1874 if (size_so_far != fpop->size)
1875 {
1876 if (TARGET_FULL_FP_BLOCKS)
1877 fprintf (file, "\t.space %d\n", fpop->size - size_so_far);
1878 else
1879 abort ();
1880 }
1881 }
1882
1883 /* Update for next subroutine. */
1884 subr_number++;
1885 text_section ();
1886 }
1887
1888 /* Initialize floating-point operation table. */
1889
1890 static void
1891 init_fpops()
1892 {
1893 register int i;
1894
1895 first_fpop = last_fpop_in_mem = 0;
1896 for (i = 0; i < FP_HASH_SIZE; i++)
1897 fp_hash_table[i] = 0;
1898 }
This page took 0.126459 seconds and 6 git commands to generate.