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