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