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