]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/alpha/alpha.c
Update mainline egcs to gcc2 snapshot 971021.
[thirdparty/gcc.git] / gcc / config / alpha / alpha.c
CommitLineData
a6f12d7c 1/* Subroutines used for code generation on the DEC Alpha.
7f11fbd5 2 Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
d60a05a1 3 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
a6f12d7c
RK
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
38ead7f3
RK
19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
a6f12d7c
RK
21
22
a6f12d7c 23#include "config.h"
e9a25f70 24#include <stdio.h>
a6f12d7c
RK
25#include "rtl.h"
26#include "regs.h"
27#include "hard-reg-set.h"
28#include "real.h"
29#include "insn-config.h"
30#include "conditions.h"
31#include "insn-flags.h"
32#include "output.h"
33#include "insn-attr.h"
34#include "flags.h"
35#include "recog.h"
36#include "reload.h"
37#include "expr.h"
38#include "obstack.h"
39#include "tree.h"
9ecc37f0
RH
40#include "except.h"
41#include "function.h"
42
43/* External data. */
44extern char *version_string;
45extern int rtx_equal_function_value_matters;
a6f12d7c 46
da792a68 47/* Specify which cpu to schedule for. */
9ecc37f0 48
9b009d45 49enum processor_type alpha_cpu;
da792a68 50
6245e3df
RK
51/* Specify how accurate floating-point traps need to be. */
52
53enum alpha_trap_precision alpha_tp;
54
55/* Specify the floating-point rounding mode. */
56
57enum alpha_fp_rounding_mode alpha_fprm;
58
59/* Specify which things cause traps. */
60
61enum alpha_fp_trap_mode alpha_fptm;
62
63/* Strings decoded into the above options. */
9ecc37f0 64
da792a68 65char *alpha_cpu_string; /* -mcpu=ev[4|5] */
6245e3df
RK
66char *alpha_tp_string; /* -mtrap-precision=[p|s|i] */
67char *alpha_fprm_string; /* -mfp-rounding-mode=[n|m|c|d] */
68char *alpha_fptm_string; /* -mfp-trap-mode=[n|u|su|sui] */
69
a6f12d7c
RK
70/* Save information from a "cmpxx" operation until the branch or scc is
71 emitted. */
72
73rtx alpha_compare_op0, alpha_compare_op1;
74int alpha_compare_fp_p;
75
76/* Save the name of the current function as used by the assembler. This
77 is used by the epilogue. */
78
79char *alpha_function_name;
80
48f6bfac
RK
81/* Non-zero if inside of a function, because the Alpha asm can't
82 handle .files inside of functions. */
83
84static int inside_function = FALSE;
85
a6f12d7c
RK
86/* Nonzero if the current function needs gp. */
87
88int alpha_function_needs_gp;
0f33506c 89
9ecc37f0
RH
90/* If non-null, this rtx holds the return address for the function. */
91
92static rtx alpha_return_addr_rtx;
d60a05a1
RK
93
94/* Declarations of static functions. */
95static void alpha_set_memflags_1 PROTO((rtx, int, int, int));
9102cd1f
RK
96static rtx alpha_emit_set_const_1 PROTO((rtx, enum machine_mode,
97 HOST_WIDE_INT, int));
d60a05a1 98static void add_long_const PROTO((FILE *, HOST_WIDE_INT, int, int, int));
89cfc2c6
RK
99
100/* Compute the size of the save area in the stack. */
101static void alpha_sa_mask PROTO((unsigned long *imaskP,
102 unsigned long *fmaskP));
e9a25f70
JL
103/* Get the number of args of a function in one of two ways. */
104#ifdef OPEN_VMS
105#define NUM_ARGS current_function_args_info.num_args
106#else
107#define NUM_ARGS current_function_args_info
108#endif
a6f12d7c 109\f
6245e3df
RK
110/* Parse target option strings. */
111
112void
113override_options ()
114{
74dad6ce 115 alpha_cpu
e9a25f70
JL
116 = TARGET_CPU_DEFAULT & MASK_CPU_EV6 ? PROCESSOR_EV6
117 : (TARGET_CPU_DEFAULT & MASK_CPU_EV5 ? PROCESSOR_EV5 : PROCESSOR_EV4);
10d5c73f 118
da792a68
RK
119 if (alpha_cpu_string)
120 {
10d5c73f
RK
121 if (! strcmp (alpha_cpu_string, "ev4")
122 || ! strcmp (alpha_cpu_string, "21064"))
e9a25f70
JL
123 {
124 alpha_cpu = PROCESSOR_EV4;
125 target_flags &= ~ (MASK_BWX | MASK_CIX | MASK_MAX);
126 }
10d5c73f
RK
127 else if (! strcmp (alpha_cpu_string, "ev5")
128 || ! strcmp (alpha_cpu_string, "21164"))
e9a25f70
JL
129 {
130 alpha_cpu = PROCESSOR_EV5;
131 target_flags &= ~ (MASK_BWX | MASK_CIX | MASK_MAX);
132 }
9b009d45
RK
133 else if (! strcmp (alpha_cpu_string, "ev56")
134 || ! strcmp (alpha_cpu_string, "21164a"))
135 {
136 alpha_cpu = PROCESSOR_EV5;
e9a25f70
JL
137 target_flags |= MASK_BWX;
138 target_flags &= ~ (MASK_CIX | MASK_MAX);
139 }
140 else if (! strcmp (alpha_cpu_string, "pca56")
141 || ! strcmp (alpha_cpu_string, "21164PC"))
142 {
143 alpha_cpu = PROCESSOR_EV5;
144 target_flags |= MASK_BWX | MASK_MAX;
145 target_flags &= ~ MASK_CIX;
146 }
147 else if (! strcmp (alpha_cpu_string, "ev6")
148 || ! strcmp (alpha_cpu_string, "21264"))
149 {
150 alpha_cpu = PROCESSOR_EV6;
151 target_flags |= MASK_BWX | MASK_CIX | MASK_MAX;
9b009d45 152 }
da792a68 153 else
10d5c73f 154 error ("bad value `%s' for -mcpu switch", alpha_cpu_string);
da792a68
RK
155 }
156
6245e3df
RK
157 alpha_tp = ALPHA_TP_PROG;
158 alpha_fprm = ALPHA_FPRM_NORM;
159 alpha_fptm = ALPHA_FPTM_N;
160
161 if (TARGET_IEEE)
162 {
10d5c73f
RK
163 alpha_tp = ALPHA_TP_INSN;
164 alpha_fptm = ALPHA_FPTM_SU;
6245e3df
RK
165 }
166
167 if (TARGET_IEEE_WITH_INEXACT)
168 {
10d5c73f
RK
169 alpha_tp = ALPHA_TP_INSN;
170 alpha_fptm = ALPHA_FPTM_SUI;
6245e3df
RK
171 }
172
173 if (alpha_tp_string)
10d5c73f
RK
174 {
175 if (! strcmp (alpha_tp_string, "p"))
6245e3df 176 alpha_tp = ALPHA_TP_PROG;
10d5c73f 177 else if (! strcmp (alpha_tp_string, "f"))
6245e3df 178 alpha_tp = ALPHA_TP_FUNC;
10d5c73f 179 else if (! strcmp (alpha_tp_string, "i"))
6245e3df 180 alpha_tp = ALPHA_TP_INSN;
10d5c73f
RK
181 else
182 error ("bad value `%s' for -mtrap-precision switch", alpha_tp_string);
183 }
6245e3df
RK
184
185 if (alpha_fprm_string)
10d5c73f
RK
186 {
187 if (! strcmp (alpha_fprm_string, "n"))
6245e3df 188 alpha_fprm = ALPHA_FPRM_NORM;
10d5c73f 189 else if (! strcmp (alpha_fprm_string, "m"))
6245e3df 190 alpha_fprm = ALPHA_FPRM_MINF;
10d5c73f 191 else if (! strcmp (alpha_fprm_string, "c"))
6245e3df 192 alpha_fprm = ALPHA_FPRM_CHOP;
10d5c73f 193 else if (! strcmp (alpha_fprm_string,"d"))
6245e3df 194 alpha_fprm = ALPHA_FPRM_DYN;
10d5c73f
RK
195 else
196 error ("bad value `%s' for -mfp-rounding-mode switch",
6245e3df 197 alpha_fprm_string);
10d5c73f 198 }
6245e3df
RK
199
200 if (alpha_fptm_string)
10d5c73f
RK
201 {
202 if (strcmp (alpha_fptm_string, "n") == 0)
203 alpha_fptm = ALPHA_FPTM_N;
204 else if (strcmp (alpha_fptm_string, "u") == 0)
205 alpha_fptm = ALPHA_FPTM_U;
206 else if (strcmp (alpha_fptm_string, "su") == 0)
207 alpha_fptm = ALPHA_FPTM_SU;
208 else if (strcmp (alpha_fptm_string, "sui") == 0)
209 alpha_fptm = ALPHA_FPTM_SUI;
210 else
211 error ("bad value `%s' for -mfp-trap-mode switch", alpha_fptm_string);
212 }
6245e3df
RK
213
214 /* Do some sanity checks on the above option. */
215
10d5c73f
RK
216 if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI)
217 && alpha_tp != ALPHA_TP_INSN)
6245e3df 218 {
10d5c73f 219 warning ("fp software completion requires -mtrap-precision=i");
6245e3df
RK
220 alpha_tp = ALPHA_TP_INSN;
221 }
89cfc2c6
RK
222
223 if (TARGET_FLOAT_VAX)
224 {
225 if (alpha_fprm == ALPHA_FPRM_MINF || alpha_fprm == ALPHA_FPRM_DYN)
226 {
227 warning ("rounding mode not supported for VAX floats");
228 alpha_fprm = ALPHA_FPRM_NORM;
229 }
230 if (alpha_fptm == ALPHA_FPTM_SUI)
231 {
232 warning ("trap mode not supported for VAX floats");
233 alpha_fptm = ALPHA_FPTM_SU;
234 }
235 }
6245e3df
RK
236}
237\f
a6f12d7c
RK
238/* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
239
240int
241zap_mask (value)
242 HOST_WIDE_INT value;
243{
244 int i;
245
246 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
247 i++, value >>= 8)
248 if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
249 return 0;
250
251 return 1;
252}
253
254/* Returns 1 if OP is either the constant zero or a register. If a
255 register, it must be in the proper mode unless MODE is VOIDmode. */
256
257int
258reg_or_0_operand (op, mode)
259 register rtx op;
260 enum machine_mode mode;
261{
262 return op == const0_rtx || register_operand (op, mode);
263}
264
f4014bfd
RK
265/* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
266 any register. */
267
268int
269reg_or_6bit_operand (op, mode)
270 register rtx op;
271 enum machine_mode mode;
272{
273 return ((GET_CODE (op) == CONST_INT
274 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64)
275 || register_operand (op, mode));
276}
277
278
a6f12d7c
RK
279/* Return 1 if OP is an 8-bit constant or any register. */
280
281int
282reg_or_8bit_operand (op, mode)
283 register rtx op;
284 enum machine_mode mode;
285{
286 return ((GET_CODE (op) == CONST_INT
287 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
288 || register_operand (op, mode));
289}
290
14edc0e4
TG
291/* Return 1 if OP is an 8-bit constant. */
292
293int
294cint8_operand (op, mode)
295 register rtx op;
296 enum machine_mode mode;
297{
298 return (GET_CODE (op) == CONST_INT
299 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100);
300}
301
a6f12d7c
RK
302/* Return 1 if the operand is a valid second operand to an add insn. */
303
304int
305add_operand (op, mode)
306 register rtx op;
307 enum machine_mode mode;
308{
309 if (GET_CODE (op) == CONST_INT)
e6118f89
RK
310 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'K')
311 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L')
312 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'O'));
a6f12d7c
RK
313
314 return register_operand (op, mode);
315}
316
317/* Return 1 if the operand is a valid second operand to a sign-extending
318 add insn. */
319
320int
321sext_add_operand (op, mode)
322 register rtx op;
323 enum machine_mode mode;
324{
325 if (GET_CODE (op) == CONST_INT)
326 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 255
327 || (unsigned HOST_WIDE_INT) (- INTVAL (op)) < 255);
328
329 return register_operand (op, mode);
330}
331
332/* Return 1 if OP is the constant 4 or 8. */
333
334int
335const48_operand (op, mode)
336 register rtx op;
337 enum machine_mode mode;
338{
339 return (GET_CODE (op) == CONST_INT
340 && (INTVAL (op) == 4 || INTVAL (op) == 8));
341}
342
343/* Return 1 if OP is a valid first operand to an AND insn. */
344
345int
346and_operand (op, mode)
347 register rtx op;
348 enum machine_mode mode;
349{
350 if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
351 return (zap_mask (CONST_DOUBLE_LOW (op))
352 && zap_mask (CONST_DOUBLE_HIGH (op)));
353
354 if (GET_CODE (op) == CONST_INT)
355 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
356 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
357 || zap_mask (INTVAL (op)));
358
359 return register_operand (op, mode);
360}
361
c7def335 362/* Return 1 if OP is a valid first operand to an IOR or XOR insn. */
8088469d
RK
363
364int
c7def335 365or_operand (op, mode)
8088469d
RK
366 register rtx op;
367 enum machine_mode mode;
368{
369 if (GET_CODE (op) == CONST_INT)
370 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
371 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100);
372
373 return register_operand (op, mode);
374}
375
a6f12d7c
RK
376/* Return 1 if OP is a constant that is the width, in bits, of an integral
377 mode smaller than DImode. */
378
379int
380mode_width_operand (op, mode)
381 register rtx op;
382 enum machine_mode mode;
383{
384 return (GET_CODE (op) == CONST_INT
385 && (INTVAL (op) == 8 || INTVAL (op) == 16 || INTVAL (op) == 32));
386}
387
388/* Return 1 if OP is a constant that is the width of an integral machine mode
389 smaller than an integer. */
390
391int
392mode_mask_operand (op, mode)
393 register rtx op;
394 enum machine_mode mode;
395{
396#if HOST_BITS_PER_WIDE_INT == 32
397 if (GET_CODE (op) == CONST_DOUBLE)
398 return CONST_DOUBLE_HIGH (op) == 0 && CONST_DOUBLE_LOW (op) == -1;
399#endif
400
16b02ae0
RK
401 return (GET_CODE (op) == CONST_INT
402 && (INTVAL (op) == 0xff
403 || INTVAL (op) == 0xffff
a6f12d7c 404#if HOST_BITS_PER_WIDE_INT == 64
16b02ae0 405 || INTVAL (op) == 0xffffffff
a6f12d7c 406#endif
16b02ae0 407 ));
a6f12d7c
RK
408}
409
410/* Return 1 if OP is a multiple of 8 less than 64. */
411
412int
413mul8_operand (op, mode)
414 register rtx op;
415 enum machine_mode mode;
416{
417 return (GET_CODE (op) == CONST_INT
418 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64
419 && (INTVAL (op) & 7) == 0);
420}
421
422/* Return 1 if OP is the constant zero in floating-point. */
423
424int
425fp0_operand (op, mode)
426 register rtx op;
427 enum machine_mode mode;
428{
429 return (GET_MODE (op) == mode
430 && GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode));
431}
432
433/* Return 1 if OP is the floating-point constant zero or a register. */
434
435int
436reg_or_fp0_operand (op, mode)
437 register rtx op;
438 enum machine_mode mode;
439{
440 return fp0_operand (op, mode) || register_operand (op, mode);
441}
442
443/* Return 1 if OP is a register or a constant integer. */
444
445
446int
447reg_or_cint_operand (op, mode)
448 register rtx op;
449 enum machine_mode mode;
450{
451 return GET_CODE (op) == CONST_INT || register_operand (op, mode);
452}
453
8d36d33b
RK
454/* Return 1 if OP is something that can be reloaded into a register;
455 if it is a MEM, it need not be valid. */
456
457int
458some_operand (op, mode)
459 register rtx op;
460 enum machine_mode mode;
461{
462 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
463 return 0;
464
465 switch (GET_CODE (op))
466 {
467 case REG: case MEM: case CONST_DOUBLE:
468 case CONST_INT: case LABEL_REF: case SYMBOL_REF: case CONST:
469 return 1;
470
471 case SUBREG:
472 return some_operand (SUBREG_REG (op), VOIDmode);
473 }
474
475 return 0;
476}
477
a6f12d7c
RK
478/* Return 1 if OP is a valid operand for the source of a move insn. */
479
480int
481input_operand (op, mode)
482 register rtx op;
483 enum machine_mode mode;
484{
485 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
486 return 0;
487
488 if (GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE (op) != mode)
489 return 0;
490
491 switch (GET_CODE (op))
492 {
493 case LABEL_REF:
494 case SYMBOL_REF:
495 case CONST:
7daa56f5
RK
496 /* This handles both the Windows/NT and OSF cases. */
497 return mode == ptr_mode || mode == DImode;
a6f12d7c
RK
498
499 case REG:
500 return 1;
501
502 case SUBREG:
503 if (register_operand (op, mode))
504 return 1;
505 /* ... fall through ... */
506 case MEM:
e9a25f70 507 return ((TARGET_BWX || (mode != HImode && mode != QImode))
a2574dbe 508 && general_operand (op, mode));
a6f12d7c
RK
509
510 case CONST_DOUBLE:
511 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
512
513 case CONST_INT:
514 return mode == QImode || mode == HImode || add_operand (op, mode);
515 }
516
517 return 0;
518}
519
0f33506c
RK
520/* Return 1 if OP is a SYMBOL_REF for a function known to be in this
521 file. */
a6f12d7c
RK
522
523int
0f33506c 524current_file_function_operand (op, mode)
a6f12d7c
RK
525 rtx op;
526 enum machine_mode mode;
527{
528 return (GET_CODE (op) == SYMBOL_REF
d14d353d 529 && ! profile_flag && ! profile_block_flag
0f33506c
RK
530 && (SYMBOL_REF_FLAG (op)
531 || op == XEXP (DECL_RTL (current_function_decl), 0)));
a6f12d7c
RK
532}
533
6bcf5f0a
RK
534/* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
535
536int
537call_operand (op, mode)
538 rtx op;
539 enum machine_mode mode;
540{
541 if (mode != Pmode)
542 return 0;
543
7e277025 544 return (GET_CODE (op) == SYMBOL_REF
89cfc2c6 545 || (GET_CODE (op) == REG && (TARGET_OPEN_VMS || REGNO (op) == 27)));
6bcf5f0a
RK
546}
547
a6f12d7c
RK
548/* Return 1 if OP is a valid Alpha comparison operator. Here we know which
549 comparisons are valid in which insn. */
550
551int
552alpha_comparison_operator (op, mode)
553 register rtx op;
554 enum machine_mode mode;
555{
556 enum rtx_code code = GET_CODE (op);
557
558 if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
559 return 0;
560
561 return (code == EQ || code == LE || code == LT
562 || (mode == DImode && (code == LEU || code == LTU)));
563}
564
5bf6c48a
RK
565/* Return 1 if OP is a valid Alpha swapped comparison operator. */
566
567int
568alpha_swapped_comparison_operator (op, mode)
569 register rtx op;
570 enum machine_mode mode;
571{
572 enum rtx_code code = GET_CODE (op);
573
574 if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
575 return 0;
576
577 code = swap_condition (code);
578 return (code == EQ || code == LE || code == LT
579 || (mode == DImode && (code == LEU || code == LTU)));
580}
581
a6f12d7c
RK
582/* Return 1 if OP is a signed comparison operation. */
583
584int
585signed_comparison_operator (op, mode)
586 register rtx op;
587 enum machine_mode mode;
588{
589 switch (GET_CODE (op))
590 {
591 case EQ: case NE: case LE: case LT: case GE: case GT:
592 return 1;
593 }
594
595 return 0;
596}
597
598/* Return 1 if this is a divide or modulus operator. */
599
600int
601divmod_operator (op, mode)
602 register rtx op;
603 enum machine_mode mode;
604{
605 switch (GET_CODE (op))
606 {
607 case DIV: case MOD: case UDIV: case UMOD:
608 return 1;
609 }
610
611 return 0;
612}
613
614/* Return 1 if this memory address is a known aligned register plus
615 a constant. It must be a valid address. This means that we can do
616 this as an aligned reference plus some offset.
617
618 Take into account what reload will do.
619
620 We could say that out-of-range stack slots are alignable, but that would
621 complicate get_aligned_mem and it isn't worth the trouble since few
622 functions have large stack space. */
623
624int
625aligned_memory_operand (op, mode)
626 register rtx op;
627 enum machine_mode mode;
628{
629 if (GET_CODE (op) == SUBREG)
630 {
631 if (GET_MODE (op) != mode)
632 return 0;
633 op = SUBREG_REG (op);
634 mode = GET_MODE (op);
635 }
636
637 if (reload_in_progress && GET_CODE (op) == REG
638 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
639 op = reg_equiv_mem[REGNO (op)];
640
641 if (GET_CODE (op) != MEM || GET_MODE (op) != mode
642 || ! memory_address_p (mode, XEXP (op, 0)))
643 return 0;
644
645 op = XEXP (op, 0);
646
647 if (GET_CODE (op) == PLUS)
648 op = XEXP (op, 0);
649
650 return (GET_CODE (op) == REG
adb18b68 651 && REGNO_POINTER_ALIGN (REGNO (op)) >= 4);
a6f12d7c
RK
652}
653
654/* Similar, but return 1 if OP is a MEM which is not alignable. */
655
656int
657unaligned_memory_operand (op, mode)
658 register rtx op;
659 enum machine_mode mode;
660{
661 if (GET_CODE (op) == SUBREG)
662 {
663 if (GET_MODE (op) != mode)
664 return 0;
665 op = SUBREG_REG (op);
666 mode = GET_MODE (op);
667 }
668
669 if (reload_in_progress && GET_CODE (op) == REG
670 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
671 op = reg_equiv_mem[REGNO (op)];
672
673 if (GET_CODE (op) != MEM || GET_MODE (op) != mode)
674 return 0;
675
676 op = XEXP (op, 0);
677
678 if (! memory_address_p (mode, op))
679 return 1;
680
681 if (GET_CODE (op) == PLUS)
682 op = XEXP (op, 0);
683
684 return (GET_CODE (op) != REG
adb18b68
RK
685 || REGNO_POINTER_ALIGN (REGNO (op)) < 4);
686}
687
688/* Return 1 if OP is either a register or an unaligned memory location. */
689
690int
691reg_or_unaligned_mem_operand (op, mode)
692 rtx op;
693 enum machine_mode mode;
694{
695 return register_operand (op, mode) || unaligned_memory_operand (op, mode);
a6f12d7c
RK
696}
697
698/* Return 1 if OP is any memory location. During reload a pseudo matches. */
699
700int
701any_memory_operand (op, mode)
702 register rtx op;
703 enum machine_mode mode;
704{
705 return (GET_CODE (op) == MEM
706 || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
707 || (reload_in_progress && GET_CODE (op) == REG
708 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
709 || (reload_in_progress && GET_CODE (op) == SUBREG
710 && GET_CODE (SUBREG_REG (op)) == REG
711 && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));
712}
713
714/* REF is an alignable memory location. Place an aligned SImode
715 reference into *PALIGNED_MEM and the number of bits to shift into
716 *PBITNUM. */
717
718void
719get_aligned_mem (ref, paligned_mem, pbitnum)
720 rtx ref;
721 rtx *paligned_mem, *pbitnum;
722{
723 rtx base;
724 HOST_WIDE_INT offset = 0;
725
726 if (GET_CODE (ref) == SUBREG)
727 {
728 offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
729 if (BYTES_BIG_ENDIAN)
730 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
731 - MIN (UNITS_PER_WORD,
732 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
733 ref = SUBREG_REG (ref);
734 }
735
736 if (GET_CODE (ref) == REG)
737 ref = reg_equiv_mem[REGNO (ref)];
738
739 if (reload_in_progress)
740 base = find_replacement (&XEXP (ref, 0));
741 else
742 base = XEXP (ref, 0);
743
744 if (GET_CODE (base) == PLUS)
745 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
746
747 *paligned_mem = gen_rtx (MEM, SImode,
748 plus_constant (base, offset & ~3));
749 MEM_IN_STRUCT_P (*paligned_mem) = MEM_IN_STRUCT_P (ref);
750 MEM_VOLATILE_P (*paligned_mem) = MEM_VOLATILE_P (ref);
751 RTX_UNCHANGING_P (*paligned_mem) = RTX_UNCHANGING_P (ref);
752
753 *pbitnum = GEN_INT ((offset & 3) * 8);
754}
755
adb18b68
RK
756/* Similar, but just get the address. Handle the two reload cases.
757 Add EXTRA_OFFSET to the address we return. */
a6f12d7c
RK
758
759rtx
adb18b68 760get_unaligned_address (ref, extra_offset)
a6f12d7c 761 rtx ref;
adb18b68 762 int extra_offset;
a6f12d7c
RK
763{
764 rtx base;
765 HOST_WIDE_INT offset = 0;
766
767 if (GET_CODE (ref) == SUBREG)
768 {
769 offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
770 if (BYTES_BIG_ENDIAN)
771 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
772 - MIN (UNITS_PER_WORD,
773 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
774 ref = SUBREG_REG (ref);
775 }
776
777 if (GET_CODE (ref) == REG)
778 ref = reg_equiv_mem[REGNO (ref)];
779
780 if (reload_in_progress)
781 base = find_replacement (&XEXP (ref, 0));
782 else
783 base = XEXP (ref, 0);
784
785 if (GET_CODE (base) == PLUS)
786 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
787
adb18b68 788 return plus_constant (base, offset + extra_offset);
a6f12d7c
RK
789}
790\f
791/* Subfunction of the following function. Update the flags of any MEM
792 found in part of X. */
793
794static void
795alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
796 rtx x;
797 int in_struct_p, volatile_p, unchanging_p;
798{
799 int i;
800
801 switch (GET_CODE (x))
802 {
803 case SEQUENCE:
804 case PARALLEL:
805 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
806 alpha_set_memflags_1 (XVECEXP (x, 0, i), in_struct_p, volatile_p,
807 unchanging_p);
808 break;
809
810 case INSN:
811 alpha_set_memflags_1 (PATTERN (x), in_struct_p, volatile_p,
812 unchanging_p);
813 break;
814
815 case SET:
816 alpha_set_memflags_1 (SET_DEST (x), in_struct_p, volatile_p,
817 unchanging_p);
818 alpha_set_memflags_1 (SET_SRC (x), in_struct_p, volatile_p,
819 unchanging_p);
820 break;
821
822 case MEM:
823 MEM_IN_STRUCT_P (x) = in_struct_p;
824 MEM_VOLATILE_P (x) = volatile_p;
825 RTX_UNCHANGING_P (x) = unchanging_p;
826 break;
827 }
828}
829
830/* Given INSN, which is either an INSN or a SEQUENCE generated to
831 perform a memory operation, look for any MEMs in either a SET_DEST or
832 a SET_SRC and copy the in-struct, unchanging, and volatile flags from
833 REF into each of the MEMs found. If REF is not a MEM, don't do
834 anything. */
835
836void
837alpha_set_memflags (insn, ref)
838 rtx insn;
839 rtx ref;
840{
841 /* Note that it is always safe to get these flags, though they won't
842 be what we think if REF is not a MEM. */
843 int in_struct_p = MEM_IN_STRUCT_P (ref);
844 int volatile_p = MEM_VOLATILE_P (ref);
845 int unchanging_p = RTX_UNCHANGING_P (ref);
846
847 if (GET_CODE (ref) != MEM
848 || (! in_struct_p && ! volatile_p && ! unchanging_p))
849 return;
850
851 alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
852}
853\f
854/* Try to output insns to set TARGET equal to the constant C if it can be
fd94addf
RK
855 done in less than N insns. Do all computations in MODE. Returns the place
856 where the output has been placed if it can be done and the insns have been
857 emitted. If it would take more than N insns, zero is returned and no
858 insns and emitted. */
a6f12d7c 859
fd94addf
RK
860rtx
861alpha_emit_set_const (target, mode, c, n)
a6f12d7c 862 rtx target;
fd94addf 863 enum machine_mode mode;
a6f12d7c
RK
864 HOST_WIDE_INT c;
865 int n;
9102cd1f
RK
866{
867 rtx pat;
868 int i;
869
870 /* Try 1 insn, then 2, then up to N. */
871 for (i = 1; i <= n; i++)
872 if ((pat = alpha_emit_set_const_1 (target, mode, c, i)) != 0)
873 return pat;
874
875 return 0;
876}
877
878/* Internal routine for the above to check for N or below insns. */
879
880static rtx
881alpha_emit_set_const_1 (target, mode, c, n)
882 rtx target;
883 enum machine_mode mode;
884 HOST_WIDE_INT c;
885 int n;
a6f12d7c
RK
886{
887 HOST_WIDE_INT new = c;
888 int i, bits;
fd94addf
RK
889 /* Use a pseudo if highly optimizing and still generating RTL. */
890 rtx subtarget
891 = (flag_expensive_optimizations && rtx_equal_function_value_matters
892 ? 0 : target);
893 rtx temp;
a6f12d7c
RK
894
895#if HOST_BITS_PER_WIDE_INT == 64
896 /* We are only called for SImode and DImode. If this is SImode, ensure that
897 we are sign extended to a full word. This does not make any sense when
898 cross-compiling on a narrow machine. */
899
fd94addf 900 if (mode == SImode)
a6f12d7c
RK
901 c = (c & 0xffffffff) - 2 * (c & 0x80000000);
902#endif
903
904 /* If this is a sign-extended 32-bit constant, we can do this in at most
905 three insns, so do it if we have enough insns left. We always have
0af3ee30
RK
906 a sign-extended 32-bit constant when compiling on a narrow machine.
907 Note that we cannot handle the constant 0x80000000. */
a6f12d7c 908
0af3ee30
RK
909 if ((HOST_BITS_PER_WIDE_INT != 64
910 || c >> 31 == -1 || c >> 31 == 0)
5c71c5b1 911 && c != 0x80000000U)
a6f12d7c
RK
912 {
913 HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
914 HOST_WIDE_INT tmp1 = c - low;
915 HOST_WIDE_INT high
916 = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
a6f12d7c
RK
917 HOST_WIDE_INT extra = 0;
918
ab034cfc
RK
919 /* If HIGH will be interpreted as negative but the constant is
920 positive, we must adjust it to do two ldha insns. */
921
922 if ((high & 0x8000) != 0 && c >= 0)
a6f12d7c
RK
923 {
924 extra = 0x4000;
925 tmp1 -= 0x40000000;
926 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
927 }
928
929 if (c == low || (low == 0 && extra == 0))
fd94addf 930 return copy_to_suggested_reg (GEN_INT (c), target, mode);
9102cd1f 931 else if (n >= 2 + (extra != 0))
a6f12d7c 932 {
fd94addf
RK
933 temp = copy_to_suggested_reg (GEN_INT (low), subtarget, mode);
934
a6f12d7c 935 if (extra != 0)
fd94addf
RK
936 temp = expand_binop (mode, add_optab, temp, GEN_INT (extra << 16),
937 subtarget, 0, OPTAB_WIDEN);
a6f12d7c 938
fd94addf
RK
939 return expand_binop (mode, add_optab, temp, GEN_INT (high << 16),
940 target, 0, OPTAB_WIDEN);
a6f12d7c
RK
941 }
942 }
943
0af3ee30 944 /* If we couldn't do it that way, try some other methods. But if we have
f444f304
RK
945 no instructions left, don't bother. Likewise, if this is SImode and
946 we can't make pseudos, we can't do anything since the expand_binop
947 and expand_unop calls will widen and try to make pseudos. */
a6f12d7c 948
f444f304
RK
949 if (n == 1
950 || (mode == SImode && ! rtx_equal_function_value_matters))
a6f12d7c
RK
951 return 0;
952
0af3ee30 953#if HOST_BITS_PER_WIDE_INT == 64
a6f12d7c
RK
954 /* First, see if can load a value into the target that is the same as the
955 constant except that all bytes that are 0 are changed to be 0xff. If we
956 can, then we can do a ZAPNOT to obtain the desired constant. */
957
958 for (i = 0; i < 64; i += 8)
959 if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
960 new |= (HOST_WIDE_INT) 0xff << i;
961
57cfde96
RK
962 /* We are only called for SImode and DImode. If this is SImode, ensure that
963 we are sign extended to a full word. */
964
965 if (mode == SImode)
966 new = (new & 0xffffffff) - 2 * (new & 0x80000000);
967
968 if (new != c
969 && (temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0)
fd94addf
RK
970 return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
971 target, 0, OPTAB_WIDEN);
0af3ee30 972#endif
a6f12d7c 973
0af3ee30 974 /* Next, see if we can load a related constant and then shift and possibly
a6f12d7c
RK
975 negate it to get the constant we want. Try this once each increasing
976 numbers of insns. */
977
978 for (i = 1; i < n; i++)
979 {
980 /* First try complementing. */
fd94addf
RK
981 if ((temp = alpha_emit_set_const (subtarget, mode, ~ c, i)) != 0)
982 return expand_unop (mode, one_cmpl_optab, temp, target, 0);
a6f12d7c 983
fd94addf 984 /* Next try to form a constant and do a left shift. We can do this
a6f12d7c
RK
985 if some low-order bits are zero; the exact_log2 call below tells
986 us that information. The bits we are shifting out could be any
987 value, but here we'll just try the 0- and sign-extended forms of
988 the constant. To try to increase the chance of having the same
989 constant in more than one insn, start at the highest number of
990 bits to shift, but try all possibilities in case a ZAPNOT will
991 be useful. */
992
993 if ((bits = exact_log2 (c & - c)) > 0)
994 for (; bits > 0; bits--)
0af3ee30
RK
995 if ((temp = (alpha_emit_set_const
996 (subtarget, mode,
997 (unsigned HOST_WIDE_INT) c >> bits, i))) != 0
fd94addf
RK
998 || ((temp = (alpha_emit_set_const
999 (subtarget, mode,
1000 ((unsigned HOST_WIDE_INT) c) >> bits, i)))
1001 != 0))
1002 return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
1003 target, 0, OPTAB_WIDEN);
a6f12d7c
RK
1004
1005 /* Now try high-order zero bits. Here we try the shifted-in bits as
57cfde96
RK
1006 all zero and all ones. Be careful to avoid shifting outside the
1007 mode and to avoid shifting outside the host wide int size. */
a6f12d7c 1008
57cfde96
RK
1009 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1010 - floor_log2 (c) - 1)) > 0)
a6f12d7c 1011 for (; bits > 0; bits--)
fd94addf
RK
1012 if ((temp = alpha_emit_set_const (subtarget, mode,
1013 c << bits, i)) != 0
1014 || ((temp = (alpha_emit_set_const
1015 (subtarget, mode,
1016 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1017 i)))
1018 != 0))
1019 return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
57cfde96 1020 target, 1, OPTAB_WIDEN);
a6f12d7c
RK
1021
1022 /* Now try high-order 1 bits. We get that with a sign-extension.
57cfde96
RK
1023 But one bit isn't enough here. Be careful to avoid shifting outside
1024 the mode and to avoid shifting outside the host wide int size. */
a6f12d7c 1025
57cfde96
RK
1026 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1027 - floor_log2 (~ c) - 2)) > 0)
a6f12d7c 1028 for (; bits > 0; bits--)
fd94addf
RK
1029 if ((temp = alpha_emit_set_const (subtarget, mode,
1030 c << bits, i)) != 0
1031 || ((temp = (alpha_emit_set_const
1032 (subtarget, mode,
1033 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1034 i)))
1035 != 0))
1036 return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
1037 target, 0, OPTAB_WIDEN);
a6f12d7c
RK
1038 }
1039
1040 return 0;
1041}
758d2c0c 1042
97aea203
RK
1043#if HOST_BITS_PER_WIDE_INT == 64
1044/* Having failed to find a 3 insn sequence in alpha_emit_set_const,
1045 fall back to a straight forward decomposition. We do this to avoid
1046 exponential run times encountered when looking for longer sequences
1047 with alpha_emit_set_const. */
1048
1049rtx
1050alpha_emit_set_long_const (target, c)
1051 rtx target;
1052 HOST_WIDE_INT c;
1053{
1054 /* Use a pseudo if highly optimizing and still generating RTL. */
1055 rtx subtarget
1056 = (flag_expensive_optimizations && rtx_equal_function_value_matters
1057 ? 0 : target);
1058 HOST_WIDE_INT d1, d2, d3, d4;
c3741733 1059 rtx r1, r2;
97aea203
RK
1060
1061 /* Decompose the entire word */
1062 d1 = ((c & 0xffff) ^ 0x8000) - 0x8000;
1063 c -= d1;
1064 d2 = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000;
1065 c = (c - d2) >> 32;
1066 d3 = ((c & 0xffff) ^ 0x8000) - 0x8000;
1067 c -= d3;
1068 d4 = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000;
1069
1070 if (c - d4 != 0)
1071 abort();
1072
1073 /* Construct the high word */
1074 if (d3 == 0)
c3741733 1075 r1 = copy_to_suggested_reg (GEN_INT (d4), subtarget, DImode);
97aea203 1076 else if (d4 == 0)
c3741733 1077 r1 = copy_to_suggested_reg (GEN_INT (d3), subtarget, DImode);
97aea203 1078 else
c3741733
RK
1079 r1 = expand_binop (DImode, add_optab, GEN_INT (d3), GEN_INT (d4),
1080 subtarget, 0, OPTAB_WIDEN);
97aea203
RK
1081
1082 /* Shift it into place */
c3741733
RK
1083 r2 = expand_binop (DImode, ashl_optab, r1, GEN_INT (32),
1084 subtarget, 0, OPTAB_WIDEN);
97aea203 1085
c3741733
RK
1086 if (subtarget == 0 && d1 == d3 && d2 == d4)
1087 r1 = expand_binop (DImode, add_optab, r1, r2, subtarget, 0, OPTAB_WIDEN);
1088 else
1089 {
1090 r1 = r2;
1091
1092 /* Add in the low word */
1093 if (d2 != 0)
1094 r1 = expand_binop (DImode, add_optab, r1, GEN_INT (d2),
1095 subtarget, 0, OPTAB_WIDEN);
1096 if (d1 != 0)
1097 r1 = expand_binop (DImode, add_optab, r1, GEN_INT (d1),
1098 subtarget, 0, OPTAB_WIDEN);
1099 }
97aea203
RK
1100
1101 if (subtarget == 0)
c3741733 1102 r1 = copy_to_suggested_reg(r1, target, DImode);
97aea203 1103
c3741733 1104 return r1;
97aea203
RK
1105}
1106#endif /* HOST_BITS_PER_WIDE_INT == 64 */
1107
758d2c0c
RK
1108/* Rewrite a comparison against zero CMP of the form
1109 (CODE (cc0) (const_int 0)) so it can be written validly in
1110 a conditional move (if_then_else CMP ...).
1111 If both of the operands that set cc0 are non-zero we must emit
1112 an insn to perform the compare (it can't be done within
1113 the conditional move). */
1114rtx
1115alpha_emit_conditional_move (cmp, mode)
1116 rtx cmp;
1117 enum machine_mode mode;
1118{
1ad2a62d 1119 enum rtx_code code = GET_CODE (cmp);
89b7c471 1120 enum rtx_code cmov_code = NE;
758d2c0c
RK
1121 rtx op0 = alpha_compare_op0;
1122 rtx op1 = alpha_compare_op1;
1ad2a62d
RK
1123 enum machine_mode cmp_mode
1124 = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
1125 enum machine_mode cmp_op_mode = alpha_compare_fp_p ? DFmode : DImode;
1126 rtx tem;
758d2c0c 1127
1ad2a62d 1128 if (alpha_compare_fp_p != FLOAT_MODE_P (mode))
758d2c0c
RK
1129 return 0;
1130
1131 /* We may be able to use a conditional move directly.
1132 This avoids emitting spurious compares. */
1ad2a62d
RK
1133 if (signed_comparison_operator (cmp, cmp_op_mode)
1134 && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
1135 return gen_rtx (code, VOIDmode, op0, op1);
758d2c0c
RK
1136
1137 /* We can't put the comparison insides a conditional move;
1138 emit a compare instruction and put that inside the
1ad2a62d
RK
1139 conditional move. Make sure we emit only comparisons we have;
1140 swap or reverse as necessary. */
758d2c0c 1141
758d2c0c
RK
1142 switch (code)
1143 {
1ad2a62d
RK
1144 case EQ: case LE: case LT: case LEU: case LTU:
1145 /* We have these compares: */
758d2c0c 1146 break;
1ad2a62d 1147
758d2c0c 1148 case NE:
1ad2a62d
RK
1149 /* This must be reversed. */
1150 code = reverse_condition (code);
89b7c471 1151 cmov_code = EQ;
758d2c0c 1152 break;
1ad2a62d
RK
1153
1154 case GE: case GT: case GEU: case GTU:
1155 /* These must be swapped. Make sure the new first operand is in
1156 a register. */
1157 code = swap_condition (code);
1158 tem = op0, op0 = op1, op1 = tem;
1159 op0 = force_reg (cmp_mode, op0);
758d2c0c 1160 break;
1ad2a62d 1161
758d2c0c 1162 default:
1ad2a62d 1163 abort ();
758d2c0c
RK
1164 }
1165
1ad2a62d
RK
1166 tem = gen_reg_rtx (cmp_op_mode);
1167 emit_move_insn (tem, gen_rtx (code, cmp_op_mode, op0, op1));
89b7c471 1168 return gen_rtx (cmov_code, VOIDmode, tem, CONST0_RTX (cmp_op_mode));
758d2c0c 1169}
a6f12d7c
RK
1170\f
1171/* Adjust the cost of a scheduling dependency. Return the new cost of
1172 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
1173
1174int
1175alpha_adjust_cost (insn, link, dep_insn, cost)
1176 rtx insn;
1177 rtx link;
1178 rtx dep_insn;
1179 int cost;
1180{
74835ed8 1181 rtx set, set_src;
a6f12d7c
RK
1182
1183 /* If the dependence is an anti-dependence, there is no cost. For an
1184 output dependence, there is sometimes a cost, but it doesn't seem
1185 worth handling those few cases. */
1186
1187 if (REG_NOTE_KIND (link) != 0)
1188 return 0;
1189
da792a68
RK
1190 if (alpha_cpu == PROCESSOR_EV5)
1191 {
74835ed8
RH
1192 /* On EV5, "A special bypass provides an effective latency of 0
1193 cycles for an ICMP or ILOG insn producing the test operand of an
1194 IBR or CMOV insn." */
1195
da792a68
RK
1196 if (recog_memoized (dep_insn) >= 0
1197 && (get_attr_type (dep_insn) == TYPE_ICMP
1198 || get_attr_type (dep_insn) == TYPE_ILOG)
1199 && recog_memoized (insn) >= 0
1200 && (get_attr_type (insn) == TYPE_IBR
1201 || (get_attr_type (insn) == TYPE_CMOV
1202 && !((set = single_set (dep_insn)) != 0
1203 && GET_CODE (PATTERN (insn)) == SET
74835ed8
RH
1204 && (set_src = SET_SRC (PATTERN (insn)),
1205 GET_CODE (set_src) == IF_THEN_ELSE)
1206 && (set = SET_DEST (set),
1207 rtx_equal_p (set, XEXP (set_src, 1))
1208 || rtx_equal_p (set, XEXP (set_src, 2)))))))
1209 return 0;
1210
1211 /* On EV5 it takes longer to get data to the multiplier than to
1212 anywhere else, so increase costs. */
1213
1214 if (recog_memoized (insn) >= 0
1215 && recog_memoized (dep_insn) >= 0
1216 && (get_attr_type (insn) == TYPE_IMULL
1217 || get_attr_type (insn) == TYPE_IMULQ
1218 || get_attr_type (insn) == TYPE_IMULH)
1219 && (set = single_set (dep_insn)) != 0
1220 && GET_CODE (PATTERN (insn)) == SET
1221 && (set_src = SET_SRC (PATTERN (insn)),
1222 GET_CODE (set_src) == MULT)
1223 && (set = SET_DEST (set),
1224 rtx_equal_p (set, XEXP (set_src, 0))
1225 || rtx_equal_p (set, XEXP (set_src, 1))))
1226 {
1227 switch (get_attr_type (insn))
1228 {
1229 case TYPE_LD:
1230 case TYPE_CMOV:
1231 case TYPE_IMULL:
1232 case TYPE_IMULQ:
1233 case TYPE_IMULH:
1234 return cost + 1;
1235 case TYPE_JSR:
1236 case TYPE_IADD:
1237 case TYPE_ILOG:
1238 case TYPE_SHIFT:
1239 case TYPE_ICMP:
1240 return cost + 2;
1241 }
1242 }
1243 }
1244 else
1245 {
1246 /* On EV4, if INSN is a store insn and DEP_INSN is setting the data
1247 being stored, we can sometimes lower the cost. */
1248
1249 if (recog_memoized (insn) >= 0 && get_attr_type (insn) == TYPE_ST
1250 && (set = single_set (dep_insn)) != 0
1251 && GET_CODE (PATTERN (insn)) == SET
1252 && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
1253 {
1254 switch (get_attr_type (dep_insn))
1255 {
1256 case TYPE_LD:
1257 /* No savings here. */
1258 return cost;
1259
1260 case TYPE_IMULL:
1261 case TYPE_IMULQ:
1262 case TYPE_IMULH:
1263 /* In these cases, we save one cycle. */
1264 return cost - 1;
1265
1266 default:
1267 /* In all other cases, we save two cycles. */
1268 return MAX (0, cost - 2);
1269 }
1270 }
1271
1272 /* Another case that needs adjustment is an arithmetic or logical
1273 operation. It's cost is usually one cycle, but we default it to
1274 two in the MD file. The only case that it is actually two is
1275 for the address in loads and stores. */
1276
1277 if (recog_memoized (dep_insn) >= 0
1278 && (get_attr_type (dep_insn) == TYPE_IADD
1279 || get_attr_type (dep_insn) == TYPE_ILOG))
1280 {
1281 switch (get_attr_type (insn))
1282 {
1283 case TYPE_LD:
1284 case TYPE_ST:
1285 return cost;
1286 default:
1287 return 1;
1288 }
1289 }
1290
1291 /* The final case is when a compare feeds into an integer branch;
1292 the cost is only one cycle in that case. */
1293
1294 if (recog_memoized (dep_insn) >= 0
1295 && get_attr_type (dep_insn) == TYPE_ICMP
1296 && recog_memoized (insn) >= 0
1297 && get_attr_type (insn) == TYPE_IBR)
da792a68 1298 return 1;
74835ed8 1299 }
a6f12d7c
RK
1300
1301 /* Otherwise, return the default cost. */
a6f12d7c
RK
1302 return cost;
1303}
9ecc37f0
RH
1304\f
1305/* Functions to save and restore alpha_return_addr_rtx. */
1306
1307struct machine_function
1308{
1309 rtx ra_rtx;
1310};
1311
1312static void
1313alpha_save_machine_status (p)
1314 struct function *p;
1315{
1316 struct machine_function *machine =
1317 (struct machine_function *) xmalloc (sizeof (struct machine_function));
1318
1319 p->machine = machine;
1320 machine->ra_rtx = alpha_return_addr_rtx;
1321}
1322
1323static void
1324alpha_restore_machine_status (p)
1325 struct function *p;
1326{
1327 struct machine_function *machine = p->machine;
1328
1329 alpha_return_addr_rtx = machine->ra_rtx;
1330
1331 free (machine);
1332 p->machine = (struct machine_function *)0;
1333}
1334
1335/* Do anything needed before RTL is emitted for each function. */
1336
1337void
1338alpha_init_expanders ()
1339{
1340 alpha_return_addr_rtx = NULL_RTX;
1341
1342 /* Arrange to save and restore machine status around nested functions. */
1343 save_machine_status = alpha_save_machine_status;
1344 restore_machine_status = alpha_restore_machine_status;
1345}
1346
1347/* Start the ball rolling with RETURN_ADDR_RTX. */
1348
1349rtx
1350alpha_return_addr (count, frame)
1351 int count;
1352 rtx frame;
1353{
1354 rtx init, first;
1355
1356 if (count != 0)
1357 return const0_rtx;
1358
1359 if (alpha_return_addr_rtx)
1360 return alpha_return_addr_rtx;
1361
1362 /* No rtx yet. Invent one, and initialize it from $26 in the prologue. */
1363 alpha_return_addr_rtx = gen_reg_rtx (Pmode);
1364 init = gen_rtx (SET, Pmode, alpha_return_addr_rtx, gen_rtx (REG, Pmode, 26));
1365
1366 /* Emit the insn to the prologue with the other argument copies. */
1367 push_topmost_sequence ();
1368 emit_insn_after (init, get_insns ());
1369 pop_topmost_sequence ();
1370
1371 return alpha_return_addr_rtx;
1372}
1373
1374static int
1375alpha_ra_ever_killed ()
1376{
1377 rtx i, ra;
1378
1379 if (!alpha_return_addr_rtx)
1380 return regs_ever_live[REG_RA];
1381
1382 return reg_set_between_p (gen_rtx (REG, REG_RA), get_insns(), NULL_RTX);
1383}
1384
a6f12d7c
RK
1385\f
1386/* Print an operand. Recognize special options, documented below. */
1387
1388void
1389print_operand (file, x, code)
1390 FILE *file;
1391 rtx x;
1392 char code;
1393{
1394 int i;
1395
1396 switch (code)
1397 {
6245e3df
RK
1398 case '&':
1399 /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
1400 chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
1401 mode. alpha_fprm controls which suffix is generated. */
1402 switch (alpha_fprm)
1403 {
1404 case ALPHA_FPRM_NORM:
1405 break;
1406 case ALPHA_FPRM_MINF:
1407 fputc ('m', file);
1408 break;
1409 case ALPHA_FPRM_CHOP:
1410 fputc ('c', file);
1411 break;
1412 case ALPHA_FPRM_DYN:
1413 fputc ('d', file);
1414 break;
1415 }
1416 break;
1417
1418 case '\'':
1419 /* Generates trap-mode suffix for instructions that accept the su
1420 suffix only (cmpt et al). */
1421 if (alpha_tp == ALPHA_TP_INSN)
1422 fputs ("su", file);
1423 break;
1424
1425 case ')':
1426 /* Generates trap-mode suffix for instructions that accept the u, su,
1427 and sui suffix. This is the bulk of the IEEE floating point
1428 instructions (addt et al). */
1429 switch (alpha_fptm)
1430 {
1431 case ALPHA_FPTM_N:
1432 break;
1433 case ALPHA_FPTM_U:
1434 fputc ('u', file);
1435 break;
1436 case ALPHA_FPTM_SU:
1437 fputs ("su", file);
1438 break;
1439 case ALPHA_FPTM_SUI:
1440 fputs ("sui", file);
1441 break;
1442 }
1443 break;
1444
1445 case '+':
1446 /* Generates trap-mode suffix for instructions that accept the sui
1447 suffix (cvtqt and cvtqs). */
1448 switch (alpha_fptm)
1449 {
1450 case ALPHA_FPTM_N: case ALPHA_FPTM_U:
1451 case ALPHA_FPTM_SU: /* cvtqt/cvtqs can't cause underflow */
1452 break;
1453 case ALPHA_FPTM_SUI:
1454 fputs ("sui", file);
1455 break;
1456 }
1457 break;
1458
89cfc2c6
RK
1459 case ',':
1460 /* Generates single precision instruction suffix. */
e9a25f70 1461 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'f' : 's'));
89cfc2c6
RK
1462 break;
1463
1464 case '-':
1465 /* Generates double precision instruction suffix. */
e9a25f70 1466 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'g' : 't'));
89cfc2c6
RK
1467 break;
1468
a6f12d7c
RK
1469 case 'r':
1470 /* If this operand is the constant zero, write it as "$31". */
1471 if (GET_CODE (x) == REG)
1472 fprintf (file, "%s", reg_names[REGNO (x)]);
1473 else if (x == CONST0_RTX (GET_MODE (x)))
1474 fprintf (file, "$31");
1475 else
1476 output_operand_lossage ("invalid %%r value");
1477
1478 break;
1479
1480 case 'R':
1481 /* Similar, but for floating-point. */
1482 if (GET_CODE (x) == REG)
1483 fprintf (file, "%s", reg_names[REGNO (x)]);
1484 else if (x == CONST0_RTX (GET_MODE (x)))
1485 fprintf (file, "$f31");
1486 else
1487 output_operand_lossage ("invalid %%R value");
1488
1489 break;
1490
1491 case 'N':
1492 /* Write the 1's complement of a constant. */
1493 if (GET_CODE (x) != CONST_INT)
1494 output_operand_lossage ("invalid %%N value");
1495
0bc8ae6e 1496 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
a6f12d7c
RK
1497 break;
1498
1499 case 'P':
1500 /* Write 1 << C, for a constant C. */
1501 if (GET_CODE (x) != CONST_INT)
1502 output_operand_lossage ("invalid %%P value");
1503
0bc8ae6e 1504 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
a6f12d7c
RK
1505 break;
1506
1507 case 'h':
1508 /* Write the high-order 16 bits of a constant, sign-extended. */
1509 if (GET_CODE (x) != CONST_INT)
1510 output_operand_lossage ("invalid %%h value");
1511
0bc8ae6e 1512 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
a6f12d7c
RK
1513 break;
1514
1515 case 'L':
1516 /* Write the low-order 16 bits of a constant, sign-extended. */
1517 if (GET_CODE (x) != CONST_INT)
1518 output_operand_lossage ("invalid %%L value");
1519
0bc8ae6e
RK
1520 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
1521 (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
a6f12d7c
RK
1522 break;
1523
1524 case 'm':
1525 /* Write mask for ZAP insn. */
1526 if (GET_CODE (x) == CONST_DOUBLE)
1527 {
1528 HOST_WIDE_INT mask = 0;
1529 HOST_WIDE_INT value;
1530
1531 value = CONST_DOUBLE_LOW (x);
1532 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
1533 i++, value >>= 8)
1534 if (value & 0xff)
1535 mask |= (1 << i);
1536
1537 value = CONST_DOUBLE_HIGH (x);
1538 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
1539 i++, value >>= 8)
1540 if (value & 0xff)
1541 mask |= (1 << (i + sizeof (int)));
1542
0bc8ae6e 1543 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
a6f12d7c
RK
1544 }
1545
1546 else if (GET_CODE (x) == CONST_INT)
1547 {
1548 HOST_WIDE_INT mask = 0, value = INTVAL (x);
1549
1550 for (i = 0; i < 8; i++, value >>= 8)
1551 if (value & 0xff)
1552 mask |= (1 << i);
1553
0bc8ae6e 1554 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
a6f12d7c
RK
1555 }
1556 else
1557 output_operand_lossage ("invalid %%m value");
1558 break;
1559
1560 case 'M':
1561 /* 'b', 'w', or 'l' as the value of the constant. */
1562 if (GET_CODE (x) != CONST_INT
1563 || (INTVAL (x) != 8 && INTVAL (x) != 16 && INTVAL (x) != 32))
1564 output_operand_lossage ("invalid %%M value");
1565
1566 fprintf (file, "%s",
1567 INTVAL (x) == 8 ? "b" : INTVAL (x) == 16 ? "w" : "l");
1568 break;
1569
1570 case 'U':
1571 /* Similar, except do it from the mask. */
1572 if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
1573 fprintf (file, "b");
1574 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
1575 fprintf (file, "w");
1576#if HOST_BITS_PER_WIDE_INT == 32
1577 else if (GET_CODE (x) == CONST_DOUBLE
1578 && CONST_DOUBLE_HIGH (x) == 0
1579 && CONST_DOUBLE_LOW (x) == -1)
1580 fprintf (file, "l");
1581#else
1582 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
1583 fprintf (file, "l");
1584#endif
1585 else
1586 output_operand_lossage ("invalid %%U value");
1587 break;
1588
1589 case 's':
1590 /* Write the constant value divided by 8. */
1591 if (GET_CODE (x) != CONST_INT
1592 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
1593 && (INTVAL (x) & 7) != 8)
1594 output_operand_lossage ("invalid %%s value");
1595
0bc8ae6e 1596 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
a6f12d7c
RK
1597 break;
1598
1599 case 'S':
1600 /* Same, except compute (64 - c) / 8 */
1601
1602 if (GET_CODE (x) != CONST_INT
1603 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
1604 && (INTVAL (x) & 7) != 8)
1605 output_operand_lossage ("invalid %%s value");
1606
0bc8ae6e 1607 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
a6f12d7c
RK
1608 break;
1609
bdd4c95a 1610 case 'C': case 'D': case 'c': case 'd':
a6f12d7c 1611 /* Write out comparison name. */
bdd4c95a
RK
1612 {
1613 enum rtx_code c = GET_CODE (x);
1614
1615 if (GET_RTX_CLASS (c) != '<')
1616 output_operand_lossage ("invalid %%C value");
1617
1618 if (code == 'D')
1619 c = reverse_condition (c);
1620 else if (code == 'c')
1621 c = swap_condition (c);
1622 else if (code == 'd')
1623 c = swap_condition (reverse_condition (c));
1624
1625 if (c == LEU)
1626 fprintf (file, "ule");
1627 else if (c == LTU)
1628 fprintf (file, "ult");
1629 else
1630 fprintf (file, "%s", GET_RTX_NAME (c));
1631 }
ab561e66
RK
1632 break;
1633
a6f12d7c
RK
1634 case 'E':
1635 /* Write the divide or modulus operator. */
1636 switch (GET_CODE (x))
1637 {
1638 case DIV:
1639 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
1640 break;
1641 case UDIV:
1642 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
1643 break;
1644 case MOD:
1645 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
1646 break;
1647 case UMOD:
1648 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
1649 break;
1650 default:
1651 output_operand_lossage ("invalid %%E value");
1652 break;
1653 }
1654 break;
1655
a6f12d7c
RK
1656 case 'A':
1657 /* Write "_u" for unaligned access. */
1658 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
1659 fprintf (file, "_u");
1660 break;
1661
1662 case 0:
1663 if (GET_CODE (x) == REG)
1664 fprintf (file, "%s", reg_names[REGNO (x)]);
1665 else if (GET_CODE (x) == MEM)
1666 output_address (XEXP (x, 0));
1667 else
1668 output_addr_const (file, x);
1669 break;
1670
1671 default:
1672 output_operand_lossage ("invalid %%xn code");
1673 }
1674}
1675\f
1676/* Do what is necessary for `va_start'. The argument is ignored;
937868a2 1677 We look at the current function to determine if stdarg or varargs
a6f12d7c
RK
1678 is used and fill in an initial va_list. A pointer to this constructor
1679 is returned. */
1680
1681struct rtx_def *
1682alpha_builtin_saveregs (arglist)
1683 tree arglist;
1684{
5b838011 1685 rtx block, addr, dest, argsize;
a6f12d7c 1686 tree fntype = TREE_TYPE (current_function_decl);
937868a2
RK
1687 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1688 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1689 != void_type_node));
a6f12d7c 1690
0f33506c 1691 /* Compute the current position into the args, taking into account
29587b1c 1692 both registers and memory. Both of these are already included in
e9a25f70 1693 NUM_ARGS. */
a6f12d7c 1694
e9a25f70 1695 argsize = GEN_INT (NUM_ARGS * UNITS_PER_WORD);
29587b1c 1696
89cfc2c6 1697 /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base up by 48,
29587b1c
JW
1698 storing fp arg registers in the first 48 bytes, and the integer arg
1699 registers in the next 48 bytes. This is only done, however, if any
1700 integer registers need to be stored.
1701
1702 If no integer registers need be stored, then we must subtract 48 in
1703 order to account for the integer arg registers which are counted in
1704 argsize above, but which are not actually stored on the stack. */
1705
89cfc2c6
RK
1706 if (TARGET_OPEN_VMS)
1707 addr = plus_constant (virtual_incoming_args_rtx,
e9a25f70 1708 NUM_ARGS <= 5 + stdarg
89cfc2c6
RK
1709 ? UNITS_PER_WORD : - 6 * UNITS_PER_WORD);
1710 else
e9a25f70 1711 addr = (NUM_ARGS <= 5 + stdarg
89cfc2c6
RK
1712 ? plus_constant (virtual_incoming_args_rtx,
1713 6 * UNITS_PER_WORD)
1714 : plus_constant (virtual_incoming_args_rtx,
1715 - (6 * UNITS_PER_WORD)));
1d783d31 1716
89cfc2c6
RK
1717 /* For VMS, we include the argsize, while on Unix, it's handled as
1718 a separate field. */
1719 if (TARGET_OPEN_VMS)
1720 addr = plus_constant (addr, INTVAL (argsize));
a6f12d7c 1721
89cfc2c6 1722 addr = force_operand (addr, NULL_RTX);
1d783d31
RK
1723
1724#ifdef POINTERS_EXTEND_UNSIGNED
1725 addr = convert_memory_address (ptr_mode, addr);
1726#endif
1727
89cfc2c6
RK
1728 if (TARGET_OPEN_VMS)
1729 return addr;
1730 else
1731 {
1732 /* Allocate the va_list constructor */
1733 block = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
1734 RTX_UNCHANGING_P (block) = 1;
1735 RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
1736
1737 /* Store the address of the first integer register in the __base
1738 member. */
1739
5b838011
RK
1740 dest = change_address (block, ptr_mode, XEXP (block, 0));
1741 emit_move_insn (dest, addr);
89cfc2c6 1742
5b838011
RK
1743 if (flag_check_memory_usage)
1744 emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3, dest,
1745 ptr_mode, GEN_INT (GET_MODE_SIZE (ptr_mode)),
1746 TYPE_MODE (sizetype),
1747 GEN_INT (MEMORY_USE_RW), QImode);
1748
89cfc2c6 1749 /* Store the argsize as the __va_offset member. */
5b838011
RK
1750 dest = change_address (block, TYPE_MODE (integer_type_node),
1751 plus_constant (XEXP (block, 0),
1752 POINTER_SIZE/BITS_PER_UNIT));
1753 emit_move_insn (dest, argsize);
1754
1755 if (flag_check_memory_usage)
1756 emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3, dest,
1757 ptr_mode,
1758 GEN_INT (GET_MODE_SIZE
1759 (TYPE_MODE (integer_type_node))),
1760 TYPE_MODE (sizetype),
1761 GEN_INT (MEMORY_USE_RW), QImode);
89cfc2c6
RK
1762
1763 /* Return the address of the va_list constructor, but don't put it in a
1764 register. Doing so would fail when not optimizing and produce worse
1765 code when optimizing. */
1766 return XEXP (block, 0);
1767 }
a6f12d7c
RK
1768}
1769\f
e9a25f70
JL
1770#if OPEN_VMS
1771#define REG_PV 27
1772#define REG_RA 26
1773#else
1774#define REG_RA 26
1775#endif
1776
1777/* Find the current function's return address.
1778
1779 ??? It would be better to arrange things such that if we would ordinarily
1780 have been a leaf function and we didn't spill the hard reg that we
1781 wouldn't have to save the register in the prolog. But it's not clear
1782 how to get the right information at the right time. */
1783
1784static rtx alpha_return_addr_rtx;
1785
1786rtx
1787alpha_return_addr ()
1788{
1789 rtx ret;
1790
1791 if ((ret = alpha_return_addr_rtx) == NULL)
1792 {
1793 alpha_return_addr_rtx = ret = gen_reg_rtx (Pmode);
1794
1795 emit_insn_after (gen_rtx (SET, VOIDmode, ret,
1796 gen_rtx (REG, Pmode, REG_RA)),
1797 get_insns ());
1798 }
1799
1800 return ret;
1801}
1802
a6f12d7c
RK
1803/* This page contains routines that are used to determine what the function
1804 prologue and epilogue code will do and write them out. */
1805
1806/* Compute the size of the save area in the stack. */
1807
89cfc2c6
RK
1808#if OPEN_VMS
1809
89cfc2c6
RK
1810/* These variables are used for communication between the following functions.
1811 They indicate various things about the current function being compiled
1812 that are used to tell what kind of prologue, epilogue and procedure
1813 descriptior to generate. */
1814
1815/* Nonzero if we need a stack procedure. */
1816static int is_stack_procedure;
1817
1818/* Register number (either FP or SP) that is used to unwind the frame. */
1819static int unwind_regno;
1820
1821/* Register number used to save FP. We need not have one for RA since
1822 we don't modify it for register procedures. This is only defined
1823 for register frame procedures. */
1824static int save_fp_regno;
1825
1826/* Register number used to reference objects off our PV. */
1827static int base_regno;
1828
1829/* Compute register masks for saved registers. */
1830
1831static void
1832alpha_sa_mask (imaskP, fmaskP)
1833 unsigned long *imaskP;
1834 unsigned long *fmaskP;
1835{
1836 unsigned long imask = 0;
1837 unsigned long fmask = 0;
1838 int i;
1839
1840 if (is_stack_procedure)
1841 imask |= (1L << HARD_FRAME_POINTER_REGNUM);
1842
1843 /* One for every register we have to save. */
1844
1845 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
9ecc37f0
RH
1846 if (! fixed_regs[i] && ! call_used_regs[i]
1847 && regs_ever_live[i] && i != REG_RA)
89cfc2c6
RK
1848 {
1849 if (i < 32)
1850 imask |= (1L << i);
1851 else
1852 fmask |= (1L << (i - 32));
1853 }
1854
1855 *imaskP = imask;
1856 *fmaskP = fmask;
1857
1858 return;
1859}
1860
1861int
1862alpha_sa_size ()
1863{
1864 int sa_size = 0;
1865 HOST_WIDE_INT stack_needed;
1866 int i;
1867
1868 /* One for every register we have to save. */
1869
1870 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
9ecc37f0
RH
1871 if (! fixed_regs[i] && ! call_used_regs[i]
1872 && regs_ever_live[i] && i != REG_RA)
89cfc2c6
RK
1873 sa_size++;
1874
1875 /* Start by assuming we can use a register procedure if we don't make any
1876 calls (REG_RA not used) or need to save any registers and a stack
1877 procedure if we do. */
9ecc37f0 1878 is_stack_procedure = sa_size != 0 || alpha_ra_ever_killed ();
89cfc2c6
RK
1879
1880 /* Decide whether to refer to objects off our PV via FP or PV.
1881 If we need need FP for something else or if we receive a nonlocal
1882 goto (which expects PV to contain the value), we must use PV.
1883 Otherwise, start by assuming we can use FP. */
1884 base_regno = (frame_pointer_needed || current_function_has_nonlocal_label
1885 || is_stack_procedure
1886 || current_function_outgoing_args_size
1887 ? REG_PV : HARD_FRAME_POINTER_REGNUM);
1888
1889 /* If we want to copy PV into FP, we need to find some register in which to
1890 save FP. */
1891
1892 save_fp_regno = -1;
1893
1894 if (base_regno == HARD_FRAME_POINTER_REGNUM)
1895 for (i = 0; i < 32; i++)
1896 if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
1897 save_fp_regno = i;
1898
1899 if (save_fp_regno == -1)
1900 base_regno = REG_PV, is_stack_procedure = 1;
1901
1902 /* Stack unwinding should be done via FP unless we use it for PV. */
1903 unwind_regno
1904 = base_regno == REG_PV ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM;
1905
1906 /* If this is a stack procedure, allow space for saving FP and RA. */
1907 if (is_stack_procedure)
1908 sa_size += 2;
1909
1910 return sa_size * 8;
1911}
1912
1913int
1914alpha_pv_save_size ()
1915{
1916 alpha_sa_size ();
1917 return is_stack_procedure ? 8 : 0;
1918}
1919
1920int
1921alpha_using_fp ()
1922{
1923 alpha_sa_size ();
1924 return unwind_regno == HARD_FRAME_POINTER_REGNUM;
1925}
1926
1927#else /* ! OPEN_VMS */
1928
a6f12d7c
RK
1929int
1930alpha_sa_size ()
1931{
1932 int size = 0;
1933 int i;
1934
1935 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
9ecc37f0
RH
1936 if (! fixed_regs[i] && ! call_used_regs[i]
1937 && regs_ever_live[i] && i != REG_RA)
a6f12d7c
RK
1938 size++;
1939
c97e3db7
RK
1940 /* If some registers were saved but not reg 26, reg 26 must also
1941 be saved, so leave space for it. */
9ecc37f0 1942 if (size != 0 || alpha_ra_ever_killed ())
0f33506c 1943 size++;
a6f12d7c 1944
d60a05a1
RK
1945 /* Our size must be even (multiple of 16 bytes). */
1946 if (size & 1)
1947 size ++;
1948
0f33506c 1949 return size * 8;
a6f12d7c
RK
1950}
1951
89cfc2c6
RK
1952#endif /* ! OPEN_VMS */
1953
a6f12d7c
RK
1954/* Return 1 if this function can directly return via $26. */
1955
1956int
1957direct_return ()
1958{
89cfc2c6 1959 return (! TARGET_OPEN_VMS && reload_completed && alpha_sa_size () == 0
a6f12d7c 1960 && get_frame_size () == 0
f13703f9 1961 && current_function_outgoing_args_size == 0
a6f12d7c
RK
1962 && current_function_pretend_args_size == 0);
1963}
1964
0f33506c
RK
1965/* Write a version stamp. Don't write anything if we are running as a
1966 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
1967
89cfc2c6 1968#if !defined(CROSS_COMPILE) && !defined(_WIN32) && !defined(__linux__) && !defined(VMS)
0f33506c
RK
1969#include <stamp.h>
1970#endif
1971
1972void
1973alpha_write_verstamp (file)
1974 FILE *file;
1975{
1976#ifdef MS_STAMP
aec4ca5e 1977 fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
0f33506c
RK
1978#endif
1979}
ec6840c1
RK
1980\f
1981/* Write code to add constant C to register number IN_REG (possibly 31)
d60a05a1
RK
1982 and put the result into OUT_REG. Use TEMP_REG as a scratch register;
1983 usually this will be OUT_REG, but should not be if OUT_REG is
1984 STACK_POINTER_REGNUM, since it must be updated in a single instruction.
1985 Write the code to FILE. */
ec6840c1
RK
1986
1987static void
d60a05a1 1988add_long_const (file, c, in_reg, out_reg, temp_reg)
ec6840c1 1989 FILE *file;
d60a05a1
RK
1990 HOST_WIDE_INT c;
1991 int in_reg, out_reg, temp_reg;
ec6840c1
RK
1992{
1993 HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
1994 HOST_WIDE_INT tmp1 = c - low;
1995 HOST_WIDE_INT high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1996 HOST_WIDE_INT extra = 0;
1997
1998 /* We don't have code to write out constants larger than 32 bits. */
1999#if HOST_BITS_PER_LONG_INT == 64
2000 if ((unsigned HOST_WIDE_INT) c >> 32 != 0)
2001 abort ();
2002#endif
2003
2004 /* If HIGH will be interpreted as negative, we must adjust it to do two
2005 ldha insns. Note that we will never be building a negative constant
2006 here. */
2007
2008 if (high & 0x8000)
2009 {
2010 extra = 0x4000;
2011 tmp1 -= 0x40000000;
2012 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
2013 }
2014
2015 if (low != 0)
2016 {
d60a05a1
RK
2017 int result_reg = (extra == 0 && high == 0) ? out_reg : temp_reg;
2018
ec6840c1 2019 if (low >= 0 && low < 255)
d60a05a1 2020 fprintf (file, "\taddq $%d,%d,$%d\n", in_reg, low, result_reg);
ec6840c1 2021 else
d60a05a1
RK
2022 fprintf (file, "\tlda $%d,%d($%d)\n", result_reg, low, in_reg);
2023
2024 in_reg = result_reg;
ec6840c1
RK
2025 }
2026
2027 if (extra)
2028 {
d60a05a1
RK
2029 int result_reg = (high == 0) ? out_reg : temp_reg;
2030
2031 fprintf (file, "\tldah $%d,%d($%d)\n", result_reg, extra, in_reg);
2032 in_reg = result_reg;
ec6840c1
RK
2033 }
2034
2035 if (high)
2036 fprintf (file, "\tldah $%d,%d($%d)\n", out_reg, high, in_reg);
2037}
0f33506c 2038
a6f12d7c
RK
2039/* Write function prologue. */
2040
89cfc2c6
RK
2041#if OPEN_VMS
2042
89cfc2c6
RK
2043/* On vms we have two kinds of functions:
2044
2045 - stack frame (PROC_STACK)
2046 these are 'normal' functions with local vars and which are
2047 calling other functions
2048 - register frame (PROC_REGISTER)
2049 keeps all data in registers, needs no stack
2050
2051 We must pass this to the assembler so it can generate the
2052 proper pdsc (procedure descriptor)
2053 This is done with the '.pdesc' command.
2054
2055 size is the stack size needed for local variables. */
2056
2057void
2058output_prolog (file, size)
2059 FILE *file;
44afaf6d 2060 HOST_WIDE_INT size;
89cfc2c6
RK
2061{
2062 unsigned long imask = 0;
2063 unsigned long fmask = 0;
2064 /* Stack space needed for pushing registers clobbered by us. */
2065 HOST_WIDE_INT sa_size;
2066 /* Complete stack size needed. */
2067 HOST_WIDE_INT frame_size;
2068 /* Offset from base reg to register save area. */
2069 int rsa_offset = 8;
2070 /* Offset during register save. */
2071 int reg_offset;
2072 /* Label for the procedure entry. */
a3b0df2d 2073 char *entry_label = (char *) alloca (strlen (alpha_function_name) + 5);
89cfc2c6
RK
2074 int i;
2075
2076 sa_size = alpha_sa_size ();
2077 frame_size
2078 = ALPHA_ROUND (sa_size
2079 + (is_stack_procedure ? 8 : 0)
2080 + size + current_function_pretend_args_size);
2081
89cfc2c6
RK
2082 /* Issue function start and label. */
2083 fprintf (file, "\t.ent ");
2084 assemble_name (file, alpha_function_name);
2085 fprintf (file, "\n");
a3b0df2d 2086 sprintf (entry_label, "%s..en", alpha_function_name);
89cfc2c6
RK
2087 ASM_OUTPUT_LABEL (file, entry_label);
2088 inside_function = TRUE;
2089
2090 fprintf (file, "\t.base $%d\n", base_regno);
2091
2092 /* Calculate register masks for clobbered registers. */
2093
2094 if (is_stack_procedure)
2095 alpha_sa_mask (&imask, &fmask);
2096
2097 /* Adjust the stack by the frame size. If the frame size is > 4096
2098 bytes, we need to be sure we probe somewhere in the first and last
2099 4096 bytes (we can probably get away without the latter test) and
2100 every 8192 bytes in between. If the frame size is > 32768, we
2101 do this in a loop. Otherwise, we generate the explicit probe
2102 instructions.
2103
2104 Note that we are only allowed to adjust sp once in the prologue. */
2105
2106 if (frame_size < 32768)
2107 {
2108 if (frame_size > 4096)
2109 {
2110 int probed = 4096;
2111
2112 fprintf (file, "\tstq $31,-%d($30)\n", probed);
2113
2114 while (probed + 8192 < frame_size)
2115 fprintf (file, "\tstq $31,-%d($30)\n", probed += 8192);
2116
2117 /* We only have to do this probe if we aren't saving registers. */
2118 if (sa_size == 0 && probed + 4096 < frame_size)
2119 fprintf (file, "\tstq $31,-%d($30)\n", frame_size);
2120 }
2121
2122 if (frame_size != 0)
2123 fprintf (file, "\tlda $30,-%d($30)\n", frame_size);
2124 }
2125 else
2126 {
2127 /* Here we generate code to set R4 to SP + 4096 and set R23 to the
2128 number of 8192 byte blocks to probe. We then probe each block
2129 in the loop and then set SP to the proper location. If the
2130 amount remaining is > 4096, we have to do one more probe if we
2131 are not saving any registers. */
2132
2133 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
2134 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
2135
2136 add_long_const (file, blocks, 31, 23, 23);
2137
2138 fprintf (file, "\tlda $22,4096($30)\n");
2139
2140 assemble_name (file, alpha_function_name);
2141 fprintf (file, "..sc:\n");
2142
2143 fprintf (file, "\tstq $31,-8192($22)\n");
2144 fprintf (file, "\tsubq $23,1,$23\n");
2145 fprintf (file, "\tlda $22,-8192($22)\n");
2146
2147 fprintf (file, "\tbne $23,");
2148 assemble_name (file, alpha_function_name);
2149 fprintf (file, "..sc\n");
2150
2151 if (leftover > 4096 && sa_size == 0)
2152 fprintf (file, "\tstq $31,-%d($22)\n", leftover);
2153
2154 fprintf (file, "\tlda $30,-%d($22)\n", leftover);
2155 }
2156
2157 if (is_stack_procedure)
2158 {
2159 int reg_offset = rsa_offset;
2160
2161 /* Store R26 (RA) first. */
2162 fprintf (file, "\tstq $26,%d($30)\n", reg_offset);
2163 reg_offset += 8;
2164
2165 /* Store integer regs. according to mask. */
2166 for (i = 0; i < 32; i++)
2167 if (imask & (1L<<i))
2168 {
2169 fprintf (file, "\tstq $%d,%d($30)\n", i, reg_offset);
2170 reg_offset += 8;
2171 }
2172
2173 /* Print the register mask and do floating-point saves. */
2174
2175 if (imask)
2176 fprintf (file, "\t.mask 0x%x,0\n", imask);
2177
2178 for (i = 0; i < 32; i++)
2179 {
2180 if (fmask & (1L << i))
2181 {
2182 fprintf (file, "\tstt $f%d,%d($30)\n", i, reg_offset);
2183 reg_offset += 8;
2184 }
2185 }
2186
2187 /* Print the floating-point mask, if we've saved any fp register. */
2188 if (fmask)
2189 fprintf (file, "\t.fmask 0x%x,0\n", fmask);
2190
2191 fprintf (file, "\tstq $27,0($30)\n");
2192 }
2193 else
2194 {
2195 fprintf (file, "\t.fp_save $%d\n", save_fp_regno);
2196 fprintf (file, "\tbis $%d,$%d,$%d\n", HARD_FRAME_POINTER_REGNUM,
2197 HARD_FRAME_POINTER_REGNUM, save_fp_regno);
2198 }
2199
2200 if (base_regno != REG_PV)
2201 fprintf (file, "\tbis $%d,$%d,$%d\n", REG_PV, REG_PV, base_regno);
2202
2203 if (unwind_regno == HARD_FRAME_POINTER_REGNUM)
2204 fprintf (file, "\tbis $%d,$%d,$%d\n", STACK_POINTER_REGNUM,
2205 STACK_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM);
2206
2207 /* Describe our frame. */
2208 fprintf (file, "\t.frame $%d,%d,$26,%d\n",
2209 unwind_regno, frame_size, rsa_offset);
2210
2211 /* If we have to allocate space for outgoing args, do it now. */
2212 if (current_function_outgoing_args_size != 0)
2213 fprintf (file, "\tlda $%d,%d($%d)\n", STACK_POINTER_REGNUM,
2214 - ALPHA_ROUND (current_function_outgoing_args_size),
2215 HARD_FRAME_POINTER_REGNUM);
2216
2217 fprintf (file, "\t.prologue\n");
2218
2219 link_section ();
2220 fprintf (file, "\t.align 3\n");
2221 ASM_OUTPUT_LABEL (file, alpha_function_name);
2222 fprintf (file, "\t.pdesc ");
2223 assemble_name (file, alpha_function_name);
2224 fprintf (file, "..en,%s\n", is_stack_procedure ? "stack" : "reg");
2225 alpha_need_linkage (alpha_function_name, 1);
2226 text_section ();
2227
2228 return;
2229}
2230
2231/* Write function epilogue. */
2232
2233void
2234output_epilog (file, size)
2235 FILE *file;
2236 int size;
2237{
2238 unsigned long imask = 0;
2239 unsigned long fmask = 0;
2240 /* Stack space needed for pushing registers clobbered by us. */
2241 HOST_WIDE_INT sa_size = alpha_sa_size ();
2242 /* Complete stack size needed. */
2243 HOST_WIDE_INT frame_size
2244 = ALPHA_ROUND (sa_size
2245 + (is_stack_procedure ? 8 : 0)
2246 + size + current_function_pretend_args_size);
2247 int i;
2248 rtx insn = get_last_insn ();
2249
2250 /* If the last insn was a BARRIER, we don't have to write anything except
2251 the .end pseudo-op. */
2252
2253 if (GET_CODE (insn) == NOTE)
2254 insn = prev_nonnote_insn (insn);
2255
2256 if (insn == 0 || GET_CODE (insn) != BARRIER)
2257 {
2258 /* Restore clobbered registers, load FP last. */
2259
2260 if (is_stack_procedure)
2261 {
2262 int rsa_offset = 8;
2263 int reg_offset;
2264 int fp_offset;
2265
2266 if (unwind_regno == HARD_FRAME_POINTER_REGNUM)
2267 fprintf (file, "\tbis $%d,$%d,$%d\n", HARD_FRAME_POINTER_REGNUM,
2268 HARD_FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM);
2269
2270 alpha_sa_mask (&imask, &fmask);
2271
2272 /* Start reloading registers after RA. */
2273 reg_offset = rsa_offset + 8;
2274
2275 for (i = 0; i < 32; i++)
2276 if (imask & (1L<<i))
2277 {
2278 if (i == HARD_FRAME_POINTER_REGNUM)
2279 fp_offset = reg_offset;
2280 else
2281 fprintf (file, "\tldq $%d,%d($30)\n",
2282 i, reg_offset);
2283 reg_offset += 8;
2284 }
2285
2286 for (i = 0; i < 32; i++)
2287 if (fmask & (1L << i))
2288 {
2289 fprintf (file, "\tldt $f%d,%d($30)\n", i, reg_offset);
2290 reg_offset += 8;
2291 }
2292
2293 /* Restore R26 (RA). */
2294 fprintf (file, "\tldq $26,%d($30)\n", rsa_offset);
2295
2296 /* Restore R29 (FP). */
2297 fprintf (file, "\tldq $29,%d($30)\n", fp_offset);
2298 }
2299 else
2300 fprintf (file, "\tbis $%d,$%d,$%d\n", save_fp_regno, save_fp_regno,
2301 HARD_FRAME_POINTER_REGNUM);
2302
2303 if (frame_size != 0)
2304 {
2305 if (frame_size < 32768)
2306 fprintf (file, "\tlda $30,%d($30)\n", frame_size);
2307 else
2308 {
2309 long high = frame_size >> 16;
2310 long low = frame_size & 0xffff;
2311 if (low & 0x8000)
2312 {
2313 high++;
2314 low = -32768 + (low & 0x7fff);
2315 }
2316 fprintf (file, "\tldah $2,%ld($31)\n", high);
2317 fprintf (file, "\tlda $2,%ld($2)\n", low);
2318 fprintf (file, "\taddq $30,$2,$30\n");
2319 }
2320 }
2321
2322 /* Finally return to the caller. */
2323 fprintf (file, "\tret $31,($26),1\n");
2324 }
2325
2326 /* End the function. */
2327 fprintf (file, "\t.end ");
2328 assemble_name (file, alpha_function_name);
2329 fprintf (file, "\n");
2330 inside_function = FALSE;
2331
2332 /* Show that we know this function if it is called again. */
2333 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
2334}
2335
2336#else /* !OPEN_VMS */
2337
9ecc37f0
RH
2338static int
2339alpha_does_function_need_gp ()
2340{
2341 rtx insn;
2342
2343 /* We never need a GP for Windows/NT. */
2344 if (TARGET_WINDOWS_NT)
2345 return 0;
2346
2347#ifdef TARGET_PROFILING_NEEDS_GP
2348 if (profile_flag)
2349 return 1;
2350#endif
2351
2352 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
2353 Even if we are a static function, we still need to do this in case
2354 our address is taken and passed to something like qsort. */
2355
2356 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2357 if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
2358 && GET_CODE (PATTERN (insn)) != USE
2359 && GET_CODE (PATTERN (insn)) != CLOBBER)
2360 {
2361 enum attr_type type = get_attr_type (insn);
2362 if (type == TYPE_LDSYM || type == TYPE_JSR)
2363 return 1;
2364 }
2365
2366 return 0;
2367}
2368
e9a25f70
JL
2369int
2370vms_valid_decl_attribute_p (decl, attributes, identifier, args)
2371 tree decl;
2372 tree attributes;
2373 tree identifier;
2374 tree args;
2375{
2376 if (is_attribute_p ("overlaid", identifier))
2377 return (args == NULL_TREE);
2378 return 0;
2379}
2380
a6f12d7c
RK
2381void
2382output_prolog (file, size)
2383 FILE *file;
2384 int size;
2385{
d60a05a1
RK
2386 HOST_WIDE_INT out_args_size
2387 = ALPHA_ROUND (current_function_outgoing_args_size);
2388 HOST_WIDE_INT sa_size = alpha_sa_size ();
2389 HOST_WIDE_INT frame_size
2390 = (out_args_size + sa_size
2391 + ALPHA_ROUND (size + current_function_pretend_args_size));
2392 HOST_WIDE_INT reg_offset = out_args_size;
ec6840c1
RK
2393 HOST_WIDE_INT start_reg_offset = reg_offset;
2394 HOST_WIDE_INT actual_start_reg_offset = start_reg_offset;
0273f326 2395 int int_reg_save_area_size = 0;
a6f12d7c 2396 unsigned reg_mask = 0;
0d24ff5d 2397 int i, sa_reg;
a6f12d7c 2398
d60a05a1 2399 /* Ecoff can handle multiple .file directives, so put out file and lineno.
48f6bfac
RK
2400 We have to do that before the .ent directive as we cannot switch
2401 files within procedures with native ecoff because line numbers are
2402 linked to procedure descriptors.
2403 Outputting the lineno helps debugging of one line functions as they
2404 would otherwise get no line number at all. Please note that we would
ddd5a7c1 2405 like to put out last_linenum from final.c, but it is not accessible. */
48f6bfac
RK
2406
2407 if (write_symbols == SDB_DEBUG)
2408 {
2409 ASM_OUTPUT_SOURCE_FILENAME (file,
2410 DECL_SOURCE_FILE (current_function_decl));
2411 if (debug_info_level != DINFO_LEVEL_TERSE)
d60a05a1
RK
2412 ASM_OUTPUT_SOURCE_LINE (file,
2413 DECL_SOURCE_LINE (current_function_decl));
48f6bfac
RK
2414 }
2415
2416 /* The assembly language programmer's guide states that the second argument
2417 to the .ent directive, the lex_level, is ignored by the assembler,
2418 so we might as well omit it. */
2419
33d01c33
RK
2420 if (!flag_inhibit_size_directive)
2421 {
2422 fprintf (file, "\t.ent ");
2423 assemble_name (file, alpha_function_name);
2424 fprintf (file, "\n");
2425 }
48f6bfac
RK
2426 ASM_OUTPUT_LABEL (file, alpha_function_name);
2427 inside_function = TRUE;
2428
33d01c33 2429 if (TARGET_IEEE_CONFORMANT && !flag_inhibit_size_directive)
6245e3df
RK
2430 /* Set flags in procedure descriptor to request IEEE-conformant
2431 math-library routines. The value we set it to is PDSC_EXC_IEEE
2432 (/usr/include/pdsc.h). */
2433 fprintf (file, "\t.eflag 48\n");
2434
48f6bfac
RK
2435 /* Set up offsets to alpha virtual arg/local debugging pointer. */
2436
2437 alpha_auto_offset = -frame_size + current_function_pretend_args_size;
2438 alpha_arg_offset = -frame_size + 48;
2439
9ecc37f0 2440 alpha_function_needs_gp = alpha_does_function_need_gp ();
a6f12d7c 2441
6c882425 2442 if (TARGET_WINDOWS_NT == 0)
9973f4a2
RK
2443 {
2444 if (alpha_function_needs_gp)
2445 fprintf (file, "\tldgp $29,0($27)\n");
a6f12d7c 2446
9973f4a2
RK
2447 /* Put a label after the GP load so we can enter the function at it. */
2448 assemble_name (file, alpha_function_name);
2449 fprintf (file, "..ng:\n");
2450 }
a6f12d7c 2451
c97e3db7
RK
2452 /* Adjust the stack by the frame size. If the frame size is > 4096
2453 bytes, we need to be sure we probe somewhere in the first and last
2454 4096 bytes (we can probably get away without the latter test) and
2455 every 8192 bytes in between. If the frame size is > 32768, we
2456 do this in a loop. Otherwise, we generate the explicit probe
2457 instructions.
a6f12d7c 2458
c97e3db7
RK
2459 Note that we are only allowed to adjust sp once in the prologue. */
2460
2461 if (frame_size < 32768)
2462 {
2463 if (frame_size > 4096)
2464 {
2465 int probed = 4096;
c97e3db7 2466
ea8e4ec5 2467 fprintf (file, "\tstq $31,-%d($30)\n", probed);
c97e3db7
RK
2468
2469 while (probed + 8192 < frame_size)
ea8e4ec5 2470 fprintf (file, "\tstq $31,-%d($30)\n", probed += 8192);
c97e3db7 2471
d60a05a1
RK
2472 /* We only have to do this probe if we aren't saving registers. */
2473 if (sa_size == 0 && probed + 4096 < frame_size)
ea8e4ec5 2474 fprintf (file, "\tstq $31,-%d($30)\n", frame_size);
c97e3db7
RK
2475 }
2476
2477 if (frame_size != 0)
2478 fprintf (file, "\tlda $30,-%d($30)\n", frame_size);
2479 }
2480 else
a6f12d7c 2481 {
c97e3db7
RK
2482 /* Here we generate code to set R4 to SP + 4096 and set R5 to the
2483 number of 8192 byte blocks to probe. We then probe each block
2484 in the loop and then set SP to the proper location. If the
d60a05a1
RK
2485 amount remaining is > 4096, we have to do one more probe if we
2486 are not saving any registers. */
c97e3db7
RK
2487
2488 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
2489 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
a6f12d7c 2490
d60a05a1 2491 add_long_const (file, blocks, 31, 5, 5);
c97e3db7
RK
2492
2493 fprintf (file, "\tlda $4,4096($30)\n");
5b9589fe
RK
2494
2495 assemble_name (file, alpha_function_name);
2496 fprintf (file, "..sc:\n");
2497
ea8e4ec5 2498 fprintf (file, "\tstq $31,-8192($4)\n");
c97e3db7
RK
2499 fprintf (file, "\tsubq $5,1,$5\n");
2500 fprintf (file, "\tlda $4,-8192($4)\n");
5b9589fe 2501
28c1753a 2502 fprintf (file, "\tbne $5,");
5b9589fe 2503 assemble_name (file, alpha_function_name);
28c1753a 2504 fprintf (file, "..sc\n");
5b9589fe 2505
d60a05a1 2506 if (leftover > 4096 && sa_size == 0)
ea8e4ec5
RK
2507 fprintf (file, "\tstq $31,-%d($4)\n", leftover);
2508
2509 fprintf (file, "\tlda $30,-%d($4)\n", leftover);
a6f12d7c 2510 }
a6f12d7c 2511
0f33506c 2512 /* Describe our frame. */
33d01c33
RK
2513 if (!flag_inhibit_size_directive)
2514 {
2515 fprintf (file, "\t.frame $%d,%d,$26,%d\n",
2516 (frame_pointer_needed
2517 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM),
2518 frame_size, current_function_pretend_args_size);
2519 }
0d24ff5d
RH
2520
2521 /* Cope with very large offsets to the register save area. */
2522 sa_reg = 30;
2523 if (reg_offset + sa_size > 0x8000)
2524 {
2525 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
2526 if (low + sa_size <= 0x8000)
2527 {
2528 add_long_const (file, reg_offset - low, 30, 24, 24);
2529 reg_offset = low;
2530 }
2531 else
2532 {
2533 add_long_const (file, reg_offset, 30, 24, 24);
2534 reg_offset = 0;
2535 }
2536 sa_reg = 24;
2537 }
a6f12d7c 2538
9ecc37f0 2539 /* Save register RA if any other register needs to be saved. */
d60a05a1 2540 if (sa_size != 0)
a6f12d7c 2541 {
9ecc37f0 2542 reg_mask |= 1 << REG_RA;
0d24ff5d 2543 fprintf (file, "\tstq $26,%d($%d)\n", reg_offset, sa_reg);
a6f12d7c 2544 reg_offset += 8;
0273f326 2545 int_reg_save_area_size += 8;
a6f12d7c
RK
2546 }
2547
0f33506c 2548 /* Now save any other used integer registers required to be saved. */
a6f12d7c 2549 for (i = 0; i < 32; i++)
9ecc37f0
RH
2550 if (! fixed_regs[i] && ! call_used_regs[i]
2551 && regs_ever_live[i] && i != REG_RA)
a6f12d7c
RK
2552 {
2553 reg_mask |= 1 << i;
0d24ff5d 2554 fprintf (file, "\tstq $%d,%d($%d)\n", i, reg_offset, sa_reg);
a6f12d7c 2555 reg_offset += 8;
0273f326 2556 int_reg_save_area_size += 8;
a6f12d7c
RK
2557 }
2558
2559 /* Print the register mask and do floating-point saves. */
33d01c33 2560 if (reg_mask && !flag_inhibit_size_directive)
a6f12d7c 2561 fprintf (file, "\t.mask 0x%x,%d\n", reg_mask,
ec6840c1 2562 actual_start_reg_offset - frame_size);
a6f12d7c
RK
2563
2564 start_reg_offset = reg_offset;
2565 reg_mask = 0;
2566
2567 for (i = 0; i < 32; i++)
2568 if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
2569 && regs_ever_live[i + 32])
2570 {
2571 reg_mask |= 1 << i;
0d24ff5d 2572 fprintf (file, "\tstt $f%d,%d($%d)\n", i, reg_offset, sa_reg);
a6f12d7c
RK
2573 reg_offset += 8;
2574 }
2575
2576 /* Print the floating-point mask, if we've saved any fp register. */
33d01c33 2577 if (reg_mask && !flag_inhibit_size_directive)
0273f326
RK
2578 fprintf (file, "\t.fmask 0x%x,%d\n", reg_mask,
2579 actual_start_reg_offset - frame_size + int_reg_save_area_size);
a6f12d7c 2580
0f33506c
RK
2581 /* If we need a frame pointer, set it from the stack pointer. Note that
2582 this must always be the last instruction in the prologue. */
a6f12d7c 2583 if (frame_pointer_needed)
0f33506c
RK
2584 fprintf (file, "\tbis $30,$30,$15\n");
2585
2586 /* End the prologue and say if we used gp. */
33d01c33
RK
2587 if (!flag_inhibit_size_directive)
2588 fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
a6f12d7c
RK
2589}
2590
2591/* Write function epilogue. */
2592
2593void
2594output_epilog (file, size)
2595 FILE *file;
2596 int size;
2597{
2598 rtx insn = get_last_insn ();
d60a05a1
RK
2599 HOST_WIDE_INT out_args_size
2600 = ALPHA_ROUND (current_function_outgoing_args_size);
2601 HOST_WIDE_INT sa_size = alpha_sa_size ();
2602 HOST_WIDE_INT frame_size
2603 = (out_args_size + sa_size
2604 + ALPHA_ROUND (size + current_function_pretend_args_size));
2605 HOST_WIDE_INT reg_offset = out_args_size;
ec6840c1 2606 HOST_WIDE_INT frame_size_from_reg_save = frame_size - reg_offset;
d60a05a1
RK
2607 int restore_fp
2608 = frame_pointer_needed && regs_ever_live[HARD_FRAME_POINTER_REGNUM];
a6f12d7c
RK
2609 int i;
2610
2611 /* If the last insn was a BARRIER, we don't have to write anything except
2612 the .end pseudo-op. */
2613 if (GET_CODE (insn) == NOTE)
2614 insn = prev_nonnote_insn (insn);
2615 if (insn == 0 || GET_CODE (insn) != BARRIER)
2616 {
d1085180 2617 int fp_offset = 0;
0d24ff5d 2618 int sa_reg;
a6f12d7c 2619
0f33506c 2620 /* If we have a frame pointer, restore SP from it. */
a6f12d7c 2621 if (frame_pointer_needed)
0f33506c 2622 fprintf (file, "\tbis $15,$15,$30\n");
a6f12d7c 2623
0d24ff5d
RH
2624 /* Cope with large offsets to the register save area. */
2625 sa_reg = 30;
2626 if (reg_offset + sa_size > 0x8000)
2627 {
2628 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
2629 if (low + sa_size <= 0x8000)
2630 {
2631 add_long_const (file, reg_offset - low, 30, 24, 24);
2632 reg_offset = low;
2633 }
2634 else
2635 {
2636 add_long_const (file, reg_offset, 30, 24, 24);
2637 reg_offset = 0;
2638 }
2639 sa_reg = 24;
2640 }
2641
a6f12d7c
RK
2642 /* Restore all the registers, starting with the return address
2643 register. */
d60a05a1 2644 if (sa_size != 0)
a6f12d7c 2645 {
0d24ff5d 2646 fprintf (file, "\tldq $26,%d($%d)\n", reg_offset, sa_reg);
a6f12d7c
RK
2647 reg_offset += 8;
2648 }
2649
0f33506c
RK
2650 /* Now restore any other used integer registers that that we saved,
2651 except for FP if it is being used as FP, since it must be
2652 restored last. */
2653
a6f12d7c
RK
2654 for (i = 0; i < 32; i++)
2655 if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i]
2656 && i != 26)
2657 {
d60a05a1 2658 if (i == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
0f33506c
RK
2659 fp_offset = reg_offset;
2660 else
0d24ff5d 2661 fprintf (file, "\tldq $%d,%d($%d)\n", i, reg_offset, sa_reg);
a6f12d7c
RK
2662 reg_offset += 8;
2663 }
2664
2665 for (i = 0; i < 32; i++)
2666 if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
2667 && regs_ever_live[i + 32])
2668 {
0d24ff5d 2669 fprintf (file, "\tldt $f%d,%d($%d)\n", i, reg_offset, sa_reg);
a6f12d7c
RK
2670 reg_offset += 8;
2671 }
2672
d60a05a1
RK
2673 /* If the stack size is large and we have a frame pointer, compute the
2674 size of the stack into a register because the old FP restore, stack
2675 pointer adjust, and return are required to be consecutive
2676 instructions. */
2677 if (frame_size > 32767 && restore_fp)
2678 add_long_const (file, frame_size, 31, 1, 1);
0f33506c
RK
2679
2680 /* If we needed a frame pointer and we have to restore it, do it
ec6840c1
RK
2681 now. This must be done in one instruction immediately
2682 before the SP update. */
d1085180 2683 if (restore_fp && fp_offset)
0d24ff5d 2684 fprintf (file, "\tldq $15,%d($%d)\n", fp_offset, sa_reg);
0f33506c 2685
d60a05a1
RK
2686 /* Now update the stack pointer, if needed. Only one instruction must
2687 modify the stack pointer. It must be the last instruction in the
2688 sequence and must be an ADDQ or LDA instruction. If the frame
2689 pointer was loaded above, we may only put one instruction here. */
2690
2691 if (frame_size > 32768 && restore_fp)
2692 fprintf (file, "\taddq $1,$30,$30\n");
2693 else
2694 add_long_const (file, frame_size, 30, 30, 1);
a6f12d7c 2695
0f33506c 2696 /* Finally return to the caller. */
a6f12d7c
RK
2697 fprintf (file, "\tret $31,($26),1\n");
2698 }
2699
2700 /* End the function. */
33d01c33
RK
2701 if (!flag_inhibit_size_directive)
2702 {
2703 fprintf (file, "\t.end ");
2704 assemble_name (file, alpha_function_name);
2705 fprintf (file, "\n");
2706 }
48f6bfac 2707 inside_function = FALSE;
9973f4a2
RK
2708
2709 /* Show that we know this function if it is called again. */
2710 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
e9a25f70
JL
2711
2712 alpha_return_addr_rtx = 0;
a6f12d7c 2713}
89cfc2c6 2714#endif /* !OPEN_VMS */
48f6bfac
RK
2715\f
2716/* Debugging support. */
2717
2718#include "gstab.h"
2719
2720/* Count the number of sdb related labels are generated (to find block
2721 start and end boundaries). */
2722
2723int sdb_label_count = 0;
2724
2725/* Next label # for each statement. */
2726
2727static int sym_lineno = 0;
2728
2729/* Count the number of .file directives, so that .loc is up to date. */
2730
2731static int num_source_filenames = 0;
2732
2733/* Name of the file containing the current function. */
2734
2735static char *current_function_file = "";
2736
2737/* Offsets to alpha virtual arg/local debugging pointers. */
2738
2739long alpha_arg_offset;
2740long alpha_auto_offset;
2741\f
2742/* Emit a new filename to a stream. */
2743
2744void
2745alpha_output_filename (stream, name)
2746 FILE *stream;
2747 char *name;
2748{
2749 static int first_time = TRUE;
2750 char ltext_label_name[100];
2751
2752 if (first_time)
2753 {
2754 first_time = FALSE;
2755 ++num_source_filenames;
2756 current_function_file = name;
2757 fprintf (stream, "\t.file\t%d ", num_source_filenames);
2758 output_quoted_string (stream, name);
2759 fprintf (stream, "\n");
2760 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
2761 fprintf (stream, "\t#@stabs\n");
2762 }
2763
6af601b3 2764 else if (write_symbols == DBX_DEBUG)
48f6bfac
RK
2765 {
2766 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
2767 fprintf (stream, "%s ", ASM_STABS_OP);
2768 output_quoted_string (stream, name);
2769 fprintf (stream, ",%d,0,0,%s\n", N_SOL, &ltext_label_name[1]);
2770 }
2771
2772 else if (name != current_function_file
2773 && strcmp (name, current_function_file) != 0)
2774 {
2775 if (inside_function && ! TARGET_GAS)
2776 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
2777 else
2778 {
2779 ++num_source_filenames;
2780 current_function_file = name;
2781 fprintf (stream, "\t.file\t%d ", num_source_filenames);
2782 }
2783
2784 output_quoted_string (stream, name);
2785 fprintf (stream, "\n");
2786 }
2787}
2788\f
2789/* Emit a linenumber to a stream. */
2790
2791void
2792alpha_output_lineno (stream, line)
2793 FILE *stream;
2794 int line;
2795{
6af601b3 2796 if (write_symbols == DBX_DEBUG)
48f6bfac
RK
2797 {
2798 /* mips-tfile doesn't understand .stabd directives. */
2799 ++sym_lineno;
2800 fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
2801 sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
2802 }
2803 else
40828e35 2804 fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
48f6bfac 2805}
6245e3df
RK
2806\f
2807/* Structure to show the current status of registers and memory. */
2808
2809struct shadow_summary
2810{
2811 struct {
2ea844d3
RH
2812 unsigned long i : 31; /* Mask of int regs */
2813 unsigned long fp : 31; /* Mask of fp regs */
6245e3df
RK
2814 unsigned long mem : 1; /* mem == imem | fpmem */
2815 } used, defd;
2816};
2817
2818/* Summary the effects of expression X on the machine. Update SUM, a pointer
2819 to the summary structure. SET is nonzero if the insn is setting the
2820 object, otherwise zero. */
2821
2822static void
2823summarize_insn (x, sum, set)
2824 rtx x;
2825 struct shadow_summary *sum;
2826 int set;
2827{
2828 char *format_ptr;
2829 int i, j;
2830
2831 if (x == 0)
2832 return;
2833
2834 switch (GET_CODE (x))
2835 {
2836 /* ??? Note that this case would be incorrect if the Alpha had a
2837 ZERO_EXTRACT in SET_DEST. */
2838 case SET:
2839 summarize_insn (SET_SRC (x), sum, 0);
2840 summarize_insn (SET_DEST (x), sum, 1);
2841 break;
2842
2843 case CLOBBER:
2844 summarize_insn (XEXP (x, 0), sum, 1);
2845 break;
2846
2847 case USE:
2848 summarize_insn (XEXP (x, 0), sum, 0);
2849 break;
2850
2851 case PARALLEL:
8fed04e5 2852 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
6245e3df
RK
2853 summarize_insn (XVECEXP (x, 0, i), sum, 0);
2854 break;
2855
2856 case REG:
2857 {
2858 int regno = REGNO (x);
2859 unsigned long mask = 1UL << (regno % 32);
2860
2861 if (regno == 31 || regno == 63)
2862 break;
2863
2864 if (set)
2865 {
2866 if (regno < 32)
2867 sum->defd.i |= mask;
2868 else
2869 sum->defd.fp |= mask;
2870 }
2871 else
2872 {
2873 if (regno < 32)
2874 sum->used.i |= mask;
2875 else
2876 sum->used.fp |= mask;
2877 }
2878 }
2879 break;
2880
2881 case MEM:
2882 if (set)
2883 sum->defd.mem = 1;
2884 else
2885 sum->used.mem = 1;
2886
2887 /* Find the regs used in memory address computation: */
2888 summarize_insn (XEXP (x, 0), sum, 0);
2889 break;
2890
8ba46994 2891 case SUBREG:
66d91cb9 2892 summarize_insn (SUBREG_REG (x), sum, set);
8ba46994
RK
2893 break;
2894
2895 case CONST_INT: case CONST_DOUBLE:
2896 case SYMBOL_REF: case LABEL_REF: case CONST:
2897 break;
2898
6245e3df
RK
2899 /* Handle common unary and binary ops for efficiency. */
2900 case COMPARE: case PLUS: case MINUS: case MULT: case DIV:
2901 case MOD: case UDIV: case UMOD: case AND: case IOR:
2902 case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT:
2903 case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX:
2904 case NE: case EQ: case GE: case GT: case LE:
2905 case LT: case GEU: case GTU: case LEU: case LTU:
2906 summarize_insn (XEXP (x, 0), sum, 0);
2907 summarize_insn (XEXP (x, 1), sum, 0);
2908 break;
2909
2910 case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
2911 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
2912 case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
2913 case SQRT: case FFS:
2914 summarize_insn (XEXP (x, 0), sum, 0);
2915 break;
2916
2917 default:
2918 format_ptr = GET_RTX_FORMAT (GET_CODE (x));
8fed04e5 2919 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
bed95fa1 2920 switch (format_ptr[i])
6245e3df
RK
2921 {
2922 case 'e':
2923 summarize_insn (XEXP (x, i), sum, 0);
2924 break;
2925
2926 case 'E':
8fed04e5 2927 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
6245e3df
RK
2928 summarize_insn (XVECEXP (x, i, j), sum, 0);
2929 break;
2930
2931 default:
2932 abort ();
2933 }
2934 }
2935}
6245e3df 2936
2ea844d3
RH
2937/* Ensure a sufficient number of `trapb' insns are in the code when the user
2938 requests code with a trap precision of functions or instructions.
6245e3df
RK
2939
2940 In naive mode, when the user requests a trap-precision of "instruction", a
2941 trapb is needed after every instruction that may generate a trap (and after
2942 jsr/bsr instructions, because called functions may import a trap from the
2943 caller). This ensures that the code is resumption safe but it is also slow.
2944
2945 When optimizations are turned on, we delay issuing a trapb as long as
2946 possible. In this context, a trap shadow is the sequence of instructions
2947 that starts with a (potentially) trap generating instruction and extends to
2948 the next trapb or call_pal instruction (but GCC never generates call_pal by
2949 itself). We can delay (and therefore sometimes omit) a trapb subject to the
2950 following conditions:
2951
2952 (a) On entry to the trap shadow, if any Alpha register or memory location
2953 contains a value that is used as an operand value by some instruction in
2954 the trap shadow (live on entry), then no instruction in the trap shadow
2955 may modify the register or memory location.
2956
2957 (b) Within the trap shadow, the computation of the base register for a
2958 memory load or store instruction may not involve using the result
2959 of an instruction that might generate an UNPREDICTABLE result.
2960
2961 (c) Within the trap shadow, no register may be used more than once as a
2962 destination register. (This is to make life easier for the trap-handler.)
2963
2ea844d3 2964 (d) The trap shadow may not include any branch instructions. */
6245e3df 2965
2ea844d3
RH
2966static void
2967alpha_handle_trap_shadows (insns)
2968 rtx insns;
6245e3df 2969{
2ea844d3
RH
2970 struct shadow_summary shadow;
2971 int trap_pending, exception_nesting;
2972 rtx i;
6245e3df 2973
2ea844d3
RH
2974 if (alpha_tp == ALPHA_TP_PROG && !flag_exceptions)
2975 return;
6245e3df 2976
2ea844d3
RH
2977 trap_pending = 0;
2978 exception_nesting = 0;
2979 shadow.used.i = 0;
2980 shadow.used.fp = 0;
2981 shadow.used.mem = 0;
2982 shadow.defd = shadow.used;
2983
2984 for (i = insns; i ; i = NEXT_INSN (i))
2985 {
2986 if (GET_CODE (i) == NOTE)
2987 {
2988 switch (NOTE_LINE_NUMBER (i))
2989 {
2990 case NOTE_INSN_EH_REGION_BEG:
2991 exception_nesting++;
2992 if (trap_pending)
2993 goto close_shadow;
2994 break;
2995
2996 case NOTE_INSN_EH_REGION_END:
2997 exception_nesting--;
2998 if (trap_pending)
2999 goto close_shadow;
3000 break;
3001
3002 case NOTE_INSN_EPILOGUE_BEG:
3003 if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
3004 goto close_shadow;
3005 break;
3006 }
3007 }
3008 else if (trap_pending)
3009 {
3010 if (alpha_tp == ALPHA_TP_FUNC)
3011 {
3012 if (GET_CODE (i) == JUMP_INSN
3013 && GET_CODE (PATTERN (i)) == RETURN)
3014 goto close_shadow;
3015 }
3016 else if (alpha_tp == ALPHA_TP_INSN)
3017 {
3018 if (optimize > 0)
3019 {
3020 struct shadow_summary sum;
3021
3022 sum.used.i = 0;
3023 sum.used.fp = 0;
3024 sum.used.mem = 0;
3025 sum.defd = shadow.used;
3026
3027 switch (GET_CODE (i))
3028 {
3029 case INSN:
3030 /* Annoyingly, get_attr_trap will abort on USE. */
3031 if (GET_CODE (PATTERN (i)) == USE)
3032 break;
3033
3034 summarize_insn (PATTERN (i), &sum, 0);
3035
3036 if ((sum.defd.i & shadow.defd.i)
3037 || (sum.defd.fp & shadow.defd.fp))
3038 {
3039 /* (c) would be violated */
3040 goto close_shadow;
3041 }
3042
3043 /* Combine shadow with summary of current insn: */
3044 shadow.used.i |= sum.used.i;
3045 shadow.used.fp |= sum.used.fp;
3046 shadow.used.mem |= sum.used.mem;
3047 shadow.defd.i |= sum.defd.i;
3048 shadow.defd.fp |= sum.defd.fp;
3049 shadow.defd.mem |= sum.defd.mem;
3050
3051 if ((sum.defd.i & shadow.used.i)
3052 || (sum.defd.fp & shadow.used.fp)
3053 || (sum.defd.mem & shadow.used.mem))
3054 {
3055 /* (a) would be violated (also takes care of (b)) */
3056 if (get_attr_trap (i) == TRAP_YES
3057 && ((sum.defd.i & sum.used.i)
3058 || (sum.defd.fp & sum.used.fp)))
3059 abort ();
3060
3061 goto close_shadow;
3062 }
3063 break;
3064
3065 case JUMP_INSN:
3066 case CALL_INSN:
3067 case CODE_LABEL:
3068 goto close_shadow;
3069
3070 default:
6245e3df 3071 abort ();
2ea844d3
RH
3072 }
3073 }
3074 else
3075 {
3076 close_shadow:
3077 emit_insn_before (gen_trapb (), i);
3078 trap_pending = 0;
3079 shadow.used.i = 0;
3080 shadow.used.fp = 0;
3081 shadow.used.mem = 0;
3082 shadow.defd = shadow.used;
3083 }
3084 }
3085 }
6245e3df 3086
4f3f5e9f
RH
3087 if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
3088 && GET_CODE (i) == INSN
3089 && GET_CODE (PATTERN (i)) != USE
3090 && GET_CODE (PATTERN (i)) != CLOBBER
3091 && get_attr_trap (i) == TRAP_YES)
3092 {
3093 if (optimize && !trap_pending)
3094 summarize_insn (PATTERN (i), &shadow, 0);
3095 trap_pending = 1;
3096 }
6245e3df
RK
3097 }
3098}
a874dd18 3099
2ea844d3
RH
3100/* Machine dependant reorg pass. */
3101
3102void
3103alpha_reorg (insns)
3104 rtx insns;
3105{
3106 alpha_handle_trap_shadows (insns);
3107}
3108
3109\f
a874dd18
RK
3110/* Check a floating-point value for validity for a particular machine mode. */
3111
3112static char *float_strings[] =
3113{
39d78b32 3114 /* These are for FLOAT_VAX. */
a874dd18
RK
3115 "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
3116 "-1.70141173319264430e+38",
3117 "2.93873587705571877e-39", /* 2^-128 */
39d78b32
RK
3118 "-2.93873587705571877e-39",
3119 /* These are for the default broken IEEE mode, which traps
3120 on infinity or denormal numbers. */
3121 "3.402823466385288598117e+38", /* 2^128 (1 - 2^-24) */
3122 "-3.402823466385288598117e+38",
3123 "1.1754943508222875079687e-38", /* 2^-126 */
3124 "-1.1754943508222875079687e-38",
a874dd18
RK
3125};
3126
39d78b32 3127static REAL_VALUE_TYPE float_values[8];
a874dd18
RK
3128static int inited_float_values = 0;
3129
3130int
3131check_float_value (mode, d, overflow)
3132 enum machine_mode mode;
3133 REAL_VALUE_TYPE *d;
3134 int overflow;
3135{
3136
3137 if (TARGET_IEEE || TARGET_IEEE_CONFORMANT || TARGET_IEEE_WITH_INEXACT)
3138 return 0;
3139
3140 if (inited_float_values == 0)
3141 {
3142 int i;
39d78b32 3143 for (i = 0; i < 8; i++)
a874dd18
RK
3144 float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
3145
3146 inited_float_values = 1;
3147 }
3148
3149 if (mode == SFmode)
3150 {
3151 REAL_VALUE_TYPE r;
39d78b32
RK
3152 REAL_VALUE_TYPE *fvptr;
3153
3154 if (TARGET_FLOAT_VAX)
3155 fvptr = &float_values[0];
3156 else
3157 fvptr = &float_values[4];
a874dd18 3158
acbdd7dd 3159 bcopy ((char *) d, (char *) &r, sizeof (REAL_VALUE_TYPE));
39d78b32 3160 if (REAL_VALUES_LESS (fvptr[0], r))
a874dd18 3161 {
39d78b32 3162 bcopy ((char *) &fvptr[0], (char *) d,
acbdd7dd 3163 sizeof (REAL_VALUE_TYPE));
a874dd18
RK
3164 return 1;
3165 }
39d78b32 3166 else if (REAL_VALUES_LESS (r, fvptr[1]))
a874dd18 3167 {
39d78b32 3168 bcopy ((char *) &fvptr[1], (char *) d,
acbdd7dd 3169 sizeof (REAL_VALUE_TYPE));
a874dd18
RK
3170 return 1;
3171 }
3172 else if (REAL_VALUES_LESS (dconst0, r)
39d78b32 3173 && REAL_VALUES_LESS (r, fvptr[2]))
a874dd18 3174 {
acbdd7dd 3175 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
a874dd18
RK
3176 return 1;
3177 }
3178 else if (REAL_VALUES_LESS (r, dconst0)
39d78b32 3179 && REAL_VALUES_LESS (fvptr[3], r))
a874dd18 3180 {
acbdd7dd 3181 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
a874dd18
RK
3182 return 1;
3183 }
3184 }
3185
3186 return 0;
3187}
89cfc2c6
RK
3188
3189#if OPEN_VMS
3190
e9a25f70 3191/* Return the VMS argument type corresponding to MODE. */
89cfc2c6 3192
e9a25f70
JL
3193enum avms_arg_type
3194alpha_arg_type (mode)
3195 enum machine_mode mode;
3196{
3197 switch (mode)
89cfc2c6 3198 {
e9a25f70
JL
3199 case SFmode:
3200 return TARGET_FLOAT_VAX ? FF : FS;
3201 case DFmode:
3202 return TARGET_FLOAT_VAX ? FD : FT;
3203 default:
3204 return I64;
89cfc2c6 3205 }
e9a25f70 3206}
89cfc2c6 3207
e9a25f70
JL
3208/* Return an rtx for an integer representing the VMS Argument Information
3209 register value. */
89cfc2c6 3210
e9a25f70
JL
3211struct rtx_def *
3212alpha_arg_info_reg_val (cum)
3213 CUMULATIVE_ARGS cum;
3214{
3215 unsigned HOST_WIDE_INT regval = cum.num_args;
3216 int i;
89cfc2c6 3217
e9a25f70
JL
3218 for (i = 0; i < 6; i++)
3219 regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
89cfc2c6 3220
e9a25f70
JL
3221 return GEN_INT (regval);
3222}
3223\f
89cfc2c6
RK
3224/* Structure to collect function names for final output
3225 in link section. */
3226
3227enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
3228
3229
3230struct alpha_links {
3231 struct alpha_links *next;
3232 char *name;
3233 enum links_kind kind;
3234};
3235
3236static struct alpha_links *alpha_links_base = 0;
3237
3238/* Make (or fake) .linkage entry for function call.
3239
3240 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition. */
3241
3242void
3243alpha_need_linkage (name, is_local)
3244 char *name;
3245 int is_local;
3246{
3247 rtx x;
3248 struct alpha_links *lptr, *nptr;
3249
3250 if (name[0] == '*')
3251 name++;
3252
3253 /* Is this name already defined ? */
3254
3255 for (lptr = alpha_links_base; lptr; lptr = lptr->next)
3256 if (strcmp (lptr->name, name) == 0)
3257 {
3258 if (is_local)
3259 {
9398dc27 3260 /* Defined here but external assumed. */
89cfc2c6
RK
3261 if (lptr->kind == KIND_EXTERN)
3262 lptr->kind = KIND_LOCAL;
3263 }
3264 else
3265 {
9398dc27 3266 /* Used here but unused assumed. */
89cfc2c6
RK
3267 if (lptr->kind == KIND_UNUSED)
3268 lptr->kind = KIND_LOCAL;
3269 }
3270 return;
3271 }
3272
3273 nptr = (struct alpha_links *) xmalloc (sizeof (struct alpha_links));
3274 nptr->next = alpha_links_base;
3275 nptr->name = xstrdup (name);
3276
3277 /* Assume external if no definition. */
3278 nptr->kind = (is_local ? KIND_UNUSED : KIND_EXTERN);
3279
9398dc27
RK
3280 /* Ensure we have an IDENTIFIER so assemble_name can mark is used. */
3281 get_identifier (name);
3282
89cfc2c6
RK
3283 alpha_links_base = nptr;
3284
3285 return;
3286}
3287
3288
3289void
3290alpha_write_linkage (stream)
3291 FILE *stream;
3292{
3293 struct alpha_links *lptr, *nptr;
3294
3295 readonly_section ();
3296
3297 fprintf (stream, "\t.align 3\n");
3298
3299 for (lptr = alpha_links_base; lptr; lptr = nptr)
3300 {
3301 nptr = lptr->next;
3302
3303 if (lptr->kind == KIND_UNUSED
3304 || ! TREE_SYMBOL_REFERENCED (get_identifier (lptr->name)))
3305 continue;
3306
3307 fprintf (stream, "%s..lk:\n", lptr->name);
3308 if (lptr->kind == KIND_LOCAL)
3309 {
3310 /* Local and used, build linkage pair. */
3311 fprintf (stream, "\t.quad %s..en\n", lptr->name);
3312 fprintf (stream, "\t.quad %s\n", lptr->name);
3313 }
3314 else
3315 /* External and used, request linkage pair. */
3316 fprintf (stream, "\t.linkage %s\n", lptr->name);
3317 }
3318}
3319
3320#else
3321
3322void
3323alpha_need_linkage (name, is_local)
3324 char *name;
3325 int is_local;
3326{
3327}
3328
3329#endif /* OPEN_VMS */
3330