(alpha_tp, alpha_fprm, alpha_fptm): New variables.
[gcc.git] / gcc / config / alpha / alpha.c
1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
3 Contributed by Richard Kenner (kenner@vlsi1.ultra.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, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22
23 #include <stdio.h>
24 #include "config.h"
25 #include "rtl.h"
26 #include "regs.h"
27 #include "hard-reg-set.h"
28 #include "real.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "insn-flags.h"
32 #include "output.h"
33 #include "insn-attr.h"
34 #include "flags.h"
35 #include "recog.h"
36 #include "reload.h"
37 #include "expr.h"
38 #include "obstack.h"
39 #include "tree.h"
40
41 /* Specify how accurate floating-point traps need to be. */
42
43 enum alpha_trap_precision alpha_tp;
44
45 /* Specify the floating-point rounding mode. */
46
47 enum alpha_fp_rounding_mode alpha_fprm;
48
49 /* Specify which things cause traps. */
50
51 enum alpha_fp_trap_mode alpha_fptm;
52
53 /* Strings decoded into the above options. */
54 char *alpha_tp_string; /* -mtrap-precision=[p|s|i] */
55 char *alpha_fprm_string; /* -mfp-rounding-mode=[n|m|c|d] */
56 char *alpha_fptm_string; /* -mfp-trap-mode=[n|u|su|sui] */
57
58 /* Save information from a "cmpxx" operation until the branch or scc is
59 emitted. */
60
61 rtx alpha_compare_op0, alpha_compare_op1;
62 int alpha_compare_fp_p;
63
64 /* Save the name of the current function as used by the assembler. This
65 is used by the epilogue. */
66
67 char *alpha_function_name;
68
69 /* Non-zero if inside of a function, because the Alpha asm can't
70 handle .files inside of functions. */
71
72 static int inside_function = FALSE;
73
74 /* Non-zero if an instruction that may cause a trap is pending. */
75
76 static int trap_pending = 0;
77
78 /* Nonzero if the current function needs gp. */
79
80 int alpha_function_needs_gp;
81
82 extern char *version_string;
83 extern int rtx_equal_function_value_matters;
84
85 /* Declarations of static functions. */
86 static void alpha_set_memflags_1 PROTO((rtx, int, int, int));
87 static void add_long_const PROTO((FILE *, HOST_WIDE_INT, int, int, int));
88 \f
89 /* Parse target option strings. */
90
91 void
92 override_options ()
93 {
94 alpha_tp = ALPHA_TP_PROG;
95 alpha_fprm = ALPHA_FPRM_NORM;
96 alpha_fptm = ALPHA_FPTM_N;
97
98 if (TARGET_IEEE)
99 {
100 alpha_tp_string = "i";
101 alpha_fptm_string = "su";
102 target_flags |= MASK_IEEE_CONFORMANT;
103 }
104
105 if (TARGET_IEEE_WITH_INEXACT)
106 {
107 alpha_tp_string = "i";
108 alpha_fptm_string = "sui";
109 target_flags |= MASK_IEEE_CONFORMANT;
110 }
111
112 if (alpha_tp_string)
113 switch (alpha_tp_string[0])
114 {
115 case 'p':
116 alpha_tp = ALPHA_TP_PROG;
117 break;
118
119 case 'f':
120 alpha_tp = ALPHA_TP_FUNC;
121 break;
122
123 case 'i':
124 alpha_tp = ALPHA_TP_INSN;
125 break;
126
127 default:
128 error ("bad value (%s) for -mtrap-precision switch",
129 alpha_tp_string);
130 break;
131 }
132
133 if (alpha_fprm_string)
134 switch (alpha_fprm_string[0])
135 {
136 case 'n':
137 alpha_fprm = ALPHA_FPRM_NORM;
138 break;
139
140 case 'm':
141 alpha_fprm = ALPHA_FPRM_MINF;
142 break;
143
144 case 'c':
145 alpha_fprm = ALPHA_FPRM_CHOP;
146 break;
147
148 case 'd':
149 alpha_fprm = ALPHA_FPRM_DYN;
150 break;
151
152 default:
153 error ("bad value (%s) for -mfp-rounding-mode switch",
154 alpha_fprm_string);
155 break;
156 }
157
158 if (alpha_fptm_string)
159 if (strcmp (alpha_fptm_string, "n") == 0)
160 alpha_fptm = ALPHA_FPTM_N;
161 else if (strcmp (alpha_fptm_string, "u") == 0)
162 alpha_fptm = ALPHA_FPTM_U;
163 else if (strcmp (alpha_fptm_string, "su") == 0)
164 alpha_fptm = ALPHA_FPTM_SU;
165 else if (strcmp (alpha_fptm_string, "sui") == 0)
166 alpha_fptm = ALPHA_FPTM_SUI;
167 else
168 error ("bad value (%s) for -mfp-trap-mode switch",
169 alpha_fptm_string);
170
171 /* Do some sanity checks on the above option. */
172
173 if (alpha_fptm >= ALPHA_FPTM_SU && alpha_tp != ALPHA_TP_INSN)
174 {
175 error ("fp software completion requires -mtrap-precision=i");
176 alpha_tp = ALPHA_TP_INSN;
177 }
178 }
179 \f
180 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
181
182 int
183 zap_mask (value)
184 HOST_WIDE_INT value;
185 {
186 int i;
187
188 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
189 i++, value >>= 8)
190 if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
191 return 0;
192
193 return 1;
194 }
195
196 /* Returns 1 if OP is either the constant zero or a register. If a
197 register, it must be in the proper mode unless MODE is VOIDmode. */
198
199 int
200 reg_or_0_operand (op, mode)
201 register rtx op;
202 enum machine_mode mode;
203 {
204 return op == const0_rtx || register_operand (op, mode);
205 }
206
207 /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
208 any register. */
209
210 int
211 reg_or_6bit_operand (op, mode)
212 register rtx op;
213 enum machine_mode mode;
214 {
215 return ((GET_CODE (op) == CONST_INT
216 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64)
217 || register_operand (op, mode));
218 }
219
220
221 /* Return 1 if OP is an 8-bit constant or any register. */
222
223 int
224 reg_or_8bit_operand (op, mode)
225 register rtx op;
226 enum machine_mode mode;
227 {
228 return ((GET_CODE (op) == CONST_INT
229 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
230 || register_operand (op, mode));
231 }
232
233 /* Return 1 if OP is an 8-bit constant. */
234
235 int
236 cint8_operand (op, mode)
237 register rtx op;
238 enum machine_mode mode;
239 {
240 return (GET_CODE (op) == CONST_INT
241 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100);
242 }
243
244 /* Return 1 if the operand is a valid second operand to an add insn. */
245
246 int
247 add_operand (op, mode)
248 register rtx op;
249 enum machine_mode mode;
250 {
251 if (GET_CODE (op) == CONST_INT)
252 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'K')
253 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L')
254 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'O'));
255
256 return register_operand (op, mode);
257 }
258
259 /* Return 1 if the operand is a valid second operand to a sign-extending
260 add insn. */
261
262 int
263 sext_add_operand (op, mode)
264 register rtx op;
265 enum machine_mode mode;
266 {
267 if (GET_CODE (op) == CONST_INT)
268 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 255
269 || (unsigned HOST_WIDE_INT) (- INTVAL (op)) < 255);
270
271 return register_operand (op, mode);
272 }
273
274 /* Return 1 if OP is the constant 4 or 8. */
275
276 int
277 const48_operand (op, mode)
278 register rtx op;
279 enum machine_mode mode;
280 {
281 return (GET_CODE (op) == CONST_INT
282 && (INTVAL (op) == 4 || INTVAL (op) == 8));
283 }
284
285 /* Return 1 if OP is a valid first operand to an AND insn. */
286
287 int
288 and_operand (op, mode)
289 register rtx op;
290 enum machine_mode mode;
291 {
292 if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
293 return (zap_mask (CONST_DOUBLE_LOW (op))
294 && zap_mask (CONST_DOUBLE_HIGH (op)));
295
296 if (GET_CODE (op) == CONST_INT)
297 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
298 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
299 || zap_mask (INTVAL (op)));
300
301 return register_operand (op, mode);
302 }
303
304 /* Return 1 if OP is a valid first operand to an IOR or XOR insn. */
305
306 int
307 or_operand (op, mode)
308 register rtx op;
309 enum machine_mode mode;
310 {
311 if (GET_CODE (op) == CONST_INT)
312 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
313 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100);
314
315 return register_operand (op, mode);
316 }
317
318 /* Return 1 if OP is a constant that is the width, in bits, of an integral
319 mode smaller than DImode. */
320
321 int
322 mode_width_operand (op, mode)
323 register rtx op;
324 enum machine_mode mode;
325 {
326 return (GET_CODE (op) == CONST_INT
327 && (INTVAL (op) == 8 || INTVAL (op) == 16 || INTVAL (op) == 32));
328 }
329
330 /* Return 1 if OP is a constant that is the width of an integral machine mode
331 smaller than an integer. */
332
333 int
334 mode_mask_operand (op, mode)
335 register rtx op;
336 enum machine_mode mode;
337 {
338 #if HOST_BITS_PER_WIDE_INT == 32
339 if (GET_CODE (op) == CONST_DOUBLE)
340 return CONST_DOUBLE_HIGH (op) == 0 && CONST_DOUBLE_LOW (op) == -1;
341 #endif
342
343 return (GET_CODE (op) == CONST_INT
344 && (INTVAL (op) == 0xff
345 || INTVAL (op) == 0xffff
346 #if HOST_BITS_PER_WIDE_INT == 64
347 || INTVAL (op) == 0xffffffff
348 #endif
349 ));
350 }
351
352 /* Return 1 if OP is a multiple of 8 less than 64. */
353
354 int
355 mul8_operand (op, mode)
356 register rtx op;
357 enum machine_mode mode;
358 {
359 return (GET_CODE (op) == CONST_INT
360 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64
361 && (INTVAL (op) & 7) == 0);
362 }
363
364 /* Return 1 if OP is the constant zero in floating-point. */
365
366 int
367 fp0_operand (op, mode)
368 register rtx op;
369 enum machine_mode mode;
370 {
371 return (GET_MODE (op) == mode
372 && GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode));
373 }
374
375 /* Return 1 if OP is the floating-point constant zero or a register. */
376
377 int
378 reg_or_fp0_operand (op, mode)
379 register rtx op;
380 enum machine_mode mode;
381 {
382 return fp0_operand (op, mode) || register_operand (op, mode);
383 }
384
385 /* Return 1 if OP is a register or a constant integer. */
386
387
388 int
389 reg_or_cint_operand (op, mode)
390 register rtx op;
391 enum machine_mode mode;
392 {
393 return GET_CODE (op) == CONST_INT || register_operand (op, mode);
394 }
395
396 /* Return 1 if OP is something that can be reloaded into a register;
397 if it is a MEM, it need not be valid. */
398
399 int
400 some_operand (op, mode)
401 register rtx op;
402 enum machine_mode mode;
403 {
404 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
405 return 0;
406
407 switch (GET_CODE (op))
408 {
409 case REG: case MEM: case CONST_DOUBLE:
410 case CONST_INT: case LABEL_REF: case SYMBOL_REF: case CONST:
411 return 1;
412
413 case SUBREG:
414 return some_operand (SUBREG_REG (op), VOIDmode);
415 }
416
417 return 0;
418 }
419
420 /* Return 1 if OP is a valid operand for the source of a move insn. */
421
422 int
423 input_operand (op, mode)
424 register rtx op;
425 enum machine_mode mode;
426 {
427 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
428 return 0;
429
430 if (GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE (op) != mode)
431 return 0;
432
433 switch (GET_CODE (op))
434 {
435 case LABEL_REF:
436 case SYMBOL_REF:
437 case CONST:
438 /* This handles both the Windows/NT and OSF cases. */
439 return mode == ptr_mode || mode == DImode;
440
441 case REG:
442 return 1;
443
444 case SUBREG:
445 if (register_operand (op, mode))
446 return 1;
447 /* ... fall through ... */
448 case MEM:
449 return mode != HImode && mode != QImode && general_operand (op, mode);
450
451 case CONST_DOUBLE:
452 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
453
454 case CONST_INT:
455 return mode == QImode || mode == HImode || add_operand (op, mode);
456 }
457
458 return 0;
459 }
460
461 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
462 file. */
463
464 int
465 current_file_function_operand (op, mode)
466 rtx op;
467 enum machine_mode mode;
468 {
469 return (GET_CODE (op) == SYMBOL_REF
470 && ! profile_flag && ! profile_block_flag
471 && (SYMBOL_REF_FLAG (op)
472 || op == XEXP (DECL_RTL (current_function_decl), 0)));
473 }
474
475 /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
476
477 int
478 call_operand (op, mode)
479 rtx op;
480 enum machine_mode mode;
481 {
482 if (mode != Pmode)
483 return 0;
484
485 return (GET_CODE (op) == SYMBOL_REF
486 || (GET_CODE (op) == REG && REGNO (op) == 27));
487 }
488
489 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
490 comparisons are valid in which insn. */
491
492 int
493 alpha_comparison_operator (op, mode)
494 register rtx op;
495 enum machine_mode mode;
496 {
497 enum rtx_code code = GET_CODE (op);
498
499 if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
500 return 0;
501
502 return (code == EQ || code == LE || code == LT
503 || (mode == DImode && (code == LEU || code == LTU)));
504 }
505
506 /* Return 1 if OP is a signed comparison operation. */
507
508 int
509 signed_comparison_operator (op, mode)
510 register rtx op;
511 enum machine_mode mode;
512 {
513 switch (GET_CODE (op))
514 {
515 case EQ: case NE: case LE: case LT: case GE: case GT:
516 return 1;
517 }
518
519 return 0;
520 }
521
522 /* Return 1 if this is a divide or modulus operator. */
523
524 int
525 divmod_operator (op, mode)
526 register rtx op;
527 enum machine_mode mode;
528 {
529 switch (GET_CODE (op))
530 {
531 case DIV: case MOD: case UDIV: case UMOD:
532 return 1;
533 }
534
535 return 0;
536 }
537
538 /* Return 1 if this memory address is a known aligned register plus
539 a constant. It must be a valid address. This means that we can do
540 this as an aligned reference plus some offset.
541
542 Take into account what reload will do.
543
544 We could say that out-of-range stack slots are alignable, but that would
545 complicate get_aligned_mem and it isn't worth the trouble since few
546 functions have large stack space. */
547
548 int
549 aligned_memory_operand (op, mode)
550 register rtx op;
551 enum machine_mode mode;
552 {
553 if (GET_CODE (op) == SUBREG)
554 {
555 if (GET_MODE (op) != mode)
556 return 0;
557 op = SUBREG_REG (op);
558 mode = GET_MODE (op);
559 }
560
561 if (reload_in_progress && GET_CODE (op) == REG
562 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
563 op = reg_equiv_mem[REGNO (op)];
564
565 if (GET_CODE (op) != MEM || GET_MODE (op) != mode
566 || ! memory_address_p (mode, XEXP (op, 0)))
567 return 0;
568
569 op = XEXP (op, 0);
570
571 if (GET_CODE (op) == PLUS)
572 op = XEXP (op, 0);
573
574 return (GET_CODE (op) == REG
575 && REGNO_POINTER_ALIGN (REGNO (op)) >= 4);
576 }
577
578 /* Similar, but return 1 if OP is a MEM which is not alignable. */
579
580 int
581 unaligned_memory_operand (op, mode)
582 register rtx op;
583 enum machine_mode mode;
584 {
585 if (GET_CODE (op) == SUBREG)
586 {
587 if (GET_MODE (op) != mode)
588 return 0;
589 op = SUBREG_REG (op);
590 mode = GET_MODE (op);
591 }
592
593 if (reload_in_progress && GET_CODE (op) == REG
594 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
595 op = reg_equiv_mem[REGNO (op)];
596
597 if (GET_CODE (op) != MEM || GET_MODE (op) != mode)
598 return 0;
599
600 op = XEXP (op, 0);
601
602 if (! memory_address_p (mode, op))
603 return 1;
604
605 if (GET_CODE (op) == PLUS)
606 op = XEXP (op, 0);
607
608 return (GET_CODE (op) != REG
609 || REGNO_POINTER_ALIGN (REGNO (op)) < 4);
610 }
611
612 /* Return 1 if OP is either a register or an unaligned memory location. */
613
614 int
615 reg_or_unaligned_mem_operand (op, mode)
616 rtx op;
617 enum machine_mode mode;
618 {
619 return register_operand (op, mode) || unaligned_memory_operand (op, mode);
620 }
621
622 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
623
624 int
625 any_memory_operand (op, mode)
626 register rtx op;
627 enum machine_mode mode;
628 {
629 return (GET_CODE (op) == MEM
630 || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
631 || (reload_in_progress && GET_CODE (op) == REG
632 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
633 || (reload_in_progress && GET_CODE (op) == SUBREG
634 && GET_CODE (SUBREG_REG (op)) == REG
635 && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));
636 }
637
638 /* REF is an alignable memory location. Place an aligned SImode
639 reference into *PALIGNED_MEM and the number of bits to shift into
640 *PBITNUM. */
641
642 void
643 get_aligned_mem (ref, paligned_mem, pbitnum)
644 rtx ref;
645 rtx *paligned_mem, *pbitnum;
646 {
647 rtx base;
648 HOST_WIDE_INT offset = 0;
649
650 if (GET_CODE (ref) == SUBREG)
651 {
652 offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
653 if (BYTES_BIG_ENDIAN)
654 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
655 - MIN (UNITS_PER_WORD,
656 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
657 ref = SUBREG_REG (ref);
658 }
659
660 if (GET_CODE (ref) == REG)
661 ref = reg_equiv_mem[REGNO (ref)];
662
663 if (reload_in_progress)
664 base = find_replacement (&XEXP (ref, 0));
665 else
666 base = XEXP (ref, 0);
667
668 if (GET_CODE (base) == PLUS)
669 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
670
671 *paligned_mem = gen_rtx (MEM, SImode,
672 plus_constant (base, offset & ~3));
673 MEM_IN_STRUCT_P (*paligned_mem) = MEM_IN_STRUCT_P (ref);
674 MEM_VOLATILE_P (*paligned_mem) = MEM_VOLATILE_P (ref);
675 RTX_UNCHANGING_P (*paligned_mem) = RTX_UNCHANGING_P (ref);
676
677 *pbitnum = GEN_INT ((offset & 3) * 8);
678 }
679
680 /* Similar, but just get the address. Handle the two reload cases.
681 Add EXTRA_OFFSET to the address we return. */
682
683 rtx
684 get_unaligned_address (ref, extra_offset)
685 rtx ref;
686 int extra_offset;
687 {
688 rtx base;
689 HOST_WIDE_INT offset = 0;
690
691 if (GET_CODE (ref) == SUBREG)
692 {
693 offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
694 if (BYTES_BIG_ENDIAN)
695 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
696 - MIN (UNITS_PER_WORD,
697 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
698 ref = SUBREG_REG (ref);
699 }
700
701 if (GET_CODE (ref) == REG)
702 ref = reg_equiv_mem[REGNO (ref)];
703
704 if (reload_in_progress)
705 base = find_replacement (&XEXP (ref, 0));
706 else
707 base = XEXP (ref, 0);
708
709 if (GET_CODE (base) == PLUS)
710 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
711
712 return plus_constant (base, offset + extra_offset);
713 }
714 \f
715 /* Subfunction of the following function. Update the flags of any MEM
716 found in part of X. */
717
718 static void
719 alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
720 rtx x;
721 int in_struct_p, volatile_p, unchanging_p;
722 {
723 int i;
724
725 switch (GET_CODE (x))
726 {
727 case SEQUENCE:
728 case PARALLEL:
729 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
730 alpha_set_memflags_1 (XVECEXP (x, 0, i), in_struct_p, volatile_p,
731 unchanging_p);
732 break;
733
734 case INSN:
735 alpha_set_memflags_1 (PATTERN (x), in_struct_p, volatile_p,
736 unchanging_p);
737 break;
738
739 case SET:
740 alpha_set_memflags_1 (SET_DEST (x), in_struct_p, volatile_p,
741 unchanging_p);
742 alpha_set_memflags_1 (SET_SRC (x), in_struct_p, volatile_p,
743 unchanging_p);
744 break;
745
746 case MEM:
747 MEM_IN_STRUCT_P (x) = in_struct_p;
748 MEM_VOLATILE_P (x) = volatile_p;
749 RTX_UNCHANGING_P (x) = unchanging_p;
750 break;
751 }
752 }
753
754 /* Given INSN, which is either an INSN or a SEQUENCE generated to
755 perform a memory operation, look for any MEMs in either a SET_DEST or
756 a SET_SRC and copy the in-struct, unchanging, and volatile flags from
757 REF into each of the MEMs found. If REF is not a MEM, don't do
758 anything. */
759
760 void
761 alpha_set_memflags (insn, ref)
762 rtx insn;
763 rtx ref;
764 {
765 /* Note that it is always safe to get these flags, though they won't
766 be what we think if REF is not a MEM. */
767 int in_struct_p = MEM_IN_STRUCT_P (ref);
768 int volatile_p = MEM_VOLATILE_P (ref);
769 int unchanging_p = RTX_UNCHANGING_P (ref);
770
771 if (GET_CODE (ref) != MEM
772 || (! in_struct_p && ! volatile_p && ! unchanging_p))
773 return;
774
775 alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
776 }
777 \f
778 /* Try to output insns to set TARGET equal to the constant C if it can be
779 done in less than N insns. Do all computations in MODE. Returns the place
780 where the output has been placed if it can be done and the insns have been
781 emitted. If it would take more than N insns, zero is returned and no
782 insns and emitted. */
783
784 rtx
785 alpha_emit_set_const (target, mode, c, n)
786 rtx target;
787 enum machine_mode mode;
788 HOST_WIDE_INT c;
789 int n;
790 {
791 HOST_WIDE_INT new = c;
792 int i, bits;
793 /* Use a pseudo if highly optimizing and still generating RTL. */
794 rtx subtarget
795 = (flag_expensive_optimizations && rtx_equal_function_value_matters
796 ? 0 : target);
797 rtx temp;
798
799 #if HOST_BITS_PER_WIDE_INT == 64
800 /* We are only called for SImode and DImode. If this is SImode, ensure that
801 we are sign extended to a full word. This does not make any sense when
802 cross-compiling on a narrow machine. */
803
804 if (mode == SImode)
805 c = (c & 0xffffffff) - 2 * (c & 0x80000000);
806 #endif
807
808 /* If this is a sign-extended 32-bit constant, we can do this in at most
809 three insns, so do it if we have enough insns left. We always have
810 a sign-extended 32-bit constant when compiling on a narrow machine.
811 Note that we cannot handle the constant 0x80000000. */
812
813 if ((HOST_BITS_PER_WIDE_INT != 64
814 || c >> 31 == -1 || c >> 31 == 0)
815 && c != 0x80000000U)
816 {
817 HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
818 HOST_WIDE_INT tmp1 = c - low;
819 HOST_WIDE_INT high
820 = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
821 HOST_WIDE_INT extra = 0;
822
823 /* If HIGH will be interpreted as negative but the constant is
824 positive, we must adjust it to do two ldha insns. */
825
826 if ((high & 0x8000) != 0 && c >= 0)
827 {
828 extra = 0x4000;
829 tmp1 -= 0x40000000;
830 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
831 }
832
833 if (c == low || (low == 0 && extra == 0))
834 return copy_to_suggested_reg (GEN_INT (c), target, mode);
835 else if (n >= 2 + (extra != 0)
836 /* We can't do this when SImode if HIGH required adjustment.
837 This is because the code relies on an implicit overflow
838 which is invisible to the RTL. We can thus get incorrect
839 code if the two ldah instructions are combined. */
840 && ! (mode == SImode && extra != 0))
841 {
842 temp = copy_to_suggested_reg (GEN_INT (low), subtarget, mode);
843
844 if (extra != 0)
845 temp = expand_binop (mode, add_optab, temp, GEN_INT (extra << 16),
846 subtarget, 0, OPTAB_WIDEN);
847
848 return expand_binop (mode, add_optab, temp, GEN_INT (high << 16),
849 target, 0, OPTAB_WIDEN);
850 }
851 }
852
853 /* If we couldn't do it that way, try some other methods. But if we have
854 no instructions left, don't bother. Likewise, if this is SImode and
855 we can't make pseudos, we can't do anything since the expand_binop
856 and expand_unop calls will widen and try to make pseudos. */
857
858 if (n == 1
859 || (mode == SImode && ! rtx_equal_function_value_matters))
860 return 0;
861
862 #if HOST_BITS_PER_WIDE_INT == 64
863 /* First, see if can load a value into the target that is the same as the
864 constant except that all bytes that are 0 are changed to be 0xff. If we
865 can, then we can do a ZAPNOT to obtain the desired constant. */
866
867 for (i = 0; i < 64; i += 8)
868 if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
869 new |= (HOST_WIDE_INT) 0xff << i;
870
871 /* We are only called for SImode and DImode. If this is SImode, ensure that
872 we are sign extended to a full word. */
873
874 if (mode == SImode)
875 new = (new & 0xffffffff) - 2 * (new & 0x80000000);
876
877 if (new != c
878 && (temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0)
879 return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
880 target, 0, OPTAB_WIDEN);
881 #endif
882
883 /* Next, see if we can load a related constant and then shift and possibly
884 negate it to get the constant we want. Try this once each increasing
885 numbers of insns. */
886
887 for (i = 1; i < n; i++)
888 {
889 /* First try complementing. */
890 if ((temp = alpha_emit_set_const (subtarget, mode, ~ c, i)) != 0)
891 return expand_unop (mode, one_cmpl_optab, temp, target, 0);
892
893 /* Next try to form a constant and do a left shift. We can do this
894 if some low-order bits are zero; the exact_log2 call below tells
895 us that information. The bits we are shifting out could be any
896 value, but here we'll just try the 0- and sign-extended forms of
897 the constant. To try to increase the chance of having the same
898 constant in more than one insn, start at the highest number of
899 bits to shift, but try all possibilities in case a ZAPNOT will
900 be useful. */
901
902 if ((bits = exact_log2 (c & - c)) > 0)
903 for (; bits > 0; bits--)
904 if ((temp = (alpha_emit_set_const
905 (subtarget, mode,
906 (unsigned HOST_WIDE_INT) c >> bits, i))) != 0
907 || ((temp = (alpha_emit_set_const
908 (subtarget, mode,
909 ((unsigned HOST_WIDE_INT) c) >> bits, i)))
910 != 0))
911 return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
912 target, 0, OPTAB_WIDEN);
913
914 /* Now try high-order zero bits. Here we try the shifted-in bits as
915 all zero and all ones. Be careful to avoid shifting outside the
916 mode and to avoid shifting outside the host wide int size. */
917
918 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
919 - floor_log2 (c) - 1)) > 0)
920 for (; bits > 0; bits--)
921 if ((temp = alpha_emit_set_const (subtarget, mode,
922 c << bits, i)) != 0
923 || ((temp = (alpha_emit_set_const
924 (subtarget, mode,
925 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
926 i)))
927 != 0))
928 return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
929 target, 1, OPTAB_WIDEN);
930
931 /* Now try high-order 1 bits. We get that with a sign-extension.
932 But one bit isn't enough here. Be careful to avoid shifting outside
933 the mode and to avoid shifting outside the host wide int size. */
934
935 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
936 - floor_log2 (~ c) - 2)) > 0)
937 for (; bits > 0; bits--)
938 if ((temp = alpha_emit_set_const (subtarget, mode,
939 c << bits, i)) != 0
940 || ((temp = (alpha_emit_set_const
941 (subtarget, mode,
942 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
943 i)))
944 != 0))
945 return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
946 target, 0, OPTAB_WIDEN);
947 }
948
949 return 0;
950 }
951 \f
952 /* Adjust the cost of a scheduling dependency. Return the new cost of
953 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
954
955 int
956 alpha_adjust_cost (insn, link, dep_insn, cost)
957 rtx insn;
958 rtx link;
959 rtx dep_insn;
960 int cost;
961 {
962 rtx set;
963
964 /* If the dependence is an anti-dependence, there is no cost. For an
965 output dependence, there is sometimes a cost, but it doesn't seem
966 worth handling those few cases. */
967
968 if (REG_NOTE_KIND (link) != 0)
969 return 0;
970
971 /* If INSN is a store insn and DEP_INSN is setting the data being stored,
972 we can sometimes lower the cost. */
973
974 if (recog_memoized (insn) >= 0 && get_attr_type (insn) == TYPE_ST
975 && (set = single_set (dep_insn)) != 0
976 && GET_CODE (PATTERN (insn)) == SET
977 && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
978 switch (get_attr_type (dep_insn))
979 {
980 case TYPE_LD:
981 /* No savings here. */
982 return cost;
983
984 case TYPE_IMULL:
985 case TYPE_IMULQ:
986 /* In these cases, we save one cycle. */
987 return cost - 2;
988
989 default:
990 /* In all other cases, we save two cycles. */
991 return MAX (0, cost - 4);
992 }
993
994 /* Another case that needs adjustment is an arithmetic or logical
995 operation. It's cost is usually one cycle, but we default it to
996 two in the MD file. The only case that it is actually two is
997 for the address in loads and stores. */
998
999 if (recog_memoized (dep_insn) >= 0
1000 && get_attr_type (dep_insn) == TYPE_IADDLOG)
1001 switch (get_attr_type (insn))
1002 {
1003 case TYPE_LD:
1004 case TYPE_ST:
1005 return cost;
1006
1007 default:
1008 return 2;
1009 }
1010
1011 /* The final case is when a compare feeds into an integer branch. The cost
1012 is only one cycle in that case. */
1013
1014 if (recog_memoized (dep_insn) >= 0
1015 && get_attr_type (dep_insn) == TYPE_ICMP
1016 && recog_memoized (insn) >= 0
1017 && get_attr_type (insn) == TYPE_IBR)
1018 return 2;
1019
1020 /* Otherwise, return the default cost. */
1021
1022 return cost;
1023 }
1024 \f
1025 /* Print an operand. Recognize special options, documented below. */
1026
1027 void
1028 print_operand (file, x, code)
1029 FILE *file;
1030 rtx x;
1031 char code;
1032 {
1033 int i;
1034
1035 switch (code)
1036 {
1037 case '&':
1038 /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
1039 chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
1040 mode. alpha_fprm controls which suffix is generated. */
1041 switch (alpha_fprm)
1042 {
1043 case ALPHA_FPRM_NORM:
1044 break;
1045 case ALPHA_FPRM_MINF:
1046 fputc ('m', file);
1047 break;
1048 case ALPHA_FPRM_CHOP:
1049 fputc ('c', file);
1050 break;
1051 case ALPHA_FPRM_DYN:
1052 fputc ('d', file);
1053 break;
1054 }
1055 break;
1056
1057 case '\'':
1058 /* Generates trap-mode suffix for instructions that accept the su
1059 suffix only (cmpt et al). */
1060 if (alpha_tp == ALPHA_TP_INSN)
1061 fputs ("su", file);
1062 break;
1063
1064 case ')':
1065 /* Generates trap-mode suffix for instructions that accept the u, su,
1066 and sui suffix. This is the bulk of the IEEE floating point
1067 instructions (addt et al). */
1068 switch (alpha_fptm)
1069 {
1070 case ALPHA_FPTM_N:
1071 break;
1072 case ALPHA_FPTM_U:
1073 fputc ('u', file);
1074 break;
1075 case ALPHA_FPTM_SU:
1076 fputs ("su", file);
1077 break;
1078 case ALPHA_FPTM_SUI:
1079 fputs ("sui", file);
1080 break;
1081 }
1082 break;
1083
1084 case '+':
1085 /* Generates trap-mode suffix for instructions that accept the sui
1086 suffix (cvtqt and cvtqs). */
1087 switch (alpha_fptm)
1088 {
1089 case ALPHA_FPTM_N: case ALPHA_FPTM_U:
1090 case ALPHA_FPTM_SU: /* cvtqt/cvtqs can't cause underflow */
1091 break;
1092 case ALPHA_FPTM_SUI:
1093 fputs ("sui", file);
1094 break;
1095 }
1096 break;
1097
1098 case 'r':
1099 /* If this operand is the constant zero, write it as "$31". */
1100 if (GET_CODE (x) == REG)
1101 fprintf (file, "%s", reg_names[REGNO (x)]);
1102 else if (x == CONST0_RTX (GET_MODE (x)))
1103 fprintf (file, "$31");
1104 else
1105 output_operand_lossage ("invalid %%r value");
1106
1107 break;
1108
1109 case 'R':
1110 /* Similar, but for floating-point. */
1111 if (GET_CODE (x) == REG)
1112 fprintf (file, "%s", reg_names[REGNO (x)]);
1113 else if (x == CONST0_RTX (GET_MODE (x)))
1114 fprintf (file, "$f31");
1115 else
1116 output_operand_lossage ("invalid %%R value");
1117
1118 break;
1119
1120 case 'N':
1121 /* Write the 1's complement of a constant. */
1122 if (GET_CODE (x) != CONST_INT)
1123 output_operand_lossage ("invalid %%N value");
1124
1125 fprintf (file, "%ld", ~ INTVAL (x));
1126 break;
1127
1128 case 'P':
1129 /* Write 1 << C, for a constant C. */
1130 if (GET_CODE (x) != CONST_INT)
1131 output_operand_lossage ("invalid %%P value");
1132
1133 fprintf (file, "%ld", (HOST_WIDE_INT) 1 << INTVAL (x));
1134 break;
1135
1136 case 'h':
1137 /* Write the high-order 16 bits of a constant, sign-extended. */
1138 if (GET_CODE (x) != CONST_INT)
1139 output_operand_lossage ("invalid %%h value");
1140
1141 fprintf (file, "%ld", INTVAL (x) >> 16);
1142 break;
1143
1144 case 'L':
1145 /* Write the low-order 16 bits of a constant, sign-extended. */
1146 if (GET_CODE (x) != CONST_INT)
1147 output_operand_lossage ("invalid %%L value");
1148
1149 fprintf (file, "%ld", (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
1150 break;
1151
1152 case 'm':
1153 /* Write mask for ZAP insn. */
1154 if (GET_CODE (x) == CONST_DOUBLE)
1155 {
1156 HOST_WIDE_INT mask = 0;
1157 HOST_WIDE_INT value;
1158
1159 value = CONST_DOUBLE_LOW (x);
1160 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
1161 i++, value >>= 8)
1162 if (value & 0xff)
1163 mask |= (1 << i);
1164
1165 value = CONST_DOUBLE_HIGH (x);
1166 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
1167 i++, value >>= 8)
1168 if (value & 0xff)
1169 mask |= (1 << (i + sizeof (int)));
1170
1171 fprintf (file, "%ld", mask & 0xff);
1172 }
1173
1174 else if (GET_CODE (x) == CONST_INT)
1175 {
1176 HOST_WIDE_INT mask = 0, value = INTVAL (x);
1177
1178 for (i = 0; i < 8; i++, value >>= 8)
1179 if (value & 0xff)
1180 mask |= (1 << i);
1181
1182 fprintf (file, "%ld", mask);
1183 }
1184 else
1185 output_operand_lossage ("invalid %%m value");
1186 break;
1187
1188 case 'M':
1189 /* 'b', 'w', or 'l' as the value of the constant. */
1190 if (GET_CODE (x) != CONST_INT
1191 || (INTVAL (x) != 8 && INTVAL (x) != 16 && INTVAL (x) != 32))
1192 output_operand_lossage ("invalid %%M value");
1193
1194 fprintf (file, "%s",
1195 INTVAL (x) == 8 ? "b" : INTVAL (x) == 16 ? "w" : "l");
1196 break;
1197
1198 case 'U':
1199 /* Similar, except do it from the mask. */
1200 if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
1201 fprintf (file, "b");
1202 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
1203 fprintf (file, "w");
1204 #if HOST_BITS_PER_WIDE_INT == 32
1205 else if (GET_CODE (x) == CONST_DOUBLE
1206 && CONST_DOUBLE_HIGH (x) == 0
1207 && CONST_DOUBLE_LOW (x) == -1)
1208 fprintf (file, "l");
1209 #else
1210 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
1211 fprintf (file, "l");
1212 #endif
1213 else
1214 output_operand_lossage ("invalid %%U value");
1215 break;
1216
1217 case 's':
1218 /* Write the constant value divided by 8. */
1219 if (GET_CODE (x) != CONST_INT
1220 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
1221 && (INTVAL (x) & 7) != 8)
1222 output_operand_lossage ("invalid %%s value");
1223
1224 fprintf (file, "%ld", INTVAL (x) / 8);
1225 break;
1226
1227 case 'S':
1228 /* Same, except compute (64 - c) / 8 */
1229
1230 if (GET_CODE (x) != CONST_INT
1231 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
1232 && (INTVAL (x) & 7) != 8)
1233 output_operand_lossage ("invalid %%s value");
1234
1235 fprintf (file, "%ld", (64 - INTVAL (x)) / 8);
1236 break;
1237
1238 case 'C':
1239 /* Write out comparison name. */
1240 if (GET_RTX_CLASS (GET_CODE (x)) != '<')
1241 output_operand_lossage ("invalid %%C value");
1242
1243 if (GET_CODE (x) == LEU)
1244 fprintf (file, "ule");
1245 else if (GET_CODE (x) == LTU)
1246 fprintf (file, "ult");
1247 else
1248 fprintf (file, "%s", GET_RTX_NAME (GET_CODE (x)));
1249 break;
1250
1251 case 'D':
1252 /* Similar, but write reversed code. We can't get an unsigned code
1253 here. */
1254 if (GET_RTX_CLASS (GET_CODE (x)) != '<')
1255 output_operand_lossage ("invalid %%D value");
1256
1257 fprintf (file, "%s", GET_RTX_NAME (reverse_condition (GET_CODE (x))));
1258 break;
1259
1260 case 'c':
1261 /* Similar to `c', but swap. We can't get unsigned here either. */
1262 if (GET_RTX_CLASS (GET_CODE (x)) != '<')
1263 output_operand_lossage ("invalid %%D value");
1264
1265 fprintf (file, "%s", GET_RTX_NAME (swap_condition (GET_CODE (x))));
1266 break;
1267
1268 case 'd':
1269 /* Similar, but reverse and swap. We can't get unsigned here either. */
1270 if (GET_RTX_CLASS (GET_CODE (x)) != '<')
1271 output_operand_lossage ("invalid %%D value");
1272
1273 fprintf (file, "%s",
1274 GET_RTX_NAME (swap_condition (reverse_condition ((GET_CODE (x))))));
1275 break;
1276
1277 case 'E':
1278 /* Write the divide or modulus operator. */
1279 switch (GET_CODE (x))
1280 {
1281 case DIV:
1282 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
1283 break;
1284 case UDIV:
1285 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
1286 break;
1287 case MOD:
1288 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
1289 break;
1290 case UMOD:
1291 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
1292 break;
1293 default:
1294 output_operand_lossage ("invalid %%E value");
1295 break;
1296 }
1297 break;
1298
1299 case 'A':
1300 /* Write "_u" for unaligned access. */
1301 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
1302 fprintf (file, "_u");
1303 break;
1304
1305 case 0:
1306 if (GET_CODE (x) == REG)
1307 fprintf (file, "%s", reg_names[REGNO (x)]);
1308 else if (GET_CODE (x) == MEM)
1309 output_address (XEXP (x, 0));
1310 else
1311 output_addr_const (file, x);
1312 break;
1313
1314 default:
1315 output_operand_lossage ("invalid %%xn code");
1316 }
1317 }
1318 \f
1319 /* Do what is necessary for `va_start'. The argument is ignored;
1320 We look at the current function to determine if stdarg or varargs
1321 is used and fill in an initial va_list. A pointer to this constructor
1322 is returned. */
1323
1324 struct rtx_def *
1325 alpha_builtin_saveregs (arglist)
1326 tree arglist;
1327 {
1328 rtx block, addr, argsize;
1329 tree fntype = TREE_TYPE (current_function_decl);
1330 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1331 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1332 != void_type_node));
1333
1334 /* Compute the current position into the args, taking into account
1335 both registers and memory. Both of these are already included in
1336 current_function_args_info. */
1337
1338 argsize = GEN_INT (current_function_args_info * UNITS_PER_WORD);
1339
1340 /* SETUP_INCOMING_VARARGS moves the starting address base up by 48,
1341 storing fp arg registers in the first 48 bytes, and the integer arg
1342 registers in the next 48 bytes. This is only done, however, if any
1343 integer registers need to be stored.
1344
1345 If no integer registers need be stored, then we must subtract 48 in
1346 order to account for the integer arg registers which are counted in
1347 argsize above, but which are not actually stored on the stack. */
1348
1349 addr = (current_function_args_info <= 5 + stdarg
1350 ? plus_constant (virtual_incoming_args_rtx, 6 * UNITS_PER_WORD)
1351 : plus_constant (virtual_incoming_args_rtx, - (6 * UNITS_PER_WORD)));
1352
1353 addr = force_operand (addr, NULL_RTX);
1354
1355 /* Allocate the va_list constructor */
1356 block = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
1357 RTX_UNCHANGING_P (block) = 1;
1358 RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
1359
1360 /* Store the address of the first integer register in the __base member. */
1361
1362 #ifdef POINTERS_EXTEND_UNSIGNED
1363 addr = convert_memory_address (ptr_mode, addr);
1364 #endif
1365
1366 emit_move_insn (change_address (block, ptr_mode, XEXP (block, 0)), addr);
1367
1368 /* Store the argsize as the __va_offset member. */
1369 emit_move_insn (change_address (block, TYPE_MODE (integer_type_node),
1370 plus_constant (XEXP (block, 0),
1371 POINTER_SIZE/BITS_PER_UNIT)),
1372 argsize);
1373
1374 /* Return the address of the va_list constructor, but don't put it in a
1375 register. Doing so would fail when not optimizing and produce worse
1376 code when optimizing. */
1377 return XEXP (block, 0);
1378 }
1379 \f
1380 /* This page contains routines that are used to determine what the function
1381 prologue and epilogue code will do and write them out. */
1382
1383 /* Compute the size of the save area in the stack. */
1384
1385 int
1386 alpha_sa_size ()
1387 {
1388 int size = 0;
1389 int i;
1390
1391 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1392 if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i])
1393 size++;
1394
1395 /* If some registers were saved but not reg 26, reg 26 must also
1396 be saved, so leave space for it. */
1397 if (size != 0 && ! regs_ever_live[26])
1398 size++;
1399
1400 /* Our size must be even (multiple of 16 bytes). */
1401 if (size & 1)
1402 size ++;
1403
1404 return size * 8;
1405 }
1406
1407 /* Return 1 if this function can directly return via $26. */
1408
1409 int
1410 direct_return ()
1411 {
1412 return (reload_completed && alpha_sa_size () == 0
1413 && get_frame_size () == 0
1414 && current_function_outgoing_args_size == 0
1415 && current_function_pretend_args_size == 0);
1416 }
1417
1418 /* Write a version stamp. Don't write anything if we are running as a
1419 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
1420
1421 #if !defined(CROSS_COMPILE) && !defined(_WIN32)
1422 #include <stamp.h>
1423 #endif
1424
1425 void
1426 alpha_write_verstamp (file)
1427 FILE *file;
1428 {
1429 #ifdef MS_STAMP
1430 fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
1431 #endif
1432 }
1433 \f
1434 /* Write code to add constant C to register number IN_REG (possibly 31)
1435 and put the result into OUT_REG. Use TEMP_REG as a scratch register;
1436 usually this will be OUT_REG, but should not be if OUT_REG is
1437 STACK_POINTER_REGNUM, since it must be updated in a single instruction.
1438 Write the code to FILE. */
1439
1440 static void
1441 add_long_const (file, c, in_reg, out_reg, temp_reg)
1442 FILE *file;
1443 HOST_WIDE_INT c;
1444 int in_reg, out_reg, temp_reg;
1445 {
1446 HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
1447 HOST_WIDE_INT tmp1 = c - low;
1448 HOST_WIDE_INT high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1449 HOST_WIDE_INT extra = 0;
1450
1451 /* We don't have code to write out constants larger than 32 bits. */
1452 #if HOST_BITS_PER_LONG_INT == 64
1453 if ((unsigned HOST_WIDE_INT) c >> 32 != 0)
1454 abort ();
1455 #endif
1456
1457 /* If HIGH will be interpreted as negative, we must adjust it to do two
1458 ldha insns. Note that we will never be building a negative constant
1459 here. */
1460
1461 if (high & 0x8000)
1462 {
1463 extra = 0x4000;
1464 tmp1 -= 0x40000000;
1465 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1466 }
1467
1468 if (low != 0)
1469 {
1470 int result_reg = (extra == 0 && high == 0) ? out_reg : temp_reg;
1471
1472 if (low >= 0 && low < 255)
1473 fprintf (file, "\taddq $%d,%d,$%d\n", in_reg, low, result_reg);
1474 else
1475 fprintf (file, "\tlda $%d,%d($%d)\n", result_reg, low, in_reg);
1476
1477 in_reg = result_reg;
1478 }
1479
1480 if (extra)
1481 {
1482 int result_reg = (high == 0) ? out_reg : temp_reg;
1483
1484 fprintf (file, "\tldah $%d,%d($%d)\n", result_reg, extra, in_reg);
1485 in_reg = result_reg;
1486 }
1487
1488 if (high)
1489 fprintf (file, "\tldah $%d,%d($%d)\n", out_reg, high, in_reg);
1490 }
1491
1492 /* Write function prologue. */
1493
1494 void
1495 output_prolog (file, size)
1496 FILE *file;
1497 int size;
1498 {
1499 HOST_WIDE_INT out_args_size
1500 = ALPHA_ROUND (current_function_outgoing_args_size);
1501 HOST_WIDE_INT sa_size = alpha_sa_size ();
1502 HOST_WIDE_INT frame_size
1503 = (out_args_size + sa_size
1504 + ALPHA_ROUND (size + current_function_pretend_args_size));
1505 HOST_WIDE_INT reg_offset = out_args_size;
1506 HOST_WIDE_INT start_reg_offset = reg_offset;
1507 HOST_WIDE_INT actual_start_reg_offset = start_reg_offset;
1508 int int_reg_save_area_size = 0;
1509 rtx insn;
1510 unsigned reg_mask = 0;
1511 int i;
1512
1513 /* Ecoff can handle multiple .file directives, so put out file and lineno.
1514 We have to do that before the .ent directive as we cannot switch
1515 files within procedures with native ecoff because line numbers are
1516 linked to procedure descriptors.
1517 Outputting the lineno helps debugging of one line functions as they
1518 would otherwise get no line number at all. Please note that we would
1519 like to put out last_linenum from final.c, but it is not accessible. */
1520
1521 if (write_symbols == SDB_DEBUG)
1522 {
1523 ASM_OUTPUT_SOURCE_FILENAME (file,
1524 DECL_SOURCE_FILE (current_function_decl));
1525 if (debug_info_level != DINFO_LEVEL_TERSE)
1526 ASM_OUTPUT_SOURCE_LINE (file,
1527 DECL_SOURCE_LINE (current_function_decl));
1528 }
1529
1530 /* The assembly language programmer's guide states that the second argument
1531 to the .ent directive, the lex_level, is ignored by the assembler,
1532 so we might as well omit it. */
1533
1534 fprintf (file, "\t.ent ");
1535 assemble_name (file, alpha_function_name);
1536 fprintf (file, "\n");
1537 ASM_OUTPUT_LABEL (file, alpha_function_name);
1538 inside_function = TRUE;
1539
1540 if (TARGET_IEEE_CONFORMANT)
1541 /* Set flags in procedure descriptor to request IEEE-conformant
1542 math-library routines. The value we set it to is PDSC_EXC_IEEE
1543 (/usr/include/pdsc.h). */
1544 fprintf (file, "\t.eflag 48\n");
1545
1546 /* Set up offsets to alpha virtual arg/local debugging pointer. */
1547
1548 alpha_auto_offset = -frame_size + current_function_pretend_args_size;
1549 alpha_arg_offset = -frame_size + 48;
1550
1551 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
1552 Even if we are a static function, we still need to do this in case
1553 our address is taken and passed to something like qsort.
1554
1555 We never need a GP for Windows/NT. */
1556
1557 alpha_function_needs_gp = 0;
1558
1559 #ifdef TARGET_PROFILING_NEEDS_GP
1560 if (profile_flag)
1561 alpha_function_needs_gp = 1;
1562 #endif
1563
1564 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1565 if ((GET_CODE (insn) == CALL_INSN)
1566 || (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
1567 && GET_CODE (PATTERN (insn)) != USE
1568 && GET_CODE (PATTERN (insn)) != CLOBBER
1569 && (get_attr_type (insn) == TYPE_LDSYM
1570 || get_attr_type (insn) == TYPE_ISUBR)))
1571 {
1572 alpha_function_needs_gp = 1;
1573 break;
1574 }
1575
1576 if (WINDOWS_NT == 0)
1577 {
1578 if (alpha_function_needs_gp)
1579 fprintf (file, "\tldgp $29,0($27)\n");
1580
1581 /* Put a label after the GP load so we can enter the function at it. */
1582 assemble_name (file, alpha_function_name);
1583 fprintf (file, "..ng:\n");
1584 }
1585
1586 /* Adjust the stack by the frame size. If the frame size is > 4096
1587 bytes, we need to be sure we probe somewhere in the first and last
1588 4096 bytes (we can probably get away without the latter test) and
1589 every 8192 bytes in between. If the frame size is > 32768, we
1590 do this in a loop. Otherwise, we generate the explicit probe
1591 instructions.
1592
1593 Note that we are only allowed to adjust sp once in the prologue. */
1594
1595 if (frame_size < 32768)
1596 {
1597 if (frame_size > 4096)
1598 {
1599 int probed = 4096;
1600
1601 fprintf (file, "\tstq $31,-%d($30)\n", probed);
1602
1603 while (probed + 8192 < frame_size)
1604 fprintf (file, "\tstq $31,-%d($30)\n", probed += 8192);
1605
1606 /* We only have to do this probe if we aren't saving registers. */
1607 if (sa_size == 0 && probed + 4096 < frame_size)
1608 fprintf (file, "\tstq $31,-%d($30)\n", frame_size);
1609 }
1610
1611 if (frame_size != 0)
1612 fprintf (file, "\tlda $30,-%d($30)\n", frame_size);
1613 }
1614 else
1615 {
1616 /* Here we generate code to set R4 to SP + 4096 and set R5 to the
1617 number of 8192 byte blocks to probe. We then probe each block
1618 in the loop and then set SP to the proper location. If the
1619 amount remaining is > 4096, we have to do one more probe if we
1620 are not saving any registers. */
1621
1622 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
1623 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
1624
1625 add_long_const (file, blocks, 31, 5, 5);
1626
1627 fprintf (file, "\tlda $4,4096($30)\n");
1628
1629 assemble_name (file, alpha_function_name);
1630 fprintf (file, "..sc:\n");
1631
1632 fprintf (file, "\tstq $31,-8192($4)\n");
1633 fprintf (file, "\tsubq $5,1,$5\n");
1634 fprintf (file, "\tlda $4,-8192($4)\n");
1635
1636 fprintf (file, "\tbne $5,");
1637 assemble_name (file, alpha_function_name);
1638 fprintf (file, "..sc\n");
1639
1640 if (leftover > 4096 && sa_size == 0)
1641 fprintf (file, "\tstq $31,-%d($4)\n", leftover);
1642
1643 fprintf (file, "\tlda $30,-%d($4)\n", leftover);
1644 }
1645
1646 /* Describe our frame. */
1647 fprintf (file, "\t.frame $%d,%d,$26,%d\n",
1648 (frame_pointer_needed
1649 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM),
1650 frame_size, current_function_pretend_args_size);
1651
1652 /* Save register 26 if any other register needs to be saved. */
1653 if (sa_size != 0)
1654 {
1655 reg_mask |= 1 << 26;
1656 fprintf (file, "\tstq $26,%d($30)\n", reg_offset);
1657 reg_offset += 8;
1658 int_reg_save_area_size += 8;
1659 }
1660
1661 /* Now save any other used integer registers required to be saved. */
1662 for (i = 0; i < 32; i++)
1663 if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i] && i != 26)
1664 {
1665 reg_mask |= 1 << i;
1666 fprintf (file, "\tstq $%d,%d($30)\n", i, reg_offset);
1667 reg_offset += 8;
1668 int_reg_save_area_size += 8;
1669 }
1670
1671 /* Print the register mask and do floating-point saves. */
1672 if (reg_mask)
1673 fprintf (file, "\t.mask 0x%x,%d\n", reg_mask,
1674 actual_start_reg_offset - frame_size);
1675
1676 start_reg_offset = reg_offset;
1677 reg_mask = 0;
1678
1679 for (i = 0; i < 32; i++)
1680 if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
1681 && regs_ever_live[i + 32])
1682 {
1683 reg_mask |= 1 << i;
1684 fprintf (file, "\tstt $f%d,%d($30)\n", i, reg_offset);
1685 reg_offset += 8;
1686 }
1687
1688 /* Print the floating-point mask, if we've saved any fp register. */
1689 if (reg_mask)
1690 fprintf (file, "\t.fmask 0x%x,%d\n", reg_mask,
1691 actual_start_reg_offset - frame_size + int_reg_save_area_size);
1692
1693 /* If we need a frame pointer, set it from the stack pointer. Note that
1694 this must always be the last instruction in the prologue. */
1695 if (frame_pointer_needed)
1696 fprintf (file, "\tbis $30,$30,$15\n");
1697
1698 /* End the prologue and say if we used gp. */
1699 fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
1700 }
1701
1702 /* Write function epilogue. */
1703
1704 void
1705 output_epilog (file, size)
1706 FILE *file;
1707 int size;
1708 {
1709 rtx insn = get_last_insn ();
1710 HOST_WIDE_INT out_args_size
1711 = ALPHA_ROUND (current_function_outgoing_args_size);
1712 HOST_WIDE_INT sa_size = alpha_sa_size ();
1713 HOST_WIDE_INT frame_size
1714 = (out_args_size + sa_size
1715 + ALPHA_ROUND (size + current_function_pretend_args_size));
1716 HOST_WIDE_INT reg_offset = out_args_size;
1717 HOST_WIDE_INT frame_size_from_reg_save = frame_size - reg_offset;
1718 int restore_fp
1719 = frame_pointer_needed && regs_ever_live[HARD_FRAME_POINTER_REGNUM];
1720 int i;
1721
1722 /* If the last insn was a BARRIER, we don't have to write anything except
1723 the .end pseudo-op. */
1724 if (GET_CODE (insn) == NOTE)
1725 insn = prev_nonnote_insn (insn);
1726 if (insn == 0 || GET_CODE (insn) != BARRIER)
1727 {
1728 int fp_offset = 0;
1729
1730 final_prescan_insn (NULL_RTX, NULL_PTR, 0);
1731
1732 /* If we have a frame pointer, restore SP from it. */
1733 if (frame_pointer_needed)
1734 fprintf (file, "\tbis $15,$15,$30\n");
1735
1736 /* Restore all the registers, starting with the return address
1737 register. */
1738 if (sa_size != 0)
1739 {
1740 fprintf (file, "\tldq $26,%d($30)\n", reg_offset);
1741 reg_offset += 8;
1742 }
1743
1744 /* Now restore any other used integer registers that that we saved,
1745 except for FP if it is being used as FP, since it must be
1746 restored last. */
1747
1748 for (i = 0; i < 32; i++)
1749 if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i]
1750 && i != 26)
1751 {
1752 if (i == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
1753 fp_offset = reg_offset;
1754 else
1755 fprintf (file, "\tldq $%d,%d($30)\n", i, reg_offset);
1756 reg_offset += 8;
1757 }
1758
1759 for (i = 0; i < 32; i++)
1760 if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
1761 && regs_ever_live[i + 32])
1762 {
1763 fprintf (file, "\tldt $f%d,%d($30)\n", i, reg_offset);
1764 reg_offset += 8;
1765 }
1766
1767 /* If the stack size is large and we have a frame pointer, compute the
1768 size of the stack into a register because the old FP restore, stack
1769 pointer adjust, and return are required to be consecutive
1770 instructions. */
1771 if (frame_size > 32767 && restore_fp)
1772 add_long_const (file, frame_size, 31, 1, 1);
1773
1774 /* If we needed a frame pointer and we have to restore it, do it
1775 now. This must be done in one instruction immediately
1776 before the SP update. */
1777 if (restore_fp && fp_offset)
1778 fprintf (file, "\tldq $15,%d($30)\n", fp_offset);
1779
1780 /* Now update the stack pointer, if needed. Only one instruction must
1781 modify the stack pointer. It must be the last instruction in the
1782 sequence and must be an ADDQ or LDA instruction. If the frame
1783 pointer was loaded above, we may only put one instruction here. */
1784
1785 if (frame_size > 32768 && restore_fp)
1786 fprintf (file, "\taddq $1,$30,$30\n");
1787 else
1788 add_long_const (file, frame_size, 30, 30, 1);
1789
1790 /* Finally return to the caller. */
1791 fprintf (file, "\tret $31,($26),1\n");
1792 }
1793
1794 /* End the function. */
1795 fprintf (file, "\t.end ");
1796 assemble_name (file, alpha_function_name);
1797 fprintf (file, "\n");
1798 inside_function = FALSE;
1799
1800 /* Show that we know this function if it is called again. */
1801 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
1802 }
1803 \f
1804 /* Debugging support. */
1805
1806 #include "gstab.h"
1807
1808 /* Count the number of sdb related labels are generated (to find block
1809 start and end boundaries). */
1810
1811 int sdb_label_count = 0;
1812
1813 /* Next label # for each statement. */
1814
1815 static int sym_lineno = 0;
1816
1817 /* Count the number of .file directives, so that .loc is up to date. */
1818
1819 static int num_source_filenames = 0;
1820
1821 /* Name of the file containing the current function. */
1822
1823 static char *current_function_file = "";
1824
1825 /* Offsets to alpha virtual arg/local debugging pointers. */
1826
1827 long alpha_arg_offset;
1828 long alpha_auto_offset;
1829 \f
1830 /* Emit a new filename to a stream. */
1831
1832 void
1833 alpha_output_filename (stream, name)
1834 FILE *stream;
1835 char *name;
1836 {
1837 static int first_time = TRUE;
1838 char ltext_label_name[100];
1839
1840 if (first_time)
1841 {
1842 first_time = FALSE;
1843 ++num_source_filenames;
1844 current_function_file = name;
1845 fprintf (stream, "\t.file\t%d ", num_source_filenames);
1846 output_quoted_string (stream, name);
1847 fprintf (stream, "\n");
1848 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
1849 fprintf (stream, "\t#@stabs\n");
1850 }
1851
1852 else if (!TARGET_GAS && write_symbols == DBX_DEBUG)
1853 {
1854 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
1855 fprintf (stream, "%s ", ASM_STABS_OP);
1856 output_quoted_string (stream, name);
1857 fprintf (stream, ",%d,0,0,%s\n", N_SOL, &ltext_label_name[1]);
1858 }
1859
1860 else if (name != current_function_file
1861 && strcmp (name, current_function_file) != 0)
1862 {
1863 if (inside_function && ! TARGET_GAS)
1864 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
1865 else
1866 {
1867 ++num_source_filenames;
1868 current_function_file = name;
1869 fprintf (stream, "\t.file\t%d ", num_source_filenames);
1870 }
1871
1872 output_quoted_string (stream, name);
1873 fprintf (stream, "\n");
1874 }
1875 }
1876 \f
1877 /* Emit a linenumber to a stream. */
1878
1879 void
1880 alpha_output_lineno (stream, line)
1881 FILE *stream;
1882 int line;
1883 {
1884 if (! TARGET_GAS && write_symbols == DBX_DEBUG)
1885 {
1886 /* mips-tfile doesn't understand .stabd directives. */
1887 ++sym_lineno;
1888 fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
1889 sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
1890 }
1891 else
1892 fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
1893 }
1894 \f
1895 /* Structure to show the current status of registers and memory. */
1896
1897 struct shadow_summary
1898 {
1899 struct {
1900 unsigned long i : 32; /* Mask of int regs */
1901 unsigned long fp : 32; /* Mask of fp regs */
1902 unsigned long mem : 1; /* mem == imem | fpmem */
1903 } used, defd;
1904 };
1905
1906 /* Summary the effects of expression X on the machine. Update SUM, a pointer
1907 to the summary structure. SET is nonzero if the insn is setting the
1908 object, otherwise zero. */
1909
1910 static void
1911 summarize_insn (x, sum, set)
1912 rtx x;
1913 struct shadow_summary *sum;
1914 int set;
1915 {
1916 char *format_ptr;
1917 int i, j;
1918
1919 if (x == 0)
1920 return;
1921
1922 switch (GET_CODE (x))
1923 {
1924 /* ??? Note that this case would be incorrect if the Alpha had a
1925 ZERO_EXTRACT in SET_DEST. */
1926 case SET:
1927 summarize_insn (SET_SRC (x), sum, 0);
1928 summarize_insn (SET_DEST (x), sum, 1);
1929 break;
1930
1931 case CLOBBER:
1932 summarize_insn (XEXP (x, 0), sum, 1);
1933 break;
1934
1935 case USE:
1936 summarize_insn (XEXP (x, 0), sum, 0);
1937 break;
1938
1939 case PARALLEL:
1940 for (i = XVECLEN (x, 0); i >= 0; i--)
1941 summarize_insn (XVECEXP (x, 0, i), sum, 0);
1942 break;
1943
1944 case REG:
1945 {
1946 int regno = REGNO (x);
1947 unsigned long mask = 1UL << (regno % 32);
1948
1949 if (regno == 31 || regno == 63)
1950 break;
1951
1952 if (set)
1953 {
1954 if (regno < 32)
1955 sum->defd.i |= mask;
1956 else
1957 sum->defd.fp |= mask;
1958 }
1959 else
1960 {
1961 if (regno < 32)
1962 sum->used.i |= mask;
1963 else
1964 sum->used.fp |= mask;
1965 }
1966 }
1967 break;
1968
1969 case MEM:
1970 if (set)
1971 sum->defd.mem = 1;
1972 else
1973 sum->used.mem = 1;
1974
1975 /* Find the regs used in memory address computation: */
1976 summarize_insn (XEXP (x, 0), sum, 0);
1977 break;
1978
1979 /* Handle common unary and binary ops for efficiency. */
1980 case COMPARE: case PLUS: case MINUS: case MULT: case DIV:
1981 case MOD: case UDIV: case UMOD: case AND: case IOR:
1982 case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT:
1983 case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX:
1984 case NE: case EQ: case GE: case GT: case LE:
1985 case LT: case GEU: case GTU: case LEU: case LTU:
1986 summarize_insn (XEXP (x, 0), sum, 0);
1987 summarize_insn (XEXP (x, 1), sum, 0);
1988 break;
1989
1990 case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
1991 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
1992 case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
1993 case SQRT: case FFS:
1994 summarize_insn (XEXP (x, 0), sum, 0);
1995 break;
1996
1997 default:
1998 format_ptr = GET_RTX_FORMAT (GET_CODE (x));
1999 for (i = GET_RTX_LENGTH (GET_CODE (x)); i >= 0; i--)
2000 switch (*format_ptr++)
2001 {
2002 case 'e':
2003 summarize_insn (XEXP (x, i), sum, 0);
2004 break;
2005
2006 case 'E':
2007 for (j = XVECLEN (x, i); j >= 0; j--)
2008 summarize_insn (XVECEXP (x, i, j), sum, 0);
2009 break;
2010
2011 default:
2012 abort ();
2013 }
2014 }
2015 }
2016 \f
2017 /* This function is executed just prior to the output of assembler code for
2018 INSN to modify the extracted operands so they will be output differently.
2019
2020 OPVEC is the vector containing the operands extracted from INSN, and
2021 NOPERANDS is the number of elements of the vector which contain meaningful
2022 data for this insn. The contents of this vector are what will be used to
2023 convert the insn template into assembler code, so you can change the
2024 assembler output by changing the contents of the vector.
2025
2026 We use this function to ensure a sufficient number of `trapb' instructions
2027 are in the code when the user requests code with a trap precision of
2028 functions or instructions.
2029
2030 In naive mode, when the user requests a trap-precision of "instruction", a
2031 trapb is needed after every instruction that may generate a trap (and after
2032 jsr/bsr instructions, because called functions may import a trap from the
2033 caller). This ensures that the code is resumption safe but it is also slow.
2034
2035 When optimizations are turned on, we delay issuing a trapb as long as
2036 possible. In this context, a trap shadow is the sequence of instructions
2037 that starts with a (potentially) trap generating instruction and extends to
2038 the next trapb or call_pal instruction (but GCC never generates call_pal by
2039 itself). We can delay (and therefore sometimes omit) a trapb subject to the
2040 following conditions:
2041
2042 (a) On entry to the trap shadow, if any Alpha register or memory location
2043 contains a value that is used as an operand value by some instruction in
2044 the trap shadow (live on entry), then no instruction in the trap shadow
2045 may modify the register or memory location.
2046
2047 (b) Within the trap shadow, the computation of the base register for a
2048 memory load or store instruction may not involve using the result
2049 of an instruction that might generate an UNPREDICTABLE result.
2050
2051 (c) Within the trap shadow, no register may be used more than once as a
2052 destination register. (This is to make life easier for the trap-handler.)
2053
2054 (d) The trap shadow may not include any branch instructions.
2055
2056 */
2057
2058 void
2059 final_prescan_insn (insn, opvec, noperands)
2060 rtx insn;
2061 rtx *opvec;
2062 int noperands;
2063 {
2064 static struct shadow_summary shadow = {0, 0, 0, 0, 0};
2065
2066 #define CLOSE_SHADOW \
2067 do \
2068 { \
2069 fputs ("\ttrapb\n", asm_out_file); \
2070 trap_pending = 0; \
2071 bzero ((char *) &shadow, sizeof shadow); \
2072 } \
2073 while (0)
2074
2075 if (alpha_tp == ALPHA_TP_PROG)
2076 return;
2077
2078 if (trap_pending)
2079 switch (alpha_tp)
2080 {
2081 case ALPHA_TP_FUNC:
2082 /* Generate one trapb before epilogue (indicated by INSN==0) */
2083 if (insn == 0)
2084 CLOSE_SHADOW;
2085 break;
2086
2087 case ALPHA_TP_INSN:
2088 if (optimize && insn != 0)
2089 {
2090 struct shadow_summary sum = {0, 0, 0};
2091
2092 switch (GET_CODE(insn))
2093 {
2094 case INSN:
2095 summarize_insn (PATTERN (insn), &sum, 0);
2096
2097 if ((sum.defd.i & shadow.defd.i)
2098 || (sum.defd.fp & shadow.defd.fp))
2099 {
2100 /* (c) would be violated */
2101 CLOSE_SHADOW;
2102 break;
2103 }
2104
2105 /* Combine shadow with summary of current insn: */
2106 shadow.used.i |= sum.used.i;
2107 shadow.used.fp |= sum.used.fp;
2108 shadow.used.mem |= sum.used.mem;
2109 shadow.defd.i |= sum.defd.i;
2110 shadow.defd.fp |= sum.defd.fp;
2111 shadow.defd.mem |= sum.defd.mem;
2112
2113 if ((sum.defd.i & shadow.used.i)
2114 || (sum.defd.fp & shadow.used.fp)
2115 || (sum.defd.mem & shadow.used.mem))
2116 {
2117 /* (a) would be violated (also takes care of (b)). */
2118 if (get_attr_trap (insn) == TRAP_YES
2119 && ((sum.defd.i & sum.used.i)
2120 || (sum.defd.fp & sum.used.fp)))
2121 abort ();
2122
2123 CLOSE_SHADOW;
2124 break;
2125 }
2126 break;
2127
2128 case JUMP_INSN:
2129 case CALL_INSN:
2130 case CODE_LABEL:
2131 CLOSE_SHADOW;
2132 break;
2133
2134 default:
2135 abort ();
2136 }
2137 }
2138 else
2139 CLOSE_SHADOW;
2140 break;
2141 }
2142
2143 if (insn != 0 && get_attr_trap (insn) == TRAP_YES)
2144 {
2145 if (optimize && !trap_pending && GET_CODE (insn) == INSN)
2146 summarize_insn (PATTERN (insn), &shadow, 0);
2147 trap_pending = 1;
2148 }
2149 }