1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001 Free Software Foundation, Inc.
4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
6 This file is part of GNU CC.
8 GNU CC 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 GNU CC 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 GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
29 #include "hard-reg-set.h"
31 #include "insn-config.h"
32 #include "conditions.h"
34 #include "insn-attr.h"
45 #include "integrate.h"
48 #include "target-def.h"
51 extern int rtx_equal_function_value_matters;
53 /* Specify which cpu to schedule for. */
55 enum processor_type alpha_cpu;
56 static const char * const alpha_cpu_name[] =
61 /* Specify how accurate floating-point traps need to be. */
63 enum alpha_trap_precision alpha_tp;
65 /* Specify the floating-point rounding mode. */
67 enum alpha_fp_rounding_mode alpha_fprm;
69 /* Specify which things cause traps. */
71 enum alpha_fp_trap_mode alpha_fptm;
73 /* Strings decoded into the above options. */
75 const char *alpha_cpu_string; /* -mcpu= */
76 const char *alpha_tune_string; /* -mtune= */
77 const char *alpha_tp_string; /* -mtrap-precision=[p|s|i] */
78 const char *alpha_fprm_string; /* -mfp-rounding-mode=[n|m|c|d] */
79 const char *alpha_fptm_string; /* -mfp-trap-mode=[n|u|su|sui] */
80 const char *alpha_mlat_string; /* -mmemory-latency= */
82 /* Save information from a "cmpxx" operation until the branch or scc is
85 struct alpha_compare alpha_compare;
87 /* Non-zero if inside of a function, because the Alpha asm can't
88 handle .files inside of functions. */
90 static int inside_function = FALSE;
92 /* The number of cycles of latency we should assume on memory reads. */
94 int alpha_memory_latency = 3;
96 /* Whether the function needs the GP. */
98 static int alpha_function_needs_gp;
100 /* The alias set for prologue/epilogue register save/restore. */
102 static int alpha_sr_alias_set;
104 /* The assembler name of the current function. */
106 static const char *alpha_fnname;
108 /* The next explicit relocation sequence number. */
109 int alpha_next_sequence_number = 1;
111 /* The literal and gpdisp sequence numbers for this insn, as printed
112 by %# and %* respectively. */
113 int alpha_this_literal_sequence_number;
114 int alpha_this_gpdisp_sequence_number;
116 /* Declarations of static functions. */
117 static bool local_symbol_p
119 static void alpha_set_memflags_1
120 PARAMS ((rtx, int, int, int));
121 static rtx alpha_emit_set_const_1
122 PARAMS ((rtx, enum machine_mode, HOST_WIDE_INT, int));
123 static void alpha_expand_unaligned_load_words
124 PARAMS ((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
125 static void alpha_expand_unaligned_store_words
126 PARAMS ((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
127 static void alpha_sa_mask
128 PARAMS ((unsigned long *imaskP, unsigned long *fmaskP));
129 static int find_lo_sum
130 PARAMS ((rtx *, void *));
131 static int alpha_does_function_need_gp
133 static int alpha_ra_ever_killed
135 static const char *get_trap_mode_suffix
137 static const char *get_round_mode_suffix
139 static rtx set_frame_related_p
141 static const char *alpha_lookup_xfloating_lib_func
142 PARAMS ((enum rtx_code));
143 static int alpha_compute_xfloating_mode_arg
144 PARAMS ((enum rtx_code, enum alpha_fp_rounding_mode));
145 static void alpha_emit_xfloating_libcall
146 PARAMS ((const char *, rtx, rtx[], int, rtx));
147 static rtx alpha_emit_xfloating_compare
148 PARAMS ((enum rtx_code, rtx, rtx));
149 static void alpha_output_function_end_prologue
151 static int alpha_adjust_cost
152 PARAMS ((rtx, rtx, rtx, int));
153 static int alpha_issue_rate
155 static int alpha_variable_issue
156 PARAMS ((FILE *, int, rtx, int));
158 #if TARGET_ABI_UNICOSMK
159 static void alpha_init_machine_status
160 PARAMS ((struct function *p));
161 static void alpha_mark_machine_status
162 PARAMS ((struct function *p));
163 static void alpha_free_machine_status
164 PARAMS ((struct function *p));
167 static void unicosmk_output_deferred_case_vectors PARAMS ((FILE *));
168 static void unicosmk_gen_dsib PARAMS ((unsigned long *imaskP));
169 static void unicosmk_output_ssib PARAMS ((FILE *, const char *));
170 static int unicosmk_need_dex PARAMS ((rtx));
172 /* Get the number of args of a function in one of two ways. */
173 #if TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK
174 #define NUM_ARGS current_function_args_info.num_args
176 #define NUM_ARGS current_function_args_info
182 /* Initialize the GCC target structure. */
183 #if TARGET_ABI_OPEN_VMS
184 const struct attribute_spec vms_attribute_table[];
185 static unsigned int vms_section_type_flags PARAMS ((tree, const char *, int));
186 static void vms_asm_named_section PARAMS ((const char *, unsigned int));
187 static void vms_asm_out_constructor PARAMS ((rtx, int));
188 static void vms_asm_out_destructor PARAMS ((rtx, int));
189 # undef TARGET_ATTRIBUTE_TABLE
190 # define TARGET_ATTRIBUTE_TABLE vms_attribute_table
191 # undef TARGET_SECTION_TYPE_FLAGS
192 # define TARGET_SECTION_TYPE_FLAGS vms_section_type_flags
195 #if TARGET_ABI_UNICOSMK
196 static void unicosmk_asm_named_section PARAMS ((const char *, unsigned int));
197 static void unicosmk_insert_attributes PARAMS ((tree, tree *));
198 static unsigned int unicosmk_section_type_flags PARAMS ((tree, const char *,
200 # undef TARGET_INSERT_ATTRIBUTES
201 # define TARGET_INSERT_ATTRIBUTES unicosmk_insert_attributes
202 # undef TARGET_SECTION_TYPE_FLAGS
203 # define TARGET_SECTION_TYPE_FLAGS unicosmk_section_type_flags
206 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
207 #define TARGET_ASM_FUNCTION_END_PROLOGUE alpha_output_function_end_prologue
209 #undef TARGET_SCHED_ADJUST_COST
210 #define TARGET_SCHED_ADJUST_COST alpha_adjust_cost
211 #undef TARGET_SCHED_ISSUE_RATE
212 #define TARGET_SCHED_ISSUE_RATE alpha_issue_rate
213 #undef TARGET_SCHED_VARIABLE_ISSUE
214 #define TARGET_SCHED_VARIABLE_ISSUE alpha_variable_issue
216 struct gcc_target targetm = TARGET_INITIALIZER;
218 /* Parse target option strings. */
224 static const struct cpu_table {
225 const char *const name;
226 const enum processor_type processor;
229 #define EV5_MASK (MASK_CPU_EV5)
230 #define EV6_MASK (MASK_CPU_EV6|MASK_BWX|MASK_MAX|MASK_FIX)
231 { "ev4", PROCESSOR_EV4, 0 },
232 { "ev45", PROCESSOR_EV4, 0 },
233 { "21064", PROCESSOR_EV4, 0 },
234 { "ev5", PROCESSOR_EV5, EV5_MASK },
235 { "21164", PROCESSOR_EV5, EV5_MASK },
236 { "ev56", PROCESSOR_EV5, EV5_MASK|MASK_BWX },
237 { "21164a", PROCESSOR_EV5, EV5_MASK|MASK_BWX },
238 { "pca56", PROCESSOR_EV5, EV5_MASK|MASK_BWX|MASK_MAX },
239 { "21164PC",PROCESSOR_EV5, EV5_MASK|MASK_BWX|MASK_MAX },
240 { "21164pc",PROCESSOR_EV5, EV5_MASK|MASK_BWX|MASK_MAX },
241 { "ev6", PROCESSOR_EV6, EV6_MASK },
242 { "21264", PROCESSOR_EV6, EV6_MASK },
243 { "ev67", PROCESSOR_EV6, EV6_MASK|MASK_CIX },
244 { "21264a", PROCESSOR_EV6, EV6_MASK|MASK_CIX },
248 /* Unicos/Mk doesn't have shared libraries. */
249 if (TARGET_ABI_UNICOSMK && flag_pic)
251 warning ("-f%s ignored for Unicos/Mk (not supported)",
252 (flag_pic > 1) ? "PIC" : "pic");
256 /* On Unicos/Mk, the native compiler consistenly generates /d suffices for
257 floating-point instructions. Make that the default for this target. */
258 if (TARGET_ABI_UNICOSMK)
259 alpha_fprm = ALPHA_FPRM_DYN;
261 alpha_fprm = ALPHA_FPRM_NORM;
263 alpha_tp = ALPHA_TP_PROG;
264 alpha_fptm = ALPHA_FPTM_N;
266 /* We cannot use su and sui qualifiers for conversion instructions on
267 Unicos/Mk. I'm not sure if this is due to assembler or hardware
268 limitations. Right now, we issue a warning if -mieee is specified
269 and then ignore it; eventually, we should either get it right or
270 disable the option altogether. */
274 if (TARGET_ABI_UNICOSMK)
275 warning ("-mieee not supported on Unicos/Mk");
278 alpha_tp = ALPHA_TP_INSN;
279 alpha_fptm = ALPHA_FPTM_SU;
283 if (TARGET_IEEE_WITH_INEXACT)
285 if (TARGET_ABI_UNICOSMK)
286 warning ("-mieee-with-inexact not supported on Unicos/Mk");
289 alpha_tp = ALPHA_TP_INSN;
290 alpha_fptm = ALPHA_FPTM_SUI;
296 if (! strcmp (alpha_tp_string, "p"))
297 alpha_tp = ALPHA_TP_PROG;
298 else if (! strcmp (alpha_tp_string, "f"))
299 alpha_tp = ALPHA_TP_FUNC;
300 else if (! strcmp (alpha_tp_string, "i"))
301 alpha_tp = ALPHA_TP_INSN;
303 error ("bad value `%s' for -mtrap-precision switch", alpha_tp_string);
306 if (alpha_fprm_string)
308 if (! strcmp (alpha_fprm_string, "n"))
309 alpha_fprm = ALPHA_FPRM_NORM;
310 else if (! strcmp (alpha_fprm_string, "m"))
311 alpha_fprm = ALPHA_FPRM_MINF;
312 else if (! strcmp (alpha_fprm_string, "c"))
313 alpha_fprm = ALPHA_FPRM_CHOP;
314 else if (! strcmp (alpha_fprm_string,"d"))
315 alpha_fprm = ALPHA_FPRM_DYN;
317 error ("bad value `%s' for -mfp-rounding-mode switch",
321 if (alpha_fptm_string)
323 if (strcmp (alpha_fptm_string, "n") == 0)
324 alpha_fptm = ALPHA_FPTM_N;
325 else if (strcmp (alpha_fptm_string, "u") == 0)
326 alpha_fptm = ALPHA_FPTM_U;
327 else if (strcmp (alpha_fptm_string, "su") == 0)
328 alpha_fptm = ALPHA_FPTM_SU;
329 else if (strcmp (alpha_fptm_string, "sui") == 0)
330 alpha_fptm = ALPHA_FPTM_SUI;
332 error ("bad value `%s' for -mfp-trap-mode switch", alpha_fptm_string);
336 = TARGET_CPU_DEFAULT & MASK_CPU_EV6 ? PROCESSOR_EV6
337 : (TARGET_CPU_DEFAULT & MASK_CPU_EV5 ? PROCESSOR_EV5 : PROCESSOR_EV4);
339 if (alpha_cpu_string)
341 for (i = 0; cpu_table [i].name; i++)
342 if (! strcmp (alpha_cpu_string, cpu_table [i].name))
344 alpha_cpu = cpu_table [i].processor;
345 target_flags &= ~ (MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX
346 | MASK_CPU_EV5 | MASK_CPU_EV6);
347 target_flags |= cpu_table [i].flags;
350 if (! cpu_table [i].name)
351 error ("bad value `%s' for -mcpu switch", alpha_cpu_string);
354 if (alpha_tune_string)
356 for (i = 0; cpu_table [i].name; i++)
357 if (! strcmp (alpha_tune_string, cpu_table [i].name))
359 alpha_cpu = cpu_table [i].processor;
362 if (! cpu_table [i].name)
363 error ("bad value `%s' for -mcpu switch", alpha_tune_string);
366 /* Do some sanity checks on the above options. */
368 if (TARGET_ABI_UNICOSMK && alpha_fptm != ALPHA_FPTM_N)
370 warning ("trap mode not supported on Unicos/Mk");
371 alpha_fptm = ALPHA_FPTM_N;
374 if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI)
375 && alpha_tp != ALPHA_TP_INSN && ! TARGET_CPU_EV6)
377 warning ("fp software completion requires -mtrap-precision=i");
378 alpha_tp = ALPHA_TP_INSN;
383 /* Except for EV6 pass 1 (not released), we always have precise
384 arithmetic traps. Which means we can do software completion
385 without minding trap shadows. */
386 alpha_tp = ALPHA_TP_PROG;
389 if (TARGET_FLOAT_VAX)
391 if (alpha_fprm == ALPHA_FPRM_MINF || alpha_fprm == ALPHA_FPRM_DYN)
393 warning ("rounding mode not supported for VAX floats");
394 alpha_fprm = ALPHA_FPRM_NORM;
396 if (alpha_fptm == ALPHA_FPTM_SUI)
398 warning ("trap mode not supported for VAX floats");
399 alpha_fptm = ALPHA_FPTM_SU;
407 if (!alpha_mlat_string)
408 alpha_mlat_string = "L1";
410 if (ISDIGIT ((unsigned char)alpha_mlat_string[0])
411 && (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0'))
413 else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l')
414 && ISDIGIT ((unsigned char)alpha_mlat_string[1])
415 && alpha_mlat_string[2] == '\0')
417 static int const cache_latency[][4] =
419 { 3, 30, -1 }, /* ev4 -- Bcache is a guess */
420 { 2, 12, 38 }, /* ev5 -- Bcache from PC164 LMbench numbers */
421 { 3, 12, 30 }, /* ev6 -- Bcache from DS20 LMbench. */
424 lat = alpha_mlat_string[1] - '0';
425 if (lat <= 0 || lat > 3 || cache_latency[alpha_cpu][lat-1] == -1)
427 warning ("L%d cache latency unknown for %s",
428 lat, alpha_cpu_name[alpha_cpu]);
432 lat = cache_latency[alpha_cpu][lat-1];
434 else if (! strcmp (alpha_mlat_string, "main"))
436 /* Most current memories have about 370ns latency. This is
437 a reasonable guess for a fast cpu. */
442 warning ("bad value `%s' for -mmemory-latency", alpha_mlat_string);
446 alpha_memory_latency = lat;
449 /* Default the definition of "small data" to 8 bytes. */
453 /* Infer TARGET_SMALL_DATA from -fpic/-fPIC. */
455 target_flags |= MASK_SMALL_DATA;
456 else if (flag_pic == 2)
457 target_flags &= ~MASK_SMALL_DATA;
459 /* Align labels and loops for optimal branching. */
460 /* ??? Kludge these by not doing anything if we don't optimize and also if
461 we are writing ECOFF symbols to work around a bug in DEC's assembler. */
462 if (optimize > 0 && write_symbols != SDB_DEBUG)
464 if (align_loops <= 0)
466 if (align_jumps <= 0)
469 if (align_functions <= 0)
470 align_functions = 16;
472 /* Acquire a unique set number for our register saves and restores. */
473 alpha_sr_alias_set = new_alias_set ();
475 /* Register variables and functions with the garbage collector. */
477 #if TARGET_ABI_UNICOSMK
478 /* Set up function hooks. */
479 init_machine_status = alpha_init_machine_status;
480 mark_machine_status = alpha_mark_machine_status;
481 free_machine_status = alpha_free_machine_status;
485 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
493 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
495 if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
501 /* Returns 1 if OP is either the constant zero or a register. If a
502 register, it must be in the proper mode unless MODE is VOIDmode. */
505 reg_or_0_operand (op, mode)
507 enum machine_mode mode;
509 return op == const0_rtx || register_operand (op, mode);
512 /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
516 reg_or_6bit_operand (op, mode)
518 enum machine_mode mode;
520 return ((GET_CODE (op) == CONST_INT
521 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64)
522 || register_operand (op, mode));
526 /* Return 1 if OP is an 8-bit constant or any register. */
529 reg_or_8bit_operand (op, mode)
531 enum machine_mode mode;
533 return ((GET_CODE (op) == CONST_INT
534 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
535 || register_operand (op, mode));
538 /* Return 1 if OP is an 8-bit constant. */
541 cint8_operand (op, mode)
543 enum machine_mode mode ATTRIBUTE_UNUSED;
545 return ((GET_CODE (op) == CONST_INT
546 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100));
549 /* Return 1 if the operand is a valid second operand to an add insn. */
552 add_operand (op, mode)
554 enum machine_mode mode;
556 if (GET_CODE (op) == CONST_INT)
557 /* Constraints I, J, O and P are covered by K. */
558 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'K')
559 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
561 return register_operand (op, mode);
564 /* Return 1 if the operand is a valid second operand to a sign-extending
568 sext_add_operand (op, mode)
570 enum machine_mode mode;
572 if (GET_CODE (op) == CONST_INT)
573 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
574 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'O'));
576 return reg_not_elim_operand (op, mode);
579 /* Return 1 if OP is the constant 4 or 8. */
582 const48_operand (op, mode)
584 enum machine_mode mode ATTRIBUTE_UNUSED;
586 return (GET_CODE (op) == CONST_INT
587 && (INTVAL (op) == 4 || INTVAL (op) == 8));
590 /* Return 1 if OP is a valid first operand to an AND insn. */
593 and_operand (op, mode)
595 enum machine_mode mode;
597 if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
598 return (zap_mask (CONST_DOUBLE_LOW (op))
599 && zap_mask (CONST_DOUBLE_HIGH (op)));
601 if (GET_CODE (op) == CONST_INT)
602 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
603 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
604 || zap_mask (INTVAL (op)));
606 return register_operand (op, mode);
609 /* Return 1 if OP is a valid first operand to an IOR or XOR insn. */
612 or_operand (op, mode)
614 enum machine_mode mode;
616 if (GET_CODE (op) == CONST_INT)
617 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
618 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100);
620 return register_operand (op, mode);
623 /* Return 1 if OP is a constant that is the width, in bits, of an integral
624 mode smaller than DImode. */
627 mode_width_operand (op, mode)
629 enum machine_mode mode ATTRIBUTE_UNUSED;
631 return (GET_CODE (op) == CONST_INT
632 && (INTVAL (op) == 8 || INTVAL (op) == 16
633 || INTVAL (op) == 32 || INTVAL (op) == 64));
636 /* Return 1 if OP is a constant that is the width of an integral machine mode
637 smaller than an integer. */
640 mode_mask_operand (op, mode)
642 enum machine_mode mode ATTRIBUTE_UNUSED;
644 #if HOST_BITS_PER_WIDE_INT == 32
645 if (GET_CODE (op) == CONST_DOUBLE)
646 return (CONST_DOUBLE_LOW (op) == -1
647 && (CONST_DOUBLE_HIGH (op) == -1
648 || CONST_DOUBLE_HIGH (op) == 0));
650 if (GET_CODE (op) == CONST_DOUBLE)
651 return (CONST_DOUBLE_LOW (op) == -1 && CONST_DOUBLE_HIGH (op) == 0);
654 return (GET_CODE (op) == CONST_INT
655 && (INTVAL (op) == 0xff
656 || INTVAL (op) == 0xffff
657 || INTVAL (op) == (HOST_WIDE_INT)0xffffffff
658 #if HOST_BITS_PER_WIDE_INT == 64
664 /* Return 1 if OP is a multiple of 8 less than 64. */
667 mul8_operand (op, mode)
669 enum machine_mode mode ATTRIBUTE_UNUSED;
671 return (GET_CODE (op) == CONST_INT
672 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64
673 && (INTVAL (op) & 7) == 0);
676 /* Return 1 if OP is the constant zero in floating-point. */
679 fp0_operand (op, mode)
681 enum machine_mode mode;
683 return (GET_MODE (op) == mode
684 && GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode));
687 /* Return 1 if OP is the floating-point constant zero or a register. */
690 reg_or_fp0_operand (op, mode)
692 enum machine_mode mode;
694 return fp0_operand (op, mode) || register_operand (op, mode);
697 /* Return 1 if OP is a hard floating-point register. */
700 hard_fp_register_operand (op, mode)
702 enum machine_mode mode;
704 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
707 if (GET_CODE (op) == SUBREG)
708 op = SUBREG_REG (op);
709 return GET_CODE (op) == REG && REGNO_REG_CLASS (REGNO (op)) == FLOAT_REGS;
712 /* Return 1 if OP is a hard general register. */
715 hard_int_register_operand (op, mode)
717 enum machine_mode mode;
719 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
722 if (GET_CODE (op) == SUBREG)
723 op = SUBREG_REG (op);
724 return GET_CODE (op) == REG && REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS;
727 /* Return 1 if OP is a register or a constant integer. */
731 reg_or_cint_operand (op, mode)
733 enum machine_mode mode;
735 return (GET_CODE (op) == CONST_INT
736 || register_operand (op, mode));
739 /* Return 1 if OP is something that can be reloaded into a register;
740 if it is a MEM, it need not be valid. */
743 some_operand (op, mode)
745 enum machine_mode mode;
747 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
750 switch (GET_CODE (op))
752 case REG: case MEM: case CONST_DOUBLE: case CONST_INT: case LABEL_REF:
753 case SYMBOL_REF: case CONST:
757 return some_operand (SUBREG_REG (op), VOIDmode);
766 /* Likewise, but don't accept constants. */
769 some_ni_operand (op, mode)
771 enum machine_mode mode;
773 if (GET_MODE (op) != mode && mode != VOIDmode)
776 if (GET_CODE (op) == SUBREG)
777 op = SUBREG_REG (op);
779 return (GET_CODE (op) == REG || GET_CODE (op) == MEM);
782 /* Return 1 if OP is a valid operand for the source of a move insn. */
785 input_operand (op, mode)
787 enum machine_mode mode;
789 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
792 if (GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE (op) != mode)
795 switch (GET_CODE (op))
800 if (TARGET_EXPLICIT_RELOCS)
803 /* This handles both the Windows/NT and OSF cases. */
804 return mode == ptr_mode || mode == DImode;
811 if (register_operand (op, mode))
813 /* ... fall through ... */
815 return ((TARGET_BWX || (mode != HImode && mode != QImode))
816 && general_operand (op, mode));
819 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
822 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
838 current_file_function_operand (op, mode)
840 enum machine_mode mode ATTRIBUTE_UNUSED;
842 if (GET_CODE (op) != SYMBOL_REF)
845 if (! SYMBOL_REF_FLAG (op)
846 && op != XEXP (DECL_RTL (current_function_decl), 0))
852 /* Return 1 if OP is a SYMBOL_REF for which we can make a call via bsr. */
855 direct_call_operand (op, mode)
857 enum machine_mode mode;
859 /* Must be defined in this file. */
860 if (! current_file_function_operand (op, mode))
863 /* If profiling is implemented via linker tricks, we can't jump
864 to the nogp alternate entry point. */
865 /* ??? TARGET_PROFILING_NEEDS_GP isn't really the right test,
866 but is approximately correct for the OSF ABIs. Don't know
867 what to do for VMS, NT, or UMK. */
868 if (! TARGET_PROFILING_NEEDS_GP
869 && ! profile_flag && ! profile_block_flag)
875 /* Return true if OP is a LABEL_REF, or SYMBOL_REF or CONST referencing
876 a variable known to be defined in this file. */
882 const char *str = XSTR (op, 0);
884 /* ??? SYMBOL_REF_FLAG is set for local function symbols, but we
885 run into problems with the rtl inliner in that the symbol was
886 once external, but is local after inlining, which results in
887 unrecognizable insns. */
889 return (CONSTANT_POOL_ADDRESS_P (op)
890 /* If @, then ENCODE_SECTION_INFO sez it's local. */
892 /* If *$, then ASM_GENERATE_INTERNAL_LABEL sez it's local. */
893 || (str[0] == '*' && str[1] == '$'));
897 local_symbolic_operand (op, mode)
899 enum machine_mode mode;
901 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
904 if (GET_CODE (op) == LABEL_REF)
907 if (GET_CODE (op) == CONST
908 && GET_CODE (XEXP (op, 0)) == PLUS
909 && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
910 op = XEXP (XEXP (op, 0), 0);
912 if (GET_CODE (op) != SYMBOL_REF)
915 return local_symbol_p (op);
918 /* Return true if OP is a SYMBOL_REF or CONST referencing a variable
919 known to be defined in this file in the small data area. */
922 small_symbolic_operand (op, mode)
924 enum machine_mode mode ATTRIBUTE_UNUSED;
928 if (! TARGET_SMALL_DATA)
931 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
934 if (GET_CODE (op) == CONST
935 && GET_CODE (XEXP (op, 0)) == PLUS
936 && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
937 op = XEXP (XEXP (op, 0), 0);
939 if (GET_CODE (op) != SYMBOL_REF)
942 if (CONSTANT_POOL_ADDRESS_P (op))
943 return GET_MODE_SIZE (get_pool_mode (op)) <= (unsigned) g_switch_value;
947 return str[0] == '@' && str[1] == 's';
951 /* Return true if OP is a SYMBOL_REF or CONST referencing a variable
952 not known (or known not) to be defined in this file. */
955 global_symbolic_operand (op, mode)
957 enum machine_mode mode;
959 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
962 if (GET_CODE (op) == CONST
963 && GET_CODE (XEXP (op, 0)) == PLUS
964 && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
965 op = XEXP (XEXP (op, 0), 0);
967 if (GET_CODE (op) != SYMBOL_REF)
970 return ! local_symbol_p (op);
973 /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
976 call_operand (op, mode)
978 enum machine_mode mode;
983 if (GET_CODE (op) == REG)
986 return REGNO (op) == 27;
990 if (TARGET_ABI_UNICOSMK)
992 if (GET_CODE (op) == SYMBOL_REF)
998 /* Returns 1 if OP is a symbolic operand, i.e. a symbol_ref or a label_ref,
999 possibly with an offset. */
1002 symbolic_operand (op, mode)
1004 enum machine_mode mode;
1006 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
1008 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
1010 if (GET_CODE (op) == CONST
1011 && GET_CODE (XEXP (op,0)) == PLUS
1012 && GET_CODE (XEXP (XEXP (op,0), 0)) == SYMBOL_REF
1013 && GET_CODE (XEXP (XEXP (op,0), 1)) == CONST_INT)
1018 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
1019 comparisons are valid in which insn. */
1022 alpha_comparison_operator (op, mode)
1024 enum machine_mode mode;
1026 enum rtx_code code = GET_CODE (op);
1028 if (mode != GET_MODE (op) && mode != VOIDmode)
1031 return (code == EQ || code == LE || code == LT
1032 || code == LEU || code == LTU);
1035 /* Return 1 if OP is a valid Alpha comparison operator against zero.
1036 Here we know which comparisons are valid in which insn. */
1039 alpha_zero_comparison_operator (op, mode)
1041 enum machine_mode mode;
1043 enum rtx_code code = GET_CODE (op);
1045 if (mode != GET_MODE (op) && mode != VOIDmode)
1048 return (code == EQ || code == NE || code == LE || code == LT
1049 || code == LEU || code == LTU);
1052 /* Return 1 if OP is a valid Alpha swapped comparison operator. */
1055 alpha_swapped_comparison_operator (op, mode)
1057 enum machine_mode mode;
1059 enum rtx_code code = GET_CODE (op);
1061 if ((mode != GET_MODE (op) && mode != VOIDmode)
1062 || GET_RTX_CLASS (code) != '<')
1065 code = swap_condition (code);
1066 return (code == EQ || code == LE || code == LT
1067 || code == LEU || code == LTU);
1070 /* Return 1 if OP is a signed comparison operation. */
1073 signed_comparison_operator (op, mode)
1075 enum machine_mode mode ATTRIBUTE_UNUSED;
1077 enum rtx_code code = GET_CODE (op);
1079 if (mode != GET_MODE (op) && mode != VOIDmode)
1082 return (code == EQ || code == NE
1083 || code == LE || code == LT
1084 || code == GE || code == GT);
1087 /* Return 1 if OP is a valid Alpha floating point comparison operator.
1088 Here we know which comparisons are valid in which insn. */
1091 alpha_fp_comparison_operator (op, mode)
1093 enum machine_mode mode;
1095 enum rtx_code code = GET_CODE (op);
1097 if (mode != GET_MODE (op) && mode != VOIDmode)
1100 return (code == EQ || code == LE || code == LT || code == UNORDERED);
1103 /* Return 1 if this is a divide or modulus operator. */
1106 divmod_operator (op, mode)
1108 enum machine_mode mode ATTRIBUTE_UNUSED;
1110 switch (GET_CODE (op))
1112 case DIV: case MOD: case UDIV: case UMOD:
1122 /* Return 1 if this memory address is a known aligned register plus
1123 a constant. It must be a valid address. This means that we can do
1124 this as an aligned reference plus some offset.
1126 Take into account what reload will do. */
1129 aligned_memory_operand (op, mode)
1131 enum machine_mode mode;
1135 if (reload_in_progress)
1138 if (GET_CODE (tmp) == SUBREG)
1139 tmp = SUBREG_REG (tmp);
1140 if (GET_CODE (tmp) == REG
1141 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
1143 op = reg_equiv_memory_loc[REGNO (tmp)];
1149 if (GET_CODE (op) != MEM
1150 || GET_MODE (op) != mode)
1154 /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
1155 sorts of constructs. Dig for the real base register. */
1156 if (reload_in_progress
1157 && GET_CODE (op) == PLUS
1158 && GET_CODE (XEXP (op, 0)) == PLUS)
1159 base = XEXP (XEXP (op, 0), 0);
1162 if (! memory_address_p (mode, op))
1164 base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op);
1167 return (GET_CODE (base) == REG && REGNO_POINTER_ALIGN (REGNO (base)) >= 32);
1170 /* Similar, but return 1 if OP is a MEM which is not alignable. */
1173 unaligned_memory_operand (op, mode)
1175 enum machine_mode mode;
1179 if (reload_in_progress)
1182 if (GET_CODE (tmp) == SUBREG)
1183 tmp = SUBREG_REG (tmp);
1184 if (GET_CODE (tmp) == REG
1185 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
1187 op = reg_equiv_memory_loc[REGNO (tmp)];
1193 if (GET_CODE (op) != MEM
1194 || GET_MODE (op) != mode)
1198 /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
1199 sorts of constructs. Dig for the real base register. */
1200 if (reload_in_progress
1201 && GET_CODE (op) == PLUS
1202 && GET_CODE (XEXP (op, 0)) == PLUS)
1203 base = XEXP (XEXP (op, 0), 0);
1206 if (! memory_address_p (mode, op))
1208 base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op);
1211 return (GET_CODE (base) == REG && REGNO_POINTER_ALIGN (REGNO (base)) < 32);
1214 /* Return 1 if OP is either a register or an unaligned memory location. */
1217 reg_or_unaligned_mem_operand (op, mode)
1219 enum machine_mode mode;
1221 return register_operand (op, mode) || unaligned_memory_operand (op, mode);
1224 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
1227 any_memory_operand (op, mode)
1229 enum machine_mode mode ATTRIBUTE_UNUSED;
1231 return (GET_CODE (op) == MEM
1232 || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
1233 || (reload_in_progress && GET_CODE (op) == REG
1234 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
1235 || (reload_in_progress && GET_CODE (op) == SUBREG
1236 && GET_CODE (SUBREG_REG (op)) == REG
1237 && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));
1240 /* Returns 1 if OP is not an eliminable register.
1242 This exists to cure a pathological abort in the s8addq (et al) patterns,
1244 long foo () { long t; bar(); return (long) &t * 26107; }
1246 which run afoul of a hack in reload to cure a (presumably) similar
1247 problem with lea-type instructions on other targets. But there is
1248 one of us and many of them, so work around the problem by selectively
1249 preventing combine from making the optimization. */
1252 reg_not_elim_operand (op, mode)
1254 enum machine_mode mode;
1257 if (GET_CODE (op) == SUBREG)
1258 inner = SUBREG_REG (op);
1259 if (inner == frame_pointer_rtx || inner == arg_pointer_rtx)
1262 return register_operand (op, mode);
1265 /* Return 1 is OP is a memory location that is not a reference (using
1266 an AND) to an unaligned location. Take into account what reload
1270 normal_memory_operand (op, mode)
1272 enum machine_mode mode ATTRIBUTE_UNUSED;
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)];
1284 /* This may not have been assigned an equivalent address if it will
1285 be eliminated. In that case, it doesn't matter what we do. */
1291 return GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) != AND;
1294 /* Accept a register, but not a subreg of any kind. This allows us to
1295 avoid pathological cases in reload wrt data movement common in
1296 int->fp conversion. */
1299 reg_no_subreg_operand (op, mode)
1301 enum machine_mode mode;
1303 if (GET_CODE (op) == SUBREG)
1305 return register_operand (op, mode);
1308 /* Recognize a addition operation that includes a constant. Used to
1309 convince reload to canonize (plus (plus reg c1) c2) during register
1313 addition_operation (op, mode)
1315 enum machine_mode mode;
1317 if (GET_MODE (op) != mode && mode != VOIDmode)
1319 if (GET_CODE (op) == PLUS
1320 && register_operand (XEXP (op, 0), mode)
1321 && GET_CODE (XEXP (op, 1)) == CONST_INT
1322 && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (op, 1)), 'K'))
1327 /* Return 1 if this function can directly return via $26. */
1332 return (! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK
1334 && alpha_sa_size () == 0
1335 && get_frame_size () == 0
1336 && current_function_outgoing_args_size == 0
1337 && current_function_pretend_args_size == 0);
1340 /* Return the ADDR_VEC associated with a tablejump insn. */
1343 alpha_tablejump_addr_vec (insn)
1348 tmp = JUMP_LABEL (insn);
1351 tmp = NEXT_INSN (tmp);
1354 if (GET_CODE (tmp) == JUMP_INSN
1355 && GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC)
1356 return PATTERN (tmp);
1360 /* Return the label of the predicted edge, or CONST0_RTX if we don't know. */
1363 alpha_tablejump_best_label (insn)
1366 rtx jump_table = alpha_tablejump_addr_vec (insn);
1367 rtx best_label = NULL_RTX;
1369 /* ??? Once the CFG doesn't keep getting completely rebuilt, look
1370 there for edge frequency counts from profile data. */
1374 int n_labels = XVECLEN (jump_table, 1);
1375 int best_count = -1;
1378 for (i = 0; i < n_labels; i++)
1382 for (j = i + 1; j < n_labels; j++)
1383 if (XEXP (XVECEXP (jump_table, 1, i), 0)
1384 == XEXP (XVECEXP (jump_table, 1, j), 0))
1387 if (count > best_count)
1388 best_count = count, best_label = XVECEXP (jump_table, 1, i);
1392 return best_label ? best_label : const0_rtx;
1395 /* If we are referencing a function that is static, make the SYMBOL_REF
1396 special. We use this to see indicate we can branch to this function
1397 without setting PV or restoring GP.
1399 If this is a variable that is known to be defined locally, add "@v"
1400 to the name. If in addition the variable is to go in .sdata/.sbss,
1401 then add "@s" instead. */
1404 alpha_encode_section_info (decl)
1407 const char *symbol_str;
1408 bool is_local, is_small;
1410 if (TREE_CODE (decl) == FUNCTION_DECL)
1412 if (! TREE_PUBLIC (decl))
1413 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
1417 /* Early out if we're not going to do anything with this data. */
1418 if (! TARGET_EXPLICIT_RELOCS)
1421 /* Careful not to prod global register variables. */
1422 if (TREE_CODE (decl) != VAR_DECL
1423 || GET_CODE (DECL_RTL (decl)) != MEM
1424 || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
1427 symbol_str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
1429 /* A variable is considered "local" if it is defined in this module. */
1431 if (DECL_EXTERNAL (decl))
1433 /* Linkonce and weak data is never local. */
1434 else if (DECL_ONE_ONLY (decl) || DECL_WEAK (decl))
1436 else if (! TREE_PUBLIC (decl))
1438 /* If PIC, then assume that any global name can be overridden by
1439 symbols resolved from other modules. */
1442 /* Uninitialized COMMON variable may be unified with symbols
1443 resolved from other modules. */
1444 else if (DECL_COMMON (decl)
1445 && (DECL_INITIAL (decl) == NULL
1446 || DECL_INITIAL (decl) == error_mark_node))
1448 /* Otherwise we're left with initialized (or non-common) global data
1449 which is of necessity defined locally. */
1453 /* Determine if DECL will wind up in .sdata/.sbss. */
1456 if (DECL_SECTION_NAME (decl))
1458 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
1459 if (strcmp (section, ".sdata") == 0
1460 || strcmp (section, ".sbss") == 0)
1465 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
1467 /* If the variable has already been defined in the output file, then it
1468 is too late to put it in sdata if it wasn't put there in the first
1469 place. The test is here rather than above, because if it is already
1470 in sdata, then it can stay there. */
1472 if (TREE_ASM_WRITTEN (decl))
1475 /* If this is an incomplete type with size 0, then we can't put it in
1476 sdata because it might be too big when completed. */
1477 else if (size > 0 && size <= g_switch_value)
1481 /* Finally, encode this into the symbol string. */
1488 if (symbol_str[0] == '@')
1490 if (symbol_str[1] == (is_small ? 's' : 'v'))
1495 len = strlen (symbol_str) + 1;
1496 newstr = alloca (len + 2);
1499 newstr[1] = (is_small ? 's' : 'v');
1500 memcpy (newstr + 2, symbol_str, len);
1502 string = ggc_alloc_string (newstr, len + 2 - 1);
1503 XSTR (XEXP (DECL_RTL (decl), 0), 0) = string;
1505 else if (symbol_str[0] == '@')
1509 /* legitimate_address_p recognizes an RTL expression that is a valid
1510 memory address for an instruction. The MODE argument is the
1511 machine mode for the MEM expression that wants to use this address.
1513 For Alpha, we have either a constant address or the sum of a
1514 register and a constant address, or just a register. For DImode,
1515 any of those forms can be surrounded with an AND that clear the
1516 low-order three bits; this is an "unaligned" access. */
1519 alpha_legitimate_address_p (mode, x, strict)
1520 enum machine_mode mode;
1524 /* If this is an ldq_u type address, discard the outer AND. */
1526 && GET_CODE (x) == AND
1527 && GET_CODE (XEXP (x, 1)) == CONST_INT
1528 && INTVAL (XEXP (x, 1)) == -8)
1531 /* Discard non-paradoxical subregs. */
1532 if (GET_CODE (x) == SUBREG
1533 && (GET_MODE_SIZE (GET_MODE (x))
1534 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
1537 /* Unadorned general registers are valid. */
1540 ? STRICT_REG_OK_FOR_BASE_P (x)
1541 : NONSTRICT_REG_OK_FOR_BASE_P (x)))
1544 /* Constant addresses (i.e. +/- 32k) are valid. */
1545 if (CONSTANT_ADDRESS_P (x))
1548 /* Register plus a small constant offset is valid. */
1549 if (GET_CODE (x) == PLUS)
1551 rtx ofs = XEXP (x, 1);
1554 /* Discard non-paradoxical subregs. */
1555 if (GET_CODE (x) == SUBREG
1556 && (GET_MODE_SIZE (GET_MODE (x))
1557 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
1563 && NONSTRICT_REG_OK_FP_BASE_P (x)
1564 && GET_CODE (ofs) == CONST_INT)
1567 ? STRICT_REG_OK_FOR_BASE_P (x)
1568 : NONSTRICT_REG_OK_FOR_BASE_P (x))
1569 && CONSTANT_ADDRESS_P (ofs))
1572 else if (GET_CODE (x) == ADDRESSOF
1573 && GET_CODE (ofs) == CONST_INT)
1577 /* If we're managing explicit relocations, LO_SUM is valid. */
1578 else if (TARGET_EXPLICIT_RELOCS && GET_CODE (x) == LO_SUM)
1580 rtx ofs = XEXP (x, 1);
1583 /* Discard non-paradoxical subregs. */
1584 if (GET_CODE (x) == SUBREG
1585 && (GET_MODE_SIZE (GET_MODE (x))
1586 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
1589 /* Must have a valid base register. */
1592 ? STRICT_REG_OK_FOR_BASE_P (x)
1593 : NONSTRICT_REG_OK_FOR_BASE_P (x))))
1596 /* The symbol must be local. */
1597 if (local_symbolic_operand (ofs, Pmode))
1604 /* Try machine-dependent ways of modifying an illegitimate address
1605 to be legitimate. If we find one, return the new, valid address. */
1608 alpha_legitimize_address (x, oldx, mode)
1610 rtx oldx ATTRIBUTE_UNUSED;
1611 enum machine_mode mode ATTRIBUTE_UNUSED;
1613 HOST_WIDE_INT addend;
1615 /* If the address is (plus reg const_int) and the CONST_INT is not a
1616 valid offset, compute the high part of the constant and add it to
1617 the register. Then our address is (plus temp low-part-const). */
1618 if (GET_CODE (x) == PLUS
1619 && GET_CODE (XEXP (x, 0)) == REG
1620 && GET_CODE (XEXP (x, 1)) == CONST_INT
1621 && ! CONSTANT_ADDRESS_P (XEXP (x, 1)))
1623 addend = INTVAL (XEXP (x, 1));
1628 /* If the address is (const (plus FOO const_int)), find the low-order
1629 part of the CONST_INT. Then load FOO plus any high-order part of the
1630 CONST_INT into a register. Our address is (plus reg low-part-const).
1631 This is done to reduce the number of GOT entries. */
1632 if (GET_CODE (x) == CONST
1633 && GET_CODE (XEXP (x, 0)) == PLUS
1634 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
1636 addend = INTVAL (XEXP (XEXP (x, 0), 1));
1637 x = force_reg (Pmode, XEXP (XEXP (x, 0), 0));
1641 /* If we have a (plus reg const), emit the load as in (2), then add
1642 the two registers, and finally generate (plus reg low-part-const) as
1644 if (GET_CODE (x) == PLUS
1645 && GET_CODE (XEXP (x, 0)) == REG
1646 && GET_CODE (XEXP (x, 1)) == CONST
1647 && GET_CODE (XEXP (XEXP (x, 1), 0)) == PLUS
1648 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == CONST_INT)
1650 addend = INTVAL (XEXP (XEXP (XEXP (x, 1), 0), 1));
1651 x = expand_simple_binop (Pmode, PLUS, XEXP (x, 0),
1652 XEXP (XEXP (XEXP (x, 1), 0), 0),
1653 NULL_RTX, 1, OPTAB_LIB_WIDEN);
1657 /* If this is a local symbol, split the address into HIGH/LO_SUM parts. */
1658 if (TARGET_EXPLICIT_RELOCS && symbolic_operand (x, Pmode))
1661 if (local_symbolic_operand (x, Pmode))
1663 if (small_symbolic_operand (x, Pmode))
1664 scratch = pic_offset_table_rtx;
1669 scratch = gen_reg_rtx (Pmode);
1671 tmp = gen_rtx_HIGH (Pmode, x);
1672 tmp = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmp);
1673 insn = emit_insn (gen_rtx_SET (VOIDmode, scratch, tmp));
1674 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, tmp,
1678 return gen_rtx_LO_SUM (Pmode, scratch, x);
1682 scratch = gen_reg_rtx (Pmode);
1683 emit_insn (gen_movdi_er_high_g (scratch, pic_offset_table_rtx,
1685 /* ??? FIXME: Tag the use of scratch with a lituse. */
1694 HOST_WIDE_INT lowpart = (addend & 0xffff) - 2 * (addend & 0x8000);
1695 HOST_WIDE_INT highpart = addend - lowpart;
1696 x = expand_simple_binop (Pmode, PLUS, x, GEN_INT (highpart),
1697 NULL_RTX, 1, OPTAB_LIB_WIDEN);
1698 return plus_constant (x, lowpart);
1702 /* Try a machine-dependent way of reloading an illegitimate address
1703 operand. If we find one, push the reload and return the new rtx. */
1706 alpha_legitimize_reload_address (x, mode, opnum, type, ind_levels)
1708 enum machine_mode mode ATTRIBUTE_UNUSED;
1711 int ind_levels ATTRIBUTE_UNUSED;
1713 /* We must recognize output that we have already generated ourselves. */
1714 if (GET_CODE (x) == PLUS
1715 && GET_CODE (XEXP (x, 0)) == PLUS
1716 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
1717 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
1718 && GET_CODE (XEXP (x, 1)) == CONST_INT)
1720 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
1721 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
1726 /* We wish to handle large displacements off a base register by
1727 splitting the addend across an ldah and the mem insn. This
1728 cuts number of extra insns needed from 3 to 1. */
1729 if (GET_CODE (x) == PLUS
1730 && GET_CODE (XEXP (x, 0)) == REG
1731 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
1732 && REGNO_OK_FOR_BASE_P (REGNO (XEXP (x, 0)))
1733 && GET_CODE (XEXP (x, 1)) == CONST_INT)
1735 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
1736 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1738 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
1740 /* Check for 32-bit overflow. */
1741 if (high + low != val)
1744 /* Reload the high part into a base reg; leave the low part
1745 in the mem directly. */
1746 x = gen_rtx_PLUS (GET_MODE (x),
1747 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
1751 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
1752 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
1760 /* REF is an alignable memory location. Place an aligned SImode
1761 reference into *PALIGNED_MEM and the number of bits to shift into
1762 *PBITNUM. SCRATCH is a free register for use in reloading out
1763 of range stack slots. */
1766 get_aligned_mem (ref, paligned_mem, pbitnum)
1768 rtx *paligned_mem, *pbitnum;
1771 HOST_WIDE_INT offset = 0;
1773 if (GET_CODE (ref) != MEM)
1776 if (reload_in_progress
1777 && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
1779 base = find_replacement (&XEXP (ref, 0));
1781 if (! memory_address_p (GET_MODE (ref), base))
1786 base = XEXP (ref, 0);
1789 if (GET_CODE (base) == PLUS)
1790 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
1792 *paligned_mem = gen_rtx_MEM (SImode, plus_constant (base, offset & ~3));
1793 MEM_COPY_ATTRIBUTES (*paligned_mem, ref);
1795 /* Sadly, we cannot use alias sets here because we may overlap other
1796 data in a different alias set. */
1797 set_mem_alias_set (*paligned_mem, 0);
1799 if (WORDS_BIG_ENDIAN)
1800 *pbitnum = GEN_INT (32 - (GET_MODE_BITSIZE (GET_MODE (ref))
1801 + (offset & 3) * 8));
1803 *pbitnum = GEN_INT ((offset & 3) * 8);
1806 /* Similar, but just get the address. Handle the two reload cases.
1807 Add EXTRA_OFFSET to the address we return. */
1810 get_unaligned_address (ref, extra_offset)
1815 HOST_WIDE_INT offset = 0;
1817 if (GET_CODE (ref) != MEM)
1820 if (reload_in_progress
1821 && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
1823 base = find_replacement (&XEXP (ref, 0));
1825 if (! memory_address_p (GET_MODE (ref), base))
1830 base = XEXP (ref, 0);
1833 if (GET_CODE (base) == PLUS)
1834 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
1836 return plus_constant (base, offset + extra_offset);
1839 /* Loading and storing HImode or QImode values to and from memory
1840 usually requires a scratch register. The exceptions are loading
1841 QImode and HImode from an aligned address to a general register
1842 unless byte instructions are permitted.
1844 We also cannot load an unaligned address or a paradoxical SUBREG
1845 into an FP register.
1847 We also cannot do integral arithmetic into FP regs, as might result
1848 from register elimination into a DImode fp register. */
1851 secondary_reload_class (class, mode, x, in)
1852 enum reg_class class;
1853 enum machine_mode mode;
1857 if ((mode == QImode || mode == HImode) && ! TARGET_BWX)
1859 if (GET_CODE (x) == MEM
1860 || (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
1861 || (GET_CODE (x) == SUBREG
1862 && (GET_CODE (SUBREG_REG (x)) == MEM
1863 || (GET_CODE (SUBREG_REG (x)) == REG
1864 && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER))))
1866 if (!in || !aligned_memory_operand(x, mode))
1867 return GENERAL_REGS;
1871 if (class == FLOAT_REGS)
1873 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
1874 return GENERAL_REGS;
1876 if (GET_CODE (x) == SUBREG
1877 && (GET_MODE_SIZE (GET_MODE (x))
1878 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
1879 return GENERAL_REGS;
1881 if (in && INTEGRAL_MODE_P (mode)
1882 && ! (memory_operand (x, mode) || x == const0_rtx))
1883 return GENERAL_REGS;
1889 /* Subfunction of the following function. Update the flags of any MEM
1890 found in part of X. */
1893 alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
1895 int in_struct_p, volatile_p, unchanging_p;
1899 switch (GET_CODE (x))
1903 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
1904 alpha_set_memflags_1 (XVECEXP (x, 0, i), in_struct_p, volatile_p,
1909 alpha_set_memflags_1 (PATTERN (x), in_struct_p, volatile_p,
1914 alpha_set_memflags_1 (SET_DEST (x), in_struct_p, volatile_p,
1916 alpha_set_memflags_1 (SET_SRC (x), in_struct_p, volatile_p,
1921 MEM_IN_STRUCT_P (x) = in_struct_p;
1922 MEM_VOLATILE_P (x) = volatile_p;
1923 RTX_UNCHANGING_P (x) = unchanging_p;
1924 /* Sadly, we cannot use alias sets because the extra aliasing
1925 produced by the AND interferes. Given that two-byte quantities
1926 are the only thing we would be able to differentiate anyway,
1927 there does not seem to be any point in convoluting the early
1928 out of the alias check. */
1936 /* Given INSN, which is either an INSN or a SEQUENCE generated to
1937 perform a memory operation, look for any MEMs in either a SET_DEST or
1938 a SET_SRC and copy the in-struct, unchanging, and volatile flags from
1939 REF into each of the MEMs found. If REF is not a MEM, don't do
1943 alpha_set_memflags (insn, ref)
1947 int in_struct_p, volatile_p, unchanging_p;
1949 if (GET_CODE (ref) != MEM)
1952 in_struct_p = MEM_IN_STRUCT_P (ref);
1953 volatile_p = MEM_VOLATILE_P (ref);
1954 unchanging_p = RTX_UNCHANGING_P (ref);
1956 /* This is only called from alpha.md, after having had something
1957 generated from one of the insn patterns. So if everything is
1958 zero, the pattern is already up-to-date. */
1959 if (! in_struct_p && ! volatile_p && ! unchanging_p)
1962 alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
1965 /* Try to output insns to set TARGET equal to the constant C if it can be
1966 done in less than N insns. Do all computations in MODE. Returns the place
1967 where the output has been placed if it can be done and the insns have been
1968 emitted. If it would take more than N insns, zero is returned and no
1969 insns and emitted. */
1972 alpha_emit_set_const (target, mode, c, n)
1974 enum machine_mode mode;
1981 /* Try 1 insn, then 2, then up to N. */
1982 for (i = 1; i <= n; i++)
1983 if ((pat = alpha_emit_set_const_1 (target, mode, c, i)) != 0)
1989 /* Internal routine for the above to check for N or below insns. */
1992 alpha_emit_set_const_1 (target, mode, c, n)
1994 enum machine_mode mode;
2000 /* Use a pseudo if highly optimizing and still generating RTL. */
2002 = (flag_expensive_optimizations && rtx_equal_function_value_matters
2006 #if HOST_BITS_PER_WIDE_INT == 64
2007 /* We are only called for SImode and DImode. If this is SImode, ensure that
2008 we are sign extended to a full word. This does not make any sense when
2009 cross-compiling on a narrow machine. */
2012 c = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000;
2015 /* If this is a sign-extended 32-bit constant, we can do this in at most
2016 three insns, so do it if we have enough insns left. We always have
2017 a sign-extended 32-bit constant when compiling on a narrow machine. */
2019 if (HOST_BITS_PER_WIDE_INT != 64
2020 || c >> 31 == -1 || c >> 31 == 0)
2022 HOST_WIDE_INT low = ((c & 0xffff) ^ 0x8000) - 0x8000;
2023 HOST_WIDE_INT tmp1 = c - low;
2024 HOST_WIDE_INT high = (((tmp1 >> 16) & 0xffff) ^ 0x8000) - 0x8000;
2025 HOST_WIDE_INT extra = 0;
2027 /* If HIGH will be interpreted as negative but the constant is
2028 positive, we must adjust it to do two ldha insns. */
2030 if ((high & 0x8000) != 0 && c >= 0)
2034 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
2037 if (c == low || (low == 0 && extra == 0))
2039 /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
2040 but that meant that we can't handle INT_MIN on 32-bit machines
2041 (like NT/Alpha), because we recurse indefinitely through
2042 emit_move_insn to gen_movdi. So instead, since we know exactly
2043 what we want, create it explicitly. */
2046 target = gen_reg_rtx (mode);
2047 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (c)));
2050 else if (n >= 2 + (extra != 0))
2052 temp = copy_to_suggested_reg (GEN_INT (high << 16), subtarget, mode);
2055 temp = expand_binop (mode, add_optab, temp, GEN_INT (extra << 16),
2056 subtarget, 0, OPTAB_WIDEN);
2058 return expand_binop (mode, add_optab, temp, GEN_INT (low),
2059 target, 0, OPTAB_WIDEN);
2063 /* If we couldn't do it that way, try some other methods. But if we have
2064 no instructions left, don't bother. Likewise, if this is SImode and
2065 we can't make pseudos, we can't do anything since the expand_binop
2066 and expand_unop calls will widen and try to make pseudos. */
2069 || (mode == SImode && ! rtx_equal_function_value_matters))
2072 /* Next, see if we can load a related constant and then shift and possibly
2073 negate it to get the constant we want. Try this once each increasing
2074 numbers of insns. */
2076 for (i = 1; i < n; i++)
2078 /* First, see if minus some low bits, we've an easy load of
2081 new = ((c & 0xffff) ^ 0x8000) - 0x8000;
2083 && (temp = alpha_emit_set_const (subtarget, mode, c - new, i)) != 0)
2084 return expand_binop (mode, add_optab, temp, GEN_INT (new),
2085 target, 0, OPTAB_WIDEN);
2087 /* Next try complementing. */
2088 if ((temp = alpha_emit_set_const (subtarget, mode, ~ c, i)) != 0)
2089 return expand_unop (mode, one_cmpl_optab, temp, target, 0);
2091 /* Next try to form a constant and do a left shift. We can do this
2092 if some low-order bits are zero; the exact_log2 call below tells
2093 us that information. The bits we are shifting out could be any
2094 value, but here we'll just try the 0- and sign-extended forms of
2095 the constant. To try to increase the chance of having the same
2096 constant in more than one insn, start at the highest number of
2097 bits to shift, but try all possibilities in case a ZAPNOT will
2100 if ((bits = exact_log2 (c & - c)) > 0)
2101 for (; bits > 0; bits--)
2102 if ((temp = (alpha_emit_set_const
2103 (subtarget, mode, c >> bits, i))) != 0
2104 || ((temp = (alpha_emit_set_const
2106 ((unsigned HOST_WIDE_INT) c) >> bits, i)))
2108 return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
2109 target, 0, OPTAB_WIDEN);
2111 /* Now try high-order zero bits. Here we try the shifted-in bits as
2112 all zero and all ones. Be careful to avoid shifting outside the
2113 mode and to avoid shifting outside the host wide int size. */
2114 /* On narrow hosts, don't shift a 1 into the high bit, since we'll
2115 confuse the recursive call and set all of the high 32 bits. */
2117 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
2118 - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64))) > 0)
2119 for (; bits > 0; bits--)
2120 if ((temp = alpha_emit_set_const (subtarget, mode,
2122 || ((temp = (alpha_emit_set_const
2124 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
2127 return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
2128 target, 1, OPTAB_WIDEN);
2130 /* Now try high-order 1 bits. We get that with a sign-extension.
2131 But one bit isn't enough here. Be careful to avoid shifting outside
2132 the mode and to avoid shifting outside the host wide int size. */
2134 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
2135 - floor_log2 (~ c) - 2)) > 0)
2136 for (; bits > 0; bits--)
2137 if ((temp = alpha_emit_set_const (subtarget, mode,
2139 || ((temp = (alpha_emit_set_const
2141 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
2144 return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
2145 target, 0, OPTAB_WIDEN);
2148 #if HOST_BITS_PER_WIDE_INT == 64
2149 /* Finally, see if can load a value into the target that is the same as the
2150 constant except that all bytes that are 0 are changed to be 0xff. If we
2151 can, then we can do a ZAPNOT to obtain the desired constant. */
2154 for (i = 0; i < 64; i += 8)
2155 if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
2156 new |= (HOST_WIDE_INT) 0xff << i;
2158 /* We are only called for SImode and DImode. If this is SImode, ensure that
2159 we are sign extended to a full word. */
2162 new = ((new & 0xffffffff) ^ 0x80000000) - 0x80000000;
2164 if (new != c && new != -1
2165 && (temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0)
2166 return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
2167 target, 0, OPTAB_WIDEN);
2173 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
2174 fall back to a straight forward decomposition. We do this to avoid
2175 exponential run times encountered when looking for longer sequences
2176 with alpha_emit_set_const. */
2179 alpha_emit_set_long_const (target, c1, c2)
2181 HOST_WIDE_INT c1, c2;
2183 HOST_WIDE_INT d1, d2, d3, d4;
2185 /* Decompose the entire word */
2186 #if HOST_BITS_PER_WIDE_INT >= 64
2187 if (c2 != -(c1 < 0))
2189 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
2191 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
2192 c1 = (c1 - d2) >> 32;
2193 d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
2195 d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
2199 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
2201 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
2205 d3 = ((c2 & 0xffff) ^ 0x8000) - 0x8000;
2207 d4 = ((c2 & 0xffffffff) ^ 0x80000000) - 0x80000000;
2212 /* Construct the high word */
2215 emit_move_insn (target, GEN_INT (d4));
2217 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d3)));
2220 emit_move_insn (target, GEN_INT (d3));
2222 /* Shift it into place */
2223 emit_move_insn (target, gen_rtx_ASHIFT (DImode, target, GEN_INT (32)));
2225 /* Add in the low bits. */
2227 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d2)));
2229 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d1)));
2234 /* Expand a move instruction; return true if all work is done.
2235 We don't handle non-bwx subword loads here. */
2238 alpha_expand_mov (mode, operands)
2239 enum machine_mode mode;
2242 /* If the output is not a register, the input must be. */
2243 if (GET_CODE (operands[0]) == MEM
2244 && ! reg_or_0_operand (operands[1], mode))
2245 operands[1] = force_reg (mode, operands[1]);
2247 if (TARGET_EXPLICIT_RELOCS && symbolic_operand (operands[1], mode))
2249 if (local_symbolic_operand (operands[1], mode))
2253 if (small_symbolic_operand (operands[1], Pmode))
2254 scratch = pic_offset_table_rtx;
2259 scratch = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
2261 tmp = gen_rtx_HIGH (Pmode, operands[1]);
2262 tmp = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmp);
2263 insn = emit_insn (gen_rtx_SET (VOIDmode, scratch, tmp));
2264 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, tmp,
2268 operands[1] = gen_rtx_LO_SUM (Pmode, scratch, operands[1]);
2273 emit_insn (gen_movdi_er_high_g (operands[0], pic_offset_table_rtx,
2274 operands[1], const0_rtx));
2279 /* Early out for non-constants and valid constants. */
2280 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], mode))
2283 /* Split large integers. */
2284 if (GET_CODE (operands[1]) == CONST_INT
2285 || GET_CODE (operands[1]) == CONST_DOUBLE)
2287 HOST_WIDE_INT i0, i1;
2288 rtx temp = NULL_RTX;
2290 if (GET_CODE (operands[1]) == CONST_INT)
2292 i0 = INTVAL (operands[1]);
2295 else if (HOST_BITS_PER_WIDE_INT >= 64)
2297 i0 = CONST_DOUBLE_LOW (operands[1]);
2302 i0 = CONST_DOUBLE_LOW (operands[1]);
2303 i1 = CONST_DOUBLE_HIGH (operands[1]);
2306 if (HOST_BITS_PER_WIDE_INT >= 64 || i1 == -(i0 < 0))
2307 temp = alpha_emit_set_const (operands[0], mode, i0, 3);
2309 if (!temp && TARGET_BUILD_CONSTANTS)
2310 temp = alpha_emit_set_long_const (operands[0], i0, i1);
2314 if (rtx_equal_p (operands[0], temp))
2321 /* Otherwise we've nothing left but to drop the thing to memory. */
2322 operands[1] = force_const_mem (DImode, operands[1]);
2323 if (reload_in_progress)
2325 emit_move_insn (operands[0], XEXP (operands[1], 0));
2326 operands[1] = copy_rtx (operands[1]);
2327 XEXP (operands[1], 0) = operands[0];
2330 operands[1] = validize_mem (operands[1]);
2334 /* Expand a non-bwx QImode or HImode move instruction;
2335 return true if all work is done. */
2338 alpha_expand_mov_nobwx (mode, operands)
2339 enum machine_mode mode;
2342 /* If the output is not a register, the input must be. */
2343 if (GET_CODE (operands[0]) == MEM)
2344 operands[1] = force_reg (mode, operands[1]);
2346 /* Handle four memory cases, unaligned and aligned for either the input
2347 or the output. The only case where we can be called during reload is
2348 for aligned loads; all other cases require temporaries. */
2350 if (GET_CODE (operands[1]) == MEM
2351 || (GET_CODE (operands[1]) == SUBREG
2352 && GET_CODE (SUBREG_REG (operands[1])) == MEM)
2353 || (reload_in_progress && GET_CODE (operands[1]) == REG
2354 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
2355 || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
2356 && GET_CODE (SUBREG_REG (operands[1])) == REG
2357 && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
2359 if (aligned_memory_operand (operands[1], mode))
2361 if (reload_in_progress)
2363 emit_insn ((mode == QImode
2364 ? gen_reload_inqi_help
2365 : gen_reload_inhi_help)
2366 (operands[0], operands[1],
2367 gen_rtx_REG (SImode, REGNO (operands[0]))));
2371 rtx aligned_mem, bitnum;
2372 rtx scratch = gen_reg_rtx (SImode);
2374 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
2376 emit_insn ((mode == QImode
2377 ? gen_aligned_loadqi
2378 : gen_aligned_loadhi)
2379 (operands[0], aligned_mem, bitnum, scratch));
2384 /* Don't pass these as parameters since that makes the generated
2385 code depend on parameter evaluation order which will cause
2386 bootstrap failures. */
2388 rtx temp1 = gen_reg_rtx (DImode);
2389 rtx temp2 = gen_reg_rtx (DImode);
2390 rtx seq = ((mode == QImode
2391 ? gen_unaligned_loadqi
2392 : gen_unaligned_loadhi)
2393 (operands[0], get_unaligned_address (operands[1], 0),
2396 alpha_set_memflags (seq, operands[1]);
2402 if (GET_CODE (operands[0]) == MEM
2403 || (GET_CODE (operands[0]) == SUBREG
2404 && GET_CODE (SUBREG_REG (operands[0])) == MEM)
2405 || (reload_in_progress && GET_CODE (operands[0]) == REG
2406 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
2407 || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
2408 && GET_CODE (SUBREG_REG (operands[0])) == REG
2409 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
2411 if (aligned_memory_operand (operands[0], mode))
2413 rtx aligned_mem, bitnum;
2414 rtx temp1 = gen_reg_rtx (SImode);
2415 rtx temp2 = gen_reg_rtx (SImode);
2417 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
2419 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
2424 rtx temp1 = gen_reg_rtx (DImode);
2425 rtx temp2 = gen_reg_rtx (DImode);
2426 rtx temp3 = gen_reg_rtx (DImode);
2427 rtx seq = ((mode == QImode
2428 ? gen_unaligned_storeqi
2429 : gen_unaligned_storehi)
2430 (get_unaligned_address (operands[0], 0),
2431 operands[1], temp1, temp2, temp3));
2433 alpha_set_memflags (seq, operands[0]);
2442 /* Generate an unsigned DImode to FP conversion. This is the same code
2443 optabs would emit if we didn't have TFmode patterns.
2445 For SFmode, this is the only construction I've found that can pass
2446 gcc.c-torture/execute/ieee/rbug.c. No scenario that uses DFmode
2447 intermediates will work, because you'll get intermediate rounding
2448 that ruins the end result. Some of this could be fixed by turning
2449 on round-to-positive-infinity, but that requires diddling the fpsr,
2450 which kills performance. I tried turning this around and converting
2451 to a negative number, so that I could turn on /m, but either I did
2452 it wrong or there's something else cause I wound up with the exact
2453 same single-bit error. There is a branch-less form of this same code:
2464 fcmoveq $f10,$f11,$f0
2466 I'm not using it because it's the same number of instructions as
2467 this branch-full form, and it has more serialized long latency
2468 instructions on the critical path.
2470 For DFmode, we can avoid rounding errors by breaking up the word
2471 into two pieces, converting them separately, and adding them back:
2473 LC0: .long 0,0x5f800000
2478 cpyse $f11,$f31,$f10
2479 cpyse $f31,$f11,$f11
2487 This doesn't seem to be a clear-cut win over the optabs form.
2488 It probably all depends on the distribution of numbers being
2489 converted -- in the optabs form, all but high-bit-set has a
2490 much lower minimum execution time. */
2493 alpha_emit_floatuns (operands)
2496 rtx neglab, donelab, i0, i1, f0, in, out;
2497 enum machine_mode mode;
2500 in = force_reg (DImode, operands[1]);
2501 mode = GET_MODE (out);
2502 neglab = gen_label_rtx ();
2503 donelab = gen_label_rtx ();
2504 i0 = gen_reg_rtx (DImode);
2505 i1 = gen_reg_rtx (DImode);
2506 f0 = gen_reg_rtx (mode);
2508 emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, DImode, 0,
2511 emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_FLOAT (mode, in)));
2512 emit_jump_insn (gen_jump (donelab));
2515 emit_label (neglab);
2517 emit_insn (gen_lshrdi3 (i0, in, const1_rtx));
2518 emit_insn (gen_anddi3 (i1, in, const1_rtx));
2519 emit_insn (gen_iordi3 (i0, i0, i1));
2520 emit_insn (gen_rtx_SET (VOIDmode, f0, gen_rtx_FLOAT (mode, i0)));
2521 emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_PLUS (mode, f0, f0)));
2523 emit_label (donelab);
2526 /* Generate the comparison for a conditional branch. */
2529 alpha_emit_conditional_branch (code)
2532 enum rtx_code cmp_code, branch_code;
2533 enum machine_mode cmp_mode, branch_mode = VOIDmode;
2534 rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
2537 if (alpha_compare.fp_p && GET_MODE (op0) == TFmode)
2539 if (! TARGET_HAS_XFLOATING_LIBS)
2542 /* X_floating library comparison functions return
2546 Convert the compare against the raw return value. */
2548 if (code == UNORDERED || code == ORDERED)
2553 op0 = alpha_emit_xfloating_compare (cmp_code, op0, op1);
2555 alpha_compare.fp_p = 0;
2557 if (code == UNORDERED)
2559 else if (code == ORDERED)
2565 /* The general case: fold the comparison code to the types of compares
2566 that we have, choosing the branch as necessary. */
2569 case EQ: case LE: case LT: case LEU: case LTU:
2571 /* We have these compares: */
2572 cmp_code = code, branch_code = NE;
2577 /* These must be reversed. */
2578 cmp_code = reverse_condition (code), branch_code = EQ;
2581 case GE: case GT: case GEU: case GTU:
2582 /* For FP, we swap them, for INT, we reverse them. */
2583 if (alpha_compare.fp_p)
2585 cmp_code = swap_condition (code);
2587 tem = op0, op0 = op1, op1 = tem;
2591 cmp_code = reverse_condition (code);
2600 if (alpha_compare.fp_p)
2603 if (flag_unsafe_math_optimizations)
2605 /* When we are not as concerned about non-finite values, and we
2606 are comparing against zero, we can branch directly. */
2607 if (op1 == CONST0_RTX (DFmode))
2608 cmp_code = NIL, branch_code = code;
2609 else if (op0 == CONST0_RTX (DFmode))
2611 /* Undo the swap we probably did just above. */
2612 tem = op0, op0 = op1, op1 = tem;
2613 branch_code = swap_condition (cmp_code);
2619 /* ??? We mark the the branch mode to be CCmode to prevent the
2620 compare and branch from being combined, since the compare
2621 insn follows IEEE rules that the branch does not. */
2622 branch_mode = CCmode;
2629 /* The following optimizations are only for signed compares. */
2630 if (code != LEU && code != LTU && code != GEU && code != GTU)
2632 /* Whee. Compare and branch against 0 directly. */
2633 if (op1 == const0_rtx)
2634 cmp_code = NIL, branch_code = code;
2636 /* We want to use cmpcc/bcc when we can, since there is a zero delay
2637 bypass between logicals and br/cmov on EV5. But we don't want to
2638 force valid immediate constants into registers needlessly. */
2639 else if (GET_CODE (op1) == CONST_INT)
2641 HOST_WIDE_INT v = INTVAL (op1), n = -v;
2643 if (! CONST_OK_FOR_LETTER_P (v, 'I')
2644 && (CONST_OK_FOR_LETTER_P (n, 'K')
2645 || CONST_OK_FOR_LETTER_P (n, 'L')))
2647 cmp_code = PLUS, branch_code = code;
2653 if (!reg_or_0_operand (op0, DImode))
2654 op0 = force_reg (DImode, op0);
2655 if (cmp_code != PLUS && !reg_or_8bit_operand (op1, DImode))
2656 op1 = force_reg (DImode, op1);
2659 /* Emit an initial compare instruction, if necessary. */
2661 if (cmp_code != NIL)
2663 tem = gen_reg_rtx (cmp_mode);
2664 emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
2667 /* Zero the operands. */
2668 memset (&alpha_compare, 0, sizeof (alpha_compare));
2670 /* Return the branch comparison. */
2671 return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
2674 /* Certain simplifications can be done to make invalid setcc operations
2675 valid. Return the final comparison, or NULL if we can't work. */
2678 alpha_emit_setcc (code)
2681 enum rtx_code cmp_code;
2682 rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
2683 int fp_p = alpha_compare.fp_p;
2686 /* Zero the operands. */
2687 memset (&alpha_compare, 0, sizeof (alpha_compare));
2689 if (fp_p && GET_MODE (op0) == TFmode)
2691 if (! TARGET_HAS_XFLOATING_LIBS)
2694 /* X_floating library comparison functions return
2698 Convert the compare against the raw return value. */
2700 if (code == UNORDERED || code == ORDERED)
2705 op0 = alpha_emit_xfloating_compare (cmp_code, op0, op1);
2709 if (code == UNORDERED)
2711 else if (code == ORDERED)
2717 if (fp_p && !TARGET_FIX)
2720 /* The general case: fold the comparison code to the types of compares
2721 that we have, choosing the branch as necessary. */
2726 case EQ: case LE: case LT: case LEU: case LTU:
2728 /* We have these compares. */
2730 cmp_code = code, code = NE;
2734 if (!fp_p && op1 == const0_rtx)
2739 cmp_code = reverse_condition (code);
2743 case GE: case GT: case GEU: case GTU:
2744 /* These normally need swapping, but for integer zero we have
2745 special patterns that recognize swapped operands. */
2746 if (!fp_p && op1 == const0_rtx)
2748 code = swap_condition (code);
2750 cmp_code = code, code = NE;
2751 tmp = op0, op0 = op1, op1 = tmp;
2760 if (!register_operand (op0, DImode))
2761 op0 = force_reg (DImode, op0);
2762 if (!reg_or_8bit_operand (op1, DImode))
2763 op1 = force_reg (DImode, op1);
2766 /* Emit an initial compare instruction, if necessary. */
2767 if (cmp_code != NIL)
2769 enum machine_mode mode = fp_p ? DFmode : DImode;
2771 tmp = gen_reg_rtx (mode);
2772 emit_insn (gen_rtx_SET (VOIDmode, tmp,
2773 gen_rtx_fmt_ee (cmp_code, mode, op0, op1)));
2775 op0 = fp_p ? gen_lowpart (DImode, tmp) : tmp;
2779 /* Return the setcc comparison. */
2780 return gen_rtx_fmt_ee (code, DImode, op0, op1);
2784 /* Rewrite a comparison against zero CMP of the form
2785 (CODE (cc0) (const_int 0)) so it can be written validly in
2786 a conditional move (if_then_else CMP ...).
2787 If both of the operands that set cc0 are non-zero we must emit
2788 an insn to perform the compare (it can't be done within
2789 the conditional move). */
2791 alpha_emit_conditional_move (cmp, mode)
2793 enum machine_mode mode;
2795 enum rtx_code code = GET_CODE (cmp);
2796 enum rtx_code cmov_code = NE;
2797 rtx op0 = alpha_compare.op0;
2798 rtx op1 = alpha_compare.op1;
2799 int fp_p = alpha_compare.fp_p;
2800 enum machine_mode cmp_mode
2801 = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
2802 enum machine_mode cmp_op_mode = fp_p ? DFmode : DImode;
2803 enum machine_mode cmov_mode = VOIDmode;
2804 int local_fast_math = flag_unsafe_math_optimizations;
2807 /* Zero the operands. */
2808 memset (&alpha_compare, 0, sizeof (alpha_compare));
2810 if (fp_p != FLOAT_MODE_P (mode))
2812 enum rtx_code cmp_code;
2817 /* If we have fp<->int register move instructions, do a cmov by
2818 performing the comparison in fp registers, and move the
2819 zero/non-zero value to integer registers, where we can then
2820 use a normal cmov, or vice-versa. */
2824 case EQ: case LE: case LT: case LEU: case LTU:
2825 /* We have these compares. */
2826 cmp_code = code, code = NE;
2830 /* This must be reversed. */
2831 cmp_code = EQ, code = EQ;
2834 case GE: case GT: case GEU: case GTU:
2835 /* These normally need swapping, but for integer zero we have
2836 special patterns that recognize swapped operands. */
2837 if (!fp_p && op1 == const0_rtx)
2838 cmp_code = code, code = NE;
2841 cmp_code = swap_condition (code);
2843 tem = op0, op0 = op1, op1 = tem;
2851 tem = gen_reg_rtx (cmp_op_mode);
2852 emit_insn (gen_rtx_SET (VOIDmode, tem,
2853 gen_rtx_fmt_ee (cmp_code, cmp_op_mode,
2856 cmp_mode = cmp_op_mode = fp_p ? DImode : DFmode;
2857 op0 = gen_lowpart (cmp_op_mode, tem);
2858 op1 = CONST0_RTX (cmp_op_mode);
2860 local_fast_math = 1;
2863 /* We may be able to use a conditional move directly.
2864 This avoids emitting spurious compares. */
2865 if (signed_comparison_operator (cmp, VOIDmode)
2866 && (!fp_p || local_fast_math)
2867 && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
2868 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
2870 /* We can't put the comparison inside the conditional move;
2871 emit a compare instruction and put that inside the
2872 conditional move. Make sure we emit only comparisons we have;
2873 swap or reverse as necessary. */
2880 case EQ: case LE: case LT: case LEU: case LTU:
2881 /* We have these compares: */
2885 /* This must be reversed. */
2886 code = reverse_condition (code);
2890 case GE: case GT: case GEU: case GTU:
2891 /* These must be swapped. */
2892 if (op1 != CONST0_RTX (cmp_mode))
2894 code = swap_condition (code);
2895 tem = op0, op0 = op1, op1 = tem;
2905 if (!reg_or_0_operand (op0, DImode))
2906 op0 = force_reg (DImode, op0);
2907 if (!reg_or_8bit_operand (op1, DImode))
2908 op1 = force_reg (DImode, op1);
2911 /* ??? We mark the branch mode to be CCmode to prevent the compare
2912 and cmov from being combined, since the compare insn follows IEEE
2913 rules that the cmov does not. */
2914 if (fp_p && !local_fast_math)
2917 tem = gen_reg_rtx (cmp_op_mode);
2918 emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
2919 return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
2922 /* Simplify a conditional move of two constants into a setcc with
2923 arithmetic. This is done with a splitter since combine would
2924 just undo the work if done during code generation. It also catches
2925 cases we wouldn't have before cse. */
2928 alpha_split_conditional_move (code, dest, cond, t_rtx, f_rtx)
2930 rtx dest, cond, t_rtx, f_rtx;
2932 HOST_WIDE_INT t, f, diff;
2933 enum machine_mode mode;
2934 rtx target, subtarget, tmp;
2936 mode = GET_MODE (dest);
2941 if (((code == NE || code == EQ) && diff < 0)
2942 || (code == GE || code == GT))
2944 code = reverse_condition (code);
2945 diff = t, t = f, f = diff;
2949 subtarget = target = dest;
2952 target = gen_lowpart (DImode, dest);
2953 if (! no_new_pseudos)
2954 subtarget = gen_reg_rtx (DImode);
2959 if (f == 0 && exact_log2 (diff) > 0
2960 /* On EV6, we've got enough shifters to make non-arithmatic shifts
2961 viable over a longer latency cmove. On EV5, the E0 slot is a
2962 scarce resource, and on EV4 shift has the same latency as a cmove. */
2963 && (diff <= 8 || alpha_cpu == PROCESSOR_EV6))
2965 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2966 emit_insn (gen_rtx_SET (VOIDmode, subtarget, tmp));
2968 tmp = gen_rtx_ASHIFT (DImode, subtarget, GEN_INT (exact_log2 (t)));
2969 emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
2971 else if (f == 0 && t == -1)
2973 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2974 emit_insn (gen_rtx_SET (VOIDmode, subtarget, tmp));
2976 emit_insn (gen_negdi2 (target, subtarget));
2978 else if (diff == 1 || diff == 4 || diff == 8)
2982 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2983 emit_insn (gen_rtx_SET (VOIDmode, subtarget, tmp));
2986 emit_insn (gen_adddi3 (target, subtarget, GEN_INT (f)));
2989 add_op = GEN_INT (f);
2990 if (sext_add_operand (add_op, mode))
2992 tmp = gen_rtx_MULT (DImode, subtarget, GEN_INT (diff));
2993 tmp = gen_rtx_PLUS (DImode, tmp, add_op);
2994 emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
3006 /* Look up the function X_floating library function name for the
3010 alpha_lookup_xfloating_lib_func (code)
3015 const enum rtx_code code;
3016 const char *const func;
3019 static const struct xfloating_op vms_xfloating_ops[] =
3021 { PLUS, "OTS$ADD_X" },
3022 { MINUS, "OTS$SUB_X" },
3023 { MULT, "OTS$MUL_X" },
3024 { DIV, "OTS$DIV_X" },
3025 { EQ, "OTS$EQL_X" },
3026 { NE, "OTS$NEQ_X" },
3027 { LT, "OTS$LSS_X" },
3028 { LE, "OTS$LEQ_X" },
3029 { GT, "OTS$GTR_X" },
3030 { GE, "OTS$GEQ_X" },
3031 { FIX, "OTS$CVTXQ" },
3032 { FLOAT, "OTS$CVTQX" },
3033 { UNSIGNED_FLOAT, "OTS$CVTQUX" },
3034 { FLOAT_EXTEND, "OTS$CVT_FLOAT_T_X" },
3035 { FLOAT_TRUNCATE, "OTS$CVT_FLOAT_X_T" },
3038 static const struct xfloating_op osf_xfloating_ops[] =
3040 { PLUS, "_OtsAddX" },
3041 { MINUS, "_OtsSubX" },
3042 { MULT, "_OtsMulX" },
3043 { DIV, "_OtsDivX" },
3050 { FIX, "_OtsCvtXQ" },
3051 { FLOAT, "_OtsCvtQX" },
3052 { UNSIGNED_FLOAT, "_OtsCvtQUX" },
3053 { FLOAT_EXTEND, "_OtsConvertFloatTX" },
3054 { FLOAT_TRUNCATE, "_OtsConvertFloatXT" },
3057 const struct xfloating_op *ops;
3058 const long n = ARRAY_SIZE (osf_xfloating_ops);
3061 /* How irritating. Nothing to key off for the table. Hardcode
3062 knowledge of the G_floating routines. */
3063 if (TARGET_FLOAT_VAX)
3065 if (TARGET_ABI_OPEN_VMS)
3067 if (code == FLOAT_EXTEND)
3068 return "OTS$CVT_FLOAT_G_X";
3069 if (code == FLOAT_TRUNCATE)
3070 return "OTS$CVT_FLOAT_X_G";
3074 if (code == FLOAT_EXTEND)
3075 return "_OtsConvertFloatGX";
3076 if (code == FLOAT_TRUNCATE)
3077 return "_OtsConvertFloatXG";
3081 if (TARGET_ABI_OPEN_VMS)
3082 ops = vms_xfloating_ops;
3084 ops = osf_xfloating_ops;
3086 for (i = 0; i < n; ++i)
3087 if (ops[i].code == code)
3093 /* Most X_floating operations take the rounding mode as an argument.
3094 Compute that here. */
3097 alpha_compute_xfloating_mode_arg (code, round)
3099 enum alpha_fp_rounding_mode round;
3105 case ALPHA_FPRM_NORM:
3108 case ALPHA_FPRM_MINF:
3111 case ALPHA_FPRM_CHOP:
3114 case ALPHA_FPRM_DYN:
3120 /* XXX For reference, round to +inf is mode = 3. */
3123 if (code == FLOAT_TRUNCATE && alpha_fptm == ALPHA_FPTM_N)
3129 /* Emit an X_floating library function call.
3131 Note that these functions do not follow normal calling conventions:
3132 TFmode arguments are passed in two integer registers (as opposed to
3133 indirect); TFmode return values appear in R16+R17.
3135 FUNC is the function name to call.
3136 TARGET is where the output belongs.
3137 OPERANDS are the inputs.
3138 NOPERANDS is the count of inputs.
3139 EQUIV is the expression equivalent for the function.
3143 alpha_emit_xfloating_libcall (func, target, operands, noperands, equiv)
3150 rtx usage = NULL_RTX, tmp, reg;
3155 for (i = 0; i < noperands; ++i)
3157 switch (GET_MODE (operands[i]))
3160 reg = gen_rtx_REG (TFmode, regno);
3165 reg = gen_rtx_REG (DFmode, regno + 32);
3170 if (GET_CODE (operands[i]) != CONST_INT)
3174 reg = gen_rtx_REG (DImode, regno);
3182 emit_move_insn (reg, operands[i]);
3183 usage = alloc_EXPR_LIST (0, gen_rtx_USE (VOIDmode, reg), usage);
3186 switch (GET_MODE (target))
3189 reg = gen_rtx_REG (TFmode, 16);
3192 reg = gen_rtx_REG (DFmode, 32);
3195 reg = gen_rtx_REG (DImode, 0);
3201 tmp = gen_rtx_MEM (QImode, gen_rtx_SYMBOL_REF (Pmode, (char *) func));
3202 tmp = emit_call_insn (GEN_CALL_VALUE (reg, tmp, const0_rtx,
3203 const0_rtx, const0_rtx));
3204 CALL_INSN_FUNCTION_USAGE (tmp) = usage;
3209 emit_libcall_block (tmp, target, reg, equiv);
3212 /* Emit an X_floating library function call for arithmetic (+,-,*,/). */
3215 alpha_emit_xfloating_arith (code, operands)
3221 rtx out_operands[3];
3223 func = alpha_lookup_xfloating_lib_func (code);
3224 mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
3226 out_operands[0] = operands[1];
3227 out_operands[1] = operands[2];
3228 out_operands[2] = GEN_INT (mode);
3229 alpha_emit_xfloating_libcall (func, operands[0], out_operands, 3,
3230 gen_rtx_fmt_ee (code, TFmode, operands[1],
3234 /* Emit an X_floating library function call for a comparison. */
3237 alpha_emit_xfloating_compare (code, op0, op1)
3242 rtx out, operands[2];
3244 func = alpha_lookup_xfloating_lib_func (code);
3248 out = gen_reg_rtx (DImode);
3250 /* ??? Strange mode for equiv because what's actually returned
3251 is -1,0,1, not a proper boolean value. */
3252 alpha_emit_xfloating_libcall (func, out, operands, 2,
3253 gen_rtx_fmt_ee (code, CCmode, op0, op1));
3258 /* Emit an X_floating library function call for a conversion. */
3261 alpha_emit_xfloating_cvt (code, operands)
3265 int noperands = 1, mode;
3266 rtx out_operands[2];
3269 func = alpha_lookup_xfloating_lib_func (code);
3271 out_operands[0] = operands[1];
3276 mode = alpha_compute_xfloating_mode_arg (code, ALPHA_FPRM_CHOP);
3277 out_operands[1] = GEN_INT (mode);
3280 case FLOAT_TRUNCATE:
3281 mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
3282 out_operands[1] = GEN_INT (mode);
3289 alpha_emit_xfloating_libcall (func, operands[0], out_operands, noperands,
3290 gen_rtx_fmt_e (code, GET_MODE (operands[0]),
3294 /* Split a TFmode OP[1] into DImode OP[2,3] and likewise for
3295 OP[0] into OP[0,1]. Naturally, output operand ordering is
3299 alpha_split_tfmode_pair (operands)
3302 if (GET_CODE (operands[1]) == REG)
3304 operands[3] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1);
3305 operands[2] = gen_rtx_REG (DImode, REGNO (operands[1]));
3307 else if (GET_CODE (operands[1]) == MEM)
3309 operands[3] = adjust_address (operands[1], DImode, 8);
3310 operands[2] = adjust_address (operands[1], DImode, 0);
3312 else if (operands[1] == CONST0_RTX (TFmode))
3313 operands[2] = operands[3] = const0_rtx;
3317 if (GET_CODE (operands[0]) == REG)
3319 operands[1] = gen_rtx_REG (DImode, REGNO (operands[0]) + 1);
3320 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
3322 else if (GET_CODE (operands[0]) == MEM)
3324 operands[1] = adjust_address (operands[0], DImode, 8);
3325 operands[0] = adjust_address (operands[0], DImode, 0);
3331 /* Implement negtf2 or abstf2. Op0 is destination, op1 is source,
3332 op2 is a register containing the sign bit, operation is the
3333 logical operation to be performed. */
3336 alpha_split_tfmode_frobsign (operands, operation)
3338 rtx (*operation) PARAMS ((rtx, rtx, rtx));
3340 rtx high_bit = operands[2];
3344 alpha_split_tfmode_pair (operands);
3346 /* Detect three flavours of operand overlap. */
3348 if (rtx_equal_p (operands[0], operands[2]))
3350 else if (rtx_equal_p (operands[1], operands[2]))
3352 if (rtx_equal_p (operands[0], high_bit))
3359 emit_move_insn (operands[0], operands[2]);
3361 /* ??? If the destination overlaps both source tf and high_bit, then
3362 assume source tf is dead in its entirety and use the other half
3363 for a scratch register. Otherwise "scratch" is just the proper
3364 destination register. */
3365 scratch = operands[move < 2 ? 1 : 3];
3367 emit_insn ((*operation) (scratch, high_bit, operands[3]));
3371 emit_move_insn (operands[0], operands[2]);
3373 emit_move_insn (operands[1], scratch);
3377 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
3381 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
3382 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
3383 lda r3,X(r11) lda r3,X+2(r11)
3384 extwl r1,r3,r1 extql r1,r3,r1
3385 extwh r2,r3,r2 extqh r2,r3,r2
3386 or r1.r2.r1 or r1,r2,r1
3389 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
3390 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
3391 lda r3,X(r11) lda r3,X(r11)
3392 extll r1,r3,r1 extll r1,r3,r1
3393 extlh r2,r3,r2 extlh r2,r3,r2
3394 or r1.r2.r1 addl r1,r2,r1
3396 quad: ldq_u r1,X(r11)
3405 alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
3407 HOST_WIDE_INT size, ofs;
3410 rtx meml, memh, addr, extl, exth, tmp, mema;
3411 enum machine_mode mode;
3413 meml = gen_reg_rtx (DImode);
3414 memh = gen_reg_rtx (DImode);
3415 addr = gen_reg_rtx (DImode);
3416 extl = gen_reg_rtx (DImode);
3417 exth = gen_reg_rtx (DImode);
3419 mema = XEXP (mem, 0);
3420 if (GET_CODE (mema) == LO_SUM)
3421 mema = force_reg (Pmode, mema);
3423 /* AND addresses cannot be in any alias set, since they may implicitly
3424 alias surrounding code. Ideally we'd have some alias set that
3425 covered all types except those with alignment 8 or higher. */
3427 tmp = change_address (mem, DImode,
3428 gen_rtx_AND (DImode,
3429 plus_constant (mema, ofs),
3431 set_mem_alias_set (tmp, 0);
3432 emit_move_insn (meml, tmp);
3434 tmp = change_address (mem, DImode,
3435 gen_rtx_AND (DImode,
3436 plus_constant (mema, ofs + size - 1),
3438 set_mem_alias_set (tmp, 0);
3439 emit_move_insn (memh, tmp);
3441 if (WORDS_BIG_ENDIAN && sign && (size == 2 || size == 4))
3443 emit_move_insn (addr, plus_constant (mema, -1));
3445 emit_insn (gen_extqh_be (extl, meml, addr));
3446 emit_insn (gen_extxl_be (exth, memh, GEN_INT (64), addr));
3448 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
3449 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (64 - size*8),
3450 addr, 1, OPTAB_WIDEN);
3452 else if (sign && size == 2)
3454 emit_move_insn (addr, plus_constant (mema, ofs+2));
3456 emit_insn (gen_extxl_le (extl, meml, GEN_INT (64), addr));
3457 emit_insn (gen_extqh_le (exth, memh, addr));
3459 /* We must use tgt here for the target. Alpha-vms port fails if we use
3460 addr for the target, because addr is marked as a pointer and combine
3461 knows that pointers are always sign-extended 32 bit values. */
3462 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
3463 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48),
3464 addr, 1, OPTAB_WIDEN);
3468 if (WORDS_BIG_ENDIAN)
3470 emit_move_insn (addr, plus_constant (mema, ofs+size-1));
3474 emit_insn (gen_extwh_be (extl, meml, addr));
3479 emit_insn (gen_extlh_be (extl, meml, addr));
3484 emit_insn (gen_extqh_be (extl, meml, addr));
3491 emit_insn (gen_extxl_be (exth, memh, GEN_INT (size*8), addr));
3495 emit_move_insn (addr, plus_constant (mema, ofs));
3496 emit_insn (gen_extxl_le (extl, meml, GEN_INT (size*8), addr));
3500 emit_insn (gen_extwh_le (exth, memh, addr));
3505 emit_insn (gen_extlh_le (exth, memh, addr));
3510 emit_insn (gen_extqh_le (exth, memh, addr));
3519 addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
3520 gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
3525 emit_move_insn (tgt, gen_lowpart(GET_MODE (tgt), addr));
3528 /* Similarly, use ins and msk instructions to perform unaligned stores. */
3531 alpha_expand_unaligned_store (dst, src, size, ofs)
3533 HOST_WIDE_INT size, ofs;
3535 rtx dstl, dsth, addr, insl, insh, meml, memh, dsta;
3537 dstl = gen_reg_rtx (DImode);
3538 dsth = gen_reg_rtx (DImode);
3539 insl = gen_reg_rtx (DImode);
3540 insh = gen_reg_rtx (DImode);
3542 dsta = XEXP (dst, 0);
3543 if (GET_CODE (dsta) == LO_SUM)
3544 dsta = force_reg (Pmode, dsta);
3546 /* AND addresses cannot be in any alias set, since they may implicitly
3547 alias surrounding code. Ideally we'd have some alias set that
3548 covered all types except those with alignment 8 or higher. */
3550 meml = change_address (dst, DImode,
3551 gen_rtx_AND (DImode,
3552 plus_constant (dsta, ofs),
3554 set_mem_alias_set (meml, 0);
3556 memh = change_address (dst, DImode,
3557 gen_rtx_AND (DImode,
3558 plus_constant (dsta, ofs + size - 1),
3560 set_mem_alias_set (memh, 0);
3562 emit_move_insn (dsth, memh);
3563 emit_move_insn (dstl, meml);
3564 if (WORDS_BIG_ENDIAN)
3566 addr = copy_addr_to_reg (plus_constant (dsta, ofs+size-1));
3568 if (src != const0_rtx)
3573 emit_insn (gen_inswl_be (insh, gen_lowpart (HImode,src), addr));
3576 emit_insn (gen_insll_be (insh, gen_lowpart (SImode,src), addr));
3579 emit_insn (gen_insql_be (insh, gen_lowpart (DImode,src), addr));
3582 emit_insn (gen_insxh (insl, gen_lowpart (DImode, src),
3583 GEN_INT (size*8), addr));
3589 emit_insn (gen_mskxl_be (dsth, dsth, GEN_INT (0xffff), addr));
3592 emit_insn (gen_mskxl_be (dsth, dsth, GEN_INT (0xffffffff), addr));
3596 #if HOST_BITS_PER_WIDE_INT == 32
3597 rtx msk = immed_double_const (0xffffffff, 0xffffffff, DImode);
3599 rtx msk = immed_double_const (0xffffffffffffffff, 0, DImode);
3601 emit_insn (gen_mskxl_be (dsth, dsth, msk, addr));
3606 emit_insn (gen_mskxh (dstl, dstl, GEN_INT (size*8), addr));
3610 addr = copy_addr_to_reg (plus_constant (dsta, ofs));
3612 if (src != const0_rtx)
3614 emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
3615 GEN_INT (size*8), addr));
3620 emit_insn (gen_inswl_le (insl, gen_lowpart (HImode, src), addr));
3623 emit_insn (gen_insll_le (insl, gen_lowpart (SImode, src), addr));
3626 emit_insn (gen_insql_le (insl, src, addr));
3631 emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
3636 emit_insn (gen_mskxl_le (dstl, dstl, GEN_INT (0xffff), addr));
3639 emit_insn (gen_mskxl_le (dstl, dstl, GEN_INT (0xffffffff), addr));
3643 #if HOST_BITS_PER_WIDE_INT == 32
3644 rtx msk = immed_double_const (0xffffffff, 0xffffffff, DImode);
3646 rtx msk = immed_double_const (0xffffffffffffffff, 0, DImode);
3648 emit_insn (gen_mskxl_le (dstl, dstl, msk, addr));
3654 if (src != const0_rtx)
3656 dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
3657 dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
3660 if (WORDS_BIG_ENDIAN)
3662 emit_move_insn (meml, dstl);
3663 emit_move_insn (memh, dsth);
3667 /* Must store high before low for degenerate case of aligned. */
3668 emit_move_insn (memh, dsth);
3669 emit_move_insn (meml, dstl);
3673 /* The block move code tries to maximize speed by separating loads and
3674 stores at the expense of register pressure: we load all of the data
3675 before we store it back out. There are two secondary effects worth
3676 mentioning, that this speeds copying to/from aligned and unaligned
3677 buffers, and that it makes the code significantly easier to write. */
3679 #define MAX_MOVE_WORDS 8
3681 /* Load an integral number of consecutive unaligned quadwords. */
3684 alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
3687 HOST_WIDE_INT words, ofs;
3689 rtx const im8 = GEN_INT (-8);
3690 rtx const i64 = GEN_INT (64);
3691 rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
3692 rtx sreg, areg, tmp, smema;
3695 smema = XEXP (smem, 0);
3696 if (GET_CODE (smema) == LO_SUM)
3697 smema = force_reg (Pmode, smema);
3699 /* Generate all the tmp registers we need. */
3700 for (i = 0; i < words; ++i)
3702 data_regs[i] = out_regs[i];
3703 ext_tmps[i] = gen_reg_rtx (DImode);
3705 data_regs[words] = gen_reg_rtx (DImode);
3708 smem = adjust_address (smem, GET_MODE (smem), ofs);
3710 /* Load up all of the source data. */
3711 for (i = 0; i < words; ++i)
3713 tmp = change_address (smem, DImode,
3714 gen_rtx_AND (DImode,
3715 plus_constant (smema, 8*i),
3717 set_mem_alias_set (tmp, 0);
3718 emit_move_insn (data_regs[i], tmp);
3721 tmp = change_address (smem, DImode,
3722 gen_rtx_AND (DImode,
3723 plus_constant (smema, 8*words - 1),
3725 set_mem_alias_set (tmp, 0);
3726 emit_move_insn (data_regs[words], tmp);
3728 /* Extract the half-word fragments. Unfortunately DEC decided to make
3729 extxh with offset zero a noop instead of zeroing the register, so
3730 we must take care of that edge condition ourselves with cmov. */
3732 sreg = copy_addr_to_reg (smema);
3733 areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
3735 if (WORDS_BIG_ENDIAN)
3736 emit_move_insn (sreg, plus_constant (sreg, 7));
3737 for (i = 0; i < words; ++i)
3739 if (WORDS_BIG_ENDIAN)
3741 emit_insn (gen_extqh_be (data_regs[i], data_regs[i], sreg));
3742 emit_insn (gen_extxl_be (ext_tmps[i], data_regs[i+1], i64, sreg));
3746 emit_insn (gen_extxl_le (data_regs[i], data_regs[i], i64, sreg));
3747 emit_insn (gen_extqh_le (ext_tmps[i], data_regs[i+1], sreg));
3749 emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
3750 gen_rtx_IF_THEN_ELSE (DImode,
3751 gen_rtx_EQ (DImode, areg,
3753 const0_rtx, ext_tmps[i])));
3756 /* Merge the half-words into whole words. */
3757 for (i = 0; i < words; ++i)
3759 out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
3760 ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
3764 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
3765 may be NULL to store zeros. */
3768 alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
3771 HOST_WIDE_INT words, ofs;
3773 rtx const im8 = GEN_INT (-8);
3774 rtx const i64 = GEN_INT (64);
3775 #if HOST_BITS_PER_WIDE_INT == 32
3776 rtx const im1 = immed_double_const (0xffffffff, 0xffffffff, DImode);
3778 rtx const im1 = immed_double_const (0xffffffffffffffff, 0, DImode);
3780 rtx ins_tmps[MAX_MOVE_WORDS];
3781 rtx st_tmp_1, st_tmp_2, dreg;
3782 rtx st_addr_1, st_addr_2, dmema;
3785 dmema = XEXP (dmem, 0);
3786 if (GET_CODE (dmema) == LO_SUM)
3787 dmema = force_reg (Pmode, dmema);
3789 /* Generate all the tmp registers we need. */
3790 if (data_regs != NULL)
3791 for (i = 0; i < words; ++i)
3792 ins_tmps[i] = gen_reg_rtx(DImode);
3793 st_tmp_1 = gen_reg_rtx(DImode);
3794 st_tmp_2 = gen_reg_rtx(DImode);
3797 dmem = adjust_address (dmem, GET_MODE (dmem), ofs);
3799 st_addr_2 = change_address (dmem, DImode,
3800 gen_rtx_AND (DImode,
3801 plus_constant (dmema, words*8 - 1),
3803 set_mem_alias_set (st_addr_2, 0);
3805 st_addr_1 = change_address (dmem, DImode,
3806 gen_rtx_AND (DImode, dmema, im8));
3807 set_mem_alias_set (st_addr_1, 0);
3809 /* Load up the destination end bits. */
3810 emit_move_insn (st_tmp_2, st_addr_2);
3811 emit_move_insn (st_tmp_1, st_addr_1);
3813 /* Shift the input data into place. */
3814 dreg = copy_addr_to_reg (dmema);
3815 if (WORDS_BIG_ENDIAN)
3816 emit_move_insn (dreg, plus_constant (dreg, 7));
3817 if (data_regs != NULL)
3819 for (i = words-1; i >= 0; --i)
3821 if (WORDS_BIG_ENDIAN)
3823 emit_insn (gen_insql_be (ins_tmps[i], data_regs[i], dreg));
3824 emit_insn (gen_insxh (data_regs[i], data_regs[i], i64, dreg));
3828 emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
3829 emit_insn (gen_insql_le (data_regs[i], data_regs[i], dreg));
3832 for (i = words-1; i > 0; --i)
3834 ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
3835 ins_tmps[i-1], ins_tmps[i-1], 1,
3840 /* Split and merge the ends with the destination data. */
3841 if (WORDS_BIG_ENDIAN)
3843 emit_insn (gen_mskxl_be (st_tmp_2, st_tmp_2, im1, dreg));
3844 emit_insn (gen_mskxh (st_tmp_1, st_tmp_1, i64, dreg));
3848 emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
3849 emit_insn (gen_mskxl_le (st_tmp_1, st_tmp_1, im1, dreg));
3852 if (data_regs != NULL)
3854 st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
3855 st_tmp_2, 1, OPTAB_WIDEN);
3856 st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
3857 st_tmp_1, 1, OPTAB_WIDEN);
3861 if (WORDS_BIG_ENDIAN)
3862 emit_move_insn (st_addr_1, st_tmp_1);
3864 emit_move_insn (st_addr_2, st_tmp_2);
3865 for (i = words-1; i > 0; --i)
3867 rtx tmp = change_address (dmem, DImode,
3868 gen_rtx_AND (DImode,
3869 plus_constant(dmema,
3870 WORDS_BIG_ENDIAN ? i*8-1 : i*8),
3872 set_mem_alias_set (tmp, 0);
3873 emit_move_insn (tmp, data_regs ? ins_tmps[i-1] : const0_rtx);
3875 if (WORDS_BIG_ENDIAN)
3876 emit_move_insn (st_addr_2, st_tmp_2);
3878 emit_move_insn (st_addr_1, st_tmp_1);
3882 /* Expand string/block move operations.
3884 operands[0] is the pointer to the destination.
3885 operands[1] is the pointer to the source.
3886 operands[2] is the number of bytes to move.
3887 operands[3] is the alignment. */
3890 alpha_expand_block_move (operands)
3893 rtx bytes_rtx = operands[2];
3894 rtx align_rtx = operands[3];
3895 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
3896 HOST_WIDE_INT bytes = orig_bytes;
3897 HOST_WIDE_INT src_align = INTVAL (align_rtx) * BITS_PER_UNIT;
3898 HOST_WIDE_INT dst_align = src_align;
3899 rtx orig_src = operands[1];
3900 rtx orig_dst = operands[0];
3901 rtx data_regs[2 * MAX_MOVE_WORDS + 16];
3903 unsigned int i, words, ofs, nregs = 0;
3905 if (orig_bytes <= 0)
3907 else if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD)
3910 /* Look for additional alignment information from recorded register info. */
3912 tmp = XEXP (orig_src, 0);
3913 if (GET_CODE (tmp) == REG)
3914 src_align = MAX (src_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
3915 else if (GET_CODE (tmp) == PLUS
3916 && GET_CODE (XEXP (tmp, 0)) == REG
3917 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
3919 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
3920 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
3924 if (a >= 64 && c % 8 == 0)
3926 else if (a >= 32 && c % 4 == 0)
3928 else if (a >= 16 && c % 2 == 0)
3933 tmp = XEXP (orig_dst, 0);
3934 if (GET_CODE (tmp) == REG)
3935 dst_align = MAX (dst_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
3936 else if (GET_CODE (tmp) == PLUS
3937 && GET_CODE (XEXP (tmp, 0)) == REG
3938 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
3940 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
3941 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
3945 if (a >= 64 && c % 8 == 0)
3947 else if (a >= 32 && c % 4 == 0)
3949 else if (a >= 16 && c % 2 == 0)
3954 /* Load the entire block into registers. */
3955 if (GET_CODE (XEXP (orig_src, 0)) == ADDRESSOF)
3957 enum machine_mode mode;
3959 tmp = XEXP (XEXP (orig_src, 0), 0);
3961 /* Don't use the existing register if we're reading more than
3962 is held in the register. Nor if there is not a mode that
3963 handles the exact size. */
3964 mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);
3966 && GET_MODE_SIZE (GET_MODE (tmp)) >= bytes)
3970 data_regs[nregs] = gen_lowpart (DImode, tmp);
3971 data_regs[nregs + 1] = gen_highpart (DImode, tmp);
3975 data_regs[nregs++] = gen_lowpart (mode, tmp);
3980 /* No appropriate mode; fall back on memory. */
3981 orig_src = replace_equiv_address (orig_src,
3982 copy_addr_to_reg (XEXP (orig_src, 0)));
3983 src_align = GET_MODE_BITSIZE (GET_MODE (tmp));
3987 if (src_align >= 64 && bytes >= 8)
3991 for (i = 0; i < words; ++i)
3992 data_regs[nregs + i] = gen_reg_rtx (DImode);
3994 for (i = 0; i < words; ++i)
3995 emit_move_insn (data_regs[nregs + i],
3996 adjust_address (orig_src, DImode, ofs + i * 8));
4003 if (src_align >= 32 && bytes >= 4)
4007 for (i = 0; i < words; ++i)
4008 data_regs[nregs + i] = gen_reg_rtx (SImode);
4010 for (i = 0; i < words; ++i)
4011 emit_move_insn (data_regs[nregs + i],
4012 adjust_address (orig_src, SImode, ofs + i * 4));
4023 for (i = 0; i < words+1; ++i)
4024 data_regs[nregs + i] = gen_reg_rtx (DImode);
4026 alpha_expand_unaligned_load_words (data_regs + nregs, orig_src,
4034 if (! TARGET_BWX && bytes >= 4)
4036 data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
4037 alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
4044 if (src_align >= 16)
4047 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
4048 emit_move_insn (tmp, adjust_address (orig_src, HImode, ofs));
4051 } while (bytes >= 2);
4053 else if (! TARGET_BWX)
4055 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
4056 alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
4064 data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
4065 emit_move_insn (tmp, adjust_address (orig_src, QImode, ofs));
4072 if (nregs > ARRAY_SIZE (data_regs))
4075 /* Now save it back out again. */
4079 if (GET_CODE (XEXP (orig_dst, 0)) == ADDRESSOF)
4081 enum machine_mode mode;
4082 tmp = XEXP (XEXP (orig_dst, 0), 0);
4084 mode = mode_for_size (orig_bytes * BITS_PER_UNIT, MODE_INT, 1);
4085 if (GET_MODE (tmp) == mode)
4089 emit_move_insn (tmp, data_regs[0]);
4094 else if (nregs == 2 && mode == TImode)
4096 /* Undo the subregging done above when copying between
4097 two TImode registers. */
4098 if (GET_CODE (data_regs[0]) == SUBREG
4099 && GET_MODE (SUBREG_REG (data_regs[0])) == TImode)
4100 emit_move_insn (tmp, SUBREG_REG (data_regs[0]));
4106 emit_move_insn (gen_lowpart (DImode, tmp), data_regs[0]);
4107 emit_move_insn (gen_highpart (DImode, tmp), data_regs[1]);
4111 emit_no_conflict_block (seq, tmp, data_regs[0],
4112 data_regs[1], NULL_RTX);
4120 /* ??? If nregs > 1, consider reconstructing the word in regs. */
4121 /* ??? Optimize mode < dst_mode with strict_low_part. */
4123 /* No appropriate mode; fall back on memory. We can speed things
4124 up by recognizing extra alignment information. */
4125 orig_dst = replace_equiv_address (orig_dst,
4126 copy_addr_to_reg (XEXP (orig_dst, 0)));
4127 dst_align = GET_MODE_BITSIZE (GET_MODE (tmp));
4130 /* Write out the data in whatever chunks reading the source allowed. */
4131 if (dst_align >= 64)
4133 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
4135 emit_move_insn (adjust_address (orig_dst, DImode, ofs),
4142 if (dst_align >= 32)
4144 /* If the source has remaining DImode regs, write them out in
4146 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
4148 tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
4149 NULL_RTX, 1, OPTAB_WIDEN);
4151 emit_move_insn (adjust_address (orig_dst, SImode, ofs),
4152 gen_lowpart (SImode, data_regs[i]));
4153 emit_move_insn (adjust_address (orig_dst, SImode, ofs + 4),
4154 gen_lowpart (SImode, tmp));
4159 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
4161 emit_move_insn (adjust_address (orig_dst, SImode, ofs),
4168 if (i < nregs && GET_MODE (data_regs[i]) == DImode)
4170 /* Write out a remaining block of words using unaligned methods. */
4172 for (words = 1; i + words < nregs; words++)
4173 if (GET_MODE (data_regs[i + words]) != DImode)
4177 alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
4179 alpha_expand_unaligned_store_words (data_regs + i, orig_dst,
4186 /* Due to the above, this won't be aligned. */
4187 /* ??? If we have more than one of these, consider constructing full
4188 words in registers and using alpha_expand_unaligned_store_words. */
4189 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
4191 alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
4196 if (dst_align >= 16)
4197 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
4199 emit_move_insn (adjust_address (orig_dst, HImode, ofs), data_regs[i]);
4204 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
4206 alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
4211 while (i < nregs && GET_MODE (data_regs[i]) == QImode)
4213 emit_move_insn (adjust_address (orig_dst, QImode, ofs), data_regs[i]);
4227 alpha_expand_block_clear (operands)
4230 rtx bytes_rtx = operands[1];
4231 rtx align_rtx = operands[2];
4232 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
4233 HOST_WIDE_INT bytes = orig_bytes;
4234 HOST_WIDE_INT align = INTVAL (align_rtx) * BITS_PER_UNIT;
4235 HOST_WIDE_INT alignofs = 0;
4236 rtx orig_dst = operands[0];
4238 int i, words, ofs = 0;
4240 if (orig_bytes <= 0)
4242 if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD)
4245 /* Look for stricter alignment. */
4246 tmp = XEXP (orig_dst, 0);
4247 if (GET_CODE (tmp) == REG)
4248 align = MAX (align, REGNO_POINTER_ALIGN (REGNO (tmp)));
4249 else if (GET_CODE (tmp) == PLUS
4250 && GET_CODE (XEXP (tmp, 0)) == REG
4251 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
4253 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
4254 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
4259 align = a, alignofs = 8 - c % 8;
4261 align = a, alignofs = 4 - c % 4;
4263 align = a, alignofs = 2 - c % 2;
4266 else if (GET_CODE (tmp) == ADDRESSOF)
4268 enum machine_mode mode;
4270 mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);
4271 if (GET_MODE (XEXP (tmp, 0)) == mode)
4273 emit_move_insn (XEXP (tmp, 0), const0_rtx);
4277 /* No appropriate mode; fall back on memory. */
4278 orig_dst = replace_equiv_address (orig_dst, copy_addr_to_reg (tmp));
4279 align = GET_MODE_BITSIZE (GET_MODE (XEXP (tmp, 0)));
4282 /* Handle an unaligned prefix first. */
4286 #if HOST_BITS_PER_WIDE_INT >= 64
4287 /* Given that alignofs is bounded by align, the only time BWX could
4288 generate three stores is for a 7 byte fill. Prefer two individual
4289 stores over a load/mask/store sequence. */
4290 if ((!TARGET_BWX || alignofs == 7)
4292 && !(alignofs == 4 && bytes >= 4))
4294 enum machine_mode mode = (align >= 64 ? DImode : SImode);
4295 int inv_alignofs = (align >= 64 ? 8 : 4) - alignofs;
4299 mem = adjust_address (orig_dst, mode, ofs - inv_alignofs);
4300 set_mem_alias_set (mem, 0);
4302 mask = ~(~(HOST_WIDE_INT)0 << (inv_alignofs * 8));
4303 if (bytes < alignofs)
4305 mask |= ~(HOST_WIDE_INT)0 << ((inv_alignofs + bytes) * 8);
4316 tmp = expand_binop (mode, and_optab, mem, GEN_INT (mask),
4317 NULL_RTX, 1, OPTAB_WIDEN);
4319 emit_move_insn (mem, tmp);
4323 if (TARGET_BWX && (alignofs & 1) && bytes >= 1)
4325 emit_move_insn (adjust_address (orig_dst, QImode, ofs), const0_rtx);
4330 if (TARGET_BWX && align >= 16 && (alignofs & 3) == 2 && bytes >= 2)
4332 emit_move_insn (adjust_address (orig_dst, HImode, ofs), const0_rtx);
4337 if (alignofs == 4 && bytes >= 4)
4339 emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx);
4345 /* If we've not used the extra lead alignment information by now,
4346 we won't be able to. Downgrade align to match what's left over. */
4349 alignofs = alignofs & -alignofs;
4350 align = MIN (align, alignofs * BITS_PER_UNIT);
4354 /* Handle a block of contiguous long-words. */
4356 if (align >= 64 && bytes >= 8)
4360 for (i = 0; i < words; ++i)
4361 emit_move_insn (adjust_address (orig_dst, DImode, ofs + i * 8),
4368 /* If the block is large and appropriately aligned, emit a single
4369 store followed by a sequence of stq_u insns. */
4371 if (align >= 32 && bytes > 16)
4375 emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx);
4379 orig_dsta = XEXP (orig_dst, 0);
4380 if (GET_CODE (orig_dsta) == LO_SUM)
4381 orig_dsta = force_reg (Pmode, orig_dsta);
4384 for (i = 0; i < words; ++i)
4387 = change_address (orig_dst, DImode,
4388 gen_rtx_AND (DImode,
4389 plus_constant (orig_dsta, ofs + i*8),
4391 set_mem_alias_set (mem, 0);
4392 emit_move_insn (mem, const0_rtx);
4395 /* Depending on the alignment, the first stq_u may have overlapped
4396 with the initial stl, which means that the last stq_u didn't
4397 write as much as it would appear. Leave those questionable bytes
4399 bytes -= words * 8 - 4;
4400 ofs += words * 8 - 4;
4403 /* Handle a smaller block of aligned words. */
4405 if ((align >= 64 && bytes == 4)
4406 || (align == 32 && bytes >= 4))
4410 for (i = 0; i < words; ++i)
4411 emit_move_insn (adjust_address (orig_dst, SImode, ofs + i * 4),
4418 /* An unaligned block uses stq_u stores for as many as possible. */
4424 alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
4430 /* Next clean up any trailing pieces. */
4432 #if HOST_BITS_PER_WIDE_INT >= 64
4433 /* Count the number of bits in BYTES for which aligned stores could
4436 for (i = (TARGET_BWX ? 1 : 4); i * BITS_PER_UNIT <= align ; i <<= 1)
4440 /* If we have appropriate alignment (and it wouldn't take too many
4441 instructions otherwise), mask out the bytes we need. */
4442 if (TARGET_BWX ? words > 2 : bytes > 0)
4449 mem = adjust_address (orig_dst, DImode, ofs);
4450 set_mem_alias_set (mem, 0);
4452 mask = ~(HOST_WIDE_INT)0 << (bytes * 8);
4454 tmp = expand_binop (DImode, and_optab, mem, GEN_INT (mask),
4455 NULL_RTX, 1, OPTAB_WIDEN);
4457 emit_move_insn (mem, tmp);
4460 else if (align >= 32 && bytes < 4)
4465 mem = adjust_address (orig_dst, SImode, ofs);
4466 set_mem_alias_set (mem, 0);
4468 mask = ~(HOST_WIDE_INT)0 << (bytes * 8);
4470 tmp = expand_binop (SImode, and_optab, mem, GEN_INT (mask),
4471 NULL_RTX, 1, OPTAB_WIDEN);
4473 emit_move_insn (mem, tmp);
4479 if (!TARGET_BWX && bytes >= 4)
4481 alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
4491 emit_move_insn (adjust_address (orig_dst, HImode, ofs),
4495 } while (bytes >= 2);
4497 else if (! TARGET_BWX)
4499 alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
4507 emit_move_insn (adjust_address (orig_dst, QImode, ofs), const0_rtx);
4515 /* Adjust the cost of a scheduling dependency. Return the new cost of
4516 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
4519 alpha_adjust_cost (insn, link, dep_insn, cost)
4526 enum attr_type insn_type, dep_insn_type;
4528 /* If the dependence is an anti-dependence, there is no cost. For an
4529 output dependence, there is sometimes a cost, but it doesn't seem
4530 worth handling those few cases. */
4532 if (REG_NOTE_KIND (link) != 0)
4535 /* If we can't recognize the insns, we can't really do anything. */
4536 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
4539 insn_type = get_attr_type (insn);
4540 dep_insn_type = get_attr_type (dep_insn);
4542 /* Bring in the user-defined memory latency. */
4543 if (dep_insn_type == TYPE_ILD
4544 || dep_insn_type == TYPE_FLD
4545 || dep_insn_type == TYPE_LDSYM)
4546 cost += alpha_memory_latency-1;
4551 /* On EV4, if INSN is a store insn and DEP_INSN is setting the data
4552 being stored, we can sometimes lower the cost. */
4554 if ((insn_type == TYPE_IST || insn_type == TYPE_FST)
4555 && (set = single_set (dep_insn)) != 0
4556 && GET_CODE (PATTERN (insn)) == SET
4557 && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
4559 switch (dep_insn_type)
4563 /* No savings here. */
4567 /* In these cases, we save one cycle. */
4571 /* In all other cases, we save two cycles. */
4572 return MAX (0, cost - 2);
4576 /* Another case that needs adjustment is an arithmetic or logical
4577 operation. It's cost is usually one cycle, but we default it to
4578 two in the MD file. The only case that it is actually two is
4579 for the address in loads, stores, and jumps. */
4581 if (dep_insn_type == TYPE_IADD || dep_insn_type == TYPE_ILOG)
4596 /* The final case is when a compare feeds into an integer branch;
4597 the cost is only one cycle in that case. */
4599 if (dep_insn_type == TYPE_ICMP && insn_type == TYPE_IBR)
4604 /* And the lord DEC saith: "A special bypass provides an effective
4605 latency of 0 cycles for an ICMP or ILOG insn producing the test
4606 operand of an IBR or ICMOV insn." */
4608 if ((dep_insn_type == TYPE_ICMP || dep_insn_type == TYPE_ILOG)
4609 && (set = single_set (dep_insn)) != 0)
4611 /* A branch only has one input. This must be it. */
4612 if (insn_type == TYPE_IBR)
4614 /* A conditional move has three, make sure it is the test. */
4615 if (insn_type == TYPE_ICMOV
4616 && GET_CODE (set_src = PATTERN (insn)) == SET
4617 && GET_CODE (set_src = SET_SRC (set_src)) == IF_THEN_ELSE
4618 && rtx_equal_p (SET_DEST (set), XEXP (set_src, 0)))
4622 /* "The multiplier is unable to receive data from IEU bypass paths.
4623 The instruction issues at the expected time, but its latency is
4624 increased by the time it takes for the input data to become
4625 available to the multiplier" -- which happens in pipeline stage
4626 six, when results are comitted to the register file. */
4628 if (insn_type == TYPE_IMUL)
4630 switch (dep_insn_type)
4632 /* These insns produce their results in pipeline stage five. */
4639 /* Other integer insns produce results in pipeline stage four. */
4647 /* There is additional latency to move the result of (most) FP
4648 operations anywhere but the FP register file. */
4650 if ((insn_type == TYPE_FST || insn_type == TYPE_FTOI)
4651 && (dep_insn_type == TYPE_FADD ||
4652 dep_insn_type == TYPE_FMUL ||
4653 dep_insn_type == TYPE_FCMOV))
4659 /* Otherwise, return the default cost. */
4663 /* Function to initialize the issue rate used by the scheduler. */
4667 return (alpha_cpu == PROCESSOR_EV4 ? 2 : 4);
4671 alpha_variable_issue (dump, verbose, insn, cim)
4672 FILE *dump ATTRIBUTE_UNUSED;
4673 int verbose ATTRIBUTE_UNUSED;
4677 if (recog_memoized (insn) < 0 || get_attr_type (insn) == TYPE_MULTI)
4684 /* Register global variables and machine-specific functions with the
4685 garbage collector. */
4687 #if TARGET_ABI_UNICOSMK
4689 alpha_init_machine_status (p)
4693 (struct machine_function *) xcalloc (1, sizeof (struct machine_function));
4695 p->machine->first_ciw = NULL_RTX;
4696 p->machine->last_ciw = NULL_RTX;
4697 p->machine->ciw_count = 0;
4698 p->machine->addr_list = NULL_RTX;
4702 alpha_mark_machine_status (p)
4705 struct machine_function *machine = p->machine;
4709 ggc_mark_rtx (machine->first_ciw);
4710 ggc_mark_rtx (machine->addr_list);
4715 alpha_free_machine_status (p)
4721 #endif /* TARGET_ABI_UNICOSMK */
4723 /* Functions to save and restore alpha_return_addr_rtx. */
4725 /* Start the ball rolling with RETURN_ADDR_RTX. */
4728 alpha_return_addr (count, frame)
4730 rtx frame ATTRIBUTE_UNUSED;
4735 return get_hard_reg_initial_val (Pmode, REG_RA);
4738 /* Return or create a pseudo containing the gp value for the current
4739 function. Needed only if TARGET_LD_BUGGY_LDGP. */
4742 alpha_gp_save_rtx ()
4744 return get_hard_reg_initial_val (DImode, 29);
4748 alpha_ra_ever_killed ()
4752 #ifdef ASM_OUTPUT_MI_THUNK
4753 if (current_function_is_thunk)
4756 if (!has_hard_reg_initial_val (Pmode, REG_RA))
4757 return regs_ever_live[REG_RA];
4759 push_topmost_sequence ();
4761 pop_topmost_sequence ();
4763 return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX);
4767 /* Return the trap mode suffix applicable to the current
4768 instruction, or NULL. */
4771 get_trap_mode_suffix ()
4773 enum attr_trap_suffix s = get_attr_trap_suffix (current_output_insn);
4777 case TRAP_SUFFIX_NONE:
4780 case TRAP_SUFFIX_SU:
4781 if (alpha_fptm >= ALPHA_FPTM_SU)
4785 case TRAP_SUFFIX_SUI:
4786 if (alpha_fptm >= ALPHA_FPTM_SUI)
4790 case TRAP_SUFFIX_V_SV:
4798 case ALPHA_FPTM_SUI:
4803 case TRAP_SUFFIX_V_SV_SVI:
4812 case ALPHA_FPTM_SUI:
4817 case TRAP_SUFFIX_U_SU_SUI:
4826 case ALPHA_FPTM_SUI:
4834 /* Return the rounding mode suffix applicable to the current
4835 instruction, or NULL. */
4838 get_round_mode_suffix ()
4840 enum attr_round_suffix s = get_attr_round_suffix (current_output_insn);
4844 case ROUND_SUFFIX_NONE:
4846 case ROUND_SUFFIX_NORMAL:
4849 case ALPHA_FPRM_NORM:
4851 case ALPHA_FPRM_MINF:
4853 case ALPHA_FPRM_CHOP:
4855 case ALPHA_FPRM_DYN:
4860 case ROUND_SUFFIX_C:
4866 /* Print an operand. Recognize special options, documented below. */
4869 print_operand (file, x, code)
4879 /* Print the assembler name of the current function. */
4880 assemble_name (file, alpha_fnname);
4885 const char *trap = get_trap_mode_suffix ();
4886 const char *round = get_round_mode_suffix ();
4889 fprintf (file, (TARGET_AS_SLASH_BEFORE_SUFFIX ? "/%s%s" : "%s%s"),
4890 (trap ? trap : ""), (round ? round : ""));
4895 /* Generates single precision instruction suffix. */
4896 fputc ((TARGET_FLOAT_VAX ? 'f' : 's'), file);
4900 /* Generates double precision instruction suffix. */
4901 fputc ((TARGET_FLOAT_VAX ? 'g' : 't'), file);
4905 if (alpha_this_literal_sequence_number == 0)
4906 alpha_this_literal_sequence_number = alpha_next_sequence_number++;
4907 fprintf (file, "%d", alpha_this_literal_sequence_number);
4911 if (alpha_this_gpdisp_sequence_number == 0)
4912 alpha_this_gpdisp_sequence_number = alpha_next_sequence_number++;
4913 fprintf (file, "%d", alpha_this_gpdisp_sequence_number);
4917 if (GET_CODE (x) == HIGH)
4918 output_addr_const (file, XEXP (x, 0));
4920 output_operand_lossage ("invalid %%H value");
4924 /* If this operand is the constant zero, write it as "$31". */
4925 if (GET_CODE (x) == REG)
4926 fprintf (file, "%s", reg_names[REGNO (x)]);
4927 else if (x == CONST0_RTX (GET_MODE (x)))
4928 fprintf (file, "$31");
4930 output_operand_lossage ("invalid %%r value");
4934 /* Similar, but for floating-point. */
4935 if (GET_CODE (x) == REG)
4936 fprintf (file, "%s", reg_names[REGNO (x)]);
4937 else if (x == CONST0_RTX (GET_MODE (x)))
4938 fprintf (file, "$f31");
4940 output_operand_lossage ("invalid %%R value");
4944 /* Write the 1's complement of a constant. */
4945 if (GET_CODE (x) != CONST_INT)
4946 output_operand_lossage ("invalid %%N value");
4948 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
4952 /* Write 1 << C, for a constant C. */
4953 if (GET_CODE (x) != CONST_INT)
4954 output_operand_lossage ("invalid %%P value");
4956 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
4960 /* Write the high-order 16 bits of a constant, sign-extended. */
4961 if (GET_CODE (x) != CONST_INT)
4962 output_operand_lossage ("invalid %%h value");
4964 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
4968 /* Write the low-order 16 bits of a constant, sign-extended. */
4969 if (GET_CODE (x) != CONST_INT)
4970 output_operand_lossage ("invalid %%L value");
4972 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4973 (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
4977 /* Write mask for ZAP insn. */
4978 if (GET_CODE (x) == CONST_DOUBLE)
4980 HOST_WIDE_INT mask = 0;
4981 HOST_WIDE_INT value;
4983 value = CONST_DOUBLE_LOW (x);
4984 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
4989 value = CONST_DOUBLE_HIGH (x);
4990 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
4993 mask |= (1 << (i + sizeof (int)));
4995 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
4998 else if (GET_CODE (x) == CONST_INT)
5000 HOST_WIDE_INT mask = 0, value = INTVAL (x);
5002 for (i = 0; i < 8; i++, value >>= 8)
5006 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
5009 output_operand_lossage ("invalid %%m value");
5013 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
5014 if (GET_CODE (x) != CONST_INT
5015 || (INTVAL (x) != 8 && INTVAL (x) != 16
5016 && INTVAL (x) != 32 && INTVAL (x) != 64))
5017 output_operand_lossage ("invalid %%M value");
5019 fprintf (file, "%s",
5020 (INTVAL (x) == 8 ? "b"
5021 : INTVAL (x) == 16 ? "w"
5022 : INTVAL (x) == 32 ? "l"
5027 /* Similar, except do it from the mask. */
5028 if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
5029 fprintf (file, "b");
5030 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
5031 fprintf (file, "w");
5032 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
5033 fprintf (file, "l");
5034 #if HOST_BITS_PER_WIDE_INT == 32
5035 else if (GET_CODE (x) == CONST_DOUBLE
5036 && CONST_DOUBLE_HIGH (x) == 0
5037 && CONST_DOUBLE_LOW (x) == -1)
5038 fprintf (file, "l");
5039 else if (GET_CODE (x) == CONST_DOUBLE
5040 && CONST_DOUBLE_HIGH (x) == -1
5041 && CONST_DOUBLE_LOW (x) == -1)
5042 fprintf (file, "q");
5044 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == -1)
5045 fprintf (file, "q");
5046 else if (GET_CODE (x) == CONST_DOUBLE
5047 && CONST_DOUBLE_HIGH (x) == 0
5048 && CONST_DOUBLE_LOW (x) == -1)
5049 fprintf (file, "q");
5052 output_operand_lossage ("invalid %%U value");
5056 /* Write the constant value divided by 8 for little-endian mode or
5057 (56 - value) / 8 for big-endian mode. */
5059 if (GET_CODE (x) != CONST_INT
5060 || (unsigned HOST_WIDE_INT) INTVAL (x) >= (WORDS_BIG_ENDIAN
5063 || (INTVAL (x) & 7) != 0)
5064 output_operand_lossage ("invalid %%s value");
5066 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
5068 ? (56 - INTVAL (x)) / 8
5073 /* Same, except compute (64 - c) / 8 */
5075 if (GET_CODE (x) != CONST_INT
5076 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
5077 && (INTVAL (x) & 7) != 8)
5078 output_operand_lossage ("invalid %%s value");
5080 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
5085 /* On Unicos/Mk systems: use a DEX expression if the symbol
5086 clashes with a register name. */
5087 int dex = unicosmk_need_dex (x);
5089 fprintf (file, "DEX(%d)", dex);
5091 output_addr_const (file, x);
5095 case 'C': case 'D': case 'c': case 'd':
5096 /* Write out comparison name. */
5098 enum rtx_code c = GET_CODE (x);
5100 if (GET_RTX_CLASS (c) != '<')
5101 output_operand_lossage ("invalid %%C value");
5103 else if (code == 'D')
5104 c = reverse_condition (c);
5105 else if (code == 'c')
5106 c = swap_condition (c);
5107 else if (code == 'd')
5108 c = swap_condition (reverse_condition (c));
5111 fprintf (file, "ule");
5113 fprintf (file, "ult");
5114 else if (c == UNORDERED)
5115 fprintf (file, "un");
5117 fprintf (file, "%s", GET_RTX_NAME (c));
5122 /* Write the divide or modulus operator. */
5123 switch (GET_CODE (x))
5126 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
5129 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
5132 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
5135 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
5138 output_operand_lossage ("invalid %%E value");
5144 /* Write "_u" for unaligned access. */
5145 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
5146 fprintf (file, "_u");
5150 if (GET_CODE (x) == REG)
5151 fprintf (file, "%s", reg_names[REGNO (x)]);
5152 else if (GET_CODE (x) == MEM)
5153 output_address (XEXP (x, 0));
5155 output_addr_const (file, x);
5159 output_operand_lossage ("invalid %%xn code");
5164 print_operand_address (file, addr)
5169 HOST_WIDE_INT offset = 0;
5171 if (GET_CODE (addr) == AND)
5172 addr = XEXP (addr, 0);
5174 if (GET_CODE (addr) == PLUS
5175 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
5177 offset = INTVAL (XEXP (addr, 1));
5178 addr = XEXP (addr, 0);
5181 if (GET_CODE (addr) == LO_SUM)
5183 output_addr_const (file, XEXP (addr, 1));
5187 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
5190 addr = XEXP (addr, 0);
5191 if (GET_CODE (addr) == REG)
5192 basereg = REGNO (addr);
5193 else if (GET_CODE (addr) == SUBREG
5194 && GET_CODE (SUBREG_REG (addr)) == REG)
5195 basereg = subreg_regno (addr);
5199 fprintf (file, "($%d)\t\t!%s", basereg,
5200 (basereg == 29 ? "gprel" : "gprellow"));
5204 if (GET_CODE (addr) == REG)
5205 basereg = REGNO (addr);
5206 else if (GET_CODE (addr) == SUBREG
5207 && GET_CODE (SUBREG_REG (addr)) == REG)
5208 basereg = subreg_regno (addr);
5209 else if (GET_CODE (addr) == CONST_INT)
5210 offset = INTVAL (addr);
5214 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
5215 fprintf (file, "($%d)", basereg);
5218 /* Emit RTL insns to initialize the variable parts of a trampoline at
5219 TRAMP. FNADDR is an RTX for the address of the function's pure
5220 code. CXT is an RTX for the static chain value for the function.
5222 The three offset parameters are for the individual template's
5223 layout. A JMPOFS < 0 indicates that the trampoline does not
5224 contain instructions at all.
5226 We assume here that a function will be called many more times than
5227 its address is taken (e.g., it might be passed to qsort), so we
5228 take the trouble to initialize the "hint" field in the JMP insn.
5229 Note that the hint field is PC (new) + 4 * bits 13:0. */
5232 alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs)
5233 rtx tramp, fnaddr, cxt;
5234 int fnofs, cxtofs, jmpofs;
5236 rtx temp, temp1, addr;
5237 /* VMS really uses DImode pointers in memory at this point. */
5238 enum machine_mode mode = TARGET_ABI_OPEN_VMS ? Pmode : ptr_mode;
5240 #ifdef POINTERS_EXTEND_UNSIGNED
5241 fnaddr = convert_memory_address (mode, fnaddr);
5242 cxt = convert_memory_address (mode, cxt);
5245 /* Store function address and CXT. */
5246 addr = memory_address (mode, plus_constant (tramp, fnofs));
5247 emit_move_insn (gen_rtx_MEM (mode, addr), fnaddr);
5248 addr = memory_address (mode, plus_constant (tramp, cxtofs));
5249 emit_move_insn (gen_rtx_MEM (mode, addr), cxt);
5251 /* This has been disabled since the hint only has a 32k range, and in
5252 no existing OS is the stack within 32k of the text segment. */
5253 if (0 && jmpofs >= 0)
5255 /* Compute hint value. */
5256 temp = force_operand (plus_constant (tramp, jmpofs+4), NULL_RTX);
5257 temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1,
5259 temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
5260 build_int_2 (2, 0), NULL_RTX, 1);
5261 temp = expand_and (gen_lowpart (SImode, temp), GEN_INT (0x3fff), 0);
5263 /* Merge in the hint. */
5264 addr = memory_address (SImode, plus_constant (tramp, jmpofs));
5265 temp1 = force_reg (SImode, gen_rtx_MEM (SImode, addr));
5266 temp1 = expand_and (temp1, GEN_INT (0xffffc000), NULL_RTX);
5267 temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1,
5269 emit_move_insn (gen_rtx_MEM (SImode, addr), temp1);
5272 #ifdef TRANSFER_FROM_TRAMPOLINE
5273 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
5274 0, VOIDmode, 1, addr, Pmode);
5278 emit_insn (gen_imb ());
5281 /* Determine where to put an argument to a function.
5282 Value is zero to push the argument on the stack,
5283 or a hard register in which to store the argument.
5285 MODE is the argument's machine mode.
5286 TYPE is the data type of the argument (as a tree).
5287 This is null for libcalls where that information may
5289 CUM is a variable of type CUMULATIVE_ARGS which gives info about
5290 the preceding args and about the function being called.
5291 NAMED is nonzero if this argument is a named parameter
5292 (otherwise it is an extra parameter matching an ellipsis).
5294 On Alpha the first 6 words of args are normally in registers
5295 and the rest are pushed. */
5298 function_arg (cum, mode, type, named)
5299 CUMULATIVE_ARGS cum;
5300 enum machine_mode mode;
5302 int named ATTRIBUTE_UNUSED;
5307 /* Set up defaults for FP operands passed in FP registers, and
5308 integral operands passed in integer registers. */
5310 && (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
5311 || GET_MODE_CLASS (mode) == MODE_FLOAT))
5316 /* ??? Irritatingly, the definition of CUMULATIVE_ARGS is different for
5317 the three platforms, so we can't avoid conditional compilation. */
5318 #if TARGET_ABI_OPEN_VMS
5320 if (mode == VOIDmode)
5321 return alpha_arg_info_reg_val (cum);
5323 num_args = cum.num_args;
5324 if (num_args >= 6 || MUST_PASS_IN_STACK (mode, type))
5328 #if TARGET_ABI_UNICOSMK
5332 /* If this is the last argument, generate the call info word (CIW). */
5333 /* ??? We don't include the caller's line number in the CIW because
5334 I don't know how to determine it if debug infos are turned off. */
5335 if (mode == VOIDmode)
5344 for (i = 0; i < cum.num_reg_words && i < 5; i++)
5345 if (cum.reg_args_type[i])
5346 lo |= (1 << (7 - i));
5348 if (cum.num_reg_words == 6 && cum.reg_args_type[5])
5351 lo |= cum.num_reg_words;
5353 #if HOST_BITS_PER_WIDE_INT == 32
5354 hi = (cum.num_args << 20) | cum.num_arg_words;
5356 lo = lo | (cum.num_args << 52) | (cum.num_arg_words << 32);
5359 ciw = immed_double_const (lo, hi, DImode);
5361 return gen_rtx_UNSPEC (DImode, gen_rtvec (1, ciw),
5362 UNSPEC_UMK_LOAD_CIW);
5365 size = ALPHA_ARG_SIZE (mode, type, named);
5366 num_args = cum.num_reg_words;
5367 if (MUST_PASS_IN_STACK (mode, type)
5368 || cum.num_reg_words + size > 6 || cum.force_stack)
5370 else if (type && TYPE_MODE (type) == BLKmode)
5374 reg1 = gen_rtx_REG (DImode, num_args + 16);
5375 reg1 = gen_rtx_EXPR_LIST (DImode, reg1, const0_rtx);
5377 /* The argument fits in two registers. Note that we still need to
5378 reserve a register for empty structures. */
5382 return gen_rtx_PARALLEL (mode, gen_rtvec (1, reg1));
5385 reg2 = gen_rtx_REG (DImode, num_args + 17);
5386 reg2 = gen_rtx_EXPR_LIST (DImode, reg2, GEN_INT (8));
5387 return gen_rtx_PARALLEL (mode, gen_rtvec (2, reg1, reg2));
5397 /* VOID is passed as a special flag for "last argument". */
5398 if (type == void_type_node)
5400 else if (MUST_PASS_IN_STACK (mode, type))
5402 else if (FUNCTION_ARG_PASS_BY_REFERENCE (cum, mode, type, named))
5405 #endif /* TARGET_ABI_UNICOSMK */
5406 #endif /* TARGET_ABI_OPEN_VMS */
5408 return gen_rtx_REG (mode, num_args + basereg);
5412 alpha_build_va_list ()
5414 tree base, ofs, record, type_decl;
5416 if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK)
5417 return ptr_type_node;
5419 record = make_lang_type (RECORD_TYPE);
5420 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
5421 TREE_CHAIN (record) = type_decl;
5422 TYPE_NAME (record) = type_decl;
5424 /* C++? SET_IS_AGGR_TYPE (record, 1); */
5426 ofs = build_decl (FIELD_DECL, get_identifier ("__offset"),
5428 DECL_FIELD_CONTEXT (ofs) = record;
5430 base = build_decl (FIELD_DECL, get_identifier ("__base"),
5432 DECL_FIELD_CONTEXT (base) = record;
5433 TREE_CHAIN (base) = ofs;
5435 TYPE_FIELDS (record) = base;
5436 layout_type (record);
5442 alpha_va_start (stdarg_p, valist, nextarg)
5445 rtx nextarg ATTRIBUTE_UNUSED;
5447 HOST_WIDE_INT offset;
5448 tree t, offset_field, base_field;
5450 if (TREE_CODE (TREE_TYPE (valist)) == ERROR_MARK)
5453 if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK)
5454 std_expand_builtin_va_start (stdarg_p, valist, nextarg);
5456 /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base
5457 up by 48, storing fp arg registers in the first 48 bytes, and the
5458 integer arg registers in the next 48 bytes. This is only done,
5459 however, if any integer registers need to be stored.
5461 If no integer registers need be stored, then we must subtract 48
5462 in order to account for the integer arg registers which are counted
5463 in argsize above, but which are not actually stored on the stack. */
5465 if (NUM_ARGS <= 5 + stdarg_p)
5466 offset = 6 * UNITS_PER_WORD;
5468 offset = -6 * UNITS_PER_WORD;
5470 base_field = TYPE_FIELDS (TREE_TYPE (valist));
5471 offset_field = TREE_CHAIN (base_field);
5473 base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
5474 valist, base_field);
5475 offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
5476 valist, offset_field);
5478 t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
5479 t = build (PLUS_EXPR, ptr_type_node, t, build_int_2 (offset, 0));
5480 t = build (MODIFY_EXPR, TREE_TYPE (base_field), base_field, t);
5481 TREE_SIDE_EFFECTS (t) = 1;
5482 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5484 t = build_int_2 (NUM_ARGS*UNITS_PER_WORD, 0);
5485 t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field, t);
5486 TREE_SIDE_EFFECTS (t) = 1;
5487 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5491 alpha_va_arg (valist, type)
5494 HOST_WIDE_INT tsize;
5497 tree offset_field, base_field, addr_tree, addend;
5498 tree wide_type, wide_ofs;
5501 if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK)
5502 return std_expand_builtin_va_arg (valist, type);
5504 tsize = ((TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT + 7) / 8) * 8;
5506 base_field = TYPE_FIELDS (TREE_TYPE (valist));
5507 offset_field = TREE_CHAIN (base_field);
5509 base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
5510 valist, base_field);
5511 offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
5512 valist, offset_field);
5514 wide_type = make_signed_type (64);
5515 wide_ofs = save_expr (build1 (CONVERT_EXPR, wide_type, offset_field));
5519 if (TYPE_MODE (type) == TFmode || TYPE_MODE (type) == TCmode)
5522 tsize = UNITS_PER_WORD;
5524 else if (FLOAT_TYPE_P (type))
5526 tree fpaddend, cond;
5528 fpaddend = fold (build (PLUS_EXPR, TREE_TYPE (addend),
5529 addend, build_int_2 (-6*8, 0)));
5531 cond = fold (build (LT_EXPR, integer_type_node,
5532 wide_ofs, build_int_2 (6*8, 0)));
5534 addend = fold (build (COND_EXPR, TREE_TYPE (addend), cond,
5538 addr_tree = build (PLUS_EXPR, TREE_TYPE (base_field),
5539 base_field, addend);
5541 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
5542 addr = copy_to_reg (addr);
5544 t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field,
5545 build (PLUS_EXPR, TREE_TYPE (offset_field),
5546 offset_field, build_int_2 (tsize, 0)));
5547 TREE_SIDE_EFFECTS (t) = 1;
5548 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5552 addr = force_reg (Pmode, addr);
5553 addr = gen_rtx_MEM (Pmode, addr);
5559 /* This page contains routines that are used to determine what the function
5560 prologue and epilogue code will do and write them out. */
5562 /* Compute the size of the save area in the stack. */
5564 /* These variables are used for communication between the following functions.
5565 They indicate various things about the current function being compiled
5566 that are used to tell what kind of prologue, epilogue and procedure
5567 descriptior to generate. */
5569 /* Nonzero if we need a stack procedure. */
5570 static int alpha_is_stack_procedure;
5572 /* Register number (either FP or SP) that is used to unwind the frame. */
5573 static int vms_unwind_regno;
5575 /* Register number used to save FP. We need not have one for RA since
5576 we don't modify it for register procedures. This is only defined
5577 for register frame procedures. */
5578 static int vms_save_fp_regno;
5580 /* Register number used to reference objects off our PV. */
5581 static int vms_base_regno;
5583 /* Compute register masks for saved registers. */
5586 alpha_sa_mask (imaskP, fmaskP)
5587 unsigned long *imaskP;
5588 unsigned long *fmaskP;
5590 unsigned long imask = 0;
5591 unsigned long fmask = 0;
5594 #ifdef ASM_OUTPUT_MI_THUNK
5595 if (!current_function_is_thunk)
5598 if (TARGET_ABI_OPEN_VMS && alpha_is_stack_procedure)
5599 imask |= (1L << HARD_FRAME_POINTER_REGNUM);
5601 /* One for every register we have to save. */
5602 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
5603 if (! fixed_regs[i] && ! call_used_regs[i]
5604 && regs_ever_live[i] && i != REG_RA
5605 && (!TARGET_ABI_UNICOSMK || i != HARD_FRAME_POINTER_REGNUM))
5610 fmask |= (1L << (i - 32));
5613 /* We need to restore these for the handler. */
5614 if (current_function_calls_eh_return)
5618 unsigned regno = EH_RETURN_DATA_REGNO (i);
5619 if (regno == INVALID_REGNUM)
5621 imask |= 1L << regno;
5625 if (!TARGET_ABI_UNICOSMK)
5627 /* If any register spilled, then spill the return address also. */
5628 /* ??? This is required by the Digital stack unwind specification
5629 and isn't needed if we're doing Dwarf2 unwinding. */
5630 if (imask || fmask || alpha_ra_ever_killed ())
5631 imask |= (1L << REG_RA);
5645 #ifdef ASM_OUTPUT_MI_THUNK
5646 if (current_function_is_thunk)
5651 if (TARGET_ABI_UNICOSMK)
5653 for (i = 9; i < 15 && sa_size == 0; i++)
5654 if (! fixed_regs[i] && ! call_used_regs[i]
5655 && regs_ever_live[i])
5657 for (i = 32 + 2; i < 32 + 10 && sa_size == 0; i++)
5658 if (! fixed_regs[i] && ! call_used_regs[i]
5659 && regs_ever_live[i])
5664 /* One for every register we have to save. */
5665 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
5666 if (! fixed_regs[i] && ! call_used_regs[i]
5667 && regs_ever_live[i] && i != REG_RA)
5672 if (TARGET_ABI_UNICOSMK)
5674 /* We might not need to generate a frame if we don't make any calls
5675 (including calls to __T3E_MISMATCH if this is a vararg function),
5676 don't have any local variables which require stack slots, don't
5677 use alloca and have not determined that we need a frame for other
5680 alpha_is_stack_procedure = sa_size != 0
5681 || alpha_ra_ever_killed ()
5682 || get_frame_size() != 0
5683 || current_function_outgoing_args_size
5684 || current_function_varargs
5685 || current_function_stdarg
5686 || current_function_calls_alloca
5687 || frame_pointer_needed;
5689 /* Always reserve space for saving callee-saved registers if we
5690 need a frame as required by the calling convention. */
5691 if (alpha_is_stack_procedure)
5694 else if (TARGET_ABI_OPEN_VMS)
5696 /* Start by assuming we can use a register procedure if we don't
5697 make any calls (REG_RA not used) or need to save any
5698 registers and a stack procedure if we do. */
5699 alpha_is_stack_procedure = sa_size != 0 || alpha_ra_ever_killed ();
5701 /* Decide whether to refer to objects off our PV via FP or PV.
5702 If we need FP for something else or if we receive a nonlocal
5703 goto (which expects PV to contain the value), we must use PV.
5704 Otherwise, start by assuming we can use FP. */
5705 vms_base_regno = (frame_pointer_needed
5706 || current_function_has_nonlocal_label
5707 || alpha_is_stack_procedure
5708 || current_function_outgoing_args_size
5709 ? REG_PV : HARD_FRAME_POINTER_REGNUM);
5711 /* If we want to copy PV into FP, we need to find some register
5712 in which to save FP. */
5714 vms_save_fp_regno = -1;
5715 if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
5716 for (i = 0; i < 32; i++)
5717 if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
5718 vms_save_fp_regno = i;
5720 if (vms_save_fp_regno == -1)
5721 vms_base_regno = REG_PV, alpha_is_stack_procedure = 1;
5723 /* Stack unwinding should be done via FP unless we use it for PV. */
5724 vms_unwind_regno = (vms_base_regno == REG_PV
5725 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
5727 /* If this is a stack procedure, allow space for saving FP and RA. */
5728 if (alpha_is_stack_procedure)
5733 /* If some registers were saved but not RA, RA must also be saved,
5734 so leave space for it. */
5735 if (!TARGET_ABI_UNICOSMK && (sa_size != 0 || alpha_ra_ever_killed ()))
5738 /* Our size must be even (multiple of 16 bytes). */
5747 alpha_pv_save_size ()
5750 return alpha_is_stack_procedure ? 8 : 0;
5757 return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM;
5760 #if TARGET_ABI_OPEN_VMS
5762 const struct attribute_spec vms_attribute_table[] =
5764 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
5765 { "overlaid", 0, 0, true, false, false, NULL },
5766 { NULL, 0, 0, false, false, false, NULL }
5772 find_lo_sum (px, data)
5774 void *data ATTRIBUTE_UNUSED;
5776 return GET_CODE (*px) == LO_SUM;
5780 alpha_does_function_need_gp ()
5784 /* The GP being variable is an OSF abi thing. */
5785 if (! TARGET_ABI_OSF)
5788 if (TARGET_PROFILING_NEEDS_GP && profile_flag)
5791 #ifdef ASM_OUTPUT_MI_THUNK
5792 if (current_function_is_thunk)
5796 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
5797 Even if we are a static function, we still need to do this in case
5798 our address is taken and passed to something like qsort. */
5800 push_topmost_sequence ();
5801 insn = get_insns ();
5802 pop_topmost_sequence ();
5804 for (; insn; insn = NEXT_INSN (insn))
5806 && GET_CODE (PATTERN (insn)) != USE
5807 && GET_CODE (PATTERN (insn)) != CLOBBER)
5809 enum attr_type type = get_attr_type (insn);
5810 if (type == TYPE_LDSYM || type == TYPE_JSR)
5812 if (TARGET_EXPLICIT_RELOCS
5813 && for_each_rtx (&PATTERN (insn), find_lo_sum, NULL) > 0)
5820 /* Write a version stamp. Don't write anything if we are running as a
5821 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
5828 alpha_write_verstamp (file)
5829 FILE *file ATTRIBUTE_UNUSED;
5832 fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
5836 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
5840 set_frame_related_p ()
5842 rtx seq = gen_sequence ();
5845 if (GET_CODE (seq) == SEQUENCE)
5847 int i = XVECLEN (seq, 0);
5849 RTX_FRAME_RELATED_P (XVECEXP (seq, 0, i)) = 1;
5850 return emit_insn (seq);
5854 seq = emit_insn (seq);
5855 RTX_FRAME_RELATED_P (seq) = 1;
5860 #define FRP(exp) (start_sequence (), exp, set_frame_related_p ())
5862 /* Write function prologue. */
5864 /* On vms we have two kinds of functions:
5866 - stack frame (PROC_STACK)
5867 these are 'normal' functions with local vars and which are
5868 calling other functions
5869 - register frame (PROC_REGISTER)
5870 keeps all data in registers, needs no stack
5872 We must pass this to the assembler so it can generate the
5873 proper pdsc (procedure descriptor)
5874 This is done with the '.pdesc' command.
5876 On not-vms, we don't really differentiate between the two, as we can
5877 simply allocate stack without saving registers. */
5880 alpha_expand_prologue ()
5882 /* Registers to save. */
5883 unsigned long imask = 0;
5884 unsigned long fmask = 0;
5885 /* Stack space needed for pushing registers clobbered by us. */
5886 HOST_WIDE_INT sa_size;
5887 /* Complete stack size needed. */
5888 HOST_WIDE_INT frame_size;
5889 /* Offset from base reg to register save area. */
5890 HOST_WIDE_INT reg_offset;
5894 sa_size = alpha_sa_size ();
5896 frame_size = get_frame_size ();
5897 if (TARGET_ABI_OPEN_VMS)
5898 frame_size = ALPHA_ROUND (sa_size
5899 + (alpha_is_stack_procedure ? 8 : 0)
5901 + current_function_pretend_args_size);
5902 else if (TARGET_ABI_UNICOSMK)
5903 /* We have to allocate space for the DSIB if we generate a frame. */
5904 frame_size = ALPHA_ROUND (sa_size
5905 + (alpha_is_stack_procedure ? 48 : 0))
5906 + ALPHA_ROUND (frame_size
5907 + current_function_outgoing_args_size);
5909 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
5911 + ALPHA_ROUND (frame_size
5912 + current_function_pretend_args_size));
5914 if (TARGET_ABI_OPEN_VMS)
5917 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
5919 alpha_sa_mask (&imask, &fmask);
5921 /* Emit an insn to reload GP, if needed. */
5924 alpha_function_needs_gp = alpha_does_function_need_gp ();
5925 if (alpha_function_needs_gp)
5926 emit_insn (gen_prologue_ldgp ());
5929 /* TARGET_PROFILING_NEEDS_GP actually implies that we need to insert
5930 the call to mcount ourselves, rather than having the linker do it
5931 magically in response to -pg. Since _mcount has special linkage,
5932 don't represent the call as a call. */
5933 if (TARGET_PROFILING_NEEDS_GP && profile_flag)
5934 emit_insn (gen_prologue_mcount ());
5936 if (TARGET_ABI_UNICOSMK)
5937 unicosmk_gen_dsib (&imask);
5939 /* Adjust the stack by the frame size. If the frame size is > 4096
5940 bytes, we need to be sure we probe somewhere in the first and last
5941 4096 bytes (we can probably get away without the latter test) and
5942 every 8192 bytes in between. If the frame size is > 32768, we
5943 do this in a loop. Otherwise, we generate the explicit probe
5946 Note that we are only allowed to adjust sp once in the prologue. */
5948 if (frame_size <= 32768)
5950 if (frame_size > 4096)
5955 emit_insn (gen_probe_stack (GEN_INT (TARGET_ABI_UNICOSMK
5958 while ((probed += 8192) < frame_size);
5960 /* We only have to do this probe if we aren't saving registers. */
5961 if (sa_size == 0 && probed + 4096 < frame_size)
5962 emit_insn (gen_probe_stack (GEN_INT (-frame_size)));
5965 if (frame_size != 0)
5966 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
5967 GEN_INT (TARGET_ABI_UNICOSMK
5973 /* Here we generate code to set R22 to SP + 4096 and set R23 to the
5974 number of 8192 byte blocks to probe. We then probe each block
5975 in the loop and then set SP to the proper location. If the
5976 amount remaining is > 4096, we have to do one more probe if we
5977 are not saving any registers. */
5979 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
5980 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
5981 rtx ptr = gen_rtx_REG (DImode, 22);
5982 rtx count = gen_rtx_REG (DImode, 23);
5985 emit_move_insn (count, GEN_INT (blocks));
5986 emit_insn (gen_adddi3 (ptr, stack_pointer_rtx,
5987 GEN_INT (TARGET_ABI_UNICOSMK ? 4096 - 64 : 4096)));
5989 /* Because of the difficulty in emitting a new basic block this
5990 late in the compilation, generate the loop as a single insn. */
5991 emit_insn (gen_prologue_stack_probe_loop (count, ptr));
5993 if (leftover > 4096 && sa_size == 0)
5995 rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover));
5996 MEM_VOLATILE_P (last) = 1;
5997 emit_move_insn (last, const0_rtx);
6000 if (TARGET_ABI_WINDOWS_NT)
6002 /* For NT stack unwind (done by 'reverse execution'), it's
6003 not OK to take the result of a loop, even though the value
6004 is already in ptr, so we reload it via a single operation
6005 and subtract it to sp.
6007 Yes, that's correct -- we have to reload the whole constant
6008 into a temporary via ldah+lda then subtract from sp. To
6009 ensure we get ldah+lda, we use a special pattern. */
6011 HOST_WIDE_INT lo, hi;
6012 lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
6013 hi = frame_size - lo;
6015 emit_move_insn (ptr, GEN_INT (hi));
6016 emit_insn (gen_nt_lda (ptr, GEN_INT (lo)));
6017 seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
6022 seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr,
6023 GEN_INT (-leftover)));
6026 /* This alternative is special, because the DWARF code cannot
6027 possibly intuit through the loop above. So we invent this
6028 note it looks at instead. */
6029 RTX_FRAME_RELATED_P (seq) = 1;
6031 = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
6032 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
6033 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
6034 GEN_INT (TARGET_ABI_UNICOSMK
6040 if (!TARGET_ABI_UNICOSMK)
6042 /* Cope with very large offsets to the register save area. */
6043 sa_reg = stack_pointer_rtx;
6044 if (reg_offset + sa_size > 0x8000)
6046 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
6049 if (low + sa_size <= 0x8000)
6050 bias = reg_offset - low, reg_offset = low;
6052 bias = reg_offset, reg_offset = 0;
6054 sa_reg = gen_rtx_REG (DImode, 24);
6055 FRP (emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx,
6059 /* Save regs in stack order. Beginning with VMS PV. */
6060 if (TARGET_ABI_OPEN_VMS && alpha_is_stack_procedure)
6062 mem = gen_rtx_MEM (DImode, stack_pointer_rtx);
6063 set_mem_alias_set (mem, alpha_sr_alias_set);
6064 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_PV)));
6067 /* Save register RA next. */
6068 if (imask & (1L << REG_RA))
6070 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
6071 set_mem_alias_set (mem, alpha_sr_alias_set);
6072 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
6073 imask &= ~(1L << REG_RA);
6077 /* Now save any other registers required to be saved. */
6078 for (i = 0; i < 32; i++)
6079 if (imask & (1L << i))
6081 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
6082 set_mem_alias_set (mem, alpha_sr_alias_set);
6083 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, i)));
6087 for (i = 0; i < 32; i++)
6088 if (fmask & (1L << i))
6090 mem = gen_rtx_MEM (DFmode, plus_constant (sa_reg, reg_offset));
6091 set_mem_alias_set (mem, alpha_sr_alias_set);
6092 FRP (emit_move_insn (mem, gen_rtx_REG (DFmode, i+32)));
6096 else if (TARGET_ABI_UNICOSMK && alpha_is_stack_procedure)
6098 /* The standard frame on the T3E includes space for saving registers.
6099 We just have to use it. We don't have to save the return address and
6100 the old frame pointer here - they are saved in the DSIB. */
6103 for (i = 9; i < 15; i++)
6104 if (imask & (1L << i))
6106 mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx,
6108 set_mem_alias_set (mem, alpha_sr_alias_set);
6109 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, i)));
6112 for (i = 2; i < 10; i++)
6113 if (fmask & (1L << i))
6115 mem = gen_rtx_MEM (DFmode, plus_constant (hard_frame_pointer_rtx,
6117 set_mem_alias_set (mem, alpha_sr_alias_set);
6118 FRP (emit_move_insn (mem, gen_rtx_REG (DFmode, i+32)));
6123 if (TARGET_ABI_OPEN_VMS)
6125 if (!alpha_is_stack_procedure)
6126 /* Register frame procedures save the fp. */
6127 /* ??? Ought to have a dwarf2 save for this. */
6128 emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
6129 hard_frame_pointer_rtx);
6131 if (vms_base_regno != REG_PV)
6132 emit_insn (gen_force_movdi (gen_rtx_REG (DImode, vms_base_regno),
6133 gen_rtx_REG (DImode, REG_PV)));
6135 if (vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
6136 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
6138 /* If we have to allocate space for outgoing args, do it now. */
6139 if (current_function_outgoing_args_size != 0)
6142 plus_constant (hard_frame_pointer_rtx,
6144 (current_function_outgoing_args_size)))));
6146 else if (!TARGET_ABI_UNICOSMK)
6148 /* If we need a frame pointer, set it from the stack pointer. */
6149 if (frame_pointer_needed)
6151 if (TARGET_CAN_FAULT_IN_PROLOGUE)
6152 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
6154 /* This must always be the last instruction in the
6155 prologue, thus we emit a special move + clobber. */
6156 FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx,
6157 stack_pointer_rtx, sa_reg)));
6161 /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
6162 the prologue, for exception handling reasons, we cannot do this for
6163 any insn that might fault. We could prevent this for mems with a
6164 (clobber:BLK (scratch)), but this doesn't work for fp insns. So we
6165 have to prevent all such scheduling with a blockage.
6167 Linux, on the other hand, never bothered to implement OSF/1's
6168 exception handling, and so doesn't care about such things. Anyone
6169 planning to use dwarf2 frame-unwind info can also omit the blockage. */
6171 if (! TARGET_CAN_FAULT_IN_PROLOGUE)
6172 emit_insn (gen_blockage ());
6175 /* Output the textual info surrounding the prologue. */
6178 alpha_start_function (file, fnname, decl)
6181 tree decl ATTRIBUTE_UNUSED;
6183 unsigned long imask = 0;
6184 unsigned long fmask = 0;
6185 /* Stack space needed for pushing registers clobbered by us. */
6186 HOST_WIDE_INT sa_size;
6187 /* Complete stack size needed. */
6188 HOST_WIDE_INT frame_size;
6189 /* Offset from base reg to register save area. */
6190 HOST_WIDE_INT reg_offset;
6191 char *entry_label = (char *) alloca (strlen (fnname) + 6);
6194 /* Don't emit an extern directive for functions defined in the same file. */
6195 if (TARGET_ABI_UNICOSMK)
6198 name_tree = get_identifier (fnname);
6199 TREE_ASM_WRITTEN (name_tree) = 1;
6202 alpha_fnname = fnname;
6203 sa_size = alpha_sa_size ();
6205 frame_size = get_frame_size ();
6206 if (TARGET_ABI_OPEN_VMS)
6207 frame_size = ALPHA_ROUND (sa_size
6208 + (alpha_is_stack_procedure ? 8 : 0)
6210 + current_function_pretend_args_size);
6211 else if (TARGET_ABI_UNICOSMK)
6212 frame_size = ALPHA_ROUND (sa_size
6213 + (alpha_is_stack_procedure ? 48 : 0))
6214 + ALPHA_ROUND (frame_size
6215 + current_function_outgoing_args_size);
6217 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
6219 + ALPHA_ROUND (frame_size
6220 + current_function_pretend_args_size));
6222 if (TARGET_ABI_OPEN_VMS)
6225 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
6227 alpha_sa_mask (&imask, &fmask);
6229 /* Ecoff can handle multiple .file directives, so put out file and lineno.
6230 We have to do that before the .ent directive as we cannot switch
6231 files within procedures with native ecoff because line numbers are
6232 linked to procedure descriptors.
6233 Outputting the lineno helps debugging of one line functions as they
6234 would otherwise get no line number at all. Please note that we would
6235 like to put out last_linenum from final.c, but it is not accessible. */
6237 if (write_symbols == SDB_DEBUG)
6239 #ifdef ASM_OUTPUT_SOURCE_FILENAME
6240 ASM_OUTPUT_SOURCE_FILENAME (file,
6241 DECL_SOURCE_FILE (current_function_decl));
6243 #ifdef ASM_OUTPUT_SOURCE_LINE
6244 if (debug_info_level != DINFO_LEVEL_TERSE)
6245 ASM_OUTPUT_SOURCE_LINE (file,
6246 DECL_SOURCE_LINE (current_function_decl));
6250 /* Issue function start and label. */
6251 if (TARGET_ABI_OPEN_VMS
6252 || (!TARGET_ABI_UNICOSMK && !flag_inhibit_size_directive))
6254 fputs ("\t.ent ", file);
6255 assemble_name (file, fnname);
6258 /* If the function needs GP, we'll write the "..ng" label there.
6259 Otherwise, do it here. */
6260 if (TARGET_ABI_OSF && ! alpha_function_needs_gp)
6263 assemble_name (file, fnname);
6264 fputs ("..ng:\n", file);
6268 strcpy (entry_label, fnname);
6269 if (TARGET_ABI_OPEN_VMS)
6270 strcat (entry_label, "..en");
6272 /* For public functions, the label must be globalized by appending an
6273 additional colon. */
6274 if (TARGET_ABI_UNICOSMK && TREE_PUBLIC (decl))
6275 strcat (entry_label, ":");
6277 ASM_OUTPUT_LABEL (file, entry_label);
6278 inside_function = TRUE;
6280 if (TARGET_ABI_OPEN_VMS)
6281 fprintf (file, "\t.base $%d\n", vms_base_regno);
6283 if (!TARGET_ABI_OPEN_VMS && !TARGET_ABI_UNICOSMK && TARGET_IEEE_CONFORMANT
6284 && !flag_inhibit_size_directive)
6286 /* Set flags in procedure descriptor to request IEEE-conformant
6287 math-library routines. The value we set it to is PDSC_EXC_IEEE
6288 (/usr/include/pdsc.h). */
6289 fputs ("\t.eflag 48\n", file);
6292 /* Set up offsets to alpha virtual arg/local debugging pointer. */
6293 alpha_auto_offset = -frame_size + current_function_pretend_args_size;
6294 alpha_arg_offset = -frame_size + 48;
6296 /* Describe our frame. If the frame size is larger than an integer,
6297 print it as zero to avoid an assembler error. We won't be
6298 properly describing such a frame, but that's the best we can do. */
6299 if (TARGET_ABI_UNICOSMK)
6301 else if (TARGET_ABI_OPEN_VMS)
6303 fprintf (file, "\t.frame $%d,", vms_unwind_regno);
6304 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
6305 frame_size >= (1l << 31) ? 0 : frame_size);
6306 fputs (",$26,", file);
6307 fprintf (file, HOST_WIDE_INT_PRINT_DEC, reg_offset);
6310 else if (!flag_inhibit_size_directive)
6312 fprintf (file, "\t.frame $%d,",
6313 (frame_pointer_needed
6314 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM));
6315 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
6316 frame_size >= (1l << 31) ? 0 : frame_size);
6317 fprintf (file, ",$26,%d\n", current_function_pretend_args_size);
6320 /* Describe which registers were spilled. */
6321 if (TARGET_ABI_UNICOSMK)
6323 else if (TARGET_ABI_OPEN_VMS)
6326 /* ??? Does VMS care if mask contains ra? The old code didn't
6327 set it, so I don't here. */
6328 fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1L << REG_RA));
6330 fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
6331 if (!alpha_is_stack_procedure)
6332 fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
6334 else if (!flag_inhibit_size_directive)
6338 fprintf (file, "\t.mask 0x%lx,", imask);
6339 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
6340 frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
6343 for (i = 0; i < 32; ++i)
6344 if (imask & (1L << i))
6350 fprintf (file, "\t.fmask 0x%lx,", fmask);
6351 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
6352 frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
6357 #if TARGET_ABI_OPEN_VMS
6358 /* Ifdef'ed cause readonly_section and link_section are only
6360 readonly_section ();
6361 fprintf (file, "\t.align 3\n");
6362 assemble_name (file, fnname); fputs ("..na:\n", file);
6363 fputs ("\t.ascii \"", file);
6364 assemble_name (file, fnname);
6365 fputs ("\\0\"\n", file);
6368 fprintf (file, "\t.align 3\n");
6369 fputs ("\t.name ", file);
6370 assemble_name (file, fnname);
6371 fputs ("..na\n", file);
6372 ASM_OUTPUT_LABEL (file, fnname);
6373 fprintf (file, "\t.pdesc ");
6374 assemble_name (file, fnname);
6375 fprintf (file, "..en,%s\n", alpha_is_stack_procedure ? "stack" : "reg");
6376 alpha_need_linkage (fnname, 1);
6381 /* Emit the .prologue note at the scheduled end of the prologue. */
6384 alpha_output_function_end_prologue (file)
6387 if (TARGET_ABI_UNICOSMK)
6389 else if (TARGET_ABI_OPEN_VMS)
6390 fputs ("\t.prologue\n", file);
6391 else if (TARGET_ABI_WINDOWS_NT)
6392 fputs ("\t.prologue 0\n", file);
6393 else if (!flag_inhibit_size_directive)
6394 fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
6397 /* Write function epilogue. */
6399 /* ??? At some point we will want to support full unwind, and so will
6400 need to mark the epilogue as well. At the moment, we just confuse
6403 #define FRP(exp) exp
6406 alpha_expand_epilogue ()
6408 /* Registers to save. */
6409 unsigned long imask = 0;
6410 unsigned long fmask = 0;
6411 /* Stack space needed for pushing registers clobbered by us. */
6412 HOST_WIDE_INT sa_size;
6413 /* Complete stack size needed. */
6414 HOST_WIDE_INT frame_size;
6415 /* Offset from base reg to register save area. */
6416 HOST_WIDE_INT reg_offset;
6417 int fp_is_frame_pointer, fp_offset;
6418 rtx sa_reg, sa_reg_exp = NULL;
6419 rtx sp_adj1, sp_adj2, mem;
6423 sa_size = alpha_sa_size ();
6425 frame_size = get_frame_size ();
6426 if (TARGET_ABI_OPEN_VMS)
6427 frame_size = ALPHA_ROUND (sa_size
6428 + (alpha_is_stack_procedure ? 8 : 0)
6430 + current_function_pretend_args_size);
6431 else if (TARGET_ABI_UNICOSMK)
6432 frame_size = ALPHA_ROUND (sa_size
6433 + (alpha_is_stack_procedure ? 48 : 0))
6434 + ALPHA_ROUND (frame_size
6435 + current_function_outgoing_args_size);
6437 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
6439 + ALPHA_ROUND (frame_size
6440 + current_function_pretend_args_size));
6442 if (TARGET_ABI_OPEN_VMS)
6445 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
6447 alpha_sa_mask (&imask, &fmask);
6449 fp_is_frame_pointer = ((TARGET_ABI_OPEN_VMS && alpha_is_stack_procedure)
6450 || (!TARGET_ABI_OPEN_VMS && frame_pointer_needed));
6452 sa_reg = stack_pointer_rtx;
6454 if (current_function_calls_eh_return)
6455 eh_ofs = EH_RETURN_STACKADJ_RTX;
6459 if (!TARGET_ABI_UNICOSMK && sa_size)
6461 /* If we have a frame pointer, restore SP from it. */
6462 if ((TARGET_ABI_OPEN_VMS
6463 && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
6464 || (!TARGET_ABI_OPEN_VMS && frame_pointer_needed))
6465 FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx));
6467 /* Cope with very large offsets to the register save area. */
6468 if (reg_offset + sa_size > 0x8000)
6470 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
6473 if (low + sa_size <= 0x8000)
6474 bias = reg_offset - low, reg_offset = low;
6476 bias = reg_offset, reg_offset = 0;
6478 sa_reg = gen_rtx_REG (DImode, 22);
6479 sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
6481 FRP (emit_move_insn (sa_reg, sa_reg_exp));
6484 /* Restore registers in order, excepting a true frame pointer. */
6486 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
6488 set_mem_alias_set (mem, alpha_sr_alias_set);
6489 FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
6492 imask &= ~(1L << REG_RA);
6494 for (i = 0; i < 32; ++i)
6495 if (imask & (1L << i))
6497 if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
6498 fp_offset = reg_offset;
6501 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
6502 set_mem_alias_set (mem, alpha_sr_alias_set);
6503 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
6508 for (i = 0; i < 32; ++i)
6509 if (fmask & (1L << i))
6511 mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
6512 set_mem_alias_set (mem, alpha_sr_alias_set);
6513 FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
6517 else if (TARGET_ABI_UNICOSMK && alpha_is_stack_procedure)
6519 /* Restore callee-saved general-purpose registers. */
6523 for (i = 9; i < 15; i++)
6524 if (imask & (1L << i))
6526 mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx,
6528 set_mem_alias_set (mem, alpha_sr_alias_set);
6529 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
6533 for (i = 2; i < 10; i++)
6534 if (fmask & (1L << i))
6536 mem = gen_rtx_MEM (DFmode, plus_constant(hard_frame_pointer_rtx,
6538 set_mem_alias_set (mem, alpha_sr_alias_set);
6539 FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
6543 /* Restore the return address from the DSIB. */
6545 mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx, -8));
6546 set_mem_alias_set (mem, alpha_sr_alias_set);
6547 FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
6550 if (frame_size || eh_ofs)
6552 sp_adj1 = stack_pointer_rtx;
6556 sp_adj1 = gen_rtx_REG (DImode, 23);
6557 emit_move_insn (sp_adj1,
6558 gen_rtx_PLUS (Pmode, stack_pointer_rtx, eh_ofs));
6561 /* If the stack size is large, begin computation into a temporary
6562 register so as not to interfere with a potential fp restore,
6563 which must be consecutive with an SP restore. */
6564 if (frame_size < 32768
6565 && ! (TARGET_ABI_UNICOSMK && current_function_calls_alloca))
6566 sp_adj2 = GEN_INT (frame_size);
6567 else if (TARGET_ABI_UNICOSMK)
6569 sp_adj1 = gen_rtx_REG (DImode, 23);
6570 FRP (emit_move_insn (sp_adj1, hard_frame_pointer_rtx));
6571 sp_adj2 = const0_rtx;
6573 else if (frame_size < 0x40007fffL)
6575 int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
6577 sp_adj2 = plus_constant (sp_adj1, frame_size - low);
6578 if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
6582 sp_adj1 = gen_rtx_REG (DImode, 23);
6583 FRP (emit_move_insn (sp_adj1, sp_adj2));
6585 sp_adj2 = GEN_INT (low);
6589 rtx tmp = gen_rtx_REG (DImode, 23);
6590 FRP (sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3));
6593 /* We can't drop new things to memory this late, afaik,
6594 so build it up by pieces. */
6595 FRP (sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
6596 -(frame_size < 0)));
6602 /* From now on, things must be in order. So emit blockages. */
6604 /* Restore the frame pointer. */
6605 if (TARGET_ABI_UNICOSMK)
6607 emit_insn (gen_blockage ());
6608 mem = gen_rtx_MEM (DImode,
6609 plus_constant (hard_frame_pointer_rtx, -16));
6610 set_mem_alias_set (mem, alpha_sr_alias_set);
6611 FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
6613 else if (fp_is_frame_pointer)
6615 emit_insn (gen_blockage ());
6616 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, fp_offset));
6617 set_mem_alias_set (mem, alpha_sr_alias_set);
6618 FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
6620 else if (TARGET_ABI_OPEN_VMS)
6622 emit_insn (gen_blockage ());
6623 FRP (emit_move_insn (hard_frame_pointer_rtx,
6624 gen_rtx_REG (DImode, vms_save_fp_regno)));
6627 /* Restore the stack pointer. */
6628 emit_insn (gen_blockage ());
6629 if (sp_adj2 == const0_rtx)
6630 FRP (emit_move_insn (stack_pointer_rtx, sp_adj1));
6632 FRP (emit_move_insn (stack_pointer_rtx,
6633 gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)));
6637 if (TARGET_ABI_OPEN_VMS && !alpha_is_stack_procedure)
6639 emit_insn (gen_blockage ());
6640 FRP (emit_move_insn (hard_frame_pointer_rtx,
6641 gen_rtx_REG (DImode, vms_save_fp_regno)));
6643 else if (TARGET_ABI_UNICOSMK && !alpha_is_stack_procedure)
6645 /* Decrement the frame pointer if the function does not have a
6648 emit_insn (gen_blockage ());
6649 FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
6650 hard_frame_pointer_rtx, GEN_INT (-1))));
6655 /* Output the rest of the textual info surrounding the epilogue. */
6658 alpha_end_function (file, fnname, decl)
6661 tree decl ATTRIBUTE_UNUSED;
6663 /* End the function. */
6664 if (!TARGET_ABI_UNICOSMK && !flag_inhibit_size_directive)
6666 fputs ("\t.end ", file);
6667 assemble_name (file, fnname);
6670 inside_function = FALSE;
6672 /* Show that we know this function if it is called again.
6674 Don't do this for global functions in object files destined for a
6675 shared library because the function may be overridden by the application
6676 or other libraries. Similarly, don't do this for weak functions. */
6678 if (!DECL_WEAK (current_function_decl)
6679 && (!flag_pic || !TREE_PUBLIC (current_function_decl)))
6680 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
6682 /* Output jump tables and the static subroutine information block. */
6683 if (TARGET_ABI_UNICOSMK)
6685 unicosmk_output_ssib (file, fnname);
6686 unicosmk_output_deferred_case_vectors (file);
6690 /* Debugging support. */
6694 /* Count the number of sdb related labels are generated (to find block
6695 start and end boundaries). */
6697 int sdb_label_count = 0;
6699 /* Next label # for each statement. */
6701 static int sym_lineno = 0;
6703 /* Count the number of .file directives, so that .loc is up to date. */
6705 static int num_source_filenames = 0;
6707 /* Name of the file containing the current function. */
6709 static const char *current_function_file = "";
6711 /* Offsets to alpha virtual arg/local debugging pointers. */
6713 long alpha_arg_offset;
6714 long alpha_auto_offset;
6716 /* Emit a new filename to a stream. */
6719 alpha_output_filename (stream, name)
6723 static int first_time = TRUE;
6724 char ltext_label_name[100];
6729 ++num_source_filenames;
6730 current_function_file = name;
6731 fprintf (stream, "\t.file\t%d ", num_source_filenames);
6732 output_quoted_string (stream, name);
6733 fprintf (stream, "\n");
6734 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
6735 fprintf (stream, "\t#@stabs\n");
6738 else if (write_symbols == DBX_DEBUG)
6740 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
6741 fprintf (stream, "%s", ASM_STABS_OP);
6742 output_quoted_string (stream, name);
6743 fprintf (stream, ",%d,0,0,%s\n", N_SOL, <ext_label_name[1]);
6746 else if (name != current_function_file
6747 && strcmp (name, current_function_file) != 0)
6749 if (inside_function && ! TARGET_GAS)
6750 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
6753 ++num_source_filenames;
6754 current_function_file = name;
6755 fprintf (stream, "\t.file\t%d ", num_source_filenames);
6758 output_quoted_string (stream, name);
6759 fprintf (stream, "\n");
6763 /* Emit a linenumber to a stream. */
6766 alpha_output_lineno (stream, line)
6770 if (write_symbols == DBX_DEBUG)
6772 /* mips-tfile doesn't understand .stabd directives. */
6774 fprintf (stream, "$LM%d:\n%s%d,0,%d,$LM%d\n",
6775 sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
6778 fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
6781 /* Structure to show the current status of registers and memory. */
6783 struct shadow_summary
6786 unsigned int i : 31; /* Mask of int regs */
6787 unsigned int fp : 31; /* Mask of fp regs */
6788 unsigned int mem : 1; /* mem == imem | fpmem */
6792 static void summarize_insn PARAMS ((rtx, struct shadow_summary *, int));
6793 static void alpha_handle_trap_shadows PARAMS ((rtx));
6795 /* Summary the effects of expression X on the machine. Update SUM, a pointer
6796 to the summary structure. SET is nonzero if the insn is setting the
6797 object, otherwise zero. */
6800 summarize_insn (x, sum, set)
6802 struct shadow_summary *sum;
6805 const char *format_ptr;
6811 switch (GET_CODE (x))
6813 /* ??? Note that this case would be incorrect if the Alpha had a
6814 ZERO_EXTRACT in SET_DEST. */
6816 summarize_insn (SET_SRC (x), sum, 0);
6817 summarize_insn (SET_DEST (x), sum, 1);
6821 summarize_insn (XEXP (x, 0), sum, 1);
6825 summarize_insn (XEXP (x, 0), sum, 0);
6829 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
6830 summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
6834 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
6835 summarize_insn (XVECEXP (x, 0, i), sum, 0);
6839 summarize_insn (SUBREG_REG (x), sum, 0);
6844 int regno = REGNO (x);
6845 unsigned long mask = ((unsigned long) 1) << (regno % 32);
6847 if (regno == 31 || regno == 63)
6853 sum->defd.i |= mask;
6855 sum->defd.fp |= mask;
6860 sum->used.i |= mask;
6862 sum->used.fp |= mask;
6873 /* Find the regs used in memory address computation: */
6874 summarize_insn (XEXP (x, 0), sum, 0);
6877 case CONST_INT: case CONST_DOUBLE:
6878 case SYMBOL_REF: case LABEL_REF: case CONST:
6882 /* Handle common unary and binary ops for efficiency. */
6883 case COMPARE: case PLUS: case MINUS: case MULT: case DIV:
6884 case MOD: case UDIV: case UMOD: case AND: case IOR:
6885 case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT:
6886 case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX:
6887 case NE: case EQ: case GE: case GT: case LE:
6888 case LT: case GEU: case GTU: case LEU: case LTU:
6889 summarize_insn (XEXP (x, 0), sum, 0);
6890 summarize_insn (XEXP (x, 1), sum, 0);
6893 case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
6894 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
6895 case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
6896 case SQRT: case FFS:
6897 summarize_insn (XEXP (x, 0), sum, 0);
6901 format_ptr = GET_RTX_FORMAT (GET_CODE (x));
6902 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
6903 switch (format_ptr[i])
6906 summarize_insn (XEXP (x, i), sum, 0);
6910 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
6911 summarize_insn (XVECEXP (x, i, j), sum, 0);
6923 /* Ensure a sufficient number of `trapb' insns are in the code when
6924 the user requests code with a trap precision of functions or
6927 In naive mode, when the user requests a trap-precision of
6928 "instruction", a trapb is needed after every instruction that may
6929 generate a trap. This ensures that the code is resumption safe but
6932 When optimizations are turned on, we delay issuing a trapb as long
6933 as possible. In this context, a trap shadow is the sequence of
6934 instructions that starts with a (potentially) trap generating
6935 instruction and extends to the next trapb or call_pal instruction
6936 (but GCC never generates call_pal by itself). We can delay (and
6937 therefore sometimes omit) a trapb subject to the following
6940 (a) On entry to the trap shadow, if any Alpha register or memory
6941 location contains a value that is used as an operand value by some
6942 instruction in the trap shadow (live on entry), then no instruction
6943 in the trap shadow may modify the register or memory location.
6945 (b) Within the trap shadow, the computation of the base register
6946 for a memory load or store instruction may not involve using the
6947 result of an instruction that might generate an UNPREDICTABLE
6950 (c) Within the trap shadow, no register may be used more than once
6951 as a destination register. (This is to make life easier for the
6954 (d) The trap shadow may not include any branch instructions. */
6957 alpha_handle_trap_shadows (insns)
6960 struct shadow_summary shadow;
6961 int trap_pending, exception_nesting;
6965 exception_nesting = 0;
6968 shadow.used.mem = 0;
6969 shadow.defd = shadow.used;
6971 for (i = insns; i ; i = NEXT_INSN (i))
6973 if (GET_CODE (i) == NOTE)
6975 switch (NOTE_LINE_NUMBER (i))
6977 case NOTE_INSN_EH_REGION_BEG:
6978 exception_nesting++;
6983 case NOTE_INSN_EH_REGION_END:
6984 exception_nesting--;
6989 case NOTE_INSN_EPILOGUE_BEG:
6990 if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
6995 else if (trap_pending)
6997 if (alpha_tp == ALPHA_TP_FUNC)
6999 if (GET_CODE (i) == JUMP_INSN
7000 && GET_CODE (PATTERN (i)) == RETURN)
7003 else if (alpha_tp == ALPHA_TP_INSN)
7007 struct shadow_summary sum;
7012 sum.defd = sum.used;
7014 switch (GET_CODE (i))
7017 /* Annoyingly, get_attr_trap will abort on these. */
7018 if (GET_CODE (PATTERN (i)) == USE
7019 || GET_CODE (PATTERN (i)) == CLOBBER)
7022 summarize_insn (PATTERN (i), &sum, 0);
7024 if ((sum.defd.i & shadow.defd.i)
7025 || (sum.defd.fp & shadow.defd.fp))
7027 /* (c) would be violated */
7031 /* Combine shadow with summary of current insn: */
7032 shadow.used.i |= sum.used.i;
7033 shadow.used.fp |= sum.used.fp;
7034 shadow.used.mem |= sum.used.mem;
7035 shadow.defd.i |= sum.defd.i;
7036 shadow.defd.fp |= sum.defd.fp;
7037 shadow.defd.mem |= sum.defd.mem;
7039 if ((sum.defd.i & shadow.used.i)
7040 || (sum.defd.fp & shadow.used.fp)
7041 || (sum.defd.mem & shadow.used.mem))
7043 /* (a) would be violated (also takes care of (b)) */
7044 if (get_attr_trap (i) == TRAP_YES
7045 && ((sum.defd.i & sum.used.i)
7046 || (sum.defd.fp & sum.used.fp)))
7065 n = emit_insn_before (gen_trapb (), i);
7066 PUT_MODE (n, TImode);
7067 PUT_MODE (i, TImode);
7071 shadow.used.mem = 0;
7072 shadow.defd = shadow.used;
7077 if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
7078 && GET_CODE (i) == INSN
7079 && GET_CODE (PATTERN (i)) != USE
7080 && GET_CODE (PATTERN (i)) != CLOBBER
7081 && get_attr_trap (i) == TRAP_YES)
7083 if (optimize && !trap_pending)
7084 summarize_insn (PATTERN (i), &shadow, 0);
7090 /* Alpha can only issue instruction groups simultaneously if they are
7091 suitibly aligned. This is very processor-specific. */
7093 enum alphaev4_pipe {
7100 enum alphaev5_pipe {
7111 static enum alphaev4_pipe alphaev4_insn_pipe PARAMS ((rtx));
7112 static enum alphaev5_pipe alphaev5_insn_pipe PARAMS ((rtx));
7113 static rtx alphaev4_next_group PARAMS ((rtx, int *, int *));
7114 static rtx alphaev5_next_group PARAMS ((rtx, int *, int *));
7115 static rtx alphaev4_next_nop PARAMS ((int *));
7116 static rtx alphaev5_next_nop PARAMS ((int *));
7118 static void alpha_align_insns
7119 PARAMS ((rtx, unsigned int, rtx (*)(rtx, int *, int *), rtx (*)(int *)));
7121 static enum alphaev4_pipe
7122 alphaev4_insn_pipe (insn)
7125 if (recog_memoized (insn) < 0)
7127 if (get_attr_length (insn) != 4)
7130 switch (get_attr_type (insn))
7163 static enum alphaev5_pipe
7164 alphaev5_insn_pipe (insn)
7167 if (recog_memoized (insn) < 0)
7169 if (get_attr_length (insn) != 4)
7172 switch (get_attr_type (insn))
7212 /* IN_USE is a mask of the slots currently filled within the insn group.
7213 The mask bits come from alphaev4_pipe above. If EV4_IBX is set, then
7214 the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.
7216 LEN is, of course, the length of the group in bytes. */
7219 alphaev4_next_group (insn, pin_use, plen)
7221 int *pin_use, *plen;
7228 || GET_CODE (PATTERN (insn)) == CLOBBER
7229 || GET_CODE (PATTERN (insn)) == USE)
7234 enum alphaev4_pipe pipe;
7236 pipe = alphaev4_insn_pipe (insn);
7240 /* Force complex instructions to start new groups. */
7244 /* If this is a completely unrecognized insn, its an asm.
7245 We don't know how long it is, so record length as -1 to
7246 signal a needed realignment. */
7247 if (recog_memoized (insn) < 0)
7250 len = get_attr_length (insn);
7254 if (in_use & EV4_IB0)
7256 if (in_use & EV4_IB1)
7261 in_use |= EV4_IB0 | EV4_IBX;
7265 if (in_use & EV4_IB0)
7267 if (!(in_use & EV4_IBX) || (in_use & EV4_IB1))
7275 if (in_use & EV4_IB1)
7285 /* Haifa doesn't do well scheduling branches. */
7286 if (GET_CODE (insn) == JUMP_INSN)
7290 insn = next_nonnote_insn (insn);
7292 if (!insn || ! INSN_P (insn))
7295 /* Let Haifa tell us where it thinks insn group boundaries are. */
7296 if (GET_MODE (insn) == TImode)
7299 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
7304 insn = next_nonnote_insn (insn);
7312 /* IN_USE is a mask of the slots currently filled within the insn group.
7313 The mask bits come from alphaev5_pipe above. If EV5_E01 is set, then
7314 the insn in EV5_E0 can be swapped by the hardware into EV5_E1.
7316 LEN is, of course, the length of the group in bytes. */
7319 alphaev5_next_group (insn, pin_use, plen)
7321 int *pin_use, *plen;
7328 || GET_CODE (PATTERN (insn)) == CLOBBER
7329 || GET_CODE (PATTERN (insn)) == USE)
7334 enum alphaev5_pipe pipe;
7336 pipe = alphaev5_insn_pipe (insn);
7340 /* Force complex instructions to start new groups. */
7344 /* If this is a completely unrecognized insn, its an asm.
7345 We don't know how long it is, so record length as -1 to
7346 signal a needed realignment. */
7347 if (recog_memoized (insn) < 0)
7350 len = get_attr_length (insn);
7353 /* ??? Most of the places below, we would like to abort, as
7354 it would indicate an error either in Haifa, or in the
7355 scheduling description. Unfortunately, Haifa never
7356 schedules the last instruction of the BB, so we don't
7357 have an accurate TI bit to go off. */
7359 if (in_use & EV5_E0)
7361 if (in_use & EV5_E1)
7366 in_use |= EV5_E0 | EV5_E01;
7370 if (in_use & EV5_E0)
7372 if (!(in_use & EV5_E01) || (in_use & EV5_E1))
7380 if (in_use & EV5_E1)
7386 if (in_use & EV5_FA)
7388 if (in_use & EV5_FM)
7393 in_use |= EV5_FA | EV5_FAM;
7397 if (in_use & EV5_FA)
7403 if (in_use & EV5_FM)
7416 /* Haifa doesn't do well scheduling branches. */
7417 /* ??? If this is predicted not-taken, slotting continues, except
7418 that no more IBR, FBR, or JSR insns may be slotted. */
7419 if (GET_CODE (insn) == JUMP_INSN)
7423 insn = next_nonnote_insn (insn);
7425 if (!insn || ! INSN_P (insn))
7428 /* Let Haifa tell us where it thinks insn group boundaries are. */
7429 if (GET_MODE (insn) == TImode)
7432 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
7437 insn = next_nonnote_insn (insn);
7446 alphaev4_next_nop (pin_use)
7449 int in_use = *pin_use;
7452 if (!(in_use & EV4_IB0))
7457 else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX)
7462 else if (TARGET_FP && !(in_use & EV4_IB1))
7475 alphaev5_next_nop (pin_use)
7478 int in_use = *pin_use;
7481 if (!(in_use & EV5_E1))
7486 else if (TARGET_FP && !(in_use & EV5_FA))
7491 else if (TARGET_FP && !(in_use & EV5_FM))
7503 /* The instruction group alignment main loop. */
7506 alpha_align_insns (insns, max_align, next_group, next_nop)
7508 unsigned int max_align;
7509 rtx (*next_group) PARAMS ((rtx, int *, int *));
7510 rtx (*next_nop) PARAMS ((int *));
7512 /* ALIGN is the known alignment for the insn group. */
7514 /* OFS is the offset of the current insn in the insn group. */
7516 int prev_in_use, in_use, len;
7519 /* Let shorten branches care for assigning alignments to code labels. */
7520 shorten_branches (insns);
7522 align = (FUNCTION_BOUNDARY / BITS_PER_UNIT < max_align
7523 ? FUNCTION_BOUNDARY / BITS_PER_UNIT : max_align);
7525 ofs = prev_in_use = 0;
7527 if (GET_CODE (i) == NOTE)
7528 i = next_nonnote_insn (i);
7532 next = (*next_group) (i, &in_use, &len);
7534 /* When we see a label, resync alignment etc. */
7535 if (GET_CODE (i) == CODE_LABEL)
7537 unsigned int new_align = 1 << label_to_alignment (i);
7539 if (new_align >= align)
7541 align = new_align < max_align ? new_align : max_align;
7545 else if (ofs & (new_align-1))
7546 ofs = (ofs | (new_align-1)) + 1;
7551 /* Handle complex instructions special. */
7552 else if (in_use == 0)
7554 /* Asms will have length < 0. This is a signal that we have
7555 lost alignment knowledge. Assume, however, that the asm
7556 will not mis-align instructions. */
7565 /* If the known alignment is smaller than the recognized insn group,
7566 realign the output. */
7567 else if ((int) align < len)
7569 unsigned int new_log_align = len > 8 ? 4 : 3;
7572 where = prev_nonnote_insn (i);
7573 if (!where || GET_CODE (where) != CODE_LABEL)
7576 emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
7577 align = 1 << new_log_align;
7581 /* If the group won't fit in the same INT16 as the previous,
7582 we need to add padding to keep the group together. Rather
7583 than simply leaving the insn filling to the assembler, we
7584 can make use of the knowledge of what sorts of instructions
7585 were issued in the previous group to make sure that all of
7586 the added nops are really free. */
7587 else if (ofs + len > (int) align)
7589 int nop_count = (align - ofs) / 4;
7592 /* Insert nops before labels and branches to truely merge the
7593 execution of the nops with the previous instruction group. */
7594 where = prev_nonnote_insn (i);
7597 if (GET_CODE (where) == CODE_LABEL)
7599 rtx where2 = prev_nonnote_insn (where);
7600 if (where2 && GET_CODE (where2) == JUMP_INSN)
7603 else if (GET_CODE (where) != JUMP_INSN)
7610 emit_insn_before ((*next_nop)(&prev_in_use), where);
7611 while (--nop_count);
7615 ofs = (ofs + len) & (align - 1);
7616 prev_in_use = in_use;
7621 /* Machine dependant reorg pass. */
7627 if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
7628 alpha_handle_trap_shadows (insns);
7630 /* Due to the number of extra trapb insns, don't bother fixing up
7631 alignment when trap precision is instruction. Moreover, we can
7632 only do our job when sched2 is run. */
7633 if (optimize && !optimize_size
7634 && alpha_tp != ALPHA_TP_INSN
7635 && flag_schedule_insns_after_reload)
7637 if (alpha_cpu == PROCESSOR_EV4)
7638 alpha_align_insns (insns, 8, alphaev4_next_group, alphaev4_next_nop);
7639 else if (alpha_cpu == PROCESSOR_EV5)
7640 alpha_align_insns (insns, 16, alphaev5_next_group, alphaev5_next_nop);
7644 /* Check a floating-point value for validity for a particular machine mode. */
7646 static const char * const float_strings[] =
7648 /* These are for FLOAT_VAX. */
7649 "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
7650 "-1.70141173319264430e+38",
7651 "2.93873587705571877e-39", /* 2^-128 */
7652 "-2.93873587705571877e-39",
7653 /* These are for the default broken IEEE mode, which traps
7654 on infinity or denormal numbers. */
7655 "3.402823466385288598117e+38", /* 2^128 (1 - 2^-24) */
7656 "-3.402823466385288598117e+38",
7657 "1.1754943508222875079687e-38", /* 2^-126 */
7658 "-1.1754943508222875079687e-38",
7661 static REAL_VALUE_TYPE float_values[8];
7662 static int inited_float_values = 0;
7665 check_float_value (mode, d, overflow)
7666 enum machine_mode mode;
7668 int overflow ATTRIBUTE_UNUSED;
7671 if (TARGET_IEEE || TARGET_IEEE_CONFORMANT || TARGET_IEEE_WITH_INEXACT)
7674 if (inited_float_values == 0)
7677 for (i = 0; i < 8; i++)
7678 float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
7680 inited_float_values = 1;
7686 REAL_VALUE_TYPE *fvptr;
7688 if (TARGET_FLOAT_VAX)
7689 fvptr = &float_values[0];
7691 fvptr = &float_values[4];
7693 memcpy (&r, d, sizeof (REAL_VALUE_TYPE));
7694 if (REAL_VALUES_LESS (fvptr[0], r))
7696 memcpy (d, &fvptr[0], sizeof (REAL_VALUE_TYPE));
7699 else if (REAL_VALUES_LESS (r, fvptr[1]))
7701 memcpy (d, &fvptr[1], sizeof (REAL_VALUE_TYPE));
7704 else if (REAL_VALUES_LESS (dconst0, r)
7705 && REAL_VALUES_LESS (r, fvptr[2]))
7707 memcpy (d, &dconst0, sizeof (REAL_VALUE_TYPE));
7710 else if (REAL_VALUES_LESS (r, dconst0)
7711 && REAL_VALUES_LESS (fvptr[3], r))
7713 memcpy (d, &dconst0, sizeof (REAL_VALUE_TYPE));
7721 #if TARGET_ABI_OPEN_VMS
7723 /* Return the VMS argument type corresponding to MODE. */
7726 alpha_arg_type (mode)
7727 enum machine_mode mode;
7732 return TARGET_FLOAT_VAX ? FF : FS;
7734 return TARGET_FLOAT_VAX ? FD : FT;
7740 /* Return an rtx for an integer representing the VMS Argument Information
7744 alpha_arg_info_reg_val (cum)
7745 CUMULATIVE_ARGS cum;
7747 unsigned HOST_WIDE_INT regval = cum.num_args;
7750 for (i = 0; i < 6; i++)
7751 regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
7753 return GEN_INT (regval);
7756 #include <splay-tree.h>
7758 /* Structure to collect function names for final output
7761 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
7766 enum links_kind kind;
7769 static splay_tree alpha_links;
7771 static int mark_alpha_links_node PARAMS ((splay_tree_node, void *));
7772 static void mark_alpha_links PARAMS ((void *));
7773 static int alpha_write_one_linkage PARAMS ((splay_tree_node, void *));
7775 /* Protect alpha_links from garbage collection. */
7778 mark_alpha_links_node (node, data)
7779 splay_tree_node node;
7780 void *data ATTRIBUTE_UNUSED;
7782 struct alpha_links *links = (struct alpha_links *) node->value;
7783 ggc_mark_rtx (links->linkage);
7788 mark_alpha_links (ptr)
7791 splay_tree tree = *(splay_tree *) ptr;
7792 splay_tree_foreach (tree, mark_alpha_links_node, NULL);
7795 /* Make (or fake) .linkage entry for function call.
7797 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition.
7799 Return an SYMBOL_REF rtx for the linkage. */
7802 alpha_need_linkage (name, is_local)
7806 splay_tree_node node;
7807 struct alpha_links *al;
7814 /* Is this name already defined? */
7816 node = splay_tree_lookup (alpha_links, (splay_tree_key) name);
7819 al = (struct alpha_links *) node->value;
7822 /* Defined here but external assumed. */
7823 if (al->kind == KIND_EXTERN)
7824 al->kind = KIND_LOCAL;
7828 /* Used here but unused assumed. */
7829 if (al->kind == KIND_UNUSED)
7830 al->kind = KIND_LOCAL;
7837 alpha_links = splay_tree_new ((splay_tree_compare_fn) strcmp,
7838 (splay_tree_delete_key_fn) free,
7839 (splay_tree_delete_key_fn) free);
7840 ggc_add_root (&alpha_links, 1, 1, mark_alpha_links);
7843 al = (struct alpha_links *) xmalloc (sizeof (struct alpha_links));
7844 name = xstrdup (name);
7846 /* Assume external if no definition. */
7847 al->kind = (is_local ? KIND_UNUSED : KIND_EXTERN);
7849 /* Ensure we have an IDENTIFIER so assemble_name can mark it used. */
7850 get_identifier (name);
7852 /* Construct a SYMBOL_REF for us to call. */
7854 size_t name_len = strlen (name);
7855 char *linksym = alloca (name_len + 6);
7857 memcpy (linksym + 1, name, name_len);
7858 memcpy (linksym + 1 + name_len, "..lk", 5);
7859 al->linkage = gen_rtx_SYMBOL_REF (Pmode,
7860 ggc_alloc_string (linksym, name_len + 5));
7863 splay_tree_insert (alpha_links, (splay_tree_key) name,
7864 (splay_tree_value) al);
7870 alpha_write_one_linkage (node, data)
7871 splay_tree_node node;
7874 const char *const name = (const char *) node->key;
7875 struct alpha_links *links = (struct alpha_links *) node->value;
7876 FILE *stream = (FILE *) data;
7878 if (links->kind == KIND_UNUSED
7879 || ! TREE_SYMBOL_REFERENCED (get_identifier (name)))
7882 fprintf (stream, "$%s..lk:\n", name);
7883 if (links->kind == KIND_LOCAL)
7885 /* Local and used, build linkage pair. */
7886 fprintf (stream, "\t.quad %s..en\n", name);
7887 fprintf (stream, "\t.quad %s\n", name);
7891 /* External and used, request linkage pair. */
7892 fprintf (stream, "\t.linkage %s\n", name);
7899 alpha_write_linkage (stream)
7902 readonly_section ();
7903 fprintf (stream, "\t.align 3\n");
7904 splay_tree_foreach (alpha_links, alpha_write_one_linkage, stream);
7907 /* Given a decl, a section name, and whether the decl initializer
7908 has relocs, choose attributes for the section. */
7910 #define SECTION_VMS_OVERLAY SECTION_FORGET
7913 vms_section_type_flags (decl, name, reloc)
7918 unsigned int flags = default_section_type_flags (decl, name, reloc);
7920 if (decl && DECL_ATTRIBUTES (decl)
7921 && lookup_attribute ("overlaid", DECL_ATTRIBUTES (decl)))
7922 flags |= SECTION_VMS_OVERLAY;
7927 /* Switch to an arbitrary section NAME with attributes as specified
7928 by FLAGS. ALIGN specifies any known alignment requirements for
7929 the section; 0 if the default should be used. */
7932 vms_asm_named_section (name, flags)
7936 const char *flag_str = "";
7938 if (flags & SECTION_VMS_OVERLAY)
7940 else if (flags & SECTION_DEBUG)
7941 flag_str = ",NOWRT";
7943 fprintf (asm_out_file, ".section\t%s%s\n", name, flag_str);
7946 /* Record an element in the table of global constructors. SYMBOL is
7947 a SYMBOL_REF of the function to be called; PRIORITY is a number
7948 between 0 and MAX_INIT_PRIORITY.
7950 Differs from default_ctors_section_asm_out_constructor in that the
7951 width of the .ctors entry is always 64 bits, rather than the 32 bits
7952 used by a normal pointer. */
7955 vms_asm_out_constructor (symbol, priority)
7957 int priority ATTRIBUTE_UNUSED;
7960 assemble_align (BITS_PER_WORD);
7961 assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
7965 vms_asm_out_destructor (symbol, priority)
7967 int priority ATTRIBUTE_UNUSED;
7970 assemble_align (BITS_PER_WORD);
7971 assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
7976 alpha_need_linkage (name, is_local)
7977 const char *name ATTRIBUTE_UNUSED;
7978 int is_local ATTRIBUTE_UNUSED;
7983 #endif /* TARGET_ABI_OPEN_VMS */
7985 #if TARGET_ABI_UNICOSMK
7987 static void unicosmk_output_module_name PARAMS ((FILE *));
7988 static void unicosmk_output_default_externs PARAMS ((FILE *));
7989 static void unicosmk_output_dex PARAMS ((FILE *));
7990 static void unicosmk_output_externs PARAMS ((FILE *));
7991 static void unicosmk_output_addr_vec PARAMS ((FILE *, rtx));
7992 static const char *unicosmk_ssib_name PARAMS ((void));
7995 /* Define the offset between two registers, one to be eliminated, and the
7996 other its replacement, at the start of a routine. */
7999 unicosmk_initial_elimination_offset (from, to)
8005 fixed_size = alpha_sa_size();
8006 if (fixed_size != 0)
8009 if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
8011 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
8013 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
8014 return (ALPHA_ROUND (current_function_outgoing_args_size)
8015 + ALPHA_ROUND (get_frame_size()));
8016 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
8017 return (ALPHA_ROUND (fixed_size)
8018 + ALPHA_ROUND (get_frame_size()
8019 + current_function_outgoing_args_size));
8024 /* Output the module name for .ident and .end directives. We have to strip
8025 directories and add make sure that the module name starts with a letter
8029 unicosmk_output_module_name (file)
8034 /* Strip directories. */
8036 name = strrchr (main_input_filename, '/');
8040 name = main_input_filename;
8042 /* CAM only accepts module names that start with a letter or '$'. We
8043 prefix the module name with a '$' if necessary. */
8045 if (!ISALPHA (*name))
8046 fprintf (file, "$%s", name);
8051 /* Output text that to appear at the beginning of an assembler file. */
8054 unicosmk_asm_file_start (file)
8059 fputs ("\t.ident\t", file);
8060 unicosmk_output_module_name (file);
8061 fputs ("\n\n", file);
8063 /* The Unicos/Mk assembler uses different register names. Instead of trying
8064 to support them, we simply use micro definitions. */
8066 /* CAM has different register names: rN for the integer register N and fN
8067 for the floating-point register N. Instead of trying to use these in
8068 alpha.md, we define the symbols $N and $fN to refer to the appropriate
8071 for (i = 0; i < 32; ++i)
8072 fprintf (file, "$%d <- r%d\n", i, i);
8074 for (i = 0; i < 32; ++i)
8075 fprintf (file, "$f%d <- f%d\n", i, i);
8079 /* The .align directive fill unused space with zeroes which does not work
8080 in code sections. We define the macro 'gcc@code@align' which uses nops
8081 instead. Note that it assumes that code sections always have the
8082 biggest possible alignment since . refers to the current offset from
8083 the beginning of the section. */
8085 fputs ("\t.macro gcc@code@align n\n", file);
8086 fputs ("gcc@n@bytes = 1 << n\n", file);
8087 fputs ("gcc@here = . % gcc@n@bytes\n", file);
8088 fputs ("\t.if ne, gcc@here, 0\n", file);
8089 fputs ("\t.repeat (gcc@n@bytes - gcc@here) / 4\n", file);
8090 fputs ("\tbis r31,r31,r31\n", file);
8091 fputs ("\t.endr\n", file);
8092 fputs ("\t.endif\n", file);
8093 fputs ("\t.endm gcc@code@align\n\n", file);
8095 /* Output extern declarations which should always be visible. */
8096 unicosmk_output_default_externs (file);
8098 /* Open a dummy section. We always need to be inside a section for the
8099 section-switching code to work correctly.
8100 ??? This should be a module id or something like that. I still have to
8101 figure out what the rules for those are. */
8102 fputs ("\n\t.psect\t$SG00000,data\n", file);
8105 /* Output text to appear at the end of an assembler file. This includes all
8106 pending extern declarations and DEX expressions. */
8109 unicosmk_asm_file_end (file)
8112 fputs ("\t.endp\n\n", file);
8114 /* Output all pending externs. */
8116 unicosmk_output_externs (file);
8118 /* Output dex definitions used for functions whose names conflict with
8121 unicosmk_output_dex (file);
8123 fputs ("\t.end\t", file);
8124 unicosmk_output_module_name (file);
8128 /* Output the definition of a common variable. */
8131 unicosmk_output_common (file, name, size, align)
8138 printf ("T3E__: common %s\n", name);
8141 fputs("\t.endp\n\n\t.psect ", file);
8142 assemble_name(file, name);
8143 fprintf(file, ",%d,common\n", floor_log2 (align / BITS_PER_UNIT));
8144 fprintf(file, "\t.byte\t0:%d\n", size);
8146 /* Mark the symbol as defined in this module. */
8147 name_tree = get_identifier (name);
8148 TREE_ASM_WRITTEN (name_tree) = 1;
8151 #define SECTION_PUBLIC SECTION_MACH_DEP
8152 #define SECTION_MAIN (SECTION_PUBLIC << 1)
8153 static int current_section_align;
8156 unicosmk_section_type_flags (decl, name, reloc)
8159 int reloc ATTRIBUTE_UNUSED;
8161 unsigned int flags = default_section_type_flags (decl, name, reloc);
8166 if (TREE_CODE (decl) == FUNCTION_DECL)
8168 current_section_align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
8169 if (align_functions_log > current_section_align)
8170 current_section_align = align_functions_log;
8172 if (! strcmp (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), "main"))
8173 flags |= SECTION_MAIN;
8176 current_section_align = floor_log2 (DECL_ALIGN (decl) / BITS_PER_UNIT);
8178 if (TREE_PUBLIC (decl))
8179 flags |= SECTION_PUBLIC;
8184 /* Generate a section name for decl and associate it with the
8188 unicosmk_unique_section (decl, reloc)
8190 int reloc ATTRIBUTE_UNUSED;
8198 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
8199 STRIP_NAME_ENCODING (name, name);
8200 len = strlen (name);
8202 if (TREE_CODE (decl) == FUNCTION_DECL)
8206 /* It is essential that we prefix the section name here because
8207 otherwise the section names generated for constructors and
8208 destructors confuse collect2. */
8210 string = alloca (len + 6);
8211 sprintf (string, "code@%s", name);
8212 DECL_SECTION_NAME (decl) = build_string (len + 5, string);
8214 else if (TREE_PUBLIC (decl))
8215 DECL_SECTION_NAME (decl) = build_string (len, name);
8220 string = alloca (len + 6);
8221 sprintf (string, "data@%s", name);
8222 DECL_SECTION_NAME (decl) = build_string (len + 5, string);
8226 /* Switch to an arbitrary section NAME with attributes as specified
8227 by FLAGS. ALIGN specifies any known alignment requirements for
8228 the section; 0 if the default should be used. */
8231 unicosmk_asm_named_section (name, flags)
8237 /* Close the previous section. */
8239 fputs ("\t.endp\n\n", asm_out_file);
8241 /* Find out what kind of section we are opening. */
8243 if (flags & SECTION_MAIN)
8244 fputs ("\t.start\tmain\n", asm_out_file);
8246 if (flags & SECTION_CODE)
8248 else if (flags & SECTION_PUBLIC)
8253 if (current_section_align != 0)
8254 fprintf (asm_out_file, "\t.psect\t%s,%d,%s\n", name,
8255 current_section_align, kind);
8257 fprintf (asm_out_file, "\t.psect\t%s,%s\n", name, kind);
8261 unicosmk_insert_attributes (decl, attr_ptr)
8263 tree *attr_ptr ATTRIBUTE_UNUSED;
8266 && (TREE_PUBLIC (decl) || TREE_CODE (decl) == FUNCTION_DECL))
8267 UNIQUE_SECTION (decl, 0);
8270 /* Output an alignment directive. We have to use the macro 'gcc@code@align'
8271 in code sections because .align fill unused space with zeroes. */
8274 unicosmk_output_align (file, align)
8278 if (inside_function)
8279 fprintf (file, "\tgcc@code@align\t%d\n", align);
8281 fprintf (file, "\t.align\t%d\n", align);
8284 /* Add a case vector to the current function's list of deferred case
8285 vectors. Case vectors have to be put into a separate section because CAM
8286 does not allow data definitions in code sections. */
8289 unicosmk_defer_case_vector (lab, vec)
8293 struct machine_function *machine = cfun->machine;
8295 vec = gen_rtx_EXPR_LIST (VOIDmode, lab, vec);
8296 machine->addr_list = gen_rtx_EXPR_LIST (VOIDmode, vec,
8297 machine->addr_list);
8300 /* Output a case vector. */
8303 unicosmk_output_addr_vec (file, vec)
8307 rtx lab = XEXP (vec, 0);
8308 rtx body = XEXP (vec, 1);
8309 int vlen = XVECLEN (body, 0);
8312 ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (lab));
8314 for (idx = 0; idx < vlen; idx++)
8316 ASM_OUTPUT_ADDR_VEC_ELT
8317 (file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0)));
8321 /* Output current function's deferred case vectors. */
8324 unicosmk_output_deferred_case_vectors (file)
8327 struct machine_function *machine = cfun->machine;
8330 if (machine->addr_list == NULL_RTX)
8334 for (t = machine->addr_list; t; t = XEXP (t, 1))
8335 unicosmk_output_addr_vec (file, XEXP (t, 0));
8338 /* Set up the dynamic subprogram information block (DSIB) and update the
8339 frame pointer register ($15) for subroutines which have a frame. If the
8340 subroutine doesn't have a frame, simply increment $15. */
8343 unicosmk_gen_dsib (imaskP)
8344 unsigned long * imaskP;
8346 if (alpha_is_stack_procedure)
8348 const char *ssib_name;
8351 /* Allocate 64 bytes for the DSIB. */
8353 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
8355 emit_insn (gen_blockage ());
8357 /* Save the return address. */
8359 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 56));
8360 set_mem_alias_set (mem, alpha_sr_alias_set);
8361 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
8362 (*imaskP) &= ~(1L << REG_RA);
8364 /* Save the old frame pointer. */
8366 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 48));
8367 set_mem_alias_set (mem, alpha_sr_alias_set);
8368 FRP (emit_move_insn (mem, hard_frame_pointer_rtx));
8369 (*imaskP) &= ~(1L << HARD_FRAME_POINTER_REGNUM);
8371 emit_insn (gen_blockage ());
8373 /* Store the SSIB pointer. */
8375 ssib_name = ggc_strdup (unicosmk_ssib_name ());
8376 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 32));
8377 set_mem_alias_set (mem, alpha_sr_alias_set);
8379 FRP (emit_move_insn (gen_rtx_REG (DImode, 5),
8380 gen_rtx_SYMBOL_REF (Pmode, ssib_name)));
8381 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, 5)));
8383 /* Save the CIW index. */
8385 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 24));
8386 set_mem_alias_set (mem, alpha_sr_alias_set);
8387 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, 25)));
8389 emit_insn (gen_blockage ());
8391 /* Set the new frame pointer. */
8393 FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
8394 stack_pointer_rtx, GEN_INT (64))));
8399 /* Increment the frame pointer register to indicate that we do not
8402 FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
8403 hard_frame_pointer_rtx, GEN_INT (1))));
8407 #define SSIB_PREFIX "__SSIB_"
8408 #define SSIB_PREFIX_LEN 7
8410 /* Generate the name of the SSIB section for the current function. */
8413 unicosmk_ssib_name ()
8415 /* This is ok since CAM won't be able to deal with names longer than that
8418 static char name[256];
8425 x = DECL_RTL (cfun->decl);
8426 if (GET_CODE (x) != MEM)
8429 if (GET_CODE (x) != SYMBOL_REF)
8431 fnname = XSTR (x, 0);
8432 STRIP_NAME_ENCODING (fnname, fnname);
8434 len = strlen (fnname);
8435 if (len + SSIB_PREFIX_LEN > 255)
8436 len = 255 - SSIB_PREFIX_LEN;
8438 strcpy (name, SSIB_PREFIX);
8439 strncpy (name + SSIB_PREFIX_LEN, fnname, len);
8440 name[len + SSIB_PREFIX_LEN] = 0;
8445 /* Output the static subroutine information block for the current
8449 unicosmk_output_ssib (file, fnname)
8457 struct machine_function *machine = cfun->machine;
8460 fprintf (file, "\t.endp\n\n\t.psect\t%s%s,data\n", user_label_prefix,
8461 unicosmk_ssib_name ());
8463 /* Some required stuff and the function name length. */
8465 len = strlen (fnname);
8466 fprintf (file, "\t.quad\t^X20008%2.2X28\n", len);
8469 ??? We don't do that yet. */
8471 fputs ("\t.quad\t0\n", file);
8473 /* Function address. */
8475 fputs ("\t.quad\t", file);
8476 assemble_name (file, fnname);
8479 fputs ("\t.quad\t0\n", file);
8480 fputs ("\t.quad\t0\n", file);
8483 ??? We do it the same way Cray CC does it but this could be
8486 for( i = 0; i < len; i++ )
8487 fprintf (file, "\t.byte\t%d\n", (int)(fnname[i]));
8488 if( (len % 8) == 0 )
8489 fputs ("\t.quad\t0\n", file);
8491 fprintf (file, "\t.bits\t%d : 0\n", (8 - (len % 8))*8);
8493 /* All call information words used in the function. */
8495 for (x = machine->first_ciw; x; x = XEXP (x, 1))
8498 fprintf (file, "\t.quad\t");
8499 #if HOST_BITS_PER_WIDE_INT == 32
8500 fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
8501 CONST_DOUBLE_HIGH (ciw), CONST_DOUBLE_LOW (ciw));
8503 fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (ciw));
8505 fprintf (file, "\n");
8509 /* Add a call information word (CIW) to the list of the current function's
8510 CIWs and return its index.
8512 X is a CONST_INT or CONST_DOUBLE representing the CIW. */
8515 unicosmk_add_call_info_word (x)
8519 struct machine_function *machine = cfun->machine;
8521 node = gen_rtx_EXPR_LIST (VOIDmode, x, NULL_RTX);
8522 if (machine->first_ciw == NULL_RTX)
8523 machine->first_ciw = node;
8525 XEXP (machine->last_ciw, 1) = node;
8527 machine->last_ciw = node;
8528 ++machine->ciw_count;
8530 return GEN_INT (machine->ciw_count
8531 + strlen (current_function_name)/8 + 5);
8534 static char unicosmk_section_buf[100];
8537 unicosmk_text_section ()
8539 static int count = 0;
8540 sprintf (unicosmk_section_buf, "\t.endp\n\n\t.psect\tgcc@text___%d,code",
8542 return unicosmk_section_buf;
8546 unicosmk_data_section ()
8548 static int count = 1;
8549 sprintf (unicosmk_section_buf, "\t.endp\n\n\t.psect\tgcc@data___%d,data",
8551 return unicosmk_section_buf;
8554 /* The Cray assembler doesn't accept extern declarations for symbols which
8555 are defined in the same file. We have to keep track of all global
8556 symbols which are referenced and/or defined in a source file and output
8557 extern declarations for those which are referenced but not defined at
8560 /* List of identifiers for which an extern declaration might have to be
8563 struct unicosmk_extern_list
8565 struct unicosmk_extern_list *next;
8569 static struct unicosmk_extern_list *unicosmk_extern_head = 0;
8571 /* Output extern declarations which are required for every asm file. */
8574 unicosmk_output_default_externs (file)
8577 static const char *const externs[] =
8578 { "__T3E_MISMATCH" };
8583 n = ARRAY_SIZE (externs);
8585 for (i = 0; i < n; i++)
8586 fprintf (file, "\t.extern\t%s\n", externs[i]);
8589 /* Output extern declarations for global symbols which are have been
8590 referenced but not defined. */
8593 unicosmk_output_externs (file)
8596 struct unicosmk_extern_list *p;
8597 const char *real_name;
8601 len = strlen (user_label_prefix);
8602 for (p = unicosmk_extern_head; p != 0; p = p->next)
8604 /* We have to strip the encoding and possibly remove user_label_prefix
8605 from the identifier in order to handle -fleading-underscore and
8606 explicit asm names correctly (cf. gcc.dg/asm-names-1.c). */
8607 STRIP_NAME_ENCODING (real_name, p->name);
8608 if (len && p->name[0] == '*'
8609 && !memcmp (real_name, user_label_prefix, len))
8612 name_tree = get_identifier (real_name);
8613 if (! TREE_ASM_WRITTEN (name_tree))
8615 TREE_ASM_WRITTEN (name_tree) = 1;
8616 fputs ("\t.extern\t", file);
8617 assemble_name (file, p->name);
8623 /* Record an extern. */
8626 unicosmk_add_extern (name)
8629 struct unicosmk_extern_list *p;
8631 p = (struct unicosmk_extern_list *)
8632 permalloc (sizeof (struct unicosmk_extern_list));
8633 p->next = unicosmk_extern_head;
8635 unicosmk_extern_head = p;
8638 /* The Cray assembler generates incorrect code if identifiers which
8639 conflict with register names are used as instruction operands. We have
8640 to replace such identifiers with DEX expressions. */
8642 /* Structure to collect identifiers which have been replaced by DEX
8645 struct unicosmk_dex {
8646 struct unicosmk_dex *next;
8650 /* List of identifiers which have been replaced by DEX expressions. The DEX
8651 number is determined by the position in the list. */
8653 static struct unicosmk_dex *unicosmk_dex_list = NULL;
8655 /* The number of elements in the DEX list. */
8657 static int unicosmk_dex_count = 0;
8659 /* Check if NAME must be replaced by a DEX expression. */
8662 unicosmk_special_name (name)
8671 if (name[0] != 'r' && name[0] != 'f' && name[0] != 'R' && name[0] != 'F')
8677 return (name[2] == '\0' || (ISDIGIT (name[2]) && name[3] == '\0'));
8680 return (name[2] == '\0'
8681 || ((name[2] == '0' || name[2] == '1') && name[3] == '\0'));
8684 return (ISDIGIT (name[1]) && name[2] == '\0');
8688 /* Return the DEX number if X must be replaced by a DEX expression and 0
8692 unicosmk_need_dex (x)
8695 struct unicosmk_dex *dex;
8699 if (GET_CODE (x) != SYMBOL_REF)
8703 if (! unicosmk_special_name (name))
8706 i = unicosmk_dex_count;
8707 for (dex = unicosmk_dex_list; dex; dex = dex->next)
8709 if (! strcmp (name, dex->name))
8714 dex = (struct unicosmk_dex *) permalloc (sizeof (struct unicosmk_dex));
8716 dex->next = unicosmk_dex_list;
8717 unicosmk_dex_list = dex;
8719 ++unicosmk_dex_count;
8720 return unicosmk_dex_count;
8723 /* Output the DEX definitions for this file. */
8726 unicosmk_output_dex (file)
8729 struct unicosmk_dex *dex;
8732 if (unicosmk_dex_list == NULL)
8735 fprintf (file, "\t.dexstart\n");
8737 i = unicosmk_dex_count;
8738 for (dex = unicosmk_dex_list; dex; dex = dex->next)
8740 fprintf (file, "\tDEX (%d) = ", i);
8741 assemble_name (file, dex->name);
8746 fprintf (file, "\t.dexend\n");
8752 unicosmk_output_deferred_case_vectors (file)
8753 FILE *file ATTRIBUTE_UNUSED;
8757 unicosmk_gen_dsib (imaskP)
8758 unsigned long * imaskP ATTRIBUTE_UNUSED;
8762 unicosmk_output_ssib (file, fnname)
8763 FILE * file ATTRIBUTE_UNUSED;
8764 const char * fnname ATTRIBUTE_UNUSED;
8768 unicosmk_add_call_info_word (x)
8769 rtx x ATTRIBUTE_UNUSED;
8775 unicosmk_need_dex (x)
8776 rtx x ATTRIBUTE_UNUSED;
8781 #endif /* TARGET_ABI_UNICOSMK */