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)
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. */
26 #include "coretypes.h"
31 #include "hard-reg-set.h"
33 #include "insn-config.h"
34 #include "conditions.h"
36 #include "insn-attr.h"
47 #include "integrate.h"
50 #include "target-def.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
[] =
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
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
] =
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 */
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 */
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
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
202 #define NUM_ARGS current_function_args_info
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
);
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. */
224 override_options (void)
227 static const struct cpu_table
{
228 const char *const name
;
229 const enum processor_type processor
;
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
},
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");
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
;
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. */
277 if (TARGET_ABI_UNICOSMK
)
278 warning ("-mieee not supported on Unicos/Mk");
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");
292 alpha_tp
= ALPHA_TP_INSN
;
293 alpha_fptm
= ALPHA_FPTM_SUI
;
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
;
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
;
320 error ("bad value `%s' for -mfp-rounding-mode switch",
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
;
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)
342 else if (strcmp (alpha_tls_size_string
, "32") == 0)
344 else if (strcmp (alpha_tls_size_string
, "64") == 0)
347 error ("bad value `%s' for -mtls-size switch", alpha_tls_size_string
);
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
;
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
;
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
;
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
;
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
]);
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. */
460 warning ("bad value `%s' for -mmemory-latency", alpha_mlat_string
);
464 alpha_memory_latency
= lat
;
467 /* Default the definition of "small data" to 8 bytes. */
471 /* Infer TARGET_SMALL_DATA from -fpic/-fPIC. */
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)
484 if (align_jumps
<= 0)
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
)
514 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
516 if ((value
& 0xff) != 0 && (value
& 0xff) != 0xff)
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
)
530 if (GET_CODE (op
) != UNSPEC
|| XINT (op
, 1) != unspec
)
532 op
= XVECEXP (op
, 0, 0);
534 if (GET_CODE (op
) != SYMBOL_REF
)
537 if (SYMBOL_REF_LOCAL_P (op
))
539 if (alpha_tls_size
> size
)
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
;
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
)
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
)];
583 /* Implements CONST_OK_FOR_LETTER_P. Return true if the value matches
584 the range defined for C in [I-P]. */
587 alpha_const_ok_for_letter_p (HOST_WIDE_INT value
, int c
)
592 /* An unsigned 8 bit constant. */
593 return (unsigned HOST_WIDE_INT
) value
< 0x100;
595 /* The constant zero. */
598 /* A signed 16 bit constant. */
599 return (unsigned HOST_WIDE_INT
) (value
+ 0x8000) < 0x10000;
601 /* A shifted signed 16 bit constant appropriate for LDAH. */
602 return ((value
& 0xffff) == 0
603 && ((value
) >> 31 == -1 || value
>> 31 == 0));
605 /* A constant that can be AND'ed with using a ZAP insn. */
606 return zap_mask (value
);
608 /* A complemented unsigned 8 bit constant. */
609 return (unsigned HOST_WIDE_INT
) (~ value
) < 0x100;
611 /* A negated unsigned 8 bit constant. */
612 return (unsigned HOST_WIDE_INT
) (- value
) < 0x100;
614 /* The constant 1, 2 or 3. */
615 return value
== 1 || value
== 2 || value
== 3;
622 /* Implements CONST_DOUBLE_OK_FOR_LETTER_P. Return true if VALUE
623 matches for C in [GH]. */
626 alpha_const_double_ok_for_letter_p (rtx value
, int c
)
631 /* The floating point zero constant. */
632 return (GET_MODE_CLASS (GET_MODE (value
)) == MODE_FLOAT
633 && value
== CONST0_RTX (GET_MODE (value
)));
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
)));
646 /* Implements CONST_DOUBLE_OK_FOR_LETTER_P. Return true if VALUE
650 alpha_extra_constraint (rtx value
, int c
)
655 return normal_memory_operand (value
, VOIDmode
);
657 return direct_call_operand (value
, Pmode
);
659 return (GET_CODE (value
) == CONST_INT
660 && (unsigned HOST_WIDE_INT
) INTVAL (value
) < 64);
662 return GET_CODE (value
) == HIGH
;
664 return TARGET_ABI_UNICOSMK
&& symbolic_operand (value
, VOIDmode
);
666 return (GET_CODE (value
) == CONST_VECTOR
667 && value
== CONST0_RTX (GET_MODE (value
)));
673 /* Implements target hook vector_mode_supported_p. */
675 alpha_vector_mode_supported_p (enum machine_mode mode
)
678 && ((mode
== V8QImode
)
679 || (mode
== V4HImode
)
680 || (mode
== V2SImode
)))
686 /* Return 1 if this function can directly return via $26. */
691 return (! TARGET_ABI_OPEN_VMS
&& ! TARGET_ABI_UNICOSMK
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
)
706 tmp
= JUMP_LABEL (insn
);
709 tmp
= NEXT_INSN (tmp
);
712 if (GET_CODE (tmp
) == JUMP_INSN
713 && GET_CODE (PATTERN (tmp
)) == ADDR_DIFF_VEC
)
714 return PATTERN (tmp
);
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. */
731 int n_labels
= XVECLEN (jump_table
, 1);
735 for (i
= 0; i
< n_labels
; i
++)
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))
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
)
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
;
770 /* Return true if the function DECL will share the same GP as any
771 function in the current unit of translation. */
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
))
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
)
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. */
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
)
803 /* Functions are never in the small data area. Duh. */
804 if (TREE_CODE (exp
) == FUNCTION_DECL
)
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)
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
)
827 #if TARGET_ABI_OPEN_VMS
829 alpha_linkage_symbol_p (const char *symname
)
831 int symlen
= strlen (symname
);
834 return strcmp (&symname
[symlen
- 4], "..lk") == 0;
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))))
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. */
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. */
862 && GET_CODE (x
) == AND
863 && GET_CODE (XEXP (x
, 1)) == CONST_INT
864 && INTVAL (XEXP (x
, 1)) == -8)
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
)))))
873 /* Unadorned general registers are valid. */
876 ? STRICT_REG_OK_FOR_BASE_P (x
)
877 : NONSTRICT_REG_OK_FOR_BASE_P (x
)))
880 /* Constant addresses (i.e. +/- 32k) are valid. */
881 if (CONSTANT_ADDRESS_P (x
))
884 #if TARGET_ABI_OPEN_VMS
885 if (LINKAGE_SYMBOL_REF_P (x
))
889 /* Register plus a small constant offset is valid. */
890 if (GET_CODE (x
) == PLUS
)
892 rtx ofs
= XEXP (x
, 1);
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
)))))
904 && NONSTRICT_REG_OK_FP_BASE_P (x
)
905 && GET_CODE (ofs
) == CONST_INT
)
908 ? STRICT_REG_OK_FOR_BASE_P (x
)
909 : NONSTRICT_REG_OK_FOR_BASE_P (x
))
910 && CONSTANT_ADDRESS_P (ofs
))
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
))
922 if (GET_CODE (x
) == LO_SUM
)
924 rtx ofs
= XEXP (x
, 1);
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
)))))
933 /* Must have a valid base register. */
936 ? STRICT_REG_OK_FOR_BASE_P (x
)
937 : NONSTRICT_REG_OK_FOR_BASE_P (x
))))
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
))
951 /* Build the SYMBOL_REF for __tls_get_addr. */
953 static GTY(()) rtx tls_get_addr_libfunc
;
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));
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. */
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));
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
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
);
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
:
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 ();
1041 emit_libcall_block (insn
, dest
, r0
, x
);
1044 case TLS_MODEL_LOCAL_DYNAMIC
:
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 ();
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
));
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
));
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
))
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
);
1132 HOST_WIDE_INT low
, high
;
1134 low
= ((addend
& 0xffff) ^ 0x8000) - 0x8000;
1136 high
= ((addend
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1140 x
= expand_simple_binop (Pmode
, PLUS
, x
, GEN_INT (addend
),
1141 (no_new_pseudos
? scratch
: NULL_RTX
),
1142 1, OPTAB_LIB_WIDEN
);
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
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. */
1164 /* Otherwise, we can make a tail call if the target function shares
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, \
1179 some_small_symbolic_operand_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
1183 /* Don't re-split. */
1184 if (GET_CODE (x
) == LO_SUM
)
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
);
1197 split_small_symbolic_operand_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
1201 /* Don't re-split. */
1202 if (GET_CODE (x
) == LO_SUM
)
1205 if (small_symbolic_operand (x
, Pmode
))
1207 x
= gen_rtx_LO_SUM (Pmode
, pic_offset_table_rtx
, x
);
1216 split_small_symbolic_operand (rtx x
)
1219 for_each_rtx (&x
, split_small_symbolic_operand_1
, NULL
);
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. */
1238 alpha_cannot_copy_insn_p (rtx insn
)
1240 if (!reload_completed
|| !TARGET_EXPLICIT_RELOCS
)
1242 if (recog_memoized (insn
) >= 0)
1243 return get_attr_cannot_copy (insn
);
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,
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;
1283 = (((val
- low
) & 0xffffffff) ^ 0x80000000) - 0x80000000;
1285 /* Check for 32-bit overflow. */
1286 if (high
+ low
!= val
)
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),
1296 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
1297 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
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. */
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
;
1317 cost_data
= &alpha_rtx_cost_size
;
1319 cost_data
= &alpha_rtx_cost_data
[alpha_cpu
];
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)
1337 if (x
== CONST0_RTX (mode
))
1339 else if ((outer_code
== PLUS
&& add_operand (x
, VOIDmode
))
1340 || (outer_code
== AND
&& and_operand (x
, VOIDmode
)))
1342 else if (add_operand (x
, VOIDmode
) || and_operand (x
, VOIDmode
))
1345 *total
= COSTS_N_INSNS (2);
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);
1360 /* Otherwise we do a load from the GOT. */
1361 *total
= COSTS_N_INSNS (optimize_size
? 1 : alpha_memory_latency
);
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));
1379 *total
= cost_data
->fp_mult
;
1380 else if (mode
== DImode
)
1381 *total
= cost_data
->int_mult_di
;
1383 *total
= cost_data
->int_mult_si
;
1387 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
1388 && INTVAL (XEXP (x
, 1)) <= 3)
1390 *total
= COSTS_N_INSNS (1);
1397 *total
= cost_data
->int_shift
;
1402 *total
= cost_data
->fp_add
;
1404 *total
= cost_data
->int_cmov
;
1412 *total
= cost_data
->int_div
;
1413 else if (mode
== SFmode
)
1414 *total
= cost_data
->fp_div_sf
;
1416 *total
= cost_data
->fp_div_df
;
1420 *total
= COSTS_N_INSNS (optimize_size
? 1 : alpha_memory_latency
);
1426 *total
= COSTS_N_INSNS (1);
1434 *total
= COSTS_N_INSNS (1) + cost_data
->int_cmov
;
1440 case UNSIGNED_FLOAT
:
1444 case FLOAT_TRUNCATE
:
1445 *total
= cost_data
->fp_add
;
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. */
1459 get_aligned_mem (rtx ref
, rtx
*paligned_mem
, rtx
*pbitnum
)
1462 HOST_WIDE_INT offset
= 0;
1464 if (GET_CODE (ref
) != MEM
)
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
))
1477 base
= XEXP (ref
, 0);
1480 if (GET_CODE (base
) == PLUS
)
1481 offset
+= INTVAL (XEXP (base
, 1)), base
= XEXP (base
, 0);
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));
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
)
1500 HOST_WIDE_INT offset
= 0;
1502 if (GET_CODE (ref
) != MEM
)
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
))
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. */
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
)))
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
)
1541 if (class == ALL_REGS
)
1542 return GENERAL_REGS
;
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. */
1550 return (class == ALL_REGS
? GENERAL_REGS
: 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. */
1567 secondary_reload_class (enum reg_class
class, enum machine_mode mode
,
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
;
1602 /* Subfunction of the following function. Update the flags of any MEM
1603 found in part of X. */
1606 alpha_set_memflags_1 (rtx
*xp
, void *data
)
1608 rtx x
= *xp
, orig
= (rtx
) data
;
1610 if (GET_CODE (x
) != MEM
)
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. */
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. */
1635 alpha_set_memflags (rtx insn
, rtx ref
)
1639 if (GET_CODE (ref
) != MEM
)
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
))
1653 base_ptr
= &PATTERN (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. */
1662 alpha_emit_set_const_1 (rtx target
, enum machine_mode mode
,
1663 HOST_WIDE_INT c
, int n
)
1667 /* Use a pseudo if highly optimizing and still generating RTL. */
1669 = (flag_expensive_optimizations
&& !no_new_pseudos
? 0 : target
);
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)
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. */
1703 target
= gen_reg_rtx (mode
);
1704 emit_insn (gen_rtx_SET (VOIDmode
, target
, GEN_INT (c
)));
1707 else if (n
>= 2 + (extra
!= 0))
1711 emit_insn (gen_rtx_SET (VOIDmode
, target
, GEN_INT (high
<< 16)));
1715 temp
= copy_to_suggested_reg (GEN_INT (high
<< 16),
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. */
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
);
1735 target
= gen_reg_rtx (mode
);
1736 insn
= gen_rtx_PLUS (mode
, temp
, GEN_INT (low
));
1737 insn
= gen_rtx_SET (VOIDmode
, target
, insn
);
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
))
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
1760 new = ((c
& 0xffff) ^ 0x8000) - 0x8000;
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
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
1785 ((unsigned HOST_WIDE_INT
) c
) >> bits
, i
)))
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
,
1801 || ((temp
= (alpha_emit_set_const
1803 ((c
<< bits
) | (((HOST_WIDE_INT
) 1 << bits
) - 1)),
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
,
1818 || ((temp
= (alpha_emit_set_const
1820 ((c
<< bits
) | (((HOST_WIDE_INT
) 1 << bits
) - 1)),
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. */
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. */
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
);
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
)
1863 rtx orig_target
= target
;
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
);
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
);
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
));
1890 /* Allow for the case where we changed the mode of TARGET. */
1891 if (result
== target
)
1892 result
= orig_target
;
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))
1911 d1
= ((c1
& 0xffff) ^ 0x8000) - 0x8000;
1913 d2
= ((c1
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1914 c1
= (c1
- d2
) >> 32;
1915 d3
= ((c1
& 0xffff) ^ 0x8000) - 0x8000;
1917 d4
= ((c1
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1921 d1
= ((c1
& 0xffff) ^ 0x8000) - 0x8000;
1923 d2
= ((c1
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1927 d3
= ((c2
& 0xffff) ^ 0x8000) - 0x8000;
1929 d4
= ((c2
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1934 /* Construct the high word */
1937 emit_move_insn (target
, GEN_INT (d4
));
1939 emit_move_insn (target
, gen_rtx_PLUS (DImode
, target
, GEN_INT (d3
)));
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. */
1949 emit_move_insn (target
, gen_rtx_PLUS (DImode
, target
, GEN_INT (d2
)));
1951 emit_move_insn (target
, gen_rtx_PLUS (DImode
, target
, GEN_INT (d1
)));
1956 /* Expand a move instruction; return true if all work is done.
1957 We don't handle non-bwx subword loads here. */
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
))
1972 tmp
= alpha_legitimize_address (operands
[1], operands
[0], mode
);
1975 if (tmp
== operands
[0])
1982 /* Early out for non-constants and valid constants. */
1983 if (! CONSTANT_P (operands
[1]) || input_operand (operands
[1], mode
))
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]);
1998 else if (HOST_BITS_PER_WIDE_INT
>= 64)
2000 i0
= CONST_DOUBLE_LOW (operands
[1]);
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
);
2017 if (rtx_equal_p (operands
[0], temp
))
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];
2033 operands
[1] = validize_mem (operands
[1]);
2037 /* Expand a non-bwx QImode or HImode move instruction;
2038 return true if all work is done. */
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]))));
2072 rtx aligned_mem
, bitnum
;
2073 rtx scratch
= gen_reg_rtx (SImode
);
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;
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
));
2091 emit_move_insn (operands
[0], gen_lowpart (mode
, subtarget
));
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
;
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;
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),
2117 alpha_set_memflags (seq
, operands
[1]);
2121 emit_move_insn (operands
[0], gen_lowpart (mode
, subtarget
));
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
,
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]);
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:
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
2202 cpyse $f11,$f31,$f10
2203 cpyse $f31,$f11,$f11
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. */
2217 alpha_emit_floatuns (rtx operands
[2])
2219 rtx neglab
, donelab
, i0
, i1
, f0
, in
, out
;
2220 enum machine_mode mode
;
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
));
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
;
2258 if (alpha_compare
.fp_p
&& GET_MODE (op0
) == TFmode
)
2260 if (! TARGET_HAS_XFLOATING_LIBS
)
2263 /* X_floating library comparison functions return
2267 Convert the compare against the raw return value. */
2289 op0
= alpha_emit_xfloating_compare (cmp_code
, op0
, op1
);
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. */
2298 case EQ
: case LE
: case LT
: case LEU
: case LTU
:
2300 /* We have these compares: */
2301 cmp_code
= code
, branch_code
= NE
;
2306 /* These must be reversed. */
2307 cmp_code
= reverse_condition (code
), branch_code
= EQ
;
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
);
2316 tem
= op0
, op0
= op1
, op1
= tem
;
2320 cmp_code
= reverse_condition (code
);
2329 if (alpha_compare
.fp_p
)
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
);
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
;
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
;
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. */
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
;
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
)
2428 /* X_floating library comparison functions return
2432 Convert the compare against the raw return value. */
2434 if (code
== UNORDERED
|| code
== ORDERED
)
2439 op0
= alpha_emit_xfloating_compare (cmp_code
, op0
, op1
);
2443 if (code
== UNORDERED
)
2445 else if (code
== ORDERED
)
2451 if (fp_p
&& !TARGET_FIX
)
2454 /* The general case: fold the comparison code to the types of compares
2455 that we have, choosing the branch as necessary. */
2460 case EQ
: case LE
: case LT
: case LEU
: case LTU
:
2462 /* We have these compares. */
2464 cmp_code
= code
, code
= NE
;
2468 if (!fp_p
&& op1
== const0_rtx
)
2473 cmp_code
= reverse_condition (code
);
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
)
2482 code
= swap_condition (code
);
2484 cmp_code
= code
, code
= NE
;
2485 tmp
= op0
, op0
= op1
, op1
= tmp
;
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
;
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
;
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
;
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. */
2557 case EQ
: case LE
: case LT
: case LEU
: case LTU
:
2558 /* We have these compares. */
2559 cmp_code
= code
, code
= NE
;
2563 /* This must be reversed. */
2564 cmp_code
= EQ
, code
= EQ
;
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
;
2574 cmp_code
= swap_condition (code
);
2576 tem
= op0
, op0
= op1
, op1
= tem
;
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
,
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
);
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. */
2613 case EQ
: case LE
: case LT
: case LEU
: case LTU
:
2614 /* We have these compares: */
2618 /* This must be reversed. */
2619 code
= reverse_condition (code
);
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
;
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
)
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
);
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
;
2681 subtarget
= target
= dest
;
2684 target
= gen_lowpart (DImode
, dest
);
2685 if (! no_new_pseudos
)
2686 subtarget
= gen_reg_rtx (DImode
);
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
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)
2718 tmp
= gen_rtx_fmt_ee (code
, DImode
, cond
, const0_rtx
);
2719 emit_insn (gen_rtx_SET (VOIDmode
, copy_rtx (subtarget
), tmp
));
2722 emit_insn (gen_adddi3 (target
, copy_rtx (subtarget
), GEN_INT (f
)));
2725 add_op
= GEN_INT (f
);
2726 if (sext_add_operand (add_op
, mode
))
2728 tmp
= gen_rtx_MULT (DImode
, copy_rtx (subtarget
),
2730 tmp
= gen_rtx_PLUS (DImode
, tmp
, add_op
);
2731 emit_insn (gen_rtx_SET (VOIDmode
, target
, tmp
));
2743 /* Look up the function X_floating library function name for the
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
;
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 }
2780 alpha_lookup_xfloating_lib_func (enum rtx_code code
)
2782 struct xfloating_op
*ops
= xfloating_ops
;
2783 long n
= ARRAY_SIZE (xfloating_ops
);
2786 /* How irritating. Nothing to key off for the main table. */
2787 if (TARGET_FLOAT_VAX
&& (code
== FLOAT_EXTEND
|| code
== FLOAT_TRUNCATE
))
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
;
2799 func
= init_one_libfunc (TARGET_ABI_OPEN_VMS
2800 ? ops
->vms_func
: ops
->osf_func
);
2801 ops
->libcall
= func
;
2809 /* Most X_floating operations take the rounding mode as an argument.
2810 Compute that here. */
2813 alpha_compute_xfloating_mode_arg (enum rtx_code code
,
2814 enum alpha_fp_rounding_mode round
)
2820 case ALPHA_FPRM_NORM
:
2823 case ALPHA_FPRM_MINF
:
2826 case ALPHA_FPRM_CHOP
:
2829 case ALPHA_FPRM_DYN
:
2835 /* XXX For reference, round to +inf is mode = 3. */
2838 if (code
== FLOAT_TRUNCATE
&& alpha_fptm
== ALPHA_FPTM_N
)
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.
2858 alpha_emit_xfloating_libcall (rtx func
, rtx target
, rtx operands
[],
2859 int noperands
, rtx equiv
)
2861 rtx usage
= NULL_RTX
, tmp
, reg
;
2866 for (i
= 0; i
< noperands
; ++i
)
2868 switch (GET_MODE (operands
[i
]))
2871 reg
= gen_rtx_REG (TFmode
, regno
);
2876 reg
= gen_rtx_REG (DFmode
, regno
+ 32);
2881 if (GET_CODE (operands
[i
]) != CONST_INT
)
2885 reg
= gen_rtx_REG (DImode
, regno
);
2893 emit_move_insn (reg
, operands
[i
]);
2894 usage
= alloc_EXPR_LIST (0, gen_rtx_USE (VOIDmode
, reg
), usage
);
2897 switch (GET_MODE (target
))
2900 reg
= gen_rtx_REG (TFmode
, 16);
2903 reg
= gen_rtx_REG (DFmode
, 32);
2906 reg
= gen_rtx_REG (DImode
, 0);
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;
2921 emit_libcall_block (tmp
, target
, reg
, equiv
);
2924 /* Emit an X_floating library function call for arithmetic (+,-,*,/). */
2927 alpha_emit_xfloating_arith (enum rtx_code code
, rtx operands
[])
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],
2944 /* Emit an X_floating library function call for a comparison. */
2947 alpha_emit_xfloating_compare (enum rtx_code code
, rtx op0
, rtx op1
)
2950 rtx out
, operands
[2];
2952 func
= alpha_lookup_xfloating_lib_func (code
);
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
));
2966 /* Emit an X_floating library function call for a conversion. */
2969 alpha_emit_xfloating_cvt (enum rtx_code orig_code
, rtx operands
[])
2971 int noperands
= 1, mode
;
2972 rtx out_operands
[2];
2974 enum rtx_code code
= orig_code
;
2976 if (code
== UNSIGNED_FIX
)
2979 func
= alpha_lookup_xfloating_lib_func (code
);
2981 out_operands
[0] = operands
[1];
2986 mode
= alpha_compute_xfloating_mode_arg (code
, ALPHA_FPRM_CHOP
);
2987 out_operands
[1] = GEN_INT (mode
);
2990 case FLOAT_TRUNCATE
:
2991 mode
= alpha_compute_xfloating_mode_arg (code
, alpha_fprm
);
2992 out_operands
[1] = GEN_INT (mode
);
2999 alpha_emit_xfloating_libcall (func
, operands
[0], out_operands
, noperands
,
3000 gen_rtx_fmt_e (orig_code
,
3001 GET_MODE (operands
[0]),
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
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
;
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);
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. */
3046 alpha_split_tfmode_frobsign (rtx operands
[3], rtx (*operation
) (rtx
, rtx
, rtx
))
3048 rtx high_bit
= operands
[2];
3052 alpha_split_tfmode_pair (operands
);
3054 /* Detect three flavors of operand overlap. */
3056 if (rtx_equal_p (operands
[0], operands
[2]))
3058 else if (rtx_equal_p (operands
[1], operands
[2]))
3060 if (rtx_equal_p (operands
[0], high_bit
))
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]));
3079 emit_move_insn (operands
[0], operands
[2]);
3081 emit_move_insn (operands
[1], scratch
);
3085 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
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
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)
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
),
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),
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
);
3174 if (WORDS_BIG_ENDIAN
)
3176 emit_move_insn (addr
, plus_constant (mema
, ofs
+size
-1));
3180 emit_insn (gen_extwh_be (extl
, meml
, addr
));
3185 emit_insn (gen_extlh_be (extl
, meml
, addr
));
3190 emit_insn (gen_extqh_be (extl
, meml
, addr
));
3197 emit_insn (gen_extxl_be (exth
, memh
, GEN_INT (size
*8), addr
));
3201 emit_move_insn (addr
, plus_constant (mema
, ofs
));
3202 emit_insn (gen_extxl_le (extl
, meml
, GEN_INT (size
*8), addr
));
3206 emit_insn (gen_extwh_le (exth
, memh
, addr
));
3211 emit_insn (gen_extlh_le (exth
, memh
, addr
));
3216 emit_insn (gen_extqh_le (exth
, memh
, addr
));
3225 addr
= expand_binop (mode
, ior_optab
, gen_lowpart (mode
, extl
),
3226 gen_lowpart (mode
, exth
), gen_lowpart (mode
, tgt
),
3231 emit_move_insn (tgt
, gen_lowpart(GET_MODE (tgt
), addr
));
3234 /* Similarly, use ins and msk instructions to perform unaligned stores. */
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
),
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),
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
)
3278 emit_insn (gen_inswl_be (insh
, gen_lowpart (HImode
,src
), addr
));
3281 emit_insn (gen_insll_be (insh
, gen_lowpart (SImode
,src
), addr
));
3284 emit_insn (gen_insql_be (insh
, gen_lowpart (DImode
,src
), addr
));
3287 emit_insn (gen_insxh (insl
, gen_lowpart (DImode
, src
),
3288 GEN_INT (size
*8), addr
));
3294 emit_insn (gen_mskxl_be (dsth
, dsth
, GEN_INT (0xffff), addr
));
3298 rtx msk
= immed_double_const (0xffffffff, 0, DImode
);
3299 emit_insn (gen_mskxl_be (dsth
, dsth
, msk
, addr
));
3303 emit_insn (gen_mskxl_be (dsth
, dsth
, constm1_rtx
, addr
));
3307 emit_insn (gen_mskxh (dstl
, dstl
, GEN_INT (size
*8), addr
));
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
));
3321 emit_insn (gen_inswl_le (insl
, gen_lowpart (HImode
, src
), addr
));
3324 emit_insn (gen_insll_le (insl
, gen_lowpart (SImode
, src
), addr
));
3327 emit_insn (gen_insql_le (insl
, src
, addr
));
3332 emit_insn (gen_mskxh (dsth
, dsth
, GEN_INT (size
*8), addr
));
3337 emit_insn (gen_mskxl_le (dstl
, dstl
, GEN_INT (0xffff), addr
));
3341 rtx msk
= immed_double_const (0xffffffff, 0, DImode
);
3342 emit_insn (gen_mskxl_le (dstl
, dstl
, msk
, addr
));
3346 emit_insn (gen_mskxl_le (dstl
, dstl
, constm1_rtx
, addr
));
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
);
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. */
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
;
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
);
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
),
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),
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
,
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
));
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
,
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. */
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
;
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
);
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),
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
));
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,
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
));
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
);
3549 if (WORDS_BIG_ENDIAN
)
3550 emit_move_insn (st_addr_1
, st_tmp_1
);
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),
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
);
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];
3590 unsigned int i
, words
, ofs
, nregs
= 0;
3592 if (orig_bytes
<= 0)
3594 else if (orig_bytes
> MAX_MOVE_WORDS
* UNITS_PER_WORD
)
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)));
3611 if (a
>= 64 && c
% 8 == 0)
3613 else if (a
>= 32 && c
% 4 == 0)
3615 else if (a
>= 16 && c
% 2 == 0)
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)));
3632 if (a
>= 64 && c
% 8 == 0)
3634 else if (a
>= 32 && c
% 4 == 0)
3636 else if (a
>= 16 && c
% 2 == 0)
3642 if (src_align
>= 64 && 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));
3658 if (src_align
>= 32 && 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));
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
,
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);
3699 if (src_align
>= 16)
3702 data_regs
[nregs
++] = tmp
= gen_reg_rtx (HImode
);
3703 emit_move_insn (tmp
, adjust_address (orig_src
, HImode
, ofs
));
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);
3719 data_regs
[nregs
++] = tmp
= gen_reg_rtx (QImode
);
3720 emit_move_insn (tmp
, adjust_address (orig_src
, QImode
, ofs
));
3725 if (nregs
> ARRAY_SIZE (data_regs
))
3728 /* Now save it back out again. */
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
),
3744 if (dst_align
>= 32)
3746 /* If the source has remaining DImode regs, write them out in
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
));
3761 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == SImode
)
3763 emit_move_insn (adjust_address (orig_dst
, SImode
, ofs
),
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
)
3779 alpha_expand_unaligned_store (orig_dst
, data_regs
[i
], 8, ofs
);
3781 alpha_expand_unaligned_store_words (data_regs
+ i
, orig_dst
,
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
);
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
]);
3806 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == HImode
)
3808 alpha_expand_unaligned_store (orig_dst
, data_regs
[i
], 2, ofs
);
3813 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == QImode
)
3815 emit_move_insn (adjust_address (orig_dst
, QImode
, ofs
), data_regs
[i
]);
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];
3837 int i
, words
, ofs
= 0;
3839 if (orig_bytes
<= 0)
3841 if (orig_bytes
> MAX_MOVE_WORDS
* UNITS_PER_WORD
)
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)));
3858 align
= a
, alignofs
= 8 - c
% 8;
3860 align
= a
, alignofs
= 4 - c
% 4;
3862 align
= a
, alignofs
= 2 - c
% 2;
3866 /* Handle an unaligned prefix first. */
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)
3876 && !(alignofs
== 4 && bytes
>= 4))
3878 enum machine_mode mode
= (align
>= 64 ? DImode
: SImode
);
3879 int inv_alignofs
= (align
>= 64 ? 8 : 4) - alignofs
;
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);
3900 tmp
= expand_binop (mode
, and_optab
, mem
, GEN_INT (mask
),
3901 NULL_RTX
, 1, OPTAB_WIDEN
);
3903 emit_move_insn (mem
, tmp
);
3907 if (TARGET_BWX
&& (alignofs
& 1) && bytes
>= 1)
3909 emit_move_insn (adjust_address (orig_dst
, QImode
, ofs
), const0_rtx
);
3914 if (TARGET_BWX
&& align
>= 16 && (alignofs
& 3) == 2 && bytes
>= 2)
3916 emit_move_insn (adjust_address (orig_dst
, HImode
, ofs
), const0_rtx
);
3921 if (alignofs
== 4 && bytes
>= 4)
3923 emit_move_insn (adjust_address (orig_dst
, SImode
, ofs
), const0_rtx
);
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. */
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)
3944 for (i
= 0; i
< words
; ++i
)
3945 emit_move_insn (adjust_address (orig_dst
, DImode
, ofs
+ i
* 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)
3959 emit_move_insn (adjust_address (orig_dst
, SImode
, ofs
), const0_rtx
);
3963 orig_dsta
= XEXP (orig_dst
, 0);
3964 if (GET_CODE (orig_dsta
) == LO_SUM
)
3965 orig_dsta
= force_reg (Pmode
, orig_dsta
);
3968 for (i
= 0; i
< words
; ++i
)
3971 = change_address (orig_dst
, DImode
,
3972 gen_rtx_AND (DImode
,
3973 plus_constant (orig_dsta
, ofs
+ i
*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
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))
3994 for (i
= 0; i
< words
; ++i
)
3995 emit_move_insn (adjust_address (orig_dst
, SImode
, ofs
+ i
* 4),
4002 /* An unaligned block uses stq_u stores for as many as possible. */
4008 alpha_expand_unaligned_store_words (NULL
, orig_dst
, words
, ofs
);
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
4020 for (i
= (TARGET_BWX
? 1 : 4); i
* BITS_PER_UNIT
<= align
; i
<<= 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)
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
);
4044 else if (align
>= 32 && bytes
< 4)
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
);
4063 if (!TARGET_BWX
&& bytes
>= 4)
4065 alpha_expand_unaligned_store (orig_dst
, const0_rtx
, 4, ofs
);
4075 emit_move_insn (adjust_address (orig_dst
, HImode
, ofs
),
4079 } while (bytes
>= 2);
4081 else if (! TARGET_BWX
)
4083 alpha_expand_unaligned_store (orig_dst
, const0_rtx
, 2, ofs
);
4091 emit_move_insn (adjust_address (orig_dst
, QImode
, ofs
), const0_rtx
);
4099 /* Returns a mask so that zap(x, value) == x & mask. */
4102 alpha_expand_zap_mask (HOST_WIDE_INT value
)
4107 if (HOST_BITS_PER_WIDE_INT
>= 64)
4109 HOST_WIDE_INT mask
= 0;
4111 for (i
= 7; i
>= 0; --i
)
4114 if (!((value
>> i
) & 1))
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
)
4127 if (!((value
>> i
) & 1))
4131 for (i
= 3; i
>= 0; --i
)
4134 if (!((value
>> i
) & 1))
4138 result
= immed_double_const (mask_lo
, mask_hi
, DImode
);
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
);
4156 op1
= gen_lowpart (mode
, op1
);
4158 if (op2
== const0_rtx
)
4159 op2
= CONST0_RTX (mode
);
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. */
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)
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)
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. */
4198 /* The number of instructions that can be issued per cycle. */
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. */
4215 alpha_multipass_dfa_lookahead (void)
4217 return (alpha_cpu
== PROCESSOR_EV6
? 4 : 2);
4220 /* Machine-specific function data. */
4222 struct machine_function
GTY(())
4225 /* List of call information words for calls from this function. */
4226 struct rtx_def
*first_ciw
;
4227 struct rtx_def
*last_ciw
;
4230 /* List of deferred case vectors. */
4231 struct rtx_def
*addr_list
;
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
)
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
;
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
);
4280 emit_insn_after (seq
, entry_of_function ());
4282 cfun
->machine
->gp_save_rtx
= m
;
4289 alpha_ra_ever_killed (void)
4293 if (!has_hard_reg_initial_val (Pmode
, REG_RA
))
4294 return regs_ever_live
[REG_RA
];
4296 push_topmost_sequence ();
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. */
4308 get_trap_mode_suffix (void)
4310 enum attr_trap_suffix s
= get_attr_trap_suffix (current_output_insn
);
4314 case TRAP_SUFFIX_NONE
:
4317 case TRAP_SUFFIX_SU
:
4318 if (alpha_fptm
>= ALPHA_FPTM_SU
)
4322 case TRAP_SUFFIX_SUI
:
4323 if (alpha_fptm
>= ALPHA_FPTM_SUI
)
4327 case TRAP_SUFFIX_V_SV
:
4335 case ALPHA_FPTM_SUI
:
4340 case TRAP_SUFFIX_V_SV_SVI
:
4349 case ALPHA_FPTM_SUI
:
4354 case TRAP_SUFFIX_U_SU_SUI
:
4363 case ALPHA_FPTM_SUI
:
4371 /* Return the rounding mode suffix applicable to the current
4372 instruction, or NULL. */
4375 get_round_mode_suffix (void)
4377 enum attr_round_suffix s
= get_attr_round_suffix (current_output_insn
);
4381 case ROUND_SUFFIX_NONE
:
4383 case ROUND_SUFFIX_NORMAL
:
4386 case ALPHA_FPRM_NORM
:
4388 case ALPHA_FPRM_MINF
:
4390 case ALPHA_FPRM_CHOP
:
4392 case ALPHA_FPRM_DYN
:
4397 case ROUND_SUFFIX_C
:
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. */
4407 get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
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);
4422 get_some_local_dynamic_name (void)
4426 if (cfun
->machine
->some_ld_name
)
4427 return cfun
->machine
->some_ld_name
;
4429 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
4431 && for_each_rtx (&PATTERN (insn
), get_some_local_dynamic_name_1
, 0))
4432 return cfun
->machine
->some_ld_name
;
4437 /* Print an operand. Recognize special options, documented below. */
4440 print_operand (FILE *file
, rtx x
, int code
)
4447 /* Print the assembler name of the current function. */
4448 assemble_name (file
, alpha_fnname
);
4452 assemble_name (file
, get_some_local_dynamic_name ());
4457 const char *trap
= get_trap_mode_suffix ();
4458 const char *round
= get_round_mode_suffix ();
4461 fprintf (file
, (TARGET_AS_SLASH_BEFORE_SUFFIX
? "/%s%s" : "%s%s"),
4462 (trap
? trap
: ""), (round
? round
: ""));
4467 /* Generates single precision instruction suffix. */
4468 fputc ((TARGET_FLOAT_VAX
? 'f' : 's'), file
);
4472 /* Generates double precision instruction suffix. */
4473 fputc ((TARGET_FLOAT_VAX
? 'g' : 't'), file
);
4477 /* Generates a nop after a noreturn call at the very end of the
4479 if (next_real_insn (current_output_insn
) == 0)
4480 fprintf (file
, "\n\tnop");
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
);
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
);
4496 if (GET_CODE (x
) == HIGH
)
4497 output_addr_const (file
, XEXP (x
, 0));
4499 output_operand_lossage ("invalid %%H value");
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";
4520 output_operand_lossage ("invalid %%J value");
4524 if (x
!= const0_rtx
)
4525 fprintf (file
, "\t\t!%s!%d", lituse
, (int) INTVAL (x
));
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");
4536 output_operand_lossage ("invalid %%r value");
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");
4546 output_operand_lossage ("invalid %%R value");
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
));
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
));
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);
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));
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
;
4595 value
= CONST_DOUBLE_HIGH (x
);
4596 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
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)
4612 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, mask
);
4615 output_operand_lossage ("invalid %%m value");
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"
4633 /* Similar, except do it from the mask. */
4634 if (GET_CODE (x
) == CONST_INT
)
4636 HOST_WIDE_INT value
= INTVAL (x
);
4643 if (value
== 0xffff)
4648 if (value
== 0xffffffff)
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)
4667 output_operand_lossage ("invalid %%U value");
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
4678 || (INTVAL (x
) & 7) != 0)
4679 output_operand_lossage ("invalid %%s value");
4681 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
4683 ? (56 - INTVAL (x
)) / 8
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);
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
);
4704 fprintf (file
, "DEX(%d)", dex
);
4706 output_addr_const (file
, x
);
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
));
4726 fprintf (file
, "ule");
4728 fprintf (file
, "ult");
4729 else if (c
== UNORDERED
)
4730 fprintf (file
, "un");
4732 fprintf (file
, "%s", GET_RTX_NAME (c
));
4737 /* Write the divide or modulus operator. */
4738 switch (GET_CODE (x
))
4741 fprintf (file
, "div%s", GET_MODE (x
) == SImode
? "l" : "q");
4744 fprintf (file
, "div%su", GET_MODE (x
) == SImode
? "l" : "q");
4747 fprintf (file
, "rem%s", GET_MODE (x
) == SImode
? "l" : "q");
4750 fprintf (file
, "rem%su", GET_MODE (x
) == SImode
? "l" : "q");
4753 output_operand_lossage ("invalid %%E value");
4759 /* Write "_u" for unaligned access. */
4760 if (GET_CODE (x
) == MEM
&& GET_CODE (XEXP (x
, 0)) == AND
)
4761 fprintf (file
, "_u");
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))
4775 output_addr_const (file
, XVECEXP (XEXP (x
, 0), 0, 0));
4778 output_operand_lossage ("unknown relocation unspec");
4783 output_addr_const (file
, x
);
4787 output_operand_lossage ("invalid %%xn code");
4792 print_operand_address (FILE *file
, rtx addr
)
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))
4819 reloclo
= (alpha_tls_size
== 16 ? "dtprel" : "dtprello");
4823 reloclo
= (alpha_tls_size
== 16 ? "tprel" : "tprello");
4826 output_operand_lossage ("unknown relocation unspec");
4830 output_addr_const (file
, XVECEXP (op1
, 0, 0));
4835 reloclo
= "gprellow";
4836 output_addr_const (file
, op1
);
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
);
4851 fprintf (file
, "($%d)\t\t!%s", basereg
,
4852 (basereg
== 29 ? reloc16
: reloclo
));
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));
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)));
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. */
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
);
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,
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,
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
);
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
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
)
4973 /* Don't get confused and pass small structures in FP registers. */
4974 if (type
&& AGGREGATE_TYPE_P (type
))
4978 #ifdef ENABLE_CHECKING
4979 /* With alpha_split_complex_arg, we shouldn't see any raw complex
4981 if (COMPLEX_MODE_P (mode
))
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
)
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
;
5002 || targetm
.calls
.must_pass_in_stack (mode
, type
))
5005 #elif TARGET_ABI_UNICOSMK
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
)
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])
5028 lo
|= cum
.num_reg_words
;
5030 #if HOST_BITS_PER_WIDE_INT == 32
5031 hi
= (cum
.num_args
<< 20) | cum
.num_arg_words
;
5033 lo
= lo
| ((HOST_WIDE_INT
) cum
.num_args
<< 52)
5034 | ((HOST_WIDE_INT
) cum
.num_arg_words
<< 32);
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
;
5046 || cum
.num_reg_words
+ size
> 6
5047 || targetm
.calls
.must_pass_in_stack (mode
, type
))
5049 else if (type
&& TYPE_MODE (type
) == BLKmode
)
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. */
5061 return gen_rtx_PARALLEL (mode
, gen_rtvec (1, reg1
));
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
5076 /* VOID is passed as a special flag for "last argument". */
5077 if (type
== void_type_node
)
5079 else if (targetm
.calls
.must_pass_in_stack (mode
, type
))
5083 #error Unhandled ABI
5086 return gen_rtx_REG (mode
, num_args
+ basereg
);
5089 /* Return true if TYPE must be returned in memory, instead of in registers. */
5092 alpha_return_in_memory (tree type
, tree fndecl ATTRIBUTE_UNUSED
)
5094 enum machine_mode mode
= VOIDmode
;
5099 mode
= TYPE_MODE (type
);
5101 /* All aggregates are returned in memory. */
5102 if (AGGREGATE_TYPE_P (type
))
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. */
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
);
5121 case MODE_COMPLEX_INT
:
5122 case MODE_VECTOR_INT
:
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. */
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. */
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
))
5168 mode
= TYPE_MODE (valtype
);
5170 class = GET_MODE_CLASS (mode
);
5174 PROMOTE_MODE (mode
, dummy
, valtype
);
5177 case MODE_COMPLEX_INT
:
5178 case MODE_VECTOR_INT
:
5186 case MODE_COMPLEX_FLOAT
:
5188 enum machine_mode cmode
= GET_MODE_INNER (mode
);
5190 return gen_rtx_PARALLEL
5193 gen_rtx_EXPR_LIST (VOIDmode
, gen_rtx_REG (cmode
, 32),
5195 gen_rtx_EXPR_LIST (VOIDmode
, gen_rtx_REG (cmode
, 33),
5196 GEN_INT (GET_MODE_SIZE (cmode
)))));
5203 return gen_rtx_REG (mode
, regnum
);
5206 /* TCmode complex values are passed by invisible reference. We
5207 should not split these values. */
5210 alpha_split_complex_arg (tree type
)
5212 return TYPE_MODE (type
) != TCmode
;
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"),
5238 DECL_FIELD_CONTEXT (ofs
) = record
;
5239 TREE_CHAIN (ofs
) = space
;
5241 base
= build_decl (FIELD_DECL
, get_identifier ("__base"),
5243 DECL_FIELD_CONTEXT (base
) = record
;
5244 TREE_CHAIN (base
) = ofs
;
5246 TYPE_FIELDS (record
) = base
;
5247 layout_type (record
);
5252 /* Perform any needed actions needed for a function that is receiving a
5253 variable number of arguments. */
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)
5271 emit_insn (gen_umk_mismatch_args (GEN_INT (num_reg_words
+ 1)));
5272 emit_insn (gen_arg_home_umk ());
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)
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
;
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
5304 CUMULATIVE_ARGS cum
= *pcum
;
5311 int set
= get_varargs_alias_set ();
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
,
5327 *pretend_size
= 12 * UNITS_PER_WORD
;
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
)
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. */
5356 offset
= TARGET_ABI_OPEN_VMS
? UNITS_PER_WORD
: 6 * UNITS_PER_WORD
;
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
);
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
);
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
);
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
,
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
,
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
,
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
))
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
);
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
;
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);
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
);
5503 r
= build_fold_indirect_ref (r
);
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
,
5536 ALPHA_BUILTIN_ZAPNOT
,
5537 ALPHA_BUILTIN_AMASK
,
5538 ALPHA_BUILTIN_IMPLVER
,
5540 ALPHA_BUILTIN_THREAD_POINTER
,
5541 ALPHA_BUILTIN_SET_THREAD_POINTER
,
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
,
5555 ALPHA_BUILTIN_UNPKBL
,
5556 ALPHA_BUILTIN_UNPKBW
,
5561 ALPHA_BUILTIN_CTPOP
,
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
,
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
,
5614 CODE_FOR_builtin_cttz
,
5615 CODE_FOR_builtin_ctlz
,
5616 CODE_FOR_builtin_ctpop
5619 struct alpha_builtin_def
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
}
5680 alpha_init_builtins (void)
5682 const struct alpha_builtin_def
*p
;
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
,
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
,
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
,
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
,
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
,
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. */
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
)
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
;
5746 if (fcode
>= ALPHA_BUILTIN_max
)
5747 internal_error ("bad builtin fcode");
5748 icode
= code_for_builtin
[fcode
];
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;
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
)
5763 if (arity
> MAX_ARGS
)
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
]);
5776 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
5778 || GET_MODE (target
) != tmode
5779 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
5780 target
= gen_reg_rtx (tmode
);
5786 pat
= GEN_FCN (icode
) (target
);
5790 pat
= GEN_FCN (icode
) (target
, op
[0]);
5792 pat
= GEN_FCN (icode
) (op
[0]);
5795 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
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. */
5838 alpha_sa_mask (unsigned long *imaskP
, unsigned long *fmaskP
)
5840 unsigned long imask
= 0;
5841 unsigned long fmask
= 0;
5844 /* When outputting a thunk, we don't have valid register life info,
5845 but assemble_start_function wants to output .frame and .mask
5847 if (current_function_is_thunk
)
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
))
5864 imask
|= (1UL << i
);
5866 fmask
|= (1UL << (i
- 32));
5869 /* We need to restore these for the handler. */
5870 if (current_function_calls_eh_return
)
5874 unsigned regno
= EH_RETURN_DATA_REGNO (i
);
5875 if (regno
== INVALID_REGNUM
)
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. */
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
);
5897 alpha_sa_size (void)
5899 unsigned long mask
[2];
5903 alpha_sa_mask (&mask
[0], &mask
[1]);
5905 if (TARGET_ABI_UNICOSMK
)
5907 if (mask
[0] || mask
[1])
5912 for (j
= 0; j
< 2; ++j
)
5913 for (i
= 0; i
< 32; ++i
)
5914 if ((mask
[j
] >> i
) & 1)
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
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
)
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
;
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
)
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. */
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
)
5991 /* Our size must be even (multiple of 16 bytes). */
5999 /* Define the offset between two registers, one to be eliminated,
6000 and the other its replacement, at the start of a routine. */
6003 alpha_initial_elimination_offset (unsigned int from
,
6004 unsigned int to ATTRIBUTE_UNUSED
)
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
);
6024 alpha_pv_save_size (void)
6027 return alpha_procedure_type
== PT_STACK
? 8 : 0;
6031 alpha_using_fp (void)
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
}
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;
6063 alpha_does_function_need_gp (void)
6067 /* The GP being variable is an OSF abi thing. */
6068 if (! TARGET_ABI_OSF
)
6071 /* We need the gp to load the address of __mcount. */
6072 if (TARGET_PROFILING_NEEDS_GP
&& current_function_profile
)
6075 /* The code emitted by alpha_output_mi_thunk_osf uses the gp. */
6076 if (current_function_is_thunk
)
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
)
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
))
6096 && GET_CODE (PATTERN (insn
)) != USE
6097 && GET_CODE (PATTERN (insn
)) != CLOBBER
6098 && get_attr_usegp (insn
))
6105 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
6109 set_frame_related_p (void)
6111 rtx seq
= get_insns ();
6122 while (insn
!= NULL_RTX
)
6124 RTX_FRAME_RELATED_P (insn
) = 1;
6125 insn
= NEXT_INSN (insn
);
6127 seq
= emit_insn (seq
);
6131 seq
= emit_insn (seq
);
6132 RTX_FRAME_RELATED_P (seq
) = 1;
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. */
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
;
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)
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
);
6186 frame_size
= (ALPHA_ROUND (current_function_outgoing_args_size
)
6188 + ALPHA_ROUND (frame_size
6189 + current_function_pretend_args_size
));
6191 if (TARGET_ABI_OPEN_VMS
)
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. */
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
6223 Note that we are only allowed to adjust sp once in the prologue. */
6225 if (frame_size
<= 32768)
6227 if (frame_size
> 4096)
6232 emit_insn (gen_probe_stack (GEN_INT (TARGET_ABI_UNICOSMK
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
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);
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
,
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;
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
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;
6325 if (low
+ sa_size
<= 0x8000)
6326 bias
= reg_offset
- low
, reg_offset
= low
;
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
,
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
);
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
)));
6363 /* Store a zero if requested for unwinding. */
6364 if (imask
& (1UL << 31))
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
;
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)));
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. */
6397 for (i
= 9; i
< 15; i
++)
6398 if (imask
& (1UL << i
))
6400 mem
= gen_rtx_MEM (DImode
, plus_constant(hard_frame_pointer_rtx
,
6402 set_mem_alias_set (mem
, alpha_sr_alias_set
);
6403 FRP (emit_move_insn (mem
, gen_rtx_REG (DImode
, i
)));
6406 for (i
= 2; i
< 10; i
++)
6407 if (fmask
& (1UL << i
))
6409 mem
= gen_rtx_MEM (DFmode
, plus_constant (hard_frame_pointer_rtx
,
6411 set_mem_alias_set (mem
, alpha_sr_alias_set
);
6412 FRP (emit_move_insn (mem
, gen_rtx_REG (DFmode
, i
+32)));
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)
6437 = emit_move_insn (stack_pointer_rtx
,
6439 (hard_frame_pointer_rtx
,
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
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
));
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. */
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);
6507 /* Don't emit an extern directive for functions defined in the same file. */
6508 if (TARGET_ABI_UNICOSMK
)
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)
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
);
6530 frame_size
= (ALPHA_ROUND (current_function_outgoing_args_size
)
6532 + ALPHA_ROUND (frame_size
6533 + current_function_pretend_args_size
));
6535 if (TARGET_ABI_OPEN_VMS
)
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
));
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);
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
);
6571 /* If the function needs GP, we'll write the "..ng" label there.
6572 Otherwise, do it here. */
6574 && ! alpha_function_needs_gp
6575 && ! current_function_is_thunk
)
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",
6620 frame_size
>= (1UL << 31) ? 0 : frame_size
,
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
)
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
));
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
)
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
))
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);
6673 /* Emit the .prologue note at the scheduled end of the prologue. */
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
6695 #define FRP(exp) exp
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
;
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)
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
);
6729 frame_size
= (ALPHA_ROUND (current_function_outgoing_args_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
)
6742 reg_offset
= ALPHA_ROUND (current_function_outgoing_args_size
);
6744 alpha_sa_mask (&imask
, &fmask
);
6747 = ((TARGET_ABI_OPEN_VMS
&& alpha_procedure_type
== PT_STACK
)
6748 || (!TARGET_ABI_OPEN_VMS
&& frame_pointer_needed
));
6750 sa_reg
= stack_pointer_rtx
;
6752 if (current_function_calls_eh_return
)
6753 eh_ofs
= EH_RETURN_STACKADJ_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;
6771 if (low
+ sa_size
<= 0x8000)
6772 bias
= reg_offset
- low
, reg_offset
= low
;
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
));
6786 set_mem_alias_set (mem
, alpha_sr_alias_set
);
6787 FRP (emit_move_insn (gen_rtx_REG (DImode
, REG_RA
), mem
));
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
;
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
));
6806 if (imask
& (1UL << 31))
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
));
6818 else if (TARGET_ABI_UNICOSMK
&& alpha_procedure_type
== PT_STACK
)
6820 /* Restore callee-saved general-purpose registers. */
6824 for (i
= 9; i
< 15; i
++)
6825 if (imask
& (1UL << i
))
6827 mem
= gen_rtx_MEM (DImode
, plus_constant(hard_frame_pointer_rtx
,
6829 set_mem_alias_set (mem
, alpha_sr_alias_set
);
6830 FRP (emit_move_insn (gen_rtx_REG (DImode
, i
), mem
));
6834 for (i
= 2; i
< 10; i
++)
6835 if (fmask
& (1UL << i
))
6837 mem
= gen_rtx_MEM (DFmode
, plus_constant(hard_frame_pointer_rtx
,
6839 set_mem_alias_set (mem
, alpha_sr_alias_set
);
6840 FRP (emit_move_insn (gen_rtx_REG (DFmode
, i
+32), mem
));
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
;
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
))
6883 sp_adj1
= gen_rtx_REG (DImode
, 23);
6884 FRP (emit_move_insn (sp_adj1
, sp_adj2
));
6886 sp_adj2
= GEN_INT (low
);
6890 rtx tmp
= gen_rtx_REG (DImode
, 23);
6891 FRP (sp_adj2
= alpha_emit_set_const (tmp
, DImode
, frame_size
, 3));
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)));
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
));
6933 FRP (emit_move_insn (stack_pointer_rtx
,
6934 gen_rtx_PLUS (DImode
, sp_adj1
, sp_adj2
)));
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
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. */
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
);
6965 /* End the function. */
6966 if (!TARGET_ABI_UNICOSMK
&& !flag_inhibit_size_directive
)
6968 fputs ("\t.end ", file
);
6969 assemble_name (file
, fnname
);
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
);
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... */
6993 alpha_output_mi_thunk_osf (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
6994 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
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);
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
)
7020 emit_insn (gen_adddi3 (this, this, GEN_INT (hi
)));
7022 emit_insn (gen_adddi3 (this, this, GEN_INT (lo
)));
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. */
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
)
7044 emit_insn (gen_adddi3 (tmp
, tmp
, GEN_INT (hi
)));
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
));
7054 tmp2
= gen_rtx_PLUS (Pmode
, tmp
, GEN_INT (lo
));
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. */
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. */
7115 alpha_output_filename (FILE *stream
, const char *name
)
7117 static int first_time
= TRUE
;
7118 char ltext_label_name
[100];
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
, <ext_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
);
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. */
7160 alpha_output_lineno (FILE *stream
, int line
)
7162 if (write_symbols
== DBX_DEBUG
)
7164 /* mips-tfile doesn't understand .stabd directives. */
7166 fprintf (stream
, "$LM%d:\n%s%d,0,%d,$LM%d\n",
7167 sym_lineno
, ASM_STABN_OP
, N_SLINE
, line
, sym_lineno
);
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
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 */
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. */
7189 summarize_insn (rtx x
, struct shadow_summary
*sum
, int set
)
7191 const char *format_ptr
;
7197 switch (GET_CODE (x
))
7199 /* ??? Note that this case would be incorrect if the Alpha had a
7200 ZERO_EXTRACT in SET_DEST. */
7202 summarize_insn (SET_SRC (x
), sum
, 0);
7203 summarize_insn (SET_DEST (x
), sum
, 1);
7207 summarize_insn (XEXP (x
, 0), sum
, 1);
7211 summarize_insn (XEXP (x
, 0), sum
, 0);
7215 for (i
= ASM_OPERANDS_INPUT_LENGTH (x
) - 1; i
>= 0; i
--)
7216 summarize_insn (ASM_OPERANDS_INPUT (x
, i
), sum
, 0);
7220 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
7221 summarize_insn (XVECEXP (x
, 0, i
), sum
, 0);
7225 summarize_insn (SUBREG_REG (x
), sum
, 0);
7230 int regno
= REGNO (x
);
7231 unsigned long mask
= ((unsigned long) 1) << (regno
% 32);
7233 if (regno
== 31 || regno
== 63)
7239 sum
->defd
.i
|= mask
;
7241 sum
->defd
.fp
|= mask
;
7246 sum
->used
.i
|= mask
;
7248 sum
->used
.fp
|= mask
;
7259 /* Find the regs used in memory address computation: */
7260 summarize_insn (XEXP (x
, 0), sum
, 0);
7263 case CONST_INT
: case CONST_DOUBLE
:
7264 case SYMBOL_REF
: case LABEL_REF
: case CONST
:
7265 case SCRATCH
: case ASM_INPUT
:
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);
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);
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
])
7292 summarize_insn (XEXP (x
, i
), sum
, 0);
7296 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
7297 summarize_insn (XVECEXP (x
, i
, j
), sum
, 0);
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
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
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
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
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
7340 (d) The trap shadow may not include any branch instructions. */
7343 alpha_handle_trap_shadows (void)
7345 struct shadow_summary shadow
;
7346 int trap_pending
, exception_nesting
;
7350 exception_nesting
= 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
++;
7368 case NOTE_INSN_EH_REGION_END
:
7369 exception_nesting
--;
7374 case NOTE_INSN_EPILOGUE_BEG
:
7375 if (trap_pending
&& alpha_tp
>= ALPHA_TP_FUNC
)
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
)
7388 else if (alpha_tp
== ALPHA_TP_INSN
)
7392 struct shadow_summary sum
;
7397 sum
.defd
= sum
.used
;
7399 switch (GET_CODE (i
))
7402 /* Annoyingly, get_attr_trap will abort on these. */
7403 if (GET_CODE (PATTERN (i
)) == USE
7404 || GET_CODE (PATTERN (i
)) == CLOBBER
)
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 */
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
)))
7450 n
= emit_insn_before (gen_trapb (), i
);
7451 PUT_MODE (n
, TImode
);
7452 PUT_MODE (i
, TImode
);
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);
7475 /* Alpha can only issue instruction groups simultaneously if they are
7476 suitably aligned. This is very processor-specific. */
7478 enum alphaev4_pipe
{
7485 enum alphaev5_pipe
{
7496 static enum alphaev4_pipe
7497 alphaev4_insn_pipe (rtx insn
)
7499 if (recog_memoized (insn
) < 0)
7501 if (get_attr_length (insn
) != 4)
7504 switch (get_attr_type (insn
))
7538 static enum alphaev5_pipe
7539 alphaev5_insn_pipe (rtx insn
)
7541 if (recog_memoized (insn
) < 0)
7543 if (get_attr_length (insn
) != 4)
7546 switch (get_attr_type (insn
))
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. */
7594 alphaev4_next_group (rtx insn
, int *pin_use
, int *plen
)
7601 || GET_CODE (PATTERN (insn
)) == CLOBBER
7602 || GET_CODE (PATTERN (insn
)) == USE
)
7607 enum alphaev4_pipe pipe
;
7609 pipe
= alphaev4_insn_pipe (insn
);
7613 /* Force complex instructions to start new groups. */
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)
7623 len
= get_attr_length (insn
);
7627 if (in_use
& EV4_IB0
)
7629 if (in_use
& EV4_IB1
)
7634 in_use
|= EV4_IB0
| EV4_IBX
;
7638 if (in_use
& EV4_IB0
)
7640 if (!(in_use
& EV4_IBX
) || (in_use
& EV4_IB1
))
7648 if (in_use
& EV4_IB1
)
7658 /* Haifa doesn't do well scheduling branches. */
7659 if (GET_CODE (insn
) == JUMP_INSN
)
7663 insn
= next_nonnote_insn (insn
);
7665 if (!insn
|| ! INSN_P (insn
))
7668 /* Let Haifa tell us where it thinks insn group boundaries are. */
7669 if (GET_MODE (insn
) == TImode
)
7672 if (GET_CODE (insn
) == CLOBBER
|| GET_CODE (insn
) == USE
)
7677 insn
= next_nonnote_insn (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. */
7692 alphaev5_next_group (rtx insn
, int *pin_use
, int *plen
)
7699 || GET_CODE (PATTERN (insn
)) == CLOBBER
7700 || GET_CODE (PATTERN (insn
)) == USE
)
7705 enum alphaev5_pipe pipe
;
7707 pipe
= alphaev5_insn_pipe (insn
);
7711 /* Force complex instructions to start new groups. */
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)
7721 len
= get_attr_length (insn
);
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. */
7730 if (in_use
& EV5_E0
)
7732 if (in_use
& EV5_E1
)
7737 in_use
|= EV5_E0
| EV5_E01
;
7741 if (in_use
& EV5_E0
)
7743 if (!(in_use
& EV5_E01
) || (in_use
& EV5_E1
))
7751 if (in_use
& EV5_E1
)
7757 if (in_use
& EV5_FA
)
7759 if (in_use
& EV5_FM
)
7764 in_use
|= EV5_FA
| EV5_FAM
;
7768 if (in_use
& EV5_FA
)
7774 if (in_use
& EV5_FM
)
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
)
7794 insn
= next_nonnote_insn (insn
);
7796 if (!insn
|| ! INSN_P (insn
))
7799 /* Let Haifa tell us where it thinks insn group boundaries are. */
7800 if (GET_MODE (insn
) == TImode
)
7803 if (GET_CODE (insn
) == CLOBBER
|| GET_CODE (insn
) == USE
)
7808 insn
= next_nonnote_insn (insn
);
7817 alphaev4_next_nop (int *pin_use
)
7819 int in_use
= *pin_use
;
7822 if (!(in_use
& EV4_IB0
))
7827 else if ((in_use
& (EV4_IBX
|EV4_IB1
)) == EV4_IBX
)
7832 else if (TARGET_FP
&& !(in_use
& EV4_IB1
))
7845 alphaev5_next_nop (int *pin_use
)
7847 int in_use
= *pin_use
;
7850 if (!(in_use
& EV5_E1
))
7855 else if (TARGET_FP
&& !(in_use
& EV5_FA
))
7860 else if (TARGET_FP
&& !(in_use
& EV5_FM
))
7872 /* The instruction group alignment main loop. */
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. */
7881 /* OFS is the offset of the current insn in the insn group. */
7883 int prev_in_use
, in_use
, len
;
7886 /* Let shorten branches care for assigning alignments to code labels. */
7887 shorten_branches (get_insns ());
7889 if (align_functions
< 4)
7891 else if ((unsigned int) align_functions
< max_align
)
7892 align
= align_functions
;
7896 ofs
= prev_in_use
= 0;
7898 if (GET_CODE (i
) == NOTE
)
7899 i
= next_nonnote_insn (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
;
7916 else if (ofs
& (new_align
-1))
7917 ofs
= (ofs
| (new_align
-1)) + 1;
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. */
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;
7943 where
= prev
= prev_nonnote_insn (i
);
7944 if (!where
|| GET_CODE (where
) != CODE_LABEL
)
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
;
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;
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
);
7973 if (GET_CODE (where
) == CODE_LABEL
)
7975 rtx where2
= prev_nonnote_insn (where
);
7976 if (where2
&& GET_CODE (where2
) == JUMP_INSN
)
7979 else if (GET_CODE (where
) == INSN
)
7986 emit_insn_before ((*next_nop
)(&prev_in_use
), where
);
7987 while (--nop_count
);
7991 ofs
= (ofs
+ len
) & (align
- 1);
7992 prev_in_use
= in_use
;
7997 /* Machine dependent reorg pass. */
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
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
);
8035 default_file_start ();
8037 fprintf (asm_out_file
, "\t.verstamp %d %d\n", MS_STAMP
, LS_STAMP
);
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
,
8049 TARGET_CPU_EV6
? "ev6"
8051 ? (TARGET_MAX
? "pca56" : TARGET_BWX
? "ev56" : "ev5")
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. */
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. */
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(())
8084 enum links_kind lkind
;
8085 enum reloc_kind rkind
;
8088 struct alpha_funcs
GTY(())
8091 splay_tree
GTY ((param1_is (char *), param2_is (struct alpha_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. */
8107 alpha_arg_type (enum machine_mode mode
)
8112 return TARGET_FLOAT_VAX
? FF
: FS
;
8114 return TARGET_FLOAT_VAX
? FD
: FT
;
8120 /* Return an rtx for an integer representing the VMS Argument Information
8124 alpha_arg_info_reg_val (CUMULATIVE_ARGS cum
)
8126 unsigned HOST_WIDE_INT regval
= cum
.num_args
;
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
;
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
));
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
);
8175 al
= (struct alpha_links
*) node
->value
;
8178 /* Defined here but external assumed. */
8179 if (al
->lkind
== KIND_EXTERN
)
8180 al
->lkind
= KIND_LOCAL
;
8184 /* Used here but unused assumed. */
8185 if (al
->lkind
== KIND_UNUSED
)
8186 al
->lkind
= KIND_LOCAL
;
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);
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
);
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
;
8236 splay_tree_node lnode
;
8238 /* Is this name already defined? */
8240 lnode
= splay_tree_lookup (cfaf
->links
, (splay_tree_key
) name
);
8242 al
= (struct alpha_links
*) lnode
->value
;
8245 cfaf
->links
= splay_tree_new_ggc ((splay_tree_compare_fn
) strcmp
);
8253 splay_tree_node node
= 0;
8254 struct alpha_links
*anl
;
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
);
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
);
8284 al
->rkind
= KIND_CODEADDR
;
8286 al
->rkind
= KIND_LINKAGE
;
8289 return gen_rtx_MEM (Pmode
, plus_constant (al
->linkage
, 8));
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
);
8311 /* External and used, request code address. */
8312 fprintf (stream
, "\t.code_address %s\n", name
);
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
);
8325 /* External and used, request linkage pair. */
8326 fprintf (stream
, "\t.linkage %s\n", name
);
8334 alpha_write_linkage (FILE *stream
, const char *funname
, tree fundecl
)
8336 splay_tree_node node
;
8337 struct alpha_funcs
*func
;
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");
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)
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
;
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. */
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. */
8417 vms_asm_out_constructor (rtx symbol
, int priority ATTRIBUTE_UNUSED
)
8420 assemble_align (BITS_PER_WORD
);
8421 assemble_integer (symbol
, UNITS_PER_WORD
, BITS_PER_WORD
, 1);
8425 vms_asm_out_destructor (rtx symbol
, int priority ATTRIBUTE_UNUSED
)
8428 assemble_align (BITS_PER_WORD
);
8429 assemble_integer (symbol
, UNITS_PER_WORD
, BITS_PER_WORD
, 1);
8434 alpha_need_linkage (const char *name ATTRIBUTE_UNUSED
,
8435 int is_local ATTRIBUTE_UNUSED
)
8441 alpha_use_linkage (rtx linkage ATTRIBUTE_UNUSED
,
8442 tree cfundecl ATTRIBUTE_UNUSED
,
8443 int lflag ATTRIBUTE_UNUSED
,
8444 int rflag ATTRIBUTE_UNUSED
)
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
8458 unicosmk_must_pass_in_stack (enum machine_mode mode
, tree type
)
8463 if (TREE_CODE (TYPE_SIZE (type
)) != INTEGER_CST
)
8465 if (TREE_ADDRESSABLE (type
))
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
)
8479 fixed_size
= alpha_sa_size();
8480 if (fixed_size
!= 0)
8483 if (from
== FRAME_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
8485 else if (from
== ARG_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
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
));
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
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
))
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. */
8523 unicosmk_output_common (FILE *file
, const char *name
, int size
, int align
)
8526 printf ("T3E__: common %s\n", name
);
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
;
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
);
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
;
8562 current_section_align
= floor_log2 (DECL_ALIGN (decl
) / BITS_PER_UNIT
);
8564 if (TREE_PUBLIC (decl
))
8565 flags
|= SECTION_PUBLIC
;
8570 /* Generate a section name for decl and associate it with the
8574 unicosmk_unique_section (tree decl
, int reloc ATTRIBUTE_UNUSED
)
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
)
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
);
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. */
8615 unicosmk_asm_named_section (const char *name
, unsigned int flags
)
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
)
8630 else if (flags
& SECTION_PUBLIC
)
8635 if (current_section_align
!= 0)
8636 fprintf (asm_out_file
, "\t.psect\t%s,%d,%s\n", name
,
8637 current_section_align
, kind
);
8639 fprintf (asm_out_file
, "\t.psect\t%s,%s\n", name
, kind
);
8643 unicosmk_insert_attributes (tree decl
, tree
*attr_ptr ATTRIBUTE_UNUSED
)
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. */
8654 unicosmk_output_align (FILE *file
, int align
)
8656 if (inside_function
)
8657 fprintf (file
, "\tgcc@code@align\t%d\n", align
);
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. */
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. */
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);
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. */
8698 unicosmk_output_deferred_case_vectors (FILE *file
)
8700 struct machine_function
*machine
= cfun
->machine
;
8703 if (machine
->addr_list
== NULL_RTX
)
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
8717 unicosmk_ssib_name (void)
8719 /* This is ok since CAM won't be able to deal with names longer than that
8722 static char name
[256];
8728 x
= DECL_RTL (cfun
->decl
);
8729 if (GET_CODE (x
) != MEM
)
8732 if (GET_CODE (x
) != SYMBOL_REF
)
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;
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. */
8752 unicosmk_gen_dsib (unsigned long *imaskP
)
8754 if (alpha_procedure_type
== PT_STACK
)
8756 const char *ssib_name
;
8759 /* Allocate 64 bytes for the DSIB. */
8761 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx
, stack_pointer_rtx
,
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))));
8807 /* Increment the frame pointer register to indicate that we do not
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
8819 unicosmk_output_ssib (FILE *file
, const char *fnname
)
8825 struct machine_function
*machine
= cfun
->machine
;
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
);
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
);
8847 fputs ("\t.quad\t0\n", file
);
8848 fputs ("\t.quad\t0\n", file
);
8851 ??? We do it the same way Cray CC does it but this could be
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
);
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))
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
));
8870 fprintf (file
, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX
"\n", INTVAL (ciw
));
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
)
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
;
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];
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",
8907 return unicosmk_section_buf
;
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",
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
8925 /* List of identifiers for which an extern declaration might have to be
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
;
8935 static struct unicosmk_extern_list
*unicosmk_extern_head
= 0;
8937 /* Output extern declarations which are required for every asm file. */
8940 unicosmk_output_default_externs (FILE *file
)
8942 static const char *const externs
[] =
8943 { "__T3E_MISMATCH" };
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. */
8958 unicosmk_output_externs (FILE *file
)
8960 struct unicosmk_extern_list
*p
;
8961 const char *real_name
;
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
))
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
);
8987 /* Record an extern. */
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
;
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
9007 /* FIXME: needs to use GC, so it can be saved and restored for PCH. */
9009 struct unicosmk_dex
{
9010 struct unicosmk_dex
*next
;
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. */
9026 unicosmk_special_name (const char *name
)
9034 if (name
[0] != 'r' && name
[0] != 'f' && name
[0] != 'R' && name
[0] != 'F')
9040 return (name
[2] == '\0' || (ISDIGIT (name
[2]) && name
[3] == '\0'));
9043 return (name
[2] == '\0'
9044 || ((name
[2] == '0' || name
[2] == '1') && name
[3] == '\0'));
9047 return (ISDIGIT (name
[1]) && name
[2] == '\0');
9051 /* Return the DEX number if X must be replaced by a DEX expression and 0
9055 unicosmk_need_dex (rtx x
)
9057 struct unicosmk_dex
*dex
;
9061 if (GET_CODE (x
) != SYMBOL_REF
)
9065 if (! unicosmk_special_name (name
))
9068 i
= unicosmk_dex_count
;
9069 for (dex
= unicosmk_dex_list
; dex
; dex
= dex
->next
)
9071 if (! strcmp (name
, dex
->name
))
9076 dex
= (struct unicosmk_dex
*) xmalloc (sizeof (struct unicosmk_dex
));
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. */
9088 unicosmk_output_dex (FILE *file
)
9090 struct unicosmk_dex
*dex
;
9093 if (unicosmk_dex_list
== NULL
)
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
);
9107 fprintf (file
, "\t.dexend\n");
9110 /* Output text that to appear at the beginning of an assembler file. */
9113 unicosmk_file_start (void)
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
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. */
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
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
);
9188 unicosmk_output_deferred_case_vectors (FILE *file ATTRIBUTE_UNUSED
)
9192 unicosmk_gen_dsib (unsigned long *imaskP ATTRIBUTE_UNUSED
)
9196 unicosmk_output_ssib (FILE * file ATTRIBUTE_UNUSED
,
9197 const char * fnname ATTRIBUTE_UNUSED
)
9201 unicosmk_add_call_info_word (rtx x ATTRIBUTE_UNUSED
)
9207 unicosmk_need_dex (rtx x ATTRIBUTE_UNUSED
)
9212 #endif /* TARGET_ABI_UNICOSMK */
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
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
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
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"
9286 #ifdef OBJECT_FORMAT_ELF
9287 #undef TARGET_ASM_SELECT_RTX_SECTION
9288 #define TARGET_ASM_SELECT_RTX_SECTION alpha_elf_select_rtx_section
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
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
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
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
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"