unwind-dw2.c (_Unwind_GetGR): Honor DWARF_ZERO_REG.
[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 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 `%s' 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 `%s' 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 `%s' 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 `%s' 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 `%s' 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 `%s' 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 `%s' 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 /* Honor misaligned loads, for those we promised to do so. */
1986 if (GET_CODE (operands[1]) == MEM
1987 && alpha_vector_mode_supported_p (mode)
1988 && MEM_ALIGN (operands[1]) < GET_MODE_ALIGNMENT (mode))
1989 {
1990 rtx tmp;
1991 if (register_operand (operands[0], mode))
1992 tmp = operands[0];
1993 else
1994 tmp = gen_reg_rtx (mode);
1995 alpha_expand_unaligned_load (tmp, operands[1], 8, 0, 0);
1996 if (tmp == operands[0])
1997 return true;
1998 operands[1] = tmp;
1999 }
2000
2001 /* If the output is not a register, the input must be. */
2002 if (GET_CODE (operands[0]) == MEM
2003 && ! reg_or_0_operand (operands[1], mode))
2004 operands[1] = force_reg (mode, operands[1]);
2005
2006 /* Honor misaligned stores, for those we promised to do so. */
2007 if (GET_CODE (operands[0]) == MEM
2008 && alpha_vector_mode_supported_p (mode)
2009 && MEM_ALIGN (operands[0]) < GET_MODE_ALIGNMENT (mode))
2010 {
2011 alpha_expand_unaligned_store (operands[0], operands[1], 8, 0);
2012 return true;
2013 }
2014
2015 /* Allow legitimize_address to perform some simplifications. */
2016 if (mode == Pmode && symbolic_operand (operands[1], mode))
2017 {
2018 rtx tmp;
2019
2020 tmp = alpha_legitimize_address (operands[1], operands[0], mode);
2021 if (tmp)
2022 {
2023 if (tmp == operands[0])
2024 return true;
2025 operands[1] = tmp;
2026 return false;
2027 }
2028 }
2029
2030 /* Early out for non-constants and valid constants. */
2031 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], mode))
2032 return false;
2033
2034 /* Split large integers. */
2035 if (GET_CODE (operands[1]) == CONST_INT
2036 || GET_CODE (operands[1]) == CONST_DOUBLE)
2037 {
2038 HOST_WIDE_INT i0, i1;
2039 rtx temp = NULL_RTX;
2040
2041 if (GET_CODE (operands[1]) == CONST_INT)
2042 {
2043 i0 = INTVAL (operands[1]);
2044 i1 = -(i0 < 0);
2045 }
2046 else if (HOST_BITS_PER_WIDE_INT >= 64)
2047 {
2048 i0 = CONST_DOUBLE_LOW (operands[1]);
2049 i1 = -(i0 < 0);
2050 }
2051 else
2052 {
2053 i0 = CONST_DOUBLE_LOW (operands[1]);
2054 i1 = CONST_DOUBLE_HIGH (operands[1]);
2055 }
2056
2057 if (HOST_BITS_PER_WIDE_INT >= 64 || i1 == -(i0 < 0))
2058 temp = alpha_emit_set_const (operands[0], mode, i0, 3);
2059
2060 if (!temp && TARGET_BUILD_CONSTANTS)
2061 temp = alpha_emit_set_long_const (operands[0], i0, i1);
2062
2063 if (temp)
2064 {
2065 if (rtx_equal_p (operands[0], temp))
2066 return true;
2067 operands[1] = temp;
2068 return false;
2069 }
2070 }
2071
2072 /* Otherwise we've nothing left but to drop the thing to memory. */
2073 operands[1] = force_const_mem (mode, operands[1]);
2074 if (reload_in_progress)
2075 {
2076 emit_move_insn (operands[0], XEXP (operands[1], 0));
2077 operands[1] = copy_rtx (operands[1]);
2078 XEXP (operands[1], 0) = operands[0];
2079 }
2080 else
2081 operands[1] = validize_mem (operands[1]);
2082 return false;
2083 }
2084
2085 /* Expand a non-bwx QImode or HImode move instruction;
2086 return true if all work is done. */
2087
2088 bool
2089 alpha_expand_mov_nobwx (enum machine_mode mode, rtx *operands)
2090 {
2091 /* If the output is not a register, the input must be. */
2092 if (GET_CODE (operands[0]) == MEM)
2093 operands[1] = force_reg (mode, operands[1]);
2094
2095 /* Handle four memory cases, unaligned and aligned for either the input
2096 or the output. The only case where we can be called during reload is
2097 for aligned loads; all other cases require temporaries. */
2098
2099 if (GET_CODE (operands[1]) == MEM
2100 || (GET_CODE (operands[1]) == SUBREG
2101 && GET_CODE (SUBREG_REG (operands[1])) == MEM)
2102 || (reload_in_progress && GET_CODE (operands[1]) == REG
2103 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
2104 || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
2105 && GET_CODE (SUBREG_REG (operands[1])) == REG
2106 && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
2107 {
2108 if (aligned_memory_operand (operands[1], mode))
2109 {
2110 if (reload_in_progress)
2111 {
2112 emit_insn ((mode == QImode
2113 ? gen_reload_inqi_help
2114 : gen_reload_inhi_help)
2115 (operands[0], operands[1],
2116 gen_rtx_REG (SImode, REGNO (operands[0]))));
2117 }
2118 else
2119 {
2120 rtx aligned_mem, bitnum;
2121 rtx scratch = gen_reg_rtx (SImode);
2122 rtx subtarget;
2123 bool copyout;
2124
2125 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
2126
2127 subtarget = operands[0];
2128 if (GET_CODE (subtarget) == REG)
2129 subtarget = gen_lowpart (DImode, subtarget), copyout = false;
2130 else
2131 subtarget = gen_reg_rtx (DImode), copyout = true;
2132
2133 emit_insn ((mode == QImode
2134 ? gen_aligned_loadqi
2135 : gen_aligned_loadhi)
2136 (subtarget, aligned_mem, bitnum, scratch));
2137
2138 if (copyout)
2139 emit_move_insn (operands[0], gen_lowpart (mode, subtarget));
2140 }
2141 }
2142 else
2143 {
2144 /* Don't pass these as parameters since that makes the generated
2145 code depend on parameter evaluation order which will cause
2146 bootstrap failures. */
2147
2148 rtx temp1, temp2, seq, subtarget;
2149 bool copyout;
2150
2151 temp1 = gen_reg_rtx (DImode);
2152 temp2 = gen_reg_rtx (DImode);
2153
2154 subtarget = operands[0];
2155 if (GET_CODE (subtarget) == REG)
2156 subtarget = gen_lowpart (DImode, subtarget), copyout = false;
2157 else
2158 subtarget = gen_reg_rtx (DImode), copyout = true;
2159
2160 seq = ((mode == QImode
2161 ? gen_unaligned_loadqi
2162 : gen_unaligned_loadhi)
2163 (subtarget, get_unaligned_address (operands[1], 0),
2164 temp1, temp2));
2165 alpha_set_memflags (seq, operands[1]);
2166 emit_insn (seq);
2167
2168 if (copyout)
2169 emit_move_insn (operands[0], gen_lowpart (mode, subtarget));
2170 }
2171 return true;
2172 }
2173
2174 if (GET_CODE (operands[0]) == MEM
2175 || (GET_CODE (operands[0]) == SUBREG
2176 && GET_CODE (SUBREG_REG (operands[0])) == MEM)
2177 || (reload_in_progress && GET_CODE (operands[0]) == REG
2178 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
2179 || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
2180 && GET_CODE (SUBREG_REG (operands[0])) == REG
2181 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
2182 {
2183 if (aligned_memory_operand (operands[0], mode))
2184 {
2185 rtx aligned_mem, bitnum;
2186 rtx temp1 = gen_reg_rtx (SImode);
2187 rtx temp2 = gen_reg_rtx (SImode);
2188
2189 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
2190
2191 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
2192 temp1, temp2));
2193 }
2194 else
2195 {
2196 rtx temp1 = gen_reg_rtx (DImode);
2197 rtx temp2 = gen_reg_rtx (DImode);
2198 rtx temp3 = gen_reg_rtx (DImode);
2199 rtx seq = ((mode == QImode
2200 ? gen_unaligned_storeqi
2201 : gen_unaligned_storehi)
2202 (get_unaligned_address (operands[0], 0),
2203 operands[1], temp1, temp2, temp3));
2204
2205 alpha_set_memflags (seq, operands[0]);
2206 emit_insn (seq);
2207 }
2208 return true;
2209 }
2210
2211 return false;
2212 }
2213
2214 /* Generate an unsigned DImode to FP conversion. This is the same code
2215 optabs would emit if we didn't have TFmode patterns.
2216
2217 For SFmode, this is the only construction I've found that can pass
2218 gcc.c-torture/execute/ieee/rbug.c. No scenario that uses DFmode
2219 intermediates will work, because you'll get intermediate rounding
2220 that ruins the end result. Some of this could be fixed by turning
2221 on round-to-positive-infinity, but that requires diddling the fpsr,
2222 which kills performance. I tried turning this around and converting
2223 to a negative number, so that I could turn on /m, but either I did
2224 it wrong or there's something else cause I wound up with the exact
2225 same single-bit error. There is a branch-less form of this same code:
2226
2227 srl $16,1,$1
2228 and $16,1,$2
2229 cmplt $16,0,$3
2230 or $1,$2,$2
2231 cmovge $16,$16,$2
2232 itoft $3,$f10
2233 itoft $2,$f11
2234 cvtqs $f11,$f11
2235 adds $f11,$f11,$f0
2236 fcmoveq $f10,$f11,$f0
2237
2238 I'm not using it because it's the same number of instructions as
2239 this branch-full form, and it has more serialized long latency
2240 instructions on the critical path.
2241
2242 For DFmode, we can avoid rounding errors by breaking up the word
2243 into two pieces, converting them separately, and adding them back:
2244
2245 LC0: .long 0,0x5f800000
2246
2247 itoft $16,$f11
2248 lda $2,LC0
2249 cmplt $16,0,$1
2250 cpyse $f11,$f31,$f10
2251 cpyse $f31,$f11,$f11
2252 s4addq $1,$2,$1
2253 lds $f12,0($1)
2254 cvtqt $f10,$f10
2255 cvtqt $f11,$f11
2256 addt $f12,$f10,$f0
2257 addt $f0,$f11,$f0
2258
2259 This doesn't seem to be a clear-cut win over the optabs form.
2260 It probably all depends on the distribution of numbers being
2261 converted -- in the optabs form, all but high-bit-set has a
2262 much lower minimum execution time. */
2263
2264 void
2265 alpha_emit_floatuns (rtx operands[2])
2266 {
2267 rtx neglab, donelab, i0, i1, f0, in, out;
2268 enum machine_mode mode;
2269
2270 out = operands[0];
2271 in = force_reg (DImode, operands[1]);
2272 mode = GET_MODE (out);
2273 neglab = gen_label_rtx ();
2274 donelab = gen_label_rtx ();
2275 i0 = gen_reg_rtx (DImode);
2276 i1 = gen_reg_rtx (DImode);
2277 f0 = gen_reg_rtx (mode);
2278
2279 emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, DImode, 0, neglab);
2280
2281 emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_FLOAT (mode, in)));
2282 emit_jump_insn (gen_jump (donelab));
2283 emit_barrier ();
2284
2285 emit_label (neglab);
2286
2287 emit_insn (gen_lshrdi3 (i0, in, const1_rtx));
2288 emit_insn (gen_anddi3 (i1, in, const1_rtx));
2289 emit_insn (gen_iordi3 (i0, i0, i1));
2290 emit_insn (gen_rtx_SET (VOIDmode, f0, gen_rtx_FLOAT (mode, i0)));
2291 emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_PLUS (mode, f0, f0)));
2292
2293 emit_label (donelab);
2294 }
2295
2296 /* Generate the comparison for a conditional branch. */
2297
2298 rtx
2299 alpha_emit_conditional_branch (enum rtx_code code)
2300 {
2301 enum rtx_code cmp_code, branch_code;
2302 enum machine_mode cmp_mode, branch_mode = VOIDmode;
2303 rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
2304 rtx tem;
2305
2306 if (alpha_compare.fp_p && GET_MODE (op0) == TFmode)
2307 {
2308 if (! TARGET_HAS_XFLOATING_LIBS)
2309 abort ();
2310
2311 /* X_floating library comparison functions return
2312 -1 unordered
2313 0 false
2314 1 true
2315 Convert the compare against the raw return value. */
2316
2317 switch (code)
2318 {
2319 case UNORDERED:
2320 cmp_code = EQ;
2321 code = LT;
2322 break;
2323 case ORDERED:
2324 cmp_code = EQ;
2325 code = GE;
2326 break;
2327 case NE:
2328 cmp_code = NE;
2329 code = NE;
2330 break;
2331 default:
2332 cmp_code = code;
2333 code = GT;
2334 break;
2335 }
2336
2337 op0 = alpha_emit_xfloating_compare (cmp_code, op0, op1);
2338 op1 = const0_rtx;
2339 alpha_compare.fp_p = 0;
2340 }
2341
2342 /* The general case: fold the comparison code to the types of compares
2343 that we have, choosing the branch as necessary. */
2344 switch (code)
2345 {
2346 case EQ: case LE: case LT: case LEU: case LTU:
2347 case UNORDERED:
2348 /* We have these compares: */
2349 cmp_code = code, branch_code = NE;
2350 break;
2351
2352 case NE:
2353 case ORDERED:
2354 /* These must be reversed. */
2355 cmp_code = reverse_condition (code), branch_code = EQ;
2356 break;
2357
2358 case GE: case GT: case GEU: case GTU:
2359 /* For FP, we swap them, for INT, we reverse them. */
2360 if (alpha_compare.fp_p)
2361 {
2362 cmp_code = swap_condition (code);
2363 branch_code = NE;
2364 tem = op0, op0 = op1, op1 = tem;
2365 }
2366 else
2367 {
2368 cmp_code = reverse_condition (code);
2369 branch_code = EQ;
2370 }
2371 break;
2372
2373 default:
2374 abort ();
2375 }
2376
2377 if (alpha_compare.fp_p)
2378 {
2379 cmp_mode = DFmode;
2380 if (flag_unsafe_math_optimizations)
2381 {
2382 /* When we are not as concerned about non-finite values, and we
2383 are comparing against zero, we can branch directly. */
2384 if (op1 == CONST0_RTX (DFmode))
2385 cmp_code = UNKNOWN, branch_code = code;
2386 else if (op0 == CONST0_RTX (DFmode))
2387 {
2388 /* Undo the swap we probably did just above. */
2389 tem = op0, op0 = op1, op1 = tem;
2390 branch_code = swap_condition (cmp_code);
2391 cmp_code = UNKNOWN;
2392 }
2393 }
2394 else
2395 {
2396 /* ??? We mark the branch mode to be CCmode to prevent the
2397 compare and branch from being combined, since the compare
2398 insn follows IEEE rules that the branch does not. */
2399 branch_mode = CCmode;
2400 }
2401 }
2402 else
2403 {
2404 cmp_mode = DImode;
2405
2406 /* The following optimizations are only for signed compares. */
2407 if (code != LEU && code != LTU && code != GEU && code != GTU)
2408 {
2409 /* Whee. Compare and branch against 0 directly. */
2410 if (op1 == const0_rtx)
2411 cmp_code = UNKNOWN, branch_code = code;
2412
2413 /* If the constants doesn't fit into an immediate, but can
2414 be generated by lda/ldah, we adjust the argument and
2415 compare against zero, so we can use beq/bne directly. */
2416 /* ??? Don't do this when comparing against symbols, otherwise
2417 we'll reduce (&x == 0x1234) to (&x-0x1234 == 0), which will
2418 be declared false out of hand (at least for non-weak). */
2419 else if (GET_CODE (op1) == CONST_INT
2420 && (code == EQ || code == NE)
2421 && !(symbolic_operand (op0, VOIDmode)
2422 || (GET_CODE (op0) == REG && REG_POINTER (op0))))
2423 {
2424 HOST_WIDE_INT v = INTVAL (op1), n = -v;
2425
2426 if (! CONST_OK_FOR_LETTER_P (v, 'I')
2427 && (CONST_OK_FOR_LETTER_P (n, 'K')
2428 || CONST_OK_FOR_LETTER_P (n, 'L')))
2429 {
2430 cmp_code = PLUS, branch_code = code;
2431 op1 = GEN_INT (n);
2432 }
2433 }
2434 }
2435
2436 if (!reg_or_0_operand (op0, DImode))
2437 op0 = force_reg (DImode, op0);
2438 if (cmp_code != PLUS && !reg_or_8bit_operand (op1, DImode))
2439 op1 = force_reg (DImode, op1);
2440 }
2441
2442 /* Emit an initial compare instruction, if necessary. */
2443 tem = op0;
2444 if (cmp_code != UNKNOWN)
2445 {
2446 tem = gen_reg_rtx (cmp_mode);
2447 emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
2448 }
2449
2450 /* Zero the operands. */
2451 memset (&alpha_compare, 0, sizeof (alpha_compare));
2452
2453 /* Return the branch comparison. */
2454 return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
2455 }
2456
2457 /* Certain simplifications can be done to make invalid setcc operations
2458 valid. Return the final comparison, or NULL if we can't work. */
2459
2460 rtx
2461 alpha_emit_setcc (enum rtx_code code)
2462 {
2463 enum rtx_code cmp_code;
2464 rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
2465 int fp_p = alpha_compare.fp_p;
2466 rtx tmp;
2467
2468 /* Zero the operands. */
2469 memset (&alpha_compare, 0, sizeof (alpha_compare));
2470
2471 if (fp_p && GET_MODE (op0) == TFmode)
2472 {
2473 if (! TARGET_HAS_XFLOATING_LIBS)
2474 abort ();
2475
2476 /* X_floating library comparison functions return
2477 -1 unordered
2478 0 false
2479 1 true
2480 Convert the compare against the raw return value. */
2481
2482 if (code == UNORDERED || code == ORDERED)
2483 cmp_code = EQ;
2484 else
2485 cmp_code = code;
2486
2487 op0 = alpha_emit_xfloating_compare (cmp_code, op0, op1);
2488 op1 = const0_rtx;
2489 fp_p = 0;
2490
2491 if (code == UNORDERED)
2492 code = LT;
2493 else if (code == ORDERED)
2494 code = GE;
2495 else
2496 code = GT;
2497 }
2498
2499 if (fp_p && !TARGET_FIX)
2500 return NULL_RTX;
2501
2502 /* The general case: fold the comparison code to the types of compares
2503 that we have, choosing the branch as necessary. */
2504
2505 cmp_code = UNKNOWN;
2506 switch (code)
2507 {
2508 case EQ: case LE: case LT: case LEU: case LTU:
2509 case UNORDERED:
2510 /* We have these compares. */
2511 if (fp_p)
2512 cmp_code = code, code = NE;
2513 break;
2514
2515 case NE:
2516 if (!fp_p && op1 == const0_rtx)
2517 break;
2518 /* FALLTHRU */
2519
2520 case ORDERED:
2521 cmp_code = reverse_condition (code);
2522 code = EQ;
2523 break;
2524
2525 case GE: case GT: case GEU: case GTU:
2526 /* These normally need swapping, but for integer zero we have
2527 special patterns that recognize swapped operands. */
2528 if (!fp_p && op1 == const0_rtx)
2529 break;
2530 code = swap_condition (code);
2531 if (fp_p)
2532 cmp_code = code, code = NE;
2533 tmp = op0, op0 = op1, op1 = tmp;
2534 break;
2535
2536 default:
2537 abort ();
2538 }
2539
2540 if (!fp_p)
2541 {
2542 if (!register_operand (op0, DImode))
2543 op0 = force_reg (DImode, op0);
2544 if (!reg_or_8bit_operand (op1, DImode))
2545 op1 = force_reg (DImode, op1);
2546 }
2547
2548 /* Emit an initial compare instruction, if necessary. */
2549 if (cmp_code != UNKNOWN)
2550 {
2551 enum machine_mode mode = fp_p ? DFmode : DImode;
2552
2553 tmp = gen_reg_rtx (mode);
2554 emit_insn (gen_rtx_SET (VOIDmode, tmp,
2555 gen_rtx_fmt_ee (cmp_code, mode, op0, op1)));
2556
2557 op0 = fp_p ? gen_lowpart (DImode, tmp) : tmp;
2558 op1 = const0_rtx;
2559 }
2560
2561 /* Return the setcc comparison. */
2562 return gen_rtx_fmt_ee (code, DImode, op0, op1);
2563 }
2564
2565
2566 /* Rewrite a comparison against zero CMP of the form
2567 (CODE (cc0) (const_int 0)) so it can be written validly in
2568 a conditional move (if_then_else CMP ...).
2569 If both of the operands that set cc0 are nonzero we must emit
2570 an insn to perform the compare (it can't be done within
2571 the conditional move). */
2572
2573 rtx
2574 alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
2575 {
2576 enum rtx_code code = GET_CODE (cmp);
2577 enum rtx_code cmov_code = NE;
2578 rtx op0 = alpha_compare.op0;
2579 rtx op1 = alpha_compare.op1;
2580 int fp_p = alpha_compare.fp_p;
2581 enum machine_mode cmp_mode
2582 = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
2583 enum machine_mode cmp_op_mode = fp_p ? DFmode : DImode;
2584 enum machine_mode cmov_mode = VOIDmode;
2585 int local_fast_math = flag_unsafe_math_optimizations;
2586 rtx tem;
2587
2588 /* Zero the operands. */
2589 memset (&alpha_compare, 0, sizeof (alpha_compare));
2590
2591 if (fp_p != FLOAT_MODE_P (mode))
2592 {
2593 enum rtx_code cmp_code;
2594
2595 if (! TARGET_FIX)
2596 return 0;
2597
2598 /* If we have fp<->int register move instructions, do a cmov by
2599 performing the comparison in fp registers, and move the
2600 zero/nonzero value to integer registers, where we can then
2601 use a normal cmov, or vice-versa. */
2602
2603 switch (code)
2604 {
2605 case EQ: case LE: case LT: case LEU: case LTU:
2606 /* We have these compares. */
2607 cmp_code = code, code = NE;
2608 break;
2609
2610 case NE:
2611 /* This must be reversed. */
2612 cmp_code = EQ, code = EQ;
2613 break;
2614
2615 case GE: case GT: case GEU: case GTU:
2616 /* These normally need swapping, but for integer zero we have
2617 special patterns that recognize swapped operands. */
2618 if (!fp_p && op1 == const0_rtx)
2619 cmp_code = code, code = NE;
2620 else
2621 {
2622 cmp_code = swap_condition (code);
2623 code = NE;
2624 tem = op0, op0 = op1, op1 = tem;
2625 }
2626 break;
2627
2628 default:
2629 abort ();
2630 }
2631
2632 tem = gen_reg_rtx (cmp_op_mode);
2633 emit_insn (gen_rtx_SET (VOIDmode, tem,
2634 gen_rtx_fmt_ee (cmp_code, cmp_op_mode,
2635 op0, op1)));
2636
2637 cmp_mode = cmp_op_mode = fp_p ? DImode : DFmode;
2638 op0 = gen_lowpart (cmp_op_mode, tem);
2639 op1 = CONST0_RTX (cmp_op_mode);
2640 fp_p = !fp_p;
2641 local_fast_math = 1;
2642 }
2643
2644 /* We may be able to use a conditional move directly.
2645 This avoids emitting spurious compares. */
2646 if (signed_comparison_operator (cmp, VOIDmode)
2647 && (!fp_p || local_fast_math)
2648 && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
2649 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
2650
2651 /* We can't put the comparison inside the conditional move;
2652 emit a compare instruction and put that inside the
2653 conditional move. Make sure we emit only comparisons we have;
2654 swap or reverse as necessary. */
2655
2656 if (no_new_pseudos)
2657 return NULL_RTX;
2658
2659 switch (code)
2660 {
2661 case EQ: case LE: case LT: case LEU: case LTU:
2662 /* We have these compares: */
2663 break;
2664
2665 case NE:
2666 /* This must be reversed. */
2667 code = reverse_condition (code);
2668 cmov_code = EQ;
2669 break;
2670
2671 case GE: case GT: case GEU: case GTU:
2672 /* These must be swapped. */
2673 if (op1 != CONST0_RTX (cmp_mode))
2674 {
2675 code = swap_condition (code);
2676 tem = op0, op0 = op1, op1 = tem;
2677 }
2678 break;
2679
2680 default:
2681 abort ();
2682 }
2683
2684 if (!fp_p)
2685 {
2686 if (!reg_or_0_operand (op0, DImode))
2687 op0 = force_reg (DImode, op0);
2688 if (!reg_or_8bit_operand (op1, DImode))
2689 op1 = force_reg (DImode, op1);
2690 }
2691
2692 /* ??? We mark the branch mode to be CCmode to prevent the compare
2693 and cmov from being combined, since the compare insn follows IEEE
2694 rules that the cmov does not. */
2695 if (fp_p && !local_fast_math)
2696 cmov_mode = CCmode;
2697
2698 tem = gen_reg_rtx (cmp_op_mode);
2699 emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
2700 return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
2701 }
2702
2703 /* Simplify a conditional move of two constants into a setcc with
2704 arithmetic. This is done with a splitter since combine would
2705 just undo the work if done during code generation. It also catches
2706 cases we wouldn't have before cse. */
2707
2708 int
2709 alpha_split_conditional_move (enum rtx_code code, rtx dest, rtx cond,
2710 rtx t_rtx, rtx f_rtx)
2711 {
2712 HOST_WIDE_INT t, f, diff;
2713 enum machine_mode mode;
2714 rtx target, subtarget, tmp;
2715
2716 mode = GET_MODE (dest);
2717 t = INTVAL (t_rtx);
2718 f = INTVAL (f_rtx);
2719 diff = t - f;
2720
2721 if (((code == NE || code == EQ) && diff < 0)
2722 || (code == GE || code == GT))
2723 {
2724 code = reverse_condition (code);
2725 diff = t, t = f, f = diff;
2726 diff = t - f;
2727 }
2728
2729 subtarget = target = dest;
2730 if (mode != DImode)
2731 {
2732 target = gen_lowpart (DImode, dest);
2733 if (! no_new_pseudos)
2734 subtarget = gen_reg_rtx (DImode);
2735 else
2736 subtarget = target;
2737 }
2738 /* Below, we must be careful to use copy_rtx on target and subtarget
2739 in intermediate insns, as they may be a subreg rtx, which may not
2740 be shared. */
2741
2742 if (f == 0 && exact_log2 (diff) > 0
2743 /* On EV6, we've got enough shifters to make non-arithmetic shifts
2744 viable over a longer latency cmove. On EV5, the E0 slot is a
2745 scarce resource, and on EV4 shift has the same latency as a cmove. */
2746 && (diff <= 8 || alpha_cpu == PROCESSOR_EV6))
2747 {
2748 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2749 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp));
2750
2751 tmp = gen_rtx_ASHIFT (DImode, copy_rtx (subtarget),
2752 GEN_INT (exact_log2 (t)));
2753 emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
2754 }
2755 else if (f == 0 && t == -1)
2756 {
2757 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2758 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp));
2759
2760 emit_insn (gen_negdi2 (target, copy_rtx (subtarget)));
2761 }
2762 else if (diff == 1 || diff == 4 || diff == 8)
2763 {
2764 rtx add_op;
2765
2766 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2767 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp));
2768
2769 if (diff == 1)
2770 emit_insn (gen_adddi3 (target, copy_rtx (subtarget), GEN_INT (f)));
2771 else
2772 {
2773 add_op = GEN_INT (f);
2774 if (sext_add_operand (add_op, mode))
2775 {
2776 tmp = gen_rtx_MULT (DImode, copy_rtx (subtarget),
2777 GEN_INT (diff));
2778 tmp = gen_rtx_PLUS (DImode, tmp, add_op);
2779 emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
2780 }
2781 else
2782 return 0;
2783 }
2784 }
2785 else
2786 return 0;
2787
2788 return 1;
2789 }
2790 \f
2791 /* Look up the function X_floating library function name for the
2792 given operation. */
2793
2794 struct xfloating_op GTY(())
2795 {
2796 const enum rtx_code code;
2797 const char *const GTY((skip)) osf_func;
2798 const char *const GTY((skip)) vms_func;
2799 rtx libcall;
2800 };
2801
2802 static GTY(()) struct xfloating_op xfloating_ops[] =
2803 {
2804 { PLUS, "_OtsAddX", "OTS$ADD_X", 0 },
2805 { MINUS, "_OtsSubX", "OTS$SUB_X", 0 },
2806 { MULT, "_OtsMulX", "OTS$MUL_X", 0 },
2807 { DIV, "_OtsDivX", "OTS$DIV_X", 0 },
2808 { EQ, "_OtsEqlX", "OTS$EQL_X", 0 },
2809 { NE, "_OtsNeqX", "OTS$NEQ_X", 0 },
2810 { LT, "_OtsLssX", "OTS$LSS_X", 0 },
2811 { LE, "_OtsLeqX", "OTS$LEQ_X", 0 },
2812 { GT, "_OtsGtrX", "OTS$GTR_X", 0 },
2813 { GE, "_OtsGeqX", "OTS$GEQ_X", 0 },
2814 { FIX, "_OtsCvtXQ", "OTS$CVTXQ", 0 },
2815 { FLOAT, "_OtsCvtQX", "OTS$CVTQX", 0 },
2816 { UNSIGNED_FLOAT, "_OtsCvtQUX", "OTS$CVTQUX", 0 },
2817 { FLOAT_EXTEND, "_OtsConvertFloatTX", "OTS$CVT_FLOAT_T_X", 0 },
2818 { FLOAT_TRUNCATE, "_OtsConvertFloatXT", "OTS$CVT_FLOAT_X_T", 0 }
2819 };
2820
2821 static GTY(()) struct xfloating_op vax_cvt_ops[] =
2822 {
2823 { FLOAT_EXTEND, "_OtsConvertFloatGX", "OTS$CVT_FLOAT_G_X", 0 },
2824 { FLOAT_TRUNCATE, "_OtsConvertFloatXG", "OTS$CVT_FLOAT_X_G", 0 }
2825 };
2826
2827 static rtx
2828 alpha_lookup_xfloating_lib_func (enum rtx_code code)
2829 {
2830 struct xfloating_op *ops = xfloating_ops;
2831 long n = ARRAY_SIZE (xfloating_ops);
2832 long i;
2833
2834 /* How irritating. Nothing to key off for the main table. */
2835 if (TARGET_FLOAT_VAX && (code == FLOAT_EXTEND || code == FLOAT_TRUNCATE))
2836 {
2837 ops = vax_cvt_ops;
2838 n = ARRAY_SIZE (vax_cvt_ops);
2839 }
2840
2841 for (i = 0; i < n; ++i, ++ops)
2842 if (ops->code == code)
2843 {
2844 rtx func = ops->libcall;
2845 if (!func)
2846 {
2847 func = init_one_libfunc (TARGET_ABI_OPEN_VMS
2848 ? ops->vms_func : ops->osf_func);
2849 ops->libcall = func;
2850 }
2851 return func;
2852 }
2853
2854 abort();
2855 }
2856
2857 /* Most X_floating operations take the rounding mode as an argument.
2858 Compute that here. */
2859
2860 static int
2861 alpha_compute_xfloating_mode_arg (enum rtx_code code,
2862 enum alpha_fp_rounding_mode round)
2863 {
2864 int mode;
2865
2866 switch (round)
2867 {
2868 case ALPHA_FPRM_NORM:
2869 mode = 2;
2870 break;
2871 case ALPHA_FPRM_MINF:
2872 mode = 1;
2873 break;
2874 case ALPHA_FPRM_CHOP:
2875 mode = 0;
2876 break;
2877 case ALPHA_FPRM_DYN:
2878 mode = 4;
2879 break;
2880 default:
2881 abort ();
2882
2883 /* XXX For reference, round to +inf is mode = 3. */
2884 }
2885
2886 if (code == FLOAT_TRUNCATE && alpha_fptm == ALPHA_FPTM_N)
2887 mode |= 0x10000;
2888
2889 return mode;
2890 }
2891
2892 /* Emit an X_floating library function call.
2893
2894 Note that these functions do not follow normal calling conventions:
2895 TFmode arguments are passed in two integer registers (as opposed to
2896 indirect); TFmode return values appear in R16+R17.
2897
2898 FUNC is the function to call.
2899 TARGET is where the output belongs.
2900 OPERANDS are the inputs.
2901 NOPERANDS is the count of inputs.
2902 EQUIV is the expression equivalent for the function.
2903 */
2904
2905 static void
2906 alpha_emit_xfloating_libcall (rtx func, rtx target, rtx operands[],
2907 int noperands, rtx equiv)
2908 {
2909 rtx usage = NULL_RTX, tmp, reg;
2910 int regno = 16, i;
2911
2912 start_sequence ();
2913
2914 for (i = 0; i < noperands; ++i)
2915 {
2916 switch (GET_MODE (operands[i]))
2917 {
2918 case TFmode:
2919 reg = gen_rtx_REG (TFmode, regno);
2920 regno += 2;
2921 break;
2922
2923 case DFmode:
2924 reg = gen_rtx_REG (DFmode, regno + 32);
2925 regno += 1;
2926 break;
2927
2928 case VOIDmode:
2929 if (GET_CODE (operands[i]) != CONST_INT)
2930 abort ();
2931 /* FALLTHRU */
2932 case DImode:
2933 reg = gen_rtx_REG (DImode, regno);
2934 regno += 1;
2935 break;
2936
2937 default:
2938 abort ();
2939 }
2940
2941 emit_move_insn (reg, operands[i]);
2942 usage = alloc_EXPR_LIST (0, gen_rtx_USE (VOIDmode, reg), usage);
2943 }
2944
2945 switch (GET_MODE (target))
2946 {
2947 case TFmode:
2948 reg = gen_rtx_REG (TFmode, 16);
2949 break;
2950 case DFmode:
2951 reg = gen_rtx_REG (DFmode, 32);
2952 break;
2953 case DImode:
2954 reg = gen_rtx_REG (DImode, 0);
2955 break;
2956 default:
2957 abort ();
2958 }
2959
2960 tmp = gen_rtx_MEM (QImode, func);
2961 tmp = emit_call_insn (GEN_CALL_VALUE (reg, tmp, const0_rtx,
2962 const0_rtx, const0_rtx));
2963 CALL_INSN_FUNCTION_USAGE (tmp) = usage;
2964 CONST_OR_PURE_CALL_P (tmp) = 1;
2965
2966 tmp = get_insns ();
2967 end_sequence ();
2968
2969 emit_libcall_block (tmp, target, reg, equiv);
2970 }
2971
2972 /* Emit an X_floating library function call for arithmetic (+,-,*,/). */
2973
2974 void
2975 alpha_emit_xfloating_arith (enum rtx_code code, rtx operands[])
2976 {
2977 rtx func;
2978 int mode;
2979 rtx out_operands[3];
2980
2981 func = alpha_lookup_xfloating_lib_func (code);
2982 mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
2983
2984 out_operands[0] = operands[1];
2985 out_operands[1] = operands[2];
2986 out_operands[2] = GEN_INT (mode);
2987 alpha_emit_xfloating_libcall (func, operands[0], out_operands, 3,
2988 gen_rtx_fmt_ee (code, TFmode, operands[1],
2989 operands[2]));
2990 }
2991
2992 /* Emit an X_floating library function call for a comparison. */
2993
2994 static rtx
2995 alpha_emit_xfloating_compare (enum rtx_code code, rtx op0, rtx op1)
2996 {
2997 rtx func;
2998 rtx out, operands[2];
2999
3000 func = alpha_lookup_xfloating_lib_func (code);
3001
3002 operands[0] = op0;
3003 operands[1] = op1;
3004 out = gen_reg_rtx (DImode);
3005
3006 /* ??? Strange mode for equiv because what's actually returned
3007 is -1,0,1, not a proper boolean value. */
3008 alpha_emit_xfloating_libcall (func, out, operands, 2,
3009 gen_rtx_fmt_ee (code, CCmode, op0, op1));
3010
3011 return out;
3012 }
3013
3014 /* Emit an X_floating library function call for a conversion. */
3015
3016 void
3017 alpha_emit_xfloating_cvt (enum rtx_code orig_code, rtx operands[])
3018 {
3019 int noperands = 1, mode;
3020 rtx out_operands[2];
3021 rtx func;
3022 enum rtx_code code = orig_code;
3023
3024 if (code == UNSIGNED_FIX)
3025 code = FIX;
3026
3027 func = alpha_lookup_xfloating_lib_func (code);
3028
3029 out_operands[0] = operands[1];
3030
3031 switch (code)
3032 {
3033 case FIX:
3034 mode = alpha_compute_xfloating_mode_arg (code, ALPHA_FPRM_CHOP);
3035 out_operands[1] = GEN_INT (mode);
3036 noperands = 2;
3037 break;
3038 case FLOAT_TRUNCATE:
3039 mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
3040 out_operands[1] = GEN_INT (mode);
3041 noperands = 2;
3042 break;
3043 default:
3044 break;
3045 }
3046
3047 alpha_emit_xfloating_libcall (func, operands[0], out_operands, noperands,
3048 gen_rtx_fmt_e (orig_code,
3049 GET_MODE (operands[0]),
3050 operands[1]));
3051 }
3052
3053 /* Split a TFmode OP[1] into DImode OP[2,3] and likewise for
3054 OP[0] into OP[0,1]. Naturally, output operand ordering is
3055 little-endian. */
3056
3057 void
3058 alpha_split_tfmode_pair (rtx operands[4])
3059 {
3060 if (GET_CODE (operands[1]) == REG)
3061 {
3062 operands[3] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1);
3063 operands[2] = gen_rtx_REG (DImode, REGNO (operands[1]));
3064 }
3065 else if (GET_CODE (operands[1]) == MEM)
3066 {
3067 operands[3] = adjust_address (operands[1], DImode, 8);
3068 operands[2] = adjust_address (operands[1], DImode, 0);
3069 }
3070 else if (operands[1] == CONST0_RTX (TFmode))
3071 operands[2] = operands[3] = const0_rtx;
3072 else
3073 abort ();
3074
3075 if (GET_CODE (operands[0]) == REG)
3076 {
3077 operands[1] = gen_rtx_REG (DImode, REGNO (operands[0]) + 1);
3078 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
3079 }
3080 else if (GET_CODE (operands[0]) == MEM)
3081 {
3082 operands[1] = adjust_address (operands[0], DImode, 8);
3083 operands[0] = adjust_address (operands[0], DImode, 0);
3084 }
3085 else
3086 abort ();
3087 }
3088
3089 /* Implement negtf2 or abstf2. Op0 is destination, op1 is source,
3090 op2 is a register containing the sign bit, operation is the
3091 logical operation to be performed. */
3092
3093 void
3094 alpha_split_tfmode_frobsign (rtx operands[3], rtx (*operation) (rtx, rtx, rtx))
3095 {
3096 rtx high_bit = operands[2];
3097 rtx scratch;
3098 int move;
3099
3100 alpha_split_tfmode_pair (operands);
3101
3102 /* Detect three flavors of operand overlap. */
3103 move = 1;
3104 if (rtx_equal_p (operands[0], operands[2]))
3105 move = 0;
3106 else if (rtx_equal_p (operands[1], operands[2]))
3107 {
3108 if (rtx_equal_p (operands[0], high_bit))
3109 move = 2;
3110 else
3111 move = -1;
3112 }
3113
3114 if (move < 0)
3115 emit_move_insn (operands[0], operands[2]);
3116
3117 /* ??? If the destination overlaps both source tf and high_bit, then
3118 assume source tf is dead in its entirety and use the other half
3119 for a scratch register. Otherwise "scratch" is just the proper
3120 destination register. */
3121 scratch = operands[move < 2 ? 1 : 3];
3122
3123 emit_insn ((*operation) (scratch, high_bit, operands[3]));
3124
3125 if (move > 0)
3126 {
3127 emit_move_insn (operands[0], operands[2]);
3128 if (move > 1)
3129 emit_move_insn (operands[1], scratch);
3130 }
3131 }
3132 \f
3133 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
3134 unaligned data:
3135
3136 unsigned: signed:
3137 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
3138 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
3139 lda r3,X(r11) lda r3,X+2(r11)
3140 extwl r1,r3,r1 extql r1,r3,r1
3141 extwh r2,r3,r2 extqh r2,r3,r2
3142 or r1.r2.r1 or r1,r2,r1
3143 sra r1,48,r1
3144
3145 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
3146 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
3147 lda r3,X(r11) lda r3,X(r11)
3148 extll r1,r3,r1 extll r1,r3,r1
3149 extlh r2,r3,r2 extlh r2,r3,r2
3150 or r1.r2.r1 addl r1,r2,r1
3151
3152 quad: ldq_u r1,X(r11)
3153 ldq_u r2,X+7(r11)
3154 lda r3,X(r11)
3155 extql r1,r3,r1
3156 extqh r2,r3,r2
3157 or r1.r2.r1
3158 */
3159
3160 void
3161 alpha_expand_unaligned_load (rtx tgt, rtx mem, HOST_WIDE_INT size,
3162 HOST_WIDE_INT ofs, int sign)
3163 {
3164 rtx meml, memh, addr, extl, exth, tmp, mema;
3165 enum machine_mode mode;
3166
3167 meml = gen_reg_rtx (DImode);
3168 memh = gen_reg_rtx (DImode);
3169 addr = gen_reg_rtx (DImode);
3170 extl = gen_reg_rtx (DImode);
3171 exth = gen_reg_rtx (DImode);
3172
3173 mema = XEXP (mem, 0);
3174 if (GET_CODE (mema) == LO_SUM)
3175 mema = force_reg (Pmode, mema);
3176
3177 /* AND addresses cannot be in any alias set, since they may implicitly
3178 alias surrounding code. Ideally we'd have some alias set that
3179 covered all types except those with alignment 8 or higher. */
3180
3181 tmp = change_address (mem, DImode,
3182 gen_rtx_AND (DImode,
3183 plus_constant (mema, ofs),
3184 GEN_INT (-8)));
3185 set_mem_alias_set (tmp, 0);
3186 emit_move_insn (meml, tmp);
3187
3188 tmp = change_address (mem, DImode,
3189 gen_rtx_AND (DImode,
3190 plus_constant (mema, ofs + size - 1),
3191 GEN_INT (-8)));
3192 set_mem_alias_set (tmp, 0);
3193 emit_move_insn (memh, tmp);
3194
3195 if (WORDS_BIG_ENDIAN && sign && (size == 2 || size == 4))
3196 {
3197 emit_move_insn (addr, plus_constant (mema, -1));
3198
3199 emit_insn (gen_extqh_be (extl, meml, addr));
3200 emit_insn (gen_extxl_be (exth, memh, GEN_INT (64), addr));
3201
3202 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
3203 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (64 - size*8),
3204 addr, 1, OPTAB_WIDEN);
3205 }
3206 else if (sign && size == 2)
3207 {
3208 emit_move_insn (addr, plus_constant (mema, ofs+2));
3209
3210 emit_insn (gen_extxl_le (extl, meml, GEN_INT (64), addr));
3211 emit_insn (gen_extqh_le (exth, memh, addr));
3212
3213 /* We must use tgt here for the target. Alpha-vms port fails if we use
3214 addr for the target, because addr is marked as a pointer and combine
3215 knows that pointers are always sign-extended 32 bit values. */
3216 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
3217 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48),
3218 addr, 1, OPTAB_WIDEN);
3219 }
3220 else
3221 {
3222 if (WORDS_BIG_ENDIAN)
3223 {
3224 emit_move_insn (addr, plus_constant (mema, ofs+size-1));
3225 switch ((int) size)
3226 {
3227 case 2:
3228 emit_insn (gen_extwh_be (extl, meml, addr));
3229 mode = HImode;
3230 break;
3231
3232 case 4:
3233 emit_insn (gen_extlh_be (extl, meml, addr));
3234 mode = SImode;
3235 break;
3236
3237 case 8:
3238 emit_insn (gen_extqh_be (extl, meml, addr));
3239 mode = DImode;
3240 break;
3241
3242 default:
3243 abort ();
3244 }
3245 emit_insn (gen_extxl_be (exth, memh, GEN_INT (size*8), addr));
3246 }
3247 else
3248 {
3249 emit_move_insn (addr, plus_constant (mema, ofs));
3250 emit_insn (gen_extxl_le (extl, meml, GEN_INT (size*8), addr));
3251 switch ((int) size)
3252 {
3253 case 2:
3254 emit_insn (gen_extwh_le (exth, memh, addr));
3255 mode = HImode;
3256 break;
3257
3258 case 4:
3259 emit_insn (gen_extlh_le (exth, memh, addr));
3260 mode = SImode;
3261 break;
3262
3263 case 8:
3264 emit_insn (gen_extqh_le (exth, memh, addr));
3265 mode = DImode;
3266 break;
3267
3268 default:
3269 abort();
3270 }
3271 }
3272
3273 addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
3274 gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
3275 sign, OPTAB_WIDEN);
3276 }
3277
3278 if (addr != tgt)
3279 emit_move_insn (tgt, gen_lowpart(GET_MODE (tgt), addr));
3280 }
3281
3282 /* Similarly, use ins and msk instructions to perform unaligned stores. */
3283
3284 void
3285 alpha_expand_unaligned_store (rtx dst, rtx src,
3286 HOST_WIDE_INT size, HOST_WIDE_INT ofs)
3287 {
3288 rtx dstl, dsth, addr, insl, insh, meml, memh, dsta;
3289
3290 dstl = gen_reg_rtx (DImode);
3291 dsth = gen_reg_rtx (DImode);
3292 insl = gen_reg_rtx (DImode);
3293 insh = gen_reg_rtx (DImode);
3294
3295 dsta = XEXP (dst, 0);
3296 if (GET_CODE (dsta) == LO_SUM)
3297 dsta = force_reg (Pmode, dsta);
3298
3299 /* AND addresses cannot be in any alias set, since they may implicitly
3300 alias surrounding code. Ideally we'd have some alias set that
3301 covered all types except those with alignment 8 or higher. */
3302
3303 meml = change_address (dst, DImode,
3304 gen_rtx_AND (DImode,
3305 plus_constant (dsta, ofs),
3306 GEN_INT (-8)));
3307 set_mem_alias_set (meml, 0);
3308
3309 memh = change_address (dst, DImode,
3310 gen_rtx_AND (DImode,
3311 plus_constant (dsta, ofs + size - 1),
3312 GEN_INT (-8)));
3313 set_mem_alias_set (memh, 0);
3314
3315 emit_move_insn (dsth, memh);
3316 emit_move_insn (dstl, meml);
3317 if (WORDS_BIG_ENDIAN)
3318 {
3319 addr = copy_addr_to_reg (plus_constant (dsta, ofs+size-1));
3320
3321 if (src != const0_rtx)
3322 {
3323 switch ((int) size)
3324 {
3325 case 2:
3326 emit_insn (gen_inswl_be (insh, gen_lowpart (HImode,src), addr));
3327 break;
3328 case 4:
3329 emit_insn (gen_insll_be (insh, gen_lowpart (SImode,src), addr));
3330 break;
3331 case 8:
3332 emit_insn (gen_insql_be (insh, gen_lowpart (DImode,src), addr));
3333 break;
3334 }
3335 emit_insn (gen_insxh (insl, gen_lowpart (DImode, src),
3336 GEN_INT (size*8), addr));
3337 }
3338
3339 switch ((int) size)
3340 {
3341 case 2:
3342 emit_insn (gen_mskxl_be (dsth, dsth, GEN_INT (0xffff), addr));
3343 break;
3344 case 4:
3345 {
3346 rtx msk = immed_double_const (0xffffffff, 0, DImode);
3347 emit_insn (gen_mskxl_be (dsth, dsth, msk, addr));
3348 break;
3349 }
3350 case 8:
3351 emit_insn (gen_mskxl_be (dsth, dsth, constm1_rtx, addr));
3352 break;
3353 }
3354
3355 emit_insn (gen_mskxh (dstl, dstl, GEN_INT (size*8), addr));
3356 }
3357 else
3358 {
3359 addr = copy_addr_to_reg (plus_constant (dsta, ofs));
3360
3361 if (src != CONST0_RTX (GET_MODE (src)))
3362 {
3363 emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
3364 GEN_INT (size*8), addr));
3365
3366 switch ((int) size)
3367 {
3368 case 2:
3369 emit_insn (gen_inswl_le (insl, gen_lowpart (HImode, src), addr));
3370 break;
3371 case 4:
3372 emit_insn (gen_insll_le (insl, gen_lowpart (SImode, src), addr));
3373 break;
3374 case 8:
3375 emit_insn (gen_insql_le (insl, src, addr));
3376 break;
3377 }
3378 }
3379
3380 emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
3381
3382 switch ((int) size)
3383 {
3384 case 2:
3385 emit_insn (gen_mskxl_le (dstl, dstl, GEN_INT (0xffff), addr));
3386 break;
3387 case 4:
3388 {
3389 rtx msk = immed_double_const (0xffffffff, 0, DImode);
3390 emit_insn (gen_mskxl_le (dstl, dstl, msk, addr));
3391 break;
3392 }
3393 case 8:
3394 emit_insn (gen_mskxl_le (dstl, dstl, constm1_rtx, addr));
3395 break;
3396 }
3397 }
3398
3399 if (src != CONST0_RTX (GET_MODE (src)))
3400 {
3401 dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
3402 dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
3403 }
3404
3405 if (WORDS_BIG_ENDIAN)
3406 {
3407 emit_move_insn (meml, dstl);
3408 emit_move_insn (memh, dsth);
3409 }
3410 else
3411 {
3412 /* Must store high before low for degenerate case of aligned. */
3413 emit_move_insn (memh, dsth);
3414 emit_move_insn (meml, dstl);
3415 }
3416 }
3417
3418 /* The block move code tries to maximize speed by separating loads and
3419 stores at the expense of register pressure: we load all of the data
3420 before we store it back out. There are two secondary effects worth
3421 mentioning, that this speeds copying to/from aligned and unaligned
3422 buffers, and that it makes the code significantly easier to write. */
3423
3424 #define MAX_MOVE_WORDS 8
3425
3426 /* Load an integral number of consecutive unaligned quadwords. */
3427
3428 static void
3429 alpha_expand_unaligned_load_words (rtx *out_regs, rtx smem,
3430 HOST_WIDE_INT words, HOST_WIDE_INT ofs)
3431 {
3432 rtx const im8 = GEN_INT (-8);
3433 rtx const i64 = GEN_INT (64);
3434 rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
3435 rtx sreg, areg, tmp, smema;
3436 HOST_WIDE_INT i;
3437
3438 smema = XEXP (smem, 0);
3439 if (GET_CODE (smema) == LO_SUM)
3440 smema = force_reg (Pmode, smema);
3441
3442 /* Generate all the tmp registers we need. */
3443 for (i = 0; i < words; ++i)
3444 {
3445 data_regs[i] = out_regs[i];
3446 ext_tmps[i] = gen_reg_rtx (DImode);
3447 }
3448 data_regs[words] = gen_reg_rtx (DImode);
3449
3450 if (ofs != 0)
3451 smem = adjust_address (smem, GET_MODE (smem), ofs);
3452
3453 /* Load up all of the source data. */
3454 for (i = 0; i < words; ++i)
3455 {
3456 tmp = change_address (smem, DImode,
3457 gen_rtx_AND (DImode,
3458 plus_constant (smema, 8*i),
3459 im8));
3460 set_mem_alias_set (tmp, 0);
3461 emit_move_insn (data_regs[i], tmp);
3462 }
3463
3464 tmp = change_address (smem, DImode,
3465 gen_rtx_AND (DImode,
3466 plus_constant (smema, 8*words - 1),
3467 im8));
3468 set_mem_alias_set (tmp, 0);
3469 emit_move_insn (data_regs[words], tmp);
3470
3471 /* Extract the half-word fragments. Unfortunately DEC decided to make
3472 extxh with offset zero a noop instead of zeroing the register, so
3473 we must take care of that edge condition ourselves with cmov. */
3474
3475 sreg = copy_addr_to_reg (smema);
3476 areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
3477 1, OPTAB_WIDEN);
3478 if (WORDS_BIG_ENDIAN)
3479 emit_move_insn (sreg, plus_constant (sreg, 7));
3480 for (i = 0; i < words; ++i)
3481 {
3482 if (WORDS_BIG_ENDIAN)
3483 {
3484 emit_insn (gen_extqh_be (data_regs[i], data_regs[i], sreg));
3485 emit_insn (gen_extxl_be (ext_tmps[i], data_regs[i+1], i64, sreg));
3486 }
3487 else
3488 {
3489 emit_insn (gen_extxl_le (data_regs[i], data_regs[i], i64, sreg));
3490 emit_insn (gen_extqh_le (ext_tmps[i], data_regs[i+1], sreg));
3491 }
3492 emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
3493 gen_rtx_IF_THEN_ELSE (DImode,
3494 gen_rtx_EQ (DImode, areg,
3495 const0_rtx),
3496 const0_rtx, ext_tmps[i])));
3497 }
3498
3499 /* Merge the half-words into whole words. */
3500 for (i = 0; i < words; ++i)
3501 {
3502 out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
3503 ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
3504 }
3505 }
3506
3507 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
3508 may be NULL to store zeros. */
3509
3510 static void
3511 alpha_expand_unaligned_store_words (rtx *data_regs, rtx dmem,
3512 HOST_WIDE_INT words, HOST_WIDE_INT ofs)
3513 {
3514 rtx const im8 = GEN_INT (-8);
3515 rtx const i64 = GEN_INT (64);
3516 rtx ins_tmps[MAX_MOVE_WORDS];
3517 rtx st_tmp_1, st_tmp_2, dreg;
3518 rtx st_addr_1, st_addr_2, dmema;
3519 HOST_WIDE_INT i;
3520
3521 dmema = XEXP (dmem, 0);
3522 if (GET_CODE (dmema) == LO_SUM)
3523 dmema = force_reg (Pmode, dmema);
3524
3525 /* Generate all the tmp registers we need. */
3526 if (data_regs != NULL)
3527 for (i = 0; i < words; ++i)
3528 ins_tmps[i] = gen_reg_rtx(DImode);
3529 st_tmp_1 = gen_reg_rtx(DImode);
3530 st_tmp_2 = gen_reg_rtx(DImode);
3531
3532 if (ofs != 0)
3533 dmem = adjust_address (dmem, GET_MODE (dmem), ofs);
3534
3535 st_addr_2 = change_address (dmem, DImode,
3536 gen_rtx_AND (DImode,
3537 plus_constant (dmema, words*8 - 1),
3538 im8));
3539 set_mem_alias_set (st_addr_2, 0);
3540
3541 st_addr_1 = change_address (dmem, DImode,
3542 gen_rtx_AND (DImode, dmema, im8));
3543 set_mem_alias_set (st_addr_1, 0);
3544
3545 /* Load up the destination end bits. */
3546 emit_move_insn (st_tmp_2, st_addr_2);
3547 emit_move_insn (st_tmp_1, st_addr_1);
3548
3549 /* Shift the input data into place. */
3550 dreg = copy_addr_to_reg (dmema);
3551 if (WORDS_BIG_ENDIAN)
3552 emit_move_insn (dreg, plus_constant (dreg, 7));
3553 if (data_regs != NULL)
3554 {
3555 for (i = words-1; i >= 0; --i)
3556 {
3557 if (WORDS_BIG_ENDIAN)
3558 {
3559 emit_insn (gen_insql_be (ins_tmps[i], data_regs[i], dreg));
3560 emit_insn (gen_insxh (data_regs[i], data_regs[i], i64, dreg));
3561 }
3562 else
3563 {
3564 emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
3565 emit_insn (gen_insql_le (data_regs[i], data_regs[i], dreg));
3566 }
3567 }
3568 for (i = words-1; i > 0; --i)
3569 {
3570 ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
3571 ins_tmps[i-1], ins_tmps[i-1], 1,
3572 OPTAB_WIDEN);
3573 }
3574 }
3575
3576 /* Split and merge the ends with the destination data. */
3577 if (WORDS_BIG_ENDIAN)
3578 {
3579 emit_insn (gen_mskxl_be (st_tmp_2, st_tmp_2, constm1_rtx, dreg));
3580 emit_insn (gen_mskxh (st_tmp_1, st_tmp_1, i64, dreg));
3581 }
3582 else
3583 {
3584 emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
3585 emit_insn (gen_mskxl_le (st_tmp_1, st_tmp_1, constm1_rtx, dreg));
3586 }
3587
3588 if (data_regs != NULL)
3589 {
3590 st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
3591 st_tmp_2, 1, OPTAB_WIDEN);
3592 st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
3593 st_tmp_1, 1, OPTAB_WIDEN);
3594 }
3595
3596 /* Store it all. */
3597 if (WORDS_BIG_ENDIAN)
3598 emit_move_insn (st_addr_1, st_tmp_1);
3599 else
3600 emit_move_insn (st_addr_2, st_tmp_2);
3601 for (i = words-1; i > 0; --i)
3602 {
3603 rtx tmp = change_address (dmem, DImode,
3604 gen_rtx_AND (DImode,
3605 plus_constant(dmema,
3606 WORDS_BIG_ENDIAN ? i*8-1 : i*8),
3607 im8));
3608 set_mem_alias_set (tmp, 0);
3609 emit_move_insn (tmp, data_regs ? ins_tmps[i-1] : const0_rtx);
3610 }
3611 if (WORDS_BIG_ENDIAN)
3612 emit_move_insn (st_addr_2, st_tmp_2);
3613 else
3614 emit_move_insn (st_addr_1, st_tmp_1);
3615 }
3616
3617
3618 /* Expand string/block move operations.
3619
3620 operands[0] is the pointer to the destination.
3621 operands[1] is the pointer to the source.
3622 operands[2] is the number of bytes to move.
3623 operands[3] is the alignment. */
3624
3625 int
3626 alpha_expand_block_move (rtx operands[])
3627 {
3628 rtx bytes_rtx = operands[2];
3629 rtx align_rtx = operands[3];
3630 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
3631 HOST_WIDE_INT bytes = orig_bytes;
3632 HOST_WIDE_INT src_align = INTVAL (align_rtx) * BITS_PER_UNIT;
3633 HOST_WIDE_INT dst_align = src_align;
3634 rtx orig_src = operands[1];
3635 rtx orig_dst = operands[0];
3636 rtx data_regs[2 * MAX_MOVE_WORDS + 16];
3637 rtx tmp;
3638 unsigned int i, words, ofs, nregs = 0;
3639
3640 if (orig_bytes <= 0)
3641 return 1;
3642 else if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD)
3643 return 0;
3644
3645 /* Look for additional alignment information from recorded register info. */
3646
3647 tmp = XEXP (orig_src, 0);
3648 if (GET_CODE (tmp) == REG)
3649 src_align = MAX (src_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
3650 else if (GET_CODE (tmp) == PLUS
3651 && GET_CODE (XEXP (tmp, 0)) == REG
3652 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
3653 {
3654 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
3655 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
3656
3657 if (a > src_align)
3658 {
3659 if (a >= 64 && c % 8 == 0)
3660 src_align = 64;
3661 else if (a >= 32 && c % 4 == 0)
3662 src_align = 32;
3663 else if (a >= 16 && c % 2 == 0)
3664 src_align = 16;
3665 }
3666 }
3667
3668 tmp = XEXP (orig_dst, 0);
3669 if (GET_CODE (tmp) == REG)
3670 dst_align = MAX (dst_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
3671 else if (GET_CODE (tmp) == PLUS
3672 && GET_CODE (XEXP (tmp, 0)) == REG
3673 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
3674 {
3675 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
3676 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
3677
3678 if (a > dst_align)
3679 {
3680 if (a >= 64 && c % 8 == 0)
3681 dst_align = 64;
3682 else if (a >= 32 && c % 4 == 0)
3683 dst_align = 32;
3684 else if (a >= 16 && c % 2 == 0)
3685 dst_align = 16;
3686 }
3687 }
3688
3689 ofs = 0;
3690 if (src_align >= 64 && bytes >= 8)
3691 {
3692 words = bytes / 8;
3693
3694 for (i = 0; i < words; ++i)
3695 data_regs[nregs + i] = gen_reg_rtx (DImode);
3696
3697 for (i = 0; i < words; ++i)
3698 emit_move_insn (data_regs[nregs + i],
3699 adjust_address (orig_src, DImode, ofs + i * 8));
3700
3701 nregs += words;
3702 bytes -= words * 8;
3703 ofs += words * 8;
3704 }
3705
3706 if (src_align >= 32 && bytes >= 4)
3707 {
3708 words = bytes / 4;
3709
3710 for (i = 0; i < words; ++i)
3711 data_regs[nregs + i] = gen_reg_rtx (SImode);
3712
3713 for (i = 0; i < words; ++i)
3714 emit_move_insn (data_regs[nregs + i],
3715 adjust_address (orig_src, SImode, ofs + i * 4));
3716
3717 nregs += words;
3718 bytes -= words * 4;
3719 ofs += words * 4;
3720 }
3721
3722 if (bytes >= 8)
3723 {
3724 words = bytes / 8;
3725
3726 for (i = 0; i < words+1; ++i)
3727 data_regs[nregs + i] = gen_reg_rtx (DImode);
3728
3729 alpha_expand_unaligned_load_words (data_regs + nregs, orig_src,
3730 words, ofs);
3731
3732 nregs += words;
3733 bytes -= words * 8;
3734 ofs += words * 8;
3735 }
3736
3737 if (! TARGET_BWX && bytes >= 4)
3738 {
3739 data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
3740 alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
3741 bytes -= 4;
3742 ofs += 4;
3743 }
3744
3745 if (bytes >= 2)
3746 {
3747 if (src_align >= 16)
3748 {
3749 do {
3750 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
3751 emit_move_insn (tmp, adjust_address (orig_src, HImode, ofs));
3752 bytes -= 2;
3753 ofs += 2;
3754 } while (bytes >= 2);
3755 }
3756 else if (! TARGET_BWX)
3757 {
3758 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
3759 alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
3760 bytes -= 2;
3761 ofs += 2;
3762 }
3763 }
3764
3765 while (bytes > 0)
3766 {
3767 data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
3768 emit_move_insn (tmp, adjust_address (orig_src, QImode, ofs));
3769 bytes -= 1;
3770 ofs += 1;
3771 }
3772
3773 if (nregs > ARRAY_SIZE (data_regs))
3774 abort ();
3775
3776 /* Now save it back out again. */
3777
3778 i = 0, ofs = 0;
3779
3780 /* Write out the data in whatever chunks reading the source allowed. */
3781 if (dst_align >= 64)
3782 {
3783 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
3784 {
3785 emit_move_insn (adjust_address (orig_dst, DImode, ofs),
3786 data_regs[i]);
3787 ofs += 8;
3788 i++;
3789 }
3790 }
3791
3792 if (dst_align >= 32)
3793 {
3794 /* If the source has remaining DImode regs, write them out in
3795 two pieces. */
3796 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
3797 {
3798 tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
3799 NULL_RTX, 1, OPTAB_WIDEN);
3800
3801 emit_move_insn (adjust_address (orig_dst, SImode, ofs),
3802 gen_lowpart (SImode, data_regs[i]));
3803 emit_move_insn (adjust_address (orig_dst, SImode, ofs + 4),
3804 gen_lowpart (SImode, tmp));
3805 ofs += 8;
3806 i++;
3807 }
3808
3809 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
3810 {
3811 emit_move_insn (adjust_address (orig_dst, SImode, ofs),
3812 data_regs[i]);
3813 ofs += 4;
3814 i++;
3815 }
3816 }
3817
3818 if (i < nregs && GET_MODE (data_regs[i]) == DImode)
3819 {
3820 /* Write out a remaining block of words using unaligned methods. */
3821
3822 for (words = 1; i + words < nregs; words++)
3823 if (GET_MODE (data_regs[i + words]) != DImode)
3824 break;
3825
3826 if (words == 1)
3827 alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
3828 else
3829 alpha_expand_unaligned_store_words (data_regs + i, orig_dst,
3830 words, ofs);
3831
3832 i += words;
3833 ofs += words * 8;
3834 }
3835
3836 /* Due to the above, this won't be aligned. */
3837 /* ??? If we have more than one of these, consider constructing full
3838 words in registers and using alpha_expand_unaligned_store_words. */
3839 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
3840 {
3841 alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
3842 ofs += 4;
3843 i++;
3844 }
3845
3846 if (dst_align >= 16)
3847 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
3848 {
3849 emit_move_insn (adjust_address (orig_dst, HImode, ofs), data_regs[i]);
3850 i++;
3851 ofs += 2;
3852 }
3853 else
3854 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
3855 {
3856 alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
3857 i++;
3858 ofs += 2;
3859 }
3860
3861 while (i < nregs && GET_MODE (data_regs[i]) == QImode)
3862 {
3863 emit_move_insn (adjust_address (orig_dst, QImode, ofs), data_regs[i]);
3864 i++;
3865 ofs += 1;
3866 }
3867
3868 if (i != nregs)
3869 abort ();
3870
3871 return 1;
3872 }
3873
3874 int
3875 alpha_expand_block_clear (rtx operands[])
3876 {
3877 rtx bytes_rtx = operands[1];
3878 rtx align_rtx = operands[2];
3879 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
3880 HOST_WIDE_INT bytes = orig_bytes;
3881 HOST_WIDE_INT align = INTVAL (align_rtx) * BITS_PER_UNIT;
3882 HOST_WIDE_INT alignofs = 0;
3883 rtx orig_dst = operands[0];
3884 rtx tmp;
3885 int i, words, ofs = 0;
3886
3887 if (orig_bytes <= 0)
3888 return 1;
3889 if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD)
3890 return 0;
3891
3892 /* Look for stricter alignment. */
3893 tmp = XEXP (orig_dst, 0);
3894 if (GET_CODE (tmp) == REG)
3895 align = MAX (align, REGNO_POINTER_ALIGN (REGNO (tmp)));
3896 else if (GET_CODE (tmp) == PLUS
3897 && GET_CODE (XEXP (tmp, 0)) == REG
3898 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
3899 {
3900 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
3901 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
3902
3903 if (a > align)
3904 {
3905 if (a >= 64)
3906 align = a, alignofs = 8 - c % 8;
3907 else if (a >= 32)
3908 align = a, alignofs = 4 - c % 4;
3909 else if (a >= 16)
3910 align = a, alignofs = 2 - c % 2;
3911 }
3912 }
3913
3914 /* Handle an unaligned prefix first. */
3915
3916 if (alignofs > 0)
3917 {
3918 #if HOST_BITS_PER_WIDE_INT >= 64
3919 /* Given that alignofs is bounded by align, the only time BWX could
3920 generate three stores is for a 7 byte fill. Prefer two individual
3921 stores over a load/mask/store sequence. */
3922 if ((!TARGET_BWX || alignofs == 7)
3923 && align >= 32
3924 && !(alignofs == 4 && bytes >= 4))
3925 {
3926 enum machine_mode mode = (align >= 64 ? DImode : SImode);
3927 int inv_alignofs = (align >= 64 ? 8 : 4) - alignofs;
3928 rtx mem, tmp;
3929 HOST_WIDE_INT mask;
3930
3931 mem = adjust_address (orig_dst, mode, ofs - inv_alignofs);
3932 set_mem_alias_set (mem, 0);
3933
3934 mask = ~(~(HOST_WIDE_INT)0 << (inv_alignofs * 8));
3935 if (bytes < alignofs)
3936 {
3937 mask |= ~(HOST_WIDE_INT)0 << ((inv_alignofs + bytes) * 8);
3938 ofs += bytes;
3939 bytes = 0;
3940 }
3941 else
3942 {
3943 bytes -= alignofs;
3944 ofs += alignofs;
3945 }
3946 alignofs = 0;
3947
3948 tmp = expand_binop (mode, and_optab, mem, GEN_INT (mask),
3949 NULL_RTX, 1, OPTAB_WIDEN);
3950
3951 emit_move_insn (mem, tmp);
3952 }
3953 #endif
3954
3955 if (TARGET_BWX && (alignofs & 1) && bytes >= 1)
3956 {
3957 emit_move_insn (adjust_address (orig_dst, QImode, ofs), const0_rtx);
3958 bytes -= 1;
3959 ofs += 1;
3960 alignofs -= 1;
3961 }
3962 if (TARGET_BWX && align >= 16 && (alignofs & 3) == 2 && bytes >= 2)
3963 {
3964 emit_move_insn (adjust_address (orig_dst, HImode, ofs), const0_rtx);
3965 bytes -= 2;
3966 ofs += 2;
3967 alignofs -= 2;
3968 }
3969 if (alignofs == 4 && bytes >= 4)
3970 {
3971 emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx);
3972 bytes -= 4;
3973 ofs += 4;
3974 alignofs = 0;
3975 }
3976
3977 /* If we've not used the extra lead alignment information by now,
3978 we won't be able to. Downgrade align to match what's left over. */
3979 if (alignofs > 0)
3980 {
3981 alignofs = alignofs & -alignofs;
3982 align = MIN (align, alignofs * BITS_PER_UNIT);
3983 }
3984 }
3985
3986 /* Handle a block of contiguous long-words. */
3987
3988 if (align >= 64 && bytes >= 8)
3989 {
3990 words = bytes / 8;
3991
3992 for (i = 0; i < words; ++i)
3993 emit_move_insn (adjust_address (orig_dst, DImode, ofs + i * 8),
3994 const0_rtx);
3995
3996 bytes -= words * 8;
3997 ofs += words * 8;
3998 }
3999
4000 /* If the block is large and appropriately aligned, emit a single
4001 store followed by a sequence of stq_u insns. */
4002
4003 if (align >= 32 && bytes > 16)
4004 {
4005 rtx orig_dsta;
4006
4007 emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx);
4008 bytes -= 4;
4009 ofs += 4;
4010
4011 orig_dsta = XEXP (orig_dst, 0);
4012 if (GET_CODE (orig_dsta) == LO_SUM)
4013 orig_dsta = force_reg (Pmode, orig_dsta);
4014
4015 words = bytes / 8;
4016 for (i = 0; i < words; ++i)
4017 {
4018 rtx mem
4019 = change_address (orig_dst, DImode,
4020 gen_rtx_AND (DImode,
4021 plus_constant (orig_dsta, ofs + i*8),
4022 GEN_INT (-8)));
4023 set_mem_alias_set (mem, 0);
4024 emit_move_insn (mem, const0_rtx);
4025 }
4026
4027 /* Depending on the alignment, the first stq_u may have overlapped
4028 with the initial stl, which means that the last stq_u didn't
4029 write as much as it would appear. Leave those questionable bytes
4030 unaccounted for. */
4031 bytes -= words * 8 - 4;
4032 ofs += words * 8 - 4;
4033 }
4034
4035 /* Handle a smaller block of aligned words. */
4036
4037 if ((align >= 64 && bytes == 4)
4038 || (align == 32 && bytes >= 4))
4039 {
4040 words = bytes / 4;
4041
4042 for (i = 0; i < words; ++i)
4043 emit_move_insn (adjust_address (orig_dst, SImode, ofs + i * 4),
4044 const0_rtx);
4045
4046 bytes -= words * 4;
4047 ofs += words * 4;
4048 }
4049
4050 /* An unaligned block uses stq_u stores for as many as possible. */
4051
4052 if (bytes >= 8)
4053 {
4054 words = bytes / 8;
4055
4056 alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
4057
4058 bytes -= words * 8;
4059 ofs += words * 8;
4060 }
4061
4062 /* Next clean up any trailing pieces. */
4063
4064 #if HOST_BITS_PER_WIDE_INT >= 64
4065 /* Count the number of bits in BYTES for which aligned stores could
4066 be emitted. */
4067 words = 0;
4068 for (i = (TARGET_BWX ? 1 : 4); i * BITS_PER_UNIT <= align ; i <<= 1)
4069 if (bytes & i)
4070 words += 1;
4071
4072 /* If we have appropriate alignment (and it wouldn't take too many
4073 instructions otherwise), mask out the bytes we need. */
4074 if (TARGET_BWX ? words > 2 : bytes > 0)
4075 {
4076 if (align >= 64)
4077 {
4078 rtx mem, tmp;
4079 HOST_WIDE_INT mask;
4080
4081 mem = adjust_address (orig_dst, DImode, ofs);
4082 set_mem_alias_set (mem, 0);
4083
4084 mask = ~(HOST_WIDE_INT)0 << (bytes * 8);
4085
4086 tmp = expand_binop (DImode, and_optab, mem, GEN_INT (mask),
4087 NULL_RTX, 1, OPTAB_WIDEN);
4088
4089 emit_move_insn (mem, tmp);
4090 return 1;
4091 }
4092 else if (align >= 32 && bytes < 4)
4093 {
4094 rtx mem, tmp;
4095 HOST_WIDE_INT mask;
4096
4097 mem = adjust_address (orig_dst, SImode, ofs);
4098 set_mem_alias_set (mem, 0);
4099
4100 mask = ~(HOST_WIDE_INT)0 << (bytes * 8);
4101
4102 tmp = expand_binop (SImode, and_optab, mem, GEN_INT (mask),
4103 NULL_RTX, 1, OPTAB_WIDEN);
4104
4105 emit_move_insn (mem, tmp);
4106 return 1;
4107 }
4108 }
4109 #endif
4110
4111 if (!TARGET_BWX && bytes >= 4)
4112 {
4113 alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
4114 bytes -= 4;
4115 ofs += 4;
4116 }
4117
4118 if (bytes >= 2)
4119 {
4120 if (align >= 16)
4121 {
4122 do {
4123 emit_move_insn (adjust_address (orig_dst, HImode, ofs),
4124 const0_rtx);
4125 bytes -= 2;
4126 ofs += 2;
4127 } while (bytes >= 2);
4128 }
4129 else if (! TARGET_BWX)
4130 {
4131 alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
4132 bytes -= 2;
4133 ofs += 2;
4134 }
4135 }
4136
4137 while (bytes > 0)
4138 {
4139 emit_move_insn (adjust_address (orig_dst, QImode, ofs), const0_rtx);
4140 bytes -= 1;
4141 ofs += 1;
4142 }
4143
4144 return 1;
4145 }
4146
4147 /* Returns a mask so that zap(x, value) == x & mask. */
4148
4149 rtx
4150 alpha_expand_zap_mask (HOST_WIDE_INT value)
4151 {
4152 rtx result;
4153 int i;
4154
4155 if (HOST_BITS_PER_WIDE_INT >= 64)
4156 {
4157 HOST_WIDE_INT mask = 0;
4158
4159 for (i = 7; i >= 0; --i)
4160 {
4161 mask <<= 8;
4162 if (!((value >> i) & 1))
4163 mask |= 0xff;
4164 }
4165
4166 result = gen_int_mode (mask, DImode);
4167 }
4168 else if (HOST_BITS_PER_WIDE_INT == 32)
4169 {
4170 HOST_WIDE_INT mask_lo = 0, mask_hi = 0;
4171
4172 for (i = 7; i >= 4; --i)
4173 {
4174 mask_hi <<= 8;
4175 if (!((value >> i) & 1))
4176 mask_hi |= 0xff;
4177 }
4178
4179 for (i = 3; i >= 0; --i)
4180 {
4181 mask_lo <<= 8;
4182 if (!((value >> i) & 1))
4183 mask_lo |= 0xff;
4184 }
4185
4186 result = immed_double_const (mask_lo, mask_hi, DImode);
4187 }
4188 else
4189 abort ();
4190
4191 return result;
4192 }
4193
4194 void
4195 alpha_expand_builtin_vector_binop (rtx (*gen) (rtx, rtx, rtx),
4196 enum machine_mode mode,
4197 rtx op0, rtx op1, rtx op2)
4198 {
4199 op0 = gen_lowpart (mode, op0);
4200
4201 if (op1 == const0_rtx)
4202 op1 = CONST0_RTX (mode);
4203 else
4204 op1 = gen_lowpart (mode, op1);
4205
4206 if (op2 == const0_rtx)
4207 op2 = CONST0_RTX (mode);
4208 else
4209 op2 = gen_lowpart (mode, op2);
4210
4211 emit_insn ((*gen) (op0, op1, op2));
4212 }
4213 \f
4214 /* Adjust the cost of a scheduling dependency. Return the new cost of
4215 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
4216
4217 static int
4218 alpha_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
4219 {
4220 enum attr_type insn_type, dep_insn_type;
4221
4222 /* If the dependence is an anti-dependence, there is no cost. For an
4223 output dependence, there is sometimes a cost, but it doesn't seem
4224 worth handling those few cases. */
4225 if (REG_NOTE_KIND (link) != 0)
4226 return cost;
4227
4228 /* If we can't recognize the insns, we can't really do anything. */
4229 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
4230 return cost;
4231
4232 insn_type = get_attr_type (insn);
4233 dep_insn_type = get_attr_type (dep_insn);
4234
4235 /* Bring in the user-defined memory latency. */
4236 if (dep_insn_type == TYPE_ILD
4237 || dep_insn_type == TYPE_FLD
4238 || dep_insn_type == TYPE_LDSYM)
4239 cost += alpha_memory_latency-1;
4240
4241 /* Everything else handled in DFA bypasses now. */
4242
4243 return cost;
4244 }
4245
4246 /* The number of instructions that can be issued per cycle. */
4247
4248 static int
4249 alpha_issue_rate (void)
4250 {
4251 return (alpha_cpu == PROCESSOR_EV4 ? 2 : 4);
4252 }
4253
4254 /* How many alternative schedules to try. This should be as wide as the
4255 scheduling freedom in the DFA, but no wider. Making this value too
4256 large results extra work for the scheduler.
4257
4258 For EV4, loads can be issued to either IB0 or IB1, thus we have 2
4259 alternative schedules. For EV5, we can choose between E0/E1 and
4260 FA/FM. For EV6, an arithmetic insn can be issued to U0/U1/L0/L1. */
4261
4262 static int
4263 alpha_multipass_dfa_lookahead (void)
4264 {
4265 return (alpha_cpu == PROCESSOR_EV6 ? 4 : 2);
4266 }
4267 \f
4268 /* Machine-specific function data. */
4269
4270 struct machine_function GTY(())
4271 {
4272 /* For unicosmk. */
4273 /* List of call information words for calls from this function. */
4274 struct rtx_def *first_ciw;
4275 struct rtx_def *last_ciw;
4276 int ciw_count;
4277
4278 /* List of deferred case vectors. */
4279 struct rtx_def *addr_list;
4280
4281 /* For OSF. */
4282 const char *some_ld_name;
4283
4284 /* For TARGET_LD_BUGGY_LDGP. */
4285 struct rtx_def *gp_save_rtx;
4286 };
4287
4288 /* How to allocate a 'struct machine_function'. */
4289
4290 static struct machine_function *
4291 alpha_init_machine_status (void)
4292 {
4293 return ((struct machine_function *)
4294 ggc_alloc_cleared (sizeof (struct machine_function)));
4295 }
4296
4297 /* Functions to save and restore alpha_return_addr_rtx. */
4298
4299 /* Start the ball rolling with RETURN_ADDR_RTX. */
4300
4301 rtx
4302 alpha_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
4303 {
4304 if (count != 0)
4305 return const0_rtx;
4306
4307 return get_hard_reg_initial_val (Pmode, REG_RA);
4308 }
4309
4310 /* Return or create a memory slot containing the gp value for the current
4311 function. Needed only if TARGET_LD_BUGGY_LDGP. */
4312
4313 rtx
4314 alpha_gp_save_rtx (void)
4315 {
4316 rtx seq, m = cfun->machine->gp_save_rtx;
4317
4318 if (m == NULL)
4319 {
4320 start_sequence ();
4321
4322 m = assign_stack_local (DImode, UNITS_PER_WORD, BITS_PER_WORD);
4323 m = validize_mem (m);
4324 emit_move_insn (m, pic_offset_table_rtx);
4325
4326 seq = get_insns ();
4327 end_sequence ();
4328 emit_insn_after (seq, entry_of_function ());
4329
4330 cfun->machine->gp_save_rtx = m;
4331 }
4332
4333 return m;
4334 }
4335
4336 static int
4337 alpha_ra_ever_killed (void)
4338 {
4339 rtx top;
4340
4341 if (!has_hard_reg_initial_val (Pmode, REG_RA))
4342 return regs_ever_live[REG_RA];
4343
4344 push_topmost_sequence ();
4345 top = get_insns ();
4346 pop_topmost_sequence ();
4347
4348 return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX);
4349 }
4350
4351 \f
4352 /* Return the trap mode suffix applicable to the current
4353 instruction, or NULL. */
4354
4355 static const char *
4356 get_trap_mode_suffix (void)
4357 {
4358 enum attr_trap_suffix s = get_attr_trap_suffix (current_output_insn);
4359
4360 switch (s)
4361 {
4362 case TRAP_SUFFIX_NONE:
4363 return NULL;
4364
4365 case TRAP_SUFFIX_SU:
4366 if (alpha_fptm >= ALPHA_FPTM_SU)
4367 return "su";
4368 return NULL;
4369
4370 case TRAP_SUFFIX_SUI:
4371 if (alpha_fptm >= ALPHA_FPTM_SUI)
4372 return "sui";
4373 return NULL;
4374
4375 case TRAP_SUFFIX_V_SV:
4376 switch (alpha_fptm)
4377 {
4378 case ALPHA_FPTM_N:
4379 return NULL;
4380 case ALPHA_FPTM_U:
4381 return "v";
4382 case ALPHA_FPTM_SU:
4383 case ALPHA_FPTM_SUI:
4384 return "sv";
4385 }
4386 break;
4387
4388 case TRAP_SUFFIX_V_SV_SVI:
4389 switch (alpha_fptm)
4390 {
4391 case ALPHA_FPTM_N:
4392 return NULL;
4393 case ALPHA_FPTM_U:
4394 return "v";
4395 case ALPHA_FPTM_SU:
4396 return "sv";
4397 case ALPHA_FPTM_SUI:
4398 return "svi";
4399 }
4400 break;
4401
4402 case TRAP_SUFFIX_U_SU_SUI:
4403 switch (alpha_fptm)
4404 {
4405 case ALPHA_FPTM_N:
4406 return NULL;
4407 case ALPHA_FPTM_U:
4408 return "u";
4409 case ALPHA_FPTM_SU:
4410 return "su";
4411 case ALPHA_FPTM_SUI:
4412 return "sui";
4413 }
4414 break;
4415 }
4416 abort ();
4417 }
4418
4419 /* Return the rounding mode suffix applicable to the current
4420 instruction, or NULL. */
4421
4422 static const char *
4423 get_round_mode_suffix (void)
4424 {
4425 enum attr_round_suffix s = get_attr_round_suffix (current_output_insn);
4426
4427 switch (s)
4428 {
4429 case ROUND_SUFFIX_NONE:
4430 return NULL;
4431 case ROUND_SUFFIX_NORMAL:
4432 switch (alpha_fprm)
4433 {
4434 case ALPHA_FPRM_NORM:
4435 return NULL;
4436 case ALPHA_FPRM_MINF:
4437 return "m";
4438 case ALPHA_FPRM_CHOP:
4439 return "c";
4440 case ALPHA_FPRM_DYN:
4441 return "d";
4442 }
4443 break;
4444
4445 case ROUND_SUFFIX_C:
4446 return "c";
4447 }
4448 abort ();
4449 }
4450
4451 /* Locate some local-dynamic symbol still in use by this function
4452 so that we can print its name in some movdi_er_tlsldm pattern. */
4453
4454 static int
4455 get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
4456 {
4457 rtx x = *px;
4458
4459 if (GET_CODE (x) == SYMBOL_REF
4460 && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
4461 {
4462 cfun->machine->some_ld_name = XSTR (x, 0);
4463 return 1;
4464 }
4465
4466 return 0;
4467 }
4468
4469 static const char *
4470 get_some_local_dynamic_name (void)
4471 {
4472 rtx insn;
4473
4474 if (cfun->machine->some_ld_name)
4475 return cfun->machine->some_ld_name;
4476
4477 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
4478 if (INSN_P (insn)
4479 && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
4480 return cfun->machine->some_ld_name;
4481
4482 abort ();
4483 }
4484
4485 /* Print an operand. Recognize special options, documented below. */
4486
4487 void
4488 print_operand (FILE *file, rtx x, int code)
4489 {
4490 int i;
4491
4492 switch (code)
4493 {
4494 case '~':
4495 /* Print the assembler name of the current function. */
4496 assemble_name (file, alpha_fnname);
4497 break;
4498
4499 case '&':
4500 assemble_name (file, get_some_local_dynamic_name ());
4501 break;
4502
4503 case '/':
4504 {
4505 const char *trap = get_trap_mode_suffix ();
4506 const char *round = get_round_mode_suffix ();
4507
4508 if (trap || round)
4509 fprintf (file, (TARGET_AS_SLASH_BEFORE_SUFFIX ? "/%s%s" : "%s%s"),
4510 (trap ? trap : ""), (round ? round : ""));
4511 break;
4512 }
4513
4514 case ',':
4515 /* Generates single precision instruction suffix. */
4516 fputc ((TARGET_FLOAT_VAX ? 'f' : 's'), file);
4517 break;
4518
4519 case '-':
4520 /* Generates double precision instruction suffix. */
4521 fputc ((TARGET_FLOAT_VAX ? 'g' : 't'), file);
4522 break;
4523
4524 case '+':
4525 /* Generates a nop after a noreturn call at the very end of the
4526 function. */
4527 if (next_real_insn (current_output_insn) == 0)
4528 fprintf (file, "\n\tnop");
4529 break;
4530
4531 case '#':
4532 if (alpha_this_literal_sequence_number == 0)
4533 alpha_this_literal_sequence_number = alpha_next_sequence_number++;
4534 fprintf (file, "%d", alpha_this_literal_sequence_number);
4535 break;
4536
4537 case '*':
4538 if (alpha_this_gpdisp_sequence_number == 0)
4539 alpha_this_gpdisp_sequence_number = alpha_next_sequence_number++;
4540 fprintf (file, "%d", alpha_this_gpdisp_sequence_number);
4541 break;
4542
4543 case 'H':
4544 if (GET_CODE (x) == HIGH)
4545 output_addr_const (file, XEXP (x, 0));
4546 else
4547 output_operand_lossage ("invalid %%H value");
4548 break;
4549
4550 case 'J':
4551 {
4552 const char *lituse;
4553
4554 if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD_CALL)
4555 {
4556 x = XVECEXP (x, 0, 0);
4557 lituse = "lituse_tlsgd";
4558 }
4559 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM_CALL)
4560 {
4561 x = XVECEXP (x, 0, 0);
4562 lituse = "lituse_tlsldm";
4563 }
4564 else if (GET_CODE (x) == CONST_INT)
4565 lituse = "lituse_jsr";
4566 else
4567 {
4568 output_operand_lossage ("invalid %%J value");
4569 break;
4570 }
4571
4572 if (x != const0_rtx)
4573 fprintf (file, "\t\t!%s!%d", lituse, (int) INTVAL (x));
4574 }
4575 break;
4576
4577 case 'r':
4578 /* If this operand is the constant zero, write it as "$31". */
4579 if (GET_CODE (x) == REG)
4580 fprintf (file, "%s", reg_names[REGNO (x)]);
4581 else if (x == CONST0_RTX (GET_MODE (x)))
4582 fprintf (file, "$31");
4583 else
4584 output_operand_lossage ("invalid %%r value");
4585 break;
4586
4587 case 'R':
4588 /* Similar, but for floating-point. */
4589 if (GET_CODE (x) == REG)
4590 fprintf (file, "%s", reg_names[REGNO (x)]);
4591 else if (x == CONST0_RTX (GET_MODE (x)))
4592 fprintf (file, "$f31");
4593 else
4594 output_operand_lossage ("invalid %%R value");
4595 break;
4596
4597 case 'N':
4598 /* Write the 1's complement of a constant. */
4599 if (GET_CODE (x) != CONST_INT)
4600 output_operand_lossage ("invalid %%N value");
4601
4602 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
4603 break;
4604
4605 case 'P':
4606 /* Write 1 << C, for a constant C. */
4607 if (GET_CODE (x) != CONST_INT)
4608 output_operand_lossage ("invalid %%P value");
4609
4610 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
4611 break;
4612
4613 case 'h':
4614 /* Write the high-order 16 bits of a constant, sign-extended. */
4615 if (GET_CODE (x) != CONST_INT)
4616 output_operand_lossage ("invalid %%h value");
4617
4618 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
4619 break;
4620
4621 case 'L':
4622 /* Write the low-order 16 bits of a constant, sign-extended. */
4623 if (GET_CODE (x) != CONST_INT)
4624 output_operand_lossage ("invalid %%L value");
4625
4626 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4627 (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
4628 break;
4629
4630 case 'm':
4631 /* Write mask for ZAP insn. */
4632 if (GET_CODE (x) == CONST_DOUBLE)
4633 {
4634 HOST_WIDE_INT mask = 0;
4635 HOST_WIDE_INT value;
4636
4637 value = CONST_DOUBLE_LOW (x);
4638 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
4639 i++, value >>= 8)
4640 if (value & 0xff)
4641 mask |= (1 << i);
4642
4643 value = CONST_DOUBLE_HIGH (x);
4644 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
4645 i++, value >>= 8)
4646 if (value & 0xff)
4647 mask |= (1 << (i + sizeof (int)));
4648
4649 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
4650 }
4651
4652 else if (GET_CODE (x) == CONST_INT)
4653 {
4654 HOST_WIDE_INT mask = 0, value = INTVAL (x);
4655
4656 for (i = 0; i < 8; i++, value >>= 8)
4657 if (value & 0xff)
4658 mask |= (1 << i);
4659
4660 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
4661 }
4662 else
4663 output_operand_lossage ("invalid %%m value");
4664 break;
4665
4666 case 'M':
4667 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
4668 if (GET_CODE (x) != CONST_INT
4669 || (INTVAL (x) != 8 && INTVAL (x) != 16
4670 && INTVAL (x) != 32 && INTVAL (x) != 64))
4671 output_operand_lossage ("invalid %%M value");
4672
4673 fprintf (file, "%s",
4674 (INTVAL (x) == 8 ? "b"
4675 : INTVAL (x) == 16 ? "w"
4676 : INTVAL (x) == 32 ? "l"
4677 : "q"));
4678 break;
4679
4680 case 'U':
4681 /* Similar, except do it from the mask. */
4682 if (GET_CODE (x) == CONST_INT)
4683 {
4684 HOST_WIDE_INT value = INTVAL (x);
4685
4686 if (value == 0xff)
4687 {
4688 fputc ('b', file);
4689 break;
4690 }
4691 if (value == 0xffff)
4692 {
4693 fputc ('w', file);
4694 break;
4695 }
4696 if (value == 0xffffffff)
4697 {
4698 fputc ('l', file);
4699 break;
4700 }
4701 if (value == -1)
4702 {
4703 fputc ('q', file);
4704 break;
4705 }
4706 }
4707 else if (HOST_BITS_PER_WIDE_INT == 32
4708 && GET_CODE (x) == CONST_DOUBLE
4709 && CONST_DOUBLE_LOW (x) == 0xffffffff
4710 && CONST_DOUBLE_HIGH (x) == 0)
4711 {
4712 fputc ('l', file);
4713 break;
4714 }
4715 output_operand_lossage ("invalid %%U value");
4716 break;
4717
4718 case 's':
4719 /* Write the constant value divided by 8 for little-endian mode or
4720 (56 - value) / 8 for big-endian mode. */
4721
4722 if (GET_CODE (x) != CONST_INT
4723 || (unsigned HOST_WIDE_INT) INTVAL (x) >= (WORDS_BIG_ENDIAN
4724 ? 56
4725 : 64)
4726 || (INTVAL (x) & 7) != 0)
4727 output_operand_lossage ("invalid %%s value");
4728
4729 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4730 WORDS_BIG_ENDIAN
4731 ? (56 - INTVAL (x)) / 8
4732 : INTVAL (x) / 8);
4733 break;
4734
4735 case 'S':
4736 /* Same, except compute (64 - c) / 8 */
4737
4738 if (GET_CODE (x) != CONST_INT
4739 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
4740 && (INTVAL (x) & 7) != 8)
4741 output_operand_lossage ("invalid %%s value");
4742
4743 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
4744 break;
4745
4746 case 't':
4747 {
4748 /* On Unicos/Mk systems: use a DEX expression if the symbol
4749 clashes with a register name. */
4750 int dex = unicosmk_need_dex (x);
4751 if (dex)
4752 fprintf (file, "DEX(%d)", dex);
4753 else
4754 output_addr_const (file, x);
4755 }
4756 break;
4757
4758 case 'C': case 'D': case 'c': case 'd':
4759 /* Write out comparison name. */
4760 {
4761 enum rtx_code c = GET_CODE (x);
4762
4763 if (!COMPARISON_P (x))
4764 output_operand_lossage ("invalid %%C value");
4765
4766 else if (code == 'D')
4767 c = reverse_condition (c);
4768 else if (code == 'c')
4769 c = swap_condition (c);
4770 else if (code == 'd')
4771 c = swap_condition (reverse_condition (c));
4772
4773 if (c == LEU)
4774 fprintf (file, "ule");
4775 else if (c == LTU)
4776 fprintf (file, "ult");
4777 else if (c == UNORDERED)
4778 fprintf (file, "un");
4779 else
4780 fprintf (file, "%s", GET_RTX_NAME (c));
4781 }
4782 break;
4783
4784 case 'E':
4785 /* Write the divide or modulus operator. */
4786 switch (GET_CODE (x))
4787 {
4788 case DIV:
4789 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
4790 break;
4791 case UDIV:
4792 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
4793 break;
4794 case MOD:
4795 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
4796 break;
4797 case UMOD:
4798 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
4799 break;
4800 default:
4801 output_operand_lossage ("invalid %%E value");
4802 break;
4803 }
4804 break;
4805
4806 case 'A':
4807 /* Write "_u" for unaligned access. */
4808 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
4809 fprintf (file, "_u");
4810 break;
4811
4812 case 0:
4813 if (GET_CODE (x) == REG)
4814 fprintf (file, "%s", reg_names[REGNO (x)]);
4815 else if (GET_CODE (x) == MEM)
4816 output_address (XEXP (x, 0));
4817 else if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == UNSPEC)
4818 {
4819 switch (XINT (XEXP (x, 0), 1))
4820 {
4821 case UNSPEC_DTPREL:
4822 case UNSPEC_TPREL:
4823 output_addr_const (file, XVECEXP (XEXP (x, 0), 0, 0));
4824 break;
4825 default:
4826 output_operand_lossage ("unknown relocation unspec");
4827 break;
4828 }
4829 }
4830 else
4831 output_addr_const (file, x);
4832 break;
4833
4834 default:
4835 output_operand_lossage ("invalid %%xn code");
4836 }
4837 }
4838
4839 void
4840 print_operand_address (FILE *file, rtx addr)
4841 {
4842 int basereg = 31;
4843 HOST_WIDE_INT offset = 0;
4844
4845 if (GET_CODE (addr) == AND)
4846 addr = XEXP (addr, 0);
4847
4848 if (GET_CODE (addr) == PLUS
4849 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
4850 {
4851 offset = INTVAL (XEXP (addr, 1));
4852 addr = XEXP (addr, 0);
4853 }
4854
4855 if (GET_CODE (addr) == LO_SUM)
4856 {
4857 const char *reloc16, *reloclo;
4858 rtx op1 = XEXP (addr, 1);
4859
4860 if (GET_CODE (op1) == CONST && GET_CODE (XEXP (op1, 0)) == UNSPEC)
4861 {
4862 op1 = XEXP (op1, 0);
4863 switch (XINT (op1, 1))
4864 {
4865 case UNSPEC_DTPREL:
4866 reloc16 = NULL;
4867 reloclo = (alpha_tls_size == 16 ? "dtprel" : "dtprello");
4868 break;
4869 case UNSPEC_TPREL:
4870 reloc16 = NULL;
4871 reloclo = (alpha_tls_size == 16 ? "tprel" : "tprello");
4872 break;
4873 default:
4874 output_operand_lossage ("unknown relocation unspec");
4875 return;
4876 }
4877
4878 output_addr_const (file, XVECEXP (op1, 0, 0));
4879 }
4880 else
4881 {
4882 reloc16 = "gprel";
4883 reloclo = "gprellow";
4884 output_addr_const (file, op1);
4885 }
4886
4887 if (offset)
4888 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
4889
4890 addr = XEXP (addr, 0);
4891 if (GET_CODE (addr) == REG)
4892 basereg = REGNO (addr);
4893 else if (GET_CODE (addr) == SUBREG
4894 && GET_CODE (SUBREG_REG (addr)) == REG)
4895 basereg = subreg_regno (addr);
4896 else
4897 abort ();
4898
4899 fprintf (file, "($%d)\t\t!%s", basereg,
4900 (basereg == 29 ? reloc16 : reloclo));
4901 return;
4902 }
4903
4904 if (GET_CODE (addr) == REG)
4905 basereg = REGNO (addr);
4906 else if (GET_CODE (addr) == SUBREG
4907 && GET_CODE (SUBREG_REG (addr)) == REG)
4908 basereg = subreg_regno (addr);
4909 else if (GET_CODE (addr) == CONST_INT)
4910 offset = INTVAL (addr);
4911
4912 #if TARGET_ABI_OPEN_VMS
4913 else if (GET_CODE (addr) == SYMBOL_REF)
4914 {
4915 fprintf (file, "%s", XSTR (addr, 0));
4916 return;
4917 }
4918 else if (GET_CODE (addr) == CONST
4919 && GET_CODE (XEXP (addr, 0)) == PLUS
4920 && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF)
4921 {
4922 fprintf (file, "%s+" HOST_WIDE_INT_PRINT_DEC,
4923 XSTR (XEXP (XEXP (addr, 0), 0), 0),
4924 INTVAL (XEXP (XEXP (addr, 0), 1)));
4925 return;
4926 }
4927 #endif
4928
4929 else
4930 abort ();
4931
4932 fprintf (file, HOST_WIDE_INT_PRINT_DEC "($%d)", offset, basereg);
4933 }
4934 \f
4935 /* Emit RTL insns to initialize the variable parts of a trampoline at
4936 TRAMP. FNADDR is an RTX for the address of the function's pure
4937 code. CXT is an RTX for the static chain value for the function.
4938
4939 The three offset parameters are for the individual template's
4940 layout. A JMPOFS < 0 indicates that the trampoline does not
4941 contain instructions at all.
4942
4943 We assume here that a function will be called many more times than
4944 its address is taken (e.g., it might be passed to qsort), so we
4945 take the trouble to initialize the "hint" field in the JMP insn.
4946 Note that the hint field is PC (new) + 4 * bits 13:0. */
4947
4948 void
4949 alpha_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt,
4950 int fnofs, int cxtofs, int jmpofs)
4951 {
4952 rtx temp, temp1, addr;
4953 /* VMS really uses DImode pointers in memory at this point. */
4954 enum machine_mode mode = TARGET_ABI_OPEN_VMS ? Pmode : ptr_mode;
4955
4956 #ifdef POINTERS_EXTEND_UNSIGNED
4957 fnaddr = convert_memory_address (mode, fnaddr);
4958 cxt = convert_memory_address (mode, cxt);
4959 #endif
4960
4961 /* Store function address and CXT. */
4962 addr = memory_address (mode, plus_constant (tramp, fnofs));
4963 emit_move_insn (gen_rtx_MEM (mode, addr), fnaddr);
4964 addr = memory_address (mode, plus_constant (tramp, cxtofs));
4965 emit_move_insn (gen_rtx_MEM (mode, addr), cxt);
4966
4967 /* This has been disabled since the hint only has a 32k range, and in
4968 no existing OS is the stack within 32k of the text segment. */
4969 if (0 && jmpofs >= 0)
4970 {
4971 /* Compute hint value. */
4972 temp = force_operand (plus_constant (tramp, jmpofs+4), NULL_RTX);
4973 temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1,
4974 OPTAB_WIDEN);
4975 temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
4976 build_int_cst (NULL_TREE, 2), NULL_RTX, 1);
4977 temp = expand_and (SImode, gen_lowpart (SImode, temp),
4978 GEN_INT (0x3fff), 0);
4979
4980 /* Merge in the hint. */
4981 addr = memory_address (SImode, plus_constant (tramp, jmpofs));
4982 temp1 = force_reg (SImode, gen_rtx_MEM (SImode, addr));
4983 temp1 = expand_and (SImode, temp1, GEN_INT (0xffffc000), NULL_RTX);
4984 temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1,
4985 OPTAB_WIDEN);
4986 emit_move_insn (gen_rtx_MEM (SImode, addr), temp1);
4987 }
4988
4989 #ifdef ENABLE_EXECUTE_STACK
4990 emit_library_call (init_one_libfunc ("__enable_execute_stack"),
4991 0, VOIDmode, 1, tramp, Pmode);
4992 #endif
4993
4994 if (jmpofs >= 0)
4995 emit_insn (gen_imb ());
4996 }
4997 \f
4998 /* Determine where to put an argument to a function.
4999 Value is zero to push the argument on the stack,
5000 or a hard register in which to store the argument.
5001
5002 MODE is the argument's machine mode.
5003 TYPE is the data type of the argument (as a tree).
5004 This is null for libcalls where that information may
5005 not be available.
5006 CUM is a variable of type CUMULATIVE_ARGS which gives info about
5007 the preceding args and about the function being called.
5008 NAMED is nonzero if this argument is a named parameter
5009 (otherwise it is an extra parameter matching an ellipsis).
5010
5011 On Alpha the first 6 words of args are normally in registers
5012 and the rest are pushed. */
5013
5014 rtx
5015 function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode, tree type,
5016 int named ATTRIBUTE_UNUSED)
5017 {
5018 int basereg;
5019 int num_args;
5020
5021 /* Don't get confused and pass small structures in FP registers. */
5022 if (type && AGGREGATE_TYPE_P (type))
5023 basereg = 16;
5024 else
5025 {
5026 #ifdef ENABLE_CHECKING
5027 /* With alpha_split_complex_arg, we shouldn't see any raw complex
5028 values here. */
5029 if (COMPLEX_MODE_P (mode))
5030 abort ();
5031 #endif
5032
5033 /* Set up defaults for FP operands passed in FP registers, and
5034 integral operands passed in integer registers. */
5035 if (TARGET_FPREGS && GET_MODE_CLASS (mode) == MODE_FLOAT)
5036 basereg = 32 + 16;
5037 else
5038 basereg = 16;
5039 }
5040
5041 /* ??? Irritatingly, the definition of CUMULATIVE_ARGS is different for
5042 the three platforms, so we can't avoid conditional compilation. */
5043 #if TARGET_ABI_OPEN_VMS
5044 {
5045 if (mode == VOIDmode)
5046 return alpha_arg_info_reg_val (cum);
5047
5048 num_args = cum.num_args;
5049 if (num_args >= 6
5050 || targetm.calls.must_pass_in_stack (mode, type))
5051 return NULL_RTX;
5052 }
5053 #elif TARGET_ABI_UNICOSMK
5054 {
5055 int size;
5056
5057 /* If this is the last argument, generate the call info word (CIW). */
5058 /* ??? We don't include the caller's line number in the CIW because
5059 I don't know how to determine it if debug infos are turned off. */
5060 if (mode == VOIDmode)
5061 {
5062 int i;
5063 HOST_WIDE_INT lo;
5064 HOST_WIDE_INT hi;
5065 rtx ciw;
5066
5067 lo = 0;
5068
5069 for (i = 0; i < cum.num_reg_words && i < 5; i++)
5070 if (cum.reg_args_type[i])
5071 lo |= (1 << (7 - i));
5072
5073 if (cum.num_reg_words == 6 && cum.reg_args_type[5])
5074 lo |= 7;
5075 else
5076 lo |= cum.num_reg_words;
5077
5078 #if HOST_BITS_PER_WIDE_INT == 32
5079 hi = (cum.num_args << 20) | cum.num_arg_words;
5080 #else
5081 lo = lo | ((HOST_WIDE_INT) cum.num_args << 52)
5082 | ((HOST_WIDE_INT) cum.num_arg_words << 32);
5083 hi = 0;
5084 #endif
5085 ciw = immed_double_const (lo, hi, DImode);
5086
5087 return gen_rtx_UNSPEC (DImode, gen_rtvec (1, ciw),
5088 UNSPEC_UMK_LOAD_CIW);
5089 }
5090
5091 size = ALPHA_ARG_SIZE (mode, type, named);
5092 num_args = cum.num_reg_words;
5093 if (cum.force_stack
5094 || cum.num_reg_words + size > 6
5095 || targetm.calls.must_pass_in_stack (mode, type))
5096 return NULL_RTX;
5097 else if (type && TYPE_MODE (type) == BLKmode)
5098 {
5099 rtx reg1, reg2;
5100
5101 reg1 = gen_rtx_REG (DImode, num_args + 16);
5102 reg1 = gen_rtx_EXPR_LIST (DImode, reg1, const0_rtx);
5103
5104 /* The argument fits in two registers. Note that we still need to
5105 reserve a register for empty structures. */
5106 if (size == 0)
5107 return NULL_RTX;
5108 else if (size == 1)
5109 return gen_rtx_PARALLEL (mode, gen_rtvec (1, reg1));
5110 else
5111 {
5112 reg2 = gen_rtx_REG (DImode, num_args + 17);
5113 reg2 = gen_rtx_EXPR_LIST (DImode, reg2, GEN_INT (8));
5114 return gen_rtx_PARALLEL (mode, gen_rtvec (2, reg1, reg2));
5115 }
5116 }
5117 }
5118 #elif TARGET_ABI_OSF
5119 {
5120 if (cum >= 6)
5121 return NULL_RTX;
5122 num_args = cum;
5123
5124 /* VOID is passed as a special flag for "last argument". */
5125 if (type == void_type_node)
5126 basereg = 16;
5127 else if (targetm.calls.must_pass_in_stack (mode, type))
5128 return NULL_RTX;
5129 }
5130 #else
5131 #error Unhandled ABI
5132 #endif
5133
5134 return gen_rtx_REG (mode, num_args + basereg);
5135 }
5136
5137 /* Return true if TYPE must be returned in memory, instead of in registers. */
5138
5139 static bool
5140 alpha_return_in_memory (tree type, tree fndecl ATTRIBUTE_UNUSED)
5141 {
5142 enum machine_mode mode = VOIDmode;
5143 int size;
5144
5145 if (type)
5146 {
5147 mode = TYPE_MODE (type);
5148
5149 /* All aggregates are returned in memory. */
5150 if (AGGREGATE_TYPE_P (type))
5151 return true;
5152 }
5153
5154 size = GET_MODE_SIZE (mode);
5155 switch (GET_MODE_CLASS (mode))
5156 {
5157 case MODE_VECTOR_FLOAT:
5158 /* Pass all float vectors in memory, like an aggregate. */
5159 return true;
5160
5161 case MODE_COMPLEX_FLOAT:
5162 /* We judge complex floats on the size of their element,
5163 not the size of the whole type. */
5164 size = GET_MODE_UNIT_SIZE (mode);
5165 break;
5166
5167 case MODE_INT:
5168 case MODE_FLOAT:
5169 case MODE_COMPLEX_INT:
5170 case MODE_VECTOR_INT:
5171 break;
5172
5173 default:
5174 /* ??? We get called on all sorts of random stuff from
5175 aggregate_value_p. We can't abort, but it's not clear
5176 what's safe to return. Pretend it's a struct I guess. */
5177 return true;
5178 }
5179
5180 /* Otherwise types must fit in one register. */
5181 return size > UNITS_PER_WORD;
5182 }
5183
5184 /* Return true if TYPE should be passed by invisible reference. */
5185
5186 static bool
5187 alpha_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
5188 enum machine_mode mode,
5189 tree type ATTRIBUTE_UNUSED,
5190 bool named ATTRIBUTE_UNUSED)
5191 {
5192 return mode == TFmode || mode == TCmode;
5193 }
5194
5195 /* Define how to find the value returned by a function. VALTYPE is the
5196 data type of the value (as a tree). If the precise function being
5197 called is known, FUNC is its FUNCTION_DECL; otherwise, FUNC is 0.
5198 MODE is set instead of VALTYPE for libcalls.
5199
5200 On Alpha the value is found in $0 for integer functions and
5201 $f0 for floating-point functions. */
5202
5203 rtx
5204 function_value (tree valtype, tree func ATTRIBUTE_UNUSED,
5205 enum machine_mode mode)
5206 {
5207 unsigned int regnum, dummy;
5208 enum mode_class class;
5209
5210 #ifdef ENABLE_CHECKING
5211 if (valtype && alpha_return_in_memory (valtype, func))
5212 abort ();
5213 #endif
5214
5215 if (valtype)
5216 mode = TYPE_MODE (valtype);
5217
5218 class = GET_MODE_CLASS (mode);
5219 switch (class)
5220 {
5221 case MODE_INT:
5222 PROMOTE_MODE (mode, dummy, valtype);
5223 /* FALLTHRU */
5224
5225 case MODE_COMPLEX_INT:
5226 case MODE_VECTOR_INT:
5227 regnum = 0;
5228 break;
5229
5230 case MODE_FLOAT:
5231 regnum = 32;
5232 break;
5233
5234 case MODE_COMPLEX_FLOAT:
5235 {
5236 enum machine_mode cmode = GET_MODE_INNER (mode);
5237
5238 return gen_rtx_PARALLEL
5239 (VOIDmode,
5240 gen_rtvec (2,
5241 gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (cmode, 32),
5242 const0_rtx),
5243 gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (cmode, 33),
5244 GEN_INT (GET_MODE_SIZE (cmode)))));
5245 }
5246
5247 default:
5248 abort ();
5249 }
5250
5251 return gen_rtx_REG (mode, regnum);
5252 }
5253
5254 /* TCmode complex values are passed by invisible reference. We
5255 should not split these values. */
5256
5257 static bool
5258 alpha_split_complex_arg (tree type)
5259 {
5260 return TYPE_MODE (type) != TCmode;
5261 }
5262
5263 static tree
5264 alpha_build_builtin_va_list (void)
5265 {
5266 tree base, ofs, space, record, type_decl;
5267
5268 if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK)
5269 return ptr_type_node;
5270
5271 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
5272 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
5273 TREE_CHAIN (record) = type_decl;
5274 TYPE_NAME (record) = type_decl;
5275
5276 /* C++? SET_IS_AGGR_TYPE (record, 1); */
5277
5278 /* Dummy field to prevent alignment warnings. */
5279 space = build_decl (FIELD_DECL, NULL_TREE, integer_type_node);
5280 DECL_FIELD_CONTEXT (space) = record;
5281 DECL_ARTIFICIAL (space) = 1;
5282 DECL_IGNORED_P (space) = 1;
5283
5284 ofs = build_decl (FIELD_DECL, get_identifier ("__offset"),
5285 integer_type_node);
5286 DECL_FIELD_CONTEXT (ofs) = record;
5287 TREE_CHAIN (ofs) = space;
5288
5289 base = build_decl (FIELD_DECL, get_identifier ("__base"),
5290 ptr_type_node);
5291 DECL_FIELD_CONTEXT (base) = record;
5292 TREE_CHAIN (base) = ofs;
5293
5294 TYPE_FIELDS (record) = base;
5295 layout_type (record);
5296
5297 return record;
5298 }
5299
5300 /* Perform any needed actions needed for a function that is receiving a
5301 variable number of arguments. */
5302
5303 static void
5304 alpha_setup_incoming_varargs (CUMULATIVE_ARGS *pcum,
5305 enum machine_mode mode ATTRIBUTE_UNUSED,
5306 tree type ATTRIBUTE_UNUSED,
5307 int *pretend_size, int no_rtl)
5308 {
5309 #if TARGET_ABI_UNICOSMK
5310 /* On Unicos/Mk, the standard subroutine __T3E_MISMATCH stores all register
5311 arguments on the stack. Unfortunately, it doesn't always store the first
5312 one (i.e. the one that arrives in $16 or $f16). This is not a problem
5313 with stdargs as we always have at least one named argument there. */
5314 int num_reg_words = pcum->num_reg_words;
5315 if (num_reg_words < 6)
5316 {
5317 if (!no_rtl)
5318 {
5319 emit_insn (gen_umk_mismatch_args (GEN_INT (num_reg_words + 1)));
5320 emit_insn (gen_arg_home_umk ());
5321 }
5322 *pretend_size = 0;
5323 }
5324 #elif TARGET_ABI_OPEN_VMS
5325 /* For VMS, we allocate space for all 6 arg registers plus a count.
5326
5327 However, if NO registers need to be saved, don't allocate any space.
5328 This is not only because we won't need the space, but because AP
5329 includes the current_pretend_args_size and we don't want to mess up
5330 any ap-relative addresses already made. */
5331 if (pcum->num_args < 6)
5332 {
5333 if (!no_rtl)
5334 {
5335 emit_move_insn (gen_rtx_REG (DImode, 1), virtual_incoming_args_rtx);
5336 emit_insn (gen_arg_home ());
5337 }
5338 *pretend_size = 7 * UNITS_PER_WORD;
5339 }
5340 #else
5341 /* On OSF/1 and friends, we allocate space for all 12 arg registers, but
5342 only push those that are remaining. However, if NO registers need to
5343 be saved, don't allocate any space. This is not only because we won't
5344 need the space, but because AP includes the current_pretend_args_size
5345 and we don't want to mess up any ap-relative addresses already made.
5346
5347 If we are not to use the floating-point registers, save the integer
5348 registers where we would put the floating-point registers. This is
5349 not the most efficient way to implement varargs with just one register
5350 class, but it isn't worth doing anything more efficient in this rare
5351 case. */
5352 CUMULATIVE_ARGS cum = *pcum;
5353
5354 if (cum >= 6)
5355 return;
5356
5357 if (!no_rtl)
5358 {
5359 int set = get_varargs_alias_set ();
5360 rtx tmp;
5361
5362 tmp = gen_rtx_MEM (BLKmode,
5363 plus_constant (virtual_incoming_args_rtx,
5364 (cum + 6) * UNITS_PER_WORD));
5365 set_mem_alias_set (tmp, set);
5366 move_block_from_reg (16 + cum, tmp, 6 - cum);
5367
5368 tmp = gen_rtx_MEM (BLKmode,
5369 plus_constant (virtual_incoming_args_rtx,
5370 cum * UNITS_PER_WORD));
5371 set_mem_alias_set (tmp, set);
5372 move_block_from_reg (16 + (TARGET_FPREGS ? 32 : 0) + cum, tmp,
5373 6 - cum);
5374 }
5375 *pretend_size = 12 * UNITS_PER_WORD;
5376 #endif
5377 }
5378
5379 void
5380 alpha_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
5381 {
5382 HOST_WIDE_INT offset;
5383 tree t, offset_field, base_field;
5384
5385 if (TREE_CODE (TREE_TYPE (valist)) == ERROR_MARK)
5386 return;
5387
5388 if (TARGET_ABI_UNICOSMK)
5389 std_expand_builtin_va_start (valist, nextarg);
5390
5391 /* For Unix, TARGET_SETUP_INCOMING_VARARGS moves the starting address base
5392 up by 48, storing fp arg registers in the first 48 bytes, and the
5393 integer arg registers in the next 48 bytes. This is only done,
5394 however, if any integer registers need to be stored.
5395
5396 If no integer registers need be stored, then we must subtract 48
5397 in order to account for the integer arg registers which are counted
5398 in argsize above, but which are not actually stored on the stack.
5399 Must further be careful here about structures straddling the last
5400 integer argument register; that futzes with pretend_args_size,
5401 which changes the meaning of AP. */
5402
5403 if (NUM_ARGS <= 6)
5404 offset = TARGET_ABI_OPEN_VMS ? UNITS_PER_WORD : 6 * UNITS_PER_WORD;
5405 else
5406 offset = -6 * UNITS_PER_WORD + current_function_pretend_args_size;
5407
5408 if (TARGET_ABI_OPEN_VMS)
5409 {
5410 nextarg = plus_constant (nextarg, offset);
5411 nextarg = plus_constant (nextarg, NUM_ARGS * UNITS_PER_WORD);
5412 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
5413 make_tree (ptr_type_node, nextarg));
5414 TREE_SIDE_EFFECTS (t) = 1;
5415
5416 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5417 }
5418 else
5419 {
5420 base_field = TYPE_FIELDS (TREE_TYPE (valist));
5421 offset_field = TREE_CHAIN (base_field);
5422
5423 base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
5424 valist, base_field, NULL_TREE);
5425 offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
5426 valist, offset_field, NULL_TREE);
5427
5428 t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
5429 t = build (PLUS_EXPR, ptr_type_node, t,
5430 build_int_cst (NULL_TREE, offset));
5431 t = build (MODIFY_EXPR, TREE_TYPE (base_field), base_field, t);
5432 TREE_SIDE_EFFECTS (t) = 1;
5433 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5434
5435 t = build_int_cst (NULL_TREE, NUM_ARGS * UNITS_PER_WORD);
5436 t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field, t);
5437 TREE_SIDE_EFFECTS (t) = 1;
5438 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5439 }
5440 }
5441
5442 static tree
5443 alpha_gimplify_va_arg_1 (tree type, tree base, tree offset, tree *pre_p)
5444 {
5445 tree type_size, ptr_type, addend, t, addr, internal_post;
5446
5447 /* If the type could not be passed in registers, skip the block
5448 reserved for the registers. */
5449 if (targetm.calls.must_pass_in_stack (TYPE_MODE (type), type))
5450 {
5451 t = build_int_cst (TREE_TYPE (offset), 6*8);
5452 t = build (MODIFY_EXPR, TREE_TYPE (offset), offset,
5453 build (MAX_EXPR, TREE_TYPE (offset), offset, t));
5454 gimplify_and_add (t, pre_p);
5455 }
5456
5457 addend = offset;
5458 ptr_type = build_pointer_type (type);
5459
5460 if (TREE_CODE (type) == COMPLEX_TYPE)
5461 {
5462 tree real_part, imag_part, real_temp;
5463
5464 real_part = alpha_gimplify_va_arg_1 (TREE_TYPE (type), base,
5465 offset, pre_p);
5466
5467 /* Copy the value into a new temporary, lest the formal temporary
5468 be reused out from under us. */
5469 real_temp = get_initialized_tmp_var (real_part, pre_p, NULL);
5470
5471 imag_part = alpha_gimplify_va_arg_1 (TREE_TYPE (type), base,
5472 offset, pre_p);
5473
5474 return build (COMPLEX_EXPR, type, real_temp, imag_part);
5475 }
5476 else if (TREE_CODE (type) == REAL_TYPE)
5477 {
5478 tree fpaddend, cond, fourtyeight;
5479
5480 fourtyeight = build_int_cst (TREE_TYPE (addend), 6*8);
5481 fpaddend = fold (build (MINUS_EXPR, TREE_TYPE (addend),
5482 addend, fourtyeight));
5483 cond = fold (build (LT_EXPR, boolean_type_node, addend, fourtyeight));
5484 addend = fold (build (COND_EXPR, TREE_TYPE (addend), cond,
5485 fpaddend, addend));
5486 }
5487
5488 /* Build the final address and force that value into a temporary. */
5489 addr = build (PLUS_EXPR, ptr_type, fold_convert (ptr_type, base),
5490 fold_convert (ptr_type, addend));
5491 internal_post = NULL;
5492 gimplify_expr (&addr, pre_p, &internal_post, is_gimple_val, fb_rvalue);
5493 append_to_statement_list (internal_post, pre_p);
5494
5495 /* Update the offset field. */
5496 type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type));
5497 if (type_size == NULL || TREE_OVERFLOW (type_size))
5498 t = size_zero_node;
5499 else
5500 {
5501 t = size_binop (PLUS_EXPR, type_size, size_int (7));
5502 t = size_binop (TRUNC_DIV_EXPR, t, size_int (8));
5503 t = size_binop (MULT_EXPR, t, size_int (8));
5504 }
5505 t = fold_convert (TREE_TYPE (offset), t);
5506 t = build (MODIFY_EXPR, void_type_node, offset,
5507 build (PLUS_EXPR, TREE_TYPE (offset), offset, t));
5508 gimplify_and_add (t, pre_p);
5509
5510 return build_fold_indirect_ref (addr);
5511 }
5512
5513 static tree
5514 alpha_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
5515 {
5516 tree offset_field, base_field, offset, base, t, r;
5517 bool indirect;
5518
5519 if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK)
5520 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
5521
5522 base_field = TYPE_FIELDS (va_list_type_node);
5523 offset_field = TREE_CHAIN (base_field);
5524 base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
5525 valist, base_field, NULL_TREE);
5526 offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
5527 valist, offset_field, NULL_TREE);
5528
5529 /* Pull the fields of the structure out into temporaries. Since we never
5530 modify the base field, we can use a formal temporary. Sign-extend the
5531 offset field so that it's the proper width for pointer arithmetic. */
5532 base = get_formal_tmp_var (base_field, pre_p);
5533
5534 t = fold_convert (lang_hooks.types.type_for_size (64, 0), offset_field);
5535 offset = get_initialized_tmp_var (t, pre_p, NULL);
5536
5537 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
5538 if (indirect)
5539 type = build_pointer_type (type);
5540
5541 /* Find the value. Note that this will be a stable indirection, or
5542 a composite of stable indirections in the case of complex. */
5543 r = alpha_gimplify_va_arg_1 (type, base, offset, pre_p);
5544
5545 /* Stuff the offset temporary back into its field. */
5546 t = build (MODIFY_EXPR, void_type_node, offset_field,
5547 fold_convert (TREE_TYPE (offset_field), offset));
5548 gimplify_and_add (t, pre_p);
5549
5550 if (indirect)
5551 r = build_fold_indirect_ref (r);
5552
5553 return r;
5554 }
5555 \f
5556 /* Builtins. */
5557
5558 enum alpha_builtin
5559 {
5560 ALPHA_BUILTIN_CMPBGE,
5561 ALPHA_BUILTIN_EXTBL,
5562 ALPHA_BUILTIN_EXTWL,
5563 ALPHA_BUILTIN_EXTLL,
5564 ALPHA_BUILTIN_EXTQL,
5565 ALPHA_BUILTIN_EXTWH,
5566 ALPHA_BUILTIN_EXTLH,
5567 ALPHA_BUILTIN_EXTQH,
5568 ALPHA_BUILTIN_INSBL,
5569 ALPHA_BUILTIN_INSWL,
5570 ALPHA_BUILTIN_INSLL,
5571 ALPHA_BUILTIN_INSQL,
5572 ALPHA_BUILTIN_INSWH,
5573 ALPHA_BUILTIN_INSLH,
5574 ALPHA_BUILTIN_INSQH,
5575 ALPHA_BUILTIN_MSKBL,
5576 ALPHA_BUILTIN_MSKWL,
5577 ALPHA_BUILTIN_MSKLL,
5578 ALPHA_BUILTIN_MSKQL,
5579 ALPHA_BUILTIN_MSKWH,
5580 ALPHA_BUILTIN_MSKLH,
5581 ALPHA_BUILTIN_MSKQH,
5582 ALPHA_BUILTIN_UMULH,
5583 ALPHA_BUILTIN_ZAP,
5584 ALPHA_BUILTIN_ZAPNOT,
5585 ALPHA_BUILTIN_AMASK,
5586 ALPHA_BUILTIN_IMPLVER,
5587 ALPHA_BUILTIN_RPCC,
5588 ALPHA_BUILTIN_THREAD_POINTER,
5589 ALPHA_BUILTIN_SET_THREAD_POINTER,
5590
5591 /* TARGET_MAX */
5592 ALPHA_BUILTIN_MINUB8,
5593 ALPHA_BUILTIN_MINSB8,
5594 ALPHA_BUILTIN_MINUW4,
5595 ALPHA_BUILTIN_MINSW4,
5596 ALPHA_BUILTIN_MAXUB8,
5597 ALPHA_BUILTIN_MAXSB8,
5598 ALPHA_BUILTIN_MAXUW4,
5599 ALPHA_BUILTIN_MAXSW4,
5600 ALPHA_BUILTIN_PERR,
5601 ALPHA_BUILTIN_PKLB,
5602 ALPHA_BUILTIN_PKWB,
5603 ALPHA_BUILTIN_UNPKBL,
5604 ALPHA_BUILTIN_UNPKBW,
5605
5606 /* TARGET_CIX */
5607 ALPHA_BUILTIN_CTTZ,
5608 ALPHA_BUILTIN_CTLZ,
5609 ALPHA_BUILTIN_CTPOP,
5610
5611 ALPHA_BUILTIN_max
5612 };
5613
5614 static unsigned int const code_for_builtin[ALPHA_BUILTIN_max] = {
5615 CODE_FOR_builtin_cmpbge,
5616 CODE_FOR_builtin_extbl,
5617 CODE_FOR_builtin_extwl,
5618 CODE_FOR_builtin_extll,
5619 CODE_FOR_builtin_extql,
5620 CODE_FOR_builtin_extwh,
5621 CODE_FOR_builtin_extlh,
5622 CODE_FOR_builtin_extqh,
5623 CODE_FOR_builtin_insbl,
5624 CODE_FOR_builtin_inswl,
5625 CODE_FOR_builtin_insll,
5626 CODE_FOR_builtin_insql,
5627 CODE_FOR_builtin_inswh,
5628 CODE_FOR_builtin_inslh,
5629 CODE_FOR_builtin_insqh,
5630 CODE_FOR_builtin_mskbl,
5631 CODE_FOR_builtin_mskwl,
5632 CODE_FOR_builtin_mskll,
5633 CODE_FOR_builtin_mskql,
5634 CODE_FOR_builtin_mskwh,
5635 CODE_FOR_builtin_msklh,
5636 CODE_FOR_builtin_mskqh,
5637 CODE_FOR_umuldi3_highpart,
5638 CODE_FOR_builtin_zap,
5639 CODE_FOR_builtin_zapnot,
5640 CODE_FOR_builtin_amask,
5641 CODE_FOR_builtin_implver,
5642 CODE_FOR_builtin_rpcc,
5643 CODE_FOR_load_tp,
5644 CODE_FOR_set_tp,
5645
5646 /* TARGET_MAX */
5647 CODE_FOR_builtin_minub8,
5648 CODE_FOR_builtin_minsb8,
5649 CODE_FOR_builtin_minuw4,
5650 CODE_FOR_builtin_minsw4,
5651 CODE_FOR_builtin_maxub8,
5652 CODE_FOR_builtin_maxsb8,
5653 CODE_FOR_builtin_maxuw4,
5654 CODE_FOR_builtin_maxsw4,
5655 CODE_FOR_builtin_perr,
5656 CODE_FOR_builtin_pklb,
5657 CODE_FOR_builtin_pkwb,
5658 CODE_FOR_builtin_unpkbl,
5659 CODE_FOR_builtin_unpkbw,
5660
5661 /* TARGET_CIX */
5662 CODE_FOR_builtin_cttz,
5663 CODE_FOR_builtin_ctlz,
5664 CODE_FOR_builtin_ctpop
5665 };
5666
5667 struct alpha_builtin_def
5668 {
5669 const char *name;
5670 enum alpha_builtin code;
5671 unsigned int target_mask;
5672 };
5673
5674 static struct alpha_builtin_def const zero_arg_builtins[] = {
5675 { "__builtin_alpha_implver", ALPHA_BUILTIN_IMPLVER, 0 },
5676 { "__builtin_alpha_rpcc", ALPHA_BUILTIN_RPCC, 0 }
5677 };
5678
5679 static struct alpha_builtin_def const one_arg_builtins[] = {
5680 { "__builtin_alpha_amask", ALPHA_BUILTIN_AMASK, 0 },
5681 { "__builtin_alpha_pklb", ALPHA_BUILTIN_PKLB, MASK_MAX },
5682 { "__builtin_alpha_pkwb", ALPHA_BUILTIN_PKWB, MASK_MAX },
5683 { "__builtin_alpha_unpkbl", ALPHA_BUILTIN_UNPKBL, MASK_MAX },
5684 { "__builtin_alpha_unpkbw", ALPHA_BUILTIN_UNPKBW, MASK_MAX },
5685 { "__builtin_alpha_cttz", ALPHA_BUILTIN_CTTZ, MASK_CIX },
5686 { "__builtin_alpha_ctlz", ALPHA_BUILTIN_CTLZ, MASK_CIX },
5687 { "__builtin_alpha_ctpop", ALPHA_BUILTIN_CTPOP, MASK_CIX }
5688 };
5689
5690 static struct alpha_builtin_def const two_arg_builtins[] = {
5691 { "__builtin_alpha_cmpbge", ALPHA_BUILTIN_CMPBGE, 0 },
5692 { "__builtin_alpha_extbl", ALPHA_BUILTIN_EXTBL, 0 },
5693 { "__builtin_alpha_extwl", ALPHA_BUILTIN_EXTWL, 0 },
5694 { "__builtin_alpha_extll", ALPHA_BUILTIN_EXTLL, 0 },
5695 { "__builtin_alpha_extql", ALPHA_BUILTIN_EXTQL, 0 },
5696 { "__builtin_alpha_extwh", ALPHA_BUILTIN_EXTWH, 0 },
5697 { "__builtin_alpha_extlh", ALPHA_BUILTIN_EXTLH, 0 },
5698 { "__builtin_alpha_extqh", ALPHA_BUILTIN_EXTQH, 0 },
5699 { "__builtin_alpha_insbl", ALPHA_BUILTIN_INSBL, 0 },
5700 { "__builtin_alpha_inswl", ALPHA_BUILTIN_INSWL, 0 },
5701 { "__builtin_alpha_insll", ALPHA_BUILTIN_INSLL, 0 },
5702 { "__builtin_alpha_insql", ALPHA_BUILTIN_INSQL, 0 },
5703 { "__builtin_alpha_inswh", ALPHA_BUILTIN_INSWH, 0 },
5704 { "__builtin_alpha_inslh", ALPHA_BUILTIN_INSLH, 0 },
5705 { "__builtin_alpha_insqh", ALPHA_BUILTIN_INSQH, 0 },
5706 { "__builtin_alpha_mskbl", ALPHA_BUILTIN_MSKBL, 0 },
5707 { "__builtin_alpha_mskwl", ALPHA_BUILTIN_MSKWL, 0 },
5708 { "__builtin_alpha_mskll", ALPHA_BUILTIN_MSKLL, 0 },
5709 { "__builtin_alpha_mskql", ALPHA_BUILTIN_MSKQL, 0 },
5710 { "__builtin_alpha_mskwh", ALPHA_BUILTIN_MSKWH, 0 },
5711 { "__builtin_alpha_msklh", ALPHA_BUILTIN_MSKLH, 0 },
5712 { "__builtin_alpha_mskqh", ALPHA_BUILTIN_MSKQH, 0 },
5713 { "__builtin_alpha_umulh", ALPHA_BUILTIN_UMULH, 0 },
5714 { "__builtin_alpha_zap", ALPHA_BUILTIN_ZAP, 0 },
5715 { "__builtin_alpha_zapnot", ALPHA_BUILTIN_ZAPNOT, 0 },
5716 { "__builtin_alpha_minub8", ALPHA_BUILTIN_MINUB8, MASK_MAX },
5717 { "__builtin_alpha_minsb8", ALPHA_BUILTIN_MINSB8, MASK_MAX },
5718 { "__builtin_alpha_minuw4", ALPHA_BUILTIN_MINUW4, MASK_MAX },
5719 { "__builtin_alpha_minsw4", ALPHA_BUILTIN_MINSW4, MASK_MAX },
5720 { "__builtin_alpha_maxub8", ALPHA_BUILTIN_MAXUB8, MASK_MAX },
5721 { "__builtin_alpha_maxsb8", ALPHA_BUILTIN_MAXSB8, MASK_MAX },
5722 { "__builtin_alpha_maxuw4", ALPHA_BUILTIN_MAXUW4, MASK_MAX },
5723 { "__builtin_alpha_maxsw4", ALPHA_BUILTIN_MAXSW4, MASK_MAX },
5724 { "__builtin_alpha_perr", ALPHA_BUILTIN_PERR, MASK_MAX }
5725 };
5726
5727 static void
5728 alpha_init_builtins (void)
5729 {
5730 const struct alpha_builtin_def *p;
5731 tree ftype;
5732 size_t i;
5733
5734 ftype = build_function_type (long_integer_type_node, void_list_node);
5735
5736 p = zero_arg_builtins;
5737 for (i = 0; i < ARRAY_SIZE (zero_arg_builtins); ++i, ++p)
5738 if ((target_flags & p->target_mask) == p->target_mask)
5739 lang_hooks.builtin_function (p->name, ftype, p->code, BUILT_IN_MD,
5740 NULL, NULL_TREE);
5741
5742 ftype = build_function_type_list (long_integer_type_node,
5743 long_integer_type_node, NULL_TREE);
5744
5745 p = one_arg_builtins;
5746 for (i = 0; i < ARRAY_SIZE (one_arg_builtins); ++i, ++p)
5747 if ((target_flags & p->target_mask) == p->target_mask)
5748 lang_hooks.builtin_function (p->name, ftype, p->code, BUILT_IN_MD,
5749 NULL, NULL_TREE);
5750
5751 ftype = build_function_type_list (long_integer_type_node,
5752 long_integer_type_node,
5753 long_integer_type_node, NULL_TREE);
5754
5755 p = two_arg_builtins;
5756 for (i = 0; i < ARRAY_SIZE (two_arg_builtins); ++i, ++p)
5757 if ((target_flags & p->target_mask) == p->target_mask)
5758 lang_hooks.builtin_function (p->name, ftype, p->code, BUILT_IN_MD,
5759 NULL, NULL_TREE);
5760
5761 ftype = build_function_type (ptr_type_node, void_list_node);
5762 lang_hooks.builtin_function ("__builtin_thread_pointer", ftype,
5763 ALPHA_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
5764 NULL, NULL_TREE);
5765
5766 ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
5767 lang_hooks.builtin_function ("__builtin_set_thread_pointer", ftype,
5768 ALPHA_BUILTIN_SET_THREAD_POINTER, BUILT_IN_MD,
5769 NULL, NULL_TREE);
5770 }
5771
5772 /* Expand an expression EXP that calls a built-in function,
5773 with result going to TARGET if that's convenient
5774 (and in mode MODE if that's convenient).
5775 SUBTARGET may be used as the target for computing one of EXP's operands.
5776 IGNORE is nonzero if the value is to be ignored. */
5777
5778 static rtx
5779 alpha_expand_builtin (tree exp, rtx target,
5780 rtx subtarget ATTRIBUTE_UNUSED,
5781 enum machine_mode mode ATTRIBUTE_UNUSED,
5782 int ignore ATTRIBUTE_UNUSED)
5783 {
5784 #define MAX_ARGS 2
5785
5786 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
5787 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
5788 tree arglist = TREE_OPERAND (exp, 1);
5789 enum insn_code icode;
5790 rtx op[MAX_ARGS], pat;
5791 int arity;
5792 bool nonvoid;
5793
5794 if (fcode >= ALPHA_BUILTIN_max)
5795 internal_error ("bad builtin fcode");
5796 icode = code_for_builtin[fcode];
5797 if (icode == 0)
5798 internal_error ("bad builtin fcode");
5799
5800 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
5801
5802 for (arglist = TREE_OPERAND (exp, 1), arity = 0;
5803 arglist;
5804 arglist = TREE_CHAIN (arglist), arity++)
5805 {
5806 const struct insn_operand_data *insn_op;
5807
5808 tree arg = TREE_VALUE (arglist);
5809 if (arg == error_mark_node)
5810 return NULL_RTX;
5811 if (arity > MAX_ARGS)
5812 return NULL_RTX;
5813
5814 insn_op = &insn_data[icode].operand[arity + nonvoid];
5815
5816 op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, 0);
5817
5818 if (!(*insn_op->predicate) (op[arity], insn_op->mode))
5819 op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
5820 }
5821
5822 if (nonvoid)
5823 {
5824 enum machine_mode tmode = insn_data[icode].operand[0].mode;
5825 if (!target
5826 || GET_MODE (target) != tmode
5827 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
5828 target = gen_reg_rtx (tmode);
5829 }
5830
5831 switch (arity)
5832 {
5833 case 0:
5834 pat = GEN_FCN (icode) (target);
5835 break;
5836 case 1:
5837 if (nonvoid)
5838 pat = GEN_FCN (icode) (target, op[0]);
5839 else
5840 pat = GEN_FCN (icode) (op[0]);
5841 break;
5842 case 2:
5843 pat = GEN_FCN (icode) (target, op[0], op[1]);
5844 break;
5845 default:
5846 abort ();
5847 }
5848 if (!pat)
5849 return NULL_RTX;
5850 emit_insn (pat);
5851
5852 if (nonvoid)
5853 return target;
5854 else
5855 return const0_rtx;
5856 }
5857 \f
5858 /* This page contains routines that are used to determine what the function
5859 prologue and epilogue code will do and write them out. */
5860
5861 /* Compute the size of the save area in the stack. */
5862
5863 /* These variables are used for communication between the following functions.
5864 They indicate various things about the current function being compiled
5865 that are used to tell what kind of prologue, epilogue and procedure
5866 descriptor to generate. */
5867
5868 /* Nonzero if we need a stack procedure. */
5869 enum alpha_procedure_types {PT_NULL = 0, PT_REGISTER = 1, PT_STACK = 2};
5870 static enum alpha_procedure_types alpha_procedure_type;
5871
5872 /* Register number (either FP or SP) that is used to unwind the frame. */
5873 static int vms_unwind_regno;
5874
5875 /* Register number used to save FP. We need not have one for RA since
5876 we don't modify it for register procedures. This is only defined
5877 for register frame procedures. */
5878 static int vms_save_fp_regno;
5879
5880 /* Register number used to reference objects off our PV. */
5881 static int vms_base_regno;
5882
5883 /* Compute register masks for saved registers. */
5884
5885 static void
5886 alpha_sa_mask (unsigned long *imaskP, unsigned long *fmaskP)
5887 {
5888 unsigned long imask = 0;
5889 unsigned long fmask = 0;
5890 unsigned int i;
5891
5892 /* When outputting a thunk, we don't have valid register life info,
5893 but assemble_start_function wants to output .frame and .mask
5894 directives. */
5895 if (current_function_is_thunk)
5896 {
5897 *imaskP = 0;
5898 *fmaskP = 0;
5899 return;
5900 }
5901
5902 if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
5903 imask |= (1UL << HARD_FRAME_POINTER_REGNUM);
5904
5905 /* One for every register we have to save. */
5906 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
5907 if (! fixed_regs[i] && ! call_used_regs[i]
5908 && regs_ever_live[i] && i != REG_RA
5909 && (!TARGET_ABI_UNICOSMK || i != HARD_FRAME_POINTER_REGNUM))
5910 {
5911 if (i < 32)
5912 imask |= (1UL << i);
5913 else
5914 fmask |= (1UL << (i - 32));
5915 }
5916
5917 /* We need to restore these for the handler. */
5918 if (current_function_calls_eh_return)
5919 {
5920 for (i = 0; ; ++i)
5921 {
5922 unsigned regno = EH_RETURN_DATA_REGNO (i);
5923 if (regno == INVALID_REGNUM)
5924 break;
5925 imask |= 1UL << regno;
5926 }
5927 }
5928
5929 /* If any register spilled, then spill the return address also. */
5930 /* ??? This is required by the Digital stack unwind specification
5931 and isn't needed if we're doing Dwarf2 unwinding. */
5932 if (imask || fmask || alpha_ra_ever_killed ())
5933 imask |= (1UL << REG_RA);
5934
5935 *imaskP = imask;
5936 *fmaskP = fmask;
5937 }
5938
5939 int
5940 alpha_sa_size (void)
5941 {
5942 unsigned long mask[2];
5943 int sa_size = 0;
5944 int i, j;
5945
5946 alpha_sa_mask (&mask[0], &mask[1]);
5947
5948 if (TARGET_ABI_UNICOSMK)
5949 {
5950 if (mask[0] || mask[1])
5951 sa_size = 14;
5952 }
5953 else
5954 {
5955 for (j = 0; j < 2; ++j)
5956 for (i = 0; i < 32; ++i)
5957 if ((mask[j] >> i) & 1)
5958 sa_size++;
5959 }
5960
5961 if (TARGET_ABI_UNICOSMK)
5962 {
5963 /* We might not need to generate a frame if we don't make any calls
5964 (including calls to __T3E_MISMATCH if this is a vararg function),
5965 don't have any local variables which require stack slots, don't
5966 use alloca and have not determined that we need a frame for other
5967 reasons. */
5968
5969 alpha_procedure_type
5970 = (sa_size || get_frame_size() != 0
5971 || current_function_outgoing_args_size
5972 || current_function_stdarg || current_function_calls_alloca
5973 || frame_pointer_needed)
5974 ? PT_STACK : PT_REGISTER;
5975
5976 /* Always reserve space for saving callee-saved registers if we
5977 need a frame as required by the calling convention. */
5978 if (alpha_procedure_type == PT_STACK)
5979 sa_size = 14;
5980 }
5981 else if (TARGET_ABI_OPEN_VMS)
5982 {
5983 /* Start by assuming we can use a register procedure if we don't
5984 make any calls (REG_RA not used) or need to save any
5985 registers and a stack procedure if we do. */
5986 if ((mask[0] >> REG_RA) & 1)
5987 alpha_procedure_type = PT_STACK;
5988 else if (get_frame_size() != 0)
5989 alpha_procedure_type = PT_REGISTER;
5990 else
5991 alpha_procedure_type = PT_NULL;
5992
5993 /* Don't reserve space for saving FP & RA yet. Do that later after we've
5994 made the final decision on stack procedure vs register procedure. */
5995 if (alpha_procedure_type == PT_STACK)
5996 sa_size -= 2;
5997
5998 /* Decide whether to refer to objects off our PV via FP or PV.
5999 If we need FP for something else or if we receive a nonlocal
6000 goto (which expects PV to contain the value), we must use PV.
6001 Otherwise, start by assuming we can use FP. */
6002
6003 vms_base_regno
6004 = (frame_pointer_needed
6005 || current_function_has_nonlocal_label
6006 || alpha_procedure_type == PT_STACK
6007 || current_function_outgoing_args_size)
6008 ? REG_PV : HARD_FRAME_POINTER_REGNUM;
6009
6010 /* If we want to copy PV into FP, we need to find some register
6011 in which to save FP. */
6012
6013 vms_save_fp_regno = -1;
6014 if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
6015 for (i = 0; i < 32; i++)
6016 if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
6017 vms_save_fp_regno = i;
6018
6019 if (vms_save_fp_regno == -1 && alpha_procedure_type == PT_REGISTER)
6020 vms_base_regno = REG_PV, alpha_procedure_type = PT_STACK;
6021 else if (alpha_procedure_type == PT_NULL)
6022 vms_base_regno = REG_PV;
6023
6024 /* Stack unwinding should be done via FP unless we use it for PV. */
6025 vms_unwind_regno = (vms_base_regno == REG_PV
6026 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
6027
6028 /* If this is a stack procedure, allow space for saving FP and RA. */
6029 if (alpha_procedure_type == PT_STACK)
6030 sa_size += 2;
6031 }
6032 else
6033 {
6034 /* Our size must be even (multiple of 16 bytes). */
6035 if (sa_size & 1)
6036 sa_size++;
6037 }
6038
6039 return sa_size * 8;
6040 }
6041
6042 /* Define the offset between two registers, one to be eliminated,
6043 and the other its replacement, at the start of a routine. */
6044
6045 HOST_WIDE_INT
6046 alpha_initial_elimination_offset (unsigned int from,
6047 unsigned int to ATTRIBUTE_UNUSED)
6048 {
6049 HOST_WIDE_INT ret;
6050
6051 ret = alpha_sa_size ();
6052 ret += ALPHA_ROUND (current_function_outgoing_args_size);
6053
6054 if (from == FRAME_POINTER_REGNUM)
6055 ;
6056 else if (from == ARG_POINTER_REGNUM)
6057 ret += (ALPHA_ROUND (get_frame_size ()
6058 + current_function_pretend_args_size)
6059 - current_function_pretend_args_size);
6060 else
6061 abort ();
6062
6063 return ret;
6064 }
6065
6066 int
6067 alpha_pv_save_size (void)
6068 {
6069 alpha_sa_size ();
6070 return alpha_procedure_type == PT_STACK ? 8 : 0;
6071 }
6072
6073 int
6074 alpha_using_fp (void)
6075 {
6076 alpha_sa_size ();
6077 return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM;
6078 }
6079
6080 #if TARGET_ABI_OPEN_VMS
6081
6082 const struct attribute_spec vms_attribute_table[] =
6083 {
6084 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
6085 { "overlaid", 0, 0, true, false, false, NULL },
6086 { "global", 0, 0, true, false, false, NULL },
6087 { "initialize", 0, 0, true, false, false, NULL },
6088 { NULL, 0, 0, false, false, false, NULL }
6089 };
6090
6091 #endif
6092
6093 static int
6094 find_lo_sum_using_gp (rtx *px, void *data ATTRIBUTE_UNUSED)
6095 {
6096 return GET_CODE (*px) == LO_SUM && XEXP (*px, 0) == pic_offset_table_rtx;
6097 }
6098
6099 int
6100 alpha_find_lo_sum_using_gp (rtx insn)
6101 {
6102 return for_each_rtx (&PATTERN (insn), find_lo_sum_using_gp, NULL) > 0;
6103 }
6104
6105 static int
6106 alpha_does_function_need_gp (void)
6107 {
6108 rtx insn;
6109
6110 /* The GP being variable is an OSF abi thing. */
6111 if (! TARGET_ABI_OSF)
6112 return 0;
6113
6114 /* We need the gp to load the address of __mcount. */
6115 if (TARGET_PROFILING_NEEDS_GP && current_function_profile)
6116 return 1;
6117
6118 /* The code emitted by alpha_output_mi_thunk_osf uses the gp. */
6119 if (current_function_is_thunk)
6120 return 1;
6121
6122 /* The nonlocal receiver pattern assumes that the gp is valid for
6123 the nested function. Reasonable because it's almost always set
6124 correctly already. For the cases where that's wrong, make sure
6125 the nested function loads its gp on entry. */
6126 if (current_function_has_nonlocal_goto)
6127 return 1;
6128
6129 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
6130 Even if we are a static function, we still need to do this in case
6131 our address is taken and passed to something like qsort. */
6132
6133 push_topmost_sequence ();
6134 insn = get_insns ();
6135 pop_topmost_sequence ();
6136
6137 for (; insn; insn = NEXT_INSN (insn))
6138 if (INSN_P (insn)
6139 && GET_CODE (PATTERN (insn)) != USE
6140 && GET_CODE (PATTERN (insn)) != CLOBBER
6141 && get_attr_usegp (insn))
6142 return 1;
6143
6144 return 0;
6145 }
6146
6147 \f
6148 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
6149 sequences. */
6150
6151 static rtx
6152 set_frame_related_p (void)
6153 {
6154 rtx seq = get_insns ();
6155 rtx insn;
6156
6157 end_sequence ();
6158
6159 if (!seq)
6160 return NULL_RTX;
6161
6162 if (INSN_P (seq))
6163 {
6164 insn = seq;
6165 while (insn != NULL_RTX)
6166 {
6167 RTX_FRAME_RELATED_P (insn) = 1;
6168 insn = NEXT_INSN (insn);
6169 }
6170 seq = emit_insn (seq);
6171 }
6172 else
6173 {
6174 seq = emit_insn (seq);
6175 RTX_FRAME_RELATED_P (seq) = 1;
6176 }
6177 return seq;
6178 }
6179
6180 #define FRP(exp) (start_sequence (), exp, set_frame_related_p ())
6181
6182 /* Generates a store with the proper unwind info attached. VALUE is
6183 stored at BASE_REG+BASE_OFS. If FRAME_BIAS is nonzero, then BASE_REG
6184 contains SP+FRAME_BIAS, and that is the unwind info that should be
6185 generated. If FRAME_REG != VALUE, then VALUE is being stored on
6186 behalf of FRAME_REG, and FRAME_REG should be present in the unwind. */
6187
6188 static void
6189 emit_frame_store_1 (rtx value, rtx base_reg, HOST_WIDE_INT frame_bias,
6190 HOST_WIDE_INT base_ofs, rtx frame_reg)
6191 {
6192 rtx addr, mem, insn;
6193
6194 addr = plus_constant (base_reg, base_ofs);
6195 mem = gen_rtx_MEM (DImode, addr);
6196 set_mem_alias_set (mem, alpha_sr_alias_set);
6197
6198 insn = emit_move_insn (mem, value);
6199 RTX_FRAME_RELATED_P (insn) = 1;
6200
6201 if (frame_bias || value != frame_reg)
6202 {
6203 if (frame_bias)
6204 {
6205 addr = plus_constant (stack_pointer_rtx, frame_bias + base_ofs);
6206 mem = gen_rtx_MEM (DImode, addr);
6207 }
6208
6209 REG_NOTES (insn)
6210 = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
6211 gen_rtx_SET (VOIDmode, mem, frame_reg),
6212 REG_NOTES (insn));
6213 }
6214 }
6215
6216 static void
6217 emit_frame_store (unsigned int regno, rtx base_reg,
6218 HOST_WIDE_INT frame_bias, HOST_WIDE_INT base_ofs)
6219 {
6220 rtx reg = gen_rtx_REG (DImode, regno);
6221 emit_frame_store_1 (reg, base_reg, frame_bias, base_ofs, reg);
6222 }
6223
6224 /* Write function prologue. */
6225
6226 /* On vms we have two kinds of functions:
6227
6228 - stack frame (PROC_STACK)
6229 these are 'normal' functions with local vars and which are
6230 calling other functions
6231 - register frame (PROC_REGISTER)
6232 keeps all data in registers, needs no stack
6233
6234 We must pass this to the assembler so it can generate the
6235 proper pdsc (procedure descriptor)
6236 This is done with the '.pdesc' command.
6237
6238 On not-vms, we don't really differentiate between the two, as we can
6239 simply allocate stack without saving registers. */
6240
6241 void
6242 alpha_expand_prologue (void)
6243 {
6244 /* Registers to save. */
6245 unsigned long imask = 0;
6246 unsigned long fmask = 0;
6247 /* Stack space needed for pushing registers clobbered by us. */
6248 HOST_WIDE_INT sa_size;
6249 /* Complete stack size needed. */
6250 HOST_WIDE_INT frame_size;
6251 /* Offset from base reg to register save area. */
6252 HOST_WIDE_INT reg_offset;
6253 rtx sa_reg;
6254 int i;
6255
6256 sa_size = alpha_sa_size ();
6257
6258 frame_size = get_frame_size ();
6259 if (TARGET_ABI_OPEN_VMS)
6260 frame_size = ALPHA_ROUND (sa_size
6261 + (alpha_procedure_type == PT_STACK ? 8 : 0)
6262 + frame_size
6263 + current_function_pretend_args_size);
6264 else if (TARGET_ABI_UNICOSMK)
6265 /* We have to allocate space for the DSIB if we generate a frame. */
6266 frame_size = ALPHA_ROUND (sa_size
6267 + (alpha_procedure_type == PT_STACK ? 48 : 0))
6268 + ALPHA_ROUND (frame_size
6269 + current_function_outgoing_args_size);
6270 else
6271 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
6272 + sa_size
6273 + ALPHA_ROUND (frame_size
6274 + current_function_pretend_args_size));
6275
6276 if (TARGET_ABI_OPEN_VMS)
6277 reg_offset = 8;
6278 else
6279 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
6280
6281 alpha_sa_mask (&imask, &fmask);
6282
6283 /* Emit an insn to reload GP, if needed. */
6284 if (TARGET_ABI_OSF)
6285 {
6286 alpha_function_needs_gp = alpha_does_function_need_gp ();
6287 if (alpha_function_needs_gp)
6288 emit_insn (gen_prologue_ldgp ());
6289 }
6290
6291 /* TARGET_PROFILING_NEEDS_GP actually implies that we need to insert
6292 the call to mcount ourselves, rather than having the linker do it
6293 magically in response to -pg. Since _mcount has special linkage,
6294 don't represent the call as a call. */
6295 if (TARGET_PROFILING_NEEDS_GP && current_function_profile)
6296 emit_insn (gen_prologue_mcount ());
6297
6298 if (TARGET_ABI_UNICOSMK)
6299 unicosmk_gen_dsib (&imask);
6300
6301 /* Adjust the stack by the frame size. If the frame size is > 4096
6302 bytes, we need to be sure we probe somewhere in the first and last
6303 4096 bytes (we can probably get away without the latter test) and
6304 every 8192 bytes in between. If the frame size is > 32768, we
6305 do this in a loop. Otherwise, we generate the explicit probe
6306 instructions.
6307
6308 Note that we are only allowed to adjust sp once in the prologue. */
6309
6310 if (frame_size <= 32768)
6311 {
6312 if (frame_size > 4096)
6313 {
6314 int probed = 4096;
6315
6316 do
6317 emit_insn (gen_probe_stack (GEN_INT (TARGET_ABI_UNICOSMK
6318 ? -probed + 64
6319 : -probed)));
6320 while ((probed += 8192) < frame_size);
6321
6322 /* We only have to do this probe if we aren't saving registers. */
6323 if (sa_size == 0 && probed + 4096 < frame_size)
6324 emit_insn (gen_probe_stack (GEN_INT (-frame_size)));
6325 }
6326
6327 if (frame_size != 0)
6328 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
6329 GEN_INT (TARGET_ABI_UNICOSMK
6330 ? -frame_size + 64
6331 : -frame_size))));
6332 }
6333 else
6334 {
6335 /* Here we generate code to set R22 to SP + 4096 and set R23 to the
6336 number of 8192 byte blocks to probe. We then probe each block
6337 in the loop and then set SP to the proper location. If the
6338 amount remaining is > 4096, we have to do one more probe if we
6339 are not saving any registers. */
6340
6341 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
6342 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
6343 rtx ptr = gen_rtx_REG (DImode, 22);
6344 rtx count = gen_rtx_REG (DImode, 23);
6345 rtx seq;
6346
6347 emit_move_insn (count, GEN_INT (blocks));
6348 emit_insn (gen_adddi3 (ptr, stack_pointer_rtx,
6349 GEN_INT (TARGET_ABI_UNICOSMK ? 4096 - 64 : 4096)));
6350
6351 /* Because of the difficulty in emitting a new basic block this
6352 late in the compilation, generate the loop as a single insn. */
6353 emit_insn (gen_prologue_stack_probe_loop (count, ptr));
6354
6355 if (leftover > 4096 && sa_size == 0)
6356 {
6357 rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover));
6358 MEM_VOLATILE_P (last) = 1;
6359 emit_move_insn (last, const0_rtx);
6360 }
6361
6362 if (TARGET_ABI_WINDOWS_NT)
6363 {
6364 /* For NT stack unwind (done by 'reverse execution'), it's
6365 not OK to take the result of a loop, even though the value
6366 is already in ptr, so we reload it via a single operation
6367 and subtract it to sp.
6368
6369 Yes, that's correct -- we have to reload the whole constant
6370 into a temporary via ldah+lda then subtract from sp. */
6371
6372 HOST_WIDE_INT lo, hi;
6373 lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
6374 hi = frame_size - lo;
6375
6376 emit_move_insn (ptr, GEN_INT (hi));
6377 emit_insn (gen_adddi3 (ptr, ptr, GEN_INT (lo)));
6378 seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
6379 ptr));
6380 }
6381 else
6382 {
6383 seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr,
6384 GEN_INT (-leftover)));
6385 }
6386
6387 /* This alternative is special, because the DWARF code cannot
6388 possibly intuit through the loop above. So we invent this
6389 note it looks at instead. */
6390 RTX_FRAME_RELATED_P (seq) = 1;
6391 REG_NOTES (seq)
6392 = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
6393 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
6394 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
6395 GEN_INT (TARGET_ABI_UNICOSMK
6396 ? -frame_size + 64
6397 : -frame_size))),
6398 REG_NOTES (seq));
6399 }
6400
6401 if (!TARGET_ABI_UNICOSMK)
6402 {
6403 HOST_WIDE_INT sa_bias = 0;
6404
6405 /* Cope with very large offsets to the register save area. */
6406 sa_reg = stack_pointer_rtx;
6407 if (reg_offset + sa_size > 0x8000)
6408 {
6409 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
6410 rtx sa_bias_rtx;
6411
6412 if (low + sa_size <= 0x8000)
6413 sa_bias = reg_offset - low, reg_offset = low;
6414 else
6415 sa_bias = reg_offset, reg_offset = 0;
6416
6417 sa_reg = gen_rtx_REG (DImode, 24);
6418 sa_bias_rtx = GEN_INT (sa_bias);
6419
6420 if (add_operand (sa_bias_rtx, DImode))
6421 emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, sa_bias_rtx));
6422 else
6423 {
6424 emit_move_insn (sa_reg, sa_bias_rtx);
6425 emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, sa_reg));
6426 }
6427 }
6428
6429 /* Save regs in stack order. Beginning with VMS PV. */
6430 if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
6431 emit_frame_store (REG_PV, stack_pointer_rtx, 0, 0);
6432
6433 /* Save register RA next. */
6434 if (imask & (1UL << REG_RA))
6435 {
6436 emit_frame_store (REG_RA, sa_reg, sa_bias, reg_offset);
6437 imask &= ~(1UL << REG_RA);
6438 reg_offset += 8;
6439 }
6440
6441 /* Now save any other registers required to be saved. */
6442 for (i = 0; i < 31; i++)
6443 if (imask & (1UL << i))
6444 {
6445 emit_frame_store (i, sa_reg, sa_bias, reg_offset);
6446 reg_offset += 8;
6447 }
6448
6449 for (i = 0; i < 31; i++)
6450 if (fmask & (1UL << i))
6451 {
6452 emit_frame_store (i+32, sa_reg, sa_bias, reg_offset);
6453 reg_offset += 8;
6454 }
6455 }
6456 else if (TARGET_ABI_UNICOSMK && alpha_procedure_type == PT_STACK)
6457 {
6458 /* The standard frame on the T3E includes space for saving registers.
6459 We just have to use it. We don't have to save the return address and
6460 the old frame pointer here - they are saved in the DSIB. */
6461
6462 reg_offset = -56;
6463 for (i = 9; i < 15; i++)
6464 if (imask & (1UL << i))
6465 {
6466 emit_frame_store (i, hard_frame_pointer_rtx, 0, reg_offset);
6467 reg_offset -= 8;
6468 }
6469 for (i = 2; i < 10; i++)
6470 if (fmask & (1UL << i))
6471 {
6472 emit_frame_store (i+32, hard_frame_pointer_rtx, 0, reg_offset);
6473 reg_offset -= 8;
6474 }
6475 }
6476
6477 if (TARGET_ABI_OPEN_VMS)
6478 {
6479 if (alpha_procedure_type == PT_REGISTER)
6480 /* Register frame procedures save the fp.
6481 ?? Ought to have a dwarf2 save for this. */
6482 emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
6483 hard_frame_pointer_rtx);
6484
6485 if (alpha_procedure_type != PT_NULL && vms_base_regno != REG_PV)
6486 emit_insn (gen_force_movdi (gen_rtx_REG (DImode, vms_base_regno),
6487 gen_rtx_REG (DImode, REG_PV)));
6488
6489 if (alpha_procedure_type != PT_NULL
6490 && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
6491 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
6492
6493 /* If we have to allocate space for outgoing args, do it now. */
6494 if (current_function_outgoing_args_size != 0)
6495 {
6496 rtx seq
6497 = emit_move_insn (stack_pointer_rtx,
6498 plus_constant
6499 (hard_frame_pointer_rtx,
6500 - (ALPHA_ROUND
6501 (current_function_outgoing_args_size))));
6502
6503 /* Only set FRAME_RELATED_P on the stack adjustment we just emitted
6504 if ! frame_pointer_needed. Setting the bit will change the CFA
6505 computation rule to use sp again, which would be wrong if we had
6506 frame_pointer_needed, as this means sp might move unpredictably
6507 later on.
6508
6509 Also, note that
6510 frame_pointer_needed
6511 => vms_unwind_regno == HARD_FRAME_POINTER_REGNUM
6512 and
6513 current_function_outgoing_args_size != 0
6514 => alpha_procedure_type != PT_NULL,
6515
6516 so when we are not setting the bit here, we are guaranteed to
6517 have emitted an FRP frame pointer update just before. */
6518 RTX_FRAME_RELATED_P (seq) = ! frame_pointer_needed;
6519 }
6520 }
6521 else if (!TARGET_ABI_UNICOSMK)
6522 {
6523 /* If we need a frame pointer, set it from the stack pointer. */
6524 if (frame_pointer_needed)
6525 {
6526 if (TARGET_CAN_FAULT_IN_PROLOGUE)
6527 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
6528 else
6529 /* This must always be the last instruction in the
6530 prologue, thus we emit a special move + clobber. */
6531 FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx,
6532 stack_pointer_rtx, sa_reg)));
6533 }
6534 }
6535
6536 /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
6537 the prologue, for exception handling reasons, we cannot do this for
6538 any insn that might fault. We could prevent this for mems with a
6539 (clobber:BLK (scratch)), but this doesn't work for fp insns. So we
6540 have to prevent all such scheduling with a blockage.
6541
6542 Linux, on the other hand, never bothered to implement OSF/1's
6543 exception handling, and so doesn't care about such things. Anyone
6544 planning to use dwarf2 frame-unwind info can also omit the blockage. */
6545
6546 if (! TARGET_CAN_FAULT_IN_PROLOGUE)
6547 emit_insn (gen_blockage ());
6548 }
6549
6550 /* Output the textual info surrounding the prologue. */
6551
6552 void
6553 alpha_start_function (FILE *file, const char *fnname,
6554 tree decl ATTRIBUTE_UNUSED)
6555 {
6556 unsigned long imask = 0;
6557 unsigned long fmask = 0;
6558 /* Stack space needed for pushing registers clobbered by us. */
6559 HOST_WIDE_INT sa_size;
6560 /* Complete stack size needed. */
6561 unsigned HOST_WIDE_INT frame_size;
6562 /* Offset from base reg to register save area. */
6563 HOST_WIDE_INT reg_offset;
6564 char *entry_label = (char *) alloca (strlen (fnname) + 6);
6565 int i;
6566
6567 /* Don't emit an extern directive for functions defined in the same file. */
6568 if (TARGET_ABI_UNICOSMK)
6569 {
6570 tree name_tree;
6571 name_tree = get_identifier (fnname);
6572 TREE_ASM_WRITTEN (name_tree) = 1;
6573 }
6574
6575 alpha_fnname = fnname;
6576 sa_size = alpha_sa_size ();
6577
6578 frame_size = get_frame_size ();
6579 if (TARGET_ABI_OPEN_VMS)
6580 frame_size = ALPHA_ROUND (sa_size
6581 + (alpha_procedure_type == PT_STACK ? 8 : 0)
6582 + frame_size
6583 + current_function_pretend_args_size);
6584 else if (TARGET_ABI_UNICOSMK)
6585 frame_size = ALPHA_ROUND (sa_size
6586 + (alpha_procedure_type == PT_STACK ? 48 : 0))
6587 + ALPHA_ROUND (frame_size
6588 + current_function_outgoing_args_size);
6589 else
6590 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
6591 + sa_size
6592 + ALPHA_ROUND (frame_size
6593 + current_function_pretend_args_size));
6594
6595 if (TARGET_ABI_OPEN_VMS)
6596 reg_offset = 8;
6597 else
6598 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
6599
6600 alpha_sa_mask (&imask, &fmask);
6601
6602 /* Ecoff can handle multiple .file directives, so put out file and lineno.
6603 We have to do that before the .ent directive as we cannot switch
6604 files within procedures with native ecoff because line numbers are
6605 linked to procedure descriptors.
6606 Outputting the lineno helps debugging of one line functions as they
6607 would otherwise get no line number at all. Please note that we would
6608 like to put out last_linenum from final.c, but it is not accessible. */
6609
6610 if (write_symbols == SDB_DEBUG)
6611 {
6612 #ifdef ASM_OUTPUT_SOURCE_FILENAME
6613 ASM_OUTPUT_SOURCE_FILENAME (file,
6614 DECL_SOURCE_FILE (current_function_decl));
6615 #endif
6616 #ifdef ASM_OUTPUT_SOURCE_LINE
6617 if (debug_info_level != DINFO_LEVEL_TERSE)
6618 ASM_OUTPUT_SOURCE_LINE (file,
6619 DECL_SOURCE_LINE (current_function_decl), 0);
6620 #endif
6621 }
6622
6623 /* Issue function start and label. */
6624 if (TARGET_ABI_OPEN_VMS
6625 || (!TARGET_ABI_UNICOSMK && !flag_inhibit_size_directive))
6626 {
6627 fputs ("\t.ent ", file);
6628 assemble_name (file, fnname);
6629 putc ('\n', file);
6630
6631 /* If the function needs GP, we'll write the "..ng" label there.
6632 Otherwise, do it here. */
6633 if (TARGET_ABI_OSF
6634 && ! alpha_function_needs_gp
6635 && ! current_function_is_thunk)
6636 {
6637 putc ('$', file);
6638 assemble_name (file, fnname);
6639 fputs ("..ng:\n", file);
6640 }
6641 }
6642
6643 strcpy (entry_label, fnname);
6644 if (TARGET_ABI_OPEN_VMS)
6645 strcat (entry_label, "..en");
6646
6647 /* For public functions, the label must be globalized by appending an
6648 additional colon. */
6649 if (TARGET_ABI_UNICOSMK && TREE_PUBLIC (decl))
6650 strcat (entry_label, ":");
6651
6652 ASM_OUTPUT_LABEL (file, entry_label);
6653 inside_function = TRUE;
6654
6655 if (TARGET_ABI_OPEN_VMS)
6656 fprintf (file, "\t.base $%d\n", vms_base_regno);
6657
6658 if (!TARGET_ABI_OPEN_VMS && !TARGET_ABI_UNICOSMK && TARGET_IEEE_CONFORMANT
6659 && !flag_inhibit_size_directive)
6660 {
6661 /* Set flags in procedure descriptor to request IEEE-conformant
6662 math-library routines. The value we set it to is PDSC_EXC_IEEE
6663 (/usr/include/pdsc.h). */
6664 fputs ("\t.eflag 48\n", file);
6665 }
6666
6667 /* Set up offsets to alpha virtual arg/local debugging pointer. */
6668 alpha_auto_offset = -frame_size + current_function_pretend_args_size;
6669 alpha_arg_offset = -frame_size + 48;
6670
6671 /* Describe our frame. If the frame size is larger than an integer,
6672 print it as zero to avoid an assembler error. We won't be
6673 properly describing such a frame, but that's the best we can do. */
6674 if (TARGET_ABI_UNICOSMK)
6675 ;
6676 else if (TARGET_ABI_OPEN_VMS)
6677 fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,"
6678 HOST_WIDE_INT_PRINT_DEC "\n",
6679 vms_unwind_regno,
6680 frame_size >= (1UL << 31) ? 0 : frame_size,
6681 reg_offset);
6682 else if (!flag_inhibit_size_directive)
6683 fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,%d\n",
6684 (frame_pointer_needed
6685 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM),
6686 frame_size >= (1UL << 31) ? 0 : frame_size,
6687 current_function_pretend_args_size);
6688
6689 /* Describe which registers were spilled. */
6690 if (TARGET_ABI_UNICOSMK)
6691 ;
6692 else if (TARGET_ABI_OPEN_VMS)
6693 {
6694 if (imask)
6695 /* ??? Does VMS care if mask contains ra? The old code didn't
6696 set it, so I don't here. */
6697 fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1UL << REG_RA));
6698 if (fmask)
6699 fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
6700 if (alpha_procedure_type == PT_REGISTER)
6701 fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
6702 }
6703 else if (!flag_inhibit_size_directive)
6704 {
6705 if (imask)
6706 {
6707 fprintf (file, "\t.mask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", imask,
6708 frame_size >= (1UL << 31) ? 0 : reg_offset - frame_size);
6709
6710 for (i = 0; i < 32; ++i)
6711 if (imask & (1UL << i))
6712 reg_offset += 8;
6713 }
6714
6715 if (fmask)
6716 fprintf (file, "\t.fmask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", fmask,
6717 frame_size >= (1UL << 31) ? 0 : reg_offset - frame_size);
6718 }
6719
6720 #if TARGET_ABI_OPEN_VMS
6721 /* Ifdef'ed cause link_section are only available then. */
6722 readonly_data_section ();
6723 fprintf (file, "\t.align 3\n");
6724 assemble_name (file, fnname); fputs ("..na:\n", file);
6725 fputs ("\t.ascii \"", file);
6726 assemble_name (file, fnname);
6727 fputs ("\\0\"\n", file);
6728 alpha_need_linkage (fnname, 1);
6729 text_section ();
6730 #endif
6731 }
6732
6733 /* Emit the .prologue note at the scheduled end of the prologue. */
6734
6735 static void
6736 alpha_output_function_end_prologue (FILE *file)
6737 {
6738 if (TARGET_ABI_UNICOSMK)
6739 ;
6740 else if (TARGET_ABI_OPEN_VMS)
6741 fputs ("\t.prologue\n", file);
6742 else if (TARGET_ABI_WINDOWS_NT)
6743 fputs ("\t.prologue 0\n", file);
6744 else if (!flag_inhibit_size_directive)
6745 fprintf (file, "\t.prologue %d\n",
6746 alpha_function_needs_gp || current_function_is_thunk);
6747 }
6748
6749 /* Write function epilogue. */
6750
6751 /* ??? At some point we will want to support full unwind, and so will
6752 need to mark the epilogue as well. At the moment, we just confuse
6753 dwarf2out. */
6754 #undef FRP
6755 #define FRP(exp) exp
6756
6757 void
6758 alpha_expand_epilogue (void)
6759 {
6760 /* Registers to save. */
6761 unsigned long imask = 0;
6762 unsigned long fmask = 0;
6763 /* Stack space needed for pushing registers clobbered by us. */
6764 HOST_WIDE_INT sa_size;
6765 /* Complete stack size needed. */
6766 HOST_WIDE_INT frame_size;
6767 /* Offset from base reg to register save area. */
6768 HOST_WIDE_INT reg_offset;
6769 int fp_is_frame_pointer, fp_offset;
6770 rtx sa_reg, sa_reg_exp = NULL;
6771 rtx sp_adj1, sp_adj2, mem;
6772 rtx eh_ofs;
6773 int i;
6774
6775 sa_size = alpha_sa_size ();
6776
6777 frame_size = get_frame_size ();
6778 if (TARGET_ABI_OPEN_VMS)
6779 frame_size = ALPHA_ROUND (sa_size
6780 + (alpha_procedure_type == PT_STACK ? 8 : 0)
6781 + frame_size
6782 + current_function_pretend_args_size);
6783 else if (TARGET_ABI_UNICOSMK)
6784 frame_size = ALPHA_ROUND (sa_size
6785 + (alpha_procedure_type == PT_STACK ? 48 : 0))
6786 + ALPHA_ROUND (frame_size
6787 + current_function_outgoing_args_size);
6788 else
6789 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
6790 + sa_size
6791 + ALPHA_ROUND (frame_size
6792 + current_function_pretend_args_size));
6793
6794 if (TARGET_ABI_OPEN_VMS)
6795 {
6796 if (alpha_procedure_type == PT_STACK)
6797 reg_offset = 8;
6798 else
6799 reg_offset = 0;
6800 }
6801 else
6802 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
6803
6804 alpha_sa_mask (&imask, &fmask);
6805
6806 fp_is_frame_pointer
6807 = ((TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
6808 || (!TARGET_ABI_OPEN_VMS && frame_pointer_needed));
6809 fp_offset = 0;
6810 sa_reg = stack_pointer_rtx;
6811
6812 if (current_function_calls_eh_return)
6813 eh_ofs = EH_RETURN_STACKADJ_RTX;
6814 else
6815 eh_ofs = NULL_RTX;
6816
6817 if (!TARGET_ABI_UNICOSMK && sa_size)
6818 {
6819 /* If we have a frame pointer, restore SP from it. */
6820 if ((TARGET_ABI_OPEN_VMS
6821 && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
6822 || (!TARGET_ABI_OPEN_VMS && frame_pointer_needed))
6823 FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx));
6824
6825 /* Cope with very large offsets to the register save area. */
6826 if (reg_offset + sa_size > 0x8000)
6827 {
6828 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
6829 HOST_WIDE_INT bias;
6830
6831 if (low + sa_size <= 0x8000)
6832 bias = reg_offset - low, reg_offset = low;
6833 else
6834 bias = reg_offset, reg_offset = 0;
6835
6836 sa_reg = gen_rtx_REG (DImode, 22);
6837 sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
6838
6839 FRP (emit_move_insn (sa_reg, sa_reg_exp));
6840 }
6841
6842 /* Restore registers in order, excepting a true frame pointer. */
6843
6844 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
6845 if (! eh_ofs)
6846 set_mem_alias_set (mem, alpha_sr_alias_set);
6847 FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
6848
6849 reg_offset += 8;
6850 imask &= ~(1UL << REG_RA);
6851
6852 for (i = 0; i < 31; ++i)
6853 if (imask & (1UL << i))
6854 {
6855 if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
6856 fp_offset = reg_offset;
6857 else
6858 {
6859 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
6860 set_mem_alias_set (mem, alpha_sr_alias_set);
6861 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
6862 }
6863 reg_offset += 8;
6864 }
6865
6866 for (i = 0; i < 31; ++i)
6867 if (fmask & (1UL << i))
6868 {
6869 mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
6870 set_mem_alias_set (mem, alpha_sr_alias_set);
6871 FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
6872 reg_offset += 8;
6873 }
6874 }
6875 else if (TARGET_ABI_UNICOSMK && alpha_procedure_type == PT_STACK)
6876 {
6877 /* Restore callee-saved general-purpose registers. */
6878
6879 reg_offset = -56;
6880
6881 for (i = 9; i < 15; i++)
6882 if (imask & (1UL << i))
6883 {
6884 mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx,
6885 reg_offset));
6886 set_mem_alias_set (mem, alpha_sr_alias_set);
6887 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
6888 reg_offset -= 8;
6889 }
6890
6891 for (i = 2; i < 10; i++)
6892 if (fmask & (1UL << i))
6893 {
6894 mem = gen_rtx_MEM (DFmode, plus_constant(hard_frame_pointer_rtx,
6895 reg_offset));
6896 set_mem_alias_set (mem, alpha_sr_alias_set);
6897 FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
6898 reg_offset -= 8;
6899 }
6900
6901 /* Restore the return address from the DSIB. */
6902
6903 mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx, -8));
6904 set_mem_alias_set (mem, alpha_sr_alias_set);
6905 FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
6906 }
6907
6908 if (frame_size || eh_ofs)
6909 {
6910 sp_adj1 = stack_pointer_rtx;
6911
6912 if (eh_ofs)
6913 {
6914 sp_adj1 = gen_rtx_REG (DImode, 23);
6915 emit_move_insn (sp_adj1,
6916 gen_rtx_PLUS (Pmode, stack_pointer_rtx, eh_ofs));
6917 }
6918
6919 /* If the stack size is large, begin computation into a temporary
6920 register so as not to interfere with a potential fp restore,
6921 which must be consecutive with an SP restore. */
6922 if (frame_size < 32768
6923 && ! (TARGET_ABI_UNICOSMK && current_function_calls_alloca))
6924 sp_adj2 = GEN_INT (frame_size);
6925 else if (TARGET_ABI_UNICOSMK)
6926 {
6927 sp_adj1 = gen_rtx_REG (DImode, 23);
6928 FRP (emit_move_insn (sp_adj1, hard_frame_pointer_rtx));
6929 sp_adj2 = const0_rtx;
6930 }
6931 else if (frame_size < 0x40007fffL)
6932 {
6933 int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
6934
6935 sp_adj2 = plus_constant (sp_adj1, frame_size - low);
6936 if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
6937 sp_adj1 = sa_reg;
6938 else
6939 {
6940 sp_adj1 = gen_rtx_REG (DImode, 23);
6941 FRP (emit_move_insn (sp_adj1, sp_adj2));
6942 }
6943 sp_adj2 = GEN_INT (low);
6944 }
6945 else
6946 {
6947 rtx tmp = gen_rtx_REG (DImode, 23);
6948 FRP (sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3));
6949 if (!sp_adj2)
6950 {
6951 /* We can't drop new things to memory this late, afaik,
6952 so build it up by pieces. */
6953 FRP (sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
6954 -(frame_size < 0)));
6955 if (!sp_adj2)
6956 abort ();
6957 }
6958 }
6959
6960 /* From now on, things must be in order. So emit blockages. */
6961
6962 /* Restore the frame pointer. */
6963 if (TARGET_ABI_UNICOSMK)
6964 {
6965 emit_insn (gen_blockage ());
6966 mem = gen_rtx_MEM (DImode,
6967 plus_constant (hard_frame_pointer_rtx, -16));
6968 set_mem_alias_set (mem, alpha_sr_alias_set);
6969 FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
6970 }
6971 else if (fp_is_frame_pointer)
6972 {
6973 emit_insn (gen_blockage ());
6974 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, fp_offset));
6975 set_mem_alias_set (mem, alpha_sr_alias_set);
6976 FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
6977 }
6978 else if (TARGET_ABI_OPEN_VMS)
6979 {
6980 emit_insn (gen_blockage ());
6981 FRP (emit_move_insn (hard_frame_pointer_rtx,
6982 gen_rtx_REG (DImode, vms_save_fp_regno)));
6983 }
6984
6985 /* Restore the stack pointer. */
6986 emit_insn (gen_blockage ());
6987 if (sp_adj2 == const0_rtx)
6988 FRP (emit_move_insn (stack_pointer_rtx, sp_adj1));
6989 else
6990 FRP (emit_move_insn (stack_pointer_rtx,
6991 gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)));
6992 }
6993 else
6994 {
6995 if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_REGISTER)
6996 {
6997 emit_insn (gen_blockage ());
6998 FRP (emit_move_insn (hard_frame_pointer_rtx,
6999 gen_rtx_REG (DImode, vms_save_fp_regno)));
7000 }
7001 else if (TARGET_ABI_UNICOSMK && alpha_procedure_type != PT_STACK)
7002 {
7003 /* Decrement the frame pointer if the function does not have a
7004 frame. */
7005
7006 emit_insn (gen_blockage ());
7007 FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
7008 hard_frame_pointer_rtx, constm1_rtx)));
7009 }
7010 }
7011 }
7012 \f
7013 /* Output the rest of the textual info surrounding the epilogue. */
7014
7015 void
7016 alpha_end_function (FILE *file, const char *fnname, tree decl ATTRIBUTE_UNUSED)
7017 {
7018 #if TARGET_ABI_OPEN_VMS
7019 alpha_write_linkage (file, fnname, decl);
7020 #endif
7021
7022 /* End the function. */
7023 if (!TARGET_ABI_UNICOSMK && !flag_inhibit_size_directive)
7024 {
7025 fputs ("\t.end ", file);
7026 assemble_name (file, fnname);
7027 putc ('\n', file);
7028 }
7029 inside_function = FALSE;
7030
7031 /* Output jump tables and the static subroutine information block. */
7032 if (TARGET_ABI_UNICOSMK)
7033 {
7034 unicosmk_output_ssib (file, fnname);
7035 unicosmk_output_deferred_case_vectors (file);
7036 }
7037 }
7038
7039 #if TARGET_ABI_OSF
7040 /* Emit a tail call to FUNCTION after adjusting THIS by DELTA.
7041
7042 In order to avoid the hordes of differences between generated code
7043 with and without TARGET_EXPLICIT_RELOCS, and to avoid duplicating
7044 lots of code loading up large constants, generate rtl and emit it
7045 instead of going straight to text.
7046
7047 Not sure why this idea hasn't been explored before... */
7048
7049 static void
7050 alpha_output_mi_thunk_osf (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
7051 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
7052 tree function)
7053 {
7054 HOST_WIDE_INT hi, lo;
7055 rtx this, insn, funexp;
7056
7057 reset_block_changes ();
7058
7059 /* We always require a valid GP. */
7060 emit_insn (gen_prologue_ldgp ());
7061 emit_note (NOTE_INSN_PROLOGUE_END);
7062
7063 /* Find the "this" pointer. If the function returns a structure,
7064 the structure return pointer is in $16. */
7065 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
7066 this = gen_rtx_REG (Pmode, 17);
7067 else
7068 this = gen_rtx_REG (Pmode, 16);
7069
7070 /* Add DELTA. When possible we use ldah+lda. Otherwise load the
7071 entire constant for the add. */
7072 lo = ((delta & 0xffff) ^ 0x8000) - 0x8000;
7073 hi = (((delta - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
7074 if (hi + lo == delta)
7075 {
7076 if (hi)
7077 emit_insn (gen_adddi3 (this, this, GEN_INT (hi)));
7078 if (lo)
7079 emit_insn (gen_adddi3 (this, this, GEN_INT (lo)));
7080 }
7081 else
7082 {
7083 rtx tmp = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 0),
7084 delta, -(delta < 0));
7085 emit_insn (gen_adddi3 (this, this, tmp));
7086 }
7087
7088 /* Add a delta stored in the vtable at VCALL_OFFSET. */
7089 if (vcall_offset)
7090 {
7091 rtx tmp, tmp2;
7092
7093 tmp = gen_rtx_REG (Pmode, 0);
7094 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
7095
7096 lo = ((vcall_offset & 0xffff) ^ 0x8000) - 0x8000;
7097 hi = (((vcall_offset - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
7098 if (hi + lo == vcall_offset)
7099 {
7100 if (hi)
7101 emit_insn (gen_adddi3 (tmp, tmp, GEN_INT (hi)));
7102 }
7103 else
7104 {
7105 tmp2 = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 1),
7106 vcall_offset, -(vcall_offset < 0));
7107 emit_insn (gen_adddi3 (tmp, tmp, tmp2));
7108 lo = 0;
7109 }
7110 if (lo)
7111 tmp2 = gen_rtx_PLUS (Pmode, tmp, GEN_INT (lo));
7112 else
7113 tmp2 = tmp;
7114 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp2));
7115
7116 emit_insn (gen_adddi3 (this, this, tmp));
7117 }
7118
7119 /* Generate a tail call to the target function. */
7120 if (! TREE_USED (function))
7121 {
7122 assemble_external (function);
7123 TREE_USED (function) = 1;
7124 }
7125 funexp = XEXP (DECL_RTL (function), 0);
7126 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
7127 insn = emit_call_insn (gen_sibcall (funexp, const0_rtx));
7128 SIBLING_CALL_P (insn) = 1;
7129
7130 /* Run just enough of rest_of_compilation to get the insns emitted.
7131 There's not really enough bulk here to make other passes such as
7132 instruction scheduling worth while. Note that use_thunk calls
7133 assemble_start_function and assemble_end_function. */
7134 insn = get_insns ();
7135 insn_locators_initialize ();
7136 shorten_branches (insn);
7137 final_start_function (insn, file, 1);
7138 final (insn, file, 1, 0);
7139 final_end_function ();
7140 }
7141 #endif /* TARGET_ABI_OSF */
7142 \f
7143 /* Debugging support. */
7144
7145 #include "gstab.h"
7146
7147 /* Count the number of sdb related labels are generated (to find block
7148 start and end boundaries). */
7149
7150 int sdb_label_count = 0;
7151
7152 /* Next label # for each statement. */
7153
7154 static int sym_lineno = 0;
7155
7156 /* Count the number of .file directives, so that .loc is up to date. */
7157
7158 static int num_source_filenames = 0;
7159
7160 /* Name of the file containing the current function. */
7161
7162 static const char *current_function_file = "";
7163
7164 /* Offsets to alpha virtual arg/local debugging pointers. */
7165
7166 long alpha_arg_offset;
7167 long alpha_auto_offset;
7168 \f
7169 /* Emit a new filename to a stream. */
7170
7171 void
7172 alpha_output_filename (FILE *stream, const char *name)
7173 {
7174 static int first_time = TRUE;
7175 char ltext_label_name[100];
7176
7177 if (first_time)
7178 {
7179 first_time = FALSE;
7180 ++num_source_filenames;
7181 current_function_file = name;
7182 fprintf (stream, "\t.file\t%d ", num_source_filenames);
7183 output_quoted_string (stream, name);
7184 fprintf (stream, "\n");
7185 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
7186 fprintf (stream, "\t#@stabs\n");
7187 }
7188
7189 else if (write_symbols == DBX_DEBUG)
7190 {
7191 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
7192 fprintf (stream, "%s", ASM_STABS_OP);
7193 output_quoted_string (stream, name);
7194 fprintf (stream, ",%d,0,0,%s\n", N_SOL, &ltext_label_name[1]);
7195 }
7196
7197 else if (name != current_function_file
7198 && strcmp (name, current_function_file) != 0)
7199 {
7200 if (inside_function && ! TARGET_GAS)
7201 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
7202 else
7203 {
7204 ++num_source_filenames;
7205 current_function_file = name;
7206 fprintf (stream, "\t.file\t%d ", num_source_filenames);
7207 }
7208
7209 output_quoted_string (stream, name);
7210 fprintf (stream, "\n");
7211 }
7212 }
7213
7214 /* Emit a linenumber to a stream. */
7215
7216 void
7217 alpha_output_lineno (FILE *stream, int line)
7218 {
7219 if (write_symbols == DBX_DEBUG)
7220 {
7221 /* mips-tfile doesn't understand .stabd directives. */
7222 ++sym_lineno;
7223 fprintf (stream, "$LM%d:\n%s%d,0,%d,$LM%d\n",
7224 sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
7225 }
7226 else
7227 fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
7228 }
7229 \f
7230 /* Structure to show the current status of registers and memory. */
7231
7232 struct shadow_summary
7233 {
7234 struct {
7235 unsigned int i : 31; /* Mask of int regs */
7236 unsigned int fp : 31; /* Mask of fp regs */
7237 unsigned int mem : 1; /* mem == imem | fpmem */
7238 } used, defd;
7239 };
7240
7241 /* Summary the effects of expression X on the machine. Update SUM, a pointer
7242 to the summary structure. SET is nonzero if the insn is setting the
7243 object, otherwise zero. */
7244
7245 static void
7246 summarize_insn (rtx x, struct shadow_summary *sum, int set)
7247 {
7248 const char *format_ptr;
7249 int i, j;
7250
7251 if (x == 0)
7252 return;
7253
7254 switch (GET_CODE (x))
7255 {
7256 /* ??? Note that this case would be incorrect if the Alpha had a
7257 ZERO_EXTRACT in SET_DEST. */
7258 case SET:
7259 summarize_insn (SET_SRC (x), sum, 0);
7260 summarize_insn (SET_DEST (x), sum, 1);
7261 break;
7262
7263 case CLOBBER:
7264 summarize_insn (XEXP (x, 0), sum, 1);
7265 break;
7266
7267 case USE:
7268 summarize_insn (XEXP (x, 0), sum, 0);
7269 break;
7270
7271 case ASM_OPERANDS:
7272 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
7273 summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
7274 break;
7275
7276 case PARALLEL:
7277 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
7278 summarize_insn (XVECEXP (x, 0, i), sum, 0);
7279 break;
7280
7281 case SUBREG:
7282 summarize_insn (SUBREG_REG (x), sum, 0);
7283 break;
7284
7285 case REG:
7286 {
7287 int regno = REGNO (x);
7288 unsigned long mask = ((unsigned long) 1) << (regno % 32);
7289
7290 if (regno == 31 || regno == 63)
7291 break;
7292
7293 if (set)
7294 {
7295 if (regno < 32)
7296 sum->defd.i |= mask;
7297 else
7298 sum->defd.fp |= mask;
7299 }
7300 else
7301 {
7302 if (regno < 32)
7303 sum->used.i |= mask;
7304 else
7305 sum->used.fp |= mask;
7306 }
7307 }
7308 break;
7309
7310 case MEM:
7311 if (set)
7312 sum->defd.mem = 1;
7313 else
7314 sum->used.mem = 1;
7315
7316 /* Find the regs used in memory address computation: */
7317 summarize_insn (XEXP (x, 0), sum, 0);
7318 break;
7319
7320 case CONST_INT: case CONST_DOUBLE:
7321 case SYMBOL_REF: case LABEL_REF: case CONST:
7322 case SCRATCH: case ASM_INPUT:
7323 break;
7324
7325 /* Handle common unary and binary ops for efficiency. */
7326 case COMPARE: case PLUS: case MINUS: case MULT: case DIV:
7327 case MOD: case UDIV: case UMOD: case AND: case IOR:
7328 case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT:
7329 case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX:
7330 case NE: case EQ: case GE: case GT: case LE:
7331 case LT: case GEU: case GTU: case LEU: case LTU:
7332 summarize_insn (XEXP (x, 0), sum, 0);
7333 summarize_insn (XEXP (x, 1), sum, 0);
7334 break;
7335
7336 case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
7337 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
7338 case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
7339 case SQRT: case FFS:
7340 summarize_insn (XEXP (x, 0), sum, 0);
7341 break;
7342
7343 default:
7344 format_ptr = GET_RTX_FORMAT (GET_CODE (x));
7345 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
7346 switch (format_ptr[i])
7347 {
7348 case 'e':
7349 summarize_insn (XEXP (x, i), sum, 0);
7350 break;
7351
7352 case 'E':
7353 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
7354 summarize_insn (XVECEXP (x, i, j), sum, 0);
7355 break;
7356
7357 case 'i':
7358 break;
7359
7360 default:
7361 abort ();
7362 }
7363 }
7364 }
7365
7366 /* Ensure a sufficient number of `trapb' insns are in the code when
7367 the user requests code with a trap precision of functions or
7368 instructions.
7369
7370 In naive mode, when the user requests a trap-precision of
7371 "instruction", a trapb is needed after every instruction that may
7372 generate a trap. This ensures that the code is resumption safe but
7373 it is also slow.
7374
7375 When optimizations are turned on, we delay issuing a trapb as long
7376 as possible. In this context, a trap shadow is the sequence of
7377 instructions that starts with a (potentially) trap generating
7378 instruction and extends to the next trapb or call_pal instruction
7379 (but GCC never generates call_pal by itself). We can delay (and
7380 therefore sometimes omit) a trapb subject to the following
7381 conditions:
7382
7383 (a) On entry to the trap shadow, if any Alpha register or memory
7384 location contains a value that is used as an operand value by some
7385 instruction in the trap shadow (live on entry), then no instruction
7386 in the trap shadow may modify the register or memory location.
7387
7388 (b) Within the trap shadow, the computation of the base register
7389 for a memory load or store instruction may not involve using the
7390 result of an instruction that might generate an UNPREDICTABLE
7391 result.
7392
7393 (c) Within the trap shadow, no register may be used more than once
7394 as a destination register. (This is to make life easier for the
7395 trap-handler.)
7396
7397 (d) The trap shadow may not include any branch instructions. */
7398
7399 static void
7400 alpha_handle_trap_shadows (void)
7401 {
7402 struct shadow_summary shadow;
7403 int trap_pending, exception_nesting;
7404 rtx i, n;
7405
7406 trap_pending = 0;
7407 exception_nesting = 0;
7408 shadow.used.i = 0;
7409 shadow.used.fp = 0;
7410 shadow.used.mem = 0;
7411 shadow.defd = shadow.used;
7412
7413 for (i = get_insns (); i ; i = NEXT_INSN (i))
7414 {
7415 if (GET_CODE (i) == NOTE)
7416 {
7417 switch (NOTE_LINE_NUMBER (i))
7418 {
7419 case NOTE_INSN_EH_REGION_BEG:
7420 exception_nesting++;
7421 if (trap_pending)
7422 goto close_shadow;
7423 break;
7424
7425 case NOTE_INSN_EH_REGION_END:
7426 exception_nesting--;
7427 if (trap_pending)
7428 goto close_shadow;
7429 break;
7430
7431 case NOTE_INSN_EPILOGUE_BEG:
7432 if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
7433 goto close_shadow;
7434 break;
7435 }
7436 }
7437 else if (trap_pending)
7438 {
7439 if (alpha_tp == ALPHA_TP_FUNC)
7440 {
7441 if (GET_CODE (i) == JUMP_INSN
7442 && GET_CODE (PATTERN (i)) == RETURN)
7443 goto close_shadow;
7444 }
7445 else if (alpha_tp == ALPHA_TP_INSN)
7446 {
7447 if (optimize > 0)
7448 {
7449 struct shadow_summary sum;
7450
7451 sum.used.i = 0;
7452 sum.used.fp = 0;
7453 sum.used.mem = 0;
7454 sum.defd = sum.used;
7455
7456 switch (GET_CODE (i))
7457 {
7458 case INSN:
7459 /* Annoyingly, get_attr_trap will abort on these. */
7460 if (GET_CODE (PATTERN (i)) == USE
7461 || GET_CODE (PATTERN (i)) == CLOBBER)
7462 break;
7463
7464 summarize_insn (PATTERN (i), &sum, 0);
7465
7466 if ((sum.defd.i & shadow.defd.i)
7467 || (sum.defd.fp & shadow.defd.fp))
7468 {
7469 /* (c) would be violated */
7470 goto close_shadow;
7471 }
7472
7473 /* Combine shadow with summary of current insn: */
7474 shadow.used.i |= sum.used.i;
7475 shadow.used.fp |= sum.used.fp;
7476 shadow.used.mem |= sum.used.mem;
7477 shadow.defd.i |= sum.defd.i;
7478 shadow.defd.fp |= sum.defd.fp;
7479 shadow.defd.mem |= sum.defd.mem;
7480
7481 if ((sum.defd.i & shadow.used.i)
7482 || (sum.defd.fp & shadow.used.fp)
7483 || (sum.defd.mem & shadow.used.mem))
7484 {
7485 /* (a) would be violated (also takes care of (b)) */
7486 if (get_attr_trap (i) == TRAP_YES
7487 && ((sum.defd.i & sum.used.i)
7488 || (sum.defd.fp & sum.used.fp)))
7489 abort ();
7490
7491 goto close_shadow;
7492 }
7493 break;
7494
7495 case JUMP_INSN:
7496 case CALL_INSN:
7497 case CODE_LABEL:
7498 goto close_shadow;
7499
7500 default:
7501 abort ();
7502 }
7503 }
7504 else
7505 {
7506 close_shadow:
7507 n = emit_insn_before (gen_trapb (), i);
7508 PUT_MODE (n, TImode);
7509 PUT_MODE (i, TImode);
7510 trap_pending = 0;
7511 shadow.used.i = 0;
7512 shadow.used.fp = 0;
7513 shadow.used.mem = 0;
7514 shadow.defd = shadow.used;
7515 }
7516 }
7517 }
7518
7519 if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
7520 && GET_CODE (i) == INSN
7521 && GET_CODE (PATTERN (i)) != USE
7522 && GET_CODE (PATTERN (i)) != CLOBBER
7523 && get_attr_trap (i) == TRAP_YES)
7524 {
7525 if (optimize && !trap_pending)
7526 summarize_insn (PATTERN (i), &shadow, 0);
7527 trap_pending = 1;
7528 }
7529 }
7530 }
7531 \f
7532 /* Alpha can only issue instruction groups simultaneously if they are
7533 suitably aligned. This is very processor-specific. */
7534
7535 enum alphaev4_pipe {
7536 EV4_STOP = 0,
7537 EV4_IB0 = 1,
7538 EV4_IB1 = 2,
7539 EV4_IBX = 4
7540 };
7541
7542 enum alphaev5_pipe {
7543 EV5_STOP = 0,
7544 EV5_NONE = 1,
7545 EV5_E01 = 2,
7546 EV5_E0 = 4,
7547 EV5_E1 = 8,
7548 EV5_FAM = 16,
7549 EV5_FA = 32,
7550 EV5_FM = 64
7551 };
7552
7553 static enum alphaev4_pipe
7554 alphaev4_insn_pipe (rtx insn)
7555 {
7556 if (recog_memoized (insn) < 0)
7557 return EV4_STOP;
7558 if (get_attr_length (insn) != 4)
7559 return EV4_STOP;
7560
7561 switch (get_attr_type (insn))
7562 {
7563 case TYPE_ILD:
7564 case TYPE_FLD:
7565 return EV4_IBX;
7566
7567 case TYPE_LDSYM:
7568 case TYPE_IADD:
7569 case TYPE_ILOG:
7570 case TYPE_ICMOV:
7571 case TYPE_ICMP:
7572 case TYPE_IST:
7573 case TYPE_FST:
7574 case TYPE_SHIFT:
7575 case TYPE_IMUL:
7576 case TYPE_FBR:
7577 return EV4_IB0;
7578
7579 case TYPE_MISC:
7580 case TYPE_IBR:
7581 case TYPE_JSR:
7582 case TYPE_CALLPAL:
7583 case TYPE_FCPYS:
7584 case TYPE_FCMOV:
7585 case TYPE_FADD:
7586 case TYPE_FDIV:
7587 case TYPE_FMUL:
7588 return EV4_IB1;
7589
7590 default:
7591 abort ();
7592 }
7593 }
7594
7595 static enum alphaev5_pipe
7596 alphaev5_insn_pipe (rtx insn)
7597 {
7598 if (recog_memoized (insn) < 0)
7599 return EV5_STOP;
7600 if (get_attr_length (insn) != 4)
7601 return EV5_STOP;
7602
7603 switch (get_attr_type (insn))
7604 {
7605 case TYPE_ILD:
7606 case TYPE_FLD:
7607 case TYPE_LDSYM:
7608 case TYPE_IADD:
7609 case TYPE_ILOG:
7610 case TYPE_ICMOV:
7611 case TYPE_ICMP:
7612 return EV5_E01;
7613
7614 case TYPE_IST:
7615 case TYPE_FST:
7616 case TYPE_SHIFT:
7617 case TYPE_IMUL:
7618 case TYPE_MISC:
7619 case TYPE_MVI:
7620 return EV5_E0;
7621
7622 case TYPE_IBR:
7623 case TYPE_JSR:
7624 case TYPE_CALLPAL:
7625 return EV5_E1;
7626
7627 case TYPE_FCPYS:
7628 return EV5_FAM;
7629
7630 case TYPE_FBR:
7631 case TYPE_FCMOV:
7632 case TYPE_FADD:
7633 case TYPE_FDIV:
7634 return EV5_FA;
7635
7636 case TYPE_FMUL:
7637 return EV5_FM;
7638
7639 default:
7640 abort();
7641 }
7642 }
7643
7644 /* IN_USE is a mask of the slots currently filled within the insn group.
7645 The mask bits come from alphaev4_pipe above. If EV4_IBX is set, then
7646 the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.
7647
7648 LEN is, of course, the length of the group in bytes. */
7649
7650 static rtx
7651 alphaev4_next_group (rtx insn, int *pin_use, int *plen)
7652 {
7653 int len, in_use;
7654
7655 len = in_use = 0;
7656
7657 if (! INSN_P (insn)
7658 || GET_CODE (PATTERN (insn)) == CLOBBER
7659 || GET_CODE (PATTERN (insn)) == USE)
7660 goto next_and_done;
7661
7662 while (1)
7663 {
7664 enum alphaev4_pipe pipe;
7665
7666 pipe = alphaev4_insn_pipe (insn);
7667 switch (pipe)
7668 {
7669 case EV4_STOP:
7670 /* Force complex instructions to start new groups. */
7671 if (in_use)
7672 goto done;
7673
7674 /* If this is a completely unrecognized insn, its an asm.
7675 We don't know how long it is, so record length as -1 to
7676 signal a needed realignment. */
7677 if (recog_memoized (insn) < 0)
7678 len = -1;
7679 else
7680 len = get_attr_length (insn);
7681 goto next_and_done;
7682
7683 case EV4_IBX:
7684 if (in_use & EV4_IB0)
7685 {
7686 if (in_use & EV4_IB1)
7687 goto done;
7688 in_use |= EV4_IB1;
7689 }
7690 else
7691 in_use |= EV4_IB0 | EV4_IBX;
7692 break;
7693
7694 case EV4_IB0:
7695 if (in_use & EV4_IB0)
7696 {
7697 if (!(in_use & EV4_IBX) || (in_use & EV4_IB1))
7698 goto done;
7699 in_use |= EV4_IB1;
7700 }
7701 in_use |= EV4_IB0;
7702 break;
7703
7704 case EV4_IB1:
7705 if (in_use & EV4_IB1)
7706 goto done;
7707 in_use |= EV4_IB1;
7708 break;
7709
7710 default:
7711 abort();
7712 }
7713 len += 4;
7714
7715 /* Haifa doesn't do well scheduling branches. */
7716 if (GET_CODE (insn) == JUMP_INSN)
7717 goto next_and_done;
7718
7719 next:
7720 insn = next_nonnote_insn (insn);
7721
7722 if (!insn || ! INSN_P (insn))
7723 goto done;
7724
7725 /* Let Haifa tell us where it thinks insn group boundaries are. */
7726 if (GET_MODE (insn) == TImode)
7727 goto done;
7728
7729 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
7730 goto next;
7731 }
7732
7733 next_and_done:
7734 insn = next_nonnote_insn (insn);
7735
7736 done:
7737 *plen = len;
7738 *pin_use = in_use;
7739 return insn;
7740 }
7741
7742 /* IN_USE is a mask of the slots currently filled within the insn group.
7743 The mask bits come from alphaev5_pipe above. If EV5_E01 is set, then
7744 the insn in EV5_E0 can be swapped by the hardware into EV5_E1.
7745
7746 LEN is, of course, the length of the group in bytes. */
7747
7748 static rtx
7749 alphaev5_next_group (rtx insn, int *pin_use, int *plen)
7750 {
7751 int len, in_use;
7752
7753 len = in_use = 0;
7754
7755 if (! INSN_P (insn)
7756 || GET_CODE (PATTERN (insn)) == CLOBBER
7757 || GET_CODE (PATTERN (insn)) == USE)
7758 goto next_and_done;
7759
7760 while (1)
7761 {
7762 enum alphaev5_pipe pipe;
7763
7764 pipe = alphaev5_insn_pipe (insn);
7765 switch (pipe)
7766 {
7767 case EV5_STOP:
7768 /* Force complex instructions to start new groups. */
7769 if (in_use)
7770 goto done;
7771
7772 /* If this is a completely unrecognized insn, its an asm.
7773 We don't know how long it is, so record length as -1 to
7774 signal a needed realignment. */
7775 if (recog_memoized (insn) < 0)
7776 len = -1;
7777 else
7778 len = get_attr_length (insn);
7779 goto next_and_done;
7780
7781 /* ??? Most of the places below, we would like to abort, as
7782 it would indicate an error either in Haifa, or in the
7783 scheduling description. Unfortunately, Haifa never
7784 schedules the last instruction of the BB, so we don't
7785 have an accurate TI bit to go off. */
7786 case EV5_E01:
7787 if (in_use & EV5_E0)
7788 {
7789 if (in_use & EV5_E1)
7790 goto done;
7791 in_use |= EV5_E1;
7792 }
7793 else
7794 in_use |= EV5_E0 | EV5_E01;
7795 break;
7796
7797 case EV5_E0:
7798 if (in_use & EV5_E0)
7799 {
7800 if (!(in_use & EV5_E01) || (in_use & EV5_E1))
7801 goto done;
7802 in_use |= EV5_E1;
7803 }
7804 in_use |= EV5_E0;
7805 break;
7806
7807 case EV5_E1:
7808 if (in_use & EV5_E1)
7809 goto done;
7810 in_use |= EV5_E1;
7811 break;
7812
7813 case EV5_FAM:
7814 if (in_use & EV5_FA)
7815 {
7816 if (in_use & EV5_FM)
7817 goto done;
7818 in_use |= EV5_FM;
7819 }
7820 else
7821 in_use |= EV5_FA | EV5_FAM;
7822 break;
7823
7824 case EV5_FA:
7825 if (in_use & EV5_FA)
7826 goto done;
7827 in_use |= EV5_FA;
7828 break;
7829
7830 case EV5_FM:
7831 if (in_use & EV5_FM)
7832 goto done;
7833 in_use |= EV5_FM;
7834 break;
7835
7836 case EV5_NONE:
7837 break;
7838
7839 default:
7840 abort();
7841 }
7842 len += 4;
7843
7844 /* Haifa doesn't do well scheduling branches. */
7845 /* ??? If this is predicted not-taken, slotting continues, except
7846 that no more IBR, FBR, or JSR insns may be slotted. */
7847 if (GET_CODE (insn) == JUMP_INSN)
7848 goto next_and_done;
7849
7850 next:
7851 insn = next_nonnote_insn (insn);
7852
7853 if (!insn || ! INSN_P (insn))
7854 goto done;
7855
7856 /* Let Haifa tell us where it thinks insn group boundaries are. */
7857 if (GET_MODE (insn) == TImode)
7858 goto done;
7859
7860 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
7861 goto next;
7862 }
7863
7864 next_and_done:
7865 insn = next_nonnote_insn (insn);
7866
7867 done:
7868 *plen = len;
7869 *pin_use = in_use;
7870 return insn;
7871 }
7872
7873 static rtx
7874 alphaev4_next_nop (int *pin_use)
7875 {
7876 int in_use = *pin_use;
7877 rtx nop;
7878
7879 if (!(in_use & EV4_IB0))
7880 {
7881 in_use |= EV4_IB0;
7882 nop = gen_nop ();
7883 }
7884 else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX)
7885 {
7886 in_use |= EV4_IB1;
7887 nop = gen_nop ();
7888 }
7889 else if (TARGET_FP && !(in_use & EV4_IB1))
7890 {
7891 in_use |= EV4_IB1;
7892 nop = gen_fnop ();
7893 }
7894 else
7895 nop = gen_unop ();
7896
7897 *pin_use = in_use;
7898 return nop;
7899 }
7900
7901 static rtx
7902 alphaev5_next_nop (int *pin_use)
7903 {
7904 int in_use = *pin_use;
7905 rtx nop;
7906
7907 if (!(in_use & EV5_E1))
7908 {
7909 in_use |= EV5_E1;
7910 nop = gen_nop ();
7911 }
7912 else if (TARGET_FP && !(in_use & EV5_FA))
7913 {
7914 in_use |= EV5_FA;
7915 nop = gen_fnop ();
7916 }
7917 else if (TARGET_FP && !(in_use & EV5_FM))
7918 {
7919 in_use |= EV5_FM;
7920 nop = gen_fnop ();
7921 }
7922 else
7923 nop = gen_unop ();
7924
7925 *pin_use = in_use;
7926 return nop;
7927 }
7928
7929 /* The instruction group alignment main loop. */
7930
7931 static void
7932 alpha_align_insns (unsigned int max_align,
7933 rtx (*next_group) (rtx, int *, int *),
7934 rtx (*next_nop) (int *))
7935 {
7936 /* ALIGN is the known alignment for the insn group. */
7937 unsigned int align;
7938 /* OFS is the offset of the current insn in the insn group. */
7939 int ofs;
7940 int prev_in_use, in_use, len;
7941 rtx i, next;
7942
7943 /* Let shorten branches care for assigning alignments to code labels. */
7944 shorten_branches (get_insns ());
7945
7946 if (align_functions < 4)
7947 align = 4;
7948 else if ((unsigned int) align_functions < max_align)
7949 align = align_functions;
7950 else
7951 align = max_align;
7952
7953 ofs = prev_in_use = 0;
7954 i = get_insns ();
7955 if (GET_CODE (i) == NOTE)
7956 i = next_nonnote_insn (i);
7957
7958 while (i)
7959 {
7960 next = (*next_group) (i, &in_use, &len);
7961
7962 /* When we see a label, resync alignment etc. */
7963 if (GET_CODE (i) == CODE_LABEL)
7964 {
7965 unsigned int new_align = 1 << label_to_alignment (i);
7966
7967 if (new_align >= align)
7968 {
7969 align = new_align < max_align ? new_align : max_align;
7970 ofs = 0;
7971 }
7972
7973 else if (ofs & (new_align-1))
7974 ofs = (ofs | (new_align-1)) + 1;
7975 if (len != 0)
7976 abort();
7977 }
7978
7979 /* Handle complex instructions special. */
7980 else if (in_use == 0)
7981 {
7982 /* Asms will have length < 0. This is a signal that we have
7983 lost alignment knowledge. Assume, however, that the asm
7984 will not mis-align instructions. */
7985 if (len < 0)
7986 {
7987 ofs = 0;
7988 align = 4;
7989 len = 0;
7990 }
7991 }
7992
7993 /* If the known alignment is smaller than the recognized insn group,
7994 realign the output. */
7995 else if ((int) align < len)
7996 {
7997 unsigned int new_log_align = len > 8 ? 4 : 3;
7998 rtx prev, where;
7999
8000 where = prev = prev_nonnote_insn (i);
8001 if (!where || GET_CODE (where) != CODE_LABEL)
8002 where = i;
8003
8004 /* Can't realign between a call and its gp reload. */
8005 if (! (TARGET_EXPLICIT_RELOCS
8006 && prev && GET_CODE (prev) == CALL_INSN))
8007 {
8008 emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
8009 align = 1 << new_log_align;
8010 ofs = 0;
8011 }
8012 }
8013
8014 /* If the group won't fit in the same INT16 as the previous,
8015 we need to add padding to keep the group together. Rather
8016 than simply leaving the insn filling to the assembler, we
8017 can make use of the knowledge of what sorts of instructions
8018 were issued in the previous group to make sure that all of
8019 the added nops are really free. */
8020 else if (ofs + len > (int) align)
8021 {
8022 int nop_count = (align - ofs) / 4;
8023 rtx where;
8024
8025 /* Insert nops before labels, branches, and calls to truly merge
8026 the execution of the nops with the previous instruction group. */
8027 where = prev_nonnote_insn (i);
8028 if (where)
8029 {
8030 if (GET_CODE (where) == CODE_LABEL)
8031 {
8032 rtx where2 = prev_nonnote_insn (where);
8033 if (where2 && GET_CODE (where2) == JUMP_INSN)
8034 where = where2;
8035 }
8036 else if (GET_CODE (where) == INSN)
8037 where = i;
8038 }
8039 else
8040 where = i;
8041
8042 do
8043 emit_insn_before ((*next_nop)(&prev_in_use), where);
8044 while (--nop_count);
8045 ofs = 0;
8046 }
8047
8048 ofs = (ofs + len) & (align - 1);
8049 prev_in_use = in_use;
8050 i = next;
8051 }
8052 }
8053 \f
8054 /* Machine dependent reorg pass. */
8055
8056 static void
8057 alpha_reorg (void)
8058 {
8059 if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
8060 alpha_handle_trap_shadows ();
8061
8062 /* Due to the number of extra trapb insns, don't bother fixing up
8063 alignment when trap precision is instruction. Moreover, we can
8064 only do our job when sched2 is run. */
8065 if (optimize && !optimize_size
8066 && alpha_tp != ALPHA_TP_INSN
8067 && flag_schedule_insns_after_reload)
8068 {
8069 if (alpha_cpu == PROCESSOR_EV4)
8070 alpha_align_insns (8, alphaev4_next_group, alphaev4_next_nop);
8071 else if (alpha_cpu == PROCESSOR_EV5)
8072 alpha_align_insns (16, alphaev5_next_group, alphaev5_next_nop);
8073 }
8074 }
8075 \f
8076 #if !TARGET_ABI_UNICOSMK
8077
8078 #ifdef HAVE_STAMP_H
8079 #include <stamp.h>
8080 #endif
8081
8082 static void
8083 alpha_file_start (void)
8084 {
8085 #ifdef OBJECT_FORMAT_ELF
8086 /* If emitting dwarf2 debug information, we cannot generate a .file
8087 directive to start the file, as it will conflict with dwarf2out
8088 file numbers. So it's only useful when emitting mdebug output. */
8089 targetm.file_start_file_directive = (write_symbols == DBX_DEBUG);
8090 #endif
8091
8092 default_file_start ();
8093 #ifdef MS_STAMP
8094 fprintf (asm_out_file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
8095 #endif
8096
8097 fputs ("\t.set noreorder\n", asm_out_file);
8098 fputs ("\t.set volatile\n", asm_out_file);
8099 if (!TARGET_ABI_OPEN_VMS)
8100 fputs ("\t.set noat\n", asm_out_file);
8101 if (TARGET_EXPLICIT_RELOCS)
8102 fputs ("\t.set nomacro\n", asm_out_file);
8103 if (TARGET_SUPPORT_ARCH | TARGET_BWX | TARGET_MAX | TARGET_FIX | TARGET_CIX)
8104 fprintf (asm_out_file,
8105 "\t.arch %s\n",
8106 TARGET_CPU_EV6 ? "ev6"
8107 : (TARGET_CPU_EV5
8108 ? (TARGET_MAX ? "pca56" : TARGET_BWX ? "ev56" : "ev5")
8109 : "ev4"));
8110 }
8111 #endif
8112
8113 #ifdef OBJECT_FORMAT_ELF
8114
8115 /* Switch to the section to which we should output X. The only thing
8116 special we do here is to honor small data. */
8117
8118 static void
8119 alpha_elf_select_rtx_section (enum machine_mode mode, rtx x,
8120 unsigned HOST_WIDE_INT align)
8121 {
8122 if (TARGET_SMALL_DATA && GET_MODE_SIZE (mode) <= g_switch_value)
8123 /* ??? Consider using mergeable sdata sections. */
8124 sdata_section ();
8125 else
8126 default_elf_select_rtx_section (mode, x, align);
8127 }
8128
8129 #endif /* OBJECT_FORMAT_ELF */
8130 \f
8131 /* Structure to collect function names for final output in link section. */
8132 /* Note that items marked with GTY can't be ifdef'ed out. */
8133
8134 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
8135 enum reloc_kind {KIND_LINKAGE, KIND_CODEADDR};
8136
8137 struct alpha_links GTY(())
8138 {
8139 int num;
8140 rtx linkage;
8141 enum links_kind lkind;
8142 enum reloc_kind rkind;
8143 };
8144
8145 struct alpha_funcs GTY(())
8146 {
8147 int num;
8148 splay_tree GTY ((param1_is (char *), param2_is (struct alpha_links *)))
8149 links;
8150 };
8151
8152 static GTY ((param1_is (char *), param2_is (struct alpha_links *)))
8153 splay_tree alpha_links_tree;
8154 static GTY ((param1_is (tree), param2_is (struct alpha_funcs *)))
8155 splay_tree alpha_funcs_tree;
8156
8157 static GTY(()) int alpha_funcs_num;
8158
8159 #if TARGET_ABI_OPEN_VMS
8160
8161 /* Return the VMS argument type corresponding to MODE. */
8162
8163 enum avms_arg_type
8164 alpha_arg_type (enum machine_mode mode)
8165 {
8166 switch (mode)
8167 {
8168 case SFmode:
8169 return TARGET_FLOAT_VAX ? FF : FS;
8170 case DFmode:
8171 return TARGET_FLOAT_VAX ? FD : FT;
8172 default:
8173 return I64;
8174 }
8175 }
8176
8177 /* Return an rtx for an integer representing the VMS Argument Information
8178 register value. */
8179
8180 rtx
8181 alpha_arg_info_reg_val (CUMULATIVE_ARGS cum)
8182 {
8183 unsigned HOST_WIDE_INT regval = cum.num_args;
8184 int i;
8185
8186 for (i = 0; i < 6; i++)
8187 regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
8188
8189 return GEN_INT (regval);
8190 }
8191 \f
8192 /* Make (or fake) .linkage entry for function call.
8193
8194 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition.
8195
8196 Return an SYMBOL_REF rtx for the linkage. */
8197
8198 rtx
8199 alpha_need_linkage (const char *name, int is_local)
8200 {
8201 splay_tree_node node;
8202 struct alpha_links *al;
8203
8204 if (name[0] == '*')
8205 name++;
8206
8207 if (is_local)
8208 {
8209 struct alpha_funcs *cfaf;
8210
8211 if (!alpha_funcs_tree)
8212 alpha_funcs_tree = splay_tree_new_ggc ((splay_tree_compare_fn)
8213 splay_tree_compare_pointers);
8214
8215 cfaf = (struct alpha_funcs *) ggc_alloc (sizeof (struct alpha_funcs));
8216
8217 cfaf->links = 0;
8218 cfaf->num = ++alpha_funcs_num;
8219
8220 splay_tree_insert (alpha_funcs_tree,
8221 (splay_tree_key) current_function_decl,
8222 (splay_tree_value) cfaf);
8223 }
8224
8225 if (alpha_links_tree)
8226 {
8227 /* Is this name already defined? */
8228
8229 node = splay_tree_lookup (alpha_links_tree, (splay_tree_key) name);
8230 if (node)
8231 {
8232 al = (struct alpha_links *) node->value;
8233 if (is_local)
8234 {
8235 /* Defined here but external assumed. */
8236 if (al->lkind == KIND_EXTERN)
8237 al->lkind = KIND_LOCAL;
8238 }
8239 else
8240 {
8241 /* Used here but unused assumed. */
8242 if (al->lkind == KIND_UNUSED)
8243 al->lkind = KIND_LOCAL;
8244 }
8245 return al->linkage;
8246 }
8247 }
8248 else
8249 alpha_links_tree = splay_tree_new_ggc ((splay_tree_compare_fn) strcmp);
8250
8251 al = (struct alpha_links *) ggc_alloc (sizeof (struct alpha_links));
8252 name = ggc_strdup (name);
8253
8254 /* Assume external if no definition. */
8255 al->lkind = (is_local ? KIND_UNUSED : KIND_EXTERN);
8256
8257 /* Ensure we have an IDENTIFIER so assemble_name can mark it used. */
8258 get_identifier (name);
8259
8260 /* Construct a SYMBOL_REF for us to call. */
8261 {
8262 size_t name_len = strlen (name);
8263 char *linksym = alloca (name_len + 6);
8264 linksym[0] = '$';
8265 memcpy (linksym + 1, name, name_len);
8266 memcpy (linksym + 1 + name_len, "..lk", 5);
8267 al->linkage = gen_rtx_SYMBOL_REF (Pmode,
8268 ggc_alloc_string (linksym, name_len + 5));
8269 }
8270
8271 splay_tree_insert (alpha_links_tree, (splay_tree_key) name,
8272 (splay_tree_value) al);
8273
8274 return al->linkage;
8275 }
8276
8277 rtx
8278 alpha_use_linkage (rtx linkage, tree cfundecl, int lflag, int rflag)
8279 {
8280 splay_tree_node cfunnode;
8281 struct alpha_funcs *cfaf;
8282 struct alpha_links *al;
8283 const char *name = XSTR (linkage, 0);
8284
8285 cfaf = (struct alpha_funcs *) 0;
8286 al = (struct alpha_links *) 0;
8287
8288 cfunnode = splay_tree_lookup (alpha_funcs_tree, (splay_tree_key) cfundecl);
8289 cfaf = (struct alpha_funcs *) cfunnode->value;
8290
8291 if (cfaf->links)
8292 {
8293 splay_tree_node lnode;
8294
8295 /* Is this name already defined? */
8296
8297 lnode = splay_tree_lookup (cfaf->links, (splay_tree_key) name);
8298 if (lnode)
8299 al = (struct alpha_links *) lnode->value;
8300 }
8301 else
8302 cfaf->links = splay_tree_new_ggc ((splay_tree_compare_fn) strcmp);
8303
8304 if (!al)
8305 {
8306 size_t name_len;
8307 size_t buflen;
8308 char buf [512];
8309 char *linksym;
8310 splay_tree_node node = 0;
8311 struct alpha_links *anl;
8312
8313 if (name[0] == '*')
8314 name++;
8315
8316 name_len = strlen (name);
8317
8318 al = (struct alpha_links *) ggc_alloc (sizeof (struct alpha_links));
8319 al->num = cfaf->num;
8320
8321 node = splay_tree_lookup (alpha_links_tree, (splay_tree_key) name);
8322 if (node)
8323 {
8324 anl = (struct alpha_links *) node->value;
8325 al->lkind = anl->lkind;
8326 }
8327
8328 sprintf (buf, "$%d..%s..lk", cfaf->num, name);
8329 buflen = strlen (buf);
8330 linksym = alloca (buflen + 1);
8331 memcpy (linksym, buf, buflen + 1);
8332
8333 al->linkage = gen_rtx_SYMBOL_REF
8334 (Pmode, ggc_alloc_string (linksym, buflen + 1));
8335
8336 splay_tree_insert (cfaf->links, (splay_tree_key) name,
8337 (splay_tree_value) al);
8338 }
8339
8340 if (rflag)
8341 al->rkind = KIND_CODEADDR;
8342 else
8343 al->rkind = KIND_LINKAGE;
8344
8345 if (lflag)
8346 return gen_rtx_MEM (Pmode, plus_constant (al->linkage, 8));
8347 else
8348 return al->linkage;
8349 }
8350
8351 static int
8352 alpha_write_one_linkage (splay_tree_node node, void *data)
8353 {
8354 const char *const name = (const char *) node->key;
8355 struct alpha_links *link = (struct alpha_links *) node->value;
8356 FILE *stream = (FILE *) data;
8357
8358 fprintf (stream, "$%d..%s..lk:\n", link->num, name);
8359 if (link->rkind == KIND_CODEADDR)
8360 {
8361 if (link->lkind == KIND_LOCAL)
8362 {
8363 /* Local and used */
8364 fprintf (stream, "\t.quad %s..en\n", name);
8365 }
8366 else
8367 {
8368 /* External and used, request code address. */
8369 fprintf (stream, "\t.code_address %s\n", name);
8370 }
8371 }
8372 else
8373 {
8374 if (link->lkind == KIND_LOCAL)
8375 {
8376 /* Local and used, build linkage pair. */
8377 fprintf (stream, "\t.quad %s..en\n", name);
8378 fprintf (stream, "\t.quad %s\n", name);
8379 }
8380 else
8381 {
8382 /* External and used, request linkage pair. */
8383 fprintf (stream, "\t.linkage %s\n", name);
8384 }
8385 }
8386
8387 return 0;
8388 }
8389
8390 static void
8391 alpha_write_linkage (FILE *stream, const char *funname, tree fundecl)
8392 {
8393 splay_tree_node node;
8394 struct alpha_funcs *func;
8395
8396 link_section ();
8397 fprintf (stream, "\t.align 3\n");
8398 node = splay_tree_lookup (alpha_funcs_tree, (splay_tree_key) fundecl);
8399 func = (struct alpha_funcs *) node->value;
8400
8401 fputs ("\t.name ", stream);
8402 assemble_name (stream, funname);
8403 fputs ("..na\n", stream);
8404 ASM_OUTPUT_LABEL (stream, funname);
8405 fprintf (stream, "\t.pdesc ");
8406 assemble_name (stream, funname);
8407 fprintf (stream, "..en,%s\n",
8408 alpha_procedure_type == PT_STACK ? "stack"
8409 : alpha_procedure_type == PT_REGISTER ? "reg" : "null");
8410
8411 if (func->links)
8412 {
8413 splay_tree_foreach (func->links, alpha_write_one_linkage, stream);
8414 /* splay_tree_delete (func->links); */
8415 }
8416 }
8417
8418 /* Given a decl, a section name, and whether the decl initializer
8419 has relocs, choose attributes for the section. */
8420
8421 #define SECTION_VMS_OVERLAY SECTION_FORGET
8422 #define SECTION_VMS_GLOBAL SECTION_MACH_DEP
8423 #define SECTION_VMS_INITIALIZE (SECTION_VMS_GLOBAL << 1)
8424
8425 static unsigned int
8426 vms_section_type_flags (tree decl, const char *name, int reloc)
8427 {
8428 unsigned int flags = default_section_type_flags (decl, name, reloc);
8429
8430 if (decl && DECL_ATTRIBUTES (decl)
8431 && lookup_attribute ("overlaid", DECL_ATTRIBUTES (decl)))
8432 flags |= SECTION_VMS_OVERLAY;
8433 if (decl && DECL_ATTRIBUTES (decl)
8434 && lookup_attribute ("global", DECL_ATTRIBUTES (decl)))
8435 flags |= SECTION_VMS_GLOBAL;
8436 if (decl && DECL_ATTRIBUTES (decl)
8437 && lookup_attribute ("initialize", DECL_ATTRIBUTES (decl)))
8438 flags |= SECTION_VMS_INITIALIZE;
8439
8440 return flags;
8441 }
8442
8443 /* Switch to an arbitrary section NAME with attributes as specified
8444 by FLAGS. ALIGN specifies any known alignment requirements for
8445 the section; 0 if the default should be used. */
8446
8447 static void
8448 vms_asm_named_section (const char *name, unsigned int flags,
8449 tree decl ATTRIBUTE_UNUSED)
8450 {
8451 fputc ('\n', asm_out_file);
8452 fprintf (asm_out_file, ".section\t%s", name);
8453
8454 if (flags & SECTION_VMS_OVERLAY)
8455 fprintf (asm_out_file, ",OVR");
8456 if (flags & SECTION_VMS_GLOBAL)
8457 fprintf (asm_out_file, ",GBL");
8458 if (flags & SECTION_VMS_INITIALIZE)
8459 fprintf (asm_out_file, ",NOMOD");
8460 if (flags & SECTION_DEBUG)
8461 fprintf (asm_out_file, ",NOWRT");
8462
8463 fputc ('\n', asm_out_file);
8464 }
8465
8466 /* Record an element in the table of global constructors. SYMBOL is
8467 a SYMBOL_REF of the function to be called; PRIORITY is a number
8468 between 0 and MAX_INIT_PRIORITY.
8469
8470 Differs from default_ctors_section_asm_out_constructor in that the
8471 width of the .ctors entry is always 64 bits, rather than the 32 bits
8472 used by a normal pointer. */
8473
8474 static void
8475 vms_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
8476 {
8477 ctors_section ();
8478 assemble_align (BITS_PER_WORD);
8479 assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
8480 }
8481
8482 static void
8483 vms_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
8484 {
8485 dtors_section ();
8486 assemble_align (BITS_PER_WORD);
8487 assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
8488 }
8489 #else
8490
8491 rtx
8492 alpha_need_linkage (const char *name ATTRIBUTE_UNUSED,
8493 int is_local ATTRIBUTE_UNUSED)
8494 {
8495 return NULL_RTX;
8496 }
8497
8498 rtx
8499 alpha_use_linkage (rtx linkage ATTRIBUTE_UNUSED,
8500 tree cfundecl ATTRIBUTE_UNUSED,
8501 int lflag ATTRIBUTE_UNUSED,
8502 int rflag ATTRIBUTE_UNUSED)
8503 {
8504 return NULL_RTX;
8505 }
8506
8507 #endif /* TARGET_ABI_OPEN_VMS */
8508 \f
8509 #if TARGET_ABI_UNICOSMK
8510
8511 /* This evaluates to true if we do not know how to pass TYPE solely in
8512 registers. This is the case for all arguments that do not fit in two
8513 registers. */
8514
8515 static bool
8516 unicosmk_must_pass_in_stack (enum machine_mode mode, tree type)
8517 {
8518 if (type == NULL)
8519 return false;
8520
8521 if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
8522 return true;
8523 if (TREE_ADDRESSABLE (type))
8524 return true;
8525
8526 return ALPHA_ARG_SIZE (mode, type, 0) > 2;
8527 }
8528
8529 /* Define the offset between two registers, one to be eliminated, and the
8530 other its replacement, at the start of a routine. */
8531
8532 int
8533 unicosmk_initial_elimination_offset (int from, int to)
8534 {
8535 int fixed_size;
8536
8537 fixed_size = alpha_sa_size();
8538 if (fixed_size != 0)
8539 fixed_size += 48;
8540
8541 if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
8542 return -fixed_size;
8543 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
8544 return 0;
8545 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
8546 return (ALPHA_ROUND (current_function_outgoing_args_size)
8547 + ALPHA_ROUND (get_frame_size()));
8548 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
8549 return (ALPHA_ROUND (fixed_size)
8550 + ALPHA_ROUND (get_frame_size()
8551 + current_function_outgoing_args_size));
8552 else
8553 abort ();
8554 }
8555
8556 /* Output the module name for .ident and .end directives. We have to strip
8557 directories and add make sure that the module name starts with a letter
8558 or '$'. */
8559
8560 static void
8561 unicosmk_output_module_name (FILE *file)
8562 {
8563 const char *name = lbasename (main_input_filename);
8564 unsigned len = strlen (name);
8565 char *clean_name = alloca (len + 2);
8566 char *ptr = clean_name;
8567
8568 /* CAM only accepts module names that start with a letter or '$'. We
8569 prefix the module name with a '$' if necessary. */
8570
8571 if (!ISALPHA (*name))
8572 *ptr++ = '$';
8573 memcpy (ptr, name, len + 1);
8574 clean_symbol_name (clean_name);
8575 fputs (clean_name, file);
8576 }
8577
8578 /* Output the definition of a common variable. */
8579
8580 void
8581 unicosmk_output_common (FILE *file, const char *name, int size, int align)
8582 {
8583 tree name_tree;
8584 printf ("T3E__: common %s\n", name);
8585
8586 common_section ();
8587 fputs("\t.endp\n\n\t.psect ", file);
8588 assemble_name(file, name);
8589 fprintf(file, ",%d,common\n", floor_log2 (align / BITS_PER_UNIT));
8590 fprintf(file, "\t.byte\t0:%d\n", size);
8591
8592 /* Mark the symbol as defined in this module. */
8593 name_tree = get_identifier (name);
8594 TREE_ASM_WRITTEN (name_tree) = 1;
8595 }
8596
8597 #define SECTION_PUBLIC SECTION_MACH_DEP
8598 #define SECTION_MAIN (SECTION_PUBLIC << 1)
8599 static int current_section_align;
8600
8601 static unsigned int
8602 unicosmk_section_type_flags (tree decl, const char *name,
8603 int reloc ATTRIBUTE_UNUSED)
8604 {
8605 unsigned int flags = default_section_type_flags (decl, name, reloc);
8606
8607 if (!decl)
8608 return flags;
8609
8610 if (TREE_CODE (decl) == FUNCTION_DECL)
8611 {
8612 current_section_align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
8613 if (align_functions_log > current_section_align)
8614 current_section_align = align_functions_log;
8615
8616 if (! strcmp (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), "main"))
8617 flags |= SECTION_MAIN;
8618 }
8619 else
8620 current_section_align = floor_log2 (DECL_ALIGN (decl) / BITS_PER_UNIT);
8621
8622 if (TREE_PUBLIC (decl))
8623 flags |= SECTION_PUBLIC;
8624
8625 return flags;
8626 }
8627
8628 /* Generate a section name for decl and associate it with the
8629 declaration. */
8630
8631 static void
8632 unicosmk_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
8633 {
8634 const char *name;
8635 int len;
8636
8637 if (!decl)
8638 abort ();
8639
8640 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
8641 name = default_strip_name_encoding (name);
8642 len = strlen (name);
8643
8644 if (TREE_CODE (decl) == FUNCTION_DECL)
8645 {
8646 char *string;
8647
8648 /* It is essential that we prefix the section name here because
8649 otherwise the section names generated for constructors and
8650 destructors confuse collect2. */
8651
8652 string = alloca (len + 6);
8653 sprintf (string, "code@%s", name);
8654 DECL_SECTION_NAME (decl) = build_string (len + 5, string);
8655 }
8656 else if (TREE_PUBLIC (decl))
8657 DECL_SECTION_NAME (decl) = build_string (len, name);
8658 else
8659 {
8660 char *string;
8661
8662 string = alloca (len + 6);
8663 sprintf (string, "data@%s", name);
8664 DECL_SECTION_NAME (decl) = build_string (len + 5, string);
8665 }
8666 }
8667
8668 /* Switch to an arbitrary section NAME with attributes as specified
8669 by FLAGS. ALIGN specifies any known alignment requirements for
8670 the section; 0 if the default should be used. */
8671
8672 static void
8673 unicosmk_asm_named_section (const char *name, unsigned int flags,
8674 tree decl ATTRIBUTE_UNUSED)
8675 {
8676 const char *kind;
8677
8678 /* Close the previous section. */
8679
8680 fputs ("\t.endp\n\n", asm_out_file);
8681
8682 /* Find out what kind of section we are opening. */
8683
8684 if (flags & SECTION_MAIN)
8685 fputs ("\t.start\tmain\n", asm_out_file);
8686
8687 if (flags & SECTION_CODE)
8688 kind = "code";
8689 else if (flags & SECTION_PUBLIC)
8690 kind = "common";
8691 else
8692 kind = "data";
8693
8694 if (current_section_align != 0)
8695 fprintf (asm_out_file, "\t.psect\t%s,%d,%s\n", name,
8696 current_section_align, kind);
8697 else
8698 fprintf (asm_out_file, "\t.psect\t%s,%s\n", name, kind);
8699 }
8700
8701 static void
8702 unicosmk_insert_attributes (tree decl, tree *attr_ptr ATTRIBUTE_UNUSED)
8703 {
8704 if (DECL_P (decl)
8705 && (TREE_PUBLIC (decl) || TREE_CODE (decl) == FUNCTION_DECL))
8706 unicosmk_unique_section (decl, 0);
8707 }
8708
8709 /* Output an alignment directive. We have to use the macro 'gcc@code@align'
8710 in code sections because .align fill unused space with zeroes. */
8711
8712 void
8713 unicosmk_output_align (FILE *file, int align)
8714 {
8715 if (inside_function)
8716 fprintf (file, "\tgcc@code@align\t%d\n", align);
8717 else
8718 fprintf (file, "\t.align\t%d\n", align);
8719 }
8720
8721 /* Add a case vector to the current function's list of deferred case
8722 vectors. Case vectors have to be put into a separate section because CAM
8723 does not allow data definitions in code sections. */
8724
8725 void
8726 unicosmk_defer_case_vector (rtx lab, rtx vec)
8727 {
8728 struct machine_function *machine = cfun->machine;
8729
8730 vec = gen_rtx_EXPR_LIST (VOIDmode, lab, vec);
8731 machine->addr_list = gen_rtx_EXPR_LIST (VOIDmode, vec,
8732 machine->addr_list);
8733 }
8734
8735 /* Output a case vector. */
8736
8737 static void
8738 unicosmk_output_addr_vec (FILE *file, rtx vec)
8739 {
8740 rtx lab = XEXP (vec, 0);
8741 rtx body = XEXP (vec, 1);
8742 int vlen = XVECLEN (body, 0);
8743 int idx;
8744
8745 (*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (lab));
8746
8747 for (idx = 0; idx < vlen; idx++)
8748 {
8749 ASM_OUTPUT_ADDR_VEC_ELT
8750 (file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0)));
8751 }
8752 }
8753
8754 /* Output current function's deferred case vectors. */
8755
8756 static void
8757 unicosmk_output_deferred_case_vectors (FILE *file)
8758 {
8759 struct machine_function *machine = cfun->machine;
8760 rtx t;
8761
8762 if (machine->addr_list == NULL_RTX)
8763 return;
8764
8765 data_section ();
8766 for (t = machine->addr_list; t; t = XEXP (t, 1))
8767 unicosmk_output_addr_vec (file, XEXP (t, 0));
8768 }
8769
8770 /* Generate the name of the SSIB section for the current function. */
8771
8772 #define SSIB_PREFIX "__SSIB_"
8773 #define SSIB_PREFIX_LEN 7
8774
8775 static const char *
8776 unicosmk_ssib_name (void)
8777 {
8778 /* This is ok since CAM won't be able to deal with names longer than that
8779 anyway. */
8780
8781 static char name[256];
8782
8783 rtx x;
8784 const char *fnname;
8785 int len;
8786
8787 x = DECL_RTL (cfun->decl);
8788 if (GET_CODE (x) != MEM)
8789 abort ();
8790 x = XEXP (x, 0);
8791 if (GET_CODE (x) != SYMBOL_REF)
8792 abort ();
8793 fnname = XSTR (x, 0);
8794
8795 len = strlen (fnname);
8796 if (len + SSIB_PREFIX_LEN > 255)
8797 len = 255 - SSIB_PREFIX_LEN;
8798
8799 strcpy (name, SSIB_PREFIX);
8800 strncpy (name + SSIB_PREFIX_LEN, fnname, len);
8801 name[len + SSIB_PREFIX_LEN] = 0;
8802
8803 return name;
8804 }
8805
8806 /* Set up the dynamic subprogram information block (DSIB) and update the
8807 frame pointer register ($15) for subroutines which have a frame. If the
8808 subroutine doesn't have a frame, simply increment $15. */
8809
8810 static void
8811 unicosmk_gen_dsib (unsigned long *imaskP)
8812 {
8813 if (alpha_procedure_type == PT_STACK)
8814 {
8815 const char *ssib_name;
8816 rtx mem;
8817
8818 /* Allocate 64 bytes for the DSIB. */
8819
8820 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
8821 GEN_INT (-64))));
8822 emit_insn (gen_blockage ());
8823
8824 /* Save the return address. */
8825
8826 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 56));
8827 set_mem_alias_set (mem, alpha_sr_alias_set);
8828 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
8829 (*imaskP) &= ~(1UL << REG_RA);
8830
8831 /* Save the old frame pointer. */
8832
8833 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 48));
8834 set_mem_alias_set (mem, alpha_sr_alias_set);
8835 FRP (emit_move_insn (mem, hard_frame_pointer_rtx));
8836 (*imaskP) &= ~(1UL << HARD_FRAME_POINTER_REGNUM);
8837
8838 emit_insn (gen_blockage ());
8839
8840 /* Store the SSIB pointer. */
8841
8842 ssib_name = ggc_strdup (unicosmk_ssib_name ());
8843 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 32));
8844 set_mem_alias_set (mem, alpha_sr_alias_set);
8845
8846 FRP (emit_move_insn (gen_rtx_REG (DImode, 5),
8847 gen_rtx_SYMBOL_REF (Pmode, ssib_name)));
8848 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, 5)));
8849
8850 /* Save the CIW index. */
8851
8852 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 24));
8853 set_mem_alias_set (mem, alpha_sr_alias_set);
8854 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, 25)));
8855
8856 emit_insn (gen_blockage ());
8857
8858 /* Set the new frame pointer. */
8859
8860 FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
8861 stack_pointer_rtx, GEN_INT (64))));
8862
8863 }
8864 else
8865 {
8866 /* Increment the frame pointer register to indicate that we do not
8867 have a frame. */
8868
8869 FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
8870 hard_frame_pointer_rtx, const1_rtx)));
8871 }
8872 }
8873
8874 /* Output the static subroutine information block for the current
8875 function. */
8876
8877 static void
8878 unicosmk_output_ssib (FILE *file, const char *fnname)
8879 {
8880 int len;
8881 int i;
8882 rtx x;
8883 rtx ciw;
8884 struct machine_function *machine = cfun->machine;
8885
8886 ssib_section ();
8887 fprintf (file, "\t.endp\n\n\t.psect\t%s%s,data\n", user_label_prefix,
8888 unicosmk_ssib_name ());
8889
8890 /* Some required stuff and the function name length. */
8891
8892 len = strlen (fnname);
8893 fprintf (file, "\t.quad\t^X20008%2.2X28\n", len);
8894
8895 /* Saved registers
8896 ??? We don't do that yet. */
8897
8898 fputs ("\t.quad\t0\n", file);
8899
8900 /* Function address. */
8901
8902 fputs ("\t.quad\t", file);
8903 assemble_name (file, fnname);
8904 putc ('\n', file);
8905
8906 fputs ("\t.quad\t0\n", file);
8907 fputs ("\t.quad\t0\n", file);
8908
8909 /* Function name.
8910 ??? We do it the same way Cray CC does it but this could be
8911 simplified. */
8912
8913 for( i = 0; i < len; i++ )
8914 fprintf (file, "\t.byte\t%d\n", (int)(fnname[i]));
8915 if( (len % 8) == 0 )
8916 fputs ("\t.quad\t0\n", file);
8917 else
8918 fprintf (file, "\t.bits\t%d : 0\n", (8 - (len % 8))*8);
8919
8920 /* All call information words used in the function. */
8921
8922 for (x = machine->first_ciw; x; x = XEXP (x, 1))
8923 {
8924 ciw = XEXP (x, 0);
8925 #if HOST_BITS_PER_WIDE_INT == 32
8926 fprintf (file, "\t.quad\t" HOST_WIDE_INT_PRINT_DOUBLE_HEX "\n",
8927 CONST_DOUBLE_HIGH (ciw), CONST_DOUBLE_LOW (ciw));
8928 #else
8929 fprintf (file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n", INTVAL (ciw));
8930 #endif
8931 }
8932 }
8933
8934 /* Add a call information word (CIW) to the list of the current function's
8935 CIWs and return its index.
8936
8937 X is a CONST_INT or CONST_DOUBLE representing the CIW. */
8938
8939 rtx
8940 unicosmk_add_call_info_word (rtx x)
8941 {
8942 rtx node;
8943 struct machine_function *machine = cfun->machine;
8944
8945 node = gen_rtx_EXPR_LIST (VOIDmode, x, NULL_RTX);
8946 if (machine->first_ciw == NULL_RTX)
8947 machine->first_ciw = node;
8948 else
8949 XEXP (machine->last_ciw, 1) = node;
8950
8951 machine->last_ciw = node;
8952 ++machine->ciw_count;
8953
8954 return GEN_INT (machine->ciw_count
8955 + strlen (current_function_name ())/8 + 5);
8956 }
8957
8958 static char unicosmk_section_buf[100];
8959
8960 char *
8961 unicosmk_text_section (void)
8962 {
8963 static int count = 0;
8964 sprintf (unicosmk_section_buf, "\t.endp\n\n\t.psect\tgcc@text___%d,code",
8965 count++);
8966 return unicosmk_section_buf;
8967 }
8968
8969 char *
8970 unicosmk_data_section (void)
8971 {
8972 static int count = 1;
8973 sprintf (unicosmk_section_buf, "\t.endp\n\n\t.psect\tgcc@data___%d,data",
8974 count++);
8975 return unicosmk_section_buf;
8976 }
8977
8978 /* The Cray assembler doesn't accept extern declarations for symbols which
8979 are defined in the same file. We have to keep track of all global
8980 symbols which are referenced and/or defined in a source file and output
8981 extern declarations for those which are referenced but not defined at
8982 the end of file. */
8983
8984 /* List of identifiers for which an extern declaration might have to be
8985 emitted. */
8986 /* FIXME: needs to use GC, so it can be saved and restored for PCH. */
8987
8988 struct unicosmk_extern_list
8989 {
8990 struct unicosmk_extern_list *next;
8991 const char *name;
8992 };
8993
8994 static struct unicosmk_extern_list *unicosmk_extern_head = 0;
8995
8996 /* Output extern declarations which are required for every asm file. */
8997
8998 static void
8999 unicosmk_output_default_externs (FILE *file)
9000 {
9001 static const char *const externs[] =
9002 { "__T3E_MISMATCH" };
9003
9004 int i;
9005 int n;
9006
9007 n = ARRAY_SIZE (externs);
9008
9009 for (i = 0; i < n; i++)
9010 fprintf (file, "\t.extern\t%s\n", externs[i]);
9011 }
9012
9013 /* Output extern declarations for global symbols which are have been
9014 referenced but not defined. */
9015
9016 static void
9017 unicosmk_output_externs (FILE *file)
9018 {
9019 struct unicosmk_extern_list *p;
9020 const char *real_name;
9021 int len;
9022 tree name_tree;
9023
9024 len = strlen (user_label_prefix);
9025 for (p = unicosmk_extern_head; p != 0; p = p->next)
9026 {
9027 /* We have to strip the encoding and possibly remove user_label_prefix
9028 from the identifier in order to handle -fleading-underscore and
9029 explicit asm names correctly (cf. gcc.dg/asm-names-1.c). */
9030 real_name = default_strip_name_encoding (p->name);
9031 if (len && p->name[0] == '*'
9032 && !memcmp (real_name, user_label_prefix, len))
9033 real_name += len;
9034
9035 name_tree = get_identifier (real_name);
9036 if (! TREE_ASM_WRITTEN (name_tree))
9037 {
9038 TREE_ASM_WRITTEN (name_tree) = 1;
9039 fputs ("\t.extern\t", file);
9040 assemble_name (file, p->name);
9041 putc ('\n', file);
9042 }
9043 }
9044 }
9045
9046 /* Record an extern. */
9047
9048 void
9049 unicosmk_add_extern (const char *name)
9050 {
9051 struct unicosmk_extern_list *p;
9052
9053 p = (struct unicosmk_extern_list *)
9054 xmalloc (sizeof (struct unicosmk_extern_list));
9055 p->next = unicosmk_extern_head;
9056 p->name = name;
9057 unicosmk_extern_head = p;
9058 }
9059
9060 /* The Cray assembler generates incorrect code if identifiers which
9061 conflict with register names are used as instruction operands. We have
9062 to replace such identifiers with DEX expressions. */
9063
9064 /* Structure to collect identifiers which have been replaced by DEX
9065 expressions. */
9066 /* FIXME: needs to use GC, so it can be saved and restored for PCH. */
9067
9068 struct unicosmk_dex {
9069 struct unicosmk_dex *next;
9070 const char *name;
9071 };
9072
9073 /* List of identifiers which have been replaced by DEX expressions. The DEX
9074 number is determined by the position in the list. */
9075
9076 static struct unicosmk_dex *unicosmk_dex_list = NULL;
9077
9078 /* The number of elements in the DEX list. */
9079
9080 static int unicosmk_dex_count = 0;
9081
9082 /* Check if NAME must be replaced by a DEX expression. */
9083
9084 static int
9085 unicosmk_special_name (const char *name)
9086 {
9087 if (name[0] == '*')
9088 ++name;
9089
9090 if (name[0] == '$')
9091 ++name;
9092
9093 if (name[0] != 'r' && name[0] != 'f' && name[0] != 'R' && name[0] != 'F')
9094 return 0;
9095
9096 switch (name[1])
9097 {
9098 case '1': case '2':
9099 return (name[2] == '\0' || (ISDIGIT (name[2]) && name[3] == '\0'));
9100
9101 case '3':
9102 return (name[2] == '\0'
9103 || ((name[2] == '0' || name[2] == '1') && name[3] == '\0'));
9104
9105 default:
9106 return (ISDIGIT (name[1]) && name[2] == '\0');
9107 }
9108 }
9109
9110 /* Return the DEX number if X must be replaced by a DEX expression and 0
9111 otherwise. */
9112
9113 static int
9114 unicosmk_need_dex (rtx x)
9115 {
9116 struct unicosmk_dex *dex;
9117 const char *name;
9118 int i;
9119
9120 if (GET_CODE (x) != SYMBOL_REF)
9121 return 0;
9122
9123 name = XSTR (x,0);
9124 if (! unicosmk_special_name (name))
9125 return 0;
9126
9127 i = unicosmk_dex_count;
9128 for (dex = unicosmk_dex_list; dex; dex = dex->next)
9129 {
9130 if (! strcmp (name, dex->name))
9131 return i;
9132 --i;
9133 }
9134
9135 dex = (struct unicosmk_dex *) xmalloc (sizeof (struct unicosmk_dex));
9136 dex->name = name;
9137 dex->next = unicosmk_dex_list;
9138 unicosmk_dex_list = dex;
9139
9140 ++unicosmk_dex_count;
9141 return unicosmk_dex_count;
9142 }
9143
9144 /* Output the DEX definitions for this file. */
9145
9146 static void
9147 unicosmk_output_dex (FILE *file)
9148 {
9149 struct unicosmk_dex *dex;
9150 int i;
9151
9152 if (unicosmk_dex_list == NULL)
9153 return;
9154
9155 fprintf (file, "\t.dexstart\n");
9156
9157 i = unicosmk_dex_count;
9158 for (dex = unicosmk_dex_list; dex; dex = dex->next)
9159 {
9160 fprintf (file, "\tDEX (%d) = ", i);
9161 assemble_name (file, dex->name);
9162 putc ('\n', file);
9163 --i;
9164 }
9165
9166 fprintf (file, "\t.dexend\n");
9167 }
9168
9169 /* Output text that to appear at the beginning of an assembler file. */
9170
9171 static void
9172 unicosmk_file_start (void)
9173 {
9174 int i;
9175
9176 fputs ("\t.ident\t", asm_out_file);
9177 unicosmk_output_module_name (asm_out_file);
9178 fputs ("\n\n", asm_out_file);
9179
9180 /* The Unicos/Mk assembler uses different register names. Instead of trying
9181 to support them, we simply use micro definitions. */
9182
9183 /* CAM has different register names: rN for the integer register N and fN
9184 for the floating-point register N. Instead of trying to use these in
9185 alpha.md, we define the symbols $N and $fN to refer to the appropriate
9186 register. */
9187
9188 for (i = 0; i < 32; ++i)
9189 fprintf (asm_out_file, "$%d <- r%d\n", i, i);
9190
9191 for (i = 0; i < 32; ++i)
9192 fprintf (asm_out_file, "$f%d <- f%d\n", i, i);
9193
9194 putc ('\n', asm_out_file);
9195
9196 /* The .align directive fill unused space with zeroes which does not work
9197 in code sections. We define the macro 'gcc@code@align' which uses nops
9198 instead. Note that it assumes that code sections always have the
9199 biggest possible alignment since . refers to the current offset from
9200 the beginning of the section. */
9201
9202 fputs ("\t.macro gcc@code@align n\n", asm_out_file);
9203 fputs ("gcc@n@bytes = 1 << n\n", asm_out_file);
9204 fputs ("gcc@here = . % gcc@n@bytes\n", asm_out_file);
9205 fputs ("\t.if ne, gcc@here, 0\n", asm_out_file);
9206 fputs ("\t.repeat (gcc@n@bytes - gcc@here) / 4\n", asm_out_file);
9207 fputs ("\tbis r31,r31,r31\n", asm_out_file);
9208 fputs ("\t.endr\n", asm_out_file);
9209 fputs ("\t.endif\n", asm_out_file);
9210 fputs ("\t.endm gcc@code@align\n\n", asm_out_file);
9211
9212 /* Output extern declarations which should always be visible. */
9213 unicosmk_output_default_externs (asm_out_file);
9214
9215 /* Open a dummy section. We always need to be inside a section for the
9216 section-switching code to work correctly.
9217 ??? This should be a module id or something like that. I still have to
9218 figure out what the rules for those are. */
9219 fputs ("\n\t.psect\t$SG00000,data\n", asm_out_file);
9220 }
9221
9222 /* Output text to appear at the end of an assembler file. This includes all
9223 pending extern declarations and DEX expressions. */
9224
9225 static void
9226 unicosmk_file_end (void)
9227 {
9228 fputs ("\t.endp\n\n", asm_out_file);
9229
9230 /* Output all pending externs. */
9231
9232 unicosmk_output_externs (asm_out_file);
9233
9234 /* Output dex definitions used for functions whose names conflict with
9235 register names. */
9236
9237 unicosmk_output_dex (asm_out_file);
9238
9239 fputs ("\t.end\t", asm_out_file);
9240 unicosmk_output_module_name (asm_out_file);
9241 putc ('\n', asm_out_file);
9242 }
9243
9244 #else
9245
9246 static void
9247 unicosmk_output_deferred_case_vectors (FILE *file ATTRIBUTE_UNUSED)
9248 {}
9249
9250 static void
9251 unicosmk_gen_dsib (unsigned long *imaskP ATTRIBUTE_UNUSED)
9252 {}
9253
9254 static void
9255 unicosmk_output_ssib (FILE * file ATTRIBUTE_UNUSED,
9256 const char * fnname ATTRIBUTE_UNUSED)
9257 {}
9258
9259 rtx
9260 unicosmk_add_call_info_word (rtx x ATTRIBUTE_UNUSED)
9261 {
9262 return NULL_RTX;
9263 }
9264
9265 static int
9266 unicosmk_need_dex (rtx x ATTRIBUTE_UNUSED)
9267 {
9268 return 0;
9269 }
9270
9271 #endif /* TARGET_ABI_UNICOSMK */
9272
9273 static void
9274 alpha_init_libfuncs (void)
9275 {
9276 if (TARGET_ABI_UNICOSMK)
9277 {
9278 /* Prevent gcc from generating calls to __divsi3. */
9279 set_optab_libfunc (sdiv_optab, SImode, 0);
9280 set_optab_libfunc (udiv_optab, SImode, 0);
9281
9282 /* Use the functions provided by the system library
9283 for DImode integer division. */
9284 set_optab_libfunc (sdiv_optab, DImode, "$sldiv");
9285 set_optab_libfunc (udiv_optab, DImode, "$uldiv");
9286 }
9287 else if (TARGET_ABI_OPEN_VMS)
9288 {
9289 /* Use the VMS runtime library functions for division and
9290 remainder. */
9291 set_optab_libfunc (sdiv_optab, SImode, "OTS$DIV_I");
9292 set_optab_libfunc (sdiv_optab, DImode, "OTS$DIV_L");
9293 set_optab_libfunc (udiv_optab, SImode, "OTS$DIV_UI");
9294 set_optab_libfunc (udiv_optab, DImode, "OTS$DIV_UL");
9295 set_optab_libfunc (smod_optab, SImode, "OTS$REM_I");
9296 set_optab_libfunc (smod_optab, DImode, "OTS$REM_L");
9297 set_optab_libfunc (umod_optab, SImode, "OTS$REM_UI");
9298 set_optab_libfunc (umod_optab, DImode, "OTS$REM_UL");
9299 }
9300 }
9301
9302 \f
9303 /* Initialize the GCC target structure. */
9304 #if TARGET_ABI_OPEN_VMS
9305 # undef TARGET_ATTRIBUTE_TABLE
9306 # define TARGET_ATTRIBUTE_TABLE vms_attribute_table
9307 # undef TARGET_SECTION_TYPE_FLAGS
9308 # define TARGET_SECTION_TYPE_FLAGS vms_section_type_flags
9309 #endif
9310
9311 #undef TARGET_IN_SMALL_DATA_P
9312 #define TARGET_IN_SMALL_DATA_P alpha_in_small_data_p
9313
9314 #if TARGET_ABI_UNICOSMK
9315 # undef TARGET_INSERT_ATTRIBUTES
9316 # define TARGET_INSERT_ATTRIBUTES unicosmk_insert_attributes
9317 # undef TARGET_SECTION_TYPE_FLAGS
9318 # define TARGET_SECTION_TYPE_FLAGS unicosmk_section_type_flags
9319 # undef TARGET_ASM_UNIQUE_SECTION
9320 # define TARGET_ASM_UNIQUE_SECTION unicosmk_unique_section
9321 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
9322 #define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
9323 # undef TARGET_ASM_GLOBALIZE_LABEL
9324 # define TARGET_ASM_GLOBALIZE_LABEL hook_void_FILEptr_constcharptr
9325 # undef TARGET_MUST_PASS_IN_STACK
9326 # define TARGET_MUST_PASS_IN_STACK unicosmk_must_pass_in_stack
9327 #endif
9328
9329 #undef TARGET_ASM_ALIGNED_HI_OP
9330 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
9331 #undef TARGET_ASM_ALIGNED_DI_OP
9332 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
9333
9334 /* Default unaligned ops are provided for ELF systems. To get unaligned
9335 data for non-ELF systems, we have to turn off auto alignment. */
9336 #ifndef OBJECT_FORMAT_ELF
9337 #undef TARGET_ASM_UNALIGNED_HI_OP
9338 #define TARGET_ASM_UNALIGNED_HI_OP "\t.align 0\n\t.word\t"
9339 #undef TARGET_ASM_UNALIGNED_SI_OP
9340 #define TARGET_ASM_UNALIGNED_SI_OP "\t.align 0\n\t.long\t"
9341 #undef TARGET_ASM_UNALIGNED_DI_OP
9342 #define TARGET_ASM_UNALIGNED_DI_OP "\t.align 0\n\t.quad\t"
9343 #endif
9344
9345 #ifdef OBJECT_FORMAT_ELF
9346 #undef TARGET_ASM_SELECT_RTX_SECTION
9347 #define TARGET_ASM_SELECT_RTX_SECTION alpha_elf_select_rtx_section
9348 #endif
9349
9350 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
9351 #define TARGET_ASM_FUNCTION_END_PROLOGUE alpha_output_function_end_prologue
9352
9353 #undef TARGET_INIT_LIBFUNCS
9354 #define TARGET_INIT_LIBFUNCS alpha_init_libfuncs
9355
9356 #if TARGET_ABI_UNICOSMK
9357 #undef TARGET_ASM_FILE_START
9358 #define TARGET_ASM_FILE_START unicosmk_file_start
9359 #undef TARGET_ASM_FILE_END
9360 #define TARGET_ASM_FILE_END unicosmk_file_end
9361 #else
9362 #undef TARGET_ASM_FILE_START
9363 #define TARGET_ASM_FILE_START alpha_file_start
9364 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
9365 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
9366 #endif
9367
9368 #undef TARGET_SCHED_ADJUST_COST
9369 #define TARGET_SCHED_ADJUST_COST alpha_adjust_cost
9370 #undef TARGET_SCHED_ISSUE_RATE
9371 #define TARGET_SCHED_ISSUE_RATE alpha_issue_rate
9372 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
9373 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
9374 alpha_multipass_dfa_lookahead
9375
9376 #undef TARGET_HAVE_TLS
9377 #define TARGET_HAVE_TLS HAVE_AS_TLS
9378
9379 #undef TARGET_INIT_BUILTINS
9380 #define TARGET_INIT_BUILTINS alpha_init_builtins
9381 #undef TARGET_EXPAND_BUILTIN
9382 #define TARGET_EXPAND_BUILTIN alpha_expand_builtin
9383
9384 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
9385 #define TARGET_FUNCTION_OK_FOR_SIBCALL alpha_function_ok_for_sibcall
9386 #undef TARGET_CANNOT_COPY_INSN_P
9387 #define TARGET_CANNOT_COPY_INSN_P alpha_cannot_copy_insn_p
9388 #undef TARGET_CANNOT_FORCE_CONST_MEM
9389 #define TARGET_CANNOT_FORCE_CONST_MEM alpha_cannot_force_const_mem
9390
9391 #if TARGET_ABI_OSF
9392 #undef TARGET_ASM_OUTPUT_MI_THUNK
9393 #define TARGET_ASM_OUTPUT_MI_THUNK alpha_output_mi_thunk_osf
9394 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
9395 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
9396 #endif
9397
9398 #undef TARGET_RTX_COSTS
9399 #define TARGET_RTX_COSTS alpha_rtx_costs
9400 #undef TARGET_ADDRESS_COST
9401 #define TARGET_ADDRESS_COST hook_int_rtx_0
9402
9403 #undef TARGET_MACHINE_DEPENDENT_REORG
9404 #define TARGET_MACHINE_DEPENDENT_REORG alpha_reorg
9405
9406 #undef TARGET_PROMOTE_FUNCTION_ARGS
9407 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
9408 #undef TARGET_PROMOTE_FUNCTION_RETURN
9409 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
9410 #undef TARGET_PROMOTE_PROTOTYPES
9411 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_false
9412 #undef TARGET_RETURN_IN_MEMORY
9413 #define TARGET_RETURN_IN_MEMORY alpha_return_in_memory
9414 #undef TARGET_PASS_BY_REFERENCE
9415 #define TARGET_PASS_BY_REFERENCE alpha_pass_by_reference
9416 #undef TARGET_SETUP_INCOMING_VARARGS
9417 #define TARGET_SETUP_INCOMING_VARARGS alpha_setup_incoming_varargs
9418 #undef TARGET_STRICT_ARGUMENT_NAMING
9419 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
9420 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
9421 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
9422 #undef TARGET_SPLIT_COMPLEX_ARG
9423 #define TARGET_SPLIT_COMPLEX_ARG alpha_split_complex_arg
9424 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
9425 #define TARGET_GIMPLIFY_VA_ARG_EXPR alpha_gimplify_va_arg
9426
9427 #undef TARGET_SCALAR_MODE_SUPPORTED_P
9428 #define TARGET_SCALAR_MODE_SUPPORTED_P alpha_scalar_mode_supported_p
9429 #undef TARGET_VECTOR_MODE_SUPPORTED_P
9430 #define TARGET_VECTOR_MODE_SUPPORTED_P alpha_vector_mode_supported_p
9431
9432 #undef TARGET_BUILD_BUILTIN_VA_LIST
9433 #define TARGET_BUILD_BUILTIN_VA_LIST alpha_build_builtin_va_list
9434
9435 #undef TARGET_VECTORIZE_MISALIGNED_MEM_OK
9436 #define TARGET_VECTORIZE_MISALIGNED_MEM_OK alpha_vector_mode_supported_p
9437
9438 struct gcc_target targetm = TARGET_INITIALIZER;
9439
9440 \f
9441 #include "gt-alpha.h"