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