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