]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/alpha/alpha.c
Merge in gcc2 snapshot 19980929. See gcc/ChangeLog and gcc/FSFChangeLog for
[thirdparty/gcc.git] / gcc / config / alpha / alpha.c
1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992, 93, 94, 95, 96, 97, 1998, 1999 Free Software
3 Foundation, Inc.
4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5
6 This file is part of GNU CC.
7
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
22
23
24 #include "config.h"
25 #include "system.h"
26 #include "rtl.h"
27 #include "regs.h"
28 #include "hard-reg-set.h"
29 #include "real.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-flags.h"
33 #include "output.h"
34 #include "insn-attr.h"
35 #include "flags.h"
36 #include "recog.h"
37 #include "reload.h"
38 #include "tree.h"
39 #include "expr.h"
40 #include "obstack.h"
41 #include "except.h"
42 #include "function.h"
43 #include "toplev.h"
44
45 /* External data. */
46 extern char *version_string;
47 extern int rtx_equal_function_value_matters;
48
49 /* Specify which cpu to schedule for. */
50
51 enum processor_type alpha_cpu;
52 static char* const alpha_cpu_name[] =
53 {
54 "ev4", "ev5", "ev6"
55 };
56
57 /* Specify how accurate floating-point traps need to be. */
58
59 enum alpha_trap_precision alpha_tp;
60
61 /* Specify the floating-point rounding mode. */
62
63 enum alpha_fp_rounding_mode alpha_fprm;
64
65 /* Specify which things cause traps. */
66
67 enum alpha_fp_trap_mode alpha_fptm;
68
69 /* Strings decoded into the above options. */
70
71 char *alpha_cpu_string; /* -mcpu= */
72 char *alpha_tp_string; /* -mtrap-precision=[p|s|i] */
73 char *alpha_fprm_string; /* -mfp-rounding-mode=[n|m|c|d] */
74 char *alpha_fptm_string; /* -mfp-trap-mode=[n|u|su|sui] */
75 char *alpha_mlat_string; /* -mmemory-latency= */
76
77 /* Save information from a "cmpxx" operation until the branch or scc is
78 emitted. */
79
80 rtx alpha_compare_op0, alpha_compare_op1;
81 int alpha_compare_fp_p;
82
83 /* Define the information needed to modify the epilogue for EH. */
84
85 rtx alpha_eh_epilogue_sp_ofs;
86
87 /* Non-zero if inside of a function, because the Alpha asm can't
88 handle .files inside of functions. */
89
90 static int inside_function = FALSE;
91
92 /* If non-null, this rtx holds the return address for the function. */
93
94 static rtx alpha_return_addr_rtx;
95
96 /* The number of cycles of latency we should assume on memory reads. */
97
98 int alpha_memory_latency = 3;
99
100 /* Whether the function needs the GP. */
101
102 static int alpha_function_needs_gp;
103
104 /* The alias set for prologue/epilogue register save/restore. */
105
106 static int alpha_sr_alias_set;
107
108 /* Declarations of static functions. */
109 static void alpha_set_memflags_1
110 PROTO((rtx, int, int, int));
111 static rtx alpha_emit_set_const_1
112 PROTO((rtx, enum machine_mode, HOST_WIDE_INT, int));
113 static void alpha_expand_unaligned_load_words
114 PROTO((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
115 static void alpha_expand_unaligned_store_words
116 PROTO((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
117 static void alpha_sa_mask
118 PROTO((unsigned long *imaskP, unsigned long *fmaskP));
119 static int alpha_does_function_need_gp
120 PROTO((void));
121
122
123 /* Get the number of args of a function in one of two ways. */
124 #ifdef OPEN_VMS
125 #define NUM_ARGS current_function_args_info.num_args
126 #else
127 #define NUM_ARGS current_function_args_info
128 #endif
129
130 #define REG_PV 27
131 #define REG_RA 26
132 \f
133 /* Parse target option strings. */
134
135 void
136 override_options ()
137 {
138 alpha_cpu
139 = TARGET_CPU_DEFAULT & MASK_CPU_EV6 ? PROCESSOR_EV6
140 : (TARGET_CPU_DEFAULT & MASK_CPU_EV5 ? PROCESSOR_EV5 : PROCESSOR_EV4);
141
142 if (alpha_cpu_string)
143 {
144 if (! strcmp (alpha_cpu_string, "ev4")
145 || ! strcmp (alpha_cpu_string, "21064"))
146 {
147 alpha_cpu = PROCESSOR_EV4;
148 target_flags &= ~ (MASK_BWX | MASK_CIX | MASK_MAX);
149 }
150 else if (! strcmp (alpha_cpu_string, "ev5")
151 || ! strcmp (alpha_cpu_string, "21164"))
152 {
153 alpha_cpu = PROCESSOR_EV5;
154 target_flags &= ~ (MASK_BWX | MASK_CIX | MASK_MAX);
155 }
156 else if (! strcmp (alpha_cpu_string, "ev56")
157 || ! strcmp (alpha_cpu_string, "21164a"))
158 {
159 alpha_cpu = PROCESSOR_EV5;
160 target_flags |= MASK_BWX;
161 target_flags &= ~ (MASK_CIX | MASK_MAX);
162 }
163 else if (! strcmp (alpha_cpu_string, "pca56")
164 || ! strcmp (alpha_cpu_string, "21164PC")
165 || ! strcmp (alpha_cpu_string, "21164pc"))
166 {
167 alpha_cpu = PROCESSOR_EV5;
168 target_flags |= MASK_BWX | MASK_MAX;
169 target_flags &= ~ MASK_CIX;
170 }
171 else if (! strcmp (alpha_cpu_string, "ev6")
172 || ! strcmp (alpha_cpu_string, "21264"))
173 {
174 alpha_cpu = PROCESSOR_EV6;
175 target_flags |= MASK_BWX | MASK_CIX | MASK_MAX;
176 }
177 else
178 error ("bad value `%s' for -mcpu switch", alpha_cpu_string);
179 }
180
181 alpha_tp = ALPHA_TP_PROG;
182 alpha_fprm = ALPHA_FPRM_NORM;
183 alpha_fptm = ALPHA_FPTM_N;
184
185 if (TARGET_IEEE)
186 {
187 alpha_tp = ALPHA_TP_INSN;
188 alpha_fptm = ALPHA_FPTM_SU;
189 }
190
191 if (TARGET_IEEE_WITH_INEXACT)
192 {
193 alpha_tp = ALPHA_TP_INSN;
194 alpha_fptm = ALPHA_FPTM_SUI;
195 }
196
197 if (alpha_tp_string)
198 {
199 if (! strcmp (alpha_tp_string, "p"))
200 alpha_tp = ALPHA_TP_PROG;
201 else if (! strcmp (alpha_tp_string, "f"))
202 alpha_tp = ALPHA_TP_FUNC;
203 else if (! strcmp (alpha_tp_string, "i"))
204 alpha_tp = ALPHA_TP_INSN;
205 else
206 error ("bad value `%s' for -mtrap-precision switch", alpha_tp_string);
207 }
208
209 if (alpha_fprm_string)
210 {
211 if (! strcmp (alpha_fprm_string, "n"))
212 alpha_fprm = ALPHA_FPRM_NORM;
213 else if (! strcmp (alpha_fprm_string, "m"))
214 alpha_fprm = ALPHA_FPRM_MINF;
215 else if (! strcmp (alpha_fprm_string, "c"))
216 alpha_fprm = ALPHA_FPRM_CHOP;
217 else if (! strcmp (alpha_fprm_string,"d"))
218 alpha_fprm = ALPHA_FPRM_DYN;
219 else
220 error ("bad value `%s' for -mfp-rounding-mode switch",
221 alpha_fprm_string);
222 }
223
224 if (alpha_fptm_string)
225 {
226 if (strcmp (alpha_fptm_string, "n") == 0)
227 alpha_fptm = ALPHA_FPTM_N;
228 else if (strcmp (alpha_fptm_string, "u") == 0)
229 alpha_fptm = ALPHA_FPTM_U;
230 else if (strcmp (alpha_fptm_string, "su") == 0)
231 alpha_fptm = ALPHA_FPTM_SU;
232 else if (strcmp (alpha_fptm_string, "sui") == 0)
233 alpha_fptm = ALPHA_FPTM_SUI;
234 else
235 error ("bad value `%s' for -mfp-trap-mode switch", alpha_fptm_string);
236 }
237
238 /* Do some sanity checks on the above option. */
239
240 if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI)
241 && alpha_tp != ALPHA_TP_INSN)
242 {
243 warning ("fp software completion requires -mtrap-precision=i");
244 alpha_tp = ALPHA_TP_INSN;
245 }
246
247 if (TARGET_FLOAT_VAX)
248 {
249 if (alpha_fprm == ALPHA_FPRM_MINF || alpha_fprm == ALPHA_FPRM_DYN)
250 {
251 warning ("rounding mode not supported for VAX floats");
252 alpha_fprm = ALPHA_FPRM_NORM;
253 }
254 if (alpha_fptm == ALPHA_FPTM_SUI)
255 {
256 warning ("trap mode not supported for VAX floats");
257 alpha_fptm = ALPHA_FPTM_SU;
258 }
259 }
260
261 {
262 char *end;
263 int lat;
264
265 if (!alpha_mlat_string)
266 alpha_mlat_string = "L1";
267
268 if (ISDIGIT ((unsigned char)alpha_mlat_string[0])
269 && (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0'))
270 ;
271 else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l')
272 && ISDIGIT ((unsigned char)alpha_mlat_string[1])
273 && alpha_mlat_string[2] == '\0')
274 {
275 static int const cache_latency[][4] =
276 {
277 { 3, 30, -1 }, /* ev4 -- Bcache is a guess */
278 { 2, 12, 38 }, /* ev5 -- Bcache from PC164 LMbench numbers */
279 { 3, 13, -1 }, /* ev6 -- Ho hum, doesn't exist yet */
280 };
281
282 lat = alpha_mlat_string[1] - '0';
283 if (lat < 0 || lat > 3 || cache_latency[alpha_cpu][lat-1] == -1)
284 {
285 warning ("L%d cache latency unknown for %s",
286 lat, alpha_cpu_name[alpha_cpu]);
287 lat = 3;
288 }
289 else
290 lat = cache_latency[alpha_cpu][lat-1];
291 }
292 else if (! strcmp (alpha_mlat_string, "main"))
293 {
294 /* Most current memories have about 370ns latency. This is
295 a reasonable guess for a fast cpu. */
296 lat = 150;
297 }
298 else
299 {
300 warning ("bad value `%s' for -mmemory-latency", alpha_mlat_string);
301 lat = 3;
302 }
303
304 alpha_memory_latency = lat;
305 }
306
307 /* Default the definition of "small data" to 8 bytes. */
308 if (!g_switch_set)
309 g_switch_value = 8;
310
311 /* Acquire a unique set number for our register saves and restores. */
312 alpha_sr_alias_set = new_alias_set ();
313 }
314 \f
315 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
316
317 int
318 zap_mask (value)
319 HOST_WIDE_INT value;
320 {
321 int i;
322
323 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
324 i++, value >>= 8)
325 if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
326 return 0;
327
328 return 1;
329 }
330
331 /* Returns 1 if OP is either the constant zero or a register. If a
332 register, it must be in the proper mode unless MODE is VOIDmode. */
333
334 int
335 reg_or_0_operand (op, mode)
336 register rtx op;
337 enum machine_mode mode;
338 {
339 return op == const0_rtx || register_operand (op, mode);
340 }
341
342 /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
343 any register. */
344
345 int
346 reg_or_6bit_operand (op, mode)
347 register rtx op;
348 enum machine_mode mode;
349 {
350 return ((GET_CODE (op) == CONST_INT
351 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64)
352 || register_operand (op, mode));
353 }
354
355
356 /* Return 1 if OP is an 8-bit constant or any register. */
357
358 int
359 reg_or_8bit_operand (op, mode)
360 register rtx op;
361 enum machine_mode mode;
362 {
363 return ((GET_CODE (op) == CONST_INT
364 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
365 || register_operand (op, mode));
366 }
367
368 /* Return 1 if OP is an 8-bit constant. */
369
370 int
371 cint8_operand (op, mode)
372 register rtx op;
373 enum machine_mode mode ATTRIBUTE_UNUSED;
374 {
375 return ((GET_CODE (op) == CONST_INT
376 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100));
377 }
378
379 /* Return 1 if the operand is a valid second operand to an add insn. */
380
381 int
382 add_operand (op, mode)
383 register rtx op;
384 enum machine_mode mode;
385 {
386 if (GET_CODE (op) == CONST_INT)
387 /* Constraints I, J, O and P are covered by K. */
388 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'K')
389 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
390
391 return register_operand (op, mode);
392 }
393
394 /* Return 1 if the operand is a valid second operand to a sign-extending
395 add insn. */
396
397 int
398 sext_add_operand (op, mode)
399 register rtx op;
400 enum machine_mode mode;
401 {
402 if (GET_CODE (op) == CONST_INT)
403 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
404 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'O'));
405
406 return register_operand (op, mode);
407 }
408
409 /* Return 1 if OP is the constant 4 or 8. */
410
411 int
412 const48_operand (op, mode)
413 register rtx op;
414 enum machine_mode mode ATTRIBUTE_UNUSED;
415 {
416 return (GET_CODE (op) == CONST_INT
417 && (INTVAL (op) == 4 || INTVAL (op) == 8));
418 }
419
420 /* Return 1 if OP is a valid first operand to an AND insn. */
421
422 int
423 and_operand (op, mode)
424 register rtx op;
425 enum machine_mode mode;
426 {
427 if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
428 return (zap_mask (CONST_DOUBLE_LOW (op))
429 && zap_mask (CONST_DOUBLE_HIGH (op)));
430
431 if (GET_CODE (op) == CONST_INT)
432 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
433 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
434 || zap_mask (INTVAL (op)));
435
436 return register_operand (op, mode);
437 }
438
439 /* Return 1 if OP is a valid first operand to an IOR or XOR insn. */
440
441 int
442 or_operand (op, mode)
443 register rtx op;
444 enum machine_mode mode;
445 {
446 if (GET_CODE (op) == CONST_INT)
447 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
448 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100);
449
450 return register_operand (op, mode);
451 }
452
453 /* Return 1 if OP is a constant that is the width, in bits, of an integral
454 mode smaller than DImode. */
455
456 int
457 mode_width_operand (op, mode)
458 register rtx op;
459 enum machine_mode mode ATTRIBUTE_UNUSED;
460 {
461 return (GET_CODE (op) == CONST_INT
462 && (INTVAL (op) == 8 || INTVAL (op) == 16
463 || INTVAL (op) == 32 || INTVAL (op) == 64));
464 }
465
466 /* Return 1 if OP is a constant that is the width of an integral machine mode
467 smaller than an integer. */
468
469 int
470 mode_mask_operand (op, mode)
471 register rtx op;
472 enum machine_mode mode ATTRIBUTE_UNUSED;
473 {
474 #if HOST_BITS_PER_WIDE_INT == 32
475 if (GET_CODE (op) == CONST_DOUBLE)
476 return (CONST_DOUBLE_LOW (op) == -1
477 && (CONST_DOUBLE_HIGH (op) == -1
478 || CONST_DOUBLE_HIGH (op) == 0));
479 #else
480 if (GET_CODE (op) == CONST_DOUBLE)
481 return (CONST_DOUBLE_LOW (op) == -1 && CONST_DOUBLE_HIGH (op) == 0);
482 #endif
483
484 return (GET_CODE (op) == CONST_INT
485 && (INTVAL (op) == 0xff
486 || INTVAL (op) == 0xffff
487 || INTVAL (op) == (HOST_WIDE_INT)0xffffffff
488 #if HOST_BITS_PER_WIDE_INT == 64
489 || INTVAL (op) == -1
490 #endif
491 ));
492 }
493
494 /* Return 1 if OP is a multiple of 8 less than 64. */
495
496 int
497 mul8_operand (op, mode)
498 register rtx op;
499 enum machine_mode mode ATTRIBUTE_UNUSED;
500 {
501 return (GET_CODE (op) == CONST_INT
502 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64
503 && (INTVAL (op) & 7) == 0);
504 }
505
506 /* Return 1 if OP is the constant zero in floating-point. */
507
508 int
509 fp0_operand (op, mode)
510 register rtx op;
511 enum machine_mode mode;
512 {
513 return (GET_MODE (op) == mode
514 && GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode));
515 }
516
517 /* Return 1 if OP is the floating-point constant zero or a register. */
518
519 int
520 reg_or_fp0_operand (op, mode)
521 register rtx op;
522 enum machine_mode mode;
523 {
524 return fp0_operand (op, mode) || register_operand (op, mode);
525 }
526
527 /* Return 1 if OP is a hard floating-point register. */
528
529 int
530 hard_fp_register_operand (op, mode)
531 register rtx op;
532 enum machine_mode mode;
533 {
534 return ((GET_CODE (op) == REG && REGNO_REG_CLASS (REGNO (op)) == FLOAT_REGS)
535 || (GET_CODE (op) == SUBREG
536 && hard_fp_register_operand (SUBREG_REG (op), mode)));
537 }
538
539 /* Return 1 if OP is a register or a constant integer. */
540
541
542 int
543 reg_or_cint_operand (op, mode)
544 register rtx op;
545 enum machine_mode mode;
546 {
547 return (GET_CODE (op) == CONST_INT
548 || register_operand (op, mode));
549 }
550
551 /* Return 1 if OP is something that can be reloaded into a register;
552 if it is a MEM, it need not be valid. */
553
554 int
555 some_operand (op, mode)
556 register rtx op;
557 enum machine_mode mode;
558 {
559 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
560 return 0;
561
562 switch (GET_CODE (op))
563 {
564 case REG: case MEM: case CONST_DOUBLE: case CONST_INT: case LABEL_REF:
565 case SYMBOL_REF: case CONST:
566 return 1;
567
568 case SUBREG:
569 return some_operand (SUBREG_REG (op), VOIDmode);
570
571 default:
572 break;
573 }
574
575 return 0;
576 }
577
578 /* Return 1 if OP is a valid operand for the source of a move insn. */
579
580 int
581 input_operand (op, mode)
582 register rtx op;
583 enum machine_mode mode;
584 {
585 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
586 return 0;
587
588 if (GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE (op) != mode)
589 return 0;
590
591 switch (GET_CODE (op))
592 {
593 case LABEL_REF:
594 case SYMBOL_REF:
595 case CONST:
596 /* This handles both the Windows/NT and OSF cases. */
597 return mode == ptr_mode || mode == DImode;
598
599 case REG:
600 return 1;
601
602 case SUBREG:
603 if (register_operand (op, mode))
604 return 1;
605 /* ... fall through ... */
606 case MEM:
607 return ((TARGET_BWX || (mode != HImode && mode != QImode))
608 && general_operand (op, mode));
609
610 case CONST_DOUBLE:
611 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
612
613 case CONST_INT:
614 return mode == QImode || mode == HImode || add_operand (op, mode);
615
616 case CONSTANT_P_RTX:
617 return 1;
618
619 default:
620 break;
621 }
622
623 return 0;
624 }
625
626 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
627 file. */
628
629 int
630 current_file_function_operand (op, mode)
631 rtx op;
632 enum machine_mode mode ATTRIBUTE_UNUSED;
633 {
634 return (GET_CODE (op) == SYMBOL_REF
635 && ! profile_flag && ! profile_block_flag
636 && (SYMBOL_REF_FLAG (op)
637 || op == XEXP (DECL_RTL (current_function_decl), 0)));
638 }
639
640 /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
641
642 int
643 call_operand (op, mode)
644 rtx op;
645 enum machine_mode mode;
646 {
647 if (mode != Pmode)
648 return 0;
649
650 return (GET_CODE (op) == SYMBOL_REF
651 || (GET_CODE (op) == REG
652 && (TARGET_OPEN_VMS || TARGET_WINDOWS_NT || REGNO (op) == 27)));
653 }
654
655 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
656 comparisons are valid in which insn. */
657
658 int
659 alpha_comparison_operator (op, mode)
660 register rtx op;
661 enum machine_mode mode;
662 {
663 enum rtx_code code = GET_CODE (op);
664
665 if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
666 return 0;
667
668 return (code == EQ || code == LE || code == LT
669 || (mode == DImode && (code == LEU || code == LTU)));
670 }
671
672 /* Return 1 if OP is a valid Alpha swapped comparison operator. */
673
674 int
675 alpha_swapped_comparison_operator (op, mode)
676 register rtx op;
677 enum machine_mode mode;
678 {
679 enum rtx_code code = GET_CODE (op);
680
681 if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
682 return 0;
683
684 code = swap_condition (code);
685 return (code == EQ || code == LE || code == LT
686 || (mode == DImode && (code == LEU || code == LTU)));
687 }
688
689 /* Return 1 if OP is a signed comparison operation. */
690
691 int
692 signed_comparison_operator (op, mode)
693 register rtx op;
694 enum machine_mode mode ATTRIBUTE_UNUSED;
695 {
696 switch (GET_CODE (op))
697 {
698 case EQ: case NE: case LE: case LT: case GE: case GT:
699 return 1;
700
701 default:
702 break;
703 }
704
705 return 0;
706 }
707
708 /* Return 1 if this is a divide or modulus operator. */
709
710 int
711 divmod_operator (op, mode)
712 register rtx op;
713 enum machine_mode mode ATTRIBUTE_UNUSED;
714 {
715 switch (GET_CODE (op))
716 {
717 case DIV: case MOD: case UDIV: case UMOD:
718 return 1;
719
720 default:
721 break;
722 }
723
724 return 0;
725 }
726
727 /* Return 1 if this memory address is a known aligned register plus
728 a constant. It must be a valid address. This means that we can do
729 this as an aligned reference plus some offset.
730
731 Take into account what reload will do.
732
733 We could say that out-of-range stack slots are alignable, but that would
734 complicate get_aligned_mem and it isn't worth the trouble since few
735 functions have large stack space. */
736
737 int
738 aligned_memory_operand (op, mode)
739 register rtx op;
740 enum machine_mode mode;
741 {
742 if (GET_CODE (op) == SUBREG)
743 {
744 if (GET_MODE (op) != mode)
745 return 0;
746 op = SUBREG_REG (op);
747 mode = GET_MODE (op);
748 }
749
750 if (reload_in_progress && GET_CODE (op) == REG
751 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
752 op = reg_equiv_mem[REGNO (op)];
753
754 if (GET_CODE (op) != MEM || GET_MODE (op) != mode
755 || ! memory_address_p (mode, XEXP (op, 0)))
756 return 0;
757
758 op = XEXP (op, 0);
759
760 if (GET_CODE (op) == PLUS)
761 op = XEXP (op, 0);
762
763 return (GET_CODE (op) == REG
764 && REGNO_POINTER_ALIGN (REGNO (op)) >= 4);
765 }
766
767 /* Similar, but return 1 if OP is a MEM which is not alignable. */
768
769 int
770 unaligned_memory_operand (op, mode)
771 register rtx op;
772 enum machine_mode mode;
773 {
774 if (GET_CODE (op) == SUBREG)
775 {
776 if (GET_MODE (op) != mode)
777 return 0;
778 op = SUBREG_REG (op);
779 mode = GET_MODE (op);
780 }
781
782 if (reload_in_progress && GET_CODE (op) == REG
783 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
784 op = reg_equiv_mem[REGNO (op)];
785
786 if (GET_CODE (op) != MEM || GET_MODE (op) != mode)
787 return 0;
788
789 op = XEXP (op, 0);
790
791 if (! memory_address_p (mode, op))
792 return 1;
793
794 if (GET_CODE (op) == PLUS)
795 op = XEXP (op, 0);
796
797 return (GET_CODE (op) != REG
798 || REGNO_POINTER_ALIGN (REGNO (op)) < 4);
799 }
800
801 /* Return 1 if OP is either a register or an unaligned memory location. */
802
803 int
804 reg_or_unaligned_mem_operand (op, mode)
805 rtx op;
806 enum machine_mode mode;
807 {
808 return register_operand (op, mode) || unaligned_memory_operand (op, mode);
809 }
810
811 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
812
813 int
814 any_memory_operand (op, mode)
815 register rtx op;
816 enum machine_mode mode ATTRIBUTE_UNUSED;
817 {
818 return (GET_CODE (op) == MEM
819 || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
820 || (reload_in_progress && GET_CODE (op) == REG
821 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
822 || (reload_in_progress && GET_CODE (op) == SUBREG
823 && GET_CODE (SUBREG_REG (op)) == REG
824 && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));
825 }
826
827 /* Returns 1 if OP is not an eliminable register.
828
829 This exists to cure a pathological abort in the s8addq (et al) patterns,
830
831 long foo () { long t; bar(); return (long) &t * 26107; }
832
833 which run afoul of a hack in reload to cure a (presumably) similar
834 problem with lea-type instructions on other targets. But there is
835 one of us and many of them, so work around the problem by selectively
836 preventing combine from making the optimization. */
837
838 int
839 reg_not_elim_operand (op, mode)
840 register rtx op;
841 enum machine_mode mode;
842 {
843 rtx inner = op;
844 if (GET_CODE (op) == SUBREG)
845 inner = SUBREG_REG (op);
846 if (inner == frame_pointer_rtx || inner == arg_pointer_rtx)
847 return 0;
848
849 return register_operand (op, mode);
850 }
851 \f
852 /* Return 1 if this function can directly return via $26. */
853
854 int
855 direct_return ()
856 {
857 return (! TARGET_OPEN_VMS && reload_completed && alpha_sa_size () == 0
858 && get_frame_size () == 0
859 && current_function_outgoing_args_size == 0
860 && current_function_pretend_args_size == 0);
861 }
862
863 /* Return 1 is OP is a memory location that is not an reference (using
864 an AND) to an unaligned location. Take into account what reload
865 will do. */
866
867 int
868 normal_memory_operand (op, mode)
869 register rtx op;
870 enum machine_mode mode;
871 {
872 if (reload_in_progress && GET_CODE (op) == REG
873 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
874 {
875 op = reg_equiv_mem[REGNO (op)];
876
877 /* This may not have been assigned an equivalent address if it will
878 be eliminated. In that case, it doesn't matter what we do. */
879 if (op == 0)
880 return 1;
881 }
882
883 return GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) != AND;
884 }
885
886 /* REF is an alignable memory location. Place an aligned SImode
887 reference into *PALIGNED_MEM and the number of bits to shift into
888 *PBITNUM. */
889
890 void
891 get_aligned_mem (ref, paligned_mem, pbitnum)
892 rtx ref;
893 rtx *paligned_mem, *pbitnum;
894 {
895 rtx base;
896 HOST_WIDE_INT offset = 0;
897
898 if (GET_CODE (ref) == SUBREG)
899 {
900 offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
901 if (BYTES_BIG_ENDIAN)
902 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
903 - MIN (UNITS_PER_WORD,
904 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
905 ref = SUBREG_REG (ref);
906 }
907
908 if (GET_CODE (ref) == REG)
909 ref = reg_equiv_mem[REGNO (ref)];
910
911 if (reload_in_progress)
912 base = find_replacement (&XEXP (ref, 0));
913 else
914 base = XEXP (ref, 0);
915
916 if (GET_CODE (base) == PLUS)
917 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
918
919 *paligned_mem = gen_rtx_MEM (SImode, plus_constant (base, offset & ~3));
920 MEM_COPY_ATTRIBUTES (*paligned_mem, ref);
921 RTX_UNCHANGING_P (*paligned_mem) = RTX_UNCHANGING_P (ref);
922
923 /* Sadly, we cannot use alias sets here because we may overlap other
924 data in a different alias set. */
925 /* MEM_ALIAS_SET (*paligned_mem) = MEM_ALIAS_SET (ref); */
926
927 *pbitnum = GEN_INT ((offset & 3) * 8);
928 }
929
930 /* Similar, but just get the address. Handle the two reload cases.
931 Add EXTRA_OFFSET to the address we return. */
932
933 rtx
934 get_unaligned_address (ref, extra_offset)
935 rtx ref;
936 int extra_offset;
937 {
938 rtx base;
939 HOST_WIDE_INT offset = 0;
940
941 if (GET_CODE (ref) == SUBREG)
942 {
943 offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
944 if (BYTES_BIG_ENDIAN)
945 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
946 - MIN (UNITS_PER_WORD,
947 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
948 ref = SUBREG_REG (ref);
949 }
950
951 if (GET_CODE (ref) == REG)
952 ref = reg_equiv_mem[REGNO (ref)];
953
954 if (reload_in_progress)
955 base = find_replacement (&XEXP (ref, 0));
956 else
957 base = XEXP (ref, 0);
958
959 if (GET_CODE (base) == PLUS)
960 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
961
962 return plus_constant (base, offset + extra_offset);
963 }
964 \f
965 /* Subfunction of the following function. Update the flags of any MEM
966 found in part of X. */
967
968 static void
969 alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
970 rtx x;
971 int in_struct_p, volatile_p, unchanging_p;
972 {
973 int i;
974
975 switch (GET_CODE (x))
976 {
977 case SEQUENCE:
978 case PARALLEL:
979 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
980 alpha_set_memflags_1 (XVECEXP (x, 0, i), in_struct_p, volatile_p,
981 unchanging_p);
982 break;
983
984 case INSN:
985 alpha_set_memflags_1 (PATTERN (x), in_struct_p, volatile_p,
986 unchanging_p);
987 break;
988
989 case SET:
990 alpha_set_memflags_1 (SET_DEST (x), in_struct_p, volatile_p,
991 unchanging_p);
992 alpha_set_memflags_1 (SET_SRC (x), in_struct_p, volatile_p,
993 unchanging_p);
994 break;
995
996 case MEM:
997 MEM_IN_STRUCT_P (x) = in_struct_p;
998 MEM_VOLATILE_P (x) = volatile_p;
999 RTX_UNCHANGING_P (x) = unchanging_p;
1000 /* Sadly, we cannot use alias sets because the extra aliasing
1001 produced by the AND interferes. Given that two-byte quantities
1002 are the only thing we would be able to differentiate anyway,
1003 there does not seem to be any point in convoluting the early
1004 out of the alias check. */
1005 /* MEM_ALIAS_SET (x) = alias_set; */
1006 break;
1007
1008 default:
1009 break;
1010 }
1011 }
1012
1013 /* Given INSN, which is either an INSN or a SEQUENCE generated to
1014 perform a memory operation, look for any MEMs in either a SET_DEST or
1015 a SET_SRC and copy the in-struct, unchanging, and volatile flags from
1016 REF into each of the MEMs found. If REF is not a MEM, don't do
1017 anything. */
1018
1019 void
1020 alpha_set_memflags (insn, ref)
1021 rtx insn;
1022 rtx ref;
1023 {
1024 int in_struct_p, volatile_p, unchanging_p;
1025
1026 if (GET_CODE (ref) != MEM)
1027 return;
1028
1029 in_struct_p = MEM_IN_STRUCT_P (ref);
1030 volatile_p = MEM_VOLATILE_P (ref);
1031 unchanging_p = RTX_UNCHANGING_P (ref);
1032
1033 /* This is only called from alpha.md, after having had something
1034 generated from one of the insn patterns. So if everything is
1035 zero, the pattern is already up-to-date. */
1036 if (! in_struct_p && ! volatile_p && ! unchanging_p)
1037 return;
1038
1039 alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
1040 }
1041 \f
1042 /* Try to output insns to set TARGET equal to the constant C if it can be
1043 done in less than N insns. Do all computations in MODE. Returns the place
1044 where the output has been placed if it can be done and the insns have been
1045 emitted. If it would take more than N insns, zero is returned and no
1046 insns and emitted. */
1047
1048 rtx
1049 alpha_emit_set_const (target, mode, c, n)
1050 rtx target;
1051 enum machine_mode mode;
1052 HOST_WIDE_INT c;
1053 int n;
1054 {
1055 rtx pat;
1056 int i;
1057
1058 /* Try 1 insn, then 2, then up to N. */
1059 for (i = 1; i <= n; i++)
1060 if ((pat = alpha_emit_set_const_1 (target, mode, c, i)) != 0)
1061 return pat;
1062
1063 return 0;
1064 }
1065
1066 /* Internal routine for the above to check for N or below insns. */
1067
1068 static rtx
1069 alpha_emit_set_const_1 (target, mode, c, n)
1070 rtx target;
1071 enum machine_mode mode;
1072 HOST_WIDE_INT c;
1073 int n;
1074 {
1075 HOST_WIDE_INT new = c;
1076 int i, bits;
1077 /* Use a pseudo if highly optimizing and still generating RTL. */
1078 rtx subtarget
1079 = (flag_expensive_optimizations && rtx_equal_function_value_matters
1080 ? 0 : target);
1081 rtx temp;
1082
1083 #if HOST_BITS_PER_WIDE_INT == 64
1084 /* We are only called for SImode and DImode. If this is SImode, ensure that
1085 we are sign extended to a full word. This does not make any sense when
1086 cross-compiling on a narrow machine. */
1087
1088 if (mode == SImode)
1089 c = (c & 0xffffffff) - 2 * (c & 0x80000000);
1090 #endif
1091
1092 /* If this is a sign-extended 32-bit constant, we can do this in at most
1093 three insns, so do it if we have enough insns left. We always have
1094 a sign-extended 32-bit constant when compiling on a narrow machine. */
1095
1096 if (HOST_BITS_PER_WIDE_INT != 64
1097 || c >> 31 == -1 || c >> 31 == 0)
1098 {
1099 HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
1100 HOST_WIDE_INT tmp1 = c - low;
1101 HOST_WIDE_INT high
1102 = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1103 HOST_WIDE_INT extra = 0;
1104
1105 /* If HIGH will be interpreted as negative but the constant is
1106 positive, we must adjust it to do two ldha insns. */
1107
1108 if ((high & 0x8000) != 0 && c >= 0)
1109 {
1110 extra = 0x4000;
1111 tmp1 -= 0x40000000;
1112 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1113 }
1114
1115 if (c == low || (low == 0 && extra == 0))
1116 {
1117 /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
1118 but that meant that we can't handle INT_MIN on 32-bit machines
1119 (like NT/Alpha), because we recurse indefinitely through
1120 emit_move_insn to gen_movdi. So instead, since we know exactly
1121 what we want, create it explicitly. */
1122
1123 if (target == NULL)
1124 target = gen_reg_rtx (mode);
1125 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (c)));
1126 return target;
1127 }
1128 else if (n >= 2 + (extra != 0))
1129 {
1130 temp = copy_to_suggested_reg (GEN_INT (low), subtarget, mode);
1131
1132 if (extra != 0)
1133 temp = expand_binop (mode, add_optab, temp, GEN_INT (extra << 16),
1134 subtarget, 0, OPTAB_WIDEN);
1135
1136 return expand_binop (mode, add_optab, temp, GEN_INT (high << 16),
1137 target, 0, OPTAB_WIDEN);
1138 }
1139 }
1140
1141 /* If we couldn't do it that way, try some other methods. But if we have
1142 no instructions left, don't bother. Likewise, if this is SImode and
1143 we can't make pseudos, we can't do anything since the expand_binop
1144 and expand_unop calls will widen and try to make pseudos. */
1145
1146 if (n == 1
1147 || (mode == SImode && ! rtx_equal_function_value_matters))
1148 return 0;
1149
1150 #if HOST_BITS_PER_WIDE_INT == 64
1151 /* First, see if can load a value into the target that is the same as the
1152 constant except that all bytes that are 0 are changed to be 0xff. If we
1153 can, then we can do a ZAPNOT to obtain the desired constant. */
1154
1155 for (i = 0; i < 64; i += 8)
1156 if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
1157 new |= (HOST_WIDE_INT) 0xff << i;
1158
1159 /* We are only called for SImode and DImode. If this is SImode, ensure that
1160 we are sign extended to a full word. */
1161
1162 if (mode == SImode)
1163 new = (new & 0xffffffff) - 2 * (new & 0x80000000);
1164
1165 if (new != c
1166 && (temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0)
1167 return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
1168 target, 0, OPTAB_WIDEN);
1169 #endif
1170
1171 /* Next, see if we can load a related constant and then shift and possibly
1172 negate it to get the constant we want. Try this once each increasing
1173 numbers of insns. */
1174
1175 for (i = 1; i < n; i++)
1176 {
1177 /* First try complementing. */
1178 if ((temp = alpha_emit_set_const (subtarget, mode, ~ c, i)) != 0)
1179 return expand_unop (mode, one_cmpl_optab, temp, target, 0);
1180
1181 /* Next try to form a constant and do a left shift. We can do this
1182 if some low-order bits are zero; the exact_log2 call below tells
1183 us that information. The bits we are shifting out could be any
1184 value, but here we'll just try the 0- and sign-extended forms of
1185 the constant. To try to increase the chance of having the same
1186 constant in more than one insn, start at the highest number of
1187 bits to shift, but try all possibilities in case a ZAPNOT will
1188 be useful. */
1189
1190 if ((bits = exact_log2 (c & - c)) > 0)
1191 for (; bits > 0; bits--)
1192 if ((temp = (alpha_emit_set_const
1193 (subtarget, mode,
1194 (unsigned HOST_WIDE_INT) (c >> bits), i))) != 0
1195 || ((temp = (alpha_emit_set_const
1196 (subtarget, mode,
1197 ((unsigned HOST_WIDE_INT) c) >> bits, i)))
1198 != 0))
1199 return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
1200 target, 0, OPTAB_WIDEN);
1201
1202 /* Now try high-order zero bits. Here we try the shifted-in bits as
1203 all zero and all ones. Be careful to avoid shifting outside the
1204 mode and to avoid shifting outside the host wide int size. */
1205 /* On narrow hosts, don't shift a 1 into the high bit, since we'll
1206 confuse the recursive call and set all of the high 32 bits. */
1207
1208 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1209 - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64))) > 0)
1210 for (; bits > 0; bits--)
1211 if ((temp = alpha_emit_set_const (subtarget, mode,
1212 c << bits, i)) != 0
1213 || ((temp = (alpha_emit_set_const
1214 (subtarget, mode,
1215 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1216 i)))
1217 != 0))
1218 return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
1219 target, 1, OPTAB_WIDEN);
1220
1221 /* Now try high-order 1 bits. We get that with a sign-extension.
1222 But one bit isn't enough here. Be careful to avoid shifting outside
1223 the mode and to avoid shifting outside the host wide int size. */
1224
1225 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1226 - floor_log2 (~ c) - 2)) > 0)
1227 for (; bits > 0; bits--)
1228 if ((temp = alpha_emit_set_const (subtarget, mode,
1229 c << bits, i)) != 0
1230 || ((temp = (alpha_emit_set_const
1231 (subtarget, mode,
1232 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1233 i)))
1234 != 0))
1235 return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
1236 target, 0, OPTAB_WIDEN);
1237 }
1238
1239 return 0;
1240 }
1241
1242 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
1243 fall back to a straight forward decomposition. We do this to avoid
1244 exponential run times encountered when looking for longer sequences
1245 with alpha_emit_set_const. */
1246
1247 rtx
1248 alpha_emit_set_long_const (target, c1, c2)
1249 rtx target;
1250 HOST_WIDE_INT c1, c2;
1251 {
1252 HOST_WIDE_INT d1, d2, d3, d4;
1253
1254 /* Decompose the entire word */
1255 #if HOST_BITS_PER_WIDE_INT >= 64
1256 if (c2 != -(c1 < 0))
1257 abort ();
1258 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1259 c1 -= d1;
1260 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1261 c1 = (c1 - d2) >> 32;
1262 d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1263 c1 -= d3;
1264 d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1265 if (c1 != d4)
1266 abort ();
1267 #else
1268 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1269 c1 -= d1;
1270 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1271 if (c1 != d2)
1272 abort ();
1273 c2 += (d2 < 0);
1274 d3 = ((c2 & 0xffff) ^ 0x8000) - 0x8000;
1275 c2 -= d3;
1276 d4 = ((c2 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1277 if (c2 != d4)
1278 abort ();
1279 #endif
1280
1281 /* Construct the high word */
1282 if (d4)
1283 {
1284 emit_move_insn (target, GEN_INT (d4));
1285 if (d3)
1286 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d3)));
1287 }
1288 else
1289 emit_move_insn (target, GEN_INT (d3));
1290
1291 /* Shift it into place */
1292 emit_move_insn (target, gen_rtx_ASHIFT (DImode, target, GEN_INT (32)));
1293
1294 /* Add in the low bits. */
1295 if (d2)
1296 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d2)));
1297 if (d1)
1298 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d1)));
1299
1300 return target;
1301 }
1302
1303 /* Generate the comparison for a conditional branch. */
1304
1305 rtx
1306 alpha_emit_conditional_branch (code)
1307 enum rtx_code code;
1308 {
1309 enum rtx_code cmp_code, branch_code;
1310 enum machine_mode cmp_mode, branch_mode = VOIDmode;
1311 rtx op0 = alpha_compare_op0, op1 = alpha_compare_op1;
1312 rtx tem;
1313
1314 /* The general case: fold the comparison code to the types of compares
1315 that we have, choosing the branch as necessary. */
1316 switch (code)
1317 {
1318 case EQ: case LE: case LT: case LEU: case LTU:
1319 /* We have these compares: */
1320 cmp_code = code, branch_code = NE;
1321 break;
1322
1323 case NE:
1324 /* This must be reversed. */
1325 cmp_code = EQ, branch_code = EQ;
1326 break;
1327
1328 case GE: case GT: case GEU: case GTU:
1329 /* For FP, we swap them, for INT, we reverse them. */
1330 if (alpha_compare_fp_p)
1331 {
1332 cmp_code = swap_condition (code);
1333 branch_code = NE;
1334 tem = op0, op0 = op1, op1 = tem;
1335 }
1336 else
1337 {
1338 cmp_code = reverse_condition (code);
1339 branch_code = EQ;
1340 }
1341 break;
1342
1343 default:
1344 abort ();
1345 }
1346
1347 if (alpha_compare_fp_p)
1348 {
1349 cmp_mode = DFmode;
1350 if (flag_fast_math)
1351 {
1352 /* When we are not as concerned about non-finite values, and we
1353 are comparing against zero, we can branch directly. */
1354 if (op1 == CONST0_RTX (DFmode))
1355 cmp_code = NIL, branch_code = code;
1356 else if (op0 == CONST0_RTX (DFmode))
1357 {
1358 /* Undo the swap we probably did just above. */
1359 tem = op0, op0 = op1, op1 = tem;
1360 branch_code = swap_condition (cmp_code);
1361 cmp_code = NIL;
1362 }
1363 }
1364 else
1365 {
1366 /* ??? We mark the the branch mode to be CCmode to prevent the
1367 compare and branch from being combined, since the compare
1368 insn follows IEEE rules that the branch does not. */
1369 branch_mode = CCmode;
1370 }
1371 }
1372 else
1373 {
1374 cmp_mode = DImode;
1375
1376 /* The following optimizations are only for signed compares. */
1377 if (code != LEU && code != LTU && code != GEU && code != GTU)
1378 {
1379 /* Whee. Compare and branch against 0 directly. */
1380 if (op1 == const0_rtx)
1381 cmp_code = NIL, branch_code = code;
1382
1383 /* We want to use cmpcc/bcc when we can, since there is a zero delay
1384 bypass between logicals and br/cmov on EV5. But we don't want to
1385 force valid immediate constants into registers needlessly. */
1386 else if (GET_CODE (op1) == CONST_INT)
1387 {
1388 HOST_WIDE_INT v = INTVAL (op1), n = -v;
1389
1390 if (! CONST_OK_FOR_LETTER_P (v, 'I')
1391 && (CONST_OK_FOR_LETTER_P (n, 'K')
1392 || CONST_OK_FOR_LETTER_P (n, 'L')))
1393 {
1394 cmp_code = PLUS, branch_code = code;
1395 op1 = GEN_INT (n);
1396 }
1397 }
1398 }
1399 }
1400
1401 /* Force op0 into a register. */
1402 if (GET_CODE (op0) != REG)
1403 op0 = force_reg (cmp_mode, op0);
1404
1405 /* Emit an initial compare instruction, if necessary. */
1406 tem = op0;
1407 if (cmp_code != NIL)
1408 {
1409 tem = gen_reg_rtx (cmp_mode);
1410 emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
1411 }
1412
1413 /* Return the branch comparison. */
1414 return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
1415 }
1416
1417
1418 /* Rewrite a comparison against zero CMP of the form
1419 (CODE (cc0) (const_int 0)) so it can be written validly in
1420 a conditional move (if_then_else CMP ...).
1421 If both of the operands that set cc0 are non-zero we must emit
1422 an insn to perform the compare (it can't be done within
1423 the conditional move). */
1424 rtx
1425 alpha_emit_conditional_move (cmp, mode)
1426 rtx cmp;
1427 enum machine_mode mode;
1428 {
1429 enum rtx_code code = GET_CODE (cmp);
1430 enum rtx_code cmov_code = NE;
1431 rtx op0 = alpha_compare_op0;
1432 rtx op1 = alpha_compare_op1;
1433 enum machine_mode cmp_mode
1434 = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
1435 enum machine_mode cmp_op_mode = alpha_compare_fp_p ? DFmode : DImode;
1436 enum machine_mode cmov_mode = VOIDmode;
1437 rtx tem;
1438
1439 if (alpha_compare_fp_p != FLOAT_MODE_P (mode))
1440 return 0;
1441
1442 /* We may be able to use a conditional move directly.
1443 This avoids emitting spurious compares. */
1444 if (signed_comparison_operator (cmp, cmp_op_mode)
1445 && (!alpha_compare_fp_p || flag_fast_math)
1446 && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
1447 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
1448
1449 /* We can't put the comparison insides a conditional move;
1450 emit a compare instruction and put that inside the
1451 conditional move. Make sure we emit only comparisons we have;
1452 swap or reverse as necessary. */
1453
1454 switch (code)
1455 {
1456 case EQ: case LE: case LT: case LEU: case LTU:
1457 /* We have these compares: */
1458 break;
1459
1460 case NE:
1461 /* This must be reversed. */
1462 code = reverse_condition (code);
1463 cmov_code = EQ;
1464 break;
1465
1466 case GE: case GT: case GEU: case GTU:
1467 /* These must be swapped. Make sure the new first operand is in
1468 a register. */
1469 code = swap_condition (code);
1470 tem = op0, op0 = op1, op1 = tem;
1471 op0 = force_reg (cmp_mode, op0);
1472 break;
1473
1474 default:
1475 abort ();
1476 }
1477
1478 /* ??? We mark the branch mode to be CCmode to prevent the compare
1479 and cmov from being combined, since the compare insn follows IEEE
1480 rules that the cmov does not. */
1481 if (alpha_compare_fp_p && !flag_fast_math)
1482 cmov_mode = CCmode;
1483
1484 tem = gen_reg_rtx (cmp_op_mode);
1485 emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
1486 return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
1487 }
1488 \f
1489 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
1490 unaligned data:
1491
1492 unsigned: signed:
1493 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
1494 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
1495 lda r3,X(r11) lda r3,X+2(r11)
1496 extwl r1,r3,r1 extql r1,r3,r1
1497 extwh r2,r3,r2 extqh r2,r3,r2
1498 or r1.r2.r1 or r1,r2,r1
1499 sra r1,48,r1
1500
1501 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
1502 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
1503 lda r3,X(r11) lda r3,X(r11)
1504 extll r1,r3,r1 extll r1,r3,r1
1505 extlh r2,r3,r2 extlh r2,r3,r2
1506 or r1.r2.r1 addl r1,r2,r1
1507
1508 quad: ldq_u r1,X(r11)
1509 ldq_u r2,X+7(r11)
1510 lda r3,X(r11)
1511 extql r1,r3,r1
1512 extqh r2,r3,r2
1513 or r1.r2.r1
1514 */
1515
1516 void
1517 alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
1518 rtx tgt, mem;
1519 HOST_WIDE_INT size, ofs;
1520 int sign;
1521 {
1522 rtx meml, memh, addr, extl, exth;
1523 enum machine_mode mode;
1524
1525 meml = gen_reg_rtx (DImode);
1526 memh = gen_reg_rtx (DImode);
1527 addr = gen_reg_rtx (DImode);
1528 extl = gen_reg_rtx (DImode);
1529 exth = gen_reg_rtx (DImode);
1530
1531 emit_move_insn (meml,
1532 change_address (mem, DImode,
1533 gen_rtx_AND (DImode,
1534 plus_constant (XEXP (mem, 0),
1535 ofs),
1536 GEN_INT (-8))));
1537
1538 emit_move_insn (memh,
1539 change_address (mem, DImode,
1540 gen_rtx_AND (DImode,
1541 plus_constant (XEXP (mem, 0),
1542 ofs + size - 1),
1543 GEN_INT (-8))));
1544
1545 if (sign && size == 2)
1546 {
1547 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs+2));
1548
1549 emit_insn (gen_extxl (extl, meml, GEN_INT (64), addr));
1550 emit_insn (gen_extqh (exth, memh, addr));
1551
1552 /* We must use tgt here for the target. Alpha-vms port fails if we use
1553 addr for the target, because addr is marked as a pointer and combine
1554 knows that pointers are always sign-extended 32 bit values. */
1555 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
1556 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48),
1557 addr, 1, OPTAB_WIDEN);
1558 }
1559 else
1560 {
1561 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs));
1562 emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr));
1563 switch (size)
1564 {
1565 case 2:
1566 emit_insn (gen_extwh (exth, memh, addr));
1567 mode = HImode;
1568 break;
1569
1570 case 4:
1571 emit_insn (gen_extlh (exth, memh, addr));
1572 mode = SImode;
1573 break;
1574
1575 case 8:
1576 emit_insn (gen_extqh (exth, memh, addr));
1577 mode = DImode;
1578 break;
1579 }
1580
1581 addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
1582 gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
1583 sign, OPTAB_WIDEN);
1584 }
1585
1586 if (addr != tgt)
1587 emit_move_insn (tgt, gen_lowpart(GET_MODE (tgt), addr));
1588 }
1589
1590 /* Similarly, use ins and msk instructions to perform unaligned stores. */
1591
1592 void
1593 alpha_expand_unaligned_store (dst, src, size, ofs)
1594 rtx dst, src;
1595 HOST_WIDE_INT size, ofs;
1596 {
1597 rtx dstl, dsth, addr, insl, insh, meml, memh;
1598
1599 dstl = gen_reg_rtx (DImode);
1600 dsth = gen_reg_rtx (DImode);
1601 insl = gen_reg_rtx (DImode);
1602 insh = gen_reg_rtx (DImode);
1603
1604 meml = change_address (dst, DImode,
1605 gen_rtx_AND (DImode,
1606 plus_constant (XEXP (dst, 0), ofs),
1607 GEN_INT (-8)));
1608 memh = change_address (dst, DImode,
1609 gen_rtx_AND (DImode,
1610 plus_constant (XEXP (dst, 0),
1611 ofs+size-1),
1612 GEN_INT (-8)));
1613
1614 emit_move_insn (dsth, memh);
1615 emit_move_insn (dstl, meml);
1616 addr = copy_addr_to_reg (plus_constant (XEXP (dst, 0), ofs));
1617
1618 if (src != const0_rtx)
1619 {
1620 emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
1621 GEN_INT (size*8), addr));
1622
1623 switch (size)
1624 {
1625 case 2:
1626 emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr));
1627 break;
1628 case 4:
1629 emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr));
1630 break;
1631 case 8:
1632 emit_insn (gen_insql (insl, src, addr));
1633 break;
1634 }
1635 }
1636
1637 emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
1638
1639 switch (size)
1640 {
1641 case 2:
1642 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffff), addr));
1643 break;
1644 case 4:
1645 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffffffff), addr));
1646 break;
1647 case 8:
1648 {
1649 #if HOST_BITS_PER_WIDE_INT == 32
1650 rtx msk = immed_double_const (0xffffffff, 0xffffffff, DImode);
1651 #else
1652 rtx msk = immed_double_const (0xffffffffffffffff, 0, DImode);
1653 #endif
1654 emit_insn (gen_mskxl (dstl, dstl, msk, addr));
1655 }
1656 break;
1657 }
1658
1659 if (src != const0_rtx)
1660 {
1661 dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
1662 dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
1663 }
1664
1665 /* Must store high before low for degenerate case of aligned. */
1666 emit_move_insn (memh, dsth);
1667 emit_move_insn (meml, dstl);
1668 }
1669
1670 /* The block move code tries to maximize speed by separating loads and
1671 stores at the expense of register pressure: we load all of the data
1672 before we store it back out. There are two secondary effects worth
1673 mentioning, that this speeds copying to/from aligned and unaligned
1674 buffers, and that it makes the code significantly easier to write. */
1675
1676 #define MAX_MOVE_WORDS 8
1677
1678 /* Load an integral number of consecutive unaligned quadwords. */
1679
1680 static void
1681 alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
1682 rtx *out_regs;
1683 rtx smem;
1684 HOST_WIDE_INT words, ofs;
1685 {
1686 rtx const im8 = GEN_INT (-8);
1687 rtx const i64 = GEN_INT (64);
1688 rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
1689 rtx sreg, areg;
1690 HOST_WIDE_INT i;
1691
1692 /* Generate all the tmp registers we need. */
1693 for (i = 0; i < words; ++i)
1694 {
1695 data_regs[i] = out_regs[i];
1696 ext_tmps[i] = gen_reg_rtx (DImode);
1697 }
1698 data_regs[words] = gen_reg_rtx (DImode);
1699
1700 if (ofs != 0)
1701 smem = change_address (smem, GET_MODE (smem),
1702 plus_constant (XEXP (smem, 0), ofs));
1703
1704 /* Load up all of the source data. */
1705 for (i = 0; i < words; ++i)
1706 {
1707 emit_move_insn (data_regs[i],
1708 change_address (smem, DImode,
1709 gen_rtx_AND (DImode,
1710 plus_constant (XEXP(smem,0),
1711 8*i),
1712 im8)));
1713 }
1714 emit_move_insn (data_regs[words],
1715 change_address (smem, DImode,
1716 gen_rtx_AND (DImode,
1717 plus_constant (XEXP(smem,0),
1718 8*words - 1),
1719 im8)));
1720
1721 /* Extract the half-word fragments. Unfortunately DEC decided to make
1722 extxh with offset zero a noop instead of zeroing the register, so
1723 we must take care of that edge condition ourselves with cmov. */
1724
1725 sreg = copy_addr_to_reg (XEXP (smem, 0));
1726 areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
1727 1, OPTAB_WIDEN);
1728 for (i = 0; i < words; ++i)
1729 {
1730 emit_insn (gen_extxl (data_regs[i], data_regs[i], i64, sreg));
1731
1732 emit_insn (gen_extqh (ext_tmps[i], data_regs[i+1], sreg));
1733 emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
1734 gen_rtx_IF_THEN_ELSE (DImode,
1735 gen_rtx_EQ (DImode, areg,
1736 const0_rtx),
1737 const0_rtx, ext_tmps[i])));
1738 }
1739
1740 /* Merge the half-words into whole words. */
1741 for (i = 0; i < words; ++i)
1742 {
1743 out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
1744 ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
1745 }
1746 }
1747
1748 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
1749 may be NULL to store zeros. */
1750
1751 static void
1752 alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
1753 rtx *data_regs;
1754 rtx dmem;
1755 HOST_WIDE_INT words, ofs;
1756 {
1757 rtx const im8 = GEN_INT (-8);
1758 rtx const i64 = GEN_INT (64);
1759 #if HOST_BITS_PER_WIDE_INT == 32
1760 rtx const im1 = immed_double_const (0xffffffff, 0xffffffff, DImode);
1761 #else
1762 rtx const im1 = immed_double_const (0xffffffffffffffff, 0, DImode);
1763 #endif
1764 rtx ins_tmps[MAX_MOVE_WORDS];
1765 rtx st_tmp_1, st_tmp_2, dreg;
1766 rtx st_addr_1, st_addr_2;
1767 HOST_WIDE_INT i;
1768
1769 /* Generate all the tmp registers we need. */
1770 if (data_regs != NULL)
1771 for (i = 0; i < words; ++i)
1772 ins_tmps[i] = gen_reg_rtx(DImode);
1773 st_tmp_1 = gen_reg_rtx(DImode);
1774 st_tmp_2 = gen_reg_rtx(DImode);
1775
1776 if (ofs != 0)
1777 dmem = change_address (dmem, GET_MODE (dmem),
1778 plus_constant (XEXP (dmem, 0), ofs));
1779
1780
1781 st_addr_2 = change_address (dmem, DImode,
1782 gen_rtx_AND (DImode,
1783 plus_constant (XEXP(dmem,0),
1784 words*8 - 1),
1785 im8));
1786 st_addr_1 = change_address (dmem, DImode,
1787 gen_rtx_AND (DImode,
1788 XEXP (dmem, 0),
1789 im8));
1790
1791 /* Load up the destination end bits. */
1792 emit_move_insn (st_tmp_2, st_addr_2);
1793 emit_move_insn (st_tmp_1, st_addr_1);
1794
1795 /* Shift the input data into place. */
1796 dreg = copy_addr_to_reg (XEXP (dmem, 0));
1797 if (data_regs != NULL)
1798 {
1799 for (i = words-1; i >= 0; --i)
1800 {
1801 emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
1802 emit_insn (gen_insql (data_regs[i], data_regs[i], dreg));
1803 }
1804 for (i = words-1; i > 0; --i)
1805 {
1806 ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
1807 ins_tmps[i-1], ins_tmps[i-1], 1,
1808 OPTAB_WIDEN);
1809 }
1810 }
1811
1812 /* Split and merge the ends with the destination data. */
1813 emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
1814 emit_insn (gen_mskxl (st_tmp_1, st_tmp_1, im1, dreg));
1815
1816 if (data_regs != NULL)
1817 {
1818 st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
1819 st_tmp_2, 1, OPTAB_WIDEN);
1820 st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
1821 st_tmp_1, 1, OPTAB_WIDEN);
1822 }
1823
1824 /* Store it all. */
1825 emit_move_insn (st_addr_2, st_tmp_2);
1826 for (i = words-1; i > 0; --i)
1827 {
1828 emit_move_insn (change_address (dmem, DImode,
1829 gen_rtx_AND (DImode,
1830 plus_constant(XEXP (dmem,0),
1831 i*8),
1832 im8)),
1833 data_regs ? ins_tmps[i-1] : const0_rtx);
1834 }
1835 emit_move_insn (st_addr_1, st_tmp_1);
1836 }
1837
1838
1839 /* Expand string/block move operations.
1840
1841 operands[0] is the pointer to the destination.
1842 operands[1] is the pointer to the source.
1843 operands[2] is the number of bytes to move.
1844 operands[3] is the alignment. */
1845
1846 int
1847 alpha_expand_block_move (operands)
1848 rtx operands[];
1849 {
1850 rtx bytes_rtx = operands[2];
1851 rtx align_rtx = operands[3];
1852 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
1853 HOST_WIDE_INT bytes = orig_bytes;
1854 HOST_WIDE_INT src_align = INTVAL (align_rtx);
1855 HOST_WIDE_INT dst_align = src_align;
1856 rtx orig_src = operands[1];
1857 rtx orig_dst = operands[0];
1858 rtx data_regs[2*MAX_MOVE_WORDS+16];
1859 rtx tmp;
1860 int i, words, ofs, nregs = 0;
1861
1862 if (bytes <= 0)
1863 return 1;
1864 if (bytes > MAX_MOVE_WORDS*8)
1865 return 0;
1866
1867 /* Look for additional alignment information from recorded register info. */
1868
1869 tmp = XEXP (orig_src, 0);
1870 if (GET_CODE (tmp) == REG)
1871 {
1872 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > src_align)
1873 src_align = REGNO_POINTER_ALIGN (REGNO (tmp));
1874 }
1875 else if (GET_CODE (tmp) == PLUS
1876 && GET_CODE (XEXP (tmp, 0)) == REG
1877 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
1878 {
1879 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
1880 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
1881
1882 if (a > src_align)
1883 {
1884 if (a >= 8 && c % 8 == 0)
1885 src_align = 8;
1886 else if (a >= 4 && c % 4 == 0)
1887 src_align = 4;
1888 else if (a >= 2 && c % 2 == 0)
1889 src_align = 2;
1890 }
1891 }
1892
1893 tmp = XEXP (orig_dst, 0);
1894 if (GET_CODE (tmp) == REG)
1895 {
1896 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > dst_align)
1897 dst_align = REGNO_POINTER_ALIGN (REGNO (tmp));
1898 }
1899 else if (GET_CODE (tmp) == PLUS
1900 && GET_CODE (XEXP (tmp, 0)) == REG
1901 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
1902 {
1903 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
1904 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
1905
1906 if (a > dst_align)
1907 {
1908 if (a >= 8 && c % 8 == 0)
1909 dst_align = 8;
1910 else if (a >= 4 && c % 4 == 0)
1911 dst_align = 4;
1912 else if (a >= 2 && c % 2 == 0)
1913 dst_align = 2;
1914 }
1915 }
1916
1917 /*
1918 * Load the entire block into registers.
1919 */
1920
1921 if (GET_CODE (XEXP (orig_src, 0)) == ADDRESSOF)
1922 {
1923 enum machine_mode mode;
1924 tmp = XEXP (XEXP (orig_src, 0), 0);
1925
1926 mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);
1927 if (mode != BLKmode
1928 && GET_MODE_SIZE (GET_MODE (tmp)) <= bytes)
1929 {
1930 /* Whee! Optimize the load to use the existing register. */
1931 data_regs[nregs++] = gen_lowpart (mode, tmp);
1932 goto src_done;
1933 }
1934
1935 /* ??? We could potentially be copying 3 bytes or whatnot from
1936 a wider reg. Probably not worth worrying about. */
1937 /* No appropriate mode; fall back on memory. */
1938 orig_src = change_address (orig_src, GET_MODE (orig_src),
1939 copy_addr_to_reg (XEXP (orig_src, 0)));
1940 }
1941
1942 ofs = 0;
1943 if (src_align >= 8 && bytes >= 8)
1944 {
1945 words = bytes / 8;
1946
1947 for (i = 0; i < words; ++i)
1948 data_regs[nregs+i] = gen_reg_rtx(DImode);
1949
1950 for (i = 0; i < words; ++i)
1951 {
1952 emit_move_insn (data_regs[nregs+i],
1953 change_address(orig_src, DImode,
1954 plus_constant (XEXP (orig_src, 0),
1955 ofs + i*8)));
1956 }
1957
1958 nregs += words;
1959 bytes -= words * 8;
1960 ofs += words * 8;
1961 }
1962 if (src_align >= 4 && bytes >= 4)
1963 {
1964 words = bytes / 4;
1965
1966 for (i = 0; i < words; ++i)
1967 data_regs[nregs+i] = gen_reg_rtx(SImode);
1968
1969 for (i = 0; i < words; ++i)
1970 {
1971 emit_move_insn (data_regs[nregs+i],
1972 change_address(orig_src, SImode,
1973 plus_constant (XEXP (orig_src, 0),
1974 ofs + i*4)));
1975 }
1976
1977 nregs += words;
1978 bytes -= words * 4;
1979 ofs += words * 4;
1980 }
1981 if (bytes >= 16)
1982 {
1983 words = bytes / 8;
1984
1985 for (i = 0; i < words+1; ++i)
1986 data_regs[nregs+i] = gen_reg_rtx(DImode);
1987
1988 alpha_expand_unaligned_load_words(data_regs+nregs, orig_src, words, ofs);
1989
1990 nregs += words;
1991 bytes -= words * 8;
1992 ofs += words * 8;
1993 }
1994 if (!TARGET_BWX && bytes >= 8)
1995 {
1996 data_regs[nregs++] = tmp = gen_reg_rtx (DImode);
1997 alpha_expand_unaligned_load (tmp, orig_src, 8, ofs, 0);
1998 bytes -= 8;
1999 ofs += 8;
2000 }
2001 if (!TARGET_BWX && bytes >= 4)
2002 {
2003 data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
2004 alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
2005 bytes -= 4;
2006 ofs += 4;
2007 }
2008 if (bytes >= 2)
2009 {
2010 if (src_align >= 2)
2011 {
2012 do {
2013 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
2014 emit_move_insn (tmp,
2015 change_address (orig_src, HImode,
2016 plus_constant (XEXP (orig_src, 0),
2017 ofs)));
2018 bytes -= 2;
2019 ofs += 2;
2020 } while (bytes >= 2);
2021 }
2022 else if (!TARGET_BWX)
2023 {
2024 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
2025 alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
2026 bytes -= 2;
2027 ofs += 2;
2028 }
2029 }
2030 while (bytes > 0)
2031 {
2032 data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
2033 emit_move_insn (tmp,
2034 change_address (orig_src, QImode,
2035 plus_constant (XEXP (orig_src, 0),
2036 ofs)));
2037 bytes -= 1;
2038 ofs += 1;
2039 }
2040 src_done:
2041
2042 if (nregs > (int)(sizeof(data_regs)/sizeof(*data_regs)))
2043 abort();
2044
2045 /*
2046 * Now save it back out again.
2047 */
2048
2049 i = 0, ofs = 0;
2050
2051 if (GET_CODE (XEXP (orig_dst, 0)) == ADDRESSOF)
2052 {
2053 enum machine_mode mode;
2054 tmp = XEXP (XEXP (orig_dst, 0), 0);
2055
2056 mode = mode_for_size (orig_bytes * BITS_PER_UNIT, MODE_INT, 1);
2057 if (GET_MODE (tmp) == mode && nregs == 1)
2058 {
2059 emit_move_insn (tmp, data_regs[0]);
2060 i = 1;
2061 goto dst_done;
2062 }
2063
2064 /* ??? If nregs > 1, consider reconstructing the word in regs. */
2065 /* ??? Optimize mode < dst_mode with strict_low_part. */
2066
2067 /* No appropriate mode; fall back on memory. We can speed things
2068 up by recognizing extra alignment information. */
2069 orig_dst = change_address (orig_dst, GET_MODE (orig_dst),
2070 copy_addr_to_reg (XEXP (orig_dst, 0)));
2071 dst_align = GET_MODE_SIZE (GET_MODE (tmp));
2072 }
2073
2074 /* Write out the data in whatever chunks reading the source allowed. */
2075 if (dst_align >= 8)
2076 {
2077 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2078 {
2079 emit_move_insn (change_address(orig_dst, DImode,
2080 plus_constant (XEXP (orig_dst, 0),
2081 ofs)),
2082 data_regs[i]);
2083 ofs += 8;
2084 i++;
2085 }
2086 }
2087 if (dst_align >= 4)
2088 {
2089 /* If the source has remaining DImode regs, write them out in
2090 two pieces. */
2091 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2092 {
2093 tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
2094 NULL_RTX, 1, OPTAB_WIDEN);
2095
2096 emit_move_insn (change_address(orig_dst, SImode,
2097 plus_constant (XEXP (orig_dst, 0),
2098 ofs)),
2099 gen_lowpart (SImode, data_regs[i]));
2100 emit_move_insn (change_address(orig_dst, SImode,
2101 plus_constant (XEXP (orig_dst, 0),
2102 ofs+4)),
2103 gen_lowpart (SImode, tmp));
2104 ofs += 8;
2105 i++;
2106 }
2107
2108 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2109 {
2110 emit_move_insn (change_address(orig_dst, SImode,
2111 plus_constant (XEXP (orig_dst, 0),
2112 ofs)),
2113 data_regs[i]);
2114 ofs += 4;
2115 i++;
2116 }
2117 }
2118 if (i < nregs && GET_MODE (data_regs[i]) == DImode)
2119 {
2120 /* Write out a remaining block of words using unaligned methods. */
2121
2122 for (words = 1; i+words < nregs ; ++words)
2123 if (GET_MODE (data_regs[i+words]) != DImode)
2124 break;
2125
2126 if (words == 1)
2127 alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
2128 else
2129 alpha_expand_unaligned_store_words (data_regs+i, orig_dst, words, ofs);
2130
2131 i += words;
2132 ofs += words * 8;
2133 }
2134
2135 /* Due to the above, this won't be aligned. */
2136 /* ??? If we have more than one of these, consider constructing full
2137 words in registers and using alpha_expand_unaligned_store_words. */
2138 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2139 {
2140 alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
2141 ofs += 4;
2142 i++;
2143 }
2144
2145 if (dst_align >= 2)
2146 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2147 {
2148 emit_move_insn (change_address (orig_dst, HImode,
2149 plus_constant (XEXP (orig_dst, 0),
2150 ofs)),
2151 data_regs[i]);
2152 i++;
2153 ofs += 2;
2154 }
2155 else
2156 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2157 {
2158 alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
2159 i++;
2160 ofs += 2;
2161 }
2162 while (i < nregs && GET_MODE (data_regs[i]) == QImode)
2163 {
2164 emit_move_insn (change_address (orig_dst, QImode,
2165 plus_constant (XEXP (orig_dst, 0),
2166 ofs)),
2167 data_regs[i]);
2168 i++;
2169 ofs += 1;
2170 }
2171 dst_done:
2172
2173 if (i != nregs)
2174 abort();
2175
2176 return 1;
2177 }
2178
2179 int
2180 alpha_expand_block_clear (operands)
2181 rtx operands[];
2182 {
2183 rtx bytes_rtx = operands[1];
2184 rtx align_rtx = operands[2];
2185 HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
2186 HOST_WIDE_INT align = INTVAL (align_rtx);
2187 rtx orig_dst = operands[0];
2188 rtx tmp;
2189 HOST_WIDE_INT i, words, ofs = 0;
2190
2191 if (bytes <= 0)
2192 return 1;
2193 if (bytes > MAX_MOVE_WORDS*8)
2194 return 0;
2195
2196 /* Look for stricter alignment. */
2197
2198 tmp = XEXP (orig_dst, 0);
2199 if (GET_CODE (tmp) == REG)
2200 {
2201 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > align)
2202 align = REGNO_POINTER_ALIGN (REGNO (tmp));
2203 }
2204 else if (GET_CODE (tmp) == PLUS
2205 && GET_CODE (XEXP (tmp, 0)) == REG
2206 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2207 {
2208 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2209 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2210
2211 if (a > align)
2212 {
2213 if (a >= 8 && c % 8 == 0)
2214 align = 8;
2215 else if (a >= 4 && c % 4 == 0)
2216 align = 4;
2217 else if (a >= 2 && c % 2 == 0)
2218 align = 2;
2219 }
2220 }
2221
2222 /* Handle a block of contiguous words first. */
2223
2224 if (align >= 8 && bytes >= 8)
2225 {
2226 words = bytes / 8;
2227
2228 for (i = 0; i < words; ++i)
2229 {
2230 emit_move_insn (change_address(orig_dst, DImode,
2231 plus_constant (XEXP (orig_dst, 0),
2232 ofs + i*8)),
2233 const0_rtx);
2234 }
2235
2236 bytes -= words * 8;
2237 ofs += words * 8;
2238 }
2239 if (align >= 4 && bytes >= 4)
2240 {
2241 words = bytes / 4;
2242
2243 for (i = 0; i < words; ++i)
2244 {
2245 emit_move_insn (change_address(orig_dst, SImode,
2246 plus_constant (XEXP (orig_dst, 0),
2247 ofs + i*4)),
2248 const0_rtx);
2249 }
2250
2251 bytes -= words * 4;
2252 ofs += words * 4;
2253 }
2254 if (bytes >= 16)
2255 {
2256 words = bytes / 8;
2257
2258 alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
2259
2260 bytes -= words * 8;
2261 ofs += words * 8;
2262 }
2263
2264 /* Next clean up any trailing pieces. We know from the contiguous
2265 block move that there are no aligned SImode or DImode hunks left. */
2266
2267 if (!TARGET_BWX && bytes >= 8)
2268 {
2269 alpha_expand_unaligned_store (orig_dst, const0_rtx, 8, ofs);
2270 bytes -= 8;
2271 ofs += 8;
2272 }
2273 if (!TARGET_BWX && bytes >= 4)
2274 {
2275 alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
2276 bytes -= 4;
2277 ofs += 4;
2278 }
2279 if (bytes >= 2)
2280 {
2281 if (align >= 2)
2282 {
2283 do {
2284 emit_move_insn (change_address (orig_dst, HImode,
2285 plus_constant (XEXP (orig_dst, 0),
2286 ofs)),
2287 const0_rtx);
2288 bytes -= 2;
2289 ofs += 2;
2290 } while (bytes >= 2);
2291 }
2292 else if (!TARGET_BWX)
2293 {
2294 alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
2295 bytes -= 2;
2296 ofs += 2;
2297 }
2298 }
2299 while (bytes > 0)
2300 {
2301 emit_move_insn (change_address (orig_dst, QImode,
2302 plus_constant (XEXP (orig_dst, 0),
2303 ofs)),
2304 const0_rtx);
2305 bytes -= 1;
2306 ofs += 1;
2307 }
2308
2309 return 1;
2310 }
2311
2312 \f
2313 /* Adjust the cost of a scheduling dependency. Return the new cost of
2314 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
2315
2316 int
2317 alpha_adjust_cost (insn, link, dep_insn, cost)
2318 rtx insn;
2319 rtx link;
2320 rtx dep_insn;
2321 int cost;
2322 {
2323 rtx set, set_src;
2324 enum attr_type insn_type, dep_insn_type;
2325
2326 /* If the dependence is an anti-dependence, there is no cost. For an
2327 output dependence, there is sometimes a cost, but it doesn't seem
2328 worth handling those few cases. */
2329
2330 if (REG_NOTE_KIND (link) != 0)
2331 return 0;
2332
2333 /* If we can't recognize the insns, we can't really do anything. */
2334 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
2335 return cost;
2336
2337 insn_type = get_attr_type (insn);
2338 dep_insn_type = get_attr_type (dep_insn);
2339
2340 /* Bring in the user-defined memory latency. */
2341 if (dep_insn_type == TYPE_ILD
2342 || dep_insn_type == TYPE_FLD
2343 || dep_insn_type == TYPE_LDSYM)
2344 cost += alpha_memory_latency-1;
2345
2346 switch (alpha_cpu)
2347 {
2348 case PROCESSOR_EV4:
2349 /* On EV4, if INSN is a store insn and DEP_INSN is setting the data
2350 being stored, we can sometimes lower the cost. */
2351
2352 if ((insn_type == TYPE_IST || insn_type == TYPE_FST)
2353 && (set = single_set (dep_insn)) != 0
2354 && GET_CODE (PATTERN (insn)) == SET
2355 && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
2356 {
2357 switch (dep_insn_type)
2358 {
2359 case TYPE_ILD:
2360 case TYPE_FLD:
2361 /* No savings here. */
2362 return cost;
2363
2364 case TYPE_IMUL:
2365 /* In these cases, we save one cycle. */
2366 return cost - 1;
2367
2368 default:
2369 /* In all other cases, we save two cycles. */
2370 return MAX (0, cost - 2);
2371 }
2372 }
2373
2374 /* Another case that needs adjustment is an arithmetic or logical
2375 operation. It's cost is usually one cycle, but we default it to
2376 two in the MD file. The only case that it is actually two is
2377 for the address in loads, stores, and jumps. */
2378
2379 if (dep_insn_type == TYPE_IADD || dep_insn_type == TYPE_ILOG)
2380 {
2381 switch (insn_type)
2382 {
2383 case TYPE_ILD:
2384 case TYPE_IST:
2385 case TYPE_FLD:
2386 case TYPE_FST:
2387 case TYPE_JSR:
2388 return cost;
2389 default:
2390 return 1;
2391 }
2392 }
2393
2394 /* The final case is when a compare feeds into an integer branch;
2395 the cost is only one cycle in that case. */
2396
2397 if (dep_insn_type == TYPE_ICMP && insn_type == TYPE_IBR)
2398 return 1;
2399 break;
2400
2401 case PROCESSOR_EV5:
2402 /* And the lord DEC saith: "A special bypass provides an effective
2403 latency of 0 cycles for an ICMP or ILOG insn producing the test
2404 operand of an IBR or ICMOV insn." */
2405
2406 if ((dep_insn_type == TYPE_ICMP || dep_insn_type == TYPE_ILOG)
2407 && (set = single_set (dep_insn)) != 0)
2408 {
2409 /* A branch only has one input. This must be it. */
2410 if (insn_type == TYPE_IBR)
2411 return 0;
2412 /* A conditional move has three, make sure it is the test. */
2413 if (insn_type == TYPE_ICMOV
2414 && GET_CODE (set_src = PATTERN (insn)) == SET
2415 && GET_CODE (set_src = SET_SRC (set_src)) == IF_THEN_ELSE
2416 && rtx_equal_p (SET_DEST (set), XEXP (set_src, 0)))
2417 return 0;
2418 }
2419
2420 /* "The multiplier is unable to receive data from IEU bypass paths.
2421 The instruction issues at the expected time, but its latency is
2422 increased by the time it takes for the input data to become
2423 available to the multiplier" -- which happens in pipeline stage
2424 six, when results are comitted to the register file. */
2425
2426 if (insn_type == TYPE_IMUL)
2427 {
2428 switch (dep_insn_type)
2429 {
2430 /* These insns produce their results in pipeline stage five. */
2431 case TYPE_ILD:
2432 case TYPE_ICMOV:
2433 case TYPE_IMUL:
2434 case TYPE_MVI:
2435 return cost + 1;
2436
2437 /* Other integer insns produce results in pipeline stage four. */
2438 default:
2439 return cost + 2;
2440 }
2441 }
2442 break;
2443
2444 case PROCESSOR_EV6:
2445 /* There is additional latency to move the result of (most) FP
2446 operations anywhere but the FP register file. */
2447
2448 if ((insn_type == TYPE_FST || insn_type == TYPE_FTOI)
2449 && (dep_insn_type == TYPE_FADD ||
2450 dep_insn_type == TYPE_FMUL ||
2451 dep_insn_type == TYPE_FCMOV))
2452 return cost + 2;
2453
2454 break;
2455 }
2456
2457 /* Otherwise, return the default cost. */
2458 return cost;
2459 }
2460 \f
2461 /* Functions to save and restore alpha_return_addr_rtx. */
2462
2463 struct machine_function
2464 {
2465 rtx ra_rtx;
2466 };
2467
2468 static void
2469 alpha_save_machine_status (p)
2470 struct function *p;
2471 {
2472 struct machine_function *machine =
2473 (struct machine_function *) xmalloc (sizeof (struct machine_function));
2474
2475 p->machine = machine;
2476 machine->ra_rtx = alpha_return_addr_rtx;
2477 }
2478
2479 static void
2480 alpha_restore_machine_status (p)
2481 struct function *p;
2482 {
2483 struct machine_function *machine = p->machine;
2484
2485 alpha_return_addr_rtx = machine->ra_rtx;
2486
2487 free (machine);
2488 p->machine = (struct machine_function *)0;
2489 }
2490
2491 /* Do anything needed before RTL is emitted for each function. */
2492
2493 void
2494 alpha_init_expanders ()
2495 {
2496 alpha_return_addr_rtx = NULL_RTX;
2497 alpha_eh_epilogue_sp_ofs = NULL_RTX;
2498
2499 /* Arrange to save and restore machine status around nested functions. */
2500 save_machine_status = alpha_save_machine_status;
2501 restore_machine_status = alpha_restore_machine_status;
2502 }
2503
2504 /* Start the ball rolling with RETURN_ADDR_RTX. */
2505
2506 rtx
2507 alpha_return_addr (count, frame)
2508 int count;
2509 rtx frame ATTRIBUTE_UNUSED;
2510 {
2511 rtx init;
2512
2513 if (count != 0)
2514 return const0_rtx;
2515
2516 if (alpha_return_addr_rtx)
2517 return alpha_return_addr_rtx;
2518
2519 /* No rtx yet. Invent one, and initialize it from $26 in the prologue. */
2520 alpha_return_addr_rtx = gen_reg_rtx (Pmode);
2521 init = gen_rtx_SET (VOIDmode, alpha_return_addr_rtx,
2522 gen_rtx_REG (Pmode, REG_RA));
2523
2524 /* Emit the insn to the prologue with the other argument copies. */
2525 push_topmost_sequence ();
2526 emit_insn_after (init, get_insns ());
2527 pop_topmost_sequence ();
2528
2529 return alpha_return_addr_rtx;
2530 }
2531
2532 static int
2533 alpha_ra_ever_killed ()
2534 {
2535 rtx top;
2536
2537 #ifdef ASM_OUTPUT_MI_THUNK
2538 if (current_function_is_thunk)
2539 return 0;
2540 #endif
2541 if (!alpha_return_addr_rtx)
2542 return regs_ever_live[REG_RA];
2543
2544 push_topmost_sequence ();
2545 top = get_insns ();
2546 pop_topmost_sequence ();
2547
2548 return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX);
2549 }
2550
2551 \f
2552 /* Print an operand. Recognize special options, documented below. */
2553
2554 void
2555 print_operand (file, x, code)
2556 FILE *file;
2557 rtx x;
2558 char code;
2559 {
2560 int i;
2561
2562 switch (code)
2563 {
2564 case '&':
2565 /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
2566 chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
2567 mode. alpha_fprm controls which suffix is generated. */
2568 switch (alpha_fprm)
2569 {
2570 case ALPHA_FPRM_NORM:
2571 break;
2572 case ALPHA_FPRM_MINF:
2573 fputc ('m', file);
2574 break;
2575 case ALPHA_FPRM_CHOP:
2576 fputc ('c', file);
2577 break;
2578 case ALPHA_FPRM_DYN:
2579 fputc ('d', file);
2580 break;
2581 }
2582 break;
2583
2584 case '\'':
2585 /* Generates trap-mode suffix for instructions that accept the su
2586 suffix only (cmpt et al). */
2587 if (alpha_tp == ALPHA_TP_INSN)
2588 fputs ("su", file);
2589 break;
2590
2591 case '`':
2592 /* Generates trap-mode suffix for instructions that accept the
2593 v and sv suffix. The only instruction that needs this is cvtql. */
2594 switch (alpha_fptm)
2595 {
2596 case ALPHA_FPTM_N:
2597 break;
2598 case ALPHA_FPTM_U:
2599 fputs ("v", file);
2600 break;
2601 case ALPHA_FPTM_SU:
2602 case ALPHA_FPTM_SUI:
2603 fputs ("sv", file);
2604 break;
2605 }
2606 break;
2607
2608 case '(':
2609 /* Generates trap-mode suffix for instructions that accept the
2610 v, sv, and svi suffix. The only instruction that needs this
2611 is cvttq. */
2612 switch (alpha_fptm)
2613 {
2614 case ALPHA_FPTM_N:
2615 break;
2616 case ALPHA_FPTM_U:
2617 fputs ("v", file);
2618 break;
2619 case ALPHA_FPTM_SU:
2620 fputs ("sv", file);
2621 break;
2622 case ALPHA_FPTM_SUI:
2623 fputs ("svi", file);
2624 break;
2625 }
2626 break;
2627
2628 case ')':
2629 /* Generates trap-mode suffix for instructions that accept the u, su,
2630 and sui suffix. This is the bulk of the IEEE floating point
2631 instructions (addt et al). */
2632 switch (alpha_fptm)
2633 {
2634 case ALPHA_FPTM_N:
2635 break;
2636 case ALPHA_FPTM_U:
2637 fputc ('u', file);
2638 break;
2639 case ALPHA_FPTM_SU:
2640 fputs ("su", file);
2641 break;
2642 case ALPHA_FPTM_SUI:
2643 fputs ("sui", file);
2644 break;
2645 }
2646 break;
2647
2648 case '+':
2649 /* Generates trap-mode suffix for instructions that accept the sui
2650 suffix (cvtqt and cvtqs). */
2651 switch (alpha_fptm)
2652 {
2653 case ALPHA_FPTM_N:
2654 case ALPHA_FPTM_U:
2655 case ALPHA_FPTM_SU: /* cvtqt/cvtqs can't cause underflow */
2656 break;
2657 case ALPHA_FPTM_SUI:
2658 fputs ("sui", file);
2659 break;
2660 }
2661 break;
2662
2663 case ',':
2664 /* Generates single precision instruction suffix. */
2665 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'f' : 's'));
2666 break;
2667
2668 case '-':
2669 /* Generates double precision instruction suffix. */
2670 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'g' : 't'));
2671 break;
2672
2673 case 'r':
2674 /* If this operand is the constant zero, write it as "$31". */
2675 if (GET_CODE (x) == REG)
2676 fprintf (file, "%s", reg_names[REGNO (x)]);
2677 else if (x == CONST0_RTX (GET_MODE (x)))
2678 fprintf (file, "$31");
2679 else
2680 output_operand_lossage ("invalid %%r value");
2681
2682 break;
2683
2684 case 'R':
2685 /* Similar, but for floating-point. */
2686 if (GET_CODE (x) == REG)
2687 fprintf (file, "%s", reg_names[REGNO (x)]);
2688 else if (x == CONST0_RTX (GET_MODE (x)))
2689 fprintf (file, "$f31");
2690 else
2691 output_operand_lossage ("invalid %%R value");
2692
2693 break;
2694
2695 case 'N':
2696 /* Write the 1's complement of a constant. */
2697 if (GET_CODE (x) != CONST_INT)
2698 output_operand_lossage ("invalid %%N value");
2699
2700 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
2701 break;
2702
2703 case 'P':
2704 /* Write 1 << C, for a constant C. */
2705 if (GET_CODE (x) != CONST_INT)
2706 output_operand_lossage ("invalid %%P value");
2707
2708 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
2709 break;
2710
2711 case 'h':
2712 /* Write the high-order 16 bits of a constant, sign-extended. */
2713 if (GET_CODE (x) != CONST_INT)
2714 output_operand_lossage ("invalid %%h value");
2715
2716 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
2717 break;
2718
2719 case 'L':
2720 /* Write the low-order 16 bits of a constant, sign-extended. */
2721 if (GET_CODE (x) != CONST_INT)
2722 output_operand_lossage ("invalid %%L value");
2723
2724 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
2725 (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
2726 break;
2727
2728 case 'm':
2729 /* Write mask for ZAP insn. */
2730 if (GET_CODE (x) == CONST_DOUBLE)
2731 {
2732 HOST_WIDE_INT mask = 0;
2733 HOST_WIDE_INT value;
2734
2735 value = CONST_DOUBLE_LOW (x);
2736 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2737 i++, value >>= 8)
2738 if (value & 0xff)
2739 mask |= (1 << i);
2740
2741 value = CONST_DOUBLE_HIGH (x);
2742 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2743 i++, value >>= 8)
2744 if (value & 0xff)
2745 mask |= (1 << (i + sizeof (int)));
2746
2747 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
2748 }
2749
2750 else if (GET_CODE (x) == CONST_INT)
2751 {
2752 HOST_WIDE_INT mask = 0, value = INTVAL (x);
2753
2754 for (i = 0; i < 8; i++, value >>= 8)
2755 if (value & 0xff)
2756 mask |= (1 << i);
2757
2758 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
2759 }
2760 else
2761 output_operand_lossage ("invalid %%m value");
2762 break;
2763
2764 case 'M':
2765 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
2766 if (GET_CODE (x) != CONST_INT
2767 || (INTVAL (x) != 8 && INTVAL (x) != 16
2768 && INTVAL (x) != 32 && INTVAL (x) != 64))
2769 output_operand_lossage ("invalid %%M value");
2770
2771 fprintf (file, "%s",
2772 (INTVAL (x) == 8 ? "b"
2773 : INTVAL (x) == 16 ? "w"
2774 : INTVAL (x) == 32 ? "l"
2775 : "q"));
2776 break;
2777
2778 case 'U':
2779 /* Similar, except do it from the mask. */
2780 if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
2781 fprintf (file, "b");
2782 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
2783 fprintf (file, "w");
2784 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
2785 fprintf (file, "l");
2786 #if HOST_BITS_PER_WIDE_INT == 32
2787 else if (GET_CODE (x) == CONST_DOUBLE
2788 && CONST_DOUBLE_HIGH (x) == 0
2789 && CONST_DOUBLE_LOW (x) == -1)
2790 fprintf (file, "l");
2791 else if (GET_CODE (x) == CONST_DOUBLE
2792 && CONST_DOUBLE_HIGH (x) == -1
2793 && CONST_DOUBLE_LOW (x) == -1)
2794 fprintf (file, "q");
2795 #else
2796 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == -1)
2797 fprintf (file, "q");
2798 else if (GET_CODE (x) == CONST_DOUBLE
2799 && CONST_DOUBLE_HIGH (x) == 0
2800 && CONST_DOUBLE_LOW (x) == -1)
2801 fprintf (file, "q");
2802 #endif
2803 else
2804 output_operand_lossage ("invalid %%U value");
2805 break;
2806
2807 case 's':
2808 /* Write the constant value divided by 8. */
2809 if (GET_CODE (x) != CONST_INT
2810 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
2811 && (INTVAL (x) & 7) != 8)
2812 output_operand_lossage ("invalid %%s value");
2813
2814 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
2815 break;
2816
2817 case 'S':
2818 /* Same, except compute (64 - c) / 8 */
2819
2820 if (GET_CODE (x) != CONST_INT
2821 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
2822 && (INTVAL (x) & 7) != 8)
2823 output_operand_lossage ("invalid %%s value");
2824
2825 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
2826 break;
2827
2828 case 'C': case 'D': case 'c': case 'd':
2829 /* Write out comparison name. */
2830 {
2831 enum rtx_code c = GET_CODE (x);
2832
2833 if (GET_RTX_CLASS (c) != '<')
2834 output_operand_lossage ("invalid %%C value");
2835
2836 if (code == 'D')
2837 c = reverse_condition (c);
2838 else if (code == 'c')
2839 c = swap_condition (c);
2840 else if (code == 'd')
2841 c = swap_condition (reverse_condition (c));
2842
2843 if (c == LEU)
2844 fprintf (file, "ule");
2845 else if (c == LTU)
2846 fprintf (file, "ult");
2847 else
2848 fprintf (file, "%s", GET_RTX_NAME (c));
2849 }
2850 break;
2851
2852 case 'E':
2853 /* Write the divide or modulus operator. */
2854 switch (GET_CODE (x))
2855 {
2856 case DIV:
2857 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
2858 break;
2859 case UDIV:
2860 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
2861 break;
2862 case MOD:
2863 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
2864 break;
2865 case UMOD:
2866 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
2867 break;
2868 default:
2869 output_operand_lossage ("invalid %%E value");
2870 break;
2871 }
2872 break;
2873
2874 case 'A':
2875 /* Write "_u" for unaligned access. */
2876 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
2877 fprintf (file, "_u");
2878 break;
2879
2880 case 0:
2881 if (GET_CODE (x) == REG)
2882 fprintf (file, "%s", reg_names[REGNO (x)]);
2883 else if (GET_CODE (x) == MEM)
2884 output_address (XEXP (x, 0));
2885 else
2886 output_addr_const (file, x);
2887 break;
2888
2889 default:
2890 output_operand_lossage ("invalid %%xn code");
2891 }
2892 }
2893 \f
2894 /* Emit RTL insns to initialize the variable parts of a trampoline at
2895 TRAMP. FNADDR is an RTX for the address of the function's pure
2896 code. CXT is an RTX for the static chain value for the function.
2897
2898 The three offset parameters are for the individual template's
2899 layout. A JMPOFS < 0 indicates that the trampoline does not
2900 contain instructions at all.
2901
2902 We assume here that a function will be called many more times than
2903 its address is taken (e.g., it might be passed to qsort), so we
2904 take the trouble to initialize the "hint" field in the JMP insn.
2905 Note that the hint field is PC (new) + 4 * bits 13:0. */
2906
2907 void
2908 alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs)
2909 rtx tramp, fnaddr, cxt;
2910 int fnofs, cxtofs, jmpofs;
2911 {
2912 rtx temp, temp1, addr;
2913 /* ??? Something is wrong with VMS codegen in that we get aborts when
2914 using ptr_mode. Hack around it for now. */
2915 enum machine_mode mode = TARGET_OPEN_VMS ? Pmode : ptr_mode;
2916
2917 /* Store function address and CXT. */
2918 addr = memory_address (mode, plus_constant (tramp, fnofs));
2919 emit_move_insn (gen_rtx (MEM, mode, addr), fnaddr);
2920 addr = memory_address (mode, plus_constant (tramp, cxtofs));
2921 emit_move_insn (gen_rtx (MEM, mode, addr), cxt);
2922
2923 /* This has been disabled since the hint only has a 32k range, and in
2924 no existing OS is the stack within 32k of the text segment. */
2925 if (0 && jmpofs >= 0)
2926 {
2927 /* Compute hint value. */
2928 temp = force_operand (plus_constant (tramp, jmpofs+4), NULL_RTX);
2929 temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1,
2930 OPTAB_WIDEN);
2931 temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
2932 build_int_2 (2, 0), NULL_RTX, 1);
2933 temp = expand_and (gen_lowpart (SImode, temp), GEN_INT (0x3fff), 0);
2934
2935 /* Merge in the hint. */
2936 addr = memory_address (SImode, plus_constant (tramp, jmpofs));
2937 temp1 = force_reg (SImode, gen_rtx (MEM, SImode, addr));
2938 temp1 = expand_and (temp1, GEN_INT (0xffffc000), NULL_RTX);
2939 temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1,
2940 OPTAB_WIDEN);
2941 emit_move_insn (gen_rtx (MEM, SImode, addr), temp1);
2942 }
2943
2944 #ifdef TRANSFER_FROM_TRAMPOLINE
2945 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"),
2946 0, VOIDmode, 1, addr, Pmode);
2947 #endif
2948
2949 if (jmpofs >= 0)
2950 emit_insn (gen_imb ());
2951 }
2952 \f
2953 /* Do what is necessary for `va_start'. The argument is ignored;
2954 We look at the current function to determine if stdarg or varargs
2955 is used and fill in an initial va_list. A pointer to this constructor
2956 is returned. */
2957
2958 struct rtx_def *
2959 alpha_builtin_saveregs (arglist)
2960 tree arglist ATTRIBUTE_UNUSED;
2961 {
2962 rtx block, addr, dest, argsize;
2963 tree fntype = TREE_TYPE (current_function_decl);
2964 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
2965 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2966 != void_type_node));
2967
2968 /* Compute the current position into the args, taking into account
2969 both registers and memory. Both of these are already included in
2970 NUM_ARGS. */
2971
2972 argsize = GEN_INT (NUM_ARGS * UNITS_PER_WORD);
2973
2974 /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base up by 48,
2975 storing fp arg registers in the first 48 bytes, and the integer arg
2976 registers in the next 48 bytes. This is only done, however, if any
2977 integer registers need to be stored.
2978
2979 If no integer registers need be stored, then we must subtract 48 in
2980 order to account for the integer arg registers which are counted in
2981 argsize above, but which are not actually stored on the stack. */
2982
2983 if (TARGET_OPEN_VMS)
2984 addr = plus_constant (virtual_incoming_args_rtx,
2985 NUM_ARGS <= 5 + stdarg
2986 ? UNITS_PER_WORD : - 6 * UNITS_PER_WORD);
2987 else
2988 addr = (NUM_ARGS <= 5 + stdarg
2989 ? plus_constant (virtual_incoming_args_rtx,
2990 6 * UNITS_PER_WORD)
2991 : plus_constant (virtual_incoming_args_rtx,
2992 - (6 * UNITS_PER_WORD)));
2993
2994 /* For VMS, we include the argsize, while on Unix, it's handled as
2995 a separate field. */
2996 if (TARGET_OPEN_VMS)
2997 addr = plus_constant (addr, INTVAL (argsize));
2998
2999 addr = force_operand (addr, NULL_RTX);
3000
3001 #ifdef POINTERS_EXTEND_UNSIGNED
3002 addr = convert_memory_address (ptr_mode, addr);
3003 #endif
3004
3005 if (TARGET_OPEN_VMS)
3006 return addr;
3007 else
3008 {
3009 /* Allocate the va_list constructor */
3010 block = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
3011 RTX_UNCHANGING_P (block) = 1;
3012 RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
3013
3014 /* Store the address of the first integer register in the __base
3015 member. */
3016
3017 dest = change_address (block, ptr_mode, XEXP (block, 0));
3018 emit_move_insn (dest, addr);
3019
3020 if (current_function_check_memory_usage)
3021 emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
3022 dest, ptr_mode,
3023 GEN_INT (GET_MODE_SIZE (ptr_mode)),
3024 TYPE_MODE (sizetype),
3025 GEN_INT (MEMORY_USE_RW),
3026 TYPE_MODE (integer_type_node));
3027
3028 /* Store the argsize as the __va_offset member. */
3029 dest = change_address (block, TYPE_MODE (integer_type_node),
3030 plus_constant (XEXP (block, 0),
3031 POINTER_SIZE/BITS_PER_UNIT));
3032 emit_move_insn (dest, argsize);
3033
3034 if (current_function_check_memory_usage)
3035 emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
3036 dest, ptr_mode,
3037 GEN_INT (GET_MODE_SIZE
3038 (TYPE_MODE (integer_type_node))),
3039 TYPE_MODE (sizetype),
3040 GEN_INT (MEMORY_USE_RW),
3041 TYPE_MODE (integer_type_node));
3042
3043 /* Return the address of the va_list constructor, but don't put it in a
3044 register. Doing so would fail when not optimizing and produce worse
3045 code when optimizing. */
3046 return XEXP (block, 0);
3047 }
3048 }
3049 \f
3050 /* This page contains routines that are used to determine what the function
3051 prologue and epilogue code will do and write them out. */
3052
3053 /* Compute the size of the save area in the stack. */
3054
3055 /* These variables are used for communication between the following functions.
3056 They indicate various things about the current function being compiled
3057 that are used to tell what kind of prologue, epilogue and procedure
3058 descriptior to generate. */
3059
3060 /* Nonzero if we need a stack procedure. */
3061 static int vms_is_stack_procedure;
3062
3063 /* Register number (either FP or SP) that is used to unwind the frame. */
3064 static int vms_unwind_regno;
3065
3066 /* Register number used to save FP. We need not have one for RA since
3067 we don't modify it for register procedures. This is only defined
3068 for register frame procedures. */
3069 static int vms_save_fp_regno;
3070
3071 /* Register number used to reference objects off our PV. */
3072 static int vms_base_regno;
3073
3074 /* Compute register masks for saved registers. */
3075
3076 static void
3077 alpha_sa_mask (imaskP, fmaskP)
3078 unsigned long *imaskP;
3079 unsigned long *fmaskP;
3080 {
3081 unsigned long imask = 0;
3082 unsigned long fmask = 0;
3083 int i;
3084
3085 #ifdef ASM_OUTPUT_MI_THUNK
3086 if (!current_function_is_thunk)
3087 #endif
3088 {
3089 if (TARGET_OPEN_VMS && vms_is_stack_procedure)
3090 imask |= (1L << HARD_FRAME_POINTER_REGNUM);
3091
3092 /* One for every register we have to save. */
3093 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3094 if (! fixed_regs[i] && ! call_used_regs[i]
3095 && regs_ever_live[i] && i != REG_RA)
3096 {
3097 if (i < 32)
3098 imask |= (1L << i);
3099 else
3100 fmask |= (1L << (i - 32));
3101 }
3102
3103 if (imask || fmask || alpha_ra_ever_killed ())
3104 imask |= (1L << REG_RA);
3105 }
3106
3107 *imaskP = imask;
3108 *fmaskP = fmask;
3109 }
3110
3111 int
3112 alpha_sa_size ()
3113 {
3114 int sa_size = 0;
3115 int i;
3116
3117 #ifdef ASM_OUTPUT_MI_THUNK
3118 if (current_function_is_thunk)
3119 sa_size = 0;
3120 else
3121 #endif
3122 {
3123 /* One for every register we have to save. */
3124 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3125 if (! fixed_regs[i] && ! call_used_regs[i]
3126 && regs_ever_live[i] && i != REG_RA)
3127 sa_size++;
3128 }
3129
3130 if (TARGET_OPEN_VMS)
3131 {
3132 /* Start by assuming we can use a register procedure if we don't
3133 make any calls (REG_RA not used) or need to save any
3134 registers and a stack procedure if we do. */
3135 vms_is_stack_procedure = sa_size != 0 || alpha_ra_ever_killed ();
3136
3137 /* Decide whether to refer to objects off our PV via FP or PV.
3138 If we need FP for something else or if we receive a nonlocal
3139 goto (which expects PV to contain the value), we must use PV.
3140 Otherwise, start by assuming we can use FP. */
3141 vms_base_regno = (frame_pointer_needed
3142 || current_function_has_nonlocal_label
3143 || vms_is_stack_procedure
3144 || current_function_outgoing_args_size
3145 ? REG_PV : HARD_FRAME_POINTER_REGNUM);
3146
3147 /* If we want to copy PV into FP, we need to find some register
3148 in which to save FP. */
3149
3150 vms_save_fp_regno = -1;
3151 if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
3152 for (i = 0; i < 32; i++)
3153 if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
3154 vms_save_fp_regno = i;
3155
3156 if (vms_save_fp_regno == -1)
3157 vms_base_regno = REG_PV, vms_is_stack_procedure = 1;
3158
3159 /* Stack unwinding should be done via FP unless we use it for PV. */
3160 vms_unwind_regno = (vms_base_regno == REG_PV
3161 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
3162
3163 /* If this is a stack procedure, allow space for saving FP and RA. */
3164 if (vms_is_stack_procedure)
3165 sa_size += 2;
3166 }
3167 else
3168 {
3169 /* If some registers were saved but not RA, RA must also be saved,
3170 so leave space for it. */
3171 if (sa_size != 0 || alpha_ra_ever_killed ())
3172 sa_size++;
3173
3174 /* Our size must be even (multiple of 16 bytes). */
3175 if (sa_size & 1)
3176 sa_size++;
3177 }
3178
3179 return sa_size * 8;
3180 }
3181
3182 int
3183 alpha_pv_save_size ()
3184 {
3185 alpha_sa_size ();
3186 return vms_is_stack_procedure ? 8 : 0;
3187 }
3188
3189 int
3190 alpha_using_fp ()
3191 {
3192 alpha_sa_size ();
3193 return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM;
3194 }
3195
3196 int
3197 vms_valid_decl_attribute_p (decl, attributes, identifier, args)
3198 tree decl ATTRIBUTE_UNUSED;
3199 tree attributes ATTRIBUTE_UNUSED;
3200 tree identifier;
3201 tree args;
3202 {
3203 if (is_attribute_p ("overlaid", identifier))
3204 return (args == NULL_TREE);
3205 return 0;
3206 }
3207
3208 static int
3209 alpha_does_function_need_gp ()
3210 {
3211 rtx insn;
3212
3213 /* We never need a GP for Windows/NT or VMS. */
3214 if (TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
3215 return 0;
3216
3217 #ifdef TARGET_PROFILING_NEEDS_GP
3218 if (profile_flag)
3219 return 1;
3220 #endif
3221
3222 #ifdef ASM_OUTPUT_MI_THUNK
3223 if (current_function_is_thunk)
3224 return 1;
3225 #endif
3226
3227 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
3228 Even if we are a static function, we still need to do this in case
3229 our address is taken and passed to something like qsort. */
3230
3231 push_topmost_sequence ();
3232 insn = get_insns ();
3233 pop_topmost_sequence ();
3234
3235 for (; insn; insn = NEXT_INSN (insn))
3236 if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
3237 && GET_CODE (PATTERN (insn)) != USE
3238 && GET_CODE (PATTERN (insn)) != CLOBBER)
3239 {
3240 enum attr_type type = get_attr_type (insn);
3241 if (type == TYPE_LDSYM || type == TYPE_JSR)
3242 return 1;
3243 }
3244
3245 return 0;
3246 }
3247
3248 /* Write a version stamp. Don't write anything if we are running as a
3249 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
3250
3251 #ifdef HAVE_STAMP_H
3252 #include <stamp.h>
3253 #endif
3254
3255 void
3256 alpha_write_verstamp (file)
3257 FILE *file;
3258 {
3259 #ifdef MS_STAMP
3260 fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
3261 #endif
3262 }
3263 \f
3264 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
3265 sequences. */
3266
3267 static rtx
3268 set_frame_related_p ()
3269 {
3270 rtx seq = gen_sequence ();
3271 end_sequence ();
3272
3273 if (GET_CODE (seq) == SEQUENCE)
3274 {
3275 int i = XVECLEN (seq, 0);
3276 while (--i >= 0)
3277 RTX_FRAME_RELATED_P (XVECEXP (seq, 0, i)) = 1;
3278 return emit_insn (seq);
3279 }
3280 else
3281 {
3282 seq = emit_insn (seq);
3283 RTX_FRAME_RELATED_P (seq) = 1;
3284 return seq;
3285 }
3286 }
3287
3288 #define FRP(exp) (start_sequence (), exp, set_frame_related_p ())
3289
3290 /* Write function prologue. */
3291
3292 /* On vms we have two kinds of functions:
3293
3294 - stack frame (PROC_STACK)
3295 these are 'normal' functions with local vars and which are
3296 calling other functions
3297 - register frame (PROC_REGISTER)
3298 keeps all data in registers, needs no stack
3299
3300 We must pass this to the assembler so it can generate the
3301 proper pdsc (procedure descriptor)
3302 This is done with the '.pdesc' command.
3303
3304 On not-vms, we don't really differentiate between the two, as we can
3305 simply allocate stack without saving registers. */
3306
3307 void
3308 alpha_expand_prologue ()
3309 {
3310 /* Registers to save. */
3311 unsigned long imask = 0;
3312 unsigned long fmask = 0;
3313 /* Stack space needed for pushing registers clobbered by us. */
3314 HOST_WIDE_INT sa_size;
3315 /* Complete stack size needed. */
3316 HOST_WIDE_INT frame_size;
3317 /* Offset from base reg to register save area. */
3318 HOST_WIDE_INT reg_offset;
3319 rtx sa_reg, mem;
3320 int i;
3321
3322 sa_size = alpha_sa_size ();
3323
3324 frame_size = get_frame_size ();
3325 if (TARGET_OPEN_VMS)
3326 frame_size = ALPHA_ROUND (sa_size
3327 + (vms_is_stack_procedure ? 8 : 0)
3328 + frame_size
3329 + current_function_pretend_args_size);
3330 else
3331 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
3332 + sa_size
3333 + ALPHA_ROUND (frame_size
3334 + current_function_pretend_args_size));
3335
3336 if (TARGET_OPEN_VMS)
3337 reg_offset = 8;
3338 else
3339 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
3340
3341 alpha_sa_mask (&imask, &fmask);
3342
3343 /* Adjust the stack by the frame size. If the frame size is > 4096
3344 bytes, we need to be sure we probe somewhere in the first and last
3345 4096 bytes (we can probably get away without the latter test) and
3346 every 8192 bytes in between. If the frame size is > 32768, we
3347 do this in a loop. Otherwise, we generate the explicit probe
3348 instructions.
3349
3350 Note that we are only allowed to adjust sp once in the prologue. */
3351
3352 if (frame_size <= 32768)
3353 {
3354 if (frame_size > 4096)
3355 {
3356 int probed = 4096;
3357
3358 do
3359 emit_insn (gen_probe_stack (GEN_INT (-probed)));
3360 while ((probed += 8192) < frame_size);
3361
3362 /* We only have to do this probe if we aren't saving registers. */
3363 if (sa_size == 0 && probed + 4096 < frame_size)
3364 emit_insn (gen_probe_stack (GEN_INT (-frame_size)));
3365 }
3366
3367 if (frame_size != 0)
3368 {
3369 FRP (emit_move_insn (stack_pointer_rtx,
3370 plus_constant (stack_pointer_rtx, -frame_size)));
3371 }
3372 }
3373 else
3374 {
3375 /* Here we generate code to set R22 to SP + 4096 and set R23 to the
3376 number of 8192 byte blocks to probe. We then probe each block
3377 in the loop and then set SP to the proper location. If the
3378 amount remaining is > 4096, we have to do one more probe if we
3379 are not saving any registers. */
3380
3381 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
3382 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
3383 rtx ptr = gen_rtx_REG (DImode, 22);
3384 rtx count = gen_rtx_REG (DImode, 23);
3385
3386 emit_move_insn (count, GEN_INT (blocks));
3387 emit_move_insn (ptr, plus_constant (stack_pointer_rtx, 4096));
3388
3389 /* Because of the difficulty in emitting a new basic block this
3390 late in the compilation, generate the loop as a single insn. */
3391 emit_insn (gen_prologue_stack_probe_loop (count, ptr));
3392
3393 if (leftover > 4096 && sa_size == 0)
3394 {
3395 rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover));
3396 MEM_VOLATILE_P (last) = 1;
3397 emit_move_insn (last, const0_rtx);
3398 }
3399
3400 ptr = emit_move_insn (stack_pointer_rtx, plus_constant (ptr, -leftover));
3401
3402 /* This alternative is special, because the DWARF code cannot possibly
3403 intuit through the loop above. So we invent this note it looks at
3404 instead. */
3405 RTX_FRAME_RELATED_P (ptr) = 1;
3406 REG_NOTES (ptr)
3407 = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
3408 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
3409 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
3410 GEN_INT (-frame_size))),
3411 REG_NOTES (ptr));
3412 }
3413
3414 /* Cope with very large offsets to the register save area. */
3415 sa_reg = stack_pointer_rtx;
3416 if (reg_offset + sa_size > 0x8000)
3417 {
3418 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3419 HOST_WIDE_INT bias;
3420
3421 if (low + sa_size <= 0x8000)
3422 bias = reg_offset - low, reg_offset = low;
3423 else
3424 bias = reg_offset, reg_offset = 0;
3425
3426 sa_reg = gen_rtx_REG (DImode, 24);
3427 FRP (emit_move_insn (sa_reg, plus_constant (stack_pointer_rtx, bias)));
3428 }
3429
3430 /* Save regs in stack order. Beginning with VMS PV. */
3431 if (TARGET_OPEN_VMS && vms_is_stack_procedure)
3432 {
3433 mem = gen_rtx_MEM (DImode, stack_pointer_rtx);
3434 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3435 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_PV)));
3436 }
3437
3438 /* Save register RA next. */
3439 if (imask & (1L << REG_RA))
3440 {
3441 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
3442 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3443 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
3444 imask &= ~(1L << REG_RA);
3445 reg_offset += 8;
3446 }
3447
3448 /* Now save any other registers required to be saved. */
3449 for (i = 0; i < 32; i++)
3450 if (imask & (1L << i))
3451 {
3452 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
3453 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3454 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, i)));
3455 reg_offset += 8;
3456 }
3457
3458 for (i = 0; i < 32; i++)
3459 if (fmask & (1L << i))
3460 {
3461 mem = gen_rtx_MEM (DFmode, plus_constant (sa_reg, reg_offset));
3462 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3463 FRP (emit_move_insn (mem, gen_rtx_REG (DFmode, i+32)));
3464 reg_offset += 8;
3465 }
3466
3467 if (TARGET_OPEN_VMS)
3468 {
3469 if (!vms_is_stack_procedure)
3470 {
3471 /* Register frame procedures fave the fp. */
3472 FRP (emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
3473 hard_frame_pointer_rtx));
3474 }
3475
3476 if (vms_base_regno != REG_PV)
3477 FRP (emit_move_insn (gen_rtx_REG (DImode, vms_base_regno),
3478 gen_rtx_REG (DImode, REG_PV)));
3479
3480 if (vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
3481 {
3482 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
3483 }
3484
3485 /* If we have to allocate space for outgoing args, do it now. */
3486 if (current_function_outgoing_args_size != 0)
3487 {
3488 FRP (emit_move_insn (stack_pointer_rtx,
3489 plus_constant (hard_frame_pointer_rtx,
3490 - ALPHA_ROUND (current_function_outgoing_args_size))));
3491 }
3492 }
3493 else
3494 {
3495 /* If we need a frame pointer, set it from the stack pointer. */
3496 if (frame_pointer_needed)
3497 {
3498 if (TARGET_CAN_FAULT_IN_PROLOGUE)
3499 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
3500 else
3501 {
3502 /* This must always be the last instruction in the
3503 prologue, thus we emit a special move + clobber. */
3504 FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx,
3505 stack_pointer_rtx, sa_reg)));
3506 }
3507 }
3508 }
3509
3510 /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
3511 the prologue, for exception handling reasons, we cannot do this for
3512 any insn that might fault. We could prevent this for mems with a
3513 (clobber:BLK (scratch)), but this doesn't work for fp insns. So we
3514 have to prevent all such scheduling with a blockage.
3515
3516 Linux, on the other hand, never bothered to implement OSF/1's
3517 exception handling, and so doesn't care about such things. Anyone
3518 planning to use dwarf2 frame-unwind info can also omit the blockage. */
3519
3520 if (! TARGET_CAN_FAULT_IN_PROLOGUE)
3521 emit_insn (gen_blockage ());
3522 }
3523
3524 /* Output the textual info surrounding the prologue. */
3525
3526 void
3527 alpha_start_function (file, fnname, decl)
3528 FILE *file;
3529 char *fnname;
3530 tree decl ATTRIBUTE_UNUSED;
3531 {
3532 unsigned long imask = 0;
3533 unsigned long fmask = 0;
3534 /* Stack space needed for pushing registers clobbered by us. */
3535 HOST_WIDE_INT sa_size;
3536 /* Complete stack size needed. */
3537 HOST_WIDE_INT frame_size;
3538 /* Offset from base reg to register save area. */
3539 HOST_WIDE_INT reg_offset;
3540 char *entry_label = (char *) alloca (strlen (fnname) + 6);
3541 int i;
3542
3543 sa_size = alpha_sa_size ();
3544
3545 frame_size = get_frame_size ();
3546 if (TARGET_OPEN_VMS)
3547 frame_size = ALPHA_ROUND (sa_size
3548 + (vms_is_stack_procedure ? 8 : 0)
3549 + frame_size
3550 + current_function_pretend_args_size);
3551 else
3552 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
3553 + sa_size
3554 + ALPHA_ROUND (frame_size
3555 + current_function_pretend_args_size));
3556
3557 if (TARGET_OPEN_VMS)
3558 reg_offset = 8;
3559 else
3560 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
3561
3562 alpha_sa_mask (&imask, &fmask);
3563
3564 /* Ecoff can handle multiple .file directives, so put out file and lineno.
3565 We have to do that before the .ent directive as we cannot switch
3566 files within procedures with native ecoff because line numbers are
3567 linked to procedure descriptors.
3568 Outputting the lineno helps debugging of one line functions as they
3569 would otherwise get no line number at all. Please note that we would
3570 like to put out last_linenum from final.c, but it is not accessible. */
3571
3572 if (write_symbols == SDB_DEBUG)
3573 {
3574 ASM_OUTPUT_SOURCE_FILENAME (file,
3575 DECL_SOURCE_FILE (current_function_decl));
3576 if (debug_info_level != DINFO_LEVEL_TERSE)
3577 ASM_OUTPUT_SOURCE_LINE (file,
3578 DECL_SOURCE_LINE (current_function_decl));
3579 }
3580
3581 /* Issue function start and label. */
3582 if (TARGET_OPEN_VMS || !flag_inhibit_size_directive)
3583 {
3584 fputs ("\t.ent ", file);
3585 assemble_name (file, fnname);
3586 putc ('\n', file);
3587 }
3588
3589 strcpy (entry_label, fnname);
3590 if (TARGET_OPEN_VMS)
3591 strcat (entry_label, "..en");
3592 ASM_OUTPUT_LABEL (file, entry_label);
3593 inside_function = TRUE;
3594
3595 if (TARGET_OPEN_VMS)
3596 fprintf (file, "\t.base $%d\n", vms_base_regno);
3597
3598 if (!TARGET_OPEN_VMS && TARGET_IEEE_CONFORMANT
3599 && !flag_inhibit_size_directive)
3600 {
3601 /* Set flags in procedure descriptor to request IEEE-conformant
3602 math-library routines. The value we set it to is PDSC_EXC_IEEE
3603 (/usr/include/pdsc.h). */
3604 fputs ("\t.eflag 48\n", file);
3605 }
3606
3607 /* Set up offsets to alpha virtual arg/local debugging pointer. */
3608 alpha_auto_offset = -frame_size + current_function_pretend_args_size;
3609 alpha_arg_offset = -frame_size + 48;
3610
3611 /* Describe our frame. If the frame size is larger than an integer,
3612 print it as zero to avoid an assembler error. We won't be
3613 properly describing such a frame, but that's the best we can do. */
3614 if (TARGET_OPEN_VMS)
3615 {
3616 fprintf (file, "\t.frame $%d,", vms_unwind_regno);
3617 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3618 frame_size >= (1l << 31) ? 0 : frame_size);
3619 fputs (",$26,", file);
3620 fprintf (file, HOST_WIDE_INT_PRINT_DEC, reg_offset);
3621 fputs ("\n", file);
3622 }
3623 else if (!flag_inhibit_size_directive)
3624 {
3625 fprintf (file, "\t.frame $%d,",
3626 (frame_pointer_needed
3627 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM));
3628 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3629 frame_size >= (1l << 31) ? 0 : frame_size);
3630 fprintf (file, ",$26,%d\n", current_function_pretend_args_size);
3631 }
3632
3633 /* Describe which registers were spilled. */
3634 if (TARGET_OPEN_VMS)
3635 {
3636 if (imask)
3637 /* ??? Does VMS care if mask contains ra? The old code did'nt
3638 set it, so I don't here. */
3639 fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1L << REG_RA));
3640 if (fmask)
3641 fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
3642 if (!vms_is_stack_procedure)
3643 fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
3644 }
3645 else if (!flag_inhibit_size_directive)
3646 {
3647 if (imask)
3648 {
3649 fprintf (file, "\t.mask 0x%lx,", imask);
3650 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3651 frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
3652 putc ('\n', file);
3653
3654 for (i = 0; i < 32; ++i)
3655 if (imask & (1L << i))
3656 reg_offset += 8;
3657 }
3658
3659 if (fmask)
3660 {
3661 fprintf (file, "\t.fmask 0x%lx,", fmask);
3662 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3663 frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
3664 putc ('\n', file);
3665 }
3666 }
3667
3668 /* Emit GP related things. It is rather unfortunate about the alignment
3669 issues surrounding a CODE_LABEL that forces us to do the label in
3670 plain text. */
3671 if (!TARGET_OPEN_VMS && !TARGET_WINDOWS_NT)
3672 {
3673 alpha_function_needs_gp = alpha_does_function_need_gp ();
3674 if (alpha_function_needs_gp)
3675 fputs ("\tldgp $29,0($27)\n", file);
3676
3677 putc ('$', file);
3678 assemble_name (file, fnname);
3679 fputs ("..ng:\n", file);
3680 }
3681
3682 #ifdef OPEN_VMS
3683 /* Ifdef'ed cause readonly_section and link_section are only
3684 available then. */
3685 readonly_section ();
3686 fprintf (file, "\t.align 3\n");
3687 assemble_name (file, fnname); fputs ("..na:\n", file);
3688 fputs ("\t.ascii \"", file);
3689 assemble_name (file, fnname);
3690 fputs ("\\0\"\n", file);
3691
3692 link_section ();
3693 fprintf (file, "\t.align 3\n");
3694 fputs ("\t.name ", file);
3695 assemble_name (file, fnname);
3696 fputs ("..na\n", file);
3697 ASM_OUTPUT_LABEL (file, fnname);
3698 fprintf (file, "\t.pdesc ");
3699 assemble_name (file, fnname);
3700 fprintf (file, "..en,%s\n", vms_is_stack_procedure ? "stack" : "reg");
3701 alpha_need_linkage (fnname, 1);
3702 text_section ();
3703 #endif
3704 }
3705
3706 /* Emit the .prologue note at the scheduled end of the prologue. */
3707
3708 void
3709 output_end_prologue (file)
3710 FILE *file;
3711 {
3712 if (TARGET_OPEN_VMS)
3713 fputs ("\t.prologue\n", file);
3714 else if (TARGET_WINDOWS_NT)
3715 fputs ("\t.prologue 0\n", file);
3716 else if (!flag_inhibit_size_directive)
3717 fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
3718 }
3719
3720 /* Write function epilogue. */
3721
3722 /* ??? At some point we will want to support full unwind, and so will
3723 need to mark the epilogue as well. At the moment, we just confuse
3724 dwarf2out. */
3725 #undef FRP
3726 #define FRP(exp) exp
3727
3728 void
3729 alpha_expand_epilogue ()
3730 {
3731 /* Registers to save. */
3732 unsigned long imask = 0;
3733 unsigned long fmask = 0;
3734 /* Stack space needed for pushing registers clobbered by us. */
3735 HOST_WIDE_INT sa_size;
3736 /* Complete stack size needed. */
3737 HOST_WIDE_INT frame_size;
3738 /* Offset from base reg to register save area. */
3739 HOST_WIDE_INT reg_offset;
3740 int fp_is_frame_pointer, fp_offset;
3741 rtx sa_reg, sa_reg_exp = NULL;
3742 rtx sp_adj1, sp_adj2, mem;
3743 int i;
3744
3745 sa_size = alpha_sa_size ();
3746
3747 frame_size = get_frame_size ();
3748 if (TARGET_OPEN_VMS)
3749 frame_size = ALPHA_ROUND (sa_size
3750 + (vms_is_stack_procedure ? 8 : 0)
3751 + frame_size
3752 + current_function_pretend_args_size);
3753 else
3754 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
3755 + sa_size
3756 + ALPHA_ROUND (frame_size
3757 + current_function_pretend_args_size));
3758
3759 if (TARGET_OPEN_VMS)
3760 reg_offset = 8;
3761 else
3762 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
3763
3764 alpha_sa_mask (&imask, &fmask);
3765
3766 fp_is_frame_pointer = ((TARGET_OPEN_VMS && vms_is_stack_procedure)
3767 || (!TARGET_OPEN_VMS && frame_pointer_needed));
3768
3769 if (sa_size)
3770 {
3771 /* If we have a frame pointer, restore SP from it. */
3772 if ((TARGET_OPEN_VMS
3773 && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
3774 || (!TARGET_OPEN_VMS && frame_pointer_needed))
3775 {
3776 FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx));
3777 }
3778
3779 /* Cope with very large offsets to the register save area. */
3780 sa_reg = stack_pointer_rtx;
3781 if (reg_offset + sa_size > 0x8000)
3782 {
3783 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3784 HOST_WIDE_INT bias;
3785
3786 if (low + sa_size <= 0x8000)
3787 bias = reg_offset - low, reg_offset = low;
3788 else
3789 bias = reg_offset, reg_offset = 0;
3790
3791 sa_reg = gen_rtx_REG (DImode, 22);
3792 sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
3793
3794 FRP (emit_move_insn (sa_reg, sa_reg_exp));
3795 }
3796
3797 /* Restore registers in order, excepting a true frame pointer. */
3798
3799 if (! alpha_eh_epilogue_sp_ofs)
3800 {
3801 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
3802 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3803 FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
3804 }
3805 reg_offset += 8;
3806 imask &= ~(1L << REG_RA);
3807
3808 for (i = 0; i < 32; ++i)
3809 if (imask & (1L << i))
3810 {
3811 if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
3812 fp_offset = reg_offset;
3813 else
3814 {
3815 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
3816 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3817 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
3818 }
3819 reg_offset += 8;
3820 }
3821
3822 for (i = 0; i < 32; ++i)
3823 if (fmask & (1L << i))
3824 {
3825 mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
3826 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3827 FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
3828 reg_offset += 8;
3829 }
3830 }
3831
3832 if (frame_size || alpha_eh_epilogue_sp_ofs)
3833 {
3834 sp_adj1 = stack_pointer_rtx;
3835
3836 if (alpha_eh_epilogue_sp_ofs)
3837 {
3838 sp_adj1 = gen_rtx_REG (DImode, 23);
3839 emit_move_insn (sp_adj1,
3840 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
3841 alpha_eh_epilogue_sp_ofs));
3842 }
3843
3844 /* If the stack size is large, begin computation into a temporary
3845 register so as not to interfere with a potential fp restore,
3846 which must be consecutive with an SP restore. */
3847 if (frame_size < 32768)
3848 sp_adj2 = GEN_INT (frame_size);
3849 else if (frame_size < 0x40007fffL)
3850 {
3851 int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
3852
3853 sp_adj2 = plus_constant (sp_adj1, frame_size - low);
3854 if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
3855 sp_adj1 = sa_reg;
3856 else
3857 {
3858 sp_adj1 = gen_rtx_REG (DImode, 23);
3859 FRP (emit_move_insn (sp_adj1, sp_adj2));
3860 }
3861 sp_adj2 = GEN_INT (low);
3862 }
3863 else
3864 {
3865 rtx tmp = gen_rtx_REG (DImode, 23);
3866 FRP (sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3));
3867 if (!sp_adj2)
3868 {
3869 /* We can't drop new things to memory this late, afaik,
3870 so build it up by pieces. */
3871 FRP (sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
3872 -(frame_size < 0)));
3873 if (!sp_adj2)
3874 abort ();
3875 }
3876 }
3877
3878 /* From now on, things must be in order. So emit blockages. */
3879
3880 /* Restore the frame pointer. */
3881 if (fp_is_frame_pointer)
3882 {
3883 emit_insn (gen_blockage ());
3884 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, fp_offset));
3885 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3886 FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
3887 }
3888 else if (TARGET_OPEN_VMS)
3889 {
3890 emit_insn (gen_blockage ());
3891 FRP (emit_move_insn (hard_frame_pointer_rtx,
3892 gen_rtx_REG (DImode, vms_save_fp_regno)));
3893 }
3894
3895 /* Restore the stack pointer. */
3896 emit_insn (gen_blockage ());
3897 FRP (emit_move_insn (stack_pointer_rtx,
3898 gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)));
3899 }
3900 else
3901 {
3902 if (TARGET_OPEN_VMS && !vms_is_stack_procedure)
3903 {
3904 emit_insn (gen_blockage ());
3905 FRP (emit_move_insn (hard_frame_pointer_rtx,
3906 gen_rtx_REG (DImode, vms_save_fp_regno)));
3907 }
3908 }
3909
3910 /* Return. */
3911 emit_jump_insn (gen_return_internal ());
3912 }
3913
3914 /* Output the rest of the textual info surrounding the epilogue. */
3915
3916 void
3917 alpha_end_function (file, fnname, decl)
3918 FILE *file;
3919 char *fnname;
3920 tree decl ATTRIBUTE_UNUSED;
3921 {
3922 /* End the function. */
3923 if (!flag_inhibit_size_directive)
3924 {
3925 fputs ("\t.end ", file);
3926 assemble_name (file, fnname);
3927 putc ('\n', file);
3928 }
3929 inside_function = FALSE;
3930
3931 /* Show that we know this function if it is called again.
3932
3933 Don't do this for global functions in object files destined for a
3934 shared library because the function may be overridden by the application
3935 or other libraries.
3936 ??? Is this just ELF? */
3937
3938 if (!flag_pic || !TREE_PUBLIC (current_function_decl))
3939 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
3940 }
3941 \f
3942 /* Debugging support. */
3943
3944 #include "gstab.h"
3945
3946 /* Count the number of sdb related labels are generated (to find block
3947 start and end boundaries). */
3948
3949 int sdb_label_count = 0;
3950
3951 /* Next label # for each statement. */
3952
3953 static int sym_lineno = 0;
3954
3955 /* Count the number of .file directives, so that .loc is up to date. */
3956
3957 static int num_source_filenames = 0;
3958
3959 /* Name of the file containing the current function. */
3960
3961 static char *current_function_file = "";
3962
3963 /* Offsets to alpha virtual arg/local debugging pointers. */
3964
3965 long alpha_arg_offset;
3966 long alpha_auto_offset;
3967 \f
3968 /* Emit a new filename to a stream. */
3969
3970 void
3971 alpha_output_filename (stream, name)
3972 FILE *stream;
3973 char *name;
3974 {
3975 static int first_time = TRUE;
3976 char ltext_label_name[100];
3977
3978 if (first_time)
3979 {
3980 first_time = FALSE;
3981 ++num_source_filenames;
3982 current_function_file = name;
3983 fprintf (stream, "\t.file\t%d ", num_source_filenames);
3984 output_quoted_string (stream, name);
3985 fprintf (stream, "\n");
3986 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
3987 fprintf (stream, "\t#@stabs\n");
3988 }
3989
3990 else if (write_symbols == DBX_DEBUG)
3991 {
3992 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
3993 fprintf (stream, "%s ", ASM_STABS_OP);
3994 output_quoted_string (stream, name);
3995 fprintf (stream, ",%d,0,0,%s\n", N_SOL, &ltext_label_name[1]);
3996 }
3997
3998 else if (name != current_function_file
3999 && strcmp (name, current_function_file) != 0)
4000 {
4001 if (inside_function && ! TARGET_GAS)
4002 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
4003 else
4004 {
4005 ++num_source_filenames;
4006 current_function_file = name;
4007 fprintf (stream, "\t.file\t%d ", num_source_filenames);
4008 }
4009
4010 output_quoted_string (stream, name);
4011 fprintf (stream, "\n");
4012 }
4013 }
4014 \f
4015 /* Emit a linenumber to a stream. */
4016
4017 void
4018 alpha_output_lineno (stream, line)
4019 FILE *stream;
4020 int line;
4021 {
4022 if (write_symbols == DBX_DEBUG)
4023 {
4024 /* mips-tfile doesn't understand .stabd directives. */
4025 ++sym_lineno;
4026 fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
4027 sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
4028 }
4029 else
4030 fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
4031 }
4032 \f
4033 /* Structure to show the current status of registers and memory. */
4034
4035 struct shadow_summary
4036 {
4037 struct {
4038 unsigned long i : 31; /* Mask of int regs */
4039 unsigned long fp : 31; /* Mask of fp regs */
4040 unsigned long mem : 1; /* mem == imem | fpmem */
4041 } used, defd;
4042 };
4043
4044 static void summarize_insn PROTO((rtx, struct shadow_summary *, int));
4045 static void alpha_handle_trap_shadows PROTO((rtx));
4046
4047 /* Summary the effects of expression X on the machine. Update SUM, a pointer
4048 to the summary structure. SET is nonzero if the insn is setting the
4049 object, otherwise zero. */
4050
4051 static void
4052 summarize_insn (x, sum, set)
4053 rtx x;
4054 struct shadow_summary *sum;
4055 int set;
4056 {
4057 char *format_ptr;
4058 int i, j;
4059
4060 if (x == 0)
4061 return;
4062
4063 switch (GET_CODE (x))
4064 {
4065 /* ??? Note that this case would be incorrect if the Alpha had a
4066 ZERO_EXTRACT in SET_DEST. */
4067 case SET:
4068 summarize_insn (SET_SRC (x), sum, 0);
4069 summarize_insn (SET_DEST (x), sum, 1);
4070 break;
4071
4072 case CLOBBER:
4073 summarize_insn (XEXP (x, 0), sum, 1);
4074 break;
4075
4076 case USE:
4077 summarize_insn (XEXP (x, 0), sum, 0);
4078 break;
4079
4080 case ASM_OPERANDS:
4081 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
4082 summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
4083 break;
4084
4085 case PARALLEL:
4086 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
4087 summarize_insn (XVECEXP (x, 0, i), sum, 0);
4088 break;
4089
4090 case SUBREG:
4091 summarize_insn (SUBREG_REG (x), sum, 0);
4092 break;
4093
4094 case REG:
4095 {
4096 int regno = REGNO (x);
4097 unsigned long mask = 1UL << (regno % 32);
4098
4099 if (regno == 31 || regno == 63)
4100 break;
4101
4102 if (set)
4103 {
4104 if (regno < 32)
4105 sum->defd.i |= mask;
4106 else
4107 sum->defd.fp |= mask;
4108 }
4109 else
4110 {
4111 if (regno < 32)
4112 sum->used.i |= mask;
4113 else
4114 sum->used.fp |= mask;
4115 }
4116 }
4117 break;
4118
4119 case MEM:
4120 if (set)
4121 sum->defd.mem = 1;
4122 else
4123 sum->used.mem = 1;
4124
4125 /* Find the regs used in memory address computation: */
4126 summarize_insn (XEXP (x, 0), sum, 0);
4127 break;
4128
4129 case CONST_INT: case CONST_DOUBLE:
4130 case SYMBOL_REF: case LABEL_REF: case CONST:
4131 break;
4132
4133 /* Handle common unary and binary ops for efficiency. */
4134 case COMPARE: case PLUS: case MINUS: case MULT: case DIV:
4135 case MOD: case UDIV: case UMOD: case AND: case IOR:
4136 case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT:
4137 case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX:
4138 case NE: case EQ: case GE: case GT: case LE:
4139 case LT: case GEU: case GTU: case LEU: case LTU:
4140 summarize_insn (XEXP (x, 0), sum, 0);
4141 summarize_insn (XEXP (x, 1), sum, 0);
4142 break;
4143
4144 case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
4145 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
4146 case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
4147 case SQRT: case FFS:
4148 summarize_insn (XEXP (x, 0), sum, 0);
4149 break;
4150
4151 default:
4152 format_ptr = GET_RTX_FORMAT (GET_CODE (x));
4153 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4154 switch (format_ptr[i])
4155 {
4156 case 'e':
4157 summarize_insn (XEXP (x, i), sum, 0);
4158 break;
4159
4160 case 'E':
4161 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
4162 summarize_insn (XVECEXP (x, i, j), sum, 0);
4163 break;
4164
4165 case 'i':
4166 break;
4167
4168 default:
4169 abort ();
4170 }
4171 }
4172 }
4173
4174 /* Ensure a sufficient number of `trapb' insns are in the code when
4175 the user requests code with a trap precision of functions or
4176 instructions.
4177
4178 In naive mode, when the user requests a trap-precision of
4179 "instruction", a trapb is needed after every instruction that may
4180 generate a trap. This ensures that the code is resumption safe but
4181 it is also slow.
4182
4183 When optimizations are turned on, we delay issuing a trapb as long
4184 as possible. In this context, a trap shadow is the sequence of
4185 instructions that starts with a (potentially) trap generating
4186 instruction and extends to the next trapb or call_pal instruction
4187 (but GCC never generates call_pal by itself). We can delay (and
4188 therefore sometimes omit) a trapb subject to the following
4189 conditions:
4190
4191 (a) On entry to the trap shadow, if any Alpha register or memory
4192 location contains a value that is used as an operand value by some
4193 instruction in the trap shadow (live on entry), then no instruction
4194 in the trap shadow may modify the register or memory location.
4195
4196 (b) Within the trap shadow, the computation of the base register
4197 for a memory load or store instruction may not involve using the
4198 result of an instruction that might generate an UNPREDICTABLE
4199 result.
4200
4201 (c) Within the trap shadow, no register may be used more than once
4202 as a destination register. (This is to make life easier for the
4203 trap-handler.)
4204
4205 (d) The trap shadow may not include any branch instructions. */
4206
4207 static void
4208 alpha_handle_trap_shadows (insns)
4209 rtx insns;
4210 {
4211 struct shadow_summary shadow;
4212 int trap_pending, exception_nesting;
4213 rtx i, n;
4214
4215 trap_pending = 0;
4216 exception_nesting = 0;
4217 shadow.used.i = 0;
4218 shadow.used.fp = 0;
4219 shadow.used.mem = 0;
4220 shadow.defd = shadow.used;
4221
4222 for (i = insns; i ; i = NEXT_INSN (i))
4223 {
4224 if (GET_CODE (i) == NOTE)
4225 {
4226 switch (NOTE_LINE_NUMBER (i))
4227 {
4228 case NOTE_INSN_EH_REGION_BEG:
4229 exception_nesting++;
4230 if (trap_pending)
4231 goto close_shadow;
4232 break;
4233
4234 case NOTE_INSN_EH_REGION_END:
4235 exception_nesting--;
4236 if (trap_pending)
4237 goto close_shadow;
4238 break;
4239
4240 case NOTE_INSN_EPILOGUE_BEG:
4241 if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
4242 goto close_shadow;
4243 break;
4244 }
4245 }
4246 else if (trap_pending)
4247 {
4248 if (alpha_tp == ALPHA_TP_FUNC)
4249 {
4250 if (GET_CODE (i) == JUMP_INSN
4251 && GET_CODE (PATTERN (i)) == RETURN)
4252 goto close_shadow;
4253 }
4254 else if (alpha_tp == ALPHA_TP_INSN)
4255 {
4256 if (optimize > 0)
4257 {
4258 struct shadow_summary sum;
4259
4260 sum.used.i = 0;
4261 sum.used.fp = 0;
4262 sum.used.mem = 0;
4263 sum.defd = sum.used;
4264
4265 switch (GET_CODE (i))
4266 {
4267 case INSN:
4268 /* Annoyingly, get_attr_trap will abort on these. */
4269 if (GET_CODE (PATTERN (i)) == USE
4270 || GET_CODE (PATTERN (i)) == CLOBBER)
4271 break;
4272
4273 summarize_insn (PATTERN (i), &sum, 0);
4274
4275 if ((sum.defd.i & shadow.defd.i)
4276 || (sum.defd.fp & shadow.defd.fp))
4277 {
4278 /* (c) would be violated */
4279 goto close_shadow;
4280 }
4281
4282 /* Combine shadow with summary of current insn: */
4283 shadow.used.i |= sum.used.i;
4284 shadow.used.fp |= sum.used.fp;
4285 shadow.used.mem |= sum.used.mem;
4286 shadow.defd.i |= sum.defd.i;
4287 shadow.defd.fp |= sum.defd.fp;
4288 shadow.defd.mem |= sum.defd.mem;
4289
4290 if ((sum.defd.i & shadow.used.i)
4291 || (sum.defd.fp & shadow.used.fp)
4292 || (sum.defd.mem & shadow.used.mem))
4293 {
4294 /* (a) would be violated (also takes care of (b)) */
4295 if (get_attr_trap (i) == TRAP_YES
4296 && ((sum.defd.i & sum.used.i)
4297 || (sum.defd.fp & sum.used.fp)))
4298 abort ();
4299
4300 goto close_shadow;
4301 }
4302 break;
4303
4304 case JUMP_INSN:
4305 case CALL_INSN:
4306 case CODE_LABEL:
4307 goto close_shadow;
4308
4309 default:
4310 abort ();
4311 }
4312 }
4313 else
4314 {
4315 close_shadow:
4316 n = emit_insn_before (gen_trapb (), i);
4317 PUT_MODE (n, TImode);
4318 PUT_MODE (i, TImode);
4319 trap_pending = 0;
4320 shadow.used.i = 0;
4321 shadow.used.fp = 0;
4322 shadow.used.mem = 0;
4323 shadow.defd = shadow.used;
4324 }
4325 }
4326 }
4327
4328 if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
4329 && GET_CODE (i) == INSN
4330 && GET_CODE (PATTERN (i)) != USE
4331 && GET_CODE (PATTERN (i)) != CLOBBER
4332 && get_attr_trap (i) == TRAP_YES)
4333 {
4334 if (optimize && !trap_pending)
4335 summarize_insn (PATTERN (i), &shadow, 0);
4336 trap_pending = 1;
4337 }
4338 }
4339 }
4340 \f
4341 #ifdef HAIFA
4342 /* Alpha can only issue instruction groups simultaneously if they are
4343 suitibly aligned. This is very processor-specific. */
4344
4345 enum alphaev4_pipe {
4346 EV4_STOP = 0,
4347 EV4_IB0 = 1,
4348 EV4_IB1 = 2,
4349 EV4_IBX = 4
4350 };
4351
4352 enum alphaev5_pipe {
4353 EV5_STOP = 0,
4354 EV5_NONE = 1,
4355 EV5_E01 = 2,
4356 EV5_E0 = 4,
4357 EV5_E1 = 8,
4358 EV5_FAM = 16,
4359 EV5_FA = 32,
4360 EV5_FM = 64
4361 };
4362
4363 static enum alphaev4_pipe alphaev4_insn_pipe PROTO((rtx));
4364 static enum alphaev5_pipe alphaev5_insn_pipe PROTO((rtx));
4365 static rtx alphaev4_next_group PROTO((rtx, int*, int*));
4366 static rtx alphaev5_next_group PROTO((rtx, int*, int*));
4367 static rtx alphaev4_next_nop PROTO((int*));
4368 static rtx alphaev5_next_nop PROTO((int*));
4369
4370 static void alpha_align_insns
4371 PROTO((rtx, int, rtx (*)(rtx, int*, int*), rtx (*)(int*), int));
4372
4373 static enum alphaev4_pipe
4374 alphaev4_insn_pipe (insn)
4375 rtx insn;
4376 {
4377 if (recog_memoized (insn) < 0)
4378 return EV4_STOP;
4379 if (get_attr_length (insn) != 4)
4380 return EV4_STOP;
4381
4382 switch (get_attr_type (insn))
4383 {
4384 case TYPE_ILD:
4385 case TYPE_FLD:
4386 return EV4_IBX;
4387
4388 case TYPE_LDSYM:
4389 case TYPE_IADD:
4390 case TYPE_ILOG:
4391 case TYPE_ICMOV:
4392 case TYPE_ICMP:
4393 case TYPE_IST:
4394 case TYPE_FST:
4395 case TYPE_SHIFT:
4396 case TYPE_IMUL:
4397 case TYPE_FBR:
4398 return EV4_IB0;
4399
4400 case TYPE_MISC:
4401 case TYPE_IBR:
4402 case TYPE_JSR:
4403 case TYPE_FCPYS:
4404 case TYPE_FCMOV:
4405 case TYPE_FADD:
4406 case TYPE_FDIV:
4407 case TYPE_FMUL:
4408 return EV4_IB1;
4409
4410 default:
4411 abort();
4412 }
4413 }
4414
4415 static enum alphaev5_pipe
4416 alphaev5_insn_pipe (insn)
4417 rtx insn;
4418 {
4419 if (recog_memoized (insn) < 0)
4420 return EV5_STOP;
4421 if (get_attr_length (insn) != 4)
4422 return EV5_STOP;
4423
4424 switch (get_attr_type (insn))
4425 {
4426 case TYPE_ILD:
4427 case TYPE_FLD:
4428 case TYPE_LDSYM:
4429 case TYPE_IADD:
4430 case TYPE_ILOG:
4431 case TYPE_ICMOV:
4432 case TYPE_ICMP:
4433 return EV5_E01;
4434
4435 case TYPE_IST:
4436 case TYPE_FST:
4437 case TYPE_SHIFT:
4438 case TYPE_IMUL:
4439 case TYPE_MISC:
4440 case TYPE_MVI:
4441 return EV5_E0;
4442
4443 case TYPE_IBR:
4444 case TYPE_JSR:
4445 return EV5_E1;
4446
4447 case TYPE_FCPYS:
4448 return EV5_FAM;
4449
4450 case TYPE_FBR:
4451 case TYPE_FCMOV:
4452 case TYPE_FADD:
4453 case TYPE_FDIV:
4454 return EV5_FA;
4455
4456 case TYPE_FMUL:
4457 return EV5_FM;
4458
4459 default:
4460 abort();
4461 }
4462 }
4463
4464 /* IN_USE is a mask of the slots currently filled within the insn group.
4465 The mask bits come from alphaev4_pipe above. If EV4_IBX is set, then
4466 the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.
4467
4468 LEN is, of course, the length of the group in bytes. */
4469
4470 static rtx
4471 alphaev4_next_group (insn, pin_use, plen)
4472 rtx insn;
4473 int *pin_use, *plen;
4474 {
4475 int len, in_use;
4476
4477 len = in_use = 0;
4478
4479 if (GET_RTX_CLASS (GET_CODE (insn)) != 'i'
4480 || GET_CODE (PATTERN (insn)) == CLOBBER
4481 || GET_CODE (PATTERN (insn)) == USE)
4482 goto next_and_done;
4483
4484 while (1)
4485 {
4486 enum alphaev4_pipe pipe;
4487
4488 pipe = alphaev4_insn_pipe (insn);
4489 switch (pipe)
4490 {
4491 case EV4_STOP:
4492 /* Force complex instructions to start new groups. */
4493 if (in_use)
4494 goto done;
4495
4496 /* If this is a completely unrecognized insn, its an asm.
4497 We don't know how long it is, so record length as -1 to
4498 signal a needed realignment. */
4499 if (recog_memoized (insn) < 0)
4500 len = -1;
4501 else
4502 len = get_attr_length (insn);
4503 goto next_and_done;
4504
4505 case EV4_IBX:
4506 if (in_use & EV4_IB0)
4507 {
4508 if (in_use & EV4_IB1)
4509 goto done;
4510 in_use |= EV4_IB1;
4511 }
4512 else
4513 in_use |= EV4_IB0 | EV4_IBX;
4514 break;
4515
4516 case EV4_IB0:
4517 if (in_use & EV4_IB0)
4518 {
4519 if (!(in_use & EV4_IBX) || (in_use & EV4_IB1))
4520 goto done;
4521 in_use |= EV4_IB1;
4522 }
4523 in_use |= EV4_IB0;
4524 break;
4525
4526 case EV4_IB1:
4527 if (in_use & EV4_IB1)
4528 goto done;
4529 in_use |= EV4_IB1;
4530 break;
4531
4532 default:
4533 abort();
4534 }
4535 len += 4;
4536
4537 /* Haifa doesn't do well scheduling branches. */
4538 if (GET_CODE (insn) == JUMP_INSN)
4539 goto next_and_done;
4540
4541 next:
4542 insn = next_nonnote_insn (insn);
4543
4544 if (!insn || GET_RTX_CLASS (GET_CODE (insn)) != 'i')
4545 goto done;
4546
4547 /* Let Haifa tell us where it thinks insn group boundaries are. */
4548 if (GET_MODE (insn) == TImode)
4549 goto done;
4550
4551 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
4552 goto next;
4553 }
4554
4555 next_and_done:
4556 insn = next_nonnote_insn (insn);
4557
4558 done:
4559 *plen = len;
4560 *pin_use = in_use;
4561 return insn;
4562 }
4563
4564 /* IN_USE is a mask of the slots currently filled within the insn group.
4565 The mask bits come from alphaev5_pipe above. If EV5_E01 is set, then
4566 the insn in EV5_E0 can be swapped by the hardware into EV5_E1.
4567
4568 LEN is, of course, the length of the group in bytes. */
4569
4570 static rtx
4571 alphaev5_next_group (insn, pin_use, plen)
4572 rtx insn;
4573 int *pin_use, *plen;
4574 {
4575 int len, in_use;
4576
4577 len = in_use = 0;
4578
4579 if (GET_RTX_CLASS (GET_CODE (insn)) != 'i'
4580 || GET_CODE (PATTERN (insn)) == CLOBBER
4581 || GET_CODE (PATTERN (insn)) == USE)
4582 goto next_and_done;
4583
4584 while (1)
4585 {
4586 enum alphaev5_pipe pipe;
4587
4588 pipe = alphaev5_insn_pipe (insn);
4589 switch (pipe)
4590 {
4591 case EV5_STOP:
4592 /* Force complex instructions to start new groups. */
4593 if (in_use)
4594 goto done;
4595
4596 /* If this is a completely unrecognized insn, its an asm.
4597 We don't know how long it is, so record length as -1 to
4598 signal a needed realignment. */
4599 if (recog_memoized (insn) < 0)
4600 len = -1;
4601 else
4602 len = get_attr_length (insn);
4603 goto next_and_done;
4604
4605 /* ??? Most of the places below, we would like to abort, as
4606 it would indicate an error either in Haifa, or in the
4607 scheduling description. Unfortunately, Haifa never
4608 schedules the last instruction of the BB, so we don't
4609 have an accurate TI bit to go off. */
4610 case EV5_E01:
4611 if (in_use & EV5_E0)
4612 {
4613 if (in_use & EV5_E1)
4614 goto done;
4615 in_use |= EV5_E1;
4616 }
4617 else
4618 in_use |= EV5_E0 | EV5_E01;
4619 break;
4620
4621 case EV5_E0:
4622 if (in_use & EV5_E0)
4623 {
4624 if (!(in_use & EV5_E01) || (in_use & EV5_E1))
4625 goto done;
4626 in_use |= EV5_E1;
4627 }
4628 in_use |= EV5_E0;
4629 break;
4630
4631 case EV5_E1:
4632 if (in_use & EV5_E1)
4633 goto done;
4634 in_use |= EV5_E1;
4635 break;
4636
4637 case EV5_FAM:
4638 if (in_use & EV5_FA)
4639 {
4640 if (in_use & EV5_FM)
4641 goto done;
4642 in_use |= EV5_FM;
4643 }
4644 else
4645 in_use |= EV5_FA | EV5_FAM;
4646 break;
4647
4648 case EV5_FA:
4649 if (in_use & EV5_FA)
4650 goto done;
4651 in_use |= EV5_FA;
4652 break;
4653
4654 case EV5_FM:
4655 if (in_use & EV5_FM)
4656 goto done;
4657 in_use |= EV5_FM;
4658 break;
4659
4660 case EV5_NONE:
4661 break;
4662
4663 default:
4664 abort();
4665 }
4666 len += 4;
4667
4668 /* Haifa doesn't do well scheduling branches. */
4669 /* ??? If this is predicted not-taken, slotting continues, except
4670 that no more IBR, FBR, or JSR insns may be slotted. */
4671 if (GET_CODE (insn) == JUMP_INSN)
4672 goto next_and_done;
4673
4674 next:
4675 insn = next_nonnote_insn (insn);
4676
4677 if (!insn || GET_RTX_CLASS (GET_CODE (insn)) != 'i')
4678 goto done;
4679
4680 /* Let Haifa tell us where it thinks insn group boundaries are. */
4681 if (GET_MODE (insn) == TImode)
4682 goto done;
4683
4684 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
4685 goto next;
4686 }
4687
4688 next_and_done:
4689 insn = next_nonnote_insn (insn);
4690
4691 done:
4692 *plen = len;
4693 *pin_use = in_use;
4694 return insn;
4695 }
4696
4697 static rtx
4698 alphaev4_next_nop (pin_use)
4699 int *pin_use;
4700 {
4701 int in_use = *pin_use;
4702 rtx nop;
4703
4704 if (!(in_use & EV4_IB0))
4705 {
4706 in_use |= EV4_IB0;
4707 nop = gen_nop ();
4708 }
4709 else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX)
4710 {
4711 in_use |= EV4_IB1;
4712 nop = gen_nop ();
4713 }
4714 else if (TARGET_FP && !(in_use & EV4_IB1))
4715 {
4716 in_use |= EV4_IB1;
4717 nop = gen_fnop ();
4718 }
4719 else
4720 nop = gen_unop ();
4721
4722 *pin_use = in_use;
4723 return nop;
4724 }
4725
4726 static rtx
4727 alphaev5_next_nop (pin_use)
4728 int *pin_use;
4729 {
4730 int in_use = *pin_use;
4731 rtx nop;
4732
4733 if (!(in_use & EV5_E1))
4734 {
4735 in_use |= EV5_E1;
4736 nop = gen_nop ();
4737 }
4738 else if (TARGET_FP && !(in_use & EV5_FA))
4739 {
4740 in_use |= EV5_FA;
4741 nop = gen_fnop ();
4742 }
4743 else if (TARGET_FP && !(in_use & EV5_FM))
4744 {
4745 in_use |= EV5_FM;
4746 nop = gen_fnop ();
4747 }
4748 else
4749 nop = gen_unop ();
4750
4751 *pin_use = in_use;
4752 return nop;
4753 }
4754
4755 /* The instruction group alignment main loop. */
4756
4757 static void
4758 alpha_align_insns (insns, max_align, next_group, next_nop, gp_in_use)
4759 rtx insns;
4760 int max_align;
4761 rtx (*next_group) PROTO((rtx, int*, int*));
4762 rtx (*next_nop) PROTO((int*));
4763 int gp_in_use;
4764 {
4765 /* ALIGN is the known alignment for the insn group. */
4766 int align;
4767 /* OFS is the offset of the current insn in the insn group. */
4768 int ofs;
4769 int prev_in_use, in_use, len;
4770 rtx i, next;
4771
4772 /* Let shorten branches care for assigning alignments to code labels. */
4773 shorten_branches (insns);
4774
4775 align = (FUNCTION_BOUNDARY/BITS_PER_UNIT < max_align
4776 ? FUNCTION_BOUNDARY/BITS_PER_UNIT : max_align);
4777
4778 /* Account for the initial GP load, which happens before the scheduled
4779 prologue we emitted as RTL. */
4780 ofs = prev_in_use = 0;
4781 if (alpha_does_function_need_gp())
4782 {
4783 ofs = 8 & (align - 1);
4784 prev_in_use = gp_in_use;
4785 }
4786
4787 i = insns;
4788 if (GET_CODE (i) == NOTE)
4789 i = next_nonnote_insn (i);
4790
4791 while (i)
4792 {
4793 next = (*next_group)(i, &in_use, &len);
4794
4795 /* When we see a label, resync alignment etc. */
4796 if (GET_CODE (i) == CODE_LABEL)
4797 {
4798 int new_align = 1 << label_to_alignment (i);
4799 if (new_align >= align)
4800 {
4801 align = new_align < max_align ? new_align : max_align;
4802 ofs = 0;
4803 }
4804 else if (ofs & (new_align-1))
4805 ofs = (ofs | (new_align-1)) + 1;
4806 if (len != 0)
4807 abort();
4808 }
4809
4810 /* Handle complex instructions special. */
4811 else if (in_use == 0)
4812 {
4813 /* Asms will have length < 0. This is a signal that we have
4814 lost alignment knowledge. Assume, however, that the asm
4815 will not mis-align instructions. */
4816 if (len < 0)
4817 {
4818 ofs = 0;
4819 align = 4;
4820 len = 0;
4821 }
4822 }
4823
4824 /* If the known alignment is smaller than the recognized insn group,
4825 realign the output. */
4826 else if (align < len)
4827 {
4828 int new_log_align = len > 8 ? 4 : 3;
4829 rtx where;
4830
4831 where = prev_nonnote_insn (i);
4832 if (!where || GET_CODE (where) != CODE_LABEL)
4833 where = i;
4834
4835 emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
4836 align = 1 << new_log_align;
4837 ofs = 0;
4838 }
4839
4840 /* If the group won't fit in the same INT16 as the previous,
4841 we need to add padding to keep the group together. Rather
4842 than simply leaving the insn filling to the assembler, we
4843 can make use of the knowledge of what sorts of instructions
4844 were issued in the previous group to make sure that all of
4845 the added nops are really free. */
4846 else if (ofs + len > align)
4847 {
4848 int nop_count = (align - ofs) / 4;
4849 rtx where;
4850
4851 /* Insert nops before labels and branches to truely merge the
4852 execution of the nops with the previous instruction group. */
4853 where = prev_nonnote_insn (i);
4854 if (where)
4855 {
4856 if (GET_CODE (where) == CODE_LABEL)
4857 {
4858 rtx where2 = prev_nonnote_insn (where);
4859 if (where2 && GET_CODE (where2) == JUMP_INSN)
4860 where = where2;
4861 }
4862 else if (GET_CODE (where) != JUMP_INSN)
4863 where = i;
4864 }
4865 else
4866 where = i;
4867
4868 do
4869 emit_insn_before ((*next_nop)(&prev_in_use), where);
4870 while (--nop_count);
4871 ofs = 0;
4872 }
4873
4874 ofs = (ofs + len) & (align - 1);
4875 prev_in_use = in_use;
4876 i = next;
4877 }
4878 }
4879 #endif /* HAIFA */
4880 \f
4881 /* Machine dependant reorg pass. */
4882
4883 void
4884 alpha_reorg (insns)
4885 rtx insns;
4886 {
4887 if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
4888 alpha_handle_trap_shadows (insns);
4889
4890 #ifdef HAIFA
4891 /* Due to the number of extra trapb insns, don't bother fixing up
4892 alignment when trap precision is instruction. Moreover, we can
4893 only do our job when sched2 is run and Haifa is our scheduler. */
4894 if (optimize && !optimize_size
4895 && alpha_tp != ALPHA_TP_INSN
4896 && flag_schedule_insns_after_reload)
4897 {
4898 if (alpha_cpu == PROCESSOR_EV4)
4899 alpha_align_insns (insns, 8, alphaev4_next_group,
4900 alphaev4_next_nop, EV4_IB0);
4901 else if (alpha_cpu == PROCESSOR_EV5)
4902 alpha_align_insns (insns, 16, alphaev5_next_group,
4903 alphaev5_next_nop, EV5_E01 | EV5_E0);
4904 }
4905 #endif
4906 }
4907
4908 \f
4909 /* Check a floating-point value for validity for a particular machine mode. */
4910
4911 static char * const float_strings[] =
4912 {
4913 /* These are for FLOAT_VAX. */
4914 "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
4915 "-1.70141173319264430e+38",
4916 "2.93873587705571877e-39", /* 2^-128 */
4917 "-2.93873587705571877e-39",
4918 /* These are for the default broken IEEE mode, which traps
4919 on infinity or denormal numbers. */
4920 "3.402823466385288598117e+38", /* 2^128 (1 - 2^-24) */
4921 "-3.402823466385288598117e+38",
4922 "1.1754943508222875079687e-38", /* 2^-126 */
4923 "-1.1754943508222875079687e-38",
4924 };
4925
4926 static REAL_VALUE_TYPE float_values[8];
4927 static int inited_float_values = 0;
4928
4929 int
4930 check_float_value (mode, d, overflow)
4931 enum machine_mode mode;
4932 REAL_VALUE_TYPE *d;
4933 int overflow ATTRIBUTE_UNUSED;
4934 {
4935
4936 if (TARGET_IEEE || TARGET_IEEE_CONFORMANT || TARGET_IEEE_WITH_INEXACT)
4937 return 0;
4938
4939 if (inited_float_values == 0)
4940 {
4941 int i;
4942 for (i = 0; i < 8; i++)
4943 float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
4944
4945 inited_float_values = 1;
4946 }
4947
4948 if (mode == SFmode)
4949 {
4950 REAL_VALUE_TYPE r;
4951 REAL_VALUE_TYPE *fvptr;
4952
4953 if (TARGET_FLOAT_VAX)
4954 fvptr = &float_values[0];
4955 else
4956 fvptr = &float_values[4];
4957
4958 bcopy ((char *) d, (char *) &r, sizeof (REAL_VALUE_TYPE));
4959 if (REAL_VALUES_LESS (fvptr[0], r))
4960 {
4961 bcopy ((char *) &fvptr[0], (char *) d,
4962 sizeof (REAL_VALUE_TYPE));
4963 return 1;
4964 }
4965 else if (REAL_VALUES_LESS (r, fvptr[1]))
4966 {
4967 bcopy ((char *) &fvptr[1], (char *) d,
4968 sizeof (REAL_VALUE_TYPE));
4969 return 1;
4970 }
4971 else if (REAL_VALUES_LESS (dconst0, r)
4972 && REAL_VALUES_LESS (r, fvptr[2]))
4973 {
4974 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
4975 return 1;
4976 }
4977 else if (REAL_VALUES_LESS (r, dconst0)
4978 && REAL_VALUES_LESS (fvptr[3], r))
4979 {
4980 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
4981 return 1;
4982 }
4983 }
4984
4985 return 0;
4986 }
4987
4988 #if OPEN_VMS
4989
4990 /* Return the VMS argument type corresponding to MODE. */
4991
4992 enum avms_arg_type
4993 alpha_arg_type (mode)
4994 enum machine_mode mode;
4995 {
4996 switch (mode)
4997 {
4998 case SFmode:
4999 return TARGET_FLOAT_VAX ? FF : FS;
5000 case DFmode:
5001 return TARGET_FLOAT_VAX ? FD : FT;
5002 default:
5003 return I64;
5004 }
5005 }
5006
5007 /* Return an rtx for an integer representing the VMS Argument Information
5008 register value. */
5009
5010 struct rtx_def *
5011 alpha_arg_info_reg_val (cum)
5012 CUMULATIVE_ARGS cum;
5013 {
5014 unsigned HOST_WIDE_INT regval = cum.num_args;
5015 int i;
5016
5017 for (i = 0; i < 6; i++)
5018 regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
5019
5020 return GEN_INT (regval);
5021 }
5022 \f
5023 /* Structure to collect function names for final output
5024 in link section. */
5025
5026 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
5027
5028
5029 struct alpha_links {
5030 struct alpha_links *next;
5031 char *name;
5032 enum links_kind kind;
5033 };
5034
5035 static struct alpha_links *alpha_links_base = 0;
5036
5037 /* Make (or fake) .linkage entry for function call.
5038
5039 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition. */
5040
5041 void
5042 alpha_need_linkage (name, is_local)
5043 char *name;
5044 int is_local;
5045 {
5046 rtx x;
5047 struct alpha_links *lptr, *nptr;
5048
5049 if (name[0] == '*')
5050 name++;
5051
5052 /* Is this name already defined ? */
5053
5054 for (lptr = alpha_links_base; lptr; lptr = lptr->next)
5055 if (strcmp (lptr->name, name) == 0)
5056 {
5057 if (is_local)
5058 {
5059 /* Defined here but external assumed. */
5060 if (lptr->kind == KIND_EXTERN)
5061 lptr->kind = KIND_LOCAL;
5062 }
5063 else
5064 {
5065 /* Used here but unused assumed. */
5066 if (lptr->kind == KIND_UNUSED)
5067 lptr->kind = KIND_LOCAL;
5068 }
5069 return;
5070 }
5071
5072 nptr = (struct alpha_links *) xmalloc (sizeof (struct alpha_links));
5073 nptr->next = alpha_links_base;
5074 nptr->name = xstrdup (name);
5075
5076 /* Assume external if no definition. */
5077 nptr->kind = (is_local ? KIND_UNUSED : KIND_EXTERN);
5078
5079 /* Ensure we have an IDENTIFIER so assemble_name can mark is used. */
5080 get_identifier (name);
5081
5082 alpha_links_base = nptr;
5083
5084 return;
5085 }
5086
5087
5088 void
5089 alpha_write_linkage (stream)
5090 FILE *stream;
5091 {
5092 struct alpha_links *lptr, *nptr;
5093
5094 readonly_section ();
5095
5096 fprintf (stream, "\t.align 3\n");
5097
5098 for (lptr = alpha_links_base; lptr; lptr = nptr)
5099 {
5100 nptr = lptr->next;
5101
5102 if (lptr->kind == KIND_UNUSED
5103 || ! TREE_SYMBOL_REFERENCED (get_identifier (lptr->name)))
5104 continue;
5105
5106 fprintf (stream, "$%s..lk:\n", lptr->name);
5107 if (lptr->kind == KIND_LOCAL)
5108 {
5109 /* Local and used, build linkage pair. */
5110 fprintf (stream, "\t.quad %s..en\n", lptr->name);
5111 fprintf (stream, "\t.quad %s\n", lptr->name);
5112 }
5113 else
5114 /* External and used, request linkage pair. */
5115 fprintf (stream, "\t.linkage %s\n", lptr->name);
5116 }
5117 }
5118
5119 #else
5120
5121 void
5122 alpha_need_linkage (name, is_local)
5123 char *name ATTRIBUTE_UNUSED;
5124 int is_local ATTRIBUTE_UNUSED;
5125 {
5126 }
5127
5128 #endif /* OPEN_VMS */