]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/alpha/alpha.c
darwin.c, [...]: Update copyright.
[thirdparty/gcc.git] / gcc / config / alpha / alpha.c
1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
22
23
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "regs.h"
31 #include "hard-reg-set.h"
32 #include "real.h"
33 #include "insn-config.h"
34 #include "conditions.h"
35 #include "output.h"
36 #include "insn-attr.h"
37 #include "flags.h"
38 #include "recog.h"
39 #include "expr.h"
40 #include "optabs.h"
41 #include "reload.h"
42 #include "obstack.h"
43 #include "except.h"
44 #include "function.h"
45 #include "toplev.h"
46 #include "ggc.h"
47 #include "integrate.h"
48 #include "tm_p.h"
49 #include "target.h"
50 #include "target-def.h"
51 #include "debug.h"
52 #include "langhooks.h"
53 #include <splay-tree.h>
54 #include "cfglayout.h"
55 #include "tree-gimple.h"
56
57 /* Specify which cpu to schedule for. */
58
59 enum processor_type alpha_cpu;
60 static const char * const alpha_cpu_name[] =
61 {
62 "ev4", "ev5", "ev6"
63 };
64
65 /* Specify how accurate floating-point traps need to be. */
66
67 enum alpha_trap_precision alpha_tp;
68
69 /* Specify the floating-point rounding mode. */
70
71 enum alpha_fp_rounding_mode alpha_fprm;
72
73 /* Specify which things cause traps. */
74
75 enum alpha_fp_trap_mode alpha_fptm;
76
77 /* Specify bit size of immediate TLS offsets. */
78
79 int alpha_tls_size = 32;
80
81 /* Strings decoded into the above options. */
82
83 const char *alpha_cpu_string; /* -mcpu= */
84 const char *alpha_tune_string; /* -mtune= */
85 const char *alpha_tp_string; /* -mtrap-precision=[p|s|i] */
86 const char *alpha_fprm_string; /* -mfp-rounding-mode=[n|m|c|d] */
87 const char *alpha_fptm_string; /* -mfp-trap-mode=[n|u|su|sui] */
88 const char *alpha_mlat_string; /* -mmemory-latency= */
89 const char *alpha_tls_size_string; /* -mtls-size=[16|32|64] */
90
91 /* Save information from a "cmpxx" operation until the branch or scc is
92 emitted. */
93
94 struct alpha_compare alpha_compare;
95
96 /* Nonzero if inside of a function, because the Alpha asm can't
97 handle .files inside of functions. */
98
99 static int inside_function = FALSE;
100
101 /* The number of cycles of latency we should assume on memory reads. */
102
103 int alpha_memory_latency = 3;
104
105 /* Whether the function needs the GP. */
106
107 static int alpha_function_needs_gp;
108
109 /* The alias set for prologue/epilogue register save/restore. */
110
111 static GTY(()) int alpha_sr_alias_set;
112
113 /* The assembler name of the current function. */
114
115 static const char *alpha_fnname;
116
117 /* The next explicit relocation sequence number. */
118 extern GTY(()) int alpha_next_sequence_number;
119 int alpha_next_sequence_number = 1;
120
121 /* The literal and gpdisp sequence numbers for this insn, as printed
122 by %# and %* respectively. */
123 extern GTY(()) int alpha_this_literal_sequence_number;
124 extern GTY(()) int alpha_this_gpdisp_sequence_number;
125 int alpha_this_literal_sequence_number;
126 int alpha_this_gpdisp_sequence_number;
127
128 /* Costs of various operations on the different architectures. */
129
130 struct alpha_rtx_cost_data
131 {
132 unsigned char fp_add;
133 unsigned char fp_mult;
134 unsigned char fp_div_sf;
135 unsigned char fp_div_df;
136 unsigned char int_mult_si;
137 unsigned char int_mult_di;
138 unsigned char int_shift;
139 unsigned char int_cmov;
140 unsigned short int_div;
141 };
142
143 static struct alpha_rtx_cost_data const alpha_rtx_cost_data[PROCESSOR_MAX] =
144 {
145 { /* EV4 */
146 COSTS_N_INSNS (6), /* fp_add */
147 COSTS_N_INSNS (6), /* fp_mult */
148 COSTS_N_INSNS (34), /* fp_div_sf */
149 COSTS_N_INSNS (63), /* fp_div_df */
150 COSTS_N_INSNS (23), /* int_mult_si */
151 COSTS_N_INSNS (23), /* int_mult_di */
152 COSTS_N_INSNS (2), /* int_shift */
153 COSTS_N_INSNS (2), /* int_cmov */
154 COSTS_N_INSNS (97), /* int_div */
155 },
156 { /* EV5 */
157 COSTS_N_INSNS (4), /* fp_add */
158 COSTS_N_INSNS (4), /* fp_mult */
159 COSTS_N_INSNS (15), /* fp_div_sf */
160 COSTS_N_INSNS (22), /* fp_div_df */
161 COSTS_N_INSNS (8), /* int_mult_si */
162 COSTS_N_INSNS (12), /* int_mult_di */
163 COSTS_N_INSNS (1) + 1, /* int_shift */
164 COSTS_N_INSNS (1), /* int_cmov */
165 COSTS_N_INSNS (83), /* int_div */
166 },
167 { /* EV6 */
168 COSTS_N_INSNS (4), /* fp_add */
169 COSTS_N_INSNS (4), /* fp_mult */
170 COSTS_N_INSNS (12), /* fp_div_sf */
171 COSTS_N_INSNS (15), /* fp_div_df */
172 COSTS_N_INSNS (7), /* int_mult_si */
173 COSTS_N_INSNS (7), /* int_mult_di */
174 COSTS_N_INSNS (1), /* int_shift */
175 COSTS_N_INSNS (2), /* int_cmov */
176 COSTS_N_INSNS (86), /* int_div */
177 },
178 };
179
180 /* Similar but tuned for code size instead of execution latency. The
181 extra +N is fractional cost tuning based on latency. It's used to
182 encourage use of cheaper insns like shift, but only if there's just
183 one of them. */
184
185 static struct alpha_rtx_cost_data const alpha_rtx_cost_size =
186 {
187 COSTS_N_INSNS (1), /* fp_add */
188 COSTS_N_INSNS (1), /* fp_mult */
189 COSTS_N_INSNS (1), /* fp_div_sf */
190 COSTS_N_INSNS (1) + 1, /* fp_div_df */
191 COSTS_N_INSNS (1) + 1, /* int_mult_si */
192 COSTS_N_INSNS (1) + 2, /* int_mult_di */
193 COSTS_N_INSNS (1), /* int_shift */
194 COSTS_N_INSNS (1), /* int_cmov */
195 COSTS_N_INSNS (6), /* int_div */
196 };
197
198 /* Get the number of args of a function in one of two ways. */
199 #if TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK
200 #define NUM_ARGS current_function_args_info.num_args
201 #else
202 #define NUM_ARGS current_function_args_info
203 #endif
204
205 #define REG_PV 27
206 #define REG_RA 26
207
208 /* Declarations of static functions. */
209 static struct machine_function *alpha_init_machine_status (void);
210 static rtx alpha_emit_xfloating_compare (enum rtx_code, rtx, rtx);
211
212 #if TARGET_ABI_OPEN_VMS
213 static void alpha_write_linkage (FILE *, const char *, tree);
214 #endif
215
216 static void unicosmk_output_deferred_case_vectors (FILE *);
217 static void unicosmk_gen_dsib (unsigned long *);
218 static void unicosmk_output_ssib (FILE *, const char *);
219 static int unicosmk_need_dex (rtx);
220 \f
221 /* Parse target option strings. */
222
223 void
224 override_options (void)
225 {
226 int i;
227 static const struct cpu_table {
228 const char *const name;
229 const enum processor_type processor;
230 const int flags;
231 } cpu_table[] = {
232 #define EV5_MASK (MASK_CPU_EV5)
233 #define EV6_MASK (MASK_CPU_EV6|MASK_BWX|MASK_MAX|MASK_FIX)
234 { "ev4", PROCESSOR_EV4, 0 },
235 { "ev45", PROCESSOR_EV4, 0 },
236 { "21064", PROCESSOR_EV4, 0 },
237 { "ev5", PROCESSOR_EV5, EV5_MASK },
238 { "21164", PROCESSOR_EV5, EV5_MASK },
239 { "ev56", PROCESSOR_EV5, EV5_MASK|MASK_BWX },
240 { "21164a", PROCESSOR_EV5, EV5_MASK|MASK_BWX },
241 { "pca56", PROCESSOR_EV5, EV5_MASK|MASK_BWX|MASK_MAX },
242 { "21164PC",PROCESSOR_EV5, EV5_MASK|MASK_BWX|MASK_MAX },
243 { "21164pc",PROCESSOR_EV5, EV5_MASK|MASK_BWX|MASK_MAX },
244 { "ev6", PROCESSOR_EV6, EV6_MASK },
245 { "21264", PROCESSOR_EV6, EV6_MASK },
246 { "ev67", PROCESSOR_EV6, EV6_MASK|MASK_CIX },
247 { "21264a", PROCESSOR_EV6, EV6_MASK|MASK_CIX },
248 { 0, 0, 0 }
249 };
250
251 /* Unicos/Mk doesn't have shared libraries. */
252 if (TARGET_ABI_UNICOSMK && flag_pic)
253 {
254 warning ("-f%s ignored for Unicos/Mk (not supported)",
255 (flag_pic > 1) ? "PIC" : "pic");
256 flag_pic = 0;
257 }
258
259 /* On Unicos/Mk, the native compiler consistently generates /d suffices for
260 floating-point instructions. Make that the default for this target. */
261 if (TARGET_ABI_UNICOSMK)
262 alpha_fprm = ALPHA_FPRM_DYN;
263 else
264 alpha_fprm = ALPHA_FPRM_NORM;
265
266 alpha_tp = ALPHA_TP_PROG;
267 alpha_fptm = ALPHA_FPTM_N;
268
269 /* We cannot use su and sui qualifiers for conversion instructions on
270 Unicos/Mk. I'm not sure if this is due to assembler or hardware
271 limitations. Right now, we issue a warning if -mieee is specified
272 and then ignore it; eventually, we should either get it right or
273 disable the option altogether. */
274
275 if (TARGET_IEEE)
276 {
277 if (TARGET_ABI_UNICOSMK)
278 warning ("-mieee not supported on Unicos/Mk");
279 else
280 {
281 alpha_tp = ALPHA_TP_INSN;
282 alpha_fptm = ALPHA_FPTM_SU;
283 }
284 }
285
286 if (TARGET_IEEE_WITH_INEXACT)
287 {
288 if (TARGET_ABI_UNICOSMK)
289 warning ("-mieee-with-inexact not supported on Unicos/Mk");
290 else
291 {
292 alpha_tp = ALPHA_TP_INSN;
293 alpha_fptm = ALPHA_FPTM_SUI;
294 }
295 }
296
297 if (alpha_tp_string)
298 {
299 if (! strcmp (alpha_tp_string, "p"))
300 alpha_tp = ALPHA_TP_PROG;
301 else if (! strcmp (alpha_tp_string, "f"))
302 alpha_tp = ALPHA_TP_FUNC;
303 else if (! strcmp (alpha_tp_string, "i"))
304 alpha_tp = ALPHA_TP_INSN;
305 else
306 error ("bad value %qs for -mtrap-precision switch", alpha_tp_string);
307 }
308
309 if (alpha_fprm_string)
310 {
311 if (! strcmp (alpha_fprm_string, "n"))
312 alpha_fprm = ALPHA_FPRM_NORM;
313 else if (! strcmp (alpha_fprm_string, "m"))
314 alpha_fprm = ALPHA_FPRM_MINF;
315 else if (! strcmp (alpha_fprm_string, "c"))
316 alpha_fprm = ALPHA_FPRM_CHOP;
317 else if (! strcmp (alpha_fprm_string,"d"))
318 alpha_fprm = ALPHA_FPRM_DYN;
319 else
320 error ("bad value %qs for -mfp-rounding-mode switch",
321 alpha_fprm_string);
322 }
323
324 if (alpha_fptm_string)
325 {
326 if (strcmp (alpha_fptm_string, "n") == 0)
327 alpha_fptm = ALPHA_FPTM_N;
328 else if (strcmp (alpha_fptm_string, "u") == 0)
329 alpha_fptm = ALPHA_FPTM_U;
330 else if (strcmp (alpha_fptm_string, "su") == 0)
331 alpha_fptm = ALPHA_FPTM_SU;
332 else if (strcmp (alpha_fptm_string, "sui") == 0)
333 alpha_fptm = ALPHA_FPTM_SUI;
334 else
335 error ("bad value %qs for -mfp-trap-mode switch", alpha_fptm_string);
336 }
337
338 if (alpha_tls_size_string)
339 {
340 if (strcmp (alpha_tls_size_string, "16") == 0)
341 alpha_tls_size = 16;
342 else if (strcmp (alpha_tls_size_string, "32") == 0)
343 alpha_tls_size = 32;
344 else if (strcmp (alpha_tls_size_string, "64") == 0)
345 alpha_tls_size = 64;
346 else
347 error ("bad value %qs for -mtls-size switch", alpha_tls_size_string);
348 }
349
350 alpha_cpu
351 = TARGET_CPU_DEFAULT & MASK_CPU_EV6 ? PROCESSOR_EV6
352 : (TARGET_CPU_DEFAULT & MASK_CPU_EV5 ? PROCESSOR_EV5 : PROCESSOR_EV4);
353
354 if (alpha_cpu_string)
355 {
356 for (i = 0; cpu_table [i].name; i++)
357 if (! strcmp (alpha_cpu_string, cpu_table [i].name))
358 {
359 alpha_cpu = cpu_table [i].processor;
360 target_flags &= ~ (MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX
361 | MASK_CPU_EV5 | MASK_CPU_EV6);
362 target_flags |= cpu_table [i].flags;
363 break;
364 }
365 if (! cpu_table [i].name)
366 error ("bad value %qs for -mcpu switch", alpha_cpu_string);
367 }
368
369 if (alpha_tune_string)
370 {
371 for (i = 0; cpu_table [i].name; i++)
372 if (! strcmp (alpha_tune_string, cpu_table [i].name))
373 {
374 alpha_cpu = cpu_table [i].processor;
375 break;
376 }
377 if (! cpu_table [i].name)
378 error ("bad value %qs for -mcpu switch", alpha_tune_string);
379 }
380
381 /* Do some sanity checks on the above options. */
382
383 if (TARGET_ABI_UNICOSMK && alpha_fptm != ALPHA_FPTM_N)
384 {
385 warning ("trap mode not supported on Unicos/Mk");
386 alpha_fptm = ALPHA_FPTM_N;
387 }
388
389 if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI)
390 && alpha_tp != ALPHA_TP_INSN && ! TARGET_CPU_EV6)
391 {
392 warning ("fp software completion requires -mtrap-precision=i");
393 alpha_tp = ALPHA_TP_INSN;
394 }
395
396 if (TARGET_CPU_EV6)
397 {
398 /* Except for EV6 pass 1 (not released), we always have precise
399 arithmetic traps. Which means we can do software completion
400 without minding trap shadows. */
401 alpha_tp = ALPHA_TP_PROG;
402 }
403
404 if (TARGET_FLOAT_VAX)
405 {
406 if (alpha_fprm == ALPHA_FPRM_MINF || alpha_fprm == ALPHA_FPRM_DYN)
407 {
408 warning ("rounding mode not supported for VAX floats");
409 alpha_fprm = ALPHA_FPRM_NORM;
410 }
411 if (alpha_fptm == ALPHA_FPTM_SUI)
412 {
413 warning ("trap mode not supported for VAX floats");
414 alpha_fptm = ALPHA_FPTM_SU;
415 }
416 if (target_flags_explicit & MASK_LONG_DOUBLE_128)
417 warning ("128-bit long double not supported for VAX floats");
418 target_flags &= ~MASK_LONG_DOUBLE_128;
419 }
420
421 {
422 char *end;
423 int lat;
424
425 if (!alpha_mlat_string)
426 alpha_mlat_string = "L1";
427
428 if (ISDIGIT ((unsigned char)alpha_mlat_string[0])
429 && (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0'))
430 ;
431 else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l')
432 && ISDIGIT ((unsigned char)alpha_mlat_string[1])
433 && alpha_mlat_string[2] == '\0')
434 {
435 static int const cache_latency[][4] =
436 {
437 { 3, 30, -1 }, /* ev4 -- Bcache is a guess */
438 { 2, 12, 38 }, /* ev5 -- Bcache from PC164 LMbench numbers */
439 { 3, 12, 30 }, /* ev6 -- Bcache from DS20 LMbench. */
440 };
441
442 lat = alpha_mlat_string[1] - '0';
443 if (lat <= 0 || lat > 3 || cache_latency[alpha_cpu][lat-1] == -1)
444 {
445 warning ("L%d cache latency unknown for %s",
446 lat, alpha_cpu_name[alpha_cpu]);
447 lat = 3;
448 }
449 else
450 lat = cache_latency[alpha_cpu][lat-1];
451 }
452 else if (! strcmp (alpha_mlat_string, "main"))
453 {
454 /* Most current memories have about 370ns latency. This is
455 a reasonable guess for a fast cpu. */
456 lat = 150;
457 }
458 else
459 {
460 warning ("bad value %qs for -mmemory-latency", alpha_mlat_string);
461 lat = 3;
462 }
463
464 alpha_memory_latency = lat;
465 }
466
467 /* Default the definition of "small data" to 8 bytes. */
468 if (!g_switch_set)
469 g_switch_value = 8;
470
471 /* Infer TARGET_SMALL_DATA from -fpic/-fPIC. */
472 if (flag_pic == 1)
473 target_flags |= MASK_SMALL_DATA;
474 else if (flag_pic == 2)
475 target_flags &= ~MASK_SMALL_DATA;
476
477 /* Align labels and loops for optimal branching. */
478 /* ??? Kludge these by not doing anything if we don't optimize and also if
479 we are writing ECOFF symbols to work around a bug in DEC's assembler. */
480 if (optimize > 0 && write_symbols != SDB_DEBUG)
481 {
482 if (align_loops <= 0)
483 align_loops = 16;
484 if (align_jumps <= 0)
485 align_jumps = 16;
486 }
487 if (align_functions <= 0)
488 align_functions = 16;
489
490 /* Acquire a unique set number for our register saves and restores. */
491 alpha_sr_alias_set = new_alias_set ();
492
493 /* Register variables and functions with the garbage collector. */
494
495 /* Set up function hooks. */
496 init_machine_status = alpha_init_machine_status;
497
498 /* Tell the compiler when we're using VAX floating point. */
499 if (TARGET_FLOAT_VAX)
500 {
501 REAL_MODE_FORMAT (SFmode) = &vax_f_format;
502 REAL_MODE_FORMAT (DFmode) = &vax_g_format;
503 REAL_MODE_FORMAT (TFmode) = NULL;
504 }
505 }
506 \f
507 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
508
509 int
510 zap_mask (HOST_WIDE_INT value)
511 {
512 int i;
513
514 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
515 i++, value >>= 8)
516 if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
517 return 0;
518
519 return 1;
520 }
521
522 /* Return true if OP is valid for a particular TLS relocation.
523 We are already guaranteed that OP is a CONST. */
524
525 int
526 tls_symbolic_operand_1 (rtx op, int size, int unspec)
527 {
528 op = XEXP (op, 0);
529
530 if (GET_CODE (op) != UNSPEC || XINT (op, 1) != unspec)
531 return 0;
532 op = XVECEXP (op, 0, 0);
533
534 if (GET_CODE (op) != SYMBOL_REF)
535 return 0;
536
537 if (SYMBOL_REF_LOCAL_P (op))
538 {
539 if (alpha_tls_size > size)
540 return 0;
541 }
542 else
543 {
544 if (size != 64)
545 return 0;
546 }
547
548 switch (SYMBOL_REF_TLS_MODEL (op))
549 {
550 case TLS_MODEL_LOCAL_DYNAMIC:
551 return unspec == UNSPEC_DTPREL;
552 case TLS_MODEL_INITIAL_EXEC:
553 return unspec == UNSPEC_TPREL && size == 64;
554 case TLS_MODEL_LOCAL_EXEC:
555 return unspec == UNSPEC_TPREL;
556 default:
557 abort ();
558 }
559 }
560
561 /* Used by aligned_memory_operand and unaligned_memory_operand to
562 resolve what reload is going to do with OP if it's a register. */
563
564 rtx
565 resolve_reload_operand (rtx op)
566 {
567 if (reload_in_progress)
568 {
569 rtx tmp = op;
570 if (GET_CODE (tmp) == SUBREG)
571 tmp = SUBREG_REG (tmp);
572 if (GET_CODE (tmp) == REG
573 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
574 {
575 op = reg_equiv_memory_loc[REGNO (tmp)];
576 if (op == 0)
577 return 0;
578 }
579 }
580 return op;
581 }
582
583 /* Implements CONST_OK_FOR_LETTER_P. Return true if the value matches
584 the range defined for C in [I-P]. */
585
586 bool
587 alpha_const_ok_for_letter_p (HOST_WIDE_INT value, int c)
588 {
589 switch (c)
590 {
591 case 'I':
592 /* An unsigned 8 bit constant. */
593 return (unsigned HOST_WIDE_INT) value < 0x100;
594 case 'J':
595 /* The constant zero. */
596 return value == 0;
597 case 'K':
598 /* A signed 16 bit constant. */
599 return (unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000;
600 case 'L':
601 /* A shifted signed 16 bit constant appropriate for LDAH. */
602 return ((value & 0xffff) == 0
603 && ((value) >> 31 == -1 || value >> 31 == 0));
604 case 'M':
605 /* A constant that can be AND'ed with using a ZAP insn. */
606 return zap_mask (value);
607 case 'N':
608 /* A complemented unsigned 8 bit constant. */
609 return (unsigned HOST_WIDE_INT) (~ value) < 0x100;
610 case 'O':
611 /* A negated unsigned 8 bit constant. */
612 return (unsigned HOST_WIDE_INT) (- value) < 0x100;
613 case 'P':
614 /* The constant 1, 2 or 3. */
615 return value == 1 || value == 2 || value == 3;
616
617 default:
618 return false;
619 }
620 }
621
622 /* Implements CONST_DOUBLE_OK_FOR_LETTER_P. Return true if VALUE
623 matches for C in [GH]. */
624
625 bool
626 alpha_const_double_ok_for_letter_p (rtx value, int c)
627 {
628 switch (c)
629 {
630 case 'G':
631 /* The floating point zero constant. */
632 return (GET_MODE_CLASS (GET_MODE (value)) == MODE_FLOAT
633 && value == CONST0_RTX (GET_MODE (value)));
634
635 case 'H':
636 /* A valid operand of a ZAP insn. */
637 return (GET_MODE (value) == VOIDmode
638 && zap_mask (CONST_DOUBLE_LOW (value))
639 && zap_mask (CONST_DOUBLE_HIGH (value)));
640
641 default:
642 return false;
643 }
644 }
645
646 /* Implements CONST_DOUBLE_OK_FOR_LETTER_P. Return true if VALUE
647 matches for C. */
648
649 bool
650 alpha_extra_constraint (rtx value, int c)
651 {
652 switch (c)
653 {
654 case 'Q':
655 return normal_memory_operand (value, VOIDmode);
656 case 'R':
657 return direct_call_operand (value, Pmode);
658 case 'S':
659 return (GET_CODE (value) == CONST_INT
660 && (unsigned HOST_WIDE_INT) INTVAL (value) < 64);
661 case 'T':
662 return GET_CODE (value) == HIGH;
663 case 'U':
664 return TARGET_ABI_UNICOSMK && symbolic_operand (value, VOIDmode);
665 case 'W':
666 return (GET_CODE (value) == CONST_VECTOR
667 && value == CONST0_RTX (GET_MODE (value)));
668 default:
669 return false;
670 }
671 }
672
673 /* The scalar modes supported differs from the default check-what-c-supports
674 version in that sometimes TFmode is available even when long double
675 indicates only DFmode. On unicosmk, we have the situation that HImode
676 doesn't map to any C type, but of course we still support that. */
677
678 static bool
679 alpha_scalar_mode_supported_p (enum machine_mode mode)
680 {
681 switch (mode)
682 {
683 case QImode:
684 case HImode:
685 case SImode:
686 case DImode:
687 case TImode: /* via optabs.c */
688 return true;
689
690 case SFmode:
691 case DFmode:
692 return true;
693
694 case TFmode:
695 return TARGET_HAS_XFLOATING_LIBS;
696
697 default:
698 return false;
699 }
700 }
701
702 /* Alpha implements a couple of integer vector mode operations when
703 TARGET_MAX is enabled. We do not check TARGET_MAX here, however,
704 which allows the vectorizer to operate on e.g. move instructions,
705 or when expand_vector_operations can do something useful. */
706
707 static bool
708 alpha_vector_mode_supported_p (enum machine_mode mode)
709 {
710 return mode == V8QImode || mode == V4HImode || mode == V2SImode;
711 }
712
713 /* Return 1 if this function can directly return via $26. */
714
715 int
716 direct_return (void)
717 {
718 return (! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK
719 && reload_completed
720 && alpha_sa_size () == 0
721 && get_frame_size () == 0
722 && current_function_outgoing_args_size == 0
723 && current_function_pretend_args_size == 0);
724 }
725
726 /* Return the ADDR_VEC associated with a tablejump insn. */
727
728 rtx
729 alpha_tablejump_addr_vec (rtx insn)
730 {
731 rtx tmp;
732
733 tmp = JUMP_LABEL (insn);
734 if (!tmp)
735 return NULL_RTX;
736 tmp = NEXT_INSN (tmp);
737 if (!tmp)
738 return NULL_RTX;
739 if (GET_CODE (tmp) == JUMP_INSN
740 && GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC)
741 return PATTERN (tmp);
742 return NULL_RTX;
743 }
744
745 /* Return the label of the predicted edge, or CONST0_RTX if we don't know. */
746
747 rtx
748 alpha_tablejump_best_label (rtx insn)
749 {
750 rtx jump_table = alpha_tablejump_addr_vec (insn);
751 rtx best_label = NULL_RTX;
752
753 /* ??? Once the CFG doesn't keep getting completely rebuilt, look
754 there for edge frequency counts from profile data. */
755
756 if (jump_table)
757 {
758 int n_labels = XVECLEN (jump_table, 1);
759 int best_count = -1;
760 int i, j;
761
762 for (i = 0; i < n_labels; i++)
763 {
764 int count = 1;
765
766 for (j = i + 1; j < n_labels; j++)
767 if (XEXP (XVECEXP (jump_table, 1, i), 0)
768 == XEXP (XVECEXP (jump_table, 1, j), 0))
769 count++;
770
771 if (count > best_count)
772 best_count = count, best_label = XVECEXP (jump_table, 1, i);
773 }
774 }
775
776 return best_label ? best_label : const0_rtx;
777 }
778
779 /* Return the TLS model to use for SYMBOL. */
780
781 static enum tls_model
782 tls_symbolic_operand_type (rtx symbol)
783 {
784 enum tls_model model;
785
786 if (GET_CODE (symbol) != SYMBOL_REF)
787 return 0;
788 model = SYMBOL_REF_TLS_MODEL (symbol);
789
790 /* Local-exec with a 64-bit size is the same code as initial-exec. */
791 if (model == TLS_MODEL_LOCAL_EXEC && alpha_tls_size == 64)
792 model = TLS_MODEL_INITIAL_EXEC;
793
794 return model;
795 }
796 \f
797 /* Return true if the function DECL will share the same GP as any
798 function in the current unit of translation. */
799
800 static bool
801 decl_has_samegp (tree decl)
802 {
803 /* Functions that are not local can be overridden, and thus may
804 not share the same gp. */
805 if (!(*targetm.binds_local_p) (decl))
806 return false;
807
808 /* If -msmall-data is in effect, assume that there is only one GP
809 for the module, and so any local symbol has this property. We
810 need explicit relocations to be able to enforce this for symbols
811 not defined in this unit of translation, however. */
812 if (TARGET_EXPLICIT_RELOCS && TARGET_SMALL_DATA)
813 return true;
814
815 /* Functions that are not external are defined in this UoT. */
816 /* ??? Irritatingly, static functions not yet emitted are still
817 marked "external". Apply this to non-static functions only. */
818 return !TREE_PUBLIC (decl) || !DECL_EXTERNAL (decl);
819 }
820
821 /* Return true if EXP should be placed in the small data section. */
822
823 static bool
824 alpha_in_small_data_p (tree exp)
825 {
826 /* We want to merge strings, so we never consider them small data. */
827 if (TREE_CODE (exp) == STRING_CST)
828 return false;
829
830 /* Functions are never in the small data area. Duh. */
831 if (TREE_CODE (exp) == FUNCTION_DECL)
832 return false;
833
834 if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
835 {
836 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
837 if (strcmp (section, ".sdata") == 0
838 || strcmp (section, ".sbss") == 0)
839 return true;
840 }
841 else
842 {
843 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
844
845 /* If this is an incomplete type with size 0, then we can't put it
846 in sdata because it might be too big when completed. */
847 if (size > 0 && (unsigned HOST_WIDE_INT) size <= g_switch_value)
848 return true;
849 }
850
851 return false;
852 }
853
854 #if TARGET_ABI_OPEN_VMS
855 static bool
856 alpha_linkage_symbol_p (const char *symname)
857 {
858 int symlen = strlen (symname);
859
860 if (symlen > 4)
861 return strcmp (&symname [symlen - 4], "..lk") == 0;
862
863 return false;
864 }
865
866 #define LINKAGE_SYMBOL_REF_P(X) \
867 ((GET_CODE (X) == SYMBOL_REF \
868 && alpha_linkage_symbol_p (XSTR (X, 0))) \
869 || (GET_CODE (X) == CONST \
870 && GET_CODE (XEXP (X, 0)) == PLUS \
871 && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF \
872 && alpha_linkage_symbol_p (XSTR (XEXP (XEXP (X, 0), 0), 0))))
873 #endif
874
875 /* legitimate_address_p recognizes an RTL expression that is a valid
876 memory address for an instruction. The MODE argument is the
877 machine mode for the MEM expression that wants to use this address.
878
879 For Alpha, we have either a constant address or the sum of a
880 register and a constant address, or just a register. For DImode,
881 any of those forms can be surrounded with an AND that clear the
882 low-order three bits; this is an "unaligned" access. */
883
884 bool
885 alpha_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
886 {
887 /* If this is an ldq_u type address, discard the outer AND. */
888 if (mode == DImode
889 && GET_CODE (x) == AND
890 && GET_CODE (XEXP (x, 1)) == CONST_INT
891 && INTVAL (XEXP (x, 1)) == -8)
892 x = XEXP (x, 0);
893
894 /* Discard non-paradoxical subregs. */
895 if (GET_CODE (x) == SUBREG
896 && (GET_MODE_SIZE (GET_MODE (x))
897 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
898 x = SUBREG_REG (x);
899
900 /* Unadorned general registers are valid. */
901 if (REG_P (x)
902 && (strict
903 ? STRICT_REG_OK_FOR_BASE_P (x)
904 : NONSTRICT_REG_OK_FOR_BASE_P (x)))
905 return true;
906
907 /* Constant addresses (i.e. +/- 32k) are valid. */
908 if (CONSTANT_ADDRESS_P (x))
909 return true;
910
911 #if TARGET_ABI_OPEN_VMS
912 if (LINKAGE_SYMBOL_REF_P (x))
913 return true;
914 #endif
915
916 /* Register plus a small constant offset is valid. */
917 if (GET_CODE (x) == PLUS)
918 {
919 rtx ofs = XEXP (x, 1);
920 x = XEXP (x, 0);
921
922 /* Discard non-paradoxical subregs. */
923 if (GET_CODE (x) == SUBREG
924 && (GET_MODE_SIZE (GET_MODE (x))
925 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
926 x = SUBREG_REG (x);
927
928 if (REG_P (x))
929 {
930 if (! strict
931 && NONSTRICT_REG_OK_FP_BASE_P (x)
932 && GET_CODE (ofs) == CONST_INT)
933 return true;
934 if ((strict
935 ? STRICT_REG_OK_FOR_BASE_P (x)
936 : NONSTRICT_REG_OK_FOR_BASE_P (x))
937 && CONSTANT_ADDRESS_P (ofs))
938 return true;
939 }
940 }
941
942 /* If we're managing explicit relocations, LO_SUM is valid, as
943 are small data symbols. */
944 else if (TARGET_EXPLICIT_RELOCS)
945 {
946 if (small_symbolic_operand (x, Pmode))
947 return true;
948
949 if (GET_CODE (x) == LO_SUM)
950 {
951 rtx ofs = XEXP (x, 1);
952 x = XEXP (x, 0);
953
954 /* Discard non-paradoxical subregs. */
955 if (GET_CODE (x) == SUBREG
956 && (GET_MODE_SIZE (GET_MODE (x))
957 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
958 x = SUBREG_REG (x);
959
960 /* Must have a valid base register. */
961 if (! (REG_P (x)
962 && (strict
963 ? STRICT_REG_OK_FOR_BASE_P (x)
964 : NONSTRICT_REG_OK_FOR_BASE_P (x))))
965 return false;
966
967 /* The symbol must be local. */
968 if (local_symbolic_operand (ofs, Pmode)
969 || dtp32_symbolic_operand (ofs, Pmode)
970 || tp32_symbolic_operand (ofs, Pmode))
971 return true;
972 }
973 }
974
975 return false;
976 }
977
978 /* Build the SYMBOL_REF for __tls_get_addr. */
979
980 static GTY(()) rtx tls_get_addr_libfunc;
981
982 static rtx
983 get_tls_get_addr (void)
984 {
985 if (!tls_get_addr_libfunc)
986 tls_get_addr_libfunc = init_one_libfunc ("__tls_get_addr");
987 return tls_get_addr_libfunc;
988 }
989
990 /* Try machine-dependent ways of modifying an illegitimate address
991 to be legitimate. If we find one, return the new, valid address. */
992
993 rtx
994 alpha_legitimize_address (rtx x, rtx scratch,
995 enum machine_mode mode ATTRIBUTE_UNUSED)
996 {
997 HOST_WIDE_INT addend;
998
999 /* If the address is (plus reg const_int) and the CONST_INT is not a
1000 valid offset, compute the high part of the constant and add it to
1001 the register. Then our address is (plus temp low-part-const). */
1002 if (GET_CODE (x) == PLUS
1003 && GET_CODE (XEXP (x, 0)) == REG
1004 && GET_CODE (XEXP (x, 1)) == CONST_INT
1005 && ! CONSTANT_ADDRESS_P (XEXP (x, 1)))
1006 {
1007 addend = INTVAL (XEXP (x, 1));
1008 x = XEXP (x, 0);
1009 goto split_addend;
1010 }
1011
1012 /* If the address is (const (plus FOO const_int)), find the low-order
1013 part of the CONST_INT. Then load FOO plus any high-order part of the
1014 CONST_INT into a register. Our address is (plus reg low-part-const).
1015 This is done to reduce the number of GOT entries. */
1016 if (!no_new_pseudos
1017 && GET_CODE (x) == CONST
1018 && GET_CODE (XEXP (x, 0)) == PLUS
1019 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
1020 {
1021 addend = INTVAL (XEXP (XEXP (x, 0), 1));
1022 x = force_reg (Pmode, XEXP (XEXP (x, 0), 0));
1023 goto split_addend;
1024 }
1025
1026 /* If we have a (plus reg const), emit the load as in (2), then add
1027 the two registers, and finally generate (plus reg low-part-const) as
1028 our address. */
1029 if (!no_new_pseudos
1030 && GET_CODE (x) == PLUS
1031 && GET_CODE (XEXP (x, 0)) == REG
1032 && GET_CODE (XEXP (x, 1)) == CONST
1033 && GET_CODE (XEXP (XEXP (x, 1), 0)) == PLUS
1034 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == CONST_INT)
1035 {
1036 addend = INTVAL (XEXP (XEXP (XEXP (x, 1), 0), 1));
1037 x = expand_simple_binop (Pmode, PLUS, XEXP (x, 0),
1038 XEXP (XEXP (XEXP (x, 1), 0), 0),
1039 NULL_RTX, 1, OPTAB_LIB_WIDEN);
1040 goto split_addend;
1041 }
1042
1043 /* If this is a local symbol, split the address into HIGH/LO_SUM parts. */
1044 if (TARGET_EXPLICIT_RELOCS && symbolic_operand (x, Pmode))
1045 {
1046 rtx r0, r16, eqv, tga, tp, insn, dest, seq;
1047
1048 switch (tls_symbolic_operand_type (x))
1049 {
1050 case TLS_MODEL_GLOBAL_DYNAMIC:
1051 start_sequence ();
1052
1053 r0 = gen_rtx_REG (Pmode, 0);
1054 r16 = gen_rtx_REG (Pmode, 16);
1055 tga = get_tls_get_addr ();
1056 dest = gen_reg_rtx (Pmode);
1057 seq = GEN_INT (alpha_next_sequence_number++);
1058
1059 emit_insn (gen_movdi_er_tlsgd (r16, pic_offset_table_rtx, x, seq));
1060 insn = gen_call_value_osf_tlsgd (r0, tga, seq);
1061 insn = emit_call_insn (insn);
1062 CONST_OR_PURE_CALL_P (insn) = 1;
1063 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16);
1064
1065 insn = get_insns ();
1066 end_sequence ();
1067
1068 emit_libcall_block (insn, dest, r0, x);
1069 return dest;
1070
1071 case TLS_MODEL_LOCAL_DYNAMIC:
1072 start_sequence ();
1073
1074 r0 = gen_rtx_REG (Pmode, 0);
1075 r16 = gen_rtx_REG (Pmode, 16);
1076 tga = get_tls_get_addr ();
1077 scratch = gen_reg_rtx (Pmode);
1078 seq = GEN_INT (alpha_next_sequence_number++);
1079
1080 emit_insn (gen_movdi_er_tlsldm (r16, pic_offset_table_rtx, seq));
1081 insn = gen_call_value_osf_tlsldm (r0, tga, seq);
1082 insn = emit_call_insn (insn);
1083 CONST_OR_PURE_CALL_P (insn) = 1;
1084 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16);
1085
1086 insn = get_insns ();
1087 end_sequence ();
1088
1089 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
1090 UNSPEC_TLSLDM_CALL);
1091 emit_libcall_block (insn, scratch, r0, eqv);
1092
1093 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPREL);
1094 eqv = gen_rtx_CONST (Pmode, eqv);
1095
1096 if (alpha_tls_size == 64)
1097 {
1098 dest = gen_reg_rtx (Pmode);
1099 emit_insn (gen_rtx_SET (VOIDmode, dest, eqv));
1100 emit_insn (gen_adddi3 (dest, dest, scratch));
1101 return dest;
1102 }
1103 if (alpha_tls_size == 32)
1104 {
1105 insn = gen_rtx_HIGH (Pmode, eqv);
1106 insn = gen_rtx_PLUS (Pmode, scratch, insn);
1107 scratch = gen_reg_rtx (Pmode);
1108 emit_insn (gen_rtx_SET (VOIDmode, scratch, insn));
1109 }
1110 return gen_rtx_LO_SUM (Pmode, scratch, eqv);
1111
1112 case TLS_MODEL_INITIAL_EXEC:
1113 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_TPREL);
1114 eqv = gen_rtx_CONST (Pmode, eqv);
1115 tp = gen_reg_rtx (Pmode);
1116 scratch = gen_reg_rtx (Pmode);
1117 dest = gen_reg_rtx (Pmode);
1118
1119 emit_insn (gen_load_tp (tp));
1120 emit_insn (gen_rtx_SET (VOIDmode, scratch, eqv));
1121 emit_insn (gen_adddi3 (dest, tp, scratch));
1122 return dest;
1123
1124 case TLS_MODEL_LOCAL_EXEC:
1125 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_TPREL);
1126 eqv = gen_rtx_CONST (Pmode, eqv);
1127 tp = gen_reg_rtx (Pmode);
1128
1129 emit_insn (gen_load_tp (tp));
1130 if (alpha_tls_size == 32)
1131 {
1132 insn = gen_rtx_HIGH (Pmode, eqv);
1133 insn = gen_rtx_PLUS (Pmode, tp, insn);
1134 tp = gen_reg_rtx (Pmode);
1135 emit_insn (gen_rtx_SET (VOIDmode, tp, insn));
1136 }
1137 return gen_rtx_LO_SUM (Pmode, tp, eqv);
1138 }
1139
1140 if (local_symbolic_operand (x, Pmode))
1141 {
1142 if (small_symbolic_operand (x, Pmode))
1143 return x;
1144 else
1145 {
1146 if (!no_new_pseudos)
1147 scratch = gen_reg_rtx (Pmode);
1148 emit_insn (gen_rtx_SET (VOIDmode, scratch,
1149 gen_rtx_HIGH (Pmode, x)));
1150 return gen_rtx_LO_SUM (Pmode, scratch, x);
1151 }
1152 }
1153 }
1154
1155 return NULL;
1156
1157 split_addend:
1158 {
1159 HOST_WIDE_INT low, high;
1160
1161 low = ((addend & 0xffff) ^ 0x8000) - 0x8000;
1162 addend -= low;
1163 high = ((addend & 0xffffffff) ^ 0x80000000) - 0x80000000;
1164 addend -= high;
1165
1166 if (addend)
1167 x = expand_simple_binop (Pmode, PLUS, x, GEN_INT (addend),
1168 (no_new_pseudos ? scratch : NULL_RTX),
1169 1, OPTAB_LIB_WIDEN);
1170 if (high)
1171 x = expand_simple_binop (Pmode, PLUS, x, GEN_INT (high),
1172 (no_new_pseudos ? scratch : NULL_RTX),
1173 1, OPTAB_LIB_WIDEN);
1174
1175 return plus_constant (x, low);
1176 }
1177 }
1178
1179 /* Primarily this is required for TLS symbols, but given that our move
1180 patterns *ought* to be able to handle any symbol at any time, we
1181 should never be spilling symbolic operands to the constant pool, ever. */
1182
1183 static bool
1184 alpha_cannot_force_const_mem (rtx x)
1185 {
1186 enum rtx_code code = GET_CODE (x);
1187 return code == SYMBOL_REF || code == LABEL_REF || code == CONST;
1188 }
1189
1190 /* We do not allow indirect calls to be optimized into sibling calls, nor
1191 can we allow a call to a function with a different GP to be optimized
1192 into a sibcall. */
1193
1194 static bool
1195 alpha_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
1196 {
1197 /* Can't do indirect tail calls, since we don't know if the target
1198 uses the same GP. */
1199 if (!decl)
1200 return false;
1201
1202 /* Otherwise, we can make a tail call if the target function shares
1203 the same GP. */
1204 return decl_has_samegp (decl);
1205 }
1206
1207 int
1208 some_small_symbolic_operand_int (rtx *px, void *data ATTRIBUTE_UNUSED)
1209 {
1210 rtx x = *px;
1211
1212 /* Don't re-split. */
1213 if (GET_CODE (x) == LO_SUM)
1214 return -1;
1215
1216 return small_symbolic_operand (x, Pmode) != 0;
1217 }
1218
1219 static int
1220 split_small_symbolic_operand_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
1221 {
1222 rtx x = *px;
1223
1224 /* Don't re-split. */
1225 if (GET_CODE (x) == LO_SUM)
1226 return -1;
1227
1228 if (small_symbolic_operand (x, Pmode))
1229 {
1230 x = gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, x);
1231 *px = x;
1232 return -1;
1233 }
1234
1235 return 0;
1236 }
1237
1238 rtx
1239 split_small_symbolic_operand (rtx x)
1240 {
1241 x = copy_insn (x);
1242 for_each_rtx (&x, split_small_symbolic_operand_1, NULL);
1243 return x;
1244 }
1245
1246 /* Indicate that INSN cannot be duplicated. This is true for any insn
1247 that we've marked with gpdisp relocs, since those have to stay in
1248 1-1 correspondence with one another.
1249
1250 Technically we could copy them if we could set up a mapping from one
1251 sequence number to another, across the set of insns to be duplicated.
1252 This seems overly complicated and error-prone since interblock motion
1253 from sched-ebb could move one of the pair of insns to a different block.
1254
1255 Also cannot allow jsr insns to be duplicated. If they throw exceptions,
1256 then they'll be in a different block from their ldgp. Which could lead
1257 the bb reorder code to think that it would be ok to copy just the block
1258 containing the call and branch to the block containing the ldgp. */
1259
1260 static bool
1261 alpha_cannot_copy_insn_p (rtx insn)
1262 {
1263 if (!reload_completed || !TARGET_EXPLICIT_RELOCS)
1264 return false;
1265 if (recog_memoized (insn) >= 0)
1266 return get_attr_cannot_copy (insn);
1267 else
1268 return false;
1269 }
1270
1271
1272 /* Try a machine-dependent way of reloading an illegitimate address
1273 operand. If we find one, push the reload and return the new rtx. */
1274
1275 rtx
1276 alpha_legitimize_reload_address (rtx x,
1277 enum machine_mode mode ATTRIBUTE_UNUSED,
1278 int opnum, int type,
1279 int ind_levels ATTRIBUTE_UNUSED)
1280 {
1281 /* We must recognize output that we have already generated ourselves. */
1282 if (GET_CODE (x) == PLUS
1283 && GET_CODE (XEXP (x, 0)) == PLUS
1284 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
1285 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
1286 && GET_CODE (XEXP (x, 1)) == CONST_INT)
1287 {
1288 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
1289 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
1290 opnum, type);
1291 return x;
1292 }
1293
1294 /* We wish to handle large displacements off a base register by
1295 splitting the addend across an ldah and the mem insn. This
1296 cuts number of extra insns needed from 3 to 1. */
1297 if (GET_CODE (x) == PLUS
1298 && GET_CODE (XEXP (x, 0)) == REG
1299 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
1300 && REGNO_OK_FOR_BASE_P (REGNO (XEXP (x, 0)))
1301 && GET_CODE (XEXP (x, 1)) == CONST_INT)
1302 {
1303 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
1304 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1305 HOST_WIDE_INT high
1306 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
1307
1308 /* Check for 32-bit overflow. */
1309 if (high + low != val)
1310 return NULL_RTX;
1311
1312 /* Reload the high part into a base reg; leave the low part
1313 in the mem directly. */
1314 x = gen_rtx_PLUS (GET_MODE (x),
1315 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
1316 GEN_INT (high)),
1317 GEN_INT (low));
1318
1319 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
1320 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
1321 opnum, type);
1322 return x;
1323 }
1324
1325 return NULL_RTX;
1326 }
1327 \f
1328 /* Compute a (partial) cost for rtx X. Return true if the complete
1329 cost has been computed, and false if subexpressions should be
1330 scanned. In either case, *TOTAL contains the cost result. */
1331
1332 static bool
1333 alpha_rtx_costs (rtx x, int code, int outer_code, int *total)
1334 {
1335 enum machine_mode mode = GET_MODE (x);
1336 bool float_mode_p = FLOAT_MODE_P (mode);
1337 const struct alpha_rtx_cost_data *cost_data;
1338
1339 if (optimize_size)
1340 cost_data = &alpha_rtx_cost_size;
1341 else
1342 cost_data = &alpha_rtx_cost_data[alpha_cpu];
1343
1344 switch (code)
1345 {
1346 case CONST_INT:
1347 /* If this is an 8-bit constant, return zero since it can be used
1348 nearly anywhere with no cost. If it is a valid operand for an
1349 ADD or AND, likewise return 0 if we know it will be used in that
1350 context. Otherwise, return 2 since it might be used there later.
1351 All other constants take at least two insns. */
1352 if (INTVAL (x) >= 0 && INTVAL (x) < 256)
1353 {
1354 *total = 0;
1355 return true;
1356 }
1357 /* FALLTHRU */
1358
1359 case CONST_DOUBLE:
1360 if (x == CONST0_RTX (mode))
1361 *total = 0;
1362 else if ((outer_code == PLUS && add_operand (x, VOIDmode))
1363 || (outer_code == AND && and_operand (x, VOIDmode)))
1364 *total = 0;
1365 else if (add_operand (x, VOIDmode) || and_operand (x, VOIDmode))
1366 *total = 2;
1367 else
1368 *total = COSTS_N_INSNS (2);
1369 return true;
1370
1371 case CONST:
1372 case SYMBOL_REF:
1373 case LABEL_REF:
1374 if (TARGET_EXPLICIT_RELOCS && small_symbolic_operand (x, VOIDmode))
1375 *total = COSTS_N_INSNS (outer_code != MEM);
1376 else if (TARGET_EXPLICIT_RELOCS && local_symbolic_operand (x, VOIDmode))
1377 *total = COSTS_N_INSNS (1 + (outer_code != MEM));
1378 else if (tls_symbolic_operand_type (x))
1379 /* Estimate of cost for call_pal rduniq. */
1380 /* ??? How many insns do we emit here? More than one... */
1381 *total = COSTS_N_INSNS (15);
1382 else
1383 /* Otherwise we do a load from the GOT. */
1384 *total = COSTS_N_INSNS (optimize_size ? 1 : alpha_memory_latency);
1385 return true;
1386
1387 case PLUS:
1388 case MINUS:
1389 if (float_mode_p)
1390 *total = cost_data->fp_add;
1391 else if (GET_CODE (XEXP (x, 0)) == MULT
1392 && const48_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
1393 {
1394 *total = (rtx_cost (XEXP (XEXP (x, 0), 0), outer_code)
1395 + rtx_cost (XEXP (x, 1), outer_code) + COSTS_N_INSNS (1));
1396 return true;
1397 }
1398 return false;
1399
1400 case MULT:
1401 if (float_mode_p)
1402 *total = cost_data->fp_mult;
1403 else if (mode == DImode)
1404 *total = cost_data->int_mult_di;
1405 else
1406 *total = cost_data->int_mult_si;
1407 return false;
1408
1409 case ASHIFT:
1410 if (GET_CODE (XEXP (x, 1)) == CONST_INT
1411 && INTVAL (XEXP (x, 1)) <= 3)
1412 {
1413 *total = COSTS_N_INSNS (1);
1414 return false;
1415 }
1416 /* FALLTHRU */
1417
1418 case ASHIFTRT:
1419 case LSHIFTRT:
1420 *total = cost_data->int_shift;
1421 return false;
1422
1423 case IF_THEN_ELSE:
1424 if (float_mode_p)
1425 *total = cost_data->fp_add;
1426 else
1427 *total = cost_data->int_cmov;
1428 return false;
1429
1430 case DIV:
1431 case UDIV:
1432 case MOD:
1433 case UMOD:
1434 if (!float_mode_p)
1435 *total = cost_data->int_div;
1436 else if (mode == SFmode)
1437 *total = cost_data->fp_div_sf;
1438 else
1439 *total = cost_data->fp_div_df;
1440 return false;
1441
1442 case MEM:
1443 *total = COSTS_N_INSNS (optimize_size ? 1 : alpha_memory_latency);
1444 return true;
1445
1446 case NEG:
1447 if (! float_mode_p)
1448 {
1449 *total = COSTS_N_INSNS (1);
1450 return false;
1451 }
1452 /* FALLTHRU */
1453
1454 case ABS:
1455 if (! float_mode_p)
1456 {
1457 *total = COSTS_N_INSNS (1) + cost_data->int_cmov;
1458 return false;
1459 }
1460 /* FALLTHRU */
1461
1462 case FLOAT:
1463 case UNSIGNED_FLOAT:
1464 case FIX:
1465 case UNSIGNED_FIX:
1466 case FLOAT_EXTEND:
1467 case FLOAT_TRUNCATE:
1468 *total = cost_data->fp_add;
1469 return false;
1470
1471 default:
1472 return false;
1473 }
1474 }
1475 \f
1476 /* REF is an alignable memory location. Place an aligned SImode
1477 reference into *PALIGNED_MEM and the number of bits to shift into
1478 *PBITNUM. SCRATCH is a free register for use in reloading out
1479 of range stack slots. */
1480
1481 void
1482 get_aligned_mem (rtx ref, rtx *paligned_mem, rtx *pbitnum)
1483 {
1484 rtx base;
1485 HOST_WIDE_INT offset = 0;
1486
1487 if (GET_CODE (ref) != MEM)
1488 abort ();
1489
1490 if (reload_in_progress
1491 && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
1492 {
1493 base = find_replacement (&XEXP (ref, 0));
1494
1495 if (! memory_address_p (GET_MODE (ref), base))
1496 abort ();
1497 }
1498 else
1499 {
1500 base = XEXP (ref, 0);
1501 }
1502
1503 if (GET_CODE (base) == PLUS)
1504 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
1505
1506 *paligned_mem
1507 = widen_memory_access (ref, SImode, (offset & ~3) - offset);
1508
1509 if (WORDS_BIG_ENDIAN)
1510 *pbitnum = GEN_INT (32 - (GET_MODE_BITSIZE (GET_MODE (ref))
1511 + (offset & 3) * 8));
1512 else
1513 *pbitnum = GEN_INT ((offset & 3) * 8);
1514 }
1515
1516 /* Similar, but just get the address. Handle the two reload cases.
1517 Add EXTRA_OFFSET to the address we return. */
1518
1519 rtx
1520 get_unaligned_address (rtx ref, int extra_offset)
1521 {
1522 rtx base;
1523 HOST_WIDE_INT offset = 0;
1524
1525 if (GET_CODE (ref) != MEM)
1526 abort ();
1527
1528 if (reload_in_progress
1529 && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
1530 {
1531 base = find_replacement (&XEXP (ref, 0));
1532
1533 if (! memory_address_p (GET_MODE (ref), base))
1534 abort ();
1535 }
1536 else
1537 {
1538 base = XEXP (ref, 0);
1539 }
1540
1541 if (GET_CODE (base) == PLUS)
1542 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
1543
1544 return plus_constant (base, offset + extra_offset);
1545 }
1546
1547 /* On the Alpha, all (non-symbolic) constants except zero go into
1548 a floating-point register via memory. Note that we cannot
1549 return anything that is not a subset of CLASS, and that some
1550 symbolic constants cannot be dropped to memory. */
1551
1552 enum reg_class
1553 alpha_preferred_reload_class(rtx x, enum reg_class class)
1554 {
1555 /* Zero is present in any register class. */
1556 if (x == CONST0_RTX (GET_MODE (x)))
1557 return class;
1558
1559 /* These sorts of constants we can easily drop to memory. */
1560 if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
1561 {
1562 if (class == FLOAT_REGS)
1563 return NO_REGS;
1564 if (class == ALL_REGS)
1565 return GENERAL_REGS;
1566 return class;
1567 }
1568
1569 /* All other kinds of constants should not (and in the case of HIGH
1570 cannot) be dropped to memory -- instead we use a GENERAL_REGS
1571 secondary reload. */
1572 if (CONSTANT_P (x))
1573 return (class == ALL_REGS ? GENERAL_REGS : class);
1574
1575 return class;
1576 }
1577
1578 /* Loading and storing HImode or QImode values to and from memory
1579 usually requires a scratch register. The exceptions are loading
1580 QImode and HImode from an aligned address to a general register
1581 unless byte instructions are permitted.
1582
1583 We also cannot load an unaligned address or a paradoxical SUBREG
1584 into an FP register.
1585
1586 We also cannot do integral arithmetic into FP regs, as might result
1587 from register elimination into a DImode fp register. */
1588
1589 enum reg_class
1590 secondary_reload_class (enum reg_class class, enum machine_mode mode,
1591 rtx x, int in)
1592 {
1593 if ((mode == QImode || mode == HImode) && ! TARGET_BWX)
1594 {
1595 if (GET_CODE (x) == MEM
1596 || (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
1597 || (GET_CODE (x) == SUBREG
1598 && (GET_CODE (SUBREG_REG (x)) == MEM
1599 || (GET_CODE (SUBREG_REG (x)) == REG
1600 && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER))))
1601 {
1602 if (!in || !aligned_memory_operand(x, mode))
1603 return GENERAL_REGS;
1604 }
1605 }
1606
1607 if (class == FLOAT_REGS)
1608 {
1609 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
1610 return GENERAL_REGS;
1611
1612 if (GET_CODE (x) == SUBREG
1613 && (GET_MODE_SIZE (GET_MODE (x))
1614 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
1615 return GENERAL_REGS;
1616
1617 if (in && INTEGRAL_MODE_P (mode)
1618 && ! (memory_operand (x, mode) || x == const0_rtx))
1619 return GENERAL_REGS;
1620 }
1621
1622 return NO_REGS;
1623 }
1624 \f
1625 /* Subfunction of the following function. Update the flags of any MEM
1626 found in part of X. */
1627
1628 static int
1629 alpha_set_memflags_1 (rtx *xp, void *data)
1630 {
1631 rtx x = *xp, orig = (rtx) data;
1632
1633 if (GET_CODE (x) != MEM)
1634 return 0;
1635
1636 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (orig);
1637 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (orig);
1638 MEM_SCALAR_P (x) = MEM_SCALAR_P (orig);
1639 MEM_NOTRAP_P (x) = MEM_NOTRAP_P (orig);
1640 MEM_READONLY_P (x) = MEM_READONLY_P (orig);
1641
1642 /* Sadly, we cannot use alias sets because the extra aliasing
1643 produced by the AND interferes. Given that two-byte quantities
1644 are the only thing we would be able to differentiate anyway,
1645 there does not seem to be any point in convoluting the early
1646 out of the alias check. */
1647
1648 return -1;
1649 }
1650
1651 /* Given INSN, which is an INSN list or the PATTERN of a single insn
1652 generated to perform a memory operation, look for any MEMs in either
1653 a SET_DEST or a SET_SRC and copy the in-struct, unchanging, and
1654 volatile flags from REF into each of the MEMs found. If REF is not
1655 a MEM, don't do anything. */
1656
1657 void
1658 alpha_set_memflags (rtx insn, rtx ref)
1659 {
1660 rtx *base_ptr;
1661
1662 if (GET_CODE (ref) != MEM)
1663 return;
1664
1665 /* This is only called from alpha.md, after having had something
1666 generated from one of the insn patterns. So if everything is
1667 zero, the pattern is already up-to-date. */
1668 if (!MEM_VOLATILE_P (ref)
1669 && !MEM_IN_STRUCT_P (ref)
1670 && !MEM_SCALAR_P (ref)
1671 && !MEM_NOTRAP_P (ref)
1672 && !MEM_READONLY_P (ref))
1673 return;
1674
1675 if (INSN_P (insn))
1676 base_ptr = &PATTERN (insn);
1677 else
1678 base_ptr = &insn;
1679 for_each_rtx (base_ptr, alpha_set_memflags_1, (void *) ref);
1680 }
1681 \f
1682 /* Internal routine for alpha_emit_set_const to check for N or below insns. */
1683
1684 static rtx
1685 alpha_emit_set_const_1 (rtx target, enum machine_mode mode,
1686 HOST_WIDE_INT c, int n)
1687 {
1688 HOST_WIDE_INT new;
1689 int i, bits;
1690 /* Use a pseudo if highly optimizing and still generating RTL. */
1691 rtx subtarget
1692 = (flag_expensive_optimizations && !no_new_pseudos ? 0 : target);
1693 rtx temp, insn;
1694
1695 /* If this is a sign-extended 32-bit constant, we can do this in at most
1696 three insns, so do it if we have enough insns left. We always have
1697 a sign-extended 32-bit constant when compiling on a narrow machine. */
1698
1699 if (HOST_BITS_PER_WIDE_INT != 64
1700 || c >> 31 == -1 || c >> 31 == 0)
1701 {
1702 HOST_WIDE_INT low = ((c & 0xffff) ^ 0x8000) - 0x8000;
1703 HOST_WIDE_INT tmp1 = c - low;
1704 HOST_WIDE_INT high = (((tmp1 >> 16) & 0xffff) ^ 0x8000) - 0x8000;
1705 HOST_WIDE_INT extra = 0;
1706
1707 /* If HIGH will be interpreted as negative but the constant is
1708 positive, we must adjust it to do two ldha insns. */
1709
1710 if ((high & 0x8000) != 0 && c >= 0)
1711 {
1712 extra = 0x4000;
1713 tmp1 -= 0x40000000;
1714 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1715 }
1716
1717 if (c == low || (low == 0 && extra == 0))
1718 {
1719 /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
1720 but that meant that we can't handle INT_MIN on 32-bit machines
1721 (like NT/Alpha), because we recurse indefinitely through
1722 emit_move_insn to gen_movdi. So instead, since we know exactly
1723 what we want, create it explicitly. */
1724
1725 if (target == NULL)
1726 target = gen_reg_rtx (mode);
1727 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (c)));
1728 return target;
1729 }
1730 else if (n >= 2 + (extra != 0))
1731 {
1732 if (no_new_pseudos)
1733 {
1734 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (high << 16)));
1735 temp = target;
1736 }
1737 else
1738 temp = copy_to_suggested_reg (GEN_INT (high << 16),
1739 subtarget, mode);
1740
1741 /* As of 2002-02-23, addsi3 is only available when not optimizing.
1742 This means that if we go through expand_binop, we'll try to
1743 generate extensions, etc, which will require new pseudos, which
1744 will fail during some split phases. The SImode add patterns
1745 still exist, but are not named. So build the insns by hand. */
1746
1747 if (extra != 0)
1748 {
1749 if (! subtarget)
1750 subtarget = gen_reg_rtx (mode);
1751 insn = gen_rtx_PLUS (mode, temp, GEN_INT (extra << 16));
1752 insn = gen_rtx_SET (VOIDmode, subtarget, insn);
1753 emit_insn (insn);
1754 temp = subtarget;
1755 }
1756
1757 if (target == NULL)
1758 target = gen_reg_rtx (mode);
1759 insn = gen_rtx_PLUS (mode, temp, GEN_INT (low));
1760 insn = gen_rtx_SET (VOIDmode, target, insn);
1761 emit_insn (insn);
1762 return target;
1763 }
1764 }
1765
1766 /* If we couldn't do it that way, try some other methods. But if we have
1767 no instructions left, don't bother. Likewise, if this is SImode and
1768 we can't make pseudos, we can't do anything since the expand_binop
1769 and expand_unop calls will widen and try to make pseudos. */
1770
1771 if (n == 1 || (mode == SImode && no_new_pseudos))
1772 return 0;
1773
1774 /* Next, see if we can load a related constant and then shift and possibly
1775 negate it to get the constant we want. Try this once each increasing
1776 numbers of insns. */
1777
1778 for (i = 1; i < n; i++)
1779 {
1780 /* First, see if minus some low bits, we've an easy load of
1781 high bits. */
1782
1783 new = ((c & 0xffff) ^ 0x8000) - 0x8000;
1784 if (new != 0
1785 && (temp = alpha_emit_set_const (subtarget, mode, c - new, i)) != 0)
1786 return expand_binop (mode, add_optab, temp, GEN_INT (new),
1787 target, 0, OPTAB_WIDEN);
1788
1789 /* Next try complementing. */
1790 if ((temp = alpha_emit_set_const (subtarget, mode, ~ c, i)) != 0)
1791 return expand_unop (mode, one_cmpl_optab, temp, target, 0);
1792
1793 /* Next try to form a constant and do a left shift. We can do this
1794 if some low-order bits are zero; the exact_log2 call below tells
1795 us that information. The bits we are shifting out could be any
1796 value, but here we'll just try the 0- and sign-extended forms of
1797 the constant. To try to increase the chance of having the same
1798 constant in more than one insn, start at the highest number of
1799 bits to shift, but try all possibilities in case a ZAPNOT will
1800 be useful. */
1801
1802 if ((bits = exact_log2 (c & - c)) > 0)
1803 for (; bits > 0; bits--)
1804 if ((temp = (alpha_emit_set_const
1805 (subtarget, mode, c >> bits, i))) != 0
1806 || ((temp = (alpha_emit_set_const
1807 (subtarget, mode,
1808 ((unsigned HOST_WIDE_INT) c) >> bits, i)))
1809 != 0))
1810 return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
1811 target, 0, OPTAB_WIDEN);
1812
1813 /* Now try high-order zero bits. Here we try the shifted-in bits as
1814 all zero and all ones. Be careful to avoid shifting outside the
1815 mode and to avoid shifting outside the host wide int size. */
1816 /* On narrow hosts, don't shift a 1 into the high bit, since we'll
1817 confuse the recursive call and set all of the high 32 bits. */
1818
1819 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1820 - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64))) > 0)
1821 for (; bits > 0; bits--)
1822 if ((temp = alpha_emit_set_const (subtarget, mode,
1823 c << bits, i)) != 0
1824 || ((temp = (alpha_emit_set_const
1825 (subtarget, mode,
1826 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1827 i)))
1828 != 0))
1829 return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
1830 target, 1, OPTAB_WIDEN);
1831
1832 /* Now try high-order 1 bits. We get that with a sign-extension.
1833 But one bit isn't enough here. Be careful to avoid shifting outside
1834 the mode and to avoid shifting outside the host wide int size. */
1835
1836 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1837 - floor_log2 (~ c) - 2)) > 0)
1838 for (; bits > 0; bits--)
1839 if ((temp = alpha_emit_set_const (subtarget, mode,
1840 c << bits, i)) != 0
1841 || ((temp = (alpha_emit_set_const
1842 (subtarget, mode,
1843 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1844 i)))
1845 != 0))
1846 return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
1847 target, 0, OPTAB_WIDEN);
1848 }
1849
1850 #if HOST_BITS_PER_WIDE_INT == 64
1851 /* Finally, see if can load a value into the target that is the same as the
1852 constant except that all bytes that are 0 are changed to be 0xff. If we
1853 can, then we can do a ZAPNOT to obtain the desired constant. */
1854
1855 new = c;
1856 for (i = 0; i < 64; i += 8)
1857 if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
1858 new |= (HOST_WIDE_INT) 0xff << i;
1859
1860 /* We are only called for SImode and DImode. If this is SImode, ensure that
1861 we are sign extended to a full word. */
1862
1863 if (mode == SImode)
1864 new = ((new & 0xffffffff) ^ 0x80000000) - 0x80000000;
1865
1866 if (new != c && new != -1
1867 && (temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0)
1868 return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
1869 target, 0, OPTAB_WIDEN);
1870 #endif
1871
1872 return 0;
1873 }
1874
1875 /* Try to output insns to set TARGET equal to the constant C if it can be
1876 done in less than N insns. Do all computations in MODE. Returns the place
1877 where the output has been placed if it can be done and the insns have been
1878 emitted. If it would take more than N insns, zero is returned and no
1879 insns and emitted. */
1880
1881 rtx
1882 alpha_emit_set_const (rtx target, enum machine_mode mode,
1883 HOST_WIDE_INT c, int n)
1884 {
1885 rtx result = 0;
1886 rtx orig_target = target;
1887 int i;
1888
1889 /* If we can't make any pseudos, TARGET is an SImode hard register, we
1890 can't load this constant in one insn, do this in DImode. */
1891 if (no_new_pseudos && mode == SImode
1892 && GET_CODE (target) == REG && REGNO (target) < FIRST_PSEUDO_REGISTER
1893 && (result = alpha_emit_set_const_1 (target, mode, c, 1)) == 0)
1894 {
1895 target = gen_lowpart (DImode, target);
1896 mode = DImode;
1897 }
1898
1899 /* Try 1 insn, then 2, then up to N. */
1900 for (i = 1; i <= n; i++)
1901 {
1902 result = alpha_emit_set_const_1 (target, mode, c, i);
1903 if (result)
1904 {
1905 rtx insn = get_last_insn ();
1906 rtx set = single_set (insn);
1907 if (! CONSTANT_P (SET_SRC (set)))
1908 set_unique_reg_note (get_last_insn (), REG_EQUAL, GEN_INT (c));
1909 break;
1910 }
1911 }
1912
1913 /* Allow for the case where we changed the mode of TARGET. */
1914 if (result == target)
1915 result = orig_target;
1916
1917 return result;
1918 }
1919
1920 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
1921 fall back to a straight forward decomposition. We do this to avoid
1922 exponential run times encountered when looking for longer sequences
1923 with alpha_emit_set_const. */
1924
1925 rtx
1926 alpha_emit_set_long_const (rtx target, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
1927 {
1928 HOST_WIDE_INT d1, d2, d3, d4;
1929
1930 /* Decompose the entire word */
1931 #if HOST_BITS_PER_WIDE_INT >= 64
1932 if (c2 != -(c1 < 0))
1933 abort ();
1934 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1935 c1 -= d1;
1936 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1937 c1 = (c1 - d2) >> 32;
1938 d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1939 c1 -= d3;
1940 d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1941 if (c1 != d4)
1942 abort ();
1943 #else
1944 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1945 c1 -= d1;
1946 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1947 if (c1 != d2)
1948 abort ();
1949 c2 += (d2 < 0);
1950 d3 = ((c2 & 0xffff) ^ 0x8000) - 0x8000;
1951 c2 -= d3;
1952 d4 = ((c2 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1953 if (c2 != d4)
1954 abort ();
1955 #endif
1956
1957 /* Construct the high word */
1958 if (d4)
1959 {
1960 emit_move_insn (target, GEN_INT (d4));
1961 if (d3)
1962 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d3)));
1963 }
1964 else
1965 emit_move_insn (target, GEN_INT (d3));
1966
1967 /* Shift it into place */
1968 emit_move_insn (target, gen_rtx_ASHIFT (DImode, target, GEN_INT (32)));
1969
1970 /* Add in the low bits. */
1971 if (d2)
1972 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d2)));
1973 if (d1)
1974 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d1)));
1975
1976 return target;
1977 }
1978
1979 /* Expand a move instruction; return true if all work is done.
1980 We don't handle non-bwx subword loads here. */
1981
1982 bool
1983 alpha_expand_mov (enum machine_mode mode, rtx *operands)
1984 {
1985 /* If the output is not a register, the input must be. */
1986 if (GET_CODE (operands[0]) == MEM
1987 && ! reg_or_0_operand (operands[1], mode))
1988 operands[1] = force_reg (mode, operands[1]);
1989
1990 /* Allow legitimize_address to perform some simplifications. */
1991 if (mode == Pmode && symbolic_operand (operands[1], mode))
1992 {
1993 rtx tmp;
1994
1995 tmp = alpha_legitimize_address (operands[1], operands[0], mode);
1996 if (tmp)
1997 {
1998 if (tmp == operands[0])
1999 return true;
2000 operands[1] = tmp;
2001 return false;
2002 }
2003 }
2004
2005 /* Early out for non-constants and valid constants. */
2006 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], mode))
2007 return false;
2008
2009 /* Split large integers. */
2010 if (GET_CODE (operands[1]) == CONST_INT
2011 || GET_CODE (operands[1]) == CONST_DOUBLE)
2012 {
2013 HOST_WIDE_INT i0, i1;
2014 rtx temp = NULL_RTX;
2015
2016 if (GET_CODE (operands[1]) == CONST_INT)
2017 {
2018 i0 = INTVAL (operands[1]);
2019 i1 = -(i0 < 0);
2020 }
2021 else if (HOST_BITS_PER_WIDE_INT >= 64)
2022 {
2023 i0 = CONST_DOUBLE_LOW (operands[1]);
2024 i1 = -(i0 < 0);
2025 }
2026 else
2027 {
2028 i0 = CONST_DOUBLE_LOW (operands[1]);
2029 i1 = CONST_DOUBLE_HIGH (operands[1]);
2030 }
2031
2032 if (HOST_BITS_PER_WIDE_INT >= 64 || i1 == -(i0 < 0))
2033 temp = alpha_emit_set_const (operands[0], mode, i0, 3);
2034
2035 if (!temp && TARGET_BUILD_CONSTANTS)
2036 temp = alpha_emit_set_long_const (operands[0], i0, i1);
2037
2038 if (temp)
2039 {
2040 if (rtx_equal_p (operands[0], temp))
2041 return true;
2042 operands[1] = temp;
2043 return false;
2044 }
2045 }
2046
2047 /* Otherwise we've nothing left but to drop the thing to memory. */
2048 operands[1] = force_const_mem (mode, operands[1]);
2049 if (reload_in_progress)
2050 {
2051 emit_move_insn (operands[0], XEXP (operands[1], 0));
2052 operands[1] = copy_rtx (operands[1]);
2053 XEXP (operands[1], 0) = operands[0];
2054 }
2055 else
2056 operands[1] = validize_mem (operands[1]);
2057 return false;
2058 }
2059
2060 /* Expand a non-bwx QImode or HImode move instruction;
2061 return true if all work is done. */
2062
2063 bool
2064 alpha_expand_mov_nobwx (enum machine_mode mode, rtx *operands)
2065 {
2066 /* If the output is not a register, the input must be. */
2067 if (GET_CODE (operands[0]) == MEM)
2068 operands[1] = force_reg (mode, operands[1]);
2069
2070 /* Handle four memory cases, unaligned and aligned for either the input
2071 or the output. The only case where we can be called during reload is
2072 for aligned loads; all other cases require temporaries. */
2073
2074 if (GET_CODE (operands[1]) == MEM
2075 || (GET_CODE (operands[1]) == SUBREG
2076 && GET_CODE (SUBREG_REG (operands[1])) == MEM)
2077 || (reload_in_progress && GET_CODE (operands[1]) == REG
2078 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
2079 || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
2080 && GET_CODE (SUBREG_REG (operands[1])) == REG
2081 && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
2082 {
2083 if (aligned_memory_operand (operands[1], mode))
2084 {
2085 if (reload_in_progress)
2086 {
2087 emit_insn ((mode == QImode
2088 ? gen_reload_inqi_help
2089 : gen_reload_inhi_help)
2090 (operands[0], operands[1],
2091 gen_rtx_REG (SImode, REGNO (operands[0]))));
2092 }
2093 else
2094 {
2095 rtx aligned_mem, bitnum;
2096 rtx scratch = gen_reg_rtx (SImode);
2097 rtx subtarget;
2098 bool copyout;
2099
2100 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
2101
2102 subtarget = operands[0];
2103 if (GET_CODE (subtarget) == REG)
2104 subtarget = gen_lowpart (DImode, subtarget), copyout = false;
2105 else
2106 subtarget = gen_reg_rtx (DImode), copyout = true;
2107
2108 emit_insn ((mode == QImode
2109 ? gen_aligned_loadqi
2110 : gen_aligned_loadhi)
2111 (subtarget, aligned_mem, bitnum, scratch));
2112
2113 if (copyout)
2114 emit_move_insn (operands[0], gen_lowpart (mode, subtarget));
2115 }
2116 }
2117 else
2118 {
2119 /* Don't pass these as parameters since that makes the generated
2120 code depend on parameter evaluation order which will cause
2121 bootstrap failures. */
2122
2123 rtx temp1, temp2, seq, subtarget;
2124 bool copyout;
2125
2126 temp1 = gen_reg_rtx (DImode);
2127 temp2 = gen_reg_rtx (DImode);
2128
2129 subtarget = operands[0];
2130 if (GET_CODE (subtarget) == REG)
2131 subtarget = gen_lowpart (DImode, subtarget), copyout = false;
2132 else
2133 subtarget = gen_reg_rtx (DImode), copyout = true;
2134
2135 seq = ((mode == QImode
2136 ? gen_unaligned_loadqi
2137 : gen_unaligned_loadhi)
2138 (subtarget, get_unaligned_address (operands[1], 0),
2139 temp1, temp2));
2140 alpha_set_memflags (seq, operands[1]);
2141 emit_insn (seq);
2142
2143 if (copyout)
2144 emit_move_insn (operands[0], gen_lowpart (mode, subtarget));
2145 }
2146 return true;
2147 }
2148
2149 if (GET_CODE (operands[0]) == MEM
2150 || (GET_CODE (operands[0]) == SUBREG
2151 && GET_CODE (SUBREG_REG (operands[0])) == MEM)
2152 || (reload_in_progress && GET_CODE (operands[0]) == REG
2153 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
2154 || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
2155 && GET_CODE (SUBREG_REG (operands[0])) == REG
2156 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
2157 {
2158 if (aligned_memory_operand (operands[0], mode))
2159 {
2160 rtx aligned_mem, bitnum;
2161 rtx temp1 = gen_reg_rtx (SImode);
2162 rtx temp2 = gen_reg_rtx (SImode);
2163
2164 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
2165
2166 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
2167 temp1, temp2));
2168 }
2169 else
2170 {
2171 rtx temp1 = gen_reg_rtx (DImode);
2172 rtx temp2 = gen_reg_rtx (DImode);
2173 rtx temp3 = gen_reg_rtx (DImode);
2174 rtx seq = ((mode == QImode
2175 ? gen_unaligned_storeqi
2176 : gen_unaligned_storehi)
2177 (get_unaligned_address (operands[0], 0),
2178 operands[1], temp1, temp2, temp3));
2179
2180 alpha_set_memflags (seq, operands[0]);
2181 emit_insn (seq);
2182 }
2183 return true;
2184 }
2185
2186 return false;
2187 }
2188
2189 /* Implement the movmisalign patterns. One of the operands is a memory
2190 that is not naturally aligned. Emit instructions to load it. */
2191
2192 void
2193 alpha_expand_movmisalign (enum machine_mode mode, rtx *operands)
2194 {
2195 /* Honor misaligned loads, for those we promised to do so. */
2196 if (MEM_P (operands[1]))
2197 {
2198 rtx tmp;
2199
2200 if (register_operand (operands[0], mode))
2201 tmp = operands[0];
2202 else
2203 tmp = gen_reg_rtx (mode);
2204
2205 alpha_expand_unaligned_load (tmp, operands[1], 8, 0, 0);
2206 if (tmp != operands[0])
2207 emit_move_insn (operands[0], tmp);
2208 }
2209 else if (MEM_P (operands[0]))
2210 {
2211 if (!reg_or_0_operand (operands[1], mode))
2212 operands[1] = force_reg (mode, operands[1]);
2213 alpha_expand_unaligned_store (operands[0], operands[1], 8, 0);
2214 }
2215 else
2216 gcc_unreachable ();
2217 }
2218
2219 /* Generate an unsigned DImode to FP conversion. This is the same code
2220 optabs would emit if we didn't have TFmode patterns.
2221
2222 For SFmode, this is the only construction I've found that can pass
2223 gcc.c-torture/execute/ieee/rbug.c. No scenario that uses DFmode
2224 intermediates will work, because you'll get intermediate rounding
2225 that ruins the end result. Some of this could be fixed by turning
2226 on round-to-positive-infinity, but that requires diddling the fpsr,
2227 which kills performance. I tried turning this around and converting
2228 to a negative number, so that I could turn on /m, but either I did
2229 it wrong or there's something else cause I wound up with the exact
2230 same single-bit error. There is a branch-less form of this same code:
2231
2232 srl $16,1,$1
2233 and $16,1,$2
2234 cmplt $16,0,$3
2235 or $1,$2,$2
2236 cmovge $16,$16,$2
2237 itoft $3,$f10
2238 itoft $2,$f11
2239 cvtqs $f11,$f11
2240 adds $f11,$f11,$f0
2241 fcmoveq $f10,$f11,$f0
2242
2243 I'm not using it because it's the same number of instructions as
2244 this branch-full form, and it has more serialized long latency
2245 instructions on the critical path.
2246
2247 For DFmode, we can avoid rounding errors by breaking up the word
2248 into two pieces, converting them separately, and adding them back:
2249
2250 LC0: .long 0,0x5f800000
2251
2252 itoft $16,$f11
2253 lda $2,LC0
2254 cmplt $16,0,$1
2255 cpyse $f11,$f31,$f10
2256 cpyse $f31,$f11,$f11
2257 s4addq $1,$2,$1
2258 lds $f12,0($1)
2259 cvtqt $f10,$f10
2260 cvtqt $f11,$f11
2261 addt $f12,$f10,$f0
2262 addt $f0,$f11,$f0
2263
2264 This doesn't seem to be a clear-cut win over the optabs form.
2265 It probably all depends on the distribution of numbers being
2266 converted -- in the optabs form, all but high-bit-set has a
2267 much lower minimum execution time. */
2268
2269 void
2270 alpha_emit_floatuns (rtx operands[2])
2271 {
2272 rtx neglab, donelab, i0, i1, f0, in, out;
2273 enum machine_mode mode;
2274
2275 out = operands[0];
2276 in = force_reg (DImode, operands[1]);
2277 mode = GET_MODE (out);
2278 neglab = gen_label_rtx ();
2279 donelab = gen_label_rtx ();
2280 i0 = gen_reg_rtx (DImode);
2281 i1 = gen_reg_rtx (DImode);
2282 f0 = gen_reg_rtx (mode);
2283
2284 emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, DImode, 0, neglab);
2285
2286 emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_FLOAT (mode, in)));
2287 emit_jump_insn (gen_jump (donelab));
2288 emit_barrier ();
2289
2290 emit_label (neglab);
2291
2292 emit_insn (gen_lshrdi3 (i0, in, const1_rtx));
2293 emit_insn (gen_anddi3 (i1, in, const1_rtx));
2294 emit_insn (gen_iordi3 (i0, i0, i1));
2295 emit_insn (gen_rtx_SET (VOIDmode, f0, gen_rtx_FLOAT (mode, i0)));
2296 emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_PLUS (mode, f0, f0)));
2297
2298 emit_label (donelab);
2299 }
2300
2301 /* Generate the comparison for a conditional branch. */
2302
2303 rtx
2304 alpha_emit_conditional_branch (enum rtx_code code)
2305 {
2306 enum rtx_code cmp_code, branch_code;
2307 enum machine_mode cmp_mode, branch_mode = VOIDmode;
2308 rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
2309 rtx tem;
2310
2311 if (alpha_compare.fp_p && GET_MODE (op0) == TFmode)
2312 {
2313 if (! TARGET_HAS_XFLOATING_LIBS)
2314 abort ();
2315
2316 /* X_floating library comparison functions return
2317 -1 unordered
2318 0 false
2319 1 true
2320 Convert the compare against the raw return value. */
2321
2322 switch (code)
2323 {
2324 case UNORDERED:
2325 cmp_code = EQ;
2326 code = LT;
2327 break;
2328 case ORDERED:
2329 cmp_code = EQ;
2330 code = GE;
2331 break;
2332 case NE:
2333 cmp_code = NE;
2334 code = NE;
2335 break;
2336 default:
2337 cmp_code = code;
2338 code = GT;
2339 break;
2340 }
2341
2342 op0 = alpha_emit_xfloating_compare (cmp_code, op0, op1);
2343 op1 = const0_rtx;
2344 alpha_compare.fp_p = 0;
2345 }
2346
2347 /* The general case: fold the comparison code to the types of compares
2348 that we have, choosing the branch as necessary. */
2349 switch (code)
2350 {
2351 case EQ: case LE: case LT: case LEU: case LTU:
2352 case UNORDERED:
2353 /* We have these compares: */
2354 cmp_code = code, branch_code = NE;
2355 break;
2356
2357 case NE:
2358 case ORDERED:
2359 /* These must be reversed. */
2360 cmp_code = reverse_condition (code), branch_code = EQ;
2361 break;
2362
2363 case GE: case GT: case GEU: case GTU:
2364 /* For FP, we swap them, for INT, we reverse them. */
2365 if (alpha_compare.fp_p)
2366 {
2367 cmp_code = swap_condition (code);
2368 branch_code = NE;
2369 tem = op0, op0 = op1, op1 = tem;
2370 }
2371 else
2372 {
2373 cmp_code = reverse_condition (code);
2374 branch_code = EQ;
2375 }
2376 break;
2377
2378 default:
2379 abort ();
2380 }
2381
2382 if (alpha_compare.fp_p)
2383 {
2384 cmp_mode = DFmode;
2385 if (flag_unsafe_math_optimizations)
2386 {
2387 /* When we are not as concerned about non-finite values, and we
2388 are comparing against zero, we can branch directly. */
2389 if (op1 == CONST0_RTX (DFmode))
2390 cmp_code = UNKNOWN, branch_code = code;
2391 else if (op0 == CONST0_RTX (DFmode))
2392 {
2393 /* Undo the swap we probably did just above. */
2394 tem = op0, op0 = op1, op1 = tem;
2395 branch_code = swap_condition (cmp_code);
2396 cmp_code = UNKNOWN;
2397 }
2398 }
2399 else
2400 {
2401 /* ??? We mark the branch mode to be CCmode to prevent the
2402 compare and branch from being combined, since the compare
2403 insn follows IEEE rules that the branch does not. */
2404 branch_mode = CCmode;
2405 }
2406 }
2407 else
2408 {
2409 cmp_mode = DImode;
2410
2411 /* The following optimizations are only for signed compares. */
2412 if (code != LEU && code != LTU && code != GEU && code != GTU)
2413 {
2414 /* Whee. Compare and branch against 0 directly. */
2415 if (op1 == const0_rtx)
2416 cmp_code = UNKNOWN, branch_code = code;
2417
2418 /* If the constants doesn't fit into an immediate, but can
2419 be generated by lda/ldah, we adjust the argument and
2420 compare against zero, so we can use beq/bne directly. */
2421 /* ??? Don't do this when comparing against symbols, otherwise
2422 we'll reduce (&x == 0x1234) to (&x-0x1234 == 0), which will
2423 be declared false out of hand (at least for non-weak). */
2424 else if (GET_CODE (op1) == CONST_INT
2425 && (code == EQ || code == NE)
2426 && !(symbolic_operand (op0, VOIDmode)
2427 || (GET_CODE (op0) == REG && REG_POINTER (op0))))
2428 {
2429 HOST_WIDE_INT v = INTVAL (op1), n = -v;
2430
2431 if (! CONST_OK_FOR_LETTER_P (v, 'I')
2432 && (CONST_OK_FOR_LETTER_P (n, 'K')
2433 || CONST_OK_FOR_LETTER_P (n, 'L')))
2434 {
2435 cmp_code = PLUS, branch_code = code;
2436 op1 = GEN_INT (n);
2437 }
2438 }
2439 }
2440
2441 if (!reg_or_0_operand (op0, DImode))
2442 op0 = force_reg (DImode, op0);
2443 if (cmp_code != PLUS && !reg_or_8bit_operand (op1, DImode))
2444 op1 = force_reg (DImode, op1);
2445 }
2446
2447 /* Emit an initial compare instruction, if necessary. */
2448 tem = op0;
2449 if (cmp_code != UNKNOWN)
2450 {
2451 tem = gen_reg_rtx (cmp_mode);
2452 emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
2453 }
2454
2455 /* Zero the operands. */
2456 memset (&alpha_compare, 0, sizeof (alpha_compare));
2457
2458 /* Return the branch comparison. */
2459 return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
2460 }
2461
2462 /* Certain simplifications can be done to make invalid setcc operations
2463 valid. Return the final comparison, or NULL if we can't work. */
2464
2465 rtx
2466 alpha_emit_setcc (enum rtx_code code)
2467 {
2468 enum rtx_code cmp_code;
2469 rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
2470 int fp_p = alpha_compare.fp_p;
2471 rtx tmp;
2472
2473 /* Zero the operands. */
2474 memset (&alpha_compare, 0, sizeof (alpha_compare));
2475
2476 if (fp_p && GET_MODE (op0) == TFmode)
2477 {
2478 if (! TARGET_HAS_XFLOATING_LIBS)
2479 abort ();
2480
2481 /* X_floating library comparison functions return
2482 -1 unordered
2483 0 false
2484 1 true
2485 Convert the compare against the raw return value. */
2486
2487 if (code == UNORDERED || code == ORDERED)
2488 cmp_code = EQ;
2489 else
2490 cmp_code = code;
2491
2492 op0 = alpha_emit_xfloating_compare (cmp_code, op0, op1);
2493 op1 = const0_rtx;
2494 fp_p = 0;
2495
2496 if (code == UNORDERED)
2497 code = LT;
2498 else if (code == ORDERED)
2499 code = GE;
2500 else
2501 code = GT;
2502 }
2503
2504 if (fp_p && !TARGET_FIX)
2505 return NULL_RTX;
2506
2507 /* The general case: fold the comparison code to the types of compares
2508 that we have, choosing the branch as necessary. */
2509
2510 cmp_code = UNKNOWN;
2511 switch (code)
2512 {
2513 case EQ: case LE: case LT: case LEU: case LTU:
2514 case UNORDERED:
2515 /* We have these compares. */
2516 if (fp_p)
2517 cmp_code = code, code = NE;
2518 break;
2519
2520 case NE:
2521 if (!fp_p && op1 == const0_rtx)
2522 break;
2523 /* FALLTHRU */
2524
2525 case ORDERED:
2526 cmp_code = reverse_condition (code);
2527 code = EQ;
2528 break;
2529
2530 case GE: case GT: case GEU: case GTU:
2531 /* These normally need swapping, but for integer zero we have
2532 special patterns that recognize swapped operands. */
2533 if (!fp_p && op1 == const0_rtx)
2534 break;
2535 code = swap_condition (code);
2536 if (fp_p)
2537 cmp_code = code, code = NE;
2538 tmp = op0, op0 = op1, op1 = tmp;
2539 break;
2540
2541 default:
2542 abort ();
2543 }
2544
2545 if (!fp_p)
2546 {
2547 if (!register_operand (op0, DImode))
2548 op0 = force_reg (DImode, op0);
2549 if (!reg_or_8bit_operand (op1, DImode))
2550 op1 = force_reg (DImode, op1);
2551 }
2552
2553 /* Emit an initial compare instruction, if necessary. */
2554 if (cmp_code != UNKNOWN)
2555 {
2556 enum machine_mode mode = fp_p ? DFmode : DImode;
2557
2558 tmp = gen_reg_rtx (mode);
2559 emit_insn (gen_rtx_SET (VOIDmode, tmp,
2560 gen_rtx_fmt_ee (cmp_code, mode, op0, op1)));
2561
2562 op0 = fp_p ? gen_lowpart (DImode, tmp) : tmp;
2563 op1 = const0_rtx;
2564 }
2565
2566 /* Return the setcc comparison. */
2567 return gen_rtx_fmt_ee (code, DImode, op0, op1);
2568 }
2569
2570
2571 /* Rewrite a comparison against zero CMP of the form
2572 (CODE (cc0) (const_int 0)) so it can be written validly in
2573 a conditional move (if_then_else CMP ...).
2574 If both of the operands that set cc0 are nonzero we must emit
2575 an insn to perform the compare (it can't be done within
2576 the conditional move). */
2577
2578 rtx
2579 alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
2580 {
2581 enum rtx_code code = GET_CODE (cmp);
2582 enum rtx_code cmov_code = NE;
2583 rtx op0 = alpha_compare.op0;
2584 rtx op1 = alpha_compare.op1;
2585 int fp_p = alpha_compare.fp_p;
2586 enum machine_mode cmp_mode
2587 = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
2588 enum machine_mode cmp_op_mode = fp_p ? DFmode : DImode;
2589 enum machine_mode cmov_mode = VOIDmode;
2590 int local_fast_math = flag_unsafe_math_optimizations;
2591 rtx tem;
2592
2593 /* Zero the operands. */
2594 memset (&alpha_compare, 0, sizeof (alpha_compare));
2595
2596 if (fp_p != FLOAT_MODE_P (mode))
2597 {
2598 enum rtx_code cmp_code;
2599
2600 if (! TARGET_FIX)
2601 return 0;
2602
2603 /* If we have fp<->int register move instructions, do a cmov by
2604 performing the comparison in fp registers, and move the
2605 zero/nonzero value to integer registers, where we can then
2606 use a normal cmov, or vice-versa. */
2607
2608 switch (code)
2609 {
2610 case EQ: case LE: case LT: case LEU: case LTU:
2611 /* We have these compares. */
2612 cmp_code = code, code = NE;
2613 break;
2614
2615 case NE:
2616 /* This must be reversed. */
2617 cmp_code = EQ, code = EQ;
2618 break;
2619
2620 case GE: case GT: case GEU: case GTU:
2621 /* These normally need swapping, but for integer zero we have
2622 special patterns that recognize swapped operands. */
2623 if (!fp_p && op1 == const0_rtx)
2624 cmp_code = code, code = NE;
2625 else
2626 {
2627 cmp_code = swap_condition (code);
2628 code = NE;
2629 tem = op0, op0 = op1, op1 = tem;
2630 }
2631 break;
2632
2633 default:
2634 abort ();
2635 }
2636
2637 tem = gen_reg_rtx (cmp_op_mode);
2638 emit_insn (gen_rtx_SET (VOIDmode, tem,
2639 gen_rtx_fmt_ee (cmp_code, cmp_op_mode,
2640 op0, op1)));
2641
2642 cmp_mode = cmp_op_mode = fp_p ? DImode : DFmode;
2643 op0 = gen_lowpart (cmp_op_mode, tem);
2644 op1 = CONST0_RTX (cmp_op_mode);
2645 fp_p = !fp_p;
2646 local_fast_math = 1;
2647 }
2648
2649 /* We may be able to use a conditional move directly.
2650 This avoids emitting spurious compares. */
2651 if (signed_comparison_operator (cmp, VOIDmode)
2652 && (!fp_p || local_fast_math)
2653 && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
2654 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
2655
2656 /* We can't put the comparison inside the conditional move;
2657 emit a compare instruction and put that inside the
2658 conditional move. Make sure we emit only comparisons we have;
2659 swap or reverse as necessary. */
2660
2661 if (no_new_pseudos)
2662 return NULL_RTX;
2663
2664 switch (code)
2665 {
2666 case EQ: case LE: case LT: case LEU: case LTU:
2667 /* We have these compares: */
2668 break;
2669
2670 case NE:
2671 /* This must be reversed. */
2672 code = reverse_condition (code);
2673 cmov_code = EQ;
2674 break;
2675
2676 case GE: case GT: case GEU: case GTU:
2677 /* These must be swapped. */
2678 if (op1 != CONST0_RTX (cmp_mode))
2679 {
2680 code = swap_condition (code);
2681 tem = op0, op0 = op1, op1 = tem;
2682 }
2683 break;
2684
2685 default:
2686 abort ();
2687 }
2688
2689 if (!fp_p)
2690 {
2691 if (!reg_or_0_operand (op0, DImode))
2692 op0 = force_reg (DImode, op0);
2693 if (!reg_or_8bit_operand (op1, DImode))
2694 op1 = force_reg (DImode, op1);
2695 }
2696
2697 /* ??? We mark the branch mode to be CCmode to prevent the compare
2698 and cmov from being combined, since the compare insn follows IEEE
2699 rules that the cmov does not. */
2700 if (fp_p && !local_fast_math)
2701 cmov_mode = CCmode;
2702
2703 tem = gen_reg_rtx (cmp_op_mode);
2704 emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
2705 return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
2706 }
2707
2708 /* Simplify a conditional move of two constants into a setcc with
2709 arithmetic. This is done with a splitter since combine would
2710 just undo the work if done during code generation. It also catches
2711 cases we wouldn't have before cse. */
2712
2713 int
2714 alpha_split_conditional_move (enum rtx_code code, rtx dest, rtx cond,
2715 rtx t_rtx, rtx f_rtx)
2716 {
2717 HOST_WIDE_INT t, f, diff;
2718 enum machine_mode mode;
2719 rtx target, subtarget, tmp;
2720
2721 mode = GET_MODE (dest);
2722 t = INTVAL (t_rtx);
2723 f = INTVAL (f_rtx);
2724 diff = t - f;
2725
2726 if (((code == NE || code == EQ) && diff < 0)
2727 || (code == GE || code == GT))
2728 {
2729 code = reverse_condition (code);
2730 diff = t, t = f, f = diff;
2731 diff = t - f;
2732 }
2733
2734 subtarget = target = dest;
2735 if (mode != DImode)
2736 {
2737 target = gen_lowpart (DImode, dest);
2738 if (! no_new_pseudos)
2739 subtarget = gen_reg_rtx (DImode);
2740 else
2741 subtarget = target;
2742 }
2743 /* Below, we must be careful to use copy_rtx on target and subtarget
2744 in intermediate insns, as they may be a subreg rtx, which may not
2745 be shared. */
2746
2747 if (f == 0 && exact_log2 (diff) > 0
2748 /* On EV6, we've got enough shifters to make non-arithmetic shifts
2749 viable over a longer latency cmove. On EV5, the E0 slot is a
2750 scarce resource, and on EV4 shift has the same latency as a cmove. */
2751 && (diff <= 8 || alpha_cpu == PROCESSOR_EV6))
2752 {
2753 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2754 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp));
2755
2756 tmp = gen_rtx_ASHIFT (DImode, copy_rtx (subtarget),
2757 GEN_INT (exact_log2 (t)));
2758 emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
2759 }
2760 else if (f == 0 && t == -1)
2761 {
2762 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2763 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp));
2764
2765 emit_insn (gen_negdi2 (target, copy_rtx (subtarget)));
2766 }
2767 else if (diff == 1 || diff == 4 || diff == 8)
2768 {
2769 rtx add_op;
2770
2771 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2772 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp));
2773
2774 if (diff == 1)
2775 emit_insn (gen_adddi3 (target, copy_rtx (subtarget), GEN_INT (f)));
2776 else
2777 {
2778 add_op = GEN_INT (f);
2779 if (sext_add_operand (add_op, mode))
2780 {
2781 tmp = gen_rtx_MULT (DImode, copy_rtx (subtarget),
2782 GEN_INT (diff));
2783 tmp = gen_rtx_PLUS (DImode, tmp, add_op);
2784 emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
2785 }
2786 else
2787 return 0;
2788 }
2789 }
2790 else
2791 return 0;
2792
2793 return 1;
2794 }
2795 \f
2796 /* Look up the function X_floating library function name for the
2797 given operation. */
2798
2799 struct xfloating_op GTY(())
2800 {
2801 const enum rtx_code code;
2802 const char *const GTY((skip)) osf_func;
2803 const char *const GTY((skip)) vms_func;
2804 rtx libcall;
2805 };
2806
2807 static GTY(()) struct xfloating_op xfloating_ops[] =
2808 {
2809 { PLUS, "_OtsAddX", "OTS$ADD_X", 0 },
2810 { MINUS, "_OtsSubX", "OTS$SUB_X", 0 },
2811 { MULT, "_OtsMulX", "OTS$MUL_X", 0 },
2812 { DIV, "_OtsDivX", "OTS$DIV_X", 0 },
2813 { EQ, "_OtsEqlX", "OTS$EQL_X", 0 },
2814 { NE, "_OtsNeqX", "OTS$NEQ_X", 0 },
2815 { LT, "_OtsLssX", "OTS$LSS_X", 0 },
2816 { LE, "_OtsLeqX", "OTS$LEQ_X", 0 },
2817 { GT, "_OtsGtrX", "OTS$GTR_X", 0 },
2818 { GE, "_OtsGeqX", "OTS$GEQ_X", 0 },
2819 { FIX, "_OtsCvtXQ", "OTS$CVTXQ", 0 },
2820 { FLOAT, "_OtsCvtQX", "OTS$CVTQX", 0 },
2821 { UNSIGNED_FLOAT, "_OtsCvtQUX", "OTS$CVTQUX", 0 },
2822 { FLOAT_EXTEND, "_OtsConvertFloatTX", "OTS$CVT_FLOAT_T_X", 0 },
2823 { FLOAT_TRUNCATE, "_OtsConvertFloatXT", "OTS$CVT_FLOAT_X_T", 0 }
2824 };
2825
2826 static GTY(()) struct xfloating_op vax_cvt_ops[] =
2827 {
2828 { FLOAT_EXTEND, "_OtsConvertFloatGX", "OTS$CVT_FLOAT_G_X", 0 },
2829 { FLOAT_TRUNCATE, "_OtsConvertFloatXG", "OTS$CVT_FLOAT_X_G", 0 }
2830 };
2831
2832 static rtx
2833 alpha_lookup_xfloating_lib_func (enum rtx_code code)
2834 {
2835 struct xfloating_op *ops = xfloating_ops;
2836 long n = ARRAY_SIZE (xfloating_ops);
2837 long i;
2838
2839 /* How irritating. Nothing to key off for the main table. */
2840 if (TARGET_FLOAT_VAX && (code == FLOAT_EXTEND || code == FLOAT_TRUNCATE))
2841 {
2842 ops = vax_cvt_ops;
2843 n = ARRAY_SIZE (vax_cvt_ops);
2844 }
2845
2846 for (i = 0; i < n; ++i, ++ops)
2847 if (ops->code == code)
2848 {
2849 rtx func = ops->libcall;
2850 if (!func)
2851 {
2852 func = init_one_libfunc (TARGET_ABI_OPEN_VMS
2853 ? ops->vms_func : ops->osf_func);
2854 ops->libcall = func;
2855 }
2856 return func;
2857 }
2858
2859 abort();
2860 }
2861
2862 /* Most X_floating operations take the rounding mode as an argument.
2863 Compute that here. */
2864
2865 static int
2866 alpha_compute_xfloating_mode_arg (enum rtx_code code,
2867 enum alpha_fp_rounding_mode round)
2868 {
2869 int mode;
2870
2871 switch (round)
2872 {
2873 case ALPHA_FPRM_NORM:
2874 mode = 2;
2875 break;
2876 case ALPHA_FPRM_MINF:
2877 mode = 1;
2878 break;
2879 case ALPHA_FPRM_CHOP:
2880 mode = 0;
2881 break;
2882 case ALPHA_FPRM_DYN:
2883 mode = 4;
2884 break;
2885 default:
2886 abort ();
2887
2888 /* XXX For reference, round to +inf is mode = 3. */
2889 }
2890
2891 if (code == FLOAT_TRUNCATE && alpha_fptm == ALPHA_FPTM_N)
2892 mode |= 0x10000;
2893
2894 return mode;
2895 }
2896
2897 /* Emit an X_floating library function call.
2898
2899 Note that these functions do not follow normal calling conventions:
2900 TFmode arguments are passed in two integer registers (as opposed to
2901 indirect); TFmode return values appear in R16+R17.
2902
2903 FUNC is the function to call.
2904 TARGET is where the output belongs.
2905 OPERANDS are the inputs.
2906 NOPERANDS is the count of inputs.
2907 EQUIV is the expression equivalent for the function.
2908 */
2909
2910 static void
2911 alpha_emit_xfloating_libcall (rtx func, rtx target, rtx operands[],
2912 int noperands, rtx equiv)
2913 {
2914 rtx usage = NULL_RTX, tmp, reg;
2915 int regno = 16, i;
2916
2917 start_sequence ();
2918
2919 for (i = 0; i < noperands; ++i)
2920 {
2921 switch (GET_MODE (operands[i]))
2922 {
2923 case TFmode:
2924 reg = gen_rtx_REG (TFmode, regno);
2925 regno += 2;
2926 break;
2927
2928 case DFmode:
2929 reg = gen_rtx_REG (DFmode, regno + 32);
2930 regno += 1;
2931 break;
2932
2933 case VOIDmode:
2934 if (GET_CODE (operands[i]) != CONST_INT)
2935 abort ();
2936 /* FALLTHRU */
2937 case DImode:
2938 reg = gen_rtx_REG (DImode, regno);
2939 regno += 1;
2940 break;
2941
2942 default:
2943 abort ();
2944 }
2945
2946 emit_move_insn (reg, operands[i]);
2947 usage = alloc_EXPR_LIST (0, gen_rtx_USE (VOIDmode, reg), usage);
2948 }
2949
2950 switch (GET_MODE (target))
2951 {
2952 case TFmode:
2953 reg = gen_rtx_REG (TFmode, 16);
2954 break;
2955 case DFmode:
2956 reg = gen_rtx_REG (DFmode, 32);
2957 break;
2958 case DImode:
2959 reg = gen_rtx_REG (DImode, 0);
2960 break;
2961 default:
2962 abort ();
2963 }
2964
2965 tmp = gen_rtx_MEM (QImode, func);
2966 tmp = emit_call_insn (GEN_CALL_VALUE (reg, tmp, const0_rtx,
2967 const0_rtx, const0_rtx));
2968 CALL_INSN_FUNCTION_USAGE (tmp) = usage;
2969 CONST_OR_PURE_CALL_P (tmp) = 1;
2970
2971 tmp = get_insns ();
2972 end_sequence ();
2973
2974 emit_libcall_block (tmp, target, reg, equiv);
2975 }
2976
2977 /* Emit an X_floating library function call for arithmetic (+,-,*,/). */
2978
2979 void
2980 alpha_emit_xfloating_arith (enum rtx_code code, rtx operands[])
2981 {
2982 rtx func;
2983 int mode;
2984 rtx out_operands[3];
2985
2986 func = alpha_lookup_xfloating_lib_func (code);
2987 mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
2988
2989 out_operands[0] = operands[1];
2990 out_operands[1] = operands[2];
2991 out_operands[2] = GEN_INT (mode);
2992 alpha_emit_xfloating_libcall (func, operands[0], out_operands, 3,
2993 gen_rtx_fmt_ee (code, TFmode, operands[1],
2994 operands[2]));
2995 }
2996
2997 /* Emit an X_floating library function call for a comparison. */
2998
2999 static rtx
3000 alpha_emit_xfloating_compare (enum rtx_code code, rtx op0, rtx op1)
3001 {
3002 rtx func;
3003 rtx out, operands[2];
3004
3005 func = alpha_lookup_xfloating_lib_func (code);
3006
3007 operands[0] = op0;
3008 operands[1] = op1;
3009 out = gen_reg_rtx (DImode);
3010
3011 /* ??? Strange mode for equiv because what's actually returned
3012 is -1,0,1, not a proper boolean value. */
3013 alpha_emit_xfloating_libcall (func, out, operands, 2,
3014 gen_rtx_fmt_ee (code, CCmode, op0, op1));
3015
3016 return out;
3017 }
3018
3019 /* Emit an X_floating library function call for a conversion. */
3020
3021 void
3022 alpha_emit_xfloating_cvt (enum rtx_code orig_code, rtx operands[])
3023 {
3024 int noperands = 1, mode;
3025 rtx out_operands[2];
3026 rtx func;
3027 enum rtx_code code = orig_code;
3028
3029 if (code == UNSIGNED_FIX)
3030 code = FIX;
3031
3032 func = alpha_lookup_xfloating_lib_func (code);
3033
3034 out_operands[0] = operands[1];
3035
3036 switch (code)
3037 {
3038 case FIX:
3039 mode = alpha_compute_xfloating_mode_arg (code, ALPHA_FPRM_CHOP);
3040 out_operands[1] = GEN_INT (mode);
3041 noperands = 2;
3042 break;
3043 case FLOAT_TRUNCATE:
3044 mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
3045 out_operands[1] = GEN_INT (mode);
3046 noperands = 2;
3047 break;
3048 default:
3049 break;
3050 }
3051
3052 alpha_emit_xfloating_libcall (func, operands[0], out_operands, noperands,
3053 gen_rtx_fmt_e (orig_code,
3054 GET_MODE (operands[0]),
3055 operands[1]));
3056 }
3057
3058 /* Split a TFmode OP[1] into DImode OP[2,3] and likewise for
3059 OP[0] into OP[0,1]. Naturally, output operand ordering is
3060 little-endian. */
3061
3062 void
3063 alpha_split_tfmode_pair (rtx operands[4])
3064 {
3065 if (GET_CODE (operands[1]) == REG)
3066 {
3067 operands[3] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1);
3068 operands[2] = gen_rtx_REG (DImode, REGNO (operands[1]));
3069 }
3070 else if (GET_CODE (operands[1]) == MEM)
3071 {
3072 operands[3] = adjust_address (operands[1], DImode, 8);
3073 operands[2] = adjust_address (operands[1], DImode, 0);
3074 }
3075 else if (operands[1] == CONST0_RTX (TFmode))
3076 operands[2] = operands[3] = const0_rtx;
3077 else
3078 abort ();
3079
3080 if (GET_CODE (operands[0]) == REG)
3081 {
3082 operands[1] = gen_rtx_REG (DImode, REGNO (operands[0]) + 1);
3083 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
3084 }
3085 else if (GET_CODE (operands[0]) == MEM)
3086 {
3087 operands[1] = adjust_address (operands[0], DImode, 8);
3088 operands[0] = adjust_address (operands[0], DImode, 0);
3089 }
3090 else
3091 abort ();
3092 }
3093
3094 /* Implement negtf2 or abstf2. Op0 is destination, op1 is source,
3095 op2 is a register containing the sign bit, operation is the
3096 logical operation to be performed. */
3097
3098 void
3099 alpha_split_tfmode_frobsign (rtx operands[3], rtx (*operation) (rtx, rtx, rtx))
3100 {
3101 rtx high_bit = operands[2];
3102 rtx scratch;
3103 int move;
3104
3105 alpha_split_tfmode_pair (operands);
3106
3107 /* Detect three flavors of operand overlap. */
3108 move = 1;
3109 if (rtx_equal_p (operands[0], operands[2]))
3110 move = 0;
3111 else if (rtx_equal_p (operands[1], operands[2]))
3112 {
3113 if (rtx_equal_p (operands[0], high_bit))
3114 move = 2;
3115 else
3116 move = -1;
3117 }
3118
3119 if (move < 0)
3120 emit_move_insn (operands[0], operands[2]);
3121
3122 /* ??? If the destination overlaps both source tf and high_bit, then
3123 assume source tf is dead in its entirety and use the other half
3124 for a scratch register. Otherwise "scratch" is just the proper
3125 destination register. */
3126 scratch = operands[move < 2 ? 1 : 3];
3127
3128 emit_insn ((*operation) (scratch, high_bit, operands[3]));
3129
3130 if (move > 0)
3131 {
3132 emit_move_insn (operands[0], operands[2]);
3133 if (move > 1)
3134 emit_move_insn (operands[1], scratch);
3135 }
3136 }
3137 \f
3138 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
3139 unaligned data:
3140
3141 unsigned: signed:
3142 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
3143 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
3144 lda r3,X(r11) lda r3,X+2(r11)
3145 extwl r1,r3,r1 extql r1,r3,r1
3146 extwh r2,r3,r2 extqh r2,r3,r2
3147 or r1.r2.r1 or r1,r2,r1
3148 sra r1,48,r1
3149
3150 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
3151 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
3152 lda r3,X(r11) lda r3,X(r11)
3153 extll r1,r3,r1 extll r1,r3,r1
3154 extlh r2,r3,r2 extlh r2,r3,r2
3155 or r1.r2.r1 addl r1,r2,r1
3156
3157 quad: ldq_u r1,X(r11)
3158 ldq_u r2,X+7(r11)
3159 lda r3,X(r11)
3160 extql r1,r3,r1
3161 extqh r2,r3,r2
3162 or r1.r2.r1
3163 */
3164
3165 void
3166 alpha_expand_unaligned_load (rtx tgt, rtx mem, HOST_WIDE_INT size,
3167 HOST_WIDE_INT ofs, int sign)
3168 {
3169 rtx meml, memh, addr, extl, exth, tmp, mema;
3170 enum machine_mode mode;
3171
3172 if (TARGET_BWX && size == 2)
3173 {
3174 meml = adjust_address (mem, QImode, ofs);
3175 memh = adjust_address (mem, QImode, ofs+1);
3176 if (BYTES_BIG_ENDIAN)
3177 tmp = meml, meml = memh, memh = tmp;
3178 extl = gen_reg_rtx (DImode);
3179 exth = gen_reg_rtx (DImode);
3180 emit_insn (gen_zero_extendqidi2 (extl, meml));
3181 emit_insn (gen_zero_extendqidi2 (exth, memh));
3182 exth = expand_simple_binop (DImode, ASHIFT, exth, GEN_INT (8),
3183 NULL, 1, OPTAB_LIB_WIDEN);
3184 addr = expand_simple_binop (DImode, IOR, extl, exth,
3185 NULL, 1, OPTAB_LIB_WIDEN);
3186
3187 if (sign && GET_MODE (tgt) != HImode)
3188 {
3189 addr = gen_lowpart (HImode, addr);
3190 emit_insn (gen_extend_insn (tgt, addr, GET_MODE (tgt), HImode, 0));
3191 }
3192 else
3193 {
3194 if (GET_MODE (tgt) != DImode)
3195 addr = gen_lowpart (GET_MODE (tgt), addr);
3196 emit_move_insn (tgt, addr);
3197 }
3198 return;
3199 }
3200
3201 meml = gen_reg_rtx (DImode);
3202 memh = gen_reg_rtx (DImode);
3203 addr = gen_reg_rtx (DImode);
3204 extl = gen_reg_rtx (DImode);
3205 exth = gen_reg_rtx (DImode);
3206
3207 mema = XEXP (mem, 0);
3208 if (GET_CODE (mema) == LO_SUM)
3209 mema = force_reg (Pmode, mema);
3210
3211 /* AND addresses cannot be in any alias set, since they may implicitly
3212 alias surrounding code. Ideally we'd have some alias set that
3213 covered all types except those with alignment 8 or higher. */
3214
3215 tmp = change_address (mem, DImode,
3216 gen_rtx_AND (DImode,
3217 plus_constant (mema, ofs),
3218 GEN_INT (-8)));
3219 set_mem_alias_set (tmp, 0);
3220 emit_move_insn (meml, tmp);
3221
3222 tmp = change_address (mem, DImode,
3223 gen_rtx_AND (DImode,
3224 plus_constant (mema, ofs + size - 1),
3225 GEN_INT (-8)));
3226 set_mem_alias_set (tmp, 0);
3227 emit_move_insn (memh, tmp);
3228
3229 if (WORDS_BIG_ENDIAN && sign && (size == 2 || size == 4))
3230 {
3231 emit_move_insn (addr, plus_constant (mema, -1));
3232
3233 emit_insn (gen_extqh_be (extl, meml, addr));
3234 emit_insn (gen_extxl_be (exth, memh, GEN_INT (64), addr));
3235
3236 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
3237 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (64 - size*8),
3238 addr, 1, OPTAB_WIDEN);
3239 }
3240 else if (sign && size == 2)
3241 {
3242 emit_move_insn (addr, plus_constant (mema, ofs+2));
3243
3244 emit_insn (gen_extxl_le (extl, meml, GEN_INT (64), addr));
3245 emit_insn (gen_extqh_le (exth, memh, addr));
3246
3247 /* We must use tgt here for the target. Alpha-vms port fails if we use
3248 addr for the target, because addr is marked as a pointer and combine
3249 knows that pointers are always sign-extended 32 bit values. */
3250 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
3251 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48),
3252 addr, 1, OPTAB_WIDEN);
3253 }
3254 else
3255 {
3256 if (WORDS_BIG_ENDIAN)
3257 {
3258 emit_move_insn (addr, plus_constant (mema, ofs+size-1));
3259 switch ((int) size)
3260 {
3261 case 2:
3262 emit_insn (gen_extwh_be (extl, meml, addr));
3263 mode = HImode;
3264 break;
3265
3266 case 4:
3267 emit_insn (gen_extlh_be (extl, meml, addr));
3268 mode = SImode;
3269 break;
3270
3271 case 8:
3272 emit_insn (gen_extqh_be (extl, meml, addr));
3273 mode = DImode;
3274 break;
3275
3276 default:
3277 abort ();
3278 }
3279 emit_insn (gen_extxl_be (exth, memh, GEN_INT (size*8), addr));
3280 }
3281 else
3282 {
3283 emit_move_insn (addr, plus_constant (mema, ofs));
3284 emit_insn (gen_extxl_le (extl, meml, GEN_INT (size*8), addr));
3285 switch ((int) size)
3286 {
3287 case 2:
3288 emit_insn (gen_extwh_le (exth, memh, addr));
3289 mode = HImode;
3290 break;
3291
3292 case 4:
3293 emit_insn (gen_extlh_le (exth, memh, addr));
3294 mode = SImode;
3295 break;
3296
3297 case 8:
3298 emit_insn (gen_extqh_le (exth, memh, addr));
3299 mode = DImode;
3300 break;
3301
3302 default:
3303 abort();
3304 }
3305 }
3306
3307 addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
3308 gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
3309 sign, OPTAB_WIDEN);
3310 }
3311
3312 if (addr != tgt)
3313 emit_move_insn (tgt, gen_lowpart (GET_MODE (tgt), addr));
3314 }
3315
3316 /* Similarly, use ins and msk instructions to perform unaligned stores. */
3317
3318 void
3319 alpha_expand_unaligned_store (rtx dst, rtx src,
3320 HOST_WIDE_INT size, HOST_WIDE_INT ofs)
3321 {
3322 rtx dstl, dsth, addr, insl, insh, meml, memh, dsta;
3323
3324 if (TARGET_BWX && size == 2)
3325 {
3326 if (src != const0_rtx)
3327 {
3328 dstl = gen_lowpart (QImode, src);
3329 dsth = expand_simple_binop (DImode, LSHIFTRT, src, GEN_INT (8),
3330 NULL, 1, OPTAB_LIB_WIDEN);
3331 dsth = gen_lowpart (QImode, dsth);
3332 }
3333 else
3334 dstl = dsth = const0_rtx;
3335
3336 meml = adjust_address (dst, QImode, ofs);
3337 memh = adjust_address (dst, QImode, ofs+1);
3338 if (BYTES_BIG_ENDIAN)
3339 addr = meml, meml = memh, memh = addr;
3340
3341 emit_move_insn (meml, dstl);
3342 emit_move_insn (memh, dsth);
3343 return;
3344 }
3345
3346 dstl = gen_reg_rtx (DImode);
3347 dsth = gen_reg_rtx (DImode);
3348 insl = gen_reg_rtx (DImode);
3349 insh = gen_reg_rtx (DImode);
3350
3351 dsta = XEXP (dst, 0);
3352 if (GET_CODE (dsta) == LO_SUM)
3353 dsta = force_reg (Pmode, dsta);
3354
3355 /* AND addresses cannot be in any alias set, since they may implicitly
3356 alias surrounding code. Ideally we'd have some alias set that
3357 covered all types except those with alignment 8 or higher. */
3358
3359 meml = change_address (dst, DImode,
3360 gen_rtx_AND (DImode,
3361 plus_constant (dsta, ofs),
3362 GEN_INT (-8)));
3363 set_mem_alias_set (meml, 0);
3364
3365 memh = change_address (dst, DImode,
3366 gen_rtx_AND (DImode,
3367 plus_constant (dsta, ofs + size - 1),
3368 GEN_INT (-8)));
3369 set_mem_alias_set (memh, 0);
3370
3371 emit_move_insn (dsth, memh);
3372 emit_move_insn (dstl, meml);
3373 if (WORDS_BIG_ENDIAN)
3374 {
3375 addr = copy_addr_to_reg (plus_constant (dsta, ofs+size-1));
3376
3377 if (src != const0_rtx)
3378 {
3379 switch ((int) size)
3380 {
3381 case 2:
3382 emit_insn (gen_inswl_be (insh, gen_lowpart (HImode,src), addr));
3383 break;
3384 case 4:
3385 emit_insn (gen_insll_be (insh, gen_lowpart (SImode,src), addr));
3386 break;
3387 case 8:
3388 emit_insn (gen_insql_be (insh, gen_lowpart (DImode,src), addr));
3389 break;
3390 }
3391 emit_insn (gen_insxh (insl, gen_lowpart (DImode, src),
3392 GEN_INT (size*8), addr));
3393 }
3394
3395 switch ((int) size)
3396 {
3397 case 2:
3398 emit_insn (gen_mskxl_be (dsth, dsth, GEN_INT (0xffff), addr));
3399 break;
3400 case 4:
3401 {
3402 rtx msk = immed_double_const (0xffffffff, 0, DImode);
3403 emit_insn (gen_mskxl_be (dsth, dsth, msk, addr));
3404 break;
3405 }
3406 case 8:
3407 emit_insn (gen_mskxl_be (dsth, dsth, constm1_rtx, addr));
3408 break;
3409 }
3410
3411 emit_insn (gen_mskxh (dstl, dstl, GEN_INT (size*8), addr));
3412 }
3413 else
3414 {
3415 addr = copy_addr_to_reg (plus_constant (dsta, ofs));
3416
3417 if (src != CONST0_RTX (GET_MODE (src)))
3418 {
3419 emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
3420 GEN_INT (size*8), addr));
3421
3422 switch ((int) size)
3423 {
3424 case 2:
3425 emit_insn (gen_inswl_le (insl, gen_lowpart (HImode, src), addr));
3426 break;
3427 case 4:
3428 emit_insn (gen_insll_le (insl, gen_lowpart (SImode, src), addr));
3429 break;
3430 case 8:
3431 emit_insn (gen_insql_le (insl, src, addr));
3432 break;
3433 }
3434 }
3435
3436 emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
3437
3438 switch ((int) size)
3439 {
3440 case 2:
3441 emit_insn (gen_mskxl_le (dstl, dstl, GEN_INT (0xffff), addr));
3442 break;
3443 case 4:
3444 {
3445 rtx msk = immed_double_const (0xffffffff, 0, DImode);
3446 emit_insn (gen_mskxl_le (dstl, dstl, msk, addr));
3447 break;
3448 }
3449 case 8:
3450 emit_insn (gen_mskxl_le (dstl, dstl, constm1_rtx, addr));
3451 break;
3452 }
3453 }
3454
3455 if (src != CONST0_RTX (GET_MODE (src)))
3456 {
3457 dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
3458 dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
3459 }
3460
3461 if (WORDS_BIG_ENDIAN)
3462 {
3463 emit_move_insn (meml, dstl);
3464 emit_move_insn (memh, dsth);
3465 }
3466 else
3467 {
3468 /* Must store high before low for degenerate case of aligned. */
3469 emit_move_insn (memh, dsth);
3470 emit_move_insn (meml, dstl);
3471 }
3472 }
3473
3474 /* The block move code tries to maximize speed by separating loads and
3475 stores at the expense of register pressure: we load all of the data
3476 before we store it back out. There are two secondary effects worth
3477 mentioning, that this speeds copying to/from aligned and unaligned
3478 buffers, and that it makes the code significantly easier to write. */
3479
3480 #define MAX_MOVE_WORDS 8
3481
3482 /* Load an integral number of consecutive unaligned quadwords. */
3483
3484 static void
3485 alpha_expand_unaligned_load_words (rtx *out_regs, rtx smem,
3486 HOST_WIDE_INT words, HOST_WIDE_INT ofs)
3487 {
3488 rtx const im8 = GEN_INT (-8);
3489 rtx const i64 = GEN_INT (64);
3490 rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
3491 rtx sreg, areg, tmp, smema;
3492 HOST_WIDE_INT i;
3493
3494 smema = XEXP (smem, 0);
3495 if (GET_CODE (smema) == LO_SUM)
3496 smema = force_reg (Pmode, smema);
3497
3498 /* Generate all the tmp registers we need. */
3499 for (i = 0; i < words; ++i)
3500 {
3501 data_regs[i] = out_regs[i];
3502 ext_tmps[i] = gen_reg_rtx (DImode);
3503 }
3504 data_regs[words] = gen_reg_rtx (DImode);
3505
3506 if (ofs != 0)
3507 smem = adjust_address (smem, GET_MODE (smem), ofs);
3508
3509 /* Load up all of the source data. */
3510 for (i = 0; i < words; ++i)
3511 {
3512 tmp = change_address (smem, DImode,
3513 gen_rtx_AND (DImode,
3514 plus_constant (smema, 8*i),
3515 im8));
3516 set_mem_alias_set (tmp, 0);
3517 emit_move_insn (data_regs[i], tmp);
3518 }
3519
3520 tmp = change_address (smem, DImode,
3521 gen_rtx_AND (DImode,
3522 plus_constant (smema, 8*words - 1),
3523 im8));
3524 set_mem_alias_set (tmp, 0);
3525 emit_move_insn (data_regs[words], tmp);
3526
3527 /* Extract the half-word fragments. Unfortunately DEC decided to make
3528 extxh with offset zero a noop instead of zeroing the register, so
3529 we must take care of that edge condition ourselves with cmov. */
3530
3531 sreg = copy_addr_to_reg (smema);
3532 areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
3533 1, OPTAB_WIDEN);
3534 if (WORDS_BIG_ENDIAN)
3535 emit_move_insn (sreg, plus_constant (sreg, 7));
3536 for (i = 0; i < words; ++i)
3537 {
3538 if (WORDS_BIG_ENDIAN)
3539 {
3540 emit_insn (gen_extqh_be (data_regs[i], data_regs[i], sreg));
3541 emit_insn (gen_extxl_be (ext_tmps[i], data_regs[i+1], i64, sreg));
3542 }
3543 else
3544 {
3545 emit_insn (gen_extxl_le (data_regs[i], data_regs[i], i64, sreg));
3546 emit_insn (gen_extqh_le (ext_tmps[i], data_regs[i+1], sreg));
3547 }
3548 emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
3549 gen_rtx_IF_THEN_ELSE (DImode,
3550 gen_rtx_EQ (DImode, areg,
3551 const0_rtx),
3552 const0_rtx, ext_tmps[i])));
3553 }
3554
3555 /* Merge the half-words into whole words. */
3556 for (i = 0; i < words; ++i)
3557 {
3558 out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
3559 ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
3560 }
3561 }
3562
3563 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
3564 may be NULL to store zeros. */
3565
3566 static void
3567 alpha_expand_unaligned_store_words (rtx *data_regs, rtx dmem,
3568 HOST_WIDE_INT words, HOST_WIDE_INT ofs)
3569 {
3570 rtx const im8 = GEN_INT (-8);
3571 rtx const i64 = GEN_INT (64);
3572 rtx ins_tmps[MAX_MOVE_WORDS];
3573 rtx st_tmp_1, st_tmp_2, dreg;
3574 rtx st_addr_1, st_addr_2, dmema;
3575 HOST_WIDE_INT i;
3576
3577 dmema = XEXP (dmem, 0);
3578 if (GET_CODE (dmema) == LO_SUM)
3579 dmema = force_reg (Pmode, dmema);
3580
3581 /* Generate all the tmp registers we need. */
3582 if (data_regs != NULL)
3583 for (i = 0; i < words; ++i)
3584 ins_tmps[i] = gen_reg_rtx(DImode);
3585 st_tmp_1 = gen_reg_rtx(DImode);
3586 st_tmp_2 = gen_reg_rtx(DImode);
3587
3588 if (ofs != 0)
3589 dmem = adjust_address (dmem, GET_MODE (dmem), ofs);
3590
3591 st_addr_2 = change_address (dmem, DImode,
3592 gen_rtx_AND (DImode,
3593 plus_constant (dmema, words*8 - 1),
3594 im8));
3595 set_mem_alias_set (st_addr_2, 0);
3596
3597 st_addr_1 = change_address (dmem, DImode,
3598 gen_rtx_AND (DImode, dmema, im8));
3599 set_mem_alias_set (st_addr_1, 0);
3600
3601 /* Load up the destination end bits. */
3602 emit_move_insn (st_tmp_2, st_addr_2);
3603 emit_move_insn (st_tmp_1, st_addr_1);
3604
3605 /* Shift the input data into place. */
3606 dreg = copy_addr_to_reg (dmema);
3607 if (WORDS_BIG_ENDIAN)
3608 emit_move_insn (dreg, plus_constant (dreg, 7));
3609 if (data_regs != NULL)
3610 {
3611 for (i = words-1; i >= 0; --i)
3612 {
3613 if (WORDS_BIG_ENDIAN)
3614 {
3615 emit_insn (gen_insql_be (ins_tmps[i], data_regs[i], dreg));
3616 emit_insn (gen_insxh (data_regs[i], data_regs[i], i64, dreg));
3617 }
3618 else
3619 {
3620 emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
3621 emit_insn (gen_insql_le (data_regs[i], data_regs[i], dreg));
3622 }
3623 }
3624 for (i = words-1; i > 0; --i)
3625 {
3626 ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
3627 ins_tmps[i-1], ins_tmps[i-1], 1,
3628 OPTAB_WIDEN);
3629 }
3630 }
3631
3632 /* Split and merge the ends with the destination data. */
3633 if (WORDS_BIG_ENDIAN)
3634 {
3635 emit_insn (gen_mskxl_be (st_tmp_2, st_tmp_2, constm1_rtx, dreg));
3636 emit_insn (gen_mskxh (st_tmp_1, st_tmp_1, i64, dreg));
3637 }
3638 else
3639 {
3640 emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
3641 emit_insn (gen_mskxl_le (st_tmp_1, st_tmp_1, constm1_rtx, dreg));
3642 }
3643
3644 if (data_regs != NULL)
3645 {
3646 st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
3647 st_tmp_2, 1, OPTAB_WIDEN);
3648 st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
3649 st_tmp_1, 1, OPTAB_WIDEN);
3650 }
3651
3652 /* Store it all. */
3653 if (WORDS_BIG_ENDIAN)
3654 emit_move_insn (st_addr_1, st_tmp_1);
3655 else
3656 emit_move_insn (st_addr_2, st_tmp_2);
3657 for (i = words-1; i > 0; --i)
3658 {
3659 rtx tmp = change_address (dmem, DImode,
3660 gen_rtx_AND (DImode,
3661 plus_constant(dmema,
3662 WORDS_BIG_ENDIAN ? i*8-1 : i*8),
3663 im8));
3664 set_mem_alias_set (tmp, 0);
3665 emit_move_insn (tmp, data_regs ? ins_tmps[i-1] : const0_rtx);
3666 }
3667 if (WORDS_BIG_ENDIAN)
3668 emit_move_insn (st_addr_2, st_tmp_2);
3669 else
3670 emit_move_insn (st_addr_1, st_tmp_1);
3671 }
3672
3673
3674 /* Expand string/block move operations.
3675
3676 operands[0] is the pointer to the destination.
3677 operands[1] is the pointer to the source.
3678 operands[2] is the number of bytes to move.
3679 operands[3] is the alignment. */
3680
3681 int
3682 alpha_expand_block_move (rtx operands[])
3683 {
3684 rtx bytes_rtx = operands[2];
3685 rtx align_rtx = operands[3];
3686 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
3687 HOST_WIDE_INT bytes = orig_bytes;
3688 HOST_WIDE_INT src_align = INTVAL (align_rtx) * BITS_PER_UNIT;
3689 HOST_WIDE_INT dst_align = src_align;
3690 rtx orig_src = operands[1];
3691 rtx orig_dst = operands[0];
3692 rtx data_regs[2 * MAX_MOVE_WORDS + 16];
3693 rtx tmp;
3694 unsigned int i, words, ofs, nregs = 0;
3695
3696 if (orig_bytes <= 0)
3697 return 1;
3698 else if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD)
3699 return 0;
3700
3701 /* Look for additional alignment information from recorded register info. */
3702
3703 tmp = XEXP (orig_src, 0);
3704 if (GET_CODE (tmp) == REG)
3705 src_align = MAX (src_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
3706 else if (GET_CODE (tmp) == PLUS
3707 && GET_CODE (XEXP (tmp, 0)) == REG
3708 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
3709 {
3710 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
3711 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
3712
3713 if (a > src_align)
3714 {
3715 if (a >= 64 && c % 8 == 0)
3716 src_align = 64;
3717 else if (a >= 32 && c % 4 == 0)
3718 src_align = 32;
3719 else if (a >= 16 && c % 2 == 0)
3720 src_align = 16;
3721 }
3722 }
3723
3724 tmp = XEXP (orig_dst, 0);
3725 if (GET_CODE (tmp) == REG)
3726 dst_align = MAX (dst_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
3727 else if (GET_CODE (tmp) == PLUS
3728 && GET_CODE (XEXP (tmp, 0)) == REG
3729 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
3730 {
3731 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
3732 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
3733
3734 if (a > dst_align)
3735 {
3736 if (a >= 64 && c % 8 == 0)
3737 dst_align = 64;
3738 else if (a >= 32 && c % 4 == 0)
3739 dst_align = 32;
3740 else if (a >= 16 && c % 2 == 0)
3741 dst_align = 16;
3742 }
3743 }
3744
3745 ofs = 0;
3746 if (src_align >= 64 && bytes >= 8)
3747 {
3748 words = bytes / 8;
3749
3750 for (i = 0; i < words; ++i)
3751 data_regs[nregs + i] = gen_reg_rtx (DImode);
3752
3753 for (i = 0; i < words; ++i)
3754 emit_move_insn (data_regs[nregs + i],
3755 adjust_address (orig_src, DImode, ofs + i * 8));
3756
3757 nregs += words;
3758 bytes -= words * 8;
3759 ofs += words * 8;
3760 }
3761
3762 if (src_align >= 32 && bytes >= 4)
3763 {
3764 words = bytes / 4;
3765
3766 for (i = 0; i < words; ++i)
3767 data_regs[nregs + i] = gen_reg_rtx (SImode);
3768
3769 for (i = 0; i < words; ++i)
3770 emit_move_insn (data_regs[nregs + i],
3771 adjust_address (orig_src, SImode, ofs + i * 4));
3772
3773 nregs += words;
3774 bytes -= words * 4;
3775 ofs += words * 4;
3776 }
3777
3778 if (bytes >= 8)
3779 {
3780 words = bytes / 8;
3781
3782 for (i = 0; i < words+1; ++i)
3783 data_regs[nregs + i] = gen_reg_rtx (DImode);
3784
3785 alpha_expand_unaligned_load_words (data_regs + nregs, orig_src,
3786 words, ofs);
3787
3788 nregs += words;
3789 bytes -= words * 8;
3790 ofs += words * 8;
3791 }
3792
3793 if (! TARGET_BWX && bytes >= 4)
3794 {
3795 data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
3796 alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
3797 bytes -= 4;
3798 ofs += 4;
3799 }
3800
3801 if (bytes >= 2)
3802 {
3803 if (src_align >= 16)
3804 {
3805 do {
3806 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
3807 emit_move_insn (tmp, adjust_address (orig_src, HImode, ofs));
3808 bytes -= 2;
3809 ofs += 2;
3810 } while (bytes >= 2);
3811 }
3812 else if (! TARGET_BWX)
3813 {
3814 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
3815 alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
3816 bytes -= 2;
3817 ofs += 2;
3818 }
3819 }
3820
3821 while (bytes > 0)
3822 {
3823 data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
3824 emit_move_insn (tmp, adjust_address (orig_src, QImode, ofs));
3825 bytes -= 1;
3826 ofs += 1;
3827 }
3828
3829 if (nregs > ARRAY_SIZE (data_regs))
3830 abort ();
3831
3832 /* Now save it back out again. */
3833
3834 i = 0, ofs = 0;
3835
3836 /* Write out the data in whatever chunks reading the source allowed. */
3837 if (dst_align >= 64)
3838 {
3839 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
3840 {
3841 emit_move_insn (adjust_address (orig_dst, DImode, ofs),
3842 data_regs[i]);
3843 ofs += 8;
3844 i++;
3845 }
3846 }
3847
3848 if (dst_align >= 32)
3849 {
3850 /* If the source has remaining DImode regs, write them out in
3851 two pieces. */
3852 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
3853 {
3854 tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
3855 NULL_RTX, 1, OPTAB_WIDEN);
3856
3857 emit_move_insn (adjust_address (orig_dst, SImode, ofs),
3858 gen_lowpart (SImode, data_regs[i]));
3859 emit_move_insn (adjust_address (orig_dst, SImode, ofs + 4),
3860 gen_lowpart (SImode, tmp));
3861 ofs += 8;
3862 i++;
3863 }
3864
3865 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
3866 {
3867 emit_move_insn (adjust_address (orig_dst, SImode, ofs),
3868 data_regs[i]);
3869 ofs += 4;
3870 i++;
3871 }
3872 }
3873
3874 if (i < nregs && GET_MODE (data_regs[i]) == DImode)
3875 {
3876 /* Write out a remaining block of words using unaligned methods. */
3877
3878 for (words = 1; i + words < nregs; words++)
3879 if (GET_MODE (data_regs[i + words]) != DImode)
3880 break;
3881
3882 if (words == 1)
3883 alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
3884 else
3885 alpha_expand_unaligned_store_words (data_regs + i, orig_dst,
3886 words, ofs);
3887
3888 i += words;
3889 ofs += words * 8;
3890 }
3891
3892 /* Due to the above, this won't be aligned. */
3893 /* ??? If we have more than one of these, consider constructing full
3894 words in registers and using alpha_expand_unaligned_store_words. */
3895 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
3896 {
3897 alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
3898 ofs += 4;
3899 i++;
3900 }
3901
3902 if (dst_align >= 16)
3903 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
3904 {
3905 emit_move_insn (adjust_address (orig_dst, HImode, ofs), data_regs[i]);
3906 i++;
3907 ofs += 2;
3908 }
3909 else
3910 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
3911 {
3912 alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
3913 i++;
3914 ofs += 2;
3915 }
3916
3917 while (i < nregs && GET_MODE (data_regs[i]) == QImode)
3918 {
3919 emit_move_insn (adjust_address (orig_dst, QImode, ofs), data_regs[i]);
3920 i++;
3921 ofs += 1;
3922 }
3923
3924 if (i != nregs)
3925 abort ();
3926
3927 return 1;
3928 }
3929
3930 int
3931 alpha_expand_block_clear (rtx operands[])
3932 {
3933 rtx bytes_rtx = operands[1];
3934 rtx align_rtx = operands[2];
3935 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
3936 HOST_WIDE_INT bytes = orig_bytes;
3937 HOST_WIDE_INT align = INTVAL (align_rtx) * BITS_PER_UNIT;
3938 HOST_WIDE_INT alignofs = 0;
3939 rtx orig_dst = operands[0];
3940 rtx tmp;
3941 int i, words, ofs = 0;
3942
3943 if (orig_bytes <= 0)
3944 return 1;
3945 if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD)
3946 return 0;
3947
3948 /* Look for stricter alignment. */
3949 tmp = XEXP (orig_dst, 0);
3950 if (GET_CODE (tmp) == REG)
3951 align = MAX (align, REGNO_POINTER_ALIGN (REGNO (tmp)));
3952 else if (GET_CODE (tmp) == PLUS
3953 && GET_CODE (XEXP (tmp, 0)) == REG
3954 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
3955 {
3956 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
3957 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
3958
3959 if (a > align)
3960 {
3961 if (a >= 64)
3962 align = a, alignofs = 8 - c % 8;
3963 else if (a >= 32)
3964 align = a, alignofs = 4 - c % 4;
3965 else if (a >= 16)
3966 align = a, alignofs = 2 - c % 2;
3967 }
3968 }
3969
3970 /* Handle an unaligned prefix first. */
3971
3972 if (alignofs > 0)
3973 {
3974 #if HOST_BITS_PER_WIDE_INT >= 64
3975 /* Given that alignofs is bounded by align, the only time BWX could
3976 generate three stores is for a 7 byte fill. Prefer two individual
3977 stores over a load/mask/store sequence. */
3978 if ((!TARGET_BWX || alignofs == 7)
3979 && align >= 32
3980 && !(alignofs == 4 && bytes >= 4))
3981 {
3982 enum machine_mode mode = (align >= 64 ? DImode : SImode);
3983 int inv_alignofs = (align >= 64 ? 8 : 4) - alignofs;
3984 rtx mem, tmp;
3985 HOST_WIDE_INT mask;
3986
3987 mem = adjust_address (orig_dst, mode, ofs - inv_alignofs);
3988 set_mem_alias_set (mem, 0);
3989
3990 mask = ~(~(HOST_WIDE_INT)0 << (inv_alignofs * 8));
3991 if (bytes < alignofs)
3992 {
3993 mask |= ~(HOST_WIDE_INT)0 << ((inv_alignofs + bytes) * 8);
3994 ofs += bytes;
3995 bytes = 0;
3996 }
3997 else
3998 {
3999 bytes -= alignofs;
4000 ofs += alignofs;
4001 }
4002 alignofs = 0;
4003
4004 tmp = expand_binop (mode, and_optab, mem, GEN_INT (mask),
4005 NULL_RTX, 1, OPTAB_WIDEN);
4006
4007 emit_move_insn (mem, tmp);
4008 }
4009 #endif
4010
4011 if (TARGET_BWX && (alignofs & 1) && bytes >= 1)
4012 {
4013 emit_move_insn (adjust_address (orig_dst, QImode, ofs), const0_rtx);
4014 bytes -= 1;
4015 ofs += 1;
4016 alignofs -= 1;
4017 }
4018 if (TARGET_BWX && align >= 16 && (alignofs & 3) == 2 && bytes >= 2)
4019 {
4020 emit_move_insn (adjust_address (orig_dst, HImode, ofs), const0_rtx);
4021 bytes -= 2;
4022 ofs += 2;
4023 alignofs -= 2;
4024 }
4025 if (alignofs == 4 && bytes >= 4)
4026 {
4027 emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx);
4028 bytes -= 4;
4029 ofs += 4;
4030 alignofs = 0;
4031 }
4032
4033 /* If we've not used the extra lead alignment information by now,
4034 we won't be able to. Downgrade align to match what's left over. */
4035 if (alignofs > 0)
4036 {
4037 alignofs = alignofs & -alignofs;
4038 align = MIN (align, alignofs * BITS_PER_UNIT);
4039 }
4040 }
4041
4042 /* Handle a block of contiguous long-words. */
4043
4044 if (align >= 64 && bytes >= 8)
4045 {
4046 words = bytes / 8;
4047
4048 for (i = 0; i < words; ++i)
4049 emit_move_insn (adjust_address (orig_dst, DImode, ofs + i * 8),
4050 const0_rtx);
4051
4052 bytes -= words * 8;
4053 ofs += words * 8;
4054 }
4055
4056 /* If the block is large and appropriately aligned, emit a single
4057 store followed by a sequence of stq_u insns. */
4058
4059 if (align >= 32 && bytes > 16)
4060 {
4061 rtx orig_dsta;
4062
4063 emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx);
4064 bytes -= 4;
4065 ofs += 4;
4066
4067 orig_dsta = XEXP (orig_dst, 0);
4068 if (GET_CODE (orig_dsta) == LO_SUM)
4069 orig_dsta = force_reg (Pmode, orig_dsta);
4070
4071 words = bytes / 8;
4072 for (i = 0; i < words; ++i)
4073 {
4074 rtx mem
4075 = change_address (orig_dst, DImode,
4076 gen_rtx_AND (DImode,
4077 plus_constant (orig_dsta, ofs + i*8),
4078 GEN_INT (-8)));
4079 set_mem_alias_set (mem, 0);
4080 emit_move_insn (mem, const0_rtx);
4081 }
4082
4083 /* Depending on the alignment, the first stq_u may have overlapped
4084 with the initial stl, which means that the last stq_u didn't
4085 write as much as it would appear. Leave those questionable bytes
4086 unaccounted for. */
4087 bytes -= words * 8 - 4;
4088 ofs += words * 8 - 4;
4089 }
4090
4091 /* Handle a smaller block of aligned words. */
4092
4093 if ((align >= 64 && bytes == 4)
4094 || (align == 32 && bytes >= 4))
4095 {
4096 words = bytes / 4;
4097
4098 for (i = 0; i < words; ++i)
4099 emit_move_insn (adjust_address (orig_dst, SImode, ofs + i * 4),
4100 const0_rtx);
4101
4102 bytes -= words * 4;
4103 ofs += words * 4;
4104 }
4105
4106 /* An unaligned block uses stq_u stores for as many as possible. */
4107
4108 if (bytes >= 8)
4109 {
4110 words = bytes / 8;
4111
4112 alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
4113
4114 bytes -= words * 8;
4115 ofs += words * 8;
4116 }
4117
4118 /* Next clean up any trailing pieces. */
4119
4120 #if HOST_BITS_PER_WIDE_INT >= 64
4121 /* Count the number of bits in BYTES for which aligned stores could
4122 be emitted. */
4123 words = 0;
4124 for (i = (TARGET_BWX ? 1 : 4); i * BITS_PER_UNIT <= align ; i <<= 1)
4125 if (bytes & i)
4126 words += 1;
4127
4128 /* If we have appropriate alignment (and it wouldn't take too many
4129 instructions otherwise), mask out the bytes we need. */
4130 if (TARGET_BWX ? words > 2 : bytes > 0)
4131 {
4132 if (align >= 64)
4133 {
4134 rtx mem, tmp;
4135 HOST_WIDE_INT mask;
4136
4137 mem = adjust_address (orig_dst, DImode, ofs);
4138 set_mem_alias_set (mem, 0);
4139
4140 mask = ~(HOST_WIDE_INT)0 << (bytes * 8);
4141
4142 tmp = expand_binop (DImode, and_optab, mem, GEN_INT (mask),
4143 NULL_RTX, 1, OPTAB_WIDEN);
4144
4145 emit_move_insn (mem, tmp);
4146 return 1;
4147 }
4148 else if (align >= 32 && bytes < 4)
4149 {
4150 rtx mem, tmp;
4151 HOST_WIDE_INT mask;
4152
4153 mem = adjust_address (orig_dst, SImode, ofs);
4154 set_mem_alias_set (mem, 0);
4155
4156 mask = ~(HOST_WIDE_INT)0 << (bytes * 8);
4157
4158 tmp = expand_binop (SImode, and_optab, mem, GEN_INT (mask),
4159 NULL_RTX, 1, OPTAB_WIDEN);
4160
4161 emit_move_insn (mem, tmp);
4162 return 1;
4163 }
4164 }
4165 #endif
4166
4167 if (!TARGET_BWX && bytes >= 4)
4168 {
4169 alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
4170 bytes -= 4;
4171 ofs += 4;
4172 }
4173
4174 if (bytes >= 2)
4175 {
4176 if (align >= 16)
4177 {
4178 do {
4179 emit_move_insn (adjust_address (orig_dst, HImode, ofs),
4180 const0_rtx);
4181 bytes -= 2;
4182 ofs += 2;
4183 } while (bytes >= 2);
4184 }
4185 else if (! TARGET_BWX)
4186 {
4187 alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
4188 bytes -= 2;
4189 ofs += 2;
4190 }
4191 }
4192
4193 while (bytes > 0)
4194 {
4195 emit_move_insn (adjust_address (orig_dst, QImode, ofs), const0_rtx);
4196 bytes -= 1;
4197 ofs += 1;
4198 }
4199
4200 return 1;
4201 }
4202
4203 /* Returns a mask so that zap(x, value) == x & mask. */
4204
4205 rtx
4206 alpha_expand_zap_mask (HOST_WIDE_INT value)
4207 {
4208 rtx result;
4209 int i;
4210
4211 if (HOST_BITS_PER_WIDE_INT >= 64)
4212 {
4213 HOST_WIDE_INT mask = 0;
4214
4215 for (i = 7; i >= 0; --i)
4216 {
4217 mask <<= 8;
4218 if (!((value >> i) & 1))
4219 mask |= 0xff;
4220 }
4221
4222 result = gen_int_mode (mask, DImode);
4223 }
4224 else if (HOST_BITS_PER_WIDE_INT == 32)
4225 {
4226 HOST_WIDE_INT mask_lo = 0, mask_hi = 0;
4227
4228 for (i = 7; i >= 4; --i)
4229 {
4230 mask_hi <<= 8;
4231 if (!((value >> i) & 1))
4232 mask_hi |= 0xff;
4233 }
4234
4235 for (i = 3; i >= 0; --i)
4236 {
4237 mask_lo <<= 8;
4238 if (!((value >> i) & 1))
4239 mask_lo |= 0xff;
4240 }
4241
4242 result = immed_double_const (mask_lo, mask_hi, DImode);
4243 }
4244 else
4245 abort ();
4246
4247 return result;
4248 }
4249
4250 void
4251 alpha_expand_builtin_vector_binop (rtx (*gen) (rtx, rtx, rtx),
4252 enum machine_mode mode,
4253 rtx op0, rtx op1, rtx op2)
4254 {
4255 op0 = gen_lowpart (mode, op0);
4256
4257 if (op1 == const0_rtx)
4258 op1 = CONST0_RTX (mode);
4259 else
4260 op1 = gen_lowpart (mode, op1);
4261
4262 if (op2 == const0_rtx)
4263 op2 = CONST0_RTX (mode);
4264 else
4265 op2 = gen_lowpart (mode, op2);
4266
4267 emit_insn ((*gen) (op0, op1, op2));
4268 }
4269 \f
4270 /* Adjust the cost of a scheduling dependency. Return the new cost of
4271 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
4272
4273 static int
4274 alpha_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
4275 {
4276 enum attr_type insn_type, dep_insn_type;
4277
4278 /* If the dependence is an anti-dependence, there is no cost. For an
4279 output dependence, there is sometimes a cost, but it doesn't seem
4280 worth handling those few cases. */
4281 if (REG_NOTE_KIND (link) != 0)
4282 return cost;
4283
4284 /* If we can't recognize the insns, we can't really do anything. */
4285 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
4286 return cost;
4287
4288 insn_type = get_attr_type (insn);
4289 dep_insn_type = get_attr_type (dep_insn);
4290
4291 /* Bring in the user-defined memory latency. */
4292 if (dep_insn_type == TYPE_ILD
4293 || dep_insn_type == TYPE_FLD
4294 || dep_insn_type == TYPE_LDSYM)
4295 cost += alpha_memory_latency-1;
4296
4297 /* Everything else handled in DFA bypasses now. */
4298
4299 return cost;
4300 }
4301
4302 /* The number of instructions that can be issued per cycle. */
4303
4304 static int
4305 alpha_issue_rate (void)
4306 {
4307 return (alpha_cpu == PROCESSOR_EV4 ? 2 : 4);
4308 }
4309
4310 /* How many alternative schedules to try. This should be as wide as the
4311 scheduling freedom in the DFA, but no wider. Making this value too
4312 large results extra work for the scheduler.
4313
4314 For EV4, loads can be issued to either IB0 or IB1, thus we have 2
4315 alternative schedules. For EV5, we can choose between E0/E1 and
4316 FA/FM. For EV6, an arithmetic insn can be issued to U0/U1/L0/L1. */
4317
4318 static int
4319 alpha_multipass_dfa_lookahead (void)
4320 {
4321 return (alpha_cpu == PROCESSOR_EV6 ? 4 : 2);
4322 }
4323 \f
4324 /* Machine-specific function data. */
4325
4326 struct machine_function GTY(())
4327 {
4328 /* For unicosmk. */
4329 /* List of call information words for calls from this function. */
4330 struct rtx_def *first_ciw;
4331 struct rtx_def *last_ciw;
4332 int ciw_count;
4333
4334 /* List of deferred case vectors. */
4335 struct rtx_def *addr_list;
4336
4337 /* For OSF. */
4338 const char *some_ld_name;
4339
4340 /* For TARGET_LD_BUGGY_LDGP. */
4341 struct rtx_def *gp_save_rtx;
4342 };
4343
4344 /* How to allocate a 'struct machine_function'. */
4345
4346 static struct machine_function *
4347 alpha_init_machine_status (void)
4348 {
4349 return ((struct machine_function *)
4350 ggc_alloc_cleared (sizeof (struct machine_function)));
4351 }
4352
4353 /* Functions to save and restore alpha_return_addr_rtx. */
4354
4355 /* Start the ball rolling with RETURN_ADDR_RTX. */
4356
4357 rtx
4358 alpha_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
4359 {
4360 if (count != 0)
4361 return const0_rtx;
4362
4363 return get_hard_reg_initial_val (Pmode, REG_RA);
4364 }
4365
4366 /* Return or create a memory slot containing the gp value for the current
4367 function. Needed only if TARGET_LD_BUGGY_LDGP. */
4368
4369 rtx
4370 alpha_gp_save_rtx (void)
4371 {
4372 rtx seq, m = cfun->machine->gp_save_rtx;
4373
4374 if (m == NULL)
4375 {
4376 start_sequence ();
4377
4378 m = assign_stack_local (DImode, UNITS_PER_WORD, BITS_PER_WORD);
4379 m = validize_mem (m);
4380 emit_move_insn (m, pic_offset_table_rtx);
4381
4382 seq = get_insns ();
4383 end_sequence ();
4384 emit_insn_after (seq, entry_of_function ());
4385
4386 cfun->machine->gp_save_rtx = m;
4387 }
4388
4389 return m;
4390 }
4391
4392 static int
4393 alpha_ra_ever_killed (void)
4394 {
4395 rtx top;
4396
4397 if (!has_hard_reg_initial_val (Pmode, REG_RA))
4398 return regs_ever_live[REG_RA];
4399
4400 push_topmost_sequence ();
4401 top = get_insns ();
4402 pop_topmost_sequence ();
4403
4404 return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX);
4405 }
4406
4407 \f
4408 /* Return the trap mode suffix applicable to the current
4409 instruction, or NULL. */
4410
4411 static const char *
4412 get_trap_mode_suffix (void)
4413 {
4414 enum attr_trap_suffix s = get_attr_trap_suffix (current_output_insn);
4415
4416 switch (s)
4417 {
4418 case TRAP_SUFFIX_NONE:
4419 return NULL;
4420
4421 case TRAP_SUFFIX_SU:
4422 if (alpha_fptm >= ALPHA_FPTM_SU)
4423 return "su";
4424 return NULL;
4425
4426 case TRAP_SUFFIX_SUI:
4427 if (alpha_fptm >= ALPHA_FPTM_SUI)
4428 return "sui";
4429 return NULL;
4430
4431 case TRAP_SUFFIX_V_SV:
4432 switch (alpha_fptm)
4433 {
4434 case ALPHA_FPTM_N:
4435 return NULL;
4436 case ALPHA_FPTM_U:
4437 return "v";
4438 case ALPHA_FPTM_SU:
4439 case ALPHA_FPTM_SUI:
4440 return "sv";
4441 }
4442 break;
4443
4444 case TRAP_SUFFIX_V_SV_SVI:
4445 switch (alpha_fptm)
4446 {
4447 case ALPHA_FPTM_N:
4448 return NULL;
4449 case ALPHA_FPTM_U:
4450 return "v";
4451 case ALPHA_FPTM_SU:
4452 return "sv";
4453 case ALPHA_FPTM_SUI:
4454 return "svi";
4455 }
4456 break;
4457
4458 case TRAP_SUFFIX_U_SU_SUI:
4459 switch (alpha_fptm)
4460 {
4461 case ALPHA_FPTM_N:
4462 return NULL;
4463 case ALPHA_FPTM_U:
4464 return "u";
4465 case ALPHA_FPTM_SU:
4466 return "su";
4467 case ALPHA_FPTM_SUI:
4468 return "sui";
4469 }
4470 break;
4471 }
4472 abort ();
4473 }
4474
4475 /* Return the rounding mode suffix applicable to the current
4476 instruction, or NULL. */
4477
4478 static const char *
4479 get_round_mode_suffix (void)
4480 {
4481 enum attr_round_suffix s = get_attr_round_suffix (current_output_insn);
4482
4483 switch (s)
4484 {
4485 case ROUND_SUFFIX_NONE:
4486 return NULL;
4487 case ROUND_SUFFIX_NORMAL:
4488 switch (alpha_fprm)
4489 {
4490 case ALPHA_FPRM_NORM:
4491 return NULL;
4492 case ALPHA_FPRM_MINF:
4493 return "m";
4494 case ALPHA_FPRM_CHOP:
4495 return "c";
4496 case ALPHA_FPRM_DYN:
4497 return "d";
4498 }
4499 break;
4500
4501 case ROUND_SUFFIX_C:
4502 return "c";
4503 }
4504 abort ();
4505 }
4506
4507 /* Locate some local-dynamic symbol still in use by this function
4508 so that we can print its name in some movdi_er_tlsldm pattern. */
4509
4510 static int
4511 get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
4512 {
4513 rtx x = *px;
4514
4515 if (GET_CODE (x) == SYMBOL_REF
4516 && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
4517 {
4518 cfun->machine->some_ld_name = XSTR (x, 0);
4519 return 1;
4520 }
4521
4522 return 0;
4523 }
4524
4525 static const char *
4526 get_some_local_dynamic_name (void)
4527 {
4528 rtx insn;
4529
4530 if (cfun->machine->some_ld_name)
4531 return cfun->machine->some_ld_name;
4532
4533 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
4534 if (INSN_P (insn)
4535 && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
4536 return cfun->machine->some_ld_name;
4537
4538 abort ();
4539 }
4540
4541 /* Print an operand. Recognize special options, documented below. */
4542
4543 void
4544 print_operand (FILE *file, rtx x, int code)
4545 {
4546 int i;
4547
4548 switch (code)
4549 {
4550 case '~':
4551 /* Print the assembler name of the current function. */
4552 assemble_name (file, alpha_fnname);
4553 break;
4554
4555 case '&':
4556 assemble_name (file, get_some_local_dynamic_name ());
4557 break;
4558
4559 case '/':
4560 {
4561 const char *trap = get_trap_mode_suffix ();
4562 const char *round = get_round_mode_suffix ();
4563
4564 if (trap || round)
4565 fprintf (file, (TARGET_AS_SLASH_BEFORE_SUFFIX ? "/%s%s" : "%s%s"),
4566 (trap ? trap : ""), (round ? round : ""));
4567 break;
4568 }
4569
4570 case ',':
4571 /* Generates single precision instruction suffix. */
4572 fputc ((TARGET_FLOAT_VAX ? 'f' : 's'), file);
4573 break;
4574
4575 case '-':
4576 /* Generates double precision instruction suffix. */
4577 fputc ((TARGET_FLOAT_VAX ? 'g' : 't'), file);
4578 break;
4579
4580 case '+':
4581 /* Generates a nop after a noreturn call at the very end of the
4582 function. */
4583 if (next_real_insn (current_output_insn) == 0)
4584 fprintf (file, "\n\tnop");
4585 break;
4586
4587 case '#':
4588 if (alpha_this_literal_sequence_number == 0)
4589 alpha_this_literal_sequence_number = alpha_next_sequence_number++;
4590 fprintf (file, "%d", alpha_this_literal_sequence_number);
4591 break;
4592
4593 case '*':
4594 if (alpha_this_gpdisp_sequence_number == 0)
4595 alpha_this_gpdisp_sequence_number = alpha_next_sequence_number++;
4596 fprintf (file, "%d", alpha_this_gpdisp_sequence_number);
4597 break;
4598
4599 case 'H':
4600 if (GET_CODE (x) == HIGH)
4601 output_addr_const (file, XEXP (x, 0));
4602 else
4603 output_operand_lossage ("invalid %%H value");
4604 break;
4605
4606 case 'J':
4607 {
4608 const char *lituse;
4609
4610 if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD_CALL)
4611 {
4612 x = XVECEXP (x, 0, 0);
4613 lituse = "lituse_tlsgd";
4614 }
4615 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM_CALL)
4616 {
4617 x = XVECEXP (x, 0, 0);
4618 lituse = "lituse_tlsldm";
4619 }
4620 else if (GET_CODE (x) == CONST_INT)
4621 lituse = "lituse_jsr";
4622 else
4623 {
4624 output_operand_lossage ("invalid %%J value");
4625 break;
4626 }
4627
4628 if (x != const0_rtx)
4629 fprintf (file, "\t\t!%s!%d", lituse, (int) INTVAL (x));
4630 }
4631 break;
4632
4633 case 'r':
4634 /* If this operand is the constant zero, write it as "$31". */
4635 if (GET_CODE (x) == REG)
4636 fprintf (file, "%s", reg_names[REGNO (x)]);
4637 else if (x == CONST0_RTX (GET_MODE (x)))
4638 fprintf (file, "$31");
4639 else
4640 output_operand_lossage ("invalid %%r value");
4641 break;
4642
4643 case 'R':
4644 /* Similar, but for floating-point. */
4645 if (GET_CODE (x) == REG)
4646 fprintf (file, "%s", reg_names[REGNO (x)]);
4647 else if (x == CONST0_RTX (GET_MODE (x)))
4648 fprintf (file, "$f31");
4649 else
4650 output_operand_lossage ("invalid %%R value");
4651 break;
4652
4653 case 'N':
4654 /* Write the 1's complement of a constant. */
4655 if (GET_CODE (x) != CONST_INT)
4656 output_operand_lossage ("invalid %%N value");
4657
4658 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
4659 break;
4660
4661 case 'P':
4662 /* Write 1 << C, for a constant C. */
4663 if (GET_CODE (x) != CONST_INT)
4664 output_operand_lossage ("invalid %%P value");
4665
4666 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
4667 break;
4668
4669 case 'h':
4670 /* Write the high-order 16 bits of a constant, sign-extended. */
4671 if (GET_CODE (x) != CONST_INT)
4672 output_operand_lossage ("invalid %%h value");
4673
4674 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
4675 break;
4676
4677 case 'L':
4678 /* Write the low-order 16 bits of a constant, sign-extended. */
4679 if (GET_CODE (x) != CONST_INT)
4680 output_operand_lossage ("invalid %%L value");
4681
4682 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4683 (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
4684 break;
4685
4686 case 'm':
4687 /* Write mask for ZAP insn. */
4688 if (GET_CODE (x) == CONST_DOUBLE)
4689 {
4690 HOST_WIDE_INT mask = 0;
4691 HOST_WIDE_INT value;
4692
4693 value = CONST_DOUBLE_LOW (x);
4694 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
4695 i++, value >>= 8)
4696 if (value & 0xff)
4697 mask |= (1 << i);
4698
4699 value = CONST_DOUBLE_HIGH (x);
4700 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
4701 i++, value >>= 8)
4702 if (value & 0xff)
4703 mask |= (1 << (i + sizeof (int)));
4704
4705 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
4706 }
4707
4708 else if (GET_CODE (x) == CONST_INT)
4709 {
4710 HOST_WIDE_INT mask = 0, value = INTVAL (x);
4711
4712 for (i = 0; i < 8; i++, value >>= 8)
4713 if (value & 0xff)
4714 mask |= (1 << i);
4715
4716 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
4717 }
4718 else
4719 output_operand_lossage ("invalid %%m value");
4720 break;
4721
4722 case 'M':
4723 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
4724 if (GET_CODE (x) != CONST_INT
4725 || (INTVAL (x) != 8 && INTVAL (x) != 16
4726 && INTVAL (x) != 32 && INTVAL (x) != 64))
4727 output_operand_lossage ("invalid %%M value");
4728
4729 fprintf (file, "%s",
4730 (INTVAL (x) == 8 ? "b"
4731 : INTVAL (x) == 16 ? "w"
4732 : INTVAL (x) == 32 ? "l"
4733 : "q"));
4734 break;
4735
4736 case 'U':
4737 /* Similar, except do it from the mask. */
4738 if (GET_CODE (x) == CONST_INT)
4739 {
4740 HOST_WIDE_INT value = INTVAL (x);
4741
4742 if (value == 0xff)
4743 {
4744 fputc ('b', file);
4745 break;
4746 }
4747 if (value == 0xffff)
4748 {
4749 fputc ('w', file);
4750 break;
4751 }
4752 if (value == 0xffffffff)
4753 {
4754 fputc ('l', file);
4755 break;
4756 }
4757 if (value == -1)
4758 {
4759 fputc ('q', file);
4760 break;
4761 }
4762 }
4763 else if (HOST_BITS_PER_WIDE_INT == 32
4764 && GET_CODE (x) == CONST_DOUBLE
4765 && CONST_DOUBLE_LOW (x) == 0xffffffff
4766 && CONST_DOUBLE_HIGH (x) == 0)
4767 {
4768 fputc ('l', file);
4769 break;
4770 }
4771 output_operand_lossage ("invalid %%U value");
4772 break;
4773
4774 case 's':
4775 /* Write the constant value divided by 8 for little-endian mode or
4776 (56 - value) / 8 for big-endian mode. */
4777
4778 if (GET_CODE (x) != CONST_INT
4779 || (unsigned HOST_WIDE_INT) INTVAL (x) >= (WORDS_BIG_ENDIAN
4780 ? 56
4781 : 64)
4782 || (INTVAL (x) & 7) != 0)
4783 output_operand_lossage ("invalid %%s value");
4784
4785 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4786 WORDS_BIG_ENDIAN
4787 ? (56 - INTVAL (x)) / 8
4788 : INTVAL (x) / 8);
4789 break;
4790
4791 case 'S':
4792 /* Same, except compute (64 - c) / 8 */
4793
4794 if (GET_CODE (x) != CONST_INT
4795 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
4796 && (INTVAL (x) & 7) != 8)
4797 output_operand_lossage ("invalid %%s value");
4798
4799 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
4800 break;
4801
4802 case 't':
4803 {
4804 /* On Unicos/Mk systems: use a DEX expression if the symbol
4805 clashes with a register name. */
4806 int dex = unicosmk_need_dex (x);
4807 if (dex)
4808 fprintf (file, "DEX(%d)", dex);
4809 else
4810 output_addr_const (file, x);
4811 }
4812 break;
4813
4814 case 'C': case 'D': case 'c': case 'd':
4815 /* Write out comparison name. */
4816 {
4817 enum rtx_code c = GET_CODE (x);
4818
4819 if (!COMPARISON_P (x))
4820 output_operand_lossage ("invalid %%C value");
4821
4822 else if (code == 'D')
4823 c = reverse_condition (c);
4824 else if (code == 'c')
4825 c = swap_condition (c);
4826 else if (code == 'd')
4827 c = swap_condition (reverse_condition (c));
4828
4829 if (c == LEU)
4830 fprintf (file, "ule");
4831 else if (c == LTU)
4832 fprintf (file, "ult");
4833 else if (c == UNORDERED)
4834 fprintf (file, "un");
4835 else
4836 fprintf (file, "%s", GET_RTX_NAME (c));
4837 }
4838 break;
4839
4840 case 'E':
4841 /* Write the divide or modulus operator. */
4842 switch (GET_CODE (x))
4843 {
4844 case DIV:
4845 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
4846 break;
4847 case UDIV:
4848 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
4849 break;
4850 case MOD:
4851 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
4852 break;
4853 case UMOD:
4854 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
4855 break;
4856 default:
4857 output_operand_lossage ("invalid %%E value");
4858 break;
4859 }
4860 break;
4861
4862 case 'A':
4863 /* Write "_u" for unaligned access. */
4864 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
4865 fprintf (file, "_u");
4866 break;
4867
4868 case 0:
4869 if (GET_CODE (x) == REG)
4870 fprintf (file, "%s", reg_names[REGNO (x)]);
4871 else if (GET_CODE (x) == MEM)
4872 output_address (XEXP (x, 0));
4873 else if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == UNSPEC)
4874 {
4875 switch (XINT (XEXP (x, 0), 1))
4876 {
4877 case UNSPEC_DTPREL:
4878 case UNSPEC_TPREL:
4879 output_addr_const (file, XVECEXP (XEXP (x, 0), 0, 0));
4880 break;
4881 default:
4882 output_operand_lossage ("unknown relocation unspec");
4883 break;
4884 }
4885 }
4886 else
4887 output_addr_const (file, x);
4888 break;
4889
4890 default:
4891 output_operand_lossage ("invalid %%xn code");
4892 }
4893 }
4894
4895 void
4896 print_operand_address (FILE *file, rtx addr)
4897 {
4898 int basereg = 31;
4899 HOST_WIDE_INT offset = 0;
4900
4901 if (GET_CODE (addr) == AND)
4902 addr = XEXP (addr, 0);
4903
4904 if (GET_CODE (addr) == PLUS
4905 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
4906 {
4907 offset = INTVAL (XEXP (addr, 1));
4908 addr = XEXP (addr, 0);
4909 }
4910
4911 if (GET_CODE (addr) == LO_SUM)
4912 {
4913 const char *reloc16, *reloclo;
4914 rtx op1 = XEXP (addr, 1);
4915
4916 if (GET_CODE (op1) == CONST && GET_CODE (XEXP (op1, 0)) == UNSPEC)
4917 {
4918 op1 = XEXP (op1, 0);
4919 switch (XINT (op1, 1))
4920 {
4921 case UNSPEC_DTPREL:
4922 reloc16 = NULL;
4923 reloclo = (alpha_tls_size == 16 ? "dtprel" : "dtprello");
4924 break;
4925 case UNSPEC_TPREL:
4926 reloc16 = NULL;
4927 reloclo = (alpha_tls_size == 16 ? "tprel" : "tprello");
4928 break;
4929 default:
4930 output_operand_lossage ("unknown relocation unspec");
4931 return;
4932 }
4933
4934 output_addr_const (file, XVECEXP (op1, 0, 0));
4935 }
4936 else
4937 {
4938 reloc16 = "gprel";
4939 reloclo = "gprellow";
4940 output_addr_const (file, op1);
4941 }
4942
4943 if (offset)
4944 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
4945
4946 addr = XEXP (addr, 0);
4947 if (GET_CODE (addr) == REG)
4948 basereg = REGNO (addr);
4949 else if (GET_CODE (addr) == SUBREG
4950 && GET_CODE (SUBREG_REG (addr)) == REG)
4951 basereg = subreg_regno (addr);
4952 else
4953 abort ();
4954
4955 fprintf (file, "($%d)\t\t!%s", basereg,
4956 (basereg == 29 ? reloc16 : reloclo));
4957 return;
4958 }
4959
4960 if (GET_CODE (addr) == REG)
4961 basereg = REGNO (addr);
4962 else if (GET_CODE (addr) == SUBREG
4963 && GET_CODE (SUBREG_REG (addr)) == REG)
4964 basereg = subreg_regno (addr);
4965 else if (GET_CODE (addr) == CONST_INT)
4966 offset = INTVAL (addr);
4967
4968 #if TARGET_ABI_OPEN_VMS
4969 else if (GET_CODE (addr) == SYMBOL_REF)
4970 {
4971 fprintf (file, "%s", XSTR (addr, 0));
4972 return;
4973 }
4974 else if (GET_CODE (addr) == CONST
4975 && GET_CODE (XEXP (addr, 0)) == PLUS
4976 && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF)
4977 {
4978 fprintf (file, "%s+" HOST_WIDE_INT_PRINT_DEC,
4979 XSTR (XEXP (XEXP (addr, 0), 0), 0),
4980 INTVAL (XEXP (XEXP (addr, 0), 1)));
4981 return;
4982 }
4983 #endif
4984
4985 else
4986 abort ();
4987
4988 fprintf (file, HOST_WIDE_INT_PRINT_DEC "($%d)", offset, basereg);
4989 }
4990 \f
4991 /* Emit RTL insns to initialize the variable parts of a trampoline at
4992 TRAMP. FNADDR is an RTX for the address of the function's pure
4993 code. CXT is an RTX for the static chain value for the function.
4994
4995 The three offset parameters are for the individual template's
4996 layout. A JMPOFS < 0 indicates that the trampoline does not
4997 contain instructions at all.
4998
4999 We assume here that a function will be called many more times than
5000 its address is taken (e.g., it might be passed to qsort), so we
5001 take the trouble to initialize the "hint" field in the JMP insn.
5002 Note that the hint field is PC (new) + 4 * bits 13:0. */
5003
5004 void
5005 alpha_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt,
5006 int fnofs, int cxtofs, int jmpofs)
5007 {
5008 rtx temp, temp1, addr;
5009 /* VMS really uses DImode pointers in memory at this point. */
5010 enum machine_mode mode = TARGET_ABI_OPEN_VMS ? Pmode : ptr_mode;
5011
5012 #ifdef POINTERS_EXTEND_UNSIGNED
5013 fnaddr = convert_memory_address (mode, fnaddr);
5014 cxt = convert_memory_address (mode, cxt);
5015 #endif
5016
5017 /* Store function address and CXT. */
5018 addr = memory_address (mode, plus_constant (tramp, fnofs));
5019 emit_move_insn (gen_rtx_MEM (mode, addr), fnaddr);
5020 addr = memory_address (mode, plus_constant (tramp, cxtofs));
5021 emit_move_insn (gen_rtx_MEM (mode, addr), cxt);
5022
5023 /* This has been disabled since the hint only has a 32k range, and in
5024 no existing OS is the stack within 32k of the text segment. */
5025 if (0 && jmpofs >= 0)
5026 {
5027 /* Compute hint value. */
5028 temp = force_operand (plus_constant (tramp, jmpofs+4), NULL_RTX);
5029 temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1,
5030 OPTAB_WIDEN);
5031 temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
5032 build_int_cst (NULL_TREE, 2), NULL_RTX, 1);
5033 temp = expand_and (SImode, gen_lowpart (SImode, temp),
5034 GEN_INT (0x3fff), 0);
5035
5036 /* Merge in the hint. */
5037 addr = memory_address (SImode, plus_constant (tramp, jmpofs));
5038 temp1 = force_reg (SImode, gen_rtx_MEM (SImode, addr));
5039 temp1 = expand_and (SImode, temp1, GEN_INT (0xffffc000), NULL_RTX);
5040 temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1,
5041 OPTAB_WIDEN);
5042 emit_move_insn (gen_rtx_MEM (SImode, addr), temp1);
5043 }
5044
5045 #ifdef ENABLE_EXECUTE_STACK
5046 emit_library_call (init_one_libfunc ("__enable_execute_stack"),
5047 0, VOIDmode, 1, tramp, Pmode);
5048 #endif
5049
5050 if (jmpofs >= 0)
5051 emit_insn (gen_imb ());
5052 }
5053 \f
5054 /* Determine where to put an argument to a function.
5055 Value is zero to push the argument on the stack,
5056 or a hard register in which to store the argument.
5057
5058 MODE is the argument's machine mode.
5059 TYPE is the data type of the argument (as a tree).
5060 This is null for libcalls where that information may
5061 not be available.
5062 CUM is a variable of type CUMULATIVE_ARGS which gives info about
5063 the preceding args and about the function being called.
5064 NAMED is nonzero if this argument is a named parameter
5065 (otherwise it is an extra parameter matching an ellipsis).
5066
5067 On Alpha the first 6 words of args are normally in registers
5068 and the rest are pushed. */
5069
5070 rtx
5071 function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode, tree type,
5072 int named ATTRIBUTE_UNUSED)
5073 {
5074 int basereg;
5075 int num_args;
5076
5077 /* Don't get confused and pass small structures in FP registers. */
5078 if (type && AGGREGATE_TYPE_P (type))
5079 basereg = 16;
5080 else
5081 {
5082 #ifdef ENABLE_CHECKING
5083 /* With alpha_split_complex_arg, we shouldn't see any raw complex
5084 values here. */
5085 if (COMPLEX_MODE_P (mode))
5086 abort ();
5087 #endif
5088
5089 /* Set up defaults for FP operands passed in FP registers, and
5090 integral operands passed in integer registers. */
5091 if (TARGET_FPREGS && GET_MODE_CLASS (mode) == MODE_FLOAT)
5092 basereg = 32 + 16;
5093 else
5094 basereg = 16;
5095 }
5096
5097 /* ??? Irritatingly, the definition of CUMULATIVE_ARGS is different for
5098 the three platforms, so we can't avoid conditional compilation. */
5099 #if TARGET_ABI_OPEN_VMS
5100 {
5101 if (mode == VOIDmode)
5102 return alpha_arg_info_reg_val (cum);
5103
5104 num_args = cum.num_args;
5105 if (num_args >= 6
5106 || targetm.calls.must_pass_in_stack (mode, type))
5107 return NULL_RTX;
5108 }
5109 #elif TARGET_ABI_UNICOSMK
5110 {
5111 int size;
5112
5113 /* If this is the last argument, generate the call info word (CIW). */
5114 /* ??? We don't include the caller's line number in the CIW because
5115 I don't know how to determine it if debug infos are turned off. */
5116 if (mode == VOIDmode)
5117 {
5118 int i;
5119 HOST_WIDE_INT lo;
5120 HOST_WIDE_INT hi;
5121 rtx ciw;
5122
5123 lo = 0;
5124
5125 for (i = 0; i < cum.num_reg_words && i < 5; i++)
5126 if (cum.reg_args_type[i])
5127 lo |= (1 << (7 - i));
5128
5129 if (cum.num_reg_words == 6 && cum.reg_args_type[5])
5130 lo |= 7;
5131 else
5132 lo |= cum.num_reg_words;
5133
5134 #if HOST_BITS_PER_WIDE_INT == 32
5135 hi = (cum.num_args << 20) | cum.num_arg_words;
5136 #else
5137 lo = lo | ((HOST_WIDE_INT) cum.num_args << 52)
5138 | ((HOST_WIDE_INT) cum.num_arg_words << 32);
5139 hi = 0;
5140 #endif
5141 ciw = immed_double_const (lo, hi, DImode);
5142
5143 return gen_rtx_UNSPEC (DImode, gen_rtvec (1, ciw),
5144 UNSPEC_UMK_LOAD_CIW);
5145 }
5146
5147 size = ALPHA_ARG_SIZE (mode, type, named);
5148 num_args = cum.num_reg_words;
5149 if (cum.force_stack
5150 || cum.num_reg_words + size > 6
5151 || targetm.calls.must_pass_in_stack (mode, type))
5152 return NULL_RTX;
5153 else if (type && TYPE_MODE (type) == BLKmode)
5154 {
5155 rtx reg1, reg2;
5156
5157 reg1 = gen_rtx_REG (DImode, num_args + 16);
5158 reg1 = gen_rtx_EXPR_LIST (DImode, reg1, const0_rtx);
5159
5160 /* The argument fits in two registers. Note that we still need to
5161 reserve a register for empty structures. */
5162 if (size == 0)
5163 return NULL_RTX;
5164 else if (size == 1)
5165 return gen_rtx_PARALLEL (mode, gen_rtvec (1, reg1));
5166 else
5167 {
5168 reg2 = gen_rtx_REG (DImode, num_args + 17);
5169 reg2 = gen_rtx_EXPR_LIST (DImode, reg2, GEN_INT (8));
5170 return gen_rtx_PARALLEL (mode, gen_rtvec (2, reg1, reg2));
5171 }
5172 }
5173 }
5174 #elif TARGET_ABI_OSF
5175 {
5176 if (cum >= 6)
5177 return NULL_RTX;
5178 num_args = cum;
5179
5180 /* VOID is passed as a special flag for "last argument". */
5181 if (type == void_type_node)
5182 basereg = 16;
5183 else if (targetm.calls.must_pass_in_stack (mode, type))
5184 return NULL_RTX;
5185 }
5186 #else
5187 #error Unhandled ABI
5188 #endif
5189
5190 return gen_rtx_REG (mode, num_args + basereg);
5191 }
5192
5193 static int
5194 alpha_arg_partial_bytes (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
5195 enum machine_mode mode ATTRIBUTE_UNUSED,
5196 tree type ATTRIBUTE_UNUSED,
5197 bool named ATTRIBUTE_UNUSED)
5198 {
5199 int words = 0;
5200
5201 #if TARGET_ABI_OPEN_VMS
5202 if (cum->num_args < 6
5203 && 6 < cum->num_args + ALPHA_ARG_SIZE (mode, type, named))
5204 words = 6 - (CUM).num_args;
5205 #elif TARGET_ABI_UNICOSMK
5206 /* Never any split arguments. */
5207 #elif TARGET_ABI_OSF
5208 if (*cum < 6 && 6 < *cum + ALPHA_ARG_SIZE (mode, type, named))
5209 words = 6 - *cum;
5210 #else
5211 #error Unhandled ABI
5212 #endif
5213
5214 return words * UNITS_PER_WORD;
5215 }
5216
5217
5218 /* Return true if TYPE must be returned in memory, instead of in registers. */
5219
5220 static bool
5221 alpha_return_in_memory (tree type, tree fndecl ATTRIBUTE_UNUSED)
5222 {
5223 enum machine_mode mode = VOIDmode;
5224 int size;
5225
5226 if (type)
5227 {
5228 mode = TYPE_MODE (type);
5229
5230 /* All aggregates are returned in memory. */
5231 if (AGGREGATE_TYPE_P (type))
5232 return true;
5233 }
5234
5235 size = GET_MODE_SIZE (mode);
5236 switch (GET_MODE_CLASS (mode))
5237 {
5238 case MODE_VECTOR_FLOAT:
5239 /* Pass all float vectors in memory, like an aggregate. */
5240 return true;
5241
5242 case MODE_COMPLEX_FLOAT:
5243 /* We judge complex floats on the size of their element,
5244 not the size of the whole type. */
5245 size = GET_MODE_UNIT_SIZE (mode);
5246 break;
5247
5248 case MODE_INT:
5249 case MODE_FLOAT:
5250 case MODE_COMPLEX_INT:
5251 case MODE_VECTOR_INT:
5252 break;
5253
5254 default:
5255 /* ??? We get called on all sorts of random stuff from
5256 aggregate_value_p. We can't abort, but it's not clear
5257 what's safe to return. Pretend it's a struct I guess. */
5258 return true;
5259 }
5260
5261 /* Otherwise types must fit in one register. */
5262 return size > UNITS_PER_WORD;
5263 }
5264
5265 /* Return true if TYPE should be passed by invisible reference. */
5266
5267 static bool
5268 alpha_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
5269 enum machine_mode mode,
5270 tree type ATTRIBUTE_UNUSED,
5271 bool named ATTRIBUTE_UNUSED)
5272 {
5273 return mode == TFmode || mode == TCmode;
5274 }
5275
5276 /* Define how to find the value returned by a function. VALTYPE is the
5277 data type of the value (as a tree). If the precise function being
5278 called is known, FUNC is its FUNCTION_DECL; otherwise, FUNC is 0.
5279 MODE is set instead of VALTYPE for libcalls.
5280
5281 On Alpha the value is found in $0 for integer functions and
5282 $f0 for floating-point functions. */
5283
5284 rtx
5285 function_value (tree valtype, tree func ATTRIBUTE_UNUSED,
5286 enum machine_mode mode)
5287 {
5288 unsigned int regnum, dummy;
5289 enum mode_class class;
5290
5291 #ifdef ENABLE_CHECKING
5292 if (valtype && alpha_return_in_memory (valtype, func))
5293 abort ();
5294 #endif
5295
5296 if (valtype)
5297 mode = TYPE_MODE (valtype);
5298
5299 class = GET_MODE_CLASS (mode);
5300 switch (class)
5301 {
5302 case MODE_INT:
5303 PROMOTE_MODE (mode, dummy, valtype);
5304 /* FALLTHRU */
5305
5306 case MODE_COMPLEX_INT:
5307 case MODE_VECTOR_INT:
5308 regnum = 0;
5309 break;
5310
5311 case MODE_FLOAT:
5312 regnum = 32;
5313 break;
5314
5315 case MODE_COMPLEX_FLOAT:
5316 {
5317 enum machine_mode cmode = GET_MODE_INNER (mode);
5318
5319 return gen_rtx_PARALLEL
5320 (VOIDmode,
5321 gen_rtvec (2,
5322 gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (cmode, 32),
5323 const0_rtx),
5324 gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (cmode, 33),
5325 GEN_INT (GET_MODE_SIZE (cmode)))));
5326 }
5327
5328 default:
5329 abort ();
5330 }
5331
5332 return gen_rtx_REG (mode, regnum);
5333 }
5334
5335 /* TCmode complex values are passed by invisible reference. We
5336 should not split these values. */
5337
5338 static bool
5339 alpha_split_complex_arg (tree type)
5340 {
5341 return TYPE_MODE (type) != TCmode;
5342 }
5343
5344 static tree
5345 alpha_build_builtin_va_list (void)
5346 {
5347 tree base, ofs, space, record, type_decl;
5348
5349 if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK)
5350 return ptr_type_node;
5351
5352 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
5353 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
5354 TREE_CHAIN (record) = type_decl;
5355 TYPE_NAME (record) = type_decl;
5356
5357 /* C++? SET_IS_AGGR_TYPE (record, 1); */
5358
5359 /* Dummy field to prevent alignment warnings. */
5360 space = build_decl (FIELD_DECL, NULL_TREE, integer_type_node);
5361 DECL_FIELD_CONTEXT (space) = record;
5362 DECL_ARTIFICIAL (space) = 1;
5363 DECL_IGNORED_P (space) = 1;
5364
5365 ofs = build_decl (FIELD_DECL, get_identifier ("__offset"),
5366 integer_type_node);
5367 DECL_FIELD_CONTEXT (ofs) = record;
5368 TREE_CHAIN (ofs) = space;
5369
5370 base = build_decl (FIELD_DECL, get_identifier ("__base"),
5371 ptr_type_node);
5372 DECL_FIELD_CONTEXT (base) = record;
5373 TREE_CHAIN (base) = ofs;
5374
5375 TYPE_FIELDS (record) = base;
5376 layout_type (record);
5377
5378 return record;
5379 }
5380
5381 /* Perform any needed actions needed for a function that is receiving a
5382 variable number of arguments. */
5383
5384 static void
5385 alpha_setup_incoming_varargs (CUMULATIVE_ARGS *pcum,
5386 enum machine_mode mode ATTRIBUTE_UNUSED,
5387 tree type ATTRIBUTE_UNUSED,
5388 int *pretend_size, int no_rtl)
5389 {
5390 #if TARGET_ABI_UNICOSMK
5391 /* On Unicos/Mk, the standard subroutine __T3E_MISMATCH stores all register
5392 arguments on the stack. Unfortunately, it doesn't always store the first
5393 one (i.e. the one that arrives in $16 or $f16). This is not a problem
5394 with stdargs as we always have at least one named argument there. */
5395 int num_reg_words = pcum->num_reg_words;
5396 if (num_reg_words < 6)
5397 {
5398 if (!no_rtl)
5399 {
5400 emit_insn (gen_umk_mismatch_args (GEN_INT (num_reg_words + 1)));
5401 emit_insn (gen_arg_home_umk ());
5402 }
5403 *pretend_size = 0;
5404 }
5405 #elif TARGET_ABI_OPEN_VMS
5406 /* For VMS, we allocate space for all 6 arg registers plus a count.
5407
5408 However, if NO registers need to be saved, don't allocate any space.
5409 This is not only because we won't need the space, but because AP
5410 includes the current_pretend_args_size and we don't want to mess up
5411 any ap-relative addresses already made. */
5412 if (pcum->num_args < 6)
5413 {
5414 if (!no_rtl)
5415 {
5416 emit_move_insn (gen_rtx_REG (DImode, 1), virtual_incoming_args_rtx);
5417 emit_insn (gen_arg_home ());
5418 }
5419 *pretend_size = 7 * UNITS_PER_WORD;
5420 }
5421 #else
5422 /* On OSF/1 and friends, we allocate space for all 12 arg registers, but
5423 only push those that are remaining. However, if NO registers need to
5424 be saved, don't allocate any space. This is not only because we won't
5425 need the space, but because AP includes the current_pretend_args_size
5426 and we don't want to mess up any ap-relative addresses already made.
5427
5428 If we are not to use the floating-point registers, save the integer
5429 registers where we would put the floating-point registers. This is
5430 not the most efficient way to implement varargs with just one register
5431 class, but it isn't worth doing anything more efficient in this rare
5432 case. */
5433 CUMULATIVE_ARGS cum = *pcum;
5434
5435 if (cum >= 6)
5436 return;
5437
5438 if (!no_rtl)
5439 {
5440 int set = get_varargs_alias_set ();
5441 rtx tmp;
5442
5443 tmp = gen_rtx_MEM (BLKmode,
5444 plus_constant (virtual_incoming_args_rtx,
5445 (cum + 6) * UNITS_PER_WORD));
5446 set_mem_alias_set (tmp, set);
5447 move_block_from_reg (16 + cum, tmp, 6 - cum);
5448
5449 tmp = gen_rtx_MEM (BLKmode,
5450 plus_constant (virtual_incoming_args_rtx,
5451 cum * UNITS_PER_WORD));
5452 set_mem_alias_set (tmp, set);
5453 move_block_from_reg (16 + (TARGET_FPREGS ? 32 : 0) + cum, tmp,
5454 6 - cum);
5455 }
5456 *pretend_size = 12 * UNITS_PER_WORD;
5457 #endif
5458 }
5459
5460 void
5461 alpha_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
5462 {
5463 HOST_WIDE_INT offset;
5464 tree t, offset_field, base_field;
5465
5466 if (TREE_CODE (TREE_TYPE (valist)) == ERROR_MARK)
5467 return;
5468
5469 if (TARGET_ABI_UNICOSMK)
5470 std_expand_builtin_va_start (valist, nextarg);
5471
5472 /* For Unix, TARGET_SETUP_INCOMING_VARARGS moves the starting address base
5473 up by 48, storing fp arg registers in the first 48 bytes, and the
5474 integer arg registers in the next 48 bytes. This is only done,
5475 however, if any integer registers need to be stored.
5476
5477 If no integer registers need be stored, then we must subtract 48
5478 in order to account for the integer arg registers which are counted
5479 in argsize above, but which are not actually stored on the stack.
5480 Must further be careful here about structures straddling the last
5481 integer argument register; that futzes with pretend_args_size,
5482 which changes the meaning of AP. */
5483
5484 if (NUM_ARGS <= 6)
5485 offset = TARGET_ABI_OPEN_VMS ? UNITS_PER_WORD : 6 * UNITS_PER_WORD;
5486 else
5487 offset = -6 * UNITS_PER_WORD + current_function_pretend_args_size;
5488
5489 if (TARGET_ABI_OPEN_VMS)
5490 {
5491 nextarg = plus_constant (nextarg, offset);
5492 nextarg = plus_constant (nextarg, NUM_ARGS * UNITS_PER_WORD);
5493 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
5494 make_tree (ptr_type_node, nextarg));
5495 TREE_SIDE_EFFECTS (t) = 1;
5496
5497 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5498 }
5499 else
5500 {
5501 base_field = TYPE_FIELDS (TREE_TYPE (valist));
5502 offset_field = TREE_CHAIN (base_field);
5503
5504 base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
5505 valist, base_field, NULL_TREE);
5506 offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
5507 valist, offset_field, NULL_TREE);
5508
5509 t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
5510 t = build (PLUS_EXPR, ptr_type_node, t,
5511 build_int_cst (NULL_TREE, offset));
5512 t = build (MODIFY_EXPR, TREE_TYPE (base_field), base_field, t);
5513 TREE_SIDE_EFFECTS (t) = 1;
5514 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5515
5516 t = build_int_cst (NULL_TREE, NUM_ARGS * UNITS_PER_WORD);
5517 t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field, t);
5518 TREE_SIDE_EFFECTS (t) = 1;
5519 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5520 }
5521 }
5522
5523 static tree
5524 alpha_gimplify_va_arg_1 (tree type, tree base, tree offset, tree *pre_p)
5525 {
5526 tree type_size, ptr_type, addend, t, addr, internal_post;
5527
5528 /* If the type could not be passed in registers, skip the block
5529 reserved for the registers. */
5530 if (targetm.calls.must_pass_in_stack (TYPE_MODE (type), type))
5531 {
5532 t = build_int_cst (TREE_TYPE (offset), 6*8);
5533 t = build (MODIFY_EXPR, TREE_TYPE (offset), offset,
5534 build (MAX_EXPR, TREE_TYPE (offset), offset, t));
5535 gimplify_and_add (t, pre_p);
5536 }
5537
5538 addend = offset;
5539 ptr_type = build_pointer_type (type);
5540
5541 if (TREE_CODE (type) == COMPLEX_TYPE)
5542 {
5543 tree real_part, imag_part, real_temp;
5544
5545 real_part = alpha_gimplify_va_arg_1 (TREE_TYPE (type), base,
5546 offset, pre_p);
5547
5548 /* Copy the value into a new temporary, lest the formal temporary
5549 be reused out from under us. */
5550 real_temp = get_initialized_tmp_var (real_part, pre_p, NULL);
5551
5552 imag_part = alpha_gimplify_va_arg_1 (TREE_TYPE (type), base,
5553 offset, pre_p);
5554
5555 return build (COMPLEX_EXPR, type, real_temp, imag_part);
5556 }
5557 else if (TREE_CODE (type) == REAL_TYPE)
5558 {
5559 tree fpaddend, cond, fourtyeight;
5560
5561 fourtyeight = build_int_cst (TREE_TYPE (addend), 6*8);
5562 fpaddend = fold (build (MINUS_EXPR, TREE_TYPE (addend),
5563 addend, fourtyeight));
5564 cond = fold (build (LT_EXPR, boolean_type_node, addend, fourtyeight));
5565 addend = fold (build (COND_EXPR, TREE_TYPE (addend), cond,
5566 fpaddend, addend));
5567 }
5568
5569 /* Build the final address and force that value into a temporary. */
5570 addr = build (PLUS_EXPR, ptr_type, fold_convert (ptr_type, base),
5571 fold_convert (ptr_type, addend));
5572 internal_post = NULL;
5573 gimplify_expr (&addr, pre_p, &internal_post, is_gimple_val, fb_rvalue);
5574 append_to_statement_list (internal_post, pre_p);
5575
5576 /* Update the offset field. */
5577 type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type));
5578 if (type_size == NULL || TREE_OVERFLOW (type_size))
5579 t = size_zero_node;
5580 else
5581 {
5582 t = size_binop (PLUS_EXPR, type_size, size_int (7));
5583 t = size_binop (TRUNC_DIV_EXPR, t, size_int (8));
5584 t = size_binop (MULT_EXPR, t, size_int (8));
5585 }
5586 t = fold_convert (TREE_TYPE (offset), t);
5587 t = build (MODIFY_EXPR, void_type_node, offset,
5588 build (PLUS_EXPR, TREE_TYPE (offset), offset, t));
5589 gimplify_and_add (t, pre_p);
5590
5591 return build_fold_indirect_ref (addr);
5592 }
5593
5594 static tree
5595 alpha_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
5596 {
5597 tree offset_field, base_field, offset, base, t, r;
5598 bool indirect;
5599
5600 if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK)
5601 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
5602
5603 base_field = TYPE_FIELDS (va_list_type_node);
5604 offset_field = TREE_CHAIN (base_field);
5605 base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
5606 valist, base_field, NULL_TREE);
5607 offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
5608 valist, offset_field, NULL_TREE);
5609
5610 /* Pull the fields of the structure out into temporaries. Since we never
5611 modify the base field, we can use a formal temporary. Sign-extend the
5612 offset field so that it's the proper width for pointer arithmetic. */
5613 base = get_formal_tmp_var (base_field, pre_p);
5614
5615 t = fold_convert (lang_hooks.types.type_for_size (64, 0), offset_field);
5616 offset = get_initialized_tmp_var (t, pre_p, NULL);
5617
5618 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
5619 if (indirect)
5620 type = build_pointer_type (type);
5621
5622 /* Find the value. Note that this will be a stable indirection, or
5623 a composite of stable indirections in the case of complex. */
5624 r = alpha_gimplify_va_arg_1 (type, base, offset, pre_p);
5625
5626 /* Stuff the offset temporary back into its field. */
5627 t = build (MODIFY_EXPR, void_type_node, offset_field,
5628 fold_convert (TREE_TYPE (offset_field), offset));
5629 gimplify_and_add (t, pre_p);
5630
5631 if (indirect)
5632 r = build_fold_indirect_ref (r);
5633
5634 return r;
5635 }
5636 \f
5637 /* Builtins. */
5638
5639 enum alpha_builtin
5640 {
5641 ALPHA_BUILTIN_CMPBGE,
5642 ALPHA_BUILTIN_EXTBL,
5643 ALPHA_BUILTIN_EXTWL,
5644 ALPHA_BUILTIN_EXTLL,
5645 ALPHA_BUILTIN_EXTQL,
5646 ALPHA_BUILTIN_EXTWH,
5647 ALPHA_BUILTIN_EXTLH,
5648 ALPHA_BUILTIN_EXTQH,
5649 ALPHA_BUILTIN_INSBL,
5650 ALPHA_BUILTIN_INSWL,
5651 ALPHA_BUILTIN_INSLL,
5652 ALPHA_BUILTIN_INSQL,
5653 ALPHA_BUILTIN_INSWH,
5654 ALPHA_BUILTIN_INSLH,
5655 ALPHA_BUILTIN_INSQH,
5656 ALPHA_BUILTIN_MSKBL,
5657 ALPHA_BUILTIN_MSKWL,
5658 ALPHA_BUILTIN_MSKLL,
5659 ALPHA_BUILTIN_MSKQL,
5660 ALPHA_BUILTIN_MSKWH,
5661 ALPHA_BUILTIN_MSKLH,
5662 ALPHA_BUILTIN_MSKQH,
5663 ALPHA_BUILTIN_UMULH,
5664 ALPHA_BUILTIN_ZAP,
5665 ALPHA_BUILTIN_ZAPNOT,
5666 ALPHA_BUILTIN_AMASK,
5667 ALPHA_BUILTIN_IMPLVER,
5668 ALPHA_BUILTIN_RPCC,
5669 ALPHA_BUILTIN_THREAD_POINTER,
5670 ALPHA_BUILTIN_SET_THREAD_POINTER,
5671
5672 /* TARGET_MAX */
5673 ALPHA_BUILTIN_MINUB8,
5674 ALPHA_BUILTIN_MINSB8,
5675 ALPHA_BUILTIN_MINUW4,
5676 ALPHA_BUILTIN_MINSW4,
5677 ALPHA_BUILTIN_MAXUB8,
5678 ALPHA_BUILTIN_MAXSB8,
5679 ALPHA_BUILTIN_MAXUW4,
5680 ALPHA_BUILTIN_MAXSW4,
5681 ALPHA_BUILTIN_PERR,
5682 ALPHA_BUILTIN_PKLB,
5683 ALPHA_BUILTIN_PKWB,
5684 ALPHA_BUILTIN_UNPKBL,
5685 ALPHA_BUILTIN_UNPKBW,
5686
5687 /* TARGET_CIX */
5688 ALPHA_BUILTIN_CTTZ,
5689 ALPHA_BUILTIN_CTLZ,
5690 ALPHA_BUILTIN_CTPOP,
5691
5692 ALPHA_BUILTIN_max
5693 };
5694
5695 static unsigned int const code_for_builtin[ALPHA_BUILTIN_max] = {
5696 CODE_FOR_builtin_cmpbge,
5697 CODE_FOR_builtin_extbl,
5698 CODE_FOR_builtin_extwl,
5699 CODE_FOR_builtin_extll,
5700 CODE_FOR_builtin_extql,
5701 CODE_FOR_builtin_extwh,
5702 CODE_FOR_builtin_extlh,
5703 CODE_FOR_builtin_extqh,
5704 CODE_FOR_builtin_insbl,
5705 CODE_FOR_builtin_inswl,
5706 CODE_FOR_builtin_insll,
5707 CODE_FOR_builtin_insql,
5708 CODE_FOR_builtin_inswh,
5709 CODE_FOR_builtin_inslh,
5710 CODE_FOR_builtin_insqh,
5711 CODE_FOR_builtin_mskbl,
5712 CODE_FOR_builtin_mskwl,
5713 CODE_FOR_builtin_mskll,
5714 CODE_FOR_builtin_mskql,
5715 CODE_FOR_builtin_mskwh,
5716 CODE_FOR_builtin_msklh,
5717 CODE_FOR_builtin_mskqh,
5718 CODE_FOR_umuldi3_highpart,
5719 CODE_FOR_builtin_zap,
5720 CODE_FOR_builtin_zapnot,
5721 CODE_FOR_builtin_amask,
5722 CODE_FOR_builtin_implver,
5723 CODE_FOR_builtin_rpcc,
5724 CODE_FOR_load_tp,
5725 CODE_FOR_set_tp,
5726
5727 /* TARGET_MAX */
5728 CODE_FOR_builtin_minub8,
5729 CODE_FOR_builtin_minsb8,
5730 CODE_FOR_builtin_minuw4,
5731 CODE_FOR_builtin_minsw4,
5732 CODE_FOR_builtin_maxub8,
5733 CODE_FOR_builtin_maxsb8,
5734 CODE_FOR_builtin_maxuw4,
5735 CODE_FOR_builtin_maxsw4,
5736 CODE_FOR_builtin_perr,
5737 CODE_FOR_builtin_pklb,
5738 CODE_FOR_builtin_pkwb,
5739 CODE_FOR_builtin_unpkbl,
5740 CODE_FOR_builtin_unpkbw,
5741
5742 /* TARGET_CIX */
5743 CODE_FOR_builtin_cttz,
5744 CODE_FOR_builtin_ctlz,
5745 CODE_FOR_builtin_ctpop
5746 };
5747
5748 struct alpha_builtin_def
5749 {
5750 const char *name;
5751 enum alpha_builtin code;
5752 unsigned int target_mask;
5753 };
5754
5755 static struct alpha_builtin_def const zero_arg_builtins[] = {
5756 { "__builtin_alpha_implver", ALPHA_BUILTIN_IMPLVER, 0 },
5757 { "__builtin_alpha_rpcc", ALPHA_BUILTIN_RPCC, 0 }
5758 };
5759
5760 static struct alpha_builtin_def const one_arg_builtins[] = {
5761 { "__builtin_alpha_amask", ALPHA_BUILTIN_AMASK, 0 },
5762 { "__builtin_alpha_pklb", ALPHA_BUILTIN_PKLB, MASK_MAX },
5763 { "__builtin_alpha_pkwb", ALPHA_BUILTIN_PKWB, MASK_MAX },
5764 { "__builtin_alpha_unpkbl", ALPHA_BUILTIN_UNPKBL, MASK_MAX },
5765 { "__builtin_alpha_unpkbw", ALPHA_BUILTIN_UNPKBW, MASK_MAX },
5766 { "__builtin_alpha_cttz", ALPHA_BUILTIN_CTTZ, MASK_CIX },
5767 { "__builtin_alpha_ctlz", ALPHA_BUILTIN_CTLZ, MASK_CIX },
5768 { "__builtin_alpha_ctpop", ALPHA_BUILTIN_CTPOP, MASK_CIX }
5769 };
5770
5771 static struct alpha_builtin_def const two_arg_builtins[] = {
5772 { "__builtin_alpha_cmpbge", ALPHA_BUILTIN_CMPBGE, 0 },
5773 { "__builtin_alpha_extbl", ALPHA_BUILTIN_EXTBL, 0 },
5774 { "__builtin_alpha_extwl", ALPHA_BUILTIN_EXTWL, 0 },
5775 { "__builtin_alpha_extll", ALPHA_BUILTIN_EXTLL, 0 },
5776 { "__builtin_alpha_extql", ALPHA_BUILTIN_EXTQL, 0 },
5777 { "__builtin_alpha_extwh", ALPHA_BUILTIN_EXTWH, 0 },
5778 { "__builtin_alpha_extlh", ALPHA_BUILTIN_EXTLH, 0 },
5779 { "__builtin_alpha_extqh", ALPHA_BUILTIN_EXTQH, 0 },
5780 { "__builtin_alpha_insbl", ALPHA_BUILTIN_INSBL, 0 },
5781 { "__builtin_alpha_inswl", ALPHA_BUILTIN_INSWL, 0 },
5782 { "__builtin_alpha_insll", ALPHA_BUILTIN_INSLL, 0 },
5783 { "__builtin_alpha_insql", ALPHA_BUILTIN_INSQL, 0 },
5784 { "__builtin_alpha_inswh", ALPHA_BUILTIN_INSWH, 0 },
5785 { "__builtin_alpha_inslh", ALPHA_BUILTIN_INSLH, 0 },
5786 { "__builtin_alpha_insqh", ALPHA_BUILTIN_INSQH, 0 },
5787 { "__builtin_alpha_mskbl", ALPHA_BUILTIN_MSKBL, 0 },
5788 { "__builtin_alpha_mskwl", ALPHA_BUILTIN_MSKWL, 0 },
5789 { "__builtin_alpha_mskll", ALPHA_BUILTIN_MSKLL, 0 },
5790 { "__builtin_alpha_mskql", ALPHA_BUILTIN_MSKQL, 0 },
5791 { "__builtin_alpha_mskwh", ALPHA_BUILTIN_MSKWH, 0 },
5792 { "__builtin_alpha_msklh", ALPHA_BUILTIN_MSKLH, 0 },
5793 { "__builtin_alpha_mskqh", ALPHA_BUILTIN_MSKQH, 0 },
5794 { "__builtin_alpha_umulh", ALPHA_BUILTIN_UMULH, 0 },
5795 { "__builtin_alpha_zap", ALPHA_BUILTIN_ZAP, 0 },
5796 { "__builtin_alpha_zapnot", ALPHA_BUILTIN_ZAPNOT, 0 },
5797 { "__builtin_alpha_minub8", ALPHA_BUILTIN_MINUB8, MASK_MAX },
5798 { "__builtin_alpha_minsb8", ALPHA_BUILTIN_MINSB8, MASK_MAX },
5799 { "__builtin_alpha_minuw4", ALPHA_BUILTIN_MINUW4, MASK_MAX },
5800 { "__builtin_alpha_minsw4", ALPHA_BUILTIN_MINSW4, MASK_MAX },
5801 { "__builtin_alpha_maxub8", ALPHA_BUILTIN_MAXUB8, MASK_MAX },
5802 { "__builtin_alpha_maxsb8", ALPHA_BUILTIN_MAXSB8, MASK_MAX },
5803 { "__builtin_alpha_maxuw4", ALPHA_BUILTIN_MAXUW4, MASK_MAX },
5804 { "__builtin_alpha_maxsw4", ALPHA_BUILTIN_MAXSW4, MASK_MAX },
5805 { "__builtin_alpha_perr", ALPHA_BUILTIN_PERR, MASK_MAX }
5806 };
5807
5808 static void
5809 alpha_init_builtins (void)
5810 {
5811 const struct alpha_builtin_def *p;
5812 tree ftype;
5813 size_t i;
5814
5815 ftype = build_function_type (long_integer_type_node, void_list_node);
5816
5817 p = zero_arg_builtins;
5818 for (i = 0; i < ARRAY_SIZE (zero_arg_builtins); ++i, ++p)
5819 if ((target_flags & p->target_mask) == p->target_mask)
5820 lang_hooks.builtin_function (p->name, ftype, p->code, BUILT_IN_MD,
5821 NULL, NULL_TREE);
5822
5823 ftype = build_function_type_list (long_integer_type_node,
5824 long_integer_type_node, NULL_TREE);
5825
5826 p = one_arg_builtins;
5827 for (i = 0; i < ARRAY_SIZE (one_arg_builtins); ++i, ++p)
5828 if ((target_flags & p->target_mask) == p->target_mask)
5829 lang_hooks.builtin_function (p->name, ftype, p->code, BUILT_IN_MD,
5830 NULL, NULL_TREE);
5831
5832 ftype = build_function_type_list (long_integer_type_node,
5833 long_integer_type_node,
5834 long_integer_type_node, NULL_TREE);
5835
5836 p = two_arg_builtins;
5837 for (i = 0; i < ARRAY_SIZE (two_arg_builtins); ++i, ++p)
5838 if ((target_flags & p->target_mask) == p->target_mask)
5839 lang_hooks.builtin_function (p->name, ftype, p->code, BUILT_IN_MD,
5840 NULL, NULL_TREE);
5841
5842 ftype = build_function_type (ptr_type_node, void_list_node);
5843 lang_hooks.builtin_function ("__builtin_thread_pointer", ftype,
5844 ALPHA_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
5845 NULL, NULL_TREE);
5846
5847 ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
5848 lang_hooks.builtin_function ("__builtin_set_thread_pointer", ftype,
5849 ALPHA_BUILTIN_SET_THREAD_POINTER, BUILT_IN_MD,
5850 NULL, NULL_TREE);
5851 }
5852
5853 /* Expand an expression EXP that calls a built-in function,
5854 with result going to TARGET if that's convenient
5855 (and in mode MODE if that's convenient).
5856 SUBTARGET may be used as the target for computing one of EXP's operands.
5857 IGNORE is nonzero if the value is to be ignored. */
5858
5859 static rtx
5860 alpha_expand_builtin (tree exp, rtx target,
5861 rtx subtarget ATTRIBUTE_UNUSED,
5862 enum machine_mode mode ATTRIBUTE_UNUSED,
5863 int ignore ATTRIBUTE_UNUSED)
5864 {
5865 #define MAX_ARGS 2
5866
5867 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
5868 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
5869 tree arglist = TREE_OPERAND (exp, 1);
5870 enum insn_code icode;
5871 rtx op[MAX_ARGS], pat;
5872 int arity;
5873 bool nonvoid;
5874
5875 if (fcode >= ALPHA_BUILTIN_max)
5876 internal_error ("bad builtin fcode");
5877 icode = code_for_builtin[fcode];
5878 if (icode == 0)
5879 internal_error ("bad builtin fcode");
5880
5881 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
5882
5883 for (arglist = TREE_OPERAND (exp, 1), arity = 0;
5884 arglist;
5885 arglist = TREE_CHAIN (arglist), arity++)
5886 {
5887 const struct insn_operand_data *insn_op;
5888
5889 tree arg = TREE_VALUE (arglist);
5890 if (arg == error_mark_node)
5891 return NULL_RTX;
5892 if (arity > MAX_ARGS)
5893 return NULL_RTX;
5894
5895 insn_op = &insn_data[icode].operand[arity + nonvoid];
5896
5897 op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, 0);
5898
5899 if (!(*insn_op->predicate) (op[arity], insn_op->mode))
5900 op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
5901 }
5902
5903 if (nonvoid)
5904 {
5905 enum machine_mode tmode = insn_data[icode].operand[0].mode;
5906 if (!target
5907 || GET_MODE (target) != tmode
5908 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
5909 target = gen_reg_rtx (tmode);
5910 }
5911
5912 switch (arity)
5913 {
5914 case 0:
5915 pat = GEN_FCN (icode) (target);
5916 break;
5917 case 1:
5918 if (nonvoid)
5919 pat = GEN_FCN (icode) (target, op[0]);
5920 else
5921 pat = GEN_FCN (icode) (op[0]);
5922 break;
5923 case 2:
5924 pat = GEN_FCN (icode) (target, op[0], op[1]);
5925 break;
5926 default:
5927 abort ();
5928 }
5929 if (!pat)
5930 return NULL_RTX;
5931 emit_insn (pat);
5932
5933 if (nonvoid)
5934 return target;
5935 else
5936 return const0_rtx;
5937 }
5938 \f
5939 /* This page contains routines that are used to determine what the function
5940 prologue and epilogue code will do and write them out. */
5941
5942 /* Compute the size of the save area in the stack. */
5943
5944 /* These variables are used for communication between the following functions.
5945 They indicate various things about the current function being compiled
5946 that are used to tell what kind of prologue, epilogue and procedure
5947 descriptor to generate. */
5948
5949 /* Nonzero if we need a stack procedure. */
5950 enum alpha_procedure_types {PT_NULL = 0, PT_REGISTER = 1, PT_STACK = 2};
5951 static enum alpha_procedure_types alpha_procedure_type;
5952
5953 /* Register number (either FP or SP) that is used to unwind the frame. */
5954 static int vms_unwind_regno;
5955
5956 /* Register number used to save FP. We need not have one for RA since
5957 we don't modify it for register procedures. This is only defined
5958 for register frame procedures. */
5959 static int vms_save_fp_regno;
5960
5961 /* Register number used to reference objects off our PV. */
5962 static int vms_base_regno;
5963
5964 /* Compute register masks for saved registers. */
5965
5966 static void
5967 alpha_sa_mask (unsigned long *imaskP, unsigned long *fmaskP)
5968 {
5969 unsigned long imask = 0;
5970 unsigned long fmask = 0;
5971 unsigned int i;
5972
5973 /* When outputting a thunk, we don't have valid register life info,
5974 but assemble_start_function wants to output .frame and .mask
5975 directives. */
5976 if (current_function_is_thunk)
5977 {
5978 *imaskP = 0;
5979 *fmaskP = 0;
5980 return;
5981 }
5982
5983 if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
5984 imask |= (1UL << HARD_FRAME_POINTER_REGNUM);
5985
5986 /* One for every register we have to save. */
5987 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
5988 if (! fixed_regs[i] && ! call_used_regs[i]
5989 && regs_ever_live[i] && i != REG_RA
5990 && (!TARGET_ABI_UNICOSMK || i != HARD_FRAME_POINTER_REGNUM))
5991 {
5992 if (i < 32)
5993 imask |= (1UL << i);
5994 else
5995 fmask |= (1UL << (i - 32));
5996 }
5997
5998 /* We need to restore these for the handler. */
5999 if (current_function_calls_eh_return)
6000 {
6001 for (i = 0; ; ++i)
6002 {
6003 unsigned regno = EH_RETURN_DATA_REGNO (i);
6004 if (regno == INVALID_REGNUM)
6005 break;
6006 imask |= 1UL << regno;
6007 }
6008 }
6009
6010 /* If any register spilled, then spill the return address also. */
6011 /* ??? This is required by the Digital stack unwind specification
6012 and isn't needed if we're doing Dwarf2 unwinding. */
6013 if (imask || fmask || alpha_ra_ever_killed ())
6014 imask |= (1UL << REG_RA);
6015
6016 *imaskP = imask;
6017 *fmaskP = fmask;
6018 }
6019
6020 int
6021 alpha_sa_size (void)
6022 {
6023 unsigned long mask[2];
6024 int sa_size = 0;
6025 int i, j;
6026
6027 alpha_sa_mask (&mask[0], &mask[1]);
6028
6029 if (TARGET_ABI_UNICOSMK)
6030 {
6031 if (mask[0] || mask[1])
6032 sa_size = 14;
6033 }
6034 else
6035 {
6036 for (j = 0; j < 2; ++j)
6037 for (i = 0; i < 32; ++i)
6038 if ((mask[j] >> i) & 1)
6039 sa_size++;
6040 }
6041
6042 if (TARGET_ABI_UNICOSMK)
6043 {
6044 /* We might not need to generate a frame if we don't make any calls
6045 (including calls to __T3E_MISMATCH if this is a vararg function),
6046 don't have any local variables which require stack slots, don't
6047 use alloca and have not determined that we need a frame for other
6048 reasons. */
6049
6050 alpha_procedure_type
6051 = (sa_size || get_frame_size() != 0
6052 || current_function_outgoing_args_size
6053 || current_function_stdarg || current_function_calls_alloca
6054 || frame_pointer_needed)
6055 ? PT_STACK : PT_REGISTER;
6056
6057 /* Always reserve space for saving callee-saved registers if we
6058 need a frame as required by the calling convention. */
6059 if (alpha_procedure_type == PT_STACK)
6060 sa_size = 14;
6061 }
6062 else if (TARGET_ABI_OPEN_VMS)
6063 {
6064 /* Start by assuming we can use a register procedure if we don't
6065 make any calls (REG_RA not used) or need to save any
6066 registers and a stack procedure if we do. */
6067 if ((mask[0] >> REG_RA) & 1)
6068 alpha_procedure_type = PT_STACK;
6069 else if (get_frame_size() != 0)
6070 alpha_procedure_type = PT_REGISTER;
6071 else
6072 alpha_procedure_type = PT_NULL;
6073
6074 /* Don't reserve space for saving FP & RA yet. Do that later after we've
6075 made the final decision on stack procedure vs register procedure. */
6076 if (alpha_procedure_type == PT_STACK)
6077 sa_size -= 2;
6078
6079 /* Decide whether to refer to objects off our PV via FP or PV.
6080 If we need FP for something else or if we receive a nonlocal
6081 goto (which expects PV to contain the value), we must use PV.
6082 Otherwise, start by assuming we can use FP. */
6083
6084 vms_base_regno
6085 = (frame_pointer_needed
6086 || current_function_has_nonlocal_label
6087 || alpha_procedure_type == PT_STACK
6088 || current_function_outgoing_args_size)
6089 ? REG_PV : HARD_FRAME_POINTER_REGNUM;
6090
6091 /* If we want to copy PV into FP, we need to find some register
6092 in which to save FP. */
6093
6094 vms_save_fp_regno = -1;
6095 if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
6096 for (i = 0; i < 32; i++)
6097 if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
6098 vms_save_fp_regno = i;
6099
6100 if (vms_save_fp_regno == -1 && alpha_procedure_type == PT_REGISTER)
6101 vms_base_regno = REG_PV, alpha_procedure_type = PT_STACK;
6102 else if (alpha_procedure_type == PT_NULL)
6103 vms_base_regno = REG_PV;
6104
6105 /* Stack unwinding should be done via FP unless we use it for PV. */
6106 vms_unwind_regno = (vms_base_regno == REG_PV
6107 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
6108
6109 /* If this is a stack procedure, allow space for saving FP and RA. */
6110 if (alpha_procedure_type == PT_STACK)
6111 sa_size += 2;
6112 }
6113 else
6114 {
6115 /* Our size must be even (multiple of 16 bytes). */
6116 if (sa_size & 1)
6117 sa_size++;
6118 }
6119
6120 return sa_size * 8;
6121 }
6122
6123 /* Define the offset between two registers, one to be eliminated,
6124 and the other its replacement, at the start of a routine. */
6125
6126 HOST_WIDE_INT
6127 alpha_initial_elimination_offset (unsigned int from,
6128 unsigned int to ATTRIBUTE_UNUSED)
6129 {
6130 HOST_WIDE_INT ret;
6131
6132 ret = alpha_sa_size ();
6133 ret += ALPHA_ROUND (current_function_outgoing_args_size);
6134
6135 if (from == FRAME_POINTER_REGNUM)
6136 ;
6137 else if (from == ARG_POINTER_REGNUM)
6138 ret += (ALPHA_ROUND (get_frame_size ()
6139 + current_function_pretend_args_size)
6140 - current_function_pretend_args_size);
6141 else
6142 abort ();
6143
6144 return ret;
6145 }
6146
6147 int
6148 alpha_pv_save_size (void)
6149 {
6150 alpha_sa_size ();
6151 return alpha_procedure_type == PT_STACK ? 8 : 0;
6152 }
6153
6154 int
6155 alpha_using_fp (void)
6156 {
6157 alpha_sa_size ();
6158 return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM;
6159 }
6160
6161 #if TARGET_ABI_OPEN_VMS
6162
6163 const struct attribute_spec vms_attribute_table[] =
6164 {
6165 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
6166 { "overlaid", 0, 0, true, false, false, NULL },
6167 { "global", 0, 0, true, false, false, NULL },
6168 { "initialize", 0, 0, true, false, false, NULL },
6169 { NULL, 0, 0, false, false, false, NULL }
6170 };
6171
6172 #endif
6173
6174 static int
6175 find_lo_sum_using_gp (rtx *px, void *data ATTRIBUTE_UNUSED)
6176 {
6177 return GET_CODE (*px) == LO_SUM && XEXP (*px, 0) == pic_offset_table_rtx;
6178 }
6179
6180 int
6181 alpha_find_lo_sum_using_gp (rtx insn)
6182 {
6183 return for_each_rtx (&PATTERN (insn), find_lo_sum_using_gp, NULL) > 0;
6184 }
6185
6186 static int
6187 alpha_does_function_need_gp (void)
6188 {
6189 rtx insn;
6190
6191 /* The GP being variable is an OSF abi thing. */
6192 if (! TARGET_ABI_OSF)
6193 return 0;
6194
6195 /* We need the gp to load the address of __mcount. */
6196 if (TARGET_PROFILING_NEEDS_GP && current_function_profile)
6197 return 1;
6198
6199 /* The code emitted by alpha_output_mi_thunk_osf uses the gp. */
6200 if (current_function_is_thunk)
6201 return 1;
6202
6203 /* The nonlocal receiver pattern assumes that the gp is valid for
6204 the nested function. Reasonable because it's almost always set
6205 correctly already. For the cases where that's wrong, make sure
6206 the nested function loads its gp on entry. */
6207 if (current_function_has_nonlocal_goto)
6208 return 1;
6209
6210 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
6211 Even if we are a static function, we still need to do this in case
6212 our address is taken and passed to something like qsort. */
6213
6214 push_topmost_sequence ();
6215 insn = get_insns ();
6216 pop_topmost_sequence ();
6217
6218 for (; insn; insn = NEXT_INSN (insn))
6219 if (INSN_P (insn)
6220 && GET_CODE (PATTERN (insn)) != USE
6221 && GET_CODE (PATTERN (insn)) != CLOBBER
6222 && get_attr_usegp (insn))
6223 return 1;
6224
6225 return 0;
6226 }
6227
6228 \f
6229 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
6230 sequences. */
6231
6232 static rtx
6233 set_frame_related_p (void)
6234 {
6235 rtx seq = get_insns ();
6236 rtx insn;
6237
6238 end_sequence ();
6239
6240 if (!seq)
6241 return NULL_RTX;
6242
6243 if (INSN_P (seq))
6244 {
6245 insn = seq;
6246 while (insn != NULL_RTX)
6247 {
6248 RTX_FRAME_RELATED_P (insn) = 1;
6249 insn = NEXT_INSN (insn);
6250 }
6251 seq = emit_insn (seq);
6252 }
6253 else
6254 {
6255 seq = emit_insn (seq);
6256 RTX_FRAME_RELATED_P (seq) = 1;
6257 }
6258 return seq;
6259 }
6260
6261 #define FRP(exp) (start_sequence (), exp, set_frame_related_p ())
6262
6263 /* Generates a store with the proper unwind info attached. VALUE is
6264 stored at BASE_REG+BASE_OFS. If FRAME_BIAS is nonzero, then BASE_REG
6265 contains SP+FRAME_BIAS, and that is the unwind info that should be
6266 generated. If FRAME_REG != VALUE, then VALUE is being stored on
6267 behalf of FRAME_REG, and FRAME_REG should be present in the unwind. */
6268
6269 static void
6270 emit_frame_store_1 (rtx value, rtx base_reg, HOST_WIDE_INT frame_bias,
6271 HOST_WIDE_INT base_ofs, rtx frame_reg)
6272 {
6273 rtx addr, mem, insn;
6274
6275 addr = plus_constant (base_reg, base_ofs);
6276 mem = gen_rtx_MEM (DImode, addr);
6277 set_mem_alias_set (mem, alpha_sr_alias_set);
6278
6279 insn = emit_move_insn (mem, value);
6280 RTX_FRAME_RELATED_P (insn) = 1;
6281
6282 if (frame_bias || value != frame_reg)
6283 {
6284 if (frame_bias)
6285 {
6286 addr = plus_constant (stack_pointer_rtx, frame_bias + base_ofs);
6287 mem = gen_rtx_MEM (DImode, addr);
6288 }
6289
6290 REG_NOTES (insn)
6291 = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
6292 gen_rtx_SET (VOIDmode, mem, frame_reg),
6293 REG_NOTES (insn));
6294 }
6295 }
6296
6297 static void
6298 emit_frame_store (unsigned int regno, rtx base_reg,
6299 HOST_WIDE_INT frame_bias, HOST_WIDE_INT base_ofs)
6300 {
6301 rtx reg = gen_rtx_REG (DImode, regno);
6302 emit_frame_store_1 (reg, base_reg, frame_bias, base_ofs, reg);
6303 }
6304
6305 /* Write function prologue. */
6306
6307 /* On vms we have two kinds of functions:
6308
6309 - stack frame (PROC_STACK)
6310 these are 'normal' functions with local vars and which are
6311 calling other functions
6312 - register frame (PROC_REGISTER)
6313 keeps all data in registers, needs no stack
6314
6315 We must pass this to the assembler so it can generate the
6316 proper pdsc (procedure descriptor)
6317 This is done with the '.pdesc' command.
6318
6319 On not-vms, we don't really differentiate between the two, as we can
6320 simply allocate stack without saving registers. */
6321
6322 void
6323 alpha_expand_prologue (void)
6324 {
6325 /* Registers to save. */
6326 unsigned long imask = 0;
6327 unsigned long fmask = 0;
6328 /* Stack space needed for pushing registers clobbered by us. */
6329 HOST_WIDE_INT sa_size;
6330 /* Complete stack size needed. */
6331 HOST_WIDE_INT frame_size;
6332 /* Offset from base reg to register save area. */
6333 HOST_WIDE_INT reg_offset;
6334 rtx sa_reg;
6335 int i;
6336
6337 sa_size = alpha_sa_size ();
6338
6339 frame_size = get_frame_size ();
6340 if (TARGET_ABI_OPEN_VMS)
6341 frame_size = ALPHA_ROUND (sa_size
6342 + (alpha_procedure_type == PT_STACK ? 8 : 0)
6343 + frame_size
6344 + current_function_pretend_args_size);
6345 else if (TARGET_ABI_UNICOSMK)
6346 /* We have to allocate space for the DSIB if we generate a frame. */
6347 frame_size = ALPHA_ROUND (sa_size
6348 + (alpha_procedure_type == PT_STACK ? 48 : 0))
6349 + ALPHA_ROUND (frame_size
6350 + current_function_outgoing_args_size);
6351 else
6352 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
6353 + sa_size
6354 + ALPHA_ROUND (frame_size
6355 + current_function_pretend_args_size));
6356
6357 if (TARGET_ABI_OPEN_VMS)
6358 reg_offset = 8;
6359 else
6360 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
6361
6362 alpha_sa_mask (&imask, &fmask);
6363
6364 /* Emit an insn to reload GP, if needed. */
6365 if (TARGET_ABI_OSF)
6366 {
6367 alpha_function_needs_gp = alpha_does_function_need_gp ();
6368 if (alpha_function_needs_gp)
6369 emit_insn (gen_prologue_ldgp ());
6370 }
6371
6372 /* TARGET_PROFILING_NEEDS_GP actually implies that we need to insert
6373 the call to mcount ourselves, rather than having the linker do it
6374 magically in response to -pg. Since _mcount has special linkage,
6375 don't represent the call as a call. */
6376 if (TARGET_PROFILING_NEEDS_GP && current_function_profile)
6377 emit_insn (gen_prologue_mcount ());
6378
6379 if (TARGET_ABI_UNICOSMK)
6380 unicosmk_gen_dsib (&imask);
6381
6382 /* Adjust the stack by the frame size. If the frame size is > 4096
6383 bytes, we need to be sure we probe somewhere in the first and last
6384 4096 bytes (we can probably get away without the latter test) and
6385 every 8192 bytes in between. If the frame size is > 32768, we
6386 do this in a loop. Otherwise, we generate the explicit probe
6387 instructions.
6388
6389 Note that we are only allowed to adjust sp once in the prologue. */
6390
6391 if (frame_size <= 32768)
6392 {
6393 if (frame_size > 4096)
6394 {
6395 int probed = 4096;
6396
6397 do
6398 emit_insn (gen_probe_stack (GEN_INT (TARGET_ABI_UNICOSMK
6399 ? -probed + 64
6400 : -probed)));
6401 while ((probed += 8192) < frame_size);
6402
6403 /* We only have to do this probe if we aren't saving registers. */
6404 if (sa_size == 0 && probed + 4096 < frame_size)
6405 emit_insn (gen_probe_stack (GEN_INT (-frame_size)));
6406 }
6407
6408 if (frame_size != 0)
6409 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
6410 GEN_INT (TARGET_ABI_UNICOSMK
6411 ? -frame_size + 64
6412 : -frame_size))));
6413 }
6414 else
6415 {
6416 /* Here we generate code to set R22 to SP + 4096 and set R23 to the
6417 number of 8192 byte blocks to probe. We then probe each block
6418 in the loop and then set SP to the proper location. If the
6419 amount remaining is > 4096, we have to do one more probe if we
6420 are not saving any registers. */
6421
6422 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
6423 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
6424 rtx ptr = gen_rtx_REG (DImode, 22);
6425 rtx count = gen_rtx_REG (DImode, 23);
6426 rtx seq;
6427
6428 emit_move_insn (count, GEN_INT (blocks));
6429 emit_insn (gen_adddi3 (ptr, stack_pointer_rtx,
6430 GEN_INT (TARGET_ABI_UNICOSMK ? 4096 - 64 : 4096)));
6431
6432 /* Because of the difficulty in emitting a new basic block this
6433 late in the compilation, generate the loop as a single insn. */
6434 emit_insn (gen_prologue_stack_probe_loop (count, ptr));
6435
6436 if (leftover > 4096 && sa_size == 0)
6437 {
6438 rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover));
6439 MEM_VOLATILE_P (last) = 1;
6440 emit_move_insn (last, const0_rtx);
6441 }
6442
6443 if (TARGET_ABI_WINDOWS_NT)
6444 {
6445 /* For NT stack unwind (done by 'reverse execution'), it's
6446 not OK to take the result of a loop, even though the value
6447 is already in ptr, so we reload it via a single operation
6448 and subtract it to sp.
6449
6450 Yes, that's correct -- we have to reload the whole constant
6451 into a temporary via ldah+lda then subtract from sp. */
6452
6453 HOST_WIDE_INT lo, hi;
6454 lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
6455 hi = frame_size - lo;
6456
6457 emit_move_insn (ptr, GEN_INT (hi));
6458 emit_insn (gen_adddi3 (ptr, ptr, GEN_INT (lo)));
6459 seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
6460 ptr));
6461 }
6462 else
6463 {
6464 seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr,
6465 GEN_INT (-leftover)));
6466 }
6467
6468 /* This alternative is special, because the DWARF code cannot
6469 possibly intuit through the loop above. So we invent this
6470 note it looks at instead. */
6471 RTX_FRAME_RELATED_P (seq) = 1;
6472 REG_NOTES (seq)
6473 = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
6474 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
6475 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
6476 GEN_INT (TARGET_ABI_UNICOSMK
6477 ? -frame_size + 64
6478 : -frame_size))),
6479 REG_NOTES (seq));
6480 }
6481
6482 if (!TARGET_ABI_UNICOSMK)
6483 {
6484 HOST_WIDE_INT sa_bias = 0;
6485
6486 /* Cope with very large offsets to the register save area. */
6487 sa_reg = stack_pointer_rtx;
6488 if (reg_offset + sa_size > 0x8000)
6489 {
6490 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
6491 rtx sa_bias_rtx;
6492
6493 if (low + sa_size <= 0x8000)
6494 sa_bias = reg_offset - low, reg_offset = low;
6495 else
6496 sa_bias = reg_offset, reg_offset = 0;
6497
6498 sa_reg = gen_rtx_REG (DImode, 24);
6499 sa_bias_rtx = GEN_INT (sa_bias);
6500
6501 if (add_operand (sa_bias_rtx, DImode))
6502 emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, sa_bias_rtx));
6503 else
6504 {
6505 emit_move_insn (sa_reg, sa_bias_rtx);
6506 emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, sa_reg));
6507 }
6508 }
6509
6510 /* Save regs in stack order. Beginning with VMS PV. */
6511 if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
6512 emit_frame_store (REG_PV, stack_pointer_rtx, 0, 0);
6513
6514 /* Save register RA next. */
6515 if (imask & (1UL << REG_RA))
6516 {
6517 emit_frame_store (REG_RA, sa_reg, sa_bias, reg_offset);
6518 imask &= ~(1UL << REG_RA);
6519 reg_offset += 8;
6520 }
6521
6522 /* Now save any other registers required to be saved. */
6523 for (i = 0; i < 31; i++)
6524 if (imask & (1UL << i))
6525 {
6526 emit_frame_store (i, sa_reg, sa_bias, reg_offset);
6527 reg_offset += 8;
6528 }
6529
6530 for (i = 0; i < 31; i++)
6531 if (fmask & (1UL << i))
6532 {
6533 emit_frame_store (i+32, sa_reg, sa_bias, reg_offset);
6534 reg_offset += 8;
6535 }
6536 }
6537 else if (TARGET_ABI_UNICOSMK && alpha_procedure_type == PT_STACK)
6538 {
6539 /* The standard frame on the T3E includes space for saving registers.
6540 We just have to use it. We don't have to save the return address and
6541 the old frame pointer here - they are saved in the DSIB. */
6542
6543 reg_offset = -56;
6544 for (i = 9; i < 15; i++)
6545 if (imask & (1UL << i))
6546 {
6547 emit_frame_store (i, hard_frame_pointer_rtx, 0, reg_offset);
6548 reg_offset -= 8;
6549 }
6550 for (i = 2; i < 10; i++)
6551 if (fmask & (1UL << i))
6552 {
6553 emit_frame_store (i+32, hard_frame_pointer_rtx, 0, reg_offset);
6554 reg_offset -= 8;
6555 }
6556 }
6557
6558 if (TARGET_ABI_OPEN_VMS)
6559 {
6560 if (alpha_procedure_type == PT_REGISTER)
6561 /* Register frame procedures save the fp.
6562 ?? Ought to have a dwarf2 save for this. */
6563 emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
6564 hard_frame_pointer_rtx);
6565
6566 if (alpha_procedure_type != PT_NULL && vms_base_regno != REG_PV)
6567 emit_insn (gen_force_movdi (gen_rtx_REG (DImode, vms_base_regno),
6568 gen_rtx_REG (DImode, REG_PV)));
6569
6570 if (alpha_procedure_type != PT_NULL
6571 && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
6572 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
6573
6574 /* If we have to allocate space for outgoing args, do it now. */
6575 if (current_function_outgoing_args_size != 0)
6576 {
6577 rtx seq
6578 = emit_move_insn (stack_pointer_rtx,
6579 plus_constant
6580 (hard_frame_pointer_rtx,
6581 - (ALPHA_ROUND
6582 (current_function_outgoing_args_size))));
6583
6584 /* Only set FRAME_RELATED_P on the stack adjustment we just emitted
6585 if ! frame_pointer_needed. Setting the bit will change the CFA
6586 computation rule to use sp again, which would be wrong if we had
6587 frame_pointer_needed, as this means sp might move unpredictably
6588 later on.
6589
6590 Also, note that
6591 frame_pointer_needed
6592 => vms_unwind_regno == HARD_FRAME_POINTER_REGNUM
6593 and
6594 current_function_outgoing_args_size != 0
6595 => alpha_procedure_type != PT_NULL,
6596
6597 so when we are not setting the bit here, we are guaranteed to
6598 have emitted an FRP frame pointer update just before. */
6599 RTX_FRAME_RELATED_P (seq) = ! frame_pointer_needed;
6600 }
6601 }
6602 else if (!TARGET_ABI_UNICOSMK)
6603 {
6604 /* If we need a frame pointer, set it from the stack pointer. */
6605 if (frame_pointer_needed)
6606 {
6607 if (TARGET_CAN_FAULT_IN_PROLOGUE)
6608 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
6609 else
6610 /* This must always be the last instruction in the
6611 prologue, thus we emit a special move + clobber. */
6612 FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx,
6613 stack_pointer_rtx, sa_reg)));
6614 }
6615 }
6616
6617 /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
6618 the prologue, for exception handling reasons, we cannot do this for
6619 any insn that might fault. We could prevent this for mems with a
6620 (clobber:BLK (scratch)), but this doesn't work for fp insns. So we
6621 have to prevent all such scheduling with a blockage.
6622
6623 Linux, on the other hand, never bothered to implement OSF/1's
6624 exception handling, and so doesn't care about such things. Anyone
6625 planning to use dwarf2 frame-unwind info can also omit the blockage. */
6626
6627 if (! TARGET_CAN_FAULT_IN_PROLOGUE)
6628 emit_insn (gen_blockage ());
6629 }
6630
6631 /* Count the number of .file directives, so that .loc is up to date. */
6632 int num_source_filenames = 0;
6633
6634 /* Output the textual info surrounding the prologue. */
6635
6636 void
6637 alpha_start_function (FILE *file, const char *fnname,
6638 tree decl ATTRIBUTE_UNUSED)
6639 {
6640 unsigned long imask = 0;
6641 unsigned long fmask = 0;
6642 /* Stack space needed for pushing registers clobbered by us. */
6643 HOST_WIDE_INT sa_size;
6644 /* Complete stack size needed. */
6645 unsigned HOST_WIDE_INT frame_size;
6646 /* Offset from base reg to register save area. */
6647 HOST_WIDE_INT reg_offset;
6648 char *entry_label = (char *) alloca (strlen (fnname) + 6);
6649 int i;
6650
6651 /* Don't emit an extern directive for functions defined in the same file. */
6652 if (TARGET_ABI_UNICOSMK)
6653 {
6654 tree name_tree;
6655 name_tree = get_identifier (fnname);
6656 TREE_ASM_WRITTEN (name_tree) = 1;
6657 }
6658
6659 alpha_fnname = fnname;
6660 sa_size = alpha_sa_size ();
6661
6662 frame_size = get_frame_size ();
6663 if (TARGET_ABI_OPEN_VMS)
6664 frame_size = ALPHA_ROUND (sa_size
6665 + (alpha_procedure_type == PT_STACK ? 8 : 0)
6666 + frame_size
6667 + current_function_pretend_args_size);
6668 else if (TARGET_ABI_UNICOSMK)
6669 frame_size = ALPHA_ROUND (sa_size
6670 + (alpha_procedure_type == PT_STACK ? 48 : 0))
6671 + ALPHA_ROUND (frame_size
6672 + current_function_outgoing_args_size);
6673 else
6674 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
6675 + sa_size
6676 + ALPHA_ROUND (frame_size
6677 + current_function_pretend_args_size));
6678
6679 if (TARGET_ABI_OPEN_VMS)
6680 reg_offset = 8;
6681 else
6682 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
6683
6684 alpha_sa_mask (&imask, &fmask);
6685
6686 /* Ecoff can handle multiple .file directives, so put out file and lineno.
6687 We have to do that before the .ent directive as we cannot switch
6688 files within procedures with native ecoff because line numbers are
6689 linked to procedure descriptors.
6690 Outputting the lineno helps debugging of one line functions as they
6691 would otherwise get no line number at all. Please note that we would
6692 like to put out last_linenum from final.c, but it is not accessible. */
6693
6694 if (write_symbols == SDB_DEBUG)
6695 {
6696 #ifdef ASM_OUTPUT_SOURCE_FILENAME
6697 ASM_OUTPUT_SOURCE_FILENAME (file,
6698 DECL_SOURCE_FILE (current_function_decl));
6699 #endif
6700 #ifdef SDB_OUTPUT_SOURCE_LINE
6701 if (debug_info_level != DINFO_LEVEL_TERSE)
6702 SDB_OUTPUT_SOURCE_LINE (file,
6703 DECL_SOURCE_LINE (current_function_decl));
6704 #endif
6705 }
6706
6707 /* Issue function start and label. */
6708 if (TARGET_ABI_OPEN_VMS
6709 || (!TARGET_ABI_UNICOSMK && !flag_inhibit_size_directive))
6710 {
6711 fputs ("\t.ent ", file);
6712 assemble_name (file, fnname);
6713 putc ('\n', file);
6714
6715 /* If the function needs GP, we'll write the "..ng" label there.
6716 Otherwise, do it here. */
6717 if (TARGET_ABI_OSF
6718 && ! alpha_function_needs_gp
6719 && ! current_function_is_thunk)
6720 {
6721 putc ('$', file);
6722 assemble_name (file, fnname);
6723 fputs ("..ng:\n", file);
6724 }
6725 }
6726
6727 strcpy (entry_label, fnname);
6728 if (TARGET_ABI_OPEN_VMS)
6729 strcat (entry_label, "..en");
6730
6731 /* For public functions, the label must be globalized by appending an
6732 additional colon. */
6733 if (TARGET_ABI_UNICOSMK && TREE_PUBLIC (decl))
6734 strcat (entry_label, ":");
6735
6736 ASM_OUTPUT_LABEL (file, entry_label);
6737 inside_function = TRUE;
6738
6739 if (TARGET_ABI_OPEN_VMS)
6740 fprintf (file, "\t.base $%d\n", vms_base_regno);
6741
6742 if (!TARGET_ABI_OPEN_VMS && !TARGET_ABI_UNICOSMK && TARGET_IEEE_CONFORMANT
6743 && !flag_inhibit_size_directive)
6744 {
6745 /* Set flags in procedure descriptor to request IEEE-conformant
6746 math-library routines. The value we set it to is PDSC_EXC_IEEE
6747 (/usr/include/pdsc.h). */
6748 fputs ("\t.eflag 48\n", file);
6749 }
6750
6751 /* Set up offsets to alpha virtual arg/local debugging pointer. */
6752 alpha_auto_offset = -frame_size + current_function_pretend_args_size;
6753 alpha_arg_offset = -frame_size + 48;
6754
6755 /* Describe our frame. If the frame size is larger than an integer,
6756 print it as zero to avoid an assembler error. We won't be
6757 properly describing such a frame, but that's the best we can do. */
6758 if (TARGET_ABI_UNICOSMK)
6759 ;
6760 else if (TARGET_ABI_OPEN_VMS)
6761 fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,"
6762 HOST_WIDE_INT_PRINT_DEC "\n",
6763 vms_unwind_regno,
6764 frame_size >= (1UL << 31) ? 0 : frame_size,
6765 reg_offset);
6766 else if (!flag_inhibit_size_directive)
6767 fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,%d\n",
6768 (frame_pointer_needed
6769 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM),
6770 frame_size >= (1UL << 31) ? 0 : frame_size,
6771 current_function_pretend_args_size);
6772
6773 /* Describe which registers were spilled. */
6774 if (TARGET_ABI_UNICOSMK)
6775 ;
6776 else if (TARGET_ABI_OPEN_VMS)
6777 {
6778 if (imask)
6779 /* ??? Does VMS care if mask contains ra? The old code didn't
6780 set it, so I don't here. */
6781 fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1UL << REG_RA));
6782 if (fmask)
6783 fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
6784 if (alpha_procedure_type == PT_REGISTER)
6785 fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
6786 }
6787 else if (!flag_inhibit_size_directive)
6788 {
6789 if (imask)
6790 {
6791 fprintf (file, "\t.mask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", imask,
6792 frame_size >= (1UL << 31) ? 0 : reg_offset - frame_size);
6793
6794 for (i = 0; i < 32; ++i)
6795 if (imask & (1UL << i))
6796 reg_offset += 8;
6797 }
6798
6799 if (fmask)
6800 fprintf (file, "\t.fmask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", fmask,
6801 frame_size >= (1UL << 31) ? 0 : reg_offset - frame_size);
6802 }
6803
6804 #if TARGET_ABI_OPEN_VMS
6805 /* Ifdef'ed cause link_section are only available then. */
6806 readonly_data_section ();
6807 fprintf (file, "\t.align 3\n");
6808 assemble_name (file, fnname); fputs ("..na:\n", file);
6809 fputs ("\t.ascii \"", file);
6810 assemble_name (file, fnname);
6811 fputs ("\\0\"\n", file);
6812 alpha_need_linkage (fnname, 1);
6813 text_section ();
6814 #endif
6815 }
6816
6817 /* Emit the .prologue note at the scheduled end of the prologue. */
6818
6819 static void
6820 alpha_output_function_end_prologue (FILE *file)
6821 {
6822 if (TARGET_ABI_UNICOSMK)
6823 ;
6824 else if (TARGET_ABI_OPEN_VMS)
6825 fputs ("\t.prologue\n", file);
6826 else if (TARGET_ABI_WINDOWS_NT)
6827 fputs ("\t.prologue 0\n", file);
6828 else if (!flag_inhibit_size_directive)
6829 fprintf (file, "\t.prologue %d\n",
6830 alpha_function_needs_gp || current_function_is_thunk);
6831 }
6832
6833 /* Write function epilogue. */
6834
6835 /* ??? At some point we will want to support full unwind, and so will
6836 need to mark the epilogue as well. At the moment, we just confuse
6837 dwarf2out. */
6838 #undef FRP
6839 #define FRP(exp) exp
6840
6841 void
6842 alpha_expand_epilogue (void)
6843 {
6844 /* Registers to save. */
6845 unsigned long imask = 0;
6846 unsigned long fmask = 0;
6847 /* Stack space needed for pushing registers clobbered by us. */
6848 HOST_WIDE_INT sa_size;
6849 /* Complete stack size needed. */
6850 HOST_WIDE_INT frame_size;
6851 /* Offset from base reg to register save area. */
6852 HOST_WIDE_INT reg_offset;
6853 int fp_is_frame_pointer, fp_offset;
6854 rtx sa_reg, sa_reg_exp = NULL;
6855 rtx sp_adj1, sp_adj2, mem;
6856 rtx eh_ofs;
6857 int i;
6858
6859 sa_size = alpha_sa_size ();
6860
6861 frame_size = get_frame_size ();
6862 if (TARGET_ABI_OPEN_VMS)
6863 frame_size = ALPHA_ROUND (sa_size
6864 + (alpha_procedure_type == PT_STACK ? 8 : 0)
6865 + frame_size
6866 + current_function_pretend_args_size);
6867 else if (TARGET_ABI_UNICOSMK)
6868 frame_size = ALPHA_ROUND (sa_size
6869 + (alpha_procedure_type == PT_STACK ? 48 : 0))
6870 + ALPHA_ROUND (frame_size
6871 + current_function_outgoing_args_size);
6872 else
6873 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
6874 + sa_size
6875 + ALPHA_ROUND (frame_size
6876 + current_function_pretend_args_size));
6877
6878 if (TARGET_ABI_OPEN_VMS)
6879 {
6880 if (alpha_procedure_type == PT_STACK)
6881 reg_offset = 8;
6882 else
6883 reg_offset = 0;
6884 }
6885 else
6886 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
6887
6888 alpha_sa_mask (&imask, &fmask);
6889
6890 fp_is_frame_pointer
6891 = ((TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
6892 || (!TARGET_ABI_OPEN_VMS && frame_pointer_needed));
6893 fp_offset = 0;
6894 sa_reg = stack_pointer_rtx;
6895
6896 if (current_function_calls_eh_return)
6897 eh_ofs = EH_RETURN_STACKADJ_RTX;
6898 else
6899 eh_ofs = NULL_RTX;
6900
6901 if (!TARGET_ABI_UNICOSMK && sa_size)
6902 {
6903 /* If we have a frame pointer, restore SP from it. */
6904 if ((TARGET_ABI_OPEN_VMS
6905 && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
6906 || (!TARGET_ABI_OPEN_VMS && frame_pointer_needed))
6907 FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx));
6908
6909 /* Cope with very large offsets to the register save area. */
6910 if (reg_offset + sa_size > 0x8000)
6911 {
6912 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
6913 HOST_WIDE_INT bias;
6914
6915 if (low + sa_size <= 0x8000)
6916 bias = reg_offset - low, reg_offset = low;
6917 else
6918 bias = reg_offset, reg_offset = 0;
6919
6920 sa_reg = gen_rtx_REG (DImode, 22);
6921 sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
6922
6923 FRP (emit_move_insn (sa_reg, sa_reg_exp));
6924 }
6925
6926 /* Restore registers in order, excepting a true frame pointer. */
6927
6928 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
6929 if (! eh_ofs)
6930 set_mem_alias_set (mem, alpha_sr_alias_set);
6931 FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
6932
6933 reg_offset += 8;
6934 imask &= ~(1UL << REG_RA);
6935
6936 for (i = 0; i < 31; ++i)
6937 if (imask & (1UL << i))
6938 {
6939 if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
6940 fp_offset = reg_offset;
6941 else
6942 {
6943 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
6944 set_mem_alias_set (mem, alpha_sr_alias_set);
6945 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
6946 }
6947 reg_offset += 8;
6948 }
6949
6950 for (i = 0; i < 31; ++i)
6951 if (fmask & (1UL << i))
6952 {
6953 mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
6954 set_mem_alias_set (mem, alpha_sr_alias_set);
6955 FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
6956 reg_offset += 8;
6957 }
6958 }
6959 else if (TARGET_ABI_UNICOSMK && alpha_procedure_type == PT_STACK)
6960 {
6961 /* Restore callee-saved general-purpose registers. */
6962
6963 reg_offset = -56;
6964
6965 for (i = 9; i < 15; i++)
6966 if (imask & (1UL << i))
6967 {
6968 mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx,
6969 reg_offset));
6970 set_mem_alias_set (mem, alpha_sr_alias_set);
6971 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
6972 reg_offset -= 8;
6973 }
6974
6975 for (i = 2; i < 10; i++)
6976 if (fmask & (1UL << i))
6977 {
6978 mem = gen_rtx_MEM (DFmode, plus_constant(hard_frame_pointer_rtx,
6979 reg_offset));
6980 set_mem_alias_set (mem, alpha_sr_alias_set);
6981 FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
6982 reg_offset -= 8;
6983 }
6984
6985 /* Restore the return address from the DSIB. */
6986
6987 mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx, -8));
6988 set_mem_alias_set (mem, alpha_sr_alias_set);
6989 FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
6990 }
6991
6992 if (frame_size || eh_ofs)
6993 {
6994 sp_adj1 = stack_pointer_rtx;
6995
6996 if (eh_ofs)
6997 {
6998 sp_adj1 = gen_rtx_REG (DImode, 23);
6999 emit_move_insn (sp_adj1,
7000 gen_rtx_PLUS (Pmode, stack_pointer_rtx, eh_ofs));
7001 }
7002
7003 /* If the stack size is large, begin computation into a temporary
7004 register so as not to interfere with a potential fp restore,
7005 which must be consecutive with an SP restore. */
7006 if (frame_size < 32768
7007 && ! (TARGET_ABI_UNICOSMK && current_function_calls_alloca))
7008 sp_adj2 = GEN_INT (frame_size);
7009 else if (TARGET_ABI_UNICOSMK)
7010 {
7011 sp_adj1 = gen_rtx_REG (DImode, 23);
7012 FRP (emit_move_insn (sp_adj1, hard_frame_pointer_rtx));
7013 sp_adj2 = const0_rtx;
7014 }
7015 else if (frame_size < 0x40007fffL)
7016 {
7017 int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
7018
7019 sp_adj2 = plus_constant (sp_adj1, frame_size - low);
7020 if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
7021 sp_adj1 = sa_reg;
7022 else
7023 {
7024 sp_adj1 = gen_rtx_REG (DImode, 23);
7025 FRP (emit_move_insn (sp_adj1, sp_adj2));
7026 }
7027 sp_adj2 = GEN_INT (low);
7028 }
7029 else
7030 {
7031 rtx tmp = gen_rtx_REG (DImode, 23);
7032 FRP (sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3));
7033 if (!sp_adj2)
7034 {
7035 /* We can't drop new things to memory this late, afaik,
7036 so build it up by pieces. */
7037 FRP (sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
7038 -(frame_size < 0)));
7039 if (!sp_adj2)
7040 abort ();
7041 }
7042 }
7043
7044 /* From now on, things must be in order. So emit blockages. */
7045
7046 /* Restore the frame pointer. */
7047 if (TARGET_ABI_UNICOSMK)
7048 {
7049 emit_insn (gen_blockage ());
7050 mem = gen_rtx_MEM (DImode,
7051 plus_constant (hard_frame_pointer_rtx, -16));
7052 set_mem_alias_set (mem, alpha_sr_alias_set);
7053 FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
7054 }
7055 else if (fp_is_frame_pointer)
7056 {
7057 emit_insn (gen_blockage ());
7058 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, fp_offset));
7059 set_mem_alias_set (mem, alpha_sr_alias_set);
7060 FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
7061 }
7062 else if (TARGET_ABI_OPEN_VMS)
7063 {
7064 emit_insn (gen_blockage ());
7065 FRP (emit_move_insn (hard_frame_pointer_rtx,
7066 gen_rtx_REG (DImode, vms_save_fp_regno)));
7067 }
7068
7069 /* Restore the stack pointer. */
7070 emit_insn (gen_blockage ());
7071 if (sp_adj2 == const0_rtx)
7072 FRP (emit_move_insn (stack_pointer_rtx, sp_adj1));
7073 else
7074 FRP (emit_move_insn (stack_pointer_rtx,
7075 gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)));
7076 }
7077 else
7078 {
7079 if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_REGISTER)
7080 {
7081 emit_insn (gen_blockage ());
7082 FRP (emit_move_insn (hard_frame_pointer_rtx,
7083 gen_rtx_REG (DImode, vms_save_fp_regno)));
7084 }
7085 else if (TARGET_ABI_UNICOSMK && alpha_procedure_type != PT_STACK)
7086 {
7087 /* Decrement the frame pointer if the function does not have a
7088 frame. */
7089
7090 emit_insn (gen_blockage ());
7091 FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
7092 hard_frame_pointer_rtx, constm1_rtx)));
7093 }
7094 }
7095 }
7096 \f
7097 /* Output the rest of the textual info surrounding the epilogue. */
7098
7099 void
7100 alpha_end_function (FILE *file, const char *fnname, tree decl ATTRIBUTE_UNUSED)
7101 {
7102 #if TARGET_ABI_OPEN_VMS
7103 alpha_write_linkage (file, fnname, decl);
7104 #endif
7105
7106 /* End the function. */
7107 if (!TARGET_ABI_UNICOSMK && !flag_inhibit_size_directive)
7108 {
7109 fputs ("\t.end ", file);
7110 assemble_name (file, fnname);
7111 putc ('\n', file);
7112 }
7113 inside_function = FALSE;
7114
7115 /* Output jump tables and the static subroutine information block. */
7116 if (TARGET_ABI_UNICOSMK)
7117 {
7118 unicosmk_output_ssib (file, fnname);
7119 unicosmk_output_deferred_case_vectors (file);
7120 }
7121 }
7122
7123 #if TARGET_ABI_OSF
7124 /* Emit a tail call to FUNCTION after adjusting THIS by DELTA.
7125
7126 In order to avoid the hordes of differences between generated code
7127 with and without TARGET_EXPLICIT_RELOCS, and to avoid duplicating
7128 lots of code loading up large constants, generate rtl and emit it
7129 instead of going straight to text.
7130
7131 Not sure why this idea hasn't been explored before... */
7132
7133 static void
7134 alpha_output_mi_thunk_osf (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
7135 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
7136 tree function)
7137 {
7138 HOST_WIDE_INT hi, lo;
7139 rtx this, insn, funexp;
7140
7141 reset_block_changes ();
7142
7143 /* We always require a valid GP. */
7144 emit_insn (gen_prologue_ldgp ());
7145 emit_note (NOTE_INSN_PROLOGUE_END);
7146
7147 /* Find the "this" pointer. If the function returns a structure,
7148 the structure return pointer is in $16. */
7149 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
7150 this = gen_rtx_REG (Pmode, 17);
7151 else
7152 this = gen_rtx_REG (Pmode, 16);
7153
7154 /* Add DELTA. When possible we use ldah+lda. Otherwise load the
7155 entire constant for the add. */
7156 lo = ((delta & 0xffff) ^ 0x8000) - 0x8000;
7157 hi = (((delta - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
7158 if (hi + lo == delta)
7159 {
7160 if (hi)
7161 emit_insn (gen_adddi3 (this, this, GEN_INT (hi)));
7162 if (lo)
7163 emit_insn (gen_adddi3 (this, this, GEN_INT (lo)));
7164 }
7165 else
7166 {
7167 rtx tmp = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 0),
7168 delta, -(delta < 0));
7169 emit_insn (gen_adddi3 (this, this, tmp));
7170 }
7171
7172 /* Add a delta stored in the vtable at VCALL_OFFSET. */
7173 if (vcall_offset)
7174 {
7175 rtx tmp, tmp2;
7176
7177 tmp = gen_rtx_REG (Pmode, 0);
7178 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
7179
7180 lo = ((vcall_offset & 0xffff) ^ 0x8000) - 0x8000;
7181 hi = (((vcall_offset - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
7182 if (hi + lo == vcall_offset)
7183 {
7184 if (hi)
7185 emit_insn (gen_adddi3 (tmp, tmp, GEN_INT (hi)));
7186 }
7187 else
7188 {
7189 tmp2 = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 1),
7190 vcall_offset, -(vcall_offset < 0));
7191 emit_insn (gen_adddi3 (tmp, tmp, tmp2));
7192 lo = 0;
7193 }
7194 if (lo)
7195 tmp2 = gen_rtx_PLUS (Pmode, tmp, GEN_INT (lo));
7196 else
7197 tmp2 = tmp;
7198 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp2));
7199
7200 emit_insn (gen_adddi3 (this, this, tmp));
7201 }
7202
7203 /* Generate a tail call to the target function. */
7204 if (! TREE_USED (function))
7205 {
7206 assemble_external (function);
7207 TREE_USED (function) = 1;
7208 }
7209 funexp = XEXP (DECL_RTL (function), 0);
7210 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
7211 insn = emit_call_insn (gen_sibcall (funexp, const0_rtx));
7212 SIBLING_CALL_P (insn) = 1;
7213
7214 /* Run just enough of rest_of_compilation to get the insns emitted.
7215 There's not really enough bulk here to make other passes such as
7216 instruction scheduling worth while. Note that use_thunk calls
7217 assemble_start_function and assemble_end_function. */
7218 insn = get_insns ();
7219 insn_locators_initialize ();
7220 shorten_branches (insn);
7221 final_start_function (insn, file, 1);
7222 final (insn, file, 1, 0);
7223 final_end_function ();
7224 }
7225 #endif /* TARGET_ABI_OSF */
7226 \f
7227 /* Debugging support. */
7228
7229 #include "gstab.h"
7230
7231 /* Count the number of sdb related labels are generated (to find block
7232 start and end boundaries). */
7233
7234 int sdb_label_count = 0;
7235
7236 /* Name of the file containing the current function. */
7237
7238 static const char *current_function_file = "";
7239
7240 /* Offsets to alpha virtual arg/local debugging pointers. */
7241
7242 long alpha_arg_offset;
7243 long alpha_auto_offset;
7244 \f
7245 /* Emit a new filename to a stream. */
7246
7247 void
7248 alpha_output_filename (FILE *stream, const char *name)
7249 {
7250 static int first_time = TRUE;
7251
7252 if (first_time)
7253 {
7254 first_time = FALSE;
7255 ++num_source_filenames;
7256 current_function_file = name;
7257 fprintf (stream, "\t.file\t%d ", num_source_filenames);
7258 output_quoted_string (stream, name);
7259 fprintf (stream, "\n");
7260 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
7261 fprintf (stream, "\t#@stabs\n");
7262 }
7263
7264 else if (write_symbols == DBX_DEBUG)
7265 /* dbxout.c will emit an appropriate .stabs directive. */
7266 return;
7267
7268 else if (name != current_function_file
7269 && strcmp (name, current_function_file) != 0)
7270 {
7271 if (inside_function && ! TARGET_GAS)
7272 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
7273 else
7274 {
7275 ++num_source_filenames;
7276 current_function_file = name;
7277 fprintf (stream, "\t.file\t%d ", num_source_filenames);
7278 }
7279
7280 output_quoted_string (stream, name);
7281 fprintf (stream, "\n");
7282 }
7283 }
7284 \f
7285 /* Structure to show the current status of registers and memory. */
7286
7287 struct shadow_summary
7288 {
7289 struct {
7290 unsigned int i : 31; /* Mask of int regs */
7291 unsigned int fp : 31; /* Mask of fp regs */
7292 unsigned int mem : 1; /* mem == imem | fpmem */
7293 } used, defd;
7294 };
7295
7296 /* Summary the effects of expression X on the machine. Update SUM, a pointer
7297 to the summary structure. SET is nonzero if the insn is setting the
7298 object, otherwise zero. */
7299
7300 static void
7301 summarize_insn (rtx x, struct shadow_summary *sum, int set)
7302 {
7303 const char *format_ptr;
7304 int i, j;
7305
7306 if (x == 0)
7307 return;
7308
7309 switch (GET_CODE (x))
7310 {
7311 /* ??? Note that this case would be incorrect if the Alpha had a
7312 ZERO_EXTRACT in SET_DEST. */
7313 case SET:
7314 summarize_insn (SET_SRC (x), sum, 0);
7315 summarize_insn (SET_DEST (x), sum, 1);
7316 break;
7317
7318 case CLOBBER:
7319 summarize_insn (XEXP (x, 0), sum, 1);
7320 break;
7321
7322 case USE:
7323 summarize_insn (XEXP (x, 0), sum, 0);
7324 break;
7325
7326 case ASM_OPERANDS:
7327 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
7328 summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
7329 break;
7330
7331 case PARALLEL:
7332 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
7333 summarize_insn (XVECEXP (x, 0, i), sum, 0);
7334 break;
7335
7336 case SUBREG:
7337 summarize_insn (SUBREG_REG (x), sum, 0);
7338 break;
7339
7340 case REG:
7341 {
7342 int regno = REGNO (x);
7343 unsigned long mask = ((unsigned long) 1) << (regno % 32);
7344
7345 if (regno == 31 || regno == 63)
7346 break;
7347
7348 if (set)
7349 {
7350 if (regno < 32)
7351 sum->defd.i |= mask;
7352 else
7353 sum->defd.fp |= mask;
7354 }
7355 else
7356 {
7357 if (regno < 32)
7358 sum->used.i |= mask;
7359 else
7360 sum->used.fp |= mask;
7361 }
7362 }
7363 break;
7364
7365 case MEM:
7366 if (set)
7367 sum->defd.mem = 1;
7368 else
7369 sum->used.mem = 1;
7370
7371 /* Find the regs used in memory address computation: */
7372 summarize_insn (XEXP (x, 0), sum, 0);
7373 break;
7374
7375 case CONST_INT: case CONST_DOUBLE:
7376 case SYMBOL_REF: case LABEL_REF: case CONST:
7377 case SCRATCH: case ASM_INPUT:
7378 break;
7379
7380 /* Handle common unary and binary ops for efficiency. */
7381 case COMPARE: case PLUS: case MINUS: case MULT: case DIV:
7382 case MOD: case UDIV: case UMOD: case AND: case IOR:
7383 case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT:
7384 case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX:
7385 case NE: case EQ: case GE: case GT: case LE:
7386 case LT: case GEU: case GTU: case LEU: case LTU:
7387 summarize_insn (XEXP (x, 0), sum, 0);
7388 summarize_insn (XEXP (x, 1), sum, 0);
7389 break;
7390
7391 case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
7392 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
7393 case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
7394 case SQRT: case FFS:
7395 summarize_insn (XEXP (x, 0), sum, 0);
7396 break;
7397
7398 default:
7399 format_ptr = GET_RTX_FORMAT (GET_CODE (x));
7400 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
7401 switch (format_ptr[i])
7402 {
7403 case 'e':
7404 summarize_insn (XEXP (x, i), sum, 0);
7405 break;
7406
7407 case 'E':
7408 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
7409 summarize_insn (XVECEXP (x, i, j), sum, 0);
7410 break;
7411
7412 case 'i':
7413 break;
7414
7415 default:
7416 abort ();
7417 }
7418 }
7419 }
7420
7421 /* Ensure a sufficient number of `trapb' insns are in the code when
7422 the user requests code with a trap precision of functions or
7423 instructions.
7424
7425 In naive mode, when the user requests a trap-precision of
7426 "instruction", a trapb is needed after every instruction that may
7427 generate a trap. This ensures that the code is resumption safe but
7428 it is also slow.
7429
7430 When optimizations are turned on, we delay issuing a trapb as long
7431 as possible. In this context, a trap shadow is the sequence of
7432 instructions that starts with a (potentially) trap generating
7433 instruction and extends to the next trapb or call_pal instruction
7434 (but GCC never generates call_pal by itself). We can delay (and
7435 therefore sometimes omit) a trapb subject to the following
7436 conditions:
7437
7438 (a) On entry to the trap shadow, if any Alpha register or memory
7439 location contains a value that is used as an operand value by some
7440 instruction in the trap shadow (live on entry), then no instruction
7441 in the trap shadow may modify the register or memory location.
7442
7443 (b) Within the trap shadow, the computation of the base register
7444 for a memory load or store instruction may not involve using the
7445 result of an instruction that might generate an UNPREDICTABLE
7446 result.
7447
7448 (c) Within the trap shadow, no register may be used more than once
7449 as a destination register. (This is to make life easier for the
7450 trap-handler.)
7451
7452 (d) The trap shadow may not include any branch instructions. */
7453
7454 static void
7455 alpha_handle_trap_shadows (void)
7456 {
7457 struct shadow_summary shadow;
7458 int trap_pending, exception_nesting;
7459 rtx i, n;
7460
7461 trap_pending = 0;
7462 exception_nesting = 0;
7463 shadow.used.i = 0;
7464 shadow.used.fp = 0;
7465 shadow.used.mem = 0;
7466 shadow.defd = shadow.used;
7467
7468 for (i = get_insns (); i ; i = NEXT_INSN (i))
7469 {
7470 if (GET_CODE (i) == NOTE)
7471 {
7472 switch (NOTE_LINE_NUMBER (i))
7473 {
7474 case NOTE_INSN_EH_REGION_BEG:
7475 exception_nesting++;
7476 if (trap_pending)
7477 goto close_shadow;
7478 break;
7479
7480 case NOTE_INSN_EH_REGION_END:
7481 exception_nesting--;
7482 if (trap_pending)
7483 goto close_shadow;
7484 break;
7485
7486 case NOTE_INSN_EPILOGUE_BEG:
7487 if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
7488 goto close_shadow;
7489 break;
7490 }
7491 }
7492 else if (trap_pending)
7493 {
7494 if (alpha_tp == ALPHA_TP_FUNC)
7495 {
7496 if (GET_CODE (i) == JUMP_INSN
7497 && GET_CODE (PATTERN (i)) == RETURN)
7498 goto close_shadow;
7499 }
7500 else if (alpha_tp == ALPHA_TP_INSN)
7501 {
7502 if (optimize > 0)
7503 {
7504 struct shadow_summary sum;
7505
7506 sum.used.i = 0;
7507 sum.used.fp = 0;
7508 sum.used.mem = 0;
7509 sum.defd = sum.used;
7510
7511 switch (GET_CODE (i))
7512 {
7513 case INSN:
7514 /* Annoyingly, get_attr_trap will abort on these. */
7515 if (GET_CODE (PATTERN (i)) == USE
7516 || GET_CODE (PATTERN (i)) == CLOBBER)
7517 break;
7518
7519 summarize_insn (PATTERN (i), &sum, 0);
7520
7521 if ((sum.defd.i & shadow.defd.i)
7522 || (sum.defd.fp & shadow.defd.fp))
7523 {
7524 /* (c) would be violated */
7525 goto close_shadow;
7526 }
7527
7528 /* Combine shadow with summary of current insn: */
7529 shadow.used.i |= sum.used.i;
7530 shadow.used.fp |= sum.used.fp;
7531 shadow.used.mem |= sum.used.mem;
7532 shadow.defd.i |= sum.defd.i;
7533 shadow.defd.fp |= sum.defd.fp;
7534 shadow.defd.mem |= sum.defd.mem;
7535
7536 if ((sum.defd.i & shadow.used.i)
7537 || (sum.defd.fp & shadow.used.fp)
7538 || (sum.defd.mem & shadow.used.mem))
7539 {
7540 /* (a) would be violated (also takes care of (b)) */
7541 if (get_attr_trap (i) == TRAP_YES
7542 && ((sum.defd.i & sum.used.i)
7543 || (sum.defd.fp & sum.used.fp)))
7544 abort ();
7545
7546 goto close_shadow;
7547 }
7548 break;
7549
7550 case JUMP_INSN:
7551 case CALL_INSN:
7552 case CODE_LABEL:
7553 goto close_shadow;
7554
7555 default:
7556 abort ();
7557 }
7558 }
7559 else
7560 {
7561 close_shadow:
7562 n = emit_insn_before (gen_trapb (), i);
7563 PUT_MODE (n, TImode);
7564 PUT_MODE (i, TImode);
7565 trap_pending = 0;
7566 shadow.used.i = 0;
7567 shadow.used.fp = 0;
7568 shadow.used.mem = 0;
7569 shadow.defd = shadow.used;
7570 }
7571 }
7572 }
7573
7574 if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
7575 && GET_CODE (i) == INSN
7576 && GET_CODE (PATTERN (i)) != USE
7577 && GET_CODE (PATTERN (i)) != CLOBBER
7578 && get_attr_trap (i) == TRAP_YES)
7579 {
7580 if (optimize && !trap_pending)
7581 summarize_insn (PATTERN (i), &shadow, 0);
7582 trap_pending = 1;
7583 }
7584 }
7585 }
7586 \f
7587 /* Alpha can only issue instruction groups simultaneously if they are
7588 suitably aligned. This is very processor-specific. */
7589
7590 enum alphaev4_pipe {
7591 EV4_STOP = 0,
7592 EV4_IB0 = 1,
7593 EV4_IB1 = 2,
7594 EV4_IBX = 4
7595 };
7596
7597 enum alphaev5_pipe {
7598 EV5_STOP = 0,
7599 EV5_NONE = 1,
7600 EV5_E01 = 2,
7601 EV5_E0 = 4,
7602 EV5_E1 = 8,
7603 EV5_FAM = 16,
7604 EV5_FA = 32,
7605 EV5_FM = 64
7606 };
7607
7608 static enum alphaev4_pipe
7609 alphaev4_insn_pipe (rtx insn)
7610 {
7611 if (recog_memoized (insn) < 0)
7612 return EV4_STOP;
7613 if (get_attr_length (insn) != 4)
7614 return EV4_STOP;
7615
7616 switch (get_attr_type (insn))
7617 {
7618 case TYPE_ILD:
7619 case TYPE_FLD:
7620 return EV4_IBX;
7621
7622 case TYPE_LDSYM:
7623 case TYPE_IADD:
7624 case TYPE_ILOG:
7625 case TYPE_ICMOV:
7626 case TYPE_ICMP:
7627 case TYPE_IST:
7628 case TYPE_FST:
7629 case TYPE_SHIFT:
7630 case TYPE_IMUL:
7631 case TYPE_FBR:
7632 return EV4_IB0;
7633
7634 case TYPE_MISC:
7635 case TYPE_IBR:
7636 case TYPE_JSR:
7637 case TYPE_CALLPAL:
7638 case TYPE_FCPYS:
7639 case TYPE_FCMOV:
7640 case TYPE_FADD:
7641 case TYPE_FDIV:
7642 case TYPE_FMUL:
7643 return EV4_IB1;
7644
7645 default:
7646 abort ();
7647 }
7648 }
7649
7650 static enum alphaev5_pipe
7651 alphaev5_insn_pipe (rtx insn)
7652 {
7653 if (recog_memoized (insn) < 0)
7654 return EV5_STOP;
7655 if (get_attr_length (insn) != 4)
7656 return EV5_STOP;
7657
7658 switch (get_attr_type (insn))
7659 {
7660 case TYPE_ILD:
7661 case TYPE_FLD:
7662 case TYPE_LDSYM:
7663 case TYPE_IADD:
7664 case TYPE_ILOG:
7665 case TYPE_ICMOV:
7666 case TYPE_ICMP:
7667 return EV5_E01;
7668
7669 case TYPE_IST:
7670 case TYPE_FST:
7671 case TYPE_SHIFT:
7672 case TYPE_IMUL:
7673 case TYPE_MISC:
7674 case TYPE_MVI:
7675 return EV5_E0;
7676
7677 case TYPE_IBR:
7678 case TYPE_JSR:
7679 case TYPE_CALLPAL:
7680 return EV5_E1;
7681
7682 case TYPE_FCPYS:
7683 return EV5_FAM;
7684
7685 case TYPE_FBR:
7686 case TYPE_FCMOV:
7687 case TYPE_FADD:
7688 case TYPE_FDIV:
7689 return EV5_FA;
7690
7691 case TYPE_FMUL:
7692 return EV5_FM;
7693
7694 default:
7695 abort();
7696 }
7697 }
7698
7699 /* IN_USE is a mask of the slots currently filled within the insn group.
7700 The mask bits come from alphaev4_pipe above. If EV4_IBX is set, then
7701 the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.
7702
7703 LEN is, of course, the length of the group in bytes. */
7704
7705 static rtx
7706 alphaev4_next_group (rtx insn, int *pin_use, int *plen)
7707 {
7708 int len, in_use;
7709
7710 len = in_use = 0;
7711
7712 if (! INSN_P (insn)
7713 || GET_CODE (PATTERN (insn)) == CLOBBER
7714 || GET_CODE (PATTERN (insn)) == USE)
7715 goto next_and_done;
7716
7717 while (1)
7718 {
7719 enum alphaev4_pipe pipe;
7720
7721 pipe = alphaev4_insn_pipe (insn);
7722 switch (pipe)
7723 {
7724 case EV4_STOP:
7725 /* Force complex instructions to start new groups. */
7726 if (in_use)
7727 goto done;
7728
7729 /* If this is a completely unrecognized insn, its an asm.
7730 We don't know how long it is, so record length as -1 to
7731 signal a needed realignment. */
7732 if (recog_memoized (insn) < 0)
7733 len = -1;
7734 else
7735 len = get_attr_length (insn);
7736 goto next_and_done;
7737
7738 case EV4_IBX:
7739 if (in_use & EV4_IB0)
7740 {
7741 if (in_use & EV4_IB1)
7742 goto done;
7743 in_use |= EV4_IB1;
7744 }
7745 else
7746 in_use |= EV4_IB0 | EV4_IBX;
7747 break;
7748
7749 case EV4_IB0:
7750 if (in_use & EV4_IB0)
7751 {
7752 if (!(in_use & EV4_IBX) || (in_use & EV4_IB1))
7753 goto done;
7754 in_use |= EV4_IB1;
7755 }
7756 in_use |= EV4_IB0;
7757 break;
7758
7759 case EV4_IB1:
7760 if (in_use & EV4_IB1)
7761 goto done;
7762 in_use |= EV4_IB1;
7763 break;
7764
7765 default:
7766 abort();
7767 }
7768 len += 4;
7769
7770 /* Haifa doesn't do well scheduling branches. */
7771 if (GET_CODE (insn) == JUMP_INSN)
7772 goto next_and_done;
7773
7774 next:
7775 insn = next_nonnote_insn (insn);
7776
7777 if (!insn || ! INSN_P (insn))
7778 goto done;
7779
7780 /* Let Haifa tell us where it thinks insn group boundaries are. */
7781 if (GET_MODE (insn) == TImode)
7782 goto done;
7783
7784 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
7785 goto next;
7786 }
7787
7788 next_and_done:
7789 insn = next_nonnote_insn (insn);
7790
7791 done:
7792 *plen = len;
7793 *pin_use = in_use;
7794 return insn;
7795 }
7796
7797 /* IN_USE is a mask of the slots currently filled within the insn group.
7798 The mask bits come from alphaev5_pipe above. If EV5_E01 is set, then
7799 the insn in EV5_E0 can be swapped by the hardware into EV5_E1.
7800
7801 LEN is, of course, the length of the group in bytes. */
7802
7803 static rtx
7804 alphaev5_next_group (rtx insn, int *pin_use, int *plen)
7805 {
7806 int len, in_use;
7807
7808 len = in_use = 0;
7809
7810 if (! INSN_P (insn)
7811 || GET_CODE (PATTERN (insn)) == CLOBBER
7812 || GET_CODE (PATTERN (insn)) == USE)
7813 goto next_and_done;
7814
7815 while (1)
7816 {
7817 enum alphaev5_pipe pipe;
7818
7819 pipe = alphaev5_insn_pipe (insn);
7820 switch (pipe)
7821 {
7822 case EV5_STOP:
7823 /* Force complex instructions to start new groups. */
7824 if (in_use)
7825 goto done;
7826
7827 /* If this is a completely unrecognized insn, its an asm.
7828 We don't know how long it is, so record length as -1 to
7829 signal a needed realignment. */
7830 if (recog_memoized (insn) < 0)
7831 len = -1;
7832 else
7833 len = get_attr_length (insn);
7834 goto next_and_done;
7835
7836 /* ??? Most of the places below, we would like to abort, as
7837 it would indicate an error either in Haifa, or in the
7838 scheduling description. Unfortunately, Haifa never
7839 schedules the last instruction of the BB, so we don't
7840 have an accurate TI bit to go off. */
7841 case EV5_E01:
7842 if (in_use & EV5_E0)
7843 {
7844 if (in_use & EV5_E1)
7845 goto done;
7846 in_use |= EV5_E1;
7847 }
7848 else
7849 in_use |= EV5_E0 | EV5_E01;
7850 break;
7851
7852 case EV5_E0:
7853 if (in_use & EV5_E0)
7854 {
7855 if (!(in_use & EV5_E01) || (in_use & EV5_E1))
7856 goto done;
7857 in_use |= EV5_E1;
7858 }
7859 in_use |= EV5_E0;
7860 break;
7861
7862 case EV5_E1:
7863 if (in_use & EV5_E1)
7864 goto done;
7865 in_use |= EV5_E1;
7866 break;
7867
7868 case EV5_FAM:
7869 if (in_use & EV5_FA)
7870 {
7871 if (in_use & EV5_FM)
7872 goto done;
7873 in_use |= EV5_FM;
7874 }
7875 else
7876 in_use |= EV5_FA | EV5_FAM;
7877 break;
7878
7879 case EV5_FA:
7880 if (in_use & EV5_FA)
7881 goto done;
7882 in_use |= EV5_FA;
7883 break;
7884
7885 case EV5_FM:
7886 if (in_use & EV5_FM)
7887 goto done;
7888 in_use |= EV5_FM;
7889 break;
7890
7891 case EV5_NONE:
7892 break;
7893
7894 default:
7895 abort();
7896 }
7897 len += 4;
7898
7899 /* Haifa doesn't do well scheduling branches. */
7900 /* ??? If this is predicted not-taken, slotting continues, except
7901 that no more IBR, FBR, or JSR insns may be slotted. */
7902 if (GET_CODE (insn) == JUMP_INSN)
7903 goto next_and_done;
7904
7905 next:
7906 insn = next_nonnote_insn (insn);
7907
7908 if (!insn || ! INSN_P (insn))
7909 goto done;
7910
7911 /* Let Haifa tell us where it thinks insn group boundaries are. */
7912 if (GET_MODE (insn) == TImode)
7913 goto done;
7914
7915 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
7916 goto next;
7917 }
7918
7919 next_and_done:
7920 insn = next_nonnote_insn (insn);
7921
7922 done:
7923 *plen = len;
7924 *pin_use = in_use;
7925 return insn;
7926 }
7927
7928 static rtx
7929 alphaev4_next_nop (int *pin_use)
7930 {
7931 int in_use = *pin_use;
7932 rtx nop;
7933
7934 if (!(in_use & EV4_IB0))
7935 {
7936 in_use |= EV4_IB0;
7937 nop = gen_nop ();
7938 }
7939 else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX)
7940 {
7941 in_use |= EV4_IB1;
7942 nop = gen_nop ();
7943 }
7944 else if (TARGET_FP && !(in_use & EV4_IB1))
7945 {
7946 in_use |= EV4_IB1;
7947 nop = gen_fnop ();
7948 }
7949 else
7950 nop = gen_unop ();
7951
7952 *pin_use = in_use;
7953 return nop;
7954 }
7955
7956 static rtx
7957 alphaev5_next_nop (int *pin_use)
7958 {
7959 int in_use = *pin_use;
7960 rtx nop;
7961
7962 if (!(in_use & EV5_E1))
7963 {
7964 in_use |= EV5_E1;
7965 nop = gen_nop ();
7966 }
7967 else if (TARGET_FP && !(in_use & EV5_FA))
7968 {
7969 in_use |= EV5_FA;
7970 nop = gen_fnop ();
7971 }
7972 else if (TARGET_FP && !(in_use & EV5_FM))
7973 {
7974 in_use |= EV5_FM;
7975 nop = gen_fnop ();
7976 }
7977 else
7978 nop = gen_unop ();
7979
7980 *pin_use = in_use;
7981 return nop;
7982 }
7983
7984 /* The instruction group alignment main loop. */
7985
7986 static void
7987 alpha_align_insns (unsigned int max_align,
7988 rtx (*next_group) (rtx, int *, int *),
7989 rtx (*next_nop) (int *))
7990 {
7991 /* ALIGN is the known alignment for the insn group. */
7992 unsigned int align;
7993 /* OFS is the offset of the current insn in the insn group. */
7994 int ofs;
7995 int prev_in_use, in_use, len;
7996 rtx i, next;
7997
7998 /* Let shorten branches care for assigning alignments to code labels. */
7999 shorten_branches (get_insns ());
8000
8001 if (align_functions < 4)
8002 align = 4;
8003 else if ((unsigned int) align_functions < max_align)
8004 align = align_functions;
8005 else
8006 align = max_align;
8007
8008 ofs = prev_in_use = 0;
8009 i = get_insns ();
8010 if (GET_CODE (i) == NOTE)
8011 i = next_nonnote_insn (i);
8012
8013 while (i)
8014 {
8015 next = (*next_group) (i, &in_use, &len);
8016
8017 /* When we see a label, resync alignment etc. */
8018 if (GET_CODE (i) == CODE_LABEL)
8019 {
8020 unsigned int new_align = 1 << label_to_alignment (i);
8021
8022 if (new_align >= align)
8023 {
8024 align = new_align < max_align ? new_align : max_align;
8025 ofs = 0;
8026 }
8027
8028 else if (ofs & (new_align-1))
8029 ofs = (ofs | (new_align-1)) + 1;
8030 if (len != 0)
8031 abort();
8032 }
8033
8034 /* Handle complex instructions special. */
8035 else if (in_use == 0)
8036 {
8037 /* Asms will have length < 0. This is a signal that we have
8038 lost alignment knowledge. Assume, however, that the asm
8039 will not mis-align instructions. */
8040 if (len < 0)
8041 {
8042 ofs = 0;
8043 align = 4;
8044 len = 0;
8045 }
8046 }
8047
8048 /* If the known alignment is smaller than the recognized insn group,
8049 realign the output. */
8050 else if ((int) align < len)
8051 {
8052 unsigned int new_log_align = len > 8 ? 4 : 3;
8053 rtx prev, where;
8054
8055 where = prev = prev_nonnote_insn (i);
8056 if (!where || GET_CODE (where) != CODE_LABEL)
8057 where = i;
8058
8059 /* Can't realign between a call and its gp reload. */
8060 if (! (TARGET_EXPLICIT_RELOCS
8061 && prev && GET_CODE (prev) == CALL_INSN))
8062 {
8063 emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
8064 align = 1 << new_log_align;
8065 ofs = 0;
8066 }
8067 }
8068
8069 /* If the group won't fit in the same INT16 as the previous,
8070 we need to add padding to keep the group together. Rather
8071 than simply leaving the insn filling to the assembler, we
8072 can make use of the knowledge of what sorts of instructions
8073 were issued in the previous group to make sure that all of
8074 the added nops are really free. */
8075 else if (ofs + len > (int) align)
8076 {
8077 int nop_count = (align - ofs) / 4;
8078 rtx where;
8079
8080 /* Insert nops before labels, branches, and calls to truly merge
8081 the execution of the nops with the previous instruction group. */
8082 where = prev_nonnote_insn (i);
8083 if (where)
8084 {
8085 if (GET_CODE (where) == CODE_LABEL)
8086 {
8087 rtx where2 = prev_nonnote_insn (where);
8088 if (where2 && GET_CODE (where2) == JUMP_INSN)
8089 where = where2;
8090 }
8091 else if (GET_CODE (where) == INSN)
8092 where = i;
8093 }
8094 else
8095 where = i;
8096
8097 do
8098 emit_insn_before ((*next_nop)(&prev_in_use), where);
8099 while (--nop_count);
8100 ofs = 0;
8101 }
8102
8103 ofs = (ofs + len) & (align - 1);
8104 prev_in_use = in_use;
8105 i = next;
8106 }
8107 }
8108 \f
8109 /* Machine dependent reorg pass. */
8110
8111 static void
8112 alpha_reorg (void)
8113 {
8114 if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
8115 alpha_handle_trap_shadows ();
8116
8117 /* Due to the number of extra trapb insns, don't bother fixing up
8118 alignment when trap precision is instruction. Moreover, we can
8119 only do our job when sched2 is run. */
8120 if (optimize && !optimize_size
8121 && alpha_tp != ALPHA_TP_INSN
8122 && flag_schedule_insns_after_reload)
8123 {
8124 if (alpha_cpu == PROCESSOR_EV4)
8125 alpha_align_insns (8, alphaev4_next_group, alphaev4_next_nop);
8126 else if (alpha_cpu == PROCESSOR_EV5)
8127 alpha_align_insns (16, alphaev5_next_group, alphaev5_next_nop);
8128 }
8129 }
8130 \f
8131 #if !TARGET_ABI_UNICOSMK
8132
8133 #ifdef HAVE_STAMP_H
8134 #include <stamp.h>
8135 #endif
8136
8137 static void
8138 alpha_file_start (void)
8139 {
8140 #ifdef OBJECT_FORMAT_ELF
8141 /* If emitting dwarf2 debug information, we cannot generate a .file
8142 directive to start the file, as it will conflict with dwarf2out
8143 file numbers. So it's only useful when emitting mdebug output. */
8144 targetm.file_start_file_directive = (write_symbols == DBX_DEBUG);
8145 #endif
8146
8147 default_file_start ();
8148 #ifdef MS_STAMP
8149 fprintf (asm_out_file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
8150 #endif
8151
8152 fputs ("\t.set noreorder\n", asm_out_file);
8153 fputs ("\t.set volatile\n", asm_out_file);
8154 if (!TARGET_ABI_OPEN_VMS)
8155 fputs ("\t.set noat\n", asm_out_file);
8156 if (TARGET_EXPLICIT_RELOCS)
8157 fputs ("\t.set nomacro\n", asm_out_file);
8158 if (TARGET_SUPPORT_ARCH | TARGET_BWX | TARGET_MAX | TARGET_FIX | TARGET_CIX)
8159 fprintf (asm_out_file,
8160 "\t.arch %s\n",
8161 TARGET_CPU_EV6 ? "ev6"
8162 : (TARGET_CPU_EV5
8163 ? (TARGET_MAX ? "pca56" : TARGET_BWX ? "ev56" : "ev5")
8164 : "ev4"));
8165 }
8166 #endif
8167
8168 #ifdef OBJECT_FORMAT_ELF
8169
8170 /* Switch to the section to which we should output X. The only thing
8171 special we do here is to honor small data. */
8172
8173 static void
8174 alpha_elf_select_rtx_section (enum machine_mode mode, rtx x,
8175 unsigned HOST_WIDE_INT align)
8176 {
8177 if (TARGET_SMALL_DATA && GET_MODE_SIZE (mode) <= g_switch_value)
8178 /* ??? Consider using mergeable sdata sections. */
8179 sdata_section ();
8180 else
8181 default_elf_select_rtx_section (mode, x, align);
8182 }
8183
8184 #endif /* OBJECT_FORMAT_ELF */
8185 \f
8186 /* Structure to collect function names for final output in link section. */
8187 /* Note that items marked with GTY can't be ifdef'ed out. */
8188
8189 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
8190 enum reloc_kind {KIND_LINKAGE, KIND_CODEADDR};
8191
8192 struct alpha_links GTY(())
8193 {
8194 int num;
8195 rtx linkage;
8196 enum links_kind lkind;
8197 enum reloc_kind rkind;
8198 };
8199
8200 struct alpha_funcs GTY(())
8201 {
8202 int num;
8203 splay_tree GTY ((param1_is (char *), param2_is (struct alpha_links *)))
8204 links;
8205 };
8206
8207 static GTY ((param1_is (char *), param2_is (struct alpha_links *)))
8208 splay_tree alpha_links_tree;
8209 static GTY ((param1_is (tree), param2_is (struct alpha_funcs *)))
8210 splay_tree alpha_funcs_tree;
8211
8212 static GTY(()) int alpha_funcs_num;
8213
8214 #if TARGET_ABI_OPEN_VMS
8215
8216 /* Return the VMS argument type corresponding to MODE. */
8217
8218 enum avms_arg_type
8219 alpha_arg_type (enum machine_mode mode)
8220 {
8221 switch (mode)
8222 {
8223 case SFmode:
8224 return TARGET_FLOAT_VAX ? FF : FS;
8225 case DFmode:
8226 return TARGET_FLOAT_VAX ? FD : FT;
8227 default:
8228 return I64;
8229 }
8230 }
8231
8232 /* Return an rtx for an integer representing the VMS Argument Information
8233 register value. */
8234
8235 rtx
8236 alpha_arg_info_reg_val (CUMULATIVE_ARGS cum)
8237 {
8238 unsigned HOST_WIDE_INT regval = cum.num_args;
8239 int i;
8240
8241 for (i = 0; i < 6; i++)
8242 regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
8243
8244 return GEN_INT (regval);
8245 }
8246 \f
8247 /* Make (or fake) .linkage entry for function call.
8248
8249 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition.
8250
8251 Return an SYMBOL_REF rtx for the linkage. */
8252
8253 rtx
8254 alpha_need_linkage (const char *name, int is_local)
8255 {
8256 splay_tree_node node;
8257 struct alpha_links *al;
8258
8259 if (name[0] == '*')
8260 name++;
8261
8262 if (is_local)
8263 {
8264 struct alpha_funcs *cfaf;
8265
8266 if (!alpha_funcs_tree)
8267 alpha_funcs_tree = splay_tree_new_ggc ((splay_tree_compare_fn)
8268 splay_tree_compare_pointers);
8269
8270 cfaf = (struct alpha_funcs *) ggc_alloc (sizeof (struct alpha_funcs));
8271
8272 cfaf->links = 0;
8273 cfaf->num = ++alpha_funcs_num;
8274
8275 splay_tree_insert (alpha_funcs_tree,
8276 (splay_tree_key) current_function_decl,
8277 (splay_tree_value) cfaf);
8278 }
8279
8280 if (alpha_links_tree)
8281 {
8282 /* Is this name already defined? */
8283
8284 node = splay_tree_lookup (alpha_links_tree, (splay_tree_key) name);
8285 if (node)
8286 {
8287 al = (struct alpha_links *) node->value;
8288 if (is_local)
8289 {
8290 /* Defined here but external assumed. */
8291 if (al->lkind == KIND_EXTERN)
8292 al->lkind = KIND_LOCAL;
8293 }
8294 else
8295 {
8296 /* Used here but unused assumed. */
8297 if (al->lkind == KIND_UNUSED)
8298 al->lkind = KIND_LOCAL;
8299 }
8300 return al->linkage;
8301 }
8302 }
8303 else
8304 alpha_links_tree = splay_tree_new_ggc ((splay_tree_compare_fn) strcmp);
8305
8306 al = (struct alpha_links *) ggc_alloc (sizeof (struct alpha_links));
8307 name = ggc_strdup (name);
8308
8309 /* Assume external if no definition. */
8310 al->lkind = (is_local ? KIND_UNUSED : KIND_EXTERN);
8311
8312 /* Ensure we have an IDENTIFIER so assemble_name can mark it used. */
8313 get_identifier (name);
8314
8315 /* Construct a SYMBOL_REF for us to call. */
8316 {
8317 size_t name_len = strlen (name);
8318 char *linksym = alloca (name_len + 6);
8319 linksym[0] = '$';
8320 memcpy (linksym + 1, name, name_len);
8321 memcpy (linksym + 1 + name_len, "..lk", 5);
8322 al->linkage = gen_rtx_SYMBOL_REF (Pmode,
8323 ggc_alloc_string (linksym, name_len + 5));
8324 }
8325
8326 splay_tree_insert (alpha_links_tree, (splay_tree_key) name,
8327 (splay_tree_value) al);
8328
8329 return al->linkage;
8330 }
8331
8332 rtx
8333 alpha_use_linkage (rtx linkage, tree cfundecl, int lflag, int rflag)
8334 {
8335 splay_tree_node cfunnode;
8336 struct alpha_funcs *cfaf;
8337 struct alpha_links *al;
8338 const char *name = XSTR (linkage, 0);
8339
8340 cfaf = (struct alpha_funcs *) 0;
8341 al = (struct alpha_links *) 0;
8342
8343 cfunnode = splay_tree_lookup (alpha_funcs_tree, (splay_tree_key) cfundecl);
8344 cfaf = (struct alpha_funcs *) cfunnode->value;
8345
8346 if (cfaf->links)
8347 {
8348 splay_tree_node lnode;
8349
8350 /* Is this name already defined? */
8351
8352 lnode = splay_tree_lookup (cfaf->links, (splay_tree_key) name);
8353 if (lnode)
8354 al = (struct alpha_links *) lnode->value;
8355 }
8356 else
8357 cfaf->links = splay_tree_new_ggc ((splay_tree_compare_fn) strcmp);
8358
8359 if (!al)
8360 {
8361 size_t name_len;
8362 size_t buflen;
8363 char buf [512];
8364 char *linksym;
8365 splay_tree_node node = 0;
8366 struct alpha_links *anl;
8367
8368 if (name[0] == '*')
8369 name++;
8370
8371 name_len = strlen (name);
8372
8373 al = (struct alpha_links *) ggc_alloc (sizeof (struct alpha_links));
8374 al->num = cfaf->num;
8375
8376 node = splay_tree_lookup (alpha_links_tree, (splay_tree_key) name);
8377 if (node)
8378 {
8379 anl = (struct alpha_links *) node->value;
8380 al->lkind = anl->lkind;
8381 }
8382
8383 sprintf (buf, "$%d..%s..lk", cfaf->num, name);
8384 buflen = strlen (buf);
8385 linksym = alloca (buflen + 1);
8386 memcpy (linksym, buf, buflen + 1);
8387
8388 al->linkage = gen_rtx_SYMBOL_REF
8389 (Pmode, ggc_alloc_string (linksym, buflen + 1));
8390
8391 splay_tree_insert (cfaf->links, (splay_tree_key) name,
8392 (splay_tree_value) al);
8393 }
8394
8395 if (rflag)
8396 al->rkind = KIND_CODEADDR;
8397 else
8398 al->rkind = KIND_LINKAGE;
8399
8400 if (lflag)
8401 return gen_rtx_MEM (Pmode, plus_constant (al->linkage, 8));
8402 else
8403 return al->linkage;
8404 }
8405
8406 static int
8407 alpha_write_one_linkage (splay_tree_node node, void *data)
8408 {
8409 const char *const name = (const char *) node->key;
8410 struct alpha_links *link = (struct alpha_links *) node->value;
8411 FILE *stream = (FILE *) data;
8412
8413 fprintf (stream, "$%d..%s..lk:\n", link->num, name);
8414 if (link->rkind == KIND_CODEADDR)
8415 {
8416 if (link->lkind == KIND_LOCAL)
8417 {
8418 /* Local and used */
8419 fprintf (stream, "\t.quad %s..en\n", name);
8420 }
8421 else
8422 {
8423 /* External and used, request code address. */
8424 fprintf (stream, "\t.code_address %s\n", name);
8425 }
8426 }
8427 else
8428 {
8429 if (link->lkind == KIND_LOCAL)
8430 {
8431 /* Local and used, build linkage pair. */
8432 fprintf (stream, "\t.quad %s..en\n", name);
8433 fprintf (stream, "\t.quad %s\n", name);
8434 }
8435 else
8436 {
8437 /* External and used, request linkage pair. */
8438 fprintf (stream, "\t.linkage %s\n", name);
8439 }
8440 }
8441
8442 return 0;
8443 }
8444
8445 static void
8446 alpha_write_linkage (FILE *stream, const char *funname, tree fundecl)
8447 {
8448 splay_tree_node node;
8449 struct alpha_funcs *func;
8450
8451 link_section ();
8452 fprintf (stream, "\t.align 3\n");
8453 node = splay_tree_lookup (alpha_funcs_tree, (splay_tree_key) fundecl);
8454 func = (struct alpha_funcs *) node->value;
8455
8456 fputs ("\t.name ", stream);
8457 assemble_name (stream, funname);
8458 fputs ("..na\n", stream);
8459 ASM_OUTPUT_LABEL (stream, funname);
8460 fprintf (stream, "\t.pdesc ");
8461 assemble_name (stream, funname);
8462 fprintf (stream, "..en,%s\n",
8463 alpha_procedure_type == PT_STACK ? "stack"
8464 : alpha_procedure_type == PT_REGISTER ? "reg" : "null");
8465
8466 if (func->links)
8467 {
8468 splay_tree_foreach (func->links, alpha_write_one_linkage, stream);
8469 /* splay_tree_delete (func->links); */
8470 }
8471 }
8472
8473 /* Given a decl, a section name, and whether the decl initializer
8474 has relocs, choose attributes for the section. */
8475
8476 #define SECTION_VMS_OVERLAY SECTION_FORGET
8477 #define SECTION_VMS_GLOBAL SECTION_MACH_DEP
8478 #define SECTION_VMS_INITIALIZE (SECTION_VMS_GLOBAL << 1)
8479
8480 static unsigned int
8481 vms_section_type_flags (tree decl, const char *name, int reloc)
8482 {
8483 unsigned int flags = default_section_type_flags (decl, name, reloc);
8484
8485 if (decl && DECL_ATTRIBUTES (decl)
8486 && lookup_attribute ("overlaid", DECL_ATTRIBUTES (decl)))
8487 flags |= SECTION_VMS_OVERLAY;
8488 if (decl && DECL_ATTRIBUTES (decl)
8489 && lookup_attribute ("global", DECL_ATTRIBUTES (decl)))
8490 flags |= SECTION_VMS_GLOBAL;
8491 if (decl && DECL_ATTRIBUTES (decl)
8492 && lookup_attribute ("initialize", DECL_ATTRIBUTES (decl)))
8493 flags |= SECTION_VMS_INITIALIZE;
8494
8495 return flags;
8496 }
8497
8498 /* Switch to an arbitrary section NAME with attributes as specified
8499 by FLAGS. ALIGN specifies any known alignment requirements for
8500 the section; 0 if the default should be used. */
8501
8502 static void
8503 vms_asm_named_section (const char *name, unsigned int flags,
8504 tree decl ATTRIBUTE_UNUSED)
8505 {
8506 fputc ('\n', asm_out_file);
8507 fprintf (asm_out_file, ".section\t%s", name);
8508
8509 if (flags & SECTION_VMS_OVERLAY)
8510 fprintf (asm_out_file, ",OVR");
8511 if (flags & SECTION_VMS_GLOBAL)
8512 fprintf (asm_out_file, ",GBL");
8513 if (flags & SECTION_VMS_INITIALIZE)
8514 fprintf (asm_out_file, ",NOMOD");
8515 if (flags & SECTION_DEBUG)
8516 fprintf (asm_out_file, ",NOWRT");
8517
8518 fputc ('\n', asm_out_file);
8519 }
8520
8521 /* Record an element in the table of global constructors. SYMBOL is
8522 a SYMBOL_REF of the function to be called; PRIORITY is a number
8523 between 0 and MAX_INIT_PRIORITY.
8524
8525 Differs from default_ctors_section_asm_out_constructor in that the
8526 width of the .ctors entry is always 64 bits, rather than the 32 bits
8527 used by a normal pointer. */
8528
8529 static void
8530 vms_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
8531 {
8532 ctors_section ();
8533 assemble_align (BITS_PER_WORD);
8534 assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
8535 }
8536
8537 static void
8538 vms_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
8539 {
8540 dtors_section ();
8541 assemble_align (BITS_PER_WORD);
8542 assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
8543 }
8544 #else
8545
8546 rtx
8547 alpha_need_linkage (const char *name ATTRIBUTE_UNUSED,
8548 int is_local ATTRIBUTE_UNUSED)
8549 {
8550 return NULL_RTX;
8551 }
8552
8553 rtx
8554 alpha_use_linkage (rtx linkage ATTRIBUTE_UNUSED,
8555 tree cfundecl ATTRIBUTE_UNUSED,
8556 int lflag ATTRIBUTE_UNUSED,
8557 int rflag ATTRIBUTE_UNUSED)
8558 {
8559 return NULL_RTX;
8560 }
8561
8562 #endif /* TARGET_ABI_OPEN_VMS */
8563 \f
8564 #if TARGET_ABI_UNICOSMK
8565
8566 /* This evaluates to true if we do not know how to pass TYPE solely in
8567 registers. This is the case for all arguments that do not fit in two
8568 registers. */
8569
8570 static bool
8571 unicosmk_must_pass_in_stack (enum machine_mode mode, tree type)
8572 {
8573 if (type == NULL)
8574 return false;
8575
8576 if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
8577 return true;
8578 if (TREE_ADDRESSABLE (type))
8579 return true;
8580
8581 return ALPHA_ARG_SIZE (mode, type, 0) > 2;
8582 }
8583
8584 /* Define the offset between two registers, one to be eliminated, and the
8585 other its replacement, at the start of a routine. */
8586
8587 int
8588 unicosmk_initial_elimination_offset (int from, int to)
8589 {
8590 int fixed_size;
8591
8592 fixed_size = alpha_sa_size();
8593 if (fixed_size != 0)
8594 fixed_size += 48;
8595
8596 if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
8597 return -fixed_size;
8598 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
8599 return 0;
8600 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
8601 return (ALPHA_ROUND (current_function_outgoing_args_size)
8602 + ALPHA_ROUND (get_frame_size()));
8603 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
8604 return (ALPHA_ROUND (fixed_size)
8605 + ALPHA_ROUND (get_frame_size()
8606 + current_function_outgoing_args_size));
8607 else
8608 abort ();
8609 }
8610
8611 /* Output the module name for .ident and .end directives. We have to strip
8612 directories and add make sure that the module name starts with a letter
8613 or '$'. */
8614
8615 static void
8616 unicosmk_output_module_name (FILE *file)
8617 {
8618 const char *name = lbasename (main_input_filename);
8619 unsigned len = strlen (name);
8620 char *clean_name = alloca (len + 2);
8621 char *ptr = clean_name;
8622
8623 /* CAM only accepts module names that start with a letter or '$'. We
8624 prefix the module name with a '$' if necessary. */
8625
8626 if (!ISALPHA (*name))
8627 *ptr++ = '$';
8628 memcpy (ptr, name, len + 1);
8629 clean_symbol_name (clean_name);
8630 fputs (clean_name, file);
8631 }
8632
8633 /* Output the definition of a common variable. */
8634
8635 void
8636 unicosmk_output_common (FILE *file, const char *name, int size, int align)
8637 {
8638 tree name_tree;
8639 printf ("T3E__: common %s\n", name);
8640
8641 common_section ();
8642 fputs("\t.endp\n\n\t.psect ", file);
8643 assemble_name(file, name);
8644 fprintf(file, ",%d,common\n", floor_log2 (align / BITS_PER_UNIT));
8645 fprintf(file, "\t.byte\t0:%d\n", size);
8646
8647 /* Mark the symbol as defined in this module. */
8648 name_tree = get_identifier (name);
8649 TREE_ASM_WRITTEN (name_tree) = 1;
8650 }
8651
8652 #define SECTION_PUBLIC SECTION_MACH_DEP
8653 #define SECTION_MAIN (SECTION_PUBLIC << 1)
8654 static int current_section_align;
8655
8656 static unsigned int
8657 unicosmk_section_type_flags (tree decl, const char *name,
8658 int reloc ATTRIBUTE_UNUSED)
8659 {
8660 unsigned int flags = default_section_type_flags (decl, name, reloc);
8661
8662 if (!decl)
8663 return flags;
8664
8665 if (TREE_CODE (decl) == FUNCTION_DECL)
8666 {
8667 current_section_align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
8668 if (align_functions_log > current_section_align)
8669 current_section_align = align_functions_log;
8670
8671 if (! strcmp (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), "main"))
8672 flags |= SECTION_MAIN;
8673 }
8674 else
8675 current_section_align = floor_log2 (DECL_ALIGN (decl) / BITS_PER_UNIT);
8676
8677 if (TREE_PUBLIC (decl))
8678 flags |= SECTION_PUBLIC;
8679
8680 return flags;
8681 }
8682
8683 /* Generate a section name for decl and associate it with the
8684 declaration. */
8685
8686 static void
8687 unicosmk_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
8688 {
8689 const char *name;
8690 int len;
8691
8692 if (!decl)
8693 abort ();
8694
8695 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
8696 name = default_strip_name_encoding (name);
8697 len = strlen (name);
8698
8699 if (TREE_CODE (decl) == FUNCTION_DECL)
8700 {
8701 char *string;
8702
8703 /* It is essential that we prefix the section name here because
8704 otherwise the section names generated for constructors and
8705 destructors confuse collect2. */
8706
8707 string = alloca (len + 6);
8708 sprintf (string, "code@%s", name);
8709 DECL_SECTION_NAME (decl) = build_string (len + 5, string);
8710 }
8711 else if (TREE_PUBLIC (decl))
8712 DECL_SECTION_NAME (decl) = build_string (len, name);
8713 else
8714 {
8715 char *string;
8716
8717 string = alloca (len + 6);
8718 sprintf (string, "data@%s", name);
8719 DECL_SECTION_NAME (decl) = build_string (len + 5, string);
8720 }
8721 }
8722
8723 /* Switch to an arbitrary section NAME with attributes as specified
8724 by FLAGS. ALIGN specifies any known alignment requirements for
8725 the section; 0 if the default should be used. */
8726
8727 static void
8728 unicosmk_asm_named_section (const char *name, unsigned int flags,
8729 tree decl ATTRIBUTE_UNUSED)
8730 {
8731 const char *kind;
8732
8733 /* Close the previous section. */
8734
8735 fputs ("\t.endp\n\n", asm_out_file);
8736
8737 /* Find out what kind of section we are opening. */
8738
8739 if (flags & SECTION_MAIN)
8740 fputs ("\t.start\tmain\n", asm_out_file);
8741
8742 if (flags & SECTION_CODE)
8743 kind = "code";
8744 else if (flags & SECTION_PUBLIC)
8745 kind = "common";
8746 else
8747 kind = "data";
8748
8749 if (current_section_align != 0)
8750 fprintf (asm_out_file, "\t.psect\t%s,%d,%s\n", name,
8751 current_section_align, kind);
8752 else
8753 fprintf (asm_out_file, "\t.psect\t%s,%s\n", name, kind);
8754 }
8755
8756 static void
8757 unicosmk_insert_attributes (tree decl, tree *attr_ptr ATTRIBUTE_UNUSED)
8758 {
8759 if (DECL_P (decl)
8760 && (TREE_PUBLIC (decl) || TREE_CODE (decl) == FUNCTION_DECL))
8761 unicosmk_unique_section (decl, 0);
8762 }
8763
8764 /* Output an alignment directive. We have to use the macro 'gcc@code@align'
8765 in code sections because .align fill unused space with zeroes. */
8766
8767 void
8768 unicosmk_output_align (FILE *file, int align)
8769 {
8770 if (inside_function)
8771 fprintf (file, "\tgcc@code@align\t%d\n", align);
8772 else
8773 fprintf (file, "\t.align\t%d\n", align);
8774 }
8775
8776 /* Add a case vector to the current function's list of deferred case
8777 vectors. Case vectors have to be put into a separate section because CAM
8778 does not allow data definitions in code sections. */
8779
8780 void
8781 unicosmk_defer_case_vector (rtx lab, rtx vec)
8782 {
8783 struct machine_function *machine = cfun->machine;
8784
8785 vec = gen_rtx_EXPR_LIST (VOIDmode, lab, vec);
8786 machine->addr_list = gen_rtx_EXPR_LIST (VOIDmode, vec,
8787 machine->addr_list);
8788 }
8789
8790 /* Output a case vector. */
8791
8792 static void
8793 unicosmk_output_addr_vec (FILE *file, rtx vec)
8794 {
8795 rtx lab = XEXP (vec, 0);
8796 rtx body = XEXP (vec, 1);
8797 int vlen = XVECLEN (body, 0);
8798 int idx;
8799
8800 (*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (lab));
8801
8802 for (idx = 0; idx < vlen; idx++)
8803 {
8804 ASM_OUTPUT_ADDR_VEC_ELT
8805 (file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0)));
8806 }
8807 }
8808
8809 /* Output current function's deferred case vectors. */
8810
8811 static void
8812 unicosmk_output_deferred_case_vectors (FILE *file)
8813 {
8814 struct machine_function *machine = cfun->machine;
8815 rtx t;
8816
8817 if (machine->addr_list == NULL_RTX)
8818 return;
8819
8820 data_section ();
8821 for (t = machine->addr_list; t; t = XEXP (t, 1))
8822 unicosmk_output_addr_vec (file, XEXP (t, 0));
8823 }
8824
8825 /* Generate the name of the SSIB section for the current function. */
8826
8827 #define SSIB_PREFIX "__SSIB_"
8828 #define SSIB_PREFIX_LEN 7
8829
8830 static const char *
8831 unicosmk_ssib_name (void)
8832 {
8833 /* This is ok since CAM won't be able to deal with names longer than that
8834 anyway. */
8835
8836 static char name[256];
8837
8838 rtx x;
8839 const char *fnname;
8840 int len;
8841
8842 x = DECL_RTL (cfun->decl);
8843 if (GET_CODE (x) != MEM)
8844 abort ();
8845 x = XEXP (x, 0);
8846 if (GET_CODE (x) != SYMBOL_REF)
8847 abort ();
8848 fnname = XSTR (x, 0);
8849
8850 len = strlen (fnname);
8851 if (len + SSIB_PREFIX_LEN > 255)
8852 len = 255 - SSIB_PREFIX_LEN;
8853
8854 strcpy (name, SSIB_PREFIX);
8855 strncpy (name + SSIB_PREFIX_LEN, fnname, len);
8856 name[len + SSIB_PREFIX_LEN] = 0;
8857
8858 return name;
8859 }
8860
8861 /* Set up the dynamic subprogram information block (DSIB) and update the
8862 frame pointer register ($15) for subroutines which have a frame. If the
8863 subroutine doesn't have a frame, simply increment $15. */
8864
8865 static void
8866 unicosmk_gen_dsib (unsigned long *imaskP)
8867 {
8868 if (alpha_procedure_type == PT_STACK)
8869 {
8870 const char *ssib_name;
8871 rtx mem;
8872
8873 /* Allocate 64 bytes for the DSIB. */
8874
8875 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
8876 GEN_INT (-64))));
8877 emit_insn (gen_blockage ());
8878
8879 /* Save the return address. */
8880
8881 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 56));
8882 set_mem_alias_set (mem, alpha_sr_alias_set);
8883 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
8884 (*imaskP) &= ~(1UL << REG_RA);
8885
8886 /* Save the old frame pointer. */
8887
8888 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 48));
8889 set_mem_alias_set (mem, alpha_sr_alias_set);
8890 FRP (emit_move_insn (mem, hard_frame_pointer_rtx));
8891 (*imaskP) &= ~(1UL << HARD_FRAME_POINTER_REGNUM);
8892
8893 emit_insn (gen_blockage ());
8894
8895 /* Store the SSIB pointer. */
8896
8897 ssib_name = ggc_strdup (unicosmk_ssib_name ());
8898 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 32));
8899 set_mem_alias_set (mem, alpha_sr_alias_set);
8900
8901 FRP (emit_move_insn (gen_rtx_REG (DImode, 5),
8902 gen_rtx_SYMBOL_REF (Pmode, ssib_name)));
8903 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, 5)));
8904
8905 /* Save the CIW index. */
8906
8907 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 24));
8908 set_mem_alias_set (mem, alpha_sr_alias_set);
8909 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, 25)));
8910
8911 emit_insn (gen_blockage ());
8912
8913 /* Set the new frame pointer. */
8914
8915 FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
8916 stack_pointer_rtx, GEN_INT (64))));
8917
8918 }
8919 else
8920 {
8921 /* Increment the frame pointer register to indicate that we do not
8922 have a frame. */
8923
8924 FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
8925 hard_frame_pointer_rtx, const1_rtx)));
8926 }
8927 }
8928
8929 /* Output the static subroutine information block for the current
8930 function. */
8931
8932 static void
8933 unicosmk_output_ssib (FILE *file, const char *fnname)
8934 {
8935 int len;
8936 int i;
8937 rtx x;
8938 rtx ciw;
8939 struct machine_function *machine = cfun->machine;
8940
8941 ssib_section ();
8942 fprintf (file, "\t.endp\n\n\t.psect\t%s%s,data\n", user_label_prefix,
8943 unicosmk_ssib_name ());
8944
8945 /* Some required stuff and the function name length. */
8946
8947 len = strlen (fnname);
8948 fprintf (file, "\t.quad\t^X20008%2.2X28\n", len);
8949
8950 /* Saved registers
8951 ??? We don't do that yet. */
8952
8953 fputs ("\t.quad\t0\n", file);
8954
8955 /* Function address. */
8956
8957 fputs ("\t.quad\t", file);
8958 assemble_name (file, fnname);
8959 putc ('\n', file);
8960
8961 fputs ("\t.quad\t0\n", file);
8962 fputs ("\t.quad\t0\n", file);
8963
8964 /* Function name.
8965 ??? We do it the same way Cray CC does it but this could be
8966 simplified. */
8967
8968 for( i = 0; i < len; i++ )
8969 fprintf (file, "\t.byte\t%d\n", (int)(fnname[i]));
8970 if( (len % 8) == 0 )
8971 fputs ("\t.quad\t0\n", file);
8972 else
8973 fprintf (file, "\t.bits\t%d : 0\n", (8 - (len % 8))*8);
8974
8975 /* All call information words used in the function. */
8976
8977 for (x = machine->first_ciw; x; x = XEXP (x, 1))
8978 {
8979 ciw = XEXP (x, 0);
8980 #if HOST_BITS_PER_WIDE_INT == 32
8981 fprintf (file, "\t.quad\t" HOST_WIDE_INT_PRINT_DOUBLE_HEX "\n",
8982 CONST_DOUBLE_HIGH (ciw), CONST_DOUBLE_LOW (ciw));
8983 #else
8984 fprintf (file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n", INTVAL (ciw));
8985 #endif
8986 }
8987 }
8988
8989 /* Add a call information word (CIW) to the list of the current function's
8990 CIWs and return its index.
8991
8992 X is a CONST_INT or CONST_DOUBLE representing the CIW. */
8993
8994 rtx
8995 unicosmk_add_call_info_word (rtx x)
8996 {
8997 rtx node;
8998 struct machine_function *machine = cfun->machine;
8999
9000 node = gen_rtx_EXPR_LIST (VOIDmode, x, NULL_RTX);
9001 if (machine->first_ciw == NULL_RTX)
9002 machine->first_ciw = node;
9003 else
9004 XEXP (machine->last_ciw, 1) = node;
9005
9006 machine->last_ciw = node;
9007 ++machine->ciw_count;
9008
9009 return GEN_INT (machine->ciw_count
9010 + strlen (current_function_name ())/8 + 5);
9011 }
9012
9013 static char unicosmk_section_buf[100];
9014
9015 char *
9016 unicosmk_text_section (void)
9017 {
9018 static int count = 0;
9019 sprintf (unicosmk_section_buf, "\t.endp\n\n\t.psect\tgcc@text___%d,code",
9020 count++);
9021 return unicosmk_section_buf;
9022 }
9023
9024 char *
9025 unicosmk_data_section (void)
9026 {
9027 static int count = 1;
9028 sprintf (unicosmk_section_buf, "\t.endp\n\n\t.psect\tgcc@data___%d,data",
9029 count++);
9030 return unicosmk_section_buf;
9031 }
9032
9033 /* The Cray assembler doesn't accept extern declarations for symbols which
9034 are defined in the same file. We have to keep track of all global
9035 symbols which are referenced and/or defined in a source file and output
9036 extern declarations for those which are referenced but not defined at
9037 the end of file. */
9038
9039 /* List of identifiers for which an extern declaration might have to be
9040 emitted. */
9041 /* FIXME: needs to use GC, so it can be saved and restored for PCH. */
9042
9043 struct unicosmk_extern_list
9044 {
9045 struct unicosmk_extern_list *next;
9046 const char *name;
9047 };
9048
9049 static struct unicosmk_extern_list *unicosmk_extern_head = 0;
9050
9051 /* Output extern declarations which are required for every asm file. */
9052
9053 static void
9054 unicosmk_output_default_externs (FILE *file)
9055 {
9056 static const char *const externs[] =
9057 { "__T3E_MISMATCH" };
9058
9059 int i;
9060 int n;
9061
9062 n = ARRAY_SIZE (externs);
9063
9064 for (i = 0; i < n; i++)
9065 fprintf (file, "\t.extern\t%s\n", externs[i]);
9066 }
9067
9068 /* Output extern declarations for global symbols which are have been
9069 referenced but not defined. */
9070
9071 static void
9072 unicosmk_output_externs (FILE *file)
9073 {
9074 struct unicosmk_extern_list *p;
9075 const char *real_name;
9076 int len;
9077 tree name_tree;
9078
9079 len = strlen (user_label_prefix);
9080 for (p = unicosmk_extern_head; p != 0; p = p->next)
9081 {
9082 /* We have to strip the encoding and possibly remove user_label_prefix
9083 from the identifier in order to handle -fleading-underscore and
9084 explicit asm names correctly (cf. gcc.dg/asm-names-1.c). */
9085 real_name = default_strip_name_encoding (p->name);
9086 if (len && p->name[0] == '*'
9087 && !memcmp (real_name, user_label_prefix, len))
9088 real_name += len;
9089
9090 name_tree = get_identifier (real_name);
9091 if (! TREE_ASM_WRITTEN (name_tree))
9092 {
9093 TREE_ASM_WRITTEN (name_tree) = 1;
9094 fputs ("\t.extern\t", file);
9095 assemble_name (file, p->name);
9096 putc ('\n', file);
9097 }
9098 }
9099 }
9100
9101 /* Record an extern. */
9102
9103 void
9104 unicosmk_add_extern (const char *name)
9105 {
9106 struct unicosmk_extern_list *p;
9107
9108 p = (struct unicosmk_extern_list *)
9109 xmalloc (sizeof (struct unicosmk_extern_list));
9110 p->next = unicosmk_extern_head;
9111 p->name = name;
9112 unicosmk_extern_head = p;
9113 }
9114
9115 /* The Cray assembler generates incorrect code if identifiers which
9116 conflict with register names are used as instruction operands. We have
9117 to replace such identifiers with DEX expressions. */
9118
9119 /* Structure to collect identifiers which have been replaced by DEX
9120 expressions. */
9121 /* FIXME: needs to use GC, so it can be saved and restored for PCH. */
9122
9123 struct unicosmk_dex {
9124 struct unicosmk_dex *next;
9125 const char *name;
9126 };
9127
9128 /* List of identifiers which have been replaced by DEX expressions. The DEX
9129 number is determined by the position in the list. */
9130
9131 static struct unicosmk_dex *unicosmk_dex_list = NULL;
9132
9133 /* The number of elements in the DEX list. */
9134
9135 static int unicosmk_dex_count = 0;
9136
9137 /* Check if NAME must be replaced by a DEX expression. */
9138
9139 static int
9140 unicosmk_special_name (const char *name)
9141 {
9142 if (name[0] == '*')
9143 ++name;
9144
9145 if (name[0] == '$')
9146 ++name;
9147
9148 if (name[0] != 'r' && name[0] != 'f' && name[0] != 'R' && name[0] != 'F')
9149 return 0;
9150
9151 switch (name[1])
9152 {
9153 case '1': case '2':
9154 return (name[2] == '\0' || (ISDIGIT (name[2]) && name[3] == '\0'));
9155
9156 case '3':
9157 return (name[2] == '\0'
9158 || ((name[2] == '0' || name[2] == '1') && name[3] == '\0'));
9159
9160 default:
9161 return (ISDIGIT (name[1]) && name[2] == '\0');
9162 }
9163 }
9164
9165 /* Return the DEX number if X must be replaced by a DEX expression and 0
9166 otherwise. */
9167
9168 static int
9169 unicosmk_need_dex (rtx x)
9170 {
9171 struct unicosmk_dex *dex;
9172 const char *name;
9173 int i;
9174
9175 if (GET_CODE (x) != SYMBOL_REF)
9176 return 0;
9177
9178 name = XSTR (x,0);
9179 if (! unicosmk_special_name (name))
9180 return 0;
9181
9182 i = unicosmk_dex_count;
9183 for (dex = unicosmk_dex_list; dex; dex = dex->next)
9184 {
9185 if (! strcmp (name, dex->name))
9186 return i;
9187 --i;
9188 }
9189
9190 dex = (struct unicosmk_dex *) xmalloc (sizeof (struct unicosmk_dex));
9191 dex->name = name;
9192 dex->next = unicosmk_dex_list;
9193 unicosmk_dex_list = dex;
9194
9195 ++unicosmk_dex_count;
9196 return unicosmk_dex_count;
9197 }
9198
9199 /* Output the DEX definitions for this file. */
9200
9201 static void
9202 unicosmk_output_dex (FILE *file)
9203 {
9204 struct unicosmk_dex *dex;
9205 int i;
9206
9207 if (unicosmk_dex_list == NULL)
9208 return;
9209
9210 fprintf (file, "\t.dexstart\n");
9211
9212 i = unicosmk_dex_count;
9213 for (dex = unicosmk_dex_list; dex; dex = dex->next)
9214 {
9215 fprintf (file, "\tDEX (%d) = ", i);
9216 assemble_name (file, dex->name);
9217 putc ('\n', file);
9218 --i;
9219 }
9220
9221 fprintf (file, "\t.dexend\n");
9222 }
9223
9224 /* Output text that to appear at the beginning of an assembler file. */
9225
9226 static void
9227 unicosmk_file_start (void)
9228 {
9229 int i;
9230
9231 fputs ("\t.ident\t", asm_out_file);
9232 unicosmk_output_module_name (asm_out_file);
9233 fputs ("\n\n", asm_out_file);
9234
9235 /* The Unicos/Mk assembler uses different register names. Instead of trying
9236 to support them, we simply use micro definitions. */
9237
9238 /* CAM has different register names: rN for the integer register N and fN
9239 for the floating-point register N. Instead of trying to use these in
9240 alpha.md, we define the symbols $N and $fN to refer to the appropriate
9241 register. */
9242
9243 for (i = 0; i < 32; ++i)
9244 fprintf (asm_out_file, "$%d <- r%d\n", i, i);
9245
9246 for (i = 0; i < 32; ++i)
9247 fprintf (asm_out_file, "$f%d <- f%d\n", i, i);
9248
9249 putc ('\n', asm_out_file);
9250
9251 /* The .align directive fill unused space with zeroes which does not work
9252 in code sections. We define the macro 'gcc@code@align' which uses nops
9253 instead. Note that it assumes that code sections always have the
9254 biggest possible alignment since . refers to the current offset from
9255 the beginning of the section. */
9256
9257 fputs ("\t.macro gcc@code@align n\n", asm_out_file);
9258 fputs ("gcc@n@bytes = 1 << n\n", asm_out_file);
9259 fputs ("gcc@here = . % gcc@n@bytes\n", asm_out_file);
9260 fputs ("\t.if ne, gcc@here, 0\n", asm_out_file);
9261 fputs ("\t.repeat (gcc@n@bytes - gcc@here) / 4\n", asm_out_file);
9262 fputs ("\tbis r31,r31,r31\n", asm_out_file);
9263 fputs ("\t.endr\n", asm_out_file);
9264 fputs ("\t.endif\n", asm_out_file);
9265 fputs ("\t.endm gcc@code@align\n\n", asm_out_file);
9266
9267 /* Output extern declarations which should always be visible. */
9268 unicosmk_output_default_externs (asm_out_file);
9269
9270 /* Open a dummy section. We always need to be inside a section for the
9271 section-switching code to work correctly.
9272 ??? This should be a module id or something like that. I still have to
9273 figure out what the rules for those are. */
9274 fputs ("\n\t.psect\t$SG00000,data\n", asm_out_file);
9275 }
9276
9277 /* Output text to appear at the end of an assembler file. This includes all
9278 pending extern declarations and DEX expressions. */
9279
9280 static void
9281 unicosmk_file_end (void)
9282 {
9283 fputs ("\t.endp\n\n", asm_out_file);
9284
9285 /* Output all pending externs. */
9286
9287 unicosmk_output_externs (asm_out_file);
9288
9289 /* Output dex definitions used for functions whose names conflict with
9290 register names. */
9291
9292 unicosmk_output_dex (asm_out_file);
9293
9294 fputs ("\t.end\t", asm_out_file);
9295 unicosmk_output_module_name (asm_out_file);
9296 putc ('\n', asm_out_file);
9297 }
9298
9299 #else
9300
9301 static void
9302 unicosmk_output_deferred_case_vectors (FILE *file ATTRIBUTE_UNUSED)
9303 {}
9304
9305 static void
9306 unicosmk_gen_dsib (unsigned long *imaskP ATTRIBUTE_UNUSED)
9307 {}
9308
9309 static void
9310 unicosmk_output_ssib (FILE * file ATTRIBUTE_UNUSED,
9311 const char * fnname ATTRIBUTE_UNUSED)
9312 {}
9313
9314 rtx
9315 unicosmk_add_call_info_word (rtx x ATTRIBUTE_UNUSED)
9316 {
9317 return NULL_RTX;
9318 }
9319
9320 static int
9321 unicosmk_need_dex (rtx x ATTRIBUTE_UNUSED)
9322 {
9323 return 0;
9324 }
9325
9326 #endif /* TARGET_ABI_UNICOSMK */
9327
9328 static void
9329 alpha_init_libfuncs (void)
9330 {
9331 if (TARGET_ABI_UNICOSMK)
9332 {
9333 /* Prevent gcc from generating calls to __divsi3. */
9334 set_optab_libfunc (sdiv_optab, SImode, 0);
9335 set_optab_libfunc (udiv_optab, SImode, 0);
9336
9337 /* Use the functions provided by the system library
9338 for DImode integer division. */
9339 set_optab_libfunc (sdiv_optab, DImode, "$sldiv");
9340 set_optab_libfunc (udiv_optab, DImode, "$uldiv");
9341 }
9342 else if (TARGET_ABI_OPEN_VMS)
9343 {
9344 /* Use the VMS runtime library functions for division and
9345 remainder. */
9346 set_optab_libfunc (sdiv_optab, SImode, "OTS$DIV_I");
9347 set_optab_libfunc (sdiv_optab, DImode, "OTS$DIV_L");
9348 set_optab_libfunc (udiv_optab, SImode, "OTS$DIV_UI");
9349 set_optab_libfunc (udiv_optab, DImode, "OTS$DIV_UL");
9350 set_optab_libfunc (smod_optab, SImode, "OTS$REM_I");
9351 set_optab_libfunc (smod_optab, DImode, "OTS$REM_L");
9352 set_optab_libfunc (umod_optab, SImode, "OTS$REM_UI");
9353 set_optab_libfunc (umod_optab, DImode, "OTS$REM_UL");
9354 }
9355 }
9356
9357 \f
9358 /* Initialize the GCC target structure. */
9359 #if TARGET_ABI_OPEN_VMS
9360 # undef TARGET_ATTRIBUTE_TABLE
9361 # define TARGET_ATTRIBUTE_TABLE vms_attribute_table
9362 # undef TARGET_SECTION_TYPE_FLAGS
9363 # define TARGET_SECTION_TYPE_FLAGS vms_section_type_flags
9364 #endif
9365
9366 #undef TARGET_IN_SMALL_DATA_P
9367 #define TARGET_IN_SMALL_DATA_P alpha_in_small_data_p
9368
9369 #if TARGET_ABI_UNICOSMK
9370 # undef TARGET_INSERT_ATTRIBUTES
9371 # define TARGET_INSERT_ATTRIBUTES unicosmk_insert_attributes
9372 # undef TARGET_SECTION_TYPE_FLAGS
9373 # define TARGET_SECTION_TYPE_FLAGS unicosmk_section_type_flags
9374 # undef TARGET_ASM_UNIQUE_SECTION
9375 # define TARGET_ASM_UNIQUE_SECTION unicosmk_unique_section
9376 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
9377 #define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
9378 # undef TARGET_ASM_GLOBALIZE_LABEL
9379 # define TARGET_ASM_GLOBALIZE_LABEL hook_void_FILEptr_constcharptr
9380 # undef TARGET_MUST_PASS_IN_STACK
9381 # define TARGET_MUST_PASS_IN_STACK unicosmk_must_pass_in_stack
9382 #endif
9383
9384 #undef TARGET_ASM_ALIGNED_HI_OP
9385 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
9386 #undef TARGET_ASM_ALIGNED_DI_OP
9387 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
9388
9389 /* Default unaligned ops are provided for ELF systems. To get unaligned
9390 data for non-ELF systems, we have to turn off auto alignment. */
9391 #ifndef OBJECT_FORMAT_ELF
9392 #undef TARGET_ASM_UNALIGNED_HI_OP
9393 #define TARGET_ASM_UNALIGNED_HI_OP "\t.align 0\n\t.word\t"
9394 #undef TARGET_ASM_UNALIGNED_SI_OP
9395 #define TARGET_ASM_UNALIGNED_SI_OP "\t.align 0\n\t.long\t"
9396 #undef TARGET_ASM_UNALIGNED_DI_OP
9397 #define TARGET_ASM_UNALIGNED_DI_OP "\t.align 0\n\t.quad\t"
9398 #endif
9399
9400 #ifdef OBJECT_FORMAT_ELF
9401 #undef TARGET_ASM_SELECT_RTX_SECTION
9402 #define TARGET_ASM_SELECT_RTX_SECTION alpha_elf_select_rtx_section
9403 #endif
9404
9405 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
9406 #define TARGET_ASM_FUNCTION_END_PROLOGUE alpha_output_function_end_prologue
9407
9408 #undef TARGET_INIT_LIBFUNCS
9409 #define TARGET_INIT_LIBFUNCS alpha_init_libfuncs
9410
9411 #if TARGET_ABI_UNICOSMK
9412 #undef TARGET_ASM_FILE_START
9413 #define TARGET_ASM_FILE_START unicosmk_file_start
9414 #undef TARGET_ASM_FILE_END
9415 #define TARGET_ASM_FILE_END unicosmk_file_end
9416 #else
9417 #undef TARGET_ASM_FILE_START
9418 #define TARGET_ASM_FILE_START alpha_file_start
9419 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
9420 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
9421 #endif
9422
9423 #undef TARGET_SCHED_ADJUST_COST
9424 #define TARGET_SCHED_ADJUST_COST alpha_adjust_cost
9425 #undef TARGET_SCHED_ISSUE_RATE
9426 #define TARGET_SCHED_ISSUE_RATE alpha_issue_rate
9427 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
9428 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
9429 alpha_multipass_dfa_lookahead
9430
9431 #undef TARGET_HAVE_TLS
9432 #define TARGET_HAVE_TLS HAVE_AS_TLS
9433
9434 #undef TARGET_INIT_BUILTINS
9435 #define TARGET_INIT_BUILTINS alpha_init_builtins
9436 #undef TARGET_EXPAND_BUILTIN
9437 #define TARGET_EXPAND_BUILTIN alpha_expand_builtin
9438
9439 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
9440 #define TARGET_FUNCTION_OK_FOR_SIBCALL alpha_function_ok_for_sibcall
9441 #undef TARGET_CANNOT_COPY_INSN_P
9442 #define TARGET_CANNOT_COPY_INSN_P alpha_cannot_copy_insn_p
9443 #undef TARGET_CANNOT_FORCE_CONST_MEM
9444 #define TARGET_CANNOT_FORCE_CONST_MEM alpha_cannot_force_const_mem
9445
9446 #if TARGET_ABI_OSF
9447 #undef TARGET_ASM_OUTPUT_MI_THUNK
9448 #define TARGET_ASM_OUTPUT_MI_THUNK alpha_output_mi_thunk_osf
9449 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
9450 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
9451 #endif
9452
9453 #undef TARGET_RTX_COSTS
9454 #define TARGET_RTX_COSTS alpha_rtx_costs
9455 #undef TARGET_ADDRESS_COST
9456 #define TARGET_ADDRESS_COST hook_int_rtx_0
9457
9458 #undef TARGET_MACHINE_DEPENDENT_REORG
9459 #define TARGET_MACHINE_DEPENDENT_REORG alpha_reorg
9460
9461 #undef TARGET_PROMOTE_FUNCTION_ARGS
9462 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
9463 #undef TARGET_PROMOTE_FUNCTION_RETURN
9464 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
9465 #undef TARGET_PROMOTE_PROTOTYPES
9466 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_false
9467 #undef TARGET_RETURN_IN_MEMORY
9468 #define TARGET_RETURN_IN_MEMORY alpha_return_in_memory
9469 #undef TARGET_PASS_BY_REFERENCE
9470 #define TARGET_PASS_BY_REFERENCE alpha_pass_by_reference
9471 #undef TARGET_SETUP_INCOMING_VARARGS
9472 #define TARGET_SETUP_INCOMING_VARARGS alpha_setup_incoming_varargs
9473 #undef TARGET_STRICT_ARGUMENT_NAMING
9474 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
9475 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
9476 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
9477 #undef TARGET_SPLIT_COMPLEX_ARG
9478 #define TARGET_SPLIT_COMPLEX_ARG alpha_split_complex_arg
9479 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
9480 #define TARGET_GIMPLIFY_VA_ARG_EXPR alpha_gimplify_va_arg
9481 #undef TARGET_ARG_PARTIAL_BYTES
9482 #define TARGET_ARG_PARTIAL_BYTES alpha_arg_partial_bytes
9483
9484 #undef TARGET_SCALAR_MODE_SUPPORTED_P
9485 #define TARGET_SCALAR_MODE_SUPPORTED_P alpha_scalar_mode_supported_p
9486 #undef TARGET_VECTOR_MODE_SUPPORTED_P
9487 #define TARGET_VECTOR_MODE_SUPPORTED_P alpha_vector_mode_supported_p
9488
9489 #undef TARGET_BUILD_BUILTIN_VA_LIST
9490 #define TARGET_BUILD_BUILTIN_VA_LIST alpha_build_builtin_va_list
9491
9492 /* The Alpha architecture does not require sequential consistency. See
9493 http://www.cs.umd.edu/~pugh/java/memoryModel/AlphaReordering.html
9494 for an example of how it can be violated in practice. */
9495 #undef TARGET_RELAXED_ORDERING
9496 #define TARGET_RELAXED_ORDERING true
9497
9498 struct gcc_target targetm = TARGET_INITIALIZER;
9499
9500 \f
9501 #include "gt-alpha.h"