alpha.c (print_operand_address): Fix format specifier warnings.
[gcc.git] / gcc / config / alpha / alpha.c
1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5
6 This file is part of GNU CC.
7
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)
11 any later version.
12
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.
17
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. */
22
23
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "regs.h"
31 #include "hard-reg-set.h"
32 #include "real.h"
33 #include "insn-config.h"
34 #include "conditions.h"
35 #include "output.h"
36 #include "insn-attr.h"
37 #include "flags.h"
38 #include "recog.h"
39 #include "expr.h"
40 #include "optabs.h"
41 #include "reload.h"
42 #include "obstack.h"
43 #include "except.h"
44 #include "function.h"
45 #include "toplev.h"
46 #include "ggc.h"
47 #include "integrate.h"
48 #include "tm_p.h"
49 #include "target.h"
50 #include "target-def.h"
51 #include "debug.h"
52 #include "langhooks.h"
53 #include <splay-tree.h>
54
55 /* Specify which cpu to schedule for. */
56
57 enum processor_type alpha_cpu;
58 static const char * const alpha_cpu_name[] =
59 {
60 "ev4", "ev5", "ev6"
61 };
62
63 /* Specify how accurate floating-point traps need to be. */
64
65 enum alpha_trap_precision alpha_tp;
66
67 /* Specify the floating-point rounding mode. */
68
69 enum alpha_fp_rounding_mode alpha_fprm;
70
71 /* Specify which things cause traps. */
72
73 enum alpha_fp_trap_mode alpha_fptm;
74
75 /* Specify bit size of immediate TLS offsets. */
76
77 int alpha_tls_size = 32;
78
79 /* Strings decoded into the above options. */
80
81 const char *alpha_cpu_string; /* -mcpu= */
82 const char *alpha_tune_string; /* -mtune= */
83 const char *alpha_tp_string; /* -mtrap-precision=[p|s|i] */
84 const char *alpha_fprm_string; /* -mfp-rounding-mode=[n|m|c|d] */
85 const char *alpha_fptm_string; /* -mfp-trap-mode=[n|u|su|sui] */
86 const char *alpha_mlat_string; /* -mmemory-latency= */
87 const char *alpha_tls_size_string; /* -mtls-size=[16|32|64] */
88
89 /* Save information from a "cmpxx" operation until the branch or scc is
90 emitted. */
91
92 struct alpha_compare alpha_compare;
93
94 /* Nonzero if inside of a function, because the Alpha asm can't
95 handle .files inside of functions. */
96
97 static int inside_function = FALSE;
98
99 /* The number of cycles of latency we should assume on memory reads. */
100
101 int alpha_memory_latency = 3;
102
103 /* Whether the function needs the GP. */
104
105 static int alpha_function_needs_gp;
106
107 /* The alias set for prologue/epilogue register save/restore. */
108
109 static GTY(()) int alpha_sr_alias_set;
110
111 /* The assembler name of the current function. */
112
113 static const char *alpha_fnname;
114
115 /* The next explicit relocation sequence number. */
116 extern GTY(()) int alpha_next_sequence_number;
117 int alpha_next_sequence_number = 1;
118
119 /* The literal and gpdisp sequence numbers for this insn, as printed
120 by %# and %* respectively. */
121 extern GTY(()) int alpha_this_literal_sequence_number;
122 extern GTY(()) int alpha_this_gpdisp_sequence_number;
123 int alpha_this_literal_sequence_number;
124 int alpha_this_gpdisp_sequence_number;
125
126 /* Costs of various operations on the different architectures. */
127
128 struct alpha_rtx_cost_data
129 {
130 unsigned char fp_add;
131 unsigned char fp_mult;
132 unsigned char fp_div_sf;
133 unsigned char fp_div_df;
134 unsigned char int_mult_si;
135 unsigned char int_mult_di;
136 unsigned char int_shift;
137 unsigned char int_cmov;
138 };
139
140 static struct alpha_rtx_cost_data const alpha_rtx_cost_data[PROCESSOR_MAX] =
141 {
142 { /* EV4 */
143 COSTS_N_INSNS (6), /* fp_add */
144 COSTS_N_INSNS (6), /* fp_mult */
145 COSTS_N_INSNS (34), /* fp_div_sf */
146 COSTS_N_INSNS (63), /* fp_div_df */
147 COSTS_N_INSNS (23), /* int_mult_si */
148 COSTS_N_INSNS (23), /* int_mult_di */
149 COSTS_N_INSNS (2), /* int_shift */
150 COSTS_N_INSNS (2), /* int_cmov */
151 },
152 { /* EV5 */
153 COSTS_N_INSNS (4), /* fp_add */
154 COSTS_N_INSNS (4), /* fp_mult */
155 COSTS_N_INSNS (15), /* fp_div_sf */
156 COSTS_N_INSNS (22), /* fp_div_df */
157 COSTS_N_INSNS (8), /* int_mult_si */
158 COSTS_N_INSNS (12), /* int_mult_di */
159 COSTS_N_INSNS (1) + 1, /* int_shift */
160 COSTS_N_INSNS (1), /* int_cmov */
161 },
162 { /* EV6 */
163 COSTS_N_INSNS (4), /* fp_add */
164 COSTS_N_INSNS (4), /* fp_mult */
165 COSTS_N_INSNS (12), /* fp_div_sf */
166 COSTS_N_INSNS (15), /* fp_div_df */
167 COSTS_N_INSNS (7), /* int_mult_si */
168 COSTS_N_INSNS (7), /* int_mult_di */
169 COSTS_N_INSNS (1), /* int_shift */
170 COSTS_N_INSNS (2), /* int_cmov */
171 },
172 };
173
174 /* Declarations of static functions. */
175 static bool alpha_function_ok_for_sibcall
176 PARAMS ((tree, tree));
177 static int tls_symbolic_operand_1
178 PARAMS ((rtx, enum machine_mode, int, int));
179 static enum tls_model tls_symbolic_operand_type
180 PARAMS ((rtx));
181 static bool decl_has_samegp
182 PARAMS ((tree));
183 static bool alpha_in_small_data_p
184 PARAMS ((tree));
185 static rtx get_tls_get_addr
186 PARAMS ((void));
187 static int some_small_symbolic_operand_1
188 PARAMS ((rtx *, void *));
189 static int split_small_symbolic_operand_1
190 PARAMS ((rtx *, void *));
191 static bool alpha_cannot_copy_insn_p
192 PARAMS ((rtx));
193 static bool alpha_rtx_costs
194 PARAMS ((rtx, int, int, int *));
195 static void alpha_set_memflags_1
196 PARAMS ((rtx, int, int, int));
197 static rtx alpha_emit_set_const_1
198 PARAMS ((rtx, enum machine_mode, HOST_WIDE_INT, int));
199 static void alpha_expand_unaligned_load_words
200 PARAMS ((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
201 static void alpha_expand_unaligned_store_words
202 PARAMS ((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
203 static void alpha_init_builtins
204 PARAMS ((void));
205 static rtx alpha_expand_builtin
206 PARAMS ((tree, rtx, rtx, enum machine_mode, int));
207 static void alpha_sa_mask
208 PARAMS ((unsigned long *imaskP, unsigned long *fmaskP));
209 static int find_lo_sum_using_gp
210 PARAMS ((rtx *, void *));
211 static int alpha_does_function_need_gp
212 PARAMS ((void));
213 static int alpha_ra_ever_killed
214 PARAMS ((void));
215 static const char *get_trap_mode_suffix
216 PARAMS ((void));
217 static const char *get_round_mode_suffix
218 PARAMS ((void));
219 static const char *get_some_local_dynamic_name
220 PARAMS ((void));
221 static int get_some_local_dynamic_name_1
222 PARAMS ((rtx *, void *));
223 static rtx set_frame_related_p
224 PARAMS ((void));
225 static const char *alpha_lookup_xfloating_lib_func
226 PARAMS ((enum rtx_code));
227 static int alpha_compute_xfloating_mode_arg
228 PARAMS ((enum rtx_code, enum alpha_fp_rounding_mode));
229 static void alpha_emit_xfloating_libcall
230 PARAMS ((const char *, rtx, rtx[], int, rtx));
231 static rtx alpha_emit_xfloating_compare
232 PARAMS ((enum rtx_code, rtx, rtx));
233 static void alpha_output_function_end_prologue
234 PARAMS ((FILE *));
235 static int alpha_adjust_cost
236 PARAMS ((rtx, rtx, rtx, int));
237 static int alpha_issue_rate
238 PARAMS ((void));
239 static int alpha_use_dfa_pipeline_interface
240 PARAMS ((void));
241 static int alpha_multipass_dfa_lookahead
242 PARAMS ((void));
243 static void alpha_reorg
244 PARAMS ((void));
245
246 #ifdef OBJECT_FORMAT_ELF
247 static void alpha_elf_select_rtx_section
248 PARAMS ((enum machine_mode, rtx, unsigned HOST_WIDE_INT));
249 #endif
250
251 #if TARGET_ABI_OPEN_VMS
252 static bool alpha_linkage_symbol_p
253 PARAMS ((const char *symname));
254 static int alpha_write_one_linkage
255 PARAMS ((splay_tree_node, void *));
256 static void alpha_write_linkage
257 PARAMS ((FILE *, const char *, tree));
258 #endif
259
260 #if TARGET_ABI_OSF
261 static void alpha_output_mi_thunk_osf
262 PARAMS ((FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree));
263 #endif
264
265 static struct machine_function * alpha_init_machine_status
266 PARAMS ((void));
267
268 static void unicosmk_output_deferred_case_vectors PARAMS ((FILE *));
269 static void unicosmk_gen_dsib PARAMS ((unsigned long *imaskP));
270 static void unicosmk_output_ssib PARAMS ((FILE *, const char *));
271 static int unicosmk_need_dex PARAMS ((rtx));
272
273 /* Get the number of args of a function in one of two ways. */
274 #if TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK
275 #define NUM_ARGS current_function_args_info.num_args
276 #else
277 #define NUM_ARGS current_function_args_info
278 #endif
279
280 #define REG_PV 27
281 #define REG_RA 26
282 \f
283 /* Initialize the GCC target structure. */
284 #if TARGET_ABI_OPEN_VMS
285 const struct attribute_spec vms_attribute_table[];
286 static unsigned int vms_section_type_flags PARAMS ((tree, const char *, int));
287 static void vms_asm_named_section PARAMS ((const char *, unsigned int));
288 static void vms_asm_out_constructor PARAMS ((rtx, int));
289 static void vms_asm_out_destructor PARAMS ((rtx, int));
290 # undef TARGET_ATTRIBUTE_TABLE
291 # define TARGET_ATTRIBUTE_TABLE vms_attribute_table
292 # undef TARGET_SECTION_TYPE_FLAGS
293 # define TARGET_SECTION_TYPE_FLAGS vms_section_type_flags
294 #endif
295
296 #undef TARGET_IN_SMALL_DATA_P
297 #define TARGET_IN_SMALL_DATA_P alpha_in_small_data_p
298
299 #if TARGET_ABI_UNICOSMK
300 static void unicosmk_asm_named_section PARAMS ((const char *, unsigned int));
301 static void unicosmk_insert_attributes PARAMS ((tree, tree *));
302 static unsigned int unicosmk_section_type_flags PARAMS ((tree, const char *,
303 int));
304 static void unicosmk_unique_section PARAMS ((tree, int));
305 # undef TARGET_INSERT_ATTRIBUTES
306 # define TARGET_INSERT_ATTRIBUTES unicosmk_insert_attributes
307 # undef TARGET_SECTION_TYPE_FLAGS
308 # define TARGET_SECTION_TYPE_FLAGS unicosmk_section_type_flags
309 # undef TARGET_ASM_UNIQUE_SECTION
310 # define TARGET_ASM_UNIQUE_SECTION unicosmk_unique_section
311 # undef TARGET_ASM_GLOBALIZE_LABEL
312 # define TARGET_ASM_GLOBALIZE_LABEL hook_FILEptr_constcharptr_void
313 #endif
314
315 #undef TARGET_ASM_ALIGNED_HI_OP
316 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
317 #undef TARGET_ASM_ALIGNED_DI_OP
318 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
319
320 /* Default unaligned ops are provided for ELF systems. To get unaligned
321 data for non-ELF systems, we have to turn off auto alignment. */
322 #ifndef OBJECT_FORMAT_ELF
323 #undef TARGET_ASM_UNALIGNED_HI_OP
324 #define TARGET_ASM_UNALIGNED_HI_OP "\t.align 0\n\t.word\t"
325 #undef TARGET_ASM_UNALIGNED_SI_OP
326 #define TARGET_ASM_UNALIGNED_SI_OP "\t.align 0\n\t.long\t"
327 #undef TARGET_ASM_UNALIGNED_DI_OP
328 #define TARGET_ASM_UNALIGNED_DI_OP "\t.align 0\n\t.quad\t"
329 #endif
330
331 #ifdef OBJECT_FORMAT_ELF
332 #undef TARGET_ASM_SELECT_RTX_SECTION
333 #define TARGET_ASM_SELECT_RTX_SECTION alpha_elf_select_rtx_section
334 #endif
335
336 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
337 #define TARGET_ASM_FUNCTION_END_PROLOGUE alpha_output_function_end_prologue
338
339 #undef TARGET_SCHED_ADJUST_COST
340 #define TARGET_SCHED_ADJUST_COST alpha_adjust_cost
341 #undef TARGET_SCHED_ISSUE_RATE
342 #define TARGET_SCHED_ISSUE_RATE alpha_issue_rate
343 #undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
344 #define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE \
345 alpha_use_dfa_pipeline_interface
346 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
347 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
348 alpha_multipass_dfa_lookahead
349
350 #undef TARGET_HAVE_TLS
351 #define TARGET_HAVE_TLS HAVE_AS_TLS
352
353 #undef TARGET_INIT_BUILTINS
354 #define TARGET_INIT_BUILTINS alpha_init_builtins
355 #undef TARGET_EXPAND_BUILTIN
356 #define TARGET_EXPAND_BUILTIN alpha_expand_builtin
357
358 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
359 #define TARGET_FUNCTION_OK_FOR_SIBCALL alpha_function_ok_for_sibcall
360 #undef TARGET_CANNOT_COPY_INSN_P
361 #define TARGET_CANNOT_COPY_INSN_P alpha_cannot_copy_insn_p
362
363 #if TARGET_ABI_OSF
364 #undef TARGET_ASM_OUTPUT_MI_THUNK
365 #define TARGET_ASM_OUTPUT_MI_THUNK alpha_output_mi_thunk_osf
366 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
367 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
368 #endif
369
370 #undef TARGET_RTX_COSTS
371 #define TARGET_RTX_COSTS alpha_rtx_costs
372 #undef TARGET_ADDRESS_COST
373 #define TARGET_ADDRESS_COST hook_int_rtx_0
374
375 #undef TARGET_MACHINE_DEPENDENT_REORG
376 #define TARGET_MACHINE_DEPENDENT_REORG alpha_reorg
377
378 struct gcc_target targetm = TARGET_INITIALIZER;
379 \f
380 /* Parse target option strings. */
381
382 void
383 override_options ()
384 {
385 int i;
386 static const struct cpu_table {
387 const char *const name;
388 const enum processor_type processor;
389 const int flags;
390 } cpu_table[] = {
391 #define EV5_MASK (MASK_CPU_EV5)
392 #define EV6_MASK (MASK_CPU_EV6|MASK_BWX|MASK_MAX|MASK_FIX)
393 { "ev4", PROCESSOR_EV4, 0 },
394 { "ev45", PROCESSOR_EV4, 0 },
395 { "21064", PROCESSOR_EV4, 0 },
396 { "ev5", PROCESSOR_EV5, EV5_MASK },
397 { "21164", PROCESSOR_EV5, EV5_MASK },
398 { "ev56", PROCESSOR_EV5, EV5_MASK|MASK_BWX },
399 { "21164a", PROCESSOR_EV5, EV5_MASK|MASK_BWX },
400 { "pca56", PROCESSOR_EV5, EV5_MASK|MASK_BWX|MASK_MAX },
401 { "21164PC",PROCESSOR_EV5, EV5_MASK|MASK_BWX|MASK_MAX },
402 { "21164pc",PROCESSOR_EV5, EV5_MASK|MASK_BWX|MASK_MAX },
403 { "ev6", PROCESSOR_EV6, EV6_MASK },
404 { "21264", PROCESSOR_EV6, EV6_MASK },
405 { "ev67", PROCESSOR_EV6, EV6_MASK|MASK_CIX },
406 { "21264a", PROCESSOR_EV6, EV6_MASK|MASK_CIX },
407 { 0, 0, 0 }
408 };
409
410 /* Unicos/Mk doesn't have shared libraries. */
411 if (TARGET_ABI_UNICOSMK && flag_pic)
412 {
413 warning ("-f%s ignored for Unicos/Mk (not supported)",
414 (flag_pic > 1) ? "PIC" : "pic");
415 flag_pic = 0;
416 }
417
418 /* On Unicos/Mk, the native compiler consistenly generates /d suffices for
419 floating-point instructions. Make that the default for this target. */
420 if (TARGET_ABI_UNICOSMK)
421 alpha_fprm = ALPHA_FPRM_DYN;
422 else
423 alpha_fprm = ALPHA_FPRM_NORM;
424
425 alpha_tp = ALPHA_TP_PROG;
426 alpha_fptm = ALPHA_FPTM_N;
427
428 /* We cannot use su and sui qualifiers for conversion instructions on
429 Unicos/Mk. I'm not sure if this is due to assembler or hardware
430 limitations. Right now, we issue a warning if -mieee is specified
431 and then ignore it; eventually, we should either get it right or
432 disable the option altogether. */
433
434 if (TARGET_IEEE)
435 {
436 if (TARGET_ABI_UNICOSMK)
437 warning ("-mieee not supported on Unicos/Mk");
438 else
439 {
440 alpha_tp = ALPHA_TP_INSN;
441 alpha_fptm = ALPHA_FPTM_SU;
442 }
443 }
444
445 if (TARGET_IEEE_WITH_INEXACT)
446 {
447 if (TARGET_ABI_UNICOSMK)
448 warning ("-mieee-with-inexact not supported on Unicos/Mk");
449 else
450 {
451 alpha_tp = ALPHA_TP_INSN;
452 alpha_fptm = ALPHA_FPTM_SUI;
453 }
454 }
455
456 if (alpha_tp_string)
457 {
458 if (! strcmp (alpha_tp_string, "p"))
459 alpha_tp = ALPHA_TP_PROG;
460 else if (! strcmp (alpha_tp_string, "f"))
461 alpha_tp = ALPHA_TP_FUNC;
462 else if (! strcmp (alpha_tp_string, "i"))
463 alpha_tp = ALPHA_TP_INSN;
464 else
465 error ("bad value `%s' for -mtrap-precision switch", alpha_tp_string);
466 }
467
468 if (alpha_fprm_string)
469 {
470 if (! strcmp (alpha_fprm_string, "n"))
471 alpha_fprm = ALPHA_FPRM_NORM;
472 else if (! strcmp (alpha_fprm_string, "m"))
473 alpha_fprm = ALPHA_FPRM_MINF;
474 else if (! strcmp (alpha_fprm_string, "c"))
475 alpha_fprm = ALPHA_FPRM_CHOP;
476 else if (! strcmp (alpha_fprm_string,"d"))
477 alpha_fprm = ALPHA_FPRM_DYN;
478 else
479 error ("bad value `%s' for -mfp-rounding-mode switch",
480 alpha_fprm_string);
481 }
482
483 if (alpha_fptm_string)
484 {
485 if (strcmp (alpha_fptm_string, "n") == 0)
486 alpha_fptm = ALPHA_FPTM_N;
487 else if (strcmp (alpha_fptm_string, "u") == 0)
488 alpha_fptm = ALPHA_FPTM_U;
489 else if (strcmp (alpha_fptm_string, "su") == 0)
490 alpha_fptm = ALPHA_FPTM_SU;
491 else if (strcmp (alpha_fptm_string, "sui") == 0)
492 alpha_fptm = ALPHA_FPTM_SUI;
493 else
494 error ("bad value `%s' for -mfp-trap-mode switch", alpha_fptm_string);
495 }
496
497 if (alpha_tls_size_string)
498 {
499 if (strcmp (alpha_tls_size_string, "16") == 0)
500 alpha_tls_size = 16;
501 else if (strcmp (alpha_tls_size_string, "32") == 0)
502 alpha_tls_size = 32;
503 else if (strcmp (alpha_tls_size_string, "64") == 0)
504 alpha_tls_size = 64;
505 else
506 error ("bad value `%s' for -mtls-size switch", alpha_tls_size_string);
507 }
508
509 alpha_cpu
510 = TARGET_CPU_DEFAULT & MASK_CPU_EV6 ? PROCESSOR_EV6
511 : (TARGET_CPU_DEFAULT & MASK_CPU_EV5 ? PROCESSOR_EV5 : PROCESSOR_EV4);
512
513 if (alpha_cpu_string)
514 {
515 for (i = 0; cpu_table [i].name; i++)
516 if (! strcmp (alpha_cpu_string, cpu_table [i].name))
517 {
518 alpha_cpu = cpu_table [i].processor;
519 target_flags &= ~ (MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX
520 | MASK_CPU_EV5 | MASK_CPU_EV6);
521 target_flags |= cpu_table [i].flags;
522 break;
523 }
524 if (! cpu_table [i].name)
525 error ("bad value `%s' for -mcpu switch", alpha_cpu_string);
526 }
527
528 if (alpha_tune_string)
529 {
530 for (i = 0; cpu_table [i].name; i++)
531 if (! strcmp (alpha_tune_string, cpu_table [i].name))
532 {
533 alpha_cpu = cpu_table [i].processor;
534 break;
535 }
536 if (! cpu_table [i].name)
537 error ("bad value `%s' for -mcpu switch", alpha_tune_string);
538 }
539
540 /* Do some sanity checks on the above options. */
541
542 if (TARGET_ABI_UNICOSMK && alpha_fptm != ALPHA_FPTM_N)
543 {
544 warning ("trap mode not supported on Unicos/Mk");
545 alpha_fptm = ALPHA_FPTM_N;
546 }
547
548 if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI)
549 && alpha_tp != ALPHA_TP_INSN && ! TARGET_CPU_EV6)
550 {
551 warning ("fp software completion requires -mtrap-precision=i");
552 alpha_tp = ALPHA_TP_INSN;
553 }
554
555 if (TARGET_CPU_EV6)
556 {
557 /* Except for EV6 pass 1 (not released), we always have precise
558 arithmetic traps. Which means we can do software completion
559 without minding trap shadows. */
560 alpha_tp = ALPHA_TP_PROG;
561 }
562
563 if (TARGET_FLOAT_VAX)
564 {
565 if (alpha_fprm == ALPHA_FPRM_MINF || alpha_fprm == ALPHA_FPRM_DYN)
566 {
567 warning ("rounding mode not supported for VAX floats");
568 alpha_fprm = ALPHA_FPRM_NORM;
569 }
570 if (alpha_fptm == ALPHA_FPTM_SUI)
571 {
572 warning ("trap mode not supported for VAX floats");
573 alpha_fptm = ALPHA_FPTM_SU;
574 }
575 }
576
577 {
578 char *end;
579 int lat;
580
581 if (!alpha_mlat_string)
582 alpha_mlat_string = "L1";
583
584 if (ISDIGIT ((unsigned char)alpha_mlat_string[0])
585 && (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0'))
586 ;
587 else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l')
588 && ISDIGIT ((unsigned char)alpha_mlat_string[1])
589 && alpha_mlat_string[2] == '\0')
590 {
591 static int const cache_latency[][4] =
592 {
593 { 3, 30, -1 }, /* ev4 -- Bcache is a guess */
594 { 2, 12, 38 }, /* ev5 -- Bcache from PC164 LMbench numbers */
595 { 3, 12, 30 }, /* ev6 -- Bcache from DS20 LMbench. */
596 };
597
598 lat = alpha_mlat_string[1] - '0';
599 if (lat <= 0 || lat > 3 || cache_latency[alpha_cpu][lat-1] == -1)
600 {
601 warning ("L%d cache latency unknown for %s",
602 lat, alpha_cpu_name[alpha_cpu]);
603 lat = 3;
604 }
605 else
606 lat = cache_latency[alpha_cpu][lat-1];
607 }
608 else if (! strcmp (alpha_mlat_string, "main"))
609 {
610 /* Most current memories have about 370ns latency. This is
611 a reasonable guess for a fast cpu. */
612 lat = 150;
613 }
614 else
615 {
616 warning ("bad value `%s' for -mmemory-latency", alpha_mlat_string);
617 lat = 3;
618 }
619
620 alpha_memory_latency = lat;
621 }
622
623 /* Default the definition of "small data" to 8 bytes. */
624 if (!g_switch_set)
625 g_switch_value = 8;
626
627 /* Infer TARGET_SMALL_DATA from -fpic/-fPIC. */
628 if (flag_pic == 1)
629 target_flags |= MASK_SMALL_DATA;
630 else if (flag_pic == 2)
631 target_flags &= ~MASK_SMALL_DATA;
632
633 /* Align labels and loops for optimal branching. */
634 /* ??? Kludge these by not doing anything if we don't optimize and also if
635 we are writing ECOFF symbols to work around a bug in DEC's assembler. */
636 if (optimize > 0 && write_symbols != SDB_DEBUG)
637 {
638 if (align_loops <= 0)
639 align_loops = 16;
640 if (align_jumps <= 0)
641 align_jumps = 16;
642 }
643 if (align_functions <= 0)
644 align_functions = 16;
645
646 /* Acquire a unique set number for our register saves and restores. */
647 alpha_sr_alias_set = new_alias_set ();
648
649 /* Register variables and functions with the garbage collector. */
650
651 /* Set up function hooks. */
652 init_machine_status = alpha_init_machine_status;
653
654 /* Tell the compiler when we're using VAX floating point. */
655 if (TARGET_FLOAT_VAX)
656 {
657 real_format_for_mode[SFmode - QFmode] = &vax_f_format;
658 real_format_for_mode[DFmode - QFmode] = &vax_g_format;
659 real_format_for_mode[TFmode - QFmode] = NULL;
660 }
661 }
662 \f
663 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
664
665 int
666 zap_mask (value)
667 HOST_WIDE_INT value;
668 {
669 int i;
670
671 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
672 i++, value >>= 8)
673 if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
674 return 0;
675
676 return 1;
677 }
678
679 /* Returns 1 if OP is either the constant zero or a register. If a
680 register, it must be in the proper mode unless MODE is VOIDmode. */
681
682 int
683 reg_or_0_operand (op, mode)
684 register rtx op;
685 enum machine_mode mode;
686 {
687 return op == CONST0_RTX (mode) || register_operand (op, mode);
688 }
689
690 /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
691 any register. */
692
693 int
694 reg_or_6bit_operand (op, mode)
695 register rtx op;
696 enum machine_mode mode;
697 {
698 return ((GET_CODE (op) == CONST_INT
699 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64)
700 || register_operand (op, mode));
701 }
702
703
704 /* Return 1 if OP is an 8-bit constant or any register. */
705
706 int
707 reg_or_8bit_operand (op, mode)
708 register rtx op;
709 enum machine_mode mode;
710 {
711 return ((GET_CODE (op) == CONST_INT
712 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
713 || register_operand (op, mode));
714 }
715
716 /* Return 1 if OP is a constant or any register. */
717
718 int
719 reg_or_const_int_operand (op, mode)
720 register rtx op;
721 enum machine_mode mode;
722 {
723 return GET_CODE (op) == CONST_INT || register_operand (op, mode);
724 }
725
726 /* Return 1 if OP is an 8-bit constant. */
727
728 int
729 cint8_operand (op, mode)
730 register rtx op;
731 enum machine_mode mode ATTRIBUTE_UNUSED;
732 {
733 return ((GET_CODE (op) == CONST_INT
734 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100));
735 }
736
737 /* Return 1 if the operand is a valid second operand to an add insn. */
738
739 int
740 add_operand (op, mode)
741 register rtx op;
742 enum machine_mode mode;
743 {
744 if (GET_CODE (op) == CONST_INT)
745 /* Constraints I, J, O and P are covered by K. */
746 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'K')
747 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
748
749 return register_operand (op, mode);
750 }
751
752 /* Return 1 if the operand is a valid second operand to a sign-extending
753 add insn. */
754
755 int
756 sext_add_operand (op, mode)
757 register rtx op;
758 enum machine_mode mode;
759 {
760 if (GET_CODE (op) == CONST_INT)
761 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
762 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'O'));
763
764 return reg_not_elim_operand (op, mode);
765 }
766
767 /* Return 1 if OP is the constant 4 or 8. */
768
769 int
770 const48_operand (op, mode)
771 register rtx op;
772 enum machine_mode mode ATTRIBUTE_UNUSED;
773 {
774 return (GET_CODE (op) == CONST_INT
775 && (INTVAL (op) == 4 || INTVAL (op) == 8));
776 }
777
778 /* Return 1 if OP is a valid first operand to an AND insn. */
779
780 int
781 and_operand (op, mode)
782 register rtx op;
783 enum machine_mode mode;
784 {
785 if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
786 return (zap_mask (CONST_DOUBLE_LOW (op))
787 && zap_mask (CONST_DOUBLE_HIGH (op)));
788
789 if (GET_CODE (op) == CONST_INT)
790 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
791 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
792 || zap_mask (INTVAL (op)));
793
794 return register_operand (op, mode);
795 }
796
797 /* Return 1 if OP is a valid first operand to an IOR or XOR insn. */
798
799 int
800 or_operand (op, mode)
801 register rtx op;
802 enum machine_mode mode;
803 {
804 if (GET_CODE (op) == CONST_INT)
805 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
806 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100);
807
808 return register_operand (op, mode);
809 }
810
811 /* Return 1 if OP is a constant that is the width, in bits, of an integral
812 mode smaller than DImode. */
813
814 int
815 mode_width_operand (op, mode)
816 register rtx op;
817 enum machine_mode mode ATTRIBUTE_UNUSED;
818 {
819 return (GET_CODE (op) == CONST_INT
820 && (INTVAL (op) == 8 || INTVAL (op) == 16
821 || INTVAL (op) == 32 || INTVAL (op) == 64));
822 }
823
824 /* Return 1 if OP is a constant that is the width of an integral machine mode
825 smaller than an integer. */
826
827 int
828 mode_mask_operand (op, mode)
829 register rtx op;
830 enum machine_mode mode ATTRIBUTE_UNUSED;
831 {
832 if (GET_CODE (op) == CONST_INT)
833 {
834 HOST_WIDE_INT value = INTVAL (op);
835
836 if (value == 0xff)
837 return 1;
838 if (value == 0xffff)
839 return 1;
840 if (value == 0xffffffff)
841 return 1;
842 if (value == -1)
843 return 1;
844 }
845 else if (HOST_BITS_PER_WIDE_INT == 32 && GET_CODE (op) == CONST_DOUBLE)
846 {
847 if (CONST_DOUBLE_LOW (op) == 0xffffffff && CONST_DOUBLE_HIGH (op) == 0)
848 return 1;
849 }
850
851 return 0;
852 }
853
854 /* Return 1 if OP is a multiple of 8 less than 64. */
855
856 int
857 mul8_operand (op, mode)
858 register rtx op;
859 enum machine_mode mode ATTRIBUTE_UNUSED;
860 {
861 return (GET_CODE (op) == CONST_INT
862 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64
863 && (INTVAL (op) & 7) == 0);
864 }
865
866 /* Return 1 if OP is the zero constant for MODE. */
867
868 int
869 const0_operand (op, mode)
870 register rtx op;
871 enum machine_mode mode;
872 {
873 return op == CONST0_RTX (mode);
874 }
875
876 /* Return 1 if OP is a hard floating-point register. */
877
878 int
879 hard_fp_register_operand (op, mode)
880 register rtx op;
881 enum machine_mode mode;
882 {
883 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
884 return 0;
885
886 if (GET_CODE (op) == SUBREG)
887 op = SUBREG_REG (op);
888 return GET_CODE (op) == REG && REGNO_REG_CLASS (REGNO (op)) == FLOAT_REGS;
889 }
890
891 /* Return 1 if OP is a hard general register. */
892
893 int
894 hard_int_register_operand (op, mode)
895 register rtx op;
896 enum machine_mode mode;
897 {
898 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
899 return 0;
900
901 if (GET_CODE (op) == SUBREG)
902 op = SUBREG_REG (op);
903 return GET_CODE (op) == REG && REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS;
904 }
905
906 /* Return 1 if OP is a register or a constant integer. */
907
908
909 int
910 reg_or_cint_operand (op, mode)
911 register rtx op;
912 enum machine_mode mode;
913 {
914 return (GET_CODE (op) == CONST_INT
915 || register_operand (op, mode));
916 }
917
918 /* Return 1 if OP is something that can be reloaded into a register;
919 if it is a MEM, it need not be valid. */
920
921 int
922 some_operand (op, mode)
923 register rtx op;
924 enum machine_mode mode;
925 {
926 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
927 return 0;
928
929 switch (GET_CODE (op))
930 {
931 case REG:
932 case MEM:
933 case CONST_INT:
934 case CONST_DOUBLE:
935 case CONST_VECTOR:
936 case LABEL_REF:
937 case SYMBOL_REF:
938 case CONST:
939 case HIGH:
940 return 1;
941
942 case SUBREG:
943 return some_operand (SUBREG_REG (op), VOIDmode);
944
945 default:
946 break;
947 }
948
949 return 0;
950 }
951
952 /* Likewise, but don't accept constants. */
953
954 int
955 some_ni_operand (op, mode)
956 register rtx op;
957 enum machine_mode mode;
958 {
959 if (GET_MODE (op) != mode && mode != VOIDmode)
960 return 0;
961
962 if (GET_CODE (op) == SUBREG)
963 op = SUBREG_REG (op);
964
965 return (GET_CODE (op) == REG || GET_CODE (op) == MEM);
966 }
967
968 /* Return 1 if OP is a valid operand for the source of a move insn. */
969
970 int
971 input_operand (op, mode)
972 register rtx op;
973 enum machine_mode mode;
974 {
975 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
976 return 0;
977
978 if (GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE (op) != mode)
979 return 0;
980
981 switch (GET_CODE (op))
982 {
983 case LABEL_REF:
984 case SYMBOL_REF:
985 case CONST:
986 if (TARGET_EXPLICIT_RELOCS)
987 {
988 /* We don't split symbolic operands into something unintelligable
989 until after reload, but we do not wish non-small, non-global
990 symbolic operands to be reconstructed from their high/lo_sum
991 form. */
992 return (small_symbolic_operand (op, mode)
993 || global_symbolic_operand (op, mode)
994 || gotdtp_symbolic_operand (op, mode)
995 || gottp_symbolic_operand (op, mode));
996 }
997
998 /* This handles both the Windows/NT and OSF cases. */
999 return mode == ptr_mode || mode == DImode;
1000
1001 case HIGH:
1002 return (TARGET_EXPLICIT_RELOCS
1003 && local_symbolic_operand (XEXP (op, 0), mode));
1004
1005 case REG:
1006 case ADDRESSOF:
1007 return 1;
1008
1009 case SUBREG:
1010 if (register_operand (op, mode))
1011 return 1;
1012 /* ... fall through ... */
1013 case MEM:
1014 return ((TARGET_BWX || (mode != HImode && mode != QImode))
1015 && general_operand (op, mode));
1016
1017 case CONST_DOUBLE:
1018 case CONST_VECTOR:
1019 return op == CONST0_RTX (mode);
1020
1021 case CONST_INT:
1022 return mode == QImode || mode == HImode || add_operand (op, mode);
1023
1024 case CONSTANT_P_RTX:
1025 return 1;
1026
1027 default:
1028 break;
1029 }
1030
1031 return 0;
1032 }
1033
1034 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
1035 file, and in the same section as the current function. */
1036
1037 int
1038 samegp_function_operand (op, mode)
1039 rtx op;
1040 enum machine_mode mode ATTRIBUTE_UNUSED;
1041 {
1042 if (GET_CODE (op) != SYMBOL_REF)
1043 return false;
1044
1045 /* Easy test for recursion. */
1046 if (op == XEXP (DECL_RTL (current_function_decl), 0))
1047 return true;
1048
1049 /* Functions that are not local can be overridden, and thus may
1050 not share the same gp. */
1051 if (! SYMBOL_REF_LOCAL_P (op))
1052 return false;
1053
1054 /* If -msmall-data is in effect, assume that there is only one GP
1055 for the module, and so any local symbol has this property. We
1056 need explicit relocations to be able to enforce this for symbols
1057 not defined in this unit of translation, however. */
1058 if (TARGET_EXPLICIT_RELOCS && TARGET_SMALL_DATA)
1059 return true;
1060
1061 /* Functions that are not external are defined in this UoT,
1062 and thus must share the same gp. */
1063 return ! SYMBOL_REF_EXTERNAL_P (op);
1064 }
1065
1066 /* Return 1 if OP is a SYMBOL_REF for which we can make a call via bsr. */
1067
1068 int
1069 direct_call_operand (op, mode)
1070 rtx op;
1071 enum machine_mode mode;
1072 {
1073 tree op_decl, cfun_sec, op_sec;
1074
1075 /* Must share the same GP. */
1076 if (!samegp_function_operand (op, mode))
1077 return false;
1078
1079 /* If profiling is implemented via linker tricks, we can't jump
1080 to the nogp alternate entry point. Note that current_function_profile
1081 would not be correct, since that doesn't indicate if the target
1082 function uses profiling. */
1083 /* ??? TARGET_PROFILING_NEEDS_GP isn't really the right test,
1084 but is approximately correct for the OSF ABIs. Don't know
1085 what to do for VMS, NT, or UMK. */
1086 if (!TARGET_PROFILING_NEEDS_GP && profile_flag)
1087 return false;
1088
1089 /* Must be a function. In some cases folks create thunks in static
1090 data structures and then make calls to them. If we allow the
1091 direct call, we'll get an error from the linker about !samegp reloc
1092 against a symbol without a .prologue directive. */
1093 if (!SYMBOL_REF_FUNCTION_P (op))
1094 return false;
1095
1096 /* Must be "near" so that the branch is assumed to reach. With
1097 -msmall-text, this is assumed true of all local symbols. Since
1098 we've already checked samegp, locality is already assured. */
1099 if (TARGET_SMALL_TEXT)
1100 return true;
1101
1102 /* Otherwise, a decl is "near" if it is defined in the same section. */
1103 if (flag_function_sections)
1104 return false;
1105
1106 op_decl = SYMBOL_REF_DECL (op);
1107 if (DECL_ONE_ONLY (current_function_decl)
1108 || (op_decl && DECL_ONE_ONLY (op_decl)))
1109 return false;
1110
1111 cfun_sec = DECL_SECTION_NAME (current_function_decl);
1112 op_sec = op_decl ? DECL_SECTION_NAME (op_decl) : NULL;
1113 return ((!cfun_sec && !op_sec)
1114 || (cfun_sec && op_sec
1115 && strcmp (TREE_STRING_POINTER (cfun_sec),
1116 TREE_STRING_POINTER (op_sec)) == 0));
1117 }
1118
1119 /* Return true if OP is a LABEL_REF, or SYMBOL_REF or CONST referencing
1120 a (non-tls) variable known to be defined in this file. */
1121
1122 int
1123 local_symbolic_operand (op, mode)
1124 rtx op;
1125 enum machine_mode mode;
1126 {
1127 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
1128 return 0;
1129
1130 if (GET_CODE (op) == LABEL_REF)
1131 return 1;
1132
1133 if (GET_CODE (op) == CONST
1134 && GET_CODE (XEXP (op, 0)) == PLUS
1135 && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
1136 op = XEXP (XEXP (op, 0), 0);
1137
1138 if (GET_CODE (op) != SYMBOL_REF)
1139 return 0;
1140
1141 return SYMBOL_REF_LOCAL_P (op) && !SYMBOL_REF_TLS_MODEL (op);
1142 }
1143
1144 /* Return true if OP is a SYMBOL_REF or CONST referencing a variable
1145 known to be defined in this file in the small data area. */
1146
1147 int
1148 small_symbolic_operand (op, mode)
1149 rtx op;
1150 enum machine_mode mode ATTRIBUTE_UNUSED;
1151 {
1152 if (! TARGET_SMALL_DATA)
1153 return 0;
1154
1155 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
1156 return 0;
1157
1158 if (GET_CODE (op) == CONST
1159 && GET_CODE (XEXP (op, 0)) == PLUS
1160 && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
1161 op = XEXP (XEXP (op, 0), 0);
1162
1163 if (GET_CODE (op) != SYMBOL_REF)
1164 return 0;
1165
1166 /* ??? There's no encode_section_info equivalent for the rtl
1167 constant pool, so SYMBOL_FLAG_SMALL never gets set. */
1168 if (CONSTANT_POOL_ADDRESS_P (op))
1169 return GET_MODE_SIZE (get_pool_mode (op)) <= g_switch_value;
1170
1171 return (SYMBOL_REF_LOCAL_P (op)
1172 && SYMBOL_REF_SMALL_P (op)
1173 && SYMBOL_REF_TLS_MODEL (op) == 0);
1174 }
1175
1176 /* Return true if OP is a SYMBOL_REF or CONST referencing a variable
1177 not known (or known not) to be defined in this file. */
1178
1179 int
1180 global_symbolic_operand (op, mode)
1181 rtx op;
1182 enum machine_mode mode;
1183 {
1184 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
1185 return 0;
1186
1187 if (GET_CODE (op) == CONST
1188 && GET_CODE (XEXP (op, 0)) == PLUS
1189 && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
1190 op = XEXP (XEXP (op, 0), 0);
1191
1192 if (GET_CODE (op) != SYMBOL_REF)
1193 return 0;
1194
1195 return !SYMBOL_REF_LOCAL_P (op) && !SYMBOL_REF_TLS_MODEL (op);
1196 }
1197
1198 /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
1199
1200 int
1201 call_operand (op, mode)
1202 rtx op;
1203 enum machine_mode mode;
1204 {
1205 if (mode != Pmode)
1206 return 0;
1207
1208 if (GET_CODE (op) == REG)
1209 {
1210 if (TARGET_ABI_OSF)
1211 {
1212 /* Disallow virtual registers to cope with pathalogical test cases
1213 such as compile/930117-1.c in which the virtual reg decomposes
1214 to the frame pointer. Which is a hard reg that is not $27. */
1215 return (REGNO (op) == 27 || REGNO (op) > LAST_VIRTUAL_REGISTER);
1216 }
1217 else
1218 return 1;
1219 }
1220 if (TARGET_ABI_UNICOSMK)
1221 return 0;
1222 if (GET_CODE (op) == SYMBOL_REF)
1223 return 1;
1224
1225 return 0;
1226 }
1227
1228 /* Returns 1 if OP is a symbolic operand, i.e. a symbol_ref or a label_ref,
1229 possibly with an offset. */
1230
1231 int
1232 symbolic_operand (op, mode)
1233 register rtx op;
1234 enum machine_mode mode;
1235 {
1236 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
1237 return 0;
1238 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
1239 return 1;
1240 if (GET_CODE (op) == CONST
1241 && GET_CODE (XEXP (op,0)) == PLUS
1242 && GET_CODE (XEXP (XEXP (op,0), 0)) == SYMBOL_REF
1243 && GET_CODE (XEXP (XEXP (op,0), 1)) == CONST_INT)
1244 return 1;
1245 return 0;
1246 }
1247
1248 /* Return true if OP is valid for a particular TLS relocation. */
1249
1250 static int
1251 tls_symbolic_operand_1 (op, mode, size, unspec)
1252 rtx op;
1253 enum machine_mode mode;
1254 int size, unspec;
1255 {
1256 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
1257 return 0;
1258
1259 if (GET_CODE (op) != CONST)
1260 return 0;
1261 op = XEXP (op, 0);
1262
1263 if (GET_CODE (op) != UNSPEC || XINT (op, 1) != unspec)
1264 return 0;
1265 op = XVECEXP (op, 0, 0);
1266
1267 if (GET_CODE (op) != SYMBOL_REF)
1268 return 0;
1269
1270 if (SYMBOL_REF_LOCAL_P (op))
1271 {
1272 if (alpha_tls_size > size)
1273 return 0;
1274 }
1275 else
1276 {
1277 if (size != 64)
1278 return 0;
1279 }
1280
1281 switch (SYMBOL_REF_TLS_MODEL (op))
1282 {
1283 case TLS_MODEL_LOCAL_DYNAMIC:
1284 return unspec == UNSPEC_DTPREL;
1285 case TLS_MODEL_INITIAL_EXEC:
1286 return unspec == UNSPEC_TPREL && size == 64;
1287 case TLS_MODEL_LOCAL_EXEC:
1288 return unspec == UNSPEC_TPREL;
1289 default:
1290 abort ();
1291 }
1292 }
1293
1294 /* Return true if OP is valid for 16-bit DTP relative relocations. */
1295
1296 int
1297 dtp16_symbolic_operand (op, mode)
1298 rtx op;
1299 enum machine_mode mode;
1300 {
1301 return tls_symbolic_operand_1 (op, mode, 16, UNSPEC_DTPREL);
1302 }
1303
1304 /* Return true if OP is valid for 32-bit DTP relative relocations. */
1305
1306 int
1307 dtp32_symbolic_operand (op, mode)
1308 rtx op;
1309 enum machine_mode mode;
1310 {
1311 return tls_symbolic_operand_1 (op, mode, 32, UNSPEC_DTPREL);
1312 }
1313
1314 /* Return true if OP is valid for 64-bit DTP relative relocations. */
1315
1316 int
1317 gotdtp_symbolic_operand (op, mode)
1318 rtx op;
1319 enum machine_mode mode;
1320 {
1321 return tls_symbolic_operand_1 (op, mode, 64, UNSPEC_DTPREL);
1322 }
1323
1324 /* Return true if OP is valid for 16-bit TP relative relocations. */
1325
1326 int
1327 tp16_symbolic_operand (op, mode)
1328 rtx op;
1329 enum machine_mode mode;
1330 {
1331 return tls_symbolic_operand_1 (op, mode, 16, UNSPEC_TPREL);
1332 }
1333
1334 /* Return true if OP is valid for 32-bit TP relative relocations. */
1335
1336 int
1337 tp32_symbolic_operand (op, mode)
1338 rtx op;
1339 enum machine_mode mode;
1340 {
1341 return tls_symbolic_operand_1 (op, mode, 32, UNSPEC_TPREL);
1342 }
1343
1344 /* Return true if OP is valid for 64-bit TP relative relocations. */
1345
1346 int
1347 gottp_symbolic_operand (op, mode)
1348 rtx op;
1349 enum machine_mode mode;
1350 {
1351 return tls_symbolic_operand_1 (op, mode, 64, UNSPEC_TPREL);
1352 }
1353
1354 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
1355 comparisons are valid in which insn. */
1356
1357 int
1358 alpha_comparison_operator (op, mode)
1359 register rtx op;
1360 enum machine_mode mode;
1361 {
1362 enum rtx_code code = GET_CODE (op);
1363
1364 if (mode != GET_MODE (op) && mode != VOIDmode)
1365 return 0;
1366
1367 return (code == EQ || code == LE || code == LT
1368 || code == LEU || code == LTU);
1369 }
1370
1371 /* Return 1 if OP is a valid Alpha comparison operator against zero.
1372 Here we know which comparisons are valid in which insn. */
1373
1374 int
1375 alpha_zero_comparison_operator (op, mode)
1376 register rtx op;
1377 enum machine_mode mode;
1378 {
1379 enum rtx_code code = GET_CODE (op);
1380
1381 if (mode != GET_MODE (op) && mode != VOIDmode)
1382 return 0;
1383
1384 return (code == EQ || code == NE || code == LE || code == LT
1385 || code == LEU || code == LTU);
1386 }
1387
1388 /* Return 1 if OP is a valid Alpha swapped comparison operator. */
1389
1390 int
1391 alpha_swapped_comparison_operator (op, mode)
1392 register rtx op;
1393 enum machine_mode mode;
1394 {
1395 enum rtx_code code = GET_CODE (op);
1396
1397 if ((mode != GET_MODE (op) && mode != VOIDmode)
1398 || GET_RTX_CLASS (code) != '<')
1399 return 0;
1400
1401 code = swap_condition (code);
1402 return (code == EQ || code == LE || code == LT
1403 || code == LEU || code == LTU);
1404 }
1405
1406 /* Return 1 if OP is a signed comparison operation. */
1407
1408 int
1409 signed_comparison_operator (op, mode)
1410 register rtx op;
1411 enum machine_mode mode ATTRIBUTE_UNUSED;
1412 {
1413 enum rtx_code code = GET_CODE (op);
1414
1415 if (mode != GET_MODE (op) && mode != VOIDmode)
1416 return 0;
1417
1418 return (code == EQ || code == NE
1419 || code == LE || code == LT
1420 || code == GE || code == GT);
1421 }
1422
1423 /* Return 1 if OP is a valid Alpha floating point comparison operator.
1424 Here we know which comparisons are valid in which insn. */
1425
1426 int
1427 alpha_fp_comparison_operator (op, mode)
1428 register rtx op;
1429 enum machine_mode mode;
1430 {
1431 enum rtx_code code = GET_CODE (op);
1432
1433 if (mode != GET_MODE (op) && mode != VOIDmode)
1434 return 0;
1435
1436 return (code == EQ || code == LE || code == LT || code == UNORDERED);
1437 }
1438
1439 /* Return 1 if this is a divide or modulus operator. */
1440
1441 int
1442 divmod_operator (op, mode)
1443 register rtx op;
1444 enum machine_mode mode ATTRIBUTE_UNUSED;
1445 {
1446 switch (GET_CODE (op))
1447 {
1448 case DIV: case MOD: case UDIV: case UMOD:
1449 return 1;
1450
1451 default:
1452 break;
1453 }
1454
1455 return 0;
1456 }
1457
1458 /* Return 1 if this memory address is a known aligned register plus
1459 a constant. It must be a valid address. This means that we can do
1460 this as an aligned reference plus some offset.
1461
1462 Take into account what reload will do. */
1463
1464 int
1465 aligned_memory_operand (op, mode)
1466 register rtx op;
1467 enum machine_mode mode;
1468 {
1469 rtx base;
1470
1471 if (reload_in_progress)
1472 {
1473 rtx tmp = op;
1474 if (GET_CODE (tmp) == SUBREG)
1475 tmp = SUBREG_REG (tmp);
1476 if (GET_CODE (tmp) == REG
1477 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
1478 {
1479 op = reg_equiv_memory_loc[REGNO (tmp)];
1480 if (op == 0)
1481 return 0;
1482 }
1483 }
1484
1485 if (GET_CODE (op) != MEM
1486 || GET_MODE (op) != mode)
1487 return 0;
1488 op = XEXP (op, 0);
1489
1490 /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
1491 sorts of constructs. Dig for the real base register. */
1492 if (reload_in_progress
1493 && GET_CODE (op) == PLUS
1494 && GET_CODE (XEXP (op, 0)) == PLUS)
1495 base = XEXP (XEXP (op, 0), 0);
1496 else
1497 {
1498 if (! memory_address_p (mode, op))
1499 return 0;
1500 base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op);
1501 }
1502
1503 return (GET_CODE (base) == REG && REGNO_POINTER_ALIGN (REGNO (base)) >= 32);
1504 }
1505
1506 /* Similar, but return 1 if OP is a MEM which is not alignable. */
1507
1508 int
1509 unaligned_memory_operand (op, mode)
1510 register rtx op;
1511 enum machine_mode mode;
1512 {
1513 rtx base;
1514
1515 if (reload_in_progress)
1516 {
1517 rtx tmp = op;
1518 if (GET_CODE (tmp) == SUBREG)
1519 tmp = SUBREG_REG (tmp);
1520 if (GET_CODE (tmp) == REG
1521 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
1522 {
1523 op = reg_equiv_memory_loc[REGNO (tmp)];
1524 if (op == 0)
1525 return 0;
1526 }
1527 }
1528
1529 if (GET_CODE (op) != MEM
1530 || GET_MODE (op) != mode)
1531 return 0;
1532 op = XEXP (op, 0);
1533
1534 /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
1535 sorts of constructs. Dig for the real base register. */
1536 if (reload_in_progress
1537 && GET_CODE (op) == PLUS
1538 && GET_CODE (XEXP (op, 0)) == PLUS)
1539 base = XEXP (XEXP (op, 0), 0);
1540 else
1541 {
1542 if (! memory_address_p (mode, op))
1543 return 0;
1544 base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op);
1545 }
1546
1547 return (GET_CODE (base) == REG && REGNO_POINTER_ALIGN (REGNO (base)) < 32);
1548 }
1549
1550 /* Return 1 if OP is either a register or an unaligned memory location. */
1551
1552 int
1553 reg_or_unaligned_mem_operand (op, mode)
1554 rtx op;
1555 enum machine_mode mode;
1556 {
1557 return register_operand (op, mode) || unaligned_memory_operand (op, mode);
1558 }
1559
1560 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
1561
1562 int
1563 any_memory_operand (op, mode)
1564 register rtx op;
1565 enum machine_mode mode ATTRIBUTE_UNUSED;
1566 {
1567 return (GET_CODE (op) == MEM
1568 || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
1569 || (reload_in_progress && GET_CODE (op) == REG
1570 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
1571 || (reload_in_progress && GET_CODE (op) == SUBREG
1572 && GET_CODE (SUBREG_REG (op)) == REG
1573 && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));
1574 }
1575
1576 /* Returns 1 if OP is not an eliminable register.
1577
1578 This exists to cure a pathological abort in the s8addq (et al) patterns,
1579
1580 long foo () { long t; bar(); return (long) &t * 26107; }
1581
1582 which run afoul of a hack in reload to cure a (presumably) similar
1583 problem with lea-type instructions on other targets. But there is
1584 one of us and many of them, so work around the problem by selectively
1585 preventing combine from making the optimization. */
1586
1587 int
1588 reg_not_elim_operand (op, mode)
1589 register rtx op;
1590 enum machine_mode mode;
1591 {
1592 rtx inner = op;
1593 if (GET_CODE (op) == SUBREG)
1594 inner = SUBREG_REG (op);
1595 if (inner == frame_pointer_rtx || inner == arg_pointer_rtx)
1596 return 0;
1597
1598 return register_operand (op, mode);
1599 }
1600
1601 /* Return 1 is OP is a memory location that is not a reference (using
1602 an AND) to an unaligned location. Take into account what reload
1603 will do. */
1604
1605 int
1606 normal_memory_operand (op, mode)
1607 register rtx op;
1608 enum machine_mode mode ATTRIBUTE_UNUSED;
1609 {
1610 if (reload_in_progress)
1611 {
1612 rtx tmp = op;
1613 if (GET_CODE (tmp) == SUBREG)
1614 tmp = SUBREG_REG (tmp);
1615 if (GET_CODE (tmp) == REG
1616 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
1617 {
1618 op = reg_equiv_memory_loc[REGNO (tmp)];
1619
1620 /* This may not have been assigned an equivalent address if it will
1621 be eliminated. In that case, it doesn't matter what we do. */
1622 if (op == 0)
1623 return 1;
1624 }
1625 }
1626
1627 return GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) != AND;
1628 }
1629
1630 /* Accept a register, but not a subreg of any kind. This allows us to
1631 avoid pathological cases in reload wrt data movement common in
1632 int->fp conversion. */
1633
1634 int
1635 reg_no_subreg_operand (op, mode)
1636 register rtx op;
1637 enum machine_mode mode;
1638 {
1639 if (GET_CODE (op) != REG)
1640 return 0;
1641 return register_operand (op, mode);
1642 }
1643
1644 /* Recognize an addition operation that includes a constant. Used to
1645 convince reload to canonize (plus (plus reg c1) c2) during register
1646 elimination. */
1647
1648 int
1649 addition_operation (op, mode)
1650 register rtx op;
1651 enum machine_mode mode;
1652 {
1653 if (GET_MODE (op) != mode && mode != VOIDmode)
1654 return 0;
1655 if (GET_CODE (op) == PLUS
1656 && register_operand (XEXP (op, 0), mode)
1657 && GET_CODE (XEXP (op, 1)) == CONST_INT
1658 && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (op, 1)), 'K'))
1659 return 1;
1660 return 0;
1661 }
1662
1663 /* Implements CONST_OK_FOR_LETTER_P. Return true if the value matches
1664 the range defined for C in [I-P]. */
1665
1666 bool
1667 alpha_const_ok_for_letter_p (value, c)
1668 HOST_WIDE_INT value;
1669 int c;
1670 {
1671 switch (c)
1672 {
1673 case 'I':
1674 /* An unsigned 8 bit constant. */
1675 return (unsigned HOST_WIDE_INT) value < 0x100;
1676 case 'J':
1677 /* The constant zero. */
1678 return value == 0;
1679 case 'K':
1680 /* A signed 16 bit constant. */
1681 return (unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000;
1682 case 'L':
1683 /* A shifted signed 16 bit constant appropriate for LDAH. */
1684 return ((value & 0xffff) == 0
1685 && ((value) >> 31 == -1 || value >> 31 == 0));
1686 case 'M':
1687 /* A constant that can be AND'ed with using a ZAP insn. */
1688 return zap_mask (value);
1689 case 'N':
1690 /* A complemented unsigned 8 bit constant. */
1691 return (unsigned HOST_WIDE_INT) (~ value) < 0x100;
1692 case 'O':
1693 /* A negated unsigned 8 bit constant. */
1694 return (unsigned HOST_WIDE_INT) (- value) < 0x100;
1695 case 'P':
1696 /* The constant 1, 2 or 3. */
1697 return value == 1 || value == 2 || value == 3;
1698
1699 default:
1700 return false;
1701 }
1702 }
1703
1704 /* Implements CONST_DOUBLE_OK_FOR_LETTER_P. Return true if VALUE
1705 matches for C in [GH]. */
1706
1707 bool
1708 alpha_const_double_ok_for_letter_p (value, c)
1709 rtx value;
1710 int c;
1711 {
1712 switch (c)
1713 {
1714 case 'G':
1715 /* The floating point zero constant. */
1716 return (GET_MODE_CLASS (GET_MODE (value)) == MODE_FLOAT
1717 && value == CONST0_RTX (GET_MODE (value)));
1718
1719 case 'H':
1720 /* A valid operand of a ZAP insn. */
1721 return (GET_MODE (value) == VOIDmode
1722 && zap_mask (CONST_DOUBLE_LOW (value))
1723 && zap_mask (CONST_DOUBLE_HIGH (value)));
1724
1725 default:
1726 return false;
1727 }
1728 }
1729
1730 /* Implements CONST_DOUBLE_OK_FOR_LETTER_P. Return true if VALUE
1731 matches for C. */
1732
1733 bool
1734 alpha_extra_constraint (value, c)
1735 rtx value;
1736 int c;
1737 {
1738 switch (c)
1739 {
1740 case 'Q':
1741 return normal_memory_operand (value, VOIDmode);
1742 case 'R':
1743 return direct_call_operand (value, Pmode);
1744 case 'S':
1745 return (GET_CODE (value) == CONST_INT
1746 && (unsigned HOST_WIDE_INT) INTVAL (value) < 64);
1747 case 'T':
1748 return GET_CODE (value) == HIGH;
1749 case 'U':
1750 return TARGET_ABI_UNICOSMK && symbolic_operand (value, VOIDmode);
1751 case 'W':
1752 return (GET_CODE (value) == CONST_VECTOR
1753 && value == CONST0_RTX (GET_MODE (value)));
1754 default:
1755 return false;
1756 }
1757 }
1758
1759 /* Return 1 if this function can directly return via $26. */
1760
1761 int
1762 direct_return ()
1763 {
1764 return (! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK
1765 && reload_completed
1766 && alpha_sa_size () == 0
1767 && get_frame_size () == 0
1768 && current_function_outgoing_args_size == 0
1769 && current_function_pretend_args_size == 0);
1770 }
1771
1772 /* Return the ADDR_VEC associated with a tablejump insn. */
1773
1774 rtx
1775 alpha_tablejump_addr_vec (insn)
1776 rtx insn;
1777 {
1778 rtx tmp;
1779
1780 tmp = JUMP_LABEL (insn);
1781 if (!tmp)
1782 return NULL_RTX;
1783 tmp = NEXT_INSN (tmp);
1784 if (!tmp)
1785 return NULL_RTX;
1786 if (GET_CODE (tmp) == JUMP_INSN
1787 && GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC)
1788 return PATTERN (tmp);
1789 return NULL_RTX;
1790 }
1791
1792 /* Return the label of the predicted edge, or CONST0_RTX if we don't know. */
1793
1794 rtx
1795 alpha_tablejump_best_label (insn)
1796 rtx insn;
1797 {
1798 rtx jump_table = alpha_tablejump_addr_vec (insn);
1799 rtx best_label = NULL_RTX;
1800
1801 /* ??? Once the CFG doesn't keep getting completely rebuilt, look
1802 there for edge frequency counts from profile data. */
1803
1804 if (jump_table)
1805 {
1806 int n_labels = XVECLEN (jump_table, 1);
1807 int best_count = -1;
1808 int i, j;
1809
1810 for (i = 0; i < n_labels; i++)
1811 {
1812 int count = 1;
1813
1814 for (j = i + 1; j < n_labels; j++)
1815 if (XEXP (XVECEXP (jump_table, 1, i), 0)
1816 == XEXP (XVECEXP (jump_table, 1, j), 0))
1817 count++;
1818
1819 if (count > best_count)
1820 best_count = count, best_label = XVECEXP (jump_table, 1, i);
1821 }
1822 }
1823
1824 return best_label ? best_label : const0_rtx;
1825 }
1826
1827 /* Return the TLS model to use for SYMBOL. */
1828
1829 static enum tls_model
1830 tls_symbolic_operand_type (symbol)
1831 rtx symbol;
1832 {
1833 enum tls_model model;
1834
1835 if (GET_CODE (symbol) != SYMBOL_REF)
1836 return 0;
1837 model = SYMBOL_REF_TLS_MODEL (symbol);
1838
1839 /* Local-exec with a 64-bit size is the same code as initial-exec. */
1840 if (model == TLS_MODEL_LOCAL_EXEC && alpha_tls_size == 64)
1841 model = TLS_MODEL_INITIAL_EXEC;
1842
1843 return model;
1844 }
1845 \f
1846 /* Return true if the function DECL will share the same GP as any
1847 function in the current unit of translation. */
1848
1849 static bool
1850 decl_has_samegp (decl)
1851 tree decl;
1852 {
1853 /* Functions that are not local can be overridden, and thus may
1854 not share the same gp. */
1855 if (!(*targetm.binds_local_p) (decl))
1856 return false;
1857
1858 /* If -msmall-data is in effect, assume that there is only one GP
1859 for the module, and so any local symbol has this property. We
1860 need explicit relocations to be able to enforce this for symbols
1861 not defined in this unit of translation, however. */
1862 if (TARGET_EXPLICIT_RELOCS && TARGET_SMALL_DATA)
1863 return true;
1864
1865 /* Functions that are not external are defined in this UoT. */
1866 /* ??? Irritatingly, static functions not yet emitted are still
1867 marked "external". Apply this to non-static functions only. */
1868 return !TREE_PUBLIC (decl) || !DECL_EXTERNAL (decl);
1869 }
1870
1871 /* Return true if EXP should be placed in the small data section. */
1872
1873 static bool
1874 alpha_in_small_data_p (exp)
1875 tree exp;
1876 {
1877 /* We want to merge strings, so we never consider them small data. */
1878 if (TREE_CODE (exp) == STRING_CST)
1879 return false;
1880
1881 if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
1882 {
1883 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
1884 if (strcmp (section, ".sdata") == 0
1885 || strcmp (section, ".sbss") == 0)
1886 return true;
1887 }
1888 else
1889 {
1890 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
1891
1892 /* If this is an incomplete type with size 0, then we can't put it
1893 in sdata because it might be too big when completed. */
1894 if (size > 0 && (unsigned HOST_WIDE_INT) size <= g_switch_value)
1895 return true;
1896 }
1897
1898 return false;
1899 }
1900
1901 #if TARGET_ABI_OPEN_VMS
1902 static bool
1903 alpha_linkage_symbol_p (symname)
1904 const char *symname;
1905 {
1906 int symlen = strlen (symname);
1907
1908 if (symlen > 4)
1909 return strcmp (&symname [symlen - 4], "..lk") == 0;
1910
1911 return false;
1912 }
1913
1914 #define LINKAGE_SYMBOL_REF_P(X) \
1915 ((GET_CODE (X) == SYMBOL_REF \
1916 && alpha_linkage_symbol_p (XSTR (X, 0))) \
1917 || (GET_CODE (X) == CONST \
1918 && GET_CODE (XEXP (X, 0)) == PLUS \
1919 && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF \
1920 && alpha_linkage_symbol_p (XSTR (XEXP (XEXP (X, 0), 0), 0))))
1921 #endif
1922
1923 /* legitimate_address_p recognizes an RTL expression that is a valid
1924 memory address for an instruction. The MODE argument is the
1925 machine mode for the MEM expression that wants to use this address.
1926
1927 For Alpha, we have either a constant address or the sum of a
1928 register and a constant address, or just a register. For DImode,
1929 any of those forms can be surrounded with an AND that clear the
1930 low-order three bits; this is an "unaligned" access. */
1931
1932 bool
1933 alpha_legitimate_address_p (mode, x, strict)
1934 enum machine_mode mode;
1935 rtx x;
1936 int strict;
1937 {
1938 /* If this is an ldq_u type address, discard the outer AND. */
1939 if (mode == DImode
1940 && GET_CODE (x) == AND
1941 && GET_CODE (XEXP (x, 1)) == CONST_INT
1942 && INTVAL (XEXP (x, 1)) == -8)
1943 x = XEXP (x, 0);
1944
1945 /* Discard non-paradoxical subregs. */
1946 if (GET_CODE (x) == SUBREG
1947 && (GET_MODE_SIZE (GET_MODE (x))
1948 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
1949 x = SUBREG_REG (x);
1950
1951 /* Unadorned general registers are valid. */
1952 if (REG_P (x)
1953 && (strict
1954 ? STRICT_REG_OK_FOR_BASE_P (x)
1955 : NONSTRICT_REG_OK_FOR_BASE_P (x)))
1956 return true;
1957
1958 /* Constant addresses (i.e. +/- 32k) are valid. */
1959 if (CONSTANT_ADDRESS_P (x))
1960 return true;
1961
1962 #if TARGET_ABI_OPEN_VMS
1963 if (LINKAGE_SYMBOL_REF_P (x))
1964 return true;
1965 #endif
1966
1967 /* Register plus a small constant offset is valid. */
1968 if (GET_CODE (x) == PLUS)
1969 {
1970 rtx ofs = XEXP (x, 1);
1971 x = XEXP (x, 0);
1972
1973 /* Discard non-paradoxical subregs. */
1974 if (GET_CODE (x) == SUBREG
1975 && (GET_MODE_SIZE (GET_MODE (x))
1976 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
1977 x = SUBREG_REG (x);
1978
1979 if (REG_P (x))
1980 {
1981 if (! strict
1982 && NONSTRICT_REG_OK_FP_BASE_P (x)
1983 && GET_CODE (ofs) == CONST_INT)
1984 return true;
1985 if ((strict
1986 ? STRICT_REG_OK_FOR_BASE_P (x)
1987 : NONSTRICT_REG_OK_FOR_BASE_P (x))
1988 && CONSTANT_ADDRESS_P (ofs))
1989 return true;
1990 }
1991 else if (GET_CODE (x) == ADDRESSOF
1992 && GET_CODE (ofs) == CONST_INT)
1993 return true;
1994 }
1995
1996 /* If we're managing explicit relocations, LO_SUM is valid, as
1997 are small data symbols. */
1998 else if (TARGET_EXPLICIT_RELOCS)
1999 {
2000 if (small_symbolic_operand (x, Pmode))
2001 return true;
2002
2003 if (GET_CODE (x) == LO_SUM)
2004 {
2005 rtx ofs = XEXP (x, 1);
2006 x = XEXP (x, 0);
2007
2008 /* Discard non-paradoxical subregs. */
2009 if (GET_CODE (x) == SUBREG
2010 && (GET_MODE_SIZE (GET_MODE (x))
2011 < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
2012 x = SUBREG_REG (x);
2013
2014 /* Must have a valid base register. */
2015 if (! (REG_P (x)
2016 && (strict
2017 ? STRICT_REG_OK_FOR_BASE_P (x)
2018 : NONSTRICT_REG_OK_FOR_BASE_P (x))))
2019 return false;
2020
2021 /* The symbol must be local. */
2022 if (local_symbolic_operand (ofs, Pmode)
2023 || dtp32_symbolic_operand (ofs, Pmode)
2024 || tp32_symbolic_operand (ofs, Pmode))
2025 return true;
2026 }
2027 }
2028
2029 return false;
2030 }
2031
2032 /* Build the SYMBOL_REF for __tls_get_addr. */
2033
2034 static GTY(()) rtx tls_get_addr_libfunc;
2035
2036 static rtx
2037 get_tls_get_addr ()
2038 {
2039 if (!tls_get_addr_libfunc)
2040 tls_get_addr_libfunc = init_one_libfunc ("__tls_get_addr");
2041 return tls_get_addr_libfunc;
2042 }
2043
2044 /* Try machine-dependent ways of modifying an illegitimate address
2045 to be legitimate. If we find one, return the new, valid address. */
2046
2047 rtx
2048 alpha_legitimize_address (x, scratch, mode)
2049 rtx x;
2050 rtx scratch;
2051 enum machine_mode mode ATTRIBUTE_UNUSED;
2052 {
2053 HOST_WIDE_INT addend;
2054
2055 /* If the address is (plus reg const_int) and the CONST_INT is not a
2056 valid offset, compute the high part of the constant and add it to
2057 the register. Then our address is (plus temp low-part-const). */
2058 if (GET_CODE (x) == PLUS
2059 && GET_CODE (XEXP (x, 0)) == REG
2060 && GET_CODE (XEXP (x, 1)) == CONST_INT
2061 && ! CONSTANT_ADDRESS_P (XEXP (x, 1)))
2062 {
2063 addend = INTVAL (XEXP (x, 1));
2064 x = XEXP (x, 0);
2065 goto split_addend;
2066 }
2067
2068 /* If the address is (const (plus FOO const_int)), find the low-order
2069 part of the CONST_INT. Then load FOO plus any high-order part of the
2070 CONST_INT into a register. Our address is (plus reg low-part-const).
2071 This is done to reduce the number of GOT entries. */
2072 if (!no_new_pseudos
2073 && GET_CODE (x) == CONST
2074 && GET_CODE (XEXP (x, 0)) == PLUS
2075 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
2076 {
2077 addend = INTVAL (XEXP (XEXP (x, 0), 1));
2078 x = force_reg (Pmode, XEXP (XEXP (x, 0), 0));
2079 goto split_addend;
2080 }
2081
2082 /* If we have a (plus reg const), emit the load as in (2), then add
2083 the two registers, and finally generate (plus reg low-part-const) as
2084 our address. */
2085 if (!no_new_pseudos
2086 && GET_CODE (x) == PLUS
2087 && GET_CODE (XEXP (x, 0)) == REG
2088 && GET_CODE (XEXP (x, 1)) == CONST
2089 && GET_CODE (XEXP (XEXP (x, 1), 0)) == PLUS
2090 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == CONST_INT)
2091 {
2092 addend = INTVAL (XEXP (XEXP (XEXP (x, 1), 0), 1));
2093 x = expand_simple_binop (Pmode, PLUS, XEXP (x, 0),
2094 XEXP (XEXP (XEXP (x, 1), 0), 0),
2095 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2096 goto split_addend;
2097 }
2098
2099 /* If this is a local symbol, split the address into HIGH/LO_SUM parts. */
2100 if (TARGET_EXPLICIT_RELOCS && symbolic_operand (x, Pmode))
2101 {
2102 rtx r0, r16, eqv, tga, tp, insn, dest, seq;
2103
2104 switch (tls_symbolic_operand_type (x))
2105 {
2106 case TLS_MODEL_GLOBAL_DYNAMIC:
2107 start_sequence ();
2108
2109 r0 = gen_rtx_REG (Pmode, 0);
2110 r16 = gen_rtx_REG (Pmode, 16);
2111 tga = get_tls_get_addr ();
2112 dest = gen_reg_rtx (Pmode);
2113 seq = GEN_INT (alpha_next_sequence_number++);
2114
2115 emit_insn (gen_movdi_er_tlsgd (r16, pic_offset_table_rtx, x, seq));
2116 insn = gen_call_value_osf_tlsgd (r0, tga, seq);
2117 insn = emit_call_insn (insn);
2118 CONST_OR_PURE_CALL_P (insn) = 1;
2119 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16);
2120
2121 insn = get_insns ();
2122 end_sequence ();
2123
2124 emit_libcall_block (insn, dest, r0, x);
2125 return dest;
2126
2127 case TLS_MODEL_LOCAL_DYNAMIC:
2128 start_sequence ();
2129
2130 r0 = gen_rtx_REG (Pmode, 0);
2131 r16 = gen_rtx_REG (Pmode, 16);
2132 tga = get_tls_get_addr ();
2133 scratch = gen_reg_rtx (Pmode);
2134 seq = GEN_INT (alpha_next_sequence_number++);
2135
2136 emit_insn (gen_movdi_er_tlsldm (r16, pic_offset_table_rtx, seq));
2137 insn = gen_call_value_osf_tlsldm (r0, tga, seq);
2138 insn = emit_call_insn (insn);
2139 CONST_OR_PURE_CALL_P (insn) = 1;
2140 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16);
2141
2142 insn = get_insns ();
2143 end_sequence ();
2144
2145 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
2146 UNSPEC_TLSLDM_CALL);
2147 emit_libcall_block (insn, scratch, r0, eqv);
2148
2149 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPREL);
2150 eqv = gen_rtx_CONST (Pmode, eqv);
2151
2152 if (alpha_tls_size == 64)
2153 {
2154 dest = gen_reg_rtx (Pmode);
2155 emit_insn (gen_rtx_SET (VOIDmode, dest, eqv));
2156 emit_insn (gen_adddi3 (dest, dest, scratch));
2157 return dest;
2158 }
2159 if (alpha_tls_size == 32)
2160 {
2161 insn = gen_rtx_HIGH (Pmode, eqv);
2162 insn = gen_rtx_PLUS (Pmode, scratch, insn);
2163 scratch = gen_reg_rtx (Pmode);
2164 emit_insn (gen_rtx_SET (VOIDmode, scratch, insn));
2165 }
2166 return gen_rtx_LO_SUM (Pmode, scratch, eqv);
2167
2168 case TLS_MODEL_INITIAL_EXEC:
2169 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_TPREL);
2170 eqv = gen_rtx_CONST (Pmode, eqv);
2171 tp = gen_reg_rtx (Pmode);
2172 scratch = gen_reg_rtx (Pmode);
2173 dest = gen_reg_rtx (Pmode);
2174
2175 emit_insn (gen_load_tp (tp));
2176 emit_insn (gen_rtx_SET (VOIDmode, scratch, eqv));
2177 emit_insn (gen_adddi3 (dest, tp, scratch));
2178 return dest;
2179
2180 case TLS_MODEL_LOCAL_EXEC:
2181 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_TPREL);
2182 eqv = gen_rtx_CONST (Pmode, eqv);
2183 tp = gen_reg_rtx (Pmode);
2184
2185 emit_insn (gen_load_tp (tp));
2186 if (alpha_tls_size == 32)
2187 {
2188 insn = gen_rtx_HIGH (Pmode, eqv);
2189 insn = gen_rtx_PLUS (Pmode, tp, insn);
2190 tp = gen_reg_rtx (Pmode);
2191 emit_insn (gen_rtx_SET (VOIDmode, tp, insn));
2192 }
2193 return gen_rtx_LO_SUM (Pmode, tp, eqv);
2194 }
2195
2196 if (local_symbolic_operand (x, Pmode))
2197 {
2198 if (small_symbolic_operand (x, Pmode))
2199 return x;
2200 else
2201 {
2202 if (!no_new_pseudos)
2203 scratch = gen_reg_rtx (Pmode);
2204 emit_insn (gen_rtx_SET (VOIDmode, scratch,
2205 gen_rtx_HIGH (Pmode, x)));
2206 return gen_rtx_LO_SUM (Pmode, scratch, x);
2207 }
2208 }
2209 }
2210
2211 return NULL;
2212
2213 split_addend:
2214 {
2215 HOST_WIDE_INT low, high;
2216
2217 low = ((addend & 0xffff) ^ 0x8000) - 0x8000;
2218 addend -= low;
2219 high = ((addend & 0xffffffff) ^ 0x80000000) - 0x80000000;
2220 addend -= high;
2221
2222 if (addend)
2223 x = expand_simple_binop (Pmode, PLUS, x, GEN_INT (addend),
2224 (no_new_pseudos ? scratch : NULL_RTX),
2225 1, OPTAB_LIB_WIDEN);
2226 if (high)
2227 x = expand_simple_binop (Pmode, PLUS, x, GEN_INT (high),
2228 (no_new_pseudos ? scratch : NULL_RTX),
2229 1, OPTAB_LIB_WIDEN);
2230
2231 return plus_constant (x, low);
2232 }
2233 }
2234
2235 /* We do not allow indirect calls to be optimized into sibling calls, nor
2236 can we allow a call to a function with a different GP to be optimized
2237 into a sibcall. */
2238
2239 static bool
2240 alpha_function_ok_for_sibcall (decl, exp)
2241 tree decl;
2242 tree exp ATTRIBUTE_UNUSED;
2243 {
2244 /* Can't do indirect tail calls, since we don't know if the target
2245 uses the same GP. */
2246 if (!decl)
2247 return false;
2248
2249 /* Otherwise, we can make a tail call if the target function shares
2250 the same GP. */
2251 return decl_has_samegp (decl);
2252 }
2253
2254 /* For TARGET_EXPLICIT_RELOCS, we don't obfuscate a SYMBOL_REF to a
2255 small symbolic operand until after reload. At which point we need
2256 to replace (mem (symbol_ref)) with (mem (lo_sum $29 symbol_ref))
2257 so that sched2 has the proper dependency information. */
2258
2259 int
2260 some_small_symbolic_operand (x, mode)
2261 rtx x;
2262 enum machine_mode mode ATTRIBUTE_UNUSED;
2263 {
2264 return for_each_rtx (&x, some_small_symbolic_operand_1, NULL);
2265 }
2266
2267 static int
2268 some_small_symbolic_operand_1 (px, data)
2269 rtx *px;
2270 void *data ATTRIBUTE_UNUSED;
2271 {
2272 rtx x = *px;
2273
2274 /* Don't re-split. */
2275 if (GET_CODE (x) == LO_SUM)
2276 return -1;
2277
2278 return small_symbolic_operand (x, Pmode) != 0;
2279 }
2280
2281 rtx
2282 split_small_symbolic_operand (x)
2283 rtx x;
2284 {
2285 x = copy_insn (x);
2286 for_each_rtx (&x, split_small_symbolic_operand_1, NULL);
2287 return x;
2288 }
2289
2290 static int
2291 split_small_symbolic_operand_1 (px, data)
2292 rtx *px;
2293 void *data ATTRIBUTE_UNUSED;
2294 {
2295 rtx x = *px;
2296
2297 /* Don't re-split. */
2298 if (GET_CODE (x) == LO_SUM)
2299 return -1;
2300
2301 if (small_symbolic_operand (x, Pmode))
2302 {
2303 x = gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, x);
2304 *px = x;
2305 return -1;
2306 }
2307
2308 return 0;
2309 }
2310
2311 /* Indicate that INSN cannot be duplicated. This is true for any insn
2312 that we've marked with gpdisp relocs, since those have to stay in
2313 1-1 correspondence with one another.
2314
2315 Techinically we could copy them if we could set up a mapping from one
2316 sequence number to another, across the set of insns to be duplicated.
2317 This seems overly complicated and error-prone since interblock motion
2318 from sched-ebb could move one of the pair of insns to a different block. */
2319
2320 static bool
2321 alpha_cannot_copy_insn_p (insn)
2322 rtx insn;
2323 {
2324 rtx pat;
2325
2326 if (!reload_completed || !TARGET_EXPLICIT_RELOCS)
2327 return false;
2328
2329 if (GET_CODE (insn) != INSN)
2330 return false;
2331 if (asm_noperands (insn) >= 0)
2332 return false;
2333
2334 pat = PATTERN (insn);
2335 if (GET_CODE (pat) != SET)
2336 return false;
2337 pat = SET_SRC (pat);
2338 if (GET_CODE (pat) == UNSPEC_VOLATILE)
2339 {
2340 if (XINT (pat, 1) == UNSPECV_LDGP1
2341 || XINT (pat, 1) == UNSPECV_PLDGP2)
2342 return true;
2343 }
2344 else if (GET_CODE (pat) == UNSPEC)
2345 {
2346 if (XINT (pat, 1) == UNSPEC_LDGP2)
2347 return true;
2348 }
2349
2350 return false;
2351 }
2352
2353
2354 /* Try a machine-dependent way of reloading an illegitimate address
2355 operand. If we find one, push the reload and return the new rtx. */
2356
2357 rtx
2358 alpha_legitimize_reload_address (x, mode, opnum, type, ind_levels)
2359 rtx x;
2360 enum machine_mode mode ATTRIBUTE_UNUSED;
2361 int opnum;
2362 int type;
2363 int ind_levels ATTRIBUTE_UNUSED;
2364 {
2365 /* We must recognize output that we have already generated ourselves. */
2366 if (GET_CODE (x) == PLUS
2367 && GET_CODE (XEXP (x, 0)) == PLUS
2368 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
2369 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
2370 && GET_CODE (XEXP (x, 1)) == CONST_INT)
2371 {
2372 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2373 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
2374 opnum, type);
2375 return x;
2376 }
2377
2378 /* We wish to handle large displacements off a base register by
2379 splitting the addend across an ldah and the mem insn. This
2380 cuts number of extra insns needed from 3 to 1. */
2381 if (GET_CODE (x) == PLUS
2382 && GET_CODE (XEXP (x, 0)) == REG
2383 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
2384 && REGNO_OK_FOR_BASE_P (REGNO (XEXP (x, 0)))
2385 && GET_CODE (XEXP (x, 1)) == CONST_INT)
2386 {
2387 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
2388 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
2389 HOST_WIDE_INT high
2390 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
2391
2392 /* Check for 32-bit overflow. */
2393 if (high + low != val)
2394 return NULL_RTX;
2395
2396 /* Reload the high part into a base reg; leave the low part
2397 in the mem directly. */
2398 x = gen_rtx_PLUS (GET_MODE (x),
2399 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
2400 GEN_INT (high)),
2401 GEN_INT (low));
2402
2403 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2404 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
2405 opnum, type);
2406 return x;
2407 }
2408
2409 return NULL_RTX;
2410 }
2411 \f
2412 /* Compute a (partial) cost for rtx X. Return true if the complete
2413 cost has been computed, and false if subexpressions should be
2414 scanned. In either case, *TOTAL contains the cost result. */
2415
2416 static bool
2417 alpha_rtx_costs (x, code, outer_code, total)
2418 rtx x;
2419 int code, outer_code;
2420 int *total;
2421 {
2422 enum machine_mode mode = GET_MODE (x);
2423 bool float_mode_p = FLOAT_MODE_P (mode);
2424
2425 switch (code)
2426 {
2427 /* If this is an 8-bit constant, return zero since it can be used
2428 nearly anywhere with no cost. If it is a valid operand for an
2429 ADD or AND, likewise return 0 if we know it will be used in that
2430 context. Otherwise, return 2 since it might be used there later.
2431 All other constants take at least two insns. */
2432 case CONST_INT:
2433 if (INTVAL (x) >= 0 && INTVAL (x) < 256)
2434 {
2435 *total = 0;
2436 return true;
2437 }
2438 /* FALLTHRU */
2439
2440 case CONST_DOUBLE:
2441 if (x == CONST0_RTX (mode))
2442 *total = 0;
2443 else if ((outer_code == PLUS && add_operand (x, VOIDmode))
2444 || (outer_code == AND && and_operand (x, VOIDmode)))
2445 *total = 0;
2446 else if (add_operand (x, VOIDmode) || and_operand (x, VOIDmode))
2447 *total = 2;
2448 else
2449 *total = COSTS_N_INSNS (2);
2450 return true;
2451
2452 case CONST:
2453 case SYMBOL_REF:
2454 case LABEL_REF:
2455 if (TARGET_EXPLICIT_RELOCS && small_symbolic_operand (x, VOIDmode))
2456 *total = COSTS_N_INSNS (outer_code != MEM);
2457 else if (TARGET_EXPLICIT_RELOCS && local_symbolic_operand (x, VOIDmode))
2458 *total = COSTS_N_INSNS (1 + (outer_code != MEM));
2459 else if (tls_symbolic_operand_type (x))
2460 /* Estimate of cost for call_pal rduniq. */
2461 *total = COSTS_N_INSNS (15);
2462 else
2463 /* Otherwise we do a load from the GOT. */
2464 *total = COSTS_N_INSNS (alpha_memory_latency);
2465 return true;
2466
2467 case PLUS:
2468 case MINUS:
2469 if (float_mode_p)
2470 *total = alpha_rtx_cost_data[alpha_cpu].fp_add;
2471 else if (GET_CODE (XEXP (x, 0)) == MULT
2472 && const48_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
2473 {
2474 *total = (rtx_cost (XEXP (XEXP (x, 0), 0), outer_code)
2475 + rtx_cost (XEXP (x, 1), outer_code) + 2);
2476 return true;
2477 }
2478 return false;
2479
2480 case MULT:
2481 if (float_mode_p)
2482 *total = alpha_rtx_cost_data[alpha_cpu].fp_mult;
2483 else if (mode == DImode)
2484 *total = alpha_rtx_cost_data[alpha_cpu].int_mult_di;
2485 else
2486 *total = alpha_rtx_cost_data[alpha_cpu].int_mult_si;
2487 return false;
2488
2489 case ASHIFT:
2490 if (GET_CODE (XEXP (x, 1)) == CONST_INT
2491 && INTVAL (XEXP (x, 1)) <= 3)
2492 {
2493 *total = COSTS_N_INSNS (1);
2494 return false;
2495 }
2496 /* FALLTHRU */
2497
2498 case ASHIFTRT:
2499 case LSHIFTRT:
2500 *total = alpha_rtx_cost_data[alpha_cpu].int_shift;
2501 return false;
2502
2503 case IF_THEN_ELSE:
2504 if (float_mode_p)
2505 *total = alpha_rtx_cost_data[alpha_cpu].fp_add;
2506 else
2507 *total = alpha_rtx_cost_data[alpha_cpu].int_cmov;
2508 return false;
2509
2510 case DIV:
2511 case UDIV:
2512 case MOD:
2513 case UMOD:
2514 if (!float_mode_p)
2515 *total = COSTS_N_INSNS (70); /* ??? */
2516 else if (mode == SFmode)
2517 *total = alpha_rtx_cost_data[alpha_cpu].fp_div_sf;
2518 else
2519 *total = alpha_rtx_cost_data[alpha_cpu].fp_div_df;
2520 return false;
2521
2522 case MEM:
2523 *total = COSTS_N_INSNS (alpha_memory_latency);
2524 return true;
2525
2526 case NEG:
2527 if (! float_mode_p)
2528 {
2529 *total = COSTS_N_INSNS (1);
2530 return false;
2531 }
2532 /* FALLTHRU */
2533
2534 case ABS:
2535 if (! float_mode_p)
2536 {
2537 *total = COSTS_N_INSNS (1) + alpha_rtx_cost_data[alpha_cpu].int_cmov;
2538 return false;
2539 }
2540 /* FALLTHRU */
2541
2542 case FLOAT:
2543 case UNSIGNED_FLOAT:
2544 case FIX:
2545 case UNSIGNED_FIX:
2546 case FLOAT_EXTEND:
2547 case FLOAT_TRUNCATE:
2548 *total = alpha_rtx_cost_data[alpha_cpu].fp_add;
2549 return false;
2550
2551 default:
2552 return false;
2553 }
2554 }
2555 \f
2556 /* REF is an alignable memory location. Place an aligned SImode
2557 reference into *PALIGNED_MEM and the number of bits to shift into
2558 *PBITNUM. SCRATCH is a free register for use in reloading out
2559 of range stack slots. */
2560
2561 void
2562 get_aligned_mem (ref, paligned_mem, pbitnum)
2563 rtx ref;
2564 rtx *paligned_mem, *pbitnum;
2565 {
2566 rtx base;
2567 HOST_WIDE_INT offset = 0;
2568
2569 if (GET_CODE (ref) != MEM)
2570 abort ();
2571
2572 if (reload_in_progress
2573 && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
2574 {
2575 base = find_replacement (&XEXP (ref, 0));
2576
2577 if (! memory_address_p (GET_MODE (ref), base))
2578 abort ();
2579 }
2580 else
2581 {
2582 base = XEXP (ref, 0);
2583 }
2584
2585 if (GET_CODE (base) == PLUS)
2586 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
2587
2588 *paligned_mem
2589 = widen_memory_access (ref, SImode, (offset & ~3) - offset);
2590
2591 if (WORDS_BIG_ENDIAN)
2592 *pbitnum = GEN_INT (32 - (GET_MODE_BITSIZE (GET_MODE (ref))
2593 + (offset & 3) * 8));
2594 else
2595 *pbitnum = GEN_INT ((offset & 3) * 8);
2596 }
2597
2598 /* Similar, but just get the address. Handle the two reload cases.
2599 Add EXTRA_OFFSET to the address we return. */
2600
2601 rtx
2602 get_unaligned_address (ref, extra_offset)
2603 rtx ref;
2604 int extra_offset;
2605 {
2606 rtx base;
2607 HOST_WIDE_INT offset = 0;
2608
2609 if (GET_CODE (ref) != MEM)
2610 abort ();
2611
2612 if (reload_in_progress
2613 && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
2614 {
2615 base = find_replacement (&XEXP (ref, 0));
2616
2617 if (! memory_address_p (GET_MODE (ref), base))
2618 abort ();
2619 }
2620 else
2621 {
2622 base = XEXP (ref, 0);
2623 }
2624
2625 if (GET_CODE (base) == PLUS)
2626 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
2627
2628 return plus_constant (base, offset + extra_offset);
2629 }
2630
2631 /* On the Alpha, all (non-symbolic) constants except zero go into
2632 a floating-point register via memory. Note that we cannot
2633 return anything that is not a subset of CLASS, and that some
2634 symbolic constants cannot be dropped to memory. */
2635
2636 enum reg_class
2637 alpha_preferred_reload_class(x, class)
2638 rtx x;
2639 enum reg_class class;
2640 {
2641 /* Zero is present in any register class. */
2642 if (x == CONST0_RTX (GET_MODE (x)))
2643 return class;
2644
2645 /* These sorts of constants we can easily drop to memory. */
2646 if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
2647 {
2648 if (class == FLOAT_REGS)
2649 return NO_REGS;
2650 if (class == ALL_REGS)
2651 return GENERAL_REGS;
2652 return class;
2653 }
2654
2655 /* All other kinds of constants should not (and in the case of HIGH
2656 cannot) be dropped to memory -- instead we use a GENERAL_REGS
2657 secondary reload. */
2658 if (CONSTANT_P (x))
2659 return (class == ALL_REGS ? GENERAL_REGS : class);
2660
2661 return class;
2662 }
2663
2664 /* Loading and storing HImode or QImode values to and from memory
2665 usually requires a scratch register. The exceptions are loading
2666 QImode and HImode from an aligned address to a general register
2667 unless byte instructions are permitted.
2668
2669 We also cannot load an unaligned address or a paradoxical SUBREG
2670 into an FP register.
2671
2672 We also cannot do integral arithmetic into FP regs, as might result
2673 from register elimination into a DImode fp register. */
2674
2675 enum reg_class
2676 secondary_reload_class (class, mode, x, in)
2677 enum reg_class class;
2678 enum machine_mode mode;
2679 rtx x;
2680 int in;
2681 {
2682 if ((mode == QImode || mode == HImode) && ! TARGET_BWX)
2683 {
2684 if (GET_CODE (x) == MEM
2685 || (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
2686 || (GET_CODE (x) == SUBREG
2687 && (GET_CODE (SUBREG_REG (x)) == MEM
2688 || (GET_CODE (SUBREG_REG (x)) == REG
2689 && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER))))
2690 {
2691 if (!in || !aligned_memory_operand(x, mode))
2692 return GENERAL_REGS;
2693 }
2694 }
2695
2696 if (class == FLOAT_REGS)
2697 {
2698 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
2699 return GENERAL_REGS;
2700
2701 if (GET_CODE (x) == SUBREG
2702 && (GET_MODE_SIZE (GET_MODE (x))
2703 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
2704 return GENERAL_REGS;
2705
2706 if (in && INTEGRAL_MODE_P (mode)
2707 && ! (memory_operand (x, mode) || x == const0_rtx))
2708 return GENERAL_REGS;
2709 }
2710
2711 return NO_REGS;
2712 }
2713 \f
2714 /* Subfunction of the following function. Update the flags of any MEM
2715 found in part of X. */
2716
2717 static void
2718 alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
2719 rtx x;
2720 int in_struct_p, volatile_p, unchanging_p;
2721 {
2722 int i;
2723
2724 switch (GET_CODE (x))
2725 {
2726 case SEQUENCE:
2727 abort ();
2728
2729 case PARALLEL:
2730 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
2731 alpha_set_memflags_1 (XVECEXP (x, 0, i), in_struct_p, volatile_p,
2732 unchanging_p);
2733 break;
2734
2735 case INSN:
2736 alpha_set_memflags_1 (PATTERN (x), in_struct_p, volatile_p,
2737 unchanging_p);
2738 break;
2739
2740 case SET:
2741 alpha_set_memflags_1 (SET_DEST (x), in_struct_p, volatile_p,
2742 unchanging_p);
2743 alpha_set_memflags_1 (SET_SRC (x), in_struct_p, volatile_p,
2744 unchanging_p);
2745 break;
2746
2747 case MEM:
2748 MEM_IN_STRUCT_P (x) = in_struct_p;
2749 MEM_VOLATILE_P (x) = volatile_p;
2750 RTX_UNCHANGING_P (x) = unchanging_p;
2751 /* Sadly, we cannot use alias sets because the extra aliasing
2752 produced by the AND interferes. Given that two-byte quantities
2753 are the only thing we would be able to differentiate anyway,
2754 there does not seem to be any point in convoluting the early
2755 out of the alias check. */
2756 break;
2757
2758 default:
2759 break;
2760 }
2761 }
2762
2763 /* Given INSN, which is an INSN list or the PATTERN of a single insn
2764 generated to perform a memory operation, look for any MEMs in either
2765 a SET_DEST or a SET_SRC and copy the in-struct, unchanging, and
2766 volatile flags from REF into each of the MEMs found. If REF is not
2767 a MEM, don't do anything. */
2768
2769 void
2770 alpha_set_memflags (insn, ref)
2771 rtx insn;
2772 rtx ref;
2773 {
2774 int in_struct_p, volatile_p, unchanging_p;
2775
2776 if (GET_CODE (ref) != MEM)
2777 return;
2778
2779 in_struct_p = MEM_IN_STRUCT_P (ref);
2780 volatile_p = MEM_VOLATILE_P (ref);
2781 unchanging_p = RTX_UNCHANGING_P (ref);
2782
2783 /* This is only called from alpha.md, after having had something
2784 generated from one of the insn patterns. So if everything is
2785 zero, the pattern is already up-to-date. */
2786 if (! in_struct_p && ! volatile_p && ! unchanging_p)
2787 return;
2788
2789 alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
2790 }
2791 \f
2792 /* Try to output insns to set TARGET equal to the constant C if it can be
2793 done in less than N insns. Do all computations in MODE. Returns the place
2794 where the output has been placed if it can be done and the insns have been
2795 emitted. If it would take more than N insns, zero is returned and no
2796 insns and emitted. */
2797
2798 rtx
2799 alpha_emit_set_const (target, mode, c, n)
2800 rtx target;
2801 enum machine_mode mode;
2802 HOST_WIDE_INT c;
2803 int n;
2804 {
2805 rtx result = 0;
2806 rtx orig_target = target;
2807 int i;
2808
2809 /* If we can't make any pseudos, TARGET is an SImode hard register, we
2810 can't load this constant in one insn, do this in DImode. */
2811 if (no_new_pseudos && mode == SImode
2812 && GET_CODE (target) == REG && REGNO (target) < FIRST_PSEUDO_REGISTER
2813 && (result = alpha_emit_set_const_1 (target, mode, c, 1)) == 0)
2814 {
2815 target = gen_lowpart (DImode, target);
2816 mode = DImode;
2817 }
2818
2819 /* Try 1 insn, then 2, then up to N. */
2820 for (i = 1; i <= n; i++)
2821 {
2822 result = alpha_emit_set_const_1 (target, mode, c, i);
2823 if (result)
2824 {
2825 rtx insn = get_last_insn ();
2826 rtx set = single_set (insn);
2827 if (! CONSTANT_P (SET_SRC (set)))
2828 set_unique_reg_note (get_last_insn (), REG_EQUAL, GEN_INT (c));
2829 break;
2830 }
2831 }
2832
2833 /* Allow for the case where we changed the mode of TARGET. */
2834 if (result == target)
2835 result = orig_target;
2836
2837 return result;
2838 }
2839
2840 /* Internal routine for the above to check for N or below insns. */
2841
2842 static rtx
2843 alpha_emit_set_const_1 (target, mode, c, n)
2844 rtx target;
2845 enum machine_mode mode;
2846 HOST_WIDE_INT c;
2847 int n;
2848 {
2849 HOST_WIDE_INT new;
2850 int i, bits;
2851 /* Use a pseudo if highly optimizing and still generating RTL. */
2852 rtx subtarget
2853 = (flag_expensive_optimizations && !no_new_pseudos ? 0 : target);
2854 rtx temp, insn;
2855
2856 /* If this is a sign-extended 32-bit constant, we can do this in at most
2857 three insns, so do it if we have enough insns left. We always have
2858 a sign-extended 32-bit constant when compiling on a narrow machine. */
2859
2860 if (HOST_BITS_PER_WIDE_INT != 64
2861 || c >> 31 == -1 || c >> 31 == 0)
2862 {
2863 HOST_WIDE_INT low = ((c & 0xffff) ^ 0x8000) - 0x8000;
2864 HOST_WIDE_INT tmp1 = c - low;
2865 HOST_WIDE_INT high = (((tmp1 >> 16) & 0xffff) ^ 0x8000) - 0x8000;
2866 HOST_WIDE_INT extra = 0;
2867
2868 /* If HIGH will be interpreted as negative but the constant is
2869 positive, we must adjust it to do two ldha insns. */
2870
2871 if ((high & 0x8000) != 0 && c >= 0)
2872 {
2873 extra = 0x4000;
2874 tmp1 -= 0x40000000;
2875 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
2876 }
2877
2878 if (c == low || (low == 0 && extra == 0))
2879 {
2880 /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
2881 but that meant that we can't handle INT_MIN on 32-bit machines
2882 (like NT/Alpha), because we recurse indefinitely through
2883 emit_move_insn to gen_movdi. So instead, since we know exactly
2884 what we want, create it explicitly. */
2885
2886 if (target == NULL)
2887 target = gen_reg_rtx (mode);
2888 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (c)));
2889 return target;
2890 }
2891 else if (n >= 2 + (extra != 0))
2892 {
2893 temp = copy_to_suggested_reg (GEN_INT (high << 16), subtarget, mode);
2894
2895 /* As of 2002-02-23, addsi3 is only available when not optimizing.
2896 This means that if we go through expand_binop, we'll try to
2897 generate extensions, etc, which will require new pseudos, which
2898 will fail during some split phases. The SImode add patterns
2899 still exist, but are not named. So build the insns by hand. */
2900
2901 if (extra != 0)
2902 {
2903 if (! subtarget)
2904 subtarget = gen_reg_rtx (mode);
2905 insn = gen_rtx_PLUS (mode, temp, GEN_INT (extra << 16));
2906 insn = gen_rtx_SET (VOIDmode, subtarget, insn);
2907 emit_insn (insn);
2908 temp = subtarget;
2909 }
2910
2911 if (target == NULL)
2912 target = gen_reg_rtx (mode);
2913 insn = gen_rtx_PLUS (mode, temp, GEN_INT (low));
2914 insn = gen_rtx_SET (VOIDmode, target, insn);
2915 emit_insn (insn);
2916 return target;
2917 }
2918 }
2919
2920 /* If we couldn't do it that way, try some other methods. But if we have
2921 no instructions left, don't bother. Likewise, if this is SImode and
2922 we can't make pseudos, we can't do anything since the expand_binop
2923 and expand_unop calls will widen and try to make pseudos. */
2924
2925 if (n == 1 || (mode == SImode && no_new_pseudos))
2926 return 0;
2927
2928 /* Next, see if we can load a related constant and then shift and possibly
2929 negate it to get the constant we want. Try this once each increasing
2930 numbers of insns. */
2931
2932 for (i = 1; i < n; i++)
2933 {
2934 /* First, see if minus some low bits, we've an easy load of
2935 high bits. */
2936
2937 new = ((c & 0xffff) ^ 0x8000) - 0x8000;
2938 if (new != 0
2939 && (temp = alpha_emit_set_const (subtarget, mode, c - new, i)) != 0)
2940 return expand_binop (mode, add_optab, temp, GEN_INT (new),
2941 target, 0, OPTAB_WIDEN);
2942
2943 /* Next try complementing. */
2944 if ((temp = alpha_emit_set_const (subtarget, mode, ~ c, i)) != 0)
2945 return expand_unop (mode, one_cmpl_optab, temp, target, 0);
2946
2947 /* Next try to form a constant and do a left shift. We can do this
2948 if some low-order bits are zero; the exact_log2 call below tells
2949 us that information. The bits we are shifting out could be any
2950 value, but here we'll just try the 0- and sign-extended forms of
2951 the constant. To try to increase the chance of having the same
2952 constant in more than one insn, start at the highest number of
2953 bits to shift, but try all possibilities in case a ZAPNOT will
2954 be useful. */
2955
2956 if ((bits = exact_log2 (c & - c)) > 0)
2957 for (; bits > 0; bits--)
2958 if ((temp = (alpha_emit_set_const
2959 (subtarget, mode, c >> bits, i))) != 0
2960 || ((temp = (alpha_emit_set_const
2961 (subtarget, mode,
2962 ((unsigned HOST_WIDE_INT) c) >> bits, i)))
2963 != 0))
2964 return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
2965 target, 0, OPTAB_WIDEN);
2966
2967 /* Now try high-order zero bits. Here we try the shifted-in bits as
2968 all zero and all ones. Be careful to avoid shifting outside the
2969 mode and to avoid shifting outside the host wide int size. */
2970 /* On narrow hosts, don't shift a 1 into the high bit, since we'll
2971 confuse the recursive call and set all of the high 32 bits. */
2972
2973 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
2974 - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64))) > 0)
2975 for (; bits > 0; bits--)
2976 if ((temp = alpha_emit_set_const (subtarget, mode,
2977 c << bits, i)) != 0
2978 || ((temp = (alpha_emit_set_const
2979 (subtarget, mode,
2980 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
2981 i)))
2982 != 0))
2983 return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
2984 target, 1, OPTAB_WIDEN);
2985
2986 /* Now try high-order 1 bits. We get that with a sign-extension.
2987 But one bit isn't enough here. Be careful to avoid shifting outside
2988 the mode and to avoid shifting outside the host wide int size. */
2989
2990 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
2991 - floor_log2 (~ c) - 2)) > 0)
2992 for (; bits > 0; bits--)
2993 if ((temp = alpha_emit_set_const (subtarget, mode,
2994 c << bits, i)) != 0
2995 || ((temp = (alpha_emit_set_const
2996 (subtarget, mode,
2997 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
2998 i)))
2999 != 0))
3000 return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
3001 target, 0, OPTAB_WIDEN);
3002 }
3003
3004 #if HOST_BITS_PER_WIDE_INT == 64
3005 /* Finally, see if can load a value into the target that is the same as the
3006 constant except that all bytes that are 0 are changed to be 0xff. If we
3007 can, then we can do a ZAPNOT to obtain the desired constant. */
3008
3009 new = c;
3010 for (i = 0; i < 64; i += 8)
3011 if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
3012 new |= (HOST_WIDE_INT) 0xff << i;
3013
3014 /* We are only called for SImode and DImode. If this is SImode, ensure that
3015 we are sign extended to a full word. */
3016
3017 if (mode == SImode)
3018 new = ((new & 0xffffffff) ^ 0x80000000) - 0x80000000;
3019
3020 if (new != c && new != -1
3021 && (temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0)
3022 return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
3023 target, 0, OPTAB_WIDEN);
3024 #endif
3025
3026 return 0;
3027 }
3028
3029 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
3030 fall back to a straight forward decomposition. We do this to avoid
3031 exponential run times encountered when looking for longer sequences
3032 with alpha_emit_set_const. */
3033
3034 rtx
3035 alpha_emit_set_long_const (target, c1, c2)
3036 rtx target;
3037 HOST_WIDE_INT c1, c2;
3038 {
3039 HOST_WIDE_INT d1, d2, d3, d4;
3040
3041 /* Decompose the entire word */
3042 #if HOST_BITS_PER_WIDE_INT >= 64
3043 if (c2 != -(c1 < 0))
3044 abort ();
3045 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
3046 c1 -= d1;
3047 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
3048 c1 = (c1 - d2) >> 32;
3049 d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
3050 c1 -= d3;
3051 d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
3052 if (c1 != d4)
3053 abort ();
3054 #else
3055 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
3056 c1 -= d1;
3057 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
3058 if (c1 != d2)
3059 abort ();
3060 c2 += (d2 < 0);
3061 d3 = ((c2 & 0xffff) ^ 0x8000) - 0x8000;
3062 c2 -= d3;
3063 d4 = ((c2 & 0xffffffff) ^ 0x80000000) - 0x80000000;
3064 if (c2 != d4)
3065 abort ();
3066 #endif
3067
3068 /* Construct the high word */
3069 if (d4)
3070 {
3071 emit_move_insn (target, GEN_INT (d4));
3072 if (d3)
3073 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d3)));
3074 }
3075 else
3076 emit_move_insn (target, GEN_INT (d3));
3077
3078 /* Shift it into place */
3079 emit_move_insn (target, gen_rtx_ASHIFT (DImode, target, GEN_INT (32)));
3080
3081 /* Add in the low bits. */
3082 if (d2)
3083 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d2)));
3084 if (d1)
3085 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d1)));
3086
3087 return target;
3088 }
3089
3090 /* Expand a move instruction; return true if all work is done.
3091 We don't handle non-bwx subword loads here. */
3092
3093 bool
3094 alpha_expand_mov (mode, operands)
3095 enum machine_mode mode;
3096 rtx *operands;
3097 {
3098 /* If the output is not a register, the input must be. */
3099 if (GET_CODE (operands[0]) == MEM
3100 && ! reg_or_0_operand (operands[1], mode))
3101 operands[1] = force_reg (mode, operands[1]);
3102
3103 /* Allow legitimize_address to perform some simplifications. */
3104 if (mode == Pmode && symbolic_operand (operands[1], mode))
3105 {
3106 rtx tmp;
3107
3108 /* With RTL inlining, at -O3, rtl is generated, stored, then actually
3109 compiled at the end of compilation. In the meantime, someone can
3110 re-encode-section-info on some symbol changing it e.g. from global
3111 to local-not-small. If this happens, we'd have emitted a plain
3112 load rather than a high+losum load and not recognize the insn.
3113
3114 So if rtl inlining is in effect, we delay the global/not-global
3115 decision until rest_of_compilation by wrapping it in an
3116 UNSPEC_SYMBOL. */
3117 if (TARGET_EXPLICIT_RELOCS && flag_inline_functions
3118 && rtx_equal_function_value_matters
3119 && global_symbolic_operand (operands[1], mode))
3120 {
3121 emit_insn (gen_movdi_er_maybe_g (operands[0], operands[1]));
3122 return true;
3123 }
3124
3125 tmp = alpha_legitimize_address (operands[1], operands[0], mode);
3126 if (tmp)
3127 {
3128 if (tmp == operands[0])
3129 return true;
3130 operands[1] = tmp;
3131 return false;
3132 }
3133 }
3134
3135 /* Early out for non-constants and valid constants. */
3136 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], mode))
3137 return false;
3138
3139 /* Split large integers. */
3140 if (GET_CODE (operands[1]) == CONST_INT
3141 || GET_CODE (operands[1]) == CONST_DOUBLE)
3142 {
3143 HOST_WIDE_INT i0, i1;
3144 rtx temp = NULL_RTX;
3145
3146 if (GET_CODE (operands[1]) == CONST_INT)
3147 {
3148 i0 = INTVAL (operands[1]);
3149 i1 = -(i0 < 0);
3150 }
3151 else if (HOST_BITS_PER_WIDE_INT >= 64)
3152 {
3153 i0 = CONST_DOUBLE_LOW (operands[1]);
3154 i1 = -(i0 < 0);
3155 }
3156 else
3157 {
3158 i0 = CONST_DOUBLE_LOW (operands[1]);
3159 i1 = CONST_DOUBLE_HIGH (operands[1]);
3160 }
3161
3162 if (HOST_BITS_PER_WIDE_INT >= 64 || i1 == -(i0 < 0))
3163 temp = alpha_emit_set_const (operands[0], mode, i0, 3);
3164
3165 if (!temp && TARGET_BUILD_CONSTANTS)
3166 temp = alpha_emit_set_long_const (operands[0], i0, i1);
3167
3168 if (temp)
3169 {
3170 if (rtx_equal_p (operands[0], temp))
3171 return true;
3172 operands[1] = temp;
3173 return false;
3174 }
3175 }
3176
3177 /* Otherwise we've nothing left but to drop the thing to memory. */
3178 operands[1] = force_const_mem (mode, operands[1]);
3179 if (reload_in_progress)
3180 {
3181 emit_move_insn (operands[0], XEXP (operands[1], 0));
3182 operands[1] = copy_rtx (operands[1]);
3183 XEXP (operands[1], 0) = operands[0];
3184 }
3185 else
3186 operands[1] = validize_mem (operands[1]);
3187 return false;
3188 }
3189
3190 /* Expand a non-bwx QImode or HImode move instruction;
3191 return true if all work is done. */
3192
3193 bool
3194 alpha_expand_mov_nobwx (mode, operands)
3195 enum machine_mode mode;
3196 rtx *operands;
3197 {
3198 /* If the output is not a register, the input must be. */
3199 if (GET_CODE (operands[0]) == MEM)
3200 operands[1] = force_reg (mode, operands[1]);
3201
3202 /* Handle four memory cases, unaligned and aligned for either the input
3203 or the output. The only case where we can be called during reload is
3204 for aligned loads; all other cases require temporaries. */
3205
3206 if (GET_CODE (operands[1]) == MEM
3207 || (GET_CODE (operands[1]) == SUBREG
3208 && GET_CODE (SUBREG_REG (operands[1])) == MEM)
3209 || (reload_in_progress && GET_CODE (operands[1]) == REG
3210 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
3211 || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
3212 && GET_CODE (SUBREG_REG (operands[1])) == REG
3213 && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
3214 {
3215 if (aligned_memory_operand (operands[1], mode))
3216 {
3217 if (reload_in_progress)
3218 {
3219 emit_insn ((mode == QImode
3220 ? gen_reload_inqi_help
3221 : gen_reload_inhi_help)
3222 (operands[0], operands[1],
3223 gen_rtx_REG (SImode, REGNO (operands[0]))));
3224 }
3225 else
3226 {
3227 rtx aligned_mem, bitnum;
3228 rtx scratch = gen_reg_rtx (SImode);
3229
3230 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
3231
3232 emit_insn ((mode == QImode
3233 ? gen_aligned_loadqi
3234 : gen_aligned_loadhi)
3235 (operands[0], aligned_mem, bitnum, scratch));
3236 }
3237 }
3238 else
3239 {
3240 /* Don't pass these as parameters since that makes the generated
3241 code depend on parameter evaluation order which will cause
3242 bootstrap failures. */
3243
3244 rtx temp1 = gen_reg_rtx (DImode);
3245 rtx temp2 = gen_reg_rtx (DImode);
3246 rtx seq = ((mode == QImode
3247 ? gen_unaligned_loadqi
3248 : gen_unaligned_loadhi)
3249 (operands[0], get_unaligned_address (operands[1], 0),
3250 temp1, temp2));
3251
3252 alpha_set_memflags (seq, operands[1]);
3253 emit_insn (seq);
3254 }
3255 return true;
3256 }
3257
3258 if (GET_CODE (operands[0]) == MEM
3259 || (GET_CODE (operands[0]) == SUBREG
3260 && GET_CODE (SUBREG_REG (operands[0])) == MEM)
3261 || (reload_in_progress && GET_CODE (operands[0]) == REG
3262 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
3263 || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
3264 && GET_CODE (SUBREG_REG (operands[0])) == REG
3265 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
3266 {
3267 if (aligned_memory_operand (operands[0], mode))
3268 {
3269 rtx aligned_mem, bitnum;
3270 rtx temp1 = gen_reg_rtx (SImode);
3271 rtx temp2 = gen_reg_rtx (SImode);
3272
3273 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
3274
3275 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
3276 temp1, temp2));
3277 }
3278 else
3279 {
3280 rtx temp1 = gen_reg_rtx (DImode);
3281 rtx temp2 = gen_reg_rtx (DImode);
3282 rtx temp3 = gen_reg_rtx (DImode);
3283 rtx seq = ((mode == QImode
3284 ? gen_unaligned_storeqi
3285 : gen_unaligned_storehi)
3286 (get_unaligned_address (operands[0], 0),
3287 operands[1], temp1, temp2, temp3));
3288
3289 alpha_set_memflags (seq, operands[0]);
3290 emit_insn (seq);
3291 }
3292 return true;
3293 }
3294
3295 return false;
3296 }
3297
3298 /* Generate an unsigned DImode to FP conversion. This is the same code
3299 optabs would emit if we didn't have TFmode patterns.
3300
3301 For SFmode, this is the only construction I've found that can pass
3302 gcc.c-torture/execute/ieee/rbug.c. No scenario that uses DFmode
3303 intermediates will work, because you'll get intermediate rounding
3304 that ruins the end result. Some of this could be fixed by turning
3305 on round-to-positive-infinity, but that requires diddling the fpsr,
3306 which kills performance. I tried turning this around and converting
3307 to a negative number, so that I could turn on /m, but either I did
3308 it wrong or there's something else cause I wound up with the exact
3309 same single-bit error. There is a branch-less form of this same code:
3310
3311 srl $16,1,$1
3312 and $16,1,$2
3313 cmplt $16,0,$3
3314 or $1,$2,$2
3315 cmovge $16,$16,$2
3316 itoft $3,$f10
3317 itoft $2,$f11
3318 cvtqs $f11,$f11
3319 adds $f11,$f11,$f0
3320 fcmoveq $f10,$f11,$f0
3321
3322 I'm not using it because it's the same number of instructions as
3323 this branch-full form, and it has more serialized long latency
3324 instructions on the critical path.
3325
3326 For DFmode, we can avoid rounding errors by breaking up the word
3327 into two pieces, converting them separately, and adding them back:
3328
3329 LC0: .long 0,0x5f800000
3330
3331 itoft $16,$f11
3332 lda $2,LC0
3333 cmplt $16,0,$1
3334 cpyse $f11,$f31,$f10
3335 cpyse $f31,$f11,$f11
3336 s4addq $1,$2,$1
3337 lds $f12,0($1)
3338 cvtqt $f10,$f10
3339 cvtqt $f11,$f11
3340 addt $f12,$f10,$f0
3341 addt $f0,$f11,$f0
3342
3343 This doesn't seem to be a clear-cut win over the optabs form.
3344 It probably all depends on the distribution of numbers being
3345 converted -- in the optabs form, all but high-bit-set has a
3346 much lower minimum execution time. */
3347
3348 void
3349 alpha_emit_floatuns (operands)
3350 rtx operands[2];
3351 {
3352 rtx neglab, donelab, i0, i1, f0, in, out;
3353 enum machine_mode mode;
3354
3355 out = operands[0];
3356 in = force_reg (DImode, operands[1]);
3357 mode = GET_MODE (out);
3358 neglab = gen_label_rtx ();
3359 donelab = gen_label_rtx ();
3360 i0 = gen_reg_rtx (DImode);
3361 i1 = gen_reg_rtx (DImode);
3362 f0 = gen_reg_rtx (mode);
3363
3364 emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, DImode, 0, neglab);
3365
3366 emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_FLOAT (mode, in)));
3367 emit_jump_insn (gen_jump (donelab));
3368 emit_barrier ();
3369
3370 emit_label (neglab);
3371
3372 emit_insn (gen_lshrdi3 (i0, in, const1_rtx));
3373 emit_insn (gen_anddi3 (i1, in, const1_rtx));
3374 emit_insn (gen_iordi3 (i0, i0, i1));
3375 emit_insn (gen_rtx_SET (VOIDmode, f0, gen_rtx_FLOAT (mode, i0)));
3376 emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_PLUS (mode, f0, f0)));
3377
3378 emit_label (donelab);
3379 }
3380
3381 /* Generate the comparison for a conditional branch. */
3382
3383 rtx
3384 alpha_emit_conditional_branch (code)
3385 enum rtx_code code;
3386 {
3387 enum rtx_code cmp_code, branch_code;
3388 enum machine_mode cmp_mode, branch_mode = VOIDmode;
3389 rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
3390 rtx tem;
3391
3392 if (alpha_compare.fp_p && GET_MODE (op0) == TFmode)
3393 {
3394 if (! TARGET_HAS_XFLOATING_LIBS)
3395 abort ();
3396
3397 /* X_floating library comparison functions return
3398 -1 unordered
3399 0 false
3400 1 true
3401 Convert the compare against the raw return value. */
3402
3403 switch (code)
3404 {
3405 case UNORDERED:
3406 cmp_code = EQ;
3407 code = LT;
3408 break;
3409 case ORDERED:
3410 cmp_code = EQ;
3411 code = GE;
3412 break;
3413 case NE:
3414 cmp_code = NE;
3415 code = NE;
3416 break;
3417 default:
3418 cmp_code = code;
3419 code = GT;
3420 break;
3421 }
3422
3423 op0 = alpha_emit_xfloating_compare (cmp_code, op0, op1);
3424 op1 = const0_rtx;
3425 alpha_compare.fp_p = 0;
3426 }
3427
3428 /* The general case: fold the comparison code to the types of compares
3429 that we have, choosing the branch as necessary. */
3430 switch (code)
3431 {
3432 case EQ: case LE: case LT: case LEU: case LTU:
3433 case UNORDERED:
3434 /* We have these compares: */
3435 cmp_code = code, branch_code = NE;
3436 break;
3437
3438 case NE:
3439 case ORDERED:
3440 /* These must be reversed. */
3441 cmp_code = reverse_condition (code), branch_code = EQ;
3442 break;
3443
3444 case GE: case GT: case GEU: case GTU:
3445 /* For FP, we swap them, for INT, we reverse them. */
3446 if (alpha_compare.fp_p)
3447 {
3448 cmp_code = swap_condition (code);
3449 branch_code = NE;
3450 tem = op0, op0 = op1, op1 = tem;
3451 }
3452 else
3453 {
3454 cmp_code = reverse_condition (code);
3455 branch_code = EQ;
3456 }
3457 break;
3458
3459 default:
3460 abort ();
3461 }
3462
3463 if (alpha_compare.fp_p)
3464 {
3465 cmp_mode = DFmode;
3466 if (flag_unsafe_math_optimizations)
3467 {
3468 /* When we are not as concerned about non-finite values, and we
3469 are comparing against zero, we can branch directly. */
3470 if (op1 == CONST0_RTX (DFmode))
3471 cmp_code = NIL, branch_code = code;
3472 else if (op0 == CONST0_RTX (DFmode))
3473 {
3474 /* Undo the swap we probably did just above. */
3475 tem = op0, op0 = op1, op1 = tem;
3476 branch_code = swap_condition (cmp_code);
3477 cmp_code = NIL;
3478 }
3479 }
3480 else
3481 {
3482 /* ??? We mark the branch mode to be CCmode to prevent the
3483 compare and branch from being combined, since the compare
3484 insn follows IEEE rules that the branch does not. */
3485 branch_mode = CCmode;
3486 }
3487 }
3488 else
3489 {
3490 cmp_mode = DImode;
3491
3492 /* The following optimizations are only for signed compares. */
3493 if (code != LEU && code != LTU && code != GEU && code != GTU)
3494 {
3495 /* Whee. Compare and branch against 0 directly. */
3496 if (op1 == const0_rtx)
3497 cmp_code = NIL, branch_code = code;
3498
3499 /* We want to use cmpcc/bcc when we can, since there is a zero delay
3500 bypass between logicals and br/cmov on EV5. But we don't want to
3501 force valid immediate constants into registers needlessly. */
3502 else if (GET_CODE (op1) == CONST_INT)
3503 {
3504 HOST_WIDE_INT v = INTVAL (op1), n = -v;
3505
3506 if (! CONST_OK_FOR_LETTER_P (v, 'I')
3507 && (CONST_OK_FOR_LETTER_P (n, 'K')
3508 || CONST_OK_FOR_LETTER_P (n, 'L')))
3509 {
3510 cmp_code = PLUS, branch_code = code;
3511 op1 = GEN_INT (n);
3512 }
3513 }
3514 }
3515
3516 if (!reg_or_0_operand (op0, DImode))
3517 op0 = force_reg (DImode, op0);
3518 if (cmp_code != PLUS && !reg_or_8bit_operand (op1, DImode))
3519 op1 = force_reg (DImode, op1);
3520 }
3521
3522 /* Emit an initial compare instruction, if necessary. */
3523 tem = op0;
3524 if (cmp_code != NIL)
3525 {
3526 tem = gen_reg_rtx (cmp_mode);
3527 emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
3528 }
3529
3530 /* Zero the operands. */
3531 memset (&alpha_compare, 0, sizeof (alpha_compare));
3532
3533 /* Return the branch comparison. */
3534 return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
3535 }
3536
3537 /* Certain simplifications can be done to make invalid setcc operations
3538 valid. Return the final comparison, or NULL if we can't work. */
3539
3540 rtx
3541 alpha_emit_setcc (code)
3542 enum rtx_code code;
3543 {
3544 enum rtx_code cmp_code;
3545 rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
3546 int fp_p = alpha_compare.fp_p;
3547 rtx tmp;
3548
3549 /* Zero the operands. */
3550 memset (&alpha_compare, 0, sizeof (alpha_compare));
3551
3552 if (fp_p && GET_MODE (op0) == TFmode)
3553 {
3554 if (! TARGET_HAS_XFLOATING_LIBS)
3555 abort ();
3556
3557 /* X_floating library comparison functions return
3558 -1 unordered
3559 0 false
3560 1 true
3561 Convert the compare against the raw return value. */
3562
3563 if (code == UNORDERED || code == ORDERED)
3564 cmp_code = EQ;
3565 else
3566 cmp_code = code;
3567
3568 op0 = alpha_emit_xfloating_compare (cmp_code, op0, op1);
3569 op1 = const0_rtx;
3570 fp_p = 0;
3571
3572 if (code == UNORDERED)
3573 code = LT;
3574 else if (code == ORDERED)
3575 code = GE;
3576 else
3577 code = GT;
3578 }
3579
3580 if (fp_p && !TARGET_FIX)
3581 return NULL_RTX;
3582
3583 /* The general case: fold the comparison code to the types of compares
3584 that we have, choosing the branch as necessary. */
3585
3586 cmp_code = NIL;
3587 switch (code)
3588 {
3589 case EQ: case LE: case LT: case LEU: case LTU:
3590 case UNORDERED:
3591 /* We have these compares. */
3592 if (fp_p)
3593 cmp_code = code, code = NE;
3594 break;
3595
3596 case NE:
3597 if (!fp_p && op1 == const0_rtx)
3598 break;
3599 /* FALLTHRU */
3600
3601 case ORDERED:
3602 cmp_code = reverse_condition (code);
3603 code = EQ;
3604 break;
3605
3606 case GE: case GT: case GEU: case GTU:
3607 /* These normally need swapping, but for integer zero we have
3608 special patterns that recognize swapped operands. */
3609 if (!fp_p && op1 == const0_rtx)
3610 break;
3611 code = swap_condition (code);
3612 if (fp_p)
3613 cmp_code = code, code = NE;
3614 tmp = op0, op0 = op1, op1 = tmp;
3615 break;
3616
3617 default:
3618 abort ();
3619 }
3620
3621 if (!fp_p)
3622 {
3623 if (!register_operand (op0, DImode))
3624 op0 = force_reg (DImode, op0);
3625 if (!reg_or_8bit_operand (op1, DImode))
3626 op1 = force_reg (DImode, op1);
3627 }
3628
3629 /* Emit an initial compare instruction, if necessary. */
3630 if (cmp_code != NIL)
3631 {
3632 enum machine_mode mode = fp_p ? DFmode : DImode;
3633
3634 tmp = gen_reg_rtx (mode);
3635 emit_insn (gen_rtx_SET (VOIDmode, tmp,
3636 gen_rtx_fmt_ee (cmp_code, mode, op0, op1)));
3637
3638 op0 = fp_p ? gen_lowpart (DImode, tmp) : tmp;
3639 op1 = const0_rtx;
3640 }
3641
3642 /* Return the setcc comparison. */
3643 return gen_rtx_fmt_ee (code, DImode, op0, op1);
3644 }
3645
3646
3647 /* Rewrite a comparison against zero CMP of the form
3648 (CODE (cc0) (const_int 0)) so it can be written validly in
3649 a conditional move (if_then_else CMP ...).
3650 If both of the operands that set cc0 are nonzero we must emit
3651 an insn to perform the compare (it can't be done within
3652 the conditional move). */
3653 rtx
3654 alpha_emit_conditional_move (cmp, mode)
3655 rtx cmp;
3656 enum machine_mode mode;
3657 {
3658 enum rtx_code code = GET_CODE (cmp);
3659 enum rtx_code cmov_code = NE;
3660 rtx op0 = alpha_compare.op0;
3661 rtx op1 = alpha_compare.op1;
3662 int fp_p = alpha_compare.fp_p;
3663 enum machine_mode cmp_mode
3664 = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
3665 enum machine_mode cmp_op_mode = fp_p ? DFmode : DImode;
3666 enum machine_mode cmov_mode = VOIDmode;
3667 int local_fast_math = flag_unsafe_math_optimizations;
3668 rtx tem;
3669
3670 /* Zero the operands. */
3671 memset (&alpha_compare, 0, sizeof (alpha_compare));
3672
3673 if (fp_p != FLOAT_MODE_P (mode))
3674 {
3675 enum rtx_code cmp_code;
3676
3677 if (! TARGET_FIX)
3678 return 0;
3679
3680 /* If we have fp<->int register move instructions, do a cmov by
3681 performing the comparison in fp registers, and move the
3682 zero/nonzero value to integer registers, where we can then
3683 use a normal cmov, or vice-versa. */
3684
3685 switch (code)
3686 {
3687 case EQ: case LE: case LT: case LEU: case LTU:
3688 /* We have these compares. */
3689 cmp_code = code, code = NE;
3690 break;
3691
3692 case NE:
3693 /* This must be reversed. */
3694 cmp_code = EQ, code = EQ;
3695 break;
3696
3697 case GE: case GT: case GEU: case GTU:
3698 /* These normally need swapping, but for integer zero we have
3699 special patterns that recognize swapped operands. */
3700 if (!fp_p && op1 == const0_rtx)
3701 cmp_code = code, code = NE;
3702 else
3703 {
3704 cmp_code = swap_condition (code);
3705 code = NE;
3706 tem = op0, op0 = op1, op1 = tem;
3707 }
3708 break;
3709
3710 default:
3711 abort ();
3712 }
3713
3714 tem = gen_reg_rtx (cmp_op_mode);
3715 emit_insn (gen_rtx_SET (VOIDmode, tem,
3716 gen_rtx_fmt_ee (cmp_code, cmp_op_mode,
3717 op0, op1)));
3718
3719 cmp_mode = cmp_op_mode = fp_p ? DImode : DFmode;
3720 op0 = gen_lowpart (cmp_op_mode, tem);
3721 op1 = CONST0_RTX (cmp_op_mode);
3722 fp_p = !fp_p;
3723 local_fast_math = 1;
3724 }
3725
3726 /* We may be able to use a conditional move directly.
3727 This avoids emitting spurious compares. */
3728 if (signed_comparison_operator (cmp, VOIDmode)
3729 && (!fp_p || local_fast_math)
3730 && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
3731 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
3732
3733 /* We can't put the comparison inside the conditional move;
3734 emit a compare instruction and put that inside the
3735 conditional move. Make sure we emit only comparisons we have;
3736 swap or reverse as necessary. */
3737
3738 if (no_new_pseudos)
3739 return NULL_RTX;
3740
3741 switch (code)
3742 {
3743 case EQ: case LE: case LT: case LEU: case LTU:
3744 /* We have these compares: */
3745 break;
3746
3747 case NE:
3748 /* This must be reversed. */
3749 code = reverse_condition (code);
3750 cmov_code = EQ;
3751 break;
3752
3753 case GE: case GT: case GEU: case GTU:
3754 /* These must be swapped. */
3755 if (op1 != CONST0_RTX (cmp_mode))
3756 {
3757 code = swap_condition (code);
3758 tem = op0, op0 = op1, op1 = tem;
3759 }
3760 break;
3761
3762 default:
3763 abort ();
3764 }
3765
3766 if (!fp_p)
3767 {
3768 if (!reg_or_0_operand (op0, DImode))
3769 op0 = force_reg (DImode, op0);
3770 if (!reg_or_8bit_operand (op1, DImode))
3771 op1 = force_reg (DImode, op1);
3772 }
3773
3774 /* ??? We mark the branch mode to be CCmode to prevent the compare
3775 and cmov from being combined, since the compare insn follows IEEE
3776 rules that the cmov does not. */
3777 if (fp_p && !local_fast_math)
3778 cmov_mode = CCmode;
3779
3780 tem = gen_reg_rtx (cmp_op_mode);
3781 emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
3782 return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
3783 }
3784
3785 /* Simplify a conditional move of two constants into a setcc with
3786 arithmetic. This is done with a splitter since combine would
3787 just undo the work if done during code generation. It also catches
3788 cases we wouldn't have before cse. */
3789
3790 int
3791 alpha_split_conditional_move (code, dest, cond, t_rtx, f_rtx)
3792 enum rtx_code code;
3793 rtx dest, cond, t_rtx, f_rtx;
3794 {
3795 HOST_WIDE_INT t, f, diff;
3796 enum machine_mode mode;
3797 rtx target, subtarget, tmp;
3798
3799 mode = GET_MODE (dest);
3800 t = INTVAL (t_rtx);
3801 f = INTVAL (f_rtx);
3802 diff = t - f;
3803
3804 if (((code == NE || code == EQ) && diff < 0)
3805 || (code == GE || code == GT))
3806 {
3807 code = reverse_condition (code);
3808 diff = t, t = f, f = diff;
3809 diff = t - f;
3810 }
3811
3812 subtarget = target = dest;
3813 if (mode != DImode)
3814 {
3815 target = gen_lowpart (DImode, dest);
3816 if (! no_new_pseudos)
3817 subtarget = gen_reg_rtx (DImode);
3818 else
3819 subtarget = target;
3820 }
3821 /* Below, we must be careful to use copy_rtx on target and subtarget
3822 in intermediate insns, as they may be a subreg rtx, which may not
3823 be shared. */
3824
3825 if (f == 0 && exact_log2 (diff) > 0
3826 /* On EV6, we've got enough shifters to make non-arithmatic shifts
3827 viable over a longer latency cmove. On EV5, the E0 slot is a
3828 scarce resource, and on EV4 shift has the same latency as a cmove. */
3829 && (diff <= 8 || alpha_cpu == PROCESSOR_EV6))
3830 {
3831 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
3832 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp));
3833
3834 tmp = gen_rtx_ASHIFT (DImode, copy_rtx (subtarget),
3835 GEN_INT (exact_log2 (t)));
3836 emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
3837 }
3838 else if (f == 0 && t == -1)
3839 {
3840 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
3841 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp));
3842
3843 emit_insn (gen_negdi2 (target, copy_rtx (subtarget)));
3844 }
3845 else if (diff == 1 || diff == 4 || diff == 8)
3846 {
3847 rtx add_op;
3848
3849 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
3850 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp));
3851
3852 if (diff == 1)
3853 emit_insn (gen_adddi3 (target, copy_rtx (subtarget), GEN_INT (f)));
3854 else
3855 {
3856 add_op = GEN_INT (f);
3857 if (sext_add_operand (add_op, mode))
3858 {
3859 tmp = gen_rtx_MULT (DImode, copy_rtx (subtarget),
3860 GEN_INT (diff));
3861 tmp = gen_rtx_PLUS (DImode, tmp, add_op);
3862 emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
3863 }
3864 else
3865 return 0;
3866 }
3867 }
3868 else
3869 return 0;
3870
3871 return 1;
3872 }
3873 \f
3874 /* Look up the function X_floating library function name for the
3875 given operation. */
3876
3877 static const char *
3878 alpha_lookup_xfloating_lib_func (code)
3879 enum rtx_code code;
3880 {
3881 struct xfloating_op
3882 {
3883 const enum rtx_code code;
3884 const char *const func;
3885 };
3886
3887 static const struct xfloating_op vms_xfloating_ops[] =
3888 {
3889 { PLUS, "OTS$ADD_X" },
3890 { MINUS, "OTS$SUB_X" },
3891 { MULT, "OTS$MUL_X" },
3892 { DIV, "OTS$DIV_X" },
3893 { EQ, "OTS$EQL_X" },
3894 { NE, "OTS$NEQ_X" },
3895 { LT, "OTS$LSS_X" },
3896 { LE, "OTS$LEQ_X" },
3897 { GT, "OTS$GTR_X" },
3898 { GE, "OTS$GEQ_X" },
3899 { FIX, "OTS$CVTXQ" },
3900 { FLOAT, "OTS$CVTQX" },
3901 { UNSIGNED_FLOAT, "OTS$CVTQUX" },
3902 { FLOAT_EXTEND, "OTS$CVT_FLOAT_T_X" },
3903 { FLOAT_TRUNCATE, "OTS$CVT_FLOAT_X_T" },
3904 };
3905
3906 static const struct xfloating_op osf_xfloating_ops[] =
3907 {
3908 { PLUS, "_OtsAddX" },
3909 { MINUS, "_OtsSubX" },
3910 { MULT, "_OtsMulX" },
3911 { DIV, "_OtsDivX" },
3912 { EQ, "_OtsEqlX" },
3913 { NE, "_OtsNeqX" },
3914 { LT, "_OtsLssX" },
3915 { LE, "_OtsLeqX" },
3916 { GT, "_OtsGtrX" },
3917 { GE, "_OtsGeqX" },
3918 { FIX, "_OtsCvtXQ" },
3919 { FLOAT, "_OtsCvtQX" },
3920 { UNSIGNED_FLOAT, "_OtsCvtQUX" },
3921 { FLOAT_EXTEND, "_OtsConvertFloatTX" },
3922 { FLOAT_TRUNCATE, "_OtsConvertFloatXT" },
3923 };
3924
3925 const struct xfloating_op *ops;
3926 const long n = ARRAY_SIZE (osf_xfloating_ops);
3927 long i;
3928
3929 /* How irritating. Nothing to key off for the table. Hardcode
3930 knowledge of the G_floating routines. */
3931 if (TARGET_FLOAT_VAX)
3932 {
3933 if (TARGET_ABI_OPEN_VMS)
3934 {
3935 if (code == FLOAT_EXTEND)
3936 return "OTS$CVT_FLOAT_G_X";
3937 if (code == FLOAT_TRUNCATE)
3938 return "OTS$CVT_FLOAT_X_G";
3939 }
3940 else
3941 {
3942 if (code == FLOAT_EXTEND)
3943 return "_OtsConvertFloatGX";
3944 if (code == FLOAT_TRUNCATE)
3945 return "_OtsConvertFloatXG";
3946 }
3947 }
3948
3949 if (TARGET_ABI_OPEN_VMS)
3950 ops = vms_xfloating_ops;
3951 else
3952 ops = osf_xfloating_ops;
3953
3954 for (i = 0; i < n; ++i)
3955 if (ops[i].code == code)
3956 return ops[i].func;
3957
3958 abort();
3959 }
3960
3961 /* Most X_floating operations take the rounding mode as an argument.
3962 Compute that here. */
3963
3964 static int
3965 alpha_compute_xfloating_mode_arg (code, round)
3966 enum rtx_code code;
3967 enum alpha_fp_rounding_mode round;
3968 {
3969 int mode;
3970
3971 switch (round)
3972 {
3973 case ALPHA_FPRM_NORM:
3974 mode = 2;
3975 break;
3976 case ALPHA_FPRM_MINF:
3977 mode = 1;
3978 break;
3979 case ALPHA_FPRM_CHOP:
3980 mode = 0;
3981 break;
3982 case ALPHA_FPRM_DYN:
3983 mode = 4;
3984 break;
3985 default:
3986 abort ();
3987
3988 /* XXX For reference, round to +inf is mode = 3. */
3989 }
3990
3991 if (code == FLOAT_TRUNCATE && alpha_fptm == ALPHA_FPTM_N)
3992 mode |= 0x10000;
3993
3994 return mode;
3995 }
3996
3997 /* Emit an X_floating library function call.
3998
3999 Note that these functions do not follow normal calling conventions:
4000 TFmode arguments are passed in two integer registers (as opposed to
4001 indirect); TFmode return values appear in R16+R17.
4002
4003 FUNC is the function name to call.
4004 TARGET is where the output belongs.
4005 OPERANDS are the inputs.
4006 NOPERANDS is the count of inputs.
4007 EQUIV is the expression equivalent for the function.
4008 */
4009
4010 static void
4011 alpha_emit_xfloating_libcall (func, target, operands, noperands, equiv)
4012 const char *func;
4013 rtx target;
4014 rtx operands[];
4015 int noperands;
4016 rtx equiv;
4017 {
4018 rtx usage = NULL_RTX, tmp, reg;
4019 int regno = 16, i;
4020
4021 start_sequence ();
4022
4023 for (i = 0; i < noperands; ++i)
4024 {
4025 switch (GET_MODE (operands[i]))
4026 {
4027 case TFmode:
4028 reg = gen_rtx_REG (TFmode, regno);
4029 regno += 2;
4030 break;
4031
4032 case DFmode:
4033 reg = gen_rtx_REG (DFmode, regno + 32);
4034 regno += 1;
4035 break;
4036
4037 case VOIDmode:
4038 if (GET_CODE (operands[i]) != CONST_INT)
4039 abort ();
4040 /* FALLTHRU */
4041 case DImode:
4042 reg = gen_rtx_REG (DImode, regno);
4043 regno += 1;
4044 break;
4045
4046 default:
4047 abort ();
4048 }
4049
4050 emit_move_insn (reg, operands[i]);
4051 usage = alloc_EXPR_LIST (0, gen_rtx_USE (VOIDmode, reg), usage);
4052 }
4053
4054 switch (GET_MODE (target))
4055 {
4056 case TFmode:
4057 reg = gen_rtx_REG (TFmode, 16);
4058 break;
4059 case DFmode:
4060 reg = gen_rtx_REG (DFmode, 32);
4061 break;
4062 case DImode:
4063 reg = gen_rtx_REG (DImode, 0);
4064 break;
4065 default:
4066 abort ();
4067 }
4068
4069 tmp = gen_rtx_MEM (QImode, init_one_libfunc (func));
4070 tmp = emit_call_insn (GEN_CALL_VALUE (reg, tmp, const0_rtx,
4071 const0_rtx, const0_rtx));
4072 CALL_INSN_FUNCTION_USAGE (tmp) = usage;
4073
4074 tmp = get_insns ();
4075 end_sequence ();
4076
4077 emit_libcall_block (tmp, target, reg, equiv);
4078 }
4079
4080 /* Emit an X_floating library function call for arithmetic (+,-,*,/). */
4081
4082 void
4083 alpha_emit_xfloating_arith (code, operands)
4084 enum rtx_code code;
4085 rtx operands[];
4086 {
4087 const char *func;
4088 int mode;
4089 rtx out_operands[3];
4090
4091 func = alpha_lookup_xfloating_lib_func (code);
4092 mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
4093
4094 out_operands[0] = operands[1];
4095 out_operands[1] = operands[2];
4096 out_operands[2] = GEN_INT (mode);
4097 alpha_emit_xfloating_libcall (func, operands[0], out_operands, 3,
4098 gen_rtx_fmt_ee (code, TFmode, operands[1],
4099 operands[2]));
4100 }
4101
4102 /* Emit an X_floating library function call for a comparison. */
4103
4104 static rtx
4105 alpha_emit_xfloating_compare (code, op0, op1)
4106 enum rtx_code code;
4107 rtx op0, op1;
4108 {
4109 const char *func;
4110 rtx out, operands[2];
4111
4112 func = alpha_lookup_xfloating_lib_func (code);
4113
4114 operands[0] = op0;
4115 operands[1] = op1;
4116 out = gen_reg_rtx (DImode);
4117
4118 /* ??? Strange mode for equiv because what's actually returned
4119 is -1,0,1, not a proper boolean value. */
4120 alpha_emit_xfloating_libcall (func, out, operands, 2,
4121 gen_rtx_fmt_ee (code, CCmode, op0, op1));
4122
4123 return out;
4124 }
4125
4126 /* Emit an X_floating library function call for a conversion. */
4127
4128 void
4129 alpha_emit_xfloating_cvt (code, operands)
4130 enum rtx_code code;
4131 rtx operands[];
4132 {
4133 int noperands = 1, mode;
4134 rtx out_operands[2];
4135 const char *func;
4136
4137 func = alpha_lookup_xfloating_lib_func (code);
4138
4139 out_operands[0] = operands[1];
4140
4141 switch (code)
4142 {
4143 case FIX:
4144 mode = alpha_compute_xfloating_mode_arg (code, ALPHA_FPRM_CHOP);
4145 out_operands[1] = GEN_INT (mode);
4146 noperands = 2;
4147 break;
4148 case FLOAT_TRUNCATE:
4149 mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
4150 out_operands[1] = GEN_INT (mode);
4151 noperands = 2;
4152 break;
4153 default:
4154 break;
4155 }
4156
4157 alpha_emit_xfloating_libcall (func, operands[0], out_operands, noperands,
4158 gen_rtx_fmt_e (code, GET_MODE (operands[0]),
4159 operands[1]));
4160 }
4161
4162 /* Split a TFmode OP[1] into DImode OP[2,3] and likewise for
4163 OP[0] into OP[0,1]. Naturally, output operand ordering is
4164 little-endian. */
4165
4166 void
4167 alpha_split_tfmode_pair (operands)
4168 rtx operands[4];
4169 {
4170 if (GET_CODE (operands[1]) == REG)
4171 {
4172 operands[3] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1);
4173 operands[2] = gen_rtx_REG (DImode, REGNO (operands[1]));
4174 }
4175 else if (GET_CODE (operands[1]) == MEM)
4176 {
4177 operands[3] = adjust_address (operands[1], DImode, 8);
4178 operands[2] = adjust_address (operands[1], DImode, 0);
4179 }
4180 else if (operands[1] == CONST0_RTX (TFmode))
4181 operands[2] = operands[3] = const0_rtx;
4182 else
4183 abort ();
4184
4185 if (GET_CODE (operands[0]) == REG)
4186 {
4187 operands[1] = gen_rtx_REG (DImode, REGNO (operands[0]) + 1);
4188 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
4189 }
4190 else if (GET_CODE (operands[0]) == MEM)
4191 {
4192 operands[1] = adjust_address (operands[0], DImode, 8);
4193 operands[0] = adjust_address (operands[0], DImode, 0);
4194 }
4195 else
4196 abort ();
4197 }
4198
4199 /* Implement negtf2 or abstf2. Op0 is destination, op1 is source,
4200 op2 is a register containing the sign bit, operation is the
4201 logical operation to be performed. */
4202
4203 void
4204 alpha_split_tfmode_frobsign (operands, operation)
4205 rtx operands[3];
4206 rtx (*operation) PARAMS ((rtx, rtx, rtx));
4207 {
4208 rtx high_bit = operands[2];
4209 rtx scratch;
4210 int move;
4211
4212 alpha_split_tfmode_pair (operands);
4213
4214 /* Detect three flavors of operand overlap. */
4215 move = 1;
4216 if (rtx_equal_p (operands[0], operands[2]))
4217 move = 0;
4218 else if (rtx_equal_p (operands[1], operands[2]))
4219 {
4220 if (rtx_equal_p (operands[0], high_bit))
4221 move = 2;
4222 else
4223 move = -1;
4224 }
4225
4226 if (move < 0)
4227 emit_move_insn (operands[0], operands[2]);
4228
4229 /* ??? If the destination overlaps both source tf and high_bit, then
4230 assume source tf is dead in its entirety and use the other half
4231 for a scratch register. Otherwise "scratch" is just the proper
4232 destination register. */
4233 scratch = operands[move < 2 ? 1 : 3];
4234
4235 emit_insn ((*operation) (scratch, high_bit, operands[3]));
4236
4237 if (move > 0)
4238 {
4239 emit_move_insn (operands[0], operands[2]);
4240 if (move > 1)
4241 emit_move_insn (operands[1], scratch);
4242 }
4243 }
4244 \f
4245 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
4246 unaligned data:
4247
4248 unsigned: signed:
4249 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
4250 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
4251 lda r3,X(r11) lda r3,X+2(r11)
4252 extwl r1,r3,r1 extql r1,r3,r1
4253 extwh r2,r3,r2 extqh r2,r3,r2
4254 or r1.r2.r1 or r1,r2,r1
4255 sra r1,48,r1
4256
4257 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
4258 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
4259 lda r3,X(r11) lda r3,X(r11)
4260 extll r1,r3,r1 extll r1,r3,r1
4261 extlh r2,r3,r2 extlh r2,r3,r2
4262 or r1.r2.r1 addl r1,r2,r1
4263
4264 quad: ldq_u r1,X(r11)
4265 ldq_u r2,X+7(r11)
4266 lda r3,X(r11)
4267 extql r1,r3,r1
4268 extqh r2,r3,r2
4269 or r1.r2.r1
4270 */
4271
4272 void
4273 alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
4274 rtx tgt, mem;
4275 HOST_WIDE_INT size, ofs;
4276 int sign;
4277 {
4278 rtx meml, memh, addr, extl, exth, tmp, mema;
4279 enum machine_mode mode;
4280
4281 meml = gen_reg_rtx (DImode);
4282 memh = gen_reg_rtx (DImode);
4283 addr = gen_reg_rtx (DImode);
4284 extl = gen_reg_rtx (DImode);
4285 exth = gen_reg_rtx (DImode);
4286
4287 mema = XEXP (mem, 0);
4288 if (GET_CODE (mema) == LO_SUM)
4289 mema = force_reg (Pmode, mema);
4290
4291 /* AND addresses cannot be in any alias set, since they may implicitly
4292 alias surrounding code. Ideally we'd have some alias set that
4293 covered all types except those with alignment 8 or higher. */
4294
4295 tmp = change_address (mem, DImode,
4296 gen_rtx_AND (DImode,
4297 plus_constant (mema, ofs),
4298 GEN_INT (-8)));
4299 set_mem_alias_set (tmp, 0);
4300 emit_move_insn (meml, tmp);
4301
4302 tmp = change_address (mem, DImode,
4303 gen_rtx_AND (DImode,
4304 plus_constant (mema, ofs + size - 1),
4305 GEN_INT (-8)));
4306 set_mem_alias_set (tmp, 0);
4307 emit_move_insn (memh, tmp);
4308
4309 if (WORDS_BIG_ENDIAN && sign && (size == 2 || size == 4))
4310 {
4311 emit_move_insn (addr, plus_constant (mema, -1));
4312
4313 emit_insn (gen_extqh_be (extl, meml, addr));
4314 emit_insn (gen_extxl_be (exth, memh, GEN_INT (64), addr));
4315
4316 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
4317 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (64 - size*8),
4318 addr, 1, OPTAB_WIDEN);
4319 }
4320 else if (sign && size == 2)
4321 {
4322 emit_move_insn (addr, plus_constant (mema, ofs+2));
4323
4324 emit_insn (gen_extxl_le (extl, meml, GEN_INT (64), addr));
4325 emit_insn (gen_extqh_le (exth, memh, addr));
4326
4327 /* We must use tgt here for the target. Alpha-vms port fails if we use
4328 addr for the target, because addr is marked as a pointer and combine
4329 knows that pointers are always sign-extended 32 bit values. */
4330 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
4331 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48),
4332 addr, 1, OPTAB_WIDEN);
4333 }
4334 else
4335 {
4336 if (WORDS_BIG_ENDIAN)
4337 {
4338 emit_move_insn (addr, plus_constant (mema, ofs+size-1));
4339 switch ((int) size)
4340 {
4341 case 2:
4342 emit_insn (gen_extwh_be (extl, meml, addr));
4343 mode = HImode;
4344 break;
4345
4346 case 4:
4347 emit_insn (gen_extlh_be (extl, meml, addr));
4348 mode = SImode;
4349 break;
4350
4351 case 8:
4352 emit_insn (gen_extqh_be (extl, meml, addr));
4353 mode = DImode;
4354 break;
4355
4356 default:
4357 abort ();
4358 }
4359 emit_insn (gen_extxl_be (exth, memh, GEN_INT (size*8), addr));
4360 }
4361 else
4362 {
4363 emit_move_insn (addr, plus_constant (mema, ofs));
4364 emit_insn (gen_extxl_le (extl, meml, GEN_INT (size*8), addr));
4365 switch ((int) size)
4366 {
4367 case 2:
4368 emit_insn (gen_extwh_le (exth, memh, addr));
4369 mode = HImode;
4370 break;
4371
4372 case 4:
4373 emit_insn (gen_extlh_le (exth, memh, addr));
4374 mode = SImode;
4375 break;
4376
4377 case 8:
4378 emit_insn (gen_extqh_le (exth, memh, addr));
4379 mode = DImode;
4380 break;
4381
4382 default:
4383 abort();
4384 }
4385 }
4386
4387 addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
4388 gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
4389 sign, OPTAB_WIDEN);
4390 }
4391
4392 if (addr != tgt)
4393 emit_move_insn (tgt, gen_lowpart(GET_MODE (tgt), addr));
4394 }
4395
4396 /* Similarly, use ins and msk instructions to perform unaligned stores. */
4397
4398 void
4399 alpha_expand_unaligned_store (dst, src, size, ofs)
4400 rtx dst, src;
4401 HOST_WIDE_INT size, ofs;
4402 {
4403 rtx dstl, dsth, addr, insl, insh, meml, memh, dsta;
4404
4405 dstl = gen_reg_rtx (DImode);
4406 dsth = gen_reg_rtx (DImode);
4407 insl = gen_reg_rtx (DImode);
4408 insh = gen_reg_rtx (DImode);
4409
4410 dsta = XEXP (dst, 0);
4411 if (GET_CODE (dsta) == LO_SUM)
4412 dsta = force_reg (Pmode, dsta);
4413
4414 /* AND addresses cannot be in any alias set, since they may implicitly
4415 alias surrounding code. Ideally we'd have some alias set that
4416 covered all types except those with alignment 8 or higher. */
4417
4418 meml = change_address (dst, DImode,
4419 gen_rtx_AND (DImode,
4420 plus_constant (dsta, ofs),
4421 GEN_INT (-8)));
4422 set_mem_alias_set (meml, 0);
4423
4424 memh = change_address (dst, DImode,
4425 gen_rtx_AND (DImode,
4426 plus_constant (dsta, ofs + size - 1),
4427 GEN_INT (-8)));
4428 set_mem_alias_set (memh, 0);
4429
4430 emit_move_insn (dsth, memh);
4431 emit_move_insn (dstl, meml);
4432 if (WORDS_BIG_ENDIAN)
4433 {
4434 addr = copy_addr_to_reg (plus_constant (dsta, ofs+size-1));
4435
4436 if (src != const0_rtx)
4437 {
4438 switch ((int) size)
4439 {
4440 case 2:
4441 emit_insn (gen_inswl_be (insh, gen_lowpart (HImode,src), addr));
4442 break;
4443 case 4:
4444 emit_insn (gen_insll_be (insh, gen_lowpart (SImode,src), addr));
4445 break;
4446 case 8:
4447 emit_insn (gen_insql_be (insh, gen_lowpart (DImode,src), addr));
4448 break;
4449 }
4450 emit_insn (gen_insxh (insl, gen_lowpart (DImode, src),
4451 GEN_INT (size*8), addr));
4452 }
4453
4454 switch ((int) size)
4455 {
4456 case 2:
4457 emit_insn (gen_mskxl_be (dsth, dsth, GEN_INT (0xffff), addr));
4458 break;
4459 case 4:
4460 {
4461 rtx msk = immed_double_const (0xffffffff, 0, DImode);
4462 emit_insn (gen_mskxl_be (dsth, dsth, msk, addr));
4463 break;
4464 }
4465 case 8:
4466 emit_insn (gen_mskxl_be (dsth, dsth, constm1_rtx, addr));
4467 break;
4468 }
4469
4470 emit_insn (gen_mskxh (dstl, dstl, GEN_INT (size*8), addr));
4471 }
4472 else
4473 {
4474 addr = copy_addr_to_reg (plus_constant (dsta, ofs));
4475
4476 if (src != const0_rtx)
4477 {
4478 emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
4479 GEN_INT (size*8), addr));
4480
4481 switch ((int) size)
4482 {
4483 case 2:
4484 emit_insn (gen_inswl_le (insl, gen_lowpart (HImode, src), addr));
4485 break;
4486 case 4:
4487 emit_insn (gen_insll_le (insl, gen_lowpart (SImode, src), addr));
4488 break;
4489 case 8:
4490 emit_insn (gen_insql_le (insl, src, addr));
4491 break;
4492 }
4493 }
4494
4495 emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
4496
4497 switch ((int) size)
4498 {
4499 case 2:
4500 emit_insn (gen_mskxl_le (dstl, dstl, GEN_INT (0xffff), addr));
4501 break;
4502 case 4:
4503 {
4504 rtx msk = immed_double_const (0xffffffff, 0, DImode);
4505 emit_insn (gen_mskxl_le (dstl, dstl, msk, addr));
4506 break;
4507 }
4508 case 8:
4509 emit_insn (gen_mskxl_le (dstl, dstl, constm1_rtx, addr));
4510 break;
4511 }
4512 }
4513
4514 if (src != const0_rtx)
4515 {
4516 dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
4517 dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
4518 }
4519
4520 if (WORDS_BIG_ENDIAN)
4521 {
4522 emit_move_insn (meml, dstl);
4523 emit_move_insn (memh, dsth);
4524 }
4525 else
4526 {
4527 /* Must store high before low for degenerate case of aligned. */
4528 emit_move_insn (memh, dsth);
4529 emit_move_insn (meml, dstl);
4530 }
4531 }
4532
4533 /* The block move code tries to maximize speed by separating loads and
4534 stores at the expense of register pressure: we load all of the data
4535 before we store it back out. There are two secondary effects worth
4536 mentioning, that this speeds copying to/from aligned and unaligned
4537 buffers, and that it makes the code significantly easier to write. */
4538
4539 #define MAX_MOVE_WORDS 8
4540
4541 /* Load an integral number of consecutive unaligned quadwords. */
4542
4543 static void
4544 alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
4545 rtx *out_regs;
4546 rtx smem;
4547 HOST_WIDE_INT words, ofs;
4548 {
4549 rtx const im8 = GEN_INT (-8);
4550 rtx const i64 = GEN_INT (64);
4551 rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
4552 rtx sreg, areg, tmp, smema;
4553 HOST_WIDE_INT i;
4554
4555 smema = XEXP (smem, 0);
4556 if (GET_CODE (smema) == LO_SUM)
4557 smema = force_reg (Pmode, smema);
4558
4559 /* Generate all the tmp registers we need. */
4560 for (i = 0; i < words; ++i)
4561 {
4562 data_regs[i] = out_regs[i];
4563 ext_tmps[i] = gen_reg_rtx (DImode);
4564 }
4565 data_regs[words] = gen_reg_rtx (DImode);
4566
4567 if (ofs != 0)
4568 smem = adjust_address (smem, GET_MODE (smem), ofs);
4569
4570 /* Load up all of the source data. */
4571 for (i = 0; i < words; ++i)
4572 {
4573 tmp = change_address (smem, DImode,
4574 gen_rtx_AND (DImode,
4575 plus_constant (smema, 8*i),
4576 im8));
4577 set_mem_alias_set (tmp, 0);
4578 emit_move_insn (data_regs[i], tmp);
4579 }
4580
4581 tmp = change_address (smem, DImode,
4582 gen_rtx_AND (DImode,
4583 plus_constant (smema, 8*words - 1),
4584 im8));
4585 set_mem_alias_set (tmp, 0);
4586 emit_move_insn (data_regs[words], tmp);
4587
4588 /* Extract the half-word fragments. Unfortunately DEC decided to make
4589 extxh with offset zero a noop instead of zeroing the register, so
4590 we must take care of that edge condition ourselves with cmov. */
4591
4592 sreg = copy_addr_to_reg (smema);
4593 areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
4594 1, OPTAB_WIDEN);
4595 if (WORDS_BIG_ENDIAN)
4596 emit_move_insn (sreg, plus_constant (sreg, 7));
4597 for (i = 0; i < words; ++i)
4598 {
4599 if (WORDS_BIG_ENDIAN)
4600 {
4601 emit_insn (gen_extqh_be (data_regs[i], data_regs[i], sreg));
4602 emit_insn (gen_extxl_be (ext_tmps[i], data_regs[i+1], i64, sreg));
4603 }
4604 else
4605 {
4606 emit_insn (gen_extxl_le (data_regs[i], data_regs[i], i64, sreg));
4607 emit_insn (gen_extqh_le (ext_tmps[i], data_regs[i+1], sreg));
4608 }
4609 emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
4610 gen_rtx_IF_THEN_ELSE (DImode,
4611 gen_rtx_EQ (DImode, areg,
4612 const0_rtx),
4613 const0_rtx, ext_tmps[i])));
4614 }
4615
4616 /* Merge the half-words into whole words. */
4617 for (i = 0; i < words; ++i)
4618 {
4619 out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
4620 ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
4621 }
4622 }
4623
4624 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
4625 may be NULL to store zeros. */
4626
4627 static void
4628 alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
4629 rtx *data_regs;
4630 rtx dmem;
4631 HOST_WIDE_INT words, ofs;
4632 {
4633 rtx const im8 = GEN_INT (-8);
4634 rtx const i64 = GEN_INT (64);
4635 rtx ins_tmps[MAX_MOVE_WORDS];
4636 rtx st_tmp_1, st_tmp_2, dreg;
4637 rtx st_addr_1, st_addr_2, dmema;
4638 HOST_WIDE_INT i;
4639
4640 dmema = XEXP (dmem, 0);
4641 if (GET_CODE (dmema) == LO_SUM)
4642 dmema = force_reg (Pmode, dmema);
4643
4644 /* Generate all the tmp registers we need. */
4645 if (data_regs != NULL)
4646 for (i = 0; i < words; ++i)
4647 ins_tmps[i] = gen_reg_rtx(DImode);
4648 st_tmp_1 = gen_reg_rtx(DImode);
4649 st_tmp_2 = gen_reg_rtx(DImode);
4650
4651 if (ofs != 0)
4652 dmem = adjust_address (dmem, GET_MODE (dmem), ofs);
4653
4654 st_addr_2 = change_address (dmem, DImode,
4655 gen_rtx_AND (DImode,
4656 plus_constant (dmema, words*8 - 1),
4657 im8));
4658 set_mem_alias_set (st_addr_2, 0);
4659
4660 st_addr_1 = change_address (dmem, DImode,
4661 gen_rtx_AND (DImode, dmema, im8));
4662 set_mem_alias_set (st_addr_1, 0);
4663
4664 /* Load up the destination end bits. */
4665 emit_move_insn (st_tmp_2, st_addr_2);
4666 emit_move_insn (st_tmp_1, st_addr_1);
4667
4668 /* Shift the input data into place. */
4669 dreg = copy_addr_to_reg (dmema);
4670 if (WORDS_BIG_ENDIAN)
4671 emit_move_insn (dreg, plus_constant (dreg, 7));
4672 if (data_regs != NULL)
4673 {
4674 for (i = words-1; i >= 0; --i)
4675 {
4676 if (WORDS_BIG_ENDIAN)
4677 {
4678 emit_insn (gen_insql_be (ins_tmps[i], data_regs[i], dreg));
4679 emit_insn (gen_insxh (data_regs[i], data_regs[i], i64, dreg));
4680 }
4681 else
4682 {
4683 emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
4684 emit_insn (gen_insql_le (data_regs[i], data_regs[i], dreg));
4685 }
4686 }
4687 for (i = words-1; i > 0; --i)
4688 {
4689 ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
4690 ins_tmps[i-1], ins_tmps[i-1], 1,
4691 OPTAB_WIDEN);
4692 }
4693 }
4694
4695 /* Split and merge the ends with the destination data. */
4696 if (WORDS_BIG_ENDIAN)
4697 {
4698 emit_insn (gen_mskxl_be (st_tmp_2, st_tmp_2, constm1_rtx, dreg));
4699 emit_insn (gen_mskxh (st_tmp_1, st_tmp_1, i64, dreg));
4700 }
4701 else
4702 {
4703 emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
4704 emit_insn (gen_mskxl_le (st_tmp_1, st_tmp_1, constm1_rtx, dreg));
4705 }
4706
4707 if (data_regs != NULL)
4708 {
4709 st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
4710 st_tmp_2, 1, OPTAB_WIDEN);
4711 st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
4712 st_tmp_1, 1, OPTAB_WIDEN);
4713 }
4714
4715 /* Store it all. */
4716 if (WORDS_BIG_ENDIAN)
4717 emit_move_insn (st_addr_1, st_tmp_1);
4718 else
4719 emit_move_insn (st_addr_2, st_tmp_2);
4720 for (i = words-1; i > 0; --i)
4721 {
4722 rtx tmp = change_address (dmem, DImode,
4723 gen_rtx_AND (DImode,
4724 plus_constant(dmema,
4725 WORDS_BIG_ENDIAN ? i*8-1 : i*8),
4726 im8));
4727 set_mem_alias_set (tmp, 0);
4728 emit_move_insn (tmp, data_regs ? ins_tmps[i-1] : const0_rtx);
4729 }
4730 if (WORDS_BIG_ENDIAN)
4731 emit_move_insn (st_addr_2, st_tmp_2);
4732 else
4733 emit_move_insn (st_addr_1, st_tmp_1);
4734 }
4735
4736
4737 /* Expand string/block move operations.
4738
4739 operands[0] is the pointer to the destination.
4740 operands[1] is the pointer to the source.
4741 operands[2] is the number of bytes to move.
4742 operands[3] is the alignment. */
4743
4744 int
4745 alpha_expand_block_move (operands)
4746 rtx operands[];
4747 {
4748 rtx bytes_rtx = operands[2];
4749 rtx align_rtx = operands[3];
4750 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
4751 HOST_WIDE_INT bytes = orig_bytes;
4752 HOST_WIDE_INT src_align = INTVAL (align_rtx) * BITS_PER_UNIT;
4753 HOST_WIDE_INT dst_align = src_align;
4754 rtx orig_src = operands[1];
4755 rtx orig_dst = operands[0];
4756 rtx data_regs[2 * MAX_MOVE_WORDS + 16];
4757 rtx tmp;
4758 unsigned int i, words, ofs, nregs = 0;
4759
4760 if (orig_bytes <= 0)
4761 return 1;
4762 else if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD)
4763 return 0;
4764
4765 /* Look for additional alignment information from recorded register info. */
4766
4767 tmp = XEXP (orig_src, 0);
4768 if (GET_CODE (tmp) == REG)
4769 src_align = MAX (src_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
4770 else if (GET_CODE (tmp) == PLUS
4771 && GET_CODE (XEXP (tmp, 0)) == REG
4772 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
4773 {
4774 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
4775 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
4776
4777 if (a > src_align)
4778 {
4779 if (a >= 64 && c % 8 == 0)
4780 src_align = 64;
4781 else if (a >= 32 && c % 4 == 0)
4782 src_align = 32;
4783 else if (a >= 16 && c % 2 == 0)
4784 src_align = 16;
4785 }
4786 }
4787
4788 tmp = XEXP (orig_dst, 0);
4789 if (GET_CODE (tmp) == REG)
4790 dst_align = MAX (dst_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
4791 else if (GET_CODE (tmp) == PLUS
4792 && GET_CODE (XEXP (tmp, 0)) == REG
4793 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
4794 {
4795 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
4796 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
4797
4798 if (a > dst_align)
4799 {
4800 if (a >= 64 && c % 8 == 0)
4801 dst_align = 64;
4802 else if (a >= 32 && c % 4 == 0)
4803 dst_align = 32;
4804 else if (a >= 16 && c % 2 == 0)
4805 dst_align = 16;
4806 }
4807 }
4808
4809 /* Load the entire block into registers. */
4810 if (GET_CODE (XEXP (orig_src, 0)) == ADDRESSOF)
4811 {
4812 enum machine_mode mode;
4813
4814 tmp = XEXP (XEXP (orig_src, 0), 0);
4815
4816 /* Don't use the existing register if we're reading more than
4817 is held in the register. Nor if there is not a mode that
4818 handles the exact size. */
4819 mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);
4820 if (mode != BLKmode
4821 && GET_MODE_SIZE (GET_MODE (tmp)) >= bytes)
4822 {
4823 if (mode == TImode)
4824 {
4825 data_regs[nregs] = gen_lowpart (DImode, tmp);
4826 data_regs[nregs + 1] = gen_highpart (DImode, tmp);
4827 nregs += 2;
4828 }
4829 else
4830 data_regs[nregs++] = gen_lowpart (mode, tmp);
4831
4832 goto src_done;
4833 }
4834
4835 /* No appropriate mode; fall back on memory. */
4836 orig_src = replace_equiv_address (orig_src,
4837 copy_addr_to_reg (XEXP (orig_src, 0)));
4838 src_align = GET_MODE_BITSIZE (GET_MODE (tmp));
4839 }
4840
4841 ofs = 0;
4842 if (src_align >= 64 && bytes >= 8)
4843 {
4844 words = bytes / 8;
4845
4846 for (i = 0; i < words; ++i)
4847 data_regs[nregs + i] = gen_reg_rtx (DImode);
4848
4849 for (i = 0; i < words; ++i)
4850 emit_move_insn (data_regs[nregs + i],
4851 adjust_address (orig_src, DImode, ofs + i * 8));
4852
4853 nregs += words;
4854 bytes -= words * 8;
4855 ofs += words * 8;
4856 }
4857
4858 if (src_align >= 32 && bytes >= 4)
4859 {
4860 words = bytes / 4;
4861
4862 for (i = 0; i < words; ++i)
4863 data_regs[nregs + i] = gen_reg_rtx (SImode);
4864
4865 for (i = 0; i < words; ++i)
4866 emit_move_insn (data_regs[nregs + i],
4867 adjust_address (orig_src, SImode, ofs + i * 4));
4868
4869 nregs += words;
4870 bytes -= words * 4;
4871 ofs += words * 4;
4872 }
4873
4874 if (bytes >= 8)
4875 {
4876 words = bytes / 8;
4877
4878 for (i = 0; i < words+1; ++i)
4879 data_regs[nregs + i] = gen_reg_rtx (DImode);
4880
4881 alpha_expand_unaligned_load_words (data_regs + nregs, orig_src,
4882 words, ofs);
4883
4884 nregs += words;
4885 bytes -= words * 8;
4886 ofs += words * 8;
4887 }
4888
4889 if (! TARGET_BWX && bytes >= 4)
4890 {
4891 data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
4892 alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
4893 bytes -= 4;
4894 ofs += 4;
4895 }
4896
4897 if (bytes >= 2)
4898 {
4899 if (src_align >= 16)
4900 {
4901 do {
4902 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
4903 emit_move_insn (tmp, adjust_address (orig_src, HImode, ofs));
4904 bytes -= 2;
4905 ofs += 2;
4906 } while (bytes >= 2);
4907 }
4908 else if (! TARGET_BWX)
4909 {
4910 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
4911 alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
4912 bytes -= 2;
4913 ofs += 2;
4914 }
4915 }
4916
4917 while (bytes > 0)
4918 {
4919 data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
4920 emit_move_insn (tmp, adjust_address (orig_src, QImode, ofs));
4921 bytes -= 1;
4922 ofs += 1;
4923 }
4924
4925 src_done:
4926
4927 if (nregs > ARRAY_SIZE (data_regs))
4928 abort ();
4929
4930 /* Now save it back out again. */
4931
4932 i = 0, ofs = 0;
4933
4934 if (GET_CODE (XEXP (orig_dst, 0)) == ADDRESSOF)
4935 {
4936 enum machine_mode mode;
4937 tmp = XEXP (XEXP (orig_dst, 0), 0);
4938
4939 mode = mode_for_size (orig_bytes * BITS_PER_UNIT, MODE_INT, 1);
4940 if (GET_MODE (tmp) == mode)
4941 {
4942 if (nregs == 1)
4943 {
4944 emit_move_insn (tmp, data_regs[0]);
4945 i = 1;
4946 goto dst_done;
4947 }
4948
4949 else if (nregs == 2 && mode == TImode)
4950 {
4951 /* Undo the subregging done above when copying between
4952 two TImode registers. */
4953 if (GET_CODE (data_regs[0]) == SUBREG
4954 && GET_MODE (SUBREG_REG (data_regs[0])) == TImode)
4955 emit_move_insn (tmp, SUBREG_REG (data_regs[0]));
4956 else
4957 {
4958 rtx seq;
4959
4960 start_sequence ();
4961 emit_move_insn (gen_lowpart (DImode, tmp), data_regs[0]);
4962 emit_move_insn (gen_highpart (DImode, tmp), data_regs[1]);
4963 seq = get_insns ();
4964 end_sequence ();
4965
4966 emit_no_conflict_block (seq, tmp, data_regs[0],
4967 data_regs[1], NULL_RTX);
4968 }
4969
4970 i = 2;
4971 goto dst_done;
4972 }
4973 }
4974
4975 /* ??? If nregs > 1, consider reconstructing the word in regs. */
4976 /* ??? Optimize mode < dst_mode with strict_low_part. */
4977
4978 /* No appropriate mode; fall back on memory. We can speed things
4979 up by recognizing extra alignment information. */
4980 orig_dst = replace_equiv_address (orig_dst,
4981 copy_addr_to_reg (XEXP (orig_dst, 0)));
4982 dst_align = GET_MODE_BITSIZE (GET_MODE (tmp));
4983 }
4984
4985 /* Write out the data in whatever chunks reading the source allowed. */
4986 if (dst_align >= 64)
4987 {
4988 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
4989 {
4990 emit_move_insn (adjust_address (orig_dst, DImode, ofs),
4991 data_regs[i]);
4992 ofs += 8;
4993 i++;
4994 }
4995 }
4996
4997 if (dst_align >= 32)
4998 {
4999 /* If the source has remaining DImode regs, write them out in
5000 two pieces. */
5001 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
5002 {
5003 tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
5004 NULL_RTX, 1, OPTAB_WIDEN);
5005
5006 emit_move_insn (adjust_address (orig_dst, SImode, ofs),
5007 gen_lowpart (SImode, data_regs[i]));
5008 emit_move_insn (adjust_address (orig_dst, SImode, ofs + 4),
5009 gen_lowpart (SImode, tmp));
5010 ofs += 8;
5011 i++;
5012 }
5013
5014 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
5015 {
5016 emit_move_insn (adjust_address (orig_dst, SImode, ofs),
5017 data_regs[i]);
5018 ofs += 4;
5019 i++;
5020 }
5021 }
5022
5023 if (i < nregs && GET_MODE (data_regs[i]) == DImode)
5024 {
5025 /* Write out a remaining block of words using unaligned methods. */
5026
5027 for (words = 1; i + words < nregs; words++)
5028 if (GET_MODE (data_regs[i + words]) != DImode)
5029 break;
5030
5031 if (words == 1)
5032 alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
5033 else
5034 alpha_expand_unaligned_store_words (data_regs + i, orig_dst,
5035 words, ofs);
5036
5037 i += words;
5038 ofs += words * 8;
5039 }
5040
5041 /* Due to the above, this won't be aligned. */
5042 /* ??? If we have more than one of these, consider constructing full
5043 words in registers and using alpha_expand_unaligned_store_words. */
5044 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
5045 {
5046 alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
5047 ofs += 4;
5048 i++;
5049 }
5050
5051 if (dst_align >= 16)
5052 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
5053 {
5054 emit_move_insn (adjust_address (orig_dst, HImode, ofs), data_regs[i]);
5055 i++;
5056 ofs += 2;
5057 }
5058 else
5059 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
5060 {
5061 alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
5062 i++;
5063 ofs += 2;
5064 }
5065
5066 while (i < nregs && GET_MODE (data_regs[i]) == QImode)
5067 {
5068 emit_move_insn (adjust_address (orig_dst, QImode, ofs), data_regs[i]);
5069 i++;
5070 ofs += 1;
5071 }
5072
5073 dst_done:
5074
5075 if (i != nregs)
5076 abort ();
5077
5078 return 1;
5079 }
5080
5081 int
5082 alpha_expand_block_clear (operands)
5083 rtx operands[];
5084 {
5085 rtx bytes_rtx = operands[1];
5086 rtx align_rtx = operands[2];
5087 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
5088 HOST_WIDE_INT bytes = orig_bytes;
5089 HOST_WIDE_INT align = INTVAL (align_rtx) * BITS_PER_UNIT;
5090 HOST_WIDE_INT alignofs = 0;
5091 rtx orig_dst = operands[0];
5092 rtx tmp;
5093 int i, words, ofs = 0;
5094
5095 if (orig_bytes <= 0)
5096 return 1;
5097 if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD)
5098 return 0;
5099
5100 /* Look for stricter alignment. */
5101 tmp = XEXP (orig_dst, 0);
5102 if (GET_CODE (tmp) == REG)
5103 align = MAX (align, REGNO_POINTER_ALIGN (REGNO (tmp)));
5104 else if (GET_CODE (tmp) == PLUS
5105 && GET_CODE (XEXP (tmp, 0)) == REG
5106 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
5107 {
5108 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
5109 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
5110
5111 if (a > align)
5112 {
5113 if (a >= 64)
5114 align = a, alignofs = 8 - c % 8;
5115 else if (a >= 32)
5116 align = a, alignofs = 4 - c % 4;
5117 else if (a >= 16)
5118 align = a, alignofs = 2 - c % 2;
5119 }
5120 }
5121 else if (GET_CODE (tmp) == ADDRESSOF)
5122 {
5123 enum machine_mode mode;
5124
5125 mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);
5126 if (GET_MODE (XEXP (tmp, 0)) == mode)
5127 {
5128 emit_move_insn (XEXP (tmp, 0), const0_rtx);
5129 return 1;
5130 }
5131
5132 /* No appropriate mode; fall back on memory. */
5133 orig_dst = replace_equiv_address (orig_dst, copy_addr_to_reg (tmp));
5134 align = GET_MODE_BITSIZE (GET_MODE (XEXP (tmp, 0)));
5135 }
5136
5137 /* Handle an unaligned prefix first. */
5138
5139 if (alignofs > 0)
5140 {
5141 #if HOST_BITS_PER_WIDE_INT >= 64
5142 /* Given that alignofs is bounded by align, the only time BWX could
5143 generate three stores is for a 7 byte fill. Prefer two individual
5144 stores over a load/mask/store sequence. */
5145 if ((!TARGET_BWX || alignofs == 7)
5146 && align >= 32
5147 && !(alignofs == 4 && bytes >= 4))
5148 {
5149 enum machine_mode mode = (align >= 64 ? DImode : SImode);
5150 int inv_alignofs = (align >= 64 ? 8 : 4) - alignofs;
5151 rtx mem, tmp;
5152 HOST_WIDE_INT mask;
5153
5154 mem = adjust_address (orig_dst, mode, ofs - inv_alignofs);
5155 set_mem_alias_set (mem, 0);
5156
5157 mask = ~(~(HOST_WIDE_INT)0 << (inv_alignofs * 8));
5158 if (bytes < alignofs)
5159 {
5160 mask |= ~(HOST_WIDE_INT)0 << ((inv_alignofs + bytes) * 8);
5161 ofs += bytes;
5162 bytes = 0;
5163 }
5164 else
5165 {
5166 bytes -= alignofs;
5167 ofs += alignofs;
5168 }
5169 alignofs = 0;
5170
5171 tmp = expand_binop (mode, and_optab, mem, GEN_INT (mask),
5172 NULL_RTX, 1, OPTAB_WIDEN);
5173
5174 emit_move_insn (mem, tmp);
5175 }
5176 #endif
5177
5178 if (TARGET_BWX && (alignofs & 1) && bytes >= 1)
5179 {
5180 emit_move_insn (adjust_address (orig_dst, QImode, ofs), const0_rtx);
5181 bytes -= 1;
5182 ofs += 1;
5183 alignofs -= 1;
5184 }
5185 if (TARGET_BWX && align >= 16 && (alignofs & 3) == 2 && bytes >= 2)
5186 {
5187 emit_move_insn (adjust_address (orig_dst, HImode, ofs), const0_rtx);
5188 bytes -= 2;
5189 ofs += 2;
5190 alignofs -= 2;
5191 }
5192 if (alignofs == 4 && bytes >= 4)
5193 {
5194 emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx);
5195 bytes -= 4;
5196 ofs += 4;
5197 alignofs = 0;
5198 }
5199
5200 /* If we've not used the extra lead alignment information by now,
5201 we won't be able to. Downgrade align to match what's left over. */
5202 if (alignofs > 0)
5203 {
5204 alignofs = alignofs & -alignofs;
5205 align = MIN (align, alignofs * BITS_PER_UNIT);
5206 }
5207 }
5208
5209 /* Handle a block of contiguous long-words. */
5210
5211 if (align >= 64 && bytes >= 8)
5212 {
5213 words = bytes / 8;
5214
5215 for (i = 0; i < words; ++i)
5216 emit_move_insn (adjust_address (orig_dst, DImode, ofs + i * 8),
5217 const0_rtx);
5218
5219 bytes -= words * 8;
5220 ofs += words * 8;
5221 }
5222
5223 /* If the block is large and appropriately aligned, emit a single
5224 store followed by a sequence of stq_u insns. */
5225
5226 if (align >= 32 && bytes > 16)
5227 {
5228 rtx orig_dsta;
5229
5230 emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx);
5231 bytes -= 4;
5232 ofs += 4;
5233
5234 orig_dsta = XEXP (orig_dst, 0);
5235 if (GET_CODE (orig_dsta) == LO_SUM)
5236 orig_dsta = force_reg (Pmode, orig_dsta);
5237
5238 words = bytes / 8;
5239 for (i = 0; i < words; ++i)
5240 {
5241 rtx mem
5242 = change_address (orig_dst, DImode,
5243 gen_rtx_AND (DImode,
5244 plus_constant (orig_dsta, ofs + i*8),
5245 GEN_INT (-8)));
5246 set_mem_alias_set (mem, 0);
5247 emit_move_insn (mem, const0_rtx);
5248 }
5249
5250 /* Depending on the alignment, the first stq_u may have overlapped
5251 with the initial stl, which means that the last stq_u didn't
5252 write as much as it would appear. Leave those questionable bytes
5253 unaccounted for. */
5254 bytes -= words * 8 - 4;
5255 ofs += words * 8 - 4;
5256 }
5257
5258 /* Handle a smaller block of aligned words. */
5259
5260 if ((align >= 64 && bytes == 4)
5261 || (align == 32 && bytes >= 4))
5262 {
5263 words = bytes / 4;
5264
5265 for (i = 0; i < words; ++i)
5266 emit_move_insn (adjust_address (orig_dst, SImode, ofs + i * 4),
5267 const0_rtx);
5268
5269 bytes -= words * 4;
5270 ofs += words * 4;
5271 }
5272
5273 /* An unaligned block uses stq_u stores for as many as possible. */
5274
5275 if (bytes >= 8)
5276 {
5277 words = bytes / 8;
5278
5279 alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
5280
5281 bytes -= words * 8;
5282 ofs += words * 8;
5283 }
5284
5285 /* Next clean up any trailing pieces. */
5286
5287 #if HOST_BITS_PER_WIDE_INT >= 64
5288 /* Count the number of bits in BYTES for which aligned stores could
5289 be emitted. */
5290 words = 0;
5291 for (i = (TARGET_BWX ? 1 : 4); i * BITS_PER_UNIT <= align ; i <<= 1)
5292 if (bytes & i)
5293 words += 1;
5294
5295 /* If we have appropriate alignment (and it wouldn't take too many
5296 instructions otherwise), mask out the bytes we need. */
5297 if (TARGET_BWX ? words > 2 : bytes > 0)
5298 {
5299 if (align >= 64)
5300 {
5301 rtx mem, tmp;
5302 HOST_WIDE_INT mask;
5303
5304 mem = adjust_address (orig_dst, DImode, ofs);
5305 set_mem_alias_set (mem, 0);
5306
5307 mask = ~(HOST_WIDE_INT)0 << (bytes * 8);
5308
5309 tmp = expand_binop (DImode, and_optab, mem, GEN_INT (mask),
5310 NULL_RTX, 1, OPTAB_WIDEN);
5311
5312 emit_move_insn (mem, tmp);
5313 return 1;
5314 }
5315 else if (align >= 32 && bytes < 4)
5316 {
5317 rtx mem, tmp;
5318 HOST_WIDE_INT mask;
5319
5320 mem = adjust_address (orig_dst, SImode, ofs);
5321 set_mem_alias_set (mem, 0);
5322
5323 mask = ~(HOST_WIDE_INT)0 << (bytes * 8);
5324
5325 tmp = expand_binop (SImode, and_optab, mem, GEN_INT (mask),
5326 NULL_RTX, 1, OPTAB_WIDEN);
5327
5328 emit_move_insn (mem, tmp);
5329 return 1;
5330 }
5331 }
5332 #endif
5333
5334 if (!TARGET_BWX && bytes >= 4)
5335 {
5336 alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
5337 bytes -= 4;
5338 ofs += 4;
5339 }
5340
5341 if (bytes >= 2)
5342 {
5343 if (align >= 16)
5344 {
5345 do {
5346 emit_move_insn (adjust_address (orig_dst, HImode, ofs),
5347 const0_rtx);
5348 bytes -= 2;
5349 ofs += 2;
5350 } while (bytes >= 2);
5351 }
5352 else if (! TARGET_BWX)
5353 {
5354 alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
5355 bytes -= 2;
5356 ofs += 2;
5357 }
5358 }
5359
5360 while (bytes > 0)
5361 {
5362 emit_move_insn (adjust_address (orig_dst, QImode, ofs), const0_rtx);
5363 bytes -= 1;
5364 ofs += 1;
5365 }
5366
5367 return 1;
5368 }
5369
5370 /* Returns a mask so that zap(x, value) == x & mask. */
5371
5372 rtx
5373 alpha_expand_zap_mask (value)
5374 HOST_WIDE_INT value;
5375 {
5376 rtx result;
5377 int i;
5378
5379 if (HOST_BITS_PER_WIDE_INT >= 64)
5380 {
5381 HOST_WIDE_INT mask = 0;
5382
5383 for (i = 7; i >= 0; --i)
5384 {
5385 mask <<= 8;
5386 if (!((value >> i) & 1))
5387 mask |= 0xff;
5388 }
5389
5390 result = gen_int_mode (mask, DImode);
5391 }
5392 else if (HOST_BITS_PER_WIDE_INT == 32)
5393 {
5394 HOST_WIDE_INT mask_lo = 0, mask_hi = 0;
5395
5396 for (i = 7; i >= 4; --i)
5397 {
5398 mask_hi <<= 8;
5399 if (!((value >> i) & 1))
5400 mask_hi |= 0xff;
5401 }
5402
5403 for (i = 3; i >= 0; --i)
5404 {
5405 mask_lo <<= 8;
5406 if (!((value >> i) & 1))
5407 mask_lo |= 0xff;
5408 }
5409
5410 result = immed_double_const (mask_lo, mask_hi, DImode);
5411 }
5412 else
5413 abort ();
5414
5415 return result;
5416 }
5417
5418 void
5419 alpha_expand_builtin_vector_binop (gen, mode, op0, op1, op2)
5420 rtx (*gen) PARAMS ((rtx, rtx, rtx));
5421 enum machine_mode mode;
5422 rtx op0, op1, op2;
5423 {
5424 op0 = gen_lowpart (mode, op0);
5425
5426 if (op1 == const0_rtx)
5427 op1 = CONST0_RTX (mode);
5428 else
5429 op1 = gen_lowpart (mode, op1);
5430
5431 if (op2 == const0_rtx)
5432 op2 = CONST0_RTX (mode);
5433 else
5434 op2 = gen_lowpart (mode, op2);
5435
5436 emit_insn ((*gen) (op0, op1, op2));
5437 }
5438 \f
5439 /* Adjust the cost of a scheduling dependency. Return the new cost of
5440 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
5441
5442 static int
5443 alpha_adjust_cost (insn, link, dep_insn, cost)
5444 rtx insn;
5445 rtx link;
5446 rtx dep_insn;
5447 int cost;
5448 {
5449 enum attr_type insn_type, dep_insn_type;
5450
5451 /* If the dependence is an anti-dependence, there is no cost. For an
5452 output dependence, there is sometimes a cost, but it doesn't seem
5453 worth handling those few cases. */
5454 if (REG_NOTE_KIND (link) != 0)
5455 return cost;
5456
5457 /* If we can't recognize the insns, we can't really do anything. */
5458 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
5459 return cost;
5460
5461 insn_type = get_attr_type (insn);
5462 dep_insn_type = get_attr_type (dep_insn);
5463
5464 /* Bring in the user-defined memory latency. */
5465 if (dep_insn_type == TYPE_ILD
5466 || dep_insn_type == TYPE_FLD
5467 || dep_insn_type == TYPE_LDSYM)
5468 cost += alpha_memory_latency-1;
5469
5470 /* Everything else handled in DFA bypasses now. */
5471
5472 return cost;
5473 }
5474
5475 /* The number of instructions that can be issued per cycle. */
5476
5477 static int
5478 alpha_issue_rate ()
5479 {
5480 return (alpha_cpu == PROCESSOR_EV4 ? 2 : 4);
5481 }
5482
5483 static int
5484 alpha_use_dfa_pipeline_interface ()
5485 {
5486 return true;
5487 }
5488
5489 /* How many alternative schedules to try. This should be as wide as the
5490 scheduling freedom in the DFA, but no wider. Making this value too
5491 large results extra work for the scheduler.
5492
5493 For EV4, loads can be issued to either IB0 or IB1, thus we have 2
5494 alternative schedules. For EV5, we can choose between E0/E1 and
5495 FA/FM. For EV6, an arithmatic insn can be issued to U0/U1/L0/L1. */
5496
5497 static int
5498 alpha_multipass_dfa_lookahead ()
5499 {
5500 return (alpha_cpu == PROCESSOR_EV6 ? 4 : 2);
5501 }
5502 \f
5503 /* Machine-specific function data. */
5504
5505 struct machine_function GTY(())
5506 {
5507 /* For unicosmk. */
5508 /* List of call information words for calls from this function. */
5509 struct rtx_def *first_ciw;
5510 struct rtx_def *last_ciw;
5511 int ciw_count;
5512
5513 /* List of deferred case vectors. */
5514 struct rtx_def *addr_list;
5515
5516 /* For OSF. */
5517 const char *some_ld_name;
5518 };
5519
5520 /* How to allocate a 'struct machine_function'. */
5521
5522 static struct machine_function *
5523 alpha_init_machine_status ()
5524 {
5525 return ((struct machine_function *)
5526 ggc_alloc_cleared (sizeof (struct machine_function)));
5527 }
5528
5529 /* Functions to save and restore alpha_return_addr_rtx. */
5530
5531 /* Start the ball rolling with RETURN_ADDR_RTX. */
5532
5533 rtx
5534 alpha_return_addr (count, frame)
5535 int count;
5536 rtx frame ATTRIBUTE_UNUSED;
5537 {
5538 if (count != 0)
5539 return const0_rtx;
5540
5541 return get_hard_reg_initial_val (Pmode, REG_RA);
5542 }
5543
5544 /* Return or create a pseudo containing the gp value for the current
5545 function. Needed only if TARGET_LD_BUGGY_LDGP. */
5546
5547 rtx
5548 alpha_gp_save_rtx ()
5549 {
5550 rtx r = get_hard_reg_initial_val (DImode, 29);
5551 if (GET_CODE (r) != MEM)
5552 r = gen_mem_addressof (r, NULL_TREE, /*rescan=*/true);
5553 return r;
5554 }
5555
5556 static int
5557 alpha_ra_ever_killed ()
5558 {
5559 rtx top;
5560
5561 if (!has_hard_reg_initial_val (Pmode, REG_RA))
5562 return regs_ever_live[REG_RA];
5563
5564 push_topmost_sequence ();
5565 top = get_insns ();
5566 pop_topmost_sequence ();
5567
5568 return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX);
5569 }
5570
5571 \f
5572 /* Return the trap mode suffix applicable to the current
5573 instruction, or NULL. */
5574
5575 static const char *
5576 get_trap_mode_suffix ()
5577 {
5578 enum attr_trap_suffix s = get_attr_trap_suffix (current_output_insn);
5579
5580 switch (s)
5581 {
5582 case TRAP_SUFFIX_NONE:
5583 return NULL;
5584
5585 case TRAP_SUFFIX_SU:
5586 if (alpha_fptm >= ALPHA_FPTM_SU)
5587 return "su";
5588 return NULL;
5589
5590 case TRAP_SUFFIX_SUI:
5591 if (alpha_fptm >= ALPHA_FPTM_SUI)
5592 return "sui";
5593 return NULL;
5594
5595 case TRAP_SUFFIX_V_SV:
5596 switch (alpha_fptm)
5597 {
5598 case ALPHA_FPTM_N:
5599 return NULL;
5600 case ALPHA_FPTM_U:
5601 return "v";
5602 case ALPHA_FPTM_SU:
5603 case ALPHA_FPTM_SUI:
5604 return "sv";
5605 }
5606 break;
5607
5608 case TRAP_SUFFIX_V_SV_SVI:
5609 switch (alpha_fptm)
5610 {
5611 case ALPHA_FPTM_N:
5612 return NULL;
5613 case ALPHA_FPTM_U:
5614 return "v";
5615 case ALPHA_FPTM_SU:
5616 return "sv";
5617 case ALPHA_FPTM_SUI:
5618 return "svi";
5619 }
5620 break;
5621
5622 case TRAP_SUFFIX_U_SU_SUI:
5623 switch (alpha_fptm)
5624 {
5625 case ALPHA_FPTM_N:
5626 return NULL;
5627 case ALPHA_FPTM_U:
5628 return "u";
5629 case ALPHA_FPTM_SU:
5630 return "su";
5631 case ALPHA_FPTM_SUI:
5632 return "sui";
5633 }
5634 break;
5635 }
5636 abort ();
5637 }
5638
5639 /* Return the rounding mode suffix applicable to the current
5640 instruction, or NULL. */
5641
5642 static const char *
5643 get_round_mode_suffix ()
5644 {
5645 enum attr_round_suffix s = get_attr_round_suffix (current_output_insn);
5646
5647 switch (s)
5648 {
5649 case ROUND_SUFFIX_NONE:
5650 return NULL;
5651 case ROUND_SUFFIX_NORMAL:
5652 switch (alpha_fprm)
5653 {
5654 case ALPHA_FPRM_NORM:
5655 return NULL;
5656 case ALPHA_FPRM_MINF:
5657 return "m";
5658 case ALPHA_FPRM_CHOP:
5659 return "c";
5660 case ALPHA_FPRM_DYN:
5661 return "d";
5662 }
5663 break;
5664
5665 case ROUND_SUFFIX_C:
5666 return "c";
5667 }
5668 abort ();
5669 }
5670
5671 /* Locate some local-dynamic symbol still in use by this function
5672 so that we can print its name in some movdi_er_tlsldm pattern. */
5673
5674 static const char *
5675 get_some_local_dynamic_name ()
5676 {
5677 rtx insn;
5678
5679 if (cfun->machine->some_ld_name)
5680 return cfun->machine->some_ld_name;
5681
5682 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
5683 if (INSN_P (insn)
5684 && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
5685 return cfun->machine->some_ld_name;
5686
5687 abort ();
5688 }
5689
5690 static int
5691 get_some_local_dynamic_name_1 (px, data)
5692 rtx *px;
5693 void *data ATTRIBUTE_UNUSED;
5694 {
5695 rtx x = *px;
5696
5697 if (GET_CODE (x) == SYMBOL_REF
5698 && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
5699 {
5700 cfun->machine->some_ld_name = XSTR (x, 0);
5701 return 1;
5702 }
5703
5704 return 0;
5705 }
5706
5707 /* Print an operand. Recognize special options, documented below. */
5708
5709 void
5710 print_operand (file, x, code)
5711 FILE *file;
5712 rtx x;
5713 int code;
5714 {
5715 int i;
5716
5717 switch (code)
5718 {
5719 case '~':
5720 /* Print the assembler name of the current function. */
5721 assemble_name (file, alpha_fnname);
5722 break;
5723
5724 case '&':
5725 assemble_name (file, get_some_local_dynamic_name ());
5726 break;
5727
5728 case '/':
5729 {
5730 const char *trap = get_trap_mode_suffix ();
5731 const char *round = get_round_mode_suffix ();
5732
5733 if (trap || round)
5734 fprintf (file, (TARGET_AS_SLASH_BEFORE_SUFFIX ? "/%s%s" : "%s%s"),
5735 (trap ? trap : ""), (round ? round : ""));
5736 break;
5737 }
5738
5739 case ',':
5740 /* Generates single precision instruction suffix. */
5741 fputc ((TARGET_FLOAT_VAX ? 'f' : 's'), file);
5742 break;
5743
5744 case '-':
5745 /* Generates double precision instruction suffix. */
5746 fputc ((TARGET_FLOAT_VAX ? 'g' : 't'), file);
5747 break;
5748
5749 case '+':
5750 /* Generates a nop after a noreturn call at the very end of the
5751 function. */
5752 if (next_real_insn (current_output_insn) == 0)
5753 fprintf (file, "\n\tnop");
5754 break;
5755
5756 case '#':
5757 if (alpha_this_literal_sequence_number == 0)
5758 alpha_this_literal_sequence_number = alpha_next_sequence_number++;
5759 fprintf (file, "%d", alpha_this_literal_sequence_number);
5760 break;
5761
5762 case '*':
5763 if (alpha_this_gpdisp_sequence_number == 0)
5764 alpha_this_gpdisp_sequence_number = alpha_next_sequence_number++;
5765 fprintf (file, "%d", alpha_this_gpdisp_sequence_number);
5766 break;
5767
5768 case 'H':
5769 if (GET_CODE (x) == HIGH)
5770 output_addr_const (file, XEXP (x, 0));
5771 else
5772 output_operand_lossage ("invalid %%H value");
5773 break;
5774
5775 case 'J':
5776 {
5777 const char *lituse;
5778
5779 if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD_CALL)
5780 {
5781 x = XVECEXP (x, 0, 0);
5782 lituse = "lituse_tlsgd";
5783 }
5784 else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM_CALL)
5785 {
5786 x = XVECEXP (x, 0, 0);
5787 lituse = "lituse_tlsldm";
5788 }
5789 else if (GET_CODE (x) == CONST_INT)
5790 lituse = "lituse_jsr";
5791 else
5792 {
5793 output_operand_lossage ("invalid %%J value");
5794 break;
5795 }
5796
5797 if (x != const0_rtx)
5798 fprintf (file, "\t\t!%s!%d", lituse, (int) INTVAL (x));
5799 }
5800 break;
5801
5802 case 'r':
5803 /* If this operand is the constant zero, write it as "$31". */
5804 if (GET_CODE (x) == REG)
5805 fprintf (file, "%s", reg_names[REGNO (x)]);
5806 else if (x == CONST0_RTX (GET_MODE (x)))
5807 fprintf (file, "$31");
5808 else
5809 output_operand_lossage ("invalid %%r value");
5810 break;
5811
5812 case 'R':
5813 /* Similar, but for floating-point. */
5814 if (GET_CODE (x) == REG)
5815 fprintf (file, "%s", reg_names[REGNO (x)]);
5816 else if (x == CONST0_RTX (GET_MODE (x)))
5817 fprintf (file, "$f31");
5818 else
5819 output_operand_lossage ("invalid %%R value");
5820 break;
5821
5822 case 'N':
5823 /* Write the 1's complement of a constant. */
5824 if (GET_CODE (x) != CONST_INT)
5825 output_operand_lossage ("invalid %%N value");
5826
5827 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
5828 break;
5829
5830 case 'P':
5831 /* Write 1 << C, for a constant C. */
5832 if (GET_CODE (x) != CONST_INT)
5833 output_operand_lossage ("invalid %%P value");
5834
5835 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
5836 break;
5837
5838 case 'h':
5839 /* Write the high-order 16 bits of a constant, sign-extended. */
5840 if (GET_CODE (x) != CONST_INT)
5841 output_operand_lossage ("invalid %%h value");
5842
5843 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
5844 break;
5845
5846 case 'L':
5847 /* Write the low-order 16 bits of a constant, sign-extended. */
5848 if (GET_CODE (x) != CONST_INT)
5849 output_operand_lossage ("invalid %%L value");
5850
5851 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
5852 (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
5853 break;
5854
5855 case 'm':
5856 /* Write mask for ZAP insn. */
5857 if (GET_CODE (x) == CONST_DOUBLE)
5858 {
5859 HOST_WIDE_INT mask = 0;
5860 HOST_WIDE_INT value;
5861
5862 value = CONST_DOUBLE_LOW (x);
5863 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
5864 i++, value >>= 8)
5865 if (value & 0xff)
5866 mask |= (1 << i);
5867
5868 value = CONST_DOUBLE_HIGH (x);
5869 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
5870 i++, value >>= 8)
5871 if (value & 0xff)
5872 mask |= (1 << (i + sizeof (int)));
5873
5874 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
5875 }
5876
5877 else if (GET_CODE (x) == CONST_INT)
5878 {
5879 HOST_WIDE_INT mask = 0, value = INTVAL (x);
5880
5881 for (i = 0; i < 8; i++, value >>= 8)
5882 if (value & 0xff)
5883 mask |= (1 << i);
5884
5885 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
5886 }
5887 else
5888 output_operand_lossage ("invalid %%m value");
5889 break;
5890
5891 case 'M':
5892 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
5893 if (GET_CODE (x) != CONST_INT
5894 || (INTVAL (x) != 8 && INTVAL (x) != 16
5895 && INTVAL (x) != 32 && INTVAL (x) != 64))
5896 output_operand_lossage ("invalid %%M value");
5897
5898 fprintf (file, "%s",
5899 (INTVAL (x) == 8 ? "b"
5900 : INTVAL (x) == 16 ? "w"
5901 : INTVAL (x) == 32 ? "l"
5902 : "q"));
5903 break;
5904
5905 case 'U':
5906 /* Similar, except do it from the mask. */
5907 if (GET_CODE (x) == CONST_INT)
5908 {
5909 HOST_WIDE_INT value = INTVAL (x);
5910
5911 if (value == 0xff)
5912 {
5913 fputc ('b', file);
5914 break;
5915 }
5916 if (value == 0xffff)
5917 {
5918 fputc ('w', file);
5919 break;
5920 }
5921 if (value == 0xffffffff)
5922 {
5923 fputc ('l', file);
5924 break;
5925 }
5926 if (value == -1)
5927 {
5928 fputc ('q', file);
5929 break;
5930 }
5931 }
5932 else if (HOST_BITS_PER_WIDE_INT == 32
5933 && GET_CODE (x) == CONST_DOUBLE
5934 && CONST_DOUBLE_LOW (x) == 0xffffffff
5935 && CONST_DOUBLE_HIGH (x) == 0)
5936 {
5937 fputc ('l', file);
5938 break;
5939 }
5940 output_operand_lossage ("invalid %%U value");
5941 break;
5942
5943 case 's':
5944 /* Write the constant value divided by 8 for little-endian mode or
5945 (56 - value) / 8 for big-endian mode. */
5946
5947 if (GET_CODE (x) != CONST_INT
5948 || (unsigned HOST_WIDE_INT) INTVAL (x) >= (WORDS_BIG_ENDIAN
5949 ? 56
5950 : 64)
5951 || (INTVAL (x) & 7) != 0)
5952 output_operand_lossage ("invalid %%s value");
5953
5954 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
5955 WORDS_BIG_ENDIAN
5956 ? (56 - INTVAL (x)) / 8
5957 : INTVAL (x) / 8);
5958 break;
5959
5960 case 'S':
5961 /* Same, except compute (64 - c) / 8 */
5962
5963 if (GET_CODE (x) != CONST_INT
5964 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
5965 && (INTVAL (x) & 7) != 8)
5966 output_operand_lossage ("invalid %%s value");
5967
5968 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
5969 break;
5970
5971 case 't':
5972 {
5973 /* On Unicos/Mk systems: use a DEX expression if the symbol
5974 clashes with a register name. */
5975 int dex = unicosmk_need_dex (x);
5976 if (dex)
5977 fprintf (file, "DEX(%d)", dex);
5978 else
5979 output_addr_const (file, x);
5980 }
5981 break;
5982
5983 case 'C': case 'D': case 'c': case 'd':
5984 /* Write out comparison name. */
5985 {
5986 enum rtx_code c = GET_CODE (x);
5987
5988 if (GET_RTX_CLASS (c) != '<')
5989 output_operand_lossage ("invalid %%C value");
5990
5991 else if (code == 'D')
5992 c = reverse_condition (c);
5993 else if (code == 'c')
5994 c = swap_condition (c);
5995 else if (code == 'd')
5996 c = swap_condition (reverse_condition (c));
5997
5998 if (c == LEU)
5999 fprintf (file, "ule");
6000 else if (c == LTU)
6001 fprintf (file, "ult");
6002 else if (c == UNORDERED)
6003 fprintf (file, "un");
6004 else
6005 fprintf (file, "%s", GET_RTX_NAME (c));
6006 }
6007 break;
6008
6009 case 'E':
6010 /* Write the divide or modulus operator. */
6011 switch (GET_CODE (x))
6012 {
6013 case DIV:
6014 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
6015 break;
6016 case UDIV:
6017 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
6018 break;
6019 case MOD:
6020 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
6021 break;
6022 case UMOD:
6023 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
6024 break;
6025 default:
6026 output_operand_lossage ("invalid %%E value");
6027 break;
6028 }
6029 break;
6030
6031 case 'A':
6032 /* Write "_u" for unaligned access. */
6033 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
6034 fprintf (file, "_u");
6035 break;
6036
6037 case 0:
6038 if (GET_CODE (x) == REG)
6039 fprintf (file, "%s", reg_names[REGNO (x)]);
6040 else if (GET_CODE (x) == MEM)
6041 output_address (XEXP (x, 0));
6042 else if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == UNSPEC)
6043 {
6044 switch (XINT (XEXP (x, 0), 1))
6045 {
6046 case UNSPEC_DTPREL:
6047 case UNSPEC_TPREL:
6048 output_addr_const (file, XVECEXP (XEXP (x, 0), 0, 0));
6049 break;
6050 default:
6051 output_operand_lossage ("unknown relocation unspec");
6052 break;
6053 }
6054 }
6055 else
6056 output_addr_const (file, x);
6057 break;
6058
6059 default:
6060 output_operand_lossage ("invalid %%xn code");
6061 }
6062 }
6063
6064 void
6065 print_operand_address (file, addr)
6066 FILE *file;
6067 rtx addr;
6068 {
6069 int basereg = 31;
6070 HOST_WIDE_INT offset = 0;
6071
6072 if (GET_CODE (addr) == AND)
6073 addr = XEXP (addr, 0);
6074
6075 if (GET_CODE (addr) == PLUS
6076 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6077 {
6078 offset = INTVAL (XEXP (addr, 1));
6079 addr = XEXP (addr, 0);
6080 }
6081
6082 if (GET_CODE (addr) == LO_SUM)
6083 {
6084 const char *reloc16, *reloclo;
6085 rtx op1 = XEXP (addr, 1);
6086
6087 if (GET_CODE (op1) == CONST && GET_CODE (XEXP (op1, 0)) == UNSPEC)
6088 {
6089 op1 = XEXP (op1, 0);
6090 switch (XINT (op1, 1))
6091 {
6092 case UNSPEC_DTPREL:
6093 reloc16 = NULL;
6094 reloclo = (alpha_tls_size == 16 ? "dtprel" : "dtprello");
6095 break;
6096 case UNSPEC_TPREL:
6097 reloc16 = NULL;
6098 reloclo = (alpha_tls_size == 16 ? "tprel" : "tprello");
6099 break;
6100 default:
6101 output_operand_lossage ("unknown relocation unspec");
6102 return;
6103 }
6104
6105 output_addr_const (file, XVECEXP (op1, 0, 0));
6106 }
6107 else
6108 {
6109 reloc16 = "gprel";
6110 reloclo = "gprellow";
6111 output_addr_const (file, op1);
6112 }
6113
6114 if (offset)
6115 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
6116
6117 addr = XEXP (addr, 0);
6118 if (GET_CODE (addr) == REG)
6119 basereg = REGNO (addr);
6120 else if (GET_CODE (addr) == SUBREG
6121 && GET_CODE (SUBREG_REG (addr)) == REG)
6122 basereg = subreg_regno (addr);
6123 else
6124 abort ();
6125
6126 fprintf (file, "($%d)\t\t!%s", basereg,
6127 (basereg == 29 ? reloc16 : reloclo));
6128 return;
6129 }
6130
6131 if (GET_CODE (addr) == REG)
6132 basereg = REGNO (addr);
6133 else if (GET_CODE (addr) == SUBREG
6134 && GET_CODE (SUBREG_REG (addr)) == REG)
6135 basereg = subreg_regno (addr);
6136 else if (GET_CODE (addr) == CONST_INT)
6137 offset = INTVAL (addr);
6138
6139 #if TARGET_ABI_OPEN_VMS
6140 else if (GET_CODE (addr) == SYMBOL_REF)
6141 {
6142 fprintf (file, "%s", XSTR (addr, 0));
6143 return;
6144 }
6145 else if (GET_CODE (addr) == CONST
6146 && GET_CODE (XEXP (addr, 0)) == PLUS
6147 && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF)
6148 {
6149 fprintf (file, "%s+" HOST_WIDE_INT_PRINT_DEC,
6150 XSTR (XEXP (XEXP (addr, 0), 0), 0),
6151 INTVAL (XEXP (XEXP (addr, 0), 1)));
6152 return;
6153 }
6154 #endif
6155
6156 else
6157 abort ();
6158
6159 fprintf (file, HOST_WIDE_INT_PRINT_DEC "($%d)", offset, basereg);
6160 }
6161 \f
6162 /* Emit RTL insns to initialize the variable parts of a trampoline at
6163 TRAMP. FNADDR is an RTX for the address of the function's pure
6164 code. CXT is an RTX for the static chain value for the function.
6165
6166 The three offset parameters are for the individual template's
6167 layout. A JMPOFS < 0 indicates that the trampoline does not
6168 contain instructions at all.
6169
6170 We assume here that a function will be called many more times than
6171 its address is taken (e.g., it might be passed to qsort), so we
6172 take the trouble to initialize the "hint" field in the JMP insn.
6173 Note that the hint field is PC (new) + 4 * bits 13:0. */
6174
6175 void
6176 alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs)
6177 rtx tramp, fnaddr, cxt;
6178 int fnofs, cxtofs, jmpofs;
6179 {
6180 rtx temp, temp1, addr;
6181 /* VMS really uses DImode pointers in memory at this point. */
6182 enum machine_mode mode = TARGET_ABI_OPEN_VMS ? Pmode : ptr_mode;
6183
6184 #ifdef POINTERS_EXTEND_UNSIGNED
6185 fnaddr = convert_memory_address (mode, fnaddr);
6186 cxt = convert_memory_address (mode, cxt);
6187 #endif
6188
6189 /* Store function address and CXT. */
6190 addr = memory_address (mode, plus_constant (tramp, fnofs));
6191 emit_move_insn (gen_rtx_MEM (mode, addr), fnaddr);
6192 addr = memory_address (mode, plus_constant (tramp, cxtofs));
6193 emit_move_insn (gen_rtx_MEM (mode, addr), cxt);
6194
6195 /* This has been disabled since the hint only has a 32k range, and in
6196 no existing OS is the stack within 32k of the text segment. */
6197 if (0 && jmpofs >= 0)
6198 {
6199 /* Compute hint value. */
6200 temp = force_operand (plus_constant (tramp, jmpofs+4), NULL_RTX);
6201 temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1,
6202 OPTAB_WIDEN);
6203 temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
6204 build_int_2 (2, 0), NULL_RTX, 1);
6205 temp = expand_and (SImode, gen_lowpart (SImode, temp),
6206 GEN_INT (0x3fff), 0);
6207
6208 /* Merge in the hint. */
6209 addr = memory_address (SImode, plus_constant (tramp, jmpofs));
6210 temp1 = force_reg (SImode, gen_rtx_MEM (SImode, addr));
6211 temp1 = expand_and (SImode, temp1, GEN_INT (0xffffc000), NULL_RTX);
6212 temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1,
6213 OPTAB_WIDEN);
6214 emit_move_insn (gen_rtx_MEM (SImode, addr), temp1);
6215 }
6216
6217 #ifdef TRANSFER_FROM_TRAMPOLINE
6218 emit_library_call (init_one_libfunc ("__enable_execute_stack"),
6219 0, VOIDmode, 1, tramp, Pmode);
6220 #endif
6221
6222 if (jmpofs >= 0)
6223 emit_insn (gen_imb ());
6224 }
6225 \f
6226 /* Determine where to put an argument to a function.
6227 Value is zero to push the argument on the stack,
6228 or a hard register in which to store the argument.
6229
6230 MODE is the argument's machine mode.
6231 TYPE is the data type of the argument (as a tree).
6232 This is null for libcalls where that information may
6233 not be available.
6234 CUM is a variable of type CUMULATIVE_ARGS which gives info about
6235 the preceding args and about the function being called.
6236 NAMED is nonzero if this argument is a named parameter
6237 (otherwise it is an extra parameter matching an ellipsis).
6238
6239 On Alpha the first 6 words of args are normally in registers
6240 and the rest are pushed. */
6241
6242 rtx
6243 function_arg (cum, mode, type, named)
6244 CUMULATIVE_ARGS cum;
6245 enum machine_mode mode;
6246 tree type;
6247 int named ATTRIBUTE_UNUSED;
6248 {
6249 int basereg;
6250 int num_args;
6251
6252 /* Set up defaults for FP operands passed in FP registers, and
6253 integral operands passed in integer registers. */
6254 if (TARGET_FPREGS
6255 && (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
6256 || GET_MODE_CLASS (mode) == MODE_FLOAT))
6257 basereg = 32 + 16;
6258 else
6259 basereg = 16;
6260
6261 /* ??? Irritatingly, the definition of CUMULATIVE_ARGS is different for
6262 the three platforms, so we can't avoid conditional compilation. */
6263 #if TARGET_ABI_OPEN_VMS
6264 {
6265 if (mode == VOIDmode)
6266 return alpha_arg_info_reg_val (cum);
6267
6268 num_args = cum.num_args;
6269 if (num_args >= 6 || MUST_PASS_IN_STACK (mode, type))
6270 return NULL_RTX;
6271 }
6272 #else
6273 #if TARGET_ABI_UNICOSMK
6274 {
6275 int size;
6276
6277 /* If this is the last argument, generate the call info word (CIW). */
6278 /* ??? We don't include the caller's line number in the CIW because
6279 I don't know how to determine it if debug infos are turned off. */
6280 if (mode == VOIDmode)
6281 {
6282 int i;
6283 HOST_WIDE_INT lo;
6284 HOST_WIDE_INT hi;
6285 rtx ciw;
6286
6287 lo = 0;
6288
6289 for (i = 0; i < cum.num_reg_words && i < 5; i++)
6290 if (cum.reg_args_type[i])
6291 lo |= (1 << (7 - i));
6292
6293 if (cum.num_reg_words == 6 && cum.reg_args_type[5])
6294 lo |= 7;
6295 else
6296 lo |= cum.num_reg_words;
6297
6298 #if HOST_BITS_PER_WIDE_INT == 32
6299 hi = (cum.num_args << 20) | cum.num_arg_words;
6300 #else
6301 lo = lo | ((HOST_WIDE_INT) cum.num_args << 52)
6302 | ((HOST_WIDE_INT) cum.num_arg_words << 32);
6303 hi = 0;
6304 #endif
6305 ciw = immed_double_const (lo, hi, DImode);
6306
6307 return gen_rtx_UNSPEC (DImode, gen_rtvec (1, ciw),
6308 UNSPEC_UMK_LOAD_CIW);
6309 }
6310
6311 size = ALPHA_ARG_SIZE (mode, type, named);
6312 num_args = cum.num_reg_words;
6313 if (MUST_PASS_IN_STACK (mode, type)
6314 || cum.num_reg_words + size > 6 || cum.force_stack)
6315 return NULL_RTX;
6316 else if (type && TYPE_MODE (type) == BLKmode)
6317 {
6318 rtx reg1, reg2;
6319
6320 reg1 = gen_rtx_REG (DImode, num_args + 16);
6321 reg1 = gen_rtx_EXPR_LIST (DImode, reg1, const0_rtx);
6322
6323 /* The argument fits in two registers. Note that we still need to
6324 reserve a register for empty structures. */
6325 if (size == 0)
6326 return NULL_RTX;
6327 else if (size == 1)
6328 return gen_rtx_PARALLEL (mode, gen_rtvec (1, reg1));
6329 else
6330 {
6331 reg2 = gen_rtx_REG (DImode, num_args + 17);
6332 reg2 = gen_rtx_EXPR_LIST (DImode, reg2, GEN_INT (8));
6333 return gen_rtx_PARALLEL (mode, gen_rtvec (2, reg1, reg2));
6334 }
6335 }
6336 }
6337 #else
6338 {
6339 if (cum >= 6)
6340 return NULL_RTX;
6341 num_args = cum;
6342
6343 /* VOID is passed as a special flag for "last argument". */
6344 if (type == void_type_node)
6345 basereg = 16;
6346 else if (MUST_PASS_IN_STACK (mode, type))
6347 return NULL_RTX;
6348 else if (FUNCTION_ARG_PASS_BY_REFERENCE (cum, mode, type, named))
6349 basereg = 16;
6350 }
6351 #endif /* TARGET_ABI_UNICOSMK */
6352 #endif /* TARGET_ABI_OPEN_VMS */
6353
6354 return gen_rtx_REG (mode, num_args + basereg);
6355 }
6356
6357 tree
6358 alpha_build_va_list ()
6359 {
6360 tree base, ofs, record, type_decl;
6361
6362 if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK)
6363 return ptr_type_node;
6364
6365 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
6366 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
6367 TREE_CHAIN (record) = type_decl;
6368 TYPE_NAME (record) = type_decl;
6369
6370 /* C++? SET_IS_AGGR_TYPE (record, 1); */
6371
6372 ofs = build_decl (FIELD_DECL, get_identifier ("__offset"),
6373 integer_type_node);
6374 DECL_FIELD_CONTEXT (ofs) = record;
6375
6376 base = build_decl (FIELD_DECL, get_identifier ("__base"),
6377 ptr_type_node);
6378 DECL_FIELD_CONTEXT (base) = record;
6379 TREE_CHAIN (base) = ofs;
6380
6381 TYPE_FIELDS (record) = base;
6382 layout_type (record);
6383
6384 return record;
6385 }
6386
6387 /* Perform any needed actions needed for a function that is receiving a
6388 variable number of arguments.
6389
6390 On the Alpha, we allocate space for all 12 arg registers, but only
6391 push those that are remaining. However, if NO registers need to be
6392 saved, don't allocate any space. This is not only because we won't
6393 need the space, but because AP includes the current_pretend_args_size
6394 and we don't want to mess up any ap-relative addresses already made.
6395
6396 If we are not to use the floating-point registers, save the integer
6397 registers where we would put the floating-point registers. This is
6398 not the most efficient way to implement varargs with just one register
6399 class, but it isn't worth doing anything more efficient in this rare
6400 case. */
6401
6402 void
6403 alpha_setup_incoming_varargs(cum, mode, type, pretend_size, no_rtl)
6404 CUMULATIVE_ARGS cum;
6405 enum machine_mode mode ATTRIBUTE_UNUSED;
6406 tree type ATTRIBUTE_UNUSED;
6407 int *pretend_size;
6408 int no_rtl;
6409 {
6410 if (cum >= 6)
6411 return;
6412
6413 if (!no_rtl)
6414 {
6415 int set = get_varargs_alias_set ();
6416 rtx tmp;
6417
6418 tmp = gen_rtx_MEM (BLKmode,
6419 plus_constant (virtual_incoming_args_rtx,
6420 (cum + 6) * UNITS_PER_WORD));
6421 set_mem_alias_set (tmp, set);
6422 move_block_from_reg (16 + cum, tmp, 6 - cum);
6423
6424 tmp = gen_rtx_MEM (BLKmode,
6425 plus_constant (virtual_incoming_args_rtx,
6426 cum * UNITS_PER_WORD));
6427 set_mem_alias_set (tmp, set);
6428 move_block_from_reg (16 + (TARGET_FPREGS ? 32 : 0) + cum, tmp,
6429 6 - cum);
6430 }
6431 *pretend_size = 12 * UNITS_PER_WORD;
6432 }
6433
6434 void
6435 alpha_va_start (valist, nextarg)
6436 tree valist;
6437 rtx nextarg ATTRIBUTE_UNUSED;
6438 {
6439 HOST_WIDE_INT offset;
6440 tree t, offset_field, base_field;
6441
6442 if (TREE_CODE (TREE_TYPE (valist)) == ERROR_MARK)
6443 return;
6444
6445 if (TARGET_ABI_UNICOSMK)
6446 std_expand_builtin_va_start (valist, nextarg);
6447
6448 /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base
6449 up by 48, storing fp arg registers in the first 48 bytes, and the
6450 integer arg registers in the next 48 bytes. This is only done,
6451 however, if any integer registers need to be stored.
6452
6453 If no integer registers need be stored, then we must subtract 48
6454 in order to account for the integer arg registers which are counted
6455 in argsize above, but which are not actually stored on the stack.
6456 Must further be careful here about structures straddling the last
6457 integer argument register; that futzes with pretend_args_size,
6458 which changes the meaning of AP. */
6459
6460 if (NUM_ARGS <= 6)
6461 offset = TARGET_ABI_OPEN_VMS ? UNITS_PER_WORD : 6 * UNITS_PER_WORD;
6462 else
6463 offset = -6 * UNITS_PER_WORD + current_function_pretend_args_size;
6464
6465 if (TARGET_ABI_OPEN_VMS)
6466 {
6467 nextarg = plus_constant (nextarg, offset);
6468 nextarg = plus_constant (nextarg, NUM_ARGS * UNITS_PER_WORD);
6469 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
6470 make_tree (ptr_type_node, nextarg));
6471 TREE_SIDE_EFFECTS (t) = 1;
6472
6473 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6474 }
6475 else
6476 {
6477 base_field = TYPE_FIELDS (TREE_TYPE (valist));
6478 offset_field = TREE_CHAIN (base_field);
6479
6480 base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
6481 valist, base_field);
6482 offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
6483 valist, offset_field);
6484
6485 t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
6486 t = build (PLUS_EXPR, ptr_type_node, t, build_int_2 (offset, 0));
6487 t = build (MODIFY_EXPR, TREE_TYPE (base_field), base_field, t);
6488 TREE_SIDE_EFFECTS (t) = 1;
6489 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6490
6491 t = build_int_2 (NUM_ARGS * UNITS_PER_WORD, 0);
6492 t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field, t);
6493 TREE_SIDE_EFFECTS (t) = 1;
6494 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6495 }
6496 }
6497
6498 rtx
6499 alpha_va_arg (valist, type)
6500 tree valist, type;
6501 {
6502 rtx addr;
6503 tree t, type_size, rounded_size;
6504 tree offset_field, base_field, addr_tree, addend;
6505 tree wide_type, wide_ofs;
6506 int indirect = 0;
6507
6508 if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK)
6509 return std_expand_builtin_va_arg (valist, type);
6510
6511 if (type == error_mark_node
6512 || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
6513 || TREE_OVERFLOW (type_size))
6514 rounded_size = size_zero_node;
6515 else
6516 rounded_size = fold (build (MULT_EXPR, sizetype,
6517 fold (build (TRUNC_DIV_EXPR, sizetype,
6518 fold (build (PLUS_EXPR, sizetype,
6519 type_size,
6520 size_int (7))),
6521 size_int (8))),
6522 size_int (8)));
6523
6524 base_field = TYPE_FIELDS (TREE_TYPE (valist));
6525 offset_field = TREE_CHAIN (base_field);
6526
6527 base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
6528 valist, base_field);
6529 offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
6530 valist, offset_field);
6531
6532 /* If the type could not be passed in registers, skip the block
6533 reserved for the registers. */
6534 if (MUST_PASS_IN_STACK (TYPE_MODE (type), type))
6535 {
6536 t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field,
6537 build (MAX_EXPR, TREE_TYPE (offset_field),
6538 offset_field, build_int_2 (6*8, 0)));
6539 TREE_SIDE_EFFECTS (t) = 1;
6540 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6541 }
6542
6543 wide_type = make_signed_type (64);
6544 wide_ofs = save_expr (build1 (CONVERT_EXPR, wide_type, offset_field));
6545
6546 addend = wide_ofs;
6547
6548 if (TYPE_MODE (type) == TFmode || TYPE_MODE (type) == TCmode)
6549 {
6550 indirect = 1;
6551 rounded_size = size_int (UNITS_PER_WORD);
6552 }
6553 else if (FLOAT_TYPE_P (type))
6554 {
6555 tree fpaddend, cond;
6556
6557 fpaddend = fold (build (PLUS_EXPR, TREE_TYPE (addend),
6558 addend, build_int_2 (-6*8, 0)));
6559
6560 cond = fold (build (LT_EXPR, integer_type_node,
6561 wide_ofs, build_int_2 (6*8, 0)));
6562
6563 addend = fold (build (COND_EXPR, TREE_TYPE (addend), cond,
6564 fpaddend, addend));
6565 }
6566
6567 addr_tree = build (PLUS_EXPR, TREE_TYPE (base_field),
6568 base_field, addend);
6569
6570 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
6571 addr = copy_to_reg (addr);
6572
6573 t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field,
6574 build (PLUS_EXPR, TREE_TYPE (offset_field),
6575 offset_field, rounded_size));
6576 TREE_SIDE_EFFECTS (t) = 1;
6577 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6578
6579 if (indirect)
6580 {
6581 addr = force_reg (Pmode, addr);
6582 addr = gen_rtx_MEM (Pmode, addr);
6583 }
6584
6585 return addr;
6586 }
6587 \f
6588 /* Builtins. */
6589
6590 enum alpha_builtin
6591 {
6592 ALPHA_BUILTIN_CMPBGE,
6593 ALPHA_BUILTIN_EXTBL,
6594 ALPHA_BUILTIN_EXTWL,
6595 ALPHA_BUILTIN_EXTLL,
6596 ALPHA_BUILTIN_EXTQL,
6597 ALPHA_BUILTIN_EXTWH,
6598 ALPHA_BUILTIN_EXTLH,
6599 ALPHA_BUILTIN_EXTQH,
6600 ALPHA_BUILTIN_INSBL,
6601 ALPHA_BUILTIN_INSWL,
6602 ALPHA_BUILTIN_INSLL,
6603 ALPHA_BUILTIN_INSQL,
6604 ALPHA_BUILTIN_INSWH,
6605 ALPHA_BUILTIN_INSLH,
6606 ALPHA_BUILTIN_INSQH,
6607 ALPHA_BUILTIN_MSKBL,
6608 ALPHA_BUILTIN_MSKWL,
6609 ALPHA_BUILTIN_MSKLL,
6610 ALPHA_BUILTIN_MSKQL,
6611 ALPHA_BUILTIN_MSKWH,
6612 ALPHA_BUILTIN_MSKLH,
6613 ALPHA_BUILTIN_MSKQH,
6614 ALPHA_BUILTIN_UMULH,
6615 ALPHA_BUILTIN_ZAP,
6616 ALPHA_BUILTIN_ZAPNOT,
6617 ALPHA_BUILTIN_AMASK,
6618 ALPHA_BUILTIN_IMPLVER,
6619 ALPHA_BUILTIN_RPCC,
6620 ALPHA_BUILTIN_THREAD_POINTER,
6621 ALPHA_BUILTIN_SET_THREAD_POINTER,
6622
6623 /* TARGET_MAX */
6624 ALPHA_BUILTIN_MINUB8,
6625 ALPHA_BUILTIN_MINSB8,
6626 ALPHA_BUILTIN_MINUW4,
6627 ALPHA_BUILTIN_MINSW4,
6628 ALPHA_BUILTIN_MAXUB8,
6629 ALPHA_BUILTIN_MAXSB8,
6630 ALPHA_BUILTIN_MAXUW4,
6631 ALPHA_BUILTIN_MAXSW4,
6632 ALPHA_BUILTIN_PERR,
6633 ALPHA_BUILTIN_PKLB,
6634 ALPHA_BUILTIN_PKWB,
6635 ALPHA_BUILTIN_UNPKBL,
6636 ALPHA_BUILTIN_UNPKBW,
6637
6638 /* TARGET_CIX */
6639 ALPHA_BUILTIN_CTTZ,
6640 ALPHA_BUILTIN_CTLZ,
6641 ALPHA_BUILTIN_CTPOP,
6642
6643 ALPHA_BUILTIN_max
6644 };
6645
6646 static unsigned int const code_for_builtin[ALPHA_BUILTIN_max] = {
6647 CODE_FOR_builtin_cmpbge,
6648 CODE_FOR_builtin_extbl,
6649 CODE_FOR_builtin_extwl,
6650 CODE_FOR_builtin_extll,
6651 CODE_FOR_builtin_extql,
6652 CODE_FOR_builtin_extwh,
6653 CODE_FOR_builtin_extlh,
6654 CODE_FOR_builtin_extqh,
6655 CODE_FOR_builtin_insbl,
6656 CODE_FOR_builtin_inswl,
6657 CODE_FOR_builtin_insll,
6658 CODE_FOR_builtin_insql,
6659 CODE_FOR_builtin_inswh,
6660 CODE_FOR_builtin_inslh,
6661 CODE_FOR_builtin_insqh,
6662 CODE_FOR_builtin_mskbl,
6663 CODE_FOR_builtin_mskwl,
6664 CODE_FOR_builtin_mskll,
6665 CODE_FOR_builtin_mskql,
6666 CODE_FOR_builtin_mskwh,
6667 CODE_FOR_builtin_msklh,
6668 CODE_FOR_builtin_mskqh,
6669 CODE_FOR_umuldi3_highpart,
6670 CODE_FOR_builtin_zap,
6671 CODE_FOR_builtin_zapnot,
6672 CODE_FOR_builtin_amask,
6673 CODE_FOR_builtin_implver,
6674 CODE_FOR_builtin_rpcc,
6675 CODE_FOR_load_tp,
6676 CODE_FOR_set_tp,
6677
6678 /* TARGET_MAX */
6679 CODE_FOR_builtin_minub8,
6680 CODE_FOR_builtin_minsb8,
6681 CODE_FOR_builtin_minuw4,
6682 CODE_FOR_builtin_minsw4,
6683 CODE_FOR_builtin_maxub8,
6684 CODE_FOR_builtin_maxsb8,
6685 CODE_FOR_builtin_maxuw4,
6686 CODE_FOR_builtin_maxsw4,
6687 CODE_FOR_builtin_perr,
6688 CODE_FOR_builtin_pklb,
6689 CODE_FOR_builtin_pkwb,
6690 CODE_FOR_builtin_unpkbl,
6691 CODE_FOR_builtin_unpkbw,
6692
6693 /* TARGET_CIX */
6694 CODE_FOR_builtin_cttz,
6695 CODE_FOR_builtin_ctlz,
6696 CODE_FOR_builtin_ctpop
6697 };
6698
6699 struct alpha_builtin_def
6700 {
6701 const char *name;
6702 enum alpha_builtin code;
6703 unsigned int target_mask;
6704 };
6705
6706 static struct alpha_builtin_def const zero_arg_builtins[] = {
6707 { "__builtin_alpha_implver", ALPHA_BUILTIN_IMPLVER, 0 },
6708 { "__builtin_alpha_rpcc", ALPHA_BUILTIN_RPCC, 0 }
6709 };
6710
6711 static struct alpha_builtin_def const one_arg_builtins[] = {
6712 { "__builtin_alpha_amask", ALPHA_BUILTIN_AMASK, 0 },
6713 { "__builtin_alpha_pklb", ALPHA_BUILTIN_PKLB, MASK_MAX },
6714 { "__builtin_alpha_pkwb", ALPHA_BUILTIN_PKWB, MASK_MAX },
6715 { "__builtin_alpha_unpkbl", ALPHA_BUILTIN_UNPKBL, MASK_MAX },
6716 { "__builtin_alpha_unpkbw", ALPHA_BUILTIN_UNPKBW, MASK_MAX },
6717 { "__builtin_alpha_cttz", ALPHA_BUILTIN_CTTZ, MASK_CIX },
6718 { "__builtin_alpha_ctlz", ALPHA_BUILTIN_CTLZ, MASK_CIX },
6719 { "__builtin_alpha_ctpop", ALPHA_BUILTIN_CTPOP, MASK_CIX }
6720 };
6721
6722 static struct alpha_builtin_def const two_arg_builtins[] = {
6723 { "__builtin_alpha_cmpbge", ALPHA_BUILTIN_CMPBGE, 0 },
6724 { "__builtin_alpha_extbl", ALPHA_BUILTIN_EXTBL, 0 },
6725 { "__builtin_alpha_extwl", ALPHA_BUILTIN_EXTWL, 0 },
6726 { "__builtin_alpha_extll", ALPHA_BUILTIN_EXTLL, 0 },
6727 { "__builtin_alpha_extql", ALPHA_BUILTIN_EXTQL, 0 },
6728 { "__builtin_alpha_extwh", ALPHA_BUILTIN_EXTWH, 0 },
6729 { "__builtin_alpha_extlh", ALPHA_BUILTIN_EXTLH, 0 },
6730 { "__builtin_alpha_extqh", ALPHA_BUILTIN_EXTQH, 0 },
6731 { "__builtin_alpha_insbl", ALPHA_BUILTIN_INSBL, 0 },
6732 { "__builtin_alpha_inswl", ALPHA_BUILTIN_INSWL, 0 },
6733 { "__builtin_alpha_insll", ALPHA_BUILTIN_INSLL, 0 },
6734 { "__builtin_alpha_insql", ALPHA_BUILTIN_INSQL, 0 },
6735 { "__builtin_alpha_inswh", ALPHA_BUILTIN_INSWH, 0 },
6736 { "__builtin_alpha_inslh", ALPHA_BUILTIN_INSLH, 0 },
6737 { "__builtin_alpha_insqh", ALPHA_BUILTIN_INSQH, 0 },
6738 { "__builtin_alpha_mskbl", ALPHA_BUILTIN_MSKBL, 0 },
6739 { "__builtin_alpha_mskwl", ALPHA_BUILTIN_MSKWL, 0 },
6740 { "__builtin_alpha_mskll", ALPHA_BUILTIN_MSKLL, 0 },
6741 { "__builtin_alpha_mskql", ALPHA_BUILTIN_MSKQL, 0 },
6742 { "__builtin_alpha_mskwh", ALPHA_BUILTIN_MSKWH, 0 },
6743 { "__builtin_alpha_msklh", ALPHA_BUILTIN_MSKLH, 0 },
6744 { "__builtin_alpha_mskqh", ALPHA_BUILTIN_MSKQH, 0 },
6745 { "__builtin_alpha_umulh", ALPHA_BUILTIN_UMULH, 0 },
6746 { "__builtin_alpha_zap", ALPHA_BUILTIN_ZAP, 0 },
6747 { "__builtin_alpha_zapnot", ALPHA_BUILTIN_ZAPNOT, 0 },
6748 { "__builtin_alpha_minub8", ALPHA_BUILTIN_MINUB8, MASK_MAX },
6749 { "__builtin_alpha_minsb8", ALPHA_BUILTIN_MINSB8, MASK_MAX },
6750 { "__builtin_alpha_minuw4", ALPHA_BUILTIN_MINUW4, MASK_MAX },
6751 { "__builtin_alpha_minsw4", ALPHA_BUILTIN_MINSW4, MASK_MAX },
6752 { "__builtin_alpha_maxub8", ALPHA_BUILTIN_MAXUB8, MASK_MAX },
6753 { "__builtin_alpha_maxsb8", ALPHA_BUILTIN_MAXSB8, MASK_MAX },
6754 { "__builtin_alpha_maxuw4", ALPHA_BUILTIN_MAXUW4, MASK_MAX },
6755 { "__builtin_alpha_maxsw4", ALPHA_BUILTIN_MAXSW4, MASK_MAX },
6756 { "__builtin_alpha_perr", ALPHA_BUILTIN_PERR, MASK_MAX }
6757 };
6758
6759 static void
6760 alpha_init_builtins ()
6761 {
6762 const struct alpha_builtin_def *p;
6763 tree ftype;
6764 size_t i;
6765
6766 ftype = build_function_type (long_integer_type_node, void_list_node);
6767
6768 p = zero_arg_builtins;
6769 for (i = 0; i < ARRAY_SIZE (zero_arg_builtins); ++i, ++p)
6770 if ((target_flags & p->target_mask) == p->target_mask)
6771 builtin_function (p->name, ftype, p->code, BUILT_IN_MD,
6772 NULL, NULL_TREE);
6773
6774 ftype = build_function_type_list (long_integer_type_node,
6775 long_integer_type_node, NULL_TREE);
6776
6777 p = one_arg_builtins;
6778 for (i = 0; i < ARRAY_SIZE (one_arg_builtins); ++i, ++p)
6779 if ((target_flags & p->target_mask) == p->target_mask)
6780 builtin_function (p->name, ftype, p->code, BUILT_IN_MD,
6781 NULL, NULL_TREE);
6782
6783 ftype = build_function_type_list (long_integer_type_node,
6784 long_integer_type_node,
6785 long_integer_type_node, NULL_TREE);
6786
6787 p = two_arg_builtins;
6788 for (i = 0; i < ARRAY_SIZE (two_arg_builtins); ++i, ++p)
6789 if ((target_flags & p->target_mask) == p->target_mask)
6790 builtin_function (p->name, ftype, p->code, BUILT_IN_MD,
6791 NULL, NULL_TREE);
6792
6793 ftype = build_function_type (ptr_type_node, void_list_node);
6794 builtin_function ("__builtin_thread_pointer", ftype,
6795 ALPHA_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
6796 NULL, NULL_TREE);
6797
6798 ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
6799 builtin_function ("__builtin_set_thread_pointer", ftype,
6800 ALPHA_BUILTIN_SET_THREAD_POINTER, BUILT_IN_MD,
6801 NULL, NULL_TREE);
6802 }
6803
6804 /* Expand an expression EXP that calls a built-in function,
6805 with result going to TARGET if that's convenient
6806 (and in mode MODE if that's convenient).
6807 SUBTARGET may be used as the target for computing one of EXP's operands.
6808 IGNORE is nonzero if the value is to be ignored. */
6809
6810 static rtx
6811 alpha_expand_builtin (exp, target, subtarget, mode, ignore)
6812 tree exp;
6813 rtx target;
6814 rtx subtarget ATTRIBUTE_UNUSED;
6815 enum machine_mode mode ATTRIBUTE_UNUSED;
6816 int ignore ATTRIBUTE_UNUSED;
6817 {
6818 #define MAX_ARGS 2
6819
6820 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
6821 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
6822 tree arglist = TREE_OPERAND (exp, 1);
6823 enum insn_code icode;
6824 rtx op[MAX_ARGS], pat;
6825 int arity;
6826 bool nonvoid;
6827
6828 if (fcode >= ALPHA_BUILTIN_max)
6829 internal_error ("bad builtin fcode");
6830 icode = code_for_builtin[fcode];
6831 if (icode == 0)
6832 internal_error ("bad builtin fcode");
6833
6834 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
6835
6836 for (arglist = TREE_OPERAND (exp, 1), arity = 0;
6837 arglist;
6838 arglist = TREE_CHAIN (arglist), arity++)
6839 {
6840 const struct insn_operand_data *insn_op;
6841
6842 tree arg = TREE_VALUE (arglist);
6843 if (arg == error_mark_node)
6844 return NULL_RTX;
6845 if (arity > MAX_ARGS)
6846 return NULL_RTX;
6847
6848 insn_op = &insn_data[icode].operand[arity + nonvoid];
6849
6850 op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, 0);
6851
6852 if (!(*insn_op->predicate) (op[arity], insn_op->mode))
6853 op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
6854 }
6855
6856 if (nonvoid)
6857 {
6858 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6859 if (!target
6860 || GET_MODE (target) != tmode
6861 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
6862 target = gen_reg_rtx (tmode);
6863 }
6864
6865 switch (arity)
6866 {
6867 case 0:
6868 pat = GEN_FCN (icode) (target);
6869 break;
6870 case 1:
6871 if (nonvoid)
6872 pat = GEN_FCN (icode) (target, op[0]);
6873 else
6874 pat = GEN_FCN (icode) (op[0]);
6875 break;
6876 case 2:
6877 pat = GEN_FCN (icode) (target, op[0], op[1]);
6878 break;
6879 default:
6880 abort ();
6881 }
6882 if (!pat)
6883 return NULL_RTX;
6884 emit_insn (pat);
6885
6886 if (nonvoid)
6887 return target;
6888 else
6889 return const0_rtx;
6890 }
6891 \f
6892 /* This page contains routines that are used to determine what the function
6893 prologue and epilogue code will do and write them out. */
6894
6895 /* Compute the size of the save area in the stack. */
6896
6897 /* These variables are used for communication between the following functions.
6898 They indicate various things about the current function being compiled
6899 that are used to tell what kind of prologue, epilogue and procedure
6900 descriptior to generate. */
6901
6902 /* Nonzero if we need a stack procedure. */
6903 enum alpha_procedure_types {PT_NULL = 0, PT_REGISTER = 1, PT_STACK = 2};
6904 static enum alpha_procedure_types alpha_procedure_type;
6905
6906 /* Register number (either FP or SP) that is used to unwind the frame. */
6907 static int vms_unwind_regno;
6908
6909 /* Register number used to save FP. We need not have one for RA since
6910 we don't modify it for register procedures. This is only defined
6911 for register frame procedures. */
6912 static int vms_save_fp_regno;
6913
6914 /* Register number used to reference objects off our PV. */
6915 static int vms_base_regno;
6916
6917 /* Compute register masks for saved registers. */
6918
6919 static void
6920 alpha_sa_mask (imaskP, fmaskP)
6921 unsigned long *imaskP;
6922 unsigned long *fmaskP;
6923 {
6924 unsigned long imask = 0;
6925 unsigned long fmask = 0;
6926 unsigned int i;
6927
6928 /* Irritatingly, there are two kinds of thunks -- those created with
6929 TARGET_ASM_OUTPUT_MI_THUNK and those with DECL_THUNK_P that go
6930 through the regular part of the compiler. In the
6931 TARGET_ASM_OUTPUT_MI_THUNK case we don't have valid register life
6932 info, but assemble_start_function wants to output .frame and
6933 .mask directives. */
6934 if (current_function_is_thunk && !no_new_pseudos)
6935 {
6936 *imaskP = 0;
6937 *fmaskP = 0;
6938 return;
6939 }
6940
6941 if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
6942 imask |= (1UL << HARD_FRAME_POINTER_REGNUM);
6943
6944 /* One for every register we have to save. */
6945 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
6946 if (! fixed_regs[i] && ! call_used_regs[i]
6947 && regs_ever_live[i] && i != REG_RA
6948 && (!TARGET_ABI_UNICOSMK || i != HARD_FRAME_POINTER_REGNUM))
6949 {
6950 if (i < 32)
6951 imask |= (1UL << i);
6952 else
6953 fmask |= (1UL << (i - 32));
6954 }
6955
6956 /* We need to restore these for the handler. */
6957 if (current_function_calls_eh_return)
6958 for (i = 0; ; ++i)
6959 {
6960 unsigned regno = EH_RETURN_DATA_REGNO (i);
6961 if (regno == INVALID_REGNUM)
6962 break;
6963 imask |= 1UL << regno;
6964 }
6965
6966 /* If any register spilled, then spill the return address also. */
6967 /* ??? This is required by the Digital stack unwind specification
6968 and isn't needed if we're doing Dwarf2 unwinding. */
6969 if (imask || fmask || alpha_ra_ever_killed ())
6970 imask |= (1UL << REG_RA);
6971
6972 *imaskP = imask;
6973 *fmaskP = fmask;
6974 }
6975
6976 int
6977 alpha_sa_size ()
6978 {
6979 unsigned long mask[2];
6980 int sa_size = 0;
6981 int i, j;
6982
6983 alpha_sa_mask (&mask[0], &mask[1]);
6984
6985 if (TARGET_ABI_UNICOSMK)
6986 {
6987 if (mask[0] || mask[1])
6988 sa_size = 14;
6989 }
6990 else
6991 {
6992 for (j = 0; j < 2; ++j)
6993 for (i = 0; i < 32; ++i)
6994 if ((mask[j] >> i) & 1)
6995 sa_size++;
6996 }
6997
6998 if (TARGET_ABI_UNICOSMK)
6999 {
7000 /* We might not need to generate a frame if we don't make any calls
7001 (including calls to __T3E_MISMATCH if this is a vararg function),
7002 don't have any local variables which require stack slots, don't
7003 use alloca and have not determined that we need a frame for other
7004 reasons. */
7005
7006 alpha_procedure_type
7007 = (sa_size || get_frame_size() != 0
7008 || current_function_outgoing_args_size
7009 || current_function_stdarg || current_function_calls_alloca
7010 || frame_pointer_needed)
7011 ? PT_STACK : PT_REGISTER;
7012
7013 /* Always reserve space for saving callee-saved registers if we
7014 need a frame as required by the calling convention. */
7015 if (alpha_procedure_type == PT_STACK)
7016 sa_size = 14;
7017 }
7018 else if (TARGET_ABI_OPEN_VMS)
7019 {
7020 /* Start by assuming we can use a register procedure if we don't
7021 make any calls (REG_RA not used) or need to save any
7022 registers and a stack procedure if we do. */
7023 if ((mask[0] >> REG_RA) & 1)
7024 alpha_procedure_type = PT_STACK;
7025 else if (get_frame_size() != 0)
7026 alpha_procedure_type = PT_REGISTER;
7027 else
7028 alpha_procedure_type = PT_NULL;
7029
7030 /* Don't reserve space for saving FP & RA yet. Do that later after we've
7031 made the final decision on stack procedure vs register procedure. */
7032 if (alpha_procedure_type == PT_STACK)
7033 sa_size -= 2;
7034
7035 /* Decide whether to refer to objects off our PV via FP or PV.
7036 If we need FP for something else or if we receive a nonlocal
7037 goto (which expects PV to contain the value), we must use PV.
7038 Otherwise, start by assuming we can use FP. */
7039
7040 vms_base_regno
7041 = (frame_pointer_needed
7042 || current_function_has_nonlocal_label
7043 || alpha_procedure_type == PT_STACK
7044 || current_function_outgoing_args_size)
7045 ? REG_PV : HARD_FRAME_POINTER_REGNUM;
7046
7047 /* If we want to copy PV into FP, we need to find some register
7048 in which to save FP. */
7049
7050 vms_save_fp_regno = -1;
7051 if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
7052 for (i = 0; i < 32; i++)
7053 if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
7054 vms_save_fp_regno = i;
7055
7056 if (vms_save_fp_regno == -1 && alpha_procedure_type == PT_REGISTER)
7057 vms_base_regno = REG_PV, alpha_procedure_type = PT_STACK;
7058 else if (alpha_procedure_type == PT_NULL)
7059 vms_base_regno = REG_PV;
7060
7061 /* Stack unwinding should be done via FP unless we use it for PV. */
7062 vms_unwind_regno = (vms_base_regno == REG_PV
7063 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
7064
7065 /* If this is a stack procedure, allow space for saving FP and RA. */
7066 if (alpha_procedure_type == PT_STACK)
7067 sa_size += 2;
7068 }
7069 else
7070 {
7071 /* Our size must be even (multiple of 16 bytes). */
7072 if (sa_size & 1)
7073 sa_size++;
7074 }
7075
7076 return sa_size * 8;
7077 }
7078
7079 /* Define the offset between two registers, one to be eliminated,
7080 and the other its replacement, at the start of a routine. */
7081
7082 HOST_WIDE_INT
7083 alpha_initial_elimination_offset (from, to)
7084 unsigned int from, to ATTRIBUTE_UNUSED;
7085 {
7086 HOST_WIDE_INT ret;
7087
7088 ret = alpha_sa_size ();
7089 ret += ALPHA_ROUND (current_function_outgoing_args_size);
7090
7091 if (from == FRAME_POINTER_REGNUM)
7092 ;
7093 else if (from == ARG_POINTER_REGNUM)
7094 ret += (ALPHA_ROUND (get_frame_size ()
7095 + current_function_pretend_args_size)
7096 - current_function_pretend_args_size);
7097 else
7098 abort ();
7099
7100 return ret;
7101 }
7102
7103 int
7104 alpha_pv_save_size ()
7105 {
7106 alpha_sa_size ();
7107 return alpha_procedure_type == PT_STACK ? 8 : 0;
7108 }
7109
7110 int
7111 alpha_using_fp ()
7112 {
7113 alpha_sa_size ();
7114 return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM;
7115 }
7116
7117 #if TARGET_ABI_OPEN_VMS
7118
7119 const struct attribute_spec vms_attribute_table[] =
7120 {
7121 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
7122 { "overlaid", 0, 0, true, false, false, NULL },
7123 { "global", 0, 0, true, false, false, NULL },
7124 { "initialize", 0, 0, true, false, false, NULL },
7125 { NULL, 0, 0, false, false, false, NULL }
7126 };
7127
7128 #endif
7129
7130 static int
7131 find_lo_sum_using_gp (px, data)
7132 rtx *px;
7133 void *data ATTRIBUTE_UNUSED;
7134 {
7135 return GET_CODE (*px) == LO_SUM && XEXP (*px, 0) == pic_offset_table_rtx;
7136 }
7137
7138 int
7139 alpha_find_lo_sum_using_gp (insn)
7140 rtx insn;
7141 {
7142 return for_each_rtx (&PATTERN (insn), find_lo_sum_using_gp, NULL) > 0;
7143 }
7144
7145 static int
7146 alpha_does_function_need_gp ()
7147 {
7148 rtx insn;
7149
7150 /* The GP being variable is an OSF abi thing. */
7151 if (! TARGET_ABI_OSF)
7152 return 0;
7153
7154 if (TARGET_PROFILING_NEEDS_GP && current_function_profile)
7155 return 1;
7156
7157 if (current_function_is_thunk)
7158 return 1;
7159
7160 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
7161 Even if we are a static function, we still need to do this in case
7162 our address is taken and passed to something like qsort. */
7163
7164 push_topmost_sequence ();
7165 insn = get_insns ();
7166 pop_topmost_sequence ();
7167
7168 for (; insn; insn = NEXT_INSN (insn))
7169 if (INSN_P (insn)
7170 && GET_CODE (PATTERN (insn)) != USE
7171 && GET_CODE (PATTERN (insn)) != CLOBBER
7172 && get_attr_usegp (insn))
7173 return 1;
7174
7175 return 0;
7176 }
7177
7178 /* Write a version stamp. Don't write anything if we are running as a
7179 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
7180
7181 #ifdef HAVE_STAMP_H
7182 #include <stamp.h>
7183 #endif
7184
7185 void
7186 alpha_write_verstamp (file)
7187 FILE *file ATTRIBUTE_UNUSED;
7188 {
7189 #ifdef MS_STAMP
7190 fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
7191 #endif
7192 }
7193 \f
7194 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
7195 sequences. */
7196
7197 static rtx
7198 set_frame_related_p ()
7199 {
7200 rtx seq = get_insns ();
7201 rtx insn;
7202
7203 end_sequence ();
7204
7205 if (!seq)
7206 return NULL_RTX;
7207
7208 if (INSN_P (seq))
7209 {
7210 insn = seq;
7211 while (insn != NULL_RTX)
7212 {
7213 RTX_FRAME_RELATED_P (insn) = 1;
7214 insn = NEXT_INSN (insn);
7215 }
7216 seq = emit_insn (seq);
7217 }
7218 else
7219 {
7220 seq = emit_insn (seq);
7221 RTX_FRAME_RELATED_P (seq) = 1;
7222 }
7223 return seq;
7224 }
7225
7226 #define FRP(exp) (start_sequence (), exp, set_frame_related_p ())
7227
7228 /* Write function prologue. */
7229
7230 /* On vms we have two kinds of functions:
7231
7232 - stack frame (PROC_STACK)
7233 these are 'normal' functions with local vars and which are
7234 calling other functions
7235 - register frame (PROC_REGISTER)
7236 keeps all data in registers, needs no stack
7237
7238 We must pass this to the assembler so it can generate the
7239 proper pdsc (procedure descriptor)
7240 This is done with the '.pdesc' command.
7241
7242 On not-vms, we don't really differentiate between the two, as we can
7243 simply allocate stack without saving registers. */
7244
7245 void
7246 alpha_expand_prologue ()
7247 {
7248 /* Registers to save. */
7249 unsigned long imask = 0;
7250 unsigned long fmask = 0;
7251 /* Stack space needed for pushing registers clobbered by us. */
7252 HOST_WIDE_INT sa_size;
7253 /* Complete stack size needed. */
7254 HOST_WIDE_INT frame_size;
7255 /* Offset from base reg to register save area. */
7256 HOST_WIDE_INT reg_offset;
7257 rtx sa_reg, mem;
7258 int i;
7259
7260 sa_size = alpha_sa_size ();
7261
7262 frame_size = get_frame_size ();
7263 if (TARGET_ABI_OPEN_VMS)
7264 frame_size = ALPHA_ROUND (sa_size
7265 + (alpha_procedure_type == PT_STACK ? 8 : 0)
7266 + frame_size
7267 + current_function_pretend_args_size);
7268 else if (TARGET_ABI_UNICOSMK)
7269 /* We have to allocate space for the DSIB if we generate a frame. */
7270 frame_size = ALPHA_ROUND (sa_size
7271 + (alpha_procedure_type == PT_STACK ? 48 : 0))
7272 + ALPHA_ROUND (frame_size
7273 + current_function_outgoing_args_size);
7274 else
7275 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
7276 + sa_size
7277 + ALPHA_ROUND (frame_size
7278 + current_function_pretend_args_size));
7279
7280 if (TARGET_ABI_OPEN_VMS)
7281 reg_offset = 8;
7282 else
7283 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
7284
7285 alpha_sa_mask (&imask, &fmask);
7286
7287 /* Emit an insn to reload GP, if needed. */
7288 if (TARGET_ABI_OSF)
7289 {
7290 alpha_function_needs_gp = alpha_does_function_need_gp ();
7291 if (alpha_function_needs_gp)
7292 emit_insn (gen_prologue_ldgp ());
7293 }
7294
7295 /* TARGET_PROFILING_NEEDS_GP actually implies that we need to insert
7296 the call to mcount ourselves, rather than having the linker do it
7297 magically in response to -pg. Since _mcount has special linkage,
7298 don't represent the call as a call. */
7299 if (TARGET_PROFILING_NEEDS_GP && current_function_profile)
7300 emit_insn (gen_prologue_mcount ());
7301
7302 if (TARGET_ABI_UNICOSMK)
7303 unicosmk_gen_dsib (&imask);
7304
7305 /* Adjust the stack by the frame size. If the frame size is > 4096
7306 bytes, we need to be sure we probe somewhere in the first and last
7307 4096 bytes (we can probably get away without the latter test) and
7308 every 8192 bytes in between. If the frame size is > 32768, we
7309 do this in a loop. Otherwise, we generate the explicit probe
7310 instructions.
7311
7312 Note that we are only allowed to adjust sp once in the prologue. */
7313
7314 if (frame_size <= 32768)
7315 {
7316 if (frame_size > 4096)
7317 {
7318 int probed = 4096;
7319
7320 do
7321 emit_insn (gen_probe_stack (GEN_INT (TARGET_ABI_UNICOSMK
7322 ? -probed + 64
7323 : -probed)));
7324 while ((probed += 8192) < frame_size);
7325
7326 /* We only have to do this probe if we aren't saving registers. */
7327 if (sa_size == 0 && probed + 4096 < frame_size)
7328 emit_insn (gen_probe_stack (GEN_INT (-frame_size)));
7329 }
7330
7331 if (frame_size != 0)
7332 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
7333 GEN_INT (TARGET_ABI_UNICOSMK
7334 ? -frame_size + 64
7335 : -frame_size))));
7336 }
7337 else
7338 {
7339 /* Here we generate code to set R22 to SP + 4096 and set R23 to the
7340 number of 8192 byte blocks to probe. We then probe each block
7341 in the loop and then set SP to the proper location. If the
7342 amount remaining is > 4096, we have to do one more probe if we
7343 are not saving any registers. */
7344
7345 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
7346 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
7347 rtx ptr = gen_rtx_REG (DImode, 22);
7348 rtx count = gen_rtx_REG (DImode, 23);
7349 rtx seq;
7350
7351 emit_move_insn (count, GEN_INT (blocks));
7352 emit_insn (gen_adddi3 (ptr, stack_pointer_rtx,
7353 GEN_INT (TARGET_ABI_UNICOSMK ? 4096 - 64 : 4096)));
7354
7355 /* Because of the difficulty in emitting a new basic block this
7356 late in the compilation, generate the loop as a single insn. */
7357 emit_insn (gen_prologue_stack_probe_loop (count, ptr));
7358
7359 if (leftover > 4096 && sa_size == 0)
7360 {
7361 rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover));
7362 MEM_VOLATILE_P (last) = 1;
7363 emit_move_insn (last, const0_rtx);
7364 }
7365
7366 if (TARGET_ABI_WINDOWS_NT)
7367 {
7368 /* For NT stack unwind (done by 'reverse execution'), it's
7369 not OK to take the result of a loop, even though the value
7370 is already in ptr, so we reload it via a single operation
7371 and subtract it to sp.
7372
7373 Yes, that's correct -- we have to reload the whole constant
7374 into a temporary via ldah+lda then subtract from sp. To
7375 ensure we get ldah+lda, we use a special pattern. */
7376
7377 HOST_WIDE_INT lo, hi;
7378 lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
7379 hi = frame_size - lo;
7380
7381 emit_move_insn (ptr, GEN_INT (hi));
7382 emit_insn (gen_nt_lda (ptr, GEN_INT (lo)));
7383 seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
7384 ptr));
7385 }
7386 else
7387 {
7388 seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr,
7389 GEN_INT (-leftover)));
7390 }
7391
7392 /* This alternative is special, because the DWARF code cannot
7393 possibly intuit through the loop above. So we invent this
7394 note it looks at instead. */
7395 RTX_FRAME_RELATED_P (seq) = 1;
7396 REG_NOTES (seq)
7397 = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
7398 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
7399 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
7400 GEN_INT (TARGET_ABI_UNICOSMK
7401 ? -frame_size + 64
7402 : -frame_size))),
7403 REG_NOTES (seq));
7404 }
7405
7406 if (!TARGET_ABI_UNICOSMK)
7407 {
7408 /* Cope with very large offsets to the register save area. */
7409 sa_reg = stack_pointer_rtx;
7410 if (reg_offset + sa_size > 0x8000)
7411 {
7412 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
7413 HOST_WIDE_INT bias;
7414
7415 if (low + sa_size <= 0x8000)
7416 bias = reg_offset - low, reg_offset = low;
7417 else
7418 bias = reg_offset, reg_offset = 0;
7419
7420 sa_reg = gen_rtx_REG (DImode, 24);
7421 FRP (emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx,
7422 GEN_INT (bias))));
7423 }
7424
7425 /* Save regs in stack order. Beginning with VMS PV. */
7426 if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
7427 {
7428 mem = gen_rtx_MEM (DImode, stack_pointer_rtx);
7429 set_mem_alias_set (mem, alpha_sr_alias_set);
7430 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_PV)));
7431 }
7432
7433 /* Save register RA next. */
7434 if (imask & (1UL << REG_RA))
7435 {
7436 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
7437 set_mem_alias_set (mem, alpha_sr_alias_set);
7438 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
7439 imask &= ~(1UL << REG_RA);
7440 reg_offset += 8;
7441 }
7442
7443 /* Now save any other registers required to be saved. */
7444 for (i = 0; i < 32; i++)
7445 if (imask & (1UL << i))
7446 {
7447 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
7448 set_mem_alias_set (mem, alpha_sr_alias_set);
7449 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, i)));
7450 reg_offset += 8;
7451 }
7452
7453 for (i = 0; i < 32; i++)
7454 if (fmask & (1UL << i))
7455 {
7456 mem = gen_rtx_MEM (DFmode, plus_constant (sa_reg, reg_offset));
7457 set_mem_alias_set (mem, alpha_sr_alias_set);
7458 FRP (emit_move_insn (mem, gen_rtx_REG (DFmode, i+32)));
7459 reg_offset += 8;
7460 }
7461 }
7462 else if (TARGET_ABI_UNICOSMK && alpha_procedure_type == PT_STACK)
7463 {
7464 /* The standard frame on the T3E includes space for saving registers.
7465 We just have to use it. We don't have to save the return address and
7466 the old frame pointer here - they are saved in the DSIB. */
7467
7468 reg_offset = -56;
7469 for (i = 9; i < 15; i++)
7470 if (imask & (1UL << i))
7471 {
7472 mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx,
7473 reg_offset));
7474 set_mem_alias_set (mem, alpha_sr_alias_set);
7475 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, i)));
7476 reg_offset -= 8;
7477 }
7478 for (i = 2; i < 10; i++)
7479 if (fmask & (1UL << i))
7480 {
7481 mem = gen_rtx_MEM (DFmode, plus_constant (hard_frame_pointer_rtx,
7482 reg_offset));
7483 set_mem_alias_set (mem, alpha_sr_alias_set);
7484 FRP (emit_move_insn (mem, gen_rtx_REG (DFmode, i+32)));
7485 reg_offset -= 8;
7486 }
7487 }
7488
7489 if (TARGET_ABI_OPEN_VMS)
7490 {
7491 if (alpha_procedure_type == PT_REGISTER)
7492 /* Register frame procedures save the fp.
7493 ?? Ought to have a dwarf2 save for this. */
7494 emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
7495 hard_frame_pointer_rtx);
7496
7497 if (alpha_procedure_type != PT_NULL && vms_base_regno != REG_PV)
7498 emit_insn (gen_force_movdi (gen_rtx_REG (DImode, vms_base_regno),
7499 gen_rtx_REG (DImode, REG_PV)));
7500
7501 if (alpha_procedure_type != PT_NULL
7502 && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
7503 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
7504
7505 /* If we have to allocate space for outgoing args, do it now. */
7506 if (current_function_outgoing_args_size != 0)
7507 {
7508 rtx seq
7509 = emit_move_insn (stack_pointer_rtx,
7510 plus_constant
7511 (hard_frame_pointer_rtx,
7512 - (ALPHA_ROUND
7513 (current_function_outgoing_args_size))));
7514
7515 /* Only set FRAME_RELATED_P on the stack adjustment we just emitted
7516 if ! frame_pointer_needed. Setting the bit will change the CFA
7517 computation rule to use sp again, which would be wrong if we had
7518 frame_pointer_needed, as this means sp might move unpredictably
7519 later on.
7520
7521 Also, note that
7522 frame_pointer_needed
7523 => vms_unwind_regno == HARD_FRAME_POINTER_REGNUM
7524 and
7525 current_function_outgoing_args_size != 0
7526 => alpha_procedure_type != PT_NULL,
7527
7528 so when we are not setting the bit here, we are guaranteed to
7529 have emited an FRP frame pointer update just before. */
7530 RTX_FRAME_RELATED_P (seq) = ! frame_pointer_needed;
7531 }
7532 }
7533 else if (!TARGET_ABI_UNICOSMK)
7534 {
7535 /* If we need a frame pointer, set it from the stack pointer. */
7536 if (frame_pointer_needed)
7537 {
7538 if (TARGET_CAN_FAULT_IN_PROLOGUE)
7539 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
7540 else
7541 /* This must always be the last instruction in the
7542 prologue, thus we emit a special move + clobber. */
7543 FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx,
7544 stack_pointer_rtx, sa_reg)));
7545 }
7546 }
7547
7548 /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
7549 the prologue, for exception handling reasons, we cannot do this for
7550 any insn that might fault. We could prevent this for mems with a
7551 (clobber:BLK (scratch)), but this doesn't work for fp insns. So we
7552 have to prevent all such scheduling with a blockage.
7553
7554 Linux, on the other hand, never bothered to implement OSF/1's
7555 exception handling, and so doesn't care about such things. Anyone
7556 planning to use dwarf2 frame-unwind info can also omit the blockage. */
7557
7558 if (! TARGET_CAN_FAULT_IN_PROLOGUE)
7559 emit_insn (gen_blockage ());
7560 }
7561
7562 /* Output the textual info surrounding the prologue. */
7563
7564 void
7565 alpha_start_function (file, fnname, decl)
7566 FILE *file;
7567 const char *fnname;
7568 tree decl ATTRIBUTE_UNUSED;
7569 {
7570 unsigned long imask = 0;
7571 unsigned long fmask = 0;
7572 /* Stack space needed for pushing registers clobbered by us. */
7573 HOST_WIDE_INT sa_size;
7574 /* Complete stack size needed. */
7575 unsigned HOST_WIDE_INT frame_size;
7576 /* Offset from base reg to register save area. */
7577 HOST_WIDE_INT reg_offset;
7578 char *entry_label = (char *) alloca (strlen (fnname) + 6);
7579 int i;
7580
7581 /* Don't emit an extern directive for functions defined in the same file. */
7582 if (TARGET_ABI_UNICOSMK)
7583 {
7584 tree name_tree;
7585 name_tree = get_identifier (fnname);
7586 TREE_ASM_WRITTEN (name_tree) = 1;
7587 }
7588
7589 alpha_fnname = fnname;
7590 sa_size = alpha_sa_size ();
7591
7592 frame_size = get_frame_size ();
7593 if (TARGET_ABI_OPEN_VMS)
7594 frame_size = ALPHA_ROUND (sa_size
7595 + (alpha_procedure_type == PT_STACK ? 8 : 0)
7596 + frame_size
7597 + current_function_pretend_args_size);
7598 else if (TARGET_ABI_UNICOSMK)
7599 frame_size = ALPHA_ROUND (sa_size
7600 + (alpha_procedure_type == PT_STACK ? 48 : 0))
7601 + ALPHA_ROUND (frame_size
7602 + current_function_outgoing_args_size);
7603 else
7604 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
7605 + sa_size
7606 + ALPHA_ROUND (frame_size
7607 + current_function_pretend_args_size));
7608
7609 if (TARGET_ABI_OPEN_VMS)
7610 reg_offset = 8;
7611 else
7612 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
7613
7614 alpha_sa_mask (&imask, &fmask);
7615
7616 /* Ecoff can handle multiple .file directives, so put out file and lineno.
7617 We have to do that before the .ent directive as we cannot switch
7618 files within procedures with native ecoff because line numbers are
7619 linked to procedure descriptors.
7620 Outputting the lineno helps debugging of one line functions as they
7621 would otherwise get no line number at all. Please note that we would
7622 like to put out last_linenum from final.c, but it is not accessible. */
7623
7624 if (write_symbols == SDB_DEBUG)
7625 {
7626 #ifdef ASM_OUTPUT_SOURCE_FILENAME
7627 ASM_OUTPUT_SOURCE_FILENAME (file,
7628 DECL_SOURCE_FILE (current_function_decl));
7629 #endif
7630 #ifdef ASM_OUTPUT_SOURCE_LINE
7631 if (debug_info_level != DINFO_LEVEL_TERSE)
7632 ASM_OUTPUT_SOURCE_LINE (file,
7633 DECL_SOURCE_LINE (current_function_decl));
7634 #endif
7635 }
7636
7637 /* Issue function start and label. */
7638 if (TARGET_ABI_OPEN_VMS
7639 || (!TARGET_ABI_UNICOSMK && !flag_inhibit_size_directive))
7640 {
7641 fputs ("\t.ent ", file);
7642 assemble_name (file, fnname);
7643 putc ('\n', file);
7644
7645 /* If the function needs GP, we'll write the "..ng" label there.
7646 Otherwise, do it here. */
7647 if (TARGET_ABI_OSF
7648 && ! alpha_function_needs_gp
7649 && ! current_function_is_thunk)
7650 {
7651 putc ('$', file);
7652 assemble_name (file, fnname);
7653 fputs ("..ng:\n", file);
7654 }
7655 }
7656
7657 strcpy (entry_label, fnname);
7658 if (TARGET_ABI_OPEN_VMS)
7659 strcat (entry_label, "..en");
7660
7661 /* For public functions, the label must be globalized by appending an
7662 additional colon. */
7663 if (TARGET_ABI_UNICOSMK && TREE_PUBLIC (decl))
7664 strcat (entry_label, ":");
7665
7666 ASM_OUTPUT_LABEL (file, entry_label);
7667 inside_function = TRUE;
7668
7669 if (TARGET_ABI_OPEN_VMS)
7670 fprintf (file, "\t.base $%d\n", vms_base_regno);
7671
7672 if (!TARGET_ABI_OPEN_VMS && !TARGET_ABI_UNICOSMK && TARGET_IEEE_CONFORMANT
7673 && !flag_inhibit_size_directive)
7674 {
7675 /* Set flags in procedure descriptor to request IEEE-conformant
7676 math-library routines. The value we set it to is PDSC_EXC_IEEE
7677 (/usr/include/pdsc.h). */
7678 fputs ("\t.eflag 48\n", file);
7679 }
7680
7681 /* Set up offsets to alpha virtual arg/local debugging pointer. */
7682 alpha_auto_offset = -frame_size + current_function_pretend_args_size;
7683 alpha_arg_offset = -frame_size + 48;
7684
7685 /* Describe our frame. If the frame size is larger than an integer,
7686 print it as zero to avoid an assembler error. We won't be
7687 properly describing such a frame, but that's the best we can do. */
7688 if (TARGET_ABI_UNICOSMK)
7689 ;
7690 else if (TARGET_ABI_OPEN_VMS)
7691 fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,"
7692 HOST_WIDE_INT_PRINT_DEC "\n",
7693 vms_unwind_regno,
7694 frame_size >= (1UL << 31) ? 0 : frame_size,
7695 reg_offset);
7696 else if (!flag_inhibit_size_directive)
7697 fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,%d\n",
7698 (frame_pointer_needed
7699 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM),
7700 frame_size >= (1UL << 31) ? 0 : frame_size,
7701 current_function_pretend_args_size);
7702
7703 /* Describe which registers were spilled. */
7704 if (TARGET_ABI_UNICOSMK)
7705 ;
7706 else if (TARGET_ABI_OPEN_VMS)
7707 {
7708 if (imask)
7709 /* ??? Does VMS care if mask contains ra? The old code didn't
7710 set it, so I don't here. */
7711 fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1UL << REG_RA));
7712 if (fmask)
7713 fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
7714 if (alpha_procedure_type == PT_REGISTER)
7715 fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
7716 }
7717 else if (!flag_inhibit_size_directive)
7718 {
7719 if (imask)
7720 {
7721 fprintf (file, "\t.mask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", imask,
7722 frame_size >= (1UL << 31) ? 0 : reg_offset - frame_size);
7723
7724 for (i = 0; i < 32; ++i)
7725 if (imask & (1UL << i))
7726 reg_offset += 8;
7727 }
7728
7729 if (fmask)
7730 fprintf (file, "\t.fmask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", fmask,
7731 frame_size >= (1UL << 31) ? 0 : reg_offset - frame_size);
7732 }
7733
7734 #if TARGET_ABI_OPEN_VMS
7735 /* Ifdef'ed cause link_section are only available then. */
7736 readonly_data_section ();
7737 fprintf (file, "\t.align 3\n");
7738 assemble_name (file, fnname); fputs ("..na:\n", file);
7739 fputs ("\t.ascii \"", file);
7740 assemble_name (file, fnname);
7741 fputs ("\\0\"\n", file);
7742 alpha_need_linkage (fnname, 1);
7743 text_section ();
7744 #endif
7745 }
7746
7747 /* Emit the .prologue note at the scheduled end of the prologue. */
7748
7749 static void
7750 alpha_output_function_end_prologue (file)
7751 FILE *file;
7752 {
7753 if (TARGET_ABI_UNICOSMK)
7754 ;
7755 else if (TARGET_ABI_OPEN_VMS)
7756 fputs ("\t.prologue\n", file);
7757 else if (TARGET_ABI_WINDOWS_NT)
7758 fputs ("\t.prologue 0\n", file);
7759 else if (!flag_inhibit_size_directive)
7760 fprintf (file, "\t.prologue %d\n",
7761 alpha_function_needs_gp || current_function_is_thunk);
7762 }
7763
7764 /* Write function epilogue. */
7765
7766 /* ??? At some point we will want to support full unwind, and so will
7767 need to mark the epilogue as well. At the moment, we just confuse
7768 dwarf2out. */
7769 #undef FRP
7770 #define FRP(exp) exp
7771
7772 void
7773 alpha_expand_epilogue ()
7774 {
7775 /* Registers to save. */
7776 unsigned long imask = 0;
7777 unsigned long fmask = 0;
7778 /* Stack space needed for pushing registers clobbered by us. */
7779 HOST_WIDE_INT sa_size;
7780 /* Complete stack size needed. */
7781 HOST_WIDE_INT frame_size;
7782 /* Offset from base reg to register save area. */
7783 HOST_WIDE_INT reg_offset;
7784 int fp_is_frame_pointer, fp_offset;
7785 rtx sa_reg, sa_reg_exp = NULL;
7786 rtx sp_adj1, sp_adj2, mem;
7787 rtx eh_ofs;
7788 int i;
7789
7790 sa_size = alpha_sa_size ();
7791
7792 frame_size = get_frame_size ();
7793 if (TARGET_ABI_OPEN_VMS)
7794 frame_size = ALPHA_ROUND (sa_size
7795 + (alpha_procedure_type == PT_STACK ? 8 : 0)
7796 + frame_size
7797 + current_function_pretend_args_size);
7798 else if (TARGET_ABI_UNICOSMK)
7799 frame_size = ALPHA_ROUND (sa_size
7800 + (alpha_procedure_type == PT_STACK ? 48 : 0))
7801 + ALPHA_ROUND (frame_size
7802 + current_function_outgoing_args_size);
7803 else
7804 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
7805 + sa_size
7806 + ALPHA_ROUND (frame_size
7807 + current_function_pretend_args_size));
7808
7809 if (TARGET_ABI_OPEN_VMS)
7810 {
7811 if (alpha_procedure_type == PT_STACK)
7812 reg_offset = 8;
7813 else
7814 reg_offset = 0;
7815 }
7816 else
7817 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
7818
7819 alpha_sa_mask (&imask, &fmask);
7820
7821 fp_is_frame_pointer
7822 = ((TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
7823 || (!TARGET_ABI_OPEN_VMS && frame_pointer_needed));
7824 fp_offset = 0;
7825 sa_reg = stack_pointer_rtx;
7826
7827 if (current_function_calls_eh_return)
7828 eh_ofs = EH_RETURN_STACKADJ_RTX;
7829 else
7830 eh_ofs = NULL_RTX;
7831
7832 if (!TARGET_ABI_UNICOSMK && sa_size)
7833 {
7834 /* If we have a frame pointer, restore SP from it. */
7835 if ((TARGET_ABI_OPEN_VMS
7836 && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
7837 || (!TARGET_ABI_OPEN_VMS && frame_pointer_needed))
7838 FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx));
7839
7840 /* Cope with very large offsets to the register save area. */
7841 if (reg_offset + sa_size > 0x8000)
7842 {
7843 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
7844 HOST_WIDE_INT bias;
7845
7846 if (low + sa_size <= 0x8000)
7847 bias = reg_offset - low, reg_offset = low;
7848 else
7849 bias = reg_offset, reg_offset = 0;
7850
7851 sa_reg = gen_rtx_REG (DImode, 22);
7852 sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
7853
7854 FRP (emit_move_insn (sa_reg, sa_reg_exp));
7855 }
7856
7857 /* Restore registers in order, excepting a true frame pointer. */
7858
7859 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
7860 if (! eh_ofs)
7861 set_mem_alias_set (mem, alpha_sr_alias_set);
7862 FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
7863
7864 reg_offset += 8;
7865 imask &= ~(1UL << REG_RA);
7866
7867 for (i = 0; i < 32; ++i)
7868 if (imask & (1UL << i))
7869 {
7870 if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
7871 fp_offset = reg_offset;
7872 else
7873 {
7874 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
7875 set_mem_alias_set (mem, alpha_sr_alias_set);
7876 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
7877 }
7878 reg_offset += 8;
7879 }
7880
7881 for (i = 0; i < 32; ++i)
7882 if (fmask & (1UL << i))
7883 {
7884 mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
7885 set_mem_alias_set (mem, alpha_sr_alias_set);
7886 FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
7887 reg_offset += 8;
7888 }
7889 }
7890 else if (TARGET_ABI_UNICOSMK && alpha_procedure_type == PT_STACK)
7891 {
7892 /* Restore callee-saved general-purpose registers. */
7893
7894 reg_offset = -56;
7895
7896 for (i = 9; i < 15; i++)
7897 if (imask & (1UL << i))
7898 {
7899 mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx,
7900 reg_offset));
7901 set_mem_alias_set (mem, alpha_sr_alias_set);
7902 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
7903 reg_offset -= 8;
7904 }
7905
7906 for (i = 2; i < 10; i++)
7907 if (fmask & (1UL << i))
7908 {
7909 mem = gen_rtx_MEM (DFmode, plus_constant(hard_frame_pointer_rtx,
7910 reg_offset));
7911 set_mem_alias_set (mem, alpha_sr_alias_set);
7912 FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
7913 reg_offset -= 8;
7914 }
7915
7916 /* Restore the return address from the DSIB. */
7917
7918 mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx, -8));
7919 set_mem_alias_set (mem, alpha_sr_alias_set);
7920 FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
7921 }
7922
7923 if (frame_size || eh_ofs)
7924 {
7925 sp_adj1 = stack_pointer_rtx;
7926
7927 if (eh_ofs)
7928 {
7929 sp_adj1 = gen_rtx_REG (DImode, 23);
7930 emit_move_insn (sp_adj1,
7931 gen_rtx_PLUS (Pmode, stack_pointer_rtx, eh_ofs));
7932 }
7933
7934 /* If the stack size is large, begin computation into a temporary
7935 register so as not to interfere with a potential fp restore,
7936 which must be consecutive with an SP restore. */
7937 if (frame_size < 32768
7938 && ! (TARGET_ABI_UNICOSMK && current_function_calls_alloca))
7939 sp_adj2 = GEN_INT (frame_size);
7940 else if (TARGET_ABI_UNICOSMK)
7941 {
7942 sp_adj1 = gen_rtx_REG (DImode, 23);
7943 FRP (emit_move_insn (sp_adj1, hard_frame_pointer_rtx));
7944 sp_adj2 = const0_rtx;
7945 }
7946 else if (frame_size < 0x40007fffL)
7947 {
7948 int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
7949
7950 sp_adj2 = plus_constant (sp_adj1, frame_size - low);
7951 if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
7952 sp_adj1 = sa_reg;
7953 else
7954 {
7955 sp_adj1 = gen_rtx_REG (DImode, 23);
7956 FRP (emit_move_insn (sp_adj1, sp_adj2));
7957 }
7958 sp_adj2 = GEN_INT (low);
7959 }
7960 else
7961 {
7962 rtx tmp = gen_rtx_REG (DImode, 23);
7963 FRP (sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3));
7964 if (!sp_adj2)
7965 {
7966 /* We can't drop new things to memory this late, afaik,
7967 so build it up by pieces. */
7968 FRP (sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
7969 -(frame_size < 0)));
7970 if (!sp_adj2)
7971 abort ();
7972 }
7973 }
7974
7975 /* From now on, things must be in order. So emit blockages. */
7976
7977 /* Restore the frame pointer. */
7978 if (TARGET_ABI_UNICOSMK)
7979 {
7980 emit_insn (gen_blockage ());
7981 mem = gen_rtx_MEM (DImode,
7982 plus_constant (hard_frame_pointer_rtx, -16));
7983 set_mem_alias_set (mem, alpha_sr_alias_set);
7984 FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
7985 }
7986 else if (fp_is_frame_pointer)
7987 {
7988 emit_insn (gen_blockage ());
7989 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, fp_offset));
7990 set_mem_alias_set (mem, alpha_sr_alias_set);
7991 FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
7992 }
7993 else if (TARGET_ABI_OPEN_VMS)
7994 {
7995 emit_insn (gen_blockage ());
7996 FRP (emit_move_insn (hard_frame_pointer_rtx,
7997 gen_rtx_REG (DImode, vms_save_fp_regno)));
7998 }
7999
8000 /* Restore the stack pointer. */
8001 emit_insn (gen_blockage ());
8002 if (sp_adj2 == const0_rtx)
8003 FRP (emit_move_insn (stack_pointer_rtx, sp_adj1));
8004 else
8005 FRP (emit_move_insn (stack_pointer_rtx,
8006 gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)));
8007 }
8008 else
8009 {
8010 if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_REGISTER)
8011 {
8012 emit_insn (gen_blockage ());
8013 FRP (emit_move_insn (hard_frame_pointer_rtx,
8014 gen_rtx_REG (DImode, vms_save_fp_regno)));
8015 }
8016 else if (TARGET_ABI_UNICOSMK && alpha_procedure_type != PT_STACK)
8017 {
8018 /* Decrement the frame pointer if the function does not have a
8019 frame. */
8020
8021 emit_insn (gen_blockage ());
8022 FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
8023 hard_frame_pointer_rtx, GEN_INT (-1))));
8024 }
8025 }
8026 }
8027 \f
8028 /* Output the rest of the textual info surrounding the epilogue. */
8029
8030 void
8031 alpha_end_function (file, fnname, decl)
8032 FILE *file;
8033 const char *fnname;
8034 tree decl ATTRIBUTE_UNUSED;
8035 {
8036 /* End the function. */
8037 if (!TARGET_ABI_UNICOSMK && !flag_inhibit_size_directive)
8038 {
8039 fputs ("\t.end ", file);
8040 assemble_name (file, fnname);
8041 putc ('\n', file);
8042 }
8043 inside_function = FALSE;
8044
8045 #if TARGET_ABI_OPEN_VMS
8046 alpha_write_linkage (file, fnname, decl);
8047 #endif
8048
8049 /* Output jump tables and the static subroutine information block. */
8050 if (TARGET_ABI_UNICOSMK)
8051 {
8052 unicosmk_output_ssib (file, fnname);
8053 unicosmk_output_deferred_case_vectors (file);
8054 }
8055 }
8056
8057 #if TARGET_ABI_OSF
8058 /* Emit a tail call to FUNCTION after adjusting THIS by DELTA.
8059
8060 In order to avoid the hordes of differences between generated code
8061 with and without TARGET_EXPLICIT_RELOCS, and to avoid duplicating
8062 lots of code loading up large constants, generate rtl and emit it
8063 instead of going straight to text.
8064
8065 Not sure why this idea hasn't been explored before... */
8066
8067 static void
8068 alpha_output_mi_thunk_osf (file, thunk_fndecl, delta, vcall_offset, function)
8069 FILE *file;
8070 tree thunk_fndecl ATTRIBUTE_UNUSED;
8071 HOST_WIDE_INT delta;
8072 HOST_WIDE_INT vcall_offset;
8073 tree function;
8074 {
8075 HOST_WIDE_INT hi, lo;
8076 rtx this, insn, funexp;
8077
8078 /* We always require a valid GP. */
8079 emit_insn (gen_prologue_ldgp ());
8080 emit_note (NULL, NOTE_INSN_PROLOGUE_END);
8081
8082 /* Find the "this" pointer. If the function returns a structure,
8083 the structure return pointer is in $16. */
8084 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function))))
8085 this = gen_rtx_REG (Pmode, 17);
8086 else
8087 this = gen_rtx_REG (Pmode, 16);
8088
8089 /* Add DELTA. When possible we use ldah+lda. Otherwise load the
8090 entire constant for the add. */
8091 lo = ((delta & 0xffff) ^ 0x8000) - 0x8000;
8092 hi = (((delta - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
8093 if (hi + lo == delta)
8094 {
8095 if (hi)
8096 emit_insn (gen_adddi3 (this, this, GEN_INT (hi)));
8097 if (lo)
8098 emit_insn (gen_adddi3 (this, this, GEN_INT (lo)));
8099 }
8100 else
8101 {
8102 rtx tmp = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 0),
8103 delta, -(delta < 0));
8104 emit_insn (gen_adddi3 (this, this, tmp));
8105 }
8106
8107 /* Add a delta stored in the vtable at VCALL_OFFSET. */
8108 if (vcall_offset)
8109 {
8110 rtx tmp, tmp2;
8111
8112 tmp = gen_rtx_REG (Pmode, 0);
8113 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
8114
8115 lo = ((vcall_offset & 0xffff) ^ 0x8000) - 0x8000;
8116 hi = (((vcall_offset - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
8117 if (hi + lo == vcall_offset)
8118 {
8119 if (hi)
8120 emit_insn (gen_adddi3 (tmp, tmp, GEN_INT (hi)));
8121 }
8122 else
8123 {
8124 tmp2 = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 1),
8125 vcall_offset, -(vcall_offset < 0));
8126 emit_insn (gen_adddi3 (tmp, tmp, tmp2));
8127 lo = 0;
8128 }
8129 if (lo)
8130 tmp2 = gen_rtx_PLUS (Pmode, tmp, GEN_INT (lo));
8131 else
8132 tmp2 = tmp;
8133 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp2));
8134
8135 emit_insn (gen_adddi3 (this, this, tmp));
8136 }
8137
8138 /* Generate a tail call to the target function. */
8139 if (! TREE_USED (function))
8140 {
8141 assemble_external (function);
8142 TREE_USED (function) = 1;
8143 }
8144 funexp = XEXP (DECL_RTL (function), 0);
8145 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
8146 insn = emit_call_insn (gen_sibcall (funexp, const0_rtx));
8147 SIBLING_CALL_P (insn) = 1;
8148
8149 /* Run just enough of rest_of_compilation to get the insns emitted.
8150 There's not really enough bulk here to make other passes such as
8151 instruction scheduling worth while. Note that use_thunk calls
8152 assemble_start_function and assemble_end_function. */
8153 insn = get_insns ();
8154 shorten_branches (insn);
8155 final_start_function (insn, file, 1);
8156 final (insn, file, 1, 0);
8157 final_end_function ();
8158 }
8159 #endif /* TARGET_ABI_OSF */
8160 \f
8161 /* Debugging support. */
8162
8163 #include "gstab.h"
8164
8165 /* Count the number of sdb related labels are generated (to find block
8166 start and end boundaries). */
8167
8168 int sdb_label_count = 0;
8169
8170 /* Next label # for each statement. */
8171
8172 static int sym_lineno = 0;
8173
8174 /* Count the number of .file directives, so that .loc is up to date. */
8175
8176 static int num_source_filenames = 0;
8177
8178 /* Name of the file containing the current function. */
8179
8180 static const char *current_function_file = "";
8181
8182 /* Offsets to alpha virtual arg/local debugging pointers. */
8183
8184 long alpha_arg_offset;
8185 long alpha_auto_offset;
8186 \f
8187 /* Emit a new filename to a stream. */
8188
8189 void
8190 alpha_output_filename (stream, name)
8191 FILE *stream;
8192 const char *name;
8193 {
8194 static int first_time = TRUE;
8195 char ltext_label_name[100];
8196
8197 if (first_time)
8198 {
8199 first_time = FALSE;
8200 ++num_source_filenames;
8201 current_function_file = name;
8202 fprintf (stream, "\t.file\t%d ", num_source_filenames);
8203 output_quoted_string (stream, name);
8204 fprintf (stream, "\n");
8205 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
8206 fprintf (stream, "\t#@stabs\n");
8207 }
8208
8209 else if (write_symbols == DBX_DEBUG)
8210 {
8211 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
8212 fprintf (stream, "%s", ASM_STABS_OP);
8213 output_quoted_string (stream, name);
8214 fprintf (stream, ",%d,0,0,%s\n", N_SOL, &ltext_label_name[1]);
8215 }
8216
8217 else if (name != current_function_file
8218 && strcmp (name, current_function_file) != 0)
8219 {
8220 if (inside_function && ! TARGET_GAS)
8221 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
8222 else
8223 {
8224 ++num_source_filenames;
8225 current_function_file = name;
8226 fprintf (stream, "\t.file\t%d ", num_source_filenames);
8227 }
8228
8229 output_quoted_string (stream, name);
8230 fprintf (stream, "\n");
8231 }
8232 }
8233 \f
8234 /* Emit a linenumber to a stream. */
8235
8236 void
8237 alpha_output_lineno (stream, line)
8238 FILE *stream;
8239 int line;
8240 {
8241 if (write_symbols == DBX_DEBUG)
8242 {
8243 /* mips-tfile doesn't understand .stabd directives. */
8244 ++sym_lineno;
8245 fprintf (stream, "$LM%d:\n%s%d,0,%d,$LM%d\n",
8246 sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
8247 }
8248 else
8249 fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
8250 }
8251 \f
8252 /* Structure to show the current status of registers and memory. */
8253
8254 struct shadow_summary
8255 {
8256 struct {
8257 unsigned int i : 31; /* Mask of int regs */
8258 unsigned int fp : 31; /* Mask of fp regs */
8259 unsigned int mem : 1; /* mem == imem | fpmem */
8260 } used, defd;
8261 };
8262
8263 static void summarize_insn PARAMS ((rtx, struct shadow_summary *, int));
8264 static void alpha_handle_trap_shadows PARAMS ((void));
8265
8266 /* Summary the effects of expression X on the machine. Update SUM, a pointer
8267 to the summary structure. SET is nonzero if the insn is setting the
8268 object, otherwise zero. */
8269
8270 static void
8271 summarize_insn (x, sum, set)
8272 rtx x;
8273 struct shadow_summary *sum;
8274 int set;
8275 {
8276 const char *format_ptr;
8277 int i, j;
8278
8279 if (x == 0)
8280 return;
8281
8282 switch (GET_CODE (x))
8283 {
8284 /* ??? Note that this case would be incorrect if the Alpha had a
8285 ZERO_EXTRACT in SET_DEST. */
8286 case SET:
8287 summarize_insn (SET_SRC (x), sum, 0);
8288 summarize_insn (SET_DEST (x), sum, 1);
8289 break;
8290
8291 case CLOBBER:
8292 summarize_insn (XEXP (x, 0), sum, 1);
8293 break;
8294
8295 case USE:
8296 summarize_insn (XEXP (x, 0), sum, 0);
8297 break;
8298
8299 case ASM_OPERANDS:
8300 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
8301 summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
8302 break;
8303
8304 case PARALLEL:
8305 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
8306 summarize_insn (XVECEXP (x, 0, i), sum, 0);
8307 break;
8308
8309 case SUBREG:
8310 summarize_insn (SUBREG_REG (x), sum, 0);
8311 break;
8312
8313 case REG:
8314 {
8315 int regno = REGNO (x);
8316 unsigned long mask = ((unsigned long) 1) << (regno % 32);
8317
8318 if (regno == 31 || regno == 63)
8319 break;
8320
8321 if (set)
8322 {
8323 if (regno < 32)
8324 sum->defd.i |= mask;
8325 else
8326 sum->defd.fp |= mask;
8327 }
8328 else
8329 {
8330 if (regno < 32)
8331 sum->used.i |= mask;
8332 else
8333 sum->used.fp |= mask;
8334 }
8335 }
8336 break;
8337
8338 case MEM:
8339 if (set)
8340 sum->defd.mem = 1;
8341 else
8342 sum->used.mem = 1;
8343
8344 /* Find the regs used in memory address computation: */
8345 summarize_insn (XEXP (x, 0), sum, 0);
8346 break;
8347
8348 case CONST_INT: case CONST_DOUBLE:
8349 case SYMBOL_REF: case LABEL_REF: case CONST:
8350 case SCRATCH: case ASM_INPUT:
8351 break;
8352
8353 /* Handle common unary and binary ops for efficiency. */
8354 case COMPARE: case PLUS: case MINUS: case MULT: case DIV:
8355 case MOD: case UDIV: case UMOD: case AND: case IOR:
8356 case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT:
8357 case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX:
8358 case NE: case EQ: case GE: case GT: case LE:
8359 case LT: case GEU: case GTU: case LEU: case LTU:
8360 summarize_insn (XEXP (x, 0), sum, 0);
8361 summarize_insn (XEXP (x, 1), sum, 0);
8362 break;
8363
8364 case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
8365 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
8366 case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
8367 case SQRT: case FFS:
8368 summarize_insn (XEXP (x, 0), sum, 0);
8369 break;
8370
8371 default:
8372 format_ptr = GET_RTX_FORMAT (GET_CODE (x));
8373 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
8374 switch (format_ptr[i])
8375 {
8376 case 'e':
8377 summarize_insn (XEXP (x, i), sum, 0);
8378 break;
8379
8380 case 'E':
8381 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
8382 summarize_insn (XVECEXP (x, i, j), sum, 0);
8383 break;
8384
8385 case 'i':
8386 break;
8387
8388 default:
8389 abort ();
8390 }
8391 }
8392 }
8393
8394 /* Ensure a sufficient number of `trapb' insns are in the code when
8395 the user requests code with a trap precision of functions or
8396 instructions.
8397
8398 In naive mode, when the user requests a trap-precision of
8399 "instruction", a trapb is needed after every instruction that may
8400 generate a trap. This ensures that the code is resumption safe but
8401 it is also slow.
8402
8403 When optimizations are turned on, we delay issuing a trapb as long
8404 as possible. In this context, a trap shadow is the sequence of
8405 instructions that starts with a (potentially) trap generating
8406 instruction and extends to the next trapb or call_pal instruction
8407 (but GCC never generates call_pal by itself). We can delay (and
8408 therefore sometimes omit) a trapb subject to the following
8409 conditions:
8410
8411 (a) On entry to the trap shadow, if any Alpha register or memory
8412 location contains a value that is used as an operand value by some
8413 instruction in the trap shadow (live on entry), then no instruction
8414 in the trap shadow may modify the register or memory location.
8415
8416 (b) Within the trap shadow, the computation of the base register
8417 for a memory load or store instruction may not involve using the
8418 result of an instruction that might generate an UNPREDICTABLE
8419 result.
8420
8421 (c) Within the trap shadow, no register may be used more than once
8422 as a destination register. (This is to make life easier for the
8423 trap-handler.)
8424
8425 (d) The trap shadow may not include any branch instructions. */
8426
8427 static void
8428 alpha_handle_trap_shadows ()
8429 {
8430 struct shadow_summary shadow;
8431 int trap_pending, exception_nesting;
8432 rtx i, n;
8433
8434 trap_pending = 0;
8435 exception_nesting = 0;
8436 shadow.used.i = 0;
8437 shadow.used.fp = 0;
8438 shadow.used.mem = 0;
8439 shadow.defd = shadow.used;
8440
8441 for (i = get_insns (); i ; i = NEXT_INSN (i))
8442 {
8443 if (GET_CODE (i) == NOTE)
8444 {
8445 switch (NOTE_LINE_NUMBER (i))
8446 {
8447 case NOTE_INSN_EH_REGION_BEG:
8448 exception_nesting++;
8449 if (trap_pending)
8450 goto close_shadow;
8451 break;
8452
8453 case NOTE_INSN_EH_REGION_END:
8454 exception_nesting--;
8455 if (trap_pending)
8456 goto close_shadow;
8457 break;
8458
8459 case NOTE_INSN_EPILOGUE_BEG:
8460 if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
8461 goto close_shadow;
8462 break;
8463 }
8464 }
8465 else if (trap_pending)
8466 {
8467 if (alpha_tp == ALPHA_TP_FUNC)
8468 {
8469 if (GET_CODE (i) == JUMP_INSN
8470 && GET_CODE (PATTERN (i)) == RETURN)
8471 goto close_shadow;
8472 }
8473 else if (alpha_tp == ALPHA_TP_INSN)
8474 {
8475 if (optimize > 0)
8476 {
8477 struct shadow_summary sum;
8478
8479 sum.used.i = 0;
8480 sum.used.fp = 0;
8481 sum.used.mem = 0;
8482 sum.defd = sum.used;
8483
8484 switch (GET_CODE (i))
8485 {
8486 case INSN:
8487 /* Annoyingly, get_attr_trap will abort on these. */
8488 if (GET_CODE (PATTERN (i)) == USE
8489 || GET_CODE (PATTERN (i)) == CLOBBER)
8490 break;
8491
8492 summarize_insn (PATTERN (i), &sum, 0);
8493
8494 if ((sum.defd.i & shadow.defd.i)
8495 || (sum.defd.fp & shadow.defd.fp))
8496 {
8497 /* (c) would be violated */
8498 goto close_shadow;
8499 }
8500
8501 /* Combine shadow with summary of current insn: */
8502 shadow.used.i |= sum.used.i;
8503 shadow.used.fp |= sum.used.fp;
8504 shadow.used.mem |= sum.used.mem;
8505 shadow.defd.i |= sum.defd.i;
8506 shadow.defd.fp |= sum.defd.fp;
8507 shadow.defd.mem |= sum.defd.mem;
8508
8509 if ((sum.defd.i & shadow.used.i)
8510 || (sum.defd.fp & shadow.used.fp)
8511 || (sum.defd.mem & shadow.used.mem))
8512 {
8513 /* (a) would be violated (also takes care of (b)) */
8514 if (get_attr_trap (i) == TRAP_YES
8515 && ((sum.defd.i & sum.used.i)
8516 || (sum.defd.fp & sum.used.fp)))
8517 abort ();
8518
8519 goto close_shadow;
8520 }
8521 break;
8522
8523 case JUMP_INSN:
8524 case CALL_INSN:
8525 case CODE_LABEL:
8526 goto close_shadow;
8527
8528 default:
8529 abort ();
8530 }
8531 }
8532 else
8533 {
8534 close_shadow:
8535 n = emit_insn_before (gen_trapb (), i);
8536 PUT_MODE (n, TImode);
8537 PUT_MODE (i, TImode);
8538 trap_pending = 0;
8539 shadow.used.i = 0;
8540 shadow.used.fp = 0;
8541 shadow.used.mem = 0;
8542 shadow.defd = shadow.used;
8543 }
8544 }
8545 }
8546
8547 if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
8548 && GET_CODE (i) == INSN
8549 && GET_CODE (PATTERN (i)) != USE
8550 && GET_CODE (PATTERN (i)) != CLOBBER
8551 && get_attr_trap (i) == TRAP_YES)
8552 {
8553 if (optimize && !trap_pending)
8554 summarize_insn (PATTERN (i), &shadow, 0);
8555 trap_pending = 1;
8556 }
8557 }
8558 }
8559 \f
8560 /* Alpha can only issue instruction groups simultaneously if they are
8561 suitibly aligned. This is very processor-specific. */
8562
8563 enum alphaev4_pipe {
8564 EV4_STOP = 0,
8565 EV4_IB0 = 1,
8566 EV4_IB1 = 2,
8567 EV4_IBX = 4
8568 };
8569
8570 enum alphaev5_pipe {
8571 EV5_STOP = 0,
8572 EV5_NONE = 1,
8573 EV5_E01 = 2,
8574 EV5_E0 = 4,
8575 EV5_E1 = 8,
8576 EV5_FAM = 16,
8577 EV5_FA = 32,
8578 EV5_FM = 64
8579 };
8580
8581 static enum alphaev4_pipe alphaev4_insn_pipe PARAMS ((rtx));
8582 static enum alphaev5_pipe alphaev5_insn_pipe PARAMS ((rtx));
8583 static rtx alphaev4_next_group PARAMS ((rtx, int *, int *));
8584 static rtx alphaev5_next_group PARAMS ((rtx, int *, int *));
8585 static rtx alphaev4_next_nop PARAMS ((int *));
8586 static rtx alphaev5_next_nop PARAMS ((int *));
8587
8588 static void alpha_align_insns
8589 PARAMS ((unsigned int, rtx (*)(rtx, int *, int *), rtx (*)(int *)));
8590
8591 static enum alphaev4_pipe
8592 alphaev4_insn_pipe (insn)
8593 rtx insn;
8594 {
8595 if (recog_memoized (insn) < 0)
8596 return EV4_STOP;
8597 if (get_attr_length (insn) != 4)
8598 return EV4_STOP;
8599
8600 switch (get_attr_type (insn))
8601 {
8602 case TYPE_ILD:
8603 case TYPE_FLD:
8604 return EV4_IBX;
8605
8606 case TYPE_LDSYM:
8607 case TYPE_IADD:
8608 case TYPE_ILOG:
8609 case TYPE_ICMOV:
8610 case TYPE_ICMP:
8611 case TYPE_IST:
8612 case TYPE_FST:
8613 case TYPE_SHIFT:
8614 case TYPE_IMUL:
8615 case TYPE_FBR:
8616 return EV4_IB0;
8617
8618 case TYPE_MISC:
8619 case TYPE_IBR:
8620 case TYPE_JSR:
8621 case TYPE_CALLPAL:
8622 case TYPE_FCPYS:
8623 case TYPE_FCMOV:
8624 case TYPE_FADD:
8625 case TYPE_FDIV:
8626 case TYPE_FMUL:
8627 return EV4_IB1;
8628
8629 default:
8630 abort ();
8631 }
8632 }
8633
8634 static enum alphaev5_pipe
8635 alphaev5_insn_pipe (insn)
8636 rtx insn;
8637 {
8638 if (recog_memoized (insn) < 0)
8639 return EV5_STOP;
8640 if (get_attr_length (insn) != 4)
8641 return EV5_STOP;
8642
8643 switch (get_attr_type (insn))
8644 {
8645 case TYPE_ILD:
8646 case TYPE_FLD:
8647 case TYPE_LDSYM:
8648 case TYPE_IADD:
8649 case TYPE_ILOG:
8650 case TYPE_ICMOV:
8651 case TYPE_ICMP:
8652 return EV5_E01;
8653
8654 case TYPE_IST:
8655 case TYPE_FST:
8656 case TYPE_SHIFT:
8657 case TYPE_IMUL:
8658 case TYPE_MISC:
8659 case TYPE_MVI:
8660 return EV5_E0;
8661
8662 case TYPE_IBR:
8663 case TYPE_JSR:
8664 case TYPE_CALLPAL:
8665 return EV5_E1;
8666
8667 case TYPE_FCPYS:
8668 return EV5_FAM;
8669
8670 case TYPE_FBR:
8671 case TYPE_FCMOV:
8672 case TYPE_FADD:
8673 case TYPE_FDIV:
8674 return EV5_FA;
8675
8676 case TYPE_FMUL:
8677 return EV5_FM;
8678
8679 default:
8680 abort();
8681 }
8682 }
8683
8684 /* IN_USE is a mask of the slots currently filled within the insn group.
8685 The mask bits come from alphaev4_pipe above. If EV4_IBX is set, then
8686 the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.
8687
8688 LEN is, of course, the length of the group in bytes. */
8689
8690 static rtx
8691 alphaev4_next_group (insn, pin_use, plen)
8692 rtx insn;
8693 int *pin_use, *plen;
8694 {
8695 int len, in_use;
8696
8697 len = in_use = 0;
8698
8699 if (! INSN_P (insn)
8700 || GET_CODE (PATTERN (insn)) == CLOBBER
8701 || GET_CODE (PATTERN (insn)) == USE)
8702 goto next_and_done;
8703
8704 while (1)
8705 {
8706 enum alphaev4_pipe pipe;
8707
8708 pipe = alphaev4_insn_pipe (insn);
8709 switch (pipe)
8710 {
8711 case EV4_STOP:
8712 /* Force complex instructions to start new groups. */
8713 if (in_use)
8714 goto done;
8715
8716 /* If this is a completely unrecognized insn, its an asm.
8717 We don't know how long it is, so record length as -1 to
8718 signal a needed realignment. */
8719 if (recog_memoized (insn) < 0)
8720 len = -1;
8721 else
8722 len = get_attr_length (insn);
8723 goto next_and_done;
8724
8725 case EV4_IBX:
8726 if (in_use & EV4_IB0)
8727 {
8728 if (in_use & EV4_IB1)
8729 goto done;
8730 in_use |= EV4_IB1;
8731 }
8732 else
8733 in_use |= EV4_IB0 | EV4_IBX;
8734 break;
8735
8736 case EV4_IB0:
8737 if (in_use & EV4_IB0)
8738 {
8739 if (!(in_use & EV4_IBX) || (in_use & EV4_IB1))
8740 goto done;
8741 in_use |= EV4_IB1;
8742 }
8743 in_use |= EV4_IB0;
8744 break;
8745
8746 case EV4_IB1:
8747 if (in_use & EV4_IB1)
8748 goto done;
8749 in_use |= EV4_IB1;
8750 break;
8751
8752 default:
8753 abort();
8754 }
8755 len += 4;
8756
8757 /* Haifa doesn't do well scheduling branches. */
8758 if (GET_CODE (insn) == JUMP_INSN)
8759 goto next_and_done;
8760
8761 next:
8762 insn = next_nonnote_insn (insn);
8763
8764 if (!insn || ! INSN_P (insn))
8765 goto done;
8766
8767 /* Let Haifa tell us where it thinks insn group boundaries are. */
8768 if (GET_MODE (insn) == TImode)
8769 goto done;
8770
8771 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
8772 goto next;
8773 }
8774
8775 next_and_done:
8776 insn = next_nonnote_insn (insn);
8777
8778 done:
8779 *plen = len;
8780 *pin_use = in_use;
8781 return insn;
8782 }
8783
8784 /* IN_USE is a mask of the slots currently filled within the insn group.
8785 The mask bits come from alphaev5_pipe above. If EV5_E01 is set, then
8786 the insn in EV5_E0 can be swapped by the hardware into EV5_E1.
8787
8788 LEN is, of course, the length of the group in bytes. */
8789
8790 static rtx
8791 alphaev5_next_group (insn, pin_use, plen)
8792 rtx insn;
8793 int *pin_use, *plen;
8794 {
8795 int len, in_use;
8796
8797 len = in_use = 0;
8798
8799 if (! INSN_P (insn)
8800 || GET_CODE (PATTERN (insn)) == CLOBBER
8801 || GET_CODE (PATTERN (insn)) == USE)
8802 goto next_and_done;
8803
8804 while (1)
8805 {
8806 enum alphaev5_pipe pipe;
8807
8808 pipe = alphaev5_insn_pipe (insn);
8809 switch (pipe)
8810 {
8811 case EV5_STOP:
8812 /* Force complex instructions to start new groups. */
8813 if (in_use)
8814 goto done;
8815
8816 /* If this is a completely unrecognized insn, its an asm.
8817 We don't know how long it is, so record length as -1 to
8818 signal a needed realignment. */
8819 if (recog_memoized (insn) < 0)
8820 len = -1;
8821 else
8822 len = get_attr_length (insn);
8823 goto next_and_done;
8824
8825 /* ??? Most of the places below, we would like to abort, as
8826 it would indicate an error either in Haifa, or in the
8827 scheduling description. Unfortunately, Haifa never
8828 schedules the last instruction of the BB, so we don't
8829 have an accurate TI bit to go off. */
8830 case EV5_E01:
8831 if (in_use & EV5_E0)
8832 {
8833 if (in_use & EV5_E1)
8834 goto done;
8835 in_use |= EV5_E1;
8836 }
8837 else
8838 in_use |= EV5_E0 | EV5_E01;
8839 break;
8840
8841 case EV5_E0:
8842 if (in_use & EV5_E0)
8843 {
8844 if (!(in_use & EV5_E01) || (in_use & EV5_E1))
8845 goto done;
8846 in_use |= EV5_E1;
8847 }
8848 in_use |= EV5_E0;
8849 break;
8850
8851 case EV5_E1:
8852 if (in_use & EV5_E1)
8853 goto done;
8854 in_use |= EV5_E1;
8855 break;
8856
8857 case EV5_FAM:
8858 if (in_use & EV5_FA)
8859 {
8860 if (in_use & EV5_FM)
8861 goto done;
8862 in_use |= EV5_FM;
8863 }
8864 else
8865 in_use |= EV5_FA | EV5_FAM;
8866 break;
8867
8868 case EV5_FA:
8869 if (in_use & EV5_FA)
8870 goto done;
8871 in_use |= EV5_FA;
8872 break;
8873
8874 case EV5_FM:
8875 if (in_use & EV5_FM)
8876 goto done;
8877 in_use |= EV5_FM;
8878 break;
8879
8880 case EV5_NONE:
8881 break;
8882
8883 default:
8884 abort();
8885 }
8886 len += 4;
8887
8888 /* Haifa doesn't do well scheduling branches. */
8889 /* ??? If this is predicted not-taken, slotting continues, except
8890 that no more IBR, FBR, or JSR insns may be slotted. */
8891 if (GET_CODE (insn) == JUMP_INSN)
8892 goto next_and_done;
8893
8894 next:
8895 insn = next_nonnote_insn (insn);
8896
8897 if (!insn || ! INSN_P (insn))
8898 goto done;
8899
8900 /* Let Haifa tell us where it thinks insn group boundaries are. */
8901 if (GET_MODE (insn) == TImode)
8902 goto done;
8903
8904 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
8905 goto next;
8906 }
8907
8908 next_and_done:
8909 insn = next_nonnote_insn (insn);
8910
8911 done:
8912 *plen = len;
8913 *pin_use = in_use;
8914 return insn;
8915 }
8916
8917 static rtx
8918 alphaev4_next_nop (pin_use)
8919 int *pin_use;
8920 {
8921 int in_use = *pin_use;
8922 rtx nop;
8923
8924 if (!(in_use & EV4_IB0))
8925 {
8926 in_use |= EV4_IB0;
8927 nop = gen_nop ();
8928 }
8929 else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX)
8930 {
8931 in_use |= EV4_IB1;
8932 nop = gen_nop ();
8933 }
8934 else if (TARGET_FP && !(in_use & EV4_IB1))
8935 {
8936 in_use |= EV4_IB1;
8937 nop = gen_fnop ();
8938 }
8939 else
8940 nop = gen_unop ();
8941
8942 *pin_use = in_use;
8943 return nop;
8944 }
8945
8946 static rtx
8947 alphaev5_next_nop (pin_use)
8948 int *pin_use;
8949 {
8950 int in_use = *pin_use;
8951 rtx nop;
8952
8953 if (!(in_use & EV5_E1))
8954 {
8955 in_use |= EV5_E1;
8956 nop = gen_nop ();
8957 }
8958 else if (TARGET_FP && !(in_use & EV5_FA))
8959 {
8960 in_use |= EV5_FA;
8961 nop = gen_fnop ();
8962 }
8963 else if (TARGET_FP && !(in_use & EV5_FM))
8964 {
8965 in_use |= EV5_FM;
8966 nop = gen_fnop ();
8967 }
8968 else
8969 nop = gen_unop ();
8970
8971 *pin_use = in_use;
8972 return nop;
8973 }
8974
8975 /* The instruction group alignment main loop. */
8976
8977 static void
8978 alpha_align_insns (max_align, next_group, next_nop)
8979 unsigned int max_align;
8980 rtx (*next_group) PARAMS ((rtx, int *, int *));
8981 rtx (*next_nop) PARAMS ((int *));
8982 {
8983 /* ALIGN is the known alignment for the insn group. */
8984 unsigned int align;
8985 /* OFS is the offset of the current insn in the insn group. */
8986 int ofs;
8987 int prev_in_use, in_use, len;
8988 rtx i, next;
8989
8990 /* Let shorten branches care for assigning alignments to code labels. */
8991 shorten_branches (get_insns ());
8992
8993 if (align_functions < 4)
8994 align = 4;
8995 else if ((unsigned int) align_functions < max_align)
8996 align = align_functions;
8997 else
8998 align = max_align;
8999
9000 ofs = prev_in_use = 0;
9001 i = get_insns ();
9002 if (GET_CODE (i) == NOTE)
9003 i = next_nonnote_insn (i);
9004
9005 while (i)
9006 {
9007 next = (*next_group) (i, &in_use, &len);
9008
9009 /* When we see a label, resync alignment etc. */
9010 if (GET_CODE (i) == CODE_LABEL)
9011 {
9012 unsigned int new_align = 1 << label_to_alignment (i);
9013
9014 if (new_align >= align)
9015 {
9016 align = new_align < max_align ? new_align : max_align;
9017 ofs = 0;
9018 }
9019
9020 else if (ofs & (new_align-1))
9021 ofs = (ofs | (new_align-1)) + 1;
9022 if (len != 0)
9023 abort();
9024 }
9025
9026 /* Handle complex instructions special. */
9027 else if (in_use == 0)
9028 {
9029 /* Asms will have length < 0. This is a signal that we have
9030 lost alignment knowledge. Assume, however, that the asm
9031 will not mis-align instructions. */
9032 if (len < 0)
9033 {
9034 ofs = 0;
9035 align = 4;
9036 len = 0;
9037 }
9038 }
9039
9040 /* If the known alignment is smaller than the recognized insn group,
9041 realign the output. */
9042 else if ((int) align < len)
9043 {
9044 unsigned int new_log_align = len > 8 ? 4 : 3;
9045 rtx prev, where;
9046
9047 where = prev = prev_nonnote_insn (i);
9048 if (!where || GET_CODE (where) != CODE_LABEL)
9049 where = i;
9050
9051 /* Can't realign between a call and its gp reload. */
9052 if (! (TARGET_EXPLICIT_RELOCS
9053 && prev && GET_CODE (prev) == CALL_INSN))
9054 {
9055 emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
9056 align = 1 << new_log_align;
9057 ofs = 0;
9058 }
9059 }
9060
9061 /* If the group won't fit in the same INT16 as the previous,
9062 we need to add padding to keep the group together. Rather
9063 than simply leaving the insn filling to the assembler, we
9064 can make use of the knowledge of what sorts of instructions
9065 were issued in the previous group to make sure that all of
9066 the added nops are really free. */
9067 else if (ofs + len > (int) align)
9068 {
9069 int nop_count = (align - ofs) / 4;
9070 rtx where;
9071
9072 /* Insert nops before labels, branches, and calls to truely merge
9073 the execution of the nops with the previous instruction group. */
9074 where = prev_nonnote_insn (i);
9075 if (where)
9076 {
9077 if (GET_CODE (where) == CODE_LABEL)
9078 {
9079 rtx where2 = prev_nonnote_insn (where);
9080 if (where2 && GET_CODE (where2) == JUMP_INSN)
9081 where = where2;
9082 }
9083 else if (GET_CODE (where) == INSN)
9084 where = i;
9085 }
9086 else
9087 where = i;
9088
9089 do
9090 emit_insn_before ((*next_nop)(&prev_in_use), where);
9091 while (--nop_count);
9092 ofs = 0;
9093 }
9094
9095 ofs = (ofs + len) & (align - 1);
9096 prev_in_use = in_use;
9097 i = next;
9098 }
9099 }
9100 \f
9101 /* Machine dependent reorg pass. */
9102
9103 static void
9104 alpha_reorg ()
9105 {
9106 if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
9107 alpha_handle_trap_shadows ();
9108
9109 /* Due to the number of extra trapb insns, don't bother fixing up
9110 alignment when trap precision is instruction. Moreover, we can
9111 only do our job when sched2 is run. */
9112 if (optimize && !optimize_size
9113 && alpha_tp != ALPHA_TP_INSN
9114 && flag_schedule_insns_after_reload)
9115 {
9116 if (alpha_cpu == PROCESSOR_EV4)
9117 alpha_align_insns (8, alphaev4_next_group, alphaev4_next_nop);
9118 else if (alpha_cpu == PROCESSOR_EV5)
9119 alpha_align_insns (16, alphaev5_next_group, alphaev5_next_nop);
9120 }
9121 }
9122 \f
9123 #ifdef OBJECT_FORMAT_ELF
9124
9125 /* Switch to the section to which we should output X. The only thing
9126 special we do here is to honor small data. */
9127
9128 static void
9129 alpha_elf_select_rtx_section (mode, x, align)
9130 enum machine_mode mode;
9131 rtx x;
9132 unsigned HOST_WIDE_INT align;
9133 {
9134 if (TARGET_SMALL_DATA && GET_MODE_SIZE (mode) <= g_switch_value)
9135 /* ??? Consider using mergable sdata sections. */
9136 sdata_section ();
9137 else
9138 default_elf_select_rtx_section (mode, x, align);
9139 }
9140
9141 #endif /* OBJECT_FORMAT_ELF */
9142 \f
9143 /* Structure to collect function names for final output in link section. */
9144 /* Note that items marked with GTY can't be ifdef'ed out. */
9145
9146 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
9147 enum reloc_kind {KIND_LINKAGE, KIND_CODEADDR};
9148
9149 struct alpha_links GTY(())
9150 {
9151 int num;
9152 rtx linkage;
9153 enum links_kind lkind;
9154 enum reloc_kind rkind;
9155 };
9156
9157 struct alpha_funcs GTY(())
9158 {
9159 int num;
9160 splay_tree GTY ((param1_is (char *), param2_is (struct alpha_links *)))
9161 links;
9162 };
9163
9164 static GTY ((param1_is (char *), param2_is (struct alpha_links *)))
9165 splay_tree alpha_links_tree;
9166 static GTY ((param1_is (tree), param2_is (struct alpha_funcs *)))
9167 splay_tree alpha_funcs_tree;
9168
9169 static GTY(()) int alpha_funcs_num;
9170
9171 #if TARGET_ABI_OPEN_VMS
9172
9173 /* Return the VMS argument type corresponding to MODE. */
9174
9175 enum avms_arg_type
9176 alpha_arg_type (mode)
9177 enum machine_mode mode;
9178 {
9179 switch (mode)
9180 {
9181 case SFmode:
9182 return TARGET_FLOAT_VAX ? FF : FS;
9183 case DFmode:
9184 return TARGET_FLOAT_VAX ? FD : FT;
9185 default:
9186 return I64;
9187 }
9188 }
9189
9190 /* Return an rtx for an integer representing the VMS Argument Information
9191 register value. */
9192
9193 rtx
9194 alpha_arg_info_reg_val (cum)
9195 CUMULATIVE_ARGS cum;
9196 {
9197 unsigned HOST_WIDE_INT regval = cum.num_args;
9198 int i;
9199
9200 for (i = 0; i < 6; i++)
9201 regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
9202
9203 return GEN_INT (regval);
9204 }
9205 \f
9206 /* Make (or fake) .linkage entry for function call.
9207
9208 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition.
9209
9210 Return an SYMBOL_REF rtx for the linkage. */
9211
9212 rtx
9213 alpha_need_linkage (name, is_local)
9214 const char *name;
9215 int is_local;
9216 {
9217 splay_tree_node node;
9218 struct alpha_links *al;
9219
9220 if (name[0] == '*')
9221 name++;
9222
9223 if (is_local)
9224 {
9225 struct alpha_funcs *cfaf;
9226
9227 if (!alpha_funcs_tree)
9228 alpha_funcs_tree = splay_tree_new_ggc ((splay_tree_compare_fn)
9229 splay_tree_compare_pointers);
9230
9231 cfaf = (struct alpha_funcs *) ggc_alloc (sizeof (struct alpha_funcs));
9232
9233 cfaf->links = 0;
9234 cfaf->num = ++alpha_funcs_num;
9235
9236 splay_tree_insert (alpha_funcs_tree,
9237 (splay_tree_key) current_function_decl,
9238 (splay_tree_value) cfaf);
9239 }
9240
9241 if (alpha_links_tree)
9242 {
9243 /* Is this name already defined? */
9244
9245 node = splay_tree_lookup (alpha_links_tree, (splay_tree_key) name);
9246 if (node)
9247 {
9248 al = (struct alpha_links *) node->value;
9249 if (is_local)
9250 {
9251 /* Defined here but external assumed. */
9252 if (al->lkind == KIND_EXTERN)
9253 al->lkind = KIND_LOCAL;
9254 }
9255 else
9256 {
9257 /* Used here but unused assumed. */
9258 if (al->lkind == KIND_UNUSED)
9259 al->lkind = KIND_LOCAL;
9260 }
9261 return al->linkage;
9262 }
9263 }
9264 else
9265 alpha_links_tree = splay_tree_new_ggc ((splay_tree_compare_fn) strcmp);
9266
9267 al = (struct alpha_links *) ggc_alloc (sizeof (struct alpha_links));
9268 name = ggc_strdup (name);
9269
9270 /* Assume external if no definition. */
9271 al->lkind = (is_local ? KIND_UNUSED : KIND_EXTERN);
9272
9273 /* Ensure we have an IDENTIFIER so assemble_name can mark it used. */
9274 get_identifier (name);
9275
9276 /* Construct a SYMBOL_REF for us to call. */
9277 {
9278 size_t name_len = strlen (name);
9279 char *linksym = alloca (name_len + 6);
9280 linksym[0] = '$';
9281 memcpy (linksym + 1, name, name_len);
9282 memcpy (linksym + 1 + name_len, "..lk", 5);
9283 al->linkage = gen_rtx_SYMBOL_REF (Pmode,
9284 ggc_alloc_string (linksym, name_len + 5));
9285 }
9286
9287 splay_tree_insert (alpha_links_tree, (splay_tree_key) name,
9288 (splay_tree_value) al);
9289
9290 return al->linkage;
9291 }
9292
9293 rtx
9294 alpha_use_linkage (linkage, cfundecl, lflag, rflag)
9295 rtx linkage;
9296 tree cfundecl;
9297 int lflag;
9298 int rflag;
9299 {
9300 splay_tree_node cfunnode;
9301 struct alpha_funcs *cfaf;
9302 struct alpha_links *al;
9303 const char *name = XSTR (linkage, 0);
9304
9305 cfaf = (struct alpha_funcs *) 0;
9306 al = (struct alpha_links *) 0;
9307
9308 cfunnode = splay_tree_lookup (alpha_funcs_tree, (splay_tree_key) cfundecl);
9309 cfaf = (struct alpha_funcs *) cfunnode->value;
9310
9311 if (cfaf->links)
9312 {
9313 splay_tree_node lnode;
9314
9315 /* Is this name already defined? */
9316
9317 lnode = splay_tree_lookup (cfaf->links, (splay_tree_key) name);
9318 if (lnode)
9319 al = (struct alpha_links *) lnode->value;
9320 }
9321 else
9322 cfaf->links = splay_tree_new_ggc ((splay_tree_compare_fn) strcmp);
9323
9324 if (!al)
9325 {
9326 size_t name_len;
9327 size_t buflen;
9328 char buf [512];
9329 char *linksym;
9330 splay_tree_node node = 0;
9331 struct alpha_links *anl;
9332
9333 if (name[0] == '*')
9334 name++;
9335
9336 name_len = strlen (name);
9337
9338 al = (struct alpha_links *) ggc_alloc (sizeof (struct alpha_links));
9339 al->num = cfaf->num;
9340
9341 node = splay_tree_lookup (alpha_links_tree, (splay_tree_key) name);
9342 if (node)
9343 {
9344 anl = (struct alpha_links *) node->value;
9345 al->lkind = anl->lkind;
9346 }
9347
9348 sprintf (buf, "$%d..%s..lk", cfaf->num, name);
9349 buflen = strlen (buf);
9350 linksym = alloca (buflen + 1);
9351 memcpy (linksym, buf, buflen + 1);
9352
9353 al->linkage = gen_rtx_SYMBOL_REF
9354 (Pmode, ggc_alloc_string (linksym, buflen + 1));
9355
9356 splay_tree_insert (cfaf->links, (splay_tree_key) name,
9357 (splay_tree_value) al);
9358 }
9359
9360 if (rflag)
9361 al->rkind = KIND_CODEADDR;
9362 else
9363 al->rkind = KIND_LINKAGE;
9364
9365 if (lflag)
9366 return gen_rtx_MEM (Pmode, plus_constant (al->linkage, 8));
9367 else
9368 return al->linkage;
9369 }
9370
9371 static int
9372 alpha_write_one_linkage (node, data)
9373 splay_tree_node node;
9374 void *data;
9375 {
9376 const char *const name = (const char *) node->key;
9377 struct alpha_links *link = (struct alpha_links *) node->value;
9378 FILE *stream = (FILE *) data;
9379
9380 fprintf (stream, "$%d..%s..lk:\n", link->num, name);
9381 if (link->rkind == KIND_CODEADDR)
9382 {
9383 if (link->lkind == KIND_LOCAL)
9384 {
9385 /* Local and used */
9386 fprintf (stream, "\t.quad %s..en\n", name);
9387 }
9388 else
9389 {
9390 /* External and used, request code address. */
9391 fprintf (stream, "\t.code_address %s\n", name);
9392 }
9393 }
9394 else
9395 {
9396 if (link->lkind == KIND_LOCAL)
9397 {
9398 /* Local and used, build linkage pair. */
9399 fprintf (stream, "\t.quad %s..en\n", name);
9400 fprintf (stream, "\t.quad %s\n", name);
9401 }
9402 else
9403 {
9404 /* External and used, request linkage pair. */
9405 fprintf (stream, "\t.linkage %s\n", name);
9406 }
9407 }
9408
9409 return 0;
9410 }
9411
9412 static void
9413 alpha_write_linkage (stream, funname, fundecl)
9414 FILE *stream;
9415 const char *funname;
9416 tree fundecl;
9417 {
9418 splay_tree_node node;
9419 struct alpha_funcs *func;
9420
9421 link_section ();
9422 fprintf (stream, "\t.align 3\n");
9423 node = splay_tree_lookup (alpha_funcs_tree, (splay_tree_key) fundecl);
9424 func = (struct alpha_funcs *) node->value;
9425
9426 fputs ("\t.name ", stream);
9427 assemble_name (stream, funname);
9428 fputs ("..na\n", stream);
9429 ASM_OUTPUT_LABEL (stream, funname);
9430 fprintf (stream, "\t.pdesc ");
9431 assemble_name (stream, funname);
9432 fprintf (stream, "..en,%s\n",
9433 alpha_procedure_type == PT_STACK ? "stack"
9434 : alpha_procedure_type == PT_REGISTER ? "reg" : "null");
9435
9436 if (func->links)
9437 {
9438 splay_tree_foreach (func->links, alpha_write_one_linkage, stream);
9439 /* splay_tree_delete (func->links); */
9440 }
9441 }
9442
9443 /* Given a decl, a section name, and whether the decl initializer
9444 has relocs, choose attributes for the section. */
9445
9446 #define SECTION_VMS_OVERLAY SECTION_FORGET
9447 #define SECTION_VMS_GLOBAL SECTION_MACH_DEP
9448 #define SECTION_VMS_INITIALIZE (SECTION_VMS_GLOBAL << 1)
9449
9450 static unsigned int
9451 vms_section_type_flags (decl, name, reloc)
9452 tree decl;
9453 const char *name;
9454 int reloc;
9455 {
9456 unsigned int flags = default_section_type_flags (decl, name, reloc);
9457
9458 if (decl && DECL_ATTRIBUTES (decl)
9459 && lookup_attribute ("overlaid", DECL_ATTRIBUTES (decl)))
9460 flags |= SECTION_VMS_OVERLAY;
9461 if (decl && DECL_ATTRIBUTES (decl)
9462 && lookup_attribute ("global", DECL_ATTRIBUTES (decl)))
9463 flags |= SECTION_VMS_GLOBAL;
9464 if (decl && DECL_ATTRIBUTES (decl)
9465 && lookup_attribute ("initialize", DECL_ATTRIBUTES (decl)))
9466 flags |= SECTION_VMS_INITIALIZE;
9467
9468 return flags;
9469 }
9470
9471 /* Switch to an arbitrary section NAME with attributes as specified
9472 by FLAGS. ALIGN specifies any known alignment requirements for
9473 the section; 0 if the default should be used. */
9474
9475 static void
9476 vms_asm_named_section (name, flags)
9477 const char *name;
9478 unsigned int flags;
9479 {
9480 fputc ('\n', asm_out_file);
9481 fprintf (asm_out_file, ".section\t%s", name);
9482
9483 if (flags & SECTION_VMS_OVERLAY)
9484 fprintf (asm_out_file, ",OVR");
9485 if (flags & SECTION_VMS_GLOBAL)
9486 fprintf (asm_out_file, ",GBL");
9487 if (flags & SECTION_VMS_INITIALIZE)
9488 fprintf (asm_out_file, ",NOMOD");
9489 if (flags & SECTION_DEBUG)
9490 fprintf (asm_out_file, ",NOWRT");
9491
9492 fputc ('\n', asm_out_file);
9493 }
9494
9495 /* Record an element in the table of global constructors. SYMBOL is
9496 a SYMBOL_REF of the function to be called; PRIORITY is a number
9497 between 0 and MAX_INIT_PRIORITY.
9498
9499 Differs from default_ctors_section_asm_out_constructor in that the
9500 width of the .ctors entry is always 64 bits, rather than the 32 bits
9501 used by a normal pointer. */
9502
9503 static void
9504 vms_asm_out_constructor (symbol, priority)
9505 rtx symbol;
9506 int priority ATTRIBUTE_UNUSED;
9507 {
9508 ctors_section ();
9509 assemble_align (BITS_PER_WORD);
9510 assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
9511 }
9512
9513 static void
9514 vms_asm_out_destructor (symbol, priority)
9515 rtx symbol;
9516 int priority ATTRIBUTE_UNUSED;
9517 {
9518 dtors_section ();
9519 assemble_align (BITS_PER_WORD);
9520 assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
9521 }
9522 #else
9523
9524 rtx
9525 alpha_need_linkage (name, is_local)
9526 const char *name ATTRIBUTE_UNUSED;
9527 int is_local ATTRIBUTE_UNUSED;
9528 {
9529 return NULL_RTX;
9530 }
9531
9532 rtx
9533 alpha_use_linkage (linkage, cfundecl, lflag, rflag)
9534 rtx linkage ATTRIBUTE_UNUSED;
9535 tree cfundecl ATTRIBUTE_UNUSED;
9536 int lflag ATTRIBUTE_UNUSED;
9537 int rflag ATTRIBUTE_UNUSED;
9538 {
9539 return NULL_RTX;
9540 }
9541
9542 #endif /* TARGET_ABI_OPEN_VMS */
9543 \f
9544 #if TARGET_ABI_UNICOSMK
9545
9546 static void unicosmk_output_module_name PARAMS ((FILE *));
9547 static void unicosmk_output_default_externs PARAMS ((FILE *));
9548 static void unicosmk_output_dex PARAMS ((FILE *));
9549 static void unicosmk_output_externs PARAMS ((FILE *));
9550 static void unicosmk_output_addr_vec PARAMS ((FILE *, rtx));
9551 static const char *unicosmk_ssib_name PARAMS ((void));
9552 static int unicosmk_special_name PARAMS ((const char *));
9553
9554 /* Define the offset between two registers, one to be eliminated, and the
9555 other its replacement, at the start of a routine. */
9556
9557 int
9558 unicosmk_initial_elimination_offset (from, to)
9559 int from;
9560 int to;
9561 {
9562 int fixed_size;
9563
9564 fixed_size = alpha_sa_size();
9565 if (fixed_size != 0)
9566 fixed_size += 48;
9567
9568 if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
9569 return -fixed_size;
9570 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
9571 return 0;
9572 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
9573 return (ALPHA_ROUND (current_function_outgoing_args_size)
9574 + ALPHA_ROUND (get_frame_size()));
9575 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
9576 return (ALPHA_ROUND (fixed_size)
9577 + ALPHA_ROUND (get_frame_size()
9578 + current_function_outgoing_args_size));
9579 else
9580 abort ();
9581 }
9582
9583 /* Output the module name for .ident and .end directives. We have to strip
9584 directories and add make sure that the module name starts with a letter
9585 or '$'. */
9586
9587 static void
9588 unicosmk_output_module_name (file)
9589 FILE *file;
9590 {
9591 const char *name;
9592
9593 /* Strip directories. */
9594
9595 name = strrchr (main_input_filename, '/');
9596 if (name)
9597 ++name;
9598 else
9599 name = main_input_filename;
9600
9601 /* CAM only accepts module names that start with a letter or '$'. We
9602 prefix the module name with a '$' if necessary. */
9603
9604 if (!ISALPHA (*name))
9605 putc ('$', file);
9606 output_clean_symbol_name (file, name);
9607 }
9608
9609 /* Output text that to appear at the beginning of an assembler file. */
9610
9611 void
9612 unicosmk_asm_file_start (file)
9613 FILE *file;
9614 {
9615 int i;
9616
9617 fputs ("\t.ident\t", file);
9618 unicosmk_output_module_name (file);
9619 fputs ("\n\n", file);
9620
9621 /* The Unicos/Mk assembler uses different register names. Instead of trying
9622 to support them, we simply use micro definitions. */
9623
9624 /* CAM has different register names: rN for the integer register N and fN
9625 for the floating-point register N. Instead of trying to use these in
9626 alpha.md, we define the symbols $N and $fN to refer to the appropriate
9627 register. */
9628
9629 for (i = 0; i < 32; ++i)
9630 fprintf (file, "$%d <- r%d\n", i, i);
9631
9632 for (i = 0; i < 32; ++i)
9633 fprintf (file, "$f%d <- f%d\n", i, i);
9634
9635 putc ('\n', file);
9636
9637 /* The .align directive fill unused space with zeroes which does not work
9638 in code sections. We define the macro 'gcc@code@align' which uses nops
9639 instead. Note that it assumes that code sections always have the
9640 biggest possible alignment since . refers to the current offset from
9641 the beginning of the section. */
9642
9643 fputs ("\t.macro gcc@code@align n\n", file);
9644 fputs ("gcc@n@bytes = 1 << n\n", file);
9645 fputs ("gcc@here = . % gcc@n@bytes\n", file);
9646 fputs ("\t.if ne, gcc@here, 0\n", file);
9647 fputs ("\t.repeat (gcc@n@bytes - gcc@here) / 4\n", file);
9648 fputs ("\tbis r31,r31,r31\n", file);
9649 fputs ("\t.endr\n", file);
9650 fputs ("\t.endif\n", file);
9651 fputs ("\t.endm gcc@code@align\n\n", file);
9652
9653 /* Output extern declarations which should always be visible. */
9654 unicosmk_output_default_externs (file);
9655
9656 /* Open a dummy section. We always need to be inside a section for the
9657 section-switching code to work correctly.
9658 ??? This should be a module id or something like that. I still have to
9659 figure out what the rules for those are. */
9660 fputs ("\n\t.psect\t$SG00000,data\n", file);
9661 }
9662
9663 /* Output text to appear at the end of an assembler file. This includes all
9664 pending extern declarations and DEX expressions. */
9665
9666 void
9667 unicosmk_asm_file_end (file)
9668 FILE *file;
9669 {
9670 fputs ("\t.endp\n\n", file);
9671
9672 /* Output all pending externs. */
9673
9674 unicosmk_output_externs (file);
9675
9676 /* Output dex definitions used for functions whose names conflict with
9677 register names. */
9678
9679 unicosmk_output_dex (file);
9680
9681 fputs ("\t.end\t", file);
9682 unicosmk_output_module_name (file);
9683 putc ('\n', file);
9684 }
9685
9686 /* Output the definition of a common variable. */
9687
9688 void
9689 unicosmk_output_common (file, name, size, align)
9690 FILE *file;
9691 const char *name;
9692 int size;
9693 int align;
9694 {
9695 tree name_tree;
9696 printf ("T3E__: common %s\n", name);
9697
9698 common_section ();
9699 fputs("\t.endp\n\n\t.psect ", file);
9700 assemble_name(file, name);
9701 fprintf(file, ",%d,common\n", floor_log2 (align / BITS_PER_UNIT));
9702 fprintf(file, "\t.byte\t0:%d\n", size);
9703
9704 /* Mark the symbol as defined in this module. */
9705 name_tree = get_identifier (name);
9706 TREE_ASM_WRITTEN (name_tree) = 1;
9707 }
9708
9709 #define SECTION_PUBLIC SECTION_MACH_DEP
9710 #define SECTION_MAIN (SECTION_PUBLIC << 1)
9711 static int current_section_align;
9712
9713 static unsigned int
9714 unicosmk_section_type_flags (decl, name, reloc)
9715 tree decl;
9716 const char *name;
9717 int reloc ATTRIBUTE_UNUSED;
9718 {
9719 unsigned int flags = default_section_type_flags (decl, name, reloc);
9720
9721 if (!decl)
9722 return flags;
9723
9724 if (TREE_CODE (decl) == FUNCTION_DECL)
9725 {
9726 current_section_align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
9727 if (align_functions_log > current_section_align)
9728 current_section_align = align_functions_log;
9729
9730 if (! strcmp (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), "main"))
9731 flags |= SECTION_MAIN;
9732 }
9733 else
9734 current_section_align = floor_log2 (DECL_ALIGN (decl) / BITS_PER_UNIT);
9735
9736 if (TREE_PUBLIC (decl))
9737 flags |= SECTION_PUBLIC;
9738
9739 return flags;
9740 }
9741
9742 /* Generate a section name for decl and associate it with the
9743 declaration. */
9744
9745 static void
9746 unicosmk_unique_section (decl, reloc)
9747 tree decl;
9748 int reloc ATTRIBUTE_UNUSED;
9749 {
9750 const char *name;
9751 int len;
9752
9753 if (!decl)
9754 abort ();
9755
9756 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
9757 name = default_strip_name_encoding (name);
9758 len = strlen (name);
9759
9760 if (TREE_CODE (decl) == FUNCTION_DECL)
9761 {
9762 char *string;
9763
9764 /* It is essential that we prefix the section name here because
9765 otherwise the section names generated for constructors and
9766 destructors confuse collect2. */
9767
9768 string = alloca (len + 6);
9769 sprintf (string, "code@%s", name);
9770 DECL_SECTION_NAME (decl) = build_string (len + 5, string);
9771 }
9772 else if (TREE_PUBLIC (decl))
9773 DECL_SECTION_NAME (decl) = build_string (len, name);
9774 else
9775 {
9776 char *string;
9777
9778 string = alloca (len + 6);
9779 sprintf (string, "data@%s", name);
9780 DECL_SECTION_NAME (decl) = build_string (len + 5, string);
9781 }
9782 }
9783
9784 /* Switch to an arbitrary section NAME with attributes as specified
9785 by FLAGS. ALIGN specifies any known alignment requirements for
9786 the section; 0 if the default should be used. */
9787
9788 static void
9789 unicosmk_asm_named_section (name, flags)
9790 const char *name;
9791 unsigned int flags;
9792 {
9793 const char *kind;
9794
9795 /* Close the previous section. */
9796
9797 fputs ("\t.endp\n\n", asm_out_file);
9798
9799 /* Find out what kind of section we are opening. */
9800
9801 if (flags & SECTION_MAIN)
9802 fputs ("\t.start\tmain\n", asm_out_file);
9803
9804 if (flags & SECTION_CODE)
9805 kind = "code";
9806 else if (flags & SECTION_PUBLIC)
9807 kind = "common";
9808 else
9809 kind = "data";
9810
9811 if (current_section_align != 0)
9812 fprintf (asm_out_file, "\t.psect\t%s,%d,%s\n", name,
9813 current_section_align, kind);
9814 else
9815 fprintf (asm_out_file, "\t.psect\t%s,%s\n", name, kind);
9816 }
9817
9818 static void
9819 unicosmk_insert_attributes (decl, attr_ptr)
9820 tree decl;
9821 tree *attr_ptr ATTRIBUTE_UNUSED;
9822 {
9823 if (DECL_P (decl)
9824 && (TREE_PUBLIC (decl) || TREE_CODE (decl) == FUNCTION_DECL))
9825 unicosmk_unique_section (decl, 0);
9826 }
9827
9828 /* Output an alignment directive. We have to use the macro 'gcc@code@align'
9829 in code sections because .align fill unused space with zeroes. */
9830
9831 void
9832 unicosmk_output_align (file, align)
9833 FILE *file;
9834 int align;
9835 {
9836 if (inside_function)
9837 fprintf (file, "\tgcc@code@align\t%d\n", align);
9838 else
9839 fprintf (file, "\t.align\t%d\n", align);
9840 }
9841
9842 /* Add a case vector to the current function's list of deferred case
9843 vectors. Case vectors have to be put into a separate section because CAM
9844 does not allow data definitions in code sections. */
9845
9846 void
9847 unicosmk_defer_case_vector (lab, vec)
9848 rtx lab;
9849 rtx vec;
9850 {
9851 struct machine_function *machine = cfun->machine;
9852
9853 vec = gen_rtx_EXPR_LIST (VOIDmode, lab, vec);
9854 machine->addr_list = gen_rtx_EXPR_LIST (VOIDmode, vec,
9855 machine->addr_list);
9856 }
9857
9858 /* Output a case vector. */
9859
9860 static void
9861 unicosmk_output_addr_vec (file, vec)
9862 FILE *file;
9863 rtx vec;
9864 {
9865 rtx lab = XEXP (vec, 0);
9866 rtx body = XEXP (vec, 1);
9867 int vlen = XVECLEN (body, 0);
9868 int idx;
9869
9870 (*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (lab));
9871
9872 for (idx = 0; idx < vlen; idx++)
9873 {
9874 ASM_OUTPUT_ADDR_VEC_ELT
9875 (file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0)));
9876 }
9877 }
9878
9879 /* Output current function's deferred case vectors. */
9880
9881 static void
9882 unicosmk_output_deferred_case_vectors (file)
9883 FILE *file;
9884 {
9885 struct machine_function *machine = cfun->machine;
9886 rtx t;
9887
9888 if (machine->addr_list == NULL_RTX)
9889 return;
9890
9891 data_section ();
9892 for (t = machine->addr_list; t; t = XEXP (t, 1))
9893 unicosmk_output_addr_vec (file, XEXP (t, 0));
9894 }
9895
9896 /* Set up the dynamic subprogram information block (DSIB) and update the
9897 frame pointer register ($15) for subroutines which have a frame. If the
9898 subroutine doesn't have a frame, simply increment $15. */
9899
9900 static void
9901 unicosmk_gen_dsib (imaskP)
9902 unsigned long * imaskP;
9903 {
9904 if (alpha_procedure_type == PT_STACK)
9905 {
9906 const char *ssib_name;
9907 rtx mem;
9908
9909 /* Allocate 64 bytes for the DSIB. */
9910
9911 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
9912 GEN_INT (-64))));
9913 emit_insn (gen_blockage ());
9914
9915 /* Save the return address. */
9916
9917 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 56));
9918 set_mem_alias_set (mem, alpha_sr_alias_set);
9919 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
9920 (*imaskP) &= ~(1UL << REG_RA);
9921
9922 /* Save the old frame pointer. */
9923
9924 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 48));
9925 set_mem_alias_set (mem, alpha_sr_alias_set);
9926 FRP (emit_move_insn (mem, hard_frame_pointer_rtx));
9927 (*imaskP) &= ~(1UL << HARD_FRAME_POINTER_REGNUM);
9928
9929 emit_insn (gen_blockage ());
9930
9931 /* Store the SSIB pointer. */
9932
9933 ssib_name = ggc_strdup (unicosmk_ssib_name ());
9934 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 32));
9935 set_mem_alias_set (mem, alpha_sr_alias_set);
9936
9937 FRP (emit_move_insn (gen_rtx_REG (DImode, 5),
9938 gen_rtx_SYMBOL_REF (Pmode, ssib_name)));
9939 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, 5)));
9940
9941 /* Save the CIW index. */
9942
9943 mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 24));
9944 set_mem_alias_set (mem, alpha_sr_alias_set);
9945 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, 25)));
9946
9947 emit_insn (gen_blockage ());
9948
9949 /* Set the new frame pointer. */
9950
9951 FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
9952 stack_pointer_rtx, GEN_INT (64))));
9953
9954 }
9955 else
9956 {
9957 /* Increment the frame pointer register to indicate that we do not
9958 have a frame. */
9959
9960 FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
9961 hard_frame_pointer_rtx, GEN_INT (1))));
9962 }
9963 }
9964
9965 #define SSIB_PREFIX "__SSIB_"
9966 #define SSIB_PREFIX_LEN 7
9967
9968 /* Generate the name of the SSIB section for the current function. */
9969
9970 static const char *
9971 unicosmk_ssib_name ()
9972 {
9973 /* This is ok since CAM won't be able to deal with names longer than that
9974 anyway. */
9975
9976 static char name[256];
9977
9978 rtx x;
9979 const char *fnname;
9980 int len;
9981
9982 x = DECL_RTL (cfun->decl);
9983 if (GET_CODE (x) != MEM)
9984 abort ();
9985 x = XEXP (x, 0);
9986 if (GET_CODE (x) != SYMBOL_REF)
9987 abort ();
9988 fnname = default_name_encoding (XSTR (x, 0));
9989
9990 len = strlen (fnname);
9991 if (len + SSIB_PREFIX_LEN > 255)
9992 len = 255 - SSIB_PREFIX_LEN;
9993
9994 strcpy (name, SSIB_PREFIX);
9995 strncpy (name + SSIB_PREFIX_LEN, fnname, len);
9996 name[len + SSIB_PREFIX_LEN] = 0;
9997
9998 return name;
9999 }
10000
10001 /* Output the static subroutine information block for the current
10002 function. */
10003
10004 static void
10005 unicosmk_output_ssib (file, fnname)
10006 FILE *file;
10007 const char *fnname;
10008 {
10009 int len;
10010 int i;
10011 rtx x;
10012 rtx ciw;
10013 struct machine_function *machine = cfun->machine;
10014
10015 ssib_section ();
10016 fprintf (file, "\t.endp\n\n\t.psect\t%s%s,data\n", user_label_prefix,
10017 unicosmk_ssib_name ());
10018
10019 /* Some required stuff and the function name length. */
10020
10021 len = strlen (fnname);
10022 fprintf (file, "\t.quad\t^X20008%2.2X28\n", len);
10023
10024 /* Saved registers
10025 ??? We don't do that yet. */
10026
10027 fputs ("\t.quad\t0\n", file);
10028
10029 /* Function address. */
10030
10031 fputs ("\t.quad\t", file);
10032 assemble_name (file, fnname);
10033 putc ('\n', file);
10034
10035 fputs ("\t.quad\t0\n", file);
10036 fputs ("\t.quad\t0\n", file);
10037
10038 /* Function name.
10039 ??? We do it the same way Cray CC does it but this could be
10040 simplified. */
10041
10042 for( i = 0; i < len; i++ )
10043 fprintf (file, "\t.byte\t%d\n", (int)(fnname[i]));
10044 if( (len % 8) == 0 )
10045 fputs ("\t.quad\t0\n", file);
10046 else
10047 fprintf (file, "\t.bits\t%d : 0\n", (8 - (len % 8))*8);
10048
10049 /* All call information words used in the function. */
10050
10051 for (x = machine->first_ciw; x; x = XEXP (x, 1))
10052 {
10053 ciw = XEXP (x, 0);
10054 #if HOST_BITS_PER_WIDE_INT == 32
10055 fprintf (file, "\t.quad\t" HOST_WIDE_INT_PRINT_DOUBLE_HEX "\n",
10056 CONST_DOUBLE_HIGH (ciw), CONST_DOUBLE_LOW (ciw));
10057 #else
10058 fprintf (file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n", INTVAL (ciw));
10059 #endif
10060 }
10061 }
10062
10063 /* Add a call information word (CIW) to the list of the current function's
10064 CIWs and return its index.
10065
10066 X is a CONST_INT or CONST_DOUBLE representing the CIW. */
10067
10068 rtx
10069 unicosmk_add_call_info_word (x)
10070 rtx x;
10071 {
10072 rtx node;
10073 struct machine_function *machine = cfun->machine;
10074
10075 node = gen_rtx_EXPR_LIST (VOIDmode, x, NULL_RTX);
10076 if (machine->first_ciw == NULL_RTX)
10077 machine->first_ciw = node;
10078 else
10079 XEXP (machine->last_ciw, 1) = node;
10080
10081 machine->last_ciw = node;
10082 ++machine->ciw_count;
10083
10084 return GEN_INT (machine->ciw_count
10085 + strlen (current_function_name)/8 + 5);
10086 }
10087
10088 static char unicosmk_section_buf[100];
10089
10090 char *
10091 unicosmk_text_section ()
10092 {
10093 static int count = 0;
10094 sprintf (unicosmk_section_buf, "\t.endp\n\n\t.psect\tgcc@text___%d,code",
10095 count++);
10096 return unicosmk_section_buf;
10097 }
10098
10099 char *
10100 unicosmk_data_section ()
10101 {
10102 static int count = 1;
10103 sprintf (unicosmk_section_buf, "\t.endp\n\n\t.psect\tgcc@data___%d,data",
10104 count++);
10105 return unicosmk_section_buf;
10106 }
10107
10108 /* The Cray assembler doesn't accept extern declarations for symbols which
10109 are defined in the same file. We have to keep track of all global
10110 symbols which are referenced and/or defined in a source file and output
10111 extern declarations for those which are referenced but not defined at
10112 the end of file. */
10113
10114 /* List of identifiers for which an extern declaration might have to be
10115 emitted. */
10116 /* FIXME: needs to use GC, so it can be saved and restored for PCH. */
10117
10118 struct unicosmk_extern_list
10119 {
10120 struct unicosmk_extern_list *next;
10121 const char *name;
10122 };
10123
10124 static struct unicosmk_extern_list *unicosmk_extern_head = 0;
10125
10126 /* Output extern declarations which are required for every asm file. */
10127
10128 static void
10129 unicosmk_output_default_externs (file)
10130 FILE *file;
10131 {
10132 static const char *const externs[] =
10133 { "__T3E_MISMATCH" };
10134
10135 int i;
10136 int n;
10137
10138 n = ARRAY_SIZE (externs);
10139
10140 for (i = 0; i < n; i++)
10141 fprintf (file, "\t.extern\t%s\n", externs[i]);
10142 }
10143
10144 /* Output extern declarations for global symbols which are have been
10145 referenced but not defined. */
10146
10147 static void
10148 unicosmk_output_externs (file)
10149 FILE *file;
10150 {
10151 struct unicosmk_extern_list *p;
10152 const char *real_name;
10153 int len;
10154 tree name_tree;
10155
10156 len = strlen (user_label_prefix);
10157 for (p = unicosmk_extern_head; p != 0; p = p->next)
10158 {
10159 /* We have to strip the encoding and possibly remove user_label_prefix
10160 from the identifier in order to handle -fleading-underscore and
10161 explicit asm names correctly (cf. gcc.dg/asm-names-1.c). */
10162 real_name = default_strip_name_encoding (p->name);
10163 if (len && p->name[0] == '*'
10164 && !memcmp (real_name, user_label_prefix, len))
10165 real_name += len;
10166
10167 name_tree = get_identifier (real_name);
10168 if (! TREE_ASM_WRITTEN (name_tree))
10169 {
10170 TREE_ASM_WRITTEN (name_tree) = 1;
10171 fputs ("\t.extern\t", file);
10172 assemble_name (file, p->name);
10173 putc ('\n', file);
10174 }
10175 }
10176 }
10177
10178 /* Record an extern. */
10179
10180 void
10181 unicosmk_add_extern (name)
10182 const char *name;
10183 {
10184 struct unicosmk_extern_list *p;
10185
10186 p = (struct unicosmk_extern_list *)
10187 xmalloc (sizeof (struct unicosmk_extern_list));
10188 p->next = unicosmk_extern_head;
10189 p->name = name;
10190 unicosmk_extern_head = p;
10191 }
10192
10193 /* The Cray assembler generates incorrect code if identifiers which
10194 conflict with register names are used as instruction operands. We have
10195 to replace such identifiers with DEX expressions. */
10196
10197 /* Structure to collect identifiers which have been replaced by DEX
10198 expressions. */
10199 /* FIXME: needs to use GC, so it can be saved and restored for PCH. */
10200
10201 struct unicosmk_dex {
10202 struct unicosmk_dex *next;
10203 const char *name;
10204 };
10205
10206 /* List of identifiers which have been replaced by DEX expressions. The DEX
10207 number is determined by the position in the list. */
10208
10209 static struct unicosmk_dex *unicosmk_dex_list = NULL;
10210
10211 /* The number of elements in the DEX list. */
10212
10213 static int unicosmk_dex_count = 0;
10214
10215 /* Check if NAME must be replaced by a DEX expression. */
10216
10217 static int
10218 unicosmk_special_name (name)
10219 const char *name;
10220 {
10221 if (name[0] == '*')
10222 ++name;
10223
10224 if (name[0] == '$')
10225 ++name;
10226
10227 if (name[0] != 'r' && name[0] != 'f' && name[0] != 'R' && name[0] != 'F')
10228 return 0;
10229
10230 switch (name[1])
10231 {
10232 case '1': case '2':
10233 return (name[2] == '\0' || (ISDIGIT (name[2]) && name[3] == '\0'));
10234
10235 case '3':
10236 return (name[2] == '\0'
10237 || ((name[2] == '0' || name[2] == '1') && name[3] == '\0'));
10238
10239 default:
10240 return (ISDIGIT (name[1]) && name[2] == '\0');
10241 }
10242 }
10243
10244 /* Return the DEX number if X must be replaced by a DEX expression and 0
10245 otherwise. */
10246
10247 static int
10248 unicosmk_need_dex (x)
10249 rtx x;
10250 {
10251 struct unicosmk_dex *dex;
10252 const char *name;
10253 int i;
10254
10255 if (GET_CODE (x) != SYMBOL_REF)
10256 return 0;
10257
10258 name = XSTR (x,0);
10259 if (! unicosmk_special_name (name))
10260 return 0;
10261
10262 i = unicosmk_dex_count;
10263 for (dex = unicosmk_dex_list; dex; dex = dex->next)
10264 {
10265 if (! strcmp (name, dex->name))
10266 return i;
10267 --i;
10268 }
10269
10270 dex = (struct unicosmk_dex *) xmalloc (sizeof (struct unicosmk_dex));
10271 dex->name = name;
10272 dex->next = unicosmk_dex_list;
10273 unicosmk_dex_list = dex;
10274
10275 ++unicosmk_dex_count;
10276 return unicosmk_dex_count;
10277 }
10278
10279 /* Output the DEX definitions for this file. */
10280
10281 static void
10282 unicosmk_output_dex (file)
10283 FILE *file;
10284 {
10285 struct unicosmk_dex *dex;
10286 int i;
10287
10288 if (unicosmk_dex_list == NULL)
10289 return;
10290
10291 fprintf (file, "\t.dexstart\n");
10292
10293 i = unicosmk_dex_count;
10294 for (dex = unicosmk_dex_list; dex; dex = dex->next)
10295 {
10296 fprintf (file, "\tDEX (%d) = ", i);
10297 assemble_name (file, dex->name);
10298 putc ('\n', file);
10299 --i;
10300 }
10301
10302 fprintf (file, "\t.dexend\n");
10303 }
10304
10305 #else
10306
10307 static void
10308 unicosmk_output_deferred_case_vectors (file)
10309 FILE *file ATTRIBUTE_UNUSED;
10310 {}
10311
10312 static void
10313 unicosmk_gen_dsib (imaskP)
10314 unsigned long * imaskP ATTRIBUTE_UNUSED;
10315 {}
10316
10317 static void
10318 unicosmk_output_ssib (file, fnname)
10319 FILE * file ATTRIBUTE_UNUSED;
10320 const char * fnname ATTRIBUTE_UNUSED;
10321 {}
10322
10323 rtx
10324 unicosmk_add_call_info_word (x)
10325 rtx x ATTRIBUTE_UNUSED;
10326 {
10327 return NULL_RTX;
10328 }
10329
10330 static int
10331 unicosmk_need_dex (x)
10332 rtx x ATTRIBUTE_UNUSED;
10333 {
10334 return 0;
10335 }
10336
10337 #endif /* TARGET_ABI_UNICOSMK */
10338
10339 #include "gt-alpha.h"
10340