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