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