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