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 (70), /* 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 (45), /* 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 (25), /* 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 /* Returns 1 if OP is either the constant zero or a register. If a
523 register, it must be in the proper mode unless MODE is VOIDmode. */
526 reg_or_0_operand (rtx op
, enum machine_mode mode
)
528 return op
== CONST0_RTX (mode
) || register_operand (op
, mode
);
531 /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
535 reg_or_6bit_operand (rtx op
, enum machine_mode mode
)
537 return ((GET_CODE (op
) == CONST_INT
538 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 64)
539 || register_operand (op
, mode
));
543 /* Return 1 if OP is an 8-bit constant or any register. */
546 reg_or_8bit_operand (rtx op
, enum machine_mode mode
)
548 return ((GET_CODE (op
) == CONST_INT
549 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100)
550 || register_operand (op
, mode
));
553 /* Return 1 if OP is a constant or any register. */
556 reg_or_const_int_operand (rtx op
, enum machine_mode mode
)
558 return GET_CODE (op
) == CONST_INT
|| register_operand (op
, mode
);
561 /* Return 1 if OP is an 8-bit constant. */
564 cint8_operand (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
566 return ((GET_CODE (op
) == CONST_INT
567 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100));
570 /* Return 1 if the operand is a valid second operand to an add insn. */
573 add_operand (rtx op
, enum machine_mode mode
)
575 if (GET_CODE (op
) == CONST_INT
)
576 /* Constraints I, J, O and P are covered by K. */
577 return (CONST_OK_FOR_LETTER_P (INTVAL (op
), 'K')
578 || CONST_OK_FOR_LETTER_P (INTVAL (op
), 'L'));
580 return register_operand (op
, mode
);
583 /* Return 1 if the operand is a valid second operand to a sign-extending
587 sext_add_operand (rtx op
, enum machine_mode mode
)
589 if (GET_CODE (op
) == CONST_INT
)
590 return (CONST_OK_FOR_LETTER_P (INTVAL (op
), 'I')
591 || CONST_OK_FOR_LETTER_P (INTVAL (op
), 'O'));
593 return reg_not_elim_operand (op
, mode
);
596 /* Return 1 if OP is the constant 4 or 8. */
599 const48_operand (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
601 return (GET_CODE (op
) == CONST_INT
602 && (INTVAL (op
) == 4 || INTVAL (op
) == 8));
605 /* Return 1 if OP is a valid first operand to an AND insn. */
608 and_operand (rtx op
, enum machine_mode mode
)
610 if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == VOIDmode
)
611 return (zap_mask (CONST_DOUBLE_LOW (op
))
612 && zap_mask (CONST_DOUBLE_HIGH (op
)));
614 if (GET_CODE (op
) == CONST_INT
)
615 return ((unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100
616 || (unsigned HOST_WIDE_INT
) ~ INTVAL (op
) < 0x100
617 || zap_mask (INTVAL (op
)));
619 return register_operand (op
, mode
);
622 /* Return 1 if OP is a valid first operand to an IOR or XOR insn. */
625 or_operand (rtx op
, enum machine_mode mode
)
627 if (GET_CODE (op
) == CONST_INT
)
628 return ((unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100
629 || (unsigned HOST_WIDE_INT
) ~ INTVAL (op
) < 0x100);
631 return register_operand (op
, mode
);
634 /* Return 1 if OP is a constant that is the width, in bits, of an integral
635 mode smaller than DImode. */
638 mode_width_operand (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
640 return (GET_CODE (op
) == CONST_INT
641 && (INTVAL (op
) == 8 || INTVAL (op
) == 16
642 || INTVAL (op
) == 32 || INTVAL (op
) == 64));
645 /* Return 1 if OP is a constant that is the width of an integral machine mode
646 smaller than an integer. */
649 mode_mask_operand (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
651 if (GET_CODE (op
) == CONST_INT
)
653 HOST_WIDE_INT value
= INTVAL (op
);
659 if (value
== 0xffffffff)
664 else if (HOST_BITS_PER_WIDE_INT
== 32 && GET_CODE (op
) == CONST_DOUBLE
)
666 if (CONST_DOUBLE_LOW (op
) == 0xffffffff && CONST_DOUBLE_HIGH (op
) == 0)
673 /* Return 1 if OP is a multiple of 8 less than 64. */
676 mul8_operand (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
678 return (GET_CODE (op
) == CONST_INT
679 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 64
680 && (INTVAL (op
) & 7) == 0);
683 /* Return 1 if OP is the zero constant for MODE. */
686 const0_operand (rtx op
, enum machine_mode mode
)
688 return op
== CONST0_RTX (mode
);
691 /* Return 1 if OP is a hard floating-point register. */
694 hard_fp_register_operand (rtx op
, enum machine_mode mode
)
696 if (mode
!= VOIDmode
&& GET_MODE (op
) != VOIDmode
&& mode
!= GET_MODE (op
))
699 if (GET_CODE (op
) == SUBREG
)
700 op
= SUBREG_REG (op
);
701 return GET_CODE (op
) == REG
&& REGNO_REG_CLASS (REGNO (op
)) == FLOAT_REGS
;
704 /* Return 1 if OP is a hard general register. */
707 hard_int_register_operand (rtx op
, enum machine_mode mode
)
709 if (mode
!= VOIDmode
&& GET_MODE (op
) != VOIDmode
&& mode
!= GET_MODE (op
))
712 if (GET_CODE (op
) == SUBREG
)
713 op
= SUBREG_REG (op
);
714 return GET_CODE (op
) == REG
&& REGNO_REG_CLASS (REGNO (op
)) == GENERAL_REGS
;
717 /* Return 1 if OP is a register or a constant integer. */
721 reg_or_cint_operand (rtx op
, enum machine_mode mode
)
723 return (GET_CODE (op
) == CONST_INT
724 || register_operand (op
, mode
));
727 /* Return 1 if OP is something that can be reloaded into a register;
728 if it is a MEM, it need not be valid. */
731 some_operand (rtx op
, enum machine_mode mode
)
733 if (mode
!= VOIDmode
&& GET_MODE (op
) != VOIDmode
&& mode
!= GET_MODE (op
))
736 switch (GET_CODE (op
))
750 return some_operand (SUBREG_REG (op
), VOIDmode
);
759 /* Likewise, but don't accept constants. */
762 some_ni_operand (rtx op
, enum machine_mode mode
)
764 if (GET_MODE (op
) != mode
&& mode
!= VOIDmode
)
767 if (GET_CODE (op
) == SUBREG
)
768 op
= SUBREG_REG (op
);
770 return (GET_CODE (op
) == REG
|| GET_CODE (op
) == MEM
);
773 /* Return 1 if OP is a valid operand for the source of a move insn. */
776 input_operand (rtx op
, enum machine_mode mode
)
778 if (mode
!= VOIDmode
&& GET_MODE (op
) != VOIDmode
&& mode
!= GET_MODE (op
))
781 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
&& GET_MODE (op
) != mode
)
784 switch (GET_CODE (op
))
789 if (TARGET_EXPLICIT_RELOCS
)
791 /* We don't split symbolic operands into something unintelligable
792 until after reload, but we do not wish non-small, non-global
793 symbolic operands to be reconstructed from their high/lo_sum
795 return (small_symbolic_operand (op
, mode
)
796 || global_symbolic_operand (op
, mode
)
797 || gotdtp_symbolic_operand (op
, mode
)
798 || gottp_symbolic_operand (op
, mode
));
801 /* This handles both the Windows/NT and OSF cases. */
802 return mode
== ptr_mode
|| mode
== DImode
;
805 return (TARGET_EXPLICIT_RELOCS
806 && local_symbolic_operand (XEXP (op
, 0), mode
));
813 if (register_operand (op
, mode
))
815 /* ... fall through ... */
817 return ((TARGET_BWX
|| (mode
!= HImode
&& mode
!= QImode
))
818 && general_operand (op
, mode
));
822 return op
== CONST0_RTX (mode
);
825 return mode
== QImode
|| mode
== HImode
|| add_operand (op
, mode
);
834 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
835 file, and in the same section as the current function. */
838 samegp_function_operand (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
840 if (GET_CODE (op
) != SYMBOL_REF
)
843 /* Easy test for recursion. */
844 if (op
== XEXP (DECL_RTL (current_function_decl
), 0))
847 /* Functions that are not local can be overridden, and thus may
848 not share the same gp. */
849 if (! SYMBOL_REF_LOCAL_P (op
))
852 /* If -msmall-data is in effect, assume that there is only one GP
853 for the module, and so any local symbol has this property. We
854 need explicit relocations to be able to enforce this for symbols
855 not defined in this unit of translation, however. */
856 if (TARGET_EXPLICIT_RELOCS
&& TARGET_SMALL_DATA
)
859 /* Functions that are not external are defined in this UoT,
860 and thus must share the same gp. */
861 return ! SYMBOL_REF_EXTERNAL_P (op
);
864 /* Return 1 if OP is a SYMBOL_REF for which we can make a call via bsr. */
867 direct_call_operand (rtx op
, enum machine_mode mode
)
869 tree op_decl
, cfun_sec
, op_sec
;
871 /* Must share the same GP. */
872 if (!samegp_function_operand (op
, mode
))
875 /* If profiling is implemented via linker tricks, we can't jump
876 to the nogp alternate entry point. Note that current_function_profile
877 would not be correct, since that doesn't indicate if the target
878 function uses profiling. */
879 /* ??? TARGET_PROFILING_NEEDS_GP isn't really the right test,
880 but is approximately correct for the OSF ABIs. Don't know
881 what to do for VMS, NT, or UMK. */
882 if (!TARGET_PROFILING_NEEDS_GP
&& profile_flag
)
885 /* Must be a function. In some cases folks create thunks in static
886 data structures and then make calls to them. If we allow the
887 direct call, we'll get an error from the linker about !samegp reloc
888 against a symbol without a .prologue directive. */
889 if (!SYMBOL_REF_FUNCTION_P (op
))
892 /* Must be "near" so that the branch is assumed to reach. With
893 -msmall-text, this is assumed true of all local symbols. Since
894 we've already checked samegp, locality is already assured. */
895 if (TARGET_SMALL_TEXT
)
898 /* Otherwise, a decl is "near" if it is defined in the same section. */
899 if (flag_function_sections
)
902 op_decl
= SYMBOL_REF_DECL (op
);
903 if (DECL_ONE_ONLY (current_function_decl
)
904 || (op_decl
&& DECL_ONE_ONLY (op_decl
)))
907 cfun_sec
= DECL_SECTION_NAME (current_function_decl
);
908 op_sec
= op_decl
? DECL_SECTION_NAME (op_decl
) : NULL
;
909 return ((!cfun_sec
&& !op_sec
)
910 || (cfun_sec
&& op_sec
911 && strcmp (TREE_STRING_POINTER (cfun_sec
),
912 TREE_STRING_POINTER (op_sec
)) == 0));
915 /* Return true if OP is a LABEL_REF, or SYMBOL_REF or CONST referencing
916 a (non-tls) variable known to be defined in this file. */
919 local_symbolic_operand (rtx op
, enum machine_mode mode
)
921 if (mode
!= VOIDmode
&& GET_MODE (op
) != VOIDmode
&& mode
!= GET_MODE (op
))
924 if (GET_CODE (op
) == LABEL_REF
)
927 if (GET_CODE (op
) == CONST
928 && GET_CODE (XEXP (op
, 0)) == PLUS
929 && GET_CODE (XEXP (XEXP (op
, 0), 1)) == CONST_INT
)
930 op
= XEXP (XEXP (op
, 0), 0);
932 if (GET_CODE (op
) != SYMBOL_REF
)
935 return SYMBOL_REF_LOCAL_P (op
) && !SYMBOL_REF_TLS_MODEL (op
);
938 /* Return true if OP is a SYMBOL_REF or CONST referencing a variable
939 known to be defined in this file in the small data area. */
942 small_symbolic_operand (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
944 if (! TARGET_SMALL_DATA
)
947 if (mode
!= VOIDmode
&& GET_MODE (op
) != VOIDmode
&& mode
!= GET_MODE (op
))
950 if (GET_CODE (op
) == CONST
951 && GET_CODE (XEXP (op
, 0)) == PLUS
952 && GET_CODE (XEXP (XEXP (op
, 0), 1)) == CONST_INT
)
953 op
= XEXP (XEXP (op
, 0), 0);
955 if (GET_CODE (op
) != SYMBOL_REF
)
958 /* ??? There's no encode_section_info equivalent for the rtl
959 constant pool, so SYMBOL_FLAG_SMALL never gets set. */
960 if (CONSTANT_POOL_ADDRESS_P (op
))
961 return GET_MODE_SIZE (get_pool_mode (op
)) <= g_switch_value
;
963 return (SYMBOL_REF_LOCAL_P (op
)
964 && SYMBOL_REF_SMALL_P (op
)
965 && SYMBOL_REF_TLS_MODEL (op
) == 0);
968 /* Return true if OP is a SYMBOL_REF or CONST referencing a variable
969 not known (or known not) to be defined in this file. */
972 global_symbolic_operand (rtx op
, enum machine_mode mode
)
974 if (mode
!= VOIDmode
&& GET_MODE (op
) != VOIDmode
&& mode
!= GET_MODE (op
))
977 if (GET_CODE (op
) == CONST
978 && GET_CODE (XEXP (op
, 0)) == PLUS
979 && GET_CODE (XEXP (XEXP (op
, 0), 1)) == CONST_INT
)
980 op
= XEXP (XEXP (op
, 0), 0);
982 if (GET_CODE (op
) != SYMBOL_REF
)
985 return !SYMBOL_REF_LOCAL_P (op
) && !SYMBOL_REF_TLS_MODEL (op
);
988 /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
991 call_operand (rtx op
, enum machine_mode mode
)
996 if (GET_CODE (op
) == REG
)
1000 /* Disallow virtual registers to cope with pathological test cases
1001 such as compile/930117-1.c in which the virtual reg decomposes
1002 to the frame pointer. Which is a hard reg that is not $27. */
1003 return (REGNO (op
) == 27 || REGNO (op
) > LAST_VIRTUAL_REGISTER
);
1008 if (TARGET_ABI_UNICOSMK
)
1010 if (GET_CODE (op
) == SYMBOL_REF
)
1016 /* Returns 1 if OP is a symbolic operand, i.e. a symbol_ref or a label_ref,
1017 possibly with an offset. */
1020 symbolic_operand (rtx op
, enum machine_mode mode
)
1022 if (mode
!= VOIDmode
&& GET_MODE (op
) != VOIDmode
&& mode
!= GET_MODE (op
))
1024 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
1026 if (GET_CODE (op
) == CONST
1027 && GET_CODE (XEXP (op
,0)) == PLUS
1028 && GET_CODE (XEXP (XEXP (op
,0), 0)) == SYMBOL_REF
1029 && GET_CODE (XEXP (XEXP (op
,0), 1)) == CONST_INT
)
1034 /* Return true if OP is valid for a particular TLS relocation. */
1037 tls_symbolic_operand_1 (rtx op
, enum machine_mode mode
, int size
, int unspec
)
1039 if (mode
!= VOIDmode
&& GET_MODE (op
) != VOIDmode
&& mode
!= GET_MODE (op
))
1042 if (GET_CODE (op
) != CONST
)
1046 if (GET_CODE (op
) != UNSPEC
|| XINT (op
, 1) != unspec
)
1048 op
= XVECEXP (op
, 0, 0);
1050 if (GET_CODE (op
) != SYMBOL_REF
)
1053 if (SYMBOL_REF_LOCAL_P (op
))
1055 if (alpha_tls_size
> size
)
1064 switch (SYMBOL_REF_TLS_MODEL (op
))
1066 case TLS_MODEL_LOCAL_DYNAMIC
:
1067 return unspec
== UNSPEC_DTPREL
;
1068 case TLS_MODEL_INITIAL_EXEC
:
1069 return unspec
== UNSPEC_TPREL
&& size
== 64;
1070 case TLS_MODEL_LOCAL_EXEC
:
1071 return unspec
== UNSPEC_TPREL
;
1077 /* Return true if OP is valid for 16-bit DTP relative relocations. */
1080 dtp16_symbolic_operand (rtx op
, enum machine_mode mode
)
1082 return tls_symbolic_operand_1 (op
, mode
, 16, UNSPEC_DTPREL
);
1085 /* Return true if OP is valid for 32-bit DTP relative relocations. */
1088 dtp32_symbolic_operand (rtx op
, enum machine_mode mode
)
1090 return tls_symbolic_operand_1 (op
, mode
, 32, UNSPEC_DTPREL
);
1093 /* Return true if OP is valid for 64-bit DTP relative relocations. */
1096 gotdtp_symbolic_operand (rtx op
, enum machine_mode mode
)
1098 return tls_symbolic_operand_1 (op
, mode
, 64, UNSPEC_DTPREL
);
1101 /* Return true if OP is valid for 16-bit TP relative relocations. */
1104 tp16_symbolic_operand (rtx op
, enum machine_mode mode
)
1106 return tls_symbolic_operand_1 (op
, mode
, 16, UNSPEC_TPREL
);
1109 /* Return true if OP is valid for 32-bit TP relative relocations. */
1112 tp32_symbolic_operand (rtx op
, enum machine_mode mode
)
1114 return tls_symbolic_operand_1 (op
, mode
, 32, UNSPEC_TPREL
);
1117 /* Return true if OP is valid for 64-bit TP relative relocations. */
1120 gottp_symbolic_operand (rtx op
, enum machine_mode mode
)
1122 return tls_symbolic_operand_1 (op
, mode
, 64, UNSPEC_TPREL
);
1125 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
1126 comparisons are valid in which insn. */
1129 alpha_comparison_operator (rtx op
, enum machine_mode mode
)
1131 enum rtx_code code
= GET_CODE (op
);
1133 if (mode
!= GET_MODE (op
) && mode
!= VOIDmode
)
1136 return (code
== EQ
|| code
== LE
|| code
== LT
1137 || code
== LEU
|| code
== LTU
);
1140 /* Return 1 if OP is a valid Alpha comparison operator against zero.
1141 Here we know which comparisons are valid in which insn. */
1144 alpha_zero_comparison_operator (rtx op
, enum machine_mode mode
)
1146 enum rtx_code code
= GET_CODE (op
);
1148 if (mode
!= GET_MODE (op
) && mode
!= VOIDmode
)
1151 return (code
== EQ
|| code
== NE
|| code
== LE
|| code
== LT
1152 || code
== LEU
|| code
== LTU
);
1155 /* Return 1 if OP is a valid Alpha swapped comparison operator. */
1158 alpha_swapped_comparison_operator (rtx op
, enum machine_mode mode
)
1162 if ((mode
!= GET_MODE (op
) && mode
!= VOIDmode
)
1163 || !COMPARISON_P (op
))
1166 code
= swap_condition (GET_CODE (op
));
1167 return (code
== EQ
|| code
== LE
|| code
== LT
1168 || code
== LEU
|| code
== LTU
);
1171 /* Return 1 if OP is a signed comparison operation. */
1174 signed_comparison_operator (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1176 enum rtx_code code
= GET_CODE (op
);
1178 if (mode
!= GET_MODE (op
) && mode
!= VOIDmode
)
1181 return (code
== EQ
|| code
== NE
1182 || code
== LE
|| code
== LT
1183 || code
== GE
|| code
== GT
);
1186 /* Return 1 if OP is a valid Alpha floating point comparison operator.
1187 Here we know which comparisons are valid in which insn. */
1190 alpha_fp_comparison_operator (rtx op
, enum machine_mode mode
)
1192 enum rtx_code code
= GET_CODE (op
);
1194 if (mode
!= GET_MODE (op
) && mode
!= VOIDmode
)
1197 return (code
== EQ
|| code
== LE
|| code
== LT
|| code
== UNORDERED
);
1200 /* Return 1 if this is a divide or modulus operator. */
1203 divmod_operator (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1205 enum rtx_code code
= GET_CODE (op
);
1207 return (code
== DIV
|| code
== MOD
|| code
== UDIV
|| code
== UMOD
);
1210 /* Return 1 if this is a float->int conversion operator. */
1213 fix_operator (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1215 enum rtx_code code
= GET_CODE (op
);
1217 return (code
== FIX
|| code
== UNSIGNED_FIX
);
1220 /* Return 1 if this memory address is a known aligned register plus
1221 a constant. It must be a valid address. This means that we can do
1222 this as an aligned reference plus some offset.
1224 Take into account what reload will do. */
1227 aligned_memory_operand (rtx op
, enum machine_mode mode
)
1231 if (reload_in_progress
)
1234 if (GET_CODE (tmp
) == SUBREG
)
1235 tmp
= SUBREG_REG (tmp
);
1236 if (GET_CODE (tmp
) == REG
1237 && REGNO (tmp
) >= FIRST_PSEUDO_REGISTER
)
1239 op
= reg_equiv_memory_loc
[REGNO (tmp
)];
1245 if (GET_CODE (op
) != MEM
)
1247 if (MEM_ALIGN (op
) >= 32)
1251 /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
1252 sorts of constructs. Dig for the real base register. */
1253 if (reload_in_progress
1254 && GET_CODE (op
) == PLUS
1255 && GET_CODE (XEXP (op
, 0)) == PLUS
)
1256 base
= XEXP (XEXP (op
, 0), 0);
1259 if (! memory_address_p (mode
, op
))
1261 base
= (GET_CODE (op
) == PLUS
? XEXP (op
, 0) : op
);
1264 return (GET_CODE (base
) == REG
&& REGNO_POINTER_ALIGN (REGNO (base
)) >= 32);
1267 /* Similar, but return 1 if OP is a MEM which is not alignable. */
1270 unaligned_memory_operand (rtx op
, enum machine_mode mode
)
1274 if (reload_in_progress
)
1277 if (GET_CODE (tmp
) == SUBREG
)
1278 tmp
= SUBREG_REG (tmp
);
1279 if (GET_CODE (tmp
) == REG
1280 && REGNO (tmp
) >= FIRST_PSEUDO_REGISTER
)
1282 op
= reg_equiv_memory_loc
[REGNO (tmp
)];
1288 if (GET_CODE (op
) != MEM
)
1290 if (MEM_ALIGN (op
) >= 32)
1294 /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
1295 sorts of constructs. Dig for the real base register. */
1296 if (reload_in_progress
1297 && GET_CODE (op
) == PLUS
1298 && GET_CODE (XEXP (op
, 0)) == PLUS
)
1299 base
= XEXP (XEXP (op
, 0), 0);
1302 if (! memory_address_p (mode
, op
))
1304 base
= (GET_CODE (op
) == PLUS
? XEXP (op
, 0) : op
);
1307 return (GET_CODE (base
) == REG
&& REGNO_POINTER_ALIGN (REGNO (base
)) < 32);
1310 /* Return 1 if OP is either a register or an unaligned memory location. */
1313 reg_or_unaligned_mem_operand (rtx op
, enum machine_mode mode
)
1315 return register_operand (op
, mode
) || unaligned_memory_operand (op
, mode
);
1318 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
1321 any_memory_operand (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1323 return (GET_CODE (op
) == MEM
1324 || (GET_CODE (op
) == SUBREG
&& GET_CODE (SUBREG_REG (op
)) == REG
)
1325 || (reload_in_progress
&& GET_CODE (op
) == REG
1326 && REGNO (op
) >= FIRST_PSEUDO_REGISTER
)
1327 || (reload_in_progress
&& GET_CODE (op
) == SUBREG
1328 && GET_CODE (SUBREG_REG (op
)) == REG
1329 && REGNO (SUBREG_REG (op
)) >= FIRST_PSEUDO_REGISTER
));
1332 /* Returns 1 if OP is not an eliminable register.
1334 This exists to cure a pathological abort in the s8addq (et al) patterns,
1336 long foo () { long t; bar(); return (long) &t * 26107; }
1338 which run afoul of a hack in reload to cure a (presumably) similar
1339 problem with lea-type instructions on other targets. But there is
1340 one of us and many of them, so work around the problem by selectively
1341 preventing combine from making the optimization. */
1344 reg_not_elim_operand (rtx op
, enum machine_mode mode
)
1347 if (GET_CODE (op
) == SUBREG
)
1348 inner
= SUBREG_REG (op
);
1349 if (inner
== frame_pointer_rtx
|| inner
== arg_pointer_rtx
)
1352 return register_operand (op
, mode
);
1355 /* Return 1 is OP is a memory location that is not a reference (using
1356 an AND) to an unaligned location. Take into account what reload
1360 normal_memory_operand (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
1362 if (reload_in_progress
)
1365 if (GET_CODE (tmp
) == SUBREG
)
1366 tmp
= SUBREG_REG (tmp
);
1367 if (GET_CODE (tmp
) == REG
1368 && REGNO (tmp
) >= FIRST_PSEUDO_REGISTER
)
1370 op
= reg_equiv_memory_loc
[REGNO (tmp
)];
1372 /* This may not have been assigned an equivalent address if it will
1373 be eliminated. In that case, it doesn't matter what we do. */
1379 return GET_CODE (op
) == MEM
&& GET_CODE (XEXP (op
, 0)) != AND
;
1382 /* Accept a register, but not a subreg of any kind. This allows us to
1383 avoid pathological cases in reload wrt data movement common in
1384 int->fp conversion. */
1387 reg_no_subreg_operand (rtx op
, enum machine_mode mode
)
1389 if (GET_CODE (op
) != REG
)
1391 return register_operand (op
, mode
);
1394 /* Recognize an addition operation that includes a constant. Used to
1395 convince reload to canonize (plus (plus reg c1) c2) during register
1399 addition_operation (rtx op
, enum machine_mode mode
)
1401 if (GET_MODE (op
) != mode
&& mode
!= VOIDmode
)
1403 if (GET_CODE (op
) == PLUS
1404 && register_operand (XEXP (op
, 0), mode
)
1405 && GET_CODE (XEXP (op
, 1)) == CONST_INT
1406 && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (op
, 1)), 'K'))
1411 /* Implements CONST_OK_FOR_LETTER_P. Return true if the value matches
1412 the range defined for C in [I-P]. */
1415 alpha_const_ok_for_letter_p (HOST_WIDE_INT value
, int c
)
1420 /* An unsigned 8 bit constant. */
1421 return (unsigned HOST_WIDE_INT
) value
< 0x100;
1423 /* The constant zero. */
1426 /* A signed 16 bit constant. */
1427 return (unsigned HOST_WIDE_INT
) (value
+ 0x8000) < 0x10000;
1429 /* A shifted signed 16 bit constant appropriate for LDAH. */
1430 return ((value
& 0xffff) == 0
1431 && ((value
) >> 31 == -1 || value
>> 31 == 0));
1433 /* A constant that can be AND'ed with using a ZAP insn. */
1434 return zap_mask (value
);
1436 /* A complemented unsigned 8 bit constant. */
1437 return (unsigned HOST_WIDE_INT
) (~ value
) < 0x100;
1439 /* A negated unsigned 8 bit constant. */
1440 return (unsigned HOST_WIDE_INT
) (- value
) < 0x100;
1442 /* The constant 1, 2 or 3. */
1443 return value
== 1 || value
== 2 || value
== 3;
1450 /* Implements CONST_DOUBLE_OK_FOR_LETTER_P. Return true if VALUE
1451 matches for C in [GH]. */
1454 alpha_const_double_ok_for_letter_p (rtx value
, int c
)
1459 /* The floating point zero constant. */
1460 return (GET_MODE_CLASS (GET_MODE (value
)) == MODE_FLOAT
1461 && value
== CONST0_RTX (GET_MODE (value
)));
1464 /* A valid operand of a ZAP insn. */
1465 return (GET_MODE (value
) == VOIDmode
1466 && zap_mask (CONST_DOUBLE_LOW (value
))
1467 && zap_mask (CONST_DOUBLE_HIGH (value
)));
1474 /* Implements CONST_DOUBLE_OK_FOR_LETTER_P. Return true if VALUE
1478 alpha_extra_constraint (rtx value
, int c
)
1483 return normal_memory_operand (value
, VOIDmode
);
1485 return direct_call_operand (value
, Pmode
);
1487 return (GET_CODE (value
) == CONST_INT
1488 && (unsigned HOST_WIDE_INT
) INTVAL (value
) < 64);
1490 return GET_CODE (value
) == HIGH
;
1492 return TARGET_ABI_UNICOSMK
&& symbolic_operand (value
, VOIDmode
);
1494 return (GET_CODE (value
) == CONST_VECTOR
1495 && value
== CONST0_RTX (GET_MODE (value
)));
1501 /* Return 1 if this function can directly return via $26. */
1504 direct_return (void)
1506 return (! TARGET_ABI_OPEN_VMS
&& ! TARGET_ABI_UNICOSMK
1508 && alpha_sa_size () == 0
1509 && get_frame_size () == 0
1510 && current_function_outgoing_args_size
== 0
1511 && current_function_pretend_args_size
== 0);
1514 /* Return the ADDR_VEC associated with a tablejump insn. */
1517 alpha_tablejump_addr_vec (rtx insn
)
1521 tmp
= JUMP_LABEL (insn
);
1524 tmp
= NEXT_INSN (tmp
);
1527 if (GET_CODE (tmp
) == JUMP_INSN
1528 && GET_CODE (PATTERN (tmp
)) == ADDR_DIFF_VEC
)
1529 return PATTERN (tmp
);
1533 /* Return the label of the predicted edge, or CONST0_RTX if we don't know. */
1536 alpha_tablejump_best_label (rtx insn
)
1538 rtx jump_table
= alpha_tablejump_addr_vec (insn
);
1539 rtx best_label
= NULL_RTX
;
1541 /* ??? Once the CFG doesn't keep getting completely rebuilt, look
1542 there for edge frequency counts from profile data. */
1546 int n_labels
= XVECLEN (jump_table
, 1);
1547 int best_count
= -1;
1550 for (i
= 0; i
< n_labels
; i
++)
1554 for (j
= i
+ 1; j
< n_labels
; j
++)
1555 if (XEXP (XVECEXP (jump_table
, 1, i
), 0)
1556 == XEXP (XVECEXP (jump_table
, 1, j
), 0))
1559 if (count
> best_count
)
1560 best_count
= count
, best_label
= XVECEXP (jump_table
, 1, i
);
1564 return best_label
? best_label
: const0_rtx
;
1567 /* Return the TLS model to use for SYMBOL. */
1569 static enum tls_model
1570 tls_symbolic_operand_type (rtx symbol
)
1572 enum tls_model model
;
1574 if (GET_CODE (symbol
) != SYMBOL_REF
)
1576 model
= SYMBOL_REF_TLS_MODEL (symbol
);
1578 /* Local-exec with a 64-bit size is the same code as initial-exec. */
1579 if (model
== TLS_MODEL_LOCAL_EXEC
&& alpha_tls_size
== 64)
1580 model
= TLS_MODEL_INITIAL_EXEC
;
1585 /* Return true if the function DECL will share the same GP as any
1586 function in the current unit of translation. */
1589 decl_has_samegp (tree decl
)
1591 /* Functions that are not local can be overridden, and thus may
1592 not share the same gp. */
1593 if (!(*targetm
.binds_local_p
) (decl
))
1596 /* If -msmall-data is in effect, assume that there is only one GP
1597 for the module, and so any local symbol has this property. We
1598 need explicit relocations to be able to enforce this for symbols
1599 not defined in this unit of translation, however. */
1600 if (TARGET_EXPLICIT_RELOCS
&& TARGET_SMALL_DATA
)
1603 /* Functions that are not external are defined in this UoT. */
1604 /* ??? Irritatingly, static functions not yet emitted are still
1605 marked "external". Apply this to non-static functions only. */
1606 return !TREE_PUBLIC (decl
) || !DECL_EXTERNAL (decl
);
1609 /* Return true if EXP should be placed in the small data section. */
1612 alpha_in_small_data_p (tree exp
)
1614 /* We want to merge strings, so we never consider them small data. */
1615 if (TREE_CODE (exp
) == STRING_CST
)
1618 /* Functions are never in the small data area. Duh. */
1619 if (TREE_CODE (exp
) == FUNCTION_DECL
)
1622 if (TREE_CODE (exp
) == VAR_DECL
&& DECL_SECTION_NAME (exp
))
1624 const char *section
= TREE_STRING_POINTER (DECL_SECTION_NAME (exp
));
1625 if (strcmp (section
, ".sdata") == 0
1626 || strcmp (section
, ".sbss") == 0)
1631 HOST_WIDE_INT size
= int_size_in_bytes (TREE_TYPE (exp
));
1633 /* If this is an incomplete type with size 0, then we can't put it
1634 in sdata because it might be too big when completed. */
1635 if (size
> 0 && (unsigned HOST_WIDE_INT
) size
<= g_switch_value
)
1642 #if TARGET_ABI_OPEN_VMS
1644 alpha_linkage_symbol_p (const char *symname
)
1646 int symlen
= strlen (symname
);
1649 return strcmp (&symname
[symlen
- 4], "..lk") == 0;
1654 #define LINKAGE_SYMBOL_REF_P(X) \
1655 ((GET_CODE (X) == SYMBOL_REF \
1656 && alpha_linkage_symbol_p (XSTR (X, 0))) \
1657 || (GET_CODE (X) == CONST \
1658 && GET_CODE (XEXP (X, 0)) == PLUS \
1659 && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF \
1660 && alpha_linkage_symbol_p (XSTR (XEXP (XEXP (X, 0), 0), 0))))
1663 /* legitimate_address_p recognizes an RTL expression that is a valid
1664 memory address for an instruction. The MODE argument is the
1665 machine mode for the MEM expression that wants to use this address.
1667 For Alpha, we have either a constant address or the sum of a
1668 register and a constant address, or just a register. For DImode,
1669 any of those forms can be surrounded with an AND that clear the
1670 low-order three bits; this is an "unaligned" access. */
1673 alpha_legitimate_address_p (enum machine_mode mode
, rtx x
, int strict
)
1675 /* If this is an ldq_u type address, discard the outer AND. */
1677 && GET_CODE (x
) == AND
1678 && GET_CODE (XEXP (x
, 1)) == CONST_INT
1679 && INTVAL (XEXP (x
, 1)) == -8)
1682 /* Discard non-paradoxical subregs. */
1683 if (GET_CODE (x
) == SUBREG
1684 && (GET_MODE_SIZE (GET_MODE (x
))
1685 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x
)))))
1688 /* Unadorned general registers are valid. */
1691 ? STRICT_REG_OK_FOR_BASE_P (x
)
1692 : NONSTRICT_REG_OK_FOR_BASE_P (x
)))
1695 /* Constant addresses (i.e. +/- 32k) are valid. */
1696 if (CONSTANT_ADDRESS_P (x
))
1699 #if TARGET_ABI_OPEN_VMS
1700 if (LINKAGE_SYMBOL_REF_P (x
))
1704 /* Register plus a small constant offset is valid. */
1705 if (GET_CODE (x
) == PLUS
)
1707 rtx ofs
= XEXP (x
, 1);
1710 /* Discard non-paradoxical subregs. */
1711 if (GET_CODE (x
) == SUBREG
1712 && (GET_MODE_SIZE (GET_MODE (x
))
1713 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x
)))))
1719 && NONSTRICT_REG_OK_FP_BASE_P (x
)
1720 && GET_CODE (ofs
) == CONST_INT
)
1723 ? STRICT_REG_OK_FOR_BASE_P (x
)
1724 : NONSTRICT_REG_OK_FOR_BASE_P (x
))
1725 && CONSTANT_ADDRESS_P (ofs
))
1728 else if (GET_CODE (x
) == ADDRESSOF
1729 && GET_CODE (ofs
) == CONST_INT
)
1733 /* If we're managing explicit relocations, LO_SUM is valid, as
1734 are small data symbols. */
1735 else if (TARGET_EXPLICIT_RELOCS
)
1737 if (small_symbolic_operand (x
, Pmode
))
1740 if (GET_CODE (x
) == LO_SUM
)
1742 rtx ofs
= XEXP (x
, 1);
1745 /* Discard non-paradoxical subregs. */
1746 if (GET_CODE (x
) == SUBREG
1747 && (GET_MODE_SIZE (GET_MODE (x
))
1748 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x
)))))
1751 /* Must have a valid base register. */
1754 ? STRICT_REG_OK_FOR_BASE_P (x
)
1755 : NONSTRICT_REG_OK_FOR_BASE_P (x
))))
1758 /* The symbol must be local. */
1759 if (local_symbolic_operand (ofs
, Pmode
)
1760 || dtp32_symbolic_operand (ofs
, Pmode
)
1761 || tp32_symbolic_operand (ofs
, Pmode
))
1769 /* Build the SYMBOL_REF for __tls_get_addr. */
1771 static GTY(()) rtx tls_get_addr_libfunc
;
1774 get_tls_get_addr (void)
1776 if (!tls_get_addr_libfunc
)
1777 tls_get_addr_libfunc
= init_one_libfunc ("__tls_get_addr");
1778 return tls_get_addr_libfunc
;
1781 /* Try machine-dependent ways of modifying an illegitimate address
1782 to be legitimate. If we find one, return the new, valid address. */
1785 alpha_legitimize_address (rtx x
, rtx scratch
,
1786 enum machine_mode mode ATTRIBUTE_UNUSED
)
1788 HOST_WIDE_INT addend
;
1790 /* If the address is (plus reg const_int) and the CONST_INT is not a
1791 valid offset, compute the high part of the constant and add it to
1792 the register. Then our address is (plus temp low-part-const). */
1793 if (GET_CODE (x
) == PLUS
1794 && GET_CODE (XEXP (x
, 0)) == REG
1795 && GET_CODE (XEXP (x
, 1)) == CONST_INT
1796 && ! CONSTANT_ADDRESS_P (XEXP (x
, 1)))
1798 addend
= INTVAL (XEXP (x
, 1));
1803 /* If the address is (const (plus FOO const_int)), find the low-order
1804 part of the CONST_INT. Then load FOO plus any high-order part of the
1805 CONST_INT into a register. Our address is (plus reg low-part-const).
1806 This is done to reduce the number of GOT entries. */
1808 && GET_CODE (x
) == CONST
1809 && GET_CODE (XEXP (x
, 0)) == PLUS
1810 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
)
1812 addend
= INTVAL (XEXP (XEXP (x
, 0), 1));
1813 x
= force_reg (Pmode
, XEXP (XEXP (x
, 0), 0));
1817 /* If we have a (plus reg const), emit the load as in (2), then add
1818 the two registers, and finally generate (plus reg low-part-const) as
1821 && GET_CODE (x
) == PLUS
1822 && GET_CODE (XEXP (x
, 0)) == REG
1823 && GET_CODE (XEXP (x
, 1)) == CONST
1824 && GET_CODE (XEXP (XEXP (x
, 1), 0)) == PLUS
1825 && GET_CODE (XEXP (XEXP (XEXP (x
, 1), 0), 1)) == CONST_INT
)
1827 addend
= INTVAL (XEXP (XEXP (XEXP (x
, 1), 0), 1));
1828 x
= expand_simple_binop (Pmode
, PLUS
, XEXP (x
, 0),
1829 XEXP (XEXP (XEXP (x
, 1), 0), 0),
1830 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
1834 /* If this is a local symbol, split the address into HIGH/LO_SUM parts. */
1835 if (TARGET_EXPLICIT_RELOCS
&& symbolic_operand (x
, Pmode
))
1837 rtx r0
, r16
, eqv
, tga
, tp
, insn
, dest
, seq
;
1839 switch (tls_symbolic_operand_type (x
))
1841 case TLS_MODEL_GLOBAL_DYNAMIC
:
1844 r0
= gen_rtx_REG (Pmode
, 0);
1845 r16
= gen_rtx_REG (Pmode
, 16);
1846 tga
= get_tls_get_addr ();
1847 dest
= gen_reg_rtx (Pmode
);
1848 seq
= GEN_INT (alpha_next_sequence_number
++);
1850 emit_insn (gen_movdi_er_tlsgd (r16
, pic_offset_table_rtx
, x
, seq
));
1851 insn
= gen_call_value_osf_tlsgd (r0
, tga
, seq
);
1852 insn
= emit_call_insn (insn
);
1853 CONST_OR_PURE_CALL_P (insn
) = 1;
1854 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r16
);
1856 insn
= get_insns ();
1859 emit_libcall_block (insn
, dest
, r0
, x
);
1862 case TLS_MODEL_LOCAL_DYNAMIC
:
1865 r0
= gen_rtx_REG (Pmode
, 0);
1866 r16
= gen_rtx_REG (Pmode
, 16);
1867 tga
= get_tls_get_addr ();
1868 scratch
= gen_reg_rtx (Pmode
);
1869 seq
= GEN_INT (alpha_next_sequence_number
++);
1871 emit_insn (gen_movdi_er_tlsldm (r16
, pic_offset_table_rtx
, seq
));
1872 insn
= gen_call_value_osf_tlsldm (r0
, tga
, seq
);
1873 insn
= emit_call_insn (insn
);
1874 CONST_OR_PURE_CALL_P (insn
) = 1;
1875 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r16
);
1877 insn
= get_insns ();
1880 eqv
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
),
1881 UNSPEC_TLSLDM_CALL
);
1882 emit_libcall_block (insn
, scratch
, r0
, eqv
);
1884 eqv
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, x
), UNSPEC_DTPREL
);
1885 eqv
= gen_rtx_CONST (Pmode
, eqv
);
1887 if (alpha_tls_size
== 64)
1889 dest
= gen_reg_rtx (Pmode
);
1890 emit_insn (gen_rtx_SET (VOIDmode
, dest
, eqv
));
1891 emit_insn (gen_adddi3 (dest
, dest
, scratch
));
1894 if (alpha_tls_size
== 32)
1896 insn
= gen_rtx_HIGH (Pmode
, eqv
);
1897 insn
= gen_rtx_PLUS (Pmode
, scratch
, insn
);
1898 scratch
= gen_reg_rtx (Pmode
);
1899 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, insn
));
1901 return gen_rtx_LO_SUM (Pmode
, scratch
, eqv
);
1903 case TLS_MODEL_INITIAL_EXEC
:
1904 eqv
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, x
), UNSPEC_TPREL
);
1905 eqv
= gen_rtx_CONST (Pmode
, eqv
);
1906 tp
= gen_reg_rtx (Pmode
);
1907 scratch
= gen_reg_rtx (Pmode
);
1908 dest
= gen_reg_rtx (Pmode
);
1910 emit_insn (gen_load_tp (tp
));
1911 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, eqv
));
1912 emit_insn (gen_adddi3 (dest
, tp
, scratch
));
1915 case TLS_MODEL_LOCAL_EXEC
:
1916 eqv
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, x
), UNSPEC_TPREL
);
1917 eqv
= gen_rtx_CONST (Pmode
, eqv
);
1918 tp
= gen_reg_rtx (Pmode
);
1920 emit_insn (gen_load_tp (tp
));
1921 if (alpha_tls_size
== 32)
1923 insn
= gen_rtx_HIGH (Pmode
, eqv
);
1924 insn
= gen_rtx_PLUS (Pmode
, tp
, insn
);
1925 tp
= gen_reg_rtx (Pmode
);
1926 emit_insn (gen_rtx_SET (VOIDmode
, tp
, insn
));
1928 return gen_rtx_LO_SUM (Pmode
, tp
, eqv
);
1931 if (local_symbolic_operand (x
, Pmode
))
1933 if (small_symbolic_operand (x
, Pmode
))
1937 if (!no_new_pseudos
)
1938 scratch
= gen_reg_rtx (Pmode
);
1939 emit_insn (gen_rtx_SET (VOIDmode
, scratch
,
1940 gen_rtx_HIGH (Pmode
, x
)));
1941 return gen_rtx_LO_SUM (Pmode
, scratch
, x
);
1950 HOST_WIDE_INT low
, high
;
1952 low
= ((addend
& 0xffff) ^ 0x8000) - 0x8000;
1954 high
= ((addend
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1958 x
= expand_simple_binop (Pmode
, PLUS
, x
, GEN_INT (addend
),
1959 (no_new_pseudos
? scratch
: NULL_RTX
),
1960 1, OPTAB_LIB_WIDEN
);
1962 x
= expand_simple_binop (Pmode
, PLUS
, x
, GEN_INT (high
),
1963 (no_new_pseudos
? scratch
: NULL_RTX
),
1964 1, OPTAB_LIB_WIDEN
);
1966 return plus_constant (x
, low
);
1970 /* We do not allow indirect calls to be optimized into sibling calls, nor
1971 can we allow a call to a function with a different GP to be optimized
1975 alpha_function_ok_for_sibcall (tree decl
, tree exp ATTRIBUTE_UNUSED
)
1977 /* Can't do indirect tail calls, since we don't know if the target
1978 uses the same GP. */
1982 /* Otherwise, we can make a tail call if the target function shares
1984 return decl_has_samegp (decl
);
1987 /* For TARGET_EXPLICIT_RELOCS, we don't obfuscate a SYMBOL_REF to a
1988 small symbolic operand until after reload. At which point we need
1989 to replace (mem (symbol_ref)) with (mem (lo_sum $29 symbol_ref))
1990 so that sched2 has the proper dependency information. */
1993 some_small_symbolic_operand_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
1997 /* Don't re-split. */
1998 if (GET_CODE (x
) == LO_SUM
)
2001 return small_symbolic_operand (x
, Pmode
) != 0;
2005 some_small_symbolic_operand (rtx x
, enum machine_mode mode ATTRIBUTE_UNUSED
)
2007 return for_each_rtx (&x
, some_small_symbolic_operand_1
, NULL
);
2011 split_small_symbolic_operand_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
2015 /* Don't re-split. */
2016 if (GET_CODE (x
) == LO_SUM
)
2019 if (small_symbolic_operand (x
, Pmode
))
2021 x
= gen_rtx_LO_SUM (Pmode
, pic_offset_table_rtx
, x
);
2030 split_small_symbolic_operand (rtx x
)
2033 for_each_rtx (&x
, split_small_symbolic_operand_1
, NULL
);
2037 /* Indicate that INSN cannot be duplicated. This is true for any insn
2038 that we've marked with gpdisp relocs, since those have to stay in
2039 1-1 correspondence with one another.
2041 Technically we could copy them if we could set up a mapping from one
2042 sequence number to another, across the set of insns to be duplicated.
2043 This seems overly complicated and error-prone since interblock motion
2044 from sched-ebb could move one of the pair of insns to a different block.
2046 Also cannot allow jsr insns to be duplicated. If they throw exceptions,
2047 then they'll be in a different block from their ldgp. Which could lead
2048 the bb reorder code to think that it would be ok to copy just the block
2049 containing the call and branch to the block containing the ldgp. */
2052 alpha_cannot_copy_insn_p (rtx insn
)
2054 if (!reload_completed
|| !TARGET_EXPLICIT_RELOCS
)
2056 if (recog_memoized (insn
) >= 0)
2057 return get_attr_cannot_copy (insn
);
2063 /* Try a machine-dependent way of reloading an illegitimate address
2064 operand. If we find one, push the reload and return the new rtx. */
2067 alpha_legitimize_reload_address (rtx x
,
2068 enum machine_mode mode ATTRIBUTE_UNUSED
,
2069 int opnum
, int type
,
2070 int ind_levels ATTRIBUTE_UNUSED
)
2072 /* We must recognize output that we have already generated ourselves. */
2073 if (GET_CODE (x
) == PLUS
2074 && GET_CODE (XEXP (x
, 0)) == PLUS
2075 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
2076 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
2077 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
2079 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
2080 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
2085 /* We wish to handle large displacements off a base register by
2086 splitting the addend across an ldah and the mem insn. This
2087 cuts number of extra insns needed from 3 to 1. */
2088 if (GET_CODE (x
) == PLUS
2089 && GET_CODE (XEXP (x
, 0)) == REG
2090 && REGNO (XEXP (x
, 0)) < FIRST_PSEUDO_REGISTER
2091 && REGNO_OK_FOR_BASE_P (REGNO (XEXP (x
, 0)))
2092 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
2094 HOST_WIDE_INT val
= INTVAL (XEXP (x
, 1));
2095 HOST_WIDE_INT low
= ((val
& 0xffff) ^ 0x8000) - 0x8000;
2097 = (((val
- low
) & 0xffffffff) ^ 0x80000000) - 0x80000000;
2099 /* Check for 32-bit overflow. */
2100 if (high
+ low
!= val
)
2103 /* Reload the high part into a base reg; leave the low part
2104 in the mem directly. */
2105 x
= gen_rtx_PLUS (GET_MODE (x
),
2106 gen_rtx_PLUS (GET_MODE (x
), XEXP (x
, 0),
2110 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
2111 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
2119 /* Compute a (partial) cost for rtx X. Return true if the complete
2120 cost has been computed, and false if subexpressions should be
2121 scanned. In either case, *TOTAL contains the cost result. */
2124 alpha_rtx_costs (rtx x
, int code
, int outer_code
, int *total
)
2126 enum machine_mode mode
= GET_MODE (x
);
2127 bool float_mode_p
= FLOAT_MODE_P (mode
);
2128 const struct alpha_rtx_cost_data
*cost_data
;
2131 cost_data
= &alpha_rtx_cost_size
;
2133 cost_data
= &alpha_rtx_cost_data
[alpha_cpu
];
2138 /* If this is an 8-bit constant, return zero since it can be used
2139 nearly anywhere with no cost. If it is a valid operand for an
2140 ADD or AND, likewise return 0 if we know it will be used in that
2141 context. Otherwise, return 2 since it might be used there later.
2142 All other constants take at least two insns. */
2143 if (INTVAL (x
) >= 0 && INTVAL (x
) < 256)
2151 if (x
== CONST0_RTX (mode
))
2153 else if ((outer_code
== PLUS
&& add_operand (x
, VOIDmode
))
2154 || (outer_code
== AND
&& and_operand (x
, VOIDmode
)))
2156 else if (add_operand (x
, VOIDmode
) || and_operand (x
, VOIDmode
))
2159 *total
= COSTS_N_INSNS (2);
2165 if (TARGET_EXPLICIT_RELOCS
&& small_symbolic_operand (x
, VOIDmode
))
2166 *total
= COSTS_N_INSNS (outer_code
!= MEM
);
2167 else if (TARGET_EXPLICIT_RELOCS
&& local_symbolic_operand (x
, VOIDmode
))
2168 *total
= COSTS_N_INSNS (1 + (outer_code
!= MEM
));
2169 else if (tls_symbolic_operand_type (x
))
2170 /* Estimate of cost for call_pal rduniq. */
2171 /* ??? How many insns do we emit here? More than one... */
2172 *total
= COSTS_N_INSNS (15);
2174 /* Otherwise we do a load from the GOT. */
2175 *total
= COSTS_N_INSNS (optimize_size
? 1 : alpha_memory_latency
);
2181 *total
= cost_data
->fp_add
;
2182 else if (GET_CODE (XEXP (x
, 0)) == MULT
2183 && const48_operand (XEXP (XEXP (x
, 0), 1), VOIDmode
))
2185 *total
= (rtx_cost (XEXP (XEXP (x
, 0), 0), outer_code
)
2186 + rtx_cost (XEXP (x
, 1), outer_code
) + COSTS_N_INSNS (1));
2193 *total
= cost_data
->fp_mult
;
2194 else if (mode
== DImode
)
2195 *total
= cost_data
->int_mult_di
;
2197 *total
= cost_data
->int_mult_si
;
2201 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
2202 && INTVAL (XEXP (x
, 1)) <= 3)
2204 *total
= COSTS_N_INSNS (1);
2211 *total
= cost_data
->int_shift
;
2216 *total
= cost_data
->fp_add
;
2218 *total
= cost_data
->int_cmov
;
2226 *total
= cost_data
->int_div
;
2227 else if (mode
== SFmode
)
2228 *total
= cost_data
->fp_div_sf
;
2230 *total
= cost_data
->fp_div_df
;
2234 *total
= COSTS_N_INSNS (optimize_size
? 1 : alpha_memory_latency
);
2240 *total
= COSTS_N_INSNS (1);
2248 *total
= COSTS_N_INSNS (1) + cost_data
->int_cmov
;
2254 case UNSIGNED_FLOAT
:
2258 case FLOAT_TRUNCATE
:
2259 *total
= cost_data
->fp_add
;
2267 /* REF is an alignable memory location. Place an aligned SImode
2268 reference into *PALIGNED_MEM and the number of bits to shift into
2269 *PBITNUM. SCRATCH is a free register for use in reloading out
2270 of range stack slots. */
2273 get_aligned_mem (rtx ref
, rtx
*paligned_mem
, rtx
*pbitnum
)
2276 HOST_WIDE_INT offset
= 0;
2278 if (GET_CODE (ref
) != MEM
)
2281 if (reload_in_progress
2282 && ! memory_address_p (GET_MODE (ref
), XEXP (ref
, 0)))
2284 base
= find_replacement (&XEXP (ref
, 0));
2286 if (! memory_address_p (GET_MODE (ref
), base
))
2291 base
= XEXP (ref
, 0);
2294 if (GET_CODE (base
) == PLUS
)
2295 offset
+= INTVAL (XEXP (base
, 1)), base
= XEXP (base
, 0);
2298 = widen_memory_access (ref
, SImode
, (offset
& ~3) - offset
);
2300 if (WORDS_BIG_ENDIAN
)
2301 *pbitnum
= GEN_INT (32 - (GET_MODE_BITSIZE (GET_MODE (ref
))
2302 + (offset
& 3) * 8));
2304 *pbitnum
= GEN_INT ((offset
& 3) * 8);
2307 /* Similar, but just get the address. Handle the two reload cases.
2308 Add EXTRA_OFFSET to the address we return. */
2311 get_unaligned_address (rtx ref
, int extra_offset
)
2314 HOST_WIDE_INT offset
= 0;
2316 if (GET_CODE (ref
) != MEM
)
2319 if (reload_in_progress
2320 && ! memory_address_p (GET_MODE (ref
), XEXP (ref
, 0)))
2322 base
= find_replacement (&XEXP (ref
, 0));
2324 if (! memory_address_p (GET_MODE (ref
), base
))
2329 base
= XEXP (ref
, 0);
2332 if (GET_CODE (base
) == PLUS
)
2333 offset
+= INTVAL (XEXP (base
, 1)), base
= XEXP (base
, 0);
2335 return plus_constant (base
, offset
+ extra_offset
);
2338 /* On the Alpha, all (non-symbolic) constants except zero go into
2339 a floating-point register via memory. Note that we cannot
2340 return anything that is not a subset of CLASS, and that some
2341 symbolic constants cannot be dropped to memory. */
2344 alpha_preferred_reload_class(rtx x
, enum reg_class
class)
2346 /* Zero is present in any register class. */
2347 if (x
== CONST0_RTX (GET_MODE (x
)))
2350 /* These sorts of constants we can easily drop to memory. */
2351 if (GET_CODE (x
) == CONST_INT
|| GET_CODE (x
) == CONST_DOUBLE
)
2353 if (class == FLOAT_REGS
)
2355 if (class == ALL_REGS
)
2356 return GENERAL_REGS
;
2360 /* All other kinds of constants should not (and in the case of HIGH
2361 cannot) be dropped to memory -- instead we use a GENERAL_REGS
2362 secondary reload. */
2364 return (class == ALL_REGS
? GENERAL_REGS
: class);
2369 /* Loading and storing HImode or QImode values to and from memory
2370 usually requires a scratch register. The exceptions are loading
2371 QImode and HImode from an aligned address to a general register
2372 unless byte instructions are permitted.
2374 We also cannot load an unaligned address or a paradoxical SUBREG
2375 into an FP register.
2377 We also cannot do integral arithmetic into FP regs, as might result
2378 from register elimination into a DImode fp register. */
2381 secondary_reload_class (enum reg_class
class, enum machine_mode mode
,
2384 if ((mode
== QImode
|| mode
== HImode
) && ! TARGET_BWX
)
2386 if (GET_CODE (x
) == MEM
2387 || (GET_CODE (x
) == REG
&& REGNO (x
) >= FIRST_PSEUDO_REGISTER
)
2388 || (GET_CODE (x
) == SUBREG
2389 && (GET_CODE (SUBREG_REG (x
)) == MEM
2390 || (GET_CODE (SUBREG_REG (x
)) == REG
2391 && REGNO (SUBREG_REG (x
)) >= FIRST_PSEUDO_REGISTER
))))
2393 if (!in
|| !aligned_memory_operand(x
, mode
))
2394 return GENERAL_REGS
;
2398 if (class == FLOAT_REGS
)
2400 if (GET_CODE (x
) == MEM
&& GET_CODE (XEXP (x
, 0)) == AND
)
2401 return GENERAL_REGS
;
2403 if (GET_CODE (x
) == SUBREG
2404 && (GET_MODE_SIZE (GET_MODE (x
))
2405 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x
)))))
2406 return GENERAL_REGS
;
2408 if (in
&& INTEGRAL_MODE_P (mode
)
2409 && ! (memory_operand (x
, mode
) || x
== const0_rtx
))
2410 return GENERAL_REGS
;
2416 /* Subfunction of the following function. Update the flags of any MEM
2417 found in part of X. */
2420 alpha_set_memflags_1 (rtx x
, int in_struct_p
, int volatile_p
, int unchanging_p
)
2424 switch (GET_CODE (x
))
2430 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
2431 alpha_set_memflags_1 (XVECEXP (x
, 0, i
), in_struct_p
, volatile_p
,
2436 alpha_set_memflags_1 (PATTERN (x
), in_struct_p
, volatile_p
,
2441 alpha_set_memflags_1 (SET_DEST (x
), in_struct_p
, volatile_p
,
2443 alpha_set_memflags_1 (SET_SRC (x
), in_struct_p
, volatile_p
,
2448 MEM_IN_STRUCT_P (x
) = in_struct_p
;
2449 MEM_VOLATILE_P (x
) = volatile_p
;
2450 RTX_UNCHANGING_P (x
) = unchanging_p
;
2451 /* Sadly, we cannot use alias sets because the extra aliasing
2452 produced by the AND interferes. Given that two-byte quantities
2453 are the only thing we would be able to differentiate anyway,
2454 there does not seem to be any point in convoluting the early
2455 out of the alias check. */
2463 /* Given INSN, which is an INSN list or the PATTERN of a single insn
2464 generated to perform a memory operation, look for any MEMs in either
2465 a SET_DEST or a SET_SRC and copy the in-struct, unchanging, and
2466 volatile flags from REF into each of the MEMs found. If REF is not
2467 a MEM, don't do anything. */
2470 alpha_set_memflags (rtx insn
, rtx ref
)
2472 int in_struct_p
, volatile_p
, unchanging_p
;
2474 if (GET_CODE (ref
) != MEM
)
2477 in_struct_p
= MEM_IN_STRUCT_P (ref
);
2478 volatile_p
= MEM_VOLATILE_P (ref
);
2479 unchanging_p
= RTX_UNCHANGING_P (ref
);
2481 /* This is only called from alpha.md, after having had something
2482 generated from one of the insn patterns. So if everything is
2483 zero, the pattern is already up-to-date. */
2484 if (! in_struct_p
&& ! volatile_p
&& ! unchanging_p
)
2487 alpha_set_memflags_1 (insn
, in_struct_p
, volatile_p
, unchanging_p
);
2490 /* Internal routine for alpha_emit_set_const to check for N or below insns. */
2493 alpha_emit_set_const_1 (rtx target
, enum machine_mode mode
,
2494 HOST_WIDE_INT c
, int n
)
2498 /* Use a pseudo if highly optimizing and still generating RTL. */
2500 = (flag_expensive_optimizations
&& !no_new_pseudos
? 0 : target
);
2503 /* If this is a sign-extended 32-bit constant, we can do this in at most
2504 three insns, so do it if we have enough insns left. We always have
2505 a sign-extended 32-bit constant when compiling on a narrow machine. */
2507 if (HOST_BITS_PER_WIDE_INT
!= 64
2508 || c
>> 31 == -1 || c
>> 31 == 0)
2510 HOST_WIDE_INT low
= ((c
& 0xffff) ^ 0x8000) - 0x8000;
2511 HOST_WIDE_INT tmp1
= c
- low
;
2512 HOST_WIDE_INT high
= (((tmp1
>> 16) & 0xffff) ^ 0x8000) - 0x8000;
2513 HOST_WIDE_INT extra
= 0;
2515 /* If HIGH will be interpreted as negative but the constant is
2516 positive, we must adjust it to do two ldha insns. */
2518 if ((high
& 0x8000) != 0 && c
>= 0)
2522 high
= ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
2525 if (c
== low
|| (low
== 0 && extra
== 0))
2527 /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
2528 but that meant that we can't handle INT_MIN on 32-bit machines
2529 (like NT/Alpha), because we recurse indefinitely through
2530 emit_move_insn to gen_movdi. So instead, since we know exactly
2531 what we want, create it explicitly. */
2534 target
= gen_reg_rtx (mode
);
2535 emit_insn (gen_rtx_SET (VOIDmode
, target
, GEN_INT (c
)));
2538 else if (n
>= 2 + (extra
!= 0))
2542 emit_insn (gen_rtx_SET (VOIDmode
, target
, GEN_INT (high
<< 16)));
2546 temp
= copy_to_suggested_reg (GEN_INT (high
<< 16),
2549 /* As of 2002-02-23, addsi3 is only available when not optimizing.
2550 This means that if we go through expand_binop, we'll try to
2551 generate extensions, etc, which will require new pseudos, which
2552 will fail during some split phases. The SImode add patterns
2553 still exist, but are not named. So build the insns by hand. */
2558 subtarget
= gen_reg_rtx (mode
);
2559 insn
= gen_rtx_PLUS (mode
, temp
, GEN_INT (extra
<< 16));
2560 insn
= gen_rtx_SET (VOIDmode
, subtarget
, insn
);
2566 target
= gen_reg_rtx (mode
);
2567 insn
= gen_rtx_PLUS (mode
, temp
, GEN_INT (low
));
2568 insn
= gen_rtx_SET (VOIDmode
, target
, insn
);
2574 /* If we couldn't do it that way, try some other methods. But if we have
2575 no instructions left, don't bother. Likewise, if this is SImode and
2576 we can't make pseudos, we can't do anything since the expand_binop
2577 and expand_unop calls will widen and try to make pseudos. */
2579 if (n
== 1 || (mode
== SImode
&& no_new_pseudos
))
2582 /* Next, see if we can load a related constant and then shift and possibly
2583 negate it to get the constant we want. Try this once each increasing
2584 numbers of insns. */
2586 for (i
= 1; i
< n
; i
++)
2588 /* First, see if minus some low bits, we've an easy load of
2591 new = ((c
& 0xffff) ^ 0x8000) - 0x8000;
2593 && (temp
= alpha_emit_set_const (subtarget
, mode
, c
- new, i
)) != 0)
2594 return expand_binop (mode
, add_optab
, temp
, GEN_INT (new),
2595 target
, 0, OPTAB_WIDEN
);
2597 /* Next try complementing. */
2598 if ((temp
= alpha_emit_set_const (subtarget
, mode
, ~ c
, i
)) != 0)
2599 return expand_unop (mode
, one_cmpl_optab
, temp
, target
, 0);
2601 /* Next try to form a constant and do a left shift. We can do this
2602 if some low-order bits are zero; the exact_log2 call below tells
2603 us that information. The bits we are shifting out could be any
2604 value, but here we'll just try the 0- and sign-extended forms of
2605 the constant. To try to increase the chance of having the same
2606 constant in more than one insn, start at the highest number of
2607 bits to shift, but try all possibilities in case a ZAPNOT will
2610 if ((bits
= exact_log2 (c
& - c
)) > 0)
2611 for (; bits
> 0; bits
--)
2612 if ((temp
= (alpha_emit_set_const
2613 (subtarget
, mode
, c
>> bits
, i
))) != 0
2614 || ((temp
= (alpha_emit_set_const
2616 ((unsigned HOST_WIDE_INT
) c
) >> bits
, i
)))
2618 return expand_binop (mode
, ashl_optab
, temp
, GEN_INT (bits
),
2619 target
, 0, OPTAB_WIDEN
);
2621 /* Now try high-order zero bits. Here we try the shifted-in bits as
2622 all zero and all ones. Be careful to avoid shifting outside the
2623 mode and to avoid shifting outside the host wide int size. */
2624 /* On narrow hosts, don't shift a 1 into the high bit, since we'll
2625 confuse the recursive call and set all of the high 32 bits. */
2627 if ((bits
= (MIN (HOST_BITS_PER_WIDE_INT
, GET_MODE_SIZE (mode
) * 8)
2628 - floor_log2 (c
) - 1 - (HOST_BITS_PER_WIDE_INT
< 64))) > 0)
2629 for (; bits
> 0; bits
--)
2630 if ((temp
= alpha_emit_set_const (subtarget
, mode
,
2632 || ((temp
= (alpha_emit_set_const
2634 ((c
<< bits
) | (((HOST_WIDE_INT
) 1 << bits
) - 1)),
2637 return expand_binop (mode
, lshr_optab
, temp
, GEN_INT (bits
),
2638 target
, 1, OPTAB_WIDEN
);
2640 /* Now try high-order 1 bits. We get that with a sign-extension.
2641 But one bit isn't enough here. Be careful to avoid shifting outside
2642 the mode and to avoid shifting outside the host wide int size. */
2644 if ((bits
= (MIN (HOST_BITS_PER_WIDE_INT
, GET_MODE_SIZE (mode
) * 8)
2645 - floor_log2 (~ c
) - 2)) > 0)
2646 for (; bits
> 0; bits
--)
2647 if ((temp
= alpha_emit_set_const (subtarget
, mode
,
2649 || ((temp
= (alpha_emit_set_const
2651 ((c
<< bits
) | (((HOST_WIDE_INT
) 1 << bits
) - 1)),
2654 return expand_binop (mode
, ashr_optab
, temp
, GEN_INT (bits
),
2655 target
, 0, OPTAB_WIDEN
);
2658 #if HOST_BITS_PER_WIDE_INT == 64
2659 /* Finally, see if can load a value into the target that is the same as the
2660 constant except that all bytes that are 0 are changed to be 0xff. If we
2661 can, then we can do a ZAPNOT to obtain the desired constant. */
2664 for (i
= 0; i
< 64; i
+= 8)
2665 if ((new & ((HOST_WIDE_INT
) 0xff << i
)) == 0)
2666 new |= (HOST_WIDE_INT
) 0xff << i
;
2668 /* We are only called for SImode and DImode. If this is SImode, ensure that
2669 we are sign extended to a full word. */
2672 new = ((new & 0xffffffff) ^ 0x80000000) - 0x80000000;
2674 if (new != c
&& new != -1
2675 && (temp
= alpha_emit_set_const (subtarget
, mode
, new, n
- 1)) != 0)
2676 return expand_binop (mode
, and_optab
, temp
, GEN_INT (c
| ~ new),
2677 target
, 0, OPTAB_WIDEN
);
2683 /* Try to output insns to set TARGET equal to the constant C if it can be
2684 done in less than N insns. Do all computations in MODE. Returns the place
2685 where the output has been placed if it can be done and the insns have been
2686 emitted. If it would take more than N insns, zero is returned and no
2687 insns and emitted. */
2690 alpha_emit_set_const (rtx target
, enum machine_mode mode
,
2691 HOST_WIDE_INT c
, int n
)
2694 rtx orig_target
= target
;
2697 /* If we can't make any pseudos, TARGET is an SImode hard register, we
2698 can't load this constant in one insn, do this in DImode. */
2699 if (no_new_pseudos
&& mode
== SImode
2700 && GET_CODE (target
) == REG
&& REGNO (target
) < FIRST_PSEUDO_REGISTER
2701 && (result
= alpha_emit_set_const_1 (target
, mode
, c
, 1)) == 0)
2703 target
= gen_lowpart (DImode
, target
);
2707 /* Try 1 insn, then 2, then up to N. */
2708 for (i
= 1; i
<= n
; i
++)
2710 result
= alpha_emit_set_const_1 (target
, mode
, c
, i
);
2713 rtx insn
= get_last_insn ();
2714 rtx set
= single_set (insn
);
2715 if (! CONSTANT_P (SET_SRC (set
)))
2716 set_unique_reg_note (get_last_insn (), REG_EQUAL
, GEN_INT (c
));
2721 /* Allow for the case where we changed the mode of TARGET. */
2722 if (result
== target
)
2723 result
= orig_target
;
2728 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
2729 fall back to a straight forward decomposition. We do this to avoid
2730 exponential run times encountered when looking for longer sequences
2731 with alpha_emit_set_const. */
2734 alpha_emit_set_long_const (rtx target
, HOST_WIDE_INT c1
, HOST_WIDE_INT c2
)
2736 HOST_WIDE_INT d1
, d2
, d3
, d4
;
2738 /* Decompose the entire word */
2739 #if HOST_BITS_PER_WIDE_INT >= 64
2740 if (c2
!= -(c1
< 0))
2742 d1
= ((c1
& 0xffff) ^ 0x8000) - 0x8000;
2744 d2
= ((c1
& 0xffffffff) ^ 0x80000000) - 0x80000000;
2745 c1
= (c1
- d2
) >> 32;
2746 d3
= ((c1
& 0xffff) ^ 0x8000) - 0x8000;
2748 d4
= ((c1
& 0xffffffff) ^ 0x80000000) - 0x80000000;
2752 d1
= ((c1
& 0xffff) ^ 0x8000) - 0x8000;
2754 d2
= ((c1
& 0xffffffff) ^ 0x80000000) - 0x80000000;
2758 d3
= ((c2
& 0xffff) ^ 0x8000) - 0x8000;
2760 d4
= ((c2
& 0xffffffff) ^ 0x80000000) - 0x80000000;
2765 /* Construct the high word */
2768 emit_move_insn (target
, GEN_INT (d4
));
2770 emit_move_insn (target
, gen_rtx_PLUS (DImode
, target
, GEN_INT (d3
)));
2773 emit_move_insn (target
, GEN_INT (d3
));
2775 /* Shift it into place */
2776 emit_move_insn (target
, gen_rtx_ASHIFT (DImode
, target
, GEN_INT (32)));
2778 /* Add in the low bits. */
2780 emit_move_insn (target
, gen_rtx_PLUS (DImode
, target
, GEN_INT (d2
)));
2782 emit_move_insn (target
, gen_rtx_PLUS (DImode
, target
, GEN_INT (d1
)));
2787 /* Expand a move instruction; return true if all work is done.
2788 We don't handle non-bwx subword loads here. */
2791 alpha_expand_mov (enum machine_mode mode
, rtx
*operands
)
2793 /* If the output is not a register, the input must be. */
2794 if (GET_CODE (operands
[0]) == MEM
2795 && ! reg_or_0_operand (operands
[1], mode
))
2796 operands
[1] = force_reg (mode
, operands
[1]);
2798 /* Allow legitimize_address to perform some simplifications. */
2799 if (mode
== Pmode
&& symbolic_operand (operands
[1], mode
))
2803 /* With RTL inlining, at -O3, rtl is generated, stored, then actually
2804 compiled at the end of compilation. In the meantime, someone can
2805 re-encode-section-info on some symbol changing it e.g. from global
2806 to local-not-small. If this happens, we'd have emitted a plain
2807 load rather than a high+losum load and not recognize the insn.
2809 So if rtl inlining is in effect, we delay the global/not-global
2810 decision until rest_of_compilation by wrapping it in an
2812 if (TARGET_EXPLICIT_RELOCS
&& flag_inline_functions
2813 && rtx_equal_function_value_matters
2814 && global_symbolic_operand (operands
[1], mode
))
2816 emit_insn (gen_movdi_er_maybe_g (operands
[0], operands
[1]));
2820 tmp
= alpha_legitimize_address (operands
[1], operands
[0], mode
);
2823 if (tmp
== operands
[0])
2830 /* Early out for non-constants and valid constants. */
2831 if (! CONSTANT_P (operands
[1]) || input_operand (operands
[1], mode
))
2834 /* Split large integers. */
2835 if (GET_CODE (operands
[1]) == CONST_INT
2836 || GET_CODE (operands
[1]) == CONST_DOUBLE
)
2838 HOST_WIDE_INT i0
, i1
;
2839 rtx temp
= NULL_RTX
;
2841 if (GET_CODE (operands
[1]) == CONST_INT
)
2843 i0
= INTVAL (operands
[1]);
2846 else if (HOST_BITS_PER_WIDE_INT
>= 64)
2848 i0
= CONST_DOUBLE_LOW (operands
[1]);
2853 i0
= CONST_DOUBLE_LOW (operands
[1]);
2854 i1
= CONST_DOUBLE_HIGH (operands
[1]);
2857 if (HOST_BITS_PER_WIDE_INT
>= 64 || i1
== -(i0
< 0))
2858 temp
= alpha_emit_set_const (operands
[0], mode
, i0
, 3);
2860 if (!temp
&& TARGET_BUILD_CONSTANTS
)
2861 temp
= alpha_emit_set_long_const (operands
[0], i0
, i1
);
2865 if (rtx_equal_p (operands
[0], temp
))
2872 /* Otherwise we've nothing left but to drop the thing to memory. */
2873 operands
[1] = force_const_mem (mode
, operands
[1]);
2874 if (reload_in_progress
)
2876 emit_move_insn (operands
[0], XEXP (operands
[1], 0));
2877 operands
[1] = copy_rtx (operands
[1]);
2878 XEXP (operands
[1], 0) = operands
[0];
2881 operands
[1] = validize_mem (operands
[1]);
2885 /* Expand a non-bwx QImode or HImode move instruction;
2886 return true if all work is done. */
2889 alpha_expand_mov_nobwx (enum machine_mode mode
, rtx
*operands
)
2891 /* If the output is not a register, the input must be. */
2892 if (GET_CODE (operands
[0]) == MEM
)
2893 operands
[1] = force_reg (mode
, operands
[1]);
2895 /* Handle four memory cases, unaligned and aligned for either the input
2896 or the output. The only case where we can be called during reload is
2897 for aligned loads; all other cases require temporaries. */
2899 if (GET_CODE (operands
[1]) == MEM
2900 || (GET_CODE (operands
[1]) == SUBREG
2901 && GET_CODE (SUBREG_REG (operands
[1])) == MEM
)
2902 || (reload_in_progress
&& GET_CODE (operands
[1]) == REG
2903 && REGNO (operands
[1]) >= FIRST_PSEUDO_REGISTER
)
2904 || (reload_in_progress
&& GET_CODE (operands
[1]) == SUBREG
2905 && GET_CODE (SUBREG_REG (operands
[1])) == REG
2906 && REGNO (SUBREG_REG (operands
[1])) >= FIRST_PSEUDO_REGISTER
))
2908 if (aligned_memory_operand (operands
[1], mode
))
2910 if (reload_in_progress
)
2912 emit_insn ((mode
== QImode
2913 ? gen_reload_inqi_help
2914 : gen_reload_inhi_help
)
2915 (operands
[0], operands
[1],
2916 gen_rtx_REG (SImode
, REGNO (operands
[0]))));
2920 rtx aligned_mem
, bitnum
;
2921 rtx scratch
= gen_reg_rtx (SImode
);
2925 get_aligned_mem (operands
[1], &aligned_mem
, &bitnum
);
2927 subtarget
= operands
[0];
2928 if (GET_CODE (subtarget
) == REG
)
2929 subtarget
= gen_lowpart (DImode
, subtarget
), copyout
= false;
2931 subtarget
= gen_reg_rtx (DImode
), copyout
= true;
2933 emit_insn ((mode
== QImode
2934 ? gen_aligned_loadqi
2935 : gen_aligned_loadhi
)
2936 (subtarget
, aligned_mem
, bitnum
, scratch
));
2939 emit_move_insn (operands
[0], gen_lowpart (mode
, subtarget
));
2944 /* Don't pass these as parameters since that makes the generated
2945 code depend on parameter evaluation order which will cause
2946 bootstrap failures. */
2948 rtx temp1
, temp2
, seq
, subtarget
;
2951 temp1
= gen_reg_rtx (DImode
);
2952 temp2
= gen_reg_rtx (DImode
);
2954 subtarget
= operands
[0];
2955 if (GET_CODE (subtarget
) == REG
)
2956 subtarget
= gen_lowpart (DImode
, subtarget
), copyout
= false;
2958 subtarget
= gen_reg_rtx (DImode
), copyout
= true;
2960 seq
= ((mode
== QImode
2961 ? gen_unaligned_loadqi
2962 : gen_unaligned_loadhi
)
2963 (subtarget
, get_unaligned_address (operands
[1], 0),
2965 alpha_set_memflags (seq
, operands
[1]);
2969 emit_move_insn (operands
[0], gen_lowpart (mode
, subtarget
));
2974 if (GET_CODE (operands
[0]) == MEM
2975 || (GET_CODE (operands
[0]) == SUBREG
2976 && GET_CODE (SUBREG_REG (operands
[0])) == MEM
)
2977 || (reload_in_progress
&& GET_CODE (operands
[0]) == REG
2978 && REGNO (operands
[0]) >= FIRST_PSEUDO_REGISTER
)
2979 || (reload_in_progress
&& GET_CODE (operands
[0]) == SUBREG
2980 && GET_CODE (SUBREG_REG (operands
[0])) == REG
2981 && REGNO (operands
[0]) >= FIRST_PSEUDO_REGISTER
))
2983 if (aligned_memory_operand (operands
[0], mode
))
2985 rtx aligned_mem
, bitnum
;
2986 rtx temp1
= gen_reg_rtx (SImode
);
2987 rtx temp2
= gen_reg_rtx (SImode
);
2989 get_aligned_mem (operands
[0], &aligned_mem
, &bitnum
);
2991 emit_insn (gen_aligned_store (aligned_mem
, operands
[1], bitnum
,
2996 rtx temp1
= gen_reg_rtx (DImode
);
2997 rtx temp2
= gen_reg_rtx (DImode
);
2998 rtx temp3
= gen_reg_rtx (DImode
);
2999 rtx seq
= ((mode
== QImode
3000 ? gen_unaligned_storeqi
3001 : gen_unaligned_storehi
)
3002 (get_unaligned_address (operands
[0], 0),
3003 operands
[1], temp1
, temp2
, temp3
));
3005 alpha_set_memflags (seq
, operands
[0]);
3014 /* Generate an unsigned DImode to FP conversion. This is the same code
3015 optabs would emit if we didn't have TFmode patterns.
3017 For SFmode, this is the only construction I've found that can pass
3018 gcc.c-torture/execute/ieee/rbug.c. No scenario that uses DFmode
3019 intermediates will work, because you'll get intermediate rounding
3020 that ruins the end result. Some of this could be fixed by turning
3021 on round-to-positive-infinity, but that requires diddling the fpsr,
3022 which kills performance. I tried turning this around and converting
3023 to a negative number, so that I could turn on /m, but either I did
3024 it wrong or there's something else cause I wound up with the exact
3025 same single-bit error. There is a branch-less form of this same code:
3036 fcmoveq $f10,$f11,$f0
3038 I'm not using it because it's the same number of instructions as
3039 this branch-full form, and it has more serialized long latency
3040 instructions on the critical path.
3042 For DFmode, we can avoid rounding errors by breaking up the word
3043 into two pieces, converting them separately, and adding them back:
3045 LC0: .long 0,0x5f800000
3050 cpyse $f11,$f31,$f10
3051 cpyse $f31,$f11,$f11
3059 This doesn't seem to be a clear-cut win over the optabs form.
3060 It probably all depends on the distribution of numbers being
3061 converted -- in the optabs form, all but high-bit-set has a
3062 much lower minimum execution time. */
3065 alpha_emit_floatuns (rtx operands
[2])
3067 rtx neglab
, donelab
, i0
, i1
, f0
, in
, out
;
3068 enum machine_mode mode
;
3071 in
= force_reg (DImode
, operands
[1]);
3072 mode
= GET_MODE (out
);
3073 neglab
= gen_label_rtx ();
3074 donelab
= gen_label_rtx ();
3075 i0
= gen_reg_rtx (DImode
);
3076 i1
= gen_reg_rtx (DImode
);
3077 f0
= gen_reg_rtx (mode
);
3079 emit_cmp_and_jump_insns (in
, const0_rtx
, LT
, const0_rtx
, DImode
, 0, neglab
);
3081 emit_insn (gen_rtx_SET (VOIDmode
, out
, gen_rtx_FLOAT (mode
, in
)));
3082 emit_jump_insn (gen_jump (donelab
));
3085 emit_label (neglab
);
3087 emit_insn (gen_lshrdi3 (i0
, in
, const1_rtx
));
3088 emit_insn (gen_anddi3 (i1
, in
, const1_rtx
));
3089 emit_insn (gen_iordi3 (i0
, i0
, i1
));
3090 emit_insn (gen_rtx_SET (VOIDmode
, f0
, gen_rtx_FLOAT (mode
, i0
)));
3091 emit_insn (gen_rtx_SET (VOIDmode
, out
, gen_rtx_PLUS (mode
, f0
, f0
)));
3093 emit_label (donelab
);
3096 /* Generate the comparison for a conditional branch. */
3099 alpha_emit_conditional_branch (enum rtx_code code
)
3101 enum rtx_code cmp_code
, branch_code
;
3102 enum machine_mode cmp_mode
, branch_mode
= VOIDmode
;
3103 rtx op0
= alpha_compare
.op0
, op1
= alpha_compare
.op1
;
3106 if (alpha_compare
.fp_p
&& GET_MODE (op0
) == TFmode
)
3108 if (! TARGET_HAS_XFLOATING_LIBS
)
3111 /* X_floating library comparison functions return
3115 Convert the compare against the raw return value. */
3137 op0
= alpha_emit_xfloating_compare (cmp_code
, op0
, op1
);
3139 alpha_compare
.fp_p
= 0;
3142 /* The general case: fold the comparison code to the types of compares
3143 that we have, choosing the branch as necessary. */
3146 case EQ
: case LE
: case LT
: case LEU
: case LTU
:
3148 /* We have these compares: */
3149 cmp_code
= code
, branch_code
= NE
;
3154 /* These must be reversed. */
3155 cmp_code
= reverse_condition (code
), branch_code
= EQ
;
3158 case GE
: case GT
: case GEU
: case GTU
:
3159 /* For FP, we swap them, for INT, we reverse them. */
3160 if (alpha_compare
.fp_p
)
3162 cmp_code
= swap_condition (code
);
3164 tem
= op0
, op0
= op1
, op1
= tem
;
3168 cmp_code
= reverse_condition (code
);
3177 if (alpha_compare
.fp_p
)
3180 if (flag_unsafe_math_optimizations
)
3182 /* When we are not as concerned about non-finite values, and we
3183 are comparing against zero, we can branch directly. */
3184 if (op1
== CONST0_RTX (DFmode
))
3185 cmp_code
= NIL
, branch_code
= code
;
3186 else if (op0
== CONST0_RTX (DFmode
))
3188 /* Undo the swap we probably did just above. */
3189 tem
= op0
, op0
= op1
, op1
= tem
;
3190 branch_code
= swap_condition (cmp_code
);
3196 /* ??? We mark the branch mode to be CCmode to prevent the
3197 compare and branch from being combined, since the compare
3198 insn follows IEEE rules that the branch does not. */
3199 branch_mode
= CCmode
;
3206 /* The following optimizations are only for signed compares. */
3207 if (code
!= LEU
&& code
!= LTU
&& code
!= GEU
&& code
!= GTU
)
3209 /* Whee. Compare and branch against 0 directly. */
3210 if (op1
== const0_rtx
)
3211 cmp_code
= NIL
, branch_code
= code
;
3213 /* If the constants doesn't fit into an immediate, but can
3214 be generated by lda/ldah, we adjust the argument and
3215 compare against zero, so we can use beq/bne directly. */
3216 /* ??? Don't do this when comparing against symbols, otherwise
3217 we'll reduce (&x == 0x1234) to (&x-0x1234 == 0), which will
3218 be declared false out of hand (at least for non-weak). */
3219 else if (GET_CODE (op1
) == CONST_INT
3220 && (code
== EQ
|| code
== NE
)
3221 && !(symbolic_operand (op0
, VOIDmode
)
3222 || (GET_CODE (op0
) == REG
&& REG_POINTER (op0
))))
3224 HOST_WIDE_INT v
= INTVAL (op1
), n
= -v
;
3226 if (! CONST_OK_FOR_LETTER_P (v
, 'I')
3227 && (CONST_OK_FOR_LETTER_P (n
, 'K')
3228 || CONST_OK_FOR_LETTER_P (n
, 'L')))
3230 cmp_code
= PLUS
, branch_code
= code
;
3236 if (!reg_or_0_operand (op0
, DImode
))
3237 op0
= force_reg (DImode
, op0
);
3238 if (cmp_code
!= PLUS
&& !reg_or_8bit_operand (op1
, DImode
))
3239 op1
= force_reg (DImode
, op1
);
3242 /* Emit an initial compare instruction, if necessary. */
3244 if (cmp_code
!= NIL
)
3246 tem
= gen_reg_rtx (cmp_mode
);
3247 emit_move_insn (tem
, gen_rtx_fmt_ee (cmp_code
, cmp_mode
, op0
, op1
));
3250 /* Zero the operands. */
3251 memset (&alpha_compare
, 0, sizeof (alpha_compare
));
3253 /* Return the branch comparison. */
3254 return gen_rtx_fmt_ee (branch_code
, branch_mode
, tem
, CONST0_RTX (cmp_mode
));
3257 /* Certain simplifications can be done to make invalid setcc operations
3258 valid. Return the final comparison, or NULL if we can't work. */
3261 alpha_emit_setcc (enum rtx_code code
)
3263 enum rtx_code cmp_code
;
3264 rtx op0
= alpha_compare
.op0
, op1
= alpha_compare
.op1
;
3265 int fp_p
= alpha_compare
.fp_p
;
3268 /* Zero the operands. */
3269 memset (&alpha_compare
, 0, sizeof (alpha_compare
));
3271 if (fp_p
&& GET_MODE (op0
) == TFmode
)
3273 if (! TARGET_HAS_XFLOATING_LIBS
)
3276 /* X_floating library comparison functions return
3280 Convert the compare against the raw return value. */
3282 if (code
== UNORDERED
|| code
== ORDERED
)
3287 op0
= alpha_emit_xfloating_compare (cmp_code
, op0
, op1
);
3291 if (code
== UNORDERED
)
3293 else if (code
== ORDERED
)
3299 if (fp_p
&& !TARGET_FIX
)
3302 /* The general case: fold the comparison code to the types of compares
3303 that we have, choosing the branch as necessary. */
3308 case EQ
: case LE
: case LT
: case LEU
: case LTU
:
3310 /* We have these compares. */
3312 cmp_code
= code
, code
= NE
;
3316 if (!fp_p
&& op1
== const0_rtx
)
3321 cmp_code
= reverse_condition (code
);
3325 case GE
: case GT
: case GEU
: case GTU
:
3326 /* These normally need swapping, but for integer zero we have
3327 special patterns that recognize swapped operands. */
3328 if (!fp_p
&& op1
== const0_rtx
)
3330 code
= swap_condition (code
);
3332 cmp_code
= code
, code
= NE
;
3333 tmp
= op0
, op0
= op1
, op1
= tmp
;
3342 if (!register_operand (op0
, DImode
))
3343 op0
= force_reg (DImode
, op0
);
3344 if (!reg_or_8bit_operand (op1
, DImode
))
3345 op1
= force_reg (DImode
, op1
);
3348 /* Emit an initial compare instruction, if necessary. */
3349 if (cmp_code
!= NIL
)
3351 enum machine_mode mode
= fp_p
? DFmode
: DImode
;
3353 tmp
= gen_reg_rtx (mode
);
3354 emit_insn (gen_rtx_SET (VOIDmode
, tmp
,
3355 gen_rtx_fmt_ee (cmp_code
, mode
, op0
, op1
)));
3357 op0
= fp_p
? gen_lowpart (DImode
, tmp
) : tmp
;
3361 /* Return the setcc comparison. */
3362 return gen_rtx_fmt_ee (code
, DImode
, op0
, op1
);
3366 /* Rewrite a comparison against zero CMP of the form
3367 (CODE (cc0) (const_int 0)) so it can be written validly in
3368 a conditional move (if_then_else CMP ...).
3369 If both of the operands that set cc0 are nonzero we must emit
3370 an insn to perform the compare (it can't be done within
3371 the conditional move). */
3374 alpha_emit_conditional_move (rtx cmp
, enum machine_mode mode
)
3376 enum rtx_code code
= GET_CODE (cmp
);
3377 enum rtx_code cmov_code
= NE
;
3378 rtx op0
= alpha_compare
.op0
;
3379 rtx op1
= alpha_compare
.op1
;
3380 int fp_p
= alpha_compare
.fp_p
;
3381 enum machine_mode cmp_mode
3382 = (GET_MODE (op0
) == VOIDmode
? DImode
: GET_MODE (op0
));
3383 enum machine_mode cmp_op_mode
= fp_p
? DFmode
: DImode
;
3384 enum machine_mode cmov_mode
= VOIDmode
;
3385 int local_fast_math
= flag_unsafe_math_optimizations
;
3388 /* Zero the operands. */
3389 memset (&alpha_compare
, 0, sizeof (alpha_compare
));
3391 if (fp_p
!= FLOAT_MODE_P (mode
))
3393 enum rtx_code cmp_code
;
3398 /* If we have fp<->int register move instructions, do a cmov by
3399 performing the comparison in fp registers, and move the
3400 zero/nonzero value to integer registers, where we can then
3401 use a normal cmov, or vice-versa. */
3405 case EQ
: case LE
: case LT
: case LEU
: case LTU
:
3406 /* We have these compares. */
3407 cmp_code
= code
, code
= NE
;
3411 /* This must be reversed. */
3412 cmp_code
= EQ
, code
= EQ
;
3415 case GE
: case GT
: case GEU
: case GTU
:
3416 /* These normally need swapping, but for integer zero we have
3417 special patterns that recognize swapped operands. */
3418 if (!fp_p
&& op1
== const0_rtx
)
3419 cmp_code
= code
, code
= NE
;
3422 cmp_code
= swap_condition (code
);
3424 tem
= op0
, op0
= op1
, op1
= tem
;
3432 tem
= gen_reg_rtx (cmp_op_mode
);
3433 emit_insn (gen_rtx_SET (VOIDmode
, tem
,
3434 gen_rtx_fmt_ee (cmp_code
, cmp_op_mode
,
3437 cmp_mode
= cmp_op_mode
= fp_p
? DImode
: DFmode
;
3438 op0
= gen_lowpart (cmp_op_mode
, tem
);
3439 op1
= CONST0_RTX (cmp_op_mode
);
3441 local_fast_math
= 1;
3444 /* We may be able to use a conditional move directly.
3445 This avoids emitting spurious compares. */
3446 if (signed_comparison_operator (cmp
, VOIDmode
)
3447 && (!fp_p
|| local_fast_math
)
3448 && (op0
== CONST0_RTX (cmp_mode
) || op1
== CONST0_RTX (cmp_mode
)))
3449 return gen_rtx_fmt_ee (code
, VOIDmode
, op0
, op1
);
3451 /* We can't put the comparison inside the conditional move;
3452 emit a compare instruction and put that inside the
3453 conditional move. Make sure we emit only comparisons we have;
3454 swap or reverse as necessary. */
3461 case EQ
: case LE
: case LT
: case LEU
: case LTU
:
3462 /* We have these compares: */
3466 /* This must be reversed. */
3467 code
= reverse_condition (code
);
3471 case GE
: case GT
: case GEU
: case GTU
:
3472 /* These must be swapped. */
3473 if (op1
!= CONST0_RTX (cmp_mode
))
3475 code
= swap_condition (code
);
3476 tem
= op0
, op0
= op1
, op1
= tem
;
3486 if (!reg_or_0_operand (op0
, DImode
))
3487 op0
= force_reg (DImode
, op0
);
3488 if (!reg_or_8bit_operand (op1
, DImode
))
3489 op1
= force_reg (DImode
, op1
);
3492 /* ??? We mark the branch mode to be CCmode to prevent the compare
3493 and cmov from being combined, since the compare insn follows IEEE
3494 rules that the cmov does not. */
3495 if (fp_p
&& !local_fast_math
)
3498 tem
= gen_reg_rtx (cmp_op_mode
);
3499 emit_move_insn (tem
, gen_rtx_fmt_ee (code
, cmp_op_mode
, op0
, op1
));
3500 return gen_rtx_fmt_ee (cmov_code
, cmov_mode
, tem
, CONST0_RTX (cmp_op_mode
));
3503 /* Simplify a conditional move of two constants into a setcc with
3504 arithmetic. This is done with a splitter since combine would
3505 just undo the work if done during code generation. It also catches
3506 cases we wouldn't have before cse. */
3509 alpha_split_conditional_move (enum rtx_code code
, rtx dest
, rtx cond
,
3510 rtx t_rtx
, rtx f_rtx
)
3512 HOST_WIDE_INT t
, f
, diff
;
3513 enum machine_mode mode
;
3514 rtx target
, subtarget
, tmp
;
3516 mode
= GET_MODE (dest
);
3521 if (((code
== NE
|| code
== EQ
) && diff
< 0)
3522 || (code
== GE
|| code
== GT
))
3524 code
= reverse_condition (code
);
3525 diff
= t
, t
= f
, f
= diff
;
3529 subtarget
= target
= dest
;
3532 target
= gen_lowpart (DImode
, dest
);
3533 if (! no_new_pseudos
)
3534 subtarget
= gen_reg_rtx (DImode
);
3538 /* Below, we must be careful to use copy_rtx on target and subtarget
3539 in intermediate insns, as they may be a subreg rtx, which may not
3542 if (f
== 0 && exact_log2 (diff
) > 0
3543 /* On EV6, we've got enough shifters to make non-arithmetic shifts
3544 viable over a longer latency cmove. On EV5, the E0 slot is a
3545 scarce resource, and on EV4 shift has the same latency as a cmove. */
3546 && (diff
<= 8 || alpha_cpu
== PROCESSOR_EV6
))
3548 tmp
= gen_rtx_fmt_ee (code
, DImode
, cond
, const0_rtx
);
3549 emit_insn (gen_rtx_SET (VOIDmode
, copy_rtx (subtarget
), tmp
));
3551 tmp
= gen_rtx_ASHIFT (DImode
, copy_rtx (subtarget
),
3552 GEN_INT (exact_log2 (t
)));
3553 emit_insn (gen_rtx_SET (VOIDmode
, target
, tmp
));
3555 else if (f
== 0 && t
== -1)
3557 tmp
= gen_rtx_fmt_ee (code
, DImode
, cond
, const0_rtx
);
3558 emit_insn (gen_rtx_SET (VOIDmode
, copy_rtx (subtarget
), tmp
));
3560 emit_insn (gen_negdi2 (target
, copy_rtx (subtarget
)));
3562 else if (diff
== 1 || diff
== 4 || diff
== 8)
3566 tmp
= gen_rtx_fmt_ee (code
, DImode
, cond
, const0_rtx
);
3567 emit_insn (gen_rtx_SET (VOIDmode
, copy_rtx (subtarget
), tmp
));
3570 emit_insn (gen_adddi3 (target
, copy_rtx (subtarget
), GEN_INT (f
)));
3573 add_op
= GEN_INT (f
);
3574 if (sext_add_operand (add_op
, mode
))
3576 tmp
= gen_rtx_MULT (DImode
, copy_rtx (subtarget
),
3578 tmp
= gen_rtx_PLUS (DImode
, tmp
, add_op
);
3579 emit_insn (gen_rtx_SET (VOIDmode
, target
, tmp
));
3591 /* Look up the function X_floating library function name for the
3594 struct xfloating_op
GTY(())
3596 const enum rtx_code code
;
3597 const char *const GTY((skip
)) osf_func
;
3598 const char *const GTY((skip
)) vms_func
;
3602 static GTY(()) struct xfloating_op xfloating_ops
[] =
3604 { PLUS
, "_OtsAddX", "OTS$ADD_X", 0 },
3605 { MINUS
, "_OtsSubX", "OTS$SUB_X", 0 },
3606 { MULT
, "_OtsMulX", "OTS$MUL_X", 0 },
3607 { DIV
, "_OtsDivX", "OTS$DIV_X", 0 },
3608 { EQ
, "_OtsEqlX", "OTS$EQL_X", 0 },
3609 { NE
, "_OtsNeqX", "OTS$NEQ_X", 0 },
3610 { LT
, "_OtsLssX", "OTS$LSS_X", 0 },
3611 { LE
, "_OtsLeqX", "OTS$LEQ_X", 0 },
3612 { GT
, "_OtsGtrX", "OTS$GTR_X", 0 },
3613 { GE
, "_OtsGeqX", "OTS$GEQ_X", 0 },
3614 { FIX
, "_OtsCvtXQ", "OTS$CVTXQ", 0 },
3615 { FLOAT
, "_OtsCvtQX", "OTS$CVTQX", 0 },
3616 { UNSIGNED_FLOAT
, "_OtsCvtQUX", "OTS$CVTQUX", 0 },
3617 { FLOAT_EXTEND
, "_OtsConvertFloatTX", "OTS$CVT_FLOAT_T_X", 0 },
3618 { FLOAT_TRUNCATE
, "_OtsConvertFloatXT", "OTS$CVT_FLOAT_X_T", 0 }
3621 static GTY(()) struct xfloating_op vax_cvt_ops
[] =
3623 { FLOAT_EXTEND
, "_OtsConvertFloatGX", "OTS$CVT_FLOAT_G_X", 0 },
3624 { FLOAT_TRUNCATE
, "_OtsConvertFloatXG", "OTS$CVT_FLOAT_X_G", 0 }
3628 alpha_lookup_xfloating_lib_func (enum rtx_code code
)
3630 struct xfloating_op
*ops
= xfloating_ops
;
3631 long n
= ARRAY_SIZE (xfloating_ops
);
3634 /* How irritating. Nothing to key off for the main table. */
3635 if (TARGET_FLOAT_VAX
&& (code
== FLOAT_EXTEND
|| code
== FLOAT_TRUNCATE
))
3638 n
= ARRAY_SIZE (vax_cvt_ops
);
3641 for (i
= 0; i
< n
; ++i
, ++ops
)
3642 if (ops
->code
== code
)
3644 rtx func
= ops
->libcall
;
3647 func
= init_one_libfunc (TARGET_ABI_OPEN_VMS
3648 ? ops
->vms_func
: ops
->osf_func
);
3649 ops
->libcall
= func
;
3657 /* Most X_floating operations take the rounding mode as an argument.
3658 Compute that here. */
3661 alpha_compute_xfloating_mode_arg (enum rtx_code code
,
3662 enum alpha_fp_rounding_mode round
)
3668 case ALPHA_FPRM_NORM
:
3671 case ALPHA_FPRM_MINF
:
3674 case ALPHA_FPRM_CHOP
:
3677 case ALPHA_FPRM_DYN
:
3683 /* XXX For reference, round to +inf is mode = 3. */
3686 if (code
== FLOAT_TRUNCATE
&& alpha_fptm
== ALPHA_FPTM_N
)
3692 /* Emit an X_floating library function call.
3694 Note that these functions do not follow normal calling conventions:
3695 TFmode arguments are passed in two integer registers (as opposed to
3696 indirect); TFmode return values appear in R16+R17.
3698 FUNC is the function to call.
3699 TARGET is where the output belongs.
3700 OPERANDS are the inputs.
3701 NOPERANDS is the count of inputs.
3702 EQUIV is the expression equivalent for the function.
3706 alpha_emit_xfloating_libcall (rtx func
, rtx target
, rtx operands
[],
3707 int noperands
, rtx equiv
)
3709 rtx usage
= NULL_RTX
, tmp
, reg
;
3714 for (i
= 0; i
< noperands
; ++i
)
3716 switch (GET_MODE (operands
[i
]))
3719 reg
= gen_rtx_REG (TFmode
, regno
);
3724 reg
= gen_rtx_REG (DFmode
, regno
+ 32);
3729 if (GET_CODE (operands
[i
]) != CONST_INT
)
3733 reg
= gen_rtx_REG (DImode
, regno
);
3741 emit_move_insn (reg
, operands
[i
]);
3742 usage
= alloc_EXPR_LIST (0, gen_rtx_USE (VOIDmode
, reg
), usage
);
3745 switch (GET_MODE (target
))
3748 reg
= gen_rtx_REG (TFmode
, 16);
3751 reg
= gen_rtx_REG (DFmode
, 32);
3754 reg
= gen_rtx_REG (DImode
, 0);
3760 tmp
= gen_rtx_MEM (QImode
, func
);
3761 tmp
= emit_call_insn (GEN_CALL_VALUE (reg
, tmp
, const0_rtx
,
3762 const0_rtx
, const0_rtx
));
3763 CALL_INSN_FUNCTION_USAGE (tmp
) = usage
;
3764 CONST_OR_PURE_CALL_P (tmp
) = 1;
3769 emit_libcall_block (tmp
, target
, reg
, equiv
);
3772 /* Emit an X_floating library function call for arithmetic (+,-,*,/). */
3775 alpha_emit_xfloating_arith (enum rtx_code code
, rtx operands
[])
3779 rtx out_operands
[3];
3781 func
= alpha_lookup_xfloating_lib_func (code
);
3782 mode
= alpha_compute_xfloating_mode_arg (code
, alpha_fprm
);
3784 out_operands
[0] = operands
[1];
3785 out_operands
[1] = operands
[2];
3786 out_operands
[2] = GEN_INT (mode
);
3787 alpha_emit_xfloating_libcall (func
, operands
[0], out_operands
, 3,
3788 gen_rtx_fmt_ee (code
, TFmode
, operands
[1],
3792 /* Emit an X_floating library function call for a comparison. */
3795 alpha_emit_xfloating_compare (enum rtx_code code
, rtx op0
, rtx op1
)
3798 rtx out
, operands
[2];
3800 func
= alpha_lookup_xfloating_lib_func (code
);
3804 out
= gen_reg_rtx (DImode
);
3806 /* ??? Strange mode for equiv because what's actually returned
3807 is -1,0,1, not a proper boolean value. */
3808 alpha_emit_xfloating_libcall (func
, out
, operands
, 2,
3809 gen_rtx_fmt_ee (code
, CCmode
, op0
, op1
));
3814 /* Emit an X_floating library function call for a conversion. */
3817 alpha_emit_xfloating_cvt (enum rtx_code orig_code
, rtx operands
[])
3819 int noperands
= 1, mode
;
3820 rtx out_operands
[2];
3822 enum rtx_code code
= orig_code
;
3824 if (code
== UNSIGNED_FIX
)
3827 func
= alpha_lookup_xfloating_lib_func (code
);
3829 out_operands
[0] = operands
[1];
3834 mode
= alpha_compute_xfloating_mode_arg (code
, ALPHA_FPRM_CHOP
);
3835 out_operands
[1] = GEN_INT (mode
);
3838 case FLOAT_TRUNCATE
:
3839 mode
= alpha_compute_xfloating_mode_arg (code
, alpha_fprm
);
3840 out_operands
[1] = GEN_INT (mode
);
3847 alpha_emit_xfloating_libcall (func
, operands
[0], out_operands
, noperands
,
3848 gen_rtx_fmt_e (orig_code
,
3849 GET_MODE (operands
[0]),
3853 /* Split a TFmode OP[1] into DImode OP[2,3] and likewise for
3854 OP[0] into OP[0,1]. Naturally, output operand ordering is
3858 alpha_split_tfmode_pair (rtx operands
[4])
3860 if (GET_CODE (operands
[1]) == REG
)
3862 operands
[3] = gen_rtx_REG (DImode
, REGNO (operands
[1]) + 1);
3863 operands
[2] = gen_rtx_REG (DImode
, REGNO (operands
[1]));
3865 else if (GET_CODE (operands
[1]) == MEM
)
3867 operands
[3] = adjust_address (operands
[1], DImode
, 8);
3868 operands
[2] = adjust_address (operands
[1], DImode
, 0);
3870 else if (operands
[1] == CONST0_RTX (TFmode
))
3871 operands
[2] = operands
[3] = const0_rtx
;
3875 if (GET_CODE (operands
[0]) == REG
)
3877 operands
[1] = gen_rtx_REG (DImode
, REGNO (operands
[0]) + 1);
3878 operands
[0] = gen_rtx_REG (DImode
, REGNO (operands
[0]));
3880 else if (GET_CODE (operands
[0]) == MEM
)
3882 operands
[1] = adjust_address (operands
[0], DImode
, 8);
3883 operands
[0] = adjust_address (operands
[0], DImode
, 0);
3889 /* Implement negtf2 or abstf2. Op0 is destination, op1 is source,
3890 op2 is a register containing the sign bit, operation is the
3891 logical operation to be performed. */
3894 alpha_split_tfmode_frobsign (rtx operands
[3], rtx (*operation
) (rtx
, rtx
, rtx
))
3896 rtx high_bit
= operands
[2];
3900 alpha_split_tfmode_pair (operands
);
3902 /* Detect three flavors of operand overlap. */
3904 if (rtx_equal_p (operands
[0], operands
[2]))
3906 else if (rtx_equal_p (operands
[1], operands
[2]))
3908 if (rtx_equal_p (operands
[0], high_bit
))
3915 emit_move_insn (operands
[0], operands
[2]);
3917 /* ??? If the destination overlaps both source tf and high_bit, then
3918 assume source tf is dead in its entirety and use the other half
3919 for a scratch register. Otherwise "scratch" is just the proper
3920 destination register. */
3921 scratch
= operands
[move
< 2 ? 1 : 3];
3923 emit_insn ((*operation
) (scratch
, high_bit
, operands
[3]));
3927 emit_move_insn (operands
[0], operands
[2]);
3929 emit_move_insn (operands
[1], scratch
);
3933 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
3937 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
3938 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
3939 lda r3,X(r11) lda r3,X+2(r11)
3940 extwl r1,r3,r1 extql r1,r3,r1
3941 extwh r2,r3,r2 extqh r2,r3,r2
3942 or r1.r2.r1 or r1,r2,r1
3945 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
3946 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
3947 lda r3,X(r11) lda r3,X(r11)
3948 extll r1,r3,r1 extll r1,r3,r1
3949 extlh r2,r3,r2 extlh r2,r3,r2
3950 or r1.r2.r1 addl r1,r2,r1
3952 quad: ldq_u r1,X(r11)
3961 alpha_expand_unaligned_load (rtx tgt
, rtx mem
, HOST_WIDE_INT size
,
3962 HOST_WIDE_INT ofs
, int sign
)
3964 rtx meml
, memh
, addr
, extl
, exth
, tmp
, mema
;
3965 enum machine_mode mode
;
3967 meml
= gen_reg_rtx (DImode
);
3968 memh
= gen_reg_rtx (DImode
);
3969 addr
= gen_reg_rtx (DImode
);
3970 extl
= gen_reg_rtx (DImode
);
3971 exth
= gen_reg_rtx (DImode
);
3973 mema
= XEXP (mem
, 0);
3974 if (GET_CODE (mema
) == LO_SUM
)
3975 mema
= force_reg (Pmode
, mema
);
3977 /* AND addresses cannot be in any alias set, since they may implicitly
3978 alias surrounding code. Ideally we'd have some alias set that
3979 covered all types except those with alignment 8 or higher. */
3981 tmp
= change_address (mem
, DImode
,
3982 gen_rtx_AND (DImode
,
3983 plus_constant (mema
, ofs
),
3985 set_mem_alias_set (tmp
, 0);
3986 emit_move_insn (meml
, tmp
);
3988 tmp
= change_address (mem
, DImode
,
3989 gen_rtx_AND (DImode
,
3990 plus_constant (mema
, ofs
+ size
- 1),
3992 set_mem_alias_set (tmp
, 0);
3993 emit_move_insn (memh
, tmp
);
3995 if (WORDS_BIG_ENDIAN
&& sign
&& (size
== 2 || size
== 4))
3997 emit_move_insn (addr
, plus_constant (mema
, -1));
3999 emit_insn (gen_extqh_be (extl
, meml
, addr
));
4000 emit_insn (gen_extxl_be (exth
, memh
, GEN_INT (64), addr
));
4002 addr
= expand_binop (DImode
, ior_optab
, extl
, exth
, tgt
, 1, OPTAB_WIDEN
);
4003 addr
= expand_binop (DImode
, ashr_optab
, addr
, GEN_INT (64 - size
*8),
4004 addr
, 1, OPTAB_WIDEN
);
4006 else if (sign
&& size
== 2)
4008 emit_move_insn (addr
, plus_constant (mema
, ofs
+2));
4010 emit_insn (gen_extxl_le (extl
, meml
, GEN_INT (64), addr
));
4011 emit_insn (gen_extqh_le (exth
, memh
, addr
));
4013 /* We must use tgt here for the target. Alpha-vms port fails if we use
4014 addr for the target, because addr is marked as a pointer and combine
4015 knows that pointers are always sign-extended 32 bit values. */
4016 addr
= expand_binop (DImode
, ior_optab
, extl
, exth
, tgt
, 1, OPTAB_WIDEN
);
4017 addr
= expand_binop (DImode
, ashr_optab
, addr
, GEN_INT (48),
4018 addr
, 1, OPTAB_WIDEN
);
4022 if (WORDS_BIG_ENDIAN
)
4024 emit_move_insn (addr
, plus_constant (mema
, ofs
+size
-1));
4028 emit_insn (gen_extwh_be (extl
, meml
, addr
));
4033 emit_insn (gen_extlh_be (extl
, meml
, addr
));
4038 emit_insn (gen_extqh_be (extl
, meml
, addr
));
4045 emit_insn (gen_extxl_be (exth
, memh
, GEN_INT (size
*8), addr
));
4049 emit_move_insn (addr
, plus_constant (mema
, ofs
));
4050 emit_insn (gen_extxl_le (extl
, meml
, GEN_INT (size
*8), addr
));
4054 emit_insn (gen_extwh_le (exth
, memh
, addr
));
4059 emit_insn (gen_extlh_le (exth
, memh
, addr
));
4064 emit_insn (gen_extqh_le (exth
, memh
, addr
));
4073 addr
= expand_binop (mode
, ior_optab
, gen_lowpart (mode
, extl
),
4074 gen_lowpart (mode
, exth
), gen_lowpart (mode
, tgt
),
4079 emit_move_insn (tgt
, gen_lowpart(GET_MODE (tgt
), addr
));
4082 /* Similarly, use ins and msk instructions to perform unaligned stores. */
4085 alpha_expand_unaligned_store (rtx dst
, rtx src
,
4086 HOST_WIDE_INT size
, HOST_WIDE_INT ofs
)
4088 rtx dstl
, dsth
, addr
, insl
, insh
, meml
, memh
, dsta
;
4090 dstl
= gen_reg_rtx (DImode
);
4091 dsth
= gen_reg_rtx (DImode
);
4092 insl
= gen_reg_rtx (DImode
);
4093 insh
= gen_reg_rtx (DImode
);
4095 dsta
= XEXP (dst
, 0);
4096 if (GET_CODE (dsta
) == LO_SUM
)
4097 dsta
= force_reg (Pmode
, dsta
);
4099 /* AND addresses cannot be in any alias set, since they may implicitly
4100 alias surrounding code. Ideally we'd have some alias set that
4101 covered all types except those with alignment 8 or higher. */
4103 meml
= change_address (dst
, DImode
,
4104 gen_rtx_AND (DImode
,
4105 plus_constant (dsta
, ofs
),
4107 set_mem_alias_set (meml
, 0);
4109 memh
= change_address (dst
, DImode
,
4110 gen_rtx_AND (DImode
,
4111 plus_constant (dsta
, ofs
+ size
- 1),
4113 set_mem_alias_set (memh
, 0);
4115 emit_move_insn (dsth
, memh
);
4116 emit_move_insn (dstl
, meml
);
4117 if (WORDS_BIG_ENDIAN
)
4119 addr
= copy_addr_to_reg (plus_constant (dsta
, ofs
+size
-1));
4121 if (src
!= const0_rtx
)
4126 emit_insn (gen_inswl_be (insh
, gen_lowpart (HImode
,src
), addr
));
4129 emit_insn (gen_insll_be (insh
, gen_lowpart (SImode
,src
), addr
));
4132 emit_insn (gen_insql_be (insh
, gen_lowpart (DImode
,src
), addr
));
4135 emit_insn (gen_insxh (insl
, gen_lowpart (DImode
, src
),
4136 GEN_INT (size
*8), addr
));
4142 emit_insn (gen_mskxl_be (dsth
, dsth
, GEN_INT (0xffff), addr
));
4146 rtx msk
= immed_double_const (0xffffffff, 0, DImode
);
4147 emit_insn (gen_mskxl_be (dsth
, dsth
, msk
, addr
));
4151 emit_insn (gen_mskxl_be (dsth
, dsth
, constm1_rtx
, addr
));
4155 emit_insn (gen_mskxh (dstl
, dstl
, GEN_INT (size
*8), addr
));
4159 addr
= copy_addr_to_reg (plus_constant (dsta
, ofs
));
4161 if (src
!= const0_rtx
)
4163 emit_insn (gen_insxh (insh
, gen_lowpart (DImode
, src
),
4164 GEN_INT (size
*8), addr
));
4169 emit_insn (gen_inswl_le (insl
, gen_lowpart (HImode
, src
), addr
));
4172 emit_insn (gen_insll_le (insl
, gen_lowpart (SImode
, src
), addr
));
4175 emit_insn (gen_insql_le (insl
, src
, addr
));
4180 emit_insn (gen_mskxh (dsth
, dsth
, GEN_INT (size
*8), addr
));
4185 emit_insn (gen_mskxl_le (dstl
, dstl
, GEN_INT (0xffff), addr
));
4189 rtx msk
= immed_double_const (0xffffffff, 0, DImode
);
4190 emit_insn (gen_mskxl_le (dstl
, dstl
, msk
, addr
));
4194 emit_insn (gen_mskxl_le (dstl
, dstl
, constm1_rtx
, addr
));
4199 if (src
!= const0_rtx
)
4201 dsth
= expand_binop (DImode
, ior_optab
, insh
, dsth
, dsth
, 0, OPTAB_WIDEN
);
4202 dstl
= expand_binop (DImode
, ior_optab
, insl
, dstl
, dstl
, 0, OPTAB_WIDEN
);
4205 if (WORDS_BIG_ENDIAN
)
4207 emit_move_insn (meml
, dstl
);
4208 emit_move_insn (memh
, dsth
);
4212 /* Must store high before low for degenerate case of aligned. */
4213 emit_move_insn (memh
, dsth
);
4214 emit_move_insn (meml
, dstl
);
4218 /* The block move code tries to maximize speed by separating loads and
4219 stores at the expense of register pressure: we load all of the data
4220 before we store it back out. There are two secondary effects worth
4221 mentioning, that this speeds copying to/from aligned and unaligned
4222 buffers, and that it makes the code significantly easier to write. */
4224 #define MAX_MOVE_WORDS 8
4226 /* Load an integral number of consecutive unaligned quadwords. */
4229 alpha_expand_unaligned_load_words (rtx
*out_regs
, rtx smem
,
4230 HOST_WIDE_INT words
, HOST_WIDE_INT ofs
)
4232 rtx
const im8
= GEN_INT (-8);
4233 rtx
const i64
= GEN_INT (64);
4234 rtx ext_tmps
[MAX_MOVE_WORDS
], data_regs
[MAX_MOVE_WORDS
+1];
4235 rtx sreg
, areg
, tmp
, smema
;
4238 smema
= XEXP (smem
, 0);
4239 if (GET_CODE (smema
) == LO_SUM
)
4240 smema
= force_reg (Pmode
, smema
);
4242 /* Generate all the tmp registers we need. */
4243 for (i
= 0; i
< words
; ++i
)
4245 data_regs
[i
] = out_regs
[i
];
4246 ext_tmps
[i
] = gen_reg_rtx (DImode
);
4248 data_regs
[words
] = gen_reg_rtx (DImode
);
4251 smem
= adjust_address (smem
, GET_MODE (smem
), ofs
);
4253 /* Load up all of the source data. */
4254 for (i
= 0; i
< words
; ++i
)
4256 tmp
= change_address (smem
, DImode
,
4257 gen_rtx_AND (DImode
,
4258 plus_constant (smema
, 8*i
),
4260 set_mem_alias_set (tmp
, 0);
4261 emit_move_insn (data_regs
[i
], tmp
);
4264 tmp
= change_address (smem
, DImode
,
4265 gen_rtx_AND (DImode
,
4266 plus_constant (smema
, 8*words
- 1),
4268 set_mem_alias_set (tmp
, 0);
4269 emit_move_insn (data_regs
[words
], tmp
);
4271 /* Extract the half-word fragments. Unfortunately DEC decided to make
4272 extxh with offset zero a noop instead of zeroing the register, so
4273 we must take care of that edge condition ourselves with cmov. */
4275 sreg
= copy_addr_to_reg (smema
);
4276 areg
= expand_binop (DImode
, and_optab
, sreg
, GEN_INT (7), NULL
,
4278 if (WORDS_BIG_ENDIAN
)
4279 emit_move_insn (sreg
, plus_constant (sreg
, 7));
4280 for (i
= 0; i
< words
; ++i
)
4282 if (WORDS_BIG_ENDIAN
)
4284 emit_insn (gen_extqh_be (data_regs
[i
], data_regs
[i
], sreg
));
4285 emit_insn (gen_extxl_be (ext_tmps
[i
], data_regs
[i
+1], i64
, sreg
));
4289 emit_insn (gen_extxl_le (data_regs
[i
], data_regs
[i
], i64
, sreg
));
4290 emit_insn (gen_extqh_le (ext_tmps
[i
], data_regs
[i
+1], sreg
));
4292 emit_insn (gen_rtx_SET (VOIDmode
, ext_tmps
[i
],
4293 gen_rtx_IF_THEN_ELSE (DImode
,
4294 gen_rtx_EQ (DImode
, areg
,
4296 const0_rtx
, ext_tmps
[i
])));
4299 /* Merge the half-words into whole words. */
4300 for (i
= 0; i
< words
; ++i
)
4302 out_regs
[i
] = expand_binop (DImode
, ior_optab
, data_regs
[i
],
4303 ext_tmps
[i
], data_regs
[i
], 1, OPTAB_WIDEN
);
4307 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
4308 may be NULL to store zeros. */
4311 alpha_expand_unaligned_store_words (rtx
*data_regs
, rtx dmem
,
4312 HOST_WIDE_INT words
, HOST_WIDE_INT ofs
)
4314 rtx
const im8
= GEN_INT (-8);
4315 rtx
const i64
= GEN_INT (64);
4316 rtx ins_tmps
[MAX_MOVE_WORDS
];
4317 rtx st_tmp_1
, st_tmp_2
, dreg
;
4318 rtx st_addr_1
, st_addr_2
, dmema
;
4321 dmema
= XEXP (dmem
, 0);
4322 if (GET_CODE (dmema
) == LO_SUM
)
4323 dmema
= force_reg (Pmode
, dmema
);
4325 /* Generate all the tmp registers we need. */
4326 if (data_regs
!= NULL
)
4327 for (i
= 0; i
< words
; ++i
)
4328 ins_tmps
[i
] = gen_reg_rtx(DImode
);
4329 st_tmp_1
= gen_reg_rtx(DImode
);
4330 st_tmp_2
= gen_reg_rtx(DImode
);
4333 dmem
= adjust_address (dmem
, GET_MODE (dmem
), ofs
);
4335 st_addr_2
= change_address (dmem
, DImode
,
4336 gen_rtx_AND (DImode
,
4337 plus_constant (dmema
, words
*8 - 1),
4339 set_mem_alias_set (st_addr_2
, 0);
4341 st_addr_1
= change_address (dmem
, DImode
,
4342 gen_rtx_AND (DImode
, dmema
, im8
));
4343 set_mem_alias_set (st_addr_1
, 0);
4345 /* Load up the destination end bits. */
4346 emit_move_insn (st_tmp_2
, st_addr_2
);
4347 emit_move_insn (st_tmp_1
, st_addr_1
);
4349 /* Shift the input data into place. */
4350 dreg
= copy_addr_to_reg (dmema
);
4351 if (WORDS_BIG_ENDIAN
)
4352 emit_move_insn (dreg
, plus_constant (dreg
, 7));
4353 if (data_regs
!= NULL
)
4355 for (i
= words
-1; i
>= 0; --i
)
4357 if (WORDS_BIG_ENDIAN
)
4359 emit_insn (gen_insql_be (ins_tmps
[i
], data_regs
[i
], dreg
));
4360 emit_insn (gen_insxh (data_regs
[i
], data_regs
[i
], i64
, dreg
));
4364 emit_insn (gen_insxh (ins_tmps
[i
], data_regs
[i
], i64
, dreg
));
4365 emit_insn (gen_insql_le (data_regs
[i
], data_regs
[i
], dreg
));
4368 for (i
= words
-1; i
> 0; --i
)
4370 ins_tmps
[i
-1] = expand_binop (DImode
, ior_optab
, data_regs
[i
],
4371 ins_tmps
[i
-1], ins_tmps
[i
-1], 1,
4376 /* Split and merge the ends with the destination data. */
4377 if (WORDS_BIG_ENDIAN
)
4379 emit_insn (gen_mskxl_be (st_tmp_2
, st_tmp_2
, constm1_rtx
, dreg
));
4380 emit_insn (gen_mskxh (st_tmp_1
, st_tmp_1
, i64
, dreg
));
4384 emit_insn (gen_mskxh (st_tmp_2
, st_tmp_2
, i64
, dreg
));
4385 emit_insn (gen_mskxl_le (st_tmp_1
, st_tmp_1
, constm1_rtx
, dreg
));
4388 if (data_regs
!= NULL
)
4390 st_tmp_2
= expand_binop (DImode
, ior_optab
, st_tmp_2
, ins_tmps
[words
-1],
4391 st_tmp_2
, 1, OPTAB_WIDEN
);
4392 st_tmp_1
= expand_binop (DImode
, ior_optab
, st_tmp_1
, data_regs
[0],
4393 st_tmp_1
, 1, OPTAB_WIDEN
);
4397 if (WORDS_BIG_ENDIAN
)
4398 emit_move_insn (st_addr_1
, st_tmp_1
);
4400 emit_move_insn (st_addr_2
, st_tmp_2
);
4401 for (i
= words
-1; i
> 0; --i
)
4403 rtx tmp
= change_address (dmem
, DImode
,
4404 gen_rtx_AND (DImode
,
4405 plus_constant(dmema
,
4406 WORDS_BIG_ENDIAN
? i
*8-1 : i
*8),
4408 set_mem_alias_set (tmp
, 0);
4409 emit_move_insn (tmp
, data_regs
? ins_tmps
[i
-1] : const0_rtx
);
4411 if (WORDS_BIG_ENDIAN
)
4412 emit_move_insn (st_addr_2
, st_tmp_2
);
4414 emit_move_insn (st_addr_1
, st_tmp_1
);
4418 /* Expand string/block move operations.
4420 operands[0] is the pointer to the destination.
4421 operands[1] is the pointer to the source.
4422 operands[2] is the number of bytes to move.
4423 operands[3] is the alignment. */
4426 alpha_expand_block_move (rtx operands
[])
4428 rtx bytes_rtx
= operands
[2];
4429 rtx align_rtx
= operands
[3];
4430 HOST_WIDE_INT orig_bytes
= INTVAL (bytes_rtx
);
4431 HOST_WIDE_INT bytes
= orig_bytes
;
4432 HOST_WIDE_INT src_align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
4433 HOST_WIDE_INT dst_align
= src_align
;
4434 rtx orig_src
= operands
[1];
4435 rtx orig_dst
= operands
[0];
4436 rtx data_regs
[2 * MAX_MOVE_WORDS
+ 16];
4438 unsigned int i
, words
, ofs
, nregs
= 0;
4440 if (orig_bytes
<= 0)
4442 else if (orig_bytes
> MAX_MOVE_WORDS
* UNITS_PER_WORD
)
4445 /* Look for additional alignment information from recorded register info. */
4447 tmp
= XEXP (orig_src
, 0);
4448 if (GET_CODE (tmp
) == REG
)
4449 src_align
= MAX (src_align
, REGNO_POINTER_ALIGN (REGNO (tmp
)));
4450 else if (GET_CODE (tmp
) == PLUS
4451 && GET_CODE (XEXP (tmp
, 0)) == REG
4452 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
4454 unsigned HOST_WIDE_INT c
= INTVAL (XEXP (tmp
, 1));
4455 unsigned int a
= REGNO_POINTER_ALIGN (REGNO (XEXP (tmp
, 0)));
4459 if (a
>= 64 && c
% 8 == 0)
4461 else if (a
>= 32 && c
% 4 == 0)
4463 else if (a
>= 16 && c
% 2 == 0)
4468 tmp
= XEXP (orig_dst
, 0);
4469 if (GET_CODE (tmp
) == REG
)
4470 dst_align
= MAX (dst_align
, REGNO_POINTER_ALIGN (REGNO (tmp
)));
4471 else if (GET_CODE (tmp
) == PLUS
4472 && GET_CODE (XEXP (tmp
, 0)) == REG
4473 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
4475 unsigned HOST_WIDE_INT c
= INTVAL (XEXP (tmp
, 1));
4476 unsigned int a
= REGNO_POINTER_ALIGN (REGNO (XEXP (tmp
, 0)));
4480 if (a
>= 64 && c
% 8 == 0)
4482 else if (a
>= 32 && c
% 4 == 0)
4484 else if (a
>= 16 && c
% 2 == 0)
4489 /* Load the entire block into registers. */
4490 if (GET_CODE (XEXP (orig_src
, 0)) == ADDRESSOF
)
4492 enum machine_mode mode
;
4494 tmp
= XEXP (XEXP (orig_src
, 0), 0);
4496 /* Don't use the existing register if we're reading more than
4497 is held in the register. Nor if there is not a mode that
4498 handles the exact size. */
4499 mode
= mode_for_size (bytes
* BITS_PER_UNIT
, MODE_INT
, 1);
4500 if (GET_CODE (tmp
) == REG
4502 && GET_MODE_SIZE (GET_MODE (tmp
)) >= bytes
)
4506 data_regs
[nregs
] = gen_lowpart (DImode
, tmp
);
4507 data_regs
[nregs
+ 1] = gen_highpart (DImode
, tmp
);
4511 data_regs
[nregs
++] = gen_lowpart (mode
, tmp
);
4516 /* No appropriate mode; fall back on memory. */
4517 orig_src
= replace_equiv_address (orig_src
,
4518 copy_addr_to_reg (XEXP (orig_src
, 0)));
4519 src_align
= GET_MODE_BITSIZE (GET_MODE (tmp
));
4523 if (src_align
>= 64 && bytes
>= 8)
4527 for (i
= 0; i
< words
; ++i
)
4528 data_regs
[nregs
+ i
] = gen_reg_rtx (DImode
);
4530 for (i
= 0; i
< words
; ++i
)
4531 emit_move_insn (data_regs
[nregs
+ i
],
4532 adjust_address (orig_src
, DImode
, ofs
+ i
* 8));
4539 if (src_align
>= 32 && bytes
>= 4)
4543 for (i
= 0; i
< words
; ++i
)
4544 data_regs
[nregs
+ i
] = gen_reg_rtx (SImode
);
4546 for (i
= 0; i
< words
; ++i
)
4547 emit_move_insn (data_regs
[nregs
+ i
],
4548 adjust_address (orig_src
, SImode
, ofs
+ i
* 4));
4559 for (i
= 0; i
< words
+1; ++i
)
4560 data_regs
[nregs
+ i
] = gen_reg_rtx (DImode
);
4562 alpha_expand_unaligned_load_words (data_regs
+ nregs
, orig_src
,
4570 if (! TARGET_BWX
&& bytes
>= 4)
4572 data_regs
[nregs
++] = tmp
= gen_reg_rtx (SImode
);
4573 alpha_expand_unaligned_load (tmp
, orig_src
, 4, ofs
, 0);
4580 if (src_align
>= 16)
4583 data_regs
[nregs
++] = tmp
= gen_reg_rtx (HImode
);
4584 emit_move_insn (tmp
, adjust_address (orig_src
, HImode
, ofs
));
4587 } while (bytes
>= 2);
4589 else if (! TARGET_BWX
)
4591 data_regs
[nregs
++] = tmp
= gen_reg_rtx (HImode
);
4592 alpha_expand_unaligned_load (tmp
, orig_src
, 2, ofs
, 0);
4600 data_regs
[nregs
++] = tmp
= gen_reg_rtx (QImode
);
4601 emit_move_insn (tmp
, adjust_address (orig_src
, QImode
, ofs
));
4608 if (nregs
> ARRAY_SIZE (data_regs
))
4611 /* Now save it back out again. */
4615 if (GET_CODE (XEXP (orig_dst
, 0)) == ADDRESSOF
)
4617 enum machine_mode mode
;
4618 tmp
= XEXP (XEXP (orig_dst
, 0), 0);
4620 mode
= mode_for_size (orig_bytes
* BITS_PER_UNIT
, MODE_INT
, 1);
4621 if (GET_CODE (tmp
) == REG
&& GET_MODE (tmp
) == mode
)
4625 emit_move_insn (tmp
, data_regs
[0]);
4630 else if (nregs
== 2 && mode
== TImode
)
4632 /* Undo the subregging done above when copying between
4633 two TImode registers. */
4634 if (GET_CODE (data_regs
[0]) == SUBREG
4635 && GET_MODE (SUBREG_REG (data_regs
[0])) == TImode
)
4636 emit_move_insn (tmp
, SUBREG_REG (data_regs
[0]));
4642 emit_move_insn (gen_lowpart (DImode
, tmp
), data_regs
[0]);
4643 emit_move_insn (gen_highpart (DImode
, tmp
), data_regs
[1]);
4647 emit_no_conflict_block (seq
, tmp
, data_regs
[0],
4648 data_regs
[1], NULL_RTX
);
4656 /* ??? If nregs > 1, consider reconstructing the word in regs. */
4657 /* ??? Optimize mode < dst_mode with strict_low_part. */
4659 /* No appropriate mode; fall back on memory. We can speed things
4660 up by recognizing extra alignment information. */
4661 orig_dst
= replace_equiv_address (orig_dst
,
4662 copy_addr_to_reg (XEXP (orig_dst
, 0)));
4663 dst_align
= GET_MODE_BITSIZE (GET_MODE (tmp
));
4666 /* Write out the data in whatever chunks reading the source allowed. */
4667 if (dst_align
>= 64)
4669 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == DImode
)
4671 emit_move_insn (adjust_address (orig_dst
, DImode
, ofs
),
4678 if (dst_align
>= 32)
4680 /* If the source has remaining DImode regs, write them out in
4682 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == DImode
)
4684 tmp
= expand_binop (DImode
, lshr_optab
, data_regs
[i
], GEN_INT (32),
4685 NULL_RTX
, 1, OPTAB_WIDEN
);
4687 emit_move_insn (adjust_address (orig_dst
, SImode
, ofs
),
4688 gen_lowpart (SImode
, data_regs
[i
]));
4689 emit_move_insn (adjust_address (orig_dst
, SImode
, ofs
+ 4),
4690 gen_lowpart (SImode
, tmp
));
4695 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == SImode
)
4697 emit_move_insn (adjust_address (orig_dst
, SImode
, ofs
),
4704 if (i
< nregs
&& GET_MODE (data_regs
[i
]) == DImode
)
4706 /* Write out a remaining block of words using unaligned methods. */
4708 for (words
= 1; i
+ words
< nregs
; words
++)
4709 if (GET_MODE (data_regs
[i
+ words
]) != DImode
)
4713 alpha_expand_unaligned_store (orig_dst
, data_regs
[i
], 8, ofs
);
4715 alpha_expand_unaligned_store_words (data_regs
+ i
, orig_dst
,
4722 /* Due to the above, this won't be aligned. */
4723 /* ??? If we have more than one of these, consider constructing full
4724 words in registers and using alpha_expand_unaligned_store_words. */
4725 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == SImode
)
4727 alpha_expand_unaligned_store (orig_dst
, data_regs
[i
], 4, ofs
);
4732 if (dst_align
>= 16)
4733 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == HImode
)
4735 emit_move_insn (adjust_address (orig_dst
, HImode
, ofs
), data_regs
[i
]);
4740 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == HImode
)
4742 alpha_expand_unaligned_store (orig_dst
, data_regs
[i
], 2, ofs
);
4747 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == QImode
)
4749 emit_move_insn (adjust_address (orig_dst
, QImode
, ofs
), data_regs
[i
]);
4763 alpha_expand_block_clear (rtx operands
[])
4765 rtx bytes_rtx
= operands
[1];
4766 rtx align_rtx
= operands
[2];
4767 HOST_WIDE_INT orig_bytes
= INTVAL (bytes_rtx
);
4768 HOST_WIDE_INT bytes
= orig_bytes
;
4769 HOST_WIDE_INT align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
4770 HOST_WIDE_INT alignofs
= 0;
4771 rtx orig_dst
= operands
[0];
4773 int i
, words
, ofs
= 0;
4775 if (orig_bytes
<= 0)
4777 if (orig_bytes
> MAX_MOVE_WORDS
* UNITS_PER_WORD
)
4780 /* Look for stricter alignment. */
4781 tmp
= XEXP (orig_dst
, 0);
4782 if (GET_CODE (tmp
) == REG
)
4783 align
= MAX (align
, REGNO_POINTER_ALIGN (REGNO (tmp
)));
4784 else if (GET_CODE (tmp
) == PLUS
4785 && GET_CODE (XEXP (tmp
, 0)) == REG
4786 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
4788 HOST_WIDE_INT c
= INTVAL (XEXP (tmp
, 1));
4789 int a
= REGNO_POINTER_ALIGN (REGNO (XEXP (tmp
, 0)));
4794 align
= a
, alignofs
= 8 - c
% 8;
4796 align
= a
, alignofs
= 4 - c
% 4;
4798 align
= a
, alignofs
= 2 - c
% 2;
4801 else if (GET_CODE (tmp
) == ADDRESSOF
)
4803 enum machine_mode mode
;
4805 mode
= mode_for_size (bytes
* BITS_PER_UNIT
, MODE_INT
, 1);
4806 if (GET_MODE (XEXP (tmp
, 0)) == mode
)
4808 emit_move_insn (XEXP (tmp
, 0), const0_rtx
);
4812 /* No appropriate mode; fall back on memory. */
4813 orig_dst
= replace_equiv_address (orig_dst
, copy_addr_to_reg (tmp
));
4814 align
= GET_MODE_BITSIZE (GET_MODE (XEXP (tmp
, 0)));
4817 /* Handle an unaligned prefix first. */
4821 #if HOST_BITS_PER_WIDE_INT >= 64
4822 /* Given that alignofs is bounded by align, the only time BWX could
4823 generate three stores is for a 7 byte fill. Prefer two individual
4824 stores over a load/mask/store sequence. */
4825 if ((!TARGET_BWX
|| alignofs
== 7)
4827 && !(alignofs
== 4 && bytes
>= 4))
4829 enum machine_mode mode
= (align
>= 64 ? DImode
: SImode
);
4830 int inv_alignofs
= (align
>= 64 ? 8 : 4) - alignofs
;
4834 mem
= adjust_address (orig_dst
, mode
, ofs
- inv_alignofs
);
4835 set_mem_alias_set (mem
, 0);
4837 mask
= ~(~(HOST_WIDE_INT
)0 << (inv_alignofs
* 8));
4838 if (bytes
< alignofs
)
4840 mask
|= ~(HOST_WIDE_INT
)0 << ((inv_alignofs
+ bytes
) * 8);
4851 tmp
= expand_binop (mode
, and_optab
, mem
, GEN_INT (mask
),
4852 NULL_RTX
, 1, OPTAB_WIDEN
);
4854 emit_move_insn (mem
, tmp
);
4858 if (TARGET_BWX
&& (alignofs
& 1) && bytes
>= 1)
4860 emit_move_insn (adjust_address (orig_dst
, QImode
, ofs
), const0_rtx
);
4865 if (TARGET_BWX
&& align
>= 16 && (alignofs
& 3) == 2 && bytes
>= 2)
4867 emit_move_insn (adjust_address (orig_dst
, HImode
, ofs
), const0_rtx
);
4872 if (alignofs
== 4 && bytes
>= 4)
4874 emit_move_insn (adjust_address (orig_dst
, SImode
, ofs
), const0_rtx
);
4880 /* If we've not used the extra lead alignment information by now,
4881 we won't be able to. Downgrade align to match what's left over. */
4884 alignofs
= alignofs
& -alignofs
;
4885 align
= MIN (align
, alignofs
* BITS_PER_UNIT
);
4889 /* Handle a block of contiguous long-words. */
4891 if (align
>= 64 && bytes
>= 8)
4895 for (i
= 0; i
< words
; ++i
)
4896 emit_move_insn (adjust_address (orig_dst
, DImode
, ofs
+ i
* 8),
4903 /* If the block is large and appropriately aligned, emit a single
4904 store followed by a sequence of stq_u insns. */
4906 if (align
>= 32 && bytes
> 16)
4910 emit_move_insn (adjust_address (orig_dst
, SImode
, ofs
), const0_rtx
);
4914 orig_dsta
= XEXP (orig_dst
, 0);
4915 if (GET_CODE (orig_dsta
) == LO_SUM
)
4916 orig_dsta
= force_reg (Pmode
, orig_dsta
);
4919 for (i
= 0; i
< words
; ++i
)
4922 = change_address (orig_dst
, DImode
,
4923 gen_rtx_AND (DImode
,
4924 plus_constant (orig_dsta
, ofs
+ i
*8),
4926 set_mem_alias_set (mem
, 0);
4927 emit_move_insn (mem
, const0_rtx
);
4930 /* Depending on the alignment, the first stq_u may have overlapped
4931 with the initial stl, which means that the last stq_u didn't
4932 write as much as it would appear. Leave those questionable bytes
4934 bytes
-= words
* 8 - 4;
4935 ofs
+= words
* 8 - 4;
4938 /* Handle a smaller block of aligned words. */
4940 if ((align
>= 64 && bytes
== 4)
4941 || (align
== 32 && bytes
>= 4))
4945 for (i
= 0; i
< words
; ++i
)
4946 emit_move_insn (adjust_address (orig_dst
, SImode
, ofs
+ i
* 4),
4953 /* An unaligned block uses stq_u stores for as many as possible. */
4959 alpha_expand_unaligned_store_words (NULL
, orig_dst
, words
, ofs
);
4965 /* Next clean up any trailing pieces. */
4967 #if HOST_BITS_PER_WIDE_INT >= 64
4968 /* Count the number of bits in BYTES for which aligned stores could
4971 for (i
= (TARGET_BWX
? 1 : 4); i
* BITS_PER_UNIT
<= align
; i
<<= 1)
4975 /* If we have appropriate alignment (and it wouldn't take too many
4976 instructions otherwise), mask out the bytes we need. */
4977 if (TARGET_BWX
? words
> 2 : bytes
> 0)
4984 mem
= adjust_address (orig_dst
, DImode
, ofs
);
4985 set_mem_alias_set (mem
, 0);
4987 mask
= ~(HOST_WIDE_INT
)0 << (bytes
* 8);
4989 tmp
= expand_binop (DImode
, and_optab
, mem
, GEN_INT (mask
),
4990 NULL_RTX
, 1, OPTAB_WIDEN
);
4992 emit_move_insn (mem
, tmp
);
4995 else if (align
>= 32 && bytes
< 4)
5000 mem
= adjust_address (orig_dst
, SImode
, ofs
);
5001 set_mem_alias_set (mem
, 0);
5003 mask
= ~(HOST_WIDE_INT
)0 << (bytes
* 8);
5005 tmp
= expand_binop (SImode
, and_optab
, mem
, GEN_INT (mask
),
5006 NULL_RTX
, 1, OPTAB_WIDEN
);
5008 emit_move_insn (mem
, tmp
);
5014 if (!TARGET_BWX
&& bytes
>= 4)
5016 alpha_expand_unaligned_store (orig_dst
, const0_rtx
, 4, ofs
);
5026 emit_move_insn (adjust_address (orig_dst
, HImode
, ofs
),
5030 } while (bytes
>= 2);
5032 else if (! TARGET_BWX
)
5034 alpha_expand_unaligned_store (orig_dst
, const0_rtx
, 2, ofs
);
5042 emit_move_insn (adjust_address (orig_dst
, QImode
, ofs
), const0_rtx
);
5050 /* Returns a mask so that zap(x, value) == x & mask. */
5053 alpha_expand_zap_mask (HOST_WIDE_INT value
)
5058 if (HOST_BITS_PER_WIDE_INT
>= 64)
5060 HOST_WIDE_INT mask
= 0;
5062 for (i
= 7; i
>= 0; --i
)
5065 if (!((value
>> i
) & 1))
5069 result
= gen_int_mode (mask
, DImode
);
5071 else if (HOST_BITS_PER_WIDE_INT
== 32)
5073 HOST_WIDE_INT mask_lo
= 0, mask_hi
= 0;
5075 for (i
= 7; i
>= 4; --i
)
5078 if (!((value
>> i
) & 1))
5082 for (i
= 3; i
>= 0; --i
)
5085 if (!((value
>> i
) & 1))
5089 result
= immed_double_const (mask_lo
, mask_hi
, DImode
);
5098 alpha_expand_builtin_vector_binop (rtx (*gen
) (rtx
, rtx
, rtx
),
5099 enum machine_mode mode
,
5100 rtx op0
, rtx op1
, rtx op2
)
5102 op0
= gen_lowpart (mode
, op0
);
5104 if (op1
== const0_rtx
)
5105 op1
= CONST0_RTX (mode
);
5107 op1
= gen_lowpart (mode
, op1
);
5109 if (op2
== const0_rtx
)
5110 op2
= CONST0_RTX (mode
);
5112 op2
= gen_lowpart (mode
, op2
);
5114 emit_insn ((*gen
) (op0
, op1
, op2
));
5117 /* Adjust the cost of a scheduling dependency. Return the new cost of
5118 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
5121 alpha_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
5123 enum attr_type insn_type
, dep_insn_type
;
5125 /* If the dependence is an anti-dependence, there is no cost. For an
5126 output dependence, there is sometimes a cost, but it doesn't seem
5127 worth handling those few cases. */
5128 if (REG_NOTE_KIND (link
) != 0)
5131 /* If we can't recognize the insns, we can't really do anything. */
5132 if (recog_memoized (insn
) < 0 || recog_memoized (dep_insn
) < 0)
5135 insn_type
= get_attr_type (insn
);
5136 dep_insn_type
= get_attr_type (dep_insn
);
5138 /* Bring in the user-defined memory latency. */
5139 if (dep_insn_type
== TYPE_ILD
5140 || dep_insn_type
== TYPE_FLD
5141 || dep_insn_type
== TYPE_LDSYM
)
5142 cost
+= alpha_memory_latency
-1;
5144 /* Everything else handled in DFA bypasses now. */
5149 /* The number of instructions that can be issued per cycle. */
5152 alpha_issue_rate (void)
5154 return (alpha_cpu
== PROCESSOR_EV4
? 2 : 4);
5158 alpha_use_dfa_pipeline_interface (void)
5163 /* How many alternative schedules to try. This should be as wide as the
5164 scheduling freedom in the DFA, but no wider. Making this value too
5165 large results extra work for the scheduler.
5167 For EV4, loads can be issued to either IB0 or IB1, thus we have 2
5168 alternative schedules. For EV5, we can choose between E0/E1 and
5169 FA/FM. For EV6, an arithmetic insn can be issued to U0/U1/L0/L1. */
5172 alpha_multipass_dfa_lookahead (void)
5174 return (alpha_cpu
== PROCESSOR_EV6
? 4 : 2);
5177 /* Machine-specific function data. */
5179 struct machine_function
GTY(())
5182 /* List of call information words for calls from this function. */
5183 struct rtx_def
*first_ciw
;
5184 struct rtx_def
*last_ciw
;
5187 /* List of deferred case vectors. */
5188 struct rtx_def
*addr_list
;
5191 const char *some_ld_name
;
5193 /* For TARGET_LD_BUGGY_LDGP. */
5194 struct rtx_def
*gp_save_rtx
;
5197 /* How to allocate a 'struct machine_function'. */
5199 static struct machine_function
*
5200 alpha_init_machine_status (void)
5202 return ((struct machine_function
*)
5203 ggc_alloc_cleared (sizeof (struct machine_function
)));
5206 /* Functions to save and restore alpha_return_addr_rtx. */
5208 /* Start the ball rolling with RETURN_ADDR_RTX. */
5211 alpha_return_addr (int count
, rtx frame ATTRIBUTE_UNUSED
)
5216 return get_hard_reg_initial_val (Pmode
, REG_RA
);
5219 /* Return or create a memory slot containing the gp value for the current
5220 function. Needed only if TARGET_LD_BUGGY_LDGP. */
5223 alpha_gp_save_rtx (void)
5225 rtx seq
, m
= cfun
->machine
->gp_save_rtx
;
5231 m
= assign_stack_local (DImode
, UNITS_PER_WORD
, BITS_PER_WORD
);
5232 m
= validize_mem (m
);
5233 emit_move_insn (m
, pic_offset_table_rtx
);
5237 emit_insn_after (seq
, entry_of_function ());
5239 cfun
->machine
->gp_save_rtx
= m
;
5246 alpha_ra_ever_killed (void)
5250 if (!has_hard_reg_initial_val (Pmode
, REG_RA
))
5251 return regs_ever_live
[REG_RA
];
5253 push_topmost_sequence ();
5255 pop_topmost_sequence ();
5257 return reg_set_between_p (gen_rtx_REG (Pmode
, REG_RA
), top
, NULL_RTX
);
5261 /* Return the trap mode suffix applicable to the current
5262 instruction, or NULL. */
5265 get_trap_mode_suffix (void)
5267 enum attr_trap_suffix s
= get_attr_trap_suffix (current_output_insn
);
5271 case TRAP_SUFFIX_NONE
:
5274 case TRAP_SUFFIX_SU
:
5275 if (alpha_fptm
>= ALPHA_FPTM_SU
)
5279 case TRAP_SUFFIX_SUI
:
5280 if (alpha_fptm
>= ALPHA_FPTM_SUI
)
5284 case TRAP_SUFFIX_V_SV
:
5292 case ALPHA_FPTM_SUI
:
5297 case TRAP_SUFFIX_V_SV_SVI
:
5306 case ALPHA_FPTM_SUI
:
5311 case TRAP_SUFFIX_U_SU_SUI
:
5320 case ALPHA_FPTM_SUI
:
5328 /* Return the rounding mode suffix applicable to the current
5329 instruction, or NULL. */
5332 get_round_mode_suffix (void)
5334 enum attr_round_suffix s
= get_attr_round_suffix (current_output_insn
);
5338 case ROUND_SUFFIX_NONE
:
5340 case ROUND_SUFFIX_NORMAL
:
5343 case ALPHA_FPRM_NORM
:
5345 case ALPHA_FPRM_MINF
:
5347 case ALPHA_FPRM_CHOP
:
5349 case ALPHA_FPRM_DYN
:
5354 case ROUND_SUFFIX_C
:
5360 /* Locate some local-dynamic symbol still in use by this function
5361 so that we can print its name in some movdi_er_tlsldm pattern. */
5364 get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
5368 if (GET_CODE (x
) == SYMBOL_REF
5369 && SYMBOL_REF_TLS_MODEL (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
5371 cfun
->machine
->some_ld_name
= XSTR (x
, 0);
5379 get_some_local_dynamic_name (void)
5383 if (cfun
->machine
->some_ld_name
)
5384 return cfun
->machine
->some_ld_name
;
5386 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5388 && for_each_rtx (&PATTERN (insn
), get_some_local_dynamic_name_1
, 0))
5389 return cfun
->machine
->some_ld_name
;
5394 /* Print an operand. Recognize special options, documented below. */
5397 print_operand (FILE *file
, rtx x
, int code
)
5404 /* Print the assembler name of the current function. */
5405 assemble_name (file
, alpha_fnname
);
5409 assemble_name (file
, get_some_local_dynamic_name ());
5414 const char *trap
= get_trap_mode_suffix ();
5415 const char *round
= get_round_mode_suffix ();
5418 fprintf (file
, (TARGET_AS_SLASH_BEFORE_SUFFIX
? "/%s%s" : "%s%s"),
5419 (trap
? trap
: ""), (round
? round
: ""));
5424 /* Generates single precision instruction suffix. */
5425 fputc ((TARGET_FLOAT_VAX
? 'f' : 's'), file
);
5429 /* Generates double precision instruction suffix. */
5430 fputc ((TARGET_FLOAT_VAX
? 'g' : 't'), file
);
5434 /* Generates a nop after a noreturn call at the very end of the
5436 if (next_real_insn (current_output_insn
) == 0)
5437 fprintf (file
, "\n\tnop");
5441 if (alpha_this_literal_sequence_number
== 0)
5442 alpha_this_literal_sequence_number
= alpha_next_sequence_number
++;
5443 fprintf (file
, "%d", alpha_this_literal_sequence_number
);
5447 if (alpha_this_gpdisp_sequence_number
== 0)
5448 alpha_this_gpdisp_sequence_number
= alpha_next_sequence_number
++;
5449 fprintf (file
, "%d", alpha_this_gpdisp_sequence_number
);
5453 if (GET_CODE (x
) == HIGH
)
5454 output_addr_const (file
, XEXP (x
, 0));
5456 output_operand_lossage ("invalid %%H value");
5463 if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSGD_CALL
)
5465 x
= XVECEXP (x
, 0, 0);
5466 lituse
= "lituse_tlsgd";
5468 else if (GET_CODE (x
) == UNSPEC
&& XINT (x
, 1) == UNSPEC_TLSLDM_CALL
)
5470 x
= XVECEXP (x
, 0, 0);
5471 lituse
= "lituse_tlsldm";
5473 else if (GET_CODE (x
) == CONST_INT
)
5474 lituse
= "lituse_jsr";
5477 output_operand_lossage ("invalid %%J value");
5481 if (x
!= const0_rtx
)
5482 fprintf (file
, "\t\t!%s!%d", lituse
, (int) INTVAL (x
));
5487 /* If this operand is the constant zero, write it as "$31". */
5488 if (GET_CODE (x
) == REG
)
5489 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
5490 else if (x
== CONST0_RTX (GET_MODE (x
)))
5491 fprintf (file
, "$31");
5493 output_operand_lossage ("invalid %%r value");
5497 /* Similar, but for floating-point. */
5498 if (GET_CODE (x
) == REG
)
5499 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
5500 else if (x
== CONST0_RTX (GET_MODE (x
)))
5501 fprintf (file
, "$f31");
5503 output_operand_lossage ("invalid %%R value");
5507 /* Write the 1's complement of a constant. */
5508 if (GET_CODE (x
) != CONST_INT
)
5509 output_operand_lossage ("invalid %%N value");
5511 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ~ INTVAL (x
));
5515 /* Write 1 << C, for a constant C. */
5516 if (GET_CODE (x
) != CONST_INT
)
5517 output_operand_lossage ("invalid %%P value");
5519 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (HOST_WIDE_INT
) 1 << INTVAL (x
));
5523 /* Write the high-order 16 bits of a constant, sign-extended. */
5524 if (GET_CODE (x
) != CONST_INT
)
5525 output_operand_lossage ("invalid %%h value");
5527 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) >> 16);
5531 /* Write the low-order 16 bits of a constant, sign-extended. */
5532 if (GET_CODE (x
) != CONST_INT
)
5533 output_operand_lossage ("invalid %%L value");
5535 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
5536 (INTVAL (x
) & 0xffff) - 2 * (INTVAL (x
) & 0x8000));
5540 /* Write mask for ZAP insn. */
5541 if (GET_CODE (x
) == CONST_DOUBLE
)
5543 HOST_WIDE_INT mask
= 0;
5544 HOST_WIDE_INT value
;
5546 value
= CONST_DOUBLE_LOW (x
);
5547 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
5552 value
= CONST_DOUBLE_HIGH (x
);
5553 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
5556 mask
|= (1 << (i
+ sizeof (int)));
5558 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, mask
& 0xff);
5561 else if (GET_CODE (x
) == CONST_INT
)
5563 HOST_WIDE_INT mask
= 0, value
= INTVAL (x
);
5565 for (i
= 0; i
< 8; i
++, value
>>= 8)
5569 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, mask
);
5572 output_operand_lossage ("invalid %%m value");
5576 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
5577 if (GET_CODE (x
) != CONST_INT
5578 || (INTVAL (x
) != 8 && INTVAL (x
) != 16
5579 && INTVAL (x
) != 32 && INTVAL (x
) != 64))
5580 output_operand_lossage ("invalid %%M value");
5582 fprintf (file
, "%s",
5583 (INTVAL (x
) == 8 ? "b"
5584 : INTVAL (x
) == 16 ? "w"
5585 : INTVAL (x
) == 32 ? "l"
5590 /* Similar, except do it from the mask. */
5591 if (GET_CODE (x
) == CONST_INT
)
5593 HOST_WIDE_INT value
= INTVAL (x
);
5600 if (value
== 0xffff)
5605 if (value
== 0xffffffff)
5616 else if (HOST_BITS_PER_WIDE_INT
== 32
5617 && GET_CODE (x
) == CONST_DOUBLE
5618 && CONST_DOUBLE_LOW (x
) == 0xffffffff
5619 && CONST_DOUBLE_HIGH (x
) == 0)
5624 output_operand_lossage ("invalid %%U value");
5628 /* Write the constant value divided by 8 for little-endian mode or
5629 (56 - value) / 8 for big-endian mode. */
5631 if (GET_CODE (x
) != CONST_INT
5632 || (unsigned HOST_WIDE_INT
) INTVAL (x
) >= (WORDS_BIG_ENDIAN
5635 || (INTVAL (x
) & 7) != 0)
5636 output_operand_lossage ("invalid %%s value");
5638 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
5640 ? (56 - INTVAL (x
)) / 8
5645 /* Same, except compute (64 - c) / 8 */
5647 if (GET_CODE (x
) != CONST_INT
5648 && (unsigned HOST_WIDE_INT
) INTVAL (x
) >= 64
5649 && (INTVAL (x
) & 7) != 8)
5650 output_operand_lossage ("invalid %%s value");
5652 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (64 - INTVAL (x
)) / 8);
5657 /* On Unicos/Mk systems: use a DEX expression if the symbol
5658 clashes with a register name. */
5659 int dex
= unicosmk_need_dex (x
);
5661 fprintf (file
, "DEX(%d)", dex
);
5663 output_addr_const (file
, x
);
5667 case 'C': case 'D': case 'c': case 'd':
5668 /* Write out comparison name. */
5670 enum rtx_code c
= GET_CODE (x
);
5672 if (!COMPARISON_P (x
))
5673 output_operand_lossage ("invalid %%C value");
5675 else if (code
== 'D')
5676 c
= reverse_condition (c
);
5677 else if (code
== 'c')
5678 c
= swap_condition (c
);
5679 else if (code
== 'd')
5680 c
= swap_condition (reverse_condition (c
));
5683 fprintf (file
, "ule");
5685 fprintf (file
, "ult");
5686 else if (c
== UNORDERED
)
5687 fprintf (file
, "un");
5689 fprintf (file
, "%s", GET_RTX_NAME (c
));
5694 /* Write the divide or modulus operator. */
5695 switch (GET_CODE (x
))
5698 fprintf (file
, "div%s", GET_MODE (x
) == SImode
? "l" : "q");
5701 fprintf (file
, "div%su", GET_MODE (x
) == SImode
? "l" : "q");
5704 fprintf (file
, "rem%s", GET_MODE (x
) == SImode
? "l" : "q");
5707 fprintf (file
, "rem%su", GET_MODE (x
) == SImode
? "l" : "q");
5710 output_operand_lossage ("invalid %%E value");
5716 /* Write "_u" for unaligned access. */
5717 if (GET_CODE (x
) == MEM
&& GET_CODE (XEXP (x
, 0)) == AND
)
5718 fprintf (file
, "_u");
5722 if (GET_CODE (x
) == REG
)
5723 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
5724 else if (GET_CODE (x
) == MEM
)
5725 output_address (XEXP (x
, 0));
5726 else if (GET_CODE (x
) == CONST
&& GET_CODE (XEXP (x
, 0)) == UNSPEC
)
5728 switch (XINT (XEXP (x
, 0), 1))
5732 output_addr_const (file
, XVECEXP (XEXP (x
, 0), 0, 0));
5735 output_operand_lossage ("unknown relocation unspec");
5740 output_addr_const (file
, x
);
5744 output_operand_lossage ("invalid %%xn code");
5749 print_operand_address (FILE *file
, rtx addr
)
5752 HOST_WIDE_INT offset
= 0;
5754 if (GET_CODE (addr
) == AND
)
5755 addr
= XEXP (addr
, 0);
5757 if (GET_CODE (addr
) == PLUS
5758 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
5760 offset
= INTVAL (XEXP (addr
, 1));
5761 addr
= XEXP (addr
, 0);
5764 if (GET_CODE (addr
) == LO_SUM
)
5766 const char *reloc16
, *reloclo
;
5767 rtx op1
= XEXP (addr
, 1);
5769 if (GET_CODE (op1
) == CONST
&& GET_CODE (XEXP (op1
, 0)) == UNSPEC
)
5771 op1
= XEXP (op1
, 0);
5772 switch (XINT (op1
, 1))
5776 reloclo
= (alpha_tls_size
== 16 ? "dtprel" : "dtprello");
5780 reloclo
= (alpha_tls_size
== 16 ? "tprel" : "tprello");
5783 output_operand_lossage ("unknown relocation unspec");
5787 output_addr_const (file
, XVECEXP (op1
, 0, 0));
5792 reloclo
= "gprellow";
5793 output_addr_const (file
, op1
);
5797 fprintf (file
, "+" HOST_WIDE_INT_PRINT_DEC
, offset
);
5799 addr
= XEXP (addr
, 0);
5800 if (GET_CODE (addr
) == REG
)
5801 basereg
= REGNO (addr
);
5802 else if (GET_CODE (addr
) == SUBREG
5803 && GET_CODE (SUBREG_REG (addr
)) == REG
)
5804 basereg
= subreg_regno (addr
);
5808 fprintf (file
, "($%d)\t\t!%s", basereg
,
5809 (basereg
== 29 ? reloc16
: reloclo
));
5813 if (GET_CODE (addr
) == REG
)
5814 basereg
= REGNO (addr
);
5815 else if (GET_CODE (addr
) == SUBREG
5816 && GET_CODE (SUBREG_REG (addr
)) == REG
)
5817 basereg
= subreg_regno (addr
);
5818 else if (GET_CODE (addr
) == CONST_INT
)
5819 offset
= INTVAL (addr
);
5821 #if TARGET_ABI_OPEN_VMS
5822 else if (GET_CODE (addr
) == SYMBOL_REF
)
5824 fprintf (file
, "%s", XSTR (addr
, 0));
5827 else if (GET_CODE (addr
) == CONST
5828 && GET_CODE (XEXP (addr
, 0)) == PLUS
5829 && GET_CODE (XEXP (XEXP (addr
, 0), 0)) == SYMBOL_REF
)
5831 fprintf (file
, "%s+" HOST_WIDE_INT_PRINT_DEC
,
5832 XSTR (XEXP (XEXP (addr
, 0), 0), 0),
5833 INTVAL (XEXP (XEXP (addr
, 0), 1)));
5841 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
"($%d)", offset
, basereg
);
5844 /* Emit RTL insns to initialize the variable parts of a trampoline at
5845 TRAMP. FNADDR is an RTX for the address of the function's pure
5846 code. CXT is an RTX for the static chain value for the function.
5848 The three offset parameters are for the individual template's
5849 layout. A JMPOFS < 0 indicates that the trampoline does not
5850 contain instructions at all.
5852 We assume here that a function will be called many more times than
5853 its address is taken (e.g., it might be passed to qsort), so we
5854 take the trouble to initialize the "hint" field in the JMP insn.
5855 Note that the hint field is PC (new) + 4 * bits 13:0. */
5858 alpha_initialize_trampoline (rtx tramp
, rtx fnaddr
, rtx cxt
,
5859 int fnofs
, int cxtofs
, int jmpofs
)
5861 rtx temp
, temp1
, addr
;
5862 /* VMS really uses DImode pointers in memory at this point. */
5863 enum machine_mode mode
= TARGET_ABI_OPEN_VMS
? Pmode
: ptr_mode
;
5865 #ifdef POINTERS_EXTEND_UNSIGNED
5866 fnaddr
= convert_memory_address (mode
, fnaddr
);
5867 cxt
= convert_memory_address (mode
, cxt
);
5870 /* Store function address and CXT. */
5871 addr
= memory_address (mode
, plus_constant (tramp
, fnofs
));
5872 emit_move_insn (gen_rtx_MEM (mode
, addr
), fnaddr
);
5873 addr
= memory_address (mode
, plus_constant (tramp
, cxtofs
));
5874 emit_move_insn (gen_rtx_MEM (mode
, addr
), cxt
);
5876 /* This has been disabled since the hint only has a 32k range, and in
5877 no existing OS is the stack within 32k of the text segment. */
5878 if (0 && jmpofs
>= 0)
5880 /* Compute hint value. */
5881 temp
= force_operand (plus_constant (tramp
, jmpofs
+4), NULL_RTX
);
5882 temp
= expand_binop (DImode
, sub_optab
, fnaddr
, temp
, temp
, 1,
5884 temp
= expand_shift (RSHIFT_EXPR
, Pmode
, temp
,
5885 build_int_2 (2, 0), NULL_RTX
, 1);
5886 temp
= expand_and (SImode
, gen_lowpart (SImode
, temp
),
5887 GEN_INT (0x3fff), 0);
5889 /* Merge in the hint. */
5890 addr
= memory_address (SImode
, plus_constant (tramp
, jmpofs
));
5891 temp1
= force_reg (SImode
, gen_rtx_MEM (SImode
, addr
));
5892 temp1
= expand_and (SImode
, temp1
, GEN_INT (0xffffc000), NULL_RTX
);
5893 temp1
= expand_binop (SImode
, ior_optab
, temp1
, temp
, temp1
, 1,
5895 emit_move_insn (gen_rtx_MEM (SImode
, addr
), temp1
);
5898 #ifdef TRANSFER_FROM_TRAMPOLINE
5899 emit_library_call (init_one_libfunc ("__enable_execute_stack"),
5900 0, VOIDmode
, 1, tramp
, Pmode
);
5904 emit_insn (gen_imb ());
5907 /* Determine where to put an argument to a function.
5908 Value is zero to push the argument on the stack,
5909 or a hard register in which to store the argument.
5911 MODE is the argument's machine mode.
5912 TYPE is the data type of the argument (as a tree).
5913 This is null for libcalls where that information may
5915 CUM is a variable of type CUMULATIVE_ARGS which gives info about
5916 the preceding args and about the function being called.
5917 NAMED is nonzero if this argument is a named parameter
5918 (otherwise it is an extra parameter matching an ellipsis).
5920 On Alpha the first 6 words of args are normally in registers
5921 and the rest are pushed. */
5924 function_arg (CUMULATIVE_ARGS cum
, enum machine_mode mode
, tree type
,
5925 int named ATTRIBUTE_UNUSED
)
5930 /* Don't get confused and pass small structures in FP registers. */
5931 if (type
&& AGGREGATE_TYPE_P (type
))
5935 #ifdef ENABLE_CHECKING
5936 /* With alpha_split_complex_arg, we shouldn't see any raw complex
5938 if (COMPLEX_MODE_P (mode
))
5942 /* Set up defaults for FP operands passed in FP registers, and
5943 integral operands passed in integer registers. */
5944 if (TARGET_FPREGS
&& GET_MODE_CLASS (mode
) == MODE_FLOAT
)
5950 /* ??? Irritatingly, the definition of CUMULATIVE_ARGS is different for
5951 the three platforms, so we can't avoid conditional compilation. */
5952 #if TARGET_ABI_OPEN_VMS
5954 if (mode
== VOIDmode
)
5955 return alpha_arg_info_reg_val (cum
);
5957 num_args
= cum
.num_args
;
5958 if (num_args
>= 6 || MUST_PASS_IN_STACK (mode
, type
))
5961 #elif TARGET_ABI_UNICOSMK
5965 /* If this is the last argument, generate the call info word (CIW). */
5966 /* ??? We don't include the caller's line number in the CIW because
5967 I don't know how to determine it if debug infos are turned off. */
5968 if (mode
== VOIDmode
)
5977 for (i
= 0; i
< cum
.num_reg_words
&& i
< 5; i
++)
5978 if (cum
.reg_args_type
[i
])
5979 lo
|= (1 << (7 - i
));
5981 if (cum
.num_reg_words
== 6 && cum
.reg_args_type
[5])
5984 lo
|= cum
.num_reg_words
;
5986 #if HOST_BITS_PER_WIDE_INT == 32
5987 hi
= (cum
.num_args
<< 20) | cum
.num_arg_words
;
5989 lo
= lo
| ((HOST_WIDE_INT
) cum
.num_args
<< 52)
5990 | ((HOST_WIDE_INT
) cum
.num_arg_words
<< 32);
5993 ciw
= immed_double_const (lo
, hi
, DImode
);
5995 return gen_rtx_UNSPEC (DImode
, gen_rtvec (1, ciw
),
5996 UNSPEC_UMK_LOAD_CIW
);
5999 size
= ALPHA_ARG_SIZE (mode
, type
, named
);
6000 num_args
= cum
.num_reg_words
;
6001 if (MUST_PASS_IN_STACK (mode
, type
)
6002 || cum
.num_reg_words
+ size
> 6 || cum
.force_stack
)
6004 else if (type
&& TYPE_MODE (type
) == BLKmode
)
6008 reg1
= gen_rtx_REG (DImode
, num_args
+ 16);
6009 reg1
= gen_rtx_EXPR_LIST (DImode
, reg1
, const0_rtx
);
6011 /* The argument fits in two registers. Note that we still need to
6012 reserve a register for empty structures. */
6016 return gen_rtx_PARALLEL (mode
, gen_rtvec (1, reg1
));
6019 reg2
= gen_rtx_REG (DImode
, num_args
+ 17);
6020 reg2
= gen_rtx_EXPR_LIST (DImode
, reg2
, GEN_INT (8));
6021 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, reg1
, reg2
));
6025 #elif TARGET_ABI_OSF
6031 /* VOID is passed as a special flag for "last argument". */
6032 if (type
== void_type_node
)
6034 else if (MUST_PASS_IN_STACK (mode
, type
))
6036 else if (FUNCTION_ARG_PASS_BY_REFERENCE (cum
, mode
, type
, named
))
6040 #error Unhandled ABI
6043 return gen_rtx_REG (mode
, num_args
+ basereg
);
6046 /* Return true if TYPE must be returned in memory, instead of in registers. */
6049 alpha_return_in_memory (tree type
, tree fndecl ATTRIBUTE_UNUSED
)
6051 enum machine_mode mode
= VOIDmode
;
6056 mode
= TYPE_MODE (type
);
6058 /* All aggregates are returned in memory. */
6059 if (AGGREGATE_TYPE_P (type
))
6063 size
= GET_MODE_SIZE (mode
);
6064 switch (GET_MODE_CLASS (mode
))
6066 case MODE_VECTOR_FLOAT
:
6067 /* Pass all float vectors in memory, like an aggregate. */
6070 case MODE_COMPLEX_FLOAT
:
6071 /* We judge complex floats on the size of their element,
6072 not the size of the whole type. */
6073 size
= GET_MODE_UNIT_SIZE (mode
);
6078 case MODE_COMPLEX_INT
:
6079 case MODE_VECTOR_INT
:
6083 /* ??? We get called on all sorts of random stuff from
6084 aggregate_value_p. We can't abort, but it's not clear
6085 what's safe to return. Pretend it's a struct I guess. */
6089 /* Otherwise types must fit in one register. */
6090 return size
> UNITS_PER_WORD
;
6093 /* Define how to find the value returned by a function. VALTYPE is the
6094 data type of the value (as a tree). If the precise function being
6095 called is known, FUNC is its FUNCTION_DECL; otherwise, FUNC is 0.
6096 MODE is set instead of VALTYPE for libcalls.
6098 On Alpha the value is found in $0 for integer functions and
6099 $f0 for floating-point functions. */
6102 function_value (tree valtype
, tree func ATTRIBUTE_UNUSED
,
6103 enum machine_mode mode
)
6105 unsigned int regnum
;
6106 enum mode_class
class;
6108 #ifdef ENABLE_CHECKING
6109 if (valtype
&& alpha_return_in_memory (valtype
, func
))
6114 mode
= TYPE_MODE (valtype
);
6116 class = GET_MODE_CLASS (mode
);
6120 /* Do the same thing as PROMOTE_MODE. */
6124 case MODE_COMPLEX_INT
:
6125 case MODE_VECTOR_INT
:
6133 case MODE_COMPLEX_FLOAT
:
6135 enum machine_mode cmode
= GET_MODE_INNER (mode
);
6137 return gen_rtx_PARALLEL
6140 gen_rtx_EXPR_LIST (VOIDmode
, gen_rtx_REG (cmode
, 32),
6142 gen_rtx_EXPR_LIST (VOIDmode
, gen_rtx_REG (cmode
, 33),
6143 GEN_INT (GET_MODE_SIZE (cmode
)))));
6150 return gen_rtx_REG (mode
, regnum
);
6153 /* TCmode complex values are passed by invisible reference. We
6154 should not split these values. */
6157 alpha_split_complex_arg (tree type
)
6159 return TYPE_MODE (type
) != TCmode
;
6163 alpha_build_builtin_va_list (void)
6165 tree base
, ofs
, space
, record
, type_decl
;
6167 if (TARGET_ABI_OPEN_VMS
|| TARGET_ABI_UNICOSMK
)
6168 return ptr_type_node
;
6170 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
6171 type_decl
= build_decl (TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
6172 TREE_CHAIN (record
) = type_decl
;
6173 TYPE_NAME (record
) = type_decl
;
6175 /* C++? SET_IS_AGGR_TYPE (record, 1); */
6177 /* Dummy field to prevent alignment warnings. */
6178 space
= build_decl (FIELD_DECL
, NULL_TREE
, integer_type_node
);
6179 DECL_FIELD_CONTEXT (space
) = record
;
6180 DECL_ARTIFICIAL (space
) = 1;
6181 DECL_IGNORED_P (space
) = 1;
6183 ofs
= build_decl (FIELD_DECL
, get_identifier ("__offset"),
6185 DECL_FIELD_CONTEXT (ofs
) = record
;
6186 TREE_CHAIN (ofs
) = space
;
6188 base
= build_decl (FIELD_DECL
, get_identifier ("__base"),
6190 DECL_FIELD_CONTEXT (base
) = record
;
6191 TREE_CHAIN (base
) = ofs
;
6193 TYPE_FIELDS (record
) = base
;
6194 layout_type (record
);
6199 /* Perform any needed actions needed for a function that is receiving a
6200 variable number of arguments. */
6203 alpha_setup_incoming_varargs (CUMULATIVE_ARGS
*pcum
,
6204 enum machine_mode mode ATTRIBUTE_UNUSED
,
6205 tree type ATTRIBUTE_UNUSED
,
6206 int *pretend_size
, int no_rtl
)
6208 #if TARGET_ABI_UNICOSMK
6209 /* On Unicos/Mk, the standard subroutine __T3E_MISMATCH stores all register
6210 arguments on the stack. Unfortunately, it doesn't always store the first
6211 one (i.e. the one that arrives in $16 or $f16). This is not a problem
6212 with stdargs as we always have at least one named argument there. */
6213 int num_reg_words
= pcum
->num_reg_words
;
6214 if (num_reg_words
< 6)
6218 emit_insn (gen_umk_mismatch_args (GEN_INT (num_reg_words
+ 1)));
6219 emit_insn (gen_arg_home_umk ());
6223 #elif TARGET_ABI_OPEN_VMS
6224 /* For VMS, we allocate space for all 6 arg registers plus a count.
6226 However, if NO registers need to be saved, don't allocate any space.
6227 This is not only because we won't need the space, but because AP
6228 includes the current_pretend_args_size and we don't want to mess up
6229 any ap-relative addresses already made. */
6230 if (pcum
->num_args
< 6)
6234 emit_move_insn (gen_rtx_REG (DImode
, 1), virtual_incoming_args_rtx
);
6235 emit_insn (gen_arg_home ());
6237 *pretend_size
= 7 * UNITS_PER_WORD
;
6240 /* On OSF/1 and friends, we allocate space for all 12 arg registers, but
6241 only push those that are remaining. However, if NO registers need to
6242 be saved, don't allocate any space. This is not only because we won't
6243 need the space, but because AP includes the current_pretend_args_size
6244 and we don't want to mess up any ap-relative addresses already made.
6246 If we are not to use the floating-point registers, save the integer
6247 registers where we would put the floating-point registers. This is
6248 not the most efficient way to implement varargs with just one register
6249 class, but it isn't worth doing anything more efficient in this rare
6251 CUMULATIVE_ARGS cum
= *pcum
;
6258 int set
= get_varargs_alias_set ();
6261 tmp
= gen_rtx_MEM (BLKmode
,
6262 plus_constant (virtual_incoming_args_rtx
,
6263 (cum
+ 6) * UNITS_PER_WORD
));
6264 set_mem_alias_set (tmp
, set
);
6265 move_block_from_reg (16 + cum
, tmp
, 6 - cum
);
6267 tmp
= gen_rtx_MEM (BLKmode
,
6268 plus_constant (virtual_incoming_args_rtx
,
6269 cum
* UNITS_PER_WORD
));
6270 set_mem_alias_set (tmp
, set
);
6271 move_block_from_reg (16 + (TARGET_FPREGS
? 32 : 0) + cum
, tmp
,
6274 *pretend_size
= 12 * UNITS_PER_WORD
;
6279 alpha_va_start (tree valist
, rtx nextarg ATTRIBUTE_UNUSED
)
6281 HOST_WIDE_INT offset
;
6282 tree t
, offset_field
, base_field
;
6284 if (TREE_CODE (TREE_TYPE (valist
)) == ERROR_MARK
)
6287 if (TARGET_ABI_UNICOSMK
)
6288 std_expand_builtin_va_start (valist
, nextarg
);
6290 /* For Unix, TARGET_SETUP_INCOMING_VARARGS moves the starting address base
6291 up by 48, storing fp arg registers in the first 48 bytes, and the
6292 integer arg registers in the next 48 bytes. This is only done,
6293 however, if any integer registers need to be stored.
6295 If no integer registers need be stored, then we must subtract 48
6296 in order to account for the integer arg registers which are counted
6297 in argsize above, but which are not actually stored on the stack.
6298 Must further be careful here about structures straddling the last
6299 integer argument register; that futzes with pretend_args_size,
6300 which changes the meaning of AP. */
6303 offset
= TARGET_ABI_OPEN_VMS
? UNITS_PER_WORD
: 6 * UNITS_PER_WORD
;
6305 offset
= -6 * UNITS_PER_WORD
+ current_function_pretend_args_size
;
6307 if (TARGET_ABI_OPEN_VMS
)
6309 nextarg
= plus_constant (nextarg
, offset
);
6310 nextarg
= plus_constant (nextarg
, NUM_ARGS
* UNITS_PER_WORD
);
6311 t
= build (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
6312 make_tree (ptr_type_node
, nextarg
));
6313 TREE_SIDE_EFFECTS (t
) = 1;
6315 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6319 base_field
= TYPE_FIELDS (TREE_TYPE (valist
));
6320 offset_field
= TREE_CHAIN (base_field
);
6322 base_field
= build (COMPONENT_REF
, TREE_TYPE (base_field
),
6323 valist
, base_field
, NULL_TREE
);
6324 offset_field
= build (COMPONENT_REF
, TREE_TYPE (offset_field
),
6325 valist
, offset_field
, NULL_TREE
);
6327 t
= make_tree (ptr_type_node
, virtual_incoming_args_rtx
);
6328 t
= build (PLUS_EXPR
, ptr_type_node
, t
, build_int_2 (offset
, 0));
6329 t
= build (MODIFY_EXPR
, TREE_TYPE (base_field
), base_field
, t
);
6330 TREE_SIDE_EFFECTS (t
) = 1;
6331 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6333 t
= build_int_2 (NUM_ARGS
* UNITS_PER_WORD
, 0);
6334 t
= build (MODIFY_EXPR
, TREE_TYPE (offset_field
), offset_field
, t
);
6335 TREE_SIDE_EFFECTS (t
) = 1;
6336 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6341 alpha_gimplify_va_arg_1 (tree type
, tree base
, tree offset
, tree
*pre_p
)
6343 tree type_size
, ptr_type
, addend
, t
, addr
, internal_post
;
6346 /* If the type could not be passed in registers, skip the block
6347 reserved for the registers. */
6348 if (MUST_PASS_IN_STACK (TYPE_MODE (type
), type
))
6350 t
= fold_convert (TREE_TYPE (offset
), build_int_2 (6*8, 0));
6351 t
= build (MODIFY_EXPR
, TREE_TYPE (offset
), offset
,
6352 build (MAX_EXPR
, TREE_TYPE (offset
), offset
, t
));
6353 gimplify_and_add (t
, pre_p
);
6357 ptr_type
= build_pointer_type (type
);
6360 if (TYPE_MODE (type
) == TFmode
|| TYPE_MODE (type
) == TCmode
)
6363 ptr_type
= build_pointer_type (type
);
6366 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
6368 tree real_part
, imag_part
, real_temp
;
6370 real_part
= alpha_gimplify_va_arg_1 (TREE_TYPE (type
), base
,
6373 /* Copy the value into a new temporary, lest the formal temporary
6374 be reused out from under us. */
6375 real_temp
= get_initialized_tmp_var (real_part
, pre_p
, NULL
);
6377 imag_part
= alpha_gimplify_va_arg_1 (TREE_TYPE (type
), base
,
6380 return build (COMPLEX_EXPR
, type
, real_temp
, imag_part
);
6382 else if (TREE_CODE (type
) == REAL_TYPE
)
6384 tree fpaddend
, cond
, fourtyeight
;
6386 fourtyeight
= fold_convert (TREE_TYPE (addend
), build_int_2 (6*8, 0));
6387 fpaddend
= fold (build (MINUS_EXPR
, TREE_TYPE (addend
),
6388 addend
, fourtyeight
));
6389 cond
= fold (build (LT_EXPR
, boolean_type_node
, addend
, fourtyeight
));
6390 addend
= fold (build (COND_EXPR
, TREE_TYPE (addend
), cond
,
6394 /* Build the final address and force that value into a temporary. */
6395 addr
= build (PLUS_EXPR
, ptr_type
, fold_convert (ptr_type
, base
),
6396 fold_convert (ptr_type
, addend
));
6398 addr
= build (INDIRECT_REF
, type
, addr
);
6399 internal_post
= NULL
;
6400 gimplify_expr (&addr
, pre_p
, &internal_post
, is_gimple_val
, fb_rvalue
);
6401 append_to_statement_list (internal_post
, pre_p
);
6403 /* Update the offset field. */
6404 type_size
= TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type
));
6405 if (type_size
== NULL
|| TREE_OVERFLOW (type_size
))
6409 t
= size_binop (PLUS_EXPR
, type_size
, size_int (7));
6410 t
= size_binop (TRUNC_DIV_EXPR
, t
, size_int (8));
6411 t
= size_binop (MULT_EXPR
, t
, size_int (8));
6413 t
= fold_convert (TREE_TYPE (offset
), t
);
6414 t
= build (MODIFY_EXPR
, void_type_node
, offset
,
6415 build (PLUS_EXPR
, TREE_TYPE (offset
), offset
, t
));
6416 gimplify_and_add (t
, pre_p
);
6418 return build_fold_indirect_ref (addr
);
6422 alpha_gimplify_va_arg (tree valist
, tree type
, tree
*pre_p
, tree
*post_p
)
6424 tree offset_field
, base_field
, offset
, base
, t
, r
;
6426 if (TARGET_ABI_OPEN_VMS
|| TARGET_ABI_UNICOSMK
)
6427 return std_gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
6429 base_field
= TYPE_FIELDS (va_list_type_node
);
6430 offset_field
= TREE_CHAIN (base_field
);
6431 base_field
= build (COMPONENT_REF
, TREE_TYPE (base_field
),
6432 valist
, base_field
, NULL_TREE
);
6433 offset_field
= build (COMPONENT_REF
, TREE_TYPE (offset_field
),
6434 valist
, offset_field
, NULL_TREE
);
6436 /* Pull the fields of the structure out into temporaries. Since we never
6437 modify the base field, we can use a formal temporary. Sign-extend the
6438 offset field so that it's the proper width for pointer arithmetic. */
6439 base
= get_formal_tmp_var (base_field
, pre_p
);
6441 t
= fold_convert (lang_hooks
.types
.type_for_size (64, 0), offset_field
);
6442 offset
= get_initialized_tmp_var (t
, pre_p
, NULL
);
6444 /* Find the value. Note that this will be a stable indirection, or
6445 a composite of stable indirections in the case of complex. */
6446 r
= alpha_gimplify_va_arg_1 (type
, base
, offset
, pre_p
);
6448 /* Stuff the offset temporary back into its field. */
6449 t
= build (MODIFY_EXPR
, void_type_node
, offset_field
,
6450 fold_convert (TREE_TYPE (offset_field
), offset
));
6451 gimplify_and_add (t
, pre_p
);
6460 ALPHA_BUILTIN_CMPBGE
,
6461 ALPHA_BUILTIN_EXTBL
,
6462 ALPHA_BUILTIN_EXTWL
,
6463 ALPHA_BUILTIN_EXTLL
,
6464 ALPHA_BUILTIN_EXTQL
,
6465 ALPHA_BUILTIN_EXTWH
,
6466 ALPHA_BUILTIN_EXTLH
,
6467 ALPHA_BUILTIN_EXTQH
,
6468 ALPHA_BUILTIN_INSBL
,
6469 ALPHA_BUILTIN_INSWL
,
6470 ALPHA_BUILTIN_INSLL
,
6471 ALPHA_BUILTIN_INSQL
,
6472 ALPHA_BUILTIN_INSWH
,
6473 ALPHA_BUILTIN_INSLH
,
6474 ALPHA_BUILTIN_INSQH
,
6475 ALPHA_BUILTIN_MSKBL
,
6476 ALPHA_BUILTIN_MSKWL
,
6477 ALPHA_BUILTIN_MSKLL
,
6478 ALPHA_BUILTIN_MSKQL
,
6479 ALPHA_BUILTIN_MSKWH
,
6480 ALPHA_BUILTIN_MSKLH
,
6481 ALPHA_BUILTIN_MSKQH
,
6482 ALPHA_BUILTIN_UMULH
,
6484 ALPHA_BUILTIN_ZAPNOT
,
6485 ALPHA_BUILTIN_AMASK
,
6486 ALPHA_BUILTIN_IMPLVER
,
6488 ALPHA_BUILTIN_THREAD_POINTER
,
6489 ALPHA_BUILTIN_SET_THREAD_POINTER
,
6492 ALPHA_BUILTIN_MINUB8
,
6493 ALPHA_BUILTIN_MINSB8
,
6494 ALPHA_BUILTIN_MINUW4
,
6495 ALPHA_BUILTIN_MINSW4
,
6496 ALPHA_BUILTIN_MAXUB8
,
6497 ALPHA_BUILTIN_MAXSB8
,
6498 ALPHA_BUILTIN_MAXUW4
,
6499 ALPHA_BUILTIN_MAXSW4
,
6503 ALPHA_BUILTIN_UNPKBL
,
6504 ALPHA_BUILTIN_UNPKBW
,
6509 ALPHA_BUILTIN_CTPOP
,
6514 static unsigned int const code_for_builtin
[ALPHA_BUILTIN_max
] = {
6515 CODE_FOR_builtin_cmpbge
,
6516 CODE_FOR_builtin_extbl
,
6517 CODE_FOR_builtin_extwl
,
6518 CODE_FOR_builtin_extll
,
6519 CODE_FOR_builtin_extql
,
6520 CODE_FOR_builtin_extwh
,
6521 CODE_FOR_builtin_extlh
,
6522 CODE_FOR_builtin_extqh
,
6523 CODE_FOR_builtin_insbl
,
6524 CODE_FOR_builtin_inswl
,
6525 CODE_FOR_builtin_insll
,
6526 CODE_FOR_builtin_insql
,
6527 CODE_FOR_builtin_inswh
,
6528 CODE_FOR_builtin_inslh
,
6529 CODE_FOR_builtin_insqh
,
6530 CODE_FOR_builtin_mskbl
,
6531 CODE_FOR_builtin_mskwl
,
6532 CODE_FOR_builtin_mskll
,
6533 CODE_FOR_builtin_mskql
,
6534 CODE_FOR_builtin_mskwh
,
6535 CODE_FOR_builtin_msklh
,
6536 CODE_FOR_builtin_mskqh
,
6537 CODE_FOR_umuldi3_highpart
,
6538 CODE_FOR_builtin_zap
,
6539 CODE_FOR_builtin_zapnot
,
6540 CODE_FOR_builtin_amask
,
6541 CODE_FOR_builtin_implver
,
6542 CODE_FOR_builtin_rpcc
,
6547 CODE_FOR_builtin_minub8
,
6548 CODE_FOR_builtin_minsb8
,
6549 CODE_FOR_builtin_minuw4
,
6550 CODE_FOR_builtin_minsw4
,
6551 CODE_FOR_builtin_maxub8
,
6552 CODE_FOR_builtin_maxsb8
,
6553 CODE_FOR_builtin_maxuw4
,
6554 CODE_FOR_builtin_maxsw4
,
6555 CODE_FOR_builtin_perr
,
6556 CODE_FOR_builtin_pklb
,
6557 CODE_FOR_builtin_pkwb
,
6558 CODE_FOR_builtin_unpkbl
,
6559 CODE_FOR_builtin_unpkbw
,
6562 CODE_FOR_builtin_cttz
,
6563 CODE_FOR_builtin_ctlz
,
6564 CODE_FOR_builtin_ctpop
6567 struct alpha_builtin_def
6570 enum alpha_builtin code
;
6571 unsigned int target_mask
;
6574 static struct alpha_builtin_def
const zero_arg_builtins
[] = {
6575 { "__builtin_alpha_implver", ALPHA_BUILTIN_IMPLVER
, 0 },
6576 { "__builtin_alpha_rpcc", ALPHA_BUILTIN_RPCC
, 0 }
6579 static struct alpha_builtin_def
const one_arg_builtins
[] = {
6580 { "__builtin_alpha_amask", ALPHA_BUILTIN_AMASK
, 0 },
6581 { "__builtin_alpha_pklb", ALPHA_BUILTIN_PKLB
, MASK_MAX
},
6582 { "__builtin_alpha_pkwb", ALPHA_BUILTIN_PKWB
, MASK_MAX
},
6583 { "__builtin_alpha_unpkbl", ALPHA_BUILTIN_UNPKBL
, MASK_MAX
},
6584 { "__builtin_alpha_unpkbw", ALPHA_BUILTIN_UNPKBW
, MASK_MAX
},
6585 { "__builtin_alpha_cttz", ALPHA_BUILTIN_CTTZ
, MASK_CIX
},
6586 { "__builtin_alpha_ctlz", ALPHA_BUILTIN_CTLZ
, MASK_CIX
},
6587 { "__builtin_alpha_ctpop", ALPHA_BUILTIN_CTPOP
, MASK_CIX
}
6590 static struct alpha_builtin_def
const two_arg_builtins
[] = {
6591 { "__builtin_alpha_cmpbge", ALPHA_BUILTIN_CMPBGE
, 0 },
6592 { "__builtin_alpha_extbl", ALPHA_BUILTIN_EXTBL
, 0 },
6593 { "__builtin_alpha_extwl", ALPHA_BUILTIN_EXTWL
, 0 },
6594 { "__builtin_alpha_extll", ALPHA_BUILTIN_EXTLL
, 0 },
6595 { "__builtin_alpha_extql", ALPHA_BUILTIN_EXTQL
, 0 },
6596 { "__builtin_alpha_extwh", ALPHA_BUILTIN_EXTWH
, 0 },
6597 { "__builtin_alpha_extlh", ALPHA_BUILTIN_EXTLH
, 0 },
6598 { "__builtin_alpha_extqh", ALPHA_BUILTIN_EXTQH
, 0 },
6599 { "__builtin_alpha_insbl", ALPHA_BUILTIN_INSBL
, 0 },
6600 { "__builtin_alpha_inswl", ALPHA_BUILTIN_INSWL
, 0 },
6601 { "__builtin_alpha_insll", ALPHA_BUILTIN_INSLL
, 0 },
6602 { "__builtin_alpha_insql", ALPHA_BUILTIN_INSQL
, 0 },
6603 { "__builtin_alpha_inswh", ALPHA_BUILTIN_INSWH
, 0 },
6604 { "__builtin_alpha_inslh", ALPHA_BUILTIN_INSLH
, 0 },
6605 { "__builtin_alpha_insqh", ALPHA_BUILTIN_INSQH
, 0 },
6606 { "__builtin_alpha_mskbl", ALPHA_BUILTIN_MSKBL
, 0 },
6607 { "__builtin_alpha_mskwl", ALPHA_BUILTIN_MSKWL
, 0 },
6608 { "__builtin_alpha_mskll", ALPHA_BUILTIN_MSKLL
, 0 },
6609 { "__builtin_alpha_mskql", ALPHA_BUILTIN_MSKQL
, 0 },
6610 { "__builtin_alpha_mskwh", ALPHA_BUILTIN_MSKWH
, 0 },
6611 { "__builtin_alpha_msklh", ALPHA_BUILTIN_MSKLH
, 0 },
6612 { "__builtin_alpha_mskqh", ALPHA_BUILTIN_MSKQH
, 0 },
6613 { "__builtin_alpha_umulh", ALPHA_BUILTIN_UMULH
, 0 },
6614 { "__builtin_alpha_zap", ALPHA_BUILTIN_ZAP
, 0 },
6615 { "__builtin_alpha_zapnot", ALPHA_BUILTIN_ZAPNOT
, 0 },
6616 { "__builtin_alpha_minub8", ALPHA_BUILTIN_MINUB8
, MASK_MAX
},
6617 { "__builtin_alpha_minsb8", ALPHA_BUILTIN_MINSB8
, MASK_MAX
},
6618 { "__builtin_alpha_minuw4", ALPHA_BUILTIN_MINUW4
, MASK_MAX
},
6619 { "__builtin_alpha_minsw4", ALPHA_BUILTIN_MINSW4
, MASK_MAX
},
6620 { "__builtin_alpha_maxub8", ALPHA_BUILTIN_MAXUB8
, MASK_MAX
},
6621 { "__builtin_alpha_maxsb8", ALPHA_BUILTIN_MAXSB8
, MASK_MAX
},
6622 { "__builtin_alpha_maxuw4", ALPHA_BUILTIN_MAXUW4
, MASK_MAX
},
6623 { "__builtin_alpha_maxsw4", ALPHA_BUILTIN_MAXSW4
, MASK_MAX
},
6624 { "__builtin_alpha_perr", ALPHA_BUILTIN_PERR
, MASK_MAX
}
6628 alpha_init_builtins (void)
6630 const struct alpha_builtin_def
*p
;
6634 ftype
= build_function_type (long_integer_type_node
, void_list_node
);
6636 p
= zero_arg_builtins
;
6637 for (i
= 0; i
< ARRAY_SIZE (zero_arg_builtins
); ++i
, ++p
)
6638 if ((target_flags
& p
->target_mask
) == p
->target_mask
)
6639 builtin_function (p
->name
, ftype
, p
->code
, BUILT_IN_MD
,
6642 ftype
= build_function_type_list (long_integer_type_node
,
6643 long_integer_type_node
, NULL_TREE
);
6645 p
= one_arg_builtins
;
6646 for (i
= 0; i
< ARRAY_SIZE (one_arg_builtins
); ++i
, ++p
)
6647 if ((target_flags
& p
->target_mask
) == p
->target_mask
)
6648 builtin_function (p
->name
, ftype
, p
->code
, BUILT_IN_MD
,
6651 ftype
= build_function_type_list (long_integer_type_node
,
6652 long_integer_type_node
,
6653 long_integer_type_node
, NULL_TREE
);
6655 p
= two_arg_builtins
;
6656 for (i
= 0; i
< ARRAY_SIZE (two_arg_builtins
); ++i
, ++p
)
6657 if ((target_flags
& p
->target_mask
) == p
->target_mask
)
6658 builtin_function (p
->name
, ftype
, p
->code
, BUILT_IN_MD
,
6661 ftype
= build_function_type (ptr_type_node
, void_list_node
);
6662 builtin_function ("__builtin_thread_pointer", ftype
,
6663 ALPHA_BUILTIN_THREAD_POINTER
, BUILT_IN_MD
,
6666 ftype
= build_function_type_list (void_type_node
, ptr_type_node
, NULL_TREE
);
6667 builtin_function ("__builtin_set_thread_pointer", ftype
,
6668 ALPHA_BUILTIN_SET_THREAD_POINTER
, BUILT_IN_MD
,
6672 /* Expand an expression EXP that calls a built-in function,
6673 with result going to TARGET if that's convenient
6674 (and in mode MODE if that's convenient).
6675 SUBTARGET may be used as the target for computing one of EXP's operands.
6676 IGNORE is nonzero if the value is to be ignored. */
6679 alpha_expand_builtin (tree exp
, rtx target
,
6680 rtx subtarget ATTRIBUTE_UNUSED
,
6681 enum machine_mode mode ATTRIBUTE_UNUSED
,
6682 int ignore ATTRIBUTE_UNUSED
)
6686 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
6687 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
6688 tree arglist
= TREE_OPERAND (exp
, 1);
6689 enum insn_code icode
;
6690 rtx op
[MAX_ARGS
], pat
;
6694 if (fcode
>= ALPHA_BUILTIN_max
)
6695 internal_error ("bad builtin fcode");
6696 icode
= code_for_builtin
[fcode
];
6698 internal_error ("bad builtin fcode");
6700 nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
6702 for (arglist
= TREE_OPERAND (exp
, 1), arity
= 0;
6704 arglist
= TREE_CHAIN (arglist
), arity
++)
6706 const struct insn_operand_data
*insn_op
;
6708 tree arg
= TREE_VALUE (arglist
);
6709 if (arg
== error_mark_node
)
6711 if (arity
> MAX_ARGS
)
6714 insn_op
= &insn_data
[icode
].operand
[arity
+ nonvoid
];
6716 op
[arity
] = expand_expr (arg
, NULL_RTX
, insn_op
->mode
, 0);
6718 if (!(*insn_op
->predicate
) (op
[arity
], insn_op
->mode
))
6719 op
[arity
] = copy_to_mode_reg (insn_op
->mode
, op
[arity
]);
6724 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6726 || GET_MODE (target
) != tmode
6727 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6728 target
= gen_reg_rtx (tmode
);
6734 pat
= GEN_FCN (icode
) (target
);
6738 pat
= GEN_FCN (icode
) (target
, op
[0]);
6740 pat
= GEN_FCN (icode
) (op
[0]);
6743 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
6758 /* This page contains routines that are used to determine what the function
6759 prologue and epilogue code will do and write them out. */
6761 /* Compute the size of the save area in the stack. */
6763 /* These variables are used for communication between the following functions.
6764 They indicate various things about the current function being compiled
6765 that are used to tell what kind of prologue, epilogue and procedure
6766 descriptor to generate. */
6768 /* Nonzero if we need a stack procedure. */
6769 enum alpha_procedure_types
{PT_NULL
= 0, PT_REGISTER
= 1, PT_STACK
= 2};
6770 static enum alpha_procedure_types alpha_procedure_type
;
6772 /* Register number (either FP or SP) that is used to unwind the frame. */
6773 static int vms_unwind_regno
;
6775 /* Register number used to save FP. We need not have one for RA since
6776 we don't modify it for register procedures. This is only defined
6777 for register frame procedures. */
6778 static int vms_save_fp_regno
;
6780 /* Register number used to reference objects off our PV. */
6781 static int vms_base_regno
;
6783 /* Compute register masks for saved registers. */
6786 alpha_sa_mask (unsigned long *imaskP
, unsigned long *fmaskP
)
6788 unsigned long imask
= 0;
6789 unsigned long fmask
= 0;
6792 /* When outputting a thunk, we don't have valid register life info,
6793 but assemble_start_function wants to output .frame and .mask
6795 if (current_function_is_thunk
)
6802 if (TARGET_ABI_OPEN_VMS
&& alpha_procedure_type
== PT_STACK
)
6803 imask
|= (1UL << HARD_FRAME_POINTER_REGNUM
);
6805 /* One for every register we have to save. */
6806 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
6807 if (! fixed_regs
[i
] && ! call_used_regs
[i
]
6808 && regs_ever_live
[i
] && i
!= REG_RA
6809 && (!TARGET_ABI_UNICOSMK
|| i
!= HARD_FRAME_POINTER_REGNUM
))
6812 imask
|= (1UL << i
);
6814 fmask
|= (1UL << (i
- 32));
6817 /* We need to restore these for the handler. */
6818 if (current_function_calls_eh_return
)
6822 unsigned regno
= EH_RETURN_DATA_REGNO (i
);
6823 if (regno
== INVALID_REGNUM
)
6825 imask
|= 1UL << regno
;
6828 /* Glibc likes to use $31 as an unwind stopper for crt0. To
6829 avoid hackery in unwind-dw2.c, we need to actively store a
6830 zero in the prologue of _Unwind_RaiseException et al. */
6834 /* If any register spilled, then spill the return address also. */
6835 /* ??? This is required by the Digital stack unwind specification
6836 and isn't needed if we're doing Dwarf2 unwinding. */
6837 if (imask
|| fmask
|| alpha_ra_ever_killed ())
6838 imask
|= (1UL << REG_RA
);
6845 alpha_sa_size (void)
6847 unsigned long mask
[2];
6851 alpha_sa_mask (&mask
[0], &mask
[1]);
6853 if (TARGET_ABI_UNICOSMK
)
6855 if (mask
[0] || mask
[1])
6860 for (j
= 0; j
< 2; ++j
)
6861 for (i
= 0; i
< 32; ++i
)
6862 if ((mask
[j
] >> i
) & 1)
6866 if (TARGET_ABI_UNICOSMK
)
6868 /* We might not need to generate a frame if we don't make any calls
6869 (including calls to __T3E_MISMATCH if this is a vararg function),
6870 don't have any local variables which require stack slots, don't
6871 use alloca and have not determined that we need a frame for other
6874 alpha_procedure_type
6875 = (sa_size
|| get_frame_size() != 0
6876 || current_function_outgoing_args_size
6877 || current_function_stdarg
|| current_function_calls_alloca
6878 || frame_pointer_needed
)
6879 ? PT_STACK
: PT_REGISTER
;
6881 /* Always reserve space for saving callee-saved registers if we
6882 need a frame as required by the calling convention. */
6883 if (alpha_procedure_type
== PT_STACK
)
6886 else if (TARGET_ABI_OPEN_VMS
)
6888 /* Start by assuming we can use a register procedure if we don't
6889 make any calls (REG_RA not used) or need to save any
6890 registers and a stack procedure if we do. */
6891 if ((mask
[0] >> REG_RA
) & 1)
6892 alpha_procedure_type
= PT_STACK
;
6893 else if (get_frame_size() != 0)
6894 alpha_procedure_type
= PT_REGISTER
;
6896 alpha_procedure_type
= PT_NULL
;
6898 /* Don't reserve space for saving FP & RA yet. Do that later after we've
6899 made the final decision on stack procedure vs register procedure. */
6900 if (alpha_procedure_type
== PT_STACK
)
6903 /* Decide whether to refer to objects off our PV via FP or PV.
6904 If we need FP for something else or if we receive a nonlocal
6905 goto (which expects PV to contain the value), we must use PV.
6906 Otherwise, start by assuming we can use FP. */
6909 = (frame_pointer_needed
6910 || current_function_has_nonlocal_label
6911 || alpha_procedure_type
== PT_STACK
6912 || current_function_outgoing_args_size
)
6913 ? REG_PV
: HARD_FRAME_POINTER_REGNUM
;
6915 /* If we want to copy PV into FP, we need to find some register
6916 in which to save FP. */
6918 vms_save_fp_regno
= -1;
6919 if (vms_base_regno
== HARD_FRAME_POINTER_REGNUM
)
6920 for (i
= 0; i
< 32; i
++)
6921 if (! fixed_regs
[i
] && call_used_regs
[i
] && ! regs_ever_live
[i
])
6922 vms_save_fp_regno
= i
;
6924 if (vms_save_fp_regno
== -1 && alpha_procedure_type
== PT_REGISTER
)
6925 vms_base_regno
= REG_PV
, alpha_procedure_type
= PT_STACK
;
6926 else if (alpha_procedure_type
== PT_NULL
)
6927 vms_base_regno
= REG_PV
;
6929 /* Stack unwinding should be done via FP unless we use it for PV. */
6930 vms_unwind_regno
= (vms_base_regno
== REG_PV
6931 ? HARD_FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM
);
6933 /* If this is a stack procedure, allow space for saving FP and RA. */
6934 if (alpha_procedure_type
== PT_STACK
)
6939 /* Our size must be even (multiple of 16 bytes). */
6947 /* Define the offset between two registers, one to be eliminated,
6948 and the other its replacement, at the start of a routine. */
6951 alpha_initial_elimination_offset (unsigned int from
,
6952 unsigned int to ATTRIBUTE_UNUSED
)
6956 ret
= alpha_sa_size ();
6957 ret
+= ALPHA_ROUND (current_function_outgoing_args_size
);
6959 if (from
== FRAME_POINTER_REGNUM
)
6961 else if (from
== ARG_POINTER_REGNUM
)
6962 ret
+= (ALPHA_ROUND (get_frame_size ()
6963 + current_function_pretend_args_size
)
6964 - current_function_pretend_args_size
);
6972 alpha_pv_save_size (void)
6975 return alpha_procedure_type
== PT_STACK
? 8 : 0;
6979 alpha_using_fp (void)
6982 return vms_unwind_regno
== HARD_FRAME_POINTER_REGNUM
;
6985 #if TARGET_ABI_OPEN_VMS
6987 const struct attribute_spec vms_attribute_table
[] =
6989 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
6990 { "overlaid", 0, 0, true, false, false, NULL
},
6991 { "global", 0, 0, true, false, false, NULL
},
6992 { "initialize", 0, 0, true, false, false, NULL
},
6993 { NULL
, 0, 0, false, false, false, NULL
}
6999 find_lo_sum_using_gp (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
7001 return GET_CODE (*px
) == LO_SUM
&& XEXP (*px
, 0) == pic_offset_table_rtx
;
7005 alpha_find_lo_sum_using_gp (rtx insn
)
7007 return for_each_rtx (&PATTERN (insn
), find_lo_sum_using_gp
, NULL
) > 0;
7011 alpha_does_function_need_gp (void)
7015 /* The GP being variable is an OSF abi thing. */
7016 if (! TARGET_ABI_OSF
)
7019 /* We need the gp to load the address of __mcount. */
7020 if (TARGET_PROFILING_NEEDS_GP
&& current_function_profile
)
7023 /* The code emitted by alpha_output_mi_thunk_osf uses the gp. */
7024 if (current_function_is_thunk
)
7027 /* The nonlocal receiver pattern assumes that the gp is valid for
7028 the nested function. Reasonable because it's almost always set
7029 correctly already. For the cases where that's wrong, make sure
7030 the nested function loads its gp on entry. */
7031 if (current_function_has_nonlocal_goto
)
7034 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
7035 Even if we are a static function, we still need to do this in case
7036 our address is taken and passed to something like qsort. */
7038 push_topmost_sequence ();
7039 insn
= get_insns ();
7040 pop_topmost_sequence ();
7042 for (; insn
; insn
= NEXT_INSN (insn
))
7044 && GET_CODE (PATTERN (insn
)) != USE
7045 && GET_CODE (PATTERN (insn
)) != CLOBBER
7046 && get_attr_usegp (insn
))
7053 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
7057 set_frame_related_p (void)
7059 rtx seq
= get_insns ();
7070 while (insn
!= NULL_RTX
)
7072 RTX_FRAME_RELATED_P (insn
) = 1;
7073 insn
= NEXT_INSN (insn
);
7075 seq
= emit_insn (seq
);
7079 seq
= emit_insn (seq
);
7080 RTX_FRAME_RELATED_P (seq
) = 1;
7085 #define FRP(exp) (start_sequence (), exp, set_frame_related_p ())
7087 /* Write function prologue. */
7089 /* On vms we have two kinds of functions:
7091 - stack frame (PROC_STACK)
7092 these are 'normal' functions with local vars and which are
7093 calling other functions
7094 - register frame (PROC_REGISTER)
7095 keeps all data in registers, needs no stack
7097 We must pass this to the assembler so it can generate the
7098 proper pdsc (procedure descriptor)
7099 This is done with the '.pdesc' command.
7101 On not-vms, we don't really differentiate between the two, as we can
7102 simply allocate stack without saving registers. */
7105 alpha_expand_prologue (void)
7107 /* Registers to save. */
7108 unsigned long imask
= 0;
7109 unsigned long fmask
= 0;
7110 /* Stack space needed for pushing registers clobbered by us. */
7111 HOST_WIDE_INT sa_size
;
7112 /* Complete stack size needed. */
7113 HOST_WIDE_INT frame_size
;
7114 /* Offset from base reg to register save area. */
7115 HOST_WIDE_INT reg_offset
;
7119 sa_size
= alpha_sa_size ();
7121 frame_size
= get_frame_size ();
7122 if (TARGET_ABI_OPEN_VMS
)
7123 frame_size
= ALPHA_ROUND (sa_size
7124 + (alpha_procedure_type
== PT_STACK
? 8 : 0)
7126 + current_function_pretend_args_size
);
7127 else if (TARGET_ABI_UNICOSMK
)
7128 /* We have to allocate space for the DSIB if we generate a frame. */
7129 frame_size
= ALPHA_ROUND (sa_size
7130 + (alpha_procedure_type
== PT_STACK
? 48 : 0))
7131 + ALPHA_ROUND (frame_size
7132 + current_function_outgoing_args_size
);
7134 frame_size
= (ALPHA_ROUND (current_function_outgoing_args_size
)
7136 + ALPHA_ROUND (frame_size
7137 + current_function_pretend_args_size
));
7139 if (TARGET_ABI_OPEN_VMS
)
7142 reg_offset
= ALPHA_ROUND (current_function_outgoing_args_size
);
7144 alpha_sa_mask (&imask
, &fmask
);
7146 /* Emit an insn to reload GP, if needed. */
7149 alpha_function_needs_gp
= alpha_does_function_need_gp ();
7150 if (alpha_function_needs_gp
)
7151 emit_insn (gen_prologue_ldgp ());
7154 /* TARGET_PROFILING_NEEDS_GP actually implies that we need to insert
7155 the call to mcount ourselves, rather than having the linker do it
7156 magically in response to -pg. Since _mcount has special linkage,
7157 don't represent the call as a call. */
7158 if (TARGET_PROFILING_NEEDS_GP
&& current_function_profile
)
7159 emit_insn (gen_prologue_mcount ());
7161 if (TARGET_ABI_UNICOSMK
)
7162 unicosmk_gen_dsib (&imask
);
7164 /* Adjust the stack by the frame size. If the frame size is > 4096
7165 bytes, we need to be sure we probe somewhere in the first and last
7166 4096 bytes (we can probably get away without the latter test) and
7167 every 8192 bytes in between. If the frame size is > 32768, we
7168 do this in a loop. Otherwise, we generate the explicit probe
7171 Note that we are only allowed to adjust sp once in the prologue. */
7173 if (frame_size
<= 32768)
7175 if (frame_size
> 4096)
7180 emit_insn (gen_probe_stack (GEN_INT (TARGET_ABI_UNICOSMK
7183 while ((probed
+= 8192) < frame_size
);
7185 /* We only have to do this probe if we aren't saving registers. */
7186 if (sa_size
== 0 && probed
+ 4096 < frame_size
)
7187 emit_insn (gen_probe_stack (GEN_INT (-frame_size
)));
7190 if (frame_size
!= 0)
7191 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx
, stack_pointer_rtx
,
7192 GEN_INT (TARGET_ABI_UNICOSMK
7198 /* Here we generate code to set R22 to SP + 4096 and set R23 to the
7199 number of 8192 byte blocks to probe. We then probe each block
7200 in the loop and then set SP to the proper location. If the
7201 amount remaining is > 4096, we have to do one more probe if we
7202 are not saving any registers. */
7204 HOST_WIDE_INT blocks
= (frame_size
+ 4096) / 8192;
7205 HOST_WIDE_INT leftover
= frame_size
+ 4096 - blocks
* 8192;
7206 rtx ptr
= gen_rtx_REG (DImode
, 22);
7207 rtx count
= gen_rtx_REG (DImode
, 23);
7210 emit_move_insn (count
, GEN_INT (blocks
));
7211 emit_insn (gen_adddi3 (ptr
, stack_pointer_rtx
,
7212 GEN_INT (TARGET_ABI_UNICOSMK
? 4096 - 64 : 4096)));
7214 /* Because of the difficulty in emitting a new basic block this
7215 late in the compilation, generate the loop as a single insn. */
7216 emit_insn (gen_prologue_stack_probe_loop (count
, ptr
));
7218 if (leftover
> 4096 && sa_size
== 0)
7220 rtx last
= gen_rtx_MEM (DImode
, plus_constant (ptr
, -leftover
));
7221 MEM_VOLATILE_P (last
) = 1;
7222 emit_move_insn (last
, const0_rtx
);
7225 if (TARGET_ABI_WINDOWS_NT
)
7227 /* For NT stack unwind (done by 'reverse execution'), it's
7228 not OK to take the result of a loop, even though the value
7229 is already in ptr, so we reload it via a single operation
7230 and subtract it to sp.
7232 Yes, that's correct -- we have to reload the whole constant
7233 into a temporary via ldah+lda then subtract from sp. */
7235 HOST_WIDE_INT lo
, hi
;
7236 lo
= ((frame_size
& 0xffff) ^ 0x8000) - 0x8000;
7237 hi
= frame_size
- lo
;
7239 emit_move_insn (ptr
, GEN_INT (hi
));
7240 emit_insn (gen_adddi3 (ptr
, ptr
, GEN_INT (lo
)));
7241 seq
= emit_insn (gen_subdi3 (stack_pointer_rtx
, stack_pointer_rtx
,
7246 seq
= emit_insn (gen_adddi3 (stack_pointer_rtx
, ptr
,
7247 GEN_INT (-leftover
)));
7250 /* This alternative is special, because the DWARF code cannot
7251 possibly intuit through the loop above. So we invent this
7252 note it looks at instead. */
7253 RTX_FRAME_RELATED_P (seq
) = 1;
7255 = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
7256 gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
7257 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
7258 GEN_INT (TARGET_ABI_UNICOSMK
7264 if (!TARGET_ABI_UNICOSMK
)
7266 /* Cope with very large offsets to the register save area. */
7267 sa_reg
= stack_pointer_rtx
;
7268 if (reg_offset
+ sa_size
> 0x8000)
7270 int low
= ((reg_offset
& 0xffff) ^ 0x8000) - 0x8000;
7273 if (low
+ sa_size
<= 0x8000)
7274 bias
= reg_offset
- low
, reg_offset
= low
;
7276 bias
= reg_offset
, reg_offset
= 0;
7278 sa_reg
= gen_rtx_REG (DImode
, 24);
7279 FRP (emit_insn (gen_adddi3 (sa_reg
, stack_pointer_rtx
,
7283 /* Save regs in stack order. Beginning with VMS PV. */
7284 if (TARGET_ABI_OPEN_VMS
&& alpha_procedure_type
== PT_STACK
)
7286 mem
= gen_rtx_MEM (DImode
, stack_pointer_rtx
);
7287 set_mem_alias_set (mem
, alpha_sr_alias_set
);
7288 FRP (emit_move_insn (mem
, gen_rtx_REG (DImode
, REG_PV
)));
7291 /* Save register RA next. */
7292 if (imask
& (1UL << REG_RA
))
7294 mem
= gen_rtx_MEM (DImode
, plus_constant (sa_reg
, reg_offset
));
7295 set_mem_alias_set (mem
, alpha_sr_alias_set
);
7296 FRP (emit_move_insn (mem
, gen_rtx_REG (DImode
, REG_RA
)));
7297 imask
&= ~(1UL << REG_RA
);
7301 /* Now save any other registers required to be saved. */
7302 for (i
= 0; i
< 31; i
++)
7303 if (imask
& (1UL << i
))
7305 mem
= gen_rtx_MEM (DImode
, plus_constant (sa_reg
, reg_offset
));
7306 set_mem_alias_set (mem
, alpha_sr_alias_set
);
7307 FRP (emit_move_insn (mem
, gen_rtx_REG (DImode
, i
)));
7311 /* Store a zero if requested for unwinding. */
7312 if (imask
& (1UL << 31))
7316 mem
= gen_rtx_MEM (DImode
, plus_constant (sa_reg
, reg_offset
));
7317 set_mem_alias_set (mem
, alpha_sr_alias_set
);
7318 insn
= emit_move_insn (mem
, const0_rtx
);
7320 RTX_FRAME_RELATED_P (insn
) = 1;
7321 t
= gen_rtx_REG (Pmode
, 31);
7322 t
= gen_rtx_SET (VOIDmode
, mem
, t
);
7323 t
= gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
, t
, REG_NOTES (insn
));
7324 REG_NOTES (insn
) = t
;
7329 for (i
= 0; i
< 31; i
++)
7330 if (fmask
& (1UL << i
))
7332 mem
= gen_rtx_MEM (DFmode
, plus_constant (sa_reg
, reg_offset
));
7333 set_mem_alias_set (mem
, alpha_sr_alias_set
);
7334 FRP (emit_move_insn (mem
, gen_rtx_REG (DFmode
, i
+32)));
7338 else if (TARGET_ABI_UNICOSMK
&& alpha_procedure_type
== PT_STACK
)
7340 /* The standard frame on the T3E includes space for saving registers.
7341 We just have to use it. We don't have to save the return address and
7342 the old frame pointer here - they are saved in the DSIB. */
7345 for (i
= 9; i
< 15; i
++)
7346 if (imask
& (1UL << i
))
7348 mem
= gen_rtx_MEM (DImode
, plus_constant(hard_frame_pointer_rtx
,
7350 set_mem_alias_set (mem
, alpha_sr_alias_set
);
7351 FRP (emit_move_insn (mem
, gen_rtx_REG (DImode
, i
)));
7354 for (i
= 2; i
< 10; i
++)
7355 if (fmask
& (1UL << i
))
7357 mem
= gen_rtx_MEM (DFmode
, plus_constant (hard_frame_pointer_rtx
,
7359 set_mem_alias_set (mem
, alpha_sr_alias_set
);
7360 FRP (emit_move_insn (mem
, gen_rtx_REG (DFmode
, i
+32)));
7365 if (TARGET_ABI_OPEN_VMS
)
7367 if (alpha_procedure_type
== PT_REGISTER
)
7368 /* Register frame procedures save the fp.
7369 ?? Ought to have a dwarf2 save for this. */
7370 emit_move_insn (gen_rtx_REG (DImode
, vms_save_fp_regno
),
7371 hard_frame_pointer_rtx
);
7373 if (alpha_procedure_type
!= PT_NULL
&& vms_base_regno
!= REG_PV
)
7374 emit_insn (gen_force_movdi (gen_rtx_REG (DImode
, vms_base_regno
),
7375 gen_rtx_REG (DImode
, REG_PV
)));
7377 if (alpha_procedure_type
!= PT_NULL
7378 && vms_unwind_regno
== HARD_FRAME_POINTER_REGNUM
)
7379 FRP (emit_move_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
));
7381 /* If we have to allocate space for outgoing args, do it now. */
7382 if (current_function_outgoing_args_size
!= 0)
7385 = emit_move_insn (stack_pointer_rtx
,
7387 (hard_frame_pointer_rtx
,
7389 (current_function_outgoing_args_size
))));
7391 /* Only set FRAME_RELATED_P on the stack adjustment we just emitted
7392 if ! frame_pointer_needed. Setting the bit will change the CFA
7393 computation rule to use sp again, which would be wrong if we had
7394 frame_pointer_needed, as this means sp might move unpredictably
7398 frame_pointer_needed
7399 => vms_unwind_regno == HARD_FRAME_POINTER_REGNUM
7401 current_function_outgoing_args_size != 0
7402 => alpha_procedure_type != PT_NULL,
7404 so when we are not setting the bit here, we are guaranteed to
7405 have emitted an FRP frame pointer update just before. */
7406 RTX_FRAME_RELATED_P (seq
) = ! frame_pointer_needed
;
7409 else if (!TARGET_ABI_UNICOSMK
)
7411 /* If we need a frame pointer, set it from the stack pointer. */
7412 if (frame_pointer_needed
)
7414 if (TARGET_CAN_FAULT_IN_PROLOGUE
)
7415 FRP (emit_move_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
));
7417 /* This must always be the last instruction in the
7418 prologue, thus we emit a special move + clobber. */
7419 FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx
,
7420 stack_pointer_rtx
, sa_reg
)));
7424 /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
7425 the prologue, for exception handling reasons, we cannot do this for
7426 any insn that might fault. We could prevent this for mems with a
7427 (clobber:BLK (scratch)), but this doesn't work for fp insns. So we
7428 have to prevent all such scheduling with a blockage.
7430 Linux, on the other hand, never bothered to implement OSF/1's
7431 exception handling, and so doesn't care about such things. Anyone
7432 planning to use dwarf2 frame-unwind info can also omit the blockage. */
7434 if (! TARGET_CAN_FAULT_IN_PROLOGUE
)
7435 emit_insn (gen_blockage ());
7438 /* Output the textual info surrounding the prologue. */
7441 alpha_start_function (FILE *file
, const char *fnname
,
7442 tree decl ATTRIBUTE_UNUSED
)
7444 unsigned long imask
= 0;
7445 unsigned long fmask
= 0;
7446 /* Stack space needed for pushing registers clobbered by us. */
7447 HOST_WIDE_INT sa_size
;
7448 /* Complete stack size needed. */
7449 unsigned HOST_WIDE_INT frame_size
;
7450 /* Offset from base reg to register save area. */
7451 HOST_WIDE_INT reg_offset
;
7452 char *entry_label
= (char *) alloca (strlen (fnname
) + 6);
7455 /* Don't emit an extern directive for functions defined in the same file. */
7456 if (TARGET_ABI_UNICOSMK
)
7459 name_tree
= get_identifier (fnname
);
7460 TREE_ASM_WRITTEN (name_tree
) = 1;
7463 alpha_fnname
= fnname
;
7464 sa_size
= alpha_sa_size ();
7466 frame_size
= get_frame_size ();
7467 if (TARGET_ABI_OPEN_VMS
)
7468 frame_size
= ALPHA_ROUND (sa_size
7469 + (alpha_procedure_type
== PT_STACK
? 8 : 0)
7471 + current_function_pretend_args_size
);
7472 else if (TARGET_ABI_UNICOSMK
)
7473 frame_size
= ALPHA_ROUND (sa_size
7474 + (alpha_procedure_type
== PT_STACK
? 48 : 0))
7475 + ALPHA_ROUND (frame_size
7476 + current_function_outgoing_args_size
);
7478 frame_size
= (ALPHA_ROUND (current_function_outgoing_args_size
)
7480 + ALPHA_ROUND (frame_size
7481 + current_function_pretend_args_size
));
7483 if (TARGET_ABI_OPEN_VMS
)
7486 reg_offset
= ALPHA_ROUND (current_function_outgoing_args_size
);
7488 alpha_sa_mask (&imask
, &fmask
);
7490 /* Ecoff can handle multiple .file directives, so put out file and lineno.
7491 We have to do that before the .ent directive as we cannot switch
7492 files within procedures with native ecoff because line numbers are
7493 linked to procedure descriptors.
7494 Outputting the lineno helps debugging of one line functions as they
7495 would otherwise get no line number at all. Please note that we would
7496 like to put out last_linenum from final.c, but it is not accessible. */
7498 if (write_symbols
== SDB_DEBUG
)
7500 #ifdef ASM_OUTPUT_SOURCE_FILENAME
7501 ASM_OUTPUT_SOURCE_FILENAME (file
,
7502 DECL_SOURCE_FILE (current_function_decl
));
7504 #ifdef ASM_OUTPUT_SOURCE_LINE
7505 if (debug_info_level
!= DINFO_LEVEL_TERSE
)
7506 ASM_OUTPUT_SOURCE_LINE (file
,
7507 DECL_SOURCE_LINE (current_function_decl
), 0);
7511 /* Issue function start and label. */
7512 if (TARGET_ABI_OPEN_VMS
7513 || (!TARGET_ABI_UNICOSMK
&& !flag_inhibit_size_directive
))
7515 fputs ("\t.ent ", file
);
7516 assemble_name (file
, fnname
);
7519 /* If the function needs GP, we'll write the "..ng" label there.
7520 Otherwise, do it here. */
7522 && ! alpha_function_needs_gp
7523 && ! current_function_is_thunk
)
7526 assemble_name (file
, fnname
);
7527 fputs ("..ng:\n", file
);
7531 strcpy (entry_label
, fnname
);
7532 if (TARGET_ABI_OPEN_VMS
)
7533 strcat (entry_label
, "..en");
7535 /* For public functions, the label must be globalized by appending an
7536 additional colon. */
7537 if (TARGET_ABI_UNICOSMK
&& TREE_PUBLIC (decl
))
7538 strcat (entry_label
, ":");
7540 ASM_OUTPUT_LABEL (file
, entry_label
);
7541 inside_function
= TRUE
;
7543 if (TARGET_ABI_OPEN_VMS
)
7544 fprintf (file
, "\t.base $%d\n", vms_base_regno
);
7546 if (!TARGET_ABI_OPEN_VMS
&& !TARGET_ABI_UNICOSMK
&& TARGET_IEEE_CONFORMANT
7547 && !flag_inhibit_size_directive
)
7549 /* Set flags in procedure descriptor to request IEEE-conformant
7550 math-library routines. The value we set it to is PDSC_EXC_IEEE
7551 (/usr/include/pdsc.h). */
7552 fputs ("\t.eflag 48\n", file
);
7555 /* Set up offsets to alpha virtual arg/local debugging pointer. */
7556 alpha_auto_offset
= -frame_size
+ current_function_pretend_args_size
;
7557 alpha_arg_offset
= -frame_size
+ 48;
7559 /* Describe our frame. If the frame size is larger than an integer,
7560 print it as zero to avoid an assembler error. We won't be
7561 properly describing such a frame, but that's the best we can do. */
7562 if (TARGET_ABI_UNICOSMK
)
7564 else if (TARGET_ABI_OPEN_VMS
)
7565 fprintf (file
, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC
",$26,"
7566 HOST_WIDE_INT_PRINT_DEC
"\n",
7568 frame_size
>= (1UL << 31) ? 0 : frame_size
,
7570 else if (!flag_inhibit_size_directive
)
7571 fprintf (file
, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC
",$26,%d\n",
7572 (frame_pointer_needed
7573 ? HARD_FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM
),
7574 frame_size
>= (1UL << 31) ? 0 : frame_size
,
7575 current_function_pretend_args_size
);
7577 /* Describe which registers were spilled. */
7578 if (TARGET_ABI_UNICOSMK
)
7580 else if (TARGET_ABI_OPEN_VMS
)
7583 /* ??? Does VMS care if mask contains ra? The old code didn't
7584 set it, so I don't here. */
7585 fprintf (file
, "\t.mask 0x%lx,0\n", imask
& ~(1UL << REG_RA
));
7587 fprintf (file
, "\t.fmask 0x%lx,0\n", fmask
);
7588 if (alpha_procedure_type
== PT_REGISTER
)
7589 fprintf (file
, "\t.fp_save $%d\n", vms_save_fp_regno
);
7591 else if (!flag_inhibit_size_directive
)
7595 fprintf (file
, "\t.mask 0x%lx," HOST_WIDE_INT_PRINT_DEC
"\n", imask
,
7596 frame_size
>= (1UL << 31) ? 0 : reg_offset
- frame_size
);
7598 for (i
= 0; i
< 32; ++i
)
7599 if (imask
& (1UL << i
))
7604 fprintf (file
, "\t.fmask 0x%lx," HOST_WIDE_INT_PRINT_DEC
"\n", fmask
,
7605 frame_size
>= (1UL << 31) ? 0 : reg_offset
- frame_size
);
7608 #if TARGET_ABI_OPEN_VMS
7609 /* Ifdef'ed cause link_section are only available then. */
7610 readonly_data_section ();
7611 fprintf (file
, "\t.align 3\n");
7612 assemble_name (file
, fnname
); fputs ("..na:\n", file
);
7613 fputs ("\t.ascii \"", file
);
7614 assemble_name (file
, fnname
);
7615 fputs ("\\0\"\n", file
);
7616 alpha_need_linkage (fnname
, 1);
7621 /* Emit the .prologue note at the scheduled end of the prologue. */
7624 alpha_output_function_end_prologue (FILE *file
)
7626 if (TARGET_ABI_UNICOSMK
)
7628 else if (TARGET_ABI_OPEN_VMS
)
7629 fputs ("\t.prologue\n", file
);
7630 else if (TARGET_ABI_WINDOWS_NT
)
7631 fputs ("\t.prologue 0\n", file
);
7632 else if (!flag_inhibit_size_directive
)
7633 fprintf (file
, "\t.prologue %d\n",
7634 alpha_function_needs_gp
|| current_function_is_thunk
);
7637 /* Write function epilogue. */
7639 /* ??? At some point we will want to support full unwind, and so will
7640 need to mark the epilogue as well. At the moment, we just confuse
7643 #define FRP(exp) exp
7646 alpha_expand_epilogue (void)
7648 /* Registers to save. */
7649 unsigned long imask
= 0;
7650 unsigned long fmask
= 0;
7651 /* Stack space needed for pushing registers clobbered by us. */
7652 HOST_WIDE_INT sa_size
;
7653 /* Complete stack size needed. */
7654 HOST_WIDE_INT frame_size
;
7655 /* Offset from base reg to register save area. */
7656 HOST_WIDE_INT reg_offset
;
7657 int fp_is_frame_pointer
, fp_offset
;
7658 rtx sa_reg
, sa_reg_exp
= NULL
;
7659 rtx sp_adj1
, sp_adj2
, mem
;
7663 sa_size
= alpha_sa_size ();
7665 frame_size
= get_frame_size ();
7666 if (TARGET_ABI_OPEN_VMS
)
7667 frame_size
= ALPHA_ROUND (sa_size
7668 + (alpha_procedure_type
== PT_STACK
? 8 : 0)
7670 + current_function_pretend_args_size
);
7671 else if (TARGET_ABI_UNICOSMK
)
7672 frame_size
= ALPHA_ROUND (sa_size
7673 + (alpha_procedure_type
== PT_STACK
? 48 : 0))
7674 + ALPHA_ROUND (frame_size
7675 + current_function_outgoing_args_size
);
7677 frame_size
= (ALPHA_ROUND (current_function_outgoing_args_size
)
7679 + ALPHA_ROUND (frame_size
7680 + current_function_pretend_args_size
));
7682 if (TARGET_ABI_OPEN_VMS
)
7684 if (alpha_procedure_type
== PT_STACK
)
7690 reg_offset
= ALPHA_ROUND (current_function_outgoing_args_size
);
7692 alpha_sa_mask (&imask
, &fmask
);
7695 = ((TARGET_ABI_OPEN_VMS
&& alpha_procedure_type
== PT_STACK
)
7696 || (!TARGET_ABI_OPEN_VMS
&& frame_pointer_needed
));
7698 sa_reg
= stack_pointer_rtx
;
7700 if (current_function_calls_eh_return
)
7701 eh_ofs
= EH_RETURN_STACKADJ_RTX
;
7705 if (!TARGET_ABI_UNICOSMK
&& sa_size
)
7707 /* If we have a frame pointer, restore SP from it. */
7708 if ((TARGET_ABI_OPEN_VMS
7709 && vms_unwind_regno
== HARD_FRAME_POINTER_REGNUM
)
7710 || (!TARGET_ABI_OPEN_VMS
&& frame_pointer_needed
))
7711 FRP (emit_move_insn (stack_pointer_rtx
, hard_frame_pointer_rtx
));
7713 /* Cope with very large offsets to the register save area. */
7714 if (reg_offset
+ sa_size
> 0x8000)
7716 int low
= ((reg_offset
& 0xffff) ^ 0x8000) - 0x8000;
7719 if (low
+ sa_size
<= 0x8000)
7720 bias
= reg_offset
- low
, reg_offset
= low
;
7722 bias
= reg_offset
, reg_offset
= 0;
7724 sa_reg
= gen_rtx_REG (DImode
, 22);
7725 sa_reg_exp
= plus_constant (stack_pointer_rtx
, bias
);
7727 FRP (emit_move_insn (sa_reg
, sa_reg_exp
));
7730 /* Restore registers in order, excepting a true frame pointer. */
7732 mem
= gen_rtx_MEM (DImode
, plus_constant (sa_reg
, reg_offset
));
7734 set_mem_alias_set (mem
, alpha_sr_alias_set
);
7735 FRP (emit_move_insn (gen_rtx_REG (DImode
, REG_RA
), mem
));
7738 imask
&= ~(1UL << REG_RA
);
7740 for (i
= 0; i
< 31; ++i
)
7741 if (imask
& (1UL << i
))
7743 if (i
== HARD_FRAME_POINTER_REGNUM
&& fp_is_frame_pointer
)
7744 fp_offset
= reg_offset
;
7747 mem
= gen_rtx_MEM (DImode
, plus_constant(sa_reg
, reg_offset
));
7748 set_mem_alias_set (mem
, alpha_sr_alias_set
);
7749 FRP (emit_move_insn (gen_rtx_REG (DImode
, i
), mem
));
7754 if (imask
& (1UL << 31))
7757 for (i
= 0; i
< 31; ++i
)
7758 if (fmask
& (1UL << i
))
7760 mem
= gen_rtx_MEM (DFmode
, plus_constant(sa_reg
, reg_offset
));
7761 set_mem_alias_set (mem
, alpha_sr_alias_set
);
7762 FRP (emit_move_insn (gen_rtx_REG (DFmode
, i
+32), mem
));
7766 else if (TARGET_ABI_UNICOSMK
&& alpha_procedure_type
== PT_STACK
)
7768 /* Restore callee-saved general-purpose registers. */
7772 for (i
= 9; i
< 15; i
++)
7773 if (imask
& (1UL << i
))
7775 mem
= gen_rtx_MEM (DImode
, plus_constant(hard_frame_pointer_rtx
,
7777 set_mem_alias_set (mem
, alpha_sr_alias_set
);
7778 FRP (emit_move_insn (gen_rtx_REG (DImode
, i
), mem
));
7782 for (i
= 2; i
< 10; i
++)
7783 if (fmask
& (1UL << i
))
7785 mem
= gen_rtx_MEM (DFmode
, plus_constant(hard_frame_pointer_rtx
,
7787 set_mem_alias_set (mem
, alpha_sr_alias_set
);
7788 FRP (emit_move_insn (gen_rtx_REG (DFmode
, i
+32), mem
));
7792 /* Restore the return address from the DSIB. */
7794 mem
= gen_rtx_MEM (DImode
, plus_constant(hard_frame_pointer_rtx
, -8));
7795 set_mem_alias_set (mem
, alpha_sr_alias_set
);
7796 FRP (emit_move_insn (gen_rtx_REG (DImode
, REG_RA
), mem
));
7799 if (frame_size
|| eh_ofs
)
7801 sp_adj1
= stack_pointer_rtx
;
7805 sp_adj1
= gen_rtx_REG (DImode
, 23);
7806 emit_move_insn (sp_adj1
,
7807 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, eh_ofs
));
7810 /* If the stack size is large, begin computation into a temporary
7811 register so as not to interfere with a potential fp restore,
7812 which must be consecutive with an SP restore. */
7813 if (frame_size
< 32768
7814 && ! (TARGET_ABI_UNICOSMK
&& current_function_calls_alloca
))
7815 sp_adj2
= GEN_INT (frame_size
);
7816 else if (TARGET_ABI_UNICOSMK
)
7818 sp_adj1
= gen_rtx_REG (DImode
, 23);
7819 FRP (emit_move_insn (sp_adj1
, hard_frame_pointer_rtx
));
7820 sp_adj2
= const0_rtx
;
7822 else if (frame_size
< 0x40007fffL
)
7824 int low
= ((frame_size
& 0xffff) ^ 0x8000) - 0x8000;
7826 sp_adj2
= plus_constant (sp_adj1
, frame_size
- low
);
7827 if (sa_reg_exp
&& rtx_equal_p (sa_reg_exp
, sp_adj2
))
7831 sp_adj1
= gen_rtx_REG (DImode
, 23);
7832 FRP (emit_move_insn (sp_adj1
, sp_adj2
));
7834 sp_adj2
= GEN_INT (low
);
7838 rtx tmp
= gen_rtx_REG (DImode
, 23);
7839 FRP (sp_adj2
= alpha_emit_set_const (tmp
, DImode
, frame_size
, 3));
7842 /* We can't drop new things to memory this late, afaik,
7843 so build it up by pieces. */
7844 FRP (sp_adj2
= alpha_emit_set_long_const (tmp
, frame_size
,
7845 -(frame_size
< 0)));
7851 /* From now on, things must be in order. So emit blockages. */
7853 /* Restore the frame pointer. */
7854 if (TARGET_ABI_UNICOSMK
)
7856 emit_insn (gen_blockage ());
7857 mem
= gen_rtx_MEM (DImode
,
7858 plus_constant (hard_frame_pointer_rtx
, -16));
7859 set_mem_alias_set (mem
, alpha_sr_alias_set
);
7860 FRP (emit_move_insn (hard_frame_pointer_rtx
, mem
));
7862 else if (fp_is_frame_pointer
)
7864 emit_insn (gen_blockage ());
7865 mem
= gen_rtx_MEM (DImode
, plus_constant (sa_reg
, fp_offset
));
7866 set_mem_alias_set (mem
, alpha_sr_alias_set
);
7867 FRP (emit_move_insn (hard_frame_pointer_rtx
, mem
));
7869 else if (TARGET_ABI_OPEN_VMS
)
7871 emit_insn (gen_blockage ());
7872 FRP (emit_move_insn (hard_frame_pointer_rtx
,
7873 gen_rtx_REG (DImode
, vms_save_fp_regno
)));
7876 /* Restore the stack pointer. */
7877 emit_insn (gen_blockage ());
7878 if (sp_adj2
== const0_rtx
)
7879 FRP (emit_move_insn (stack_pointer_rtx
, sp_adj1
));
7881 FRP (emit_move_insn (stack_pointer_rtx
,
7882 gen_rtx_PLUS (DImode
, sp_adj1
, sp_adj2
)));
7886 if (TARGET_ABI_OPEN_VMS
&& alpha_procedure_type
== PT_REGISTER
)
7888 emit_insn (gen_blockage ());
7889 FRP (emit_move_insn (hard_frame_pointer_rtx
,
7890 gen_rtx_REG (DImode
, vms_save_fp_regno
)));
7892 else if (TARGET_ABI_UNICOSMK
&& alpha_procedure_type
!= PT_STACK
)
7894 /* Decrement the frame pointer if the function does not have a
7897 emit_insn (gen_blockage ());
7898 FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx
,
7899 hard_frame_pointer_rtx
, constm1_rtx
)));
7904 /* Output the rest of the textual info surrounding the epilogue. */
7907 alpha_end_function (FILE *file
, const char *fnname
, tree decl ATTRIBUTE_UNUSED
)
7909 #if TARGET_ABI_OPEN_VMS
7910 alpha_write_linkage (file
, fnname
, decl
);
7913 /* End the function. */
7914 if (!TARGET_ABI_UNICOSMK
&& !flag_inhibit_size_directive
)
7916 fputs ("\t.end ", file
);
7917 assemble_name (file
, fnname
);
7920 inside_function
= FALSE
;
7922 /* Output jump tables and the static subroutine information block. */
7923 if (TARGET_ABI_UNICOSMK
)
7925 unicosmk_output_ssib (file
, fnname
);
7926 unicosmk_output_deferred_case_vectors (file
);
7931 /* Emit a tail call to FUNCTION after adjusting THIS by DELTA.
7933 In order to avoid the hordes of differences between generated code
7934 with and without TARGET_EXPLICIT_RELOCS, and to avoid duplicating
7935 lots of code loading up large constants, generate rtl and emit it
7936 instead of going straight to text.
7938 Not sure why this idea hasn't been explored before... */
7941 alpha_output_mi_thunk_osf (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
7942 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
7945 HOST_WIDE_INT hi
, lo
;
7946 rtx
this, insn
, funexp
;
7948 reset_block_changes ();
7950 /* We always require a valid GP. */
7951 emit_insn (gen_prologue_ldgp ());
7952 emit_note (NOTE_INSN_PROLOGUE_END
);
7954 /* Find the "this" pointer. If the function returns a structure,
7955 the structure return pointer is in $16. */
7956 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
7957 this = gen_rtx_REG (Pmode
, 17);
7959 this = gen_rtx_REG (Pmode
, 16);
7961 /* Add DELTA. When possible we use ldah+lda. Otherwise load the
7962 entire constant for the add. */
7963 lo
= ((delta
& 0xffff) ^ 0x8000) - 0x8000;
7964 hi
= (((delta
- lo
) & 0xffffffff) ^ 0x80000000) - 0x80000000;
7965 if (hi
+ lo
== delta
)
7968 emit_insn (gen_adddi3 (this, this, GEN_INT (hi
)));
7970 emit_insn (gen_adddi3 (this, this, GEN_INT (lo
)));
7974 rtx tmp
= alpha_emit_set_long_const (gen_rtx_REG (Pmode
, 0),
7975 delta
, -(delta
< 0));
7976 emit_insn (gen_adddi3 (this, this, tmp
));
7979 /* Add a delta stored in the vtable at VCALL_OFFSET. */
7984 tmp
= gen_rtx_REG (Pmode
, 0);
7985 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, this));
7987 lo
= ((vcall_offset
& 0xffff) ^ 0x8000) - 0x8000;
7988 hi
= (((vcall_offset
- lo
) & 0xffffffff) ^ 0x80000000) - 0x80000000;
7989 if (hi
+ lo
== vcall_offset
)
7992 emit_insn (gen_adddi3 (tmp
, tmp
, GEN_INT (hi
)));
7996 tmp2
= alpha_emit_set_long_const (gen_rtx_REG (Pmode
, 1),
7997 vcall_offset
, -(vcall_offset
< 0));
7998 emit_insn (gen_adddi3 (tmp
, tmp
, tmp2
));
8002 tmp2
= gen_rtx_PLUS (Pmode
, tmp
, GEN_INT (lo
));
8005 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, tmp2
));
8007 emit_insn (gen_adddi3 (this, this, tmp
));
8010 /* Generate a tail call to the target function. */
8011 if (! TREE_USED (function
))
8013 assemble_external (function
);
8014 TREE_USED (function
) = 1;
8016 funexp
= XEXP (DECL_RTL (function
), 0);
8017 funexp
= gen_rtx_MEM (FUNCTION_MODE
, funexp
);
8018 insn
= emit_call_insn (gen_sibcall (funexp
, const0_rtx
));
8019 SIBLING_CALL_P (insn
) = 1;
8021 /* Run just enough of rest_of_compilation to get the insns emitted.
8022 There's not really enough bulk here to make other passes such as
8023 instruction scheduling worth while. Note that use_thunk calls
8024 assemble_start_function and assemble_end_function. */
8025 insn
= get_insns ();
8026 insn_locators_initialize ();
8027 shorten_branches (insn
);
8028 final_start_function (insn
, file
, 1);
8029 final (insn
, file
, 1, 0);
8030 final_end_function ();
8032 #endif /* TARGET_ABI_OSF */
8034 /* Debugging support. */
8038 /* Count the number of sdb related labels are generated (to find block
8039 start and end boundaries). */
8041 int sdb_label_count
= 0;
8043 /* Next label # for each statement. */
8045 static int sym_lineno
= 0;
8047 /* Count the number of .file directives, so that .loc is up to date. */
8049 static int num_source_filenames
= 0;
8051 /* Name of the file containing the current function. */
8053 static const char *current_function_file
= "";
8055 /* Offsets to alpha virtual arg/local debugging pointers. */
8057 long alpha_arg_offset
;
8058 long alpha_auto_offset
;
8060 /* Emit a new filename to a stream. */
8063 alpha_output_filename (FILE *stream
, const char *name
)
8065 static int first_time
= TRUE
;
8066 char ltext_label_name
[100];
8071 ++num_source_filenames
;
8072 current_function_file
= name
;
8073 fprintf (stream
, "\t.file\t%d ", num_source_filenames
);
8074 output_quoted_string (stream
, name
);
8075 fprintf (stream
, "\n");
8076 if (!TARGET_GAS
&& write_symbols
== DBX_DEBUG
)
8077 fprintf (stream
, "\t#@stabs\n");
8080 else if (write_symbols
== DBX_DEBUG
)
8082 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name
, "Ltext", 0);
8083 fprintf (stream
, "%s", ASM_STABS_OP
);
8084 output_quoted_string (stream
, name
);
8085 fprintf (stream
, ",%d,0,0,%s\n", N_SOL
, <ext_label_name
[1]);
8088 else if (name
!= current_function_file
8089 && strcmp (name
, current_function_file
) != 0)
8091 if (inside_function
&& ! TARGET_GAS
)
8092 fprintf (stream
, "\t#.file\t%d ", num_source_filenames
);
8095 ++num_source_filenames
;
8096 current_function_file
= name
;
8097 fprintf (stream
, "\t.file\t%d ", num_source_filenames
);
8100 output_quoted_string (stream
, name
);
8101 fprintf (stream
, "\n");
8105 /* Emit a linenumber to a stream. */
8108 alpha_output_lineno (FILE *stream
, int line
)
8110 if (write_symbols
== DBX_DEBUG
)
8112 /* mips-tfile doesn't understand .stabd directives. */
8114 fprintf (stream
, "$LM%d:\n%s%d,0,%d,$LM%d\n",
8115 sym_lineno
, ASM_STABN_OP
, N_SLINE
, line
, sym_lineno
);
8118 fprintf (stream
, "\n\t.loc\t%d %d\n", num_source_filenames
, line
);
8121 /* Structure to show the current status of registers and memory. */
8123 struct shadow_summary
8126 unsigned int i
: 31; /* Mask of int regs */
8127 unsigned int fp
: 31; /* Mask of fp regs */
8128 unsigned int mem
: 1; /* mem == imem | fpmem */
8132 /* Summary the effects of expression X on the machine. Update SUM, a pointer
8133 to the summary structure. SET is nonzero if the insn is setting the
8134 object, otherwise zero. */
8137 summarize_insn (rtx x
, struct shadow_summary
*sum
, int set
)
8139 const char *format_ptr
;
8145 switch (GET_CODE (x
))
8147 /* ??? Note that this case would be incorrect if the Alpha had a
8148 ZERO_EXTRACT in SET_DEST. */
8150 summarize_insn (SET_SRC (x
), sum
, 0);
8151 summarize_insn (SET_DEST (x
), sum
, 1);
8155 summarize_insn (XEXP (x
, 0), sum
, 1);
8159 summarize_insn (XEXP (x
, 0), sum
, 0);
8163 for (i
= ASM_OPERANDS_INPUT_LENGTH (x
) - 1; i
>= 0; i
--)
8164 summarize_insn (ASM_OPERANDS_INPUT (x
, i
), sum
, 0);
8168 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
8169 summarize_insn (XVECEXP (x
, 0, i
), sum
, 0);
8173 summarize_insn (SUBREG_REG (x
), sum
, 0);
8178 int regno
= REGNO (x
);
8179 unsigned long mask
= ((unsigned long) 1) << (regno
% 32);
8181 if (regno
== 31 || regno
== 63)
8187 sum
->defd
.i
|= mask
;
8189 sum
->defd
.fp
|= mask
;
8194 sum
->used
.i
|= mask
;
8196 sum
->used
.fp
|= mask
;
8207 /* Find the regs used in memory address computation: */
8208 summarize_insn (XEXP (x
, 0), sum
, 0);
8211 case CONST_INT
: case CONST_DOUBLE
:
8212 case SYMBOL_REF
: case LABEL_REF
: case CONST
:
8213 case SCRATCH
: case ASM_INPUT
:
8216 /* Handle common unary and binary ops for efficiency. */
8217 case COMPARE
: case PLUS
: case MINUS
: case MULT
: case DIV
:
8218 case MOD
: case UDIV
: case UMOD
: case AND
: case IOR
:
8219 case XOR
: case ASHIFT
: case ROTATE
: case ASHIFTRT
: case LSHIFTRT
:
8220 case ROTATERT
: case SMIN
: case SMAX
: case UMIN
: case UMAX
:
8221 case NE
: case EQ
: case GE
: case GT
: case LE
:
8222 case LT
: case GEU
: case GTU
: case LEU
: case LTU
:
8223 summarize_insn (XEXP (x
, 0), sum
, 0);
8224 summarize_insn (XEXP (x
, 1), sum
, 0);
8227 case NEG
: case NOT
: case SIGN_EXTEND
: case ZERO_EXTEND
:
8228 case TRUNCATE
: case FLOAT_EXTEND
: case FLOAT_TRUNCATE
: case FLOAT
:
8229 case FIX
: case UNSIGNED_FLOAT
: case UNSIGNED_FIX
: case ABS
:
8230 case SQRT
: case FFS
:
8231 summarize_insn (XEXP (x
, 0), sum
, 0);
8235 format_ptr
= GET_RTX_FORMAT (GET_CODE (x
));
8236 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
8237 switch (format_ptr
[i
])
8240 summarize_insn (XEXP (x
, i
), sum
, 0);
8244 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
8245 summarize_insn (XVECEXP (x
, i
, j
), sum
, 0);
8257 /* Ensure a sufficient number of `trapb' insns are in the code when
8258 the user requests code with a trap precision of functions or
8261 In naive mode, when the user requests a trap-precision of
8262 "instruction", a trapb is needed after every instruction that may
8263 generate a trap. This ensures that the code is resumption safe but
8266 When optimizations are turned on, we delay issuing a trapb as long
8267 as possible. In this context, a trap shadow is the sequence of
8268 instructions that starts with a (potentially) trap generating
8269 instruction and extends to the next trapb or call_pal instruction
8270 (but GCC never generates call_pal by itself). We can delay (and
8271 therefore sometimes omit) a trapb subject to the following
8274 (a) On entry to the trap shadow, if any Alpha register or memory
8275 location contains a value that is used as an operand value by some
8276 instruction in the trap shadow (live on entry), then no instruction
8277 in the trap shadow may modify the register or memory location.
8279 (b) Within the trap shadow, the computation of the base register
8280 for a memory load or store instruction may not involve using the
8281 result of an instruction that might generate an UNPREDICTABLE
8284 (c) Within the trap shadow, no register may be used more than once
8285 as a destination register. (This is to make life easier for the
8288 (d) The trap shadow may not include any branch instructions. */
8291 alpha_handle_trap_shadows (void)
8293 struct shadow_summary shadow
;
8294 int trap_pending
, exception_nesting
;
8298 exception_nesting
= 0;
8301 shadow
.used
.mem
= 0;
8302 shadow
.defd
= shadow
.used
;
8304 for (i
= get_insns (); i
; i
= NEXT_INSN (i
))
8306 if (GET_CODE (i
) == NOTE
)
8308 switch (NOTE_LINE_NUMBER (i
))
8310 case NOTE_INSN_EH_REGION_BEG
:
8311 exception_nesting
++;
8316 case NOTE_INSN_EH_REGION_END
:
8317 exception_nesting
--;
8322 case NOTE_INSN_EPILOGUE_BEG
:
8323 if (trap_pending
&& alpha_tp
>= ALPHA_TP_FUNC
)
8328 else if (trap_pending
)
8330 if (alpha_tp
== ALPHA_TP_FUNC
)
8332 if (GET_CODE (i
) == JUMP_INSN
8333 && GET_CODE (PATTERN (i
)) == RETURN
)
8336 else if (alpha_tp
== ALPHA_TP_INSN
)
8340 struct shadow_summary sum
;
8345 sum
.defd
= sum
.used
;
8347 switch (GET_CODE (i
))
8350 /* Annoyingly, get_attr_trap will abort on these. */
8351 if (GET_CODE (PATTERN (i
)) == USE
8352 || GET_CODE (PATTERN (i
)) == CLOBBER
)
8355 summarize_insn (PATTERN (i
), &sum
, 0);
8357 if ((sum
.defd
.i
& shadow
.defd
.i
)
8358 || (sum
.defd
.fp
& shadow
.defd
.fp
))
8360 /* (c) would be violated */
8364 /* Combine shadow with summary of current insn: */
8365 shadow
.used
.i
|= sum
.used
.i
;
8366 shadow
.used
.fp
|= sum
.used
.fp
;
8367 shadow
.used
.mem
|= sum
.used
.mem
;
8368 shadow
.defd
.i
|= sum
.defd
.i
;
8369 shadow
.defd
.fp
|= sum
.defd
.fp
;
8370 shadow
.defd
.mem
|= sum
.defd
.mem
;
8372 if ((sum
.defd
.i
& shadow
.used
.i
)
8373 || (sum
.defd
.fp
& shadow
.used
.fp
)
8374 || (sum
.defd
.mem
& shadow
.used
.mem
))
8376 /* (a) would be violated (also takes care of (b)) */
8377 if (get_attr_trap (i
) == TRAP_YES
8378 && ((sum
.defd
.i
& sum
.used
.i
)
8379 || (sum
.defd
.fp
& sum
.used
.fp
)))
8398 n
= emit_insn_before (gen_trapb (), i
);
8399 PUT_MODE (n
, TImode
);
8400 PUT_MODE (i
, TImode
);
8404 shadow
.used
.mem
= 0;
8405 shadow
.defd
= shadow
.used
;
8410 if ((exception_nesting
> 0 || alpha_tp
>= ALPHA_TP_FUNC
)
8411 && GET_CODE (i
) == INSN
8412 && GET_CODE (PATTERN (i
)) != USE
8413 && GET_CODE (PATTERN (i
)) != CLOBBER
8414 && get_attr_trap (i
) == TRAP_YES
)
8416 if (optimize
&& !trap_pending
)
8417 summarize_insn (PATTERN (i
), &shadow
, 0);
8423 /* Alpha can only issue instruction groups simultaneously if they are
8424 suitably aligned. This is very processor-specific. */
8426 enum alphaev4_pipe
{
8433 enum alphaev5_pipe
{
8444 static enum alphaev4_pipe
8445 alphaev4_insn_pipe (rtx insn
)
8447 if (recog_memoized (insn
) < 0)
8449 if (get_attr_length (insn
) != 4)
8452 switch (get_attr_type (insn
))
8486 static enum alphaev5_pipe
8487 alphaev5_insn_pipe (rtx insn
)
8489 if (recog_memoized (insn
) < 0)
8491 if (get_attr_length (insn
) != 4)
8494 switch (get_attr_type (insn
))
8535 /* IN_USE is a mask of the slots currently filled within the insn group.
8536 The mask bits come from alphaev4_pipe above. If EV4_IBX is set, then
8537 the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.
8539 LEN is, of course, the length of the group in bytes. */
8542 alphaev4_next_group (rtx insn
, int *pin_use
, int *plen
)
8549 || GET_CODE (PATTERN (insn
)) == CLOBBER
8550 || GET_CODE (PATTERN (insn
)) == USE
)
8555 enum alphaev4_pipe pipe
;
8557 pipe
= alphaev4_insn_pipe (insn
);
8561 /* Force complex instructions to start new groups. */
8565 /* If this is a completely unrecognized insn, its an asm.
8566 We don't know how long it is, so record length as -1 to
8567 signal a needed realignment. */
8568 if (recog_memoized (insn
) < 0)
8571 len
= get_attr_length (insn
);
8575 if (in_use
& EV4_IB0
)
8577 if (in_use
& EV4_IB1
)
8582 in_use
|= EV4_IB0
| EV4_IBX
;
8586 if (in_use
& EV4_IB0
)
8588 if (!(in_use
& EV4_IBX
) || (in_use
& EV4_IB1
))
8596 if (in_use
& EV4_IB1
)
8606 /* Haifa doesn't do well scheduling branches. */
8607 if (GET_CODE (insn
) == JUMP_INSN
)
8611 insn
= next_nonnote_insn (insn
);
8613 if (!insn
|| ! INSN_P (insn
))
8616 /* Let Haifa tell us where it thinks insn group boundaries are. */
8617 if (GET_MODE (insn
) == TImode
)
8620 if (GET_CODE (insn
) == CLOBBER
|| GET_CODE (insn
) == USE
)
8625 insn
= next_nonnote_insn (insn
);
8633 /* IN_USE is a mask of the slots currently filled within the insn group.
8634 The mask bits come from alphaev5_pipe above. If EV5_E01 is set, then
8635 the insn in EV5_E0 can be swapped by the hardware into EV5_E1.
8637 LEN is, of course, the length of the group in bytes. */
8640 alphaev5_next_group (rtx insn
, int *pin_use
, int *plen
)
8647 || GET_CODE (PATTERN (insn
)) == CLOBBER
8648 || GET_CODE (PATTERN (insn
)) == USE
)
8653 enum alphaev5_pipe pipe
;
8655 pipe
= alphaev5_insn_pipe (insn
);
8659 /* Force complex instructions to start new groups. */
8663 /* If this is a completely unrecognized insn, its an asm.
8664 We don't know how long it is, so record length as -1 to
8665 signal a needed realignment. */
8666 if (recog_memoized (insn
) < 0)
8669 len
= get_attr_length (insn
);
8672 /* ??? Most of the places below, we would like to abort, as
8673 it would indicate an error either in Haifa, or in the
8674 scheduling description. Unfortunately, Haifa never
8675 schedules the last instruction of the BB, so we don't
8676 have an accurate TI bit to go off. */
8678 if (in_use
& EV5_E0
)
8680 if (in_use
& EV5_E1
)
8685 in_use
|= EV5_E0
| EV5_E01
;
8689 if (in_use
& EV5_E0
)
8691 if (!(in_use
& EV5_E01
) || (in_use
& EV5_E1
))
8699 if (in_use
& EV5_E1
)
8705 if (in_use
& EV5_FA
)
8707 if (in_use
& EV5_FM
)
8712 in_use
|= EV5_FA
| EV5_FAM
;
8716 if (in_use
& EV5_FA
)
8722 if (in_use
& EV5_FM
)
8735 /* Haifa doesn't do well scheduling branches. */
8736 /* ??? If this is predicted not-taken, slotting continues, except
8737 that no more IBR, FBR, or JSR insns may be slotted. */
8738 if (GET_CODE (insn
) == JUMP_INSN
)
8742 insn
= next_nonnote_insn (insn
);
8744 if (!insn
|| ! INSN_P (insn
))
8747 /* Let Haifa tell us where it thinks insn group boundaries are. */
8748 if (GET_MODE (insn
) == TImode
)
8751 if (GET_CODE (insn
) == CLOBBER
|| GET_CODE (insn
) == USE
)
8756 insn
= next_nonnote_insn (insn
);
8765 alphaev4_next_nop (int *pin_use
)
8767 int in_use
= *pin_use
;
8770 if (!(in_use
& EV4_IB0
))
8775 else if ((in_use
& (EV4_IBX
|EV4_IB1
)) == EV4_IBX
)
8780 else if (TARGET_FP
&& !(in_use
& EV4_IB1
))
8793 alphaev5_next_nop (int *pin_use
)
8795 int in_use
= *pin_use
;
8798 if (!(in_use
& EV5_E1
))
8803 else if (TARGET_FP
&& !(in_use
& EV5_FA
))
8808 else if (TARGET_FP
&& !(in_use
& EV5_FM
))
8820 /* The instruction group alignment main loop. */
8823 alpha_align_insns (unsigned int max_align
,
8824 rtx (*next_group
) (rtx
, int *, int *),
8825 rtx (*next_nop
) (int *))
8827 /* ALIGN is the known alignment for the insn group. */
8829 /* OFS is the offset of the current insn in the insn group. */
8831 int prev_in_use
, in_use
, len
;
8834 /* Let shorten branches care for assigning alignments to code labels. */
8835 shorten_branches (get_insns ());
8837 if (align_functions
< 4)
8839 else if ((unsigned int) align_functions
< max_align
)
8840 align
= align_functions
;
8844 ofs
= prev_in_use
= 0;
8846 if (GET_CODE (i
) == NOTE
)
8847 i
= next_nonnote_insn (i
);
8851 next
= (*next_group
) (i
, &in_use
, &len
);
8853 /* When we see a label, resync alignment etc. */
8854 if (GET_CODE (i
) == CODE_LABEL
)
8856 unsigned int new_align
= 1 << label_to_alignment (i
);
8858 if (new_align
>= align
)
8860 align
= new_align
< max_align
? new_align
: max_align
;
8864 else if (ofs
& (new_align
-1))
8865 ofs
= (ofs
| (new_align
-1)) + 1;
8870 /* Handle complex instructions special. */
8871 else if (in_use
== 0)
8873 /* Asms will have length < 0. This is a signal that we have
8874 lost alignment knowledge. Assume, however, that the asm
8875 will not mis-align instructions. */
8884 /* If the known alignment is smaller than the recognized insn group,
8885 realign the output. */
8886 else if ((int) align
< len
)
8888 unsigned int new_log_align
= len
> 8 ? 4 : 3;
8891 where
= prev
= prev_nonnote_insn (i
);
8892 if (!where
|| GET_CODE (where
) != CODE_LABEL
)
8895 /* Can't realign between a call and its gp reload. */
8896 if (! (TARGET_EXPLICIT_RELOCS
8897 && prev
&& GET_CODE (prev
) == CALL_INSN
))
8899 emit_insn_before (gen_realign (GEN_INT (new_log_align
)), where
);
8900 align
= 1 << new_log_align
;
8905 /* If the group won't fit in the same INT16 as the previous,
8906 we need to add padding to keep the group together. Rather
8907 than simply leaving the insn filling to the assembler, we
8908 can make use of the knowledge of what sorts of instructions
8909 were issued in the previous group to make sure that all of
8910 the added nops are really free. */
8911 else if (ofs
+ len
> (int) align
)
8913 int nop_count
= (align
- ofs
) / 4;
8916 /* Insert nops before labels, branches, and calls to truly merge
8917 the execution of the nops with the previous instruction group. */
8918 where
= prev_nonnote_insn (i
);
8921 if (GET_CODE (where
) == CODE_LABEL
)
8923 rtx where2
= prev_nonnote_insn (where
);
8924 if (where2
&& GET_CODE (where2
) == JUMP_INSN
)
8927 else if (GET_CODE (where
) == INSN
)
8934 emit_insn_before ((*next_nop
)(&prev_in_use
), where
);
8935 while (--nop_count
);
8939 ofs
= (ofs
+ len
) & (align
- 1);
8940 prev_in_use
= in_use
;
8945 /* Machine dependent reorg pass. */
8950 if (alpha_tp
!= ALPHA_TP_PROG
|| flag_exceptions
)
8951 alpha_handle_trap_shadows ();
8953 /* Due to the number of extra trapb insns, don't bother fixing up
8954 alignment when trap precision is instruction. Moreover, we can
8955 only do our job when sched2 is run. */
8956 if (optimize
&& !optimize_size
8957 && alpha_tp
!= ALPHA_TP_INSN
8958 && flag_schedule_insns_after_reload
)
8960 if (alpha_cpu
== PROCESSOR_EV4
)
8961 alpha_align_insns (8, alphaev4_next_group
, alphaev4_next_nop
);
8962 else if (alpha_cpu
== PROCESSOR_EV5
)
8963 alpha_align_insns (16, alphaev5_next_group
, alphaev5_next_nop
);
8967 #if !TARGET_ABI_UNICOSMK
8974 alpha_file_start (void)
8976 #ifdef OBJECT_FORMAT_ELF
8977 /* If emitting dwarf2 debug information, we cannot generate a .file
8978 directive to start the file, as it will conflict with dwarf2out
8979 file numbers. So it's only useful when emitting mdebug output. */
8980 targetm
.file_start_file_directive
= (write_symbols
== DBX_DEBUG
);
8983 default_file_start ();
8985 fprintf (asm_out_file
, "\t.verstamp %d %d\n", MS_STAMP
, LS_STAMP
);
8988 fputs ("\t.set noreorder\n", asm_out_file
);
8989 fputs ("\t.set volatile\n", asm_out_file
);
8990 if (!TARGET_ABI_OPEN_VMS
)
8991 fputs ("\t.set noat\n", asm_out_file
);
8992 if (TARGET_EXPLICIT_RELOCS
)
8993 fputs ("\t.set nomacro\n", asm_out_file
);
8994 if (TARGET_SUPPORT_ARCH
| TARGET_BWX
| TARGET_MAX
| TARGET_FIX
| TARGET_CIX
)
8995 fprintf (asm_out_file
,
8997 TARGET_CPU_EV6
? "ev6"
8999 ? (TARGET_MAX
? "pca56" : TARGET_BWX
? "ev56" : "ev5")
9004 #ifdef OBJECT_FORMAT_ELF
9006 /* Switch to the section to which we should output X. The only thing
9007 special we do here is to honor small data. */
9010 alpha_elf_select_rtx_section (enum machine_mode mode
, rtx x
,
9011 unsigned HOST_WIDE_INT align
)
9013 if (TARGET_SMALL_DATA
&& GET_MODE_SIZE (mode
) <= g_switch_value
)
9014 /* ??? Consider using mergeable sdata sections. */
9017 default_elf_select_rtx_section (mode
, x
, align
);
9020 #endif /* OBJECT_FORMAT_ELF */
9022 /* Structure to collect function names for final output in link section. */
9023 /* Note that items marked with GTY can't be ifdef'ed out. */
9025 enum links_kind
{KIND_UNUSED
, KIND_LOCAL
, KIND_EXTERN
};
9026 enum reloc_kind
{KIND_LINKAGE
, KIND_CODEADDR
};
9028 struct alpha_links
GTY(())
9032 enum links_kind lkind
;
9033 enum reloc_kind rkind
;
9036 struct alpha_funcs
GTY(())
9039 splay_tree
GTY ((param1_is (char *), param2_is (struct alpha_links
*)))
9043 static GTY ((param1_is (char *), param2_is (struct alpha_links
*)))
9044 splay_tree alpha_links_tree
;
9045 static GTY ((param1_is (tree
), param2_is (struct alpha_funcs
*)))
9046 splay_tree alpha_funcs_tree
;
9048 static GTY(()) int alpha_funcs_num
;
9050 #if TARGET_ABI_OPEN_VMS
9052 /* Return the VMS argument type corresponding to MODE. */
9055 alpha_arg_type (enum machine_mode mode
)
9060 return TARGET_FLOAT_VAX
? FF
: FS
;
9062 return TARGET_FLOAT_VAX
? FD
: FT
;
9068 /* Return an rtx for an integer representing the VMS Argument Information
9072 alpha_arg_info_reg_val (CUMULATIVE_ARGS cum
)
9074 unsigned HOST_WIDE_INT regval
= cum
.num_args
;
9077 for (i
= 0; i
< 6; i
++)
9078 regval
|= ((int) cum
.atypes
[i
]) << (i
* 3 + 8);
9080 return GEN_INT (regval
);
9083 /* Make (or fake) .linkage entry for function call.
9085 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition.
9087 Return an SYMBOL_REF rtx for the linkage. */
9090 alpha_need_linkage (const char *name
, int is_local
)
9092 splay_tree_node node
;
9093 struct alpha_links
*al
;
9100 struct alpha_funcs
*cfaf
;
9102 if (!alpha_funcs_tree
)
9103 alpha_funcs_tree
= splay_tree_new_ggc ((splay_tree_compare_fn
)
9104 splay_tree_compare_pointers
);
9106 cfaf
= (struct alpha_funcs
*) ggc_alloc (sizeof (struct alpha_funcs
));
9109 cfaf
->num
= ++alpha_funcs_num
;
9111 splay_tree_insert (alpha_funcs_tree
,
9112 (splay_tree_key
) current_function_decl
,
9113 (splay_tree_value
) cfaf
);
9116 if (alpha_links_tree
)
9118 /* Is this name already defined? */
9120 node
= splay_tree_lookup (alpha_links_tree
, (splay_tree_key
) name
);
9123 al
= (struct alpha_links
*) node
->value
;
9126 /* Defined here but external assumed. */
9127 if (al
->lkind
== KIND_EXTERN
)
9128 al
->lkind
= KIND_LOCAL
;
9132 /* Used here but unused assumed. */
9133 if (al
->lkind
== KIND_UNUSED
)
9134 al
->lkind
= KIND_LOCAL
;
9140 alpha_links_tree
= splay_tree_new_ggc ((splay_tree_compare_fn
) strcmp
);
9142 al
= (struct alpha_links
*) ggc_alloc (sizeof (struct alpha_links
));
9143 name
= ggc_strdup (name
);
9145 /* Assume external if no definition. */
9146 al
->lkind
= (is_local
? KIND_UNUSED
: KIND_EXTERN
);
9148 /* Ensure we have an IDENTIFIER so assemble_name can mark it used. */
9149 get_identifier (name
);
9151 /* Construct a SYMBOL_REF for us to call. */
9153 size_t name_len
= strlen (name
);
9154 char *linksym
= alloca (name_len
+ 6);
9156 memcpy (linksym
+ 1, name
, name_len
);
9157 memcpy (linksym
+ 1 + name_len
, "..lk", 5);
9158 al
->linkage
= gen_rtx_SYMBOL_REF (Pmode
,
9159 ggc_alloc_string (linksym
, name_len
+ 5));
9162 splay_tree_insert (alpha_links_tree
, (splay_tree_key
) name
,
9163 (splay_tree_value
) al
);
9169 alpha_use_linkage (rtx linkage
, tree cfundecl
, int lflag
, int rflag
)
9171 splay_tree_node cfunnode
;
9172 struct alpha_funcs
*cfaf
;
9173 struct alpha_links
*al
;
9174 const char *name
= XSTR (linkage
, 0);
9176 cfaf
= (struct alpha_funcs
*) 0;
9177 al
= (struct alpha_links
*) 0;
9179 cfunnode
= splay_tree_lookup (alpha_funcs_tree
, (splay_tree_key
) cfundecl
);
9180 cfaf
= (struct alpha_funcs
*) cfunnode
->value
;
9184 splay_tree_node lnode
;
9186 /* Is this name already defined? */
9188 lnode
= splay_tree_lookup (cfaf
->links
, (splay_tree_key
) name
);
9190 al
= (struct alpha_links
*) lnode
->value
;
9193 cfaf
->links
= splay_tree_new_ggc ((splay_tree_compare_fn
) strcmp
);
9201 splay_tree_node node
= 0;
9202 struct alpha_links
*anl
;
9207 name_len
= strlen (name
);
9209 al
= (struct alpha_links
*) ggc_alloc (sizeof (struct alpha_links
));
9210 al
->num
= cfaf
->num
;
9212 node
= splay_tree_lookup (alpha_links_tree
, (splay_tree_key
) name
);
9215 anl
= (struct alpha_links
*) node
->value
;
9216 al
->lkind
= anl
->lkind
;
9219 sprintf (buf
, "$%d..%s..lk", cfaf
->num
, name
);
9220 buflen
= strlen (buf
);
9221 linksym
= alloca (buflen
+ 1);
9222 memcpy (linksym
, buf
, buflen
+ 1);
9224 al
->linkage
= gen_rtx_SYMBOL_REF
9225 (Pmode
, ggc_alloc_string (linksym
, buflen
+ 1));
9227 splay_tree_insert (cfaf
->links
, (splay_tree_key
) name
,
9228 (splay_tree_value
) al
);
9232 al
->rkind
= KIND_CODEADDR
;
9234 al
->rkind
= KIND_LINKAGE
;
9237 return gen_rtx_MEM (Pmode
, plus_constant (al
->linkage
, 8));
9243 alpha_write_one_linkage (splay_tree_node node
, void *data
)
9245 const char *const name
= (const char *) node
->key
;
9246 struct alpha_links
*link
= (struct alpha_links
*) node
->value
;
9247 FILE *stream
= (FILE *) data
;
9249 fprintf (stream
, "$%d..%s..lk:\n", link
->num
, name
);
9250 if (link
->rkind
== KIND_CODEADDR
)
9252 if (link
->lkind
== KIND_LOCAL
)
9254 /* Local and used */
9255 fprintf (stream
, "\t.quad %s..en\n", name
);
9259 /* External and used, request code address. */
9260 fprintf (stream
, "\t.code_address %s\n", name
);
9265 if (link
->lkind
== KIND_LOCAL
)
9267 /* Local and used, build linkage pair. */
9268 fprintf (stream
, "\t.quad %s..en\n", name
);
9269 fprintf (stream
, "\t.quad %s\n", name
);
9273 /* External and used, request linkage pair. */
9274 fprintf (stream
, "\t.linkage %s\n", name
);
9282 alpha_write_linkage (FILE *stream
, const char *funname
, tree fundecl
)
9284 splay_tree_node node
;
9285 struct alpha_funcs
*func
;
9288 fprintf (stream
, "\t.align 3\n");
9289 node
= splay_tree_lookup (alpha_funcs_tree
, (splay_tree_key
) fundecl
);
9290 func
= (struct alpha_funcs
*) node
->value
;
9292 fputs ("\t.name ", stream
);
9293 assemble_name (stream
, funname
);
9294 fputs ("..na\n", stream
);
9295 ASM_OUTPUT_LABEL (stream
, funname
);
9296 fprintf (stream
, "\t.pdesc ");
9297 assemble_name (stream
, funname
);
9298 fprintf (stream
, "..en,%s\n",
9299 alpha_procedure_type
== PT_STACK
? "stack"
9300 : alpha_procedure_type
== PT_REGISTER
? "reg" : "null");
9304 splay_tree_foreach (func
->links
, alpha_write_one_linkage
, stream
);
9305 /* splay_tree_delete (func->links); */
9309 /* Given a decl, a section name, and whether the decl initializer
9310 has relocs, choose attributes for the section. */
9312 #define SECTION_VMS_OVERLAY SECTION_FORGET
9313 #define SECTION_VMS_GLOBAL SECTION_MACH_DEP
9314 #define SECTION_VMS_INITIALIZE (SECTION_VMS_GLOBAL << 1)
9317 vms_section_type_flags (tree decl
, const char *name
, int reloc
)
9319 unsigned int flags
= default_section_type_flags (decl
, name
, reloc
);
9321 if (decl
&& DECL_ATTRIBUTES (decl
)
9322 && lookup_attribute ("overlaid", DECL_ATTRIBUTES (decl
)))
9323 flags
|= SECTION_VMS_OVERLAY
;
9324 if (decl
&& DECL_ATTRIBUTES (decl
)
9325 && lookup_attribute ("global", DECL_ATTRIBUTES (decl
)))
9326 flags
|= SECTION_VMS_GLOBAL
;
9327 if (decl
&& DECL_ATTRIBUTES (decl
)
9328 && lookup_attribute ("initialize", DECL_ATTRIBUTES (decl
)))
9329 flags
|= SECTION_VMS_INITIALIZE
;
9334 /* Switch to an arbitrary section NAME with attributes as specified
9335 by FLAGS. ALIGN specifies any known alignment requirements for
9336 the section; 0 if the default should be used. */
9339 vms_asm_named_section (const char *name
, unsigned int flags
)
9341 fputc ('\n', asm_out_file
);
9342 fprintf (asm_out_file
, ".section\t%s", name
);
9344 if (flags
& SECTION_VMS_OVERLAY
)
9345 fprintf (asm_out_file
, ",OVR");
9346 if (flags
& SECTION_VMS_GLOBAL
)
9347 fprintf (asm_out_file
, ",GBL");
9348 if (flags
& SECTION_VMS_INITIALIZE
)
9349 fprintf (asm_out_file
, ",NOMOD");
9350 if (flags
& SECTION_DEBUG
)
9351 fprintf (asm_out_file
, ",NOWRT");
9353 fputc ('\n', asm_out_file
);
9356 /* Record an element in the table of global constructors. SYMBOL is
9357 a SYMBOL_REF of the function to be called; PRIORITY is a number
9358 between 0 and MAX_INIT_PRIORITY.
9360 Differs from default_ctors_section_asm_out_constructor in that the
9361 width of the .ctors entry is always 64 bits, rather than the 32 bits
9362 used by a normal pointer. */
9365 vms_asm_out_constructor (rtx symbol
, int priority ATTRIBUTE_UNUSED
)
9368 assemble_align (BITS_PER_WORD
);
9369 assemble_integer (symbol
, UNITS_PER_WORD
, BITS_PER_WORD
, 1);
9373 vms_asm_out_destructor (rtx symbol
, int priority ATTRIBUTE_UNUSED
)
9376 assemble_align (BITS_PER_WORD
);
9377 assemble_integer (symbol
, UNITS_PER_WORD
, BITS_PER_WORD
, 1);
9382 alpha_need_linkage (const char *name ATTRIBUTE_UNUSED
,
9383 int is_local ATTRIBUTE_UNUSED
)
9389 alpha_use_linkage (rtx linkage ATTRIBUTE_UNUSED
,
9390 tree cfundecl ATTRIBUTE_UNUSED
,
9391 int lflag ATTRIBUTE_UNUSED
,
9392 int rflag ATTRIBUTE_UNUSED
)
9397 #endif /* TARGET_ABI_OPEN_VMS */
9399 #if TARGET_ABI_UNICOSMK
9401 /* Define the offset between two registers, one to be eliminated, and the
9402 other its replacement, at the start of a routine. */
9405 unicosmk_initial_elimination_offset (int from
, int to
)
9409 fixed_size
= alpha_sa_size();
9410 if (fixed_size
!= 0)
9413 if (from
== FRAME_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
9415 else if (from
== ARG_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
9417 else if (from
== FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
9418 return (ALPHA_ROUND (current_function_outgoing_args_size
)
9419 + ALPHA_ROUND (get_frame_size()));
9420 else if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
9421 return (ALPHA_ROUND (fixed_size
)
9422 + ALPHA_ROUND (get_frame_size()
9423 + current_function_outgoing_args_size
));
9428 /* Output the module name for .ident and .end directives. We have to strip
9429 directories and add make sure that the module name starts with a letter
9433 unicosmk_output_module_name (FILE *file
)
9435 const char *name
= lbasename (main_input_filename
);
9436 unsigned len
= strlen (name
);
9437 char *clean_name
= alloca (len
+ 2);
9438 char *ptr
= clean_name
;
9440 /* CAM only accepts module names that start with a letter or '$'. We
9441 prefix the module name with a '$' if necessary. */
9443 if (!ISALPHA (*name
))
9445 memcpy (ptr
, name
, len
+ 1);
9446 clean_symbol_name (clean_name
);
9447 fputs (clean_name
, file
);
9450 /* Output the definition of a common variable. */
9453 unicosmk_output_common (FILE *file
, const char *name
, int size
, int align
)
9456 printf ("T3E__: common %s\n", name
);
9459 fputs("\t.endp\n\n\t.psect ", file
);
9460 assemble_name(file
, name
);
9461 fprintf(file
, ",%d,common\n", floor_log2 (align
/ BITS_PER_UNIT
));
9462 fprintf(file
, "\t.byte\t0:%d\n", size
);
9464 /* Mark the symbol as defined in this module. */
9465 name_tree
= get_identifier (name
);
9466 TREE_ASM_WRITTEN (name_tree
) = 1;
9469 #define SECTION_PUBLIC SECTION_MACH_DEP
9470 #define SECTION_MAIN (SECTION_PUBLIC << 1)
9471 static int current_section_align
;
9474 unicosmk_section_type_flags (tree decl
, const char *name
,
9475 int reloc ATTRIBUTE_UNUSED
)
9477 unsigned int flags
= default_section_type_flags (decl
, name
, reloc
);
9482 if (TREE_CODE (decl
) == FUNCTION_DECL
)
9484 current_section_align
= floor_log2 (FUNCTION_BOUNDARY
/ BITS_PER_UNIT
);
9485 if (align_functions_log
> current_section_align
)
9486 current_section_align
= align_functions_log
;
9488 if (! strcmp (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
)), "main"))
9489 flags
|= SECTION_MAIN
;
9492 current_section_align
= floor_log2 (DECL_ALIGN (decl
) / BITS_PER_UNIT
);
9494 if (TREE_PUBLIC (decl
))
9495 flags
|= SECTION_PUBLIC
;
9500 /* Generate a section name for decl and associate it with the
9504 unicosmk_unique_section (tree decl
, int reloc ATTRIBUTE_UNUSED
)
9512 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
9513 name
= default_strip_name_encoding (name
);
9514 len
= strlen (name
);
9516 if (TREE_CODE (decl
) == FUNCTION_DECL
)
9520 /* It is essential that we prefix the section name here because
9521 otherwise the section names generated for constructors and
9522 destructors confuse collect2. */
9524 string
= alloca (len
+ 6);
9525 sprintf (string
, "code@%s", name
);
9526 DECL_SECTION_NAME (decl
) = build_string (len
+ 5, string
);
9528 else if (TREE_PUBLIC (decl
))
9529 DECL_SECTION_NAME (decl
) = build_string (len
, name
);
9534 string
= alloca (len
+ 6);
9535 sprintf (string
, "data@%s", name
);
9536 DECL_SECTION_NAME (decl
) = build_string (len
+ 5, string
);
9540 /* Switch to an arbitrary section NAME with attributes as specified
9541 by FLAGS. ALIGN specifies any known alignment requirements for
9542 the section; 0 if the default should be used. */
9545 unicosmk_asm_named_section (const char *name
, unsigned int flags
)
9549 /* Close the previous section. */
9551 fputs ("\t.endp\n\n", asm_out_file
);
9553 /* Find out what kind of section we are opening. */
9555 if (flags
& SECTION_MAIN
)
9556 fputs ("\t.start\tmain\n", asm_out_file
);
9558 if (flags
& SECTION_CODE
)
9560 else if (flags
& SECTION_PUBLIC
)
9565 if (current_section_align
!= 0)
9566 fprintf (asm_out_file
, "\t.psect\t%s,%d,%s\n", name
,
9567 current_section_align
, kind
);
9569 fprintf (asm_out_file
, "\t.psect\t%s,%s\n", name
, kind
);
9573 unicosmk_insert_attributes (tree decl
, tree
*attr_ptr ATTRIBUTE_UNUSED
)
9576 && (TREE_PUBLIC (decl
) || TREE_CODE (decl
) == FUNCTION_DECL
))
9577 unicosmk_unique_section (decl
, 0);
9580 /* Output an alignment directive. We have to use the macro 'gcc@code@align'
9581 in code sections because .align fill unused space with zeroes. */
9584 unicosmk_output_align (FILE *file
, int align
)
9586 if (inside_function
)
9587 fprintf (file
, "\tgcc@code@align\t%d\n", align
);
9589 fprintf (file
, "\t.align\t%d\n", align
);
9592 /* Add a case vector to the current function's list of deferred case
9593 vectors. Case vectors have to be put into a separate section because CAM
9594 does not allow data definitions in code sections. */
9597 unicosmk_defer_case_vector (rtx lab
, rtx vec
)
9599 struct machine_function
*machine
= cfun
->machine
;
9601 vec
= gen_rtx_EXPR_LIST (VOIDmode
, lab
, vec
);
9602 machine
->addr_list
= gen_rtx_EXPR_LIST (VOIDmode
, vec
,
9603 machine
->addr_list
);
9606 /* Output a case vector. */
9609 unicosmk_output_addr_vec (FILE *file
, rtx vec
)
9611 rtx lab
= XEXP (vec
, 0);
9612 rtx body
= XEXP (vec
, 1);
9613 int vlen
= XVECLEN (body
, 0);
9616 (*targetm
.asm_out
.internal_label
) (file
, "L", CODE_LABEL_NUMBER (lab
));
9618 for (idx
= 0; idx
< vlen
; idx
++)
9620 ASM_OUTPUT_ADDR_VEC_ELT
9621 (file
, CODE_LABEL_NUMBER (XEXP (XVECEXP (body
, 0, idx
), 0)));
9625 /* Output current function's deferred case vectors. */
9628 unicosmk_output_deferred_case_vectors (FILE *file
)
9630 struct machine_function
*machine
= cfun
->machine
;
9633 if (machine
->addr_list
== NULL_RTX
)
9637 for (t
= machine
->addr_list
; t
; t
= XEXP (t
, 1))
9638 unicosmk_output_addr_vec (file
, XEXP (t
, 0));
9641 /* Generate the name of the SSIB section for the current function. */
9643 #define SSIB_PREFIX "__SSIB_"
9644 #define SSIB_PREFIX_LEN 7
9647 unicosmk_ssib_name (void)
9649 /* This is ok since CAM won't be able to deal with names longer than that
9652 static char name
[256];
9658 x
= DECL_RTL (cfun
->decl
);
9659 if (GET_CODE (x
) != MEM
)
9662 if (GET_CODE (x
) != SYMBOL_REF
)
9664 fnname
= XSTR (x
, 0);
9666 len
= strlen (fnname
);
9667 if (len
+ SSIB_PREFIX_LEN
> 255)
9668 len
= 255 - SSIB_PREFIX_LEN
;
9670 strcpy (name
, SSIB_PREFIX
);
9671 strncpy (name
+ SSIB_PREFIX_LEN
, fnname
, len
);
9672 name
[len
+ SSIB_PREFIX_LEN
] = 0;
9677 /* Set up the dynamic subprogram information block (DSIB) and update the
9678 frame pointer register ($15) for subroutines which have a frame. If the
9679 subroutine doesn't have a frame, simply increment $15. */
9682 unicosmk_gen_dsib (unsigned long *imaskP
)
9684 if (alpha_procedure_type
== PT_STACK
)
9686 const char *ssib_name
;
9689 /* Allocate 64 bytes for the DSIB. */
9691 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx
, stack_pointer_rtx
,
9693 emit_insn (gen_blockage ());
9695 /* Save the return address. */
9697 mem
= gen_rtx_MEM (DImode
, plus_constant (stack_pointer_rtx
, 56));
9698 set_mem_alias_set (mem
, alpha_sr_alias_set
);
9699 FRP (emit_move_insn (mem
, gen_rtx_REG (DImode
, REG_RA
)));
9700 (*imaskP
) &= ~(1UL << REG_RA
);
9702 /* Save the old frame pointer. */
9704 mem
= gen_rtx_MEM (DImode
, plus_constant (stack_pointer_rtx
, 48));
9705 set_mem_alias_set (mem
, alpha_sr_alias_set
);
9706 FRP (emit_move_insn (mem
, hard_frame_pointer_rtx
));
9707 (*imaskP
) &= ~(1UL << HARD_FRAME_POINTER_REGNUM
);
9709 emit_insn (gen_blockage ());
9711 /* Store the SSIB pointer. */
9713 ssib_name
= ggc_strdup (unicosmk_ssib_name ());
9714 mem
= gen_rtx_MEM (DImode
, plus_constant (stack_pointer_rtx
, 32));
9715 set_mem_alias_set (mem
, alpha_sr_alias_set
);
9717 FRP (emit_move_insn (gen_rtx_REG (DImode
, 5),
9718 gen_rtx_SYMBOL_REF (Pmode
, ssib_name
)));
9719 FRP (emit_move_insn (mem
, gen_rtx_REG (DImode
, 5)));
9721 /* Save the CIW index. */
9723 mem
= gen_rtx_MEM (DImode
, plus_constant (stack_pointer_rtx
, 24));
9724 set_mem_alias_set (mem
, alpha_sr_alias_set
);
9725 FRP (emit_move_insn (mem
, gen_rtx_REG (DImode
, 25)));
9727 emit_insn (gen_blockage ());
9729 /* Set the new frame pointer. */
9731 FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx
,
9732 stack_pointer_rtx
, GEN_INT (64))));
9737 /* Increment the frame pointer register to indicate that we do not
9740 FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx
,
9741 hard_frame_pointer_rtx
, const1_rtx
)));
9745 /* Output the static subroutine information block for the current
9749 unicosmk_output_ssib (FILE *file
, const char *fnname
)
9755 struct machine_function
*machine
= cfun
->machine
;
9758 fprintf (file
, "\t.endp\n\n\t.psect\t%s%s,data\n", user_label_prefix
,
9759 unicosmk_ssib_name ());
9761 /* Some required stuff and the function name length. */
9763 len
= strlen (fnname
);
9764 fprintf (file
, "\t.quad\t^X20008%2.2X28\n", len
);
9767 ??? We don't do that yet. */
9769 fputs ("\t.quad\t0\n", file
);
9771 /* Function address. */
9773 fputs ("\t.quad\t", file
);
9774 assemble_name (file
, fnname
);
9777 fputs ("\t.quad\t0\n", file
);
9778 fputs ("\t.quad\t0\n", file
);
9781 ??? We do it the same way Cray CC does it but this could be
9784 for( i
= 0; i
< len
; i
++ )
9785 fprintf (file
, "\t.byte\t%d\n", (int)(fnname
[i
]));
9786 if( (len
% 8) == 0 )
9787 fputs ("\t.quad\t0\n", file
);
9789 fprintf (file
, "\t.bits\t%d : 0\n", (8 - (len
% 8))*8);
9791 /* All call information words used in the function. */
9793 for (x
= machine
->first_ciw
; x
; x
= XEXP (x
, 1))
9796 #if HOST_BITS_PER_WIDE_INT == 32
9797 fprintf (file
, "\t.quad\t" HOST_WIDE_INT_PRINT_DOUBLE_HEX
"\n",
9798 CONST_DOUBLE_HIGH (ciw
), CONST_DOUBLE_LOW (ciw
));
9800 fprintf (file
, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX
"\n", INTVAL (ciw
));
9805 /* Add a call information word (CIW) to the list of the current function's
9806 CIWs and return its index.
9808 X is a CONST_INT or CONST_DOUBLE representing the CIW. */
9811 unicosmk_add_call_info_word (rtx x
)
9814 struct machine_function
*machine
= cfun
->machine
;
9816 node
= gen_rtx_EXPR_LIST (VOIDmode
, x
, NULL_RTX
);
9817 if (machine
->first_ciw
== NULL_RTX
)
9818 machine
->first_ciw
= node
;
9820 XEXP (machine
->last_ciw
, 1) = node
;
9822 machine
->last_ciw
= node
;
9823 ++machine
->ciw_count
;
9825 return GEN_INT (machine
->ciw_count
9826 + strlen (current_function_name ())/8 + 5);
9829 static char unicosmk_section_buf
[100];
9832 unicosmk_text_section (void)
9834 static int count
= 0;
9835 sprintf (unicosmk_section_buf
, "\t.endp\n\n\t.psect\tgcc@text___%d,code",
9837 return unicosmk_section_buf
;
9841 unicosmk_data_section (void)
9843 static int count
= 1;
9844 sprintf (unicosmk_section_buf
, "\t.endp\n\n\t.psect\tgcc@data___%d,data",
9846 return unicosmk_section_buf
;
9849 /* The Cray assembler doesn't accept extern declarations for symbols which
9850 are defined in the same file. We have to keep track of all global
9851 symbols which are referenced and/or defined in a source file and output
9852 extern declarations for those which are referenced but not defined at
9855 /* List of identifiers for which an extern declaration might have to be
9857 /* FIXME: needs to use GC, so it can be saved and restored for PCH. */
9859 struct unicosmk_extern_list
9861 struct unicosmk_extern_list
*next
;
9865 static struct unicosmk_extern_list
*unicosmk_extern_head
= 0;
9867 /* Output extern declarations which are required for every asm file. */
9870 unicosmk_output_default_externs (FILE *file
)
9872 static const char *const externs
[] =
9873 { "__T3E_MISMATCH" };
9878 n
= ARRAY_SIZE (externs
);
9880 for (i
= 0; i
< n
; i
++)
9881 fprintf (file
, "\t.extern\t%s\n", externs
[i
]);
9884 /* Output extern declarations for global symbols which are have been
9885 referenced but not defined. */
9888 unicosmk_output_externs (FILE *file
)
9890 struct unicosmk_extern_list
*p
;
9891 const char *real_name
;
9895 len
= strlen (user_label_prefix
);
9896 for (p
= unicosmk_extern_head
; p
!= 0; p
= p
->next
)
9898 /* We have to strip the encoding and possibly remove user_label_prefix
9899 from the identifier in order to handle -fleading-underscore and
9900 explicit asm names correctly (cf. gcc.dg/asm-names-1.c). */
9901 real_name
= default_strip_name_encoding (p
->name
);
9902 if (len
&& p
->name
[0] == '*'
9903 && !memcmp (real_name
, user_label_prefix
, len
))
9906 name_tree
= get_identifier (real_name
);
9907 if (! TREE_ASM_WRITTEN (name_tree
))
9909 TREE_ASM_WRITTEN (name_tree
) = 1;
9910 fputs ("\t.extern\t", file
);
9911 assemble_name (file
, p
->name
);
9917 /* Record an extern. */
9920 unicosmk_add_extern (const char *name
)
9922 struct unicosmk_extern_list
*p
;
9924 p
= (struct unicosmk_extern_list
*)
9925 xmalloc (sizeof (struct unicosmk_extern_list
));
9926 p
->next
= unicosmk_extern_head
;
9928 unicosmk_extern_head
= p
;
9931 /* The Cray assembler generates incorrect code if identifiers which
9932 conflict with register names are used as instruction operands. We have
9933 to replace such identifiers with DEX expressions. */
9935 /* Structure to collect identifiers which have been replaced by DEX
9937 /* FIXME: needs to use GC, so it can be saved and restored for PCH. */
9939 struct unicosmk_dex
{
9940 struct unicosmk_dex
*next
;
9944 /* List of identifiers which have been replaced by DEX expressions. The DEX
9945 number is determined by the position in the list. */
9947 static struct unicosmk_dex
*unicosmk_dex_list
= NULL
;
9949 /* The number of elements in the DEX list. */
9951 static int unicosmk_dex_count
= 0;
9953 /* Check if NAME must be replaced by a DEX expression. */
9956 unicosmk_special_name (const char *name
)
9964 if (name
[0] != 'r' && name
[0] != 'f' && name
[0] != 'R' && name
[0] != 'F')
9970 return (name
[2] == '\0' || (ISDIGIT (name
[2]) && name
[3] == '\0'));
9973 return (name
[2] == '\0'
9974 || ((name
[2] == '0' || name
[2] == '1') && name
[3] == '\0'));
9977 return (ISDIGIT (name
[1]) && name
[2] == '\0');
9981 /* Return the DEX number if X must be replaced by a DEX expression and 0
9985 unicosmk_need_dex (rtx x
)
9987 struct unicosmk_dex
*dex
;
9991 if (GET_CODE (x
) != SYMBOL_REF
)
9995 if (! unicosmk_special_name (name
))
9998 i
= unicosmk_dex_count
;
9999 for (dex
= unicosmk_dex_list
; dex
; dex
= dex
->next
)
10001 if (! strcmp (name
, dex
->name
))
10006 dex
= (struct unicosmk_dex
*) xmalloc (sizeof (struct unicosmk_dex
));
10008 dex
->next
= unicosmk_dex_list
;
10009 unicosmk_dex_list
= dex
;
10011 ++unicosmk_dex_count
;
10012 return unicosmk_dex_count
;
10015 /* Output the DEX definitions for this file. */
10018 unicosmk_output_dex (FILE *file
)
10020 struct unicosmk_dex
*dex
;
10023 if (unicosmk_dex_list
== NULL
)
10026 fprintf (file
, "\t.dexstart\n");
10028 i
= unicosmk_dex_count
;
10029 for (dex
= unicosmk_dex_list
; dex
; dex
= dex
->next
)
10031 fprintf (file
, "\tDEX (%d) = ", i
);
10032 assemble_name (file
, dex
->name
);
10037 fprintf (file
, "\t.dexend\n");
10040 /* Output text that to appear at the beginning of an assembler file. */
10043 unicosmk_file_start (void)
10047 fputs ("\t.ident\t", asm_out_file
);
10048 unicosmk_output_module_name (asm_out_file
);
10049 fputs ("\n\n", asm_out_file
);
10051 /* The Unicos/Mk assembler uses different register names. Instead of trying
10052 to support them, we simply use micro definitions. */
10054 /* CAM has different register names: rN for the integer register N and fN
10055 for the floating-point register N. Instead of trying to use these in
10056 alpha.md, we define the symbols $N and $fN to refer to the appropriate
10059 for (i
= 0; i
< 32; ++i
)
10060 fprintf (asm_out_file
, "$%d <- r%d\n", i
, i
);
10062 for (i
= 0; i
< 32; ++i
)
10063 fprintf (asm_out_file
, "$f%d <- f%d\n", i
, i
);
10065 putc ('\n', asm_out_file
);
10067 /* The .align directive fill unused space with zeroes which does not work
10068 in code sections. We define the macro 'gcc@code@align' which uses nops
10069 instead. Note that it assumes that code sections always have the
10070 biggest possible alignment since . refers to the current offset from
10071 the beginning of the section. */
10073 fputs ("\t.macro gcc@code@align n\n", asm_out_file
);
10074 fputs ("gcc@n@bytes = 1 << n\n", asm_out_file
);
10075 fputs ("gcc@here = . % gcc@n@bytes\n", asm_out_file
);
10076 fputs ("\t.if ne, gcc@here, 0\n", asm_out_file
);
10077 fputs ("\t.repeat (gcc@n@bytes - gcc@here) / 4\n", asm_out_file
);
10078 fputs ("\tbis r31,r31,r31\n", asm_out_file
);
10079 fputs ("\t.endr\n", asm_out_file
);
10080 fputs ("\t.endif\n", asm_out_file
);
10081 fputs ("\t.endm gcc@code@align\n\n", asm_out_file
);
10083 /* Output extern declarations which should always be visible. */
10084 unicosmk_output_default_externs (asm_out_file
);
10086 /* Open a dummy section. We always need to be inside a section for the
10087 section-switching code to work correctly.
10088 ??? This should be a module id or something like that. I still have to
10089 figure out what the rules for those are. */
10090 fputs ("\n\t.psect\t$SG00000,data\n", asm_out_file
);
10093 /* Output text to appear at the end of an assembler file. This includes all
10094 pending extern declarations and DEX expressions. */
10097 unicosmk_file_end (void)
10099 fputs ("\t.endp\n\n", asm_out_file
);
10101 /* Output all pending externs. */
10103 unicosmk_output_externs (asm_out_file
);
10105 /* Output dex definitions used for functions whose names conflict with
10108 unicosmk_output_dex (asm_out_file
);
10110 fputs ("\t.end\t", asm_out_file
);
10111 unicosmk_output_module_name (asm_out_file
);
10112 putc ('\n', asm_out_file
);
10118 unicosmk_output_deferred_case_vectors (FILE *file ATTRIBUTE_UNUSED
)
10122 unicosmk_gen_dsib (unsigned long *imaskP ATTRIBUTE_UNUSED
)
10126 unicosmk_output_ssib (FILE * file ATTRIBUTE_UNUSED
,
10127 const char * fnname ATTRIBUTE_UNUSED
)
10131 unicosmk_add_call_info_word (rtx x ATTRIBUTE_UNUSED
)
10137 unicosmk_need_dex (rtx x ATTRIBUTE_UNUSED
)
10142 #endif /* TARGET_ABI_UNICOSMK */
10145 alpha_init_libfuncs (void)
10147 if (TARGET_ABI_UNICOSMK
)
10149 /* Prevent gcc from generating calls to __divsi3. */
10150 set_optab_libfunc (sdiv_optab
, SImode
, 0);
10151 set_optab_libfunc (udiv_optab
, SImode
, 0);
10153 /* Use the functions provided by the system library
10154 for DImode integer division. */
10155 set_optab_libfunc (sdiv_optab
, DImode
, "$sldiv");
10156 set_optab_libfunc (udiv_optab
, DImode
, "$uldiv");
10158 else if (TARGET_ABI_OPEN_VMS
)
10160 /* Use the VMS runtime library functions for division and
10162 set_optab_libfunc (sdiv_optab
, SImode
, "OTS$DIV_I");
10163 set_optab_libfunc (sdiv_optab
, DImode
, "OTS$DIV_L");
10164 set_optab_libfunc (udiv_optab
, SImode
, "OTS$DIV_UI");
10165 set_optab_libfunc (udiv_optab
, DImode
, "OTS$DIV_UL");
10166 set_optab_libfunc (smod_optab
, SImode
, "OTS$REM_I");
10167 set_optab_libfunc (smod_optab
, DImode
, "OTS$REM_L");
10168 set_optab_libfunc (umod_optab
, SImode
, "OTS$REM_UI");
10169 set_optab_libfunc (umod_optab
, DImode
, "OTS$REM_UL");
10174 /* Initialize the GCC target structure. */
10175 #if TARGET_ABI_OPEN_VMS
10176 # undef TARGET_ATTRIBUTE_TABLE
10177 # define TARGET_ATTRIBUTE_TABLE vms_attribute_table
10178 # undef TARGET_SECTION_TYPE_FLAGS
10179 # define TARGET_SECTION_TYPE_FLAGS vms_section_type_flags
10182 #undef TARGET_IN_SMALL_DATA_P
10183 #define TARGET_IN_SMALL_DATA_P alpha_in_small_data_p
10185 #if TARGET_ABI_UNICOSMK
10186 # undef TARGET_INSERT_ATTRIBUTES
10187 # define TARGET_INSERT_ATTRIBUTES unicosmk_insert_attributes
10188 # undef TARGET_SECTION_TYPE_FLAGS
10189 # define TARGET_SECTION_TYPE_FLAGS unicosmk_section_type_flags
10190 # undef TARGET_ASM_UNIQUE_SECTION
10191 # define TARGET_ASM_UNIQUE_SECTION unicosmk_unique_section
10192 # undef TARGET_ASM_GLOBALIZE_LABEL
10193 # define TARGET_ASM_GLOBALIZE_LABEL hook_void_FILEptr_constcharptr
10196 #undef TARGET_ASM_ALIGNED_HI_OP
10197 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
10198 #undef TARGET_ASM_ALIGNED_DI_OP
10199 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
10201 /* Default unaligned ops are provided for ELF systems. To get unaligned
10202 data for non-ELF systems, we have to turn off auto alignment. */
10203 #ifndef OBJECT_FORMAT_ELF
10204 #undef TARGET_ASM_UNALIGNED_HI_OP
10205 #define TARGET_ASM_UNALIGNED_HI_OP "\t.align 0\n\t.word\t"
10206 #undef TARGET_ASM_UNALIGNED_SI_OP
10207 #define TARGET_ASM_UNALIGNED_SI_OP "\t.align 0\n\t.long\t"
10208 #undef TARGET_ASM_UNALIGNED_DI_OP
10209 #define TARGET_ASM_UNALIGNED_DI_OP "\t.align 0\n\t.quad\t"
10212 #ifdef OBJECT_FORMAT_ELF
10213 #undef TARGET_ASM_SELECT_RTX_SECTION
10214 #define TARGET_ASM_SELECT_RTX_SECTION alpha_elf_select_rtx_section
10217 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
10218 #define TARGET_ASM_FUNCTION_END_PROLOGUE alpha_output_function_end_prologue
10220 #undef TARGET_INIT_LIBFUNCS
10221 #define TARGET_INIT_LIBFUNCS alpha_init_libfuncs
10223 #if TARGET_ABI_UNICOSMK
10224 #undef TARGET_ASM_FILE_START
10225 #define TARGET_ASM_FILE_START unicosmk_file_start
10226 #undef TARGET_ASM_FILE_END
10227 #define TARGET_ASM_FILE_END unicosmk_file_end
10229 #undef TARGET_ASM_FILE_START
10230 #define TARGET_ASM_FILE_START alpha_file_start
10231 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
10232 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
10235 #undef TARGET_SCHED_ADJUST_COST
10236 #define TARGET_SCHED_ADJUST_COST alpha_adjust_cost
10237 #undef TARGET_SCHED_ISSUE_RATE
10238 #define TARGET_SCHED_ISSUE_RATE alpha_issue_rate
10239 #undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
10240 #define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE \
10241 alpha_use_dfa_pipeline_interface
10242 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
10243 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
10244 alpha_multipass_dfa_lookahead
10246 #undef TARGET_HAVE_TLS
10247 #define TARGET_HAVE_TLS HAVE_AS_TLS
10249 #undef TARGET_INIT_BUILTINS
10250 #define TARGET_INIT_BUILTINS alpha_init_builtins
10251 #undef TARGET_EXPAND_BUILTIN
10252 #define TARGET_EXPAND_BUILTIN alpha_expand_builtin
10254 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
10255 #define TARGET_FUNCTION_OK_FOR_SIBCALL alpha_function_ok_for_sibcall
10256 #undef TARGET_CANNOT_COPY_INSN_P
10257 #define TARGET_CANNOT_COPY_INSN_P alpha_cannot_copy_insn_p
10260 #undef TARGET_ASM_OUTPUT_MI_THUNK
10261 #define TARGET_ASM_OUTPUT_MI_THUNK alpha_output_mi_thunk_osf
10262 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
10263 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
10266 #undef TARGET_RTX_COSTS
10267 #define TARGET_RTX_COSTS alpha_rtx_costs
10268 #undef TARGET_ADDRESS_COST
10269 #define TARGET_ADDRESS_COST hook_int_rtx_0
10271 #undef TARGET_MACHINE_DEPENDENT_REORG
10272 #define TARGET_MACHINE_DEPENDENT_REORG alpha_reorg
10274 #undef TARGET_PROMOTE_FUNCTION_ARGS
10275 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
10276 #undef TARGET_PROMOTE_FUNCTION_RETURN
10277 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
10278 #undef TARGET_PROMOTE_PROTOTYPES
10279 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_false
10280 #undef TARGET_RETURN_IN_MEMORY
10281 #define TARGET_RETURN_IN_MEMORY alpha_return_in_memory
10282 #undef TARGET_SETUP_INCOMING_VARARGS
10283 #define TARGET_SETUP_INCOMING_VARARGS alpha_setup_incoming_varargs
10284 #undef TARGET_STRICT_ARGUMENT_NAMING
10285 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
10286 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
10287 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
10288 #undef TARGET_SPLIT_COMPLEX_ARG
10289 #define TARGET_SPLIT_COMPLEX_ARG alpha_split_complex_arg
10290 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
10291 #define TARGET_GIMPLIFY_VA_ARG_EXPR alpha_gimplify_va_arg
10293 #undef TARGET_BUILD_BUILTIN_VA_LIST
10294 #define TARGET_BUILD_BUILTIN_VA_LIST alpha_build_builtin_va_list
10296 struct gcc_target targetm
= TARGET_INITIALIZER
;
10299 #include "gt-alpha.h"