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