2004-08-23 Eric Christopher <echristo@redhat.com>
[official-gcc.git] / gcc / config / alpha / alpha.c
bloba92adeb5de3d9f189da67a401fad4c134f666556
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)
6 This file is part of GCC.
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.
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.
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. */
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"
57 /* Specify which cpu to schedule for. */
59 enum processor_type alpha_cpu;
60 static const char * const alpha_cpu_name[] =
62 "ev4", "ev5", "ev6"
65 /* Specify how accurate floating-point traps need to be. */
67 enum alpha_trap_precision alpha_tp;
69 /* Specify the floating-point rounding mode. */
71 enum alpha_fp_rounding_mode alpha_fprm;
73 /* Specify which things cause traps. */
75 enum alpha_fp_trap_mode alpha_fptm;
77 /* Specify bit size of immediate TLS offsets. */
79 int alpha_tls_size = 32;
81 /* Strings decoded into the above options. */
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] */
91 /* Save information from a "cmpxx" operation until the branch or scc is
92 emitted. */
94 struct alpha_compare alpha_compare;
96 /* Nonzero if inside of a function, because the Alpha asm can't
97 handle .files inside of functions. */
99 static int inside_function = FALSE;
101 /* The number of cycles of latency we should assume on memory reads. */
103 int alpha_memory_latency = 3;
105 /* Whether the function needs the GP. */
107 static int alpha_function_needs_gp;
109 /* The alias set for prologue/epilogue register save/restore. */
111 static GTY(()) int alpha_sr_alias_set;
113 /* The assembler name of the current function. */
115 static const char *alpha_fnname;
117 /* The next explicit relocation sequence number. */
118 extern GTY(()) int alpha_next_sequence_number;
119 int alpha_next_sequence_number = 1;
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;
128 /* Costs of various operations on the different architectures. */
130 struct alpha_rtx_cost_data
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;
143 static struct alpha_rtx_cost_data const alpha_rtx_cost_data[PROCESSOR_MAX] =
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 */
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 */
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 */
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. */
185 static struct alpha_rtx_cost_data const alpha_rtx_cost_size =
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 */
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
205 #define REG_PV 27
206 #define REG_RA 26
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);
212 #if TARGET_ABI_OPEN_VMS
213 static void alpha_write_linkage (FILE *, const char *, tree);
214 #endif
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);
221 /* Parse target option strings. */
223 void
224 override_options (void)
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 }
251 /* Unicos/Mk doesn't have shared libraries. */
252 if (TARGET_ABI_UNICOSMK && flag_pic)
254 warning ("-f%s ignored for Unicos/Mk (not supported)",
255 (flag_pic > 1) ? "PIC" : "pic");
256 flag_pic = 0;
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;
266 alpha_tp = ALPHA_TP_PROG;
267 alpha_fptm = ALPHA_FPTM_N;
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. */
275 if (TARGET_IEEE)
277 if (TARGET_ABI_UNICOSMK)
278 warning ("-mieee not supported on Unicos/Mk");
279 else
281 alpha_tp = ALPHA_TP_INSN;
282 alpha_fptm = ALPHA_FPTM_SU;
286 if (TARGET_IEEE_WITH_INEXACT)
288 if (TARGET_ABI_UNICOSMK)
289 warning ("-mieee-with-inexact not supported on Unicos/Mk");
290 else
292 alpha_tp = ALPHA_TP_INSN;
293 alpha_fptm = ALPHA_FPTM_SUI;
297 if (alpha_tp_string)
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);
309 if (alpha_fprm_string)
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);
324 if (alpha_fptm_string)
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);
338 if (alpha_tls_size_string)
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);
350 alpha_cpu
351 = TARGET_CPU_DEFAULT & MASK_CPU_EV6 ? PROCESSOR_EV6
352 : (TARGET_CPU_DEFAULT & MASK_CPU_EV5 ? PROCESSOR_EV5 : PROCESSOR_EV4);
354 if (alpha_cpu_string)
356 for (i = 0; cpu_table [i].name; i++)
357 if (! strcmp (alpha_cpu_string, cpu_table [i].name))
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;
365 if (! cpu_table [i].name)
366 error ("bad value `%s' for -mcpu switch", alpha_cpu_string);
369 if (alpha_tune_string)
371 for (i = 0; cpu_table [i].name; i++)
372 if (! strcmp (alpha_tune_string, cpu_table [i].name))
374 alpha_cpu = cpu_table [i].processor;
375 break;
377 if (! cpu_table [i].name)
378 error ("bad value `%s' for -mcpu switch", alpha_tune_string);
381 /* Do some sanity checks on the above options. */
383 if (TARGET_ABI_UNICOSMK && alpha_fptm != ALPHA_FPTM_N)
385 warning ("trap mode not supported on Unicos/Mk");
386 alpha_fptm = ALPHA_FPTM_N;
389 if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI)
390 && alpha_tp != ALPHA_TP_INSN && ! TARGET_CPU_EV6)
392 warning ("fp software completion requires -mtrap-precision=i");
393 alpha_tp = ALPHA_TP_INSN;
396 if (TARGET_CPU_EV6)
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;
404 if (TARGET_FLOAT_VAX)
406 if (alpha_fprm == ALPHA_FPRM_MINF || alpha_fprm == ALPHA_FPRM_DYN)
408 warning ("rounding mode not supported for VAX floats");
409 alpha_fprm = ALPHA_FPRM_NORM;
411 if (alpha_fptm == ALPHA_FPTM_SUI)
413 warning ("trap mode not supported for VAX floats");
414 alpha_fptm = ALPHA_FPTM_SU;
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;
422 char *end;
423 int lat;
425 if (!alpha_mlat_string)
426 alpha_mlat_string = "L1";
428 if (ISDIGIT ((unsigned char)alpha_mlat_string[0])
429 && (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0'))
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')
435 static int const cache_latency[][4] =
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. */
442 lat = alpha_mlat_string[1] - '0';
443 if (lat <= 0 || lat > 3 || cache_latency[alpha_cpu][lat-1] == -1)
445 warning ("L%d cache latency unknown for %s",
446 lat, alpha_cpu_name[alpha_cpu]);
447 lat = 3;
449 else
450 lat = cache_latency[alpha_cpu][lat-1];
452 else if (! strcmp (alpha_mlat_string, "main"))
454 /* Most current memories have about 370ns latency. This is
455 a reasonable guess for a fast cpu. */
456 lat = 150;
458 else
460 warning ("bad value `%s' for -mmemory-latency", alpha_mlat_string);
461 lat = 3;
464 alpha_memory_latency = lat;
467 /* Default the definition of "small data" to 8 bytes. */
468 if (!g_switch_set)
469 g_switch_value = 8;
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;
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)
482 if (align_loops <= 0)
483 align_loops = 16;
484 if (align_jumps <= 0)
485 align_jumps = 16;
487 if (align_functions <= 0)
488 align_functions = 16;
490 /* Acquire a unique set number for our register saves and restores. */
491 alpha_sr_alias_set = new_alias_set ();
493 /* Register variables and functions with the garbage collector. */
495 /* Set up function hooks. */
496 init_machine_status = alpha_init_machine_status;
498 /* Tell the compiler when we're using VAX floating point. */
499 if (TARGET_FLOAT_VAX)
501 REAL_MODE_FORMAT (SFmode) = &vax_f_format;
502 REAL_MODE_FORMAT (DFmode) = &vax_g_format;
503 REAL_MODE_FORMAT (TFmode) = NULL;
507 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
510 zap_mask (HOST_WIDE_INT value)
512 int i;
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;
519 return 1;
522 /* Return true if OP is valid for a particular TLS relocation.
523 We are already guaranteed that OP is a CONST. */
526 tls_symbolic_operand_1 (rtx op, int size, int unspec)
528 op = XEXP (op, 0);
530 if (GET_CODE (op) != UNSPEC || XINT (op, 1) != unspec)
531 return 0;
532 op = XVECEXP (op, 0, 0);
534 if (GET_CODE (op) != SYMBOL_REF)
535 return 0;
537 if (SYMBOL_REF_LOCAL_P (op))
539 if (alpha_tls_size > size)
540 return 0;
542 else
544 if (size != 64)
545 return 0;
548 switch (SYMBOL_REF_TLS_MODEL (op))
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 ();
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. */
565 resolve_reload_operand (rtx op)
567 if (reload_in_progress)
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)
575 op = reg_equiv_memory_loc[REGNO (tmp)];
576 if (op == 0)
577 return 0;
580 return op;
583 /* Implements CONST_OK_FOR_LETTER_P. Return true if the value matches
584 the range defined for C in [I-P]. */
586 bool
587 alpha_const_ok_for_letter_p (HOST_WIDE_INT value, int c)
589 switch (c)
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;
617 default:
618 return false;
622 /* Implements CONST_DOUBLE_OK_FOR_LETTER_P. Return true if VALUE
623 matches for C in [GH]. */
625 bool
626 alpha_const_double_ok_for_letter_p (rtx value, int c)
628 switch (c)
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)));
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)));
641 default:
642 return false;
646 /* Implements CONST_DOUBLE_OK_FOR_LETTER_P. Return true if VALUE
647 matches for C. */
649 bool
650 alpha_extra_constraint (rtx value, int c)
652 switch (c)
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;
673 /* Implements target hook vector_mode_supported_p. */
674 static bool
675 alpha_vector_mode_supported_p (enum machine_mode mode)
677 if (TARGET_MAX
678 && ((mode == V8QImode)
679 || (mode == V4HImode)
680 || (mode == V2SImode)))
681 return true;
683 return false;
686 /* Return 1 if this function can directly return via $26. */
689 direct_return (void)
691 return (! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK
692 && reload_completed
693 && alpha_sa_size () == 0
694 && get_frame_size () == 0
695 && current_function_outgoing_args_size == 0
696 && current_function_pretend_args_size == 0);
699 /* Return the ADDR_VEC associated with a tablejump insn. */
702 alpha_tablejump_addr_vec (rtx insn)
704 rtx tmp;
706 tmp = JUMP_LABEL (insn);
707 if (!tmp)
708 return NULL_RTX;
709 tmp = NEXT_INSN (tmp);
710 if (!tmp)
711 return NULL_RTX;
712 if (GET_CODE (tmp) == JUMP_INSN
713 && GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC)
714 return PATTERN (tmp);
715 return NULL_RTX;
718 /* Return the label of the predicted edge, or CONST0_RTX if we don't know. */
721 alpha_tablejump_best_label (rtx insn)
723 rtx jump_table = alpha_tablejump_addr_vec (insn);
724 rtx best_label = NULL_RTX;
726 /* ??? Once the CFG doesn't keep getting completely rebuilt, look
727 there for edge frequency counts from profile data. */
729 if (jump_table)
731 int n_labels = XVECLEN (jump_table, 1);
732 int best_count = -1;
733 int i, j;
735 for (i = 0; i < n_labels; i++)
737 int count = 1;
739 for (j = i + 1; j < n_labels; j++)
740 if (XEXP (XVECEXP (jump_table, 1, i), 0)
741 == XEXP (XVECEXP (jump_table, 1, j), 0))
742 count++;
744 if (count > best_count)
745 best_count = count, best_label = XVECEXP (jump_table, 1, i);
749 return best_label ? best_label : const0_rtx;
752 /* Return the TLS model to use for SYMBOL. */
754 static enum tls_model
755 tls_symbolic_operand_type (rtx symbol)
757 enum tls_model model;
759 if (GET_CODE (symbol) != SYMBOL_REF)
760 return 0;
761 model = SYMBOL_REF_TLS_MODEL (symbol);
763 /* Local-exec with a 64-bit size is the same code as initial-exec. */
764 if (model == TLS_MODEL_LOCAL_EXEC && alpha_tls_size == 64)
765 model = TLS_MODEL_INITIAL_EXEC;
767 return model;
770 /* Return true if the function DECL will share the same GP as any
771 function in the current unit of translation. */
773 static bool
774 decl_has_samegp (tree decl)
776 /* Functions that are not local can be overridden, and thus may
777 not share the same gp. */
778 if (!(*targetm.binds_local_p) (decl))
779 return false;
781 /* If -msmall-data is in effect, assume that there is only one GP
782 for the module, and so any local symbol has this property. We
783 need explicit relocations to be able to enforce this for symbols
784 not defined in this unit of translation, however. */
785 if (TARGET_EXPLICIT_RELOCS && TARGET_SMALL_DATA)
786 return true;
788 /* Functions that are not external are defined in this UoT. */
789 /* ??? Irritatingly, static functions not yet emitted are still
790 marked "external". Apply this to non-static functions only. */
791 return !TREE_PUBLIC (decl) || !DECL_EXTERNAL (decl);
794 /* Return true if EXP should be placed in the small data section. */
796 static bool
797 alpha_in_small_data_p (tree exp)
799 /* We want to merge strings, so we never consider them small data. */
800 if (TREE_CODE (exp) == STRING_CST)
801 return false;
803 /* Functions are never in the small data area. Duh. */
804 if (TREE_CODE (exp) == FUNCTION_DECL)
805 return false;
807 if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
809 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
810 if (strcmp (section, ".sdata") == 0
811 || strcmp (section, ".sbss") == 0)
812 return true;
814 else
816 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
818 /* If this is an incomplete type with size 0, then we can't put it
819 in sdata because it might be too big when completed. */
820 if (size > 0 && (unsigned HOST_WIDE_INT) size <= g_switch_value)
821 return true;
824 return false;
827 #if TARGET_ABI_OPEN_VMS
828 static bool
829 alpha_linkage_symbol_p (const char *symname)
831 int symlen = strlen (symname);
833 if (symlen > 4)
834 return strcmp (&symname [symlen - 4], "..lk") == 0;
836 return false;
839 #define LINKAGE_SYMBOL_REF_P(X) \
840 ((GET_CODE (X) == SYMBOL_REF \
841 && alpha_linkage_symbol_p (XSTR (X, 0))) \
842 || (GET_CODE (X) == CONST \
843 && GET_CODE (XEXP (X, 0)) == PLUS \
844 && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF \
845 && alpha_linkage_symbol_p (XSTR (XEXP (XEXP (X, 0), 0), 0))))
846 #endif
848 /* legitimate_address_p recognizes an RTL expression that is a valid
849 memory address for an instruction. The MODE argument is the
850 machine mode for the MEM expression that wants to use this address.
852 For Alpha, we have either a constant address or the sum of a
853 register and a constant address, or just a register. For DImode,
854 any of those forms can be surrounded with an AND that clear the
855 low-order three bits; this is an "unaligned" access. */
857 bool
858 alpha_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
860 /* If this is an ldq_u type address, discard the outer AND. */
861 if (mode == DImode
862 && GET_CODE (x) == AND
863 && GET_CODE (XEXP (x, 1)) == CONST_INT
864 && INTVAL (XEXP (x, 1)) == -8)
865 x = XEXP (x, 0);
867 /* Discard non-paradoxical subregs. */
868 if (GET_CODE (x) == SUBREG
869 && (GET_MODE_SIZE (GET_MODE (x))
870 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
871 x = SUBREG_REG (x);
873 /* Unadorned general registers are valid. */
874 if (REG_P (x)
875 && (strict
876 ? STRICT_REG_OK_FOR_BASE_P (x)
877 : NONSTRICT_REG_OK_FOR_BASE_P (x)))
878 return true;
880 /* Constant addresses (i.e. +/- 32k) are valid. */
881 if (CONSTANT_ADDRESS_P (x))
882 return true;
884 #if TARGET_ABI_OPEN_VMS
885 if (LINKAGE_SYMBOL_REF_P (x))
886 return true;
887 #endif
889 /* Register plus a small constant offset is valid. */
890 if (GET_CODE (x) == PLUS)
892 rtx ofs = XEXP (x, 1);
893 x = XEXP (x, 0);
895 /* Discard non-paradoxical subregs. */
896 if (GET_CODE (x) == SUBREG
897 && (GET_MODE_SIZE (GET_MODE (x))
898 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
899 x = SUBREG_REG (x);
901 if (REG_P (x))
903 if (! strict
904 && NONSTRICT_REG_OK_FP_BASE_P (x)
905 && GET_CODE (ofs) == CONST_INT)
906 return true;
907 if ((strict
908 ? STRICT_REG_OK_FOR_BASE_P (x)
909 : NONSTRICT_REG_OK_FOR_BASE_P (x))
910 && CONSTANT_ADDRESS_P (ofs))
911 return true;
915 /* If we're managing explicit relocations, LO_SUM is valid, as
916 are small data symbols. */
917 else if (TARGET_EXPLICIT_RELOCS)
919 if (small_symbolic_operand (x, Pmode))
920 return true;
922 if (GET_CODE (x) == LO_SUM)
924 rtx ofs = XEXP (x, 1);
925 x = XEXP (x, 0);
927 /* Discard non-paradoxical subregs. */
928 if (GET_CODE (x) == SUBREG
929 && (GET_MODE_SIZE (GET_MODE (x))
930 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
931 x = SUBREG_REG (x);
933 /* Must have a valid base register. */
934 if (! (REG_P (x)
935 && (strict
936 ? STRICT_REG_OK_FOR_BASE_P (x)
937 : NONSTRICT_REG_OK_FOR_BASE_P (x))))
938 return false;
940 /* The symbol must be local. */
941 if (local_symbolic_operand (ofs, Pmode)
942 || dtp32_symbolic_operand (ofs, Pmode)
943 || tp32_symbolic_operand (ofs, Pmode))
944 return true;
948 return false;
951 /* Build the SYMBOL_REF for __tls_get_addr. */
953 static GTY(()) rtx tls_get_addr_libfunc;
955 static rtx
956 get_tls_get_addr (void)
958 if (!tls_get_addr_libfunc)
959 tls_get_addr_libfunc = init_one_libfunc ("__tls_get_addr");
960 return tls_get_addr_libfunc;
963 /* Try machine-dependent ways of modifying an illegitimate address
964 to be legitimate. If we find one, return the new, valid address. */
967 alpha_legitimize_address (rtx x, rtx scratch,
968 enum machine_mode mode ATTRIBUTE_UNUSED)
970 HOST_WIDE_INT addend;
972 /* If the address is (plus reg const_int) and the CONST_INT is not a
973 valid offset, compute the high part of the constant and add it to
974 the register. Then our address is (plus temp low-part-const). */
975 if (GET_CODE (x) == PLUS
976 && GET_CODE (XEXP (x, 0)) == REG
977 && GET_CODE (XEXP (x, 1)) == CONST_INT
978 && ! CONSTANT_ADDRESS_P (XEXP (x, 1)))
980 addend = INTVAL (XEXP (x, 1));
981 x = XEXP (x, 0);
982 goto split_addend;
985 /* If the address is (const (plus FOO const_int)), find the low-order
986 part of the CONST_INT. Then load FOO plus any high-order part of the
987 CONST_INT into a register. Our address is (plus reg low-part-const).
988 This is done to reduce the number of GOT entries. */
989 if (!no_new_pseudos
990 && GET_CODE (x) == CONST
991 && GET_CODE (XEXP (x, 0)) == PLUS
992 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
994 addend = INTVAL (XEXP (XEXP (x, 0), 1));
995 x = force_reg (Pmode, XEXP (XEXP (x, 0), 0));
996 goto split_addend;
999 /* If we have a (plus reg const), emit the load as in (2), then add
1000 the two registers, and finally generate (plus reg low-part-const) as
1001 our address. */
1002 if (!no_new_pseudos
1003 && GET_CODE (x) == PLUS
1004 && GET_CODE (XEXP (x, 0)) == REG
1005 && GET_CODE (XEXP (x, 1)) == CONST
1006 && GET_CODE (XEXP (XEXP (x, 1), 0)) == PLUS
1007 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == CONST_INT)
1009 addend = INTVAL (XEXP (XEXP (XEXP (x, 1), 0), 1));
1010 x = expand_simple_binop (Pmode, PLUS, XEXP (x, 0),
1011 XEXP (XEXP (XEXP (x, 1), 0), 0),
1012 NULL_RTX, 1, OPTAB_LIB_WIDEN);
1013 goto split_addend;
1016 /* If this is a local symbol, split the address into HIGH/LO_SUM parts. */
1017 if (TARGET_EXPLICIT_RELOCS && symbolic_operand (x, Pmode))
1019 rtx r0, r16, eqv, tga, tp, insn, dest, seq;
1021 switch (tls_symbolic_operand_type (x))
1023 case TLS_MODEL_GLOBAL_DYNAMIC:
1024 start_sequence ();
1026 r0 = gen_rtx_REG (Pmode, 0);
1027 r16 = gen_rtx_REG (Pmode, 16);
1028 tga = get_tls_get_addr ();
1029 dest = gen_reg_rtx (Pmode);
1030 seq = GEN_INT (alpha_next_sequence_number++);
1032 emit_insn (gen_movdi_er_tlsgd (r16, pic_offset_table_rtx, x, seq));
1033 insn = gen_call_value_osf_tlsgd (r0, tga, seq);
1034 insn = emit_call_insn (insn);
1035 CONST_OR_PURE_CALL_P (insn) = 1;
1036 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16);
1038 insn = get_insns ();
1039 end_sequence ();
1041 emit_libcall_block (insn, dest, r0, x);
1042 return dest;
1044 case TLS_MODEL_LOCAL_DYNAMIC:
1045 start_sequence ();
1047 r0 = gen_rtx_REG (Pmode, 0);
1048 r16 = gen_rtx_REG (Pmode, 16);
1049 tga = get_tls_get_addr ();
1050 scratch = gen_reg_rtx (Pmode);
1051 seq = GEN_INT (alpha_next_sequence_number++);
1053 emit_insn (gen_movdi_er_tlsldm (r16, pic_offset_table_rtx, seq));
1054 insn = gen_call_value_osf_tlsldm (r0, tga, seq);
1055 insn = emit_call_insn (insn);
1056 CONST_OR_PURE_CALL_P (insn) = 1;
1057 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16);
1059 insn = get_insns ();
1060 end_sequence ();
1062 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
1063 UNSPEC_TLSLDM_CALL);
1064 emit_libcall_block (insn, scratch, r0, eqv);
1066 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPREL);
1067 eqv = gen_rtx_CONST (Pmode, eqv);
1069 if (alpha_tls_size == 64)
1071 dest = gen_reg_rtx (Pmode);
1072 emit_insn (gen_rtx_SET (VOIDmode, dest, eqv));
1073 emit_insn (gen_adddi3 (dest, dest, scratch));
1074 return dest;
1076 if (alpha_tls_size == 32)
1078 insn = gen_rtx_HIGH (Pmode, eqv);
1079 insn = gen_rtx_PLUS (Pmode, scratch, insn);
1080 scratch = gen_reg_rtx (Pmode);
1081 emit_insn (gen_rtx_SET (VOIDmode, scratch, insn));
1083 return gen_rtx_LO_SUM (Pmode, scratch, eqv);
1085 case TLS_MODEL_INITIAL_EXEC:
1086 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_TPREL);
1087 eqv = gen_rtx_CONST (Pmode, eqv);
1088 tp = gen_reg_rtx (Pmode);
1089 scratch = gen_reg_rtx (Pmode);
1090 dest = gen_reg_rtx (Pmode);
1092 emit_insn (gen_load_tp (tp));
1093 emit_insn (gen_rtx_SET (VOIDmode, scratch, eqv));
1094 emit_insn (gen_adddi3 (dest, tp, scratch));
1095 return dest;
1097 case TLS_MODEL_LOCAL_EXEC:
1098 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_TPREL);
1099 eqv = gen_rtx_CONST (Pmode, eqv);
1100 tp = gen_reg_rtx (Pmode);
1102 emit_insn (gen_load_tp (tp));
1103 if (alpha_tls_size == 32)
1105 insn = gen_rtx_HIGH (Pmode, eqv);
1106 insn = gen_rtx_PLUS (Pmode, tp, insn);
1107 tp = gen_reg_rtx (Pmode);
1108 emit_insn (gen_rtx_SET (VOIDmode, tp, insn));
1110 return gen_rtx_LO_SUM (Pmode, tp, eqv);
1113 if (local_symbolic_operand (x, Pmode))
1115 if (small_symbolic_operand (x, Pmode))
1116 return x;
1117 else
1119 if (!no_new_pseudos)
1120 scratch = gen_reg_rtx (Pmode);
1121 emit_insn (gen_rtx_SET (VOIDmode, scratch,
1122 gen_rtx_HIGH (Pmode, x)));
1123 return gen_rtx_LO_SUM (Pmode, scratch, x);
1128 return NULL;
1130 split_addend:
1132 HOST_WIDE_INT low, high;
1134 low = ((addend & 0xffff) ^ 0x8000) - 0x8000;
1135 addend -= low;
1136 high = ((addend & 0xffffffff) ^ 0x80000000) - 0x80000000;
1137 addend -= high;
1139 if (addend)
1140 x = expand_simple_binop (Pmode, PLUS, x, GEN_INT (addend),
1141 (no_new_pseudos ? scratch : NULL_RTX),
1142 1, OPTAB_LIB_WIDEN);
1143 if (high)
1144 x = expand_simple_binop (Pmode, PLUS, x, GEN_INT (high),
1145 (no_new_pseudos ? scratch : NULL_RTX),
1146 1, OPTAB_LIB_WIDEN);
1148 return plus_constant (x, low);
1152 /* We do not allow indirect calls to be optimized into sibling calls, nor
1153 can we allow a call to a function with a different GP to be optimized
1154 into a sibcall. */
1156 static bool
1157 alpha_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
1159 /* Can't do indirect tail calls, since we don't know if the target
1160 uses the same GP. */
1161 if (!decl)
1162 return false;
1164 /* Otherwise, we can make a tail call if the target function shares
1165 the same GP. */
1166 return decl_has_samegp (decl);
1169 /* For TARGET_EXPLICIT_RELOCS, we don't obfuscate a SYMBOL_REF to a
1170 small symbolic operand until after reload. At which point we need
1171 to replace (mem (symbol_ref)) with (mem (lo_sum $29 symbol_ref))
1172 so that sched2 has the proper dependency information. */
1174 {"some_small_symbolic_operand", {SET, PARALLEL, PREFETCH, UNSPEC, \
1175 UNSPEC_VOLATILE}},
1178 static int
1179 some_small_symbolic_operand_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
1181 rtx x = *px;
1183 /* Don't re-split. */
1184 if (GET_CODE (x) == LO_SUM)
1185 return -1;
1187 return small_symbolic_operand (x, Pmode) != 0;
1191 some_small_symbolic_operand (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
1193 return for_each_rtx (&x, some_small_symbolic_operand_1, NULL);
1196 static int
1197 split_small_symbolic_operand_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
1199 rtx x = *px;
1201 /* Don't re-split. */
1202 if (GET_CODE (x) == LO_SUM)
1203 return -1;
1205 if (small_symbolic_operand (x, Pmode))
1207 x = gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, x);
1208 *px = x;
1209 return -1;
1212 return 0;
1216 split_small_symbolic_operand (rtx x)
1218 x = copy_insn (x);
1219 for_each_rtx (&x, split_small_symbolic_operand_1, NULL);
1220 return x;
1223 /* Indicate that INSN cannot be duplicated. This is true for any insn
1224 that we've marked with gpdisp relocs, since those have to stay in
1225 1-1 correspondence with one another.
1227 Technically we could copy them if we could set up a mapping from one
1228 sequence number to another, across the set of insns to be duplicated.
1229 This seems overly complicated and error-prone since interblock motion
1230 from sched-ebb could move one of the pair of insns to a different block.
1232 Also cannot allow jsr insns to be duplicated. If they throw exceptions,
1233 then they'll be in a different block from their ldgp. Which could lead
1234 the bb reorder code to think that it would be ok to copy just the block
1235 containing the call and branch to the block containing the ldgp. */
1237 static bool
1238 alpha_cannot_copy_insn_p (rtx insn)
1240 if (!reload_completed || !TARGET_EXPLICIT_RELOCS)
1241 return false;
1242 if (recog_memoized (insn) >= 0)
1243 return get_attr_cannot_copy (insn);
1244 else
1245 return false;
1249 /* Try a machine-dependent way of reloading an illegitimate address
1250 operand. If we find one, push the reload and return the new rtx. */
1253 alpha_legitimize_reload_address (rtx x,
1254 enum machine_mode mode ATTRIBUTE_UNUSED,
1255 int opnum, int type,
1256 int ind_levels ATTRIBUTE_UNUSED)
1258 /* We must recognize output that we have already generated ourselves. */
1259 if (GET_CODE (x) == PLUS
1260 && GET_CODE (XEXP (x, 0)) == PLUS
1261 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
1262 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
1263 && GET_CODE (XEXP (x, 1)) == CONST_INT)
1265 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
1266 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
1267 opnum, type);
1268 return x;
1271 /* We wish to handle large displacements off a base register by
1272 splitting the addend across an ldah and the mem insn. This
1273 cuts number of extra insns needed from 3 to 1. */
1274 if (GET_CODE (x) == PLUS
1275 && GET_CODE (XEXP (x, 0)) == REG
1276 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
1277 && REGNO_OK_FOR_BASE_P (REGNO (XEXP (x, 0)))
1278 && GET_CODE (XEXP (x, 1)) == CONST_INT)
1280 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
1281 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1282 HOST_WIDE_INT high
1283 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
1285 /* Check for 32-bit overflow. */
1286 if (high + low != val)
1287 return NULL_RTX;
1289 /* Reload the high part into a base reg; leave the low part
1290 in the mem directly. */
1291 x = gen_rtx_PLUS (GET_MODE (x),
1292 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
1293 GEN_INT (high)),
1294 GEN_INT (low));
1296 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
1297 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
1298 opnum, type);
1299 return x;
1302 return NULL_RTX;
1305 /* Compute a (partial) cost for rtx X. Return true if the complete
1306 cost has been computed, and false if subexpressions should be
1307 scanned. In either case, *TOTAL contains the cost result. */
1309 static bool
1310 alpha_rtx_costs (rtx x, int code, int outer_code, int *total)
1312 enum machine_mode mode = GET_MODE (x);
1313 bool float_mode_p = FLOAT_MODE_P (mode);
1314 const struct alpha_rtx_cost_data *cost_data;
1316 if (optimize_size)
1317 cost_data = &alpha_rtx_cost_size;
1318 else
1319 cost_data = &alpha_rtx_cost_data[alpha_cpu];
1321 switch (code)
1323 case CONST_INT:
1324 /* If this is an 8-bit constant, return zero since it can be used
1325 nearly anywhere with no cost. If it is a valid operand for an
1326 ADD or AND, likewise return 0 if we know it will be used in that
1327 context. Otherwise, return 2 since it might be used there later.
1328 All other constants take at least two insns. */
1329 if (INTVAL (x) >= 0 && INTVAL (x) < 256)
1331 *total = 0;
1332 return true;
1334 /* FALLTHRU */
1336 case CONST_DOUBLE:
1337 if (x == CONST0_RTX (mode))
1338 *total = 0;
1339 else if ((outer_code == PLUS && add_operand (x, VOIDmode))
1340 || (outer_code == AND && and_operand (x, VOIDmode)))
1341 *total = 0;
1342 else if (add_operand (x, VOIDmode) || and_operand (x, VOIDmode))
1343 *total = 2;
1344 else
1345 *total = COSTS_N_INSNS (2);
1346 return true;
1348 case CONST:
1349 case SYMBOL_REF:
1350 case LABEL_REF:
1351 if (TARGET_EXPLICIT_RELOCS && small_symbolic_operand (x, VOIDmode))
1352 *total = COSTS_N_INSNS (outer_code != MEM);
1353 else if (TARGET_EXPLICIT_RELOCS && local_symbolic_operand (x, VOIDmode))
1354 *total = COSTS_N_INSNS (1 + (outer_code != MEM));
1355 else if (tls_symbolic_operand_type (x))
1356 /* Estimate of cost for call_pal rduniq. */
1357 /* ??? How many insns do we emit here? More than one... */
1358 *total = COSTS_N_INSNS (15);
1359 else
1360 /* Otherwise we do a load from the GOT. */
1361 *total = COSTS_N_INSNS (optimize_size ? 1 : alpha_memory_latency);
1362 return true;
1364 case PLUS:
1365 case MINUS:
1366 if (float_mode_p)
1367 *total = cost_data->fp_add;
1368 else if (GET_CODE (XEXP (x, 0)) == MULT
1369 && const48_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
1371 *total = (rtx_cost (XEXP (XEXP (x, 0), 0), outer_code)
1372 + rtx_cost (XEXP (x, 1), outer_code) + COSTS_N_INSNS (1));
1373 return true;
1375 return false;
1377 case MULT:
1378 if (float_mode_p)
1379 *total = cost_data->fp_mult;
1380 else if (mode == DImode)
1381 *total = cost_data->int_mult_di;
1382 else
1383 *total = cost_data->int_mult_si;
1384 return false;
1386 case ASHIFT:
1387 if (GET_CODE (XEXP (x, 1)) == CONST_INT
1388 && INTVAL (XEXP (x, 1)) <= 3)
1390 *total = COSTS_N_INSNS (1);
1391 return false;
1393 /* FALLTHRU */
1395 case ASHIFTRT:
1396 case LSHIFTRT:
1397 *total = cost_data->int_shift;
1398 return false;
1400 case IF_THEN_ELSE:
1401 if (float_mode_p)
1402 *total = cost_data->fp_add;
1403 else
1404 *total = cost_data->int_cmov;
1405 return false;
1407 case DIV:
1408 case UDIV:
1409 case MOD:
1410 case UMOD:
1411 if (!float_mode_p)
1412 *total = cost_data->int_div;
1413 else if (mode == SFmode)
1414 *total = cost_data->fp_div_sf;
1415 else
1416 *total = cost_data->fp_div_df;
1417 return false;
1419 case MEM:
1420 *total = COSTS_N_INSNS (optimize_size ? 1 : alpha_memory_latency);
1421 return true;
1423 case NEG:
1424 if (! float_mode_p)
1426 *total = COSTS_N_INSNS (1);
1427 return false;
1429 /* FALLTHRU */
1431 case ABS:
1432 if (! float_mode_p)
1434 *total = COSTS_N_INSNS (1) + cost_data->int_cmov;
1435 return false;
1437 /* FALLTHRU */
1439 case FLOAT:
1440 case UNSIGNED_FLOAT:
1441 case FIX:
1442 case UNSIGNED_FIX:
1443 case FLOAT_EXTEND:
1444 case FLOAT_TRUNCATE:
1445 *total = cost_data->fp_add;
1446 return false;
1448 default:
1449 return false;
1453 /* REF is an alignable memory location. Place an aligned SImode
1454 reference into *PALIGNED_MEM and the number of bits to shift into
1455 *PBITNUM. SCRATCH is a free register for use in reloading out
1456 of range stack slots. */
1458 void
1459 get_aligned_mem (rtx ref, rtx *paligned_mem, rtx *pbitnum)
1461 rtx base;
1462 HOST_WIDE_INT offset = 0;
1464 if (GET_CODE (ref) != MEM)
1465 abort ();
1467 if (reload_in_progress
1468 && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
1470 base = find_replacement (&XEXP (ref, 0));
1472 if (! memory_address_p (GET_MODE (ref), base))
1473 abort ();
1475 else
1477 base = XEXP (ref, 0);
1480 if (GET_CODE (base) == PLUS)
1481 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
1483 *paligned_mem
1484 = widen_memory_access (ref, SImode, (offset & ~3) - offset);
1486 if (WORDS_BIG_ENDIAN)
1487 *pbitnum = GEN_INT (32 - (GET_MODE_BITSIZE (GET_MODE (ref))
1488 + (offset & 3) * 8));
1489 else
1490 *pbitnum = GEN_INT ((offset & 3) * 8);
1493 /* Similar, but just get the address. Handle the two reload cases.
1494 Add EXTRA_OFFSET to the address we return. */
1497 get_unaligned_address (rtx ref, int extra_offset)
1499 rtx base;
1500 HOST_WIDE_INT offset = 0;
1502 if (GET_CODE (ref) != MEM)
1503 abort ();
1505 if (reload_in_progress
1506 && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
1508 base = find_replacement (&XEXP (ref, 0));
1510 if (! memory_address_p (GET_MODE (ref), base))
1511 abort ();
1513 else
1515 base = XEXP (ref, 0);
1518 if (GET_CODE (base) == PLUS)
1519 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
1521 return plus_constant (base, offset + extra_offset);
1524 /* On the Alpha, all (non-symbolic) constants except zero go into
1525 a floating-point register via memory. Note that we cannot
1526 return anything that is not a subset of CLASS, and that some
1527 symbolic constants cannot be dropped to memory. */
1529 enum reg_class
1530 alpha_preferred_reload_class(rtx x, enum reg_class class)
1532 /* Zero is present in any register class. */
1533 if (x == CONST0_RTX (GET_MODE (x)))
1534 return class;
1536 /* These sorts of constants we can easily drop to memory. */
1537 if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
1539 if (class == FLOAT_REGS)
1540 return NO_REGS;
1541 if (class == ALL_REGS)
1542 return GENERAL_REGS;
1543 return class;
1546 /* All other kinds of constants should not (and in the case of HIGH
1547 cannot) be dropped to memory -- instead we use a GENERAL_REGS
1548 secondary reload. */
1549 if (CONSTANT_P (x))
1550 return (class == ALL_REGS ? GENERAL_REGS : class);
1552 return class;
1555 /* Loading and storing HImode or QImode values to and from memory
1556 usually requires a scratch register. The exceptions are loading
1557 QImode and HImode from an aligned address to a general register
1558 unless byte instructions are permitted.
1560 We also cannot load an unaligned address or a paradoxical SUBREG
1561 into an FP register.
1563 We also cannot do integral arithmetic into FP regs, as might result
1564 from register elimination into a DImode fp register. */
1566 enum reg_class
1567 secondary_reload_class (enum reg_class class, enum machine_mode mode,
1568 rtx x, int in)
1570 if ((mode == QImode || mode == HImode) && ! TARGET_BWX)
1572 if (GET_CODE (x) == MEM
1573 || (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
1574 || (GET_CODE (x) == SUBREG
1575 && (GET_CODE (SUBREG_REG (x)) == MEM
1576 || (GET_CODE (SUBREG_REG (x)) == REG
1577 && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER))))
1579 if (!in || !aligned_memory_operand(x, mode))
1580 return GENERAL_REGS;
1584 if (class == FLOAT_REGS)
1586 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
1587 return GENERAL_REGS;
1589 if (GET_CODE (x) == SUBREG
1590 && (GET_MODE_SIZE (GET_MODE (x))
1591 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
1592 return GENERAL_REGS;
1594 if (in && INTEGRAL_MODE_P (mode)
1595 && ! (memory_operand (x, mode) || x == const0_rtx))
1596 return GENERAL_REGS;
1599 return NO_REGS;
1602 /* Subfunction of the following function. Update the flags of any MEM
1603 found in part of X. */
1605 static int
1606 alpha_set_memflags_1 (rtx *xp, void *data)
1608 rtx x = *xp, orig = (rtx) data;
1610 if (GET_CODE (x) != MEM)
1611 return 0;
1613 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (orig);
1614 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (orig);
1615 MEM_SCALAR_P (x) = MEM_SCALAR_P (orig);
1616 MEM_NOTRAP_P (x) = MEM_NOTRAP_P (orig);
1617 MEM_READONLY_P (x) = MEM_READONLY_P (orig);
1619 /* Sadly, we cannot use alias sets because the extra aliasing
1620 produced by the AND interferes. Given that two-byte quantities
1621 are the only thing we would be able to differentiate anyway,
1622 there does not seem to be any point in convoluting the early
1623 out of the alias check. */
1625 return -1;
1628 /* Given INSN, which is an INSN list or the PATTERN of a single insn
1629 generated to perform a memory operation, look for any MEMs in either
1630 a SET_DEST or a SET_SRC and copy the in-struct, unchanging, and
1631 volatile flags from REF into each of the MEMs found. If REF is not
1632 a MEM, don't do anything. */
1634 void
1635 alpha_set_memflags (rtx insn, rtx ref)
1637 rtx *base_ptr;
1639 if (GET_CODE (ref) != MEM)
1640 return;
1642 /* This is only called from alpha.md, after having had something
1643 generated from one of the insn patterns. So if everything is
1644 zero, the pattern is already up-to-date. */
1645 if (!MEM_VOLATILE_P (ref)
1646 && !MEM_IN_STRUCT_P (ref)
1647 && !MEM_SCALAR_P (ref)
1648 && !MEM_NOTRAP_P (ref)
1649 && !MEM_READONLY_P (ref))
1650 return;
1652 if (INSN_P (insn))
1653 base_ptr = &PATTERN (insn);
1654 else
1655 base_ptr = &insn;
1656 for_each_rtx (base_ptr, alpha_set_memflags_1, (void *) ref);
1659 /* Internal routine for alpha_emit_set_const to check for N or below insns. */
1661 static rtx
1662 alpha_emit_set_const_1 (rtx target, enum machine_mode mode,
1663 HOST_WIDE_INT c, int n)
1665 HOST_WIDE_INT new;
1666 int i, bits;
1667 /* Use a pseudo if highly optimizing and still generating RTL. */
1668 rtx subtarget
1669 = (flag_expensive_optimizations && !no_new_pseudos ? 0 : target);
1670 rtx temp, insn;
1672 /* If this is a sign-extended 32-bit constant, we can do this in at most
1673 three insns, so do it if we have enough insns left. We always have
1674 a sign-extended 32-bit constant when compiling on a narrow machine. */
1676 if (HOST_BITS_PER_WIDE_INT != 64
1677 || c >> 31 == -1 || c >> 31 == 0)
1679 HOST_WIDE_INT low = ((c & 0xffff) ^ 0x8000) - 0x8000;
1680 HOST_WIDE_INT tmp1 = c - low;
1681 HOST_WIDE_INT high = (((tmp1 >> 16) & 0xffff) ^ 0x8000) - 0x8000;
1682 HOST_WIDE_INT extra = 0;
1684 /* If HIGH will be interpreted as negative but the constant is
1685 positive, we must adjust it to do two ldha insns. */
1687 if ((high & 0x8000) != 0 && c >= 0)
1689 extra = 0x4000;
1690 tmp1 -= 0x40000000;
1691 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1694 if (c == low || (low == 0 && extra == 0))
1696 /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
1697 but that meant that we can't handle INT_MIN on 32-bit machines
1698 (like NT/Alpha), because we recurse indefinitely through
1699 emit_move_insn to gen_movdi. So instead, since we know exactly
1700 what we want, create it explicitly. */
1702 if (target == NULL)
1703 target = gen_reg_rtx (mode);
1704 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (c)));
1705 return target;
1707 else if (n >= 2 + (extra != 0))
1709 if (no_new_pseudos)
1711 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (high << 16)));
1712 temp = target;
1714 else
1715 temp = copy_to_suggested_reg (GEN_INT (high << 16),
1716 subtarget, mode);
1718 /* As of 2002-02-23, addsi3 is only available when not optimizing.
1719 This means that if we go through expand_binop, we'll try to
1720 generate extensions, etc, which will require new pseudos, which
1721 will fail during some split phases. The SImode add patterns
1722 still exist, but are not named. So build the insns by hand. */
1724 if (extra != 0)
1726 if (! subtarget)
1727 subtarget = gen_reg_rtx (mode);
1728 insn = gen_rtx_PLUS (mode, temp, GEN_INT (extra << 16));
1729 insn = gen_rtx_SET (VOIDmode, subtarget, insn);
1730 emit_insn (insn);
1731 temp = subtarget;
1734 if (target == NULL)
1735 target = gen_reg_rtx (mode);
1736 insn = gen_rtx_PLUS (mode, temp, GEN_INT (low));
1737 insn = gen_rtx_SET (VOIDmode, target, insn);
1738 emit_insn (insn);
1739 return target;
1743 /* If we couldn't do it that way, try some other methods. But if we have
1744 no instructions left, don't bother. Likewise, if this is SImode and
1745 we can't make pseudos, we can't do anything since the expand_binop
1746 and expand_unop calls will widen and try to make pseudos. */
1748 if (n == 1 || (mode == SImode && no_new_pseudos))
1749 return 0;
1751 /* Next, see if we can load a related constant and then shift and possibly
1752 negate it to get the constant we want. Try this once each increasing
1753 numbers of insns. */
1755 for (i = 1; i < n; i++)
1757 /* First, see if minus some low bits, we've an easy load of
1758 high bits. */
1760 new = ((c & 0xffff) ^ 0x8000) - 0x8000;
1761 if (new != 0
1762 && (temp = alpha_emit_set_const (subtarget, mode, c - new, i)) != 0)
1763 return expand_binop (mode, add_optab, temp, GEN_INT (new),
1764 target, 0, OPTAB_WIDEN);
1766 /* Next try complementing. */
1767 if ((temp = alpha_emit_set_const (subtarget, mode, ~ c, i)) != 0)
1768 return expand_unop (mode, one_cmpl_optab, temp, target, 0);
1770 /* Next try to form a constant and do a left shift. We can do this
1771 if some low-order bits are zero; the exact_log2 call below tells
1772 us that information. The bits we are shifting out could be any
1773 value, but here we'll just try the 0- and sign-extended forms of
1774 the constant. To try to increase the chance of having the same
1775 constant in more than one insn, start at the highest number of
1776 bits to shift, but try all possibilities in case a ZAPNOT will
1777 be useful. */
1779 if ((bits = exact_log2 (c & - c)) > 0)
1780 for (; bits > 0; bits--)
1781 if ((temp = (alpha_emit_set_const
1782 (subtarget, mode, c >> bits, i))) != 0
1783 || ((temp = (alpha_emit_set_const
1784 (subtarget, mode,
1785 ((unsigned HOST_WIDE_INT) c) >> bits, i)))
1786 != 0))
1787 return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
1788 target, 0, OPTAB_WIDEN);
1790 /* Now try high-order zero bits. Here we try the shifted-in bits as
1791 all zero and all ones. Be careful to avoid shifting outside the
1792 mode and to avoid shifting outside the host wide int size. */
1793 /* On narrow hosts, don't shift a 1 into the high bit, since we'll
1794 confuse the recursive call and set all of the high 32 bits. */
1796 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1797 - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64))) > 0)
1798 for (; bits > 0; bits--)
1799 if ((temp = alpha_emit_set_const (subtarget, mode,
1800 c << bits, i)) != 0
1801 || ((temp = (alpha_emit_set_const
1802 (subtarget, mode,
1803 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1804 i)))
1805 != 0))
1806 return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
1807 target, 1, OPTAB_WIDEN);
1809 /* Now try high-order 1 bits. We get that with a sign-extension.
1810 But one bit isn't enough here. Be careful to avoid shifting outside
1811 the mode and to avoid shifting outside the host wide int size. */
1813 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1814 - floor_log2 (~ c) - 2)) > 0)
1815 for (; bits > 0; bits--)
1816 if ((temp = alpha_emit_set_const (subtarget, mode,
1817 c << bits, i)) != 0
1818 || ((temp = (alpha_emit_set_const
1819 (subtarget, mode,
1820 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1821 i)))
1822 != 0))
1823 return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
1824 target, 0, OPTAB_WIDEN);
1827 #if HOST_BITS_PER_WIDE_INT == 64
1828 /* Finally, see if can load a value into the target that is the same as the
1829 constant except that all bytes that are 0 are changed to be 0xff. If we
1830 can, then we can do a ZAPNOT to obtain the desired constant. */
1832 new = c;
1833 for (i = 0; i < 64; i += 8)
1834 if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
1835 new |= (HOST_WIDE_INT) 0xff << i;
1837 /* We are only called for SImode and DImode. If this is SImode, ensure that
1838 we are sign extended to a full word. */
1840 if (mode == SImode)
1841 new = ((new & 0xffffffff) ^ 0x80000000) - 0x80000000;
1843 if (new != c && new != -1
1844 && (temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0)
1845 return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
1846 target, 0, OPTAB_WIDEN);
1847 #endif
1849 return 0;
1852 /* Try to output insns to set TARGET equal to the constant C if it can be
1853 done in less than N insns. Do all computations in MODE. Returns the place
1854 where the output has been placed if it can be done and the insns have been
1855 emitted. If it would take more than N insns, zero is returned and no
1856 insns and emitted. */
1859 alpha_emit_set_const (rtx target, enum machine_mode mode,
1860 HOST_WIDE_INT c, int n)
1862 rtx result = 0;
1863 rtx orig_target = target;
1864 int i;
1866 /* If we can't make any pseudos, TARGET is an SImode hard register, we
1867 can't load this constant in one insn, do this in DImode. */
1868 if (no_new_pseudos && mode == SImode
1869 && GET_CODE (target) == REG && REGNO (target) < FIRST_PSEUDO_REGISTER
1870 && (result = alpha_emit_set_const_1 (target, mode, c, 1)) == 0)
1872 target = gen_lowpart (DImode, target);
1873 mode = DImode;
1876 /* Try 1 insn, then 2, then up to N. */
1877 for (i = 1; i <= n; i++)
1879 result = alpha_emit_set_const_1 (target, mode, c, i);
1880 if (result)
1882 rtx insn = get_last_insn ();
1883 rtx set = single_set (insn);
1884 if (! CONSTANT_P (SET_SRC (set)))
1885 set_unique_reg_note (get_last_insn (), REG_EQUAL, GEN_INT (c));
1886 break;
1890 /* Allow for the case where we changed the mode of TARGET. */
1891 if (result == target)
1892 result = orig_target;
1894 return result;
1897 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
1898 fall back to a straight forward decomposition. We do this to avoid
1899 exponential run times encountered when looking for longer sequences
1900 with alpha_emit_set_const. */
1903 alpha_emit_set_long_const (rtx target, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
1905 HOST_WIDE_INT d1, d2, d3, d4;
1907 /* Decompose the entire word */
1908 #if HOST_BITS_PER_WIDE_INT >= 64
1909 if (c2 != -(c1 < 0))
1910 abort ();
1911 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1912 c1 -= d1;
1913 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1914 c1 = (c1 - d2) >> 32;
1915 d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1916 c1 -= d3;
1917 d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1918 if (c1 != d4)
1919 abort ();
1920 #else
1921 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1922 c1 -= d1;
1923 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1924 if (c1 != d2)
1925 abort ();
1926 c2 += (d2 < 0);
1927 d3 = ((c2 & 0xffff) ^ 0x8000) - 0x8000;
1928 c2 -= d3;
1929 d4 = ((c2 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1930 if (c2 != d4)
1931 abort ();
1932 #endif
1934 /* Construct the high word */
1935 if (d4)
1937 emit_move_insn (target, GEN_INT (d4));
1938 if (d3)
1939 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d3)));
1941 else
1942 emit_move_insn (target, GEN_INT (d3));
1944 /* Shift it into place */
1945 emit_move_insn (target, gen_rtx_ASHIFT (DImode, target, GEN_INT (32)));
1947 /* Add in the low bits. */
1948 if (d2)
1949 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d2)));
1950 if (d1)
1951 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d1)));
1953 return target;
1956 /* Expand a move instruction; return true if all work is done.
1957 We don't handle non-bwx subword loads here. */
1959 bool
1960 alpha_expand_mov (enum machine_mode mode, rtx *operands)
1962 /* If the output is not a register, the input must be. */
1963 if (GET_CODE (operands[0]) == MEM
1964 && ! reg_or_0_operand (operands[1], mode))
1965 operands[1] = force_reg (mode, operands[1]);
1967 /* Allow legitimize_address to perform some simplifications. */
1968 if (mode == Pmode && symbolic_operand (operands[1], mode))
1970 rtx tmp;
1972 tmp = alpha_legitimize_address (operands[1], operands[0], mode);
1973 if (tmp)
1975 if (tmp == operands[0])
1976 return true;
1977 operands[1] = tmp;
1978 return false;
1982 /* Early out for non-constants and valid constants. */
1983 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], mode))
1984 return false;
1986 /* Split large integers. */
1987 if (GET_CODE (operands[1]) == CONST_INT
1988 || GET_CODE (operands[1]) == CONST_DOUBLE)
1990 HOST_WIDE_INT i0, i1;
1991 rtx temp = NULL_RTX;
1993 if (GET_CODE (operands[1]) == CONST_INT)
1995 i0 = INTVAL (operands[1]);
1996 i1 = -(i0 < 0);
1998 else if (HOST_BITS_PER_WIDE_INT >= 64)
2000 i0 = CONST_DOUBLE_LOW (operands[1]);
2001 i1 = -(i0 < 0);
2003 else
2005 i0 = CONST_DOUBLE_LOW (operands[1]);
2006 i1 = CONST_DOUBLE_HIGH (operands[1]);
2009 if (HOST_BITS_PER_WIDE_INT >= 64 || i1 == -(i0 < 0))
2010 temp = alpha_emit_set_const (operands[0], mode, i0, 3);
2012 if (!temp && TARGET_BUILD_CONSTANTS)
2013 temp = alpha_emit_set_long_const (operands[0], i0, i1);
2015 if (temp)
2017 if (rtx_equal_p (operands[0], temp))
2018 return true;
2019 operands[1] = temp;
2020 return false;
2024 /* Otherwise we've nothing left but to drop the thing to memory. */
2025 operands[1] = force_const_mem (mode, operands[1]);
2026 if (reload_in_progress)
2028 emit_move_insn (operands[0], XEXP (operands[1], 0));
2029 operands[1] = copy_rtx (operands[1]);
2030 XEXP (operands[1], 0) = operands[0];
2032 else
2033 operands[1] = validize_mem (operands[1]);
2034 return false;
2037 /* Expand a non-bwx QImode or HImode move instruction;
2038 return true if all work is done. */
2040 bool
2041 alpha_expand_mov_nobwx (enum machine_mode mode, rtx *operands)
2043 /* If the output is not a register, the input must be. */
2044 if (GET_CODE (operands[0]) == MEM)
2045 operands[1] = force_reg (mode, operands[1]);
2047 /* Handle four memory cases, unaligned and aligned for either the input
2048 or the output. The only case where we can be called during reload is
2049 for aligned loads; all other cases require temporaries. */
2051 if (GET_CODE (operands[1]) == MEM
2052 || (GET_CODE (operands[1]) == SUBREG
2053 && GET_CODE (SUBREG_REG (operands[1])) == MEM)
2054 || (reload_in_progress && GET_CODE (operands[1]) == REG
2055 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
2056 || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
2057 && GET_CODE (SUBREG_REG (operands[1])) == REG
2058 && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
2060 if (aligned_memory_operand (operands[1], mode))
2062 if (reload_in_progress)
2064 emit_insn ((mode == QImode
2065 ? gen_reload_inqi_help
2066 : gen_reload_inhi_help)
2067 (operands[0], operands[1],
2068 gen_rtx_REG (SImode, REGNO (operands[0]))));
2070 else
2072 rtx aligned_mem, bitnum;
2073 rtx scratch = gen_reg_rtx (SImode);
2074 rtx subtarget;
2075 bool copyout;
2077 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
2079 subtarget = operands[0];
2080 if (GET_CODE (subtarget) == REG)
2081 subtarget = gen_lowpart (DImode, subtarget), copyout = false;
2082 else
2083 subtarget = gen_reg_rtx (DImode), copyout = true;
2085 emit_insn ((mode == QImode
2086 ? gen_aligned_loadqi
2087 : gen_aligned_loadhi)
2088 (subtarget, aligned_mem, bitnum, scratch));
2090 if (copyout)
2091 emit_move_insn (operands[0], gen_lowpart (mode, subtarget));
2094 else
2096 /* Don't pass these as parameters since that makes the generated
2097 code depend on parameter evaluation order which will cause
2098 bootstrap failures. */
2100 rtx temp1, temp2, seq, subtarget;
2101 bool copyout;
2103 temp1 = gen_reg_rtx (DImode);
2104 temp2 = gen_reg_rtx (DImode);
2106 subtarget = operands[0];
2107 if (GET_CODE (subtarget) == REG)
2108 subtarget = gen_lowpart (DImode, subtarget), copyout = false;
2109 else
2110 subtarget = gen_reg_rtx (DImode), copyout = true;
2112 seq = ((mode == QImode
2113 ? gen_unaligned_loadqi
2114 : gen_unaligned_loadhi)
2115 (subtarget, get_unaligned_address (operands[1], 0),
2116 temp1, temp2));
2117 alpha_set_memflags (seq, operands[1]);
2118 emit_insn (seq);
2120 if (copyout)
2121 emit_move_insn (operands[0], gen_lowpart (mode, subtarget));
2123 return true;
2126 if (GET_CODE (operands[0]) == MEM
2127 || (GET_CODE (operands[0]) == SUBREG
2128 && GET_CODE (SUBREG_REG (operands[0])) == MEM)
2129 || (reload_in_progress && GET_CODE (operands[0]) == REG
2130 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
2131 || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
2132 && GET_CODE (SUBREG_REG (operands[0])) == REG
2133 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
2135 if (aligned_memory_operand (operands[0], mode))
2137 rtx aligned_mem, bitnum;
2138 rtx temp1 = gen_reg_rtx (SImode);
2139 rtx temp2 = gen_reg_rtx (SImode);
2141 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
2143 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
2144 temp1, temp2));
2146 else
2148 rtx temp1 = gen_reg_rtx (DImode);
2149 rtx temp2 = gen_reg_rtx (DImode);
2150 rtx temp3 = gen_reg_rtx (DImode);
2151 rtx seq = ((mode == QImode
2152 ? gen_unaligned_storeqi
2153 : gen_unaligned_storehi)
2154 (get_unaligned_address (operands[0], 0),
2155 operands[1], temp1, temp2, temp3));
2157 alpha_set_memflags (seq, operands[0]);
2158 emit_insn (seq);
2160 return true;
2163 return false;
2166 /* Generate an unsigned DImode to FP conversion. This is the same code
2167 optabs would emit if we didn't have TFmode patterns.
2169 For SFmode, this is the only construction I've found that can pass
2170 gcc.c-torture/execute/ieee/rbug.c. No scenario that uses DFmode
2171 intermediates will work, because you'll get intermediate rounding
2172 that ruins the end result. Some of this could be fixed by turning
2173 on round-to-positive-infinity, but that requires diddling the fpsr,
2174 which kills performance. I tried turning this around and converting
2175 to a negative number, so that I could turn on /m, but either I did
2176 it wrong or there's something else cause I wound up with the exact
2177 same single-bit error. There is a branch-less form of this same code:
2179 srl $16,1,$1
2180 and $16,1,$2
2181 cmplt $16,0,$3
2182 or $1,$2,$2
2183 cmovge $16,$16,$2
2184 itoft $3,$f10
2185 itoft $2,$f11
2186 cvtqs $f11,$f11
2187 adds $f11,$f11,$f0
2188 fcmoveq $f10,$f11,$f0
2190 I'm not using it because it's the same number of instructions as
2191 this branch-full form, and it has more serialized long latency
2192 instructions on the critical path.
2194 For DFmode, we can avoid rounding errors by breaking up the word
2195 into two pieces, converting them separately, and adding them back:
2197 LC0: .long 0,0x5f800000
2199 itoft $16,$f11
2200 lda $2,LC0
2201 cmplt $16,0,$1
2202 cpyse $f11,$f31,$f10
2203 cpyse $f31,$f11,$f11
2204 s4addq $1,$2,$1
2205 lds $f12,0($1)
2206 cvtqt $f10,$f10
2207 cvtqt $f11,$f11
2208 addt $f12,$f10,$f0
2209 addt $f0,$f11,$f0
2211 This doesn't seem to be a clear-cut win over the optabs form.
2212 It probably all depends on the distribution of numbers being
2213 converted -- in the optabs form, all but high-bit-set has a
2214 much lower minimum execution time. */
2216 void
2217 alpha_emit_floatuns (rtx operands[2])
2219 rtx neglab, donelab, i0, i1, f0, in, out;
2220 enum machine_mode mode;
2222 out = operands[0];
2223 in = force_reg (DImode, operands[1]);
2224 mode = GET_MODE (out);
2225 neglab = gen_label_rtx ();
2226 donelab = gen_label_rtx ();
2227 i0 = gen_reg_rtx (DImode);
2228 i1 = gen_reg_rtx (DImode);
2229 f0 = gen_reg_rtx (mode);
2231 emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, DImode, 0, neglab);
2233 emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_FLOAT (mode, in)));
2234 emit_jump_insn (gen_jump (donelab));
2235 emit_barrier ();
2237 emit_label (neglab);
2239 emit_insn (gen_lshrdi3 (i0, in, const1_rtx));
2240 emit_insn (gen_anddi3 (i1, in, const1_rtx));
2241 emit_insn (gen_iordi3 (i0, i0, i1));
2242 emit_insn (gen_rtx_SET (VOIDmode, f0, gen_rtx_FLOAT (mode, i0)));
2243 emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_PLUS (mode, f0, f0)));
2245 emit_label (donelab);
2248 /* Generate the comparison for a conditional branch. */
2251 alpha_emit_conditional_branch (enum rtx_code code)
2253 enum rtx_code cmp_code, branch_code;
2254 enum machine_mode cmp_mode, branch_mode = VOIDmode;
2255 rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
2256 rtx tem;
2258 if (alpha_compare.fp_p && GET_MODE (op0) == TFmode)
2260 if (! TARGET_HAS_XFLOATING_LIBS)
2261 abort ();
2263 /* X_floating library comparison functions return
2264 -1 unordered
2265 0 false
2266 1 true
2267 Convert the compare against the raw return value. */
2269 switch (code)
2271 case UNORDERED:
2272 cmp_code = EQ;
2273 code = LT;
2274 break;
2275 case ORDERED:
2276 cmp_code = EQ;
2277 code = GE;
2278 break;
2279 case NE:
2280 cmp_code = NE;
2281 code = NE;
2282 break;
2283 default:
2284 cmp_code = code;
2285 code = GT;
2286 break;
2289 op0 = alpha_emit_xfloating_compare (cmp_code, op0, op1);
2290 op1 = const0_rtx;
2291 alpha_compare.fp_p = 0;
2294 /* The general case: fold the comparison code to the types of compares
2295 that we have, choosing the branch as necessary. */
2296 switch (code)
2298 case EQ: case LE: case LT: case LEU: case LTU:
2299 case UNORDERED:
2300 /* We have these compares: */
2301 cmp_code = code, branch_code = NE;
2302 break;
2304 case NE:
2305 case ORDERED:
2306 /* These must be reversed. */
2307 cmp_code = reverse_condition (code), branch_code = EQ;
2308 break;
2310 case GE: case GT: case GEU: case GTU:
2311 /* For FP, we swap them, for INT, we reverse them. */
2312 if (alpha_compare.fp_p)
2314 cmp_code = swap_condition (code);
2315 branch_code = NE;
2316 tem = op0, op0 = op1, op1 = tem;
2318 else
2320 cmp_code = reverse_condition (code);
2321 branch_code = EQ;
2323 break;
2325 default:
2326 abort ();
2329 if (alpha_compare.fp_p)
2331 cmp_mode = DFmode;
2332 if (flag_unsafe_math_optimizations)
2334 /* When we are not as concerned about non-finite values, and we
2335 are comparing against zero, we can branch directly. */
2336 if (op1 == CONST0_RTX (DFmode))
2337 cmp_code = UNKNOWN, branch_code = code;
2338 else if (op0 == CONST0_RTX (DFmode))
2340 /* Undo the swap we probably did just above. */
2341 tem = op0, op0 = op1, op1 = tem;
2342 branch_code = swap_condition (cmp_code);
2343 cmp_code = UNKNOWN;
2346 else
2348 /* ??? We mark the branch mode to be CCmode to prevent the
2349 compare and branch from being combined, since the compare
2350 insn follows IEEE rules that the branch does not. */
2351 branch_mode = CCmode;
2354 else
2356 cmp_mode = DImode;
2358 /* The following optimizations are only for signed compares. */
2359 if (code != LEU && code != LTU && code != GEU && code != GTU)
2361 /* Whee. Compare and branch against 0 directly. */
2362 if (op1 == const0_rtx)
2363 cmp_code = UNKNOWN, branch_code = code;
2365 /* If the constants doesn't fit into an immediate, but can
2366 be generated by lda/ldah, we adjust the argument and
2367 compare against zero, so we can use beq/bne directly. */
2368 /* ??? Don't do this when comparing against symbols, otherwise
2369 we'll reduce (&x == 0x1234) to (&x-0x1234 == 0), which will
2370 be declared false out of hand (at least for non-weak). */
2371 else if (GET_CODE (op1) == CONST_INT
2372 && (code == EQ || code == NE)
2373 && !(symbolic_operand (op0, VOIDmode)
2374 || (GET_CODE (op0) == REG && REG_POINTER (op0))))
2376 HOST_WIDE_INT v = INTVAL (op1), n = -v;
2378 if (! CONST_OK_FOR_LETTER_P (v, 'I')
2379 && (CONST_OK_FOR_LETTER_P (n, 'K')
2380 || CONST_OK_FOR_LETTER_P (n, 'L')))
2382 cmp_code = PLUS, branch_code = code;
2383 op1 = GEN_INT (n);
2388 if (!reg_or_0_operand (op0, DImode))
2389 op0 = force_reg (DImode, op0);
2390 if (cmp_code != PLUS && !reg_or_8bit_operand (op1, DImode))
2391 op1 = force_reg (DImode, op1);
2394 /* Emit an initial compare instruction, if necessary. */
2395 tem = op0;
2396 if (cmp_code != UNKNOWN)
2398 tem = gen_reg_rtx (cmp_mode);
2399 emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
2402 /* Zero the operands. */
2403 memset (&alpha_compare, 0, sizeof (alpha_compare));
2405 /* Return the branch comparison. */
2406 return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
2409 /* Certain simplifications can be done to make invalid setcc operations
2410 valid. Return the final comparison, or NULL if we can't work. */
2413 alpha_emit_setcc (enum rtx_code code)
2415 enum rtx_code cmp_code;
2416 rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
2417 int fp_p = alpha_compare.fp_p;
2418 rtx tmp;
2420 /* Zero the operands. */
2421 memset (&alpha_compare, 0, sizeof (alpha_compare));
2423 if (fp_p && GET_MODE (op0) == TFmode)
2425 if (! TARGET_HAS_XFLOATING_LIBS)
2426 abort ();
2428 /* X_floating library comparison functions return
2429 -1 unordered
2430 0 false
2431 1 true
2432 Convert the compare against the raw return value. */
2434 if (code == UNORDERED || code == ORDERED)
2435 cmp_code = EQ;
2436 else
2437 cmp_code = code;
2439 op0 = alpha_emit_xfloating_compare (cmp_code, op0, op1);
2440 op1 = const0_rtx;
2441 fp_p = 0;
2443 if (code == UNORDERED)
2444 code = LT;
2445 else if (code == ORDERED)
2446 code = GE;
2447 else
2448 code = GT;
2451 if (fp_p && !TARGET_FIX)
2452 return NULL_RTX;
2454 /* The general case: fold the comparison code to the types of compares
2455 that we have, choosing the branch as necessary. */
2457 cmp_code = UNKNOWN;
2458 switch (code)
2460 case EQ: case LE: case LT: case LEU: case LTU:
2461 case UNORDERED:
2462 /* We have these compares. */
2463 if (fp_p)
2464 cmp_code = code, code = NE;
2465 break;
2467 case NE:
2468 if (!fp_p && op1 == const0_rtx)
2469 break;
2470 /* FALLTHRU */
2472 case ORDERED:
2473 cmp_code = reverse_condition (code);
2474 code = EQ;
2475 break;
2477 case GE: case GT: case GEU: case GTU:
2478 /* These normally need swapping, but for integer zero we have
2479 special patterns that recognize swapped operands. */
2480 if (!fp_p && op1 == const0_rtx)
2481 break;
2482 code = swap_condition (code);
2483 if (fp_p)
2484 cmp_code = code, code = NE;
2485 tmp = op0, op0 = op1, op1 = tmp;
2486 break;
2488 default:
2489 abort ();
2492 if (!fp_p)
2494 if (!register_operand (op0, DImode))
2495 op0 = force_reg (DImode, op0);
2496 if (!reg_or_8bit_operand (op1, DImode))
2497 op1 = force_reg (DImode, op1);
2500 /* Emit an initial compare instruction, if necessary. */
2501 if (cmp_code != UNKNOWN)
2503 enum machine_mode mode = fp_p ? DFmode : DImode;
2505 tmp = gen_reg_rtx (mode);
2506 emit_insn (gen_rtx_SET (VOIDmode, tmp,
2507 gen_rtx_fmt_ee (cmp_code, mode, op0, op1)));
2509 op0 = fp_p ? gen_lowpart (DImode, tmp) : tmp;
2510 op1 = const0_rtx;
2513 /* Return the setcc comparison. */
2514 return gen_rtx_fmt_ee (code, DImode, op0, op1);
2518 /* Rewrite a comparison against zero CMP of the form
2519 (CODE (cc0) (const_int 0)) so it can be written validly in
2520 a conditional move (if_then_else CMP ...).
2521 If both of the operands that set cc0 are nonzero we must emit
2522 an insn to perform the compare (it can't be done within
2523 the conditional move). */
2526 alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
2528 enum rtx_code code = GET_CODE (cmp);
2529 enum rtx_code cmov_code = NE;
2530 rtx op0 = alpha_compare.op0;
2531 rtx op1 = alpha_compare.op1;
2532 int fp_p = alpha_compare.fp_p;
2533 enum machine_mode cmp_mode
2534 = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
2535 enum machine_mode cmp_op_mode = fp_p ? DFmode : DImode;
2536 enum machine_mode cmov_mode = VOIDmode;
2537 int local_fast_math = flag_unsafe_math_optimizations;
2538 rtx tem;
2540 /* Zero the operands. */
2541 memset (&alpha_compare, 0, sizeof (alpha_compare));
2543 if (fp_p != FLOAT_MODE_P (mode))
2545 enum rtx_code cmp_code;
2547 if (! TARGET_FIX)
2548 return 0;
2550 /* If we have fp<->int register move instructions, do a cmov by
2551 performing the comparison in fp registers, and move the
2552 zero/nonzero value to integer registers, where we can then
2553 use a normal cmov, or vice-versa. */
2555 switch (code)
2557 case EQ: case LE: case LT: case LEU: case LTU:
2558 /* We have these compares. */
2559 cmp_code = code, code = NE;
2560 break;
2562 case NE:
2563 /* This must be reversed. */
2564 cmp_code = EQ, code = EQ;
2565 break;
2567 case GE: case GT: case GEU: case GTU:
2568 /* These normally need swapping, but for integer zero we have
2569 special patterns that recognize swapped operands. */
2570 if (!fp_p && op1 == const0_rtx)
2571 cmp_code = code, code = NE;
2572 else
2574 cmp_code = swap_condition (code);
2575 code = NE;
2576 tem = op0, op0 = op1, op1 = tem;
2578 break;
2580 default:
2581 abort ();
2584 tem = gen_reg_rtx (cmp_op_mode);
2585 emit_insn (gen_rtx_SET (VOIDmode, tem,
2586 gen_rtx_fmt_ee (cmp_code, cmp_op_mode,
2587 op0, op1)));
2589 cmp_mode = cmp_op_mode = fp_p ? DImode : DFmode;
2590 op0 = gen_lowpart (cmp_op_mode, tem);
2591 op1 = CONST0_RTX (cmp_op_mode);
2592 fp_p = !fp_p;
2593 local_fast_math = 1;
2596 /* We may be able to use a conditional move directly.
2597 This avoids emitting spurious compares. */
2598 if (signed_comparison_operator (cmp, VOIDmode)
2599 && (!fp_p || local_fast_math)
2600 && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
2601 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
2603 /* We can't put the comparison inside the conditional move;
2604 emit a compare instruction and put that inside the
2605 conditional move. Make sure we emit only comparisons we have;
2606 swap or reverse as necessary. */
2608 if (no_new_pseudos)
2609 return NULL_RTX;
2611 switch (code)
2613 case EQ: case LE: case LT: case LEU: case LTU:
2614 /* We have these compares: */
2615 break;
2617 case NE:
2618 /* This must be reversed. */
2619 code = reverse_condition (code);
2620 cmov_code = EQ;
2621 break;
2623 case GE: case GT: case GEU: case GTU:
2624 /* These must be swapped. */
2625 if (op1 != CONST0_RTX (cmp_mode))
2627 code = swap_condition (code);
2628 tem = op0, op0 = op1, op1 = tem;
2630 break;
2632 default:
2633 abort ();
2636 if (!fp_p)
2638 if (!reg_or_0_operand (op0, DImode))
2639 op0 = force_reg (DImode, op0);
2640 if (!reg_or_8bit_operand (op1, DImode))
2641 op1 = force_reg (DImode, op1);
2644 /* ??? We mark the branch mode to be CCmode to prevent the compare
2645 and cmov from being combined, since the compare insn follows IEEE
2646 rules that the cmov does not. */
2647 if (fp_p && !local_fast_math)
2648 cmov_mode = CCmode;
2650 tem = gen_reg_rtx (cmp_op_mode);
2651 emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
2652 return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
2655 /* Simplify a conditional move of two constants into a setcc with
2656 arithmetic. This is done with a splitter since combine would
2657 just undo the work if done during code generation. It also catches
2658 cases we wouldn't have before cse. */
2661 alpha_split_conditional_move (enum rtx_code code, rtx dest, rtx cond,
2662 rtx t_rtx, rtx f_rtx)
2664 HOST_WIDE_INT t, f, diff;
2665 enum machine_mode mode;
2666 rtx target, subtarget, tmp;
2668 mode = GET_MODE (dest);
2669 t = INTVAL (t_rtx);
2670 f = INTVAL (f_rtx);
2671 diff = t - f;
2673 if (((code == NE || code == EQ) && diff < 0)
2674 || (code == GE || code == GT))
2676 code = reverse_condition (code);
2677 diff = t, t = f, f = diff;
2678 diff = t - f;
2681 subtarget = target = dest;
2682 if (mode != DImode)
2684 target = gen_lowpart (DImode, dest);
2685 if (! no_new_pseudos)
2686 subtarget = gen_reg_rtx (DImode);
2687 else
2688 subtarget = target;
2690 /* Below, we must be careful to use copy_rtx on target and subtarget
2691 in intermediate insns, as they may be a subreg rtx, which may not
2692 be shared. */
2694 if (f == 0 && exact_log2 (diff) > 0
2695 /* On EV6, we've got enough shifters to make non-arithmetic shifts
2696 viable over a longer latency cmove. On EV5, the E0 slot is a
2697 scarce resource, and on EV4 shift has the same latency as a cmove. */
2698 && (diff <= 8 || alpha_cpu == PROCESSOR_EV6))
2700 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2701 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp));
2703 tmp = gen_rtx_ASHIFT (DImode, copy_rtx (subtarget),
2704 GEN_INT (exact_log2 (t)));
2705 emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
2707 else if (f == 0 && t == -1)
2709 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2710 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp));
2712 emit_insn (gen_negdi2 (target, copy_rtx (subtarget)));
2714 else if (diff == 1 || diff == 4 || diff == 8)
2716 rtx add_op;
2718 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2719 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp));
2721 if (diff == 1)
2722 emit_insn (gen_adddi3 (target, copy_rtx (subtarget), GEN_INT (f)));
2723 else
2725 add_op = GEN_INT (f);
2726 if (sext_add_operand (add_op, mode))
2728 tmp = gen_rtx_MULT (DImode, copy_rtx (subtarget),
2729 GEN_INT (diff));
2730 tmp = gen_rtx_PLUS (DImode, tmp, add_op);
2731 emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
2733 else
2734 return 0;
2737 else
2738 return 0;
2740 return 1;
2743 /* Look up the function X_floating library function name for the
2744 given operation. */
2746 struct xfloating_op GTY(())
2748 const enum rtx_code code;
2749 const char *const GTY((skip)) osf_func;
2750 const char *const GTY((skip)) vms_func;
2751 rtx libcall;
2754 static GTY(()) struct xfloating_op xfloating_ops[] =
2756 { PLUS, "_OtsAddX", "OTS$ADD_X", 0 },
2757 { MINUS, "_OtsSubX", "OTS$SUB_X", 0 },
2758 { MULT, "_OtsMulX", "OTS$MUL_X", 0 },
2759 { DIV, "_OtsDivX", "OTS$DIV_X", 0 },
2760 { EQ, "_OtsEqlX", "OTS$EQL_X", 0 },
2761 { NE, "_OtsNeqX", "OTS$NEQ_X", 0 },
2762 { LT, "_OtsLssX", "OTS$LSS_X", 0 },
2763 { LE, "_OtsLeqX", "OTS$LEQ_X", 0 },
2764 { GT, "_OtsGtrX", "OTS$GTR_X", 0 },
2765 { GE, "_OtsGeqX", "OTS$GEQ_X", 0 },
2766 { FIX, "_OtsCvtXQ", "OTS$CVTXQ", 0 },
2767 { FLOAT, "_OtsCvtQX", "OTS$CVTQX", 0 },
2768 { UNSIGNED_FLOAT, "_OtsCvtQUX", "OTS$CVTQUX", 0 },
2769 { FLOAT_EXTEND, "_OtsConvertFloatTX", "OTS$CVT_FLOAT_T_X", 0 },
2770 { FLOAT_TRUNCATE, "_OtsConvertFloatXT", "OTS$CVT_FLOAT_X_T", 0 }
2773 static GTY(()) struct xfloating_op vax_cvt_ops[] =
2775 { FLOAT_EXTEND, "_OtsConvertFloatGX", "OTS$CVT_FLOAT_G_X", 0 },
2776 { FLOAT_TRUNCATE, "_OtsConvertFloatXG", "OTS$CVT_FLOAT_X_G", 0 }
2779 static rtx
2780 alpha_lookup_xfloating_lib_func (enum rtx_code code)
2782 struct xfloating_op *ops = xfloating_ops;
2783 long n = ARRAY_SIZE (xfloating_ops);
2784 long i;
2786 /* How irritating. Nothing to key off for the main table. */
2787 if (TARGET_FLOAT_VAX && (code == FLOAT_EXTEND || code == FLOAT_TRUNCATE))
2789 ops = vax_cvt_ops;
2790 n = ARRAY_SIZE (vax_cvt_ops);
2793 for (i = 0; i < n; ++i, ++ops)
2794 if (ops->code == code)
2796 rtx func = ops->libcall;
2797 if (!func)
2799 func = init_one_libfunc (TARGET_ABI_OPEN_VMS
2800 ? ops->vms_func : ops->osf_func);
2801 ops->libcall = func;
2803 return func;
2806 abort();
2809 /* Most X_floating operations take the rounding mode as an argument.
2810 Compute that here. */
2812 static int
2813 alpha_compute_xfloating_mode_arg (enum rtx_code code,
2814 enum alpha_fp_rounding_mode round)
2816 int mode;
2818 switch (round)
2820 case ALPHA_FPRM_NORM:
2821 mode = 2;
2822 break;
2823 case ALPHA_FPRM_MINF:
2824 mode = 1;
2825 break;
2826 case ALPHA_FPRM_CHOP:
2827 mode = 0;
2828 break;
2829 case ALPHA_FPRM_DYN:
2830 mode = 4;
2831 break;
2832 default:
2833 abort ();
2835 /* XXX For reference, round to +inf is mode = 3. */
2838 if (code == FLOAT_TRUNCATE && alpha_fptm == ALPHA_FPTM_N)
2839 mode |= 0x10000;
2841 return mode;
2844 /* Emit an X_floating library function call.
2846 Note that these functions do not follow normal calling conventions:
2847 TFmode arguments are passed in two integer registers (as opposed to
2848 indirect); TFmode return values appear in R16+R17.
2850 FUNC is the function to call.
2851 TARGET is where the output belongs.
2852 OPERANDS are the inputs.
2853 NOPERANDS is the count of inputs.
2854 EQUIV is the expression equivalent for the function.
2857 static void
2858 alpha_emit_xfloating_libcall (rtx func, rtx target, rtx operands[],
2859 int noperands, rtx equiv)
2861 rtx usage = NULL_RTX, tmp, reg;
2862 int regno = 16, i;
2864 start_sequence ();
2866 for (i = 0; i < noperands; ++i)
2868 switch (GET_MODE (operands[i]))
2870 case TFmode:
2871 reg = gen_rtx_REG (TFmode, regno);
2872 regno += 2;
2873 break;
2875 case DFmode:
2876 reg = gen_rtx_REG (DFmode, regno + 32);
2877 regno += 1;
2878 break;
2880 case VOIDmode:
2881 if (GET_CODE (operands[i]) != CONST_INT)
2882 abort ();
2883 /* FALLTHRU */
2884 case DImode:
2885 reg = gen_rtx_REG (DImode, regno);
2886 regno += 1;
2887 break;
2889 default:
2890 abort ();
2893 emit_move_insn (reg, operands[i]);
2894 usage = alloc_EXPR_LIST (0, gen_rtx_USE (VOIDmode, reg), usage);
2897 switch (GET_MODE (target))
2899 case TFmode:
2900 reg = gen_rtx_REG (TFmode, 16);
2901 break;
2902 case DFmode:
2903 reg = gen_rtx_REG (DFmode, 32);
2904 break;
2905 case DImode:
2906 reg = gen_rtx_REG (DImode, 0);
2907 break;
2908 default:
2909 abort ();
2912 tmp = gen_rtx_MEM (QImode, func);
2913 tmp = emit_call_insn (GEN_CALL_VALUE (reg, tmp, const0_rtx,
2914 const0_rtx, const0_rtx));
2915 CALL_INSN_FUNCTION_USAGE (tmp) = usage;
2916 CONST_OR_PURE_CALL_P (tmp) = 1;
2918 tmp = get_insns ();
2919 end_sequence ();
2921 emit_libcall_block (tmp, target, reg, equiv);
2924 /* Emit an X_floating library function call for arithmetic (+,-,*,/). */
2926 void
2927 alpha_emit_xfloating_arith (enum rtx_code code, rtx operands[])
2929 rtx func;
2930 int mode;
2931 rtx out_operands[3];
2933 func = alpha_lookup_xfloating_lib_func (code);
2934 mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
2936 out_operands[0] = operands[1];
2937 out_operands[1] = operands[2];
2938 out_operands[2] = GEN_INT (mode);
2939 alpha_emit_xfloating_libcall (func, operands[0], out_operands, 3,
2940 gen_rtx_fmt_ee (code, TFmode, operands[1],
2941 operands[2]));
2944 /* Emit an X_floating library function call for a comparison. */
2946 static rtx
2947 alpha_emit_xfloating_compare (enum rtx_code code, rtx op0, rtx op1)
2949 rtx func;
2950 rtx out, operands[2];
2952 func = alpha_lookup_xfloating_lib_func (code);
2954 operands[0] = op0;
2955 operands[1] = op1;
2956 out = gen_reg_rtx (DImode);
2958 /* ??? Strange mode for equiv because what's actually returned
2959 is -1,0,1, not a proper boolean value. */
2960 alpha_emit_xfloating_libcall (func, out, operands, 2,
2961 gen_rtx_fmt_ee (code, CCmode, op0, op1));
2963 return out;
2966 /* Emit an X_floating library function call for a conversion. */
2968 void
2969 alpha_emit_xfloating_cvt (enum rtx_code orig_code, rtx operands[])
2971 int noperands = 1, mode;
2972 rtx out_operands[2];
2973 rtx func;
2974 enum rtx_code code = orig_code;
2976 if (code == UNSIGNED_FIX)
2977 code = FIX;
2979 func = alpha_lookup_xfloating_lib_func (code);
2981 out_operands[0] = operands[1];
2983 switch (code)
2985 case FIX:
2986 mode = alpha_compute_xfloating_mode_arg (code, ALPHA_FPRM_CHOP);
2987 out_operands[1] = GEN_INT (mode);
2988 noperands = 2;
2989 break;
2990 case FLOAT_TRUNCATE:
2991 mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
2992 out_operands[1] = GEN_INT (mode);
2993 noperands = 2;
2994 break;
2995 default:
2996 break;
2999 alpha_emit_xfloating_libcall (func, operands[0], out_operands, noperands,
3000 gen_rtx_fmt_e (orig_code,
3001 GET_MODE (operands[0]),
3002 operands[1]));
3005 /* Split a TFmode OP[1] into DImode OP[2,3] and likewise for
3006 OP[0] into OP[0,1]. Naturally, output operand ordering is
3007 little-endian. */
3009 void
3010 alpha_split_tfmode_pair (rtx operands[4])
3012 if (GET_CODE (operands[1]) == REG)
3014 operands[3] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1);
3015 operands[2] = gen_rtx_REG (DImode, REGNO (operands[1]));
3017 else if (GET_CODE (operands[1]) == MEM)
3019 operands[3] = adjust_address (operands[1], DImode, 8);
3020 operands[2] = adjust_address (operands[1], DImode, 0);
3022 else if (operands[1] == CONST0_RTX (TFmode))
3023 operands[2] = operands[3] = const0_rtx;
3024 else
3025 abort ();
3027 if (GET_CODE (operands[0]) == REG)
3029 operands[1] = gen_rtx_REG (DImode, REGNO (operands[0]) + 1);
3030 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
3032 else if (GET_CODE (operands[0]) == MEM)
3034 operands[1] = adjust_address (operands[0], DImode, 8);
3035 operands[0] = adjust_address (operands[0], DImode, 0);
3037 else
3038 abort ();
3041 /* Implement negtf2 or abstf2. Op0 is destination, op1 is source,
3042 op2 is a register containing the sign bit, operation is the
3043 logical operation to be performed. */
3045 void
3046 alpha_split_tfmode_frobsign (rtx operands[3], rtx (*operation) (rtx, rtx, rtx))
3048 rtx high_bit = operands[2];
3049 rtx scratch;
3050 int move;
3052 alpha_split_tfmode_pair (operands);
3054 /* Detect three flavors of operand overlap. */
3055 move = 1;
3056 if (rtx_equal_p (operands[0], operands[2]))
3057 move = 0;
3058 else if (rtx_equal_p (operands[1], operands[2]))
3060 if (rtx_equal_p (operands[0], high_bit))
3061 move = 2;
3062 else
3063 move = -1;
3066 if (move < 0)
3067 emit_move_insn (operands[0], operands[2]);
3069 /* ??? If the destination overlaps both source tf and high_bit, then
3070 assume source tf is dead in its entirety and use the other half
3071 for a scratch register. Otherwise "scratch" is just the proper
3072 destination register. */
3073 scratch = operands[move < 2 ? 1 : 3];
3075 emit_insn ((*operation) (scratch, high_bit, operands[3]));
3077 if (move > 0)
3079 emit_move_insn (operands[0], operands[2]);
3080 if (move > 1)
3081 emit_move_insn (operands[1], scratch);
3085 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
3086 unaligned data:
3088 unsigned: signed:
3089 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
3090 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
3091 lda r3,X(r11) lda r3,X+2(r11)
3092 extwl r1,r3,r1 extql r1,r3,r1
3093 extwh r2,r3,r2 extqh r2,r3,r2
3094 or r1.r2.r1 or r1,r2,r1
3095 sra r1,48,r1
3097 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
3098 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
3099 lda r3,X(r11) lda r3,X(r11)
3100 extll r1,r3,r1 extll r1,r3,r1
3101 extlh r2,r3,r2 extlh r2,r3,r2
3102 or r1.r2.r1 addl r1,r2,r1
3104 quad: ldq_u r1,X(r11)
3105 ldq_u r2,X+7(r11)
3106 lda r3,X(r11)
3107 extql r1,r3,r1
3108 extqh r2,r3,r2
3109 or r1.r2.r1
3112 void
3113 alpha_expand_unaligned_load (rtx tgt, rtx mem, HOST_WIDE_INT size,
3114 HOST_WIDE_INT ofs, int sign)
3116 rtx meml, memh, addr, extl, exth, tmp, mema;
3117 enum machine_mode mode;
3119 meml = gen_reg_rtx (DImode);
3120 memh = gen_reg_rtx (DImode);
3121 addr = gen_reg_rtx (DImode);
3122 extl = gen_reg_rtx (DImode);
3123 exth = gen_reg_rtx (DImode);
3125 mema = XEXP (mem, 0);
3126 if (GET_CODE (mema) == LO_SUM)
3127 mema = force_reg (Pmode, mema);
3129 /* AND addresses cannot be in any alias set, since they may implicitly
3130 alias surrounding code. Ideally we'd have some alias set that
3131 covered all types except those with alignment 8 or higher. */
3133 tmp = change_address (mem, DImode,
3134 gen_rtx_AND (DImode,
3135 plus_constant (mema, ofs),
3136 GEN_INT (-8)));
3137 set_mem_alias_set (tmp, 0);
3138 emit_move_insn (meml, tmp);
3140 tmp = change_address (mem, DImode,
3141 gen_rtx_AND (DImode,
3142 plus_constant (mema, ofs + size - 1),
3143 GEN_INT (-8)));
3144 set_mem_alias_set (tmp, 0);
3145 emit_move_insn (memh, tmp);
3147 if (WORDS_BIG_ENDIAN && sign && (size == 2 || size == 4))
3149 emit_move_insn (addr, plus_constant (mema, -1));
3151 emit_insn (gen_extqh_be (extl, meml, addr));
3152 emit_insn (gen_extxl_be (exth, memh, GEN_INT (64), addr));
3154 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
3155 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (64 - size*8),
3156 addr, 1, OPTAB_WIDEN);
3158 else if (sign && size == 2)
3160 emit_move_insn (addr, plus_constant (mema, ofs+2));
3162 emit_insn (gen_extxl_le (extl, meml, GEN_INT (64), addr));
3163 emit_insn (gen_extqh_le (exth, memh, addr));
3165 /* We must use tgt here for the target. Alpha-vms port fails if we use
3166 addr for the target, because addr is marked as a pointer and combine
3167 knows that pointers are always sign-extended 32 bit values. */
3168 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
3169 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48),
3170 addr, 1, OPTAB_WIDEN);
3172 else
3174 if (WORDS_BIG_ENDIAN)
3176 emit_move_insn (addr, plus_constant (mema, ofs+size-1));
3177 switch ((int) size)
3179 case 2:
3180 emit_insn (gen_extwh_be (extl, meml, addr));
3181 mode = HImode;
3182 break;
3184 case 4:
3185 emit_insn (gen_extlh_be (extl, meml, addr));
3186 mode = SImode;
3187 break;
3189 case 8:
3190 emit_insn (gen_extqh_be (extl, meml, addr));
3191 mode = DImode;
3192 break;
3194 default:
3195 abort ();
3197 emit_insn (gen_extxl_be (exth, memh, GEN_INT (size*8), addr));
3199 else
3201 emit_move_insn (addr, plus_constant (mema, ofs));
3202 emit_insn (gen_extxl_le (extl, meml, GEN_INT (size*8), addr));
3203 switch ((int) size)
3205 case 2:
3206 emit_insn (gen_extwh_le (exth, memh, addr));
3207 mode = HImode;
3208 break;
3210 case 4:
3211 emit_insn (gen_extlh_le (exth, memh, addr));
3212 mode = SImode;
3213 break;
3215 case 8:
3216 emit_insn (gen_extqh_le (exth, memh, addr));
3217 mode = DImode;
3218 break;
3220 default:
3221 abort();
3225 addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
3226 gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
3227 sign, OPTAB_WIDEN);
3230 if (addr != tgt)
3231 emit_move_insn (tgt, gen_lowpart(GET_MODE (tgt), addr));
3234 /* Similarly, use ins and msk instructions to perform unaligned stores. */
3236 void
3237 alpha_expand_unaligned_store (rtx dst, rtx src,
3238 HOST_WIDE_INT size, HOST_WIDE_INT ofs)
3240 rtx dstl, dsth, addr, insl, insh, meml, memh, dsta;
3242 dstl = gen_reg_rtx (DImode);
3243 dsth = gen_reg_rtx (DImode);
3244 insl = gen_reg_rtx (DImode);
3245 insh = gen_reg_rtx (DImode);
3247 dsta = XEXP (dst, 0);
3248 if (GET_CODE (dsta) == LO_SUM)
3249 dsta = force_reg (Pmode, dsta);
3251 /* AND addresses cannot be in any alias set, since they may implicitly
3252 alias surrounding code. Ideally we'd have some alias set that
3253 covered all types except those with alignment 8 or higher. */
3255 meml = change_address (dst, DImode,
3256 gen_rtx_AND (DImode,
3257 plus_constant (dsta, ofs),
3258 GEN_INT (-8)));
3259 set_mem_alias_set (meml, 0);
3261 memh = change_address (dst, DImode,
3262 gen_rtx_AND (DImode,
3263 plus_constant (dsta, ofs + size - 1),
3264 GEN_INT (-8)));
3265 set_mem_alias_set (memh, 0);
3267 emit_move_insn (dsth, memh);
3268 emit_move_insn (dstl, meml);
3269 if (WORDS_BIG_ENDIAN)
3271 addr = copy_addr_to_reg (plus_constant (dsta, ofs+size-1));
3273 if (src != const0_rtx)
3275 switch ((int) size)
3277 case 2:
3278 emit_insn (gen_inswl_be (insh, gen_lowpart (HImode,src), addr));
3279 break;
3280 case 4:
3281 emit_insn (gen_insll_be (insh, gen_lowpart (SImode,src), addr));
3282 break;
3283 case 8:
3284 emit_insn (gen_insql_be (insh, gen_lowpart (DImode,src), addr));
3285 break;
3287 emit_insn (gen_insxh (insl, gen_lowpart (DImode, src),
3288 GEN_INT (size*8), addr));
3291 switch ((int) size)
3293 case 2:
3294 emit_insn (gen_mskxl_be (dsth, dsth, GEN_INT (0xffff), addr));
3295 break;
3296 case 4:
3298 rtx msk = immed_double_const (0xffffffff, 0, DImode);
3299 emit_insn (gen_mskxl_be (dsth, dsth, msk, addr));
3300 break;
3302 case 8:
3303 emit_insn (gen_mskxl_be (dsth, dsth, constm1_rtx, addr));
3304 break;
3307 emit_insn (gen_mskxh (dstl, dstl, GEN_INT (size*8), addr));
3309 else
3311 addr = copy_addr_to_reg (plus_constant (dsta, ofs));
3313 if (src != const0_rtx)
3315 emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
3316 GEN_INT (size*8), addr));
3318 switch ((int) size)
3320 case 2:
3321 emit_insn (gen_inswl_le (insl, gen_lowpart (HImode, src), addr));
3322 break;
3323 case 4:
3324 emit_insn (gen_insll_le (insl, gen_lowpart (SImode, src), addr));
3325 break;
3326 case 8:
3327 emit_insn (gen_insql_le (insl, src, addr));
3328 break;
3332 emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
3334 switch ((int) size)
3336 case 2:
3337 emit_insn (gen_mskxl_le (dstl, dstl, GEN_INT (0xffff), addr));
3338 break;
3339 case 4:
3341 rtx msk = immed_double_const (0xffffffff, 0, DImode);
3342 emit_insn (gen_mskxl_le (dstl, dstl, msk, addr));
3343 break;
3345 case 8:
3346 emit_insn (gen_mskxl_le (dstl, dstl, constm1_rtx, addr));
3347 break;
3351 if (src != const0_rtx)
3353 dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
3354 dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
3357 if (WORDS_BIG_ENDIAN)
3359 emit_move_insn (meml, dstl);
3360 emit_move_insn (memh, dsth);
3362 else
3364 /* Must store high before low for degenerate case of aligned. */
3365 emit_move_insn (memh, dsth);
3366 emit_move_insn (meml, dstl);
3370 /* The block move code tries to maximize speed by separating loads and
3371 stores at the expense of register pressure: we load all of the data
3372 before we store it back out. There are two secondary effects worth
3373 mentioning, that this speeds copying to/from aligned and unaligned
3374 buffers, and that it makes the code significantly easier to write. */
3376 #define MAX_MOVE_WORDS 8
3378 /* Load an integral number of consecutive unaligned quadwords. */
3380 static void
3381 alpha_expand_unaligned_load_words (rtx *out_regs, rtx smem,
3382 HOST_WIDE_INT words, HOST_WIDE_INT ofs)
3384 rtx const im8 = GEN_INT (-8);
3385 rtx const i64 = GEN_INT (64);
3386 rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
3387 rtx sreg, areg, tmp, smema;
3388 HOST_WIDE_INT i;
3390 smema = XEXP (smem, 0);
3391 if (GET_CODE (smema) == LO_SUM)
3392 smema = force_reg (Pmode, smema);
3394 /* Generate all the tmp registers we need. */
3395 for (i = 0; i < words; ++i)
3397 data_regs[i] = out_regs[i];
3398 ext_tmps[i] = gen_reg_rtx (DImode);
3400 data_regs[words] = gen_reg_rtx (DImode);
3402 if (ofs != 0)
3403 smem = adjust_address (smem, GET_MODE (smem), ofs);
3405 /* Load up all of the source data. */
3406 for (i = 0; i < words; ++i)
3408 tmp = change_address (smem, DImode,
3409 gen_rtx_AND (DImode,
3410 plus_constant (smema, 8*i),
3411 im8));
3412 set_mem_alias_set (tmp, 0);
3413 emit_move_insn (data_regs[i], tmp);
3416 tmp = change_address (smem, DImode,
3417 gen_rtx_AND (DImode,
3418 plus_constant (smema, 8*words - 1),
3419 im8));
3420 set_mem_alias_set (tmp, 0);
3421 emit_move_insn (data_regs[words], tmp);
3423 /* Extract the half-word fragments. Unfortunately DEC decided to make
3424 extxh with offset zero a noop instead of zeroing the register, so
3425 we must take care of that edge condition ourselves with cmov. */
3427 sreg = copy_addr_to_reg (smema);
3428 areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
3429 1, OPTAB_WIDEN);
3430 if (WORDS_BIG_ENDIAN)
3431 emit_move_insn (sreg, plus_constant (sreg, 7));
3432 for (i = 0; i < words; ++i)
3434 if (WORDS_BIG_ENDIAN)
3436 emit_insn (gen_extqh_be (data_regs[i], data_regs[i], sreg));
3437 emit_insn (gen_extxl_be (ext_tmps[i], data_regs[i+1], i64, sreg));
3439 else
3441 emit_insn (gen_extxl_le (data_regs[i], data_regs[i], i64, sreg));
3442 emit_insn (gen_extqh_le (ext_tmps[i], data_regs[i+1], sreg));
3444 emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
3445 gen_rtx_IF_THEN_ELSE (DImode,
3446 gen_rtx_EQ (DImode, areg,
3447 const0_rtx),
3448 const0_rtx, ext_tmps[i])));
3451 /* Merge the half-words into whole words. */
3452 for (i = 0; i < words; ++i)
3454 out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
3455 ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
3459 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
3460 may be NULL to store zeros. */
3462 static void
3463 alpha_expand_unaligned_store_words (rtx *data_regs, rtx dmem,
3464 HOST_WIDE_INT words, HOST_WIDE_INT ofs)
3466 rtx const im8 = GEN_INT (-8);
3467 rtx const i64 = GEN_INT (64);
3468 rtx ins_tmps[MAX_MOVE_WORDS];
3469 rtx st_tmp_1, st_tmp_2, dreg;
3470 rtx st_addr_1, st_addr_2, dmema;
3471 HOST_WIDE_INT i;
3473 dmema = XEXP (dmem, 0);
3474 if (GET_CODE (dmema) == LO_SUM)
3475 dmema = force_reg (Pmode, dmema);
3477 /* Generate all the tmp registers we need. */
3478 if (data_regs != NULL)
3479 for (i = 0; i < words; ++i)
3480 ins_tmps[i] = gen_reg_rtx(DImode);
3481 st_tmp_1 = gen_reg_rtx(DImode);
3482 st_tmp_2 = gen_reg_rtx(DImode);
3484 if (ofs != 0)
3485 dmem = adjust_address (dmem, GET_MODE (dmem), ofs);
3487 st_addr_2 = change_address (dmem, DImode,
3488 gen_rtx_AND (DImode,
3489 plus_constant (dmema, words*8 - 1),
3490 im8));
3491 set_mem_alias_set (st_addr_2, 0);
3493 st_addr_1 = change_address (dmem, DImode,
3494 gen_rtx_AND (DImode, dmema, im8));
3495 set_mem_alias_set (st_addr_1, 0);
3497 /* Load up the destination end bits. */
3498 emit_move_insn (st_tmp_2, st_addr_2);
3499 emit_move_insn (st_tmp_1, st_addr_1);
3501 /* Shift the input data into place. */
3502 dreg = copy_addr_to_reg (dmema);
3503 if (WORDS_BIG_ENDIAN)
3504 emit_move_insn (dreg, plus_constant (dreg, 7));
3505 if (data_regs != NULL)
3507 for (i = words-1; i >= 0; --i)
3509 if (WORDS_BIG_ENDIAN)
3511 emit_insn (gen_insql_be (ins_tmps[i], data_regs[i], dreg));
3512 emit_insn (gen_insxh (data_regs[i], data_regs[i], i64, dreg));
3514 else
3516 emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
3517 emit_insn (gen_insql_le (data_regs[i], data_regs[i], dreg));
3520 for (i = words-1; i > 0; --i)
3522 ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
3523 ins_tmps[i-1], ins_tmps[i-1], 1,
3524 OPTAB_WIDEN);
3528 /* Split and merge the ends with the destination data. */
3529 if (WORDS_BIG_ENDIAN)
3531 emit_insn (gen_mskxl_be (st_tmp_2, st_tmp_2, constm1_rtx, dreg));
3532 emit_insn (gen_mskxh (st_tmp_1, st_tmp_1, i64, dreg));
3534 else
3536 emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
3537 emit_insn (gen_mskxl_le (st_tmp_1, st_tmp_1, constm1_rtx, dreg));
3540 if (data_regs != NULL)
3542 st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
3543 st_tmp_2, 1, OPTAB_WIDEN);
3544 st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
3545 st_tmp_1, 1, OPTAB_WIDEN);
3548 /* Store it all. */
3549 if (WORDS_BIG_ENDIAN)
3550 emit_move_insn (st_addr_1, st_tmp_1);
3551 else
3552 emit_move_insn (st_addr_2, st_tmp_2);
3553 for (i = words-1; i > 0; --i)
3555 rtx tmp = change_address (dmem, DImode,
3556 gen_rtx_AND (DImode,
3557 plus_constant(dmema,
3558 WORDS_BIG_ENDIAN ? i*8-1 : i*8),
3559 im8));
3560 set_mem_alias_set (tmp, 0);
3561 emit_move_insn (tmp, data_regs ? ins_tmps[i-1] : const0_rtx);
3563 if (WORDS_BIG_ENDIAN)
3564 emit_move_insn (st_addr_2, st_tmp_2);
3565 else
3566 emit_move_insn (st_addr_1, st_tmp_1);
3570 /* Expand string/block move operations.
3572 operands[0] is the pointer to the destination.
3573 operands[1] is the pointer to the source.
3574 operands[2] is the number of bytes to move.
3575 operands[3] is the alignment. */
3578 alpha_expand_block_move (rtx operands[])
3580 rtx bytes_rtx = operands[2];
3581 rtx align_rtx = operands[3];
3582 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
3583 HOST_WIDE_INT bytes = orig_bytes;
3584 HOST_WIDE_INT src_align = INTVAL (align_rtx) * BITS_PER_UNIT;
3585 HOST_WIDE_INT dst_align = src_align;
3586 rtx orig_src = operands[1];
3587 rtx orig_dst = operands[0];
3588 rtx data_regs[2 * MAX_MOVE_WORDS + 16];
3589 rtx tmp;
3590 unsigned int i, words, ofs, nregs = 0;
3592 if (orig_bytes <= 0)
3593 return 1;
3594 else if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD)
3595 return 0;
3597 /* Look for additional alignment information from recorded register info. */
3599 tmp = XEXP (orig_src, 0);
3600 if (GET_CODE (tmp) == REG)
3601 src_align = MAX (src_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
3602 else if (GET_CODE (tmp) == PLUS
3603 && GET_CODE (XEXP (tmp, 0)) == REG
3604 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
3606 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
3607 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
3609 if (a > src_align)
3611 if (a >= 64 && c % 8 == 0)
3612 src_align = 64;
3613 else if (a >= 32 && c % 4 == 0)
3614 src_align = 32;
3615 else if (a >= 16 && c % 2 == 0)
3616 src_align = 16;
3620 tmp = XEXP (orig_dst, 0);
3621 if (GET_CODE (tmp) == REG)
3622 dst_align = MAX (dst_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
3623 else if (GET_CODE (tmp) == PLUS
3624 && GET_CODE (XEXP (tmp, 0)) == REG
3625 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
3627 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
3628 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
3630 if (a > dst_align)
3632 if (a >= 64 && c % 8 == 0)
3633 dst_align = 64;
3634 else if (a >= 32 && c % 4 == 0)
3635 dst_align = 32;
3636 else if (a >= 16 && c % 2 == 0)
3637 dst_align = 16;
3641 ofs = 0;
3642 if (src_align >= 64 && bytes >= 8)
3644 words = bytes / 8;
3646 for (i = 0; i < words; ++i)
3647 data_regs[nregs + i] = gen_reg_rtx (DImode);
3649 for (i = 0; i < words; ++i)
3650 emit_move_insn (data_regs[nregs + i],
3651 adjust_address (orig_src, DImode, ofs + i * 8));
3653 nregs += words;
3654 bytes -= words * 8;
3655 ofs += words * 8;
3658 if (src_align >= 32 && bytes >= 4)
3660 words = bytes / 4;
3662 for (i = 0; i < words; ++i)
3663 data_regs[nregs + i] = gen_reg_rtx (SImode);
3665 for (i = 0; i < words; ++i)
3666 emit_move_insn (data_regs[nregs + i],
3667 adjust_address (orig_src, SImode, ofs + i * 4));
3669 nregs += words;
3670 bytes -= words * 4;
3671 ofs += words * 4;
3674 if (bytes >= 8)
3676 words = bytes / 8;
3678 for (i = 0; i < words+1; ++i)
3679 data_regs[nregs + i] = gen_reg_rtx (DImode);
3681 alpha_expand_unaligned_load_words (data_regs + nregs, orig_src,
3682 words, ofs);
3684 nregs += words;
3685 bytes -= words * 8;
3686 ofs += words * 8;
3689 if (! TARGET_BWX && bytes >= 4)
3691 data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
3692 alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
3693 bytes -= 4;
3694 ofs += 4;
3697 if (bytes >= 2)
3699 if (src_align >= 16)
3701 do {
3702 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
3703 emit_move_insn (tmp, adjust_address (orig_src, HImode, ofs));
3704 bytes -= 2;
3705 ofs += 2;
3706 } while (bytes >= 2);
3708 else if (! TARGET_BWX)
3710 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
3711 alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
3712 bytes -= 2;
3713 ofs += 2;
3717 while (bytes > 0)
3719 data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
3720 emit_move_insn (tmp, adjust_address (orig_src, QImode, ofs));
3721 bytes -= 1;
3722 ofs += 1;
3725 if (nregs > ARRAY_SIZE (data_regs))
3726 abort ();
3728 /* Now save it back out again. */
3730 i = 0, ofs = 0;
3732 /* Write out the data in whatever chunks reading the source allowed. */
3733 if (dst_align >= 64)
3735 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
3737 emit_move_insn (adjust_address (orig_dst, DImode, ofs),
3738 data_regs[i]);
3739 ofs += 8;
3740 i++;
3744 if (dst_align >= 32)
3746 /* If the source has remaining DImode regs, write them out in
3747 two pieces. */
3748 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
3750 tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
3751 NULL_RTX, 1, OPTAB_WIDEN);
3753 emit_move_insn (adjust_address (orig_dst, SImode, ofs),
3754 gen_lowpart (SImode, data_regs[i]));
3755 emit_move_insn (adjust_address (orig_dst, SImode, ofs + 4),
3756 gen_lowpart (SImode, tmp));
3757 ofs += 8;
3758 i++;
3761 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
3763 emit_move_insn (adjust_address (orig_dst, SImode, ofs),
3764 data_regs[i]);
3765 ofs += 4;
3766 i++;
3770 if (i < nregs && GET_MODE (data_regs[i]) == DImode)
3772 /* Write out a remaining block of words using unaligned methods. */
3774 for (words = 1; i + words < nregs; words++)
3775 if (GET_MODE (data_regs[i + words]) != DImode)
3776 break;
3778 if (words == 1)
3779 alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
3780 else
3781 alpha_expand_unaligned_store_words (data_regs + i, orig_dst,
3782 words, ofs);
3784 i += words;
3785 ofs += words * 8;
3788 /* Due to the above, this won't be aligned. */
3789 /* ??? If we have more than one of these, consider constructing full
3790 words in registers and using alpha_expand_unaligned_store_words. */
3791 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
3793 alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
3794 ofs += 4;
3795 i++;
3798 if (dst_align >= 16)
3799 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
3801 emit_move_insn (adjust_address (orig_dst, HImode, ofs), data_regs[i]);
3802 i++;
3803 ofs += 2;
3805 else
3806 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
3808 alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
3809 i++;
3810 ofs += 2;
3813 while (i < nregs && GET_MODE (data_regs[i]) == QImode)
3815 emit_move_insn (adjust_address (orig_dst, QImode, ofs), data_regs[i]);
3816 i++;
3817 ofs += 1;
3820 if (i != nregs)
3821 abort ();
3823 return 1;
3827 alpha_expand_block_clear (rtx operands[])
3829 rtx bytes_rtx = operands[1];
3830 rtx align_rtx = operands[2];
3831 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
3832 HOST_WIDE_INT bytes = orig_bytes;
3833 HOST_WIDE_INT align = INTVAL (align_rtx) * BITS_PER_UNIT;
3834 HOST_WIDE_INT alignofs = 0;
3835 rtx orig_dst = operands[0];
3836 rtx tmp;
3837 int i, words, ofs = 0;
3839 if (orig_bytes <= 0)
3840 return 1;
3841 if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD)
3842 return 0;
3844 /* Look for stricter alignment. */
3845 tmp = XEXP (orig_dst, 0);
3846 if (GET_CODE (tmp) == REG)
3847 align = MAX (align, REGNO_POINTER_ALIGN (REGNO (tmp)));
3848 else if (GET_CODE (tmp) == PLUS
3849 && GET_CODE (XEXP (tmp, 0)) == REG
3850 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
3852 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
3853 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
3855 if (a > align)
3857 if (a >= 64)
3858 align = a, alignofs = 8 - c % 8;
3859 else if (a >= 32)
3860 align = a, alignofs = 4 - c % 4;
3861 else if (a >= 16)
3862 align = a, alignofs = 2 - c % 2;
3866 /* Handle an unaligned prefix first. */
3868 if (alignofs > 0)
3870 #if HOST_BITS_PER_WIDE_INT >= 64
3871 /* Given that alignofs is bounded by align, the only time BWX could
3872 generate three stores is for a 7 byte fill. Prefer two individual
3873 stores over a load/mask/store sequence. */
3874 if ((!TARGET_BWX || alignofs == 7)
3875 && align >= 32
3876 && !(alignofs == 4 && bytes >= 4))
3878 enum machine_mode mode = (align >= 64 ? DImode : SImode);
3879 int inv_alignofs = (align >= 64 ? 8 : 4) - alignofs;
3880 rtx mem, tmp;
3881 HOST_WIDE_INT mask;
3883 mem = adjust_address (orig_dst, mode, ofs - inv_alignofs);
3884 set_mem_alias_set (mem, 0);
3886 mask = ~(~(HOST_WIDE_INT)0 << (inv_alignofs * 8));
3887 if (bytes < alignofs)
3889 mask |= ~(HOST_WIDE_INT)0 << ((inv_alignofs + bytes) * 8);
3890 ofs += bytes;
3891 bytes = 0;
3893 else
3895 bytes -= alignofs;
3896 ofs += alignofs;
3898 alignofs = 0;
3900 tmp = expand_binop (mode, and_optab, mem, GEN_INT (mask),
3901 NULL_RTX, 1, OPTAB_WIDEN);
3903 emit_move_insn (mem, tmp);
3905 #endif
3907 if (TARGET_BWX && (alignofs & 1) && bytes >= 1)
3909 emit_move_insn (adjust_address (orig_dst, QImode, ofs), const0_rtx);
3910 bytes -= 1;
3911 ofs += 1;
3912 alignofs -= 1;
3914 if (TARGET_BWX && align >= 16 && (alignofs & 3) == 2 && bytes >= 2)
3916 emit_move_insn (adjust_address (orig_dst, HImode, ofs), const0_rtx);
3917 bytes -= 2;
3918 ofs += 2;
3919 alignofs -= 2;
3921 if (alignofs == 4 && bytes >= 4)
3923 emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx);
3924 bytes -= 4;
3925 ofs += 4;
3926 alignofs = 0;
3929 /* If we've not used the extra lead alignment information by now,
3930 we won't be able to. Downgrade align to match what's left over. */
3931 if (alignofs > 0)
3933 alignofs = alignofs & -alignofs;
3934 align = MIN (align, alignofs * BITS_PER_UNIT);
3938 /* Handle a block of contiguous long-words. */
3940 if (align >= 64 && bytes >= 8)
3942 words = bytes / 8;
3944 for (i = 0; i < words; ++i)
3945 emit_move_insn (adjust_address (orig_dst, DImode, ofs + i * 8),
3946 const0_rtx);
3948 bytes -= words * 8;
3949 ofs += words * 8;
3952 /* If the block is large and appropriately aligned, emit a single
3953 store followed by a sequence of stq_u insns. */
3955 if (align >= 32 && bytes > 16)
3957 rtx orig_dsta;
3959 emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx);
3960 bytes -= 4;
3961 ofs += 4;
3963 orig_dsta = XEXP (orig_dst, 0);
3964 if (GET_CODE (orig_dsta) == LO_SUM)
3965 orig_dsta = force_reg (Pmode, orig_dsta);
3967 words = bytes / 8;
3968 for (i = 0; i < words; ++i)
3970 rtx mem
3971 = change_address (orig_dst, DImode,
3972 gen_rtx_AND (DImode,
3973 plus_constant (orig_dsta, ofs + i*8),
3974 GEN_INT (-8)));
3975 set_mem_alias_set (mem, 0);
3976 emit_move_insn (mem, const0_rtx);
3979 /* Depending on the alignment, the first stq_u may have overlapped
3980 with the initial stl, which means that the last stq_u didn't
3981 write as much as it would appear. Leave those questionable bytes
3982 unaccounted for. */
3983 bytes -= words * 8 - 4;
3984 ofs += words * 8 - 4;
3987 /* Handle a smaller block of aligned words. */
3989 if ((align >= 64 && bytes == 4)
3990 || (align == 32 && bytes >= 4))
3992 words = bytes / 4;
3994 for (i = 0; i < words; ++i)
3995 emit_move_insn (adjust_address (orig_dst, SImode, ofs + i * 4),
3996 const0_rtx);
3998 bytes -= words * 4;
3999 ofs += words * 4;
4002 /* An unaligned block uses stq_u stores for as many as possible. */
4004 if (bytes >= 8)
4006 words = bytes / 8;
4008 alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
4010 bytes -= words * 8;
4011 ofs += words * 8;
4014 /* Next clean up any trailing pieces. */
4016 #if HOST_BITS_PER_WIDE_INT >= 64
4017 /* Count the number of bits in BYTES for which aligned stores could
4018 be emitted. */
4019 words = 0;
4020 for (i = (TARGET_BWX ? 1 : 4); i * BITS_PER_UNIT <= align ; i <<= 1)
4021 if (bytes & i)
4022 words += 1;
4024 /* If we have appropriate alignment (and it wouldn't take too many
4025 instructions otherwise), mask out the bytes we need. */
4026 if (TARGET_BWX ? words > 2 : bytes > 0)
4028 if (align >= 64)
4030 rtx mem, tmp;
4031 HOST_WIDE_INT mask;
4033 mem = adjust_address (orig_dst, DImode, ofs);
4034 set_mem_alias_set (mem, 0);
4036 mask = ~(HOST_WIDE_INT)0 << (bytes * 8);
4038 tmp = expand_binop (DImode, and_optab, mem, GEN_INT (mask),
4039 NULL_RTX, 1, OPTAB_WIDEN);
4041 emit_move_insn (mem, tmp);
4042 return 1;
4044 else if (align >= 32 && bytes < 4)
4046 rtx mem, tmp;
4047 HOST_WIDE_INT mask;
4049 mem = adjust_address (orig_dst, SImode, ofs);
4050 set_mem_alias_set (mem, 0);
4052 mask = ~(HOST_WIDE_INT)0 << (bytes * 8);
4054 tmp = expand_binop (SImode, and_optab, mem, GEN_INT (mask),
4055 NULL_RTX, 1, OPTAB_WIDEN);
4057 emit_move_insn (mem, tmp);
4058 return 1;
4061 #endif
4063 if (!TARGET_BWX && bytes >= 4)
4065 alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
4066 bytes -= 4;
4067 ofs += 4;
4070 if (bytes >= 2)
4072 if (align >= 16)
4074 do {
4075 emit_move_insn (adjust_address (orig_dst, HImode, ofs),
4076 const0_rtx);
4077 bytes -= 2;
4078 ofs += 2;
4079 } while (bytes >= 2);
4081 else if (! TARGET_BWX)
4083 alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
4084 bytes -= 2;
4085 ofs += 2;
4089 while (bytes > 0)
4091 emit_move_insn (adjust_address (orig_dst, QImode, ofs), const0_rtx);
4092 bytes -= 1;
4093 ofs += 1;
4096 return 1;
4099 /* Returns a mask so that zap(x, value) == x & mask. */
4102 alpha_expand_zap_mask (HOST_WIDE_INT value)
4104 rtx result;
4105 int i;
4107 if (HOST_BITS_PER_WIDE_INT >= 64)
4109 HOST_WIDE_INT mask = 0;
4111 for (i = 7; i >= 0; --i)
4113 mask <<= 8;
4114 if (!((value >> i) & 1))
4115 mask |= 0xff;
4118 result = gen_int_mode (mask, DImode);
4120 else if (HOST_BITS_PER_WIDE_INT == 32)
4122 HOST_WIDE_INT mask_lo = 0, mask_hi = 0;
4124 for (i = 7; i >= 4; --i)
4126 mask_hi <<= 8;
4127 if (!((value >> i) & 1))
4128 mask_hi |= 0xff;
4131 for (i = 3; i >= 0; --i)
4133 mask_lo <<= 8;
4134 if (!((value >> i) & 1))
4135 mask_lo |= 0xff;
4138 result = immed_double_const (mask_lo, mask_hi, DImode);
4140 else
4141 abort ();
4143 return result;
4146 void
4147 alpha_expand_builtin_vector_binop (rtx (*gen) (rtx, rtx, rtx),
4148 enum machine_mode mode,
4149 rtx op0, rtx op1, rtx op2)
4151 op0 = gen_lowpart (mode, op0);
4153 if (op1 == const0_rtx)
4154 op1 = CONST0_RTX (mode);
4155 else
4156 op1 = gen_lowpart (mode, op1);
4158 if (op2 == const0_rtx)
4159 op2 = CONST0_RTX (mode);
4160 else
4161 op2 = gen_lowpart (mode, op2);
4163 emit_insn ((*gen) (op0, op1, op2));
4166 /* Adjust the cost of a scheduling dependency. Return the new cost of
4167 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
4169 static int
4170 alpha_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
4172 enum attr_type insn_type, dep_insn_type;
4174 /* If the dependence is an anti-dependence, there is no cost. For an
4175 output dependence, there is sometimes a cost, but it doesn't seem
4176 worth handling those few cases. */
4177 if (REG_NOTE_KIND (link) != 0)
4178 return cost;
4180 /* If we can't recognize the insns, we can't really do anything. */
4181 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
4182 return cost;
4184 insn_type = get_attr_type (insn);
4185 dep_insn_type = get_attr_type (dep_insn);
4187 /* Bring in the user-defined memory latency. */
4188 if (dep_insn_type == TYPE_ILD
4189 || dep_insn_type == TYPE_FLD
4190 || dep_insn_type == TYPE_LDSYM)
4191 cost += alpha_memory_latency-1;
4193 /* Everything else handled in DFA bypasses now. */
4195 return cost;
4198 /* The number of instructions that can be issued per cycle. */
4200 static int
4201 alpha_issue_rate (void)
4203 return (alpha_cpu == PROCESSOR_EV4 ? 2 : 4);
4206 /* How many alternative schedules to try. This should be as wide as the
4207 scheduling freedom in the DFA, but no wider. Making this value too
4208 large results extra work for the scheduler.
4210 For EV4, loads can be issued to either IB0 or IB1, thus we have 2
4211 alternative schedules. For EV5, we can choose between E0/E1 and
4212 FA/FM. For EV6, an arithmetic insn can be issued to U0/U1/L0/L1. */
4214 static int
4215 alpha_multipass_dfa_lookahead (void)
4217 return (alpha_cpu == PROCESSOR_EV6 ? 4 : 2);
4220 /* Machine-specific function data. */
4222 struct machine_function GTY(())
4224 /* For unicosmk. */
4225 /* List of call information words for calls from this function. */
4226 struct rtx_def *first_ciw;
4227 struct rtx_def *last_ciw;
4228 int ciw_count;
4230 /* List of deferred case vectors. */
4231 struct rtx_def *addr_list;
4233 /* For OSF. */
4234 const char *some_ld_name;
4236 /* For TARGET_LD_BUGGY_LDGP. */
4237 struct rtx_def *gp_save_rtx;
4240 /* How to allocate a 'struct machine_function'. */
4242 static struct machine_function *
4243 alpha_init_machine_status (void)
4245 return ((struct machine_function *)
4246 ggc_alloc_cleared (sizeof (struct machine_function)));
4249 /* Functions to save and restore alpha_return_addr_rtx. */
4251 /* Start the ball rolling with RETURN_ADDR_RTX. */
4254 alpha_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
4256 if (count != 0)
4257 return const0_rtx;
4259 return get_hard_reg_initial_val (Pmode, REG_RA);
4262 /* Return or create a memory slot containing the gp value for the current
4263 function. Needed only if TARGET_LD_BUGGY_LDGP. */
4266 alpha_gp_save_rtx (void)
4268 rtx seq, m = cfun->machine->gp_save_rtx;
4270 if (m == NULL)
4272 start_sequence ();
4274 m = assign_stack_local (DImode, UNITS_PER_WORD, BITS_PER_WORD);
4275 m = validize_mem (m);
4276 emit_move_insn (m, pic_offset_table_rtx);
4278 seq = get_insns ();
4279 end_sequence ();
4280 emit_insn_after (seq, entry_of_function ());
4282 cfun->machine->gp_save_rtx = m;
4285 return m;
4288 static int
4289 alpha_ra_ever_killed (void)
4291 rtx top;
4293 if (!has_hard_reg_initial_val (Pmode, REG_RA))
4294 return regs_ever_live[REG_RA];
4296 push_topmost_sequence ();
4297 top = get_insns ();
4298 pop_topmost_sequence ();
4300 return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX);
4304 /* Return the trap mode suffix applicable to the current
4305 instruction, or NULL. */
4307 static const char *
4308 get_trap_mode_suffix (void)
4310 enum attr_trap_suffix s = get_attr_trap_suffix (current_output_insn);
4312 switch (s)
4314 case TRAP_SUFFIX_NONE:
4315 return NULL;
4317 case TRAP_SUFFIX_SU:
4318 if (alpha_fptm >= ALPHA_FPTM_SU)
4319 return "su";
4320 return NULL;
4322 case TRAP_SUFFIX_SUI:
4323 if (alpha_fptm >= ALPHA_FPTM_SUI)
4324 return "sui";
4325 return NULL;
4327 case TRAP_SUFFIX_V_SV:
4328 switch (alpha_fptm)
4330 case ALPHA_FPTM_N:
4331 return NULL;
4332 case ALPHA_FPTM_U:
4333 return "v";
4334 case ALPHA_FPTM_SU:
4335 case ALPHA_FPTM_SUI:
4336 return "sv";
4338 break;
4340 case TRAP_SUFFIX_V_SV_SVI:
4341 switch (alpha_fptm)
4343 case ALPHA_FPTM_N:
4344 return NULL;
4345 case ALPHA_FPTM_U:
4346 return "v";
4347 case ALPHA_FPTM_SU:
4348 return "sv";
4349 case ALPHA_FPTM_SUI:
4350 return "svi";
4352 break;
4354 case TRAP_SUFFIX_U_SU_SUI:
4355 switch (alpha_fptm)
4357 case ALPHA_FPTM_N:
4358 return NULL;
4359 case ALPHA_FPTM_U:
4360 return "u";
4361 case ALPHA_FPTM_SU:
4362 return "su";
4363 case ALPHA_FPTM_SUI:
4364 return "sui";
4366 break;
4368 abort ();
4371 /* Return the rounding mode suffix applicable to the current
4372 instruction, or NULL. */
4374 static const char *
4375 get_round_mode_suffix (void)
4377 enum attr_round_suffix s = get_attr_round_suffix (current_output_insn);
4379 switch (s)
4381 case ROUND_SUFFIX_NONE:
4382 return NULL;
4383 case ROUND_SUFFIX_NORMAL:
4384 switch (alpha_fprm)
4386 case ALPHA_FPRM_NORM:
4387 return NULL;
4388 case ALPHA_FPRM_MINF:
4389 return "m";
4390 case ALPHA_FPRM_CHOP:
4391 return "c";
4392 case ALPHA_FPRM_DYN:
4393 return "d";
4395 break;
4397 case ROUND_SUFFIX_C:
4398 return "c";
4400 abort ();
4403 /* Locate some local-dynamic symbol still in use by this function
4404 so that we can print its name in some movdi_er_tlsldm pattern. */
4406 static int
4407 get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
4409 rtx x = *px;
4411 if (GET_CODE (x) == SYMBOL_REF
4412 && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
4414 cfun->machine->some_ld_name = XSTR (x, 0);
4415 return 1;
4418 return 0;
4421 static const char *
4422 get_some_local_dynamic_name (void)
4424 rtx insn;
4426 if (cfun->machine->some_ld_name)
4427 return cfun->machine->some_ld_name;
4429 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
4430 if (INSN_P (insn)
4431 && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
4432 return cfun->machine->some_ld_name;
4434 abort ();
4437 /* Print an operand. Recognize special options, documented below. */
4439 void
4440 print_operand (FILE *file, rtx x, int code)
4442 int i;
4444 switch (code)
4446 case '~':
4447 /* Print the assembler name of the current function. */
4448 assemble_name (file, alpha_fnname);
4449 break;
4451 case '&':
4452 assemble_name (file, get_some_local_dynamic_name ());
4453 break;
4455 case '/':
4457 const char *trap = get_trap_mode_suffix ();
4458 const char *round = get_round_mode_suffix ();
4460 if (trap || round)
4461 fprintf (file, (TARGET_AS_SLASH_BEFORE_SUFFIX ? "/%s%s" : "%s%s"),
4462 (trap ? trap : ""), (round ? round : ""));
4463 break;
4466 case ',':
4467 /* Generates single precision instruction suffix. */
4468 fputc ((TARGET_FLOAT_VAX ? 'f' : 's'), file);
4469 break;
4471 case '-':
4472 /* Generates double precision instruction suffix. */
4473 fputc ((TARGET_FLOAT_VAX ? 'g' : 't'), file);
4474 break;
4476 case '+':
4477 /* Generates a nop after a noreturn call at the very end of the
4478 function. */
4479 if (next_real_insn (current_output_insn) == 0)
4480 fprintf (file, "\n\tnop");
4481 break;
4483 case '#':
4484 if (alpha_this_literal_sequence_number == 0)
4485 alpha_this_literal_sequence_number = alpha_next_sequence_number++;
4486 fprintf (file, "%d", alpha_this_literal_sequence_number);
4487 break;
4489 case '*':
4490 if (alpha_this_gpdisp_sequence_number == 0)
4491 alpha_this_gpdisp_sequence_number = alpha_next_sequence_number++;
4492 fprintf (file, "%d", alpha_this_gpdisp_sequence_number);
4493 break;
4495 case 'H':
4496 if (GET_CODE (x) == HIGH)
4497 output_addr_const (file, XEXP (x, 0));
4498 else
4499 output_operand_lossage ("invalid %%H value");
4500 break;
4502 case 'J':
4504 const char *lituse;
4506 if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD_CALL)
4508 x = XVECEXP (x, 0, 0);
4509 lituse = "lituse_tlsgd";
4511 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM_CALL)
4513 x = XVECEXP (x, 0, 0);
4514 lituse = "lituse_tlsldm";
4516 else if (GET_CODE (x) == CONST_INT)
4517 lituse = "lituse_jsr";
4518 else
4520 output_operand_lossage ("invalid %%J value");
4521 break;
4524 if (x != const0_rtx)
4525 fprintf (file, "\t\t!%s!%d", lituse, (int) INTVAL (x));
4527 break;
4529 case 'r':
4530 /* If this operand is the constant zero, write it as "$31". */
4531 if (GET_CODE (x) == REG)
4532 fprintf (file, "%s", reg_names[REGNO (x)]);
4533 else if (x == CONST0_RTX (GET_MODE (x)))
4534 fprintf (file, "$31");
4535 else
4536 output_operand_lossage ("invalid %%r value");
4537 break;
4539 case 'R':
4540 /* Similar, but for floating-point. */
4541 if (GET_CODE (x) == REG)
4542 fprintf (file, "%s", reg_names[REGNO (x)]);
4543 else if (x == CONST0_RTX (GET_MODE (x)))
4544 fprintf (file, "$f31");
4545 else
4546 output_operand_lossage ("invalid %%R value");
4547 break;
4549 case 'N':
4550 /* Write the 1's complement of a constant. */
4551 if (GET_CODE (x) != CONST_INT)
4552 output_operand_lossage ("invalid %%N value");
4554 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
4555 break;
4557 case 'P':
4558 /* Write 1 << C, for a constant C. */
4559 if (GET_CODE (x) != CONST_INT)
4560 output_operand_lossage ("invalid %%P value");
4562 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
4563 break;
4565 case 'h':
4566 /* Write the high-order 16 bits of a constant, sign-extended. */
4567 if (GET_CODE (x) != CONST_INT)
4568 output_operand_lossage ("invalid %%h value");
4570 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
4571 break;
4573 case 'L':
4574 /* Write the low-order 16 bits of a constant, sign-extended. */
4575 if (GET_CODE (x) != CONST_INT)
4576 output_operand_lossage ("invalid %%L value");
4578 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4579 (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
4580 break;
4582 case 'm':
4583 /* Write mask for ZAP insn. */
4584 if (GET_CODE (x) == CONST_DOUBLE)
4586 HOST_WIDE_INT mask = 0;
4587 HOST_WIDE_INT value;
4589 value = CONST_DOUBLE_LOW (x);
4590 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
4591 i++, value >>= 8)
4592 if (value & 0xff)
4593 mask |= (1 << i);
4595 value = CONST_DOUBLE_HIGH (x);
4596 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
4597 i++, value >>= 8)
4598 if (value & 0xff)
4599 mask |= (1 << (i + sizeof (int)));
4601 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
4604 else if (GET_CODE (x) == CONST_INT)
4606 HOST_WIDE_INT mask = 0, value = INTVAL (x);
4608 for (i = 0; i < 8; i++, value >>= 8)
4609 if (value & 0xff)
4610 mask |= (1 << i);
4612 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
4614 else
4615 output_operand_lossage ("invalid %%m value");
4616 break;
4618 case 'M':
4619 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
4620 if (GET_CODE (x) != CONST_INT
4621 || (INTVAL (x) != 8 && INTVAL (x) != 16
4622 && INTVAL (x) != 32 && INTVAL (x) != 64))
4623 output_operand_lossage ("invalid %%M value");
4625 fprintf (file, "%s",
4626 (INTVAL (x) == 8 ? "b"
4627 : INTVAL (x) == 16 ? "w"
4628 : INTVAL (x) == 32 ? "l"
4629 : "q"));
4630 break;
4632 case 'U':
4633 /* Similar, except do it from the mask. */
4634 if (GET_CODE (x) == CONST_INT)
4636 HOST_WIDE_INT value = INTVAL (x);
4638 if (value == 0xff)
4640 fputc ('b', file);
4641 break;
4643 if (value == 0xffff)
4645 fputc ('w', file);
4646 break;
4648 if (value == 0xffffffff)
4650 fputc ('l', file);
4651 break;
4653 if (value == -1)
4655 fputc ('q', file);
4656 break;
4659 else if (HOST_BITS_PER_WIDE_INT == 32
4660 && GET_CODE (x) == CONST_DOUBLE
4661 && CONST_DOUBLE_LOW (x) == 0xffffffff
4662 && CONST_DOUBLE_HIGH (x) == 0)
4664 fputc ('l', file);
4665 break;
4667 output_operand_lossage ("invalid %%U value");
4668 break;
4670 case 's':
4671 /* Write the constant value divided by 8 for little-endian mode or
4672 (56 - value) / 8 for big-endian mode. */
4674 if (GET_CODE (x) != CONST_INT
4675 || (unsigned HOST_WIDE_INT) INTVAL (x) >= (WORDS_BIG_ENDIAN
4676 ? 56
4677 : 64)
4678 || (INTVAL (x) & 7) != 0)
4679 output_operand_lossage ("invalid %%s value");
4681 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4682 WORDS_BIG_ENDIAN
4683 ? (56 - INTVAL (x)) / 8
4684 : INTVAL (x) / 8);
4685 break;
4687 case 'S':
4688 /* Same, except compute (64 - c) / 8 */
4690 if (GET_CODE (x) != CONST_INT
4691 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
4692 && (INTVAL (x) & 7) != 8)
4693 output_operand_lossage ("invalid %%s value");
4695 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
4696 break;
4698 case 't':
4700 /* On Unicos/Mk systems: use a DEX expression if the symbol
4701 clashes with a register name. */
4702 int dex = unicosmk_need_dex (x);
4703 if (dex)
4704 fprintf (file, "DEX(%d)", dex);
4705 else
4706 output_addr_const (file, x);
4708 break;
4710 case 'C': case 'D': case 'c': case 'd':
4711 /* Write out comparison name. */
4713 enum rtx_code c = GET_CODE (x);
4715 if (!COMPARISON_P (x))
4716 output_operand_lossage ("invalid %%C value");
4718 else if (code == 'D')
4719 c = reverse_condition (c);
4720 else if (code == 'c')
4721 c = swap_condition (c);
4722 else if (code == 'd')
4723 c = swap_condition (reverse_condition (c));
4725 if (c == LEU)
4726 fprintf (file, "ule");
4727 else if (c == LTU)
4728 fprintf (file, "ult");
4729 else if (c == UNORDERED)
4730 fprintf (file, "un");
4731 else
4732 fprintf (file, "%s", GET_RTX_NAME (c));
4734 break;
4736 case 'E':
4737 /* Write the divide or modulus operator. */
4738 switch (GET_CODE (x))
4740 case DIV:
4741 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
4742 break;
4743 case UDIV:
4744 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
4745 break;
4746 case MOD:
4747 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
4748 break;
4749 case UMOD:
4750 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
4751 break;
4752 default:
4753 output_operand_lossage ("invalid %%E value");
4754 break;
4756 break;
4758 case 'A':
4759 /* Write "_u" for unaligned access. */
4760 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
4761 fprintf (file, "_u");
4762 break;
4764 case 0:
4765 if (GET_CODE (x) == REG)
4766 fprintf (file, "%s", reg_names[REGNO (x)]);
4767 else if (GET_CODE (x) == MEM)
4768 output_address (XEXP (x, 0));
4769 else if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == UNSPEC)
4771 switch (XINT (XEXP (x, 0), 1))
4773 case UNSPEC_DTPREL:
4774 case UNSPEC_TPREL:
4775 output_addr_const (file, XVECEXP (XEXP (x, 0), 0, 0));
4776 break;
4777 default:
4778 output_operand_lossage ("unknown relocation unspec");
4779 break;
4782 else
4783 output_addr_const (file, x);
4784 break;
4786 default:
4787 output_operand_lossage ("invalid %%xn code");
4791 void
4792 print_operand_address (FILE *file, rtx addr)
4794 int basereg = 31;
4795 HOST_WIDE_INT offset = 0;
4797 if (GET_CODE (addr) == AND)
4798 addr = XEXP (addr, 0);
4800 if (GET_CODE (addr) == PLUS
4801 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
4803 offset = INTVAL (XEXP (addr, 1));
4804 addr = XEXP (addr, 0);
4807 if (GET_CODE (addr) == LO_SUM)
4809 const char *reloc16, *reloclo;
4810 rtx op1 = XEXP (addr, 1);
4812 if (GET_CODE (op1) == CONST && GET_CODE (XEXP (op1, 0)) == UNSPEC)
4814 op1 = XEXP (op1, 0);
4815 switch (XINT (op1, 1))
4817 case UNSPEC_DTPREL:
4818 reloc16 = NULL;
4819 reloclo = (alpha_tls_size == 16 ? "dtprel" : "dtprello");
4820 break;
4821 case UNSPEC_TPREL:
4822 reloc16 = NULL;
4823 reloclo = (alpha_tls_size == 16 ? "tprel" : "tprello");
4824 break;
4825 default:
4826 output_operand_lossage ("unknown relocation unspec");
4827 return;
4830 output_addr_const (file, XVECEXP (op1, 0, 0));
4832 else
4834 reloc16 = "gprel";
4835 reloclo = "gprellow";
4836 output_addr_const (file, op1);
4839 if (offset)
4840 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
4842 addr = XEXP (addr, 0);
4843 if (GET_CODE (addr) == REG)
4844 basereg = REGNO (addr);
4845 else if (GET_CODE (addr) == SUBREG
4846 && GET_CODE (SUBREG_REG (addr)) == REG)
4847 basereg = subreg_regno (addr);
4848 else
4849 abort ();
4851 fprintf (file, "($%d)\t\t!%s", basereg,
4852 (basereg == 29 ? reloc16 : reloclo));
4853 return;
4856 if (GET_CODE (addr) == REG)
4857 basereg = REGNO (addr);
4858 else if (GET_CODE (addr) == SUBREG
4859 && GET_CODE (SUBREG_REG (addr)) == REG)
4860 basereg = subreg_regno (addr);
4861 else if (GET_CODE (addr) == CONST_INT)
4862 offset = INTVAL (addr);
4864 #if TARGET_ABI_OPEN_VMS
4865 else if (GET_CODE (addr) == SYMBOL_REF)
4867 fprintf (file, "%s", XSTR (addr, 0));
4868 return;
4870 else if (GET_CODE (addr) == CONST
4871 && GET_CODE (XEXP (addr, 0)) == PLUS
4872 && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF)
4874 fprintf (file, "%s+" HOST_WIDE_INT_PRINT_DEC,
4875 XSTR (XEXP (XEXP (addr, 0), 0), 0),
4876 INTVAL (XEXP (XEXP (addr, 0), 1)));
4877 return;
4879 #endif
4881 else
4882 abort ();
4884 fprintf (file, HOST_WIDE_INT_PRINT_DEC "($%d)", offset, basereg);
4887 /* Emit RTL insns to initialize the variable parts of a trampoline at
4888 TRAMP. FNADDR is an RTX for the address of the function's pure
4889 code. CXT is an RTX for the static chain value for the function.
4891 The three offset parameters are for the individual template's
4892 layout. A JMPOFS < 0 indicates that the trampoline does not
4893 contain instructions at all.
4895 We assume here that a function will be called many more times than
4896 its address is taken (e.g., it might be passed to qsort), so we
4897 take the trouble to initialize the "hint" field in the JMP insn.
4898 Note that the hint field is PC (new) + 4 * bits 13:0. */
4900 void
4901 alpha_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt,
4902 int fnofs, int cxtofs, int jmpofs)
4904 rtx temp, temp1, addr;
4905 /* VMS really uses DImode pointers in memory at this point. */
4906 enum machine_mode mode = TARGET_ABI_OPEN_VMS ? Pmode : ptr_mode;
4908 #ifdef POINTERS_EXTEND_UNSIGNED
4909 fnaddr = convert_memory_address (mode, fnaddr);
4910 cxt = convert_memory_address (mode, cxt);
4911 #endif
4913 /* Store function address and CXT. */
4914 addr = memory_address (mode, plus_constant (tramp, fnofs));
4915 emit_move_insn (gen_rtx_MEM (mode, addr), fnaddr);
4916 addr = memory_address (mode, plus_constant (tramp, cxtofs));
4917 emit_move_insn (gen_rtx_MEM (mode, addr), cxt);
4919 /* This has been disabled since the hint only has a 32k range, and in
4920 no existing OS is the stack within 32k of the text segment. */
4921 if (0 && jmpofs >= 0)
4923 /* Compute hint value. */
4924 temp = force_operand (plus_constant (tramp, jmpofs+4), NULL_RTX);
4925 temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1,
4926 OPTAB_WIDEN);
4927 temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
4928 build_int_cst (NULL_TREE, 2, 0), NULL_RTX, 1);
4929 temp = expand_and (SImode, gen_lowpart (SImode, temp),
4930 GEN_INT (0x3fff), 0);
4932 /* Merge in the hint. */
4933 addr = memory_address (SImode, plus_constant (tramp, jmpofs));
4934 temp1 = force_reg (SImode, gen_rtx_MEM (SImode, addr));
4935 temp1 = expand_and (SImode, temp1, GEN_INT (0xffffc000), NULL_RTX);
4936 temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1,
4937 OPTAB_WIDEN);
4938 emit_move_insn (gen_rtx_MEM (SImode, addr), temp1);
4941 #ifdef ENABLE_EXECUTE_STACK
4942 emit_library_call (init_one_libfunc ("__enable_execute_stack"),
4943 0, VOIDmode, 1, tramp, Pmode);
4944 #endif
4946 if (jmpofs >= 0)
4947 emit_insn (gen_imb ());
4950 /* Determine where to put an argument to a function.
4951 Value is zero to push the argument on the stack,
4952 or a hard register in which to store the argument.
4954 MODE is the argument's machine mode.
4955 TYPE is the data type of the argument (as a tree).
4956 This is null for libcalls where that information may
4957 not be available.
4958 CUM is a variable of type CUMULATIVE_ARGS which gives info about
4959 the preceding args and about the function being called.
4960 NAMED is nonzero if this argument is a named parameter
4961 (otherwise it is an extra parameter matching an ellipsis).
4963 On Alpha the first 6 words of args are normally in registers
4964 and the rest are pushed. */
4967 function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode, tree type,
4968 int named ATTRIBUTE_UNUSED)
4970 int basereg;
4971 int num_args;
4973 /* Don't get confused and pass small structures in FP registers. */
4974 if (type && AGGREGATE_TYPE_P (type))
4975 basereg = 16;
4976 else
4978 #ifdef ENABLE_CHECKING
4979 /* With alpha_split_complex_arg, we shouldn't see any raw complex
4980 values here. */
4981 if (COMPLEX_MODE_P (mode))
4982 abort ();
4983 #endif
4985 /* Set up defaults for FP operands passed in FP registers, and
4986 integral operands passed in integer registers. */
4987 if (TARGET_FPREGS && GET_MODE_CLASS (mode) == MODE_FLOAT)
4988 basereg = 32 + 16;
4989 else
4990 basereg = 16;
4993 /* ??? Irritatingly, the definition of CUMULATIVE_ARGS is different for
4994 the three platforms, so we can't avoid conditional compilation. */
4995 #if TARGET_ABI_OPEN_VMS
4997 if (mode == VOIDmode)
4998 return alpha_arg_info_reg_val (cum);
5000 num_args = cum.num_args;
5001 if (num_args >= 6
5002 || targetm.calls.must_pass_in_stack (mode, type))
5003 return NULL_RTX;
5005 #elif TARGET_ABI_UNICOSMK
5007 int size;
5009 /* If this is the last argument, generate the call info word (CIW). */
5010 /* ??? We don't include the caller's line number in the CIW because
5011 I don't know how to determine it if debug infos are turned off. */
5012 if (mode == VOIDmode)
5014 int i;
5015 HOST_WIDE_INT lo;
5016 HOST_WIDE_INT hi;
5017 rtx ciw;
5019 lo = 0;
5021 for (i = 0; i < cum.num_reg_words && i < 5; i++)
5022 if (cum.reg_args_type[i])
5023 lo |= (1 << (7 - i));
5025 if (cum.num_reg_words == 6 && cum.reg_args_type[5])
5026 lo |= 7;
5027 else
5028 lo |= cum.num_reg_words;
5030 #if HOST_BITS_PER_WIDE_INT == 32
5031 hi = (cum.num_args << 20) | cum.num_arg_words;
5032 #else
5033 lo = lo | ((HOST_WIDE_INT) cum.num_args << 52)
5034 | ((HOST_WIDE_INT) cum.num_arg_words << 32);
5035 hi = 0;
5036 #endif
5037 ciw = immed_double_const (lo, hi, DImode);
5039 return gen_rtx_UNSPEC (DImode, gen_rtvec (1, ciw),
5040 UNSPEC_UMK_LOAD_CIW);
5043 size = ALPHA_ARG_SIZE (mode, type, named);
5044 num_args = cum.num_reg_words;
5045 if (cum.force_stack
5046 || cum.num_reg_words + size > 6
5047 || targetm.calls.must_pass_in_stack (mode, type))
5048 return NULL_RTX;
5049 else if (type && TYPE_MODE (type) == BLKmode)
5051 rtx reg1, reg2;
5053 reg1 = gen_rtx_REG (DImode, num_args + 16);
5054 reg1 = gen_rtx_EXPR_LIST (DImode, reg1, const0_rtx);
5056 /* The argument fits in two registers. Note that we still need to
5057 reserve a register for empty structures. */
5058 if (size == 0)
5059 return NULL_RTX;
5060 else if (size == 1)
5061 return gen_rtx_PARALLEL (mode, gen_rtvec (1, reg1));
5062 else
5064 reg2 = gen_rtx_REG (DImode, num_args + 17);
5065 reg2 = gen_rtx_EXPR_LIST (DImode, reg2, GEN_INT (8));
5066 return gen_rtx_PARALLEL (mode, gen_rtvec (2, reg1, reg2));
5070 #elif TARGET_ABI_OSF
5072 if (cum >= 6)
5073 return NULL_RTX;
5074 num_args = cum;
5076 /* VOID is passed as a special flag for "last argument". */
5077 if (type == void_type_node)
5078 basereg = 16;
5079 else if (targetm.calls.must_pass_in_stack (mode, type))
5080 return NULL_RTX;
5082 #else
5083 #error Unhandled ABI
5084 #endif
5086 return gen_rtx_REG (mode, num_args + basereg);
5089 /* Return true if TYPE must be returned in memory, instead of in registers. */
5091 static bool
5092 alpha_return_in_memory (tree type, tree fndecl ATTRIBUTE_UNUSED)
5094 enum machine_mode mode = VOIDmode;
5095 int size;
5097 if (type)
5099 mode = TYPE_MODE (type);
5101 /* All aggregates are returned in memory. */
5102 if (AGGREGATE_TYPE_P (type))
5103 return true;
5106 size = GET_MODE_SIZE (mode);
5107 switch (GET_MODE_CLASS (mode))
5109 case MODE_VECTOR_FLOAT:
5110 /* Pass all float vectors in memory, like an aggregate. */
5111 return true;
5113 case MODE_COMPLEX_FLOAT:
5114 /* We judge complex floats on the size of their element,
5115 not the size of the whole type. */
5116 size = GET_MODE_UNIT_SIZE (mode);
5117 break;
5119 case MODE_INT:
5120 case MODE_FLOAT:
5121 case MODE_COMPLEX_INT:
5122 case MODE_VECTOR_INT:
5123 break;
5125 default:
5126 /* ??? We get called on all sorts of random stuff from
5127 aggregate_value_p. We can't abort, but it's not clear
5128 what's safe to return. Pretend it's a struct I guess. */
5129 return true;
5132 /* Otherwise types must fit in one register. */
5133 return size > UNITS_PER_WORD;
5136 /* Return true if TYPE should be passed by invisible reference. */
5138 static bool
5139 alpha_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
5140 enum machine_mode mode,
5141 tree type ATTRIBUTE_UNUSED,
5142 bool named ATTRIBUTE_UNUSED)
5144 return mode == TFmode || mode == TCmode;
5147 /* Define how to find the value returned by a function. VALTYPE is the
5148 data type of the value (as a tree). If the precise function being
5149 called is known, FUNC is its FUNCTION_DECL; otherwise, FUNC is 0.
5150 MODE is set instead of VALTYPE for libcalls.
5152 On Alpha the value is found in $0 for integer functions and
5153 $f0 for floating-point functions. */
5156 function_value (tree valtype, tree func ATTRIBUTE_UNUSED,
5157 enum machine_mode mode)
5159 unsigned int regnum, dummy;
5160 enum mode_class class;
5162 #ifdef ENABLE_CHECKING
5163 if (valtype && alpha_return_in_memory (valtype, func))
5164 abort ();
5165 #endif
5167 if (valtype)
5168 mode = TYPE_MODE (valtype);
5170 class = GET_MODE_CLASS (mode);
5171 switch (class)
5173 case MODE_INT:
5174 PROMOTE_MODE (mode, dummy, valtype);
5175 /* FALLTHRU */
5177 case MODE_COMPLEX_INT:
5178 case MODE_VECTOR_INT:
5179 regnum = 0;
5180 break;
5182 case MODE_FLOAT:
5183 regnum = 32;
5184 break;
5186 case MODE_COMPLEX_FLOAT:
5188 enum machine_mode cmode = GET_MODE_INNER (mode);
5190 return gen_rtx_PARALLEL
5191 (VOIDmode,
5192 gen_rtvec (2,
5193 gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (cmode, 32),
5194 const0_rtx),
5195 gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (cmode, 33),
5196 GEN_INT (GET_MODE_SIZE (cmode)))));
5199 default:
5200 abort ();
5203 return gen_rtx_REG (mode, regnum);
5206 /* TCmode complex values are passed by invisible reference. We
5207 should not split these values. */
5209 static bool
5210 alpha_split_complex_arg (tree type)
5212 return TYPE_MODE (type) != TCmode;
5215 static tree
5216 alpha_build_builtin_va_list (void)
5218 tree base, ofs, space, record, type_decl;
5220 if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK)
5221 return ptr_type_node;
5223 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
5224 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
5225 TREE_CHAIN (record) = type_decl;
5226 TYPE_NAME (record) = type_decl;
5228 /* C++? SET_IS_AGGR_TYPE (record, 1); */
5230 /* Dummy field to prevent alignment warnings. */
5231 space = build_decl (FIELD_DECL, NULL_TREE, integer_type_node);
5232 DECL_FIELD_CONTEXT (space) = record;
5233 DECL_ARTIFICIAL (space) = 1;
5234 DECL_IGNORED_P (space) = 1;
5236 ofs = build_decl (FIELD_DECL, get_identifier ("__offset"),
5237 integer_type_node);
5238 DECL_FIELD_CONTEXT (ofs) = record;
5239 TREE_CHAIN (ofs) = space;
5241 base = build_decl (FIELD_DECL, get_identifier ("__base"),
5242 ptr_type_node);
5243 DECL_FIELD_CONTEXT (base) = record;
5244 TREE_CHAIN (base) = ofs;
5246 TYPE_FIELDS (record) = base;
5247 layout_type (record);
5249 return record;
5252 /* Perform any needed actions needed for a function that is receiving a
5253 variable number of arguments. */
5255 static void
5256 alpha_setup_incoming_varargs (CUMULATIVE_ARGS *pcum,
5257 enum machine_mode mode ATTRIBUTE_UNUSED,
5258 tree type ATTRIBUTE_UNUSED,
5259 int *pretend_size, int no_rtl)
5261 #if TARGET_ABI_UNICOSMK
5262 /* On Unicos/Mk, the standard subroutine __T3E_MISMATCH stores all register
5263 arguments on the stack. Unfortunately, it doesn't always store the first
5264 one (i.e. the one that arrives in $16 or $f16). This is not a problem
5265 with stdargs as we always have at least one named argument there. */
5266 int num_reg_words = pcum->num_reg_words;
5267 if (num_reg_words < 6)
5269 if (!no_rtl)
5271 emit_insn (gen_umk_mismatch_args (GEN_INT (num_reg_words + 1)));
5272 emit_insn (gen_arg_home_umk ());
5274 *pretend_size = 0;
5276 #elif TARGET_ABI_OPEN_VMS
5277 /* For VMS, we allocate space for all 6 arg registers plus a count.
5279 However, if NO registers need to be saved, don't allocate any space.
5280 This is not only because we won't need the space, but because AP
5281 includes the current_pretend_args_size and we don't want to mess up
5282 any ap-relative addresses already made. */
5283 if (pcum->num_args < 6)
5285 if (!no_rtl)
5287 emit_move_insn (gen_rtx_REG (DImode, 1), virtual_incoming_args_rtx);
5288 emit_insn (gen_arg_home ());
5290 *pretend_size = 7 * UNITS_PER_WORD;
5292 #else
5293 /* On OSF/1 and friends, we allocate space for all 12 arg registers, but
5294 only push those that are remaining. However, if NO registers need to
5295 be saved, don't allocate any space. This is not only because we won't
5296 need the space, but because AP includes the current_pretend_args_size
5297 and we don't want to mess up any ap-relative addresses already made.
5299 If we are not to use the floating-point registers, save the integer
5300 registers where we would put the floating-point registers. This is
5301 not the most efficient way to implement varargs with just one register
5302 class, but it isn't worth doing anything more efficient in this rare
5303 case. */
5304 CUMULATIVE_ARGS cum = *pcum;
5306 if (cum >= 6)
5307 return;
5309 if (!no_rtl)
5311 int set = get_varargs_alias_set ();
5312 rtx tmp;
5314 tmp = gen_rtx_MEM (BLKmode,
5315 plus_constant (virtual_incoming_args_rtx,
5316 (cum + 6) * UNITS_PER_WORD));
5317 set_mem_alias_set (tmp, set);
5318 move_block_from_reg (16 + cum, tmp, 6 - cum);
5320 tmp = gen_rtx_MEM (BLKmode,
5321 plus_constant (virtual_incoming_args_rtx,
5322 cum * UNITS_PER_WORD));
5323 set_mem_alias_set (tmp, set);
5324 move_block_from_reg (16 + (TARGET_FPREGS ? 32 : 0) + cum, tmp,
5325 6 - cum);
5327 *pretend_size = 12 * UNITS_PER_WORD;
5328 #endif
5331 void
5332 alpha_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
5334 HOST_WIDE_INT offset;
5335 tree t, offset_field, base_field;
5337 if (TREE_CODE (TREE_TYPE (valist)) == ERROR_MARK)
5338 return;
5340 if (TARGET_ABI_UNICOSMK)
5341 std_expand_builtin_va_start (valist, nextarg);
5343 /* For Unix, TARGET_SETUP_INCOMING_VARARGS moves the starting address base
5344 up by 48, storing fp arg registers in the first 48 bytes, and the
5345 integer arg registers in the next 48 bytes. This is only done,
5346 however, if any integer registers need to be stored.
5348 If no integer registers need be stored, then we must subtract 48
5349 in order to account for the integer arg registers which are counted
5350 in argsize above, but which are not actually stored on the stack.
5351 Must further be careful here about structures straddling the last
5352 integer argument register; that futzes with pretend_args_size,
5353 which changes the meaning of AP. */
5355 if (NUM_ARGS <= 6)
5356 offset = TARGET_ABI_OPEN_VMS ? UNITS_PER_WORD : 6 * UNITS_PER_WORD;
5357 else
5358 offset = -6 * UNITS_PER_WORD + current_function_pretend_args_size;
5360 if (TARGET_ABI_OPEN_VMS)
5362 nextarg = plus_constant (nextarg, offset);
5363 nextarg = plus_constant (nextarg, NUM_ARGS * UNITS_PER_WORD);
5364 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
5365 make_tree (ptr_type_node, nextarg));
5366 TREE_SIDE_EFFECTS (t) = 1;
5368 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5370 else
5372 base_field = TYPE_FIELDS (TREE_TYPE (valist));
5373 offset_field = TREE_CHAIN (base_field);
5375 base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
5376 valist, base_field, NULL_TREE);
5377 offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
5378 valist, offset_field, NULL_TREE);
5380 t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
5381 t = build (PLUS_EXPR, ptr_type_node, t,
5382 build_int_cst (NULL_TREE, offset, 0));
5383 t = build (MODIFY_EXPR, TREE_TYPE (base_field), base_field, t);
5384 TREE_SIDE_EFFECTS (t) = 1;
5385 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5387 t = build_int_cst (NULL_TREE, NUM_ARGS * UNITS_PER_WORD, 0);
5388 t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field, t);
5389 TREE_SIDE_EFFECTS (t) = 1;
5390 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5394 static tree
5395 alpha_gimplify_va_arg_1 (tree type, tree base, tree offset, tree *pre_p)
5397 tree type_size, ptr_type, addend, t, addr, internal_post;
5399 /* If the type could not be passed in registers, skip the block
5400 reserved for the registers. */
5401 if (targetm.calls.must_pass_in_stack (TYPE_MODE (type), type))
5403 t = build_int_cst (TREE_TYPE (offset), 6*8, 0);
5404 t = build (MODIFY_EXPR, TREE_TYPE (offset), offset,
5405 build (MAX_EXPR, TREE_TYPE (offset), offset, t));
5406 gimplify_and_add (t, pre_p);
5409 addend = offset;
5410 ptr_type = build_pointer_type (type);
5412 if (TREE_CODE (type) == COMPLEX_TYPE)
5414 tree real_part, imag_part, real_temp;
5416 real_part = alpha_gimplify_va_arg_1 (TREE_TYPE (type), base,
5417 offset, pre_p);
5419 /* Copy the value into a new temporary, lest the formal temporary
5420 be reused out from under us. */
5421 real_temp = get_initialized_tmp_var (real_part, pre_p, NULL);
5423 imag_part = alpha_gimplify_va_arg_1 (TREE_TYPE (type), base,
5424 offset, pre_p);
5426 return build (COMPLEX_EXPR, type, real_temp, imag_part);
5428 else if (TREE_CODE (type) == REAL_TYPE)
5430 tree fpaddend, cond, fourtyeight;
5432 fourtyeight = build_int_cst (TREE_TYPE (addend), 6*8, 0);
5433 fpaddend = fold (build (MINUS_EXPR, TREE_TYPE (addend),
5434 addend, fourtyeight));
5435 cond = fold (build (LT_EXPR, boolean_type_node, addend, fourtyeight));
5436 addend = fold (build (COND_EXPR, TREE_TYPE (addend), cond,
5437 fpaddend, addend));
5440 /* Build the final address and force that value into a temporary. */
5441 addr = build (PLUS_EXPR, ptr_type, fold_convert (ptr_type, base),
5442 fold_convert (ptr_type, addend));
5443 internal_post = NULL;
5444 gimplify_expr (&addr, pre_p, &internal_post, is_gimple_val, fb_rvalue);
5445 append_to_statement_list (internal_post, pre_p);
5447 /* Update the offset field. */
5448 type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type));
5449 if (type_size == NULL || TREE_OVERFLOW (type_size))
5450 t = size_zero_node;
5451 else
5453 t = size_binop (PLUS_EXPR, type_size, size_int (7));
5454 t = size_binop (TRUNC_DIV_EXPR, t, size_int (8));
5455 t = size_binop (MULT_EXPR, t, size_int (8));
5457 t = fold_convert (TREE_TYPE (offset), t);
5458 t = build (MODIFY_EXPR, void_type_node, offset,
5459 build (PLUS_EXPR, TREE_TYPE (offset), offset, t));
5460 gimplify_and_add (t, pre_p);
5462 return build_fold_indirect_ref (addr);
5465 static tree
5466 alpha_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
5468 tree offset_field, base_field, offset, base, t, r;
5469 bool indirect;
5471 if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK)
5472 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
5474 base_field = TYPE_FIELDS (va_list_type_node);
5475 offset_field = TREE_CHAIN (base_field);
5476 base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
5477 valist, base_field, NULL_TREE);
5478 offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
5479 valist, offset_field, NULL_TREE);
5481 /* Pull the fields of the structure out into temporaries. Since we never
5482 modify the base field, we can use a formal temporary. Sign-extend the
5483 offset field so that it's the proper width for pointer arithmetic. */
5484 base = get_formal_tmp_var (base_field, pre_p);
5486 t = fold_convert (lang_hooks.types.type_for_size (64, 0), offset_field);
5487 offset = get_initialized_tmp_var (t, pre_p, NULL);
5489 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
5490 if (indirect)
5491 type = build_pointer_type (type);
5493 /* Find the value. Note that this will be a stable indirection, or
5494 a composite of stable indirections in the case of complex. */
5495 r = alpha_gimplify_va_arg_1 (type, base, offset, pre_p);
5497 /* Stuff the offset temporary back into its field. */
5498 t = build (MODIFY_EXPR, void_type_node, offset_field,
5499 fold_convert (TREE_TYPE (offset_field), offset));
5500 gimplify_and_add (t, pre_p);
5502 if (indirect)
5503 r = build_fold_indirect_ref (r);
5505 return r;
5508 /* Builtins. */
5510 enum alpha_builtin
5512 ALPHA_BUILTIN_CMPBGE,
5513 ALPHA_BUILTIN_EXTBL,
5514 ALPHA_BUILTIN_EXTWL,
5515 ALPHA_BUILTIN_EXTLL,
5516 ALPHA_BUILTIN_EXTQL,
5517 ALPHA_BUILTIN_EXTWH,
5518 ALPHA_BUILTIN_EXTLH,
5519 ALPHA_BUILTIN_EXTQH,
5520 ALPHA_BUILTIN_INSBL,
5521 ALPHA_BUILTIN_INSWL,
5522 ALPHA_BUILTIN_INSLL,
5523 ALPHA_BUILTIN_INSQL,
5524 ALPHA_BUILTIN_INSWH,
5525 ALPHA_BUILTIN_INSLH,
5526 ALPHA_BUILTIN_INSQH,
5527 ALPHA_BUILTIN_MSKBL,
5528 ALPHA_BUILTIN_MSKWL,
5529 ALPHA_BUILTIN_MSKLL,
5530 ALPHA_BUILTIN_MSKQL,
5531 ALPHA_BUILTIN_MSKWH,
5532 ALPHA_BUILTIN_MSKLH,
5533 ALPHA_BUILTIN_MSKQH,
5534 ALPHA_BUILTIN_UMULH,
5535 ALPHA_BUILTIN_ZAP,
5536 ALPHA_BUILTIN_ZAPNOT,
5537 ALPHA_BUILTIN_AMASK,
5538 ALPHA_BUILTIN_IMPLVER,
5539 ALPHA_BUILTIN_RPCC,
5540 ALPHA_BUILTIN_THREAD_POINTER,
5541 ALPHA_BUILTIN_SET_THREAD_POINTER,
5543 /* TARGET_MAX */
5544 ALPHA_BUILTIN_MINUB8,
5545 ALPHA_BUILTIN_MINSB8,
5546 ALPHA_BUILTIN_MINUW4,
5547 ALPHA_BUILTIN_MINSW4,
5548 ALPHA_BUILTIN_MAXUB8,
5549 ALPHA_BUILTIN_MAXSB8,
5550 ALPHA_BUILTIN_MAXUW4,
5551 ALPHA_BUILTIN_MAXSW4,
5552 ALPHA_BUILTIN_PERR,
5553 ALPHA_BUILTIN_PKLB,
5554 ALPHA_BUILTIN_PKWB,
5555 ALPHA_BUILTIN_UNPKBL,
5556 ALPHA_BUILTIN_UNPKBW,
5558 /* TARGET_CIX */
5559 ALPHA_BUILTIN_CTTZ,
5560 ALPHA_BUILTIN_CTLZ,
5561 ALPHA_BUILTIN_CTPOP,
5563 ALPHA_BUILTIN_max
5566 static unsigned int const code_for_builtin[ALPHA_BUILTIN_max] = {
5567 CODE_FOR_builtin_cmpbge,
5568 CODE_FOR_builtin_extbl,
5569 CODE_FOR_builtin_extwl,
5570 CODE_FOR_builtin_extll,
5571 CODE_FOR_builtin_extql,
5572 CODE_FOR_builtin_extwh,
5573 CODE_FOR_builtin_extlh,
5574 CODE_FOR_builtin_extqh,
5575 CODE_FOR_builtin_insbl,
5576 CODE_FOR_builtin_inswl,
5577 CODE_FOR_builtin_insll,
5578 CODE_FOR_builtin_insql,
5579 CODE_FOR_builtin_inswh,
5580 CODE_FOR_builtin_inslh,
5581 CODE_FOR_builtin_insqh,
5582 CODE_FOR_builtin_mskbl,
5583 CODE_FOR_builtin_mskwl,
5584 CODE_FOR_builtin_mskll,
5585 CODE_FOR_builtin_mskql,
5586 CODE_FOR_builtin_mskwh,
5587 CODE_FOR_builtin_msklh,
5588 CODE_FOR_builtin_mskqh,
5589 CODE_FOR_umuldi3_highpart,
5590 CODE_FOR_builtin_zap,
5591 CODE_FOR_builtin_zapnot,
5592 CODE_FOR_builtin_amask,
5593 CODE_FOR_builtin_implver,
5594 CODE_FOR_builtin_rpcc,
5595 CODE_FOR_load_tp,
5596 CODE_FOR_set_tp,
5598 /* TARGET_MAX */
5599 CODE_FOR_builtin_minub8,
5600 CODE_FOR_builtin_minsb8,
5601 CODE_FOR_builtin_minuw4,
5602 CODE_FOR_builtin_minsw4,
5603 CODE_FOR_builtin_maxub8,
5604 CODE_FOR_builtin_maxsb8,
5605 CODE_FOR_builtin_maxuw4,
5606 CODE_FOR_builtin_maxsw4,
5607 CODE_FOR_builtin_perr,
5608 CODE_FOR_builtin_pklb,
5609 CODE_FOR_builtin_pkwb,
5610 CODE_FOR_builtin_unpkbl,
5611 CODE_FOR_builtin_unpkbw,
5613 /* TARGET_CIX */
5614 CODE_FOR_builtin_cttz,
5615 CODE_FOR_builtin_ctlz,
5616 CODE_FOR_builtin_ctpop
5619 struct alpha_builtin_def
5621 const char *name;
5622 enum alpha_builtin code;
5623 unsigned int target_mask;
5626 static struct alpha_builtin_def const zero_arg_builtins[] = {
5627 { "__builtin_alpha_implver", ALPHA_BUILTIN_IMPLVER, 0 },
5628 { "__builtin_alpha_rpcc", ALPHA_BUILTIN_RPCC, 0 }
5631 static struct alpha_builtin_def const one_arg_builtins[] = {
5632 { "__builtin_alpha_amask", ALPHA_BUILTIN_AMASK, 0 },
5633 { "__builtin_alpha_pklb", ALPHA_BUILTIN_PKLB, MASK_MAX },
5634 { "__builtin_alpha_pkwb", ALPHA_BUILTIN_PKWB, MASK_MAX },
5635 { "__builtin_alpha_unpkbl", ALPHA_BUILTIN_UNPKBL, MASK_MAX },
5636 { "__builtin_alpha_unpkbw", ALPHA_BUILTIN_UNPKBW, MASK_MAX },
5637 { "__builtin_alpha_cttz", ALPHA_BUILTIN_CTTZ, MASK_CIX },
5638 { "__builtin_alpha_ctlz", ALPHA_BUILTIN_CTLZ, MASK_CIX },
5639 { "__builtin_alpha_ctpop", ALPHA_BUILTIN_CTPOP, MASK_CIX }
5642 static struct alpha_builtin_def const two_arg_builtins[] = {
5643 { "__builtin_alpha_cmpbge", ALPHA_BUILTIN_CMPBGE, 0 },
5644 { "__builtin_alpha_extbl", ALPHA_BUILTIN_EXTBL, 0 },
5645 { "__builtin_alpha_extwl", ALPHA_BUILTIN_EXTWL, 0 },
5646 { "__builtin_alpha_extll", ALPHA_BUILTIN_EXTLL, 0 },
5647 { "__builtin_alpha_extql", ALPHA_BUILTIN_EXTQL, 0 },
5648 { "__builtin_alpha_extwh", ALPHA_BUILTIN_EXTWH, 0 },
5649 { "__builtin_alpha_extlh", ALPHA_BUILTIN_EXTLH, 0 },
5650 { "__builtin_alpha_extqh", ALPHA_BUILTIN_EXTQH, 0 },
5651 { "__builtin_alpha_insbl", ALPHA_BUILTIN_INSBL, 0 },
5652 { "__builtin_alpha_inswl", ALPHA_BUILTIN_INSWL, 0 },
5653 { "__builtin_alpha_insll", ALPHA_BUILTIN_INSLL, 0 },
5654 { "__builtin_alpha_insql", ALPHA_BUILTIN_INSQL, 0 },
5655 { "__builtin_alpha_inswh", ALPHA_BUILTIN_INSWH, 0 },
5656 { "__builtin_alpha_inslh", ALPHA_BUILTIN_INSLH, 0 },
5657 { "__builtin_alpha_insqh", ALPHA_BUILTIN_INSQH, 0 },
5658 { "__builtin_alpha_mskbl", ALPHA_BUILTIN_MSKBL, 0 },
5659 { "__builtin_alpha_mskwl", ALPHA_BUILTIN_MSKWL, 0 },
5660 { "__builtin_alpha_mskll", ALPHA_BUILTIN_MSKLL, 0 },
5661 { "__builtin_alpha_mskql", ALPHA_BUILTIN_MSKQL, 0 },
5662 { "__builtin_alpha_mskwh", ALPHA_BUILTIN_MSKWH, 0 },
5663 { "__builtin_alpha_msklh", ALPHA_BUILTIN_MSKLH, 0 },
5664 { "__builtin_alpha_mskqh", ALPHA_BUILTIN_MSKQH, 0 },
5665 { "__builtin_alpha_umulh", ALPHA_BUILTIN_UMULH, 0 },
5666 { "__builtin_alpha_zap", ALPHA_BUILTIN_ZAP, 0 },
5667 { "__builtin_alpha_zapnot", ALPHA_BUILTIN_ZAPNOT, 0 },
5668 { "__builtin_alpha_minub8", ALPHA_BUILTIN_MINUB8, MASK_MAX },
5669 { "__builtin_alpha_minsb8", ALPHA_BUILTIN_MINSB8, MASK_MAX },
5670 { "__builtin_alpha_minuw4", ALPHA_BUILTIN_MINUW4, MASK_MAX },
5671 { "__builtin_alpha_minsw4", ALPHA_BUILTIN_MINSW4, MASK_MAX },
5672 { "__builtin_alpha_maxub8", ALPHA_BUILTIN_MAXUB8, MASK_MAX },
5673 { "__builtin_alpha_maxsb8", ALPHA_BUILTIN_MAXSB8, MASK_MAX },
5674 { "__builtin_alpha_maxuw4", ALPHA_BUILTIN_MAXUW4, MASK_MAX },
5675 { "__builtin_alpha_maxsw4", ALPHA_BUILTIN_MAXSW4, MASK_MAX },
5676 { "__builtin_alpha_perr", ALPHA_BUILTIN_PERR, MASK_MAX }
5679 static void
5680 alpha_init_builtins (void)
5682 const struct alpha_builtin_def *p;
5683 tree ftype;
5684 size_t i;
5686 ftype = build_function_type (long_integer_type_node, void_list_node);
5688 p = zero_arg_builtins;
5689 for (i = 0; i < ARRAY_SIZE (zero_arg_builtins); ++i, ++p)
5690 if ((target_flags & p->target_mask) == p->target_mask)
5691 lang_hooks.builtin_function (p->name, ftype, p->code, BUILT_IN_MD,
5692 NULL, NULL_TREE);
5694 ftype = build_function_type_list (long_integer_type_node,
5695 long_integer_type_node, NULL_TREE);
5697 p = one_arg_builtins;
5698 for (i = 0; i < ARRAY_SIZE (one_arg_builtins); ++i, ++p)
5699 if ((target_flags & p->target_mask) == p->target_mask)
5700 lang_hooks.builtin_function (p->name, ftype, p->code, BUILT_IN_MD,
5701 NULL, NULL_TREE);
5703 ftype = build_function_type_list (long_integer_type_node,
5704 long_integer_type_node,
5705 long_integer_type_node, NULL_TREE);
5707 p = two_arg_builtins;
5708 for (i = 0; i < ARRAY_SIZE (two_arg_builtins); ++i, ++p)
5709 if ((target_flags & p->target_mask) == p->target_mask)
5710 lang_hooks.builtin_function (p->name, ftype, p->code, BUILT_IN_MD,
5711 NULL, NULL_TREE);
5713 ftype = build_function_type (ptr_type_node, void_list_node);
5714 lang_hooks.builtin_function ("__builtin_thread_pointer", ftype,
5715 ALPHA_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
5716 NULL, NULL_TREE);
5718 ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
5719 lang_hooks.builtin_function ("__builtin_set_thread_pointer", ftype,
5720 ALPHA_BUILTIN_SET_THREAD_POINTER, BUILT_IN_MD,
5721 NULL, NULL_TREE);
5724 /* Expand an expression EXP that calls a built-in function,
5725 with result going to TARGET if that's convenient
5726 (and in mode MODE if that's convenient).
5727 SUBTARGET may be used as the target for computing one of EXP's operands.
5728 IGNORE is nonzero if the value is to be ignored. */
5730 static rtx
5731 alpha_expand_builtin (tree exp, rtx target,
5732 rtx subtarget ATTRIBUTE_UNUSED,
5733 enum machine_mode mode ATTRIBUTE_UNUSED,
5734 int ignore ATTRIBUTE_UNUSED)
5736 #define MAX_ARGS 2
5738 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
5739 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
5740 tree arglist = TREE_OPERAND (exp, 1);
5741 enum insn_code icode;
5742 rtx op[MAX_ARGS], pat;
5743 int arity;
5744 bool nonvoid;
5746 if (fcode >= ALPHA_BUILTIN_max)
5747 internal_error ("bad builtin fcode");
5748 icode = code_for_builtin[fcode];
5749 if (icode == 0)
5750 internal_error ("bad builtin fcode");
5752 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
5754 for (arglist = TREE_OPERAND (exp, 1), arity = 0;
5755 arglist;
5756 arglist = TREE_CHAIN (arglist), arity++)
5758 const struct insn_operand_data *insn_op;
5760 tree arg = TREE_VALUE (arglist);
5761 if (arg == error_mark_node)
5762 return NULL_RTX;
5763 if (arity > MAX_ARGS)
5764 return NULL_RTX;
5766 insn_op = &insn_data[icode].operand[arity + nonvoid];
5768 op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, 0);
5770 if (!(*insn_op->predicate) (op[arity], insn_op->mode))
5771 op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
5774 if (nonvoid)
5776 enum machine_mode tmode = insn_data[icode].operand[0].mode;
5777 if (!target
5778 || GET_MODE (target) != tmode
5779 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
5780 target = gen_reg_rtx (tmode);
5783 switch (arity)
5785 case 0:
5786 pat = GEN_FCN (icode) (target);
5787 break;
5788 case 1:
5789 if (nonvoid)
5790 pat = GEN_FCN (icode) (target, op[0]);
5791 else
5792 pat = GEN_FCN (icode) (op[0]);
5793 break;
5794 case 2:
5795 pat = GEN_FCN (icode) (target, op[0], op[1]);
5796 break;
5797 default:
5798 abort ();
5800 if (!pat)
5801 return NULL_RTX;
5802 emit_insn (pat);
5804 if (nonvoid)
5805 return target;
5806 else
5807 return const0_rtx;
5810 /* This page contains routines that are used to determine what the function
5811 prologue and epilogue code will do and write them out. */
5813 /* Compute the size of the save area in the stack. */
5815 /* These variables are used for communication between the following functions.
5816 They indicate various things about the current function being compiled
5817 that are used to tell what kind of prologue, epilogue and procedure
5818 descriptor to generate. */
5820 /* Nonzero if we need a stack procedure. */
5821 enum alpha_procedure_types {PT_NULL = 0, PT_REGISTER = 1, PT_STACK = 2};
5822 static enum alpha_procedure_types alpha_procedure_type;
5824 /* Register number (either FP or SP) that is used to unwind the frame. */
5825 static int vms_unwind_regno;
5827 /* Register number used to save FP. We need not have one for RA since
5828 we don't modify it for register procedures. This is only defined
5829 for register frame procedures. */
5830 static int vms_save_fp_regno;
5832 /* Register number used to reference objects off our PV. */
5833 static int vms_base_regno;
5835 /* Compute register masks for saved registers. */
5837 static void
5838 alpha_sa_mask (unsigned long *imaskP, unsigned long *fmaskP)
5840 unsigned long imask = 0;
5841 unsigned long fmask = 0;
5842 unsigned int i;
5844 /* When outputting a thunk, we don't have valid register life info,
5845 but assemble_start_function wants to output .frame and .mask
5846 directives. */
5847 if (current_function_is_thunk)
5849 *imaskP = 0;
5850 *fmaskP = 0;
5851 return;
5854 if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
5855 imask |= (1UL << HARD_FRAME_POINTER_REGNUM);
5857 /* One for every register we have to save. */
5858 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
5859 if (! fixed_regs[i] && ! call_used_regs[i]
5860 && regs_ever_live[i] && i != REG_RA
5861 && (!TARGET_ABI_UNICOSMK || i != HARD_FRAME_POINTER_REGNUM))
5863 if (i < 32)
5864 imask |= (1UL << i);
5865 else
5866 fmask |= (1UL << (i - 32));
5869 /* We need to restore these for the handler. */
5870 if (current_function_calls_eh_return)
5872 for (i = 0; ; ++i)
5874 unsigned regno = EH_RETURN_DATA_REGNO (i);
5875 if (regno == INVALID_REGNUM)
5876 break;
5877 imask |= 1UL << regno;
5880 /* Glibc likes to use $31 as an unwind stopper for crt0. To
5881 avoid hackery in unwind-dw2.c, we need to actively store a
5882 zero in the prologue of _Unwind_RaiseException et al. */
5883 imask |= 1UL << 31;
5886 /* If any register spilled, then spill the return address also. */
5887 /* ??? This is required by the Digital stack unwind specification
5888 and isn't needed if we're doing Dwarf2 unwinding. */
5889 if (imask || fmask || alpha_ra_ever_killed ())
5890 imask |= (1UL << REG_RA);
5892 *imaskP = imask;
5893 *fmaskP = fmask;
5897 alpha_sa_size (void)
5899 unsigned long mask[2];
5900 int sa_size = 0;
5901 int i, j;
5903 alpha_sa_mask (&mask[0], &mask[1]);
5905 if (TARGET_ABI_UNICOSMK)
5907 if (mask[0] || mask[1])
5908 sa_size = 14;
5910 else
5912 for (j = 0; j < 2; ++j)
5913 for (i = 0; i < 32; ++i)
5914 if ((mask[j] >> i) & 1)
5915 sa_size++;
5918 if (TARGET_ABI_UNICOSMK)
5920 /* We might not need to generate a frame if we don't make any calls
5921 (including calls to __T3E_MISMATCH if this is a vararg function),
5922 don't have any local variables which require stack slots, don't
5923 use alloca and have not determined that we need a frame for other
5924 reasons. */
5926 alpha_procedure_type
5927 = (sa_size || get_frame_size() != 0
5928 || current_function_outgoing_args_size
5929 || current_function_stdarg || current_function_calls_alloca
5930 || frame_pointer_needed)
5931 ? PT_STACK : PT_REGISTER;
5933 /* Always reserve space for saving callee-saved registers if we
5934 need a frame as required by the calling convention. */
5935 if (alpha_procedure_type == PT_STACK)
5936 sa_size = 14;
5938 else if (TARGET_ABI_OPEN_VMS)
5940 /* Start by assuming we can use a register procedure if we don't
5941 make any calls (REG_RA not used) or need to save any
5942 registers and a stack procedure if we do. */
5943 if ((mask[0] >> REG_RA) & 1)
5944 alpha_procedure_type = PT_STACK;
5945 else if (get_frame_size() != 0)
5946 alpha_procedure_type = PT_REGISTER;
5947 else
5948 alpha_procedure_type = PT_NULL;
5950 /* Don't reserve space for saving FP & RA yet. Do that later after we've
5951 made the final decision on stack procedure vs register procedure. */
5952 if (alpha_procedure_type == PT_STACK)
5953 sa_size -= 2;
5955 /* Decide whether to refer to objects off our PV via FP or PV.
5956 If we need FP for something else or if we receive a nonlocal
5957 goto (which expects PV to contain the value), we must use PV.
5958 Otherwise, start by assuming we can use FP. */
5960 vms_base_regno
5961 = (frame_pointer_needed
5962 || current_function_has_nonlocal_label
5963 || alpha_procedure_type == PT_STACK
5964 || current_function_outgoing_args_size)
5965 ? REG_PV : HARD_FRAME_POINTER_REGNUM;
5967 /* If we want to copy PV into FP, we need to find some register
5968 in which to save FP. */
5970 vms_save_fp_regno = -1;
5971 if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
5972 for (i = 0; i < 32; i++)
5973 if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
5974 vms_save_fp_regno = i;
5976 if (vms_save_fp_regno == -1 && alpha_procedure_type == PT_REGISTER)
5977 vms_base_regno = REG_PV, alpha_procedure_type = PT_STACK;
5978 else if (alpha_procedure_type == PT_NULL)
5979 vms_base_regno = REG_PV;
5981 /* Stack unwinding should be done via FP unless we use it for PV. */
5982 vms_unwind_regno = (vms_base_regno == REG_PV
5983 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
5985 /* If this is a stack procedure, allow space for saving FP and RA. */
5986 if (alpha_procedure_type == PT_STACK)
5987 sa_size += 2;
5989 else
5991 /* Our size must be even (multiple of 16 bytes). */
5992 if (sa_size & 1)
5993 sa_size++;
5996 return sa_size * 8;
5999 /* Define the offset between two registers, one to be eliminated,
6000 and the other its replacement, at the start of a routine. */
6002 HOST_WIDE_INT
6003 alpha_initial_elimination_offset (unsigned int from,
6004 unsigned int to ATTRIBUTE_UNUSED)
6006 HOST_WIDE_INT ret;
6008 ret = alpha_sa_size ();
6009 ret += ALPHA_ROUND (current_function_outgoing_args_size);
6011 if (from == FRAME_POINTER_REGNUM)
6013 else if (from == ARG_POINTER_REGNUM)
6014 ret += (ALPHA_ROUND (get_frame_size ()
6015 + current_function_pretend_args_size)
6016 - current_function_pretend_args_size);
6017 else
6018 abort ();
6020 return ret;
6024 alpha_pv_save_size (void)
6026 alpha_sa_size ();
6027 return alpha_procedure_type == PT_STACK ? 8 : 0;
6031 alpha_using_fp (void)
6033 alpha_sa_size ();
6034 return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM;
6037 #if TARGET_ABI_OPEN_VMS
6039 const struct attribute_spec vms_attribute_table[] =
6041 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
6042 { "overlaid", 0, 0, true, false, false, NULL },
6043 { "global", 0, 0, true, false, false, NULL },
6044 { "initialize", 0, 0, true, false, false, NULL },
6045 { NULL, 0, 0, false, false, false, NULL }
6048 #endif
6050 static int
6051 find_lo_sum_using_gp (rtx *px, void *data ATTRIBUTE_UNUSED)
6053 return GET_CODE (*px) == LO_SUM && XEXP (*px, 0) == pic_offset_table_rtx;
6057 alpha_find_lo_sum_using_gp (rtx insn)
6059 return for_each_rtx (&PATTERN (insn), find_lo_sum_using_gp, NULL) > 0;
6062 static int
6063 alpha_does_function_need_gp (void)
6065 rtx insn;
6067 /* The GP being variable is an OSF abi thing. */
6068 if (! TARGET_ABI_OSF)
6069 return 0;
6071 /* We need the gp to load the address of __mcount. */
6072 if (TARGET_PROFILING_NEEDS_GP && current_function_profile)
6073 return 1;
6075 /* The code emitted by alpha_output_mi_thunk_osf uses the gp. */
6076 if (current_function_is_thunk)
6077 return 1;
6079 /* The nonlocal receiver pattern assumes that the gp is valid for
6080 the nested function. Reasonable because it's almost always set
6081 correctly already. For the cases where that's wrong, make sure
6082 the nested function loads its gp on entry. */
6083 if (current_function_has_nonlocal_goto)
6084 return 1;
6086 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
6087 Even if we are a static function, we still need to do this in case
6088 our address is taken and passed to something like qsort. */
6090 push_topmost_sequence ();
6091 insn = get_insns ();
6092 pop_topmost_sequence ();
6094 for (; insn; insn = NEXT_INSN (insn))
6095 if (INSN_P (insn)
6096 && GET_CODE (PATTERN (insn)) != USE
6097 && GET_CODE (PATTERN (insn)) != CLOBBER
6098 && get_attr_usegp (insn))
6099 return 1;
6101 return 0;
6105 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
6106 sequences. */
6108 static rtx
6109 set_frame_related_p (void)
6111 rtx seq = get_insns ();
6112 rtx insn;
6114 end_sequence ();
6116 if (!seq)
6117 return NULL_RTX;
6119 if (INSN_P (seq))
6121 insn = seq;
6122 while (insn != NULL_RTX)
6124 RTX_FRAME_RELATED_P (insn) = 1;
6125 insn = NEXT_INSN (insn);
6127 seq = emit_insn (seq);
6129 else
6131 seq = emit_insn (seq);
6132 RTX_FRAME_RELATED_P (seq) = 1;
6134 return seq;
6137 #define FRP(exp) (start_sequence (), exp, set_frame_related_p ())
6139 /* Write function prologue. */
6141 /* On vms we have two kinds of functions:
6143 - stack frame (PROC_STACK)
6144 these are 'normal' functions with local vars and which are
6145 calling other functions
6146 - register frame (PROC_REGISTER)
6147 keeps all data in registers, needs no stack
6149 We must pass this to the assembler so it can generate the
6150 proper pdsc (procedure descriptor)
6151 This is done with the '.pdesc' command.
6153 On not-vms, we don't really differentiate between the two, as we can
6154 simply allocate stack without saving registers. */
6156 void
6157 alpha_expand_prologue (void)
6159 /* Registers to save. */
6160 unsigned long imask = 0;
6161 unsigned long fmask = 0;
6162 /* Stack space needed for pushing registers clobbered by us. */
6163 HOST_WIDE_INT sa_size;
6164 /* Complete stack size needed. */
6165 HOST_WIDE_INT frame_size;
6166 /* Offset from base reg to register save area. */
6167 HOST_WIDE_INT reg_offset;
6168 rtx sa_reg, mem;
6169 int i;
6171 sa_size = alpha_sa_size ();
6173 frame_size = get_frame_size ();
6174 if (TARGET_ABI_OPEN_VMS)
6175 frame_size = ALPHA_ROUND (sa_size
6176 + (alpha_procedure_type == PT_STACK ? 8 : 0)
6177 + frame_size
6178 + current_function_pretend_args_size);
6179 else if (TARGET_ABI_UNICOSMK)
6180 /* We have to allocate space for the DSIB if we generate a frame. */
6181 frame_size = ALPHA_ROUND (sa_size
6182 + (alpha_procedure_type == PT_STACK ? 48 : 0))
6183 + ALPHA_ROUND (frame_size
6184 + current_function_outgoing_args_size);
6185 else
6186 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
6187 + sa_size
6188 + ALPHA_ROUND (frame_size
6189 + current_function_pretend_args_size));
6191 if (TARGET_ABI_OPEN_VMS)
6192 reg_offset = 8;
6193 else
6194 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
6196 alpha_sa_mask (&imask, &fmask);
6198 /* Emit an insn to reload GP, if needed. */
6199 if (TARGET_ABI_OSF)
6201 alpha_function_needs_gp = alpha_does_function_need_gp ();
6202 if (alpha_function_needs_gp)
6203 emit_insn (gen_prologue_ldgp ());
6206 /* TARGET_PROFILING_NEEDS_GP actually implies that we need to insert
6207 the call to mcount ourselves, rather than having the linker do it
6208 magically in response to -pg. Since _mcount has special linkage,
6209 don't represent the call as a call. */
6210 if (TARGET_PROFILING_NEEDS_GP && current_function_profile)
6211 emit_insn (gen_prologue_mcount ());
6213 if (TARGET_ABI_UNICOSMK)
6214 unicosmk_gen_dsib (&imask);
6216 /* Adjust the stack by the frame size. If the frame size is > 4096
6217 bytes, we need to be sure we probe somewhere in the first and last
6218 4096 bytes (we can probably get away without the latter test) and
6219 every 8192 bytes in between. If the frame size is > 32768, we
6220 do this in a loop. Otherwise, we generate the explicit probe
6221 instructions.
6223 Note that we are only allowed to adjust sp once in the prologue. */
6225 if (frame_size <= 32768)
6227 if (frame_size > 4096)
6229 int probed = 4096;
6232 emit_insn (gen_probe_stack (GEN_INT (TARGET_ABI_UNICOSMK
6233 ? -probed + 64
6234 : -probed)));
6235 while ((probed += 8192) < frame_size);
6237 /* We only have to do this probe if we aren't saving registers. */
6238 if (sa_size == 0 && probed + 4096 < frame_size)
6239 emit_insn (gen_probe_stack (GEN_INT (-frame_size)));
6242 if (frame_size != 0)
6243 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
6244 GEN_INT (TARGET_ABI_UNICOSMK
6245 ? -frame_size + 64
6246 : -frame_size))));
6248 else
6250 /* Here we generate code to set R22 to SP + 4096 and set R23 to the
6251 number of 8192 byte blocks to probe. We then probe each block
6252 in the loop and then set SP to the proper location. If the
6253 amount remaining is > 4096, we have to do one more probe if we
6254 are not saving any registers. */
6256 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
6257 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
6258 rtx ptr = gen_rtx_REG (DImode, 22);
6259 rtx count = gen_rtx_REG (DImode, 23);
6260 rtx seq;
6262 emit_move_insn (count, GEN_INT (blocks));
6263 emit_insn (gen_adddi3 (ptr, stack_pointer_rtx,
6264 GEN_INT (TARGET_ABI_UNICOSMK ? 4096 - 64 : 4096)));
6266 /* Because of the difficulty in emitting a new basic block this
6267 late in the compilation, generate the loop as a single insn. */
6268 emit_insn (gen_prologue_stack_probe_loop (count, ptr));
6270 if (leftover > 4096 && sa_size == 0)
6272 rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover));
6273 MEM_VOLATILE_P (last) = 1;
6274 emit_move_insn (last, const0_rtx);
6277 if (TARGET_ABI_WINDOWS_NT)
6279 /* For NT stack unwind (done by 'reverse execution'), it's
6280 not OK to take the result of a loop, even though the value
6281 is already in ptr, so we reload it via a single operation
6282 and subtract it to sp.
6284 Yes, that's correct -- we have to reload the whole constant
6285 into a temporary via ldah+lda then subtract from sp. */
6287 HOST_WIDE_INT lo, hi;
6288 lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
6289 hi = frame_size - lo;
6291 emit_move_insn (ptr, GEN_INT (hi));
6292 emit_insn (gen_adddi3 (ptr, ptr, GEN_INT (lo)));
6293 seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
6294 ptr));
6296 else
6298 seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr,
6299 GEN_INT (-leftover)));
6302 /* This alternative is special, because the DWARF code cannot
6303 possibly intuit through the loop above. So we invent this
6304 note it looks at instead. */
6305 RTX_FRAME_RELATED_P (seq) = 1;
6306 REG_NOTES (seq)
6307 = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
6308 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
6309 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
6310 GEN_INT (TARGET_ABI_UNICOSMK
6311 ? -frame_size + 64
6312 : -frame_size))),
6313 REG_NOTES (seq));
6316 if (!TARGET_ABI_UNICOSMK)
6318 /* Cope with very large offsets to the register save area. */
6319 sa_reg = stack_pointer_rtx;
6320 if (reg_offset + sa_size > 0x8000)
6322 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
6323 HOST_WIDE_INT bias;
6325 if (low + sa_size <= 0x8000)
6326 bias = reg_offset - low, reg_offset = low;
6327 else
6328 bias = reg_offset, reg_offset = 0;
6330 sa_reg = gen_rtx_REG (DImode, 24);
6331 FRP (emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx,
6332 GEN_INT (bias))));
6335 /* Save regs in stack order. Beginning with VMS PV. */
6336 if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
6338 mem = gen_rtx_MEM (DImode, stack_pointer_rtx);
6339 set_mem_alias_set (mem, alpha_sr_alias_set);
6340 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_PV)));
6343 /* Save register RA next. */
6344 if (imask & (1UL << REG_RA))
6346 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
6347 set_mem_alias_set (mem, alpha_sr_alias_set);
6348 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
6349 imask &= ~(1UL << REG_RA);
6350 reg_offset += 8;
6353 /* Now save any other registers required to be saved. */
6354 for (i = 0; i < 31; i++)
6355 if (imask & (1UL << i))
6357 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
6358 set_mem_alias_set (mem, alpha_sr_alias_set);
6359 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, i)));
6360 reg_offset += 8;
6363 /* Store a zero if requested for unwinding. */
6364 if (imask & (1UL << 31))
6366 rtx insn, t;
6368 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
6369 set_mem_alias_set (mem, alpha_sr_alias_set);
6370 insn = emit_move_insn (mem, const0_rtx);
6372 RTX_FRAME_RELATED_P (insn) = 1;
6373 t = gen_rtx_REG (Pmode, 31);
6374 t = gen_rtx_SET (VOIDmode, mem, t);
6375 t = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, t, REG_NOTES (insn));
6376 REG_NOTES (insn) = t;
6378 reg_offset += 8;
6381 for (i = 0; i < 31; i++)
6382 if (fmask & (1UL << i))
6384 mem = gen_rtx_MEM (DFmode, plus_constant (sa_reg, reg_offset));
6385 set_mem_alias_set (mem, alpha_sr_alias_set);
6386 FRP (emit_move_insn (mem, gen_rtx_REG (DFmode, i+32)));
6387 reg_offset += 8;
6390 else if (TARGET_ABI_UNICOSMK && alpha_procedure_type == PT_STACK)
6392 /* The standard frame on the T3E includes space for saving registers.
6393 We just have to use it. We don't have to save the return address and
6394 the old frame pointer here - they are saved in the DSIB. */
6396 reg_offset = -56;
6397 for (i = 9; i < 15; i++)
6398 if (imask & (1UL << i))
6400 mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx,
6401 reg_offset));
6402 set_mem_alias_set (mem, alpha_sr_alias_set);
6403 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, i)));
6404 reg_offset -= 8;
6406 for (i = 2; i < 10; i++)
6407 if (fmask & (1UL << i))
6409 mem = gen_rtx_MEM (DFmode, plus_constant (hard_frame_pointer_rtx,
6410 reg_offset));
6411 set_mem_alias_set (mem, alpha_sr_alias_set);
6412 FRP (emit_move_insn (mem, gen_rtx_REG (DFmode, i+32)));
6413 reg_offset -= 8;
6417 if (TARGET_ABI_OPEN_VMS)
6419 if (alpha_procedure_type == PT_REGISTER)
6420 /* Register frame procedures save the fp.
6421 ?? Ought to have a dwarf2 save for this. */
6422 emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
6423 hard_frame_pointer_rtx);
6425 if (alpha_procedure_type != PT_NULL && vms_base_regno != REG_PV)
6426 emit_insn (gen_force_movdi (gen_rtx_REG (DImode, vms_base_regno),
6427 gen_rtx_REG (DImode, REG_PV)));
6429 if (alpha_procedure_type != PT_NULL
6430 && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
6431 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
6433 /* If we have to allocate space for outgoing args, do it now. */
6434 if (current_function_outgoing_args_size != 0)
6436 rtx seq
6437 = emit_move_insn (stack_pointer_rtx,
6438 plus_constant
6439 (hard_frame_pointer_rtx,
6440 - (ALPHA_ROUND
6441 (current_function_outgoing_args_size))));
6443 /* Only set FRAME_RELATED_P on the stack adjustment we just emitted
6444 if ! frame_pointer_needed. Setting the bit will change the CFA
6445 computation rule to use sp again, which would be wrong if we had
6446 frame_pointer_needed, as this means sp might move unpredictably
6447 later on.
6449 Also, note that
6450 frame_pointer_needed
6451 => vms_unwind_regno == HARD_FRAME_POINTER_REGNUM
6453 current_function_outgoing_args_size != 0
6454 => alpha_procedure_type != PT_NULL,
6456 so when we are not setting the bit here, we are guaranteed to
6457 have emitted an FRP frame pointer update just before. */
6458 RTX_FRAME_RELATED_P (seq) = ! frame_pointer_needed;
6461 else if (!TARGET_ABI_UNICOSMK)
6463 /* If we need a frame pointer, set it from the stack pointer. */
6464 if (frame_pointer_needed)
6466 if (TARGET_CAN_FAULT_IN_PROLOGUE)
6467 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
6468 else
6469 /* This must always be the last instruction in the
6470 prologue, thus we emit a special move + clobber. */
6471 FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx,
6472 stack_pointer_rtx, sa_reg)));
6476 /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
6477 the prologue, for exception handling reasons, we cannot do this for
6478 any insn that might fault. We could prevent this for mems with a
6479 (clobber:BLK (scratch)), but this doesn't work for fp insns. So we
6480 have to prevent all such scheduling with a blockage.
6482 Linux, on the other hand, never bothered to implement OSF/1's
6483 exception handling, and so doesn't care about such things. Anyone
6484 planning to use dwarf2 frame-unwind info can also omit the blockage. */
6486 if (! TARGET_CAN_FAULT_IN_PROLOGUE)
6487 emit_insn (gen_blockage ());
6490 /* Output the textual info surrounding the prologue. */
6492 void
6493 alpha_start_function (FILE *file, const char *fnname,
6494 tree decl ATTRIBUTE_UNUSED)
6496 unsigned long imask = 0;
6497 unsigned long fmask = 0;
6498 /* Stack space needed for pushing registers clobbered by us. */
6499 HOST_WIDE_INT sa_size;
6500 /* Complete stack size needed. */
6501 unsigned HOST_WIDE_INT frame_size;
6502 /* Offset from base reg to register save area. */
6503 HOST_WIDE_INT reg_offset;
6504 char *entry_label = (char *) alloca (strlen (fnname) + 6);
6505 int i;
6507 /* Don't emit an extern directive for functions defined in the same file. */
6508 if (TARGET_ABI_UNICOSMK)
6510 tree name_tree;
6511 name_tree = get_identifier (fnname);
6512 TREE_ASM_WRITTEN (name_tree) = 1;
6515 alpha_fnname = fnname;
6516 sa_size = alpha_sa_size ();
6518 frame_size = get_frame_size ();
6519 if (TARGET_ABI_OPEN_VMS)
6520 frame_size = ALPHA_ROUND (sa_size
6521 + (alpha_procedure_type == PT_STACK ? 8 : 0)
6522 + frame_size
6523 + current_function_pretend_args_size);
6524 else if (TARGET_ABI_UNICOSMK)
6525 frame_size = ALPHA_ROUND (sa_size
6526 + (alpha_procedure_type == PT_STACK ? 48 : 0))
6527 + ALPHA_ROUND (frame_size
6528 + current_function_outgoing_args_size);
6529 else
6530 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
6531 + sa_size
6532 + ALPHA_ROUND (frame_size
6533 + current_function_pretend_args_size));
6535 if (TARGET_ABI_OPEN_VMS)
6536 reg_offset = 8;
6537 else
6538 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
6540 alpha_sa_mask (&imask, &fmask);
6542 /* Ecoff can handle multiple .file directives, so put out file and lineno.
6543 We have to do that before the .ent directive as we cannot switch
6544 files within procedures with native ecoff because line numbers are
6545 linked to procedure descriptors.
6546 Outputting the lineno helps debugging of one line functions as they
6547 would otherwise get no line number at all. Please note that we would
6548 like to put out last_linenum from final.c, but it is not accessible. */
6550 if (write_symbols == SDB_DEBUG)
6552 #ifdef ASM_OUTPUT_SOURCE_FILENAME
6553 ASM_OUTPUT_SOURCE_FILENAME (file,
6554 DECL_SOURCE_FILE (current_function_decl));
6555 #endif
6556 #ifdef ASM_OUTPUT_SOURCE_LINE
6557 if (debug_info_level != DINFO_LEVEL_TERSE)
6558 ASM_OUTPUT_SOURCE_LINE (file,
6559 DECL_SOURCE_LINE (current_function_decl), 0);
6560 #endif
6563 /* Issue function start and label. */
6564 if (TARGET_ABI_OPEN_VMS
6565 || (!TARGET_ABI_UNICOSMK && !flag_inhibit_size_directive))
6567 fputs ("\t.ent ", file);
6568 assemble_name (file, fnname);
6569 putc ('\n', file);
6571 /* If the function needs GP, we'll write the "..ng" label there.
6572 Otherwise, do it here. */
6573 if (TARGET_ABI_OSF
6574 && ! alpha_function_needs_gp
6575 && ! current_function_is_thunk)
6577 putc ('$', file);
6578 assemble_name (file, fnname);
6579 fputs ("..ng:\n", file);
6583 strcpy (entry_label, fnname);
6584 if (TARGET_ABI_OPEN_VMS)
6585 strcat (entry_label, "..en");
6587 /* For public functions, the label must be globalized by appending an
6588 additional colon. */
6589 if (TARGET_ABI_UNICOSMK && TREE_PUBLIC (decl))
6590 strcat (entry_label, ":");
6592 ASM_OUTPUT_LABEL (file, entry_label);
6593 inside_function = TRUE;
6595 if (TARGET_ABI_OPEN_VMS)
6596 fprintf (file, "\t.base $%d\n", vms_base_regno);
6598 if (!TARGET_ABI_OPEN_VMS && !TARGET_ABI_UNICOSMK && TARGET_IEEE_CONFORMANT
6599 && !flag_inhibit_size_directive)
6601 /* Set flags in procedure descriptor to request IEEE-conformant
6602 math-library routines. The value we set it to is PDSC_EXC_IEEE
6603 (/usr/include/pdsc.h). */
6604 fputs ("\t.eflag 48\n", file);
6607 /* Set up offsets to alpha virtual arg/local debugging pointer. */
6608 alpha_auto_offset = -frame_size + current_function_pretend_args_size;
6609 alpha_arg_offset = -frame_size + 48;
6611 /* Describe our frame. If the frame size is larger than an integer,
6612 print it as zero to avoid an assembler error. We won't be
6613 properly describing such a frame, but that's the best we can do. */
6614 if (TARGET_ABI_UNICOSMK)
6616 else if (TARGET_ABI_OPEN_VMS)
6617 fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,"
6618 HOST_WIDE_INT_PRINT_DEC "\n",
6619 vms_unwind_regno,
6620 frame_size >= (1UL << 31) ? 0 : frame_size,
6621 reg_offset);
6622 else if (!flag_inhibit_size_directive)
6623 fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,%d\n",
6624 (frame_pointer_needed
6625 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM),
6626 frame_size >= (1UL << 31) ? 0 : frame_size,
6627 current_function_pretend_args_size);
6629 /* Describe which registers were spilled. */
6630 if (TARGET_ABI_UNICOSMK)
6632 else if (TARGET_ABI_OPEN_VMS)
6634 if (imask)
6635 /* ??? Does VMS care if mask contains ra? The old code didn't
6636 set it, so I don't here. */
6637 fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1UL << REG_RA));
6638 if (fmask)
6639 fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
6640 if (alpha_procedure_type == PT_REGISTER)
6641 fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
6643 else if (!flag_inhibit_size_directive)
6645 if (imask)
6647 fprintf (file, "\t.mask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", imask,
6648 frame_size >= (1UL << 31) ? 0 : reg_offset - frame_size);
6650 for (i = 0; i < 32; ++i)
6651 if (imask & (1UL << i))
6652 reg_offset += 8;
6655 if (fmask)
6656 fprintf (file, "\t.fmask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", fmask,
6657 frame_size >= (1UL << 31) ? 0 : reg_offset - frame_size);
6660 #if TARGET_ABI_OPEN_VMS
6661 /* Ifdef'ed cause link_section are only available then. */
6662 readonly_data_section ();
6663 fprintf (file, "\t.align 3\n");
6664 assemble_name (file, fnname); fputs ("..na:\n", file);
6665 fputs ("\t.ascii \"", file);
6666 assemble_name (file, fnname);
6667 fputs ("\\0\"\n", file);
6668 alpha_need_linkage (fnname, 1);
6669 text_section ();
6670 #endif
6673 /* Emit the .prologue note at the scheduled end of the prologue. */
6675 static void
6676 alpha_output_function_end_prologue (FILE *file)
6678 if (TARGET_ABI_UNICOSMK)
6680 else if (TARGET_ABI_OPEN_VMS)
6681 fputs ("\t.prologue\n", file);
6682 else if (TARGET_ABI_WINDOWS_NT)
6683 fputs ("\t.prologue 0\n", file);
6684 else if (!flag_inhibit_size_directive)
6685 fprintf (file, "\t.prologue %d\n",
6686 alpha_function_needs_gp || current_function_is_thunk);
6689 /* Write function epilogue. */
6691 /* ??? At some point we will want to support full unwind, and so will
6692 need to mark the epilogue as well. At the moment, we just confuse
6693 dwarf2out. */
6694 #undef FRP
6695 #define FRP(exp) exp
6697 void
6698 alpha_expand_epilogue (void)
6700 /* Registers to save. */
6701 unsigned long imask = 0;
6702 unsigned long fmask = 0;
6703 /* Stack space needed for pushing registers clobbered by us. */
6704 HOST_WIDE_INT sa_size;
6705 /* Complete stack size needed. */
6706 HOST_WIDE_INT frame_size;
6707 /* Offset from base reg to register save area. */
6708 HOST_WIDE_INT reg_offset;
6709 int fp_is_frame_pointer, fp_offset;
6710 rtx sa_reg, sa_reg_exp = NULL;
6711 rtx sp_adj1, sp_adj2, mem;
6712 rtx eh_ofs;
6713 int i;
6715 sa_size = alpha_sa_size ();
6717 frame_size = get_frame_size ();
6718 if (TARGET_ABI_OPEN_VMS)
6719 frame_size = ALPHA_ROUND (sa_size
6720 + (alpha_procedure_type == PT_STACK ? 8 : 0)
6721 + frame_size
6722 + current_function_pretend_args_size);
6723 else if (TARGET_ABI_UNICOSMK)
6724 frame_size = ALPHA_ROUND (sa_size
6725 + (alpha_procedure_type == PT_STACK ? 48 : 0))
6726 + ALPHA_ROUND (frame_size
6727 + current_function_outgoing_args_size);
6728 else
6729 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
6730 + sa_size
6731 + ALPHA_ROUND (frame_size
6732 + current_function_pretend_args_size));
6734 if (TARGET_ABI_OPEN_VMS)
6736 if (alpha_procedure_type == PT_STACK)
6737 reg_offset = 8;
6738 else
6739 reg_offset = 0;
6741 else
6742 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
6744 alpha_sa_mask (&imask, &fmask);
6746 fp_is_frame_pointer
6747 = ((TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
6748 || (!TARGET_ABI_OPEN_VMS && frame_pointer_needed));
6749 fp_offset = 0;
6750 sa_reg = stack_pointer_rtx;
6752 if (current_function_calls_eh_return)
6753 eh_ofs = EH_RETURN_STACKADJ_RTX;
6754 else
6755 eh_ofs = NULL_RTX;
6757 if (!TARGET_ABI_UNICOSMK && sa_size)
6759 /* If we have a frame pointer, restore SP from it. */
6760 if ((TARGET_ABI_OPEN_VMS
6761 && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
6762 || (!TARGET_ABI_OPEN_VMS && frame_pointer_needed))
6763 FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx));
6765 /* Cope with very large offsets to the register save area. */
6766 if (reg_offset + sa_size > 0x8000)
6768 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
6769 HOST_WIDE_INT bias;
6771 if (low + sa_size <= 0x8000)
6772 bias = reg_offset - low, reg_offset = low;
6773 else
6774 bias = reg_offset, reg_offset = 0;
6776 sa_reg = gen_rtx_REG (DImode, 22);
6777 sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
6779 FRP (emit_move_insn (sa_reg, sa_reg_exp));
6782 /* Restore registers in order, excepting a true frame pointer. */
6784 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
6785 if (! eh_ofs)
6786 set_mem_alias_set (mem, alpha_sr_alias_set);
6787 FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
6789 reg_offset += 8;
6790 imask &= ~(1UL << REG_RA);
6792 for (i = 0; i < 31; ++i)
6793 if (imask & (1UL << i))
6795 if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
6796 fp_offset = reg_offset;
6797 else
6799 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
6800 set_mem_alias_set (mem, alpha_sr_alias_set);
6801 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
6803 reg_offset += 8;
6806 if (imask & (1UL << 31))
6807 reg_offset += 8;
6809 for (i = 0; i < 31; ++i)
6810 if (fmask & (1UL << i))
6812 mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
6813 set_mem_alias_set (mem, alpha_sr_alias_set);
6814 FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
6815 reg_offset += 8;
6818 else if (TARGET_ABI_UNICOSMK && alpha_procedure_type == PT_STACK)
6820 /* Restore callee-saved general-purpose registers. */
6822 reg_offset = -56;
6824 for (i = 9; i < 15; i++)
6825 if (imask & (1UL << i))
6827 mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx,
6828 reg_offset));
6829 set_mem_alias_set (mem, alpha_sr_alias_set);
6830 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
6831 reg_offset -= 8;
6834 for (i = 2; i < 10; i++)
6835 if (fmask & (1UL << i))
6837 mem = gen_rtx_MEM (DFmode, plus_constant(hard_frame_pointer_rtx,
6838 reg_offset));
6839 set_mem_alias_set (mem, alpha_sr_alias_set);
6840 FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
6841 reg_offset -= 8;
6844 /* Restore the return address from the DSIB. */
6846 mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx, -8));
6847 set_mem_alias_set (mem, alpha_sr_alias_set);
6848 FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
6851 if (frame_size || eh_ofs)
6853 sp_adj1 = stack_pointer_rtx;
6855 if (eh_ofs)
6857 sp_adj1 = gen_rtx_REG (DImode, 23);
6858 emit_move_insn (sp_adj1,
6859 gen_rtx_PLUS (Pmode, stack_pointer_rtx, eh_ofs));
6862 /* If the stack size is large, begin computation into a temporary
6863 register so as not to interfere with a potential fp restore,
6864 which must be consecutive with an SP restore. */
6865 if (frame_size < 32768
6866 && ! (TARGET_ABI_UNICOSMK && current_function_calls_alloca))
6867 sp_adj2 = GEN_INT (frame_size);
6868 else if (TARGET_ABI_UNICOSMK)
6870 sp_adj1 = gen_rtx_REG (DImode, 23);
6871 FRP (emit_move_insn (sp_adj1, hard_frame_pointer_rtx));
6872 sp_adj2 = const0_rtx;
6874 else if (frame_size < 0x40007fffL)
6876 int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
6878 sp_adj2 = plus_constant (sp_adj1, frame_size - low);
6879 if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
6880 sp_adj1 = sa_reg;
6881 else
6883 sp_adj1 = gen_rtx_REG (DImode, 23);
6884 FRP (emit_move_insn (sp_adj1, sp_adj2));
6886 sp_adj2 = GEN_INT (low);
6888 else
6890 rtx tmp = gen_rtx_REG (DImode, 23);
6891 FRP (sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3));
6892 if (!sp_adj2)
6894 /* We can't drop new things to memory this late, afaik,
6895 so build it up by pieces. */
6896 FRP (sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
6897 -(frame_size < 0)));
6898 if (!sp_adj2)
6899 abort ();
6903 /* From now on, things must be in order. So emit blockages. */
6905 /* Restore the frame pointer. */
6906 if (TARGET_ABI_UNICOSMK)
6908 emit_insn (gen_blockage ());
6909 mem = gen_rtx_MEM (DImode,
6910 plus_constant (hard_frame_pointer_rtx, -16));
6911 set_mem_alias_set (mem, alpha_sr_alias_set);
6912 FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
6914 else if (fp_is_frame_pointer)
6916 emit_insn (gen_blockage ());
6917 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, fp_offset));
6918 set_mem_alias_set (mem, alpha_sr_alias_set);
6919 FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
6921 else if (TARGET_ABI_OPEN_VMS)
6923 emit_insn (gen_blockage ());
6924 FRP (emit_move_insn (hard_frame_pointer_rtx,
6925 gen_rtx_REG (DImode, vms_save_fp_regno)));
6928 /* Restore the stack pointer. */
6929 emit_insn (gen_blockage ());
6930 if (sp_adj2 == const0_rtx)
6931 FRP (emit_move_insn (stack_pointer_rtx, sp_adj1));
6932 else
6933 FRP (emit_move_insn (stack_pointer_rtx,
6934 gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)));
6936 else
6938 if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_REGISTER)
6940 emit_insn (gen_blockage ());
6941 FRP (emit_move_insn (hard_frame_pointer_rtx,
6942 gen_rtx_REG (DImode, vms_save_fp_regno)));
6944 else if (TARGET_ABI_UNICOSMK && alpha_procedure_type != PT_STACK)
6946 /* Decrement the frame pointer if the function does not have a
6947 frame. */
6949 emit_insn (gen_blockage ());
6950 FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
6951 hard_frame_pointer_rtx, constm1_rtx)));
6956 /* Output the rest of the textual info surrounding the epilogue. */
6958 void
6959 alpha_end_function (FILE *file, const char *fnname, tree decl ATTRIBUTE_UNUSED)
6961 #if TARGET_ABI_OPEN_VMS
6962 alpha_write_linkage (file, fnname, decl);
6963 #endif
6965 /* End the function. */
6966 if (!TARGET_ABI_UNICOSMK && !flag_inhibit_size_directive)
6968 fputs ("\t.end ", file);
6969 assemble_name (file, fnname);
6970 putc ('\n', file);
6972 inside_function = FALSE;
6974 /* Output jump tables and the static subroutine information block. */
6975 if (TARGET_ABI_UNICOSMK)
6977 unicosmk_output_ssib (file, fnname);
6978 unicosmk_output_deferred_case_vectors (file);
6982 #if TARGET_ABI_OSF
6983 /* Emit a tail call to FUNCTION after adjusting THIS by DELTA.
6985 In order to avoid the hordes of differences between generated code
6986 with and without TARGET_EXPLICIT_RELOCS, and to avoid duplicating
6987 lots of code loading up large constants, generate rtl and emit it
6988 instead of going straight to text.
6990 Not sure why this idea hasn't been explored before... */
6992 static void
6993 alpha_output_mi_thunk_osf (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
6994 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
6995 tree function)
6997 HOST_WIDE_INT hi, lo;
6998 rtx this, insn, funexp;
7000 reset_block_changes ();
7002 /* We always require a valid GP. */
7003 emit_insn (gen_prologue_ldgp ());
7004 emit_note (NOTE_INSN_PROLOGUE_END);
7006 /* Find the "this" pointer. If the function returns a structure,
7007 the structure return pointer is in $16. */
7008 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
7009 this = gen_rtx_REG (Pmode, 17);
7010 else
7011 this = gen_rtx_REG (Pmode, 16);
7013 /* Add DELTA. When possible we use ldah+lda. Otherwise load the
7014 entire constant for the add. */
7015 lo = ((delta & 0xffff) ^ 0x8000) - 0x8000;
7016 hi = (((delta - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
7017 if (hi + lo == delta)
7019 if (hi)
7020 emit_insn (gen_adddi3 (this, this, GEN_INT (hi)));
7021 if (lo)
7022 emit_insn (gen_adddi3 (this, this, GEN_INT (lo)));
7024 else
7026 rtx tmp = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 0),
7027 delta, -(delta < 0));
7028 emit_insn (gen_adddi3 (this, this, tmp));
7031 /* Add a delta stored in the vtable at VCALL_OFFSET. */
7032 if (vcall_offset)
7034 rtx tmp, tmp2;
7036 tmp = gen_rtx_REG (Pmode, 0);
7037 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
7039 lo = ((vcall_offset & 0xffff) ^ 0x8000) - 0x8000;
7040 hi = (((vcall_offset - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
7041 if (hi + lo == vcall_offset)
7043 if (hi)
7044 emit_insn (gen_adddi3 (tmp, tmp, GEN_INT (hi)));
7046 else
7048 tmp2 = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 1),
7049 vcall_offset, -(vcall_offset < 0));
7050 emit_insn (gen_adddi3 (tmp, tmp, tmp2));
7051 lo = 0;
7053 if (lo)
7054 tmp2 = gen_rtx_PLUS (Pmode, tmp, GEN_INT (lo));
7055 else
7056 tmp2 = tmp;
7057 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp2));
7059 emit_insn (gen_adddi3 (this, this, tmp));
7062 /* Generate a tail call to the target function. */
7063 if (! TREE_USED (function))
7065 assemble_external (function);
7066 TREE_USED (function) = 1;
7068 funexp = XEXP (DECL_RTL (function), 0);
7069 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
7070 insn = emit_call_insn (gen_sibcall (funexp, const0_rtx));
7071 SIBLING_CALL_P (insn) = 1;
7073 /* Run just enough of rest_of_compilation to get the insns emitted.
7074 There's not really enough bulk here to make other passes such as
7075 instruction scheduling worth while. Note that use_thunk calls
7076 assemble_start_function and assemble_end_function. */
7077 insn = get_insns ();
7078 insn_locators_initialize ();
7079 shorten_branches (insn);
7080 final_start_function (insn, file, 1);
7081 final (insn, file, 1, 0);
7082 final_end_function ();
7084 #endif /* TARGET_ABI_OSF */
7086 /* Debugging support. */
7088 #include "gstab.h"
7090 /* Count the number of sdb related labels are generated (to find block
7091 start and end boundaries). */
7093 int sdb_label_count = 0;
7095 /* Next label # for each statement. */
7097 static int sym_lineno = 0;
7099 /* Count the number of .file directives, so that .loc is up to date. */
7101 static int num_source_filenames = 0;
7103 /* Name of the file containing the current function. */
7105 static const char *current_function_file = "";
7107 /* Offsets to alpha virtual arg/local debugging pointers. */
7109 long alpha_arg_offset;
7110 long alpha_auto_offset;
7112 /* Emit a new filename to a stream. */
7114 void
7115 alpha_output_filename (FILE *stream, const char *name)
7117 static int first_time = TRUE;
7118 char ltext_label_name[100];
7120 if (first_time)
7122 first_time = FALSE;
7123 ++num_source_filenames;
7124 current_function_file = name;
7125 fprintf (stream, "\t.file\t%d ", num_source_filenames);
7126 output_quoted_string (stream, name);
7127 fprintf (stream, "\n");
7128 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
7129 fprintf (stream, "\t#@stabs\n");
7132 else if (write_symbols == DBX_DEBUG)
7134 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
7135 fprintf (stream, "%s", ASM_STABS_OP);
7136 output_quoted_string (stream, name);
7137 fprintf (stream, ",%d,0,0,%s\n", N_SOL, &ltext_label_name[1]);
7140 else if (name != current_function_file
7141 && strcmp (name, current_function_file) != 0)
7143 if (inside_function && ! TARGET_GAS)
7144 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
7145 else
7147 ++num_source_filenames;
7148 current_function_file = name;
7149 fprintf (stream, "\t.file\t%d ", num_source_filenames);
7152 output_quoted_string (stream, name);
7153 fprintf (stream, "\n");
7157 /* Emit a linenumber to a stream. */
7159 void
7160 alpha_output_lineno (FILE *stream, int line)
7162 if (write_symbols == DBX_DEBUG)
7164 /* mips-tfile doesn't understand .stabd directives. */
7165 ++sym_lineno;
7166 fprintf (stream, "$LM%d:\n%s%d,0,%d,$LM%d\n",
7167 sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
7169 else
7170 fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
7173 /* Structure to show the current status of registers and memory. */
7175 struct shadow_summary
7177 struct {
7178 unsigned int i : 31; /* Mask of int regs */
7179 unsigned int fp : 31; /* Mask of fp regs */
7180 unsigned int mem : 1; /* mem == imem | fpmem */
7181 } used, defd;
7184 /* Summary the effects of expression X on the machine. Update SUM, a pointer
7185 to the summary structure. SET is nonzero if the insn is setting the
7186 object, otherwise zero. */
7188 static void
7189 summarize_insn (rtx x, struct shadow_summary *sum, int set)
7191 const char *format_ptr;
7192 int i, j;
7194 if (x == 0)
7195 return;
7197 switch (GET_CODE (x))
7199 /* ??? Note that this case would be incorrect if the Alpha had a
7200 ZERO_EXTRACT in SET_DEST. */
7201 case SET:
7202 summarize_insn (SET_SRC (x), sum, 0);
7203 summarize_insn (SET_DEST (x), sum, 1);
7204 break;
7206 case CLOBBER:
7207 summarize_insn (XEXP (x, 0), sum, 1);
7208 break;
7210 case USE:
7211 summarize_insn (XEXP (x, 0), sum, 0);
7212 break;
7214 case ASM_OPERANDS:
7215 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
7216 summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
7217 break;
7219 case PARALLEL:
7220 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
7221 summarize_insn (XVECEXP (x, 0, i), sum, 0);
7222 break;
7224 case SUBREG:
7225 summarize_insn (SUBREG_REG (x), sum, 0);
7226 break;
7228 case REG:
7230 int regno = REGNO (x);
7231 unsigned long mask = ((unsigned long) 1) << (regno % 32);
7233 if (regno == 31 || regno == 63)
7234 break;
7236 if (set)
7238 if (regno < 32)
7239 sum->defd.i |= mask;
7240 else
7241 sum->defd.fp |= mask;
7243 else
7245 if (regno < 32)
7246 sum->used.i |= mask;
7247 else
7248 sum->used.fp |= mask;
7251 break;
7253 case MEM:
7254 if (set)
7255 sum->defd.mem = 1;
7256 else
7257 sum->used.mem = 1;
7259 /* Find the regs used in memory address computation: */
7260 summarize_insn (XEXP (x, 0), sum, 0);
7261 break;
7263 case CONST_INT: case CONST_DOUBLE:
7264 case SYMBOL_REF: case LABEL_REF: case CONST:
7265 case SCRATCH: case ASM_INPUT:
7266 break;
7268 /* Handle common unary and binary ops for efficiency. */
7269 case COMPARE: case PLUS: case MINUS: case MULT: case DIV:
7270 case MOD: case UDIV: case UMOD: case AND: case IOR:
7271 case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT:
7272 case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX:
7273 case NE: case EQ: case GE: case GT: case LE:
7274 case LT: case GEU: case GTU: case LEU: case LTU:
7275 summarize_insn (XEXP (x, 0), sum, 0);
7276 summarize_insn (XEXP (x, 1), sum, 0);
7277 break;
7279 case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
7280 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
7281 case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
7282 case SQRT: case FFS:
7283 summarize_insn (XEXP (x, 0), sum, 0);
7284 break;
7286 default:
7287 format_ptr = GET_RTX_FORMAT (GET_CODE (x));
7288 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
7289 switch (format_ptr[i])
7291 case 'e':
7292 summarize_insn (XEXP (x, i), sum, 0);
7293 break;
7295 case 'E':
7296 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
7297 summarize_insn (XVECEXP (x, i, j), sum, 0);
7298 break;
7300 case 'i':
7301 break;
7303 default:
7304 abort ();
7309 /* Ensure a sufficient number of `trapb' insns are in the code when
7310 the user requests code with a trap precision of functions or
7311 instructions.
7313 In naive mode, when the user requests a trap-precision of
7314 "instruction", a trapb is needed after every instruction that may
7315 generate a trap. This ensures that the code is resumption safe but
7316 it is also slow.
7318 When optimizations are turned on, we delay issuing a trapb as long
7319 as possible. In this context, a trap shadow is the sequence of
7320 instructions that starts with a (potentially) trap generating
7321 instruction and extends to the next trapb or call_pal instruction
7322 (but GCC never generates call_pal by itself). We can delay (and
7323 therefore sometimes omit) a trapb subject to the following
7324 conditions:
7326 (a) On entry to the trap shadow, if any Alpha register or memory
7327 location contains a value that is used as an operand value by some
7328 instruction in the trap shadow (live on entry), then no instruction
7329 in the trap shadow may modify the register or memory location.
7331 (b) Within the trap shadow, the computation of the base register
7332 for a memory load or store instruction may not involve using the
7333 result of an instruction that might generate an UNPREDICTABLE
7334 result.
7336 (c) Within the trap shadow, no register may be used more than once
7337 as a destination register. (This is to make life easier for the
7338 trap-handler.)
7340 (d) The trap shadow may not include any branch instructions. */
7342 static void
7343 alpha_handle_trap_shadows (void)
7345 struct shadow_summary shadow;
7346 int trap_pending, exception_nesting;
7347 rtx i, n;
7349 trap_pending = 0;
7350 exception_nesting = 0;
7351 shadow.used.i = 0;
7352 shadow.used.fp = 0;
7353 shadow.used.mem = 0;
7354 shadow.defd = shadow.used;
7356 for (i = get_insns (); i ; i = NEXT_INSN (i))
7358 if (GET_CODE (i) == NOTE)
7360 switch (NOTE_LINE_NUMBER (i))
7362 case NOTE_INSN_EH_REGION_BEG:
7363 exception_nesting++;
7364 if (trap_pending)
7365 goto close_shadow;
7366 break;
7368 case NOTE_INSN_EH_REGION_END:
7369 exception_nesting--;
7370 if (trap_pending)
7371 goto close_shadow;
7372 break;
7374 case NOTE_INSN_EPILOGUE_BEG:
7375 if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
7376 goto close_shadow;
7377 break;
7380 else if (trap_pending)
7382 if (alpha_tp == ALPHA_TP_FUNC)
7384 if (GET_CODE (i) == JUMP_INSN
7385 && GET_CODE (PATTERN (i)) == RETURN)
7386 goto close_shadow;
7388 else if (alpha_tp == ALPHA_TP_INSN)
7390 if (optimize > 0)
7392 struct shadow_summary sum;
7394 sum.used.i = 0;
7395 sum.used.fp = 0;
7396 sum.used.mem = 0;
7397 sum.defd = sum.used;
7399 switch (GET_CODE (i))
7401 case INSN:
7402 /* Annoyingly, get_attr_trap will abort on these. */
7403 if (GET_CODE (PATTERN (i)) == USE
7404 || GET_CODE (PATTERN (i)) == CLOBBER)
7405 break;
7407 summarize_insn (PATTERN (i), &sum, 0);
7409 if ((sum.defd.i & shadow.defd.i)
7410 || (sum.defd.fp & shadow.defd.fp))
7412 /* (c) would be violated */
7413 goto close_shadow;
7416 /* Combine shadow with summary of current insn: */
7417 shadow.used.i |= sum.used.i;
7418 shadow.used.fp |= sum.used.fp;
7419 shadow.used.mem |= sum.used.mem;
7420 shadow.defd.i |= sum.defd.i;
7421 shadow.defd.fp |= sum.defd.fp;
7422 shadow.defd.mem |= sum.defd.mem;
7424 if ((sum.defd.i & shadow.used.i)
7425 || (sum.defd.fp & shadow.used.fp)
7426 || (sum.defd.mem & shadow.used.mem))
7428 /* (a) would be violated (also takes care of (b)) */
7429 if (get_attr_trap (i) == TRAP_YES
7430 && ((sum.defd.i & sum.used.i)
7431 || (sum.defd.fp & sum.used.fp)))
7432 abort ();
7434 goto close_shadow;
7436 break;
7438 case JUMP_INSN:
7439 case CALL_INSN:
7440 case CODE_LABEL:
7441 goto close_shadow;
7443 default:
7444 abort ();
7447 else
7449 close_shadow:
7450 n = emit_insn_before (gen_trapb (), i);
7451 PUT_MODE (n, TImode);
7452 PUT_MODE (i, TImode);
7453 trap_pending = 0;
7454 shadow.used.i = 0;
7455 shadow.used.fp = 0;
7456 shadow.used.mem = 0;
7457 shadow.defd = shadow.used;
7462 if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
7463 && GET_CODE (i) == INSN
7464 && GET_CODE (PATTERN (i)) != USE
7465 && GET_CODE (PATTERN (i)) != CLOBBER
7466 && get_attr_trap (i) == TRAP_YES)
7468 if (optimize && !trap_pending)
7469 summarize_insn (PATTERN (i), &shadow, 0);
7470 trap_pending = 1;
7475 /* Alpha can only issue instruction groups simultaneously if they are
7476 suitably aligned. This is very processor-specific. */
7478 enum alphaev4_pipe {
7479 EV4_STOP = 0,
7480 EV4_IB0 = 1,
7481 EV4_IB1 = 2,
7482 EV4_IBX = 4
7485 enum alphaev5_pipe {
7486 EV5_STOP = 0,
7487 EV5_NONE = 1,
7488 EV5_E01 = 2,
7489 EV5_E0 = 4,
7490 EV5_E1 = 8,
7491 EV5_FAM = 16,
7492 EV5_FA = 32,
7493 EV5_FM = 64
7496 static enum alphaev4_pipe
7497 alphaev4_insn_pipe (rtx insn)
7499 if (recog_memoized (insn) < 0)
7500 return EV4_STOP;
7501 if (get_attr_length (insn) != 4)
7502 return EV4_STOP;
7504 switch (get_attr_type (insn))
7506 case TYPE_ILD:
7507 case TYPE_FLD:
7508 return EV4_IBX;
7510 case TYPE_LDSYM:
7511 case TYPE_IADD:
7512 case TYPE_ILOG:
7513 case TYPE_ICMOV:
7514 case TYPE_ICMP:
7515 case TYPE_IST:
7516 case TYPE_FST:
7517 case TYPE_SHIFT:
7518 case TYPE_IMUL:
7519 case TYPE_FBR:
7520 return EV4_IB0;
7522 case TYPE_MISC:
7523 case TYPE_IBR:
7524 case TYPE_JSR:
7525 case TYPE_CALLPAL:
7526 case TYPE_FCPYS:
7527 case TYPE_FCMOV:
7528 case TYPE_FADD:
7529 case TYPE_FDIV:
7530 case TYPE_FMUL:
7531 return EV4_IB1;
7533 default:
7534 abort ();
7538 static enum alphaev5_pipe
7539 alphaev5_insn_pipe (rtx insn)
7541 if (recog_memoized (insn) < 0)
7542 return EV5_STOP;
7543 if (get_attr_length (insn) != 4)
7544 return EV5_STOP;
7546 switch (get_attr_type (insn))
7548 case TYPE_ILD:
7549 case TYPE_FLD:
7550 case TYPE_LDSYM:
7551 case TYPE_IADD:
7552 case TYPE_ILOG:
7553 case TYPE_ICMOV:
7554 case TYPE_ICMP:
7555 return EV5_E01;
7557 case TYPE_IST:
7558 case TYPE_FST:
7559 case TYPE_SHIFT:
7560 case TYPE_IMUL:
7561 case TYPE_MISC:
7562 case TYPE_MVI:
7563 return EV5_E0;
7565 case TYPE_IBR:
7566 case TYPE_JSR:
7567 case TYPE_CALLPAL:
7568 return EV5_E1;
7570 case TYPE_FCPYS:
7571 return EV5_FAM;
7573 case TYPE_FBR:
7574 case TYPE_FCMOV:
7575 case TYPE_FADD:
7576 case TYPE_FDIV:
7577 return EV5_FA;
7579 case TYPE_FMUL:
7580 return EV5_FM;
7582 default:
7583 abort();
7587 /* IN_USE is a mask of the slots currently filled within the insn group.
7588 The mask bits come from alphaev4_pipe above. If EV4_IBX is set, then
7589 the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.
7591 LEN is, of course, the length of the group in bytes. */
7593 static rtx
7594 alphaev4_next_group (rtx insn, int *pin_use, int *plen)
7596 int len, in_use;
7598 len = in_use = 0;
7600 if (! INSN_P (insn)
7601 || GET_CODE (PATTERN (insn)) == CLOBBER
7602 || GET_CODE (PATTERN (insn)) == USE)
7603 goto next_and_done;
7605 while (1)
7607 enum alphaev4_pipe pipe;
7609 pipe = alphaev4_insn_pipe (insn);
7610 switch (pipe)
7612 case EV4_STOP:
7613 /* Force complex instructions to start new groups. */
7614 if (in_use)
7615 goto done;
7617 /* If this is a completely unrecognized insn, its an asm.
7618 We don't know how long it is, so record length as -1 to
7619 signal a needed realignment. */
7620 if (recog_memoized (insn) < 0)
7621 len = -1;
7622 else
7623 len = get_attr_length (insn);
7624 goto next_and_done;
7626 case EV4_IBX:
7627 if (in_use & EV4_IB0)
7629 if (in_use & EV4_IB1)
7630 goto done;
7631 in_use |= EV4_IB1;
7633 else
7634 in_use |= EV4_IB0 | EV4_IBX;
7635 break;
7637 case EV4_IB0:
7638 if (in_use & EV4_IB0)
7640 if (!(in_use & EV4_IBX) || (in_use & EV4_IB1))
7641 goto done;
7642 in_use |= EV4_IB1;
7644 in_use |= EV4_IB0;
7645 break;
7647 case EV4_IB1:
7648 if (in_use & EV4_IB1)
7649 goto done;
7650 in_use |= EV4_IB1;
7651 break;
7653 default:
7654 abort();
7656 len += 4;
7658 /* Haifa doesn't do well scheduling branches. */
7659 if (GET_CODE (insn) == JUMP_INSN)
7660 goto next_and_done;
7662 next:
7663 insn = next_nonnote_insn (insn);
7665 if (!insn || ! INSN_P (insn))
7666 goto done;
7668 /* Let Haifa tell us where it thinks insn group boundaries are. */
7669 if (GET_MODE (insn) == TImode)
7670 goto done;
7672 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
7673 goto next;
7676 next_and_done:
7677 insn = next_nonnote_insn (insn);
7679 done:
7680 *plen = len;
7681 *pin_use = in_use;
7682 return insn;
7685 /* IN_USE is a mask of the slots currently filled within the insn group.
7686 The mask bits come from alphaev5_pipe above. If EV5_E01 is set, then
7687 the insn in EV5_E0 can be swapped by the hardware into EV5_E1.
7689 LEN is, of course, the length of the group in bytes. */
7691 static rtx
7692 alphaev5_next_group (rtx insn, int *pin_use, int *plen)
7694 int len, in_use;
7696 len = in_use = 0;
7698 if (! INSN_P (insn)
7699 || GET_CODE (PATTERN (insn)) == CLOBBER
7700 || GET_CODE (PATTERN (insn)) == USE)
7701 goto next_and_done;
7703 while (1)
7705 enum alphaev5_pipe pipe;
7707 pipe = alphaev5_insn_pipe (insn);
7708 switch (pipe)
7710 case EV5_STOP:
7711 /* Force complex instructions to start new groups. */
7712 if (in_use)
7713 goto done;
7715 /* If this is a completely unrecognized insn, its an asm.
7716 We don't know how long it is, so record length as -1 to
7717 signal a needed realignment. */
7718 if (recog_memoized (insn) < 0)
7719 len = -1;
7720 else
7721 len = get_attr_length (insn);
7722 goto next_and_done;
7724 /* ??? Most of the places below, we would like to abort, as
7725 it would indicate an error either in Haifa, or in the
7726 scheduling description. Unfortunately, Haifa never
7727 schedules the last instruction of the BB, so we don't
7728 have an accurate TI bit to go off. */
7729 case EV5_E01:
7730 if (in_use & EV5_E0)
7732 if (in_use & EV5_E1)
7733 goto done;
7734 in_use |= EV5_E1;
7736 else
7737 in_use |= EV5_E0 | EV5_E01;
7738 break;
7740 case EV5_E0:
7741 if (in_use & EV5_E0)
7743 if (!(in_use & EV5_E01) || (in_use & EV5_E1))
7744 goto done;
7745 in_use |= EV5_E1;
7747 in_use |= EV5_E0;
7748 break;
7750 case EV5_E1:
7751 if (in_use & EV5_E1)
7752 goto done;
7753 in_use |= EV5_E1;
7754 break;
7756 case EV5_FAM:
7757 if (in_use & EV5_FA)
7759 if (in_use & EV5_FM)
7760 goto done;
7761 in_use |= EV5_FM;
7763 else
7764 in_use |= EV5_FA | EV5_FAM;
7765 break;
7767 case EV5_FA:
7768 if (in_use & EV5_FA)
7769 goto done;
7770 in_use |= EV5_FA;
7771 break;
7773 case EV5_FM:
7774 if (in_use & EV5_FM)
7775 goto done;
7776 in_use |= EV5_FM;
7777 break;
7779 case EV5_NONE:
7780 break;
7782 default:
7783 abort();
7785 len += 4;
7787 /* Haifa doesn't do well scheduling branches. */
7788 /* ??? If this is predicted not-taken, slotting continues, except
7789 that no more IBR, FBR, or JSR insns may be slotted. */
7790 if (GET_CODE (insn) == JUMP_INSN)
7791 goto next_and_done;
7793 next:
7794 insn = next_nonnote_insn (insn);
7796 if (!insn || ! INSN_P (insn))
7797 goto done;
7799 /* Let Haifa tell us where it thinks insn group boundaries are. */
7800 if (GET_MODE (insn) == TImode)
7801 goto done;
7803 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
7804 goto next;
7807 next_and_done:
7808 insn = next_nonnote_insn (insn);
7810 done:
7811 *plen = len;
7812 *pin_use = in_use;
7813 return insn;
7816 static rtx
7817 alphaev4_next_nop (int *pin_use)
7819 int in_use = *pin_use;
7820 rtx nop;
7822 if (!(in_use & EV4_IB0))
7824 in_use |= EV4_IB0;
7825 nop = gen_nop ();
7827 else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX)
7829 in_use |= EV4_IB1;
7830 nop = gen_nop ();
7832 else if (TARGET_FP && !(in_use & EV4_IB1))
7834 in_use |= EV4_IB1;
7835 nop = gen_fnop ();
7837 else
7838 nop = gen_unop ();
7840 *pin_use = in_use;
7841 return nop;
7844 static rtx
7845 alphaev5_next_nop (int *pin_use)
7847 int in_use = *pin_use;
7848 rtx nop;
7850 if (!(in_use & EV5_E1))
7852 in_use |= EV5_E1;
7853 nop = gen_nop ();
7855 else if (TARGET_FP && !(in_use & EV5_FA))
7857 in_use |= EV5_FA;
7858 nop = gen_fnop ();
7860 else if (TARGET_FP && !(in_use & EV5_FM))
7862 in_use |= EV5_FM;
7863 nop = gen_fnop ();
7865 else
7866 nop = gen_unop ();
7868 *pin_use = in_use;
7869 return nop;
7872 /* The instruction group alignment main loop. */
7874 static void
7875 alpha_align_insns (unsigned int max_align,
7876 rtx (*next_group) (rtx, int *, int *),
7877 rtx (*next_nop) (int *))
7879 /* ALIGN is the known alignment for the insn group. */
7880 unsigned int align;
7881 /* OFS is the offset of the current insn in the insn group. */
7882 int ofs;
7883 int prev_in_use, in_use, len;
7884 rtx i, next;
7886 /* Let shorten branches care for assigning alignments to code labels. */
7887 shorten_branches (get_insns ());
7889 if (align_functions < 4)
7890 align = 4;
7891 else if ((unsigned int) align_functions < max_align)
7892 align = align_functions;
7893 else
7894 align = max_align;
7896 ofs = prev_in_use = 0;
7897 i = get_insns ();
7898 if (GET_CODE (i) == NOTE)
7899 i = next_nonnote_insn (i);
7901 while (i)
7903 next = (*next_group) (i, &in_use, &len);
7905 /* When we see a label, resync alignment etc. */
7906 if (GET_CODE (i) == CODE_LABEL)
7908 unsigned int new_align = 1 << label_to_alignment (i);
7910 if (new_align >= align)
7912 align = new_align < max_align ? new_align : max_align;
7913 ofs = 0;
7916 else if (ofs & (new_align-1))
7917 ofs = (ofs | (new_align-1)) + 1;
7918 if (len != 0)
7919 abort();
7922 /* Handle complex instructions special. */
7923 else if (in_use == 0)
7925 /* Asms will have length < 0. This is a signal that we have
7926 lost alignment knowledge. Assume, however, that the asm
7927 will not mis-align instructions. */
7928 if (len < 0)
7930 ofs = 0;
7931 align = 4;
7932 len = 0;
7936 /* If the known alignment is smaller than the recognized insn group,
7937 realign the output. */
7938 else if ((int) align < len)
7940 unsigned int new_log_align = len > 8 ? 4 : 3;
7941 rtx prev, where;
7943 where = prev = prev_nonnote_insn (i);
7944 if (!where || GET_CODE (where) != CODE_LABEL)
7945 where = i;
7947 /* Can't realign between a call and its gp reload. */
7948 if (! (TARGET_EXPLICIT_RELOCS
7949 && prev && GET_CODE (prev) == CALL_INSN))
7951 emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
7952 align = 1 << new_log_align;
7953 ofs = 0;
7957 /* If the group won't fit in the same INT16 as the previous,
7958 we need to add padding to keep the group together. Rather
7959 than simply leaving the insn filling to the assembler, we
7960 can make use of the knowledge of what sorts of instructions
7961 were issued in the previous group to make sure that all of
7962 the added nops are really free. */
7963 else if (ofs + len > (int) align)
7965 int nop_count = (align - ofs) / 4;
7966 rtx where;
7968 /* Insert nops before labels, branches, and calls to truly merge
7969 the execution of the nops with the previous instruction group. */
7970 where = prev_nonnote_insn (i);
7971 if (where)
7973 if (GET_CODE (where) == CODE_LABEL)
7975 rtx where2 = prev_nonnote_insn (where);
7976 if (where2 && GET_CODE (where2) == JUMP_INSN)
7977 where = where2;
7979 else if (GET_CODE (where) == INSN)
7980 where = i;
7982 else
7983 where = i;
7986 emit_insn_before ((*next_nop)(&prev_in_use), where);
7987 while (--nop_count);
7988 ofs = 0;
7991 ofs = (ofs + len) & (align - 1);
7992 prev_in_use = in_use;
7993 i = next;
7997 /* Machine dependent reorg pass. */
7999 static void
8000 alpha_reorg (void)
8002 if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
8003 alpha_handle_trap_shadows ();
8005 /* Due to the number of extra trapb insns, don't bother fixing up
8006 alignment when trap precision is instruction. Moreover, we can
8007 only do our job when sched2 is run. */
8008 if (optimize && !optimize_size
8009 && alpha_tp != ALPHA_TP_INSN
8010 && flag_schedule_insns_after_reload)
8012 if (alpha_cpu == PROCESSOR_EV4)
8013 alpha_align_insns (8, alphaev4_next_group, alphaev4_next_nop);
8014 else if (alpha_cpu == PROCESSOR_EV5)
8015 alpha_align_insns (16, alphaev5_next_group, alphaev5_next_nop);
8019 #if !TARGET_ABI_UNICOSMK
8021 #ifdef HAVE_STAMP_H
8022 #include <stamp.h>
8023 #endif
8025 static void
8026 alpha_file_start (void)
8028 #ifdef OBJECT_FORMAT_ELF
8029 /* If emitting dwarf2 debug information, we cannot generate a .file
8030 directive to start the file, as it will conflict with dwarf2out
8031 file numbers. So it's only useful when emitting mdebug output. */
8032 targetm.file_start_file_directive = (write_symbols == DBX_DEBUG);
8033 #endif
8035 default_file_start ();
8036 #ifdef MS_STAMP
8037 fprintf (asm_out_file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
8038 #endif
8040 fputs ("\t.set noreorder\n", asm_out_file);
8041 fputs ("\t.set volatile\n", asm_out_file);
8042 if (!TARGET_ABI_OPEN_VMS)
8043 fputs ("\t.set noat\n", asm_out_file);
8044 if (TARGET_EXPLICIT_RELOCS)
8045 fputs ("\t.set nomacro\n", asm_out_file);
8046 if (TARGET_SUPPORT_ARCH | TARGET_BWX | TARGET_MAX | TARGET_FIX | TARGET_CIX)
8047 fprintf (asm_out_file,
8048 "\t.arch %s\n",
8049 TARGET_CPU_EV6 ? "ev6"
8050 : (TARGET_CPU_EV5
8051 ? (TARGET_MAX ? "pca56" : TARGET_BWX ? "ev56" : "ev5")
8052 : "ev4"));
8054 #endif
8056 #ifdef OBJECT_FORMAT_ELF
8058 /* Switch to the section to which we should output X. The only thing
8059 special we do here is to honor small data. */
8061 static void
8062 alpha_elf_select_rtx_section (enum machine_mode mode, rtx x,
8063 unsigned HOST_WIDE_INT align)
8065 if (TARGET_SMALL_DATA && GET_MODE_SIZE (mode) <= g_switch_value)
8066 /* ??? Consider using mergeable sdata sections. */
8067 sdata_section ();
8068 else
8069 default_elf_select_rtx_section (mode, x, align);
8072 #endif /* OBJECT_FORMAT_ELF */
8074 /* Structure to collect function names for final output in link section. */
8075 /* Note that items marked with GTY can't be ifdef'ed out. */
8077 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
8078 enum reloc_kind {KIND_LINKAGE, KIND_CODEADDR};
8080 struct alpha_links GTY(())
8082 int num;
8083 rtx linkage;
8084 enum links_kind lkind;
8085 enum reloc_kind rkind;
8088 struct alpha_funcs GTY(())
8090 int num;
8091 splay_tree GTY ((param1_is (char *), param2_is (struct alpha_links *)))
8092 links;
8095 static GTY ((param1_is (char *), param2_is (struct alpha_links *)))
8096 splay_tree alpha_links_tree;
8097 static GTY ((param1_is (tree), param2_is (struct alpha_funcs *)))
8098 splay_tree alpha_funcs_tree;
8100 static GTY(()) int alpha_funcs_num;
8102 #if TARGET_ABI_OPEN_VMS
8104 /* Return the VMS argument type corresponding to MODE. */
8106 enum avms_arg_type
8107 alpha_arg_type (enum machine_mode mode)
8109 switch (mode)
8111 case SFmode:
8112 return TARGET_FLOAT_VAX ? FF : FS;
8113 case DFmode:
8114 return TARGET_FLOAT_VAX ? FD : FT;
8115 default:
8116 return I64;
8120 /* Return an rtx for an integer representing the VMS Argument Information
8121 register value. */
8124 alpha_arg_info_reg_val (CUMULATIVE_ARGS cum)
8126 unsigned HOST_WIDE_INT regval = cum.num_args;
8127 int i;
8129 for (i = 0; i < 6; i++)
8130 regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
8132 return GEN_INT (regval);
8135 /* Make (or fake) .linkage entry for function call.
8137 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition.
8139 Return an SYMBOL_REF rtx for the linkage. */
8142 alpha_need_linkage (const char *name, int is_local)
8144 splay_tree_node node;
8145 struct alpha_links *al;
8147 if (name[0] == '*')
8148 name++;
8150 if (is_local)
8152 struct alpha_funcs *cfaf;
8154 if (!alpha_funcs_tree)
8155 alpha_funcs_tree = splay_tree_new_ggc ((splay_tree_compare_fn)
8156 splay_tree_compare_pointers);
8158 cfaf = (struct alpha_funcs *) ggc_alloc (sizeof (struct alpha_funcs));
8160 cfaf->links = 0;
8161 cfaf->num = ++alpha_funcs_num;
8163 splay_tree_insert (alpha_funcs_tree,
8164 (splay_tree_key) current_function_decl,
8165 (splay_tree_value) cfaf);
8168 if (alpha_links_tree)
8170 /* Is this name already defined? */
8172 node = splay_tree_lookup (alpha_links_tree, (splay_tree_key) name);
8173 if (node)
8175 al = (struct alpha_links *) node->value;
8176 if (is_local)
8178 /* Defined here but external assumed. */
8179 if (al->lkind == KIND_EXTERN)
8180 al->lkind = KIND_LOCAL;
8182 else
8184 /* Used here but unused assumed. */
8185 if (al->lkind == KIND_UNUSED)
8186 al->lkind = KIND_LOCAL;
8188 return al->linkage;
8191 else
8192 alpha_links_tree = splay_tree_new_ggc ((splay_tree_compare_fn) strcmp);
8194 al = (struct alpha_links *) ggc_alloc (sizeof (struct alpha_links));
8195 name = ggc_strdup (name);
8197 /* Assume external if no definition. */
8198 al->lkind = (is_local ? KIND_UNUSED : KIND_EXTERN);
8200 /* Ensure we have an IDENTIFIER so assemble_name can mark it used. */
8201 get_identifier (name);
8203 /* Construct a SYMBOL_REF for us to call. */
8205 size_t name_len = strlen (name);
8206 char *linksym = alloca (name_len + 6);
8207 linksym[0] = '$';
8208 memcpy (linksym + 1, name, name_len);
8209 memcpy (linksym + 1 + name_len, "..lk", 5);
8210 al->linkage = gen_rtx_SYMBOL_REF (Pmode,
8211 ggc_alloc_string (linksym, name_len + 5));
8214 splay_tree_insert (alpha_links_tree, (splay_tree_key) name,
8215 (splay_tree_value) al);
8217 return al->linkage;
8221 alpha_use_linkage (rtx linkage, tree cfundecl, int lflag, int rflag)
8223 splay_tree_node cfunnode;
8224 struct alpha_funcs *cfaf;
8225 struct alpha_links *al;
8226 const char *name = XSTR (linkage, 0);
8228 cfaf = (struct alpha_funcs *) 0;
8229 al = (struct alpha_links *) 0;
8231 cfunnode = splay_tree_lookup (alpha_funcs_tree, (splay_tree_key) cfundecl);
8232 cfaf = (struct alpha_funcs *) cfunnode->value;
8234 if (cfaf->links)
8236 splay_tree_node lnode;
8238 /* Is this name already defined? */
8240 lnode = splay_tree_lookup (cfaf->links, (splay_tree_key) name);
8241 if (lnode)
8242 al = (struct alpha_links *) lnode->value;
8244 else
8245 cfaf->links = splay_tree_new_ggc ((splay_tree_compare_fn) strcmp);
8247 if (!al)
8249 size_t name_len;
8250 size_t buflen;
8251 char buf [512];
8252 char *linksym;
8253 splay_tree_node node = 0;
8254 struct alpha_links *anl;
8256 if (name[0] == '*')
8257 name++;
8259 name_len = strlen (name);
8261 al = (struct alpha_links *) ggc_alloc (sizeof (struct alpha_links));
8262 al->num = cfaf->num;
8264 node = splay_tree_lookup (alpha_links_tree, (splay_tree_key) name);
8265 if (node)
8267 anl = (struct alpha_links *) node->value;
8268 al->lkind = anl->lkind;
8271 sprintf (buf, "$%d..%s..lk", cfaf->num, name);
8272 buflen = strlen (buf);
8273 linksym = alloca (buflen + 1);
8274 memcpy (linksym, buf, buflen + 1);
8276 al->linkage = gen_rtx_SYMBOL_REF
8277 (Pmode, ggc_alloc_string (linksym, buflen + 1));
8279 splay_tree_insert (cfaf->links, (splay_tree_key) name,
8280 (splay_tree_value) al);
8283 if (rflag)
8284 al->rkind = KIND_CODEADDR;
8285 else
8286 al->rkind = KIND_LINKAGE;
8288 if (lflag)
8289 return gen_rtx_MEM (Pmode, plus_constant (al->linkage, 8));
8290 else
8291 return al->linkage;
8294 static int
8295 alpha_write_one_linkage (splay_tree_node node, void *data)
8297 const char *const name = (const char *) node->key;
8298 struct alpha_links *link = (struct alpha_links *) node->value;
8299 FILE *stream = (FILE *) data;
8301 fprintf (stream, "$%d..%s..lk:\n", link->num, name);
8302 if (link->rkind == KIND_CODEADDR)
8304 if (link->lkind == KIND_LOCAL)
8306 /* Local and used */
8307 fprintf (stream, "\t.quad %s..en\n", name);
8309 else
8311 /* External and used, request code address. */
8312 fprintf (stream, "\t.code_address %s\n", name);
8315 else
8317 if (link->lkind == KIND_LOCAL)
8319 /* Local and used, build linkage pair. */
8320 fprintf (stream, "\t.quad %s..en\n", name);
8321 fprintf (stream, "\t.quad %s\n", name);
8323 else
8325 /* External and used, request linkage pair. */
8326 fprintf (stream, "\t.linkage %s\n", name);
8330 return 0;
8333 static void
8334 alpha_write_linkage (FILE *stream, const char *funname, tree fundecl)
8336 splay_tree_node node;
8337 struct alpha_funcs *func;
8339 link_section ();
8340 fprintf (stream, "\t.align 3\n");
8341 node = splay_tree_lookup (alpha_funcs_tree, (splay_tree_key) fundecl);
8342 func = (struct alpha_funcs *) node->value;
8344 fputs ("\t.name ", stream);
8345 assemble_name (stream, funname);
8346 fputs ("..na\n", stream);
8347 ASM_OUTPUT_LABEL (stream, funname);
8348 fprintf (stream, "\t.pdesc ");
8349 assemble_name (stream, funname);
8350 fprintf (stream, "..en,%s\n",
8351 alpha_procedure_type == PT_STACK ? "stack"
8352 : alpha_procedure_type == PT_REGISTER ? "reg" : "null");
8354 if (func->links)
8356 splay_tree_foreach (func->links, alpha_write_one_linkage, stream);
8357 /* splay_tree_delete (func->links); */
8361 /* Given a decl, a section name, and whether the decl initializer
8362 has relocs, choose attributes for the section. */
8364 #define SECTION_VMS_OVERLAY SECTION_FORGET
8365 #define SECTION_VMS_GLOBAL SECTION_MACH_DEP
8366 #define SECTION_VMS_INITIALIZE (SECTION_VMS_GLOBAL << 1)
8368 static unsigned int
8369 vms_section_type_flags (tree decl, const char *name, int reloc)
8371 unsigned int flags = default_section_type_flags (decl, name, reloc);
8373 if (decl && DECL_ATTRIBUTES (decl)
8374 && lookup_attribute ("overlaid", DECL_ATTRIBUTES (decl)))
8375 flags |= SECTION_VMS_OVERLAY;
8376 if (decl && DECL_ATTRIBUTES (decl)
8377 && lookup_attribute ("global", DECL_ATTRIBUTES (decl)))
8378 flags |= SECTION_VMS_GLOBAL;
8379 if (decl && DECL_ATTRIBUTES (decl)
8380 && lookup_attribute ("initialize", DECL_ATTRIBUTES (decl)))
8381 flags |= SECTION_VMS_INITIALIZE;
8383 return flags;
8386 /* Switch to an arbitrary section NAME with attributes as specified
8387 by FLAGS. ALIGN specifies any known alignment requirements for
8388 the section; 0 if the default should be used. */
8390 static void
8391 vms_asm_named_section (const char *name, unsigned int flags)
8393 fputc ('\n', asm_out_file);
8394 fprintf (asm_out_file, ".section\t%s", name);
8396 if (flags & SECTION_VMS_OVERLAY)
8397 fprintf (asm_out_file, ",OVR");
8398 if (flags & SECTION_VMS_GLOBAL)
8399 fprintf (asm_out_file, ",GBL");
8400 if (flags & SECTION_VMS_INITIALIZE)
8401 fprintf (asm_out_file, ",NOMOD");
8402 if (flags & SECTION_DEBUG)
8403 fprintf (asm_out_file, ",NOWRT");
8405 fputc ('\n', asm_out_file);
8408 /* Record an element in the table of global constructors. SYMBOL is
8409 a SYMBOL_REF of the function to be called; PRIORITY is a number
8410 between 0 and MAX_INIT_PRIORITY.
8412 Differs from default_ctors_section_asm_out_constructor in that the
8413 width of the .ctors entry is always 64 bits, rather than the 32 bits
8414 used by a normal pointer. */
8416 static void
8417 vms_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
8419 ctors_section ();
8420 assemble_align (BITS_PER_WORD);
8421 assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
8424 static void
8425 vms_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
8427 dtors_section ();
8428 assemble_align (BITS_PER_WORD);
8429 assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
8431 #else
8434 alpha_need_linkage (const char *name ATTRIBUTE_UNUSED,
8435 int is_local ATTRIBUTE_UNUSED)
8437 return NULL_RTX;
8441 alpha_use_linkage (rtx linkage ATTRIBUTE_UNUSED,
8442 tree cfundecl ATTRIBUTE_UNUSED,
8443 int lflag ATTRIBUTE_UNUSED,
8444 int rflag ATTRIBUTE_UNUSED)
8446 return NULL_RTX;
8449 #endif /* TARGET_ABI_OPEN_VMS */
8451 #if TARGET_ABI_UNICOSMK
8453 /* This evaluates to true if we do not know how to pass TYPE solely in
8454 registers. This is the case for all arguments that do not fit in two
8455 registers. */
8457 static bool
8458 unicosmk_must_pass_in_stack (enum machine_mode mode, tree type)
8460 if (type == NULL)
8461 return false;
8463 if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
8464 return true;
8465 if (TREE_ADDRESSABLE (type))
8466 return true;
8468 return ALPHA_ARG_SIZE (mode, type, 0) > 2;
8471 /* Define the offset between two registers, one to be eliminated, and the
8472 other its replacement, at the start of a routine. */
8475 unicosmk_initial_elimination_offset (int from, int to)
8477 int fixed_size;
8479 fixed_size = alpha_sa_size();
8480 if (fixed_size != 0)
8481 fixed_size += 48;
8483 if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
8484 return -fixed_size;
8485 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
8486 return 0;
8487 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
8488 return (ALPHA_ROUND (current_function_outgoing_args_size)
8489 + ALPHA_ROUND (get_frame_size()));
8490 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
8491 return (ALPHA_ROUND (fixed_size)
8492 + ALPHA_ROUND (get_frame_size()
8493 + current_function_outgoing_args_size));
8494 else
8495 abort ();
8498 /* Output the module name for .ident and .end directives. We have to strip
8499 directories and add make sure that the module name starts with a letter
8500 or '$'. */
8502 static void
8503 unicosmk_output_module_name (FILE *file)
8505 const char *name = lbasename (main_input_filename);
8506 unsigned len = strlen (name);
8507 char *clean_name = alloca (len + 2);
8508 char *ptr = clean_name;
8510 /* CAM only accepts module names that start with a letter or '$'. We
8511 prefix the module name with a '$' if necessary. */
8513 if (!ISALPHA (*name))
8514 *ptr++ = '$';
8515 memcpy (ptr, name, len + 1);
8516 clean_symbol_name (clean_name);
8517 fputs (clean_name, file);
8520 /* Output the definition of a common variable. */
8522 void
8523 unicosmk_output_common (FILE *file, const char *name, int size, int align)
8525 tree name_tree;
8526 printf ("T3E__: common %s\n", name);
8528 common_section ();
8529 fputs("\t.endp\n\n\t.psect ", file);
8530 assemble_name(file, name);
8531 fprintf(file, ",%d,common\n", floor_log2 (align / BITS_PER_UNIT));
8532 fprintf(file, "\t.byte\t0:%d\n", size);
8534 /* Mark the symbol as defined in this module. */
8535 name_tree = get_identifier (name);
8536 TREE_ASM_WRITTEN (name_tree) = 1;
8539 #define SECTION_PUBLIC SECTION_MACH_DEP
8540 #define SECTION_MAIN (SECTION_PUBLIC << 1)
8541 static int current_section_align;
8543 static unsigned int
8544 unicosmk_section_type_flags (tree decl, const char *name,
8545 int reloc ATTRIBUTE_UNUSED)
8547 unsigned int flags = default_section_type_flags (decl, name, reloc);
8549 if (!decl)
8550 return flags;
8552 if (TREE_CODE (decl) == FUNCTION_DECL)
8554 current_section_align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
8555 if (align_functions_log > current_section_align)
8556 current_section_align = align_functions_log;
8558 if (! strcmp (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), "main"))
8559 flags |= SECTION_MAIN;
8561 else
8562 current_section_align = floor_log2 (DECL_ALIGN (decl) / BITS_PER_UNIT);
8564 if (TREE_PUBLIC (decl))
8565 flags |= SECTION_PUBLIC;
8567 return flags;
8570 /* Generate a section name for decl and associate it with the
8571 declaration. */
8573 static void
8574 unicosmk_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
8576 const char *name;
8577 int len;
8579 if (!decl)
8580 abort ();
8582 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
8583 name = default_strip_name_encoding (name);
8584 len = strlen (name);
8586 if (TREE_CODE (decl) == FUNCTION_DECL)
8588 char *string;
8590 /* It is essential that we prefix the section name here because
8591 otherwise the section names generated for constructors and
8592 destructors confuse collect2. */
8594 string = alloca (len + 6);
8595 sprintf (string, "code@%s", name);
8596 DECL_SECTION_NAME (decl) = build_string (len + 5, string);
8598 else if (TREE_PUBLIC (decl))
8599 DECL_SECTION_NAME (decl) = build_string (len, name);
8600 else
8602 char *string;
8604 string = alloca (len + 6);
8605 sprintf (string, "data@%s", name);
8606 DECL_SECTION_NAME (decl) = build_string (len + 5, string);
8610 /* Switch to an arbitrary section NAME with attributes as specified
8611 by FLAGS. ALIGN specifies any known alignment requirements for
8612 the section; 0 if the default should be used. */
8614 static void
8615 unicosmk_asm_named_section (const char *name, unsigned int flags)
8617 const char *kind;
8619 /* Close the previous section. */
8621 fputs ("\t.endp\n\n", asm_out_file);
8623 /* Find out what kind of section we are opening. */
8625 if (flags & SECTION_MAIN)
8626 fputs ("\t.start\tmain\n", asm_out_file);
8628 if (flags & SECTION_CODE)
8629 kind = "code";
8630 else if (flags & SECTION_PUBLIC)
8631 kind = "common";
8632 else
8633 kind = "data";
8635 if (current_section_align != 0)
8636 fprintf (asm_out_file, "\t.psect\t%s,%d,%s\n", name,
8637 current_section_align, kind);
8638 else
8639 fprintf (asm_out_file, "\t.psect\t%s,%s\n", name, kind);
8642 static void
8643 unicosmk_insert_attributes (tree decl, tree *attr_ptr ATTRIBUTE_UNUSED)
8645 if (DECL_P (decl)
8646 && (TREE_PUBLIC (decl) || TREE_CODE (decl) == FUNCTION_DECL))
8647 unicosmk_unique_section (decl, 0);
8650 /* Output an alignment directive. We have to use the macro 'gcc@code@align'
8651 in code sections because .align fill unused space with zeroes. */
8653 void
8654 unicosmk_output_align (FILE *file, int align)
8656 if (inside_function)
8657 fprintf (file, "\tgcc@code@align\t%d\n", align);
8658 else
8659 fprintf (file, "\t.align\t%d\n", align);
8662 /* Add a case vector to the current function's list of deferred case
8663 vectors. Case vectors have to be put into a separate section because CAM
8664 does not allow data definitions in code sections. */
8666 void
8667 unicosmk_defer_case_vector (rtx lab, rtx vec)
8669 struct machine_function *machine = cfun->machine;
8671 vec = gen_rtx_EXPR_LIST (VOIDmode, lab, vec);
8672 machine->addr_list = gen_rtx_EXPR_LIST (VOIDmode, vec,
8673 machine->addr_list);
8676 /* Output a case vector. */
8678 static void
8679 unicosmk_output_addr_vec (FILE *file, rtx vec)
8681 rtx lab = XEXP (vec, 0);
8682 rtx body = XEXP (vec, 1);
8683 int vlen = XVECLEN (body, 0);
8684 int idx;
8686 (*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (lab));
8688 for (idx = 0; idx < vlen; idx++)
8690 ASM_OUTPUT_ADDR_VEC_ELT
8691 (file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0)));
8695 /* Output current function's deferred case vectors. */
8697 static void
8698 unicosmk_output_deferred_case_vectors (FILE *file)
8700 struct machine_function *machine = cfun->machine;
8701 rtx t;
8703 if (machine->addr_list == NULL_RTX)
8704 return;
8706 data_section ();
8707 for (t = machine->addr_list; t; t = XEXP (t, 1))
8708 unicosmk_output_addr_vec (file, XEXP (t, 0));
8711 /* Generate the name of the SSIB section for the current function. */
8713 #define SSIB_PREFIX "__SSIB_"
8714 #define SSIB_PREFIX_LEN 7
8716 static const char *
8717 unicosmk_ssib_name (void)
8719 /* This is ok since CAM won't be able to deal with names longer than that
8720 anyway. */
8722 static char name[256];
8724 rtx x;
8725 const char *fnname;
8726 int len;
8728 x = DECL_RTL (cfun->decl);
8729 if (GET_CODE (x) != MEM)
8730 abort ();
8731 x = XEXP (x, 0);
8732 if (GET_CODE (x) != SYMBOL_REF)
8733 abort ();
8734 fnname = XSTR (x, 0);
8736 len = strlen (fnname);
8737 if (len + SSIB_PREFIX_LEN > 255)
8738 len = 255 - SSIB_PREFIX_LEN;
8740 strcpy (name, SSIB_PREFIX);
8741 strncpy (name + SSIB_PREFIX_LEN, fnname, len);
8742 name[len + SSIB_PREFIX_LEN] = 0;
8744 return name;
8747 /* Set up the dynamic subprogram information block (DSIB) and update the
8748 frame pointer register ($15) for subroutines which have a frame. If the
8749 subroutine doesn't have a frame, simply increment $15. */
8751 static void
8752 unicosmk_gen_dsib (unsigned long *imaskP)
8754 if (alpha_procedure_type == PT_STACK)
8756 const char *ssib_name;
8757 rtx mem;
8759 /* Allocate 64 bytes for the DSIB. */
8761 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
8762 GEN_INT (-64))));
8763 emit_insn (gen_blockage ());
8765 /* Save the return address. */
8767 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 56));
8768 set_mem_alias_set (mem, alpha_sr_alias_set);
8769 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
8770 (*imaskP) &= ~(1UL << REG_RA);
8772 /* Save the old frame pointer. */
8774 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 48));
8775 set_mem_alias_set (mem, alpha_sr_alias_set);
8776 FRP (emit_move_insn (mem, hard_frame_pointer_rtx));
8777 (*imaskP) &= ~(1UL << HARD_FRAME_POINTER_REGNUM);
8779 emit_insn (gen_blockage ());
8781 /* Store the SSIB pointer. */
8783 ssib_name = ggc_strdup (unicosmk_ssib_name ());
8784 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 32));
8785 set_mem_alias_set (mem, alpha_sr_alias_set);
8787 FRP (emit_move_insn (gen_rtx_REG (DImode, 5),
8788 gen_rtx_SYMBOL_REF (Pmode, ssib_name)));
8789 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, 5)));
8791 /* Save the CIW index. */
8793 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 24));
8794 set_mem_alias_set (mem, alpha_sr_alias_set);
8795 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, 25)));
8797 emit_insn (gen_blockage ());
8799 /* Set the new frame pointer. */
8801 FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
8802 stack_pointer_rtx, GEN_INT (64))));
8805 else
8807 /* Increment the frame pointer register to indicate that we do not
8808 have a frame. */
8810 FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
8811 hard_frame_pointer_rtx, const1_rtx)));
8815 /* Output the static subroutine information block for the current
8816 function. */
8818 static void
8819 unicosmk_output_ssib (FILE *file, const char *fnname)
8821 int len;
8822 int i;
8823 rtx x;
8824 rtx ciw;
8825 struct machine_function *machine = cfun->machine;
8827 ssib_section ();
8828 fprintf (file, "\t.endp\n\n\t.psect\t%s%s,data\n", user_label_prefix,
8829 unicosmk_ssib_name ());
8831 /* Some required stuff and the function name length. */
8833 len = strlen (fnname);
8834 fprintf (file, "\t.quad\t^X20008%2.2X28\n", len);
8836 /* Saved registers
8837 ??? We don't do that yet. */
8839 fputs ("\t.quad\t0\n", file);
8841 /* Function address. */
8843 fputs ("\t.quad\t", file);
8844 assemble_name (file, fnname);
8845 putc ('\n', file);
8847 fputs ("\t.quad\t0\n", file);
8848 fputs ("\t.quad\t0\n", file);
8850 /* Function name.
8851 ??? We do it the same way Cray CC does it but this could be
8852 simplified. */
8854 for( i = 0; i < len; i++ )
8855 fprintf (file, "\t.byte\t%d\n", (int)(fnname[i]));
8856 if( (len % 8) == 0 )
8857 fputs ("\t.quad\t0\n", file);
8858 else
8859 fprintf (file, "\t.bits\t%d : 0\n", (8 - (len % 8))*8);
8861 /* All call information words used in the function. */
8863 for (x = machine->first_ciw; x; x = XEXP (x, 1))
8865 ciw = XEXP (x, 0);
8866 #if HOST_BITS_PER_WIDE_INT == 32
8867 fprintf (file, "\t.quad\t" HOST_WIDE_INT_PRINT_DOUBLE_HEX "\n",
8868 CONST_DOUBLE_HIGH (ciw), CONST_DOUBLE_LOW (ciw));
8869 #else
8870 fprintf (file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n", INTVAL (ciw));
8871 #endif
8875 /* Add a call information word (CIW) to the list of the current function's
8876 CIWs and return its index.
8878 X is a CONST_INT or CONST_DOUBLE representing the CIW. */
8881 unicosmk_add_call_info_word (rtx x)
8883 rtx node;
8884 struct machine_function *machine = cfun->machine;
8886 node = gen_rtx_EXPR_LIST (VOIDmode, x, NULL_RTX);
8887 if (machine->first_ciw == NULL_RTX)
8888 machine->first_ciw = node;
8889 else
8890 XEXP (machine->last_ciw, 1) = node;
8892 machine->last_ciw = node;
8893 ++machine->ciw_count;
8895 return GEN_INT (machine->ciw_count
8896 + strlen (current_function_name ())/8 + 5);
8899 static char unicosmk_section_buf[100];
8901 char *
8902 unicosmk_text_section (void)
8904 static int count = 0;
8905 sprintf (unicosmk_section_buf, "\t.endp\n\n\t.psect\tgcc@text___%d,code",
8906 count++);
8907 return unicosmk_section_buf;
8910 char *
8911 unicosmk_data_section (void)
8913 static int count = 1;
8914 sprintf (unicosmk_section_buf, "\t.endp\n\n\t.psect\tgcc@data___%d,data",
8915 count++);
8916 return unicosmk_section_buf;
8919 /* The Cray assembler doesn't accept extern declarations for symbols which
8920 are defined in the same file. We have to keep track of all global
8921 symbols which are referenced and/or defined in a source file and output
8922 extern declarations for those which are referenced but not defined at
8923 the end of file. */
8925 /* List of identifiers for which an extern declaration might have to be
8926 emitted. */
8927 /* FIXME: needs to use GC, so it can be saved and restored for PCH. */
8929 struct unicosmk_extern_list
8931 struct unicosmk_extern_list *next;
8932 const char *name;
8935 static struct unicosmk_extern_list *unicosmk_extern_head = 0;
8937 /* Output extern declarations which are required for every asm file. */
8939 static void
8940 unicosmk_output_default_externs (FILE *file)
8942 static const char *const externs[] =
8943 { "__T3E_MISMATCH" };
8945 int i;
8946 int n;
8948 n = ARRAY_SIZE (externs);
8950 for (i = 0; i < n; i++)
8951 fprintf (file, "\t.extern\t%s\n", externs[i]);
8954 /* Output extern declarations for global symbols which are have been
8955 referenced but not defined. */
8957 static void
8958 unicosmk_output_externs (FILE *file)
8960 struct unicosmk_extern_list *p;
8961 const char *real_name;
8962 int len;
8963 tree name_tree;
8965 len = strlen (user_label_prefix);
8966 for (p = unicosmk_extern_head; p != 0; p = p->next)
8968 /* We have to strip the encoding and possibly remove user_label_prefix
8969 from the identifier in order to handle -fleading-underscore and
8970 explicit asm names correctly (cf. gcc.dg/asm-names-1.c). */
8971 real_name = default_strip_name_encoding (p->name);
8972 if (len && p->name[0] == '*'
8973 && !memcmp (real_name, user_label_prefix, len))
8974 real_name += len;
8976 name_tree = get_identifier (real_name);
8977 if (! TREE_ASM_WRITTEN (name_tree))
8979 TREE_ASM_WRITTEN (name_tree) = 1;
8980 fputs ("\t.extern\t", file);
8981 assemble_name (file, p->name);
8982 putc ('\n', file);
8987 /* Record an extern. */
8989 void
8990 unicosmk_add_extern (const char *name)
8992 struct unicosmk_extern_list *p;
8994 p = (struct unicosmk_extern_list *)
8995 xmalloc (sizeof (struct unicosmk_extern_list));
8996 p->next = unicosmk_extern_head;
8997 p->name = name;
8998 unicosmk_extern_head = p;
9001 /* The Cray assembler generates incorrect code if identifiers which
9002 conflict with register names are used as instruction operands. We have
9003 to replace such identifiers with DEX expressions. */
9005 /* Structure to collect identifiers which have been replaced by DEX
9006 expressions. */
9007 /* FIXME: needs to use GC, so it can be saved and restored for PCH. */
9009 struct unicosmk_dex {
9010 struct unicosmk_dex *next;
9011 const char *name;
9014 /* List of identifiers which have been replaced by DEX expressions. The DEX
9015 number is determined by the position in the list. */
9017 static struct unicosmk_dex *unicosmk_dex_list = NULL;
9019 /* The number of elements in the DEX list. */
9021 static int unicosmk_dex_count = 0;
9023 /* Check if NAME must be replaced by a DEX expression. */
9025 static int
9026 unicosmk_special_name (const char *name)
9028 if (name[0] == '*')
9029 ++name;
9031 if (name[0] == '$')
9032 ++name;
9034 if (name[0] != 'r' && name[0] != 'f' && name[0] != 'R' && name[0] != 'F')
9035 return 0;
9037 switch (name[1])
9039 case '1': case '2':
9040 return (name[2] == '\0' || (ISDIGIT (name[2]) && name[3] == '\0'));
9042 case '3':
9043 return (name[2] == '\0'
9044 || ((name[2] == '0' || name[2] == '1') && name[3] == '\0'));
9046 default:
9047 return (ISDIGIT (name[1]) && name[2] == '\0');
9051 /* Return the DEX number if X must be replaced by a DEX expression and 0
9052 otherwise. */
9054 static int
9055 unicosmk_need_dex (rtx x)
9057 struct unicosmk_dex *dex;
9058 const char *name;
9059 int i;
9061 if (GET_CODE (x) != SYMBOL_REF)
9062 return 0;
9064 name = XSTR (x,0);
9065 if (! unicosmk_special_name (name))
9066 return 0;
9068 i = unicosmk_dex_count;
9069 for (dex = unicosmk_dex_list; dex; dex = dex->next)
9071 if (! strcmp (name, dex->name))
9072 return i;
9073 --i;
9076 dex = (struct unicosmk_dex *) xmalloc (sizeof (struct unicosmk_dex));
9077 dex->name = name;
9078 dex->next = unicosmk_dex_list;
9079 unicosmk_dex_list = dex;
9081 ++unicosmk_dex_count;
9082 return unicosmk_dex_count;
9085 /* Output the DEX definitions for this file. */
9087 static void
9088 unicosmk_output_dex (FILE *file)
9090 struct unicosmk_dex *dex;
9091 int i;
9093 if (unicosmk_dex_list == NULL)
9094 return;
9096 fprintf (file, "\t.dexstart\n");
9098 i = unicosmk_dex_count;
9099 for (dex = unicosmk_dex_list; dex; dex = dex->next)
9101 fprintf (file, "\tDEX (%d) = ", i);
9102 assemble_name (file, dex->name);
9103 putc ('\n', file);
9104 --i;
9107 fprintf (file, "\t.dexend\n");
9110 /* Output text that to appear at the beginning of an assembler file. */
9112 static void
9113 unicosmk_file_start (void)
9115 int i;
9117 fputs ("\t.ident\t", asm_out_file);
9118 unicosmk_output_module_name (asm_out_file);
9119 fputs ("\n\n", asm_out_file);
9121 /* The Unicos/Mk assembler uses different register names. Instead of trying
9122 to support them, we simply use micro definitions. */
9124 /* CAM has different register names: rN for the integer register N and fN
9125 for the floating-point register N. Instead of trying to use these in
9126 alpha.md, we define the symbols $N and $fN to refer to the appropriate
9127 register. */
9129 for (i = 0; i < 32; ++i)
9130 fprintf (asm_out_file, "$%d <- r%d\n", i, i);
9132 for (i = 0; i < 32; ++i)
9133 fprintf (asm_out_file, "$f%d <- f%d\n", i, i);
9135 putc ('\n', asm_out_file);
9137 /* The .align directive fill unused space with zeroes which does not work
9138 in code sections. We define the macro 'gcc@code@align' which uses nops
9139 instead. Note that it assumes that code sections always have the
9140 biggest possible alignment since . refers to the current offset from
9141 the beginning of the section. */
9143 fputs ("\t.macro gcc@code@align n\n", asm_out_file);
9144 fputs ("gcc@n@bytes = 1 << n\n", asm_out_file);
9145 fputs ("gcc@here = . % gcc@n@bytes\n", asm_out_file);
9146 fputs ("\t.if ne, gcc@here, 0\n", asm_out_file);
9147 fputs ("\t.repeat (gcc@n@bytes - gcc@here) / 4\n", asm_out_file);
9148 fputs ("\tbis r31,r31,r31\n", asm_out_file);
9149 fputs ("\t.endr\n", asm_out_file);
9150 fputs ("\t.endif\n", asm_out_file);
9151 fputs ("\t.endm gcc@code@align\n\n", asm_out_file);
9153 /* Output extern declarations which should always be visible. */
9154 unicosmk_output_default_externs (asm_out_file);
9156 /* Open a dummy section. We always need to be inside a section for the
9157 section-switching code to work correctly.
9158 ??? This should be a module id or something like that. I still have to
9159 figure out what the rules for those are. */
9160 fputs ("\n\t.psect\t$SG00000,data\n", asm_out_file);
9163 /* Output text to appear at the end of an assembler file. This includes all
9164 pending extern declarations and DEX expressions. */
9166 static void
9167 unicosmk_file_end (void)
9169 fputs ("\t.endp\n\n", asm_out_file);
9171 /* Output all pending externs. */
9173 unicosmk_output_externs (asm_out_file);
9175 /* Output dex definitions used for functions whose names conflict with
9176 register names. */
9178 unicosmk_output_dex (asm_out_file);
9180 fputs ("\t.end\t", asm_out_file);
9181 unicosmk_output_module_name (asm_out_file);
9182 putc ('\n', asm_out_file);
9185 #else
9187 static void
9188 unicosmk_output_deferred_case_vectors (FILE *file ATTRIBUTE_UNUSED)
9191 static void
9192 unicosmk_gen_dsib (unsigned long *imaskP ATTRIBUTE_UNUSED)
9195 static void
9196 unicosmk_output_ssib (FILE * file ATTRIBUTE_UNUSED,
9197 const char * fnname ATTRIBUTE_UNUSED)
9201 unicosmk_add_call_info_word (rtx x ATTRIBUTE_UNUSED)
9203 return NULL_RTX;
9206 static int
9207 unicosmk_need_dex (rtx x ATTRIBUTE_UNUSED)
9209 return 0;
9212 #endif /* TARGET_ABI_UNICOSMK */
9214 static void
9215 alpha_init_libfuncs (void)
9217 if (TARGET_ABI_UNICOSMK)
9219 /* Prevent gcc from generating calls to __divsi3. */
9220 set_optab_libfunc (sdiv_optab, SImode, 0);
9221 set_optab_libfunc (udiv_optab, SImode, 0);
9223 /* Use the functions provided by the system library
9224 for DImode integer division. */
9225 set_optab_libfunc (sdiv_optab, DImode, "$sldiv");
9226 set_optab_libfunc (udiv_optab, DImode, "$uldiv");
9228 else if (TARGET_ABI_OPEN_VMS)
9230 /* Use the VMS runtime library functions for division and
9231 remainder. */
9232 set_optab_libfunc (sdiv_optab, SImode, "OTS$DIV_I");
9233 set_optab_libfunc (sdiv_optab, DImode, "OTS$DIV_L");
9234 set_optab_libfunc (udiv_optab, SImode, "OTS$DIV_UI");
9235 set_optab_libfunc (udiv_optab, DImode, "OTS$DIV_UL");
9236 set_optab_libfunc (smod_optab, SImode, "OTS$REM_I");
9237 set_optab_libfunc (smod_optab, DImode, "OTS$REM_L");
9238 set_optab_libfunc (umod_optab, SImode, "OTS$REM_UI");
9239 set_optab_libfunc (umod_optab, DImode, "OTS$REM_UL");
9244 /* Initialize the GCC target structure. */
9245 #if TARGET_ABI_OPEN_VMS
9246 # undef TARGET_ATTRIBUTE_TABLE
9247 # define TARGET_ATTRIBUTE_TABLE vms_attribute_table
9248 # undef TARGET_SECTION_TYPE_FLAGS
9249 # define TARGET_SECTION_TYPE_FLAGS vms_section_type_flags
9250 #endif
9252 #undef TARGET_IN_SMALL_DATA_P
9253 #define TARGET_IN_SMALL_DATA_P alpha_in_small_data_p
9255 #if TARGET_ABI_UNICOSMK
9256 # undef TARGET_INSERT_ATTRIBUTES
9257 # define TARGET_INSERT_ATTRIBUTES unicosmk_insert_attributes
9258 # undef TARGET_SECTION_TYPE_FLAGS
9259 # define TARGET_SECTION_TYPE_FLAGS unicosmk_section_type_flags
9260 # undef TARGET_ASM_UNIQUE_SECTION
9261 # define TARGET_ASM_UNIQUE_SECTION unicosmk_unique_section
9262 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
9263 #define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
9264 # undef TARGET_ASM_GLOBALIZE_LABEL
9265 # define TARGET_ASM_GLOBALIZE_LABEL hook_void_FILEptr_constcharptr
9266 # undef TARGET_MUST_PASS_IN_STACK
9267 # define TARGET_MUST_PASS_IN_STACK unicosmk_must_pass_in_stack
9268 #endif
9270 #undef TARGET_ASM_ALIGNED_HI_OP
9271 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
9272 #undef TARGET_ASM_ALIGNED_DI_OP
9273 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
9275 /* Default unaligned ops are provided for ELF systems. To get unaligned
9276 data for non-ELF systems, we have to turn off auto alignment. */
9277 #ifndef OBJECT_FORMAT_ELF
9278 #undef TARGET_ASM_UNALIGNED_HI_OP
9279 #define TARGET_ASM_UNALIGNED_HI_OP "\t.align 0\n\t.word\t"
9280 #undef TARGET_ASM_UNALIGNED_SI_OP
9281 #define TARGET_ASM_UNALIGNED_SI_OP "\t.align 0\n\t.long\t"
9282 #undef TARGET_ASM_UNALIGNED_DI_OP
9283 #define TARGET_ASM_UNALIGNED_DI_OP "\t.align 0\n\t.quad\t"
9284 #endif
9286 #ifdef OBJECT_FORMAT_ELF
9287 #undef TARGET_ASM_SELECT_RTX_SECTION
9288 #define TARGET_ASM_SELECT_RTX_SECTION alpha_elf_select_rtx_section
9289 #endif
9291 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
9292 #define TARGET_ASM_FUNCTION_END_PROLOGUE alpha_output_function_end_prologue
9294 #undef TARGET_INIT_LIBFUNCS
9295 #define TARGET_INIT_LIBFUNCS alpha_init_libfuncs
9297 #if TARGET_ABI_UNICOSMK
9298 #undef TARGET_ASM_FILE_START
9299 #define TARGET_ASM_FILE_START unicosmk_file_start
9300 #undef TARGET_ASM_FILE_END
9301 #define TARGET_ASM_FILE_END unicosmk_file_end
9302 #else
9303 #undef TARGET_ASM_FILE_START
9304 #define TARGET_ASM_FILE_START alpha_file_start
9305 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
9306 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
9307 #endif
9309 #undef TARGET_SCHED_ADJUST_COST
9310 #define TARGET_SCHED_ADJUST_COST alpha_adjust_cost
9311 #undef TARGET_SCHED_ISSUE_RATE
9312 #define TARGET_SCHED_ISSUE_RATE alpha_issue_rate
9313 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
9314 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
9315 alpha_multipass_dfa_lookahead
9317 #undef TARGET_HAVE_TLS
9318 #define TARGET_HAVE_TLS HAVE_AS_TLS
9320 #undef TARGET_INIT_BUILTINS
9321 #define TARGET_INIT_BUILTINS alpha_init_builtins
9322 #undef TARGET_EXPAND_BUILTIN
9323 #define TARGET_EXPAND_BUILTIN alpha_expand_builtin
9325 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
9326 #define TARGET_FUNCTION_OK_FOR_SIBCALL alpha_function_ok_for_sibcall
9327 #undef TARGET_CANNOT_COPY_INSN_P
9328 #define TARGET_CANNOT_COPY_INSN_P alpha_cannot_copy_insn_p
9330 #if TARGET_ABI_OSF
9331 #undef TARGET_ASM_OUTPUT_MI_THUNK
9332 #define TARGET_ASM_OUTPUT_MI_THUNK alpha_output_mi_thunk_osf
9333 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
9334 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
9335 #endif
9337 #undef TARGET_RTX_COSTS
9338 #define TARGET_RTX_COSTS alpha_rtx_costs
9339 #undef TARGET_ADDRESS_COST
9340 #define TARGET_ADDRESS_COST hook_int_rtx_0
9342 #undef TARGET_MACHINE_DEPENDENT_REORG
9343 #define TARGET_MACHINE_DEPENDENT_REORG alpha_reorg
9345 #undef TARGET_PROMOTE_FUNCTION_ARGS
9346 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
9347 #undef TARGET_PROMOTE_FUNCTION_RETURN
9348 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
9349 #undef TARGET_PROMOTE_PROTOTYPES
9350 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_false
9351 #undef TARGET_RETURN_IN_MEMORY
9352 #define TARGET_RETURN_IN_MEMORY alpha_return_in_memory
9353 #undef TARGET_PASS_BY_REFERENCE
9354 #define TARGET_PASS_BY_REFERENCE alpha_pass_by_reference
9355 #undef TARGET_SETUP_INCOMING_VARARGS
9356 #define TARGET_SETUP_INCOMING_VARARGS alpha_setup_incoming_varargs
9357 #undef TARGET_STRICT_ARGUMENT_NAMING
9358 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
9359 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
9360 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
9361 #undef TARGET_SPLIT_COMPLEX_ARG
9362 #define TARGET_SPLIT_COMPLEX_ARG alpha_split_complex_arg
9363 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
9364 #define TARGET_GIMPLIFY_VA_ARG_EXPR alpha_gimplify_va_arg
9365 #undef TARGET_VECTOR_MODE_SUPPORTED_P
9366 #define TARGET_VECTOR_MODE_SUPPORTED_P alpha_vector_mode_supported_p
9368 #undef TARGET_BUILD_BUILTIN_VA_LIST
9369 #define TARGET_BUILD_BUILTIN_VA_LIST alpha_build_builtin_va_list
9371 struct gcc_target targetm = TARGET_INITIALIZER;
9374 #include "gt-alpha.h"