1/* Subroutines used for code generation on IBM RS/6000. 2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 4 Free Software Foundation, Inc. 5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) 6 7 This file is part of GCC. 8 9 GCC is free software; you can redistribute it and/or modify it 10 under the terms of the GNU General Public License as published 11 by the Free Software Foundation; either version 3, or (at your 12 option) any later version. 13 14 GCC is distributed in the hope that it will be useful, but WITHOUT 15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 17 License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with GCC; see the file COPYING3. If not see 21 <http://www.gnu.org/licenses/>. */ 22 23#include "config.h" 24#include "system.h" 25#include "coretypes.h" 26#include "tm.h" 27#include "rtl.h" 28#include "regs.h" 29#include "hard-reg-set.h" 30#include "real.h" 31#include "insn-config.h" 32#include "conditions.h" 33#include "insn-attr.h" 34#include "flags.h" 35#include "recog.h" 36#include "obstack.h" 37#include "tree.h" 38#include "expr.h" 39#include "optabs.h" 40#include "except.h" 41#include "function.h" 42#include "output.h" 43#include "basic-block.h" 44#include "integrate.h" 45#include "toplev.h" 46#include "ggc.h" 47#include "hashtab.h" 48#include "tm_p.h" 49#include "target.h" 50#include "target-def.h" 51#include "langhooks.h" 52#include "reload.h" 53#include "cfglayout.h" 54#include "sched-int.h" 55#include "gimple.h" 56#include "tree-flow.h" 57#include "intl.h" 58#include "params.h" 59#include "tm-constrs.h" 60#if TARGET_XCOFF 61#include "xcoffout.h" /* get declarations of xcoff_*_section_name */ 62#endif 63#if TARGET_MACHO 64#include "gstab.h" /* for N_SLINE */ 65#endif 66 67#ifndef TARGET_NO_PROTOTYPE 68#define TARGET_NO_PROTOTYPE 0 69#endif 70 71#define min(A,B) ((A) < (B) ? (A) : (B)) 72#define max(A,B) ((A) > (B) ? (A) : (B)) 73 74/* Structure used to define the rs6000 stack */ 75typedef struct rs6000_stack { 76 int first_gp_reg_save; /* first callee saved GP register used */ 77 int first_fp_reg_save; /* first callee saved FP register used */ 78 int first_altivec_reg_save; /* first callee saved AltiVec register used */ 79 int lr_save_p; /* true if the link reg needs to be saved */ 80 int cr_save_p; /* true if the CR reg needs to be saved */ 81 unsigned int vrsave_mask; /* mask of vec registers to save */ 82 int push_p; /* true if we need to allocate stack space */ 83 int calls_p; /* true if the function makes any calls */ 84 int world_save_p; /* true if we're saving *everything*: 85 r13-r31, cr, f14-f31, vrsave, v20-v31 */ 86 enum rs6000_abi abi; /* which ABI to use */ 87 int gp_save_offset; /* offset to save GP regs from initial SP */ 88 int fp_save_offset; /* offset to save FP regs from initial SP */ 89 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */ 90 int lr_save_offset; /* offset to save LR from initial SP */ 91 int cr_save_offset; /* offset to save CR from initial SP */ 92 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */ 93 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */ 94 int varargs_save_offset; /* offset to save the varargs registers */ 95 int ehrd_offset; /* offset to EH return data */ 96 int reg_size; /* register size (4 or 8) */ 97 HOST_WIDE_INT vars_size; /* variable save area size */ 98 int parm_size; /* outgoing parameter size */ 99 int save_size; /* save area size */ 100 int fixed_size; /* fixed size of stack frame */ 101 int gp_size; /* size of saved GP registers */ 102 int fp_size; /* size of saved FP registers */ 103 int altivec_size; /* size of saved AltiVec registers */ 104 int cr_size; /* size to hold CR if not in save_size */ 105 int vrsave_size; /* size to hold VRSAVE if not in save_size */ 106 int altivec_padding_size; /* size of altivec alignment padding if 107 not in save_size */ 108 int spe_gp_size; /* size of 64-bit GPR save size for SPE */ 109 int spe_padding_size; 110 HOST_WIDE_INT total_size; /* total bytes allocated for stack */ 111 int spe_64bit_regs_used; 112} rs6000_stack_t; 113 114/* A C structure for machine-specific, per-function data. 115 This is added to the cfun structure. */ 116typedef struct GTY(()) machine_function 117{ 118 /* Some local-dynamic symbol. */ 119 const char *some_ld_name; 120 /* Whether the instruction chain has been scanned already. */ 121 int insn_chain_scanned_p; 122 /* Flags if __builtin_return_address (n) with n >= 1 was used. */ 123 int ra_needs_full_frame; 124 /* Flags if __builtin_return_address (0) was used. */ 125 int ra_need_lr; 126 /* Cache lr_save_p after expansion of builtin_eh_return. */ 127 int lr_save_state; 128 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4 129 varargs save area. */ 130 HOST_WIDE_INT varargs_save_offset; 131 /* Temporary stack slot to use for SDmode copies. This slot is 132 64-bits wide and is allocated early enough so that the offset 133 does not overflow the 16-bit load/store offset field. */ 134 rtx sdmode_stack_slot; 135} machine_function; 136 137/* Target cpu type */ 138 139enum processor_type rs6000_cpu; 140struct rs6000_cpu_select rs6000_select[3] = 141{ 142 /* switch name, tune arch */ 143 { (const char *)0, "--with-cpu=", 1, 1 }, 144 { (const char *)0, "-mcpu=", 1, 1 }, 145 { (const char *)0, "-mtune=", 1, 0 }, 146}; 147 148/* Always emit branch hint bits. */ 149static GTY(()) bool rs6000_always_hint; 150 151/* Schedule instructions for group formation. */ 152static GTY(()) bool rs6000_sched_groups; 153 154/* Align branch targets. */ 155static GTY(()) bool rs6000_align_branch_targets; 156 157/* Support for -msched-costly-dep option. */ 158const char *rs6000_sched_costly_dep_str; 159enum rs6000_dependence_cost rs6000_sched_costly_dep; 160 161/* Support for -minsert-sched-nops option. */ 162const char *rs6000_sched_insert_nops_str; 163enum rs6000_nop_insertion rs6000_sched_insert_nops; 164 165/* Support targetm.vectorize.builtin_mask_for_load. */ 166static GTY(()) tree altivec_builtin_mask_for_load; 167 168/* Size of long double. */ 169int rs6000_long_double_type_size; 170 171/* IEEE quad extended precision long double. */ 172int rs6000_ieeequad; 173 174/* Nonzero to use AltiVec ABI. */ 175int rs6000_altivec_abi; 176 177/* Nonzero if we want SPE SIMD instructions. */ 178int rs6000_spe; 179 180/* Nonzero if we want SPE ABI extensions. */ 181int rs6000_spe_abi; 182 183/* Nonzero if floating point operations are done in the GPRs. */ 184int rs6000_float_gprs = 0; 185 186/* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */ 187int rs6000_darwin64_abi; 188 189/* Set to nonzero once AIX common-mode calls have been defined. */ 190static GTY(()) int common_mode_defined; 191 192/* Label number of label created for -mrelocatable, to call to so we can 193 get the address of the GOT section */ 194static int rs6000_pic_labelno; 195 196#ifdef USING_ELFOS_H 197/* Which abi to adhere to */ 198const char *rs6000_abi_name; 199 200/* Semantics of the small data area */ 201enum rs6000_sdata_type rs6000_sdata = SDATA_DATA; 202 203/* Which small data model to use */ 204const char *rs6000_sdata_name = (char *)0; 205 206/* Counter for labels which are to be placed in .fixup. */ 207int fixuplabelno = 0; 208#endif 209 210/* Bit size of immediate TLS offsets and string from which it is decoded. */ 211int rs6000_tls_size = 32; 212const char *rs6000_tls_size_string; 213 214/* ABI enumeration available for subtarget to use. */ 215enum rs6000_abi rs6000_current_abi; 216 217/* Whether to use variant of AIX ABI for PowerPC64 Linux. */ 218int dot_symbols; 219 220/* Debug flags */ 221const char *rs6000_debug_name; 222int rs6000_debug_stack; /* debug stack applications */ 223int rs6000_debug_arg; /* debug argument handling */ 224int rs6000_debug_reg; /* debug register classes */ 225int rs6000_debug_addr; /* debug memory addressing */ 226int rs6000_debug_cost; /* debug rtx_costs */ 227 228/* Specify the machine mode that pointers have. After generation of rtl, the 229 compiler makes no further distinction between pointers and any other objects 230 of this machine mode. The type is unsigned since not all things that 231 include rs6000.h also include machmode.h. */ 232unsigned rs6000_pmode; 233 234/* Width in bits of a pointer. */ 235unsigned rs6000_pointer_size; 236 237 238/* Value is TRUE if register/mode pair is acceptable. */ 239bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER]; 240 241/* Maximum number of registers needed for a given register class and mode. */ 242unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES]; 243 244/* How many registers are needed for a given register and mode. */ 245unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER]; 246 247/* Map register number to register class. */ 248enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER]; 249 250/* Reload functions based on the type and the vector unit. */ 251static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2]; 252 253/* Built in types. */ 254tree rs6000_builtin_types[RS6000_BTI_MAX]; 255tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT]; 256 257const char *rs6000_traceback_name; 258static enum { 259 traceback_default = 0, 260 traceback_none, 261 traceback_part, 262 traceback_full 263} rs6000_traceback; 264 265/* Flag to say the TOC is initialized */ 266int toc_initialized; 267char toc_label_name[10]; 268 269/* Cached value of rs6000_variable_issue. This is cached in 270 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */ 271static short cached_can_issue_more; 272 273static GTY(()) section *read_only_data_section; 274static GTY(()) section *private_data_section; 275static GTY(()) section *read_only_private_data_section; 276static GTY(()) section *sdata2_section; 277static GTY(()) section *toc_section; 278 279/* Control alignment for fields within structures. */ 280/* String from -malign-XXXXX. */ 281int rs6000_alignment_flags; 282 283/* True for any options that were explicitly set. */ 284static struct { 285 bool aix_struct_ret; /* True if -maix-struct-ret was used. */ 286 bool alignment; /* True if -malign- was used. */ 287 bool spe_abi; /* True if -mabi=spe/no-spe was used. */ 288 bool altivec_abi; /* True if -mabi=altivec/no-altivec used. */ 289 bool spe; /* True if -mspe= was used. */ 290 bool float_gprs; /* True if -mfloat-gprs= was used. */ 291 bool long_double; /* True if -mlong-double- was used. */ 292 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */ 293 bool vrsave; /* True if -mvrsave was used. */ 294} rs6000_explicit_options; 295 296struct builtin_description 297{ 298 /* mask is not const because we're going to alter it below. This 299 nonsense will go away when we rewrite the -march infrastructure 300 to give us more target flag bits. */ 301 unsigned int mask; 302 const enum insn_code icode; 303 const char *const name; 304 const enum rs6000_builtins code; 305}; 306 307/* Describe the vector unit used for modes. */ 308enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES]; 309enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES]; 310 311/* Register classes for various constraints that are based on the target 312 switches. */ 313enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX]; 314 315/* Describe the alignment of a vector. */ 316int rs6000_vector_align[NUM_MACHINE_MODES]; 317 318/* Map selected modes to types for builtins. */ 319static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2]; 320 321/* Target cpu costs. */ 322 323struct processor_costs { 324 const int mulsi; /* cost of SImode multiplication. */ 325 const int mulsi_const; /* cost of SImode multiplication by constant. */ 326 const int mulsi_const9; /* cost of SImode mult by short constant. */ 327 const int muldi; /* cost of DImode multiplication. */ 328 const int divsi; /* cost of SImode division. */ 329 const int divdi; /* cost of DImode division. */ 330 const int fp; /* cost of simple SFmode and DFmode insns. */ 331 const int dmul; /* cost of DFmode multiplication (and fmadd). */ 332 const int sdiv; /* cost of SFmode division (fdivs). */ 333 const int ddiv; /* cost of DFmode division (fdiv). */ 334 const int cache_line_size; /* cache line size in bytes. */ 335 const int l1_cache_size; /* size of l1 cache, in kilobytes. */ 336 const int l2_cache_size; /* size of l2 cache, in kilobytes. */ 337 const int simultaneous_prefetches; /* number of parallel prefetch 338 operations. */ 339}; 340 341const struct processor_costs *rs6000_cost; 342 343/* Processor costs (relative to an add) */ 344 345/* Instruction size costs on 32bit processors. */ 346static const 347struct processor_costs size32_cost = { 348 COSTS_N_INSNS (1), /* mulsi */ 349 COSTS_N_INSNS (1), /* mulsi_const */ 350 COSTS_N_INSNS (1), /* mulsi_const9 */ 351 COSTS_N_INSNS (1), /* muldi */ 352 COSTS_N_INSNS (1), /* divsi */ 353 COSTS_N_INSNS (1), /* divdi */ 354 COSTS_N_INSNS (1), /* fp */ 355 COSTS_N_INSNS (1), /* dmul */ 356 COSTS_N_INSNS (1), /* sdiv */ 357 COSTS_N_INSNS (1), /* ddiv */ 358 32, 359 0, 360 0, 361 0, 362}; 363 364/* Instruction size costs on 64bit processors. */ 365static const 366struct processor_costs size64_cost = { 367 COSTS_N_INSNS (1), /* mulsi */ 368 COSTS_N_INSNS (1), /* mulsi_const */ 369 COSTS_N_INSNS (1), /* mulsi_const9 */ 370 COSTS_N_INSNS (1), /* muldi */ 371 COSTS_N_INSNS (1), /* divsi */ 372 COSTS_N_INSNS (1), /* divdi */ 373 COSTS_N_INSNS (1), /* fp */ 374 COSTS_N_INSNS (1), /* dmul */ 375 COSTS_N_INSNS (1), /* sdiv */ 376 COSTS_N_INSNS (1), /* ddiv */ 377 128, 378 0, 379 0, 380 0, 381}; 382 383/* Instruction costs on RIOS1 processors. */ 384static const 385struct processor_costs rios1_cost = { 386 COSTS_N_INSNS (5), /* mulsi */ 387 COSTS_N_INSNS (4), /* mulsi_const */ 388 COSTS_N_INSNS (3), /* mulsi_const9 */ 389 COSTS_N_INSNS (5), /* muldi */ 390 COSTS_N_INSNS (19), /* divsi */ 391 COSTS_N_INSNS (19), /* divdi */ 392 COSTS_N_INSNS (2), /* fp */ 393 COSTS_N_INSNS (2), /* dmul */ 394 COSTS_N_INSNS (19), /* sdiv */ 395 COSTS_N_INSNS (19), /* ddiv */ 396 128, /* cache line size */ 397 64, /* l1 cache */ 398 512, /* l2 cache */ 399 0, /* streams */ 400}; 401 402/* Instruction costs on RIOS2 processors. */ 403static const 404struct processor_costs rios2_cost = { 405 COSTS_N_INSNS (2), /* mulsi */ 406 COSTS_N_INSNS (2), /* mulsi_const */ 407 COSTS_N_INSNS (2), /* mulsi_const9 */ 408 COSTS_N_INSNS (2), /* muldi */ 409 COSTS_N_INSNS (13), /* divsi */ 410 COSTS_N_INSNS (13), /* divdi */ 411 COSTS_N_INSNS (2), /* fp */ 412 COSTS_N_INSNS (2), /* dmul */ 413 COSTS_N_INSNS (17), /* sdiv */ 414 COSTS_N_INSNS (17), /* ddiv */ 415 256, /* cache line size */ 416 256, /* l1 cache */ 417 1024, /* l2 cache */ 418 0, /* streams */ 419}; 420 421/* Instruction costs on RS64A processors. */ 422static const 423struct processor_costs rs64a_cost = { 424 COSTS_N_INSNS (20), /* mulsi */ 425 COSTS_N_INSNS (12), /* mulsi_const */ 426 COSTS_N_INSNS (8), /* mulsi_const9 */ 427 COSTS_N_INSNS (34), /* muldi */ 428 COSTS_N_INSNS (65), /* divsi */ 429 COSTS_N_INSNS (67), /* divdi */ 430 COSTS_N_INSNS (4), /* fp */ 431 COSTS_N_INSNS (4), /* dmul */ 432 COSTS_N_INSNS (31), /* sdiv */ 433 COSTS_N_INSNS (31), /* ddiv */ 434 128, /* cache line size */ 435 128, /* l1 cache */ 436 2048, /* l2 cache */ 437 1, /* streams */ 438}; 439 440/* Instruction costs on MPCCORE processors. */ 441static const 442struct processor_costs mpccore_cost = { 443 COSTS_N_INSNS (2), /* mulsi */ 444 COSTS_N_INSNS (2), /* mulsi_const */ 445 COSTS_N_INSNS (2), /* mulsi_const9 */ 446 COSTS_N_INSNS (2), /* muldi */ 447 COSTS_N_INSNS (6), /* divsi */ 448 COSTS_N_INSNS (6), /* divdi */ 449 COSTS_N_INSNS (4), /* fp */ 450 COSTS_N_INSNS (5), /* dmul */ 451 COSTS_N_INSNS (10), /* sdiv */ 452 COSTS_N_INSNS (17), /* ddiv */ 453 32, /* cache line size */ 454 4, /* l1 cache */ 455 16, /* l2 cache */ 456 1, /* streams */ 457}; 458 459/* Instruction costs on PPC403 processors. */ 460static const 461struct processor_costs ppc403_cost = { 462 COSTS_N_INSNS (4), /* mulsi */ 463 COSTS_N_INSNS (4), /* mulsi_const */ 464 COSTS_N_INSNS (4), /* mulsi_const9 */ 465 COSTS_N_INSNS (4), /* muldi */ 466 COSTS_N_INSNS (33), /* divsi */ 467 COSTS_N_INSNS (33), /* divdi */ 468 COSTS_N_INSNS (11), /* fp */ 469 COSTS_N_INSNS (11), /* dmul */ 470 COSTS_N_INSNS (11), /* sdiv */ 471 COSTS_N_INSNS (11), /* ddiv */ 472 32, /* cache line size */ 473 4, /* l1 cache */ 474 16, /* l2 cache */ 475 1, /* streams */ 476}; 477 478/* Instruction costs on PPC405 processors. */ 479static const 480struct processor_costs ppc405_cost = { 481 COSTS_N_INSNS (5), /* mulsi */ 482 COSTS_N_INSNS (4), /* mulsi_const */ 483 COSTS_N_INSNS (3), /* mulsi_const9 */ 484 COSTS_N_INSNS (5), /* muldi */ 485 COSTS_N_INSNS (35), /* divsi */ 486 COSTS_N_INSNS (35), /* divdi */ 487 COSTS_N_INSNS (11), /* fp */ 488 COSTS_N_INSNS (11), /* dmul */ 489 COSTS_N_INSNS (11), /* sdiv */ 490 COSTS_N_INSNS (11), /* ddiv */ 491 32, /* cache line size */ 492 16, /* l1 cache */ 493 128, /* l2 cache */ 494 1, /* streams */ 495}; 496 497/* Instruction costs on PPC440 processors. */ 498static const 499struct processor_costs ppc440_cost = { 500 COSTS_N_INSNS (3), /* mulsi */ 501 COSTS_N_INSNS (2), /* mulsi_const */ 502 COSTS_N_INSNS (2), /* mulsi_const9 */ 503 COSTS_N_INSNS (3), /* muldi */ 504 COSTS_N_INSNS (34), /* divsi */ 505 COSTS_N_INSNS (34), /* divdi */ 506 COSTS_N_INSNS (5), /* fp */ 507 COSTS_N_INSNS (5), /* dmul */ 508 COSTS_N_INSNS (19), /* sdiv */ 509 COSTS_N_INSNS (33), /* ddiv */ 510 32, /* cache line size */ 511 32, /* l1 cache */ 512 256, /* l2 cache */ 513 1, /* streams */ 514}; 515 516/* Instruction costs on PPC476 processors. */ 517static const 518struct processor_costs ppc476_cost = { 519 COSTS_N_INSNS (4), /* mulsi */ 520 COSTS_N_INSNS (4), /* mulsi_const */ 521 COSTS_N_INSNS (4), /* mulsi_const9 */ 522 COSTS_N_INSNS (4), /* muldi */ 523 COSTS_N_INSNS (11), /* divsi */ 524 COSTS_N_INSNS (11), /* divdi */ 525 COSTS_N_INSNS (6), /* fp */ 526 COSTS_N_INSNS (6), /* dmul */ 527 COSTS_N_INSNS (19), /* sdiv */ 528 COSTS_N_INSNS (33), /* ddiv */ 529 32, /* l1 cache line size */ 530 32, /* l1 cache */ 531 512, /* l2 cache */ 532 1, /* streams */ 533}; 534 535/* Instruction costs on PPC601 processors. */ 536static const 537struct processor_costs ppc601_cost = { 538 COSTS_N_INSNS (5), /* mulsi */ 539 COSTS_N_INSNS (5), /* mulsi_const */ 540 COSTS_N_INSNS (5), /* mulsi_const9 */ 541 COSTS_N_INSNS (5), /* muldi */ 542 COSTS_N_INSNS (36), /* divsi */ 543 COSTS_N_INSNS (36), /* divdi */ 544 COSTS_N_INSNS (4), /* fp */ 545 COSTS_N_INSNS (5), /* dmul */ 546 COSTS_N_INSNS (17), /* sdiv */ 547 COSTS_N_INSNS (31), /* ddiv */ 548 32, /* cache line size */ 549 32, /* l1 cache */ 550 256, /* l2 cache */ 551 1, /* streams */ 552}; 553 554/* Instruction costs on PPC603 processors. */ 555static const 556struct processor_costs ppc603_cost = { 557 COSTS_N_INSNS (5), /* mulsi */ 558 COSTS_N_INSNS (3), /* mulsi_const */ 559 COSTS_N_INSNS (2), /* mulsi_const9 */ 560 COSTS_N_INSNS (5), /* muldi */ 561 COSTS_N_INSNS (37), /* divsi */ 562 COSTS_N_INSNS (37), /* divdi */ 563 COSTS_N_INSNS (3), /* fp */ 564 COSTS_N_INSNS (4), /* dmul */ 565 COSTS_N_INSNS (18), /* sdiv */ 566 COSTS_N_INSNS (33), /* ddiv */ 567 32, /* cache line size */ 568 8, /* l1 cache */ 569 64, /* l2 cache */ 570 1, /* streams */ 571}; 572 573/* Instruction costs on PPC604 processors. */ 574static const 575struct processor_costs ppc604_cost = { 576 COSTS_N_INSNS (4), /* mulsi */ 577 COSTS_N_INSNS (4), /* mulsi_const */ 578 COSTS_N_INSNS (4), /* mulsi_const9 */ 579 COSTS_N_INSNS (4), /* muldi */ 580 COSTS_N_INSNS (20), /* divsi */ 581 COSTS_N_INSNS (20), /* divdi */ 582 COSTS_N_INSNS (3), /* fp */ 583 COSTS_N_INSNS (3), /* dmul */ 584 COSTS_N_INSNS (18), /* sdiv */ 585 COSTS_N_INSNS (32), /* ddiv */ 586 32, /* cache line size */ 587 16, /* l1 cache */ 588 512, /* l2 cache */ 589 1, /* streams */ 590}; 591 592/* Instruction costs on PPC604e processors. */ 593static const 594struct processor_costs ppc604e_cost = { 595 COSTS_N_INSNS (2), /* mulsi */ 596 COSTS_N_INSNS (2), /* mulsi_const */ 597 COSTS_N_INSNS (2), /* mulsi_const9 */ 598 COSTS_N_INSNS (2), /* muldi */ 599 COSTS_N_INSNS (20), /* divsi */ 600 COSTS_N_INSNS (20), /* divdi */ 601 COSTS_N_INSNS (3), /* fp */ 602 COSTS_N_INSNS (3), /* dmul */ 603 COSTS_N_INSNS (18), /* sdiv */ 604 COSTS_N_INSNS (32), /* ddiv */ 605 32, /* cache line size */ 606 32, /* l1 cache */ 607 1024, /* l2 cache */ 608 1, /* streams */ 609}; 610 611/* Instruction costs on PPC620 processors. */ 612static const 613struct processor_costs ppc620_cost = { 614 COSTS_N_INSNS (5), /* mulsi */ 615 COSTS_N_INSNS (4), /* mulsi_const */ 616 COSTS_N_INSNS (3), /* mulsi_const9 */ 617 COSTS_N_INSNS (7), /* muldi */ 618 COSTS_N_INSNS (21), /* divsi */ 619 COSTS_N_INSNS (37), /* divdi */ 620 COSTS_N_INSNS (3), /* fp */ 621 COSTS_N_INSNS (3), /* dmul */ 622 COSTS_N_INSNS (18), /* sdiv */ 623 COSTS_N_INSNS (32), /* ddiv */ 624 128, /* cache line size */ 625 32, /* l1 cache */ 626 1024, /* l2 cache */ 627 1, /* streams */ 628}; 629 630/* Instruction costs on PPC630 processors. */ 631static const 632struct processor_costs ppc630_cost = { 633 COSTS_N_INSNS (5), /* mulsi */ 634 COSTS_N_INSNS (4), /* mulsi_const */ 635 COSTS_N_INSNS (3), /* mulsi_const9 */ 636 COSTS_N_INSNS (7), /* muldi */ 637 COSTS_N_INSNS (21), /* divsi */ 638 COSTS_N_INSNS (37), /* divdi */ 639 COSTS_N_INSNS (3), /* fp */ 640 COSTS_N_INSNS (3), /* dmul */ 641 COSTS_N_INSNS (17), /* sdiv */ 642 COSTS_N_INSNS (21), /* ddiv */ 643 128, /* cache line size */ 644 64, /* l1 cache */ 645 1024, /* l2 cache */ 646 1, /* streams */ 647}; 648 649/* Instruction costs on Cell processor. */ 650/* COSTS_N_INSNS (1) ~ one add. */ 651static const 652struct processor_costs ppccell_cost = { 653 COSTS_N_INSNS (9/2)+2, /* mulsi */ 654 COSTS_N_INSNS (6/2), /* mulsi_const */ 655 COSTS_N_INSNS (6/2), /* mulsi_const9 */ 656 COSTS_N_INSNS (15/2)+2, /* muldi */ 657 COSTS_N_INSNS (38/2), /* divsi */ 658 COSTS_N_INSNS (70/2), /* divdi */ 659 COSTS_N_INSNS (10/2), /* fp */ 660 COSTS_N_INSNS (10/2), /* dmul */ 661 COSTS_N_INSNS (74/2), /* sdiv */ 662 COSTS_N_INSNS (74/2), /* ddiv */ 663 128, /* cache line size */ 664 32, /* l1 cache */ 665 512, /* l2 cache */ 666 6, /* streams */ 667}; 668 669/* Instruction costs on PPC750 and PPC7400 processors. */ 670static const 671struct processor_costs ppc750_cost = { 672 COSTS_N_INSNS (5), /* mulsi */ 673 COSTS_N_INSNS (3), /* mulsi_const */ 674 COSTS_N_INSNS (2), /* mulsi_const9 */ 675 COSTS_N_INSNS (5), /* muldi */ 676 COSTS_N_INSNS (17), /* divsi */ 677 COSTS_N_INSNS (17), /* divdi */ 678 COSTS_N_INSNS (3), /* fp */ 679 COSTS_N_INSNS (3), /* dmul */ 680 COSTS_N_INSNS (17), /* sdiv */ 681 COSTS_N_INSNS (31), /* ddiv */ 682 32, /* cache line size */ 683 32, /* l1 cache */ 684 512, /* l2 cache */ 685 1, /* streams */ 686}; 687 688/* Instruction costs on PPC7450 processors. */ 689static const 690struct processor_costs ppc7450_cost = { 691 COSTS_N_INSNS (4), /* mulsi */ 692 COSTS_N_INSNS (3), /* mulsi_const */ 693 COSTS_N_INSNS (3), /* mulsi_const9 */ 694 COSTS_N_INSNS (4), /* muldi */ 695 COSTS_N_INSNS (23), /* divsi */ 696 COSTS_N_INSNS (23), /* divdi */ 697 COSTS_N_INSNS (5), /* fp */ 698 COSTS_N_INSNS (5), /* dmul */ 699 COSTS_N_INSNS (21), /* sdiv */ 700 COSTS_N_INSNS (35), /* ddiv */ 701 32, /* cache line size */ 702 32, /* l1 cache */ 703 1024, /* l2 cache */ 704 1, /* streams */ 705}; 706 707/* Instruction costs on PPC8540 processors. */ 708static const 709struct processor_costs ppc8540_cost = { 710 COSTS_N_INSNS (4), /* mulsi */ 711 COSTS_N_INSNS (4), /* mulsi_const */ 712 COSTS_N_INSNS (4), /* mulsi_const9 */ 713 COSTS_N_INSNS (4), /* muldi */ 714 COSTS_N_INSNS (19), /* divsi */ 715 COSTS_N_INSNS (19), /* divdi */ 716 COSTS_N_INSNS (4), /* fp */ 717 COSTS_N_INSNS (4), /* dmul */ 718 COSTS_N_INSNS (29), /* sdiv */ 719 COSTS_N_INSNS (29), /* ddiv */ 720 32, /* cache line size */ 721 32, /* l1 cache */ 722 256, /* l2 cache */ 723 1, /* prefetch streams /*/ 724}; 725 726/* Instruction costs on E300C2 and E300C3 cores. */ 727static const 728struct processor_costs ppce300c2c3_cost = { 729 COSTS_N_INSNS (4), /* mulsi */ 730 COSTS_N_INSNS (4), /* mulsi_const */ 731 COSTS_N_INSNS (4), /* mulsi_const9 */ 732 COSTS_N_INSNS (4), /* muldi */ 733 COSTS_N_INSNS (19), /* divsi */ 734 COSTS_N_INSNS (19), /* divdi */ 735 COSTS_N_INSNS (3), /* fp */ 736 COSTS_N_INSNS (4), /* dmul */ 737 COSTS_N_INSNS (18), /* sdiv */ 738 COSTS_N_INSNS (33), /* ddiv */ 739 32, 740 16, /* l1 cache */ 741 16, /* l2 cache */ 742 1, /* prefetch streams /*/ 743}; 744 745/* Instruction costs on PPCE500MC processors. */ 746static const 747struct processor_costs ppce500mc_cost = { 748 COSTS_N_INSNS (4), /* mulsi */ 749 COSTS_N_INSNS (4), /* mulsi_const */ 750 COSTS_N_INSNS (4), /* mulsi_const9 */ 751 COSTS_N_INSNS (4), /* muldi */ 752 COSTS_N_INSNS (14), /* divsi */ 753 COSTS_N_INSNS (14), /* divdi */ 754 COSTS_N_INSNS (8), /* fp */ 755 COSTS_N_INSNS (10), /* dmul */ 756 COSTS_N_INSNS (36), /* sdiv */ 757 COSTS_N_INSNS (66), /* ddiv */ 758 64, /* cache line size */ 759 32, /* l1 cache */ 760 128, /* l2 cache */ 761 1, /* prefetch streams /*/ 762}; 763 764/* Instruction costs on PPCE500MC64 processors. */ 765static const 766struct processor_costs ppce500mc64_cost = { 767 COSTS_N_INSNS (4), /* mulsi */ 768 COSTS_N_INSNS (4), /* mulsi_const */ 769 COSTS_N_INSNS (4), /* mulsi_const9 */ 770 COSTS_N_INSNS (4), /* muldi */ 771 COSTS_N_INSNS (14), /* divsi */ 772 COSTS_N_INSNS (14), /* divdi */ 773 COSTS_N_INSNS (4), /* fp */ 774 COSTS_N_INSNS (10), /* dmul */ 775 COSTS_N_INSNS (36), /* sdiv */ 776 COSTS_N_INSNS (66), /* ddiv */ 777 64, /* cache line size */ 778 32, /* l1 cache */ 779 128, /* l2 cache */ 780 1, /* prefetch streams /*/ 781}; 782 783/* Instruction costs on POWER4 and POWER5 processors. */ 784static const 785struct processor_costs power4_cost = { 786 COSTS_N_INSNS (3), /* mulsi */ 787 COSTS_N_INSNS (2), /* mulsi_const */ 788 COSTS_N_INSNS (2), /* mulsi_const9 */ 789 COSTS_N_INSNS (4), /* muldi */ 790 COSTS_N_INSNS (18), /* divsi */ 791 COSTS_N_INSNS (34), /* divdi */ 792 COSTS_N_INSNS (3), /* fp */ 793 COSTS_N_INSNS (3), /* dmul */ 794 COSTS_N_INSNS (17), /* sdiv */ 795 COSTS_N_INSNS (17), /* ddiv */ 796 128, /* cache line size */ 797 32, /* l1 cache */ 798 1024, /* l2 cache */ 799 8, /* prefetch streams /*/ 800}; 801 802/* Instruction costs on POWER6 processors. */ 803static const 804struct processor_costs power6_cost = { 805 COSTS_N_INSNS (8), /* mulsi */ 806 COSTS_N_INSNS (8), /* mulsi_const */ 807 COSTS_N_INSNS (8), /* mulsi_const9 */ 808 COSTS_N_INSNS (8), /* muldi */ 809 COSTS_N_INSNS (22), /* divsi */ 810 COSTS_N_INSNS (28), /* divdi */ 811 COSTS_N_INSNS (3), /* fp */ 812 COSTS_N_INSNS (3), /* dmul */ 813 COSTS_N_INSNS (13), /* sdiv */ 814 COSTS_N_INSNS (16), /* ddiv */ 815 128, /* cache line size */ 816 64, /* l1 cache */ 817 2048, /* l2 cache */ 818 16, /* prefetch streams */ 819}; 820 821/* Instruction costs on POWER7 processors. */ 822static const 823struct processor_costs power7_cost = { 824 COSTS_N_INSNS (2), /* mulsi */ 825 COSTS_N_INSNS (2), /* mulsi_const */ 826 COSTS_N_INSNS (2), /* mulsi_const9 */ 827 COSTS_N_INSNS (2), /* muldi */ 828 COSTS_N_INSNS (18), /* divsi */ 829 COSTS_N_INSNS (34), /* divdi */ 830 COSTS_N_INSNS (3), /* fp */ 831 COSTS_N_INSNS (3), /* dmul */ 832 COSTS_N_INSNS (13), /* sdiv */ 833 COSTS_N_INSNS (16), /* ddiv */ 834 128, /* cache line size */ 835 32, /* l1 cache */ 836 256, /* l2 cache */ 837 12, /* prefetch streams */ 838}; 839 840/* Instruction costs on POWER A2 processors. */ 841static const 842struct processor_costs ppca2_cost = { 843 COSTS_N_INSNS (16), /* mulsi */ 844 COSTS_N_INSNS (16), /* mulsi_const */ 845 COSTS_N_INSNS (16), /* mulsi_const9 */ 846 COSTS_N_INSNS (16), /* muldi */ 847 COSTS_N_INSNS (22), /* divsi */ 848 COSTS_N_INSNS (28), /* divdi */ 849 COSTS_N_INSNS (3), /* fp */ 850 COSTS_N_INSNS (3), /* dmul */ 851 COSTS_N_INSNS (59), /* sdiv */ 852 COSTS_N_INSNS (72), /* ddiv */ 853 64, 854 16, /* l1 cache */ 855 2048, /* l2 cache */ 856 16, /* prefetch streams */ 857}; 858 859 860/* Table that classifies rs6000 builtin functions (pure, const, etc.). */ 861#undef RS6000_BUILTIN 862#undef RS6000_BUILTIN_EQUATE 863#define RS6000_BUILTIN(NAME, TYPE) TYPE, 864#define RS6000_BUILTIN_EQUATE(NAME, VALUE) 865 866static const enum rs6000_btc builtin_classify[(int)RS6000_BUILTIN_COUNT] = 867{ 868#include "rs6000-builtin.def" 869}; 870 871#undef RS6000_BUILTIN 872#undef RS6000_BUILTIN_EQUATE 873 874 875static bool rs6000_function_ok_for_sibcall (tree, tree); 876static const char *rs6000_invalid_within_doloop (const_rtx); 877static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool); 878static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool); 879static rtx rs6000_generate_compare (rtx, enum machine_mode); 880static void rs6000_emit_stack_tie (void); 881static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx); 882static bool spe_func_has_64bit_regs_p (void); 883static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int, 884 int, HOST_WIDE_INT); 885static rtx gen_frame_mem_offset (enum machine_mode, rtx, int); 886static unsigned rs6000_hash_constant (rtx); 887static unsigned toc_hash_function (const void *); 888static int toc_hash_eq (const void *, const void *); 889static bool reg_offset_addressing_ok_p (enum machine_mode); 890static bool virtual_stack_registers_memory_p (rtx); 891static bool constant_pool_expr_p (rtx); 892static bool legitimate_small_data_p (enum machine_mode, rtx); 893static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int); 894static struct machine_function * rs6000_init_machine_status (void); 895static bool rs6000_assemble_integer (rtx, unsigned int, int); 896static bool no_global_regs_above (int, bool); 897#ifdef HAVE_GAS_HIDDEN 898static void rs6000_assemble_visibility (tree, int); 899#endif 900static int rs6000_ra_ever_killed (void); 901static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *); 902static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *); 903static bool rs6000_ms_bitfield_layout_p (const_tree); 904static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *); 905static void rs6000_eliminate_indexed_memrefs (rtx operands[2]); 906static const char *rs6000_mangle_type (const_tree); 907static void rs6000_set_default_type_attributes (tree); 908static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool); 909static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool); 910static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int, 911 enum machine_mode, bool, bool, bool); 912static bool rs6000_reg_live_or_pic_offset_p (int); 913static tree rs6000_builtin_vectorized_function (tree, tree, tree); 914static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int); 915static void rs6000_restore_saved_cr (rtx, int); 916static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT); 917static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT); 918static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, 919 tree); 920static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT); 921static bool rs6000_return_in_memory (const_tree, const_tree); 922static rtx rs6000_function_value (const_tree, const_tree, bool); 923static void rs6000_file_start (void); 924#if TARGET_ELF 925static int rs6000_elf_reloc_rw_mask (void); 926static void rs6000_elf_asm_out_constructor (rtx, int); 927static void rs6000_elf_asm_out_destructor (rtx, int); 928static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED; 929static void rs6000_elf_asm_init_sections (void); 930static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx, 931 unsigned HOST_WIDE_INT); 932static void rs6000_elf_encode_section_info (tree, rtx, int) 933 ATTRIBUTE_UNUSED; 934#endif 935static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx); 936static void rs6000_alloc_sdmode_stack_slot (void); 937static void rs6000_instantiate_decls (void); 938#if TARGET_XCOFF 939static void rs6000_xcoff_asm_output_anchor (rtx); 940static void rs6000_xcoff_asm_globalize_label (FILE *, const char *); 941static void rs6000_xcoff_asm_init_sections (void); 942static int rs6000_xcoff_reloc_rw_mask (void); 943static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree); 944static section *rs6000_xcoff_select_section (tree, int, 945 unsigned HOST_WIDE_INT); 946static void rs6000_xcoff_unique_section (tree, int); 947static section *rs6000_xcoff_select_rtx_section 948 (enum machine_mode, rtx, unsigned HOST_WIDE_INT); 949static const char * rs6000_xcoff_strip_name_encoding (const char *); 950static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int); 951static void rs6000_xcoff_file_start (void); 952static void rs6000_xcoff_file_end (void); 953#endif 954static int rs6000_variable_issue (FILE *, int, rtx, int); 955static bool rs6000_rtx_costs (rtx, int, int, int *, bool); 956static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool); 957static int rs6000_debug_address_cost (rtx, bool); 958static int rs6000_adjust_cost (rtx, rtx, rtx, int); 959static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int); 960static void rs6000_sched_init (FILE *, int, int); 961static bool is_microcoded_insn (rtx); 962static bool is_nonpipeline_insn (rtx); 963static bool is_cracked_insn (rtx); 964static bool is_branch_slot_insn (rtx); 965static bool is_load_insn (rtx); 966static rtx get_store_dest (rtx pat); 967static bool is_store_insn (rtx); 968static bool set_to_load_agen (rtx,rtx); 969static bool adjacent_mem_locations (rtx,rtx); 970static int rs6000_adjust_priority (rtx, int); 971static int rs6000_issue_rate (void); 972static bool rs6000_is_costly_dependence (dep_t, int, int); 973static rtx get_next_active_insn (rtx, rtx); 974static bool insn_terminates_group_p (rtx , enum group_termination); 975static bool insn_must_be_first_in_group (rtx); 976static bool insn_must_be_last_in_group (rtx); 977static bool is_costly_group (rtx *, rtx); 978static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *); 979static int redefine_groups (FILE *, int, rtx, rtx); 980static int pad_groups (FILE *, int, rtx, rtx); 981static void rs6000_sched_finish (FILE *, int); 982static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int); 983static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int); 984static int rs6000_use_sched_lookahead (void); 985static int rs6000_use_sched_lookahead_guard (rtx); 986static void * rs6000_alloc_sched_context (void); 987static void rs6000_init_sched_context (void *, bool); 988static void rs6000_set_sched_context (void *); 989static void rs6000_free_sched_context (void *); 990static tree rs6000_builtin_reciprocal (unsigned int, bool, bool); 991static tree rs6000_builtin_mask_for_load (void); 992static tree rs6000_builtin_mul_widen_even (tree); 993static tree rs6000_builtin_mul_widen_odd (tree); 994static tree rs6000_builtin_conversion (unsigned int, tree); 995static tree rs6000_builtin_vec_perm (tree, tree *); 996static bool rs6000_builtin_support_vector_misalignment (enum 997 machine_mode, 998 const_tree, 999 int, bool); 1000 1001static void def_builtin (int, const char *, tree, int); 1002static bool rs6000_vector_alignment_reachable (const_tree, bool); 1003static void rs6000_init_builtins (void); 1004static tree rs6000_builtin_decl (unsigned, bool); 1005 1006static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx); 1007static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx); 1008static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx); 1009static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int); 1010static void altivec_init_builtins (void); 1011static unsigned builtin_hash_function (const void *); 1012static int builtin_hash_eq (const void *, const void *); 1013static tree builtin_function_type (enum machine_mode, enum machine_mode, 1014 enum machine_mode, enum machine_mode, 1015 enum rs6000_builtins, const char *name); 1016static void rs6000_common_init_builtins (void); 1017static void rs6000_init_libfuncs (void); 1018 1019static void paired_init_builtins (void); 1020static rtx paired_expand_builtin (tree, rtx, bool *); 1021static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx); 1022static rtx paired_expand_stv_builtin (enum insn_code, tree); 1023static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx); 1024 1025static void enable_mask_for_builtins (struct builtin_description *, int, 1026 enum rs6000_builtins, 1027 enum rs6000_builtins); 1028static void spe_init_builtins (void); 1029static rtx spe_expand_builtin (tree, rtx, bool *); 1030static rtx spe_expand_stv_builtin (enum insn_code, tree); 1031static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx); 1032static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx); 1033static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx); 1034static rs6000_stack_t *rs6000_stack_info (void); 1035static void debug_stack_info (rs6000_stack_t *); 1036 1037static rtx altivec_expand_builtin (tree, rtx, bool *); 1038static rtx altivec_expand_ld_builtin (tree, rtx, bool *); 1039static rtx altivec_expand_st_builtin (tree, rtx, bool *); 1040static rtx altivec_expand_dst_builtin (tree, rtx, bool *); 1041static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx); 1042static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx); 1043static rtx altivec_expand_stv_builtin (enum insn_code, tree); 1044static rtx altivec_expand_vec_init_builtin (tree, tree, rtx); 1045static rtx altivec_expand_vec_set_builtin (tree); 1046static rtx altivec_expand_vec_ext_builtin (tree, rtx); 1047static int get_element_number (tree, tree); 1048static bool rs6000_handle_option (size_t, const char *, int); 1049static void rs6000_parse_tls_size_option (void); 1050static void rs6000_parse_yes_no_option (const char *, const char *, int *); 1051static int first_altivec_reg_to_save (void); 1052static unsigned int compute_vrsave_mask (void); 1053static void compute_save_world_info (rs6000_stack_t *info_ptr); 1054static void is_altivec_return_reg (rtx, void *); 1055static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int); 1056int easy_vector_constant (rtx, enum machine_mode); 1057static rtx rs6000_dwarf_register_span (rtx); 1058static void rs6000_init_dwarf_reg_sizes_extra (tree); 1059static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode); 1060static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode); 1061static rtx rs6000_legitimize_tls_address (rtx, enum tls_model); 1062static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED; 1063static rtx rs6000_delegitimize_address (rtx); 1064static rtx rs6000_tls_get_addr (void); 1065static rtx rs6000_got_sym (void); 1066static int rs6000_tls_symbol_ref_1 (rtx *, void *); 1067static const char *rs6000_get_some_local_dynamic_name (void); 1068static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *); 1069static rtx rs6000_complex_function_value (enum machine_mode); 1070static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *, 1071 enum machine_mode, tree); 1072static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *, 1073 HOST_WIDE_INT); 1074static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *, 1075 tree, HOST_WIDE_INT); 1076static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *, 1077 HOST_WIDE_INT, 1078 rtx[], int *); 1079static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *, 1080 const_tree, HOST_WIDE_INT, 1081 rtx[], int *); 1082static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, int, bool); 1083static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int); 1084static void rs6000_move_block_from_reg (int regno, rtx x, int nregs); 1085static void setup_incoming_varargs (CUMULATIVE_ARGS *, 1086 enum machine_mode, tree, 1087 int *, int); 1088static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, 1089 const_tree, bool); 1090static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, 1091 tree, bool); 1092static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree); 1093#if TARGET_MACHO 1094static void macho_branch_islands (void); 1095static int no_previous_def (tree function_name); 1096static tree get_prev_label (tree function_name); 1097static void rs6000_darwin_file_start (void); 1098#endif 1099 1100static tree rs6000_build_builtin_va_list (void); 1101static void rs6000_va_start (tree, rtx); 1102static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *); 1103static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree); 1104static bool rs6000_scalar_mode_supported_p (enum machine_mode); 1105static bool rs6000_vector_mode_supported_p (enum machine_mode); 1106static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx); 1107static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx, 1108 enum machine_mode); 1109static tree rs6000_stack_protect_fail (void); 1110 1111static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int, 1112 int, int *); 1113 1114static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int, 1115 int, int, int *); 1116 1117rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int, 1118 int, int *) 1119 = rs6000_legitimize_reload_address; 1120 1121static bool rs6000_mode_dependent_address (rtx); 1122static bool rs6000_debug_mode_dependent_address (rtx); 1123bool (*rs6000_mode_dependent_address_ptr) (rtx) 1124 = rs6000_mode_dependent_address; 1125 1126static enum reg_class rs6000_secondary_reload_class (enum reg_class, 1127 enum machine_mode, rtx); 1128static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class, 1129 enum machine_mode, 1130 rtx); 1131enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class, 1132 enum machine_mode, rtx) 1133 = rs6000_secondary_reload_class; 1134 1135static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class); 1136static enum reg_class rs6000_debug_preferred_reload_class (rtx, 1137 enum reg_class); 1138enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class) 1139 = rs6000_preferred_reload_class; 1140 1141static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class, 1142 enum machine_mode); 1143 1144static bool rs6000_debug_secondary_memory_needed (enum reg_class, 1145 enum reg_class, 1146 enum machine_mode); 1147 1148bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class, 1149 enum machine_mode) 1150 = rs6000_secondary_memory_needed; 1151 1152static bool rs6000_cannot_change_mode_class (enum machine_mode, 1153 enum machine_mode, 1154 enum reg_class); 1155static bool rs6000_debug_cannot_change_mode_class (enum machine_mode, 1156 enum machine_mode, 1157 enum reg_class); 1158 1159bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode, 1160 enum machine_mode, 1161 enum reg_class) 1162 = rs6000_cannot_change_mode_class; 1163 1164static enum reg_class rs6000_secondary_reload (bool, rtx, enum reg_class, 1165 enum machine_mode, 1166 struct secondary_reload_info *); 1167 1168static const enum reg_class *rs6000_ira_cover_classes (void); 1169 1170const int INSN_NOT_AVAILABLE = -1; 1171static enum machine_mode rs6000_eh_return_filter_mode (void); 1172static bool rs6000_can_eliminate (const int, const int); 1173static void rs6000_trampoline_init (rtx, tree, rtx); 1174 1175/* Hash table stuff for keeping track of TOC entries. */ 1176 1177struct GTY(()) toc_hash_struct 1178{ 1179 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy 1180 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */ 1181 rtx key; 1182 enum machine_mode key_mode; 1183 int labelno; 1184}; 1185 1186static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table; 1187 1188/* Hash table to keep track of the argument types for builtin functions. */ 1189 1190struct GTY(()) builtin_hash_struct 1191{ 1192 tree type; 1193 enum machine_mode mode[4]; /* return value + 3 arguments. */ 1194 unsigned char uns_p[4]; /* and whether the types are unsigned. */ 1195}; 1196 1197static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table; 1198 1199/* Default register names. */ 1200char rs6000_reg_names[][8] = 1201{ 1202 "0", "1", "2", "3", "4", "5", "6", "7", 1203 "8", "9", "10", "11", "12", "13", "14", "15", 1204 "16", "17", "18", "19", "20", "21", "22", "23", 1205 "24", "25", "26", "27", "28", "29", "30", "31", 1206 "0", "1", "2", "3", "4", "5", "6", "7", 1207 "8", "9", "10", "11", "12", "13", "14", "15", 1208 "16", "17", "18", "19", "20", "21", "22", "23", 1209 "24", "25", "26", "27", "28", "29", "30", "31", 1210 "mq", "lr", "ctr","ap", 1211 "0", "1", "2", "3", "4", "5", "6", "7", 1212 "xer", 1213 /* AltiVec registers. */ 1214 "0", "1", "2", "3", "4", "5", "6", "7", 1215 "8", "9", "10", "11", "12", "13", "14", "15", 1216 "16", "17", "18", "19", "20", "21", "22", "23", 1217 "24", "25", "26", "27", "28", "29", "30", "31", 1218 "vrsave", "vscr", 1219 /* SPE registers. */ 1220 "spe_acc", "spefscr", 1221 /* Soft frame pointer. */ 1222 "sfp" 1223}; 1224 1225#ifdef TARGET_REGNAMES 1226static const char alt_reg_names[][8] = 1227{ 1228 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", 1229 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", 1230 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23", 1231 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31", 1232 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7", 1233 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15", 1234 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23", 1235 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31", 1236 "mq", "lr", "ctr", "ap", 1237 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7", 1238 "xer", 1239 /* AltiVec registers. */ 1240 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7", 1241 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15", 1242 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23", 1243 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31", 1244 "vrsave", "vscr", 1245 /* SPE registers. */ 1246 "spe_acc", "spefscr", 1247 /* Soft frame pointer. */ 1248 "sfp" 1249}; 1250#endif 1251 1252/* Table of valid machine attributes. */ 1253 1254static const struct attribute_spec rs6000_attribute_table[] = 1255{ 1256 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ 1257 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute }, 1258 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute }, 1259 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute }, 1260 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute }, 1261 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute }, 1262#ifdef SUBTARGET_ATTRIBUTE_TABLE 1263 SUBTARGET_ATTRIBUTE_TABLE, 1264#endif 1265 { NULL, 0, 0, false, false, false, NULL } 1266}; 1267 1268#ifndef MASK_STRICT_ALIGN 1269#define MASK_STRICT_ALIGN 0 1270#endif 1271#ifndef TARGET_PROFILE_KERNEL 1272#define TARGET_PROFILE_KERNEL 0 1273#endif 1274 1275/* The VRSAVE bitmask puts bit %v0 as the most significant bit. */ 1276#define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO)) 1277 1278/* Initialize the GCC target structure. */ 1279#undef TARGET_ATTRIBUTE_TABLE 1280#define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table 1281#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES 1282#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes 1283 1284#undef TARGET_ASM_ALIGNED_DI_OP 1285#define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP 1286 1287/* Default unaligned ops are only provided for ELF. Find the ops needed 1288 for non-ELF systems. */ 1289#ifndef OBJECT_FORMAT_ELF 1290#if TARGET_XCOFF 1291/* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on 1292 64-bit targets. */ 1293#undef TARGET_ASM_UNALIGNED_HI_OP 1294#define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2," 1295#undef TARGET_ASM_UNALIGNED_SI_OP 1296#define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4," 1297#undef TARGET_ASM_UNALIGNED_DI_OP 1298#define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8," 1299#else 1300/* For Darwin. */ 1301#undef TARGET_ASM_UNALIGNED_HI_OP 1302#define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t" 1303#undef TARGET_ASM_UNALIGNED_SI_OP 1304#define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t" 1305#undef TARGET_ASM_UNALIGNED_DI_OP 1306#define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t" 1307#undef TARGET_ASM_ALIGNED_DI_OP 1308#define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t" 1309#endif 1310#endif 1311 1312/* This hook deals with fixups for relocatable code and DI-mode objects 1313 in 64-bit code. */ 1314#undef TARGET_ASM_INTEGER 1315#define TARGET_ASM_INTEGER rs6000_assemble_integer 1316 1317#ifdef HAVE_GAS_HIDDEN 1318#undef TARGET_ASM_ASSEMBLE_VISIBILITY 1319#define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility 1320#endif 1321 1322#undef TARGET_HAVE_TLS 1323#define TARGET_HAVE_TLS HAVE_AS_TLS 1324 1325#undef TARGET_CANNOT_FORCE_CONST_MEM 1326#define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p 1327 1328#undef TARGET_DELEGITIMIZE_ADDRESS 1329#define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address 1330 1331#undef TARGET_ASM_FUNCTION_PROLOGUE 1332#define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue 1333#undef TARGET_ASM_FUNCTION_EPILOGUE 1334#define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue 1335 1336#undef TARGET_LEGITIMIZE_ADDRESS 1337#define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address 1338 1339#undef TARGET_SCHED_VARIABLE_ISSUE 1340#define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue 1341 1342#undef TARGET_SCHED_ISSUE_RATE 1343#define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate 1344#undef TARGET_SCHED_ADJUST_COST 1345#define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost 1346#undef TARGET_SCHED_ADJUST_PRIORITY 1347#define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority 1348#undef TARGET_SCHED_IS_COSTLY_DEPENDENCE 1349#define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence 1350#undef TARGET_SCHED_INIT 1351#define TARGET_SCHED_INIT rs6000_sched_init 1352#undef TARGET_SCHED_FINISH 1353#define TARGET_SCHED_FINISH rs6000_sched_finish 1354#undef TARGET_SCHED_REORDER 1355#define TARGET_SCHED_REORDER rs6000_sched_reorder 1356#undef TARGET_SCHED_REORDER2 1357#define TARGET_SCHED_REORDER2 rs6000_sched_reorder2 1358 1359#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD 1360#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead 1361 1362#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD 1363#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard 1364 1365#undef TARGET_SCHED_ALLOC_SCHED_CONTEXT 1366#define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context 1367#undef TARGET_SCHED_INIT_SCHED_CONTEXT 1368#define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context 1369#undef TARGET_SCHED_SET_SCHED_CONTEXT 1370#define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context 1371#undef TARGET_SCHED_FREE_SCHED_CONTEXT 1372#define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context 1373 1374#undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD 1375#define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load 1376#undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN 1377#define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even 1378#undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD 1379#define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd 1380#undef TARGET_VECTORIZE_BUILTIN_CONVERSION 1381#define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion 1382#undef TARGET_VECTORIZE_BUILTIN_VEC_PERM 1383#define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm 1384#undef TARGET_SUPPORT_VECTOR_MISALIGNMENT 1385#define TARGET_SUPPORT_VECTOR_MISALIGNMENT \ 1386 rs6000_builtin_support_vector_misalignment 1387#undef TARGET_VECTOR_ALIGNMENT_REACHABLE 1388#define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable 1389 1390#undef TARGET_INIT_BUILTINS 1391#define TARGET_INIT_BUILTINS rs6000_init_builtins 1392#undef TARGET_BUILTIN_DECL 1393#define TARGET_BUILTIN_DECL rs6000_builtin_decl 1394 1395#undef TARGET_EXPAND_BUILTIN 1396#define TARGET_EXPAND_BUILTIN rs6000_expand_builtin 1397 1398#undef TARGET_MANGLE_TYPE 1399#define TARGET_MANGLE_TYPE rs6000_mangle_type 1400 1401#undef TARGET_INIT_LIBFUNCS 1402#define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs 1403 1404#if TARGET_MACHO 1405#undef TARGET_BINDS_LOCAL_P 1406#define TARGET_BINDS_LOCAL_P darwin_binds_local_p 1407#endif 1408 1409#undef TARGET_MS_BITFIELD_LAYOUT_P 1410#define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p 1411 1412#undef TARGET_ASM_OUTPUT_MI_THUNK 1413#define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk 1414 1415#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK 1416#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true 1417 1418#undef TARGET_FUNCTION_OK_FOR_SIBCALL 1419#define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall 1420 1421#undef TARGET_INVALID_WITHIN_DOLOOP 1422#define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop 1423 1424#undef TARGET_RTX_COSTS 1425#define TARGET_RTX_COSTS rs6000_rtx_costs 1426#undef TARGET_ADDRESS_COST 1427#define TARGET_ADDRESS_COST hook_int_rtx_bool_0 1428 1429#undef TARGET_DWARF_REGISTER_SPAN 1430#define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span 1431 1432#undef TARGET_INIT_DWARF_REG_SIZES_EXTRA 1433#define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra 1434 1435/* On rs6000, function arguments are promoted, as are function return 1436 values. */ 1437#undef TARGET_PROMOTE_FUNCTION_MODE 1438#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote 1439 1440#undef TARGET_RETURN_IN_MEMORY 1441#define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory 1442 1443#undef TARGET_SETUP_INCOMING_VARARGS 1444#define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs 1445 1446/* Always strict argument naming on rs6000. */ 1447#undef TARGET_STRICT_ARGUMENT_NAMING 1448#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true 1449#undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED 1450#define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true 1451#undef TARGET_SPLIT_COMPLEX_ARG 1452#define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true 1453#undef TARGET_MUST_PASS_IN_STACK 1454#define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack 1455#undef TARGET_PASS_BY_REFERENCE 1456#define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference 1457#undef TARGET_ARG_PARTIAL_BYTES 1458#define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes 1459 1460#undef TARGET_BUILD_BUILTIN_VA_LIST 1461#define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list 1462 1463#undef TARGET_EXPAND_BUILTIN_VA_START 1464#define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start 1465 1466#undef TARGET_GIMPLIFY_VA_ARG_EXPR 1467#define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg 1468 1469#undef TARGET_EH_RETURN_FILTER_MODE 1470#define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode 1471 1472#undef TARGET_SCALAR_MODE_SUPPORTED_P 1473#define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p 1474 1475#undef TARGET_VECTOR_MODE_SUPPORTED_P 1476#define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p 1477 1478#undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN 1479#define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn 1480 1481#undef TARGET_HANDLE_OPTION 1482#define TARGET_HANDLE_OPTION rs6000_handle_option 1483 1484#undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION 1485#define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \ 1486 rs6000_builtin_vectorized_function 1487 1488#undef TARGET_DEFAULT_TARGET_FLAGS 1489#define TARGET_DEFAULT_TARGET_FLAGS \ 1490 (TARGET_DEFAULT) 1491 1492#undef TARGET_STACK_PROTECT_FAIL 1493#define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail 1494 1495/* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors 1496 The PowerPC architecture requires only weak consistency among 1497 processors--that is, memory accesses between processors need not be 1498 sequentially consistent and memory accesses among processors can occur 1499 in any order. The ability to order memory accesses weakly provides 1500 opportunities for more efficient use of the system bus. Unless a 1501 dependency exists, the 604e allows read operations to precede store 1502 operations. */ 1503#undef TARGET_RELAXED_ORDERING 1504#define TARGET_RELAXED_ORDERING true 1505 1506#ifdef HAVE_AS_TLS 1507#undef TARGET_ASM_OUTPUT_DWARF_DTPREL 1508#define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel 1509#endif 1510 1511/* Use a 32-bit anchor range. This leads to sequences like: 1512 1513 addis tmp,anchor,high 1514 add dest,tmp,low 1515 1516 where tmp itself acts as an anchor, and can be shared between 1517 accesses to the same 64k page. */ 1518#undef TARGET_MIN_ANCHOR_OFFSET 1519#define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1 1520#undef TARGET_MAX_ANCHOR_OFFSET 1521#define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff 1522#undef TARGET_USE_BLOCKS_FOR_CONSTANT_P 1523#define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p 1524 1525#undef TARGET_BUILTIN_RECIPROCAL 1526#define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal 1527 1528#undef TARGET_EXPAND_TO_RTL_HOOK 1529#define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot 1530 1531#undef TARGET_INSTANTIATE_DECLS 1532#define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls 1533 1534#undef TARGET_SECONDARY_RELOAD 1535#define TARGET_SECONDARY_RELOAD rs6000_secondary_reload 1536 1537#undef TARGET_IRA_COVER_CLASSES 1538#define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes 1539 1540#undef TARGET_LEGITIMATE_ADDRESS_P 1541#define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p 1542 1543#undef TARGET_CAN_ELIMINATE 1544#define TARGET_CAN_ELIMINATE rs6000_can_eliminate 1545 1546#undef TARGET_TRAMPOLINE_INIT 1547#define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init 1548 1549#undef TARGET_FUNCTION_VALUE 1550#define TARGET_FUNCTION_VALUE rs6000_function_value 1551 1552struct gcc_target targetm = TARGET_INITIALIZER; 1553 1554/* Return number of consecutive hard regs needed starting at reg REGNO 1555 to hold something of mode MODE. 1556 This is ordinarily the length in words of a value of mode MODE 1557 but can be less for certain modes in special long registers. 1558 1559 For the SPE, GPRs are 64 bits but only 32 bits are visible in 1560 scalar instructions. The upper 32 bits are only available to the 1561 SIMD instructions. 1562 1563 POWER and PowerPC GPRs hold 32 bits worth; 1564 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */ 1565 1566static int 1567rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode) 1568{ 1569 unsigned HOST_WIDE_INT reg_size; 1570 1571 if (FP_REGNO_P (regno)) 1572 reg_size = (VECTOR_MEM_VSX_P (mode) 1573 ? UNITS_PER_VSX_WORD 1574 : UNITS_PER_FP_WORD); 1575 1576 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode)) 1577 reg_size = UNITS_PER_SPE_WORD; 1578 1579 else if (ALTIVEC_REGNO_P (regno)) 1580 reg_size = UNITS_PER_ALTIVEC_WORD; 1581 1582 /* The value returned for SCmode in the E500 double case is 2 for 1583 ABI compatibility; storing an SCmode value in a single register 1584 would require function_arg and rs6000_spe_function_arg to handle 1585 SCmode so as to pass the value correctly in a pair of 1586 registers. */ 1587 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode 1588 && !DECIMAL_FLOAT_MODE_P (mode)) 1589 reg_size = UNITS_PER_FP_WORD; 1590 1591 else 1592 reg_size = UNITS_PER_WORD; 1593 1594 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size; 1595} 1596 1597/* Value is 1 if hard register REGNO can hold a value of machine-mode 1598 MODE. */ 1599static int 1600rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode) 1601{ 1602 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1; 1603 1604 /* VSX registers that overlap the FPR registers are larger than for non-VSX 1605 implementations. Don't allow an item to be split between a FP register 1606 and an Altivec register. */ 1607 if (VECTOR_MEM_VSX_P (mode)) 1608 { 1609 if (FP_REGNO_P (regno)) 1610 return FP_REGNO_P (last_regno); 1611 1612 if (ALTIVEC_REGNO_P (regno)) 1613 return ALTIVEC_REGNO_P (last_regno); 1614 } 1615 1616 /* The GPRs can hold any mode, but values bigger than one register 1617 cannot go past R31. */ 1618 if (INT_REGNO_P (regno)) 1619 return INT_REGNO_P (last_regno); 1620 1621 /* The float registers (except for VSX vector modes) can only hold floating 1622 modes and DImode. This excludes the 32-bit decimal float mode for 1623 now. */ 1624 if (FP_REGNO_P (regno)) 1625 { 1626 if (SCALAR_FLOAT_MODE_P (mode) 1627 && (mode != TDmode || (regno % 2) == 0) 1628 && FP_REGNO_P (last_regno)) 1629 return 1; 1630 1631 if (GET_MODE_CLASS (mode) == MODE_INT 1632 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD) 1633 return 1; 1634 1635 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT 1636 && PAIRED_VECTOR_MODE (mode)) 1637 return 1; 1638 1639 return 0; 1640 } 1641 1642 /* The CR register can only hold CC modes. */ 1643 if (CR_REGNO_P (regno)) 1644 return GET_MODE_CLASS (mode) == MODE_CC; 1645 1646 if (XER_REGNO_P (regno)) 1647 return mode == PSImode; 1648 1649 /* AltiVec only in AldyVec registers. */ 1650 if (ALTIVEC_REGNO_P (regno)) 1651 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode); 1652 1653 /* ...but GPRs can hold SIMD data on the SPE in one register. */ 1654 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode)) 1655 return 1; 1656 1657 /* We cannot put TImode anywhere except general register and it must be able 1658 to fit within the register set. In the future, allow TImode in the 1659 Altivec or VSX registers. */ 1660 1661 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD; 1662} 1663 1664/* Print interesting facts about registers. */ 1665static void 1666rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name) 1667{ 1668 int r, m; 1669 1670 for (r = first_regno; r <= last_regno; ++r) 1671 { 1672 const char *comma = ""; 1673 int len; 1674 1675 if (first_regno == last_regno) 1676 fprintf (stderr, "%s:\t", reg_name); 1677 else 1678 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno); 1679 1680 len = 8; 1681 for (m = 0; m < NUM_MACHINE_MODES; ++m) 1682 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r]) 1683 { 1684 if (len > 70) 1685 { 1686 fprintf (stderr, ",\n\t"); 1687 len = 8; 1688 comma = ""; 1689 } 1690 1691 if (rs6000_hard_regno_nregs[m][r] > 1) 1692 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m), 1693 rs6000_hard_regno_nregs[m][r]); 1694 else 1695 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m)); 1696 1697 comma = ", "; 1698 } 1699 1700 if (call_used_regs[r]) 1701 { 1702 if (len > 70) 1703 { 1704 fprintf (stderr, ",\n\t"); 1705 len = 8; 1706 comma = ""; 1707 } 1708 1709 len += fprintf (stderr, "%s%s", comma, "call-used"); 1710 comma = ", "; 1711 } 1712 1713 if (fixed_regs[r]) 1714 { 1715 if (len > 70) 1716 { 1717 fprintf (stderr, ",\n\t"); 1718 len = 8; 1719 comma = ""; 1720 } 1721 1722 len += fprintf (stderr, "%s%s", comma, "fixed"); 1723 comma = ", "; 1724 } 1725 1726 if (len > 70) 1727 { 1728 fprintf (stderr, ",\n\t"); 1729 comma = ""; 1730 } 1731 1732 fprintf (stderr, "%sregno = %d\n", comma, r); 1733 } 1734} 1735 1736/* Print various interesting information with -mdebug=reg. */ 1737static void 1738rs6000_debug_reg_global (void) 1739{ 1740 const char *nl = (const char *)0; 1741 int m; 1742 char costly_num[20]; 1743 char nop_num[20]; 1744 const char *costly_str; 1745 const char *nop_str; 1746 1747 /* Map enum rs6000_vector to string. */ 1748 static const char *rs6000_debug_vector_unit[] = { 1749 "none", 1750 "altivec", 1751 "vsx", 1752 "paired", 1753 "spe", 1754 "other" 1755 }; 1756 1757 fprintf (stderr, "Register information: (last virtual reg = %d)\n", 1758 LAST_VIRTUAL_REGISTER); 1759 rs6000_debug_reg_print (0, 31, "gr"); 1760 rs6000_debug_reg_print (32, 63, "fp"); 1761 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO, 1762 LAST_ALTIVEC_REGNO, 1763 "vs"); 1764 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr"); 1765 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr"); 1766 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr"); 1767 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq"); 1768 rs6000_debug_reg_print (XER_REGNO, XER_REGNO, "xer"); 1769 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave"); 1770 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr"); 1771 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a"); 1772 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f"); 1773 1774 fprintf (stderr, 1775 "\n" 1776 "d reg_class = %s\n" 1777 "f reg_class = %s\n" 1778 "v reg_class = %s\n" 1779 "wa reg_class = %s\n" 1780 "wd reg_class = %s\n" 1781 "wf reg_class = %s\n" 1782 "ws reg_class = %s\n\n", 1783 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]], 1784 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]], 1785 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]], 1786 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]], 1787 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]], 1788 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]], 1789 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]); 1790 1791 for (m = 0; m < NUM_MACHINE_MODES; ++m) 1792 if (rs6000_vector_unit[m] || rs6000_vector_mem[m]) 1793 { 1794 nl = "\n"; 1795 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n", 1796 GET_MODE_NAME (m), 1797 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ], 1798 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]); 1799 } 1800 1801 if (nl) 1802 fputs (nl, stderr); 1803 1804 switch (rs6000_sched_costly_dep) 1805 { 1806 case max_dep_latency: 1807 costly_str = "max_dep_latency"; 1808 break; 1809 1810 case no_dep_costly: 1811 costly_str = "no_dep_costly"; 1812 break; 1813 1814 case all_deps_costly: 1815 costly_str = "all_deps_costly"; 1816 break; 1817 1818 case true_store_to_load_dep_costly: 1819 costly_str = "true_store_to_load_dep_costly"; 1820 break; 1821 1822 case store_to_load_dep_costly: 1823 costly_str = "store_to_load_dep_costly"; 1824 break; 1825 1826 default: 1827 costly_str = costly_num; 1828 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep); 1829 break; 1830 } 1831 1832 switch (rs6000_sched_insert_nops) 1833 { 1834 case sched_finish_regroup_exact: 1835 nop_str = "sched_finish_regroup_exact"; 1836 break; 1837 1838 case sched_finish_pad_groups: 1839 nop_str = "sched_finish_pad_groups"; 1840 break; 1841 1842 case sched_finish_none: 1843 nop_str = "sched_finish_none"; 1844 break; 1845 1846 default: 1847 nop_str = nop_num; 1848 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops); 1849 break; 1850 } 1851 1852 fprintf (stderr, 1853 "always_hint = %s\n" 1854 "align_branch_targets = %s\n" 1855 "sched_restricted_insns_priority = %d\n" 1856 "sched_costly_dep = %s\n" 1857 "sched_insert_nops = %s\n\n", 1858 rs6000_always_hint ? "true" : "false", 1859 rs6000_align_branch_targets ? "true" : "false", 1860 (int)rs6000_sched_restricted_insns_priority, 1861 costly_str, nop_str); 1862} 1863 1864/* Initialize the various global tables that are based on register size. */ 1865static void 1866rs6000_init_hard_regno_mode_ok (void) 1867{ 1868 int r, m, c; 1869 int align64; 1870 int align32; 1871 1872 /* Precalculate REGNO_REG_CLASS. */ 1873 rs6000_regno_regclass[0] = GENERAL_REGS; 1874 for (r = 1; r < 32; ++r) 1875 rs6000_regno_regclass[r] = BASE_REGS; 1876 1877 for (r = 32; r < 64; ++r) 1878 rs6000_regno_regclass[r] = FLOAT_REGS; 1879 1880 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r) 1881 rs6000_regno_regclass[r] = NO_REGS; 1882 1883 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r) 1884 rs6000_regno_regclass[r] = ALTIVEC_REGS; 1885 1886 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS; 1887 for (r = CR1_REGNO; r <= CR7_REGNO; ++r) 1888 rs6000_regno_regclass[r] = CR_REGS; 1889 1890 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS; 1891 rs6000_regno_regclass[LR_REGNO] = LINK_REGS; 1892 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS; 1893 rs6000_regno_regclass[XER_REGNO] = XER_REGS; 1894 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS; 1895 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS; 1896 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS; 1897 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS; 1898 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS; 1899 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS; 1900 1901 /* Precalculate vector information, this must be set up before the 1902 rs6000_hard_regno_nregs_internal below. */ 1903 for (m = 0; m < NUM_MACHINE_MODES; ++m) 1904 { 1905 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE; 1906 rs6000_vector_reload[m][0] = CODE_FOR_nothing; 1907 rs6000_vector_reload[m][1] = CODE_FOR_nothing; 1908 } 1909 1910 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++) 1911 rs6000_constraints[c] = NO_REGS; 1912 1913 /* The VSX hardware allows native alignment for vectors, but control whether the compiler 1914 believes it can use native alignment or still uses 128-bit alignment. */ 1915 if (TARGET_VSX && !TARGET_VSX_ALIGN_128) 1916 { 1917 align64 = 64; 1918 align32 = 32; 1919 } 1920 else 1921 { 1922 align64 = 128; 1923 align32 = 128; 1924 } 1925 1926 /* V2DF mode, VSX only. */ 1927 if (TARGET_VSX) 1928 { 1929 rs6000_vector_unit[V2DFmode] = VECTOR_VSX; 1930 rs6000_vector_mem[V2DFmode] = VECTOR_VSX; 1931 rs6000_vector_align[V2DFmode] = align64; 1932 } 1933 1934 /* V4SF mode, either VSX or Altivec. */ 1935 if (TARGET_VSX) 1936 { 1937 rs6000_vector_unit[V4SFmode] = VECTOR_VSX; 1938 rs6000_vector_mem[V4SFmode] = VECTOR_VSX; 1939 rs6000_vector_align[V4SFmode] = align32; 1940 } 1941 else if (TARGET_ALTIVEC) 1942 { 1943 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC; 1944 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC; 1945 rs6000_vector_align[V4SFmode] = align32; 1946 } 1947 1948 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads 1949 and stores. */ 1950 if (TARGET_ALTIVEC) 1951 { 1952 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC; 1953 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC; 1954 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC; 1955 rs6000_vector_align[V4SImode] = align32; 1956 rs6000_vector_align[V8HImode] = align32; 1957 rs6000_vector_align[V16QImode] = align32; 1958 1959 if (TARGET_VSX) 1960 { 1961 rs6000_vector_mem[V4SImode] = VECTOR_VSX; 1962 rs6000_vector_mem[V8HImode] = VECTOR_VSX; 1963 rs6000_vector_mem[V16QImode] = VECTOR_VSX; 1964 } 1965 else 1966 { 1967 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC; 1968 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC; 1969 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC; 1970 } 1971 } 1972 1973 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract. 1974 Altivec doesn't have 64-bit support. */ 1975 if (TARGET_VSX) 1976 { 1977 rs6000_vector_mem[V2DImode] = VECTOR_VSX; 1978 rs6000_vector_unit[V2DImode] = VECTOR_NONE; 1979 rs6000_vector_align[V2DImode] = align64; 1980 } 1981 1982 /* DFmode, see if we want to use the VSX unit. */ 1983 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE) 1984 { 1985 rs6000_vector_unit[DFmode] = VECTOR_VSX; 1986 rs6000_vector_mem[DFmode] 1987 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE); 1988 rs6000_vector_align[DFmode] = align64; 1989 } 1990 1991 /* TODO add SPE and paired floating point vector support. */ 1992 1993 /* Register class constaints for the constraints that depend on compile 1994 switches. */ 1995 if (TARGET_HARD_FLOAT && TARGET_FPRS) 1996 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS; 1997 1998 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) 1999 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS; 2000 2001 if (TARGET_VSX) 2002 { 2003 /* At present, we just use VSX_REGS, but we have different constraints 2004 based on the use, in case we want to fine tune the default register 2005 class used. wa = any VSX register, wf = register class to use for 2006 V4SF, wd = register class to use for V2DF, and ws = register classs to 2007 use for DF scalars. */ 2008 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS; 2009 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS; 2010 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS; 2011 if (TARGET_VSX_SCALAR_DOUBLE) 2012 rs6000_constraints[RS6000_CONSTRAINT_ws] = VSX_REGS; 2013 } 2014 2015 if (TARGET_ALTIVEC) 2016 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS; 2017 2018 /* Set up the reload helper functions. */ 2019 if (TARGET_VSX || TARGET_ALTIVEC) 2020 { 2021 if (TARGET_64BIT) 2022 { 2023 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store; 2024 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load; 2025 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store; 2026 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load; 2027 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store; 2028 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load; 2029 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store; 2030 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load; 2031 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store; 2032 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load; 2033 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store; 2034 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load; 2035 } 2036 else 2037 { 2038 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store; 2039 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load; 2040 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store; 2041 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load; 2042 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store; 2043 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load; 2044 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store; 2045 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load; 2046 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store; 2047 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load; 2048 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store; 2049 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load; 2050 } 2051 } 2052 2053 /* Precalculate HARD_REGNO_NREGS. */ 2054 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r) 2055 for (m = 0; m < NUM_MACHINE_MODES; ++m) 2056 rs6000_hard_regno_nregs[m][r] 2057 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m); 2058 2059 /* Precalculate HARD_REGNO_MODE_OK. */ 2060 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r) 2061 for (m = 0; m < NUM_MACHINE_MODES; ++m) 2062 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m)) 2063 rs6000_hard_regno_mode_ok_p[m][r] = true; 2064 2065 /* Precalculate CLASS_MAX_NREGS sizes. */ 2066 for (c = 0; c < LIM_REG_CLASSES; ++c) 2067 { 2068 int reg_size; 2069 2070 if (TARGET_VSX && VSX_REG_CLASS_P (c)) 2071 reg_size = UNITS_PER_VSX_WORD; 2072 2073 else if (c == ALTIVEC_REGS) 2074 reg_size = UNITS_PER_ALTIVEC_WORD; 2075 2076 else if (c == FLOAT_REGS) 2077 reg_size = UNITS_PER_FP_WORD; 2078 2079 else 2080 reg_size = UNITS_PER_WORD; 2081 2082 for (m = 0; m < NUM_MACHINE_MODES; ++m) 2083 rs6000_class_max_nregs[m][c] 2084 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size; 2085 } 2086 2087 if (TARGET_E500_DOUBLE) 2088 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1; 2089 2090 if (TARGET_DEBUG_REG) 2091 rs6000_debug_reg_global (); 2092} 2093 2094#if TARGET_MACHO 2095/* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */ 2096 2097static void 2098darwin_rs6000_override_options (void) 2099{ 2100 /* The Darwin ABI always includes AltiVec, can't be (validly) turned 2101 off. */ 2102 rs6000_altivec_abi = 1; 2103 TARGET_ALTIVEC_VRSAVE = 1; 2104 if (DEFAULT_ABI == ABI_DARWIN) 2105 { 2106 if (MACHO_DYNAMIC_NO_PIC_P) 2107 { 2108 if (flag_pic) 2109 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC"); 2110 flag_pic = 0; 2111 } 2112 else if (flag_pic == 1) 2113 { 2114 flag_pic = 2; 2115 } 2116 } 2117 if (TARGET_64BIT && ! TARGET_POWERPC64) 2118 { 2119 target_flags |= MASK_POWERPC64; 2120 warning (0, "-m64 requires PowerPC64 architecture, enabling"); 2121 } 2122 if (flag_mkernel) 2123 { 2124 rs6000_default_long_calls = 1; 2125 target_flags |= MASK_SOFT_FLOAT; 2126 } 2127 2128 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes 2129 Altivec. */ 2130 if (!flag_mkernel && !flag_apple_kext 2131 && TARGET_64BIT 2132 && ! (target_flags_explicit & MASK_ALTIVEC)) 2133 target_flags |= MASK_ALTIVEC; 2134 2135 /* Unless the user (not the configurer) has explicitly overridden 2136 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to 2137 G4 unless targetting the kernel. */ 2138 if (!flag_mkernel 2139 && !flag_apple_kext 2140 && strverscmp (darwin_macosx_version_min, "10.5") >= 0 2141 && ! (target_flags_explicit & MASK_ALTIVEC) 2142 && ! rs6000_select[1].string) 2143 { 2144 target_flags |= MASK_ALTIVEC; 2145 } 2146} 2147#endif 2148 2149/* If not otherwise specified by a target, make 'long double' equivalent to 2150 'double'. */ 2151 2152#ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE 2153#define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64 2154#endif 2155 2156/* Override command line options. Mostly we process the processor 2157 type and sometimes adjust other TARGET_ options. */ 2158 2159void 2160rs6000_override_options (const char *default_cpu) 2161{ 2162 size_t i, j; 2163 struct rs6000_cpu_select *ptr; 2164 int set_masks; 2165 2166 /* Simplifications for entries below. */ 2167 2168 enum { 2169 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS, 2170 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC 2171 }; 2172 2173 /* This table occasionally claims that a processor does not support 2174 a particular feature even though it does, but the feature is slower 2175 than the alternative. Thus, it shouldn't be relied on as a 2176 complete description of the processor's support. 2177 2178 Please keep this list in order, and don't forget to update the 2179 documentation in invoke.texi when adding a new processor or 2180 flag. */ 2181 static struct ptt 2182 { 2183 const char *const name; /* Canonical processor name. */ 2184 const enum processor_type processor; /* Processor type enum value. */ 2185 const int target_enable; /* Target flags to enable. */ 2186 } const processor_target_table[] 2187 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, 2188 {"403", PROCESSOR_PPC403, 2189 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN}, 2190 {"405", PROCESSOR_PPC405, 2191 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB}, 2192 {"405fp", PROCESSOR_PPC405, 2193 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB}, 2194 {"440", PROCESSOR_PPC440, 2195 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB}, 2196 {"440fp", PROCESSOR_PPC440, 2197 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB}, 2198 {"464", PROCESSOR_PPC440, 2199 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB}, 2200 {"464fp", PROCESSOR_PPC440, 2201 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB}, 2202 {"476", PROCESSOR_PPC476, 2203 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF 2204 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB}, 2205 {"476fp", PROCESSOR_PPC476, 2206 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB 2207 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB}, 2208 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK}, 2209 {"601", PROCESSOR_PPC601, 2210 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING}, 2211 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT}, 2212 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT}, 2213 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT}, 2214 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT}, 2215 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT}, 2216 {"620", PROCESSOR_PPC620, 2217 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}, 2218 {"630", PROCESSOR_PPC630, 2219 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}, 2220 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT}, 2221 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK}, 2222 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK}, 2223 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT}, 2224 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, 2225 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, 2226 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, 2227 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN 2228 | MASK_ISEL}, 2229 /* 8548 has a dummy entry for now. */ 2230 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN 2231 | MASK_ISEL}, 2232 {"a2", PROCESSOR_PPCA2, 2233 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB 2234 | MASK_CMPB | MASK_NO_UPDATE }, 2235 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, 2236 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK}, 2237 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT 2238 | MASK_ISEL}, 2239 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64 2240 | MASK_PPC_GFXOPT | MASK_ISEL}, 2241 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, 2242 {"970", PROCESSOR_POWER4, 2243 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64}, 2244 {"cell", PROCESSOR_CELL, 2245 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64}, 2246 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS}, 2247 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, 2248 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT}, 2249 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK}, 2250 {"G5", PROCESSOR_POWER4, 2251 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64}, 2252 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING}, 2253 {"power2", PROCESSOR_POWER, 2254 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING}, 2255 {"power3", PROCESSOR_PPC630, 2256 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}, 2257 {"power4", PROCESSOR_POWER4, 2258 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT 2259 | MASK_MFCRF}, 2260 {"power5", PROCESSOR_POWER5, 2261 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT 2262 | MASK_MFCRF | MASK_POPCNTB}, 2263 {"power5+", PROCESSOR_POWER5, 2264 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT 2265 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND}, 2266 {"power6", PROCESSOR_POWER6, 2267 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT 2268 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP}, 2269 {"power6x", PROCESSOR_POWER6, 2270 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT 2271 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP 2272 | MASK_MFPGPR}, 2273 {"power7", PROCESSOR_POWER7, 2274 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF 2275 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD 2276 | MASK_VSX}, /* Don't add MASK_ISEL by default */ 2277 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK}, 2278 {"powerpc64", PROCESSOR_POWERPC64, 2279 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}, 2280 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING}, 2281 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING}, 2282 {"rios2", PROCESSOR_RIOS2, 2283 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING}, 2284 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING}, 2285 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING}, 2286 {"rs64", PROCESSOR_RS64A, 2287 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64} 2288 }; 2289 2290 const size_t ptt_size = ARRAY_SIZE (processor_target_table); 2291 2292 /* Some OSs don't support saving the high part of 64-bit registers on 2293 context switch. Other OSs don't support saving Altivec registers. 2294 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC 2295 settings; if the user wants either, the user must explicitly specify 2296 them and we won't interfere with the user's specification. */ 2297 2298 enum { 2299 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING, 2300 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN 2301 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC 2302 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW 2303 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP 2304 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE) 2305 }; 2306 2307 /* Numerous experiment shows that IRA based loop pressure 2308 calculation works better for RTL loop invariant motion on targets 2309 with enough (>= 32) registers. It is an expensive optimization. 2310 So it is on only for peak performance. */ 2311 if (optimize >= 3) 2312 flag_ira_loop_pressure = 1; 2313 2314 /* Set the pointer size. */ 2315 if (TARGET_64BIT) 2316 { 2317 rs6000_pmode = (int)DImode; 2318 rs6000_pointer_size = 64; 2319 } 2320 else 2321 { 2322 rs6000_pmode = (int)SImode; 2323 rs6000_pointer_size = 32; 2324 } 2325 2326 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT; 2327#ifdef OS_MISSING_POWERPC64 2328 if (OS_MISSING_POWERPC64) 2329 set_masks &= ~MASK_POWERPC64; 2330#endif 2331#ifdef OS_MISSING_ALTIVEC 2332 if (OS_MISSING_ALTIVEC) 2333 set_masks &= ~MASK_ALTIVEC; 2334#endif 2335 2336 /* Don't override by the processor default if given explicitly. */ 2337 set_masks &= ~target_flags_explicit; 2338 2339 /* Identify the processor type. */ 2340 rs6000_select[0].string = default_cpu; 2341 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT; 2342 2343 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++) 2344 { 2345 ptr = &rs6000_select[i]; 2346 if (ptr->string != (char *)0 && ptr->string[0] != '\0') 2347 { 2348 for (j = 0; j < ptt_size; j++) 2349 if (! strcmp (ptr->string, processor_target_table[j].name)) 2350 { 2351 if (ptr->set_tune_p) 2352 rs6000_cpu = processor_target_table[j].processor; 2353 2354 if (ptr->set_arch_p) 2355 { 2356 target_flags &= ~set_masks; 2357 target_flags |= (processor_target_table[j].target_enable 2358 & set_masks); 2359 } 2360 break; 2361 } 2362 2363 if (j == ptt_size) 2364 error ("bad value (%s) for %s switch", ptr->string, ptr->name); 2365 } 2366 } 2367 2368 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3 2369 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64) 2370 { 2371 if (TARGET_ALTIVEC) 2372 error ("AltiVec not supported in this target"); 2373 if (TARGET_SPE) 2374 error ("Spe not supported in this target"); 2375 } 2376 2377 /* Disable Cell microcode if we are optimizing for the Cell 2378 and not optimizing for size. */ 2379 if (rs6000_gen_cell_microcode == -1) 2380 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL 2381 && !optimize_size); 2382 2383 /* If we are optimizing big endian systems for space and it's OK to 2384 use instructions that would be microcoded on the Cell, use the 2385 load/store multiple and string instructions. */ 2386 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode) 2387 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING); 2388 2389 /* Don't allow -mmultiple or -mstring on little endian systems 2390 unless the cpu is a 750, because the hardware doesn't support the 2391 instructions used in little endian mode, and causes an alignment 2392 trap. The 750 does not cause an alignment trap (except when the 2393 target is unaligned). */ 2394 2395 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750) 2396 { 2397 if (TARGET_MULTIPLE) 2398 { 2399 target_flags &= ~MASK_MULTIPLE; 2400 if ((target_flags_explicit & MASK_MULTIPLE) != 0) 2401 warning (0, "-mmultiple is not supported on little endian systems"); 2402 } 2403 2404 if (TARGET_STRING) 2405 { 2406 target_flags &= ~MASK_STRING; 2407 if ((target_flags_explicit & MASK_STRING) != 0) 2408 warning (0, "-mstring is not supported on little endian systems"); 2409 } 2410 } 2411 2412 /* Add some warnings for VSX. */ 2413 if (TARGET_VSX) 2414 { 2415 const char *msg = NULL; 2416 if (!TARGET_HARD_FLOAT || !TARGET_FPRS 2417 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT) 2418 { 2419 if (target_flags_explicit & MASK_VSX) 2420 msg = N_("-mvsx requires hardware floating point"); 2421 else 2422 target_flags &= ~ MASK_VSX; 2423 } 2424 else if (TARGET_PAIRED_FLOAT) 2425 msg = N_("-mvsx and -mpaired are incompatible"); 2426 /* The hardware will allow VSX and little endian, but until we make sure 2427 things like vector select, etc. work don't allow VSX on little endian 2428 systems at this point. */ 2429 else if (!BYTES_BIG_ENDIAN) 2430 msg = N_("-mvsx used with little endian code"); 2431 else if (TARGET_AVOID_XFORM > 0) 2432 msg = N_("-mvsx needs indexed addressing"); 2433 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC)) 2434 { 2435 if (target_flags_explicit & MASK_VSX) 2436 msg = N_("-mvsx and -mno-altivec are incompatible"); 2437 else 2438 msg = N_("-mno-altivec disables vsx"); 2439 } 2440 2441 if (msg) 2442 { 2443 warning (0, msg); 2444 target_flags &= ~ MASK_VSX; 2445 } 2446 else if (TARGET_VSX && !TARGET_ALTIVEC) 2447 target_flags |= MASK_ALTIVEC; 2448 } 2449 2450 /* Set debug flags */ 2451 if (rs6000_debug_name) 2452 { 2453 if (! strcmp (rs6000_debug_name, "all")) 2454 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg 2455 = rs6000_debug_addr = rs6000_debug_cost = 1; 2456 else if (! strcmp (rs6000_debug_name, "stack")) 2457 rs6000_debug_stack = 1; 2458 else if (! strcmp (rs6000_debug_name, "arg")) 2459 rs6000_debug_arg = 1; 2460 else if (! strcmp (rs6000_debug_name, "reg")) 2461 rs6000_debug_reg = 1; 2462 else if (! strcmp (rs6000_debug_name, "addr")) 2463 rs6000_debug_addr = 1; 2464 else if (! strcmp (rs6000_debug_name, "cost")) 2465 rs6000_debug_cost = 1; 2466 else 2467 error ("unknown -mdebug-%s switch", rs6000_debug_name); 2468 2469 /* If the appropriate debug option is enabled, replace the target hooks 2470 with debug versions that call the real version and then prints 2471 debugging information. */ 2472 if (TARGET_DEBUG_COST) 2473 { 2474 targetm.rtx_costs = rs6000_debug_rtx_costs; 2475 targetm.address_cost = rs6000_debug_address_cost; 2476 targetm.sched.adjust_cost = rs6000_debug_adjust_cost; 2477 } 2478 2479 if (TARGET_DEBUG_ADDR) 2480 { 2481 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p; 2482 targetm.legitimize_address = rs6000_debug_legitimize_address; 2483 rs6000_secondary_reload_class_ptr 2484 = rs6000_debug_secondary_reload_class; 2485 rs6000_secondary_memory_needed_ptr 2486 = rs6000_debug_secondary_memory_needed; 2487 rs6000_cannot_change_mode_class_ptr 2488 = rs6000_debug_cannot_change_mode_class; 2489 rs6000_preferred_reload_class_ptr 2490 = rs6000_debug_preferred_reload_class; 2491 rs6000_legitimize_reload_address_ptr 2492 = rs6000_debug_legitimize_reload_address; 2493 rs6000_mode_dependent_address_ptr 2494 = rs6000_debug_mode_dependent_address; 2495 } 2496 } 2497 2498 if (rs6000_traceback_name) 2499 { 2500 if (! strncmp (rs6000_traceback_name, "full", 4)) 2501 rs6000_traceback = traceback_full; 2502 else if (! strncmp (rs6000_traceback_name, "part", 4)) 2503 rs6000_traceback = traceback_part; 2504 else if (! strncmp (rs6000_traceback_name, "no", 2)) 2505 rs6000_traceback = traceback_none; 2506 else 2507 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>", 2508 rs6000_traceback_name); 2509 } 2510 2511 if (!rs6000_explicit_options.long_double) 2512 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE; 2513 2514#if !defined(POWERPC_LINUX) && !defined(POWERPC_NETBSD) 2515 if (!rs6000_explicit_options.ieee) 2516 rs6000_ieeequad = 1; 2517#endif 2518 2519 /* Enable Altivec ABI for AIX -maltivec. */ 2520 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX)) 2521 rs6000_altivec_abi = 1; 2522 2523 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For 2524 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can 2525 be explicitly overridden in either case. */ 2526 if (TARGET_ELF) 2527 { 2528 if (!rs6000_explicit_options.altivec_abi 2529 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX)) 2530 rs6000_altivec_abi = 1; 2531 2532 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */ 2533 if (!rs6000_explicit_options.vrsave) 2534 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi; 2535 } 2536 2537 /* Set the Darwin64 ABI as default for 64-bit Darwin. */ 2538 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT) 2539 { 2540 rs6000_darwin64_abi = 1; 2541#if TARGET_MACHO 2542 darwin_one_byte_bool = 1; 2543#endif 2544 /* Default to natural alignment, for better performance. */ 2545 rs6000_alignment_flags = MASK_ALIGN_NATURAL; 2546 } 2547 2548 /* Place FP constants in the constant pool instead of TOC 2549 if section anchors enabled. */ 2550 if (flag_section_anchors) 2551 TARGET_NO_FP_IN_TOC = 1; 2552 2553 /* Handle -mtls-size option. */ 2554 rs6000_parse_tls_size_option (); 2555 2556#ifdef SUBTARGET_OVERRIDE_OPTIONS 2557 SUBTARGET_OVERRIDE_OPTIONS; 2558#endif 2559#ifdef SUBSUBTARGET_OVERRIDE_OPTIONS 2560 SUBSUBTARGET_OVERRIDE_OPTIONS; 2561#endif 2562#ifdef SUB3TARGET_OVERRIDE_OPTIONS 2563 SUB3TARGET_OVERRIDE_OPTIONS; 2564#endif 2565 2566 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC 2567 || rs6000_cpu == PROCESSOR_PPCE500MC64) 2568 { 2569 /* The e500 and e500mc do not have string instructions, and we set 2570 MASK_STRING above when optimizing for size. */ 2571 if ((target_flags & MASK_STRING) != 0) 2572 target_flags = target_flags & ~MASK_STRING; 2573 } 2574 else if (rs6000_select[1].string != NULL) 2575 { 2576 /* For the powerpc-eabispe configuration, we set all these by 2577 default, so let's unset them if we manually set another 2578 CPU that is not the E500. */ 2579 if (!rs6000_explicit_options.spe_abi) 2580 rs6000_spe_abi = 0; 2581 if (!rs6000_explicit_options.spe) 2582 rs6000_spe = 0; 2583 if (!rs6000_explicit_options.float_gprs) 2584 rs6000_float_gprs = 0; 2585 if (!(target_flags_explicit & MASK_ISEL)) 2586 target_flags &= ~MASK_ISEL; 2587 } 2588 2589 /* Detect invalid option combinations with E500. */ 2590 CHECK_E500_OPTIONS; 2591 2592 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4 2593 && rs6000_cpu != PROCESSOR_POWER5 2594 && rs6000_cpu != PROCESSOR_POWER6 2595 && rs6000_cpu != PROCESSOR_POWER7 2596 && rs6000_cpu != PROCESSOR_PPCA2 2597 && rs6000_cpu != PROCESSOR_CELL); 2598 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4 2599 || rs6000_cpu == PROCESSOR_POWER5 2600 || rs6000_cpu == PROCESSOR_POWER7); 2601 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4 2602 || rs6000_cpu == PROCESSOR_POWER5 2603 || rs6000_cpu == PROCESSOR_POWER6 2604 || rs6000_cpu == PROCESSOR_POWER7 2605 || rs6000_cpu == PROCESSOR_PPCE500MC 2606 || rs6000_cpu == PROCESSOR_PPCE500MC64); 2607 2608 /* Allow debug switches to override the above settings. */ 2609 if (TARGET_ALWAYS_HINT > 0) 2610 rs6000_always_hint = TARGET_ALWAYS_HINT; 2611 2612 if (TARGET_SCHED_GROUPS > 0) 2613 rs6000_sched_groups = TARGET_SCHED_GROUPS; 2614 2615 if (TARGET_ALIGN_BRANCH_TARGETS > 0) 2616 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS; 2617 2618 rs6000_sched_restricted_insns_priority 2619 = (rs6000_sched_groups ? 1 : 0); 2620 2621 /* Handle -msched-costly-dep option. */ 2622 rs6000_sched_costly_dep 2623 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly); 2624 2625 if (rs6000_sched_costly_dep_str) 2626 { 2627 if (! strcmp (rs6000_sched_costly_dep_str, "no")) 2628 rs6000_sched_costly_dep = no_dep_costly; 2629 else if (! strcmp (rs6000_sched_costly_dep_str, "all")) 2630 rs6000_sched_costly_dep = all_deps_costly; 2631 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load")) 2632 rs6000_sched_costly_dep = true_store_to_load_dep_costly; 2633 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load")) 2634 rs6000_sched_costly_dep = store_to_load_dep_costly; 2635 else 2636 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost) 2637 atoi (rs6000_sched_costly_dep_str)); 2638 } 2639 2640 /* Handle -minsert-sched-nops option. */ 2641 rs6000_sched_insert_nops 2642 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none); 2643 2644 if (rs6000_sched_insert_nops_str) 2645 { 2646 if (! strcmp (rs6000_sched_insert_nops_str, "no")) 2647 rs6000_sched_insert_nops = sched_finish_none; 2648 else if (! strcmp (rs6000_sched_insert_nops_str, "pad")) 2649 rs6000_sched_insert_nops = sched_finish_pad_groups; 2650 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact")) 2651 rs6000_sched_insert_nops = sched_finish_regroup_exact; 2652 else 2653 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion) 2654 atoi (rs6000_sched_insert_nops_str)); 2655 } 2656 2657#ifdef TARGET_REGNAMES 2658 /* If the user desires alternate register names, copy in the 2659 alternate names now. */ 2660 if (TARGET_REGNAMES) 2661 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names)); 2662#endif 2663 2664 /* Set aix_struct_return last, after the ABI is determined. 2665 If -maix-struct-return or -msvr4-struct-return was explicitly 2666 used, don't override with the ABI default. */ 2667 if (!rs6000_explicit_options.aix_struct_ret) 2668 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET); 2669 2670 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD) 2671 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format; 2672 2673 if (TARGET_TOC) 2674 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1); 2675 2676 /* We can only guarantee the availability of DI pseudo-ops when 2677 assembling for 64-bit targets. */ 2678 if (!TARGET_64BIT) 2679 { 2680 targetm.asm_out.aligned_op.di = NULL; 2681 targetm.asm_out.unaligned_op.di = NULL; 2682 } 2683 2684 /* Set branch target alignment, if not optimizing for size. */ 2685 if (!optimize_size) 2686 { 2687 /* Cell wants to be aligned 8byte for dual issue. */ 2688 if (rs6000_cpu == PROCESSOR_CELL) 2689 { 2690 if (align_functions <= 0) 2691 align_functions = 8; 2692 if (align_jumps <= 0) 2693 align_jumps = 8; 2694 if (align_loops <= 0) 2695 align_loops = 8; 2696 } 2697 if (rs6000_align_branch_targets) 2698 { 2699 if (align_functions <= 0) 2700 align_functions = 16; 2701 if (align_jumps <= 0) 2702 align_jumps = 16; 2703 if (align_loops <= 0) 2704 align_loops = 16; 2705 } 2706 if (align_jumps_max_skip <= 0) 2707 align_jumps_max_skip = 15; 2708 if (align_loops_max_skip <= 0) 2709 align_loops_max_skip = 15; 2710 } 2711 2712 /* Arrange to save and restore machine status around nested functions. */ 2713 init_machine_status = rs6000_init_machine_status; 2714 2715 /* We should always be splitting complex arguments, but we can't break 2716 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */ 2717 if (DEFAULT_ABI != ABI_AIX) 2718 targetm.calls.split_complex_arg = NULL; 2719 2720 /* Initialize rs6000_cost with the appropriate target costs. */ 2721 if (optimize_size) 2722 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost; 2723 else 2724 switch (rs6000_cpu) 2725 { 2726 case PROCESSOR_RIOS1: 2727 rs6000_cost = &rios1_cost; 2728 break; 2729 2730 case PROCESSOR_RIOS2: 2731 rs6000_cost = &rios2_cost; 2732 break; 2733 2734 case PROCESSOR_RS64A: 2735 rs6000_cost = &rs64a_cost; 2736 break; 2737 2738 case PROCESSOR_MPCCORE: 2739 rs6000_cost = &mpccore_cost; 2740 break; 2741 2742 case PROCESSOR_PPC403: 2743 rs6000_cost = &ppc403_cost; 2744 break; 2745 2746 case PROCESSOR_PPC405: 2747 rs6000_cost = &ppc405_cost; 2748 break; 2749 2750 case PROCESSOR_PPC440: 2751 rs6000_cost = &ppc440_cost; 2752 break; 2753 2754 case PROCESSOR_PPC476: 2755 rs6000_cost = &ppc476_cost; 2756 break; 2757 2758 case PROCESSOR_PPC601: 2759 rs6000_cost = &ppc601_cost; 2760 break; 2761 2762 case PROCESSOR_PPC603: 2763 rs6000_cost = &ppc603_cost; 2764 break; 2765 2766 case PROCESSOR_PPC604: 2767 rs6000_cost = &ppc604_cost; 2768 break; 2769 2770 case PROCESSOR_PPC604e: 2771 rs6000_cost = &ppc604e_cost; 2772 break; 2773 2774 case PROCESSOR_PPC620: 2775 rs6000_cost = &ppc620_cost; 2776 break; 2777 2778 case PROCESSOR_PPC630: 2779 rs6000_cost = &ppc630_cost; 2780 break; 2781 2782 case PROCESSOR_CELL: 2783 rs6000_cost = &ppccell_cost; 2784 break; 2785 2786 case PROCESSOR_PPC750: 2787 case PROCESSOR_PPC7400: 2788 rs6000_cost = &ppc750_cost; 2789 break; 2790 2791 case PROCESSOR_PPC7450: 2792 rs6000_cost = &ppc7450_cost; 2793 break; 2794 2795 case PROCESSOR_PPC8540: 2796 rs6000_cost = &ppc8540_cost; 2797 break; 2798 2799 case PROCESSOR_PPCE300C2: 2800 case PROCESSOR_PPCE300C3: 2801 rs6000_cost = &ppce300c2c3_cost; 2802 break; 2803 2804 case PROCESSOR_PPCE500MC: 2805 rs6000_cost = &ppce500mc_cost; 2806 break; 2807 2808 case PROCESSOR_PPCE500MC64: 2809 rs6000_cost = &ppce500mc64_cost; 2810 break; 2811 2812 case PROCESSOR_POWER4: 2813 case PROCESSOR_POWER5: 2814 rs6000_cost = &power4_cost; 2815 break; 2816 2817 case PROCESSOR_POWER6: 2818 rs6000_cost = &power6_cost; 2819 break; 2820 2821 case PROCESSOR_POWER7: 2822 rs6000_cost = &power7_cost; 2823 break; 2824 2825 case PROCESSOR_PPCA2: 2826 rs6000_cost = &ppca2_cost; 2827 break; 2828 2829 default: 2830 gcc_unreachable (); 2831 } 2832 2833 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES)) 2834 set_param_value ("simultaneous-prefetches", 2835 rs6000_cost->simultaneous_prefetches); 2836 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE)) 2837 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size); 2838 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE)) 2839 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size); 2840 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE)) 2841 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size); 2842 2843 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0) 2844 can be optimized to ap = __builtin_next_arg (0). */ 2845 if (DEFAULT_ABI != ABI_V4) 2846 targetm.expand_builtin_va_start = NULL; 2847 2848 /* Set up single/double float flags. 2849 If TARGET_HARD_FLOAT is set, but neither single or double is set, 2850 then set both flags. */ 2851 if (TARGET_HARD_FLOAT && TARGET_FPRS 2852 && rs6000_single_float == 0 && rs6000_double_float == 0) 2853 rs6000_single_float = rs6000_double_float = 1; 2854 2855 /* Reset single and double FP flags if target is E500. */ 2856 if (TARGET_E500) 2857 { 2858 rs6000_single_float = rs6000_double_float = 0; 2859 if (TARGET_E500_SINGLE) 2860 rs6000_single_float = 1; 2861 if (TARGET_E500_DOUBLE) 2862 rs6000_single_float = rs6000_double_float = 1; 2863 } 2864 2865 /* If not explicitly specified via option, decide whether to generate indexed 2866 load/store instructions. */ 2867 if (TARGET_AVOID_XFORM == -1) 2868 /* Avoid indexed addressing when targeting Power6 in order to avoid the 2869 DERAT mispredict penalty. However the LVE and STVE altivec instructions 2870 need indexed accesses and the type used is the scalar type of the element 2871 being loaded or stored. */ 2872 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB 2873 && !TARGET_ALTIVEC); 2874 2875 rs6000_init_hard_regno_mode_ok (); 2876} 2877 2878/* Implement targetm.vectorize.builtin_mask_for_load. */ 2879static tree 2880rs6000_builtin_mask_for_load (void) 2881{ 2882 if (TARGET_ALTIVEC || TARGET_VSX) 2883 return altivec_builtin_mask_for_load; 2884 else 2885 return 0; 2886} 2887 2888/* Implement targetm.vectorize.builtin_conversion. 2889 Returns a decl of a function that implements conversion of an integer vector 2890 into a floating-point vector, or vice-versa. TYPE is the type of the integer 2891 side of the conversion. 2892 Return NULL_TREE if it is not available. */ 2893static tree 2894rs6000_builtin_conversion (unsigned int tcode, tree type) 2895{ 2896 enum tree_code code = (enum tree_code) tcode; 2897 2898 switch (code) 2899 { 2900 case FIX_TRUNC_EXPR: 2901 switch (TYPE_MODE (type)) 2902 { 2903 case V2DImode: 2904 if (!VECTOR_UNIT_VSX_P (V2DFmode)) 2905 return NULL_TREE; 2906 2907 return TYPE_UNSIGNED (type) 2908 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS] 2909 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS]; 2910 2911 case V4SImode: 2912 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode)) 2913 return NULL_TREE; 2914 2915 return TYPE_UNSIGNED (type) 2916 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI] 2917 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI]; 2918 2919 default: 2920 return NULL_TREE; 2921 } 2922 2923 case FLOAT_EXPR: 2924 switch (TYPE_MODE (type)) 2925 { 2926 case V2DImode: 2927 if (!VECTOR_UNIT_VSX_P (V2DFmode)) 2928 return NULL_TREE; 2929 2930 return TYPE_UNSIGNED (type) 2931 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP] 2932 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP]; 2933 2934 case V4SImode: 2935 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode)) 2936 return NULL_TREE; 2937 2938 return TYPE_UNSIGNED (type) 2939 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF] 2940 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF]; 2941 2942 default: 2943 return NULL_TREE; 2944 } 2945 2946 default: 2947 return NULL_TREE; 2948 } 2949} 2950 2951/* Implement targetm.vectorize.builtin_mul_widen_even. */ 2952static tree 2953rs6000_builtin_mul_widen_even (tree type) 2954{ 2955 if (!TARGET_ALTIVEC) 2956 return NULL_TREE; 2957 2958 switch (TYPE_MODE (type)) 2959 { 2960 case V8HImode: 2961 return TYPE_UNSIGNED (type) 2962 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS] 2963 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH]; 2964 2965 case V16QImode: 2966 return TYPE_UNSIGNED (type) 2967 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS] 2968 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB]; 2969 default: 2970 return NULL_TREE; 2971 } 2972} 2973 2974/* Implement targetm.vectorize.builtin_mul_widen_odd. */ 2975static tree 2976rs6000_builtin_mul_widen_odd (tree type) 2977{ 2978 if (!TARGET_ALTIVEC) 2979 return NULL_TREE; 2980 2981 switch (TYPE_MODE (type)) 2982 { 2983 case V8HImode: 2984 return TYPE_UNSIGNED (type) 2985 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS] 2986 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH]; 2987 2988 case V16QImode: 2989 return TYPE_UNSIGNED (type) 2990 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS] 2991 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB]; 2992 default: 2993 return NULL_TREE; 2994 } 2995} 2996 2997 2998/* Return true iff, data reference of TYPE can reach vector alignment (16) 2999 after applying N number of iterations. This routine does not determine 3000 how may iterations are required to reach desired alignment. */ 3001 3002static bool 3003rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed) 3004{ 3005 if (is_packed) 3006 return false; 3007 3008 if (TARGET_32BIT) 3009 { 3010 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL) 3011 return true; 3012 3013 if (rs6000_alignment_flags == MASK_ALIGN_POWER) 3014 return true; 3015 3016 return false; 3017 } 3018 else 3019 { 3020 if (TARGET_MACHO) 3021 return false; 3022 3023 /* Assuming that all other types are naturally aligned. CHECKME! */ 3024 return true; 3025 } 3026} 3027 3028/* Return true if the vector misalignment factor is supported by the 3029 target. */ 3030bool 3031rs6000_builtin_support_vector_misalignment (enum machine_mode mode, 3032 const_tree type, 3033 int misalignment, 3034 bool is_packed) 3035{ 3036 if (TARGET_VSX) 3037 { 3038 /* Return if movmisalign pattern is not supported for this mode. */ 3039 if (optab_handler (movmisalign_optab, mode)->insn_code == 3040 CODE_FOR_nothing) 3041 return false; 3042 3043 if (misalignment == -1) 3044 { 3045 /* misalignment factor is unknown at compile time but we know 3046 it's word aligned. */ 3047 if (rs6000_vector_alignment_reachable (type, is_packed)) 3048 return true; 3049 return false; 3050 } 3051 /* VSX supports word-aligned vector. */ 3052 if (misalignment % 4 == 0) 3053 return true; 3054 } 3055 return false; 3056} 3057 3058/* Implement targetm.vectorize.builtin_vec_perm. */ 3059tree 3060rs6000_builtin_vec_perm (tree type, tree *mask_element_type) 3061{ 3062 tree inner_type = TREE_TYPE (type); 3063 bool uns_p = TYPE_UNSIGNED (inner_type); 3064 tree d; 3065 3066 *mask_element_type = unsigned_char_type_node; 3067 3068 switch (TYPE_MODE (type)) 3069 { 3070 case V16QImode: 3071 d = (uns_p 3072 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS] 3073 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]); 3074 break; 3075 3076 case V8HImode: 3077 d = (uns_p 3078 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS] 3079 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]); 3080 break; 3081 3082 case V4SImode: 3083 d = (uns_p 3084 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS] 3085 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]); 3086 break; 3087 3088 case V4SFmode: 3089 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF]; 3090 break; 3091 3092 case V2DFmode: 3093 if (!TARGET_ALLOW_DF_PERMUTE) 3094 return NULL_TREE; 3095 3096 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF]; 3097 break; 3098 3099 case V2DImode: 3100 if (!TARGET_ALLOW_DF_PERMUTE) 3101 return NULL_TREE; 3102 3103 d = (uns_p 3104 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS] 3105 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]); 3106 break; 3107 3108 default: 3109 return NULL_TREE; 3110 } 3111 3112 gcc_assert (d); 3113 return d; 3114} 3115 3116/* Handle generic options of the form -mfoo=yes/no. 3117 NAME is the option name. 3118 VALUE is the option value. 3119 FLAG is the pointer to the flag where to store a 1 or 0, depending on 3120 whether the option value is 'yes' or 'no' respectively. */ 3121static void 3122rs6000_parse_yes_no_option (const char *name, const char *value, int *flag) 3123{ 3124 if (value == 0) 3125 return; 3126 else if (!strcmp (value, "yes")) 3127 *flag = 1; 3128 else if (!strcmp (value, "no")) 3129 *flag = 0; 3130 else 3131 error ("unknown -m%s= option specified: '%s'", name, value); 3132} 3133 3134/* Validate and record the size specified with the -mtls-size option. */ 3135 3136static void 3137rs6000_parse_tls_size_option (void) 3138{ 3139 if (rs6000_tls_size_string == 0) 3140 return; 3141 else if (strcmp (rs6000_tls_size_string, "16") == 0) 3142 rs6000_tls_size = 16; 3143 else if (strcmp (rs6000_tls_size_string, "32") == 0) 3144 rs6000_tls_size = 32; 3145 else if (strcmp (rs6000_tls_size_string, "64") == 0) 3146 rs6000_tls_size = 64; 3147 else 3148 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string); 3149} 3150 3151void 3152optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED) 3153{ 3154 if (DEFAULT_ABI == ABI_DARWIN) 3155 /* The Darwin libraries never set errno, so we might as well 3156 avoid calling them when that's the only reason we would. */ 3157 flag_errno_math = 0; 3158 3159 /* Double growth factor to counter reduced min jump length. */ 3160 set_param_value ("max-grow-copy-bb-insns", 16); 3161 3162 /* Enable section anchors by default. 3163 Skip section anchors for Objective C and Objective C++ 3164 until front-ends fixed. */ 3165 if (!TARGET_MACHO && lang_hooks.name[4] != 'O') 3166 flag_section_anchors = 2; 3167} 3168 3169static enum fpu_type_t 3170rs6000_parse_fpu_option (const char *option) 3171{ 3172 if (!strcmp("none", option)) return FPU_NONE; 3173 if (!strcmp("sp_lite", option)) return FPU_SF_LITE; 3174 if (!strcmp("dp_lite", option)) return FPU_DF_LITE; 3175 if (!strcmp("sp_full", option)) return FPU_SF_FULL; 3176 if (!strcmp("dp_full", option)) return FPU_DF_FULL; 3177 error("unknown value %s for -mfpu", option); 3178 return FPU_NONE; 3179} 3180 3181/* Returns a function decl for a vectorized version of the builtin function 3182 with builtin function code FN and the result vector type TYPE, or NULL_TREE 3183 if it is not available. */ 3184 3185static tree 3186rs6000_builtin_vectorized_function (tree fndecl, tree type_out, 3187 tree type_in) 3188{ 3189 enum machine_mode in_mode, out_mode; 3190 int in_n, out_n; 3191 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl); 3192 3193 if (TREE_CODE (type_out) != VECTOR_TYPE 3194 || TREE_CODE (type_in) != VECTOR_TYPE 3195 || !TARGET_VECTORIZE_BUILTINS 3196 || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL) 3197 return NULL_TREE; 3198 3199 out_mode = TYPE_MODE (TREE_TYPE (type_out)); 3200 out_n = TYPE_VECTOR_SUBPARTS (type_out); 3201 in_mode = TYPE_MODE (TREE_TYPE (type_in)); 3202 in_n = TYPE_VECTOR_SUBPARTS (type_in); 3203 3204 switch (fn) 3205 { 3206 case BUILT_IN_COPYSIGN: 3207 if (VECTOR_UNIT_VSX_P (V2DFmode) 3208 && out_mode == DFmode && out_n == 2 3209 && in_mode == DFmode && in_n == 2) 3210 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP]; 3211 break; 3212 case BUILT_IN_COPYSIGNF: 3213 if (out_mode != SFmode || out_n != 4 3214 || in_mode != SFmode || in_n != 4) 3215 break; 3216 if (VECTOR_UNIT_VSX_P (V4SFmode)) 3217 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP]; 3218 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)) 3219 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF]; 3220 break; 3221 case BUILT_IN_SQRT: 3222 if (VECTOR_UNIT_VSX_P (V2DFmode) 3223 && out_mode == DFmode && out_n == 2 3224 && in_mode == DFmode && in_n == 2) 3225 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP]; 3226 break; 3227 case BUILT_IN_SQRTF: 3228 if (VECTOR_UNIT_VSX_P (V4SFmode) 3229 && out_mode == SFmode && out_n == 4 3230 && in_mode == SFmode && in_n == 4) 3231 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP]; 3232 break; 3233 case BUILT_IN_CEIL: 3234 if (VECTOR_UNIT_VSX_P (V2DFmode) 3235 && out_mode == DFmode && out_n == 2 3236 && in_mode == DFmode && in_n == 2) 3237 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP]; 3238 break; 3239 case BUILT_IN_CEILF: 3240 if (out_mode != SFmode || out_n != 4 3241 || in_mode != SFmode || in_n != 4) 3242 break; 3243 if (VECTOR_UNIT_VSX_P (V4SFmode)) 3244 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP]; 3245 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)) 3246 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP]; 3247 break; 3248 case BUILT_IN_FLOOR: 3249 if (VECTOR_UNIT_VSX_P (V2DFmode) 3250 && out_mode == DFmode && out_n == 2 3251 && in_mode == DFmode && in_n == 2) 3252 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM]; 3253 break; 3254 case BUILT_IN_FLOORF: 3255 if (out_mode != SFmode || out_n != 4 3256 || in_mode != SFmode || in_n != 4) 3257 break; 3258 if (VECTOR_UNIT_VSX_P (V4SFmode)) 3259 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM]; 3260 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)) 3261 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM]; 3262 break; 3263 case BUILT_IN_TRUNC: 3264 if (VECTOR_UNIT_VSX_P (V2DFmode) 3265 && out_mode == DFmode && out_n == 2 3266 && in_mode == DFmode && in_n == 2) 3267 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ]; 3268 break; 3269 case BUILT_IN_TRUNCF: 3270 if (out_mode != SFmode || out_n != 4 3271 || in_mode != SFmode || in_n != 4) 3272 break; 3273 if (VECTOR_UNIT_VSX_P (V4SFmode)) 3274 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ]; 3275 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)) 3276 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ]; 3277 break; 3278 case BUILT_IN_NEARBYINT: 3279 if (VECTOR_UNIT_VSX_P (V2DFmode) 3280 && flag_unsafe_math_optimizations 3281 && out_mode == DFmode && out_n == 2 3282 && in_mode == DFmode && in_n == 2) 3283 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI]; 3284 break; 3285 case BUILT_IN_NEARBYINTF: 3286 if (VECTOR_UNIT_VSX_P (V4SFmode) 3287 && flag_unsafe_math_optimizations 3288 && out_mode == SFmode && out_n == 4 3289 && in_mode == SFmode && in_n == 4) 3290 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI]; 3291 break; 3292 case BUILT_IN_RINT: 3293 if (VECTOR_UNIT_VSX_P (V2DFmode) 3294 && !flag_trapping_math 3295 && out_mode == DFmode && out_n == 2 3296 && in_mode == DFmode && in_n == 2) 3297 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC]; 3298 break; 3299 case BUILT_IN_RINTF: 3300 if (VECTOR_UNIT_VSX_P (V4SFmode) 3301 && !flag_trapping_math 3302 && out_mode == SFmode && out_n == 4 3303 && in_mode == SFmode && in_n == 4) 3304 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC]; 3305 break; 3306 default: 3307 break; 3308 } 3309 return NULL_TREE; 3310} 3311 3312 3313/* Implement TARGET_HANDLE_OPTION. */ 3314 3315static bool 3316rs6000_handle_option (size_t code, const char *arg, int value) 3317{ 3318 enum fpu_type_t fpu_type = FPU_NONE; 3319 int isel; 3320 3321 switch (code) 3322 { 3323 case OPT_mno_power: 3324 target_flags &= ~(MASK_POWER | MASK_POWER2 3325 | MASK_MULTIPLE | MASK_STRING); 3326 target_flags_explicit |= (MASK_POWER | MASK_POWER2 3327 | MASK_MULTIPLE | MASK_STRING); 3328 break; 3329 case OPT_mno_powerpc: 3330 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT 3331 | MASK_PPC_GFXOPT | MASK_POWERPC64); 3332 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT 3333 | MASK_PPC_GFXOPT | MASK_POWERPC64); 3334 break; 3335 case OPT_mfull_toc: 3336 target_flags &= ~MASK_MINIMAL_TOC; 3337 TARGET_NO_FP_IN_TOC = 0; 3338 TARGET_NO_SUM_IN_TOC = 0; 3339 target_flags_explicit |= MASK_MINIMAL_TOC; 3340#ifdef TARGET_USES_SYSV4_OPT 3341 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be 3342 just the same as -mminimal-toc. */ 3343 target_flags |= MASK_MINIMAL_TOC; 3344 target_flags_explicit |= MASK_MINIMAL_TOC; 3345#endif 3346 break; 3347 3348#ifdef TARGET_USES_SYSV4_OPT 3349 case OPT_mtoc: 3350 /* Make -mtoc behave like -mminimal-toc. */ 3351 target_flags |= MASK_MINIMAL_TOC; 3352 target_flags_explicit |= MASK_MINIMAL_TOC; 3353 break; 3354#endif 3355 3356#ifdef TARGET_USES_AIX64_OPT 3357 case OPT_maix64: 3358#else 3359 case OPT_m64: 3360#endif 3361 target_flags |= MASK_POWERPC64 | MASK_POWERPC; 3362 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT; 3363 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC; 3364 break; 3365 3366#ifdef TARGET_USES_AIX64_OPT 3367 case OPT_maix32: 3368#else 3369 case OPT_m32: 3370#endif 3371 target_flags &= ~MASK_POWERPC64; 3372 target_flags_explicit |= MASK_POWERPC64; 3373 break; 3374 3375 case OPT_minsert_sched_nops_: 3376 rs6000_sched_insert_nops_str = arg; 3377 break; 3378 3379 case OPT_mminimal_toc: 3380 if (value == 1) 3381 { 3382 TARGET_NO_FP_IN_TOC = 0; 3383 TARGET_NO_SUM_IN_TOC = 0; 3384 } 3385 break; 3386 3387 case OPT_mpower: 3388 if (value == 1) 3389 { 3390 target_flags |= (MASK_MULTIPLE | MASK_STRING); 3391 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING); 3392 } 3393 break; 3394 3395 case OPT_mpower2: 3396 if (value == 1) 3397 { 3398 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING); 3399 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING); 3400 } 3401 break; 3402 3403 case OPT_mpowerpc_gpopt: 3404 case OPT_mpowerpc_gfxopt: 3405 if (value == 1) 3406 { 3407 target_flags |= MASK_POWERPC; 3408 target_flags_explicit |= MASK_POWERPC; 3409 } 3410 break; 3411 3412 case OPT_maix_struct_return: 3413 case OPT_msvr4_struct_return: 3414 rs6000_explicit_options.aix_struct_ret = true; 3415 break; 3416 3417 case OPT_mvrsave: 3418 rs6000_explicit_options.vrsave = true; 3419 TARGET_ALTIVEC_VRSAVE = value; 3420 break; 3421 3422 case OPT_mvrsave_: 3423 rs6000_explicit_options.vrsave = true; 3424 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE)); 3425 break; 3426 3427 case OPT_misel_: 3428 target_flags_explicit |= MASK_ISEL; 3429 isel = 0; 3430 rs6000_parse_yes_no_option ("isel", arg, &isel); 3431 if (isel) 3432 target_flags |= MASK_ISEL; 3433 else 3434 target_flags &= ~MASK_ISEL; 3435 break; 3436 3437 case OPT_mspe: 3438 rs6000_explicit_options.spe = true; 3439 rs6000_spe = value; 3440 break; 3441 3442 case OPT_mspe_: 3443 rs6000_explicit_options.spe = true; 3444 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe)); 3445 break; 3446 3447 case OPT_mdebug_: 3448 rs6000_debug_name = arg; 3449 break; 3450 3451#ifdef TARGET_USES_SYSV4_OPT 3452 case OPT_mcall_: 3453 rs6000_abi_name = arg; 3454 break; 3455 3456 case OPT_msdata_: 3457 rs6000_sdata_name = arg; 3458 break; 3459 3460 case OPT_mtls_size_: 3461 rs6000_tls_size_string = arg; 3462 break; 3463 3464 case OPT_mrelocatable: 3465 if (value == 1) 3466 { 3467 target_flags |= MASK_MINIMAL_TOC; 3468 target_flags_explicit |= MASK_MINIMAL_TOC; 3469 TARGET_NO_FP_IN_TOC = 1; 3470 } 3471 break; 3472 3473 case OPT_mrelocatable_lib: 3474 if (value == 1) 3475 { 3476 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC; 3477 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC; 3478 TARGET_NO_FP_IN_TOC = 1; 3479 } 3480 else 3481 { 3482 target_flags &= ~MASK_RELOCATABLE; 3483 target_flags_explicit |= MASK_RELOCATABLE; 3484 } 3485 break; 3486#endif 3487 3488 case OPT_mabi_: 3489 if (!strcmp (arg, "altivec")) 3490 { 3491 rs6000_explicit_options.altivec_abi = true; 3492 rs6000_altivec_abi = 1; 3493 3494 /* Enabling the AltiVec ABI turns off the SPE ABI. */ 3495 rs6000_spe_abi = 0; 3496 } 3497 else if (! strcmp (arg, "no-altivec")) 3498 { 3499 rs6000_explicit_options.altivec_abi = true; 3500 rs6000_altivec_abi = 0; 3501 } 3502 else if (! strcmp (arg, "spe")) 3503 { 3504 rs6000_explicit_options.spe_abi = true; 3505 rs6000_spe_abi = 1; 3506 rs6000_altivec_abi = 0; 3507 if (!TARGET_SPE_ABI) 3508 error ("not configured for ABI: '%s'", arg); 3509 } 3510 else if (! strcmp (arg, "no-spe")) 3511 { 3512 rs6000_explicit_options.spe_abi = true; 3513 rs6000_spe_abi = 0; 3514 } 3515 3516 /* These are here for testing during development only, do not 3517 document in the manual please. */ 3518 else if (! strcmp (arg, "d64")) 3519 { 3520 rs6000_darwin64_abi = 1; 3521 warning (0, "Using darwin64 ABI"); 3522 } 3523 else if (! strcmp (arg, "d32")) 3524 { 3525 rs6000_darwin64_abi = 0; 3526 warning (0, "Using old darwin ABI"); 3527 } 3528 3529 else if (! strcmp (arg, "ibmlongdouble")) 3530 { 3531 rs6000_explicit_options.ieee = true; 3532 rs6000_ieeequad = 0; 3533 warning (0, "Using IBM extended precision long double"); 3534 } 3535 else if (! strcmp (arg, "ieeelongdouble")) 3536 { 3537 rs6000_explicit_options.ieee = true; 3538 rs6000_ieeequad = 1; 3539 warning (0, "Using IEEE extended precision long double"); 3540 } 3541 3542 else 3543 { 3544 error ("unknown ABI specified: '%s'", arg); 3545 return false; 3546 } 3547 break; 3548 3549 case OPT_mcpu_: 3550 rs6000_select[1].string = arg; 3551 break; 3552 3553 case OPT_mtune_: 3554 rs6000_select[2].string = arg; 3555 break; 3556 3557 case OPT_mtraceback_: 3558 rs6000_traceback_name = arg; 3559 break; 3560 3561 case OPT_mfloat_gprs_: 3562 rs6000_explicit_options.float_gprs = true; 3563 if (! strcmp (arg, "yes") || ! strcmp (arg, "single")) 3564 rs6000_float_gprs = 1; 3565 else if (! strcmp (arg, "double")) 3566 rs6000_float_gprs = 2; 3567 else if (! strcmp (arg, "no")) 3568 rs6000_float_gprs = 0; 3569 else 3570 { 3571 error ("invalid option for -mfloat-gprs: '%s'", arg); 3572 return false; 3573 } 3574 break; 3575 3576 case OPT_mlong_double_: 3577 rs6000_explicit_options.long_double = true; 3578 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE; 3579 if (value != 64 && value != 128) 3580 { 3581 error ("Unknown switch -mlong-double-%s", arg); 3582 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE; 3583 return false; 3584 } 3585 else 3586 rs6000_long_double_type_size = value; 3587 break; 3588 3589 case OPT_msched_costly_dep_: 3590 rs6000_sched_costly_dep_str = arg; 3591 break; 3592 3593 case OPT_malign_: 3594 rs6000_explicit_options.alignment = true; 3595 if (! strcmp (arg, "power")) 3596 { 3597 /* On 64-bit Darwin, power alignment is ABI-incompatible with 3598 some C library functions, so warn about it. The flag may be 3599 useful for performance studies from time to time though, so 3600 don't disable it entirely. */ 3601 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT) 3602 warning (0, "-malign-power is not supported for 64-bit Darwin;" 3603 " it is incompatible with the installed C and C++ libraries"); 3604 rs6000_alignment_flags = MASK_ALIGN_POWER; 3605 } 3606 else if (! strcmp (arg, "natural")) 3607 rs6000_alignment_flags = MASK_ALIGN_NATURAL; 3608 else 3609 { 3610 error ("unknown -malign-XXXXX option specified: '%s'", arg); 3611 return false; 3612 } 3613 break; 3614 3615 case OPT_msingle_float: 3616 if (!TARGET_SINGLE_FPU) 3617 warning (0, "-msingle-float option equivalent to -mhard-float"); 3618 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */ 3619 rs6000_double_float = 0; 3620 target_flags &= ~MASK_SOFT_FLOAT; 3621 target_flags_explicit |= MASK_SOFT_FLOAT; 3622 break; 3623 3624 case OPT_mdouble_float: 3625 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */ 3626 rs6000_single_float = 1; 3627 target_flags &= ~MASK_SOFT_FLOAT; 3628 target_flags_explicit |= MASK_SOFT_FLOAT; 3629 break; 3630 3631 case OPT_msimple_fpu: 3632 if (!TARGET_SINGLE_FPU) 3633 warning (0, "-msimple-fpu option ignored"); 3634 break; 3635 3636 case OPT_mhard_float: 3637 /* -mhard_float implies -msingle-float and -mdouble-float. */ 3638 rs6000_single_float = rs6000_double_float = 1; 3639 break; 3640 3641 case OPT_msoft_float: 3642 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */ 3643 rs6000_single_float = rs6000_double_float = 0; 3644 break; 3645 3646 case OPT_mfpu_: 3647 fpu_type = rs6000_parse_fpu_option(arg); 3648 if (fpu_type != FPU_NONE) 3649 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */ 3650 { 3651 target_flags &= ~MASK_SOFT_FLOAT; 3652 target_flags_explicit |= MASK_SOFT_FLOAT; 3653 rs6000_xilinx_fpu = 1; 3654 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL) 3655 rs6000_single_float = 1; 3656 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL) 3657 rs6000_single_float = rs6000_double_float = 1; 3658 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE) 3659 rs6000_simple_fpu = 1; 3660 } 3661 else 3662 { 3663 /* -mfpu=none is equivalent to -msoft-float */ 3664 target_flags |= MASK_SOFT_FLOAT; 3665 target_flags_explicit |= MASK_SOFT_FLOAT; 3666 rs6000_single_float = rs6000_double_float = 0; 3667 } 3668 break; 3669 } 3670 return true; 3671} 3672 3673/* Do anything needed at the start of the asm file. */ 3674 3675static void 3676rs6000_file_start (void) 3677{ 3678 size_t i; 3679 char buffer[80]; 3680 const char *start = buffer; 3681 struct rs6000_cpu_select *ptr; 3682 const char *default_cpu = TARGET_CPU_DEFAULT; 3683 FILE *file = asm_out_file; 3684 3685 default_file_start (); 3686 3687#ifdef TARGET_BI_ARCH 3688 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT) 3689 default_cpu = 0; 3690#endif 3691 3692 if (flag_verbose_asm) 3693 { 3694 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START); 3695 rs6000_select[0].string = default_cpu; 3696 3697 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++) 3698 { 3699 ptr = &rs6000_select[i]; 3700 if (ptr->string != (char *)0 && ptr->string[0] != '\0') 3701 { 3702 fprintf (file, "%s %s%s", start, ptr->name, ptr->string); 3703 start = ""; 3704 } 3705 } 3706 3707 if (PPC405_ERRATUM77) 3708 { 3709 fprintf (file, "%s PPC405CR_ERRATUM77", start); 3710 start = ""; 3711 } 3712 3713#ifdef USING_ELFOS_H 3714 switch (rs6000_sdata) 3715 { 3716 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break; 3717 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break; 3718 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break; 3719 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break; 3720 } 3721 3722 if (rs6000_sdata && g_switch_value) 3723 { 3724 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start, 3725 g_switch_value); 3726 start = ""; 3727 } 3728#endif 3729 3730 if (*start == '\0') 3731 putc ('\n', file); 3732 } 3733 3734#ifdef HAVE_AS_GNU_ATTRIBUTE 3735 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4) 3736 { 3737 fprintf (file, "\t.gnu_attribute 4, %d\n", 3738 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1 3739 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3 3740 : 2)); 3741 fprintf (file, "\t.gnu_attribute 8, %d\n", 3742 (TARGET_ALTIVEC_ABI ? 2 3743 : TARGET_SPE_ABI ? 3 3744 : 1)); 3745 fprintf (file, "\t.gnu_attribute 12, %d\n", 3746 aix_struct_return ? 2 : 1); 3747 3748 } 3749#endif 3750 3751 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2)) 3752 { 3753 switch_to_section (toc_section); 3754 switch_to_section (text_section); 3755 } 3756} 3757 3758 3759/* Return nonzero if this function is known to have a null epilogue. */ 3760 3761int 3762direct_return (void) 3763{ 3764 if (reload_completed) 3765 { 3766 rs6000_stack_t *info = rs6000_stack_info (); 3767 3768 if (info->first_gp_reg_save == 32 3769 && info->first_fp_reg_save == 64 3770 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1 3771 && ! info->lr_save_p 3772 && ! info->cr_save_p 3773 && info->vrsave_mask == 0 3774 && ! info->push_p) 3775 return 1; 3776 } 3777 3778 return 0; 3779} 3780 3781/* Return the number of instructions it takes to form a constant in an 3782 integer register. */ 3783 3784int 3785num_insns_constant_wide (HOST_WIDE_INT value) 3786{ 3787 /* signed constant loadable with {cal|addi} */ 3788 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000) 3789 return 1; 3790 3791 /* constant loadable with {cau|addis} */ 3792 else if ((value & 0xffff) == 0 3793 && (value >> 31 == -1 || value >> 31 == 0)) 3794 return 1; 3795 3796#if HOST_BITS_PER_WIDE_INT == 64 3797 else if (TARGET_POWERPC64) 3798 { 3799 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000; 3800 HOST_WIDE_INT high = value >> 31; 3801 3802 if (high == 0 || high == -1) 3803 return 2; 3804 3805 high >>= 1; 3806 3807 if (low == 0) 3808 return num_insns_constant_wide (high) + 1; 3809 else if (high == 0) 3810 return num_insns_constant_wide (low) + 1; 3811 else 3812 return (num_insns_constant_wide (high) 3813 + num_insns_constant_wide (low) + 1); 3814 } 3815#endif 3816 3817 else 3818 return 2; 3819} 3820 3821int 3822num_insns_constant (rtx op, enum machine_mode mode) 3823{ 3824 HOST_WIDE_INT low, high; 3825 3826 switch (GET_CODE (op)) 3827 { 3828 case CONST_INT: 3829#if HOST_BITS_PER_WIDE_INT == 64 3830 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1 3831 && mask64_operand (op, mode)) 3832 return 2; 3833 else 3834#endif 3835 return num_insns_constant_wide (INTVAL (op)); 3836 3837 case CONST_DOUBLE: 3838 if (mode == SFmode || mode == SDmode) 3839 { 3840 long l; 3841 REAL_VALUE_TYPE rv; 3842 3843 REAL_VALUE_FROM_CONST_DOUBLE (rv, op); 3844 if (DECIMAL_FLOAT_MODE_P (mode)) 3845 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l); 3846 else 3847 REAL_VALUE_TO_TARGET_SINGLE (rv, l); 3848 return num_insns_constant_wide ((HOST_WIDE_INT) l); 3849 } 3850 3851 if (mode == VOIDmode || mode == DImode) 3852 { 3853 high = CONST_DOUBLE_HIGH (op); 3854 low = CONST_DOUBLE_LOW (op); 3855 } 3856 else 3857 { 3858 long l[2]; 3859 REAL_VALUE_TYPE rv; 3860 3861 REAL_VALUE_FROM_CONST_DOUBLE (rv, op); 3862 if (DECIMAL_FLOAT_MODE_P (mode)) 3863 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l); 3864 else 3865 REAL_VALUE_TO_TARGET_DOUBLE (rv, l); 3866 high = l[WORDS_BIG_ENDIAN == 0]; 3867 low = l[WORDS_BIG_ENDIAN != 0]; 3868 } 3869 3870 if (TARGET_32BIT) 3871 return (num_insns_constant_wide (low) 3872 + num_insns_constant_wide (high)); 3873 else 3874 { 3875 if ((high == 0 && low >= 0) 3876 || (high == -1 && low < 0)) 3877 return num_insns_constant_wide (low); 3878 3879 else if (mask64_operand (op, mode)) 3880 return 2; 3881 3882 else if (low == 0) 3883 return num_insns_constant_wide (high) + 1; 3884 3885 else 3886 return (num_insns_constant_wide (high) 3887 + num_insns_constant_wide (low) + 1); 3888 } 3889 3890 default: 3891 gcc_unreachable (); 3892 } 3893} 3894 3895/* Interpret element ELT of the CONST_VECTOR OP as an integer value. 3896 If the mode of OP is MODE_VECTOR_INT, this simply returns the 3897 corresponding element of the vector, but for V4SFmode and V2SFmode, 3898 the corresponding "float" is interpreted as an SImode integer. */ 3899 3900HOST_WIDE_INT 3901const_vector_elt_as_int (rtx op, unsigned int elt) 3902{ 3903 rtx tmp = CONST_VECTOR_ELT (op, elt); 3904 if (GET_MODE (op) == V4SFmode 3905 || GET_MODE (op) == V2SFmode) 3906 tmp = gen_lowpart (SImode, tmp); 3907 return INTVAL (tmp); 3908} 3909 3910/* Return true if OP can be synthesized with a particular vspltisb, vspltish 3911 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used 3912 depends on STEP and COPIES, one of which will be 1. If COPIES > 1, 3913 all items are set to the same value and contain COPIES replicas of the 3914 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's 3915 operand and the others are set to the value of the operand's msb. */ 3916 3917static bool 3918vspltis_constant (rtx op, unsigned step, unsigned copies) 3919{ 3920 enum machine_mode mode = GET_MODE (op); 3921 enum machine_mode inner = GET_MODE_INNER (mode); 3922 3923 unsigned i; 3924 unsigned nunits = GET_MODE_NUNITS (mode); 3925 unsigned bitsize = GET_MODE_BITSIZE (inner); 3926 unsigned mask = GET_MODE_MASK (inner); 3927 3928 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1); 3929 HOST_WIDE_INT splat_val = val; 3930 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1; 3931 3932 /* Construct the value to be splatted, if possible. If not, return 0. */ 3933 for (i = 2; i <= copies; i *= 2) 3934 { 3935 HOST_WIDE_INT small_val; 3936 bitsize /= 2; 3937 small_val = splat_val >> bitsize; 3938 mask >>= bitsize; 3939 if (splat_val != ((small_val << bitsize) | (small_val & mask))) 3940 return false; 3941 splat_val = small_val; 3942 } 3943 3944 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */ 3945 if (EASY_VECTOR_15 (splat_val)) 3946 ; 3947 3948 /* Also check if we can splat, and then add the result to itself. Do so if 3949 the value is positive, of if the splat instruction is using OP's mode; 3950 for splat_val < 0, the splat and the add should use the same mode. */ 3951 else if (EASY_VECTOR_15_ADD_SELF (splat_val) 3952 && (splat_val >= 0 || (step == 1 && copies == 1))) 3953 ; 3954 3955 /* Also check if are loading up the most significant bit which can be done by 3956 loading up -1 and shifting the value left by -1. */ 3957 else if (EASY_VECTOR_MSB (splat_val, inner)) 3958 ; 3959 3960 else 3961 return false; 3962 3963 /* Check if VAL is present in every STEP-th element, and the 3964 other elements are filled with its most significant bit. */ 3965 for (i = 0; i < nunits - 1; ++i) 3966 { 3967 HOST_WIDE_INT desired_val; 3968 if (((i + 1) & (step - 1)) == 0) 3969 desired_val = val; 3970 else 3971 desired_val = msb_val; 3972 3973 if (desired_val != const_vector_elt_as_int (op, i)) 3974 return false; 3975 } 3976 3977 return true; 3978} 3979 3980 3981/* Return true if OP is of the given MODE and can be synthesized 3982 with a vspltisb, vspltish or vspltisw. */ 3983 3984bool 3985easy_altivec_constant (rtx op, enum machine_mode mode) 3986{ 3987 unsigned step, copies; 3988 3989 if (mode == VOIDmode) 3990 mode = GET_MODE (op); 3991 else if (mode != GET_MODE (op)) 3992 return false; 3993 3994 /* Start with a vspltisw. */ 3995 step = GET_MODE_NUNITS (mode) / 4; 3996 copies = 1; 3997 3998 if (vspltis_constant (op, step, copies)) 3999 return true; 4000 4001 /* Then try with a vspltish. */ 4002 if (step == 1) 4003 copies <<= 1; 4004 else 4005 step >>= 1; 4006 4007 if (vspltis_constant (op, step, copies)) 4008 return true; 4009 4010 /* And finally a vspltisb. */ 4011 if (step == 1) 4012 copies <<= 1; 4013 else 4014 step >>= 1; 4015 4016 if (vspltis_constant (op, step, copies)) 4017 return true; 4018 4019 return false; 4020} 4021 4022/* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose 4023 result is OP. Abort if it is not possible. */ 4024 4025rtx 4026gen_easy_altivec_constant (rtx op) 4027{ 4028 enum machine_mode mode = GET_MODE (op); 4029 int nunits = GET_MODE_NUNITS (mode); 4030 rtx last = CONST_VECTOR_ELT (op, nunits - 1); 4031 unsigned step = nunits / 4; 4032 unsigned copies = 1; 4033 4034 /* Start with a vspltisw. */ 4035 if (vspltis_constant (op, step, copies)) 4036 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last)); 4037 4038 /* Then try with a vspltish. */ 4039 if (step == 1) 4040 copies <<= 1; 4041 else 4042 step >>= 1; 4043 4044 if (vspltis_constant (op, step, copies)) 4045 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last)); 4046 4047 /* And finally a vspltisb. */ 4048 if (step == 1) 4049 copies <<= 1; 4050 else 4051 step >>= 1; 4052 4053 if (vspltis_constant (op, step, copies)) 4054 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last)); 4055 4056 gcc_unreachable (); 4057} 4058 4059const char * 4060output_vec_const_move (rtx *operands) 4061{ 4062 int cst, cst2; 4063 enum machine_mode mode; 4064 rtx dest, vec; 4065 4066 dest = operands[0]; 4067 vec = operands[1]; 4068 mode = GET_MODE (dest); 4069 4070 if (TARGET_VSX && zero_constant (vec, mode)) 4071 return "xxlxor %x0,%x0,%x0"; 4072 4073 if (TARGET_ALTIVEC) 4074 { 4075 rtx splat_vec; 4076 if (zero_constant (vec, mode)) 4077 return "vxor %0,%0,%0"; 4078 4079 splat_vec = gen_easy_altivec_constant (vec); 4080 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE); 4081 operands[1] = XEXP (splat_vec, 0); 4082 if (!EASY_VECTOR_15 (INTVAL (operands[1]))) 4083 return "#"; 4084 4085 switch (GET_MODE (splat_vec)) 4086 { 4087 case V4SImode: 4088 return "vspltisw %0,%1"; 4089 4090 case V8HImode: 4091 return "vspltish %0,%1"; 4092 4093 case V16QImode: 4094 return "vspltisb %0,%1"; 4095 4096 default: 4097 gcc_unreachable (); 4098 } 4099 } 4100 4101 gcc_assert (TARGET_SPE); 4102 4103 /* Vector constant 0 is handled as a splitter of V2SI, and in the 4104 pattern of V1DI, V4HI, and V2SF. 4105 4106 FIXME: We should probably return # and add post reload 4107 splitters for these, but this way is so easy ;-). */ 4108 cst = INTVAL (CONST_VECTOR_ELT (vec, 0)); 4109 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1)); 4110 operands[1] = CONST_VECTOR_ELT (vec, 0); 4111 operands[2] = CONST_VECTOR_ELT (vec, 1); 4112 if (cst == cst2) 4113 return "li %0,%1\n\tevmergelo %0,%0,%0"; 4114 else 4115 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2"; 4116} 4117 4118/* Initialize TARGET of vector PAIRED to VALS. */ 4119 4120void 4121paired_expand_vector_init (rtx target, rtx vals) 4122{ 4123 enum machine_mode mode = GET_MODE (target); 4124 int n_elts = GET_MODE_NUNITS (mode); 4125 int n_var = 0; 4126 rtx x, new_rtx, tmp, constant_op, op1, op2; 4127 int i; 4128 4129 for (i = 0; i < n_elts; ++i) 4130 { 4131 x = XVECEXP (vals, 0, i); 4132 if (!CONSTANT_P (x)) 4133 ++n_var; 4134 } 4135 if (n_var == 0) 4136 { 4137 /* Load from constant pool. */ 4138 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0))); 4139 return; 4140 } 4141 4142 if (n_var == 2) 4143 { 4144 /* The vector is initialized only with non-constants. */ 4145 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0), 4146 XVECEXP (vals, 0, 1)); 4147 4148 emit_move_insn (target, new_rtx); 4149 return; 4150 } 4151 4152 /* One field is non-constant and the other one is a constant. Load the 4153 constant from the constant pool and use ps_merge instruction to 4154 construct the whole vector. */ 4155 op1 = XVECEXP (vals, 0, 0); 4156 op2 = XVECEXP (vals, 0, 1); 4157 4158 constant_op = (CONSTANT_P (op1)) ? op1 : op2; 4159 4160 tmp = gen_reg_rtx (GET_MODE (constant_op)); 4161 emit_move_insn (tmp, constant_op); 4162 4163 if (CONSTANT_P (op1)) 4164 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2); 4165 else 4166 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp); 4167 4168 emit_move_insn (target, new_rtx); 4169} 4170 4171void 4172paired_expand_vector_move (rtx operands[]) 4173{ 4174 rtx op0 = operands[0], op1 = operands[1]; 4175 4176 emit_move_insn (op0, op1); 4177} 4178 4179/* Emit vector compare for code RCODE. DEST is destination, OP1 and 4180 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two 4181 operands for the relation operation COND. This is a recursive 4182 function. */ 4183 4184static void 4185paired_emit_vector_compare (enum rtx_code rcode, 4186 rtx dest, rtx op0, rtx op1, 4187 rtx cc_op0, rtx cc_op1) 4188{ 4189 rtx tmp = gen_reg_rtx (V2SFmode); 4190 rtx tmp1, max, min, equal_zero; 4191 4192 gcc_assert (TARGET_PAIRED_FLOAT); 4193 gcc_assert (GET_MODE (op0) == GET_MODE (op1)); 4194 4195 switch (rcode) 4196 { 4197 case LT: 4198 case LTU: 4199 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1); 4200 return; 4201 case GE: 4202 case GEU: 4203 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1)); 4204 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode))); 4205 return; 4206 case LE: 4207 case LEU: 4208 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0); 4209 return; 4210 case GT: 4211 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1); 4212 return; 4213 case EQ: 4214 tmp1 = gen_reg_rtx (V2SFmode); 4215 max = gen_reg_rtx (V2SFmode); 4216 min = gen_reg_rtx (V2SFmode); 4217 equal_zero = gen_reg_rtx (V2SFmode); 4218 4219 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1)); 4220 emit_insn (gen_selv2sf4 4221 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode))); 4222 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0)); 4223 emit_insn (gen_selv2sf4 4224 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode))); 4225 emit_insn (gen_subv2sf3 (tmp1, min, max)); 4226 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode))); 4227 return; 4228 case NE: 4229 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1); 4230 return; 4231 case UNLE: 4232 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1); 4233 return; 4234 case UNLT: 4235 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1); 4236 return; 4237 case UNGE: 4238 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1); 4239 return; 4240 case UNGT: 4241 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1); 4242 return; 4243 default: 4244 gcc_unreachable (); 4245 } 4246 4247 return; 4248} 4249 4250/* Emit vector conditional expression. 4251 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands. 4252 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */ 4253 4254int 4255paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2, 4256 rtx cond, rtx cc_op0, rtx cc_op1) 4257{ 4258 enum rtx_code rcode = GET_CODE (cond); 4259 4260 if (!TARGET_PAIRED_FLOAT) 4261 return 0; 4262 4263 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1); 4264 4265 return 1; 4266} 4267 4268/* Initialize vector TARGET to VALS. */ 4269 4270void 4271rs6000_expand_vector_init (rtx target, rtx vals) 4272{ 4273 enum machine_mode mode = GET_MODE (target); 4274 enum machine_mode inner_mode = GET_MODE_INNER (mode); 4275 int n_elts = GET_MODE_NUNITS (mode); 4276 int n_var = 0, one_var = -1; 4277 bool all_same = true, all_const_zero = true; 4278 rtx x, mem; 4279 int i; 4280 4281 for (i = 0; i < n_elts; ++i) 4282 { 4283 x = XVECEXP (vals, 0, i); 4284 if (!CONSTANT_P (x)) 4285 ++n_var, one_var = i; 4286 else if (x != CONST0_RTX (inner_mode)) 4287 all_const_zero = false; 4288 4289 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0))) 4290 all_same = false; 4291 } 4292 4293 if (n_var == 0) 4294 { 4295 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)); 4296 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT); 4297 if ((int_vector_p || TARGET_VSX) && all_const_zero) 4298 { 4299 /* Zero register. */ 4300 emit_insn (gen_rtx_SET (VOIDmode, target, 4301 gen_rtx_XOR (mode, target, target))); 4302 return; 4303 } 4304 else if (int_vector_p && easy_vector_constant (const_vec, mode)) 4305 { 4306 /* Splat immediate. */ 4307 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec)); 4308 return; 4309 } 4310 else 4311 { 4312 /* Load from constant pool. */ 4313 emit_move_insn (target, const_vec); 4314 return; 4315 } 4316 } 4317 4318 /* Double word values on VSX can use xxpermdi or lxvdsx. */ 4319 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode)) 4320 { 4321 if (all_same) 4322 { 4323 rtx element = XVECEXP (vals, 0, 0); 4324 if (mode == V2DFmode) 4325 emit_insn (gen_vsx_splat_v2df (target, element)); 4326 else 4327 emit_insn (gen_vsx_splat_v2di (target, element)); 4328 } 4329 else 4330 { 4331 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0)); 4332 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1)); 4333 if (mode == V2DFmode) 4334 emit_insn (gen_vsx_concat_v2df (target, op0, op1)); 4335 else 4336 emit_insn (gen_vsx_concat_v2di (target, op0, op1)); 4337 } 4338 return; 4339 } 4340 4341 /* With single precision floating point on VSX, know that internally single 4342 precision is actually represented as a double, and either make 2 V2DF 4343 vectors, and convert these vectors to single precision, or do one 4344 conversion, and splat the result to the other elements. */ 4345 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode)) 4346 { 4347 if (all_same) 4348 { 4349 rtx freg = gen_reg_rtx (V4SFmode); 4350 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0)); 4351 4352 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg)); 4353 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx)); 4354 } 4355 else 4356 { 4357 rtx dbl_even = gen_reg_rtx (V2DFmode); 4358 rtx dbl_odd = gen_reg_rtx (V2DFmode); 4359 rtx flt_even = gen_reg_rtx (V4SFmode); 4360 rtx flt_odd = gen_reg_rtx (V4SFmode); 4361 4362 emit_insn (gen_vsx_concat_v2sf (dbl_even, 4363 copy_to_reg (XVECEXP (vals, 0, 0)), 4364 copy_to_reg (XVECEXP (vals, 0, 1)))); 4365 emit_insn (gen_vsx_concat_v2sf (dbl_odd, 4366 copy_to_reg (XVECEXP (vals, 0, 2)), 4367 copy_to_reg (XVECEXP (vals, 0, 3)))); 4368 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even)); 4369 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd)); 4370 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd)); 4371 } 4372 return; 4373 } 4374 4375 /* Store value to stack temp. Load vector element. Splat. However, splat 4376 of 64-bit items is not supported on Altivec. */ 4377 if (all_same && GET_MODE_SIZE (mode) <= 4) 4378 { 4379 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0); 4380 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), 4381 XVECEXP (vals, 0, 0)); 4382 x = gen_rtx_UNSPEC (VOIDmode, 4383 gen_rtvec (1, const0_rtx), UNSPEC_LVE); 4384 emit_insn (gen_rtx_PARALLEL (VOIDmode, 4385 gen_rtvec (2, 4386 gen_rtx_SET (VOIDmode, 4387 target, mem), 4388 x))); 4389 x = gen_rtx_VEC_SELECT (inner_mode, target, 4390 gen_rtx_PARALLEL (VOIDmode, 4391 gen_rtvec (1, const0_rtx))); 4392 emit_insn (gen_rtx_SET (VOIDmode, target, 4393 gen_rtx_VEC_DUPLICATE (mode, x))); 4394 return; 4395 } 4396 4397 /* One field is non-constant. Load constant then overwrite 4398 varying field. */ 4399 if (n_var == 1) 4400 { 4401 rtx copy = copy_rtx (vals); 4402 4403 /* Load constant part of vector, substitute neighboring value for 4404 varying element. */ 4405 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts); 4406 rs6000_expand_vector_init (target, copy); 4407 4408 /* Insert variable. */ 4409 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var); 4410 return; 4411 } 4412 4413 /* Construct the vector in memory one field at a time 4414 and load the whole vector. */ 4415 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0); 4416 for (i = 0; i < n_elts; i++) 4417 emit_move_insn (adjust_address_nv (mem, inner_mode, 4418 i * GET_MODE_SIZE (inner_mode)), 4419 XVECEXP (vals, 0, i)); 4420 emit_move_insn (target, mem); 4421} 4422 4423/* Set field ELT of TARGET to VAL. */ 4424 4425void 4426rs6000_expand_vector_set (rtx target, rtx val, int elt) 4427{ 4428 enum machine_mode mode = GET_MODE (target); 4429 enum machine_mode inner_mode = GET_MODE_INNER (mode); 4430 rtx reg = gen_reg_rtx (mode); 4431 rtx mask, mem, x; 4432 int width = GET_MODE_SIZE (inner_mode); 4433 int i; 4434 4435 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode)) 4436 { 4437 rtx (*set_func) (rtx, rtx, rtx, rtx) 4438 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di); 4439 emit_insn (set_func (target, target, val, GEN_INT (elt))); 4440 return; 4441 } 4442 4443 /* Load single variable value. */ 4444 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0); 4445 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val); 4446 x = gen_rtx_UNSPEC (VOIDmode, 4447 gen_rtvec (1, const0_rtx), UNSPEC_LVE); 4448 emit_insn (gen_rtx_PARALLEL (VOIDmode, 4449 gen_rtvec (2, 4450 gen_rtx_SET (VOIDmode, 4451 reg, mem), 4452 x))); 4453 4454 /* Linear sequence. */ 4455 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16)); 4456 for (i = 0; i < 16; ++i) 4457 XVECEXP (mask, 0, i) = GEN_INT (i); 4458 4459 /* Set permute mask to insert element into target. */ 4460 for (i = 0; i < width; ++i) 4461 XVECEXP (mask, 0, elt*width + i) 4462 = GEN_INT (i + 0x10); 4463 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0)); 4464 x = gen_rtx_UNSPEC (mode, 4465 gen_rtvec (3, target, reg, 4466 force_reg (V16QImode, x)), 4467 UNSPEC_VPERM); 4468 emit_insn (gen_rtx_SET (VOIDmode, target, x)); 4469} 4470 4471/* Extract field ELT from VEC into TARGET. */ 4472 4473void 4474rs6000_expand_vector_extract (rtx target, rtx vec, int elt) 4475{ 4476 enum machine_mode mode = GET_MODE (vec); 4477 enum machine_mode inner_mode = GET_MODE_INNER (mode); 4478 rtx mem; 4479 4480 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode)) 4481 { 4482 rtx (*extract_func) (rtx, rtx, rtx) 4483 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di); 4484 emit_insn (extract_func (target, vec, GEN_INT (elt))); 4485 return; 4486 } 4487 4488 /* Allocate mode-sized buffer. */ 4489 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0); 4490 4491 emit_move_insn (mem, vec); 4492 4493 /* Add offset to field within buffer matching vector element. */ 4494 mem = adjust_address_nv (mem, inner_mode, elt * GET_MODE_SIZE (inner_mode)); 4495 4496 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0)); 4497} 4498 4499/* Generates shifts and masks for a pair of rldicl or rldicr insns to 4500 implement ANDing by the mask IN. */ 4501void 4502build_mask64_2_operands (rtx in, rtx *out) 4503{ 4504#if HOST_BITS_PER_WIDE_INT >= 64 4505 unsigned HOST_WIDE_INT c, lsb, m1, m2; 4506 int shift; 4507 4508 gcc_assert (GET_CODE (in) == CONST_INT); 4509 4510 c = INTVAL (in); 4511 if (c & 1) 4512 { 4513 /* Assume c initially something like 0x00fff000000fffff. The idea 4514 is to rotate the word so that the middle ^^^^^^ group of zeros 4515 is at the MS end and can be cleared with an rldicl mask. We then 4516 rotate back and clear off the MS ^^ group of zeros with a 4517 second rldicl. */ 4518 c = ~c; /* c == 0xff000ffffff00000 */ 4519 lsb = c & -c; /* lsb == 0x0000000000100000 */ 4520 m1 = -lsb; /* m1 == 0xfffffffffff00000 */ 4521 c = ~c; /* c == 0x00fff000000fffff */ 4522 c &= -lsb; /* c == 0x00fff00000000000 */ 4523 lsb = c & -c; /* lsb == 0x0000100000000000 */ 4524 c = ~c; /* c == 0xff000fffffffffff */ 4525 c &= -lsb; /* c == 0xff00000000000000 */ 4526 shift = 0; 4527 while ((lsb >>= 1) != 0) 4528 shift++; /* shift == 44 on exit from loop */ 4529 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */ 4530 m1 = ~m1; /* m1 == 0x000000ffffffffff */ 4531 m2 = ~c; /* m2 == 0x00ffffffffffffff */ 4532 } 4533 else 4534 { 4535 /* Assume c initially something like 0xff000f0000000000. The idea 4536 is to rotate the word so that the ^^^ middle group of zeros 4537 is at the LS end and can be cleared with an rldicr mask. We then 4538 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with 4539 a second rldicr. */ 4540 lsb = c & -c; /* lsb == 0x0000010000000000 */ 4541 m2 = -lsb; /* m2 == 0xffffff0000000000 */ 4542 c = ~c; /* c == 0x00fff0ffffffffff */ 4543 c &= -lsb; /* c == 0x00fff00000000000 */ 4544 lsb = c & -c; /* lsb == 0x0000100000000000 */ 4545 c = ~c; /* c == 0xff000fffffffffff */ 4546 c &= -lsb; /* c == 0xff00000000000000 */ 4547 shift = 0; 4548 while ((lsb >>= 1) != 0) 4549 shift++; /* shift == 44 on exit from loop */ 4550 m1 = ~c; /* m1 == 0x00ffffffffffffff */ 4551 m1 >>= shift; /* m1 == 0x0000000000000fff */ 4552 m1 = ~m1; /* m1 == 0xfffffffffffff000 */ 4553 } 4554 4555 /* Note that when we only have two 0->1 and 1->0 transitions, one of the 4556 masks will be all 1's. We are guaranteed more than one transition. */ 4557 out[0] = GEN_INT (64 - shift); 4558 out[1] = GEN_INT (m1); 4559 out[2] = GEN_INT (shift); 4560 out[3] = GEN_INT (m2); 4561#else 4562 (void)in; 4563 (void)out; 4564 gcc_unreachable (); 4565#endif 4566} 4567 4568/* Return TRUE if OP is an invalid SUBREG operation on the e500. */ 4569 4570bool 4571invalid_e500_subreg (rtx op, enum machine_mode mode) 4572{ 4573 if (TARGET_E500_DOUBLE) 4574 { 4575 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or 4576 subreg:TI and reg:TF. Decimal float modes are like integer 4577 modes (only low part of each register used) for this 4578 purpose. */ 4579 if (GET_CODE (op) == SUBREG 4580 && (mode == SImode || mode == DImode || mode == TImode 4581 || mode == DDmode || mode == TDmode) 4582 && REG_P (SUBREG_REG (op)) 4583 && (GET_MODE (SUBREG_REG (op)) == DFmode 4584 || GET_MODE (SUBREG_REG (op)) == TFmode)) 4585 return true; 4586 4587 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and 4588 reg:TI. */ 4589 if (GET_CODE (op) == SUBREG 4590 && (mode == DFmode || mode == TFmode) 4591 && REG_P (SUBREG_REG (op)) 4592 && (GET_MODE (SUBREG_REG (op)) == DImode 4593 || GET_MODE (SUBREG_REG (op)) == TImode 4594 || GET_MODE (SUBREG_REG (op)) == DDmode 4595 || GET_MODE (SUBREG_REG (op)) == TDmode)) 4596 return true; 4597 } 4598 4599 if (TARGET_SPE 4600 && GET_CODE (op) == SUBREG 4601 && mode == SImode 4602 && REG_P (SUBREG_REG (op)) 4603 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op)))) 4604 return true; 4605 4606 return false; 4607} 4608 4609/* AIX increases natural record alignment to doubleword if the first 4610 field is an FP double while the FP fields remain word aligned. */ 4611 4612unsigned int 4613rs6000_special_round_type_align (tree type, unsigned int computed, 4614 unsigned int specified) 4615{ 4616 unsigned int align = MAX (computed, specified); 4617 tree field = TYPE_FIELDS (type); 4618 4619 /* Skip all non field decls */ 4620 while (field != NULL && TREE_CODE (field) != FIELD_DECL) 4621 field = TREE_CHAIN (field); 4622 4623 if (field != NULL && field != type) 4624 { 4625 type = TREE_TYPE (field); 4626 while (TREE_CODE (type) == ARRAY_TYPE) 4627 type = TREE_TYPE (type); 4628 4629 if (type != error_mark_node && TYPE_MODE (type) == DFmode) 4630 align = MAX (align, 64); 4631 } 4632 4633 return align; 4634} 4635 4636/* Darwin increases record alignment to the natural alignment of 4637 the first field. */ 4638 4639unsigned int 4640darwin_rs6000_special_round_type_align (tree type, unsigned int computed, 4641 unsigned int specified) 4642{ 4643 unsigned int align = MAX (computed, specified); 4644 4645 if (TYPE_PACKED (type)) 4646 return align; 4647 4648 /* Find the first field, looking down into aggregates. */ 4649 do { 4650 tree field = TYPE_FIELDS (type); 4651 /* Skip all non field decls */ 4652 while (field != NULL && TREE_CODE (field) != FIELD_DECL) 4653 field = TREE_CHAIN (field); 4654 if (! field) 4655 break; 4656 /* A packed field does not contribute any extra alignment. */ 4657 if (DECL_PACKED (field)) 4658 return align; 4659 type = TREE_TYPE (field); 4660 while (TREE_CODE (type) == ARRAY_TYPE) 4661 type = TREE_TYPE (type); 4662 } while (AGGREGATE_TYPE_P (type)); 4663 4664 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node) 4665 align = MAX (align, TYPE_ALIGN (type)); 4666 4667 return align; 4668} 4669 4670/* Return 1 for an operand in small memory on V.4/eabi. */ 4671 4672int 4673small_data_operand (rtx op ATTRIBUTE_UNUSED, 4674 enum machine_mode mode ATTRIBUTE_UNUSED) 4675{ 4676#if TARGET_ELF 4677 rtx sym_ref; 4678 4679 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA) 4680 return 0; 4681 4682 if (DEFAULT_ABI != ABI_V4) 4683 return 0; 4684 4685 /* Vector and float memory instructions have a limited offset on the 4686 SPE, so using a vector or float variable directly as an operand is 4687 not useful. */ 4688 if (TARGET_SPE 4689 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode))) 4690 return 0; 4691 4692 if (GET_CODE (op) == SYMBOL_REF) 4693 sym_ref = op; 4694 4695 else if (GET_CODE (op) != CONST 4696 || GET_CODE (XEXP (op, 0)) != PLUS 4697 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF 4698 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT) 4699 return 0; 4700 4701 else 4702 { 4703 rtx sum = XEXP (op, 0); 4704 HOST_WIDE_INT summand; 4705 4706 /* We have to be careful here, because it is the referenced address 4707 that must be 32k from _SDA_BASE_, not just the symbol. */ 4708 summand = INTVAL (XEXP (sum, 1)); 4709 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value) 4710 return 0; 4711 4712 sym_ref = XEXP (sum, 0); 4713 } 4714 4715 return SYMBOL_REF_SMALL_P (sym_ref); 4716#else 4717 return 0; 4718#endif 4719} 4720 4721/* Return true if either operand is a general purpose register. */ 4722 4723bool 4724gpr_or_gpr_p (rtx op0, rtx op1) 4725{ 4726 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0))) 4727 || (REG_P (op1) && INT_REGNO_P (REGNO (op1)))); 4728} 4729 4730 4731/* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */ 4732 4733static bool 4734reg_offset_addressing_ok_p (enum machine_mode mode) 4735{ 4736 switch (mode) 4737 { 4738 case V16QImode: 4739 case V8HImode: 4740 case V4SFmode: 4741 case V4SImode: 4742 case V2DFmode: 4743 case V2DImode: 4744 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */ 4745 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)) 4746 return false; 4747 break; 4748 4749 case V4HImode: 4750 case V2SImode: 4751 case V1DImode: 4752 case V2SFmode: 4753 /* Paired vector modes. Only reg+reg addressing is valid. */ 4754 if (TARGET_PAIRED_FLOAT) 4755 return false; 4756 break; 4757 4758 default: 4759 break; 4760 } 4761 4762 return true; 4763} 4764 4765static bool 4766virtual_stack_registers_memory_p (rtx op) 4767{ 4768 int regnum; 4769 4770 if (GET_CODE (op) == REG) 4771 regnum = REGNO (op); 4772 4773 else if (GET_CODE (op) == PLUS 4774 && GET_CODE (XEXP (op, 0)) == REG 4775 && GET_CODE (XEXP (op, 1)) == CONST_INT) 4776 regnum = REGNO (XEXP (op, 0)); 4777 4778 else 4779 return false; 4780 4781 return (regnum >= FIRST_VIRTUAL_REGISTER 4782 && regnum <= LAST_VIRTUAL_REGISTER); 4783} 4784 4785static bool 4786constant_pool_expr_p (rtx op) 4787{ 4788 rtx base, offset; 4789 4790 split_const (op, &base, &offset); 4791 return (GET_CODE (base) == SYMBOL_REF 4792 && CONSTANT_POOL_ADDRESS_P (base) 4793 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode)); 4794} 4795 4796bool 4797toc_relative_expr_p (rtx op) 4798{ 4799 rtx base, offset; 4800 4801 if (GET_CODE (op) != CONST) 4802 return false; 4803 4804 split_const (op, &base, &offset); 4805 return (GET_CODE (base) == UNSPEC 4806 && XINT (base, 1) == UNSPEC_TOCREL); 4807} 4808 4809bool 4810legitimate_constant_pool_address_p (rtx x) 4811{ 4812 return (TARGET_TOC 4813 && GET_CODE (x) == PLUS 4814 && GET_CODE (XEXP (x, 0)) == REG 4815 && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER) 4816 && toc_relative_expr_p (XEXP (x, 1))); 4817} 4818 4819static bool 4820legitimate_small_data_p (enum machine_mode mode, rtx x) 4821{ 4822 return (DEFAULT_ABI == ABI_V4 4823 && !flag_pic && !TARGET_TOC 4824 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST) 4825 && small_data_operand (x, mode)); 4826} 4827 4828/* SPE offset addressing is limited to 5-bits worth of double words. */ 4829#define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0) 4830 4831bool 4832rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict) 4833{ 4834 unsigned HOST_WIDE_INT offset, extra; 4835 4836 if (GET_CODE (x) != PLUS) 4837 return false; 4838 if (GET_CODE (XEXP (x, 0)) != REG) 4839 return false; 4840 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)) 4841 return false; 4842 if (!reg_offset_addressing_ok_p (mode)) 4843 return virtual_stack_registers_memory_p (x); 4844 if (legitimate_constant_pool_address_p (x)) 4845 return true; 4846 if (GET_CODE (XEXP (x, 1)) != CONST_INT) 4847 return false; 4848 4849 offset = INTVAL (XEXP (x, 1)); 4850 extra = 0; 4851 switch (mode) 4852 { 4853 case V4HImode: 4854 case V2SImode: 4855 case V1DImode: 4856 case V2SFmode: 4857 /* SPE vector modes. */ 4858 return SPE_CONST_OFFSET_OK (offset); 4859 4860 case DFmode: 4861 if (TARGET_E500_DOUBLE) 4862 return SPE_CONST_OFFSET_OK (offset); 4863 4864 /* If we are using VSX scalar loads, restrict ourselves to reg+reg 4865 addressing. */ 4866 if (VECTOR_MEM_VSX_P (DFmode)) 4867 return false; 4868 4869 case DDmode: 4870 case DImode: 4871 /* On e500v2, we may have: 4872 4873 (subreg:DF (mem:DI (plus (reg) (const_int))) 0). 4874 4875 Which gets addressed with evldd instructions. */ 4876 if (TARGET_E500_DOUBLE) 4877 return SPE_CONST_OFFSET_OK (offset); 4878 4879 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64) 4880 extra = 4; 4881 else if (offset & 3) 4882 return false; 4883 break; 4884 4885 case TFmode: 4886 if (TARGET_E500_DOUBLE) 4887 return (SPE_CONST_OFFSET_OK (offset) 4888 && SPE_CONST_OFFSET_OK (offset + 8)); 4889 4890 case TDmode: 4891 case TImode: 4892 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64) 4893 extra = 12; 4894 else if (offset & 3) 4895 return false; 4896 else 4897 extra = 8; 4898 break; 4899 4900 default: 4901 break; 4902 } 4903 4904 offset += 0x8000; 4905 return (offset < 0x10000) && (offset + extra < 0x10000); 4906} 4907 4908bool 4909legitimate_indexed_address_p (rtx x, int strict) 4910{ 4911 rtx op0, op1; 4912 4913 if (GET_CODE (x) != PLUS) 4914 return false; 4915 4916 op0 = XEXP (x, 0); 4917 op1 = XEXP (x, 1); 4918 4919 /* Recognize the rtl generated by reload which we know will later be 4920 replaced with proper base and index regs. */ 4921 if (!strict 4922 && reload_in_progress 4923 && (REG_P (op0) || GET_CODE (op0) == PLUS) 4924 && REG_P (op1)) 4925 return true; 4926 4927 return (REG_P (op0) && REG_P (op1) 4928 && ((INT_REG_OK_FOR_BASE_P (op0, strict) 4929 && INT_REG_OK_FOR_INDEX_P (op1, strict)) 4930 || (INT_REG_OK_FOR_BASE_P (op1, strict) 4931 && INT_REG_OK_FOR_INDEX_P (op0, strict)))); 4932} 4933 4934bool 4935avoiding_indexed_address_p (enum machine_mode mode) 4936{ 4937 /* Avoid indexed addressing for modes that have non-indexed 4938 load/store instruction forms. */ 4939 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode)); 4940} 4941 4942inline bool 4943legitimate_indirect_address_p (rtx x, int strict) 4944{ 4945 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict); 4946} 4947 4948bool 4949macho_lo_sum_memory_operand (rtx x, enum machine_mode mode) 4950{ 4951 if (!TARGET_MACHO || !flag_pic 4952 || mode != SImode || GET_CODE (x) != MEM) 4953 return false; 4954 x = XEXP (x, 0); 4955 4956 if (GET_CODE (x) != LO_SUM) 4957 return false; 4958 if (GET_CODE (XEXP (x, 0)) != REG) 4959 return false; 4960 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0)) 4961 return false; 4962 x = XEXP (x, 1); 4963 4964 return CONSTANT_P (x); 4965} 4966 4967static bool 4968legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict) 4969{ 4970 if (GET_CODE (x) != LO_SUM) 4971 return false; 4972 if (GET_CODE (XEXP (x, 0)) != REG) 4973 return false; 4974 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)) 4975 return false; 4976 /* Restrict addressing for DI because of our SUBREG hackery. */ 4977 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode 4978 || mode == DDmode || mode == TDmode 4979 || mode == DImode)) 4980 return false; 4981 x = XEXP (x, 1); 4982 4983 if (TARGET_ELF || TARGET_MACHO) 4984 { 4985 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic) 4986 return false; 4987 if (TARGET_TOC) 4988 return false; 4989 if (GET_MODE_NUNITS (mode) != 1) 4990 return false; 4991 if (GET_MODE_BITSIZE (mode) > 64 4992 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64 4993 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 4994 && (mode == DFmode || mode == DDmode)))) 4995 return false; 4996 4997 return CONSTANT_P (x); 4998 } 4999 5000 return false; 5001} 5002 5003 5004/* Try machine-dependent ways of modifying an illegitimate address 5005 to be legitimate. If we find one, return the new, valid address. 5006 This is used from only one place: `memory_address' in explow.c. 5007 5008 OLDX is the address as it was before break_out_memory_refs was 5009 called. In some cases it is useful to look at this to decide what 5010 needs to be done. 5011 5012 It is always safe for this function to do nothing. It exists to 5013 recognize opportunities to optimize the output. 5014 5015 On RS/6000, first check for the sum of a register with a constant 5016 integer that is out of range. If so, generate code to add the 5017 constant with the low-order 16 bits masked to the register and force 5018 this result into another register (this can be done with `cau'). 5019 Then generate an address of REG+(CONST&0xffff), allowing for the 5020 possibility of bit 16 being a one. 5021 5022 Then check for the sum of a register and something not constant, try to 5023 load the other things into a register and return the sum. */ 5024 5025static rtx 5026rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, 5027 enum machine_mode mode) 5028{ 5029 unsigned int extra = 0; 5030 5031 if (!reg_offset_addressing_ok_p (mode)) 5032 { 5033 if (virtual_stack_registers_memory_p (x)) 5034 return x; 5035 5036 /* In theory we should not be seeing addresses of the form reg+0, 5037 but just in case it is generated, optimize it away. */ 5038 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx) 5039 return force_reg (Pmode, XEXP (x, 0)); 5040 5041 /* Make sure both operands are registers. */ 5042 else if (GET_CODE (x) == PLUS) 5043 return gen_rtx_PLUS (Pmode, 5044 force_reg (Pmode, XEXP (x, 0)), 5045 force_reg (Pmode, XEXP (x, 1))); 5046 else 5047 return force_reg (Pmode, x); 5048 } 5049 if (GET_CODE (x) == SYMBOL_REF) 5050 { 5051 enum tls_model model = SYMBOL_REF_TLS_MODEL (x); 5052 if (model != 0) 5053 return rs6000_legitimize_tls_address (x, model); 5054 } 5055 5056 switch (mode) 5057 { 5058 case DFmode: 5059 case DDmode: 5060 extra = 4; 5061 break; 5062 case DImode: 5063 if (!TARGET_POWERPC64) 5064 extra = 4; 5065 break; 5066 case TFmode: 5067 case TDmode: 5068 extra = 12; 5069 break; 5070 case TImode: 5071 extra = TARGET_POWERPC64 ? 8 : 12; 5072 break; 5073 default: 5074 break; 5075 } 5076 5077 if (GET_CODE (x) == PLUS 5078 && GET_CODE (XEXP (x, 0)) == REG 5079 && GET_CODE (XEXP (x, 1)) == CONST_INT 5080 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) 5081 >= 0x10000 - extra) 5082 && !((TARGET_POWERPC64 5083 && (mode == DImode || mode == TImode) 5084 && (INTVAL (XEXP (x, 1)) & 3) != 0) 5085 || SPE_VECTOR_MODE (mode) 5086 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode 5087 || mode == DImode || mode == DDmode 5088 || mode == TDmode)))) 5089 { 5090 HOST_WIDE_INT high_int, low_int; 5091 rtx sum; 5092 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000; 5093 if (low_int >= 0x8000 - extra) 5094 low_int = 0; 5095 high_int = INTVAL (XEXP (x, 1)) - low_int; 5096 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0), 5097 GEN_INT (high_int)), 0); 5098 return plus_constant (sum, low_int); 5099 } 5100 else if (GET_CODE (x) == PLUS 5101 && GET_CODE (XEXP (x, 0)) == REG 5102 && GET_CODE (XEXP (x, 1)) != CONST_INT 5103 && GET_MODE_NUNITS (mode) == 1 5104 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) 5105 || TARGET_POWERPC64 5106 || ((mode != DImode && mode != DFmode && mode != DDmode) 5107 || (TARGET_E500_DOUBLE && mode != DDmode))) 5108 && (TARGET_POWERPC64 || mode != DImode) 5109 && !avoiding_indexed_address_p (mode) 5110 && mode != TImode 5111 && mode != TFmode 5112 && mode != TDmode) 5113 { 5114 return gen_rtx_PLUS (Pmode, XEXP (x, 0), 5115 force_reg (Pmode, force_operand (XEXP (x, 1), 0))); 5116 } 5117 else if (SPE_VECTOR_MODE (mode) 5118 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode 5119 || mode == DDmode || mode == TDmode 5120 || mode == DImode))) 5121 { 5122 if (mode == DImode) 5123 return x; 5124 /* We accept [reg + reg] and [reg + OFFSET]. */ 5125 5126 if (GET_CODE (x) == PLUS) 5127 { 5128 rtx op1 = XEXP (x, 0); 5129 rtx op2 = XEXP (x, 1); 5130 rtx y; 5131 5132 op1 = force_reg (Pmode, op1); 5133 5134 if (GET_CODE (op2) != REG 5135 && (GET_CODE (op2) != CONST_INT 5136 || !SPE_CONST_OFFSET_OK (INTVAL (op2)) 5137 || (GET_MODE_SIZE (mode) > 8 5138 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8)))) 5139 op2 = force_reg (Pmode, op2); 5140 5141 /* We can't always do [reg + reg] for these, because [reg + 5142 reg + offset] is not a legitimate addressing mode. */ 5143 y = gen_rtx_PLUS (Pmode, op1, op2); 5144 5145 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2)) 5146 return force_reg (Pmode, y); 5147 else 5148 return y; 5149 } 5150 5151 return force_reg (Pmode, x); 5152 } 5153 else if (TARGET_ELF 5154 && TARGET_32BIT 5155 && TARGET_NO_TOC 5156 && ! flag_pic 5157 && GET_CODE (x) != CONST_INT 5158 && GET_CODE (x) != CONST_DOUBLE 5159 && CONSTANT_P (x) 5160 && GET_MODE_NUNITS (mode) == 1 5161 && (GET_MODE_BITSIZE (mode) <= 32 5162 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) 5163 && (mode == DFmode || mode == DDmode)))) 5164 { 5165 rtx reg = gen_reg_rtx (Pmode); 5166 emit_insn (gen_elf_high (reg, x)); 5167 return gen_rtx_LO_SUM (Pmode, reg, x); 5168 } 5169 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC 5170 && ! flag_pic 5171#if TARGET_MACHO 5172 && ! MACHO_DYNAMIC_NO_PIC_P 5173#endif 5174 && GET_CODE (x) != CONST_INT 5175 && GET_CODE (x) != CONST_DOUBLE 5176 && CONSTANT_P (x) 5177 && GET_MODE_NUNITS (mode) == 1 5178 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) 5179 || (mode != DFmode && mode != DDmode)) 5180 && mode != DImode 5181 && mode != TImode) 5182 { 5183 rtx reg = gen_reg_rtx (Pmode); 5184 emit_insn (gen_macho_high (reg, x)); 5185 return gen_rtx_LO_SUM (Pmode, reg, x); 5186 } 5187 else if (TARGET_TOC 5188 && GET_CODE (x) == SYMBOL_REF 5189 && constant_pool_expr_p (x) 5190 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode)) 5191 { 5192 return create_TOC_reference (x); 5193 } 5194 else 5195 return x; 5196} 5197 5198/* Debug version of rs6000_legitimize_address. */ 5199static rtx 5200rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode) 5201{ 5202 rtx ret; 5203 rtx insns; 5204 5205 start_sequence (); 5206 ret = rs6000_legitimize_address (x, oldx, mode); 5207 insns = get_insns (); 5208 end_sequence (); 5209 5210 if (ret != x) 5211 { 5212 fprintf (stderr, 5213 "\nrs6000_legitimize_address: mode %s, old code %s, " 5214 "new code %s, modified\n", 5215 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)), 5216 GET_RTX_NAME (GET_CODE (ret))); 5217 5218 fprintf (stderr, "Original address:\n"); 5219 debug_rtx (x); 5220 5221 fprintf (stderr, "oldx:\n"); 5222 debug_rtx (oldx); 5223 5224 fprintf (stderr, "New address:\n"); 5225 debug_rtx (ret); 5226 5227 if (insns) 5228 { 5229 fprintf (stderr, "Insns added:\n"); 5230 debug_rtx_list (insns, 20); 5231 } 5232 } 5233 else 5234 { 5235 fprintf (stderr, 5236 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n", 5237 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x))); 5238 5239 debug_rtx (x); 5240 } 5241 5242 if (insns) 5243 emit_insn (insns); 5244 5245 return ret; 5246} 5247 5248/* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL. 5249 We need to emit DTP-relative relocations. */ 5250 5251static void 5252rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x) 5253{ 5254 switch (size) 5255 { 5256 case 4: 5257 fputs ("\t.long\t", file); 5258 break; 5259 case 8: 5260 fputs (DOUBLE_INT_ASM_OP, file); 5261 break; 5262 default: 5263 gcc_unreachable (); 5264 } 5265 output_addr_const (file, x); 5266 fputs ("@dtprel+0x8000", file); 5267} 5268 5269/* In the name of slightly smaller debug output, and to cater to 5270 general assembler lossage, recognize various UNSPEC sequences 5271 and turn them back into a direct symbol reference. */ 5272 5273static rtx 5274rs6000_delegitimize_address (rtx orig_x) 5275{ 5276 rtx x, y; 5277 5278 orig_x = delegitimize_mem_from_attrs (orig_x); 5279 x = orig_x; 5280 if (MEM_P (x)) 5281 x = XEXP (x, 0); 5282 5283 if (GET_CODE (x) == PLUS 5284 && GET_CODE (XEXP (x, 1)) == CONST 5285 && GET_CODE (XEXP (x, 0)) == REG 5286 && REGNO (XEXP (x, 0)) == TOC_REGISTER) 5287 { 5288 y = XEXP (XEXP (x, 1), 0); 5289 if (GET_CODE (y) == UNSPEC 5290 && XINT (y, 1) == UNSPEC_TOCREL) 5291 { 5292 y = XVECEXP (y, 0, 0); 5293 if (!MEM_P (orig_x)) 5294 return y; 5295 else 5296 return replace_equiv_address_nv (orig_x, y); 5297 } 5298 return orig_x; 5299 } 5300 5301 if (TARGET_MACHO 5302 && GET_CODE (orig_x) == LO_SUM 5303 && GET_CODE (XEXP (x, 1)) == CONST) 5304 { 5305 y = XEXP (XEXP (x, 1), 0); 5306 if (GET_CODE (y) == UNSPEC 5307 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET) 5308 return XVECEXP (y, 0, 0); 5309 } 5310 5311 return orig_x; 5312} 5313 5314/* Construct the SYMBOL_REF for the tls_get_addr function. */ 5315 5316static GTY(()) rtx rs6000_tls_symbol; 5317static rtx 5318rs6000_tls_get_addr (void) 5319{ 5320 if (!rs6000_tls_symbol) 5321 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr"); 5322 5323 return rs6000_tls_symbol; 5324} 5325 5326/* Construct the SYMBOL_REF for TLS GOT references. */ 5327 5328static GTY(()) rtx rs6000_got_symbol; 5329static rtx 5330rs6000_got_sym (void) 5331{ 5332 if (!rs6000_got_symbol) 5333 { 5334 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); 5335 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL; 5336 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL; 5337 } 5338 5339 return rs6000_got_symbol; 5340} 5341 5342/* ADDR contains a thread-local SYMBOL_REF. Generate code to compute 5343 this (thread-local) address. */ 5344 5345static rtx 5346rs6000_legitimize_tls_address (rtx addr, enum tls_model model) 5347{ 5348 rtx dest, insn; 5349 5350 dest = gen_reg_rtx (Pmode); 5351 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16) 5352 { 5353 rtx tlsreg; 5354 5355 if (TARGET_64BIT) 5356 { 5357 tlsreg = gen_rtx_REG (Pmode, 13); 5358 insn = gen_tls_tprel_64 (dest, tlsreg, addr); 5359 } 5360 else 5361 { 5362 tlsreg = gen_rtx_REG (Pmode, 2); 5363 insn = gen_tls_tprel_32 (dest, tlsreg, addr); 5364 } 5365 emit_insn (insn); 5366 } 5367 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32) 5368 { 5369 rtx tlsreg, tmp; 5370 5371 tmp = gen_reg_rtx (Pmode); 5372 if (TARGET_64BIT) 5373 { 5374 tlsreg = gen_rtx_REG (Pmode, 13); 5375 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr); 5376 } 5377 else 5378 { 5379 tlsreg = gen_rtx_REG (Pmode, 2); 5380 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr); 5381 } 5382 emit_insn (insn); 5383 if (TARGET_64BIT) 5384 insn = gen_tls_tprel_lo_64 (dest, tmp, addr); 5385 else 5386 insn = gen_tls_tprel_lo_32 (dest, tmp, addr); 5387 emit_insn (insn); 5388 } 5389 else 5390 { 5391 rtx r3, got, tga, tmp1, tmp2, call_insn; 5392 5393 /* We currently use relocations like @got@tlsgd for tls, which 5394 means the linker will handle allocation of tls entries, placing 5395 them in the .got section. So use a pointer to the .got section, 5396 not one to secondary TOC sections used by 64-bit -mminimal-toc, 5397 or to secondary GOT sections used by 32-bit -fPIC. */ 5398 if (TARGET_64BIT) 5399 got = gen_rtx_REG (Pmode, 2); 5400 else 5401 { 5402 if (flag_pic == 1) 5403 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM); 5404 else 5405 { 5406 rtx gsym = rs6000_got_sym (); 5407 got = gen_reg_rtx (Pmode); 5408 if (flag_pic == 0) 5409 rs6000_emit_move (got, gsym, Pmode); 5410 else 5411 { 5412 rtx mem, lab, last; 5413 5414 tmp1 = gen_reg_rtx (Pmode); 5415 tmp2 = gen_reg_rtx (Pmode); 5416 mem = gen_const_mem (Pmode, tmp1); 5417 lab = gen_label_rtx (); 5418 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab)); 5419 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO)); 5420 emit_move_insn (tmp2, mem); 5421 last = emit_insn (gen_addsi3 (got, tmp1, tmp2)); 5422 set_unique_reg_note (last, REG_EQUAL, gsym); 5423 } 5424 } 5425 } 5426 5427 if (model == TLS_MODEL_GLOBAL_DYNAMIC) 5428 { 5429 r3 = gen_rtx_REG (Pmode, 3); 5430 tga = rs6000_tls_get_addr (); 5431 emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode); 5432 5433 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT) 5434 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx); 5435 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT) 5436 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx); 5437 else if (DEFAULT_ABI == ABI_V4) 5438 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx); 5439 else 5440 gcc_unreachable (); 5441 call_insn = last_call_insn (); 5442 PATTERN (call_insn) = insn; 5443 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic) 5444 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), 5445 pic_offset_table_rtx); 5446 } 5447 else if (model == TLS_MODEL_LOCAL_DYNAMIC) 5448 { 5449 r3 = gen_rtx_REG (Pmode, 3); 5450 tga = rs6000_tls_get_addr (); 5451 tmp1 = gen_reg_rtx (Pmode); 5452 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode); 5453 5454 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT) 5455 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx); 5456 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT) 5457 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx); 5458 else if (DEFAULT_ABI == ABI_V4) 5459 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx); 5460 else 5461 gcc_unreachable (); 5462 call_insn = last_call_insn (); 5463 PATTERN (call_insn) = insn; 5464 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic) 5465 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), 5466 pic_offset_table_rtx); 5467 5468 if (rs6000_tls_size == 16) 5469 { 5470 if (TARGET_64BIT) 5471 insn = gen_tls_dtprel_64 (dest, tmp1, addr); 5472 else 5473 insn = gen_tls_dtprel_32 (dest, tmp1, addr); 5474 } 5475 else if (rs6000_tls_size == 32) 5476 { 5477 tmp2 = gen_reg_rtx (Pmode); 5478 if (TARGET_64BIT) 5479 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr); 5480 else 5481 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr); 5482 emit_insn (insn); 5483 if (TARGET_64BIT) 5484 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr); 5485 else 5486 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr); 5487 } 5488 else 5489 { 5490 tmp2 = gen_reg_rtx (Pmode); 5491 if (TARGET_64BIT) 5492 insn = gen_tls_got_dtprel_64 (tmp2, got, addr); 5493 else 5494 insn = gen_tls_got_dtprel_32 (tmp2, got, addr); 5495 emit_insn (insn); 5496 insn = gen_rtx_SET (Pmode, dest, 5497 gen_rtx_PLUS (Pmode, tmp2, tmp1)); 5498 } 5499 emit_insn (insn); 5500 } 5501 else 5502 { 5503 /* IE, or 64-bit offset LE. */ 5504 tmp2 = gen_reg_rtx (Pmode); 5505 if (TARGET_64BIT) 5506 insn = gen_tls_got_tprel_64 (tmp2, got, addr); 5507 else 5508 insn = gen_tls_got_tprel_32 (tmp2, got, addr); 5509 emit_insn (insn); 5510 if (TARGET_64BIT) 5511 insn = gen_tls_tls_64 (dest, tmp2, addr); 5512 else 5513 insn = gen_tls_tls_32 (dest, tmp2, addr); 5514 emit_insn (insn); 5515 } 5516 } 5517 5518 return dest; 5519} 5520 5521/* Return 1 if X contains a thread-local symbol. */ 5522 5523bool 5524rs6000_tls_referenced_p (rtx x) 5525{ 5526 if (! TARGET_HAVE_TLS) 5527 return false; 5528 5529 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0); 5530} 5531 5532/* Return 1 if *X is a thread-local symbol. This is the same as 5533 rs6000_tls_symbol_ref except for the type of the unused argument. */ 5534 5535static int 5536rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED) 5537{ 5538 return RS6000_SYMBOL_REF_TLS_P (*x); 5539} 5540 5541/* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to 5542 replace the input X, or the original X if no replacement is called for. 5543 The output parameter *WIN is 1 if the calling macro should goto WIN, 5544 0 if it should not. 5545 5546 For RS/6000, we wish to handle large displacements off a base 5547 register by splitting the addend across an addiu/addis and the mem insn. 5548 This cuts number of extra insns needed from 3 to 1. 5549 5550 On Darwin, we use this to generate code for floating point constants. 5551 A movsf_low is generated so we wind up with 2 instructions rather than 3. 5552 The Darwin code is inside #if TARGET_MACHO because only then are the 5553 machopic_* functions defined. */ 5554static rtx 5555rs6000_legitimize_reload_address (rtx x, enum machine_mode mode, 5556 int opnum, int type, 5557 int ind_levels ATTRIBUTE_UNUSED, int *win) 5558{ 5559 bool reg_offset_p = reg_offset_addressing_ok_p (mode); 5560 5561 /* We must recognize output that we have already generated ourselves. */ 5562 if (GET_CODE (x) == PLUS 5563 && GET_CODE (XEXP (x, 0)) == PLUS 5564 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG 5565 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 5566 && GET_CODE (XEXP (x, 1)) == CONST_INT) 5567 { 5568 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, 5569 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0, 5570 opnum, (enum reload_type)type); 5571 *win = 1; 5572 return x; 5573 } 5574 5575#if TARGET_MACHO 5576 if (DEFAULT_ABI == ABI_DARWIN && flag_pic 5577 && GET_CODE (x) == LO_SUM 5578 && GET_CODE (XEXP (x, 0)) == PLUS 5579 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx 5580 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH 5581 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1) 5582 && machopic_operand_p (XEXP (x, 1))) 5583 { 5584 /* Result of previous invocation of this function on Darwin 5585 floating point constant. */ 5586 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, 5587 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, 5588 opnum, (enum reload_type)type); 5589 *win = 1; 5590 return x; 5591 } 5592#endif 5593 5594 /* Force ld/std non-word aligned offset into base register by wrapping 5595 in offset 0. */ 5596 if (GET_CODE (x) == PLUS 5597 && GET_CODE (XEXP (x, 0)) == REG 5598 && REGNO (XEXP (x, 0)) < 32 5599 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1) 5600 && GET_CODE (XEXP (x, 1)) == CONST_INT 5601 && reg_offset_p 5602 && (INTVAL (XEXP (x, 1)) & 3) != 0 5603 && VECTOR_MEM_NONE_P (mode) 5604 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD 5605 && TARGET_POWERPC64) 5606 { 5607 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0)); 5608 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, 5609 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0, 5610 opnum, (enum reload_type) type); 5611 *win = 1; 5612 return x; 5613 } 5614 5615 if (GET_CODE (x) == PLUS 5616 && GET_CODE (XEXP (x, 0)) == REG 5617 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER 5618 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1) 5619 && GET_CODE (XEXP (x, 1)) == CONST_INT 5620 && reg_offset_p 5621 && !SPE_VECTOR_MODE (mode) 5622 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode 5623 || mode == DDmode || mode == TDmode 5624 || mode == DImode)) 5625 && VECTOR_MEM_NONE_P (mode)) 5626 { 5627 HOST_WIDE_INT val = INTVAL (XEXP (x, 1)); 5628 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; 5629 HOST_WIDE_INT high 5630 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000; 5631 5632 /* Check for 32-bit overflow. */ 5633 if (high + low != val) 5634 { 5635 *win = 0; 5636 return x; 5637 } 5638 5639 /* Reload the high part into a base reg; leave the low part 5640 in the mem directly. */ 5641 5642 x = gen_rtx_PLUS (GET_MODE (x), 5643 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0), 5644 GEN_INT (high)), 5645 GEN_INT (low)); 5646 5647 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, 5648 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0, 5649 opnum, (enum reload_type)type); 5650 *win = 1; 5651 return x; 5652 } 5653 5654 if (GET_CODE (x) == SYMBOL_REF 5655 && reg_offset_p 5656 && VECTOR_MEM_NONE_P (mode) 5657 && !SPE_VECTOR_MODE (mode) 5658#if TARGET_MACHO 5659 && DEFAULT_ABI == ABI_DARWIN 5660 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P) 5661#else 5662 && DEFAULT_ABI == ABI_V4 5663 && !flag_pic 5664#endif 5665 /* Don't do this for TFmode or TDmode, since the result isn't offsettable. 5666 The same goes for DImode without 64-bit gprs and DFmode and DDmode 5667 without fprs. */ 5668 && mode != TFmode 5669 && mode != TDmode 5670 && (mode != DImode || TARGET_POWERPC64) 5671 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64 5672 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT))) 5673 { 5674#if TARGET_MACHO 5675 if (flag_pic) 5676 { 5677 rtx offset = machopic_gen_offset (x); 5678 x = gen_rtx_LO_SUM (GET_MODE (x), 5679 gen_rtx_PLUS (Pmode, pic_offset_table_rtx, 5680 gen_rtx_HIGH (Pmode, offset)), offset); 5681 } 5682 else 5683#endif 5684 x = gen_rtx_LO_SUM (GET_MODE (x), 5685 gen_rtx_HIGH (Pmode, x), x); 5686 5687 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, 5688 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, 5689 opnum, (enum reload_type)type); 5690 *win = 1; 5691 return x; 5692 } 5693 5694 /* Reload an offset address wrapped by an AND that represents the 5695 masking of the lower bits. Strip the outer AND and let reload 5696 convert the offset address into an indirect address. For VSX, 5697 force reload to create the address with an AND in a separate 5698 register, because we can't guarantee an altivec register will 5699 be used. */ 5700 if (VECTOR_MEM_ALTIVEC_P (mode) 5701 && GET_CODE (x) == AND 5702 && GET_CODE (XEXP (x, 0)) == PLUS 5703 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG 5704 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 5705 && GET_CODE (XEXP (x, 1)) == CONST_INT 5706 && INTVAL (XEXP (x, 1)) == -16) 5707 { 5708 x = XEXP (x, 0); 5709 *win = 1; 5710 return x; 5711 } 5712 5713 if (TARGET_TOC 5714 && reg_offset_p 5715 && GET_CODE (x) == SYMBOL_REF 5716 && constant_pool_expr_p (x) 5717 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode)) 5718 { 5719 x = create_TOC_reference (x); 5720 *win = 1; 5721 return x; 5722 } 5723 *win = 0; 5724 return x; 5725} 5726 5727/* Debug version of rs6000_legitimize_reload_address. */ 5728static rtx 5729rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode, 5730 int opnum, int type, 5731 int ind_levels, int *win) 5732{ 5733 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type, 5734 ind_levels, win); 5735 fprintf (stderr, 5736 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, " 5737 "type = %d, ind_levels = %d, win = %d, original addr:\n", 5738 GET_MODE_NAME (mode), opnum, type, ind_levels, *win); 5739 debug_rtx (x); 5740 5741 if (x == ret) 5742 fprintf (stderr, "Same address returned\n"); 5743 else if (!ret) 5744 fprintf (stderr, "NULL returned\n"); 5745 else 5746 { 5747 fprintf (stderr, "New address:\n"); 5748 debug_rtx (ret); 5749 } 5750 5751 return ret; 5752} 5753 5754/* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression 5755 that is a valid memory address for an instruction. 5756 The MODE argument is the machine mode for the MEM expression 5757 that wants to use this address. 5758 5759 On the RS/6000, there are four valid address: a SYMBOL_REF that 5760 refers to a constant pool entry of an address (or the sum of it 5761 plus a constant), a short (16-bit signed) constant plus a register, 5762 the sum of two registers, or a register indirect, possibly with an 5763 auto-increment. For DFmode, DDmode and DImode with a constant plus 5764 register, we must ensure that both words are addressable or PowerPC64 5765 with offset word aligned. 5766 5767 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs, 5768 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used 5769 because adjacent memory cells are accessed by adding word-sized offsets 5770 during assembly output. */ 5771bool 5772rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict) 5773{ 5774 bool reg_offset_p = reg_offset_addressing_ok_p (mode); 5775 5776 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */ 5777 if (VECTOR_MEM_ALTIVEC_P (mode) 5778 && GET_CODE (x) == AND 5779 && GET_CODE (XEXP (x, 1)) == CONST_INT 5780 && INTVAL (XEXP (x, 1)) == -16) 5781 x = XEXP (x, 0); 5782 5783 if (RS6000_SYMBOL_REF_TLS_P (x)) 5784 return 0; 5785 if (legitimate_indirect_address_p (x, reg_ok_strict)) 5786 return 1; 5787 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC) 5788 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode) 5789 && !SPE_VECTOR_MODE (mode) 5790 && mode != TFmode 5791 && mode != TDmode 5792 /* Restrict addressing for DI because of our SUBREG hackery. */ 5793 && !(TARGET_E500_DOUBLE 5794 && (mode == DFmode || mode == DDmode || mode == DImode)) 5795 && TARGET_UPDATE 5796 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)) 5797 return 1; 5798 if (virtual_stack_registers_memory_p (x)) 5799 return 1; 5800 if (reg_offset_p && legitimate_small_data_p (mode, x)) 5801 return 1; 5802 if (reg_offset_p && legitimate_constant_pool_address_p (x)) 5803 return 1; 5804 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */ 5805 if (! reg_ok_strict 5806 && reg_offset_p 5807 && GET_CODE (x) == PLUS 5808 && GET_CODE (XEXP (x, 0)) == REG 5809 && (XEXP (x, 0) == virtual_stack_vars_rtx 5810 || XEXP (x, 0) == arg_pointer_rtx) 5811 && GET_CODE (XEXP (x, 1)) == CONST_INT) 5812 return 1; 5813 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict)) 5814 return 1; 5815 if (mode != TImode 5816 && mode != TFmode 5817 && mode != TDmode 5818 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) 5819 || TARGET_POWERPC64 5820 || (mode != DFmode && mode != DDmode) 5821 || (TARGET_E500_DOUBLE && mode != DDmode)) 5822 && (TARGET_POWERPC64 || mode != DImode) 5823 && !avoiding_indexed_address_p (mode) 5824 && legitimate_indexed_address_p (x, reg_ok_strict)) 5825 return 1; 5826 if (GET_CODE (x) == PRE_MODIFY 5827 && mode != TImode 5828 && mode != TFmode 5829 && mode != TDmode 5830 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) 5831 || TARGET_POWERPC64 5832 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE)) 5833 && (TARGET_POWERPC64 || mode != DImode) 5834 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode) 5835 && !SPE_VECTOR_MODE (mode) 5836 /* Restrict addressing for DI because of our SUBREG hackery. */ 5837 && !(TARGET_E500_DOUBLE 5838 && (mode == DFmode || mode == DDmode || mode == DImode)) 5839 && TARGET_UPDATE 5840 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict) 5841 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict) 5842 || (!avoiding_indexed_address_p (mode) 5843 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict))) 5844 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0))) 5845 return 1; 5846 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict)) 5847 return 1; 5848 return 0; 5849} 5850 5851/* Debug version of rs6000_legitimate_address_p. */ 5852static bool 5853rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x, 5854 bool reg_ok_strict) 5855{ 5856 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict); 5857 fprintf (stderr, 5858 "\nrs6000_legitimate_address_p: return = %s, mode = %s, " 5859 "strict = %d, code = %s\n", 5860 ret ? "true" : "false", 5861 GET_MODE_NAME (mode), 5862 reg_ok_strict, 5863 GET_RTX_NAME (GET_CODE (x))); 5864 debug_rtx (x); 5865 5866 return ret; 5867} 5868 5869/* Go to LABEL if ADDR (a legitimate address expression) 5870 has an effect that depends on the machine mode it is used for. 5871 5872 On the RS/6000 this is true of all integral offsets (since AltiVec 5873 and VSX modes don't allow them) or is a pre-increment or decrement. 5874 5875 ??? Except that due to conceptual problems in offsettable_address_p 5876 we can't really report the problems of integral offsets. So leave 5877 this assuming that the adjustable offset must be valid for the 5878 sub-words of a TFmode operand, which is what we had before. */ 5879 5880static bool 5881rs6000_mode_dependent_address (rtx addr) 5882{ 5883 switch (GET_CODE (addr)) 5884 { 5885 case PLUS: 5886 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx 5887 is considered a legitimate address before reload, so there 5888 are no offset restrictions in that case. Note that this 5889 condition is safe in strict mode because any address involving 5890 virtual_stack_vars_rtx or arg_pointer_rtx would already have 5891 been rejected as illegitimate. */ 5892 if (XEXP (addr, 0) != virtual_stack_vars_rtx 5893 && XEXP (addr, 0) != arg_pointer_rtx 5894 && GET_CODE (XEXP (addr, 1)) == CONST_INT) 5895 { 5896 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1)); 5897 return val + 12 + 0x8000 >= 0x10000; 5898 } 5899 break; 5900 5901 case LO_SUM: 5902 return true; 5903 5904 /* Auto-increment cases are now treated generically in recog.c. */ 5905 case PRE_MODIFY: 5906 return TARGET_UPDATE; 5907 5908 /* AND is only allowed in Altivec loads. */ 5909 case AND: 5910 return true; 5911 5912 default: 5913 break; 5914 } 5915 5916 return false; 5917} 5918 5919/* Debug version of rs6000_mode_dependent_address. */ 5920static bool 5921rs6000_debug_mode_dependent_address (rtx addr) 5922{ 5923 bool ret = rs6000_mode_dependent_address (addr); 5924 5925 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n", 5926 ret ? "true" : "false"); 5927 debug_rtx (addr); 5928 5929 return ret; 5930} 5931 5932/* Implement FIND_BASE_TERM. */ 5933 5934rtx 5935rs6000_find_base_term (rtx op) 5936{ 5937 rtx base, offset; 5938 5939 split_const (op, &base, &offset); 5940 if (GET_CODE (base) == UNSPEC) 5941 switch (XINT (base, 1)) 5942 { 5943 case UNSPEC_TOCREL: 5944 case UNSPEC_MACHOPIC_OFFSET: 5945 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term 5946 for aliasing purposes. */ 5947 return XVECEXP (base, 0, 0); 5948 } 5949 5950 return op; 5951} 5952 5953/* More elaborate version of recog's offsettable_memref_p predicate 5954 that works around the ??? note of rs6000_mode_dependent_address. 5955 In particular it accepts 5956 5957 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8]))) 5958 5959 in 32-bit mode, that the recog predicate rejects. */ 5960 5961bool 5962rs6000_offsettable_memref_p (rtx op) 5963{ 5964 if (!MEM_P (op)) 5965 return false; 5966 5967 /* First mimic offsettable_memref_p. */ 5968 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0))) 5969 return true; 5970 5971 /* offsettable_address_p invokes rs6000_mode_dependent_address, but 5972 the latter predicate knows nothing about the mode of the memory 5973 reference and, therefore, assumes that it is the largest supported 5974 mode (TFmode). As a consequence, legitimate offsettable memory 5975 references are rejected. rs6000_legitimate_offset_address_p contains 5976 the correct logic for the PLUS case of rs6000_mode_dependent_address. */ 5977 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1); 5978} 5979 5980/* Change register usage conditional on target flags. */ 5981void 5982rs6000_conditional_register_usage (void) 5983{ 5984 int i; 5985 5986 /* Set MQ register fixed (already call_used) if not POWER 5987 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not 5988 be allocated. */ 5989 if (! TARGET_POWER) 5990 fixed_regs[64] = 1; 5991 5992 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */ 5993 if (TARGET_64BIT) 5994 fixed_regs[13] = call_used_regs[13] 5995 = call_really_used_regs[13] = 1; 5996 5997 /* Conditionally disable FPRs. */ 5998 if (TARGET_SOFT_FLOAT || !TARGET_FPRS) 5999 for (i = 32; i < 64; i++) 6000 fixed_regs[i] = call_used_regs[i] 6001 = call_really_used_regs[i] = 1; 6002 6003 /* The TOC register is not killed across calls in a way that is 6004 visible to the compiler. */ 6005 if (DEFAULT_ABI == ABI_AIX) 6006 call_really_used_regs[2] = 0; 6007 6008 if (DEFAULT_ABI == ABI_V4 6009 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM 6010 && flag_pic == 2) 6011 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; 6012 6013 if (DEFAULT_ABI == ABI_V4 6014 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM 6015 && flag_pic == 1) 6016 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] 6017 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] 6018 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; 6019 6020 if (DEFAULT_ABI == ABI_DARWIN 6021 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) 6022 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] 6023 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] 6024 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; 6025 6026 if (TARGET_TOC && TARGET_MINIMAL_TOC) 6027 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] 6028 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; 6029 6030 if (TARGET_SPE) 6031 { 6032 global_regs[SPEFSCR_REGNO] = 1; 6033 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit 6034 registers in prologues and epilogues. We no longer use r14 6035 for FIXED_SCRATCH, but we're keeping r14 out of the allocation 6036 pool for link-compatibility with older versions of GCC. Once 6037 "old" code has died out, we can return r14 to the allocation 6038 pool. */ 6039 fixed_regs[14] 6040 = call_used_regs[14] 6041 = call_really_used_regs[14] = 1; 6042 } 6043 6044 if (!TARGET_ALTIVEC && !TARGET_VSX) 6045 { 6046 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i) 6047 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1; 6048 call_really_used_regs[VRSAVE_REGNO] = 1; 6049 } 6050 6051 if (TARGET_ALTIVEC || TARGET_VSX) 6052 global_regs[VSCR_REGNO] = 1; 6053 6054 if (TARGET_ALTIVEC_ABI) 6055 { 6056 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i) 6057 call_used_regs[i] = call_really_used_regs[i] = 1; 6058 6059 /* AIX reserves VR20:31 in non-extended ABI mode. */ 6060 if (TARGET_XCOFF) 6061 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i) 6062 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1; 6063 } 6064} 6065 6066/* Try to output insns to set TARGET equal to the constant C if it can 6067 be done in less than N insns. Do all computations in MODE. 6068 Returns the place where the output has been placed if it can be 6069 done and the insns have been emitted. If it would take more than N 6070 insns, zero is returned and no insns and emitted. */ 6071 6072rtx 6073rs6000_emit_set_const (rtx dest, enum machine_mode mode, 6074 rtx source, int n ATTRIBUTE_UNUSED) 6075{ 6076 rtx result, insn, set; 6077 HOST_WIDE_INT c0, c1; 6078 6079 switch (mode) 6080 { 6081 case QImode: 6082 case HImode: 6083 if (dest == NULL) 6084 dest = gen_reg_rtx (mode); 6085 emit_insn (gen_rtx_SET (VOIDmode, dest, source)); 6086 return dest; 6087 6088 case SImode: 6089 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode); 6090 6091 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result), 6092 GEN_INT (INTVAL (source) 6093 & (~ (HOST_WIDE_INT) 0xffff)))); 6094 emit_insn (gen_rtx_SET (VOIDmode, dest, 6095 gen_rtx_IOR (SImode, copy_rtx (result), 6096 GEN_INT (INTVAL (source) & 0xffff)))); 6097 result = dest; 6098 break; 6099 6100 case DImode: 6101 switch (GET_CODE (source)) 6102 { 6103 case CONST_INT: 6104 c0 = INTVAL (source); 6105 c1 = -(c0 < 0); 6106 break; 6107 6108 case CONST_DOUBLE: 6109#if HOST_BITS_PER_WIDE_INT >= 64 6110 c0 = CONST_DOUBLE_LOW (source); 6111 c1 = -(c0 < 0); 6112#else 6113 c0 = CONST_DOUBLE_LOW (source); 6114 c1 = CONST_DOUBLE_HIGH (source); 6115#endif 6116 break; 6117 6118 default: 6119 gcc_unreachable (); 6120 } 6121 6122 result = rs6000_emit_set_long_const (dest, c0, c1); 6123 break; 6124 6125 default: 6126 gcc_unreachable (); 6127 } 6128 6129 insn = get_last_insn (); 6130 set = single_set (insn); 6131 if (! CONSTANT_P (SET_SRC (set))) 6132 set_unique_reg_note (insn, REG_EQUAL, source); 6133 6134 return result; 6135} 6136 6137/* Having failed to find a 3 insn sequence in rs6000_emit_set_const, 6138 fall back to a straight forward decomposition. We do this to avoid 6139 exponential run times encountered when looking for longer sequences 6140 with rs6000_emit_set_const. */ 6141static rtx 6142rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2) 6143{ 6144 if (!TARGET_POWERPC64) 6145 { 6146 rtx operand1, operand2; 6147 6148 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0, 6149 DImode); 6150 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0, 6151 DImode); 6152 emit_move_insn (operand1, GEN_INT (c1)); 6153 emit_move_insn (operand2, GEN_INT (c2)); 6154 } 6155 else 6156 { 6157 HOST_WIDE_INT ud1, ud2, ud3, ud4; 6158 6159 ud1 = c1 & 0xffff; 6160 ud2 = (c1 & 0xffff0000) >> 16; 6161#if HOST_BITS_PER_WIDE_INT >= 64 6162 c2 = c1 >> 32; 6163#endif 6164 ud3 = c2 & 0xffff; 6165 ud4 = (c2 & 0xffff0000) >> 16; 6166 6167 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000)) 6168 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000))) 6169 { 6170 if (ud1 & 0x8000) 6171 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000))); 6172 else 6173 emit_move_insn (dest, GEN_INT (ud1)); 6174 } 6175 6176 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000)) 6177 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000))) 6178 { 6179 if (ud2 & 0x8000) 6180 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000) 6181 - 0x80000000)); 6182 else 6183 emit_move_insn (dest, GEN_INT (ud2 << 16)); 6184 if (ud1 != 0) 6185 emit_move_insn (copy_rtx (dest), 6186 gen_rtx_IOR (DImode, copy_rtx (dest), 6187 GEN_INT (ud1))); 6188 } 6189 else if (ud3 == 0 && ud4 == 0) 6190 { 6191 gcc_assert (ud2 & 0x8000); 6192 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000) 6193 - 0x80000000)); 6194 if (ud1 != 0) 6195 emit_move_insn (copy_rtx (dest), 6196 gen_rtx_IOR (DImode, copy_rtx (dest), 6197 GEN_INT (ud1))); 6198 emit_move_insn (copy_rtx (dest), 6199 gen_rtx_ZERO_EXTEND (DImode, 6200 gen_lowpart (SImode, 6201 copy_rtx (dest)))); 6202 } 6203 else if ((ud4 == 0xffff && (ud3 & 0x8000)) 6204 || (ud4 == 0 && ! (ud3 & 0x8000))) 6205 { 6206 if (ud3 & 0x8000) 6207 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000) 6208 - 0x80000000)); 6209 else 6210 emit_move_insn (dest, GEN_INT (ud3 << 16)); 6211 6212 if (ud2 != 0) 6213 emit_move_insn (copy_rtx (dest), 6214 gen_rtx_IOR (DImode, copy_rtx (dest), 6215 GEN_INT (ud2))); 6216 emit_move_insn (copy_rtx (dest), 6217 gen_rtx_ASHIFT (DImode, copy_rtx (dest), 6218 GEN_INT (16))); 6219 if (ud1 != 0) 6220 emit_move_insn (copy_rtx (dest), 6221 gen_rtx_IOR (DImode, copy_rtx (dest), 6222 GEN_INT (ud1))); 6223 } 6224 else 6225 { 6226 if (ud4 & 0x8000) 6227 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000) 6228 - 0x80000000)); 6229 else 6230 emit_move_insn (dest, GEN_INT (ud4 << 16)); 6231 6232 if (ud3 != 0) 6233 emit_move_insn (copy_rtx (dest), 6234 gen_rtx_IOR (DImode, copy_rtx (dest), 6235 GEN_INT (ud3))); 6236 6237 emit_move_insn (copy_rtx (dest), 6238 gen_rtx_ASHIFT (DImode, copy_rtx (dest), 6239 GEN_INT (32))); 6240 if (ud2 != 0) 6241 emit_move_insn (copy_rtx (dest), 6242 gen_rtx_IOR (DImode, copy_rtx (dest), 6243 GEN_INT (ud2 << 16))); 6244 if (ud1 != 0) 6245 emit_move_insn (copy_rtx (dest), 6246 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1))); 6247 } 6248 } 6249 return dest; 6250} 6251 6252/* Helper for the following. Get rid of [r+r] memory refs 6253 in cases where it won't work (TImode, TFmode, TDmode). */ 6254 6255static void 6256rs6000_eliminate_indexed_memrefs (rtx operands[2]) 6257{ 6258 if (GET_CODE (operands[0]) == MEM 6259 && GET_CODE (XEXP (operands[0], 0)) != REG 6260 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0)) 6261 && ! reload_in_progress) 6262 operands[0] 6263 = replace_equiv_address (operands[0], 6264 copy_addr_to_reg (XEXP (operands[0], 0))); 6265 6266 if (GET_CODE (operands[1]) == MEM 6267 && GET_CODE (XEXP (operands[1], 0)) != REG 6268 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0)) 6269 && ! reload_in_progress) 6270 operands[1] 6271 = replace_equiv_address (operands[1], 6272 copy_addr_to_reg (XEXP (operands[1], 0))); 6273} 6274 6275/* Emit a move from SOURCE to DEST in mode MODE. */ 6276void 6277rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode) 6278{ 6279 rtx operands[2]; 6280 operands[0] = dest; 6281 operands[1] = source; 6282 6283 if (TARGET_DEBUG_ADDR) 6284 { 6285 fprintf (stderr, 6286 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, " 6287 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n", 6288 GET_MODE_NAME (mode), 6289 reload_in_progress, 6290 reload_completed, 6291 can_create_pseudo_p ()); 6292 debug_rtx (dest); 6293 fprintf (stderr, "source:\n"); 6294 debug_rtx (source); 6295 } 6296 6297 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */ 6298 if (GET_CODE (operands[1]) == CONST_DOUBLE 6299 && ! FLOAT_MODE_P (mode) 6300 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT) 6301 { 6302 /* FIXME. This should never happen. */ 6303 /* Since it seems that it does, do the safe thing and convert 6304 to a CONST_INT. */ 6305 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode); 6306 } 6307 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE 6308 || FLOAT_MODE_P (mode) 6309 || ((CONST_DOUBLE_HIGH (operands[1]) != 0 6310 || CONST_DOUBLE_LOW (operands[1]) < 0) 6311 && (CONST_DOUBLE_HIGH (operands[1]) != -1 6312 || CONST_DOUBLE_LOW (operands[1]) >= 0))); 6313 6314 /* Check if GCC is setting up a block move that will end up using FP 6315 registers as temporaries. We must make sure this is acceptable. */ 6316 if (GET_CODE (operands[0]) == MEM 6317 && GET_CODE (operands[1]) == MEM 6318 && mode == DImode 6319 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0])) 6320 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1]))) 6321 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32 6322 ? 32 : MEM_ALIGN (operands[0]))) 6323 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32 6324 ? 32 6325 : MEM_ALIGN (operands[1])))) 6326 && ! MEM_VOLATILE_P (operands [0]) 6327 && ! MEM_VOLATILE_P (operands [1])) 6328 { 6329 emit_move_insn (adjust_address (operands[0], SImode, 0), 6330 adjust_address (operands[1], SImode, 0)); 6331 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4), 6332 adjust_address (copy_rtx (operands[1]), SImode, 4)); 6333 return; 6334 } 6335 6336 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM 6337 && !gpc_reg_operand (operands[1], mode)) 6338 operands[1] = force_reg (mode, operands[1]); 6339 6340 if (mode == SFmode && ! TARGET_POWERPC 6341 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 6342 && GET_CODE (operands[0]) == MEM) 6343 { 6344 int regnum; 6345 6346 if (reload_in_progress || reload_completed) 6347 regnum = true_regnum (operands[1]); 6348 else if (GET_CODE (operands[1]) == REG) 6349 regnum = REGNO (operands[1]); 6350 else 6351 regnum = -1; 6352 6353 /* If operands[1] is a register, on POWER it may have 6354 double-precision data in it, so truncate it to single 6355 precision. */ 6356 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER) 6357 { 6358 rtx newreg; 6359 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1]) 6360 : gen_reg_rtx (mode)); 6361 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1])); 6362 operands[1] = newreg; 6363 } 6364 } 6365 6366 /* Recognize the case where operand[1] is a reference to thread-local 6367 data and load its address to a register. */ 6368 if (rs6000_tls_referenced_p (operands[1])) 6369 { 6370 enum tls_model model; 6371 rtx tmp = operands[1]; 6372 rtx addend = NULL; 6373 6374 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS) 6375 { 6376 addend = XEXP (XEXP (tmp, 0), 1); 6377 tmp = XEXP (XEXP (tmp, 0), 0); 6378 } 6379 6380 gcc_assert (GET_CODE (tmp) == SYMBOL_REF); 6381 model = SYMBOL_REF_TLS_MODEL (tmp); 6382 gcc_assert (model != 0); 6383 6384 tmp = rs6000_legitimize_tls_address (tmp, model); 6385 if (addend) 6386 { 6387 tmp = gen_rtx_PLUS (mode, tmp, addend); 6388 tmp = force_operand (tmp, operands[0]); 6389 } 6390 operands[1] = tmp; 6391 } 6392 6393 /* Handle the case where reload calls us with an invalid address. */ 6394 if (reload_in_progress && mode == Pmode 6395 && (! general_operand (operands[1], mode) 6396 || ! nonimmediate_operand (operands[0], mode))) 6397 goto emit_set; 6398 6399 /* 128-bit constant floating-point values on Darwin should really be 6400 loaded as two parts. */ 6401 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128 6402 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE) 6403 { 6404 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't 6405 know how to get a DFmode SUBREG of a TFmode. */ 6406 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode); 6407 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0), 6408 simplify_gen_subreg (imode, operands[1], mode, 0), 6409 imode); 6410 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 6411 GET_MODE_SIZE (imode)), 6412 simplify_gen_subreg (imode, operands[1], mode, 6413 GET_MODE_SIZE (imode)), 6414 imode); 6415 return; 6416 } 6417 6418 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX) 6419 cfun->machine->sdmode_stack_slot = 6420 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX); 6421 6422 if (reload_in_progress 6423 && mode == SDmode 6424 && MEM_P (operands[0]) 6425 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot) 6426 && REG_P (operands[1])) 6427 { 6428 if (FP_REGNO_P (REGNO (operands[1]))) 6429 { 6430 rtx mem = adjust_address_nv (operands[0], DDmode, 0); 6431 mem = eliminate_regs (mem, VOIDmode, NULL_RTX); 6432 emit_insn (gen_movsd_store (mem, operands[1])); 6433 } 6434 else if (INT_REGNO_P (REGNO (operands[1]))) 6435 { 6436 rtx mem = adjust_address_nv (operands[0], mode, 4); 6437 mem = eliminate_regs (mem, VOIDmode, NULL_RTX); 6438 emit_insn (gen_movsd_hardfloat (mem, operands[1])); 6439 } 6440 else 6441 gcc_unreachable(); 6442 return; 6443 } 6444 if (reload_in_progress 6445 && mode == SDmode 6446 && REG_P (operands[0]) 6447 && MEM_P (operands[1]) 6448 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot)) 6449 { 6450 if (FP_REGNO_P (REGNO (operands[0]))) 6451 { 6452 rtx mem = adjust_address_nv (operands[1], DDmode, 0); 6453 mem = eliminate_regs (mem, VOIDmode, NULL_RTX); 6454 emit_insn (gen_movsd_load (operands[0], mem)); 6455 } 6456 else if (INT_REGNO_P (REGNO (operands[0]))) 6457 { 6458 rtx mem = adjust_address_nv (operands[1], mode, 4); 6459 mem = eliminate_regs (mem, VOIDmode, NULL_RTX); 6460 emit_insn (gen_movsd_hardfloat (operands[0], mem)); 6461 } 6462 else 6463 gcc_unreachable(); 6464 return; 6465 } 6466 6467 /* FIXME: In the long term, this switch statement should go away 6468 and be replaced by a sequence of tests based on things like 6469 mode == Pmode. */ 6470 switch (mode) 6471 { 6472 case HImode: 6473 case QImode: 6474 if (CONSTANT_P (operands[1]) 6475 && GET_CODE (operands[1]) != CONST_INT) 6476 operands[1] = force_const_mem (mode, operands[1]); 6477 break; 6478 6479 case TFmode: 6480 case TDmode: 6481 rs6000_eliminate_indexed_memrefs (operands); 6482 /* fall through */ 6483 6484 case DFmode: 6485 case DDmode: 6486 case SFmode: 6487 case SDmode: 6488 if (CONSTANT_P (operands[1]) 6489 && ! easy_fp_constant (operands[1], mode)) 6490 operands[1] = force_const_mem (mode, operands[1]); 6491 break; 6492 6493 case V16QImode: 6494 case V8HImode: 6495 case V4SFmode: 6496 case V4SImode: 6497 case V4HImode: 6498 case V2SFmode: 6499 case V2SImode: 6500 case V1DImode: 6501 case V2DFmode: 6502 case V2DImode: 6503 if (CONSTANT_P (operands[1]) 6504 && !easy_vector_constant (operands[1], mode)) 6505 operands[1] = force_const_mem (mode, operands[1]); 6506 break; 6507 6508 case SImode: 6509 case DImode: 6510 /* Use default pattern for address of ELF small data */ 6511 if (TARGET_ELF 6512 && mode == Pmode 6513 && DEFAULT_ABI == ABI_V4 6514 && (GET_CODE (operands[1]) == SYMBOL_REF 6515 || GET_CODE (operands[1]) == CONST) 6516 && small_data_operand (operands[1], mode)) 6517 { 6518 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); 6519 return; 6520 } 6521 6522 if (DEFAULT_ABI == ABI_V4 6523 && mode == Pmode && mode == SImode 6524 && flag_pic == 1 && got_operand (operands[1], mode)) 6525 { 6526 emit_insn (gen_movsi_got (operands[0], operands[1])); 6527 return; 6528 } 6529 6530 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN) 6531 && TARGET_NO_TOC 6532 && ! flag_pic 6533 && mode == Pmode 6534 && CONSTANT_P (operands[1]) 6535 && GET_CODE (operands[1]) != HIGH 6536 && GET_CODE (operands[1]) != CONST_INT) 6537 { 6538 rtx target = (!can_create_pseudo_p () 6539 ? operands[0] 6540 : gen_reg_rtx (mode)); 6541 6542 /* If this is a function address on -mcall-aixdesc, 6543 convert it to the address of the descriptor. */ 6544 if (DEFAULT_ABI == ABI_AIX 6545 && GET_CODE (operands[1]) == SYMBOL_REF 6546 && XSTR (operands[1], 0)[0] == '.') 6547 { 6548 const char *name = XSTR (operands[1], 0); 6549 rtx new_ref; 6550 while (*name == '.') 6551 name++; 6552 new_ref = gen_rtx_SYMBOL_REF (Pmode, name); 6553 CONSTANT_POOL_ADDRESS_P (new_ref) 6554 = CONSTANT_POOL_ADDRESS_P (operands[1]); 6555 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]); 6556 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]); 6557 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]); 6558 operands[1] = new_ref; 6559 } 6560 6561 if (DEFAULT_ABI == ABI_DARWIN) 6562 { 6563#if TARGET_MACHO 6564 if (MACHO_DYNAMIC_NO_PIC_P) 6565 { 6566 /* Take care of any required data indirection. */ 6567 operands[1] = rs6000_machopic_legitimize_pic_address ( 6568 operands[1], mode, operands[0]); 6569 if (operands[0] != operands[1]) 6570 emit_insn (gen_rtx_SET (VOIDmode, 6571 operands[0], operands[1])); 6572 return; 6573 } 6574#endif 6575 emit_insn (gen_macho_high (target, operands[1])); 6576 emit_insn (gen_macho_low (operands[0], target, operands[1])); 6577 return; 6578 } 6579 6580 emit_insn (gen_elf_high (target, operands[1])); 6581 emit_insn (gen_elf_low (operands[0], target, operands[1])); 6582 return; 6583 } 6584 6585 /* If this is a SYMBOL_REF that refers to a constant pool entry, 6586 and we have put it in the TOC, we just need to make a TOC-relative 6587 reference to it. */ 6588 if (TARGET_TOC 6589 && GET_CODE (operands[1]) == SYMBOL_REF 6590 && constant_pool_expr_p (operands[1]) 6591 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]), 6592 get_pool_mode (operands[1]))) 6593 { 6594 operands[1] = create_TOC_reference (operands[1]); 6595 } 6596 else if (mode == Pmode 6597 && CONSTANT_P (operands[1]) 6598 && ((GET_CODE (operands[1]) != CONST_INT 6599 && ! easy_fp_constant (operands[1], mode)) 6600 || (GET_CODE (operands[1]) == CONST_INT 6601 && num_insns_constant (operands[1], mode) > 2) 6602 || (GET_CODE (operands[0]) == REG 6603 && FP_REGNO_P (REGNO (operands[0])))) 6604 && GET_CODE (operands[1]) != HIGH 6605 && ! legitimate_constant_pool_address_p (operands[1]) 6606 && ! toc_relative_expr_p (operands[1])) 6607 { 6608 6609#if TARGET_MACHO 6610 /* Darwin uses a special PIC legitimizer. */ 6611 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT) 6612 { 6613 operands[1] = 6614 rs6000_machopic_legitimize_pic_address (operands[1], mode, 6615 operands[0]); 6616 if (operands[0] != operands[1]) 6617 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); 6618 return; 6619 } 6620#endif 6621 6622 /* If we are to limit the number of things we put in the TOC and 6623 this is a symbol plus a constant we can add in one insn, 6624 just put the symbol in the TOC and add the constant. Don't do 6625 this if reload is in progress. */ 6626 if (GET_CODE (operands[1]) == CONST 6627 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress 6628 && GET_CODE (XEXP (operands[1], 0)) == PLUS 6629 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode) 6630 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF 6631 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF) 6632 && ! side_effects_p (operands[0])) 6633 { 6634 rtx sym = 6635 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0)); 6636 rtx other = XEXP (XEXP (operands[1], 0), 1); 6637 6638 sym = force_reg (mode, sym); 6639 emit_insn (gen_add3_insn (operands[0], sym, other)); 6640 return; 6641 } 6642 6643 operands[1] = force_const_mem (mode, operands[1]); 6644 6645 if (TARGET_TOC 6646 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF 6647 && constant_pool_expr_p (XEXP (operands[1], 0)) 6648 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P ( 6649 get_pool_constant (XEXP (operands[1], 0)), 6650 get_pool_mode (XEXP (operands[1], 0)))) 6651 { 6652 operands[1] 6653 = gen_const_mem (mode, 6654 create_TOC_reference (XEXP (operands[1], 0))); 6655 set_mem_alias_set (operands[1], get_TOC_alias_set ()); 6656 } 6657 } 6658 break; 6659 6660 case TImode: 6661 rs6000_eliminate_indexed_memrefs (operands); 6662 6663 if (TARGET_POWER) 6664 { 6665 emit_insn (gen_rtx_PARALLEL (VOIDmode, 6666 gen_rtvec (2, 6667 gen_rtx_SET (VOIDmode, 6668 operands[0], operands[1]), 6669 gen_rtx_CLOBBER (VOIDmode, 6670 gen_rtx_SCRATCH (SImode))))); 6671 return; 6672 } 6673 break; 6674 6675 default: 6676 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source)); 6677 } 6678 6679 /* Above, we may have called force_const_mem which may have returned 6680 an invalid address. If we can, fix this up; otherwise, reload will 6681 have to deal with it. */ 6682 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress) 6683 operands[1] = validize_mem (operands[1]); 6684 6685 emit_set: 6686 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); 6687} 6688 6689/* Nonzero if we can use a floating-point register to pass this arg. */ 6690#define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \ 6691 (SCALAR_FLOAT_MODE_P (MODE) \ 6692 && (CUM)->fregno <= FP_ARG_MAX_REG \ 6693 && TARGET_HARD_FLOAT && TARGET_FPRS) 6694 6695/* Nonzero if we can use an AltiVec register to pass this arg. */ 6696#define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \ 6697 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \ 6698 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \ 6699 && TARGET_ALTIVEC_ABI \ 6700 && (NAMED)) 6701 6702/* Return a nonzero value to say to return the function value in 6703 memory, just as large structures are always returned. TYPE will be 6704 the data type of the value, and FNTYPE will be the type of the 6705 function doing the returning, or @code{NULL} for libcalls. 6706 6707 The AIX ABI for the RS/6000 specifies that all structures are 6708 returned in memory. The Darwin ABI does the same. The SVR4 ABI 6709 specifies that structures <= 8 bytes are returned in r3/r4, but a 6710 draft put them in memory, and GCC used to implement the draft 6711 instead of the final standard. Therefore, aix_struct_return 6712 controls this instead of DEFAULT_ABI; V.4 targets needing backward 6713 compatibility can change DRAFT_V4_STRUCT_RET to override the 6714 default, and -m switches get the final word. See 6715 rs6000_override_options for more details. 6716 6717 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit 6718 long double support is enabled. These values are returned in memory. 6719 6720 int_size_in_bytes returns -1 for variable size objects, which go in 6721 memory always. The cast to unsigned makes -1 > 8. */ 6722 6723static bool 6724rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) 6725{ 6726 /* In the darwin64 abi, try to use registers for larger structs 6727 if possible. */ 6728 if (rs6000_darwin64_abi 6729 && TREE_CODE (type) == RECORD_TYPE 6730 && int_size_in_bytes (type) > 0) 6731 { 6732 CUMULATIVE_ARGS valcum; 6733 rtx valret; 6734 6735 valcum.words = 0; 6736 valcum.fregno = FP_ARG_MIN_REG; 6737 valcum.vregno = ALTIVEC_ARG_MIN_REG; 6738 /* Do a trial code generation as if this were going to be passed 6739 as an argument; if any part goes in memory, we return NULL. */ 6740 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true); 6741 if (valret) 6742 return false; 6743 /* Otherwise fall through to more conventional ABI rules. */ 6744 } 6745 6746 if (AGGREGATE_TYPE_P (type) 6747 && (aix_struct_return 6748 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8)) 6749 return true; 6750 6751 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector 6752 modes only exist for GCC vector types if -maltivec. */ 6753 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI 6754 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type))) 6755 return false; 6756 6757 /* Return synthetic vectors in memory. */ 6758 if (TREE_CODE (type) == VECTOR_TYPE 6759 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8)) 6760 { 6761 static bool warned_for_return_big_vectors = false; 6762 if (!warned_for_return_big_vectors) 6763 { 6764 warning (0, "GCC vector returned by reference: " 6765 "non-standard ABI extension with no compatibility guarantee"); 6766 warned_for_return_big_vectors = true; 6767 } 6768 return true; 6769 } 6770 6771 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode) 6772 return true; 6773 6774 return false; 6775} 6776 6777/* Initialize a variable CUM of type CUMULATIVE_ARGS 6778 for a call to a function whose data type is FNTYPE. 6779 For a library call, FNTYPE is 0. 6780 6781 For incoming args we set the number of arguments in the prototype large 6782 so we never return a PARALLEL. */ 6783 6784void 6785init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, 6786 rtx libname ATTRIBUTE_UNUSED, int incoming, 6787 int libcall, int n_named_args) 6788{ 6789 static CUMULATIVE_ARGS zero_cumulative; 6790 6791 *cum = zero_cumulative; 6792 cum->words = 0; 6793 cum->fregno = FP_ARG_MIN_REG; 6794 cum->vregno = ALTIVEC_ARG_MIN_REG; 6795 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype)); 6796 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall) 6797 ? CALL_LIBCALL : CALL_NORMAL); 6798 cum->sysv_gregno = GP_ARG_MIN_REG; 6799 cum->stdarg = fntype 6800 && (TYPE_ARG_TYPES (fntype) != 0 6801 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) 6802 != void_type_node)); 6803 6804 cum->nargs_prototype = 0; 6805 if (incoming || cum->prototype) 6806 cum->nargs_prototype = n_named_args; 6807 6808 /* Check for a longcall attribute. */ 6809 if ((!fntype && rs6000_default_long_calls) 6810 || (fntype 6811 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype)) 6812 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype)))) 6813 cum->call_cookie |= CALL_LONG; 6814 6815 if (TARGET_DEBUG_ARG) 6816 { 6817 fprintf (stderr, "\ninit_cumulative_args:"); 6818 if (fntype) 6819 { 6820 tree ret_type = TREE_TYPE (fntype); 6821 fprintf (stderr, " ret code = %s,", 6822 tree_code_name[ (int)TREE_CODE (ret_type) ]); 6823 } 6824 6825 if (cum->call_cookie & CALL_LONG) 6826 fprintf (stderr, " longcall,"); 6827 6828 fprintf (stderr, " proto = %d, nargs = %d\n", 6829 cum->prototype, cum->nargs_prototype); 6830 } 6831 6832 if (fntype 6833 && !TARGET_ALTIVEC 6834 && TARGET_ALTIVEC_ABI 6835 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype)))) 6836 { 6837 error ("cannot return value in vector register because" 6838 " altivec instructions are disabled, use -maltivec" 6839 " to enable them"); 6840 } 6841} 6842 6843/* Return true if TYPE must be passed on the stack and not in registers. */ 6844 6845static bool 6846rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type) 6847{ 6848 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT) 6849 return must_pass_in_stack_var_size (mode, type); 6850 else 6851 return must_pass_in_stack_var_size_or_pad (mode, type); 6852} 6853 6854/* If defined, a C expression which determines whether, and in which 6855 direction, to pad out an argument with extra space. The value 6856 should be of type `enum direction': either `upward' to pad above 6857 the argument, `downward' to pad below, or `none' to inhibit 6858 padding. 6859 6860 For the AIX ABI structs are always stored left shifted in their 6861 argument slot. */ 6862 6863enum direction 6864function_arg_padding (enum machine_mode mode, const_tree type) 6865{ 6866#ifndef AGGREGATE_PADDING_FIXED 6867#define AGGREGATE_PADDING_FIXED 0 6868#endif 6869#ifndef AGGREGATES_PAD_UPWARD_ALWAYS 6870#define AGGREGATES_PAD_UPWARD_ALWAYS 0 6871#endif 6872 6873 if (!AGGREGATE_PADDING_FIXED) 6874 { 6875 /* GCC used to pass structures of the same size as integer types as 6876 if they were in fact integers, ignoring FUNCTION_ARG_PADDING. 6877 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were 6878 passed padded downward, except that -mstrict-align further 6879 muddied the water in that multi-component structures of 2 and 4 6880 bytes in size were passed padded upward. 6881 6882 The following arranges for best compatibility with previous 6883 versions of gcc, but removes the -mstrict-align dependency. */ 6884 if (BYTES_BIG_ENDIAN) 6885 { 6886 HOST_WIDE_INT size = 0; 6887 6888 if (mode == BLKmode) 6889 { 6890 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST) 6891 size = int_size_in_bytes (type); 6892 } 6893 else 6894 size = GET_MODE_SIZE (mode); 6895 6896 if (size == 1 || size == 2 || size == 4) 6897 return downward; 6898 } 6899 return upward; 6900 } 6901 6902 if (AGGREGATES_PAD_UPWARD_ALWAYS) 6903 { 6904 if (type != 0 && AGGREGATE_TYPE_P (type)) 6905 return upward; 6906 } 6907 6908 /* Fall back to the default. */ 6909 return DEFAULT_FUNCTION_ARG_PADDING (mode, type); 6910} 6911 6912/* If defined, a C expression that gives the alignment boundary, in bits, 6913 of an argument with the specified mode and type. If it is not defined, 6914 PARM_BOUNDARY is used for all arguments. 6915 6916 V.4 wants long longs and doubles to be double word aligned. Just 6917 testing the mode size is a boneheaded way to do this as it means 6918 that other types such as complex int are also double word aligned. 6919 However, we're stuck with this because changing the ABI might break 6920 existing library interfaces. 6921 6922 Doubleword align SPE vectors. 6923 Quadword align Altivec vectors. 6924 Quadword align large synthetic vector types. */ 6925 6926int 6927function_arg_boundary (enum machine_mode mode, tree type) 6928{ 6929 if (DEFAULT_ABI == ABI_V4 6930 && (GET_MODE_SIZE (mode) == 8 6931 || (TARGET_HARD_FLOAT 6932 && TARGET_FPRS 6933 && (mode == TFmode || mode == TDmode)))) 6934 return 64; 6935 else if (SPE_VECTOR_MODE (mode) 6936 || (type && TREE_CODE (type) == VECTOR_TYPE 6937 && int_size_in_bytes (type) >= 8 6938 && int_size_in_bytes (type) < 16)) 6939 return 64; 6940 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode)) 6941 || (type && TREE_CODE (type) == VECTOR_TYPE 6942 && int_size_in_bytes (type) >= 16)) 6943 return 128; 6944 else if (rs6000_darwin64_abi && mode == BLKmode 6945 && type && TYPE_ALIGN (type) > 64) 6946 return 128; 6947 else 6948 return PARM_BOUNDARY; 6949} 6950 6951/* For a function parm of MODE and TYPE, return the starting word in 6952 the parameter area. NWORDS of the parameter area are already used. */ 6953 6954static unsigned int 6955rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords) 6956{ 6957 unsigned int align; 6958 unsigned int parm_offset; 6959 6960 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1; 6961 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6; 6962 return nwords + (-(parm_offset + nwords) & align); 6963} 6964 6965/* Compute the size (in words) of a function argument. */ 6966 6967static unsigned long 6968rs6000_arg_size (enum machine_mode mode, tree type) 6969{ 6970 unsigned long size; 6971 6972 if (mode != BLKmode) 6973 size = GET_MODE_SIZE (mode); 6974 else 6975 size = int_size_in_bytes (type); 6976 6977 if (TARGET_32BIT) 6978 return (size + 3) >> 2; 6979 else 6980 return (size + 7) >> 3; 6981} 6982 6983/* Use this to flush pending int fields. */ 6984 6985static void 6986rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum, 6987 HOST_WIDE_INT bitpos) 6988{ 6989 unsigned int startbit, endbit; 6990 int intregs, intoffset; 6991 enum machine_mode mode; 6992 6993 if (cum->intoffset == -1) 6994 return; 6995 6996 intoffset = cum->intoffset; 6997 cum->intoffset = -1; 6998 6999 if (intoffset % BITS_PER_WORD != 0) 7000 { 7001 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD, 7002 MODE_INT, 0); 7003 if (mode == BLKmode) 7004 { 7005 /* We couldn't find an appropriate mode, which happens, 7006 e.g., in packed structs when there are 3 bytes to load. 7007 Back intoffset back to the beginning of the word in this 7008 case. */ 7009 intoffset = intoffset & -BITS_PER_WORD; 7010 } 7011 } 7012 7013 startbit = intoffset & -BITS_PER_WORD; 7014 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD; 7015 intregs = (endbit - startbit) / BITS_PER_WORD; 7016 cum->words += intregs; 7017} 7018 7019/* The darwin64 ABI calls for us to recurse down through structs, 7020 looking for elements passed in registers. Unfortunately, we have 7021 to track int register count here also because of misalignments 7022 in powerpc alignment mode. */ 7023 7024static void 7025rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum, 7026 tree type, 7027 HOST_WIDE_INT startbitpos) 7028{ 7029 tree f; 7030 7031 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f)) 7032 if (TREE_CODE (f) == FIELD_DECL) 7033 { 7034 HOST_WIDE_INT bitpos = startbitpos; 7035 tree ftype = TREE_TYPE (f); 7036 enum machine_mode mode; 7037 if (ftype == error_mark_node) 7038 continue; 7039 mode = TYPE_MODE (ftype); 7040 7041 if (DECL_SIZE (f) != 0 7042 && host_integerp (bit_position (f), 1)) 7043 bitpos += int_bit_position (f); 7044 7045 /* ??? FIXME: else assume zero offset. */ 7046 7047 if (TREE_CODE (ftype) == RECORD_TYPE) 7048 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos); 7049 else if (USE_FP_FOR_ARG_P (cum, mode, ftype)) 7050 { 7051 rs6000_darwin64_record_arg_advance_flush (cum, bitpos); 7052 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3; 7053 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3; 7054 } 7055 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1)) 7056 { 7057 rs6000_darwin64_record_arg_advance_flush (cum, bitpos); 7058 cum->vregno++; 7059 cum->words += 2; 7060 } 7061 else if (cum->intoffset == -1) 7062 cum->intoffset = bitpos; 7063 } 7064} 7065 7066/* Update the data in CUM to advance over an argument 7067 of mode MODE and data type TYPE. 7068 (TYPE is null for libcalls where that information may not be available.) 7069 7070 Note that for args passed by reference, function_arg will be called 7071 with MODE and TYPE set to that of the pointer to the arg, not the arg 7072 itself. */ 7073 7074void 7075function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, 7076 tree type, int named, int depth) 7077{ 7078 int size; 7079 7080 /* Only tick off an argument if we're not recursing. */ 7081 if (depth == 0) 7082 cum->nargs_prototype--; 7083 7084 if (TARGET_ALTIVEC_ABI 7085 && (ALTIVEC_VECTOR_MODE (mode) 7086 || VSX_VECTOR_MODE (mode) 7087 || (type && TREE_CODE (type) == VECTOR_TYPE 7088 && int_size_in_bytes (type) == 16))) 7089 { 7090 bool stack = false; 7091 7092 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)) 7093 { 7094 cum->vregno++; 7095 if (!TARGET_ALTIVEC) 7096 error ("cannot pass argument in vector register because" 7097 " altivec instructions are disabled, use -maltivec" 7098 " to enable them"); 7099 7100 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument 7101 even if it is going to be passed in a vector register. 7102 Darwin does the same for variable-argument functions. */ 7103 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT) 7104 || (cum->stdarg && DEFAULT_ABI != ABI_V4)) 7105 stack = true; 7106 } 7107 else 7108 stack = true; 7109 7110 if (stack) 7111 { 7112 int align; 7113 7114 /* Vector parameters must be 16-byte aligned. This places 7115 them at 2 mod 4 in terms of words in 32-bit mode, since 7116 the parameter save area starts at offset 24 from the 7117 stack. In 64-bit mode, they just have to start on an 7118 even word, since the parameter save area is 16-byte 7119 aligned. Space for GPRs is reserved even if the argument 7120 will be passed in memory. */ 7121 if (TARGET_32BIT) 7122 align = (2 - cum->words) & 3; 7123 else 7124 align = cum->words & 1; 7125 cum->words += align + rs6000_arg_size (mode, type); 7126 7127 if (TARGET_DEBUG_ARG) 7128 { 7129 fprintf (stderr, "function_adv: words = %2d, align=%d, ", 7130 cum->words, align); 7131 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n", 7132 cum->nargs_prototype, cum->prototype, 7133 GET_MODE_NAME (mode)); 7134 } 7135 } 7136 } 7137 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode) 7138 && !cum->stdarg 7139 && cum->sysv_gregno <= GP_ARG_MAX_REG) 7140 cum->sysv_gregno++; 7141 7142 else if (rs6000_darwin64_abi 7143 && mode == BLKmode 7144 && TREE_CODE (type) == RECORD_TYPE 7145 && (size = int_size_in_bytes (type)) > 0) 7146 { 7147 /* Variable sized types have size == -1 and are 7148 treated as if consisting entirely of ints. 7149 Pad to 16 byte boundary if needed. */ 7150 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD 7151 && (cum->words % 2) != 0) 7152 cum->words++; 7153 /* For varargs, we can just go up by the size of the struct. */ 7154 if (!named) 7155 cum->words += (size + 7) / 8; 7156 else 7157 { 7158 /* It is tempting to say int register count just goes up by 7159 sizeof(type)/8, but this is wrong in a case such as 7160 { int; double; int; } [powerpc alignment]. We have to 7161 grovel through the fields for these too. */ 7162 cum->intoffset = 0; 7163 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0); 7164 rs6000_darwin64_record_arg_advance_flush (cum, 7165 size * BITS_PER_UNIT); 7166 } 7167 } 7168 else if (DEFAULT_ABI == ABI_V4) 7169 { 7170 if (TARGET_HARD_FLOAT && TARGET_FPRS 7171 && ((TARGET_SINGLE_FLOAT && mode == SFmode) 7172 || (TARGET_DOUBLE_FLOAT && mode == DFmode) 7173 || (mode == TFmode && !TARGET_IEEEQUAD) 7174 || mode == SDmode || mode == DDmode || mode == TDmode)) 7175 { 7176 /* _Decimal128 must use an even/odd register pair. This assumes 7177 that the register number is odd when fregno is odd. */ 7178 if (mode == TDmode && (cum->fregno % 2) == 1) 7179 cum->fregno++; 7180 7181 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0) 7182 <= FP_ARG_V4_MAX_REG) 7183 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3; 7184 else 7185 { 7186 cum->fregno = FP_ARG_V4_MAX_REG + 1; 7187 if (mode == DFmode || mode == TFmode 7188 || mode == DDmode || mode == TDmode) 7189 cum->words += cum->words & 1; 7190 cum->words += rs6000_arg_size (mode, type); 7191 } 7192 } 7193 else 7194 { 7195 int n_words = rs6000_arg_size (mode, type); 7196 int gregno = cum->sysv_gregno; 7197 7198 /* Long long and SPE vectors are put in (r3,r4), (r5,r6), 7199 (r7,r8) or (r9,r10). As does any other 2 word item such 7200 as complex int due to a historical mistake. */ 7201 if (n_words == 2) 7202 gregno += (1 - gregno) & 1; 7203 7204 /* Multi-reg args are not split between registers and stack. */ 7205 if (gregno + n_words - 1 > GP_ARG_MAX_REG) 7206 { 7207 /* Long long and SPE vectors are aligned on the stack. 7208 So are other 2 word items such as complex int due to 7209 a historical mistake. */ 7210 if (n_words == 2) 7211 cum->words += cum->words & 1; 7212 cum->words += n_words; 7213 } 7214 7215 /* Note: continuing to accumulate gregno past when we've started 7216 spilling to the stack indicates the fact that we've started 7217 spilling to the stack to expand_builtin_saveregs. */ 7218 cum->sysv_gregno = gregno + n_words; 7219 } 7220 7221 if (TARGET_DEBUG_ARG) 7222 { 7223 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ", 7224 cum->words, cum->fregno); 7225 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ", 7226 cum->sysv_gregno, cum->nargs_prototype, cum->prototype); 7227 fprintf (stderr, "mode = %4s, named = %d\n", 7228 GET_MODE_NAME (mode), named); 7229 } 7230 } 7231 else 7232 { 7233 int n_words = rs6000_arg_size (mode, type); 7234 int start_words = cum->words; 7235 int align_words = rs6000_parm_start (mode, type, start_words); 7236 7237 cum->words = align_words + n_words; 7238 7239 if (SCALAR_FLOAT_MODE_P (mode) 7240 && TARGET_HARD_FLOAT && TARGET_FPRS) 7241 { 7242 /* _Decimal128 must be passed in an even/odd float register pair. 7243 This assumes that the register number is odd when fregno is 7244 odd. */ 7245 if (mode == TDmode && (cum->fregno % 2) == 1) 7246 cum->fregno++; 7247 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3; 7248 } 7249 7250 if (TARGET_DEBUG_ARG) 7251 { 7252 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ", 7253 cum->words, cum->fregno); 7254 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ", 7255 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode)); 7256 fprintf (stderr, "named = %d, align = %d, depth = %d\n", 7257 named, align_words - start_words, depth); 7258 } 7259 } 7260} 7261 7262static rtx 7263spe_build_register_parallel (enum machine_mode mode, int gregno) 7264{ 7265 rtx r1, r3, r5, r7; 7266 7267 switch (mode) 7268 { 7269 case DFmode: 7270 r1 = gen_rtx_REG (DImode, gregno); 7271 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx); 7272 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1)); 7273 7274 case DCmode: 7275 case TFmode: 7276 r1 = gen_rtx_REG (DImode, gregno); 7277 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx); 7278 r3 = gen_rtx_REG (DImode, gregno + 2); 7279 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8)); 7280 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3)); 7281 7282 case TCmode: 7283 r1 = gen_rtx_REG (DImode, gregno); 7284 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx); 7285 r3 = gen_rtx_REG (DImode, gregno + 2); 7286 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8)); 7287 r5 = gen_rtx_REG (DImode, gregno + 4); 7288 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16)); 7289 r7 = gen_rtx_REG (DImode, gregno + 6); 7290 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24)); 7291 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7)); 7292 7293 default: 7294 gcc_unreachable (); 7295 } 7296} 7297 7298/* Determine where to put a SIMD argument on the SPE. */ 7299static rtx 7300rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, 7301 tree type) 7302{ 7303 int gregno = cum->sysv_gregno; 7304 7305 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but 7306 are passed and returned in a pair of GPRs for ABI compatibility. */ 7307 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode 7308 || mode == DCmode || mode == TCmode)) 7309 { 7310 int n_words = rs6000_arg_size (mode, type); 7311 7312 /* Doubles go in an odd/even register pair (r5/r6, etc). */ 7313 if (mode == DFmode) 7314 gregno += (1 - gregno) & 1; 7315 7316 /* Multi-reg args are not split between registers and stack. */ 7317 if (gregno + n_words - 1 > GP_ARG_MAX_REG) 7318 return NULL_RTX; 7319 7320 return spe_build_register_parallel (mode, gregno); 7321 } 7322 if (cum->stdarg) 7323 { 7324 int n_words = rs6000_arg_size (mode, type); 7325 7326 /* SPE vectors are put in odd registers. */ 7327 if (n_words == 2 && (gregno & 1) == 0) 7328 gregno += 1; 7329 7330 if (gregno + n_words - 1 <= GP_ARG_MAX_REG) 7331 { 7332 rtx r1, r2; 7333 enum machine_mode m = SImode; 7334 7335 r1 = gen_rtx_REG (m, gregno); 7336 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx); 7337 r2 = gen_rtx_REG (m, gregno + 1); 7338 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4)); 7339 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2)); 7340 } 7341 else 7342 return NULL_RTX; 7343 } 7344 else 7345 { 7346 if (gregno <= GP_ARG_MAX_REG) 7347 return gen_rtx_REG (mode, gregno); 7348 else 7349 return NULL_RTX; 7350 } 7351} 7352 7353/* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the 7354 structure between cum->intoffset and bitpos to integer registers. */ 7355 7356static void 7357rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum, 7358 HOST_WIDE_INT bitpos, rtx rvec[], int *k) 7359{ 7360 enum machine_mode mode; 7361 unsigned int regno; 7362 unsigned int startbit, endbit; 7363 int this_regno, intregs, intoffset; 7364 rtx reg; 7365 7366 if (cum->intoffset == -1) 7367 return; 7368 7369 intoffset = cum->intoffset; 7370 cum->intoffset = -1; 7371 7372 /* If this is the trailing part of a word, try to only load that 7373 much into the register. Otherwise load the whole register. Note 7374 that in the latter case we may pick up unwanted bits. It's not a 7375 problem at the moment but may wish to revisit. */ 7376 7377 if (intoffset % BITS_PER_WORD != 0) 7378 { 7379 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD, 7380 MODE_INT, 0); 7381 if (mode == BLKmode) 7382 { 7383 /* We couldn't find an appropriate mode, which happens, 7384 e.g., in packed structs when there are 3 bytes to load. 7385 Back intoffset back to the beginning of the word in this 7386 case. */ 7387 intoffset = intoffset & -BITS_PER_WORD; 7388 mode = word_mode; 7389 } 7390 } 7391 else 7392 mode = word_mode; 7393 7394 startbit = intoffset & -BITS_PER_WORD; 7395 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD; 7396 intregs = (endbit - startbit) / BITS_PER_WORD; 7397 this_regno = cum->words + intoffset / BITS_PER_WORD; 7398 7399 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno) 7400 cum->use_stack = 1; 7401 7402 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno); 7403 if (intregs <= 0) 7404 return; 7405 7406 intoffset /= BITS_PER_UNIT; 7407 do 7408 { 7409 regno = GP_ARG_MIN_REG + this_regno; 7410 reg = gen_rtx_REG (mode, regno); 7411 rvec[(*k)++] = 7412 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset)); 7413 7414 this_regno += 1; 7415 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1; 7416 mode = word_mode; 7417 intregs -= 1; 7418 } 7419 while (intregs > 0); 7420} 7421 7422/* Recursive workhorse for the following. */ 7423 7424static void 7425rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type, 7426 HOST_WIDE_INT startbitpos, rtx rvec[], 7427 int *k) 7428{ 7429 tree f; 7430 7431 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f)) 7432 if (TREE_CODE (f) == FIELD_DECL) 7433 { 7434 HOST_WIDE_INT bitpos = startbitpos; 7435 tree ftype = TREE_TYPE (f); 7436 enum machine_mode mode; 7437 if (ftype == error_mark_node) 7438 continue; 7439 mode = TYPE_MODE (ftype); 7440 7441 if (DECL_SIZE (f) != 0 7442 && host_integerp (bit_position (f), 1)) 7443 bitpos += int_bit_position (f); 7444 7445 /* ??? FIXME: else assume zero offset. */ 7446 7447 if (TREE_CODE (ftype) == RECORD_TYPE) 7448 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k); 7449 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype)) 7450 { 7451#if 0 7452 switch (mode) 7453 { 7454 case SCmode: mode = SFmode; break; 7455 case DCmode: mode = DFmode; break; 7456 case TCmode: mode = TFmode; break; 7457 default: break; 7458 } 7459#endif 7460 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k); 7461 rvec[(*k)++] 7462 = gen_rtx_EXPR_LIST (VOIDmode, 7463 gen_rtx_REG (mode, cum->fregno++), 7464 GEN_INT (bitpos / BITS_PER_UNIT)); 7465 if (mode == TFmode || mode == TDmode) 7466 cum->fregno++; 7467 } 7468 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1)) 7469 { 7470 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k); 7471 rvec[(*k)++] 7472 = gen_rtx_EXPR_LIST (VOIDmode, 7473 gen_rtx_REG (mode, cum->vregno++), 7474 GEN_INT (bitpos / BITS_PER_UNIT)); 7475 } 7476 else if (cum->intoffset == -1) 7477 cum->intoffset = bitpos; 7478 } 7479} 7480 7481/* For the darwin64 ABI, we want to construct a PARALLEL consisting of 7482 the register(s) to be used for each field and subfield of a struct 7483 being passed by value, along with the offset of where the 7484 register's value may be found in the block. FP fields go in FP 7485 register, vector fields go in vector registers, and everything 7486 else goes in int registers, packed as in memory. 7487 7488 This code is also used for function return values. RETVAL indicates 7489 whether this is the case. 7490 7491 Much of this is taken from the SPARC V9 port, which has a similar 7492 calling convention. */ 7493 7494static rtx 7495rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type, 7496 int named, bool retval) 7497{ 7498 rtx rvec[FIRST_PSEUDO_REGISTER]; 7499 int k = 1, kbase = 1; 7500 HOST_WIDE_INT typesize = int_size_in_bytes (type); 7501 /* This is a copy; modifications are not visible to our caller. */ 7502 CUMULATIVE_ARGS copy_cum = *orig_cum; 7503 CUMULATIVE_ARGS *cum = ©_cum; 7504 7505 /* Pad to 16 byte boundary if needed. */ 7506 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD 7507 && (cum->words % 2) != 0) 7508 cum->words++; 7509 7510 cum->intoffset = 0; 7511 cum->use_stack = 0; 7512 cum->named = named; 7513 7514 /* Put entries into rvec[] for individual FP and vector fields, and 7515 for the chunks of memory that go in int regs. Note we start at 7516 element 1; 0 is reserved for an indication of using memory, and 7517 may or may not be filled in below. */ 7518 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k); 7519 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k); 7520 7521 /* If any part of the struct went on the stack put all of it there. 7522 This hack is because the generic code for 7523 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register 7524 parts of the struct are not at the beginning. */ 7525 if (cum->use_stack) 7526 { 7527 if (retval) 7528 return NULL_RTX; /* doesn't go in registers at all */ 7529 kbase = 0; 7530 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx); 7531 } 7532 if (k > 1 || cum->use_stack) 7533 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase])); 7534 else 7535 return NULL_RTX; 7536} 7537 7538/* Determine where to place an argument in 64-bit mode with 32-bit ABI. */ 7539 7540static rtx 7541rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words) 7542{ 7543 int n_units; 7544 int i, k; 7545 rtx rvec[GP_ARG_NUM_REG + 1]; 7546 7547 if (align_words >= GP_ARG_NUM_REG) 7548 return NULL_RTX; 7549 7550 n_units = rs6000_arg_size (mode, type); 7551 7552 /* Optimize the simple case where the arg fits in one gpr, except in 7553 the case of BLKmode due to assign_parms assuming that registers are 7554 BITS_PER_WORD wide. */ 7555 if (n_units == 0 7556 || (n_units == 1 && mode != BLKmode)) 7557 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words); 7558 7559 k = 0; 7560 if (align_words + n_units > GP_ARG_NUM_REG) 7561 /* Not all of the arg fits in gprs. Say that it goes in memory too, 7562 using a magic NULL_RTX component. 7563 This is not strictly correct. Only some of the arg belongs in 7564 memory, not all of it. However, the normal scheme using 7565 function_arg_partial_nregs can result in unusual subregs, eg. 7566 (subreg:SI (reg:DF) 4), which are not handled well. The code to 7567 store the whole arg to memory is often more efficient than code 7568 to store pieces, and we know that space is available in the right 7569 place for the whole arg. */ 7570 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx); 7571 7572 i = 0; 7573 do 7574 { 7575 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words); 7576 rtx off = GEN_INT (i++ * 4); 7577 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off); 7578 } 7579 while (++align_words < GP_ARG_NUM_REG && --n_units != 0); 7580 7581 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec)); 7582} 7583 7584/* Determine where to put an argument to a function. 7585 Value is zero to push the argument on the stack, 7586 or a hard register in which to store the argument. 7587 7588 MODE is the argument's machine mode. 7589 TYPE is the data type of the argument (as a tree). 7590 This is null for libcalls where that information may 7591 not be available. 7592 CUM is a variable of type CUMULATIVE_ARGS which gives info about 7593 the preceding args and about the function being called. It is 7594 not modified in this routine. 7595 NAMED is nonzero if this argument is a named parameter 7596 (otherwise it is an extra parameter matching an ellipsis). 7597 7598 On RS/6000 the first eight words of non-FP are normally in registers 7599 and the rest are pushed. Under AIX, the first 13 FP args are in registers. 7600 Under V.4, the first 8 FP args are in registers. 7601 7602 If this is floating-point and no prototype is specified, we use 7603 both an FP and integer register (or possibly FP reg and stack). Library 7604 functions (when CALL_LIBCALL is set) always have the proper types for args, 7605 so we can pass the FP value just in one register. emit_library_function 7606 doesn't support PARALLEL anyway. 7607 7608 Note that for args passed by reference, function_arg will be called 7609 with MODE and TYPE set to that of the pointer to the arg, not the arg 7610 itself. */ 7611 7612rtx 7613function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, 7614 tree type, int named) 7615{ 7616 enum rs6000_abi abi = DEFAULT_ABI; 7617 7618 /* Return a marker to indicate whether CR1 needs to set or clear the 7619 bit that V.4 uses to say fp args were passed in registers. 7620 Assume that we don't need the marker for software floating point, 7621 or compiler generated library calls. */ 7622 if (mode == VOIDmode) 7623 { 7624 if (abi == ABI_V4 7625 && (cum->call_cookie & CALL_LIBCALL) == 0 7626 && (cum->stdarg 7627 || (cum->nargs_prototype < 0 7628 && (cum->prototype || TARGET_NO_PROTOTYPE)))) 7629 { 7630 /* For the SPE, we need to crxor CR6 always. */ 7631 if (TARGET_SPE_ABI) 7632 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS); 7633 else if (TARGET_HARD_FLOAT && TARGET_FPRS) 7634 return GEN_INT (cum->call_cookie 7635 | ((cum->fregno == FP_ARG_MIN_REG) 7636 ? CALL_V4_SET_FP_ARGS 7637 : CALL_V4_CLEAR_FP_ARGS)); 7638 } 7639 7640 return GEN_INT (cum->call_cookie); 7641 } 7642 7643 if (rs6000_darwin64_abi && mode == BLKmode 7644 && TREE_CODE (type) == RECORD_TYPE) 7645 { 7646 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false); 7647 if (rslt != NULL_RTX) 7648 return rslt; 7649 /* Else fall through to usual handling. */ 7650 } 7651 7652 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)) 7653 if (TARGET_64BIT && ! cum->prototype) 7654 { 7655 /* Vector parameters get passed in vector register 7656 and also in GPRs or memory, in absence of prototype. */ 7657 int align_words; 7658 rtx slot; 7659 align_words = (cum->words + 1) & ~1; 7660 7661 if (align_words >= GP_ARG_NUM_REG) 7662 { 7663 slot = NULL_RTX; 7664 } 7665 else 7666 { 7667 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words); 7668 } 7669 return gen_rtx_PARALLEL (mode, 7670 gen_rtvec (2, 7671 gen_rtx_EXPR_LIST (VOIDmode, 7672 slot, const0_rtx), 7673 gen_rtx_EXPR_LIST (VOIDmode, 7674 gen_rtx_REG (mode, cum->vregno), 7675 const0_rtx))); 7676 } 7677 else 7678 return gen_rtx_REG (mode, cum->vregno); 7679 else if (TARGET_ALTIVEC_ABI 7680 && (ALTIVEC_VECTOR_MODE (mode) 7681 || VSX_VECTOR_MODE (mode) 7682 || (type && TREE_CODE (type) == VECTOR_TYPE 7683 && int_size_in_bytes (type) == 16))) 7684 { 7685 if (named || abi == ABI_V4) 7686 return NULL_RTX; 7687 else 7688 { 7689 /* Vector parameters to varargs functions under AIX or Darwin 7690 get passed in memory and possibly also in GPRs. */ 7691 int align, align_words, n_words; 7692 enum machine_mode part_mode; 7693 7694 /* Vector parameters must be 16-byte aligned. This places them at 7695 2 mod 4 in terms of words in 32-bit mode, since the parameter 7696 save area starts at offset 24 from the stack. In 64-bit mode, 7697 they just have to start on an even word, since the parameter 7698 save area is 16-byte aligned. */ 7699 if (TARGET_32BIT) 7700 align = (2 - cum->words) & 3; 7701 else 7702 align = cum->words & 1; 7703 align_words = cum->words + align; 7704 7705 /* Out of registers? Memory, then. */ 7706 if (align_words >= GP_ARG_NUM_REG) 7707 return NULL_RTX; 7708 7709 if (TARGET_32BIT && TARGET_POWERPC64) 7710 return rs6000_mixed_function_arg (mode, type, align_words); 7711 7712 /* The vector value goes in GPRs. Only the part of the 7713 value in GPRs is reported here. */ 7714 part_mode = mode; 7715 n_words = rs6000_arg_size (mode, type); 7716 if (align_words + n_words > GP_ARG_NUM_REG) 7717 /* Fortunately, there are only two possibilities, the value 7718 is either wholly in GPRs or half in GPRs and half not. */ 7719 part_mode = DImode; 7720 7721 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words); 7722 } 7723 } 7724 else if (TARGET_SPE_ABI && TARGET_SPE 7725 && (SPE_VECTOR_MODE (mode) 7726 || (TARGET_E500_DOUBLE && (mode == DFmode 7727 || mode == DCmode 7728 || mode == TFmode 7729 || mode == TCmode)))) 7730 return rs6000_spe_function_arg (cum, mode, type); 7731 7732 else if (abi == ABI_V4) 7733 { 7734 if (TARGET_HARD_FLOAT && TARGET_FPRS 7735 && ((TARGET_SINGLE_FLOAT && mode == SFmode) 7736 || (TARGET_DOUBLE_FLOAT && mode == DFmode) 7737 || (mode == TFmode && !TARGET_IEEEQUAD) 7738 || mode == SDmode || mode == DDmode || mode == TDmode)) 7739 { 7740 /* _Decimal128 must use an even/odd register pair. This assumes 7741 that the register number is odd when fregno is odd. */ 7742 if (mode == TDmode && (cum->fregno % 2) == 1) 7743 cum->fregno++; 7744 7745 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0) 7746 <= FP_ARG_V4_MAX_REG) 7747 return gen_rtx_REG (mode, cum->fregno); 7748 else 7749 return NULL_RTX; 7750 } 7751 else 7752 { 7753 int n_words = rs6000_arg_size (mode, type); 7754 int gregno = cum->sysv_gregno; 7755 7756 /* Long long and SPE vectors are put in (r3,r4), (r5,r6), 7757 (r7,r8) or (r9,r10). As does any other 2 word item such 7758 as complex int due to a historical mistake. */ 7759 if (n_words == 2) 7760 gregno += (1 - gregno) & 1; 7761 7762 /* Multi-reg args are not split between registers and stack. */ 7763 if (gregno + n_words - 1 > GP_ARG_MAX_REG) 7764 return NULL_RTX; 7765 7766 if (TARGET_32BIT && TARGET_POWERPC64) 7767 return rs6000_mixed_function_arg (mode, type, 7768 gregno - GP_ARG_MIN_REG); 7769 return gen_rtx_REG (mode, gregno); 7770 } 7771 } 7772 else 7773 { 7774 int align_words = rs6000_parm_start (mode, type, cum->words); 7775 7776 /* _Decimal128 must be passed in an even/odd float register pair. 7777 This assumes that the register number is odd when fregno is odd. */ 7778 if (mode == TDmode && (cum->fregno % 2) == 1) 7779 cum->fregno++; 7780 7781 if (USE_FP_FOR_ARG_P (cum, mode, type)) 7782 { 7783 rtx rvec[GP_ARG_NUM_REG + 1]; 7784 rtx r; 7785 int k; 7786 bool needs_psave; 7787 enum machine_mode fmode = mode; 7788 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3; 7789 7790 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1) 7791 { 7792 /* Currently, we only ever need one reg here because complex 7793 doubles are split. */ 7794 gcc_assert (cum->fregno == FP_ARG_MAX_REG 7795 && (fmode == TFmode || fmode == TDmode)); 7796 7797 /* Long double or _Decimal128 split over regs and memory. */ 7798 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode; 7799 } 7800 7801 /* Do we also need to pass this arg in the parameter save 7802 area? */ 7803 needs_psave = (type 7804 && (cum->nargs_prototype <= 0 7805 || (DEFAULT_ABI == ABI_AIX 7806 && TARGET_XL_COMPAT 7807 && align_words >= GP_ARG_NUM_REG))); 7808 7809 if (!needs_psave && mode == fmode) 7810 return gen_rtx_REG (fmode, cum->fregno); 7811 7812 k = 0; 7813 if (needs_psave) 7814 { 7815 /* Describe the part that goes in gprs or the stack. 7816 This piece must come first, before the fprs. */ 7817 if (align_words < GP_ARG_NUM_REG) 7818 { 7819 unsigned long n_words = rs6000_arg_size (mode, type); 7820 7821 if (align_words + n_words > GP_ARG_NUM_REG 7822 || (TARGET_32BIT && TARGET_POWERPC64)) 7823 { 7824 /* If this is partially on the stack, then we only 7825 include the portion actually in registers here. */ 7826 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode; 7827 rtx off; 7828 int i = 0; 7829 if (align_words + n_words > GP_ARG_NUM_REG) 7830 /* Not all of the arg fits in gprs. Say that it 7831 goes in memory too, using a magic NULL_RTX 7832 component. Also see comment in 7833 rs6000_mixed_function_arg for why the normal 7834 function_arg_partial_nregs scheme doesn't work 7835 in this case. */ 7836 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, 7837 const0_rtx); 7838 do 7839 { 7840 r = gen_rtx_REG (rmode, 7841 GP_ARG_MIN_REG + align_words); 7842 off = GEN_INT (i++ * GET_MODE_SIZE (rmode)); 7843 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off); 7844 } 7845 while (++align_words < GP_ARG_NUM_REG && --n_words != 0); 7846 } 7847 else 7848 { 7849 /* The whole arg fits in gprs. */ 7850 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words); 7851 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx); 7852 } 7853 } 7854 else 7855 /* It's entirely in memory. */ 7856 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx); 7857 } 7858 7859 /* Describe where this piece goes in the fprs. */ 7860 r = gen_rtx_REG (fmode, cum->fregno); 7861 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx); 7862 7863 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec)); 7864 } 7865 else if (align_words < GP_ARG_NUM_REG) 7866 { 7867 if (TARGET_32BIT && TARGET_POWERPC64) 7868 return rs6000_mixed_function_arg (mode, type, align_words); 7869 7870 if (mode == BLKmode) 7871 mode = Pmode; 7872 7873 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words); 7874 } 7875 else 7876 return NULL_RTX; 7877 } 7878} 7879 7880/* For an arg passed partly in registers and partly in memory, this is 7881 the number of bytes passed in registers. For args passed entirely in 7882 registers or entirely in memory, zero. When an arg is described by a 7883 PARALLEL, perhaps using more than one register type, this function 7884 returns the number of bytes used by the first element of the PARALLEL. */ 7885 7886static int 7887rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, 7888 tree type, bool named) 7889{ 7890 int ret = 0; 7891 int align_words; 7892 7893 if (DEFAULT_ABI == ABI_V4) 7894 return 0; 7895 7896 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named) 7897 && cum->nargs_prototype >= 0) 7898 return 0; 7899 7900 /* In this complicated case we just disable the partial_nregs code. */ 7901 if (rs6000_darwin64_abi && mode == BLKmode 7902 && TREE_CODE (type) == RECORD_TYPE 7903 && int_size_in_bytes (type) > 0) 7904 return 0; 7905 7906 align_words = rs6000_parm_start (mode, type, cum->words); 7907 7908 if (USE_FP_FOR_ARG_P (cum, mode, type)) 7909 { 7910 /* If we are passing this arg in the fixed parameter save area 7911 (gprs or memory) as well as fprs, then this function should 7912 return the number of partial bytes passed in the parameter 7913 save area rather than partial bytes passed in fprs. */ 7914 if (type 7915 && (cum->nargs_prototype <= 0 7916 || (DEFAULT_ABI == ABI_AIX 7917 && TARGET_XL_COMPAT 7918 && align_words >= GP_ARG_NUM_REG))) 7919 return 0; 7920 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3) 7921 > FP_ARG_MAX_REG + 1) 7922 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8; 7923 else if (cum->nargs_prototype >= 0) 7924 return 0; 7925 } 7926 7927 if (align_words < GP_ARG_NUM_REG 7928 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type)) 7929 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8); 7930 7931 if (ret != 0 && TARGET_DEBUG_ARG) 7932 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret); 7933 7934 return ret; 7935} 7936 7937/* A C expression that indicates when an argument must be passed by 7938 reference. If nonzero for an argument, a copy of that argument is 7939 made in memory and a pointer to the argument is passed instead of 7940 the argument itself. The pointer is passed in whatever way is 7941 appropriate for passing a pointer to that type. 7942 7943 Under V.4, aggregates and long double are passed by reference. 7944 7945 As an extension to all 32-bit ABIs, AltiVec vectors are passed by 7946 reference unless the AltiVec vector extension ABI is in force. 7947 7948 As an extension to all ABIs, variable sized types are passed by 7949 reference. */ 7950 7951static bool 7952rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, 7953 enum machine_mode mode, const_tree type, 7954 bool named ATTRIBUTE_UNUSED) 7955{ 7956 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode) 7957 { 7958 if (TARGET_DEBUG_ARG) 7959 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n"); 7960 return 1; 7961 } 7962 7963 if (!type) 7964 return 0; 7965 7966 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type)) 7967 { 7968 if (TARGET_DEBUG_ARG) 7969 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n"); 7970 return 1; 7971 } 7972 7973 if (int_size_in_bytes (type) < 0) 7974 { 7975 if (TARGET_DEBUG_ARG) 7976 fprintf (stderr, "function_arg_pass_by_reference: variable size\n"); 7977 return 1; 7978 } 7979 7980 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector 7981 modes only exist for GCC vector types if -maltivec. */ 7982 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode)) 7983 { 7984 if (TARGET_DEBUG_ARG) 7985 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n"); 7986 return 1; 7987 } 7988 7989 /* Pass synthetic vectors in memory. */ 7990 if (TREE_CODE (type) == VECTOR_TYPE 7991 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8)) 7992 { 7993 static bool warned_for_pass_big_vectors = false; 7994 if (TARGET_DEBUG_ARG) 7995 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n"); 7996 if (!warned_for_pass_big_vectors) 7997 { 7998 warning (0, "GCC vector passed by reference: " 7999 "non-standard ABI extension with no compatibility guarantee"); 8000 warned_for_pass_big_vectors = true; 8001 } 8002 return 1; 8003 } 8004 8005 return 0; 8006} 8007 8008static void 8009rs6000_move_block_from_reg (int regno, rtx x, int nregs) 8010{ 8011 int i; 8012 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode; 8013 8014 if (nregs == 0) 8015 return; 8016 8017 for (i = 0; i < nregs; i++) 8018 { 8019 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode)); 8020 if (reload_completed) 8021 { 8022 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0))) 8023 tem = NULL_RTX; 8024 else 8025 tem = simplify_gen_subreg (reg_mode, x, BLKmode, 8026 i * GET_MODE_SIZE (reg_mode)); 8027 } 8028 else 8029 tem = replace_equiv_address (tem, XEXP (tem, 0)); 8030 8031 gcc_assert (tem); 8032 8033 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i)); 8034 } 8035} 8036 8037/* Perform any needed actions needed for a function that is receiving a 8038 variable number of arguments. 8039 8040 CUM is as above. 8041 8042 MODE and TYPE are the mode and type of the current parameter. 8043 8044 PRETEND_SIZE is a variable that should be set to the amount of stack 8045 that must be pushed by the prolog to pretend that our caller pushed 8046 it. 8047 8048 Normally, this macro will push all remaining incoming registers on the 8049 stack and set PRETEND_SIZE to the length of the registers pushed. */ 8050 8051static void 8052setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode, 8053 tree type, int *pretend_size ATTRIBUTE_UNUSED, 8054 int no_rtl) 8055{ 8056 CUMULATIVE_ARGS next_cum; 8057 int reg_size = TARGET_32BIT ? 4 : 8; 8058 rtx save_area = NULL_RTX, mem; 8059 int first_reg_offset; 8060 alias_set_type set; 8061 8062 /* Skip the last named argument. */ 8063 next_cum = *cum; 8064 function_arg_advance (&next_cum, mode, type, 1, 0); 8065 8066 if (DEFAULT_ABI == ABI_V4) 8067 { 8068 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG; 8069 8070 if (! no_rtl) 8071 { 8072 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0; 8073 HOST_WIDE_INT offset = 0; 8074 8075 /* Try to optimize the size of the varargs save area. 8076 The ABI requires that ap.reg_save_area is doubleword 8077 aligned, but we don't need to allocate space for all 8078 the bytes, only those to which we actually will save 8079 anything. */ 8080 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG) 8081 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset; 8082 if (TARGET_HARD_FLOAT && TARGET_FPRS 8083 && next_cum.fregno <= FP_ARG_V4_MAX_REG 8084 && cfun->va_list_fpr_size) 8085 { 8086 if (gpr_reg_num) 8087 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG) 8088 * UNITS_PER_FP_WORD; 8089 if (cfun->va_list_fpr_size 8090 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno) 8091 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD; 8092 else 8093 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno) 8094 * UNITS_PER_FP_WORD; 8095 } 8096 if (gpr_reg_num) 8097 { 8098 offset = -((first_reg_offset * reg_size) & ~7); 8099 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size) 8100 { 8101 gpr_reg_num = cfun->va_list_gpr_size; 8102 if (reg_size == 4 && (first_reg_offset & 1)) 8103 gpr_reg_num++; 8104 } 8105 gpr_size = (gpr_reg_num * reg_size + 7) & ~7; 8106 } 8107 else if (fpr_size) 8108 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG) 8109 * UNITS_PER_FP_WORD 8110 - (int) (GP_ARG_NUM_REG * reg_size); 8111 8112 if (gpr_size + fpr_size) 8113 { 8114 rtx reg_save_area 8115 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64); 8116 gcc_assert (GET_CODE (reg_save_area) == MEM); 8117 reg_save_area = XEXP (reg_save_area, 0); 8118 if (GET_CODE (reg_save_area) == PLUS) 8119 { 8120 gcc_assert (XEXP (reg_save_area, 0) 8121 == virtual_stack_vars_rtx); 8122 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT); 8123 offset += INTVAL (XEXP (reg_save_area, 1)); 8124 } 8125 else 8126 gcc_assert (reg_save_area == virtual_stack_vars_rtx); 8127 } 8128 8129 cfun->machine->varargs_save_offset = offset; 8130 save_area = plus_constant (virtual_stack_vars_rtx, offset); 8131 } 8132 } 8133 else 8134 { 8135 first_reg_offset = next_cum.words; 8136 save_area = virtual_incoming_args_rtx; 8137 8138 if (targetm.calls.must_pass_in_stack (mode, type)) 8139 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type); 8140 } 8141 8142 set = get_varargs_alias_set (); 8143 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG 8144 && cfun->va_list_gpr_size) 8145 { 8146 int nregs = GP_ARG_NUM_REG - first_reg_offset; 8147 8148 if (va_list_gpr_counter_field) 8149 { 8150 /* V4 va_list_gpr_size counts number of registers needed. */ 8151 if (nregs > cfun->va_list_gpr_size) 8152 nregs = cfun->va_list_gpr_size; 8153 } 8154 else 8155 { 8156 /* char * va_list instead counts number of bytes needed. */ 8157 if (nregs > cfun->va_list_gpr_size / reg_size) 8158 nregs = cfun->va_list_gpr_size / reg_size; 8159 } 8160 8161 mem = gen_rtx_MEM (BLKmode, 8162 plus_constant (save_area, 8163 first_reg_offset * reg_size)); 8164 MEM_NOTRAP_P (mem) = 1; 8165 set_mem_alias_set (mem, set); 8166 set_mem_align (mem, BITS_PER_WORD); 8167 8168 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem, 8169 nregs); 8170 } 8171 8172 /* Save FP registers if needed. */ 8173 if (DEFAULT_ABI == ABI_V4 8174 && TARGET_HARD_FLOAT && TARGET_FPRS 8175 && ! no_rtl 8176 && next_cum.fregno <= FP_ARG_V4_MAX_REG 8177 && cfun->va_list_fpr_size) 8178 { 8179 int fregno = next_cum.fregno, nregs; 8180 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO); 8181 rtx lab = gen_label_rtx (); 8182 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG) 8183 * UNITS_PER_FP_WORD); 8184 8185 emit_jump_insn 8186 (gen_rtx_SET (VOIDmode, 8187 pc_rtx, 8188 gen_rtx_IF_THEN_ELSE (VOIDmode, 8189 gen_rtx_NE (VOIDmode, cr1, 8190 const0_rtx), 8191 gen_rtx_LABEL_REF (VOIDmode, lab), 8192 pc_rtx))); 8193 8194 for (nregs = 0; 8195 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size; 8196 fregno++, off += UNITS_PER_FP_WORD, nregs++) 8197 { 8198 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) 8199 ? DFmode : SFmode, 8200 plus_constant (save_area, off)); 8201 MEM_NOTRAP_P (mem) = 1; 8202 set_mem_alias_set (mem, set); 8203 set_mem_align (mem, GET_MODE_ALIGNMENT ( 8204 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) 8205 ? DFmode : SFmode)); 8206 emit_move_insn (mem, gen_rtx_REG ( 8207 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) 8208 ? DFmode : SFmode, fregno)); 8209 } 8210 8211 emit_label (lab); 8212 } 8213} 8214 8215/* Create the va_list data type. */ 8216 8217static tree 8218rs6000_build_builtin_va_list (void) 8219{ 8220 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl; 8221 8222 /* For AIX, prefer 'char *' because that's what the system 8223 header files like. */ 8224 if (DEFAULT_ABI != ABI_V4) 8225 return build_pointer_type (char_type_node); 8226 8227 record = (*lang_hooks.types.make_type) (RECORD_TYPE); 8228 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL, 8229 get_identifier ("__va_list_tag"), record); 8230 8231 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"), 8232 unsigned_char_type_node); 8233 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"), 8234 unsigned_char_type_node); 8235 /* Give the two bytes of padding a name, so that -Wpadded won't warn on 8236 every user file. */ 8237 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL, 8238 get_identifier ("reserved"), short_unsigned_type_node); 8239 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL, 8240 get_identifier ("overflow_arg_area"), 8241 ptr_type_node); 8242 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL, 8243 get_identifier ("reg_save_area"), 8244 ptr_type_node); 8245 8246 va_list_gpr_counter_field = f_gpr; 8247 va_list_fpr_counter_field = f_fpr; 8248 8249 DECL_FIELD_CONTEXT (f_gpr) = record; 8250 DECL_FIELD_CONTEXT (f_fpr) = record; 8251 DECL_FIELD_CONTEXT (f_res) = record; 8252 DECL_FIELD_CONTEXT (f_ovf) = record; 8253 DECL_FIELD_CONTEXT (f_sav) = record; 8254 8255 TREE_CHAIN (record) = type_decl; 8256 TYPE_NAME (record) = type_decl; 8257 TYPE_FIELDS (record) = f_gpr; 8258 TREE_CHAIN (f_gpr) = f_fpr; 8259 TREE_CHAIN (f_fpr) = f_res; 8260 TREE_CHAIN (f_res) = f_ovf; 8261 TREE_CHAIN (f_ovf) = f_sav; 8262 8263 layout_type (record); 8264 8265 /* The correct type is an array type of one element. */ 8266 return build_array_type (record, build_index_type (size_zero_node)); 8267} 8268 8269/* Implement va_start. */ 8270 8271static void 8272rs6000_va_start (tree valist, rtx nextarg) 8273{ 8274 HOST_WIDE_INT words, n_gpr, n_fpr; 8275 tree f_gpr, f_fpr, f_res, f_ovf, f_sav; 8276 tree gpr, fpr, ovf, sav, t; 8277 8278 /* Only SVR4 needs something special. */ 8279 if (DEFAULT_ABI != ABI_V4) 8280 { 8281 std_expand_builtin_va_start (valist, nextarg); 8282 return; 8283 } 8284 8285 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node)); 8286 f_fpr = TREE_CHAIN (f_gpr); 8287 f_res = TREE_CHAIN (f_fpr); 8288 f_ovf = TREE_CHAIN (f_res); 8289 f_sav = TREE_CHAIN (f_ovf); 8290 8291 valist = build_va_arg_indirect_ref (valist); 8292 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE); 8293 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist), 8294 f_fpr, NULL_TREE); 8295 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist), 8296 f_ovf, NULL_TREE); 8297 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist), 8298 f_sav, NULL_TREE); 8299 8300 /* Count number of gp and fp argument registers used. */ 8301 words = crtl->args.info.words; 8302 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG, 8303 GP_ARG_NUM_REG); 8304 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG, 8305 FP_ARG_NUM_REG); 8306 8307 if (TARGET_DEBUG_ARG) 8308 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = " 8309 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n", 8310 words, n_gpr, n_fpr); 8311 8312 if (cfun->va_list_gpr_size) 8313 { 8314 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr, 8315 build_int_cst (NULL_TREE, n_gpr)); 8316 TREE_SIDE_EFFECTS (t) = 1; 8317 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 8318 } 8319 8320 if (cfun->va_list_fpr_size) 8321 { 8322 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr, 8323 build_int_cst (NULL_TREE, n_fpr)); 8324 TREE_SIDE_EFFECTS (t) = 1; 8325 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 8326 } 8327 8328 /* Find the overflow area. */ 8329 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx); 8330 if (words != 0) 8331 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t, 8332 size_int (words * UNITS_PER_WORD)); 8333 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t); 8334 TREE_SIDE_EFFECTS (t) = 1; 8335 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 8336 8337 /* If there were no va_arg invocations, don't set up the register 8338 save area. */ 8339 if (!cfun->va_list_gpr_size 8340 && !cfun->va_list_fpr_size 8341 && n_gpr < GP_ARG_NUM_REG 8342 && n_fpr < FP_ARG_V4_MAX_REG) 8343 return; 8344 8345 /* Find the register save area. */ 8346 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx); 8347 if (cfun->machine->varargs_save_offset) 8348 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t, 8349 size_int (cfun->machine->varargs_save_offset)); 8350 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t); 8351 TREE_SIDE_EFFECTS (t) = 1; 8352 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 8353} 8354 8355/* Implement va_arg. */ 8356 8357tree 8358rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p, 8359 gimple_seq *post_p) 8360{ 8361 tree f_gpr, f_fpr, f_res, f_ovf, f_sav; 8362 tree gpr, fpr, ovf, sav, reg, t, u; 8363 int size, rsize, n_reg, sav_ofs, sav_scale; 8364 tree lab_false, lab_over, addr; 8365 int align; 8366 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true); 8367 int regalign = 0; 8368 gimple stmt; 8369 8370 if (pass_by_reference (NULL, TYPE_MODE (type), type, false)) 8371 { 8372 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p); 8373 return build_va_arg_indirect_ref (t); 8374 } 8375 8376 if (DEFAULT_ABI != ABI_V4) 8377 { 8378 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE) 8379 { 8380 tree elem_type = TREE_TYPE (type); 8381 enum machine_mode elem_mode = TYPE_MODE (elem_type); 8382 int elem_size = GET_MODE_SIZE (elem_mode); 8383 8384 if (elem_size < UNITS_PER_WORD) 8385 { 8386 tree real_part, imag_part; 8387 gimple_seq post = NULL; 8388 8389 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p, 8390 &post); 8391 /* Copy the value into a temporary, lest the formal temporary 8392 be reused out from under us. */ 8393 real_part = get_initialized_tmp_var (real_part, pre_p, &post); 8394 gimple_seq_add_seq (pre_p, post); 8395 8396 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p, 8397 post_p); 8398 8399 return build2 (COMPLEX_EXPR, type, real_part, imag_part); 8400 } 8401 } 8402 8403 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p); 8404 } 8405 8406 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node)); 8407 f_fpr = TREE_CHAIN (f_gpr); 8408 f_res = TREE_CHAIN (f_fpr); 8409 f_ovf = TREE_CHAIN (f_res); 8410 f_sav = TREE_CHAIN (f_ovf); 8411 8412 valist = build_va_arg_indirect_ref (valist); 8413 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE); 8414 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist), 8415 f_fpr, NULL_TREE); 8416 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist), 8417 f_ovf, NULL_TREE); 8418 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist), 8419 f_sav, NULL_TREE); 8420 8421 size = int_size_in_bytes (type); 8422 rsize = (size + 3) / 4; 8423 align = 1; 8424 8425 if (TARGET_HARD_FLOAT && TARGET_FPRS 8426 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode) 8427 || (TARGET_DOUBLE_FLOAT 8428 && (TYPE_MODE (type) == DFmode 8429 || TYPE_MODE (type) == TFmode 8430 || TYPE_MODE (type) == SDmode 8431 || TYPE_MODE (type) == DDmode 8432 || TYPE_MODE (type) == TDmode)))) 8433 { 8434 /* FP args go in FP registers, if present. */ 8435 reg = fpr; 8436 n_reg = (size + 7) / 8; 8437 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4; 8438 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4); 8439 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode) 8440 align = 8; 8441 } 8442 else 8443 { 8444 /* Otherwise into GP registers. */ 8445 reg = gpr; 8446 n_reg = rsize; 8447 sav_ofs = 0; 8448 sav_scale = 4; 8449 if (n_reg == 2) 8450 align = 8; 8451 } 8452 8453 /* Pull the value out of the saved registers.... */ 8454 8455 lab_over = NULL; 8456 addr = create_tmp_var (ptr_type_node, "addr"); 8457 8458 /* AltiVec vectors never go in registers when -mabi=altivec. */ 8459 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type))) 8460 align = 16; 8461 else 8462 { 8463 lab_false = create_artificial_label (input_location); 8464 lab_over = create_artificial_label (input_location); 8465 8466 /* Long long and SPE vectors are aligned in the registers. 8467 As are any other 2 gpr item such as complex int due to a 8468 historical mistake. */ 8469 u = reg; 8470 if (n_reg == 2 && reg == gpr) 8471 { 8472 regalign = 1; 8473 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg), 8474 build_int_cst (TREE_TYPE (reg), n_reg - 1)); 8475 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), 8476 unshare_expr (reg), u); 8477 } 8478 /* _Decimal128 is passed in even/odd fpr pairs; the stored 8479 reg number is 0 for f1, so we want to make it odd. */ 8480 else if (reg == fpr && TYPE_MODE (type) == TDmode) 8481 { 8482 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg), 8483 build_int_cst (TREE_TYPE (reg), 1)); 8484 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t); 8485 } 8486 8487 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1)); 8488 t = build2 (GE_EXPR, boolean_type_node, u, t); 8489 u = build1 (GOTO_EXPR, void_type_node, lab_false); 8490 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE); 8491 gimplify_and_add (t, pre_p); 8492 8493 t = sav; 8494 if (sav_ofs) 8495 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs)); 8496 8497 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg), 8498 build_int_cst (TREE_TYPE (reg), n_reg)); 8499 u = fold_convert (sizetype, u); 8500 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale)); 8501 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u); 8502 8503 /* _Decimal32 varargs are located in the second word of the 64-bit 8504 FP register for 32-bit binaries. */ 8505 if (!TARGET_POWERPC64 8506 && TARGET_HARD_FLOAT && TARGET_FPRS 8507 && TYPE_MODE (type) == SDmode) 8508 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size)); 8509 8510 gimplify_assign (addr, t, pre_p); 8511 8512 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over)); 8513 8514 stmt = gimple_build_label (lab_false); 8515 gimple_seq_add_stmt (pre_p, stmt); 8516 8517 if ((n_reg == 2 && !regalign) || n_reg > 2) 8518 { 8519 /* Ensure that we don't find any more args in regs. 8520 Alignment has taken care of for special cases. */ 8521 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p); 8522 } 8523 } 8524 8525 /* ... otherwise out of the overflow area. */ 8526 8527 /* Care for on-stack alignment if needed. */ 8528 t = ovf; 8529 if (align != 1) 8530 { 8531 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1)); 8532 t = fold_convert (sizetype, t); 8533 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t, 8534 size_int (-align)); 8535 t = fold_convert (TREE_TYPE (ovf), t); 8536 } 8537 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue); 8538 8539 gimplify_assign (unshare_expr (addr), t, pre_p); 8540 8541 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size)); 8542 gimplify_assign (unshare_expr (ovf), t, pre_p); 8543 8544 if (lab_over) 8545 { 8546 stmt = gimple_build_label (lab_over); 8547 gimple_seq_add_stmt (pre_p, stmt); 8548 } 8549 8550 if (STRICT_ALIGNMENT 8551 && (TYPE_ALIGN (type) 8552 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align))) 8553 { 8554 /* The value (of type complex double, for example) may not be 8555 aligned in memory in the saved registers, so copy via a 8556 temporary. (This is the same code as used for SPARC.) */ 8557 tree tmp = create_tmp_var (type, "va_arg_tmp"); 8558 tree dest_addr = build_fold_addr_expr (tmp); 8559 8560 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY], 8561 3, dest_addr, addr, size_int (rsize * 4)); 8562 8563 gimplify_and_add (copy, pre_p); 8564 addr = dest_addr; 8565 } 8566 8567 addr = fold_convert (ptrtype, addr); 8568 return build_va_arg_indirect_ref (addr); 8569} 8570 8571/* Builtins. */ 8572 8573static void 8574def_builtin (int mask, const char *name, tree type, int code) 8575{ 8576 if ((mask & target_flags) || TARGET_PAIRED_FLOAT) 8577 { 8578 tree t; 8579 if (rs6000_builtin_decls[code]) 8580 fatal_error ("internal error: builtin function to %s already processed.", 8581 name); 8582 8583 rs6000_builtin_decls[code] = t = 8584 add_builtin_function (name, type, code, BUILT_IN_MD, 8585 NULL, NULL_TREE); 8586 8587 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT); 8588 switch (builtin_classify[code]) 8589 { 8590 default: 8591 gcc_unreachable (); 8592 8593 /* assume builtin can do anything. */ 8594 case RS6000_BTC_MISC: 8595 break; 8596 8597 /* const function, function only depends on the inputs. */ 8598 case RS6000_BTC_CONST: 8599 TREE_READONLY (t) = 1; 8600 TREE_NOTHROW (t) = 1; 8601 break; 8602 8603 /* pure function, function can read global memory. */ 8604 case RS6000_BTC_PURE: 8605 DECL_PURE_P (t) = 1; 8606 TREE_NOTHROW (t) = 1; 8607 break; 8608 8609 /* Function is a math function. If rounding mode is on, then treat 8610 the function as not reading global memory, but it can have 8611 arbitrary side effects. If it is off, then assume the function is 8612 a const function. This mimics the ATTR_MATHFN_FPROUNDING 8613 attribute in builtin-attribute.def that is used for the math 8614 functions. */ 8615 case RS6000_BTC_FP_PURE: 8616 TREE_NOTHROW (t) = 1; 8617 if (flag_rounding_math) 8618 { 8619 DECL_PURE_P (t) = 1; 8620 DECL_IS_NOVOPS (t) = 1; 8621 } 8622 else 8623 TREE_READONLY (t) = 1; 8624 break; 8625 } 8626 } 8627} 8628 8629/* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */ 8630 8631static const struct builtin_description bdesc_3arg[] = 8632{ 8633 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP }, 8634 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS }, 8635 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS }, 8636 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM}, 8637 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM }, 8638 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM }, 8639 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM }, 8640 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM }, 8641 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS }, 8642 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS }, 8643 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP }, 8644 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF }, 8645 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI }, 8646 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF }, 8647 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI }, 8648 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI }, 8649 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI }, 8650 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS }, 8651 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS }, 8652 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS }, 8653 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS }, 8654 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF }, 8655 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI }, 8656 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI }, 8657 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI }, 8658 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF }, 8659 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI }, 8660 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS }, 8661 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS }, 8662 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS }, 8663 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS }, 8664 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI }, 8665 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI }, 8666 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI }, 8667 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF }, 8668 8669 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD }, 8670 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS }, 8671 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD }, 8672 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS }, 8673 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM }, 8674 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM }, 8675 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM }, 8676 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM }, 8677 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM }, 8678 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS }, 8679 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS }, 8680 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS }, 8681 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB }, 8682 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM }, 8683 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL }, 8684 8685 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP }, 8686 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP }, 8687 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP }, 8688 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP }, 8689 8690 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP }, 8691 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP }, 8692 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP }, 8693 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP }, 8694 8695 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB }, 8696 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD }, 8697 8698 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI }, 8699 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF }, 8700 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF }, 8701 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI }, 8702 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI }, 8703 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI }, 8704 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS }, 8705 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS }, 8706 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS }, 8707 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS }, 8708 8709 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI }, 8710 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF }, 8711 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF }, 8712 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI }, 8713 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI }, 8714 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI }, 8715 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS }, 8716 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS }, 8717 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS }, 8718 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS }, 8719 8720 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF }, 8721 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI }, 8722 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF }, 8723 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI }, 8724 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI }, 8725 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI }, 8726 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI }, 8727 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF }, 8728 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI }, 8729 8730 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI }, 8731 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF }, 8732 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF }, 8733 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI }, 8734 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI }, 8735 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI }, 8736 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI }, 8737 8738 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB }, 8739 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD }, 8740 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 }, 8741 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 }, 8742 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB }, 8743 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD }, 8744 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 }, 8745 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 }, 8746 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 }, 8747}; 8748 8749/* DST operations: void foo (void *, const int, const char). */ 8750 8751static const struct builtin_description bdesc_dst[] = 8752{ 8753 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST }, 8754 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT }, 8755 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST }, 8756 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT }, 8757 8758 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST }, 8759 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT }, 8760 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST }, 8761 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT } 8762}; 8763 8764/* Simple binary operations: VECc = foo (VECa, VECb). */ 8765 8766static struct builtin_description bdesc_2arg[] = 8767{ 8768 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM }, 8769 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM }, 8770 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM }, 8771 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP }, 8772 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW }, 8773 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS }, 8774 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS }, 8775 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS }, 8776 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS }, 8777 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS }, 8778 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS }, 8779 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND }, 8780 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC }, 8781 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB }, 8782 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB }, 8783 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH }, 8784 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH }, 8785 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW }, 8786 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW }, 8787 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX }, 8788 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX }, 8789 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP }, 8790 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB }, 8791 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH }, 8792 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW }, 8793 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP }, 8794 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP }, 8795 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB }, 8796 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB }, 8797 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH }, 8798 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH }, 8799 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW }, 8800 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW }, 8801 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP }, 8802 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS }, 8803 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS }, 8804 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB }, 8805 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB }, 8806 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH }, 8807 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH }, 8808 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW }, 8809 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW }, 8810 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP }, 8811 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB }, 8812 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH }, 8813 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW }, 8814 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB }, 8815 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH }, 8816 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW }, 8817 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB }, 8818 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB }, 8819 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH }, 8820 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH }, 8821 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW }, 8822 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW }, 8823 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP }, 8824 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB }, 8825 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS }, 8826 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB }, 8827 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH }, 8828 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS }, 8829 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH }, 8830 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB }, 8831 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS }, 8832 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB }, 8833 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH }, 8834 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS }, 8835 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH }, 8836 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR }, 8837 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR }, 8838 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM }, 8839 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM }, 8840 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX }, 8841 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS }, 8842 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS }, 8843 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS }, 8844 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS }, 8845 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS }, 8846 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS }, 8847 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB }, 8848 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH }, 8849 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW }, 8850 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB }, 8851 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH }, 8852 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW }, 8853 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL }, 8854 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO }, 8855 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB }, 8856 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH }, 8857 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW }, 8858 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB }, 8859 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH }, 8860 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW }, 8861 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB }, 8862 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH }, 8863 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW }, 8864 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR }, 8865 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO }, 8866 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM }, 8867 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM }, 8868 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM }, 8869 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP }, 8870 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW }, 8871 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS }, 8872 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS }, 8873 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS }, 8874 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS }, 8875 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS }, 8876 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS }, 8877 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS }, 8878 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS }, 8879 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS }, 8880 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS }, 8881 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS }, 8882 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR }, 8883 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF }, 8884 8885 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP }, 8886 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP }, 8887 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP }, 8888 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP }, 8889 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP }, 8890 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP }, 8891 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE }, 8892 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG }, 8893 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP }, 8894 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP }, 8895 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP }, 8896 8897 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP }, 8898 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP }, 8899 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP }, 8900 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP }, 8901 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP }, 8902 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP }, 8903 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE }, 8904 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG }, 8905 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP }, 8906 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP }, 8907 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP }, 8908 8909 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP }, 8910 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP }, 8911 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE }, 8912 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG }, 8913 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP }, 8914 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP }, 8915 8916 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF }, 8917 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI }, 8918 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF }, 8919 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI }, 8920 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF }, 8921 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI }, 8922 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF }, 8923 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI }, 8924 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF }, 8925 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI }, 8926 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF }, 8927 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI }, 8928 8929 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD }, 8930 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP }, 8931 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM }, 8932 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM }, 8933 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM }, 8934 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC }, 8935 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS }, 8936 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS }, 8937 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS }, 8938 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS }, 8939 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS }, 8940 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS }, 8941 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS }, 8942 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND }, 8943 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC }, 8944 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG }, 8945 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW }, 8946 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW }, 8947 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH }, 8948 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH }, 8949 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB }, 8950 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB }, 8951 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB }, 8952 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ }, 8953 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP }, 8954 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW }, 8955 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH }, 8956 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB }, 8957 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE }, 8958 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT }, 8959 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP }, 8960 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW }, 8961 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW }, 8962 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH }, 8963 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH }, 8964 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB }, 8965 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB }, 8966 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE }, 8967 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT }, 8968 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN }, 8969 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX }, 8970 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP }, 8971 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW }, 8972 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW }, 8973 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH }, 8974 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH }, 8975 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB }, 8976 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB }, 8977 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH }, 8978 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW }, 8979 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH }, 8980 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB }, 8981 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL }, 8982 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW }, 8983 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH }, 8984 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB }, 8985 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN }, 8986 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP }, 8987 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW }, 8988 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW }, 8989 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH }, 8990 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH }, 8991 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB }, 8992 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB }, 8993 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE }, 8994 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB }, 8995 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB }, 8996 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH }, 8997 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH }, 8998 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO }, 8999 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH }, 9000 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH }, 9001 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB }, 9002 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB }, 9003 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR }, 9004 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR }, 9005 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK }, 9006 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM }, 9007 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM }, 9008 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX }, 9009 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS }, 9010 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS }, 9011 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS }, 9012 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS }, 9013 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS }, 9014 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU }, 9015 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS }, 9016 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS }, 9017 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL }, 9018 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW }, 9019 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH }, 9020 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB }, 9021 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL }, 9022 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW }, 9023 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH }, 9024 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB }, 9025 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL }, 9026 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO }, 9027 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR }, 9028 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW }, 9029 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH }, 9030 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB }, 9031 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA }, 9032 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW }, 9033 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH }, 9034 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB }, 9035 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL }, 9036 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO }, 9037 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB }, 9038 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP }, 9039 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM }, 9040 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM }, 9041 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM }, 9042 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC }, 9043 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS }, 9044 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS }, 9045 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS }, 9046 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS }, 9047 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS }, 9048 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS }, 9049 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS }, 9050 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S }, 9051 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS }, 9052 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS }, 9053 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS }, 9054 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S }, 9055 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS }, 9056 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR }, 9057 9058 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL }, 9059 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV }, 9060 9061 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 }, 9062 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 }, 9063 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 }, 9064 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 }, 9065 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 }, 9066 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 }, 9067 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 }, 9068 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 }, 9069 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 }, 9070 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 }, 9071 9072 /* Place holder, leave as first spe builtin. */ 9073 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW }, 9074 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND }, 9075 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC }, 9076 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS }, 9077 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU }, 9078 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV }, 9079 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD }, 9080 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV }, 9081 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL }, 9082 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB }, 9083 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI }, 9084 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO }, 9085 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO }, 9086 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI }, 9087 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA }, 9088 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN }, 9089 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA }, 9090 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN }, 9091 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA }, 9092 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN }, 9093 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF }, 9094 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA }, 9095 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW }, 9096 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW }, 9097 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI }, 9098 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA }, 9099 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW }, 9100 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW }, 9101 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF }, 9102 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA }, 9103 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW }, 9104 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW }, 9105 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW }, 9106 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW }, 9107 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI }, 9108 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA }, 9109 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW }, 9110 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW }, 9111 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW }, 9112 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW }, 9113 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA }, 9114 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN }, 9115 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA }, 9116 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN }, 9117 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA }, 9118 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN }, 9119 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF }, 9120 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA }, 9121 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW }, 9122 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW }, 9123 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI }, 9124 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA }, 9125 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW }, 9126 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW }, 9127 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF }, 9128 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA }, 9129 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW }, 9130 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW }, 9131 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW }, 9132 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW }, 9133 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI }, 9134 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA }, 9135 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW }, 9136 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW }, 9137 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW }, 9138 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW }, 9139 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF }, 9140 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA }, 9141 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI }, 9142 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA }, 9143 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF }, 9144 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA }, 9145 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI }, 9146 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA }, 9147 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW }, 9148 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW }, 9149 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW }, 9150 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW }, 9151 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI }, 9152 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA }, 9153 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW }, 9154 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW }, 9155 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW }, 9156 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW }, 9157 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF }, 9158 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA }, 9159 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA }, 9160 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN }, 9161 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI }, 9162 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA }, 9163 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA }, 9164 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN }, 9165 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF }, 9166 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA }, 9167 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA }, 9168 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN }, 9169 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI }, 9170 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA }, 9171 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA }, 9172 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN }, 9173 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND }, 9174 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR }, 9175 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR }, 9176 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC }, 9177 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW }, 9178 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW }, 9179 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS }, 9180 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU }, 9181 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW }, 9182 9183 /* SPE binary operations expecting a 5-bit unsigned literal. */ 9184 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW }, 9185 9186 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI }, 9187 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI }, 9188 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS }, 9189 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU }, 9190 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW }, 9191 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA }, 9192 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA }, 9193 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA }, 9194 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA }, 9195 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA }, 9196 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA }, 9197 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN }, 9198 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN }, 9199 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN }, 9200 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN }, 9201 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN }, 9202 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN }, 9203 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA }, 9204 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA }, 9205 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA }, 9206 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA }, 9207 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN }, 9208 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN }, 9209 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN }, 9210 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN }, 9211 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC }, 9212 9213 /* Place-holder. Leave as last binary SPE builtin. */ 9214 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR } 9215}; 9216 9217/* AltiVec predicates. */ 9218 9219struct builtin_description_predicates 9220{ 9221 const unsigned int mask; 9222 const enum insn_code icode; 9223 const char *const name; 9224 const enum rs6000_builtins code; 9225}; 9226 9227static const struct builtin_description_predicates bdesc_altivec_preds[] = 9228{ 9229 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p", 9230 ALTIVEC_BUILTIN_VCMPBFP_P }, 9231 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p, 9232 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P }, 9233 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p, 9234 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P }, 9235 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p, 9236 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P }, 9237 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p", 9238 ALTIVEC_BUILTIN_VCMPEQUW_P }, 9239 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p", 9240 ALTIVEC_BUILTIN_VCMPGTSW_P }, 9241 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p", 9242 ALTIVEC_BUILTIN_VCMPGTUW_P }, 9243 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p", 9244 ALTIVEC_BUILTIN_VCMPEQUH_P }, 9245 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p", 9246 ALTIVEC_BUILTIN_VCMPGTSH_P }, 9247 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p", 9248 ALTIVEC_BUILTIN_VCMPGTUH_P }, 9249 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p", 9250 ALTIVEC_BUILTIN_VCMPEQUB_P }, 9251 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p", 9252 ALTIVEC_BUILTIN_VCMPGTSB_P }, 9253 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p", 9254 ALTIVEC_BUILTIN_VCMPGTUB_P }, 9255 9256 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p", 9257 VSX_BUILTIN_XVCMPEQSP_P }, 9258 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p", 9259 VSX_BUILTIN_XVCMPGESP_P }, 9260 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p", 9261 VSX_BUILTIN_XVCMPGTSP_P }, 9262 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p", 9263 VSX_BUILTIN_XVCMPEQDP_P }, 9264 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p", 9265 VSX_BUILTIN_XVCMPGEDP_P }, 9266 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p", 9267 VSX_BUILTIN_XVCMPGTDP_P }, 9268 9269 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p", 9270 ALTIVEC_BUILTIN_VCMPEQ_P }, 9271 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p", 9272 ALTIVEC_BUILTIN_VCMPGT_P }, 9273 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p", 9274 ALTIVEC_BUILTIN_VCMPGE_P } 9275}; 9276 9277/* SPE predicates. */ 9278static struct builtin_description bdesc_spe_predicates[] = 9279{ 9280 /* Place-holder. Leave as first. */ 9281 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ }, 9282 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS }, 9283 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU }, 9284 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS }, 9285 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU }, 9286 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ }, 9287 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT }, 9288 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT }, 9289 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ }, 9290 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT }, 9291 /* Place-holder. Leave as last. */ 9292 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT }, 9293}; 9294 9295/* SPE evsel predicates. */ 9296static struct builtin_description bdesc_spe_evsel[] = 9297{ 9298 /* Place-holder. Leave as first. */ 9299 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS }, 9300 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU }, 9301 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS }, 9302 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU }, 9303 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ }, 9304 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT }, 9305 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT }, 9306 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ }, 9307 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT }, 9308 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT }, 9309 /* Place-holder. Leave as last. */ 9310 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ }, 9311}; 9312 9313/* PAIRED predicates. */ 9314static const struct builtin_description bdesc_paired_preds[] = 9315{ 9316 /* Place-holder. Leave as first. */ 9317 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 }, 9318 /* Place-holder. Leave as last. */ 9319 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 }, 9320}; 9321 9322/* ABS* operations. */ 9323 9324static const struct builtin_description bdesc_abs[] = 9325{ 9326 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI }, 9327 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI }, 9328 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF }, 9329 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI }, 9330 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI }, 9331 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI }, 9332 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }, 9333 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP }, 9334 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP }, 9335 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP }, 9336 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP }, 9337}; 9338 9339/* Simple unary operations: VECb = foo (unsigned literal) or VECb = 9340 foo (VECa). */ 9341 9342static struct builtin_description bdesc_1arg[] = 9343{ 9344 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP }, 9345 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP }, 9346 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP }, 9347 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM }, 9348 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN }, 9349 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP }, 9350 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ }, 9351 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP }, 9352 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB }, 9353 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH }, 9354 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW }, 9355 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB }, 9356 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX }, 9357 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH }, 9358 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB }, 9359 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX }, 9360 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH }, 9361 9362 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP }, 9363 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP }, 9364 { MASK_VSX, CODE_FOR_vsx_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP }, 9365 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE }, 9366 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG }, 9367 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP }, 9368 9369 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP }, 9370 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP }, 9371 { MASK_VSX, CODE_FOR_vsx_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP }, 9372 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE }, 9373 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG }, 9374 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP }, 9375 9376 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP }, 9377 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP }, 9378 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP }, 9379 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP }, 9380 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE }, 9381 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG }, 9382 9383 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS }, 9384 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS }, 9385 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS }, 9386 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP }, 9387 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP }, 9388 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS }, 9389 9390 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS }, 9391 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS }, 9392 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP }, 9393 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP }, 9394 9395 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS }, 9396 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS }, 9397 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP }, 9398 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP }, 9399 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI }, 9400 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC }, 9401 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM }, 9402 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP }, 9403 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ }, 9404 9405 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS }, 9406 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS }, 9407 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP }, 9408 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP }, 9409 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI }, 9410 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC }, 9411 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM }, 9412 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP }, 9413 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ }, 9414 9415 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI }, 9416 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC }, 9417 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM }, 9418 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP }, 9419 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ }, 9420 9421 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS }, 9422 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS }, 9423 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL }, 9424 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE }, 9425 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR }, 9426 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE }, 9427 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR }, 9428 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE }, 9429 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND }, 9430 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE }, 9431 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC }, 9432 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH }, 9433 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH }, 9434 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX }, 9435 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB }, 9436 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL }, 9437 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX }, 9438 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH }, 9439 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB }, 9440 9441 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT }, 9442 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT }, 9443 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT }, 9444 9445 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF }, 9446 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF }, 9447 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI }, 9448 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI }, 9449 9450 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and 9451 end with SPE_BUILTIN_EVSUBFUSIAAW. */ 9452 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS }, 9453 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW }, 9454 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW }, 9455 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW }, 9456 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW }, 9457 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW }, 9458 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW }, 9459 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB }, 9460 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH }, 9461 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS }, 9462 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF }, 9463 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI }, 9464 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF }, 9465 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI }, 9466 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF }, 9467 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI }, 9468 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ }, 9469 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF }, 9470 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI }, 9471 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ }, 9472 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS }, 9473 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG }, 9474 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA }, 9475 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG }, 9476 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW }, 9477 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW }, 9478 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW }, 9479 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW }, 9480 9481 /* Place-holder. Leave as last unary SPE builtin. */ 9482 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW }, 9483 9484 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 }, 9485 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 }, 9486 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 }, 9487 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 }, 9488 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 } 9489}; 9490 9491static rtx 9492rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target) 9493{ 9494 rtx pat; 9495 tree arg0 = CALL_EXPR_ARG (exp, 0); 9496 rtx op0 = expand_normal (arg0); 9497 enum machine_mode tmode = insn_data[icode].operand[0].mode; 9498 enum machine_mode mode0 = insn_data[icode].operand[1].mode; 9499 9500 if (icode == CODE_FOR_nothing) 9501 /* Builtin not supported on this processor. */ 9502 return 0; 9503 9504 /* If we got invalid arguments bail out before generating bad rtl. */ 9505 if (arg0 == error_mark_node) 9506 return const0_rtx; 9507 9508 if (icode == CODE_FOR_altivec_vspltisb 9509 || icode == CODE_FOR_altivec_vspltish 9510 || icode == CODE_FOR_altivec_vspltisw 9511 || icode == CODE_FOR_spe_evsplatfi 9512 || icode == CODE_FOR_spe_evsplati) 9513 { 9514 /* Only allow 5-bit *signed* literals. */ 9515 if (GET_CODE (op0) != CONST_INT 9516 || INTVAL (op0) > 15 9517 || INTVAL (op0) < -16) 9518 { 9519 error ("argument 1 must be a 5-bit signed literal"); 9520 return const0_rtx; 9521 } 9522 } 9523 9524 if (target == 0 9525 || GET_MODE (target) != tmode 9526 || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) 9527 target = gen_reg_rtx (tmode); 9528 9529 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) 9530 op0 = copy_to_mode_reg (mode0, op0); 9531 9532 pat = GEN_FCN (icode) (target, op0); 9533 if (! pat) 9534 return 0; 9535 emit_insn (pat); 9536 9537 return target; 9538} 9539 9540static rtx 9541altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target) 9542{ 9543 rtx pat, scratch1, scratch2; 9544 tree arg0 = CALL_EXPR_ARG (exp, 0); 9545 rtx op0 = expand_normal (arg0); 9546 enum machine_mode tmode = insn_data[icode].operand[0].mode; 9547 enum machine_mode mode0 = insn_data[icode].operand[1].mode; 9548 9549 /* If we have invalid arguments, bail out before generating bad rtl. */ 9550 if (arg0 == error_mark_node) 9551 return const0_rtx; 9552 9553 if (target == 0 9554 || GET_MODE (target) != tmode 9555 || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) 9556 target = gen_reg_rtx (tmode); 9557 9558 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) 9559 op0 = copy_to_mode_reg (mode0, op0); 9560 9561 scratch1 = gen_reg_rtx (mode0); 9562 scratch2 = gen_reg_rtx (mode0); 9563 9564 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2); 9565 if (! pat) 9566 return 0; 9567 emit_insn (pat); 9568 9569 return target; 9570} 9571 9572static rtx 9573rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target) 9574{ 9575 rtx pat; 9576 tree arg0 = CALL_EXPR_ARG (exp, 0); 9577 tree arg1 = CALL_EXPR_ARG (exp, 1); 9578 rtx op0 = expand_normal (arg0); 9579 rtx op1 = expand_normal (arg1); 9580 enum machine_mode tmode = insn_data[icode].operand[0].mode; 9581 enum machine_mode mode0 = insn_data[icode].operand[1].mode; 9582 enum machine_mode mode1 = insn_data[icode].operand[2].mode; 9583 9584 if (icode == CODE_FOR_nothing) 9585 /* Builtin not supported on this processor. */ 9586 return 0; 9587 9588 /* If we got invalid arguments bail out before generating bad rtl. */ 9589 if (arg0 == error_mark_node || arg1 == error_mark_node) 9590 return const0_rtx; 9591 9592 if (icode == CODE_FOR_altivec_vcfux 9593 || icode == CODE_FOR_altivec_vcfsx 9594 || icode == CODE_FOR_altivec_vctsxs 9595 || icode == CODE_FOR_altivec_vctuxs 9596 || icode == CODE_FOR_altivec_vspltb 9597 || icode == CODE_FOR_altivec_vsplth 9598 || icode == CODE_FOR_altivec_vspltw 9599 || icode == CODE_FOR_spe_evaddiw 9600 || icode == CODE_FOR_spe_evldd 9601 || icode == CODE_FOR_spe_evldh 9602 || icode == CODE_FOR_spe_evldw 9603 || icode == CODE_FOR_spe_evlhhesplat 9604 || icode == CODE_FOR_spe_evlhhossplat 9605 || icode == CODE_FOR_spe_evlhhousplat 9606 || icode == CODE_FOR_spe_evlwhe 9607 || icode == CODE_FOR_spe_evlwhos 9608 || icode == CODE_FOR_spe_evlwhou 9609 || icode == CODE_FOR_spe_evlwhsplat 9610 || icode == CODE_FOR_spe_evlwwsplat 9611 || icode == CODE_FOR_spe_evrlwi 9612 || icode == CODE_FOR_spe_evslwi 9613 || icode == CODE_FOR_spe_evsrwis 9614 || icode == CODE_FOR_spe_evsubifw 9615 || icode == CODE_FOR_spe_evsrwiu) 9616 { 9617 /* Only allow 5-bit unsigned literals. */ 9618 STRIP_NOPS (arg1); 9619 if (TREE_CODE (arg1) != INTEGER_CST 9620 || TREE_INT_CST_LOW (arg1) & ~0x1f) 9621 { 9622 error ("argument 2 must be a 5-bit unsigned literal"); 9623 return const0_rtx; 9624 } 9625 } 9626 9627 if (target == 0 9628 || GET_MODE (target) != tmode 9629 || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) 9630 target = gen_reg_rtx (tmode); 9631 9632 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) 9633 op0 = copy_to_mode_reg (mode0, op0); 9634 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1)) 9635 op1 = copy_to_mode_reg (mode1, op1); 9636 9637 pat = GEN_FCN (icode) (target, op0, op1); 9638 if (! pat) 9639 return 0; 9640 emit_insn (pat); 9641 9642 return target; 9643} 9644 9645static rtx 9646altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target) 9647{ 9648 rtx pat, scratch; 9649 tree cr6_form = CALL_EXPR_ARG (exp, 0); 9650 tree arg0 = CALL_EXPR_ARG (exp, 1); 9651 tree arg1 = CALL_EXPR_ARG (exp, 2); 9652 rtx op0 = expand_normal (arg0); 9653 rtx op1 = expand_normal (arg1); 9654 enum machine_mode tmode = SImode; 9655 enum machine_mode mode0 = insn_data[icode].operand[1].mode; 9656 enum machine_mode mode1 = insn_data[icode].operand[2].mode; 9657 int cr6_form_int; 9658 9659 if (TREE_CODE (cr6_form) != INTEGER_CST) 9660 { 9661 error ("argument 1 of __builtin_altivec_predicate must be a constant"); 9662 return const0_rtx; 9663 } 9664 else 9665 cr6_form_int = TREE_INT_CST_LOW (cr6_form); 9666 9667 gcc_assert (mode0 == mode1); 9668 9669 /* If we have invalid arguments, bail out before generating bad rtl. */ 9670 if (arg0 == error_mark_node || arg1 == error_mark_node) 9671 return const0_rtx; 9672 9673 if (target == 0 9674 || GET_MODE (target) != tmode 9675 || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) 9676 target = gen_reg_rtx (tmode); 9677 9678 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) 9679 op0 = copy_to_mode_reg (mode0, op0); 9680 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1)) 9681 op1 = copy_to_mode_reg (mode1, op1); 9682 9683 scratch = gen_reg_rtx (mode0); 9684 9685 pat = GEN_FCN (icode) (scratch, op0, op1); 9686 if (! pat) 9687 return 0; 9688 emit_insn (pat); 9689 9690 /* The vec_any* and vec_all* predicates use the same opcodes for two 9691 different operations, but the bits in CR6 will be different 9692 depending on what information we want. So we have to play tricks 9693 with CR6 to get the right bits out. 9694 9695 If you think this is disgusting, look at the specs for the 9696 AltiVec predicates. */ 9697 9698 switch (cr6_form_int) 9699 { 9700 case 0: 9701 emit_insn (gen_cr6_test_for_zero (target)); 9702 break; 9703 case 1: 9704 emit_insn (gen_cr6_test_for_zero_reverse (target)); 9705 break; 9706 case 2: 9707 emit_insn (gen_cr6_test_for_lt (target)); 9708 break; 9709 case 3: 9710 emit_insn (gen_cr6_test_for_lt_reverse (target)); 9711 break; 9712 default: 9713 error ("argument 1 of __builtin_altivec_predicate is out of range"); 9714 break; 9715 } 9716 9717 return target; 9718} 9719 9720static rtx 9721paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target) 9722{ 9723 rtx pat, addr; 9724 tree arg0 = CALL_EXPR_ARG (exp, 0); 9725 tree arg1 = CALL_EXPR_ARG (exp, 1); 9726 enum machine_mode tmode = insn_data[icode].operand[0].mode; 9727 enum machine_mode mode0 = Pmode; 9728 enum machine_mode mode1 = Pmode; 9729 rtx op0 = expand_normal (arg0); 9730 rtx op1 = expand_normal (arg1); 9731 9732 if (icode == CODE_FOR_nothing) 9733 /* Builtin not supported on this processor. */ 9734 return 0; 9735 9736 /* If we got invalid arguments bail out before generating bad rtl. */ 9737 if (arg0 == error_mark_node || arg1 == error_mark_node) 9738 return const0_rtx; 9739 9740 if (target == 0 9741 || GET_MODE (target) != tmode 9742 || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) 9743 target = gen_reg_rtx (tmode); 9744 9745 op1 = copy_to_mode_reg (mode1, op1); 9746 9747 if (op0 == const0_rtx) 9748 { 9749 addr = gen_rtx_MEM (tmode, op1); 9750 } 9751 else 9752 { 9753 op0 = copy_to_mode_reg (mode0, op0); 9754 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1)); 9755 } 9756 9757 pat = GEN_FCN (icode) (target, addr); 9758 9759 if (! pat) 9760 return 0; 9761 emit_insn (pat); 9762 9763 return target; 9764} 9765 9766static rtx 9767altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk) 9768{ 9769 rtx pat, addr; 9770 tree arg0 = CALL_EXPR_ARG (exp, 0); 9771 tree arg1 = CALL_EXPR_ARG (exp, 1); 9772 enum machine_mode tmode = insn_data[icode].operand[0].mode; 9773 enum machine_mode mode0 = Pmode; 9774 enum machine_mode mode1 = Pmode; 9775 rtx op0 = expand_normal (arg0); 9776 rtx op1 = expand_normal (arg1); 9777 9778 if (icode == CODE_FOR_nothing) 9779 /* Builtin not supported on this processor. */ 9780 return 0; 9781 9782 /* If we got invalid arguments bail out before generating bad rtl. */ 9783 if (arg0 == error_mark_node || arg1 == error_mark_node) 9784 return const0_rtx; 9785 9786 if (target == 0 9787 || GET_MODE (target) != tmode 9788 || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) 9789 target = gen_reg_rtx (tmode); 9790 9791 op1 = copy_to_mode_reg (mode1, op1); 9792 9793 if (op0 == const0_rtx) 9794 { 9795 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1); 9796 } 9797 else 9798 { 9799 op0 = copy_to_mode_reg (mode0, op0); 9800 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1)); 9801 } 9802 9803 pat = GEN_FCN (icode) (target, addr); 9804 9805 if (! pat) 9806 return 0; 9807 emit_insn (pat); 9808 9809 return target; 9810} 9811 9812static rtx 9813spe_expand_stv_builtin (enum insn_code icode, tree exp) 9814{ 9815 tree arg0 = CALL_EXPR_ARG (exp, 0); 9816 tree arg1 = CALL_EXPR_ARG (exp, 1); 9817 tree arg2 = CALL_EXPR_ARG (exp, 2); 9818 rtx op0 = expand_normal (arg0); 9819 rtx op1 = expand_normal (arg1); 9820 rtx op2 = expand_normal (arg2); 9821 rtx pat; 9822 enum machine_mode mode0 = insn_data[icode].operand[0].mode; 9823 enum machine_mode mode1 = insn_data[icode].operand[1].mode; 9824 enum machine_mode mode2 = insn_data[icode].operand[2].mode; 9825 9826 /* Invalid arguments. Bail before doing anything stoopid! */ 9827 if (arg0 == error_mark_node 9828 || arg1 == error_mark_node 9829 || arg2 == error_mark_node) 9830 return const0_rtx; 9831 9832 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2)) 9833 op0 = copy_to_mode_reg (mode2, op0); 9834 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0)) 9835 op1 = copy_to_mode_reg (mode0, op1); 9836 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1)) 9837 op2 = copy_to_mode_reg (mode1, op2); 9838 9839 pat = GEN_FCN (icode) (op1, op2, op0); 9840 if (pat) 9841 emit_insn (pat); 9842 return NULL_RTX; 9843} 9844 9845static rtx 9846paired_expand_stv_builtin (enum insn_code icode, tree exp) 9847{ 9848 tree arg0 = CALL_EXPR_ARG (exp, 0); 9849 tree arg1 = CALL_EXPR_ARG (exp, 1); 9850 tree arg2 = CALL_EXPR_ARG (exp, 2); 9851 rtx op0 = expand_normal (arg0); 9852 rtx op1 = expand_normal (arg1); 9853 rtx op2 = expand_normal (arg2); 9854 rtx pat, addr; 9855 enum machine_mode tmode = insn_data[icode].operand[0].mode; 9856 enum machine_mode mode1 = Pmode; 9857 enum machine_mode mode2 = Pmode; 9858 9859 /* Invalid arguments. Bail before doing anything stoopid! */ 9860 if (arg0 == error_mark_node 9861 || arg1 == error_mark_node 9862 || arg2 == error_mark_node) 9863 return const0_rtx; 9864 9865 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode)) 9866 op0 = copy_to_mode_reg (tmode, op0); 9867 9868 op2 = copy_to_mode_reg (mode2, op2); 9869 9870 if (op1 == const0_rtx) 9871 { 9872 addr = gen_rtx_MEM (tmode, op2); 9873 } 9874 else 9875 { 9876 op1 = copy_to_mode_reg (mode1, op1); 9877 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2)); 9878 } 9879 9880 pat = GEN_FCN (icode) (addr, op0); 9881 if (pat) 9882 emit_insn (pat); 9883 return NULL_RTX; 9884} 9885 9886static rtx 9887altivec_expand_stv_builtin (enum insn_code icode, tree exp) 9888{ 9889 tree arg0 = CALL_EXPR_ARG (exp, 0); 9890 tree arg1 = CALL_EXPR_ARG (exp, 1); 9891 tree arg2 = CALL_EXPR_ARG (exp, 2); 9892 rtx op0 = expand_normal (arg0); 9893 rtx op1 = expand_normal (arg1); 9894 rtx op2 = expand_normal (arg2); 9895 rtx pat, addr; 9896 enum machine_mode tmode = insn_data[icode].operand[0].mode; 9897 enum machine_mode smode = insn_data[icode].operand[1].mode; 9898 enum machine_mode mode1 = Pmode; 9899 enum machine_mode mode2 = Pmode; 9900 9901 /* Invalid arguments. Bail before doing anything stoopid! */ 9902 if (arg0 == error_mark_node 9903 || arg1 == error_mark_node 9904 || arg2 == error_mark_node) 9905 return const0_rtx; 9906 9907 if (! (*insn_data[icode].operand[1].predicate) (op0, smode)) 9908 op0 = copy_to_mode_reg (smode, op0); 9909 9910 op2 = copy_to_mode_reg (mode2, op2); 9911 9912 if (op1 == const0_rtx) 9913 { 9914 addr = gen_rtx_MEM (tmode, op2); 9915 } 9916 else 9917 { 9918 op1 = copy_to_mode_reg (mode1, op1); 9919 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2)); 9920 } 9921 9922 pat = GEN_FCN (icode) (addr, op0); 9923 if (pat) 9924 emit_insn (pat); 9925 return NULL_RTX; 9926} 9927 9928static rtx 9929rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target) 9930{ 9931 rtx pat; 9932 tree arg0 = CALL_EXPR_ARG (exp, 0); 9933 tree arg1 = CALL_EXPR_ARG (exp, 1); 9934 tree arg2 = CALL_EXPR_ARG (exp, 2); 9935 rtx op0 = expand_normal (arg0); 9936 rtx op1 = expand_normal (arg1); 9937 rtx op2 = expand_normal (arg2); 9938 enum machine_mode tmode = insn_data[icode].operand[0].mode; 9939 enum machine_mode mode0 = insn_data[icode].operand[1].mode; 9940 enum machine_mode mode1 = insn_data[icode].operand[2].mode; 9941 enum machine_mode mode2 = insn_data[icode].operand[3].mode; 9942 9943 if (icode == CODE_FOR_nothing) 9944 /* Builtin not supported on this processor. */ 9945 return 0; 9946 9947 /* If we got invalid arguments bail out before generating bad rtl. */ 9948 if (arg0 == error_mark_node 9949 || arg1 == error_mark_node 9950 || arg2 == error_mark_node) 9951 return const0_rtx; 9952 9953 /* Check and prepare argument depending on the instruction code. 9954 9955 Note that a switch statement instead of the sequence of tests 9956 would be incorrect as many of the CODE_FOR values could be 9957 CODE_FOR_nothing and that would yield multiple alternatives 9958 with identical values. We'd never reach here at runtime in 9959 this case. */ 9960 if (icode == CODE_FOR_altivec_vsldoi_v4sf 9961 || icode == CODE_FOR_altivec_vsldoi_v4si 9962 || icode == CODE_FOR_altivec_vsldoi_v8hi 9963 || icode == CODE_FOR_altivec_vsldoi_v16qi) 9964 { 9965 /* Only allow 4-bit unsigned literals. */ 9966 STRIP_NOPS (arg2); 9967 if (TREE_CODE (arg2) != INTEGER_CST 9968 || TREE_INT_CST_LOW (arg2) & ~0xf) 9969 { 9970 error ("argument 3 must be a 4-bit unsigned literal"); 9971 return const0_rtx; 9972 } 9973 } 9974 else if (icode == CODE_FOR_vsx_xxpermdi_v2df 9975 || icode == CODE_FOR_vsx_xxpermdi_v2di 9976 || icode == CODE_FOR_vsx_xxsldwi_v16qi 9977 || icode == CODE_FOR_vsx_xxsldwi_v8hi 9978 || icode == CODE_FOR_vsx_xxsldwi_v4si 9979 || icode == CODE_FOR_vsx_xxsldwi_v4sf 9980 || icode == CODE_FOR_vsx_xxsldwi_v2di 9981 || icode == CODE_FOR_vsx_xxsldwi_v2df) 9982 { 9983 /* Only allow 2-bit unsigned literals. */ 9984 STRIP_NOPS (arg2); 9985 if (TREE_CODE (arg2) != INTEGER_CST 9986 || TREE_INT_CST_LOW (arg2) & ~0x3) 9987 { 9988 error ("argument 3 must be a 2-bit unsigned literal"); 9989 return const0_rtx; 9990 } 9991 } 9992 else if (icode == CODE_FOR_vsx_set_v2df 9993 || icode == CODE_FOR_vsx_set_v2di) 9994 { 9995 /* Only allow 1-bit unsigned literals. */ 9996 STRIP_NOPS (arg2); 9997 if (TREE_CODE (arg2) != INTEGER_CST 9998 || TREE_INT_CST_LOW (arg2) & ~0x1) 9999 { 10000 error ("argument 3 must be a 1-bit unsigned literal"); 10001 return const0_rtx; 10002 } 10003 } 10004 10005 if (target == 0 10006 || GET_MODE (target) != tmode 10007 || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) 10008 target = gen_reg_rtx (tmode); 10009 10010 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) 10011 op0 = copy_to_mode_reg (mode0, op0); 10012 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1)) 10013 op1 = copy_to_mode_reg (mode1, op1); 10014 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2)) 10015 op2 = copy_to_mode_reg (mode2, op2); 10016 10017 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4) 10018 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode)); 10019 else 10020 pat = GEN_FCN (icode) (target, op0, op1, op2); 10021 if (! pat) 10022 return 0; 10023 emit_insn (pat); 10024 10025 return target; 10026} 10027 10028/* Expand the lvx builtins. */ 10029static rtx 10030altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp) 10031{ 10032 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 10033 unsigned int fcode = DECL_FUNCTION_CODE (fndecl); 10034 tree arg0; 10035 enum machine_mode tmode, mode0; 10036 rtx pat, op0; 10037 enum insn_code icode; 10038 10039 switch (fcode) 10040 { 10041 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi: 10042 icode = CODE_FOR_vector_altivec_load_v16qi; 10043 break; 10044 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi: 10045 icode = CODE_FOR_vector_altivec_load_v8hi; 10046 break; 10047 case ALTIVEC_BUILTIN_LD_INTERNAL_4si: 10048 icode = CODE_FOR_vector_altivec_load_v4si; 10049 break; 10050 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf: 10051 icode = CODE_FOR_vector_altivec_load_v4sf; 10052 break; 10053 case ALTIVEC_BUILTIN_LD_INTERNAL_2df: 10054 icode = CODE_FOR_vector_altivec_load_v2df; 10055 break; 10056 case ALTIVEC_BUILTIN_LD_INTERNAL_2di: 10057 icode = CODE_FOR_vector_altivec_load_v2di; 10058 break; 10059 default: 10060 *expandedp = false; 10061 return NULL_RTX; 10062 } 10063 10064 *expandedp = true; 10065 10066 arg0 = CALL_EXPR_ARG (exp, 0); 10067 op0 = expand_normal (arg0); 10068 tmode = insn_data[icode].operand[0].mode; 10069 mode0 = insn_data[icode].operand[1].mode; 10070 10071 if (target == 0 10072 || GET_MODE (target) != tmode 10073 || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) 10074 target = gen_reg_rtx (tmode); 10075 10076 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) 10077 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0)); 10078 10079 pat = GEN_FCN (icode) (target, op0); 10080 if (! pat) 10081 return 0; 10082 emit_insn (pat); 10083 return target; 10084} 10085 10086/* Expand the stvx builtins. */ 10087static rtx 10088altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED, 10089 bool *expandedp) 10090{ 10091 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 10092 unsigned int fcode = DECL_FUNCTION_CODE (fndecl); 10093 tree arg0, arg1; 10094 enum machine_mode mode0, mode1; 10095 rtx pat, op0, op1; 10096 enum insn_code icode; 10097 10098 switch (fcode) 10099 { 10100 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi: 10101 icode = CODE_FOR_vector_altivec_store_v16qi; 10102 break; 10103 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi: 10104 icode = CODE_FOR_vector_altivec_store_v8hi; 10105 break; 10106 case ALTIVEC_BUILTIN_ST_INTERNAL_4si: 10107 icode = CODE_FOR_vector_altivec_store_v4si; 10108 break; 10109 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf: 10110 icode = CODE_FOR_vector_altivec_store_v4sf; 10111 break; 10112 case ALTIVEC_BUILTIN_ST_INTERNAL_2df: 10113 icode = CODE_FOR_vector_altivec_store_v2df; 10114 break; 10115 case ALTIVEC_BUILTIN_ST_INTERNAL_2di: 10116 icode = CODE_FOR_vector_altivec_store_v2di; 10117 break; 10118 default: 10119 *expandedp = false; 10120 return NULL_RTX; 10121 } 10122 10123 arg0 = CALL_EXPR_ARG (exp, 0); 10124 arg1 = CALL_EXPR_ARG (exp, 1); 10125 op0 = expand_normal (arg0); 10126 op1 = expand_normal (arg1); 10127 mode0 = insn_data[icode].operand[0].mode; 10128 mode1 = insn_data[icode].operand[1].mode; 10129 10130 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0)) 10131 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0)); 10132 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1)) 10133 op1 = copy_to_mode_reg (mode1, op1); 10134 10135 pat = GEN_FCN (icode) (op0, op1); 10136 if (pat) 10137 emit_insn (pat); 10138 10139 *expandedp = true; 10140 return NULL_RTX; 10141} 10142 10143/* Expand the dst builtins. */ 10144static rtx 10145altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED, 10146 bool *expandedp) 10147{ 10148 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 10149 unsigned int fcode = DECL_FUNCTION_CODE (fndecl); 10150 tree arg0, arg1, arg2; 10151 enum machine_mode mode0, mode1, mode2; 10152 rtx pat, op0, op1, op2; 10153 const struct builtin_description *d; 10154 size_t i; 10155 10156 *expandedp = false; 10157 10158 /* Handle DST variants. */ 10159 d = bdesc_dst; 10160 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++) 10161 if (d->code == fcode) 10162 { 10163 arg0 = CALL_EXPR_ARG (exp, 0); 10164 arg1 = CALL_EXPR_ARG (exp, 1); 10165 arg2 = CALL_EXPR_ARG (exp, 2); 10166 op0 = expand_normal (arg0); 10167 op1 = expand_normal (arg1); 10168 op2 = expand_normal (arg2); 10169 mode0 = insn_data[d->icode].operand[0].mode; 10170 mode1 = insn_data[d->icode].operand[1].mode; 10171 mode2 = insn_data[d->icode].operand[2].mode; 10172 10173 /* Invalid arguments, bail out before generating bad rtl. */ 10174 if (arg0 == error_mark_node 10175 || arg1 == error_mark_node 10176 || arg2 == error_mark_node) 10177 return const0_rtx; 10178 10179 *expandedp = true; 10180 STRIP_NOPS (arg2); 10181 if (TREE_CODE (arg2) != INTEGER_CST 10182 || TREE_INT_CST_LOW (arg2) & ~0x3) 10183 { 10184 error ("argument to %qs must be a 2-bit unsigned literal", d->name); 10185 return const0_rtx; 10186 } 10187 10188 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0)) 10189 op0 = copy_to_mode_reg (Pmode, op0); 10190 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1)) 10191 op1 = copy_to_mode_reg (mode1, op1); 10192 10193 pat = GEN_FCN (d->icode) (op0, op1, op2); 10194 if (pat != 0) 10195 emit_insn (pat); 10196 10197 return NULL_RTX; 10198 } 10199 10200 return NULL_RTX; 10201} 10202 10203/* Expand vec_init builtin. */ 10204static rtx 10205altivec_expand_vec_init_builtin (tree type, tree exp, rtx target) 10206{ 10207 enum machine_mode tmode = TYPE_MODE (type); 10208 enum machine_mode inner_mode = GET_MODE_INNER (tmode); 10209 int i, n_elt = GET_MODE_NUNITS (tmode); 10210 rtvec v = rtvec_alloc (n_elt); 10211 10212 gcc_assert (VECTOR_MODE_P (tmode)); 10213 gcc_assert (n_elt == call_expr_nargs (exp)); 10214 10215 for (i = 0; i < n_elt; ++i) 10216 { 10217 rtx x = expand_normal (CALL_EXPR_ARG (exp, i)); 10218 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x); 10219 } 10220 10221 if (!target || !register_operand (target, tmode)) 10222 target = gen_reg_rtx (tmode); 10223 10224 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v)); 10225 return target; 10226} 10227 10228/* Return the integer constant in ARG. Constrain it to be in the range 10229 of the subparts of VEC_TYPE; issue an error if not. */ 10230 10231static int 10232get_element_number (tree vec_type, tree arg) 10233{ 10234 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1; 10235 10236 if (!host_integerp (arg, 1) 10237 || (elt = tree_low_cst (arg, 1), elt > max)) 10238 { 10239 error ("selector must be an integer constant in the range 0..%wi", max); 10240 return 0; 10241 } 10242 10243 return elt; 10244} 10245 10246/* Expand vec_set builtin. */ 10247static rtx 10248altivec_expand_vec_set_builtin (tree exp) 10249{ 10250 enum machine_mode tmode, mode1; 10251 tree arg0, arg1, arg2; 10252 int elt; 10253 rtx op0, op1; 10254 10255 arg0 = CALL_EXPR_ARG (exp, 0); 10256 arg1 = CALL_EXPR_ARG (exp, 1); 10257 arg2 = CALL_EXPR_ARG (exp, 2); 10258 10259 tmode = TYPE_MODE (TREE_TYPE (arg0)); 10260 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0))); 10261 gcc_assert (VECTOR_MODE_P (tmode)); 10262 10263 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL); 10264 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL); 10265 elt = get_element_number (TREE_TYPE (arg0), arg2); 10266 10267 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode) 10268 op1 = convert_modes (mode1, GET_MODE (op1), op1, true); 10269 10270 op0 = force_reg (tmode, op0); 10271 op1 = force_reg (mode1, op1); 10272 10273 rs6000_expand_vector_set (op0, op1, elt); 10274 10275 return op0; 10276} 10277 10278/* Expand vec_ext builtin. */ 10279static rtx 10280altivec_expand_vec_ext_builtin (tree exp, rtx target) 10281{ 10282 enum machine_mode tmode, mode0; 10283 tree arg0, arg1; 10284 int elt; 10285 rtx op0; 10286 10287 arg0 = CALL_EXPR_ARG (exp, 0); 10288 arg1 = CALL_EXPR_ARG (exp, 1); 10289 10290 op0 = expand_normal (arg0); 10291 elt = get_element_number (TREE_TYPE (arg0), arg1); 10292 10293 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0))); 10294 mode0 = TYPE_MODE (TREE_TYPE (arg0)); 10295 gcc_assert (VECTOR_MODE_P (mode0)); 10296 10297 op0 = force_reg (mode0, op0); 10298 10299 if (optimize || !target || !register_operand (target, tmode)) 10300 target = gen_reg_rtx (tmode); 10301 10302 rs6000_expand_vector_extract (target, op0, elt); 10303 10304 return target; 10305} 10306 10307/* Expand the builtin in EXP and store the result in TARGET. Store 10308 true in *EXPANDEDP if we found a builtin to expand. */ 10309static rtx 10310altivec_expand_builtin (tree exp, rtx target, bool *expandedp) 10311{ 10312 const struct builtin_description *d; 10313 const struct builtin_description_predicates *dp; 10314 size_t i; 10315 enum insn_code icode; 10316 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 10317 tree arg0; 10318 rtx op0, pat; 10319 enum machine_mode tmode, mode0; 10320 unsigned int fcode = DECL_FUNCTION_CODE (fndecl); 10321 10322 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST 10323 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST) 10324 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST 10325 && fcode <= VSX_BUILTIN_OVERLOADED_LAST)) 10326 { 10327 *expandedp = true; 10328 error ("unresolved overload for Altivec builtin %qF", fndecl); 10329 return const0_rtx; 10330 } 10331 10332 target = altivec_expand_ld_builtin (exp, target, expandedp); 10333 if (*expandedp) 10334 return target; 10335 10336 target = altivec_expand_st_builtin (exp, target, expandedp); 10337 if (*expandedp) 10338 return target; 10339 10340 target = altivec_expand_dst_builtin (exp, target, expandedp); 10341 if (*expandedp) 10342 return target; 10343 10344 *expandedp = true; 10345 10346 switch (fcode) 10347 { 10348 case ALTIVEC_BUILTIN_STVX: 10349 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si, exp); 10350 case ALTIVEC_BUILTIN_STVEBX: 10351 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp); 10352 case ALTIVEC_BUILTIN_STVEHX: 10353 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp); 10354 case ALTIVEC_BUILTIN_STVEWX: 10355 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp); 10356 case ALTIVEC_BUILTIN_STVXL: 10357 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp); 10358 10359 case ALTIVEC_BUILTIN_STVLX: 10360 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp); 10361 case ALTIVEC_BUILTIN_STVLXL: 10362 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp); 10363 case ALTIVEC_BUILTIN_STVRX: 10364 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp); 10365 case ALTIVEC_BUILTIN_STVRXL: 10366 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp); 10367 10368 case VSX_BUILTIN_STXVD2X_V2DF: 10369 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df, exp); 10370 case VSX_BUILTIN_STXVD2X_V2DI: 10371 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2di, exp); 10372 case VSX_BUILTIN_STXVW4X_V4SF: 10373 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4sf, exp); 10374 case VSX_BUILTIN_STXVW4X_V4SI: 10375 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4si, exp); 10376 case VSX_BUILTIN_STXVW4X_V8HI: 10377 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v8hi, exp); 10378 case VSX_BUILTIN_STXVW4X_V16QI: 10379 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi, exp); 10380 10381 case ALTIVEC_BUILTIN_MFVSCR: 10382 icode = CODE_FOR_altivec_mfvscr; 10383 tmode = insn_data[icode].operand[0].mode; 10384 10385 if (target == 0 10386 || GET_MODE (target) != tmode 10387 || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) 10388 target = gen_reg_rtx (tmode); 10389 10390 pat = GEN_FCN (icode) (target); 10391 if (! pat) 10392 return 0; 10393 emit_insn (pat); 10394 return target; 10395 10396 case ALTIVEC_BUILTIN_MTVSCR: 10397 icode = CODE_FOR_altivec_mtvscr; 10398 arg0 = CALL_EXPR_ARG (exp, 0); 10399 op0 = expand_normal (arg0); 10400 mode0 = insn_data[icode].operand[0].mode; 10401 10402 /* If we got invalid arguments bail out before generating bad rtl. */ 10403 if (arg0 == error_mark_node) 10404 return const0_rtx; 10405 10406 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0)) 10407 op0 = copy_to_mode_reg (mode0, op0); 10408 10409 pat = GEN_FCN (icode) (op0); 10410 if (pat) 10411 emit_insn (pat); 10412 return NULL_RTX; 10413 10414 case ALTIVEC_BUILTIN_DSSALL: 10415 emit_insn (gen_altivec_dssall ()); 10416 return NULL_RTX; 10417 10418 case ALTIVEC_BUILTIN_DSS: 10419 icode = CODE_FOR_altivec_dss; 10420 arg0 = CALL_EXPR_ARG (exp, 0); 10421 STRIP_NOPS (arg0); 10422 op0 = expand_normal (arg0); 10423 mode0 = insn_data[icode].operand[0].mode; 10424 10425 /* If we got invalid arguments bail out before generating bad rtl. */ 10426 if (arg0 == error_mark_node) 10427 return const0_rtx; 10428 10429 if (TREE_CODE (arg0) != INTEGER_CST 10430 || TREE_INT_CST_LOW (arg0) & ~0x3) 10431 { 10432 error ("argument to dss must be a 2-bit unsigned literal"); 10433 return const0_rtx; 10434 } 10435 10436 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0)) 10437 op0 = copy_to_mode_reg (mode0, op0); 10438 10439 emit_insn (gen_altivec_dss (op0)); 10440 return NULL_RTX; 10441 10442 case ALTIVEC_BUILTIN_VEC_INIT_V4SI: 10443 case ALTIVEC_BUILTIN_VEC_INIT_V8HI: 10444 case ALTIVEC_BUILTIN_VEC_INIT_V16QI: 10445 case ALTIVEC_BUILTIN_VEC_INIT_V4SF: 10446 case VSX_BUILTIN_VEC_INIT_V2DF: 10447 case VSX_BUILTIN_VEC_INIT_V2DI: 10448 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target); 10449 10450 case ALTIVEC_BUILTIN_VEC_SET_V4SI: 10451 case ALTIVEC_BUILTIN_VEC_SET_V8HI: 10452 case ALTIVEC_BUILTIN_VEC_SET_V16QI: 10453 case ALTIVEC_BUILTIN_VEC_SET_V4SF: 10454 case VSX_BUILTIN_VEC_SET_V2DF: 10455 case VSX_BUILTIN_VEC_SET_V2DI: 10456 return altivec_expand_vec_set_builtin (exp); 10457 10458 case ALTIVEC_BUILTIN_VEC_EXT_V4SI: 10459 case ALTIVEC_BUILTIN_VEC_EXT_V8HI: 10460 case ALTIVEC_BUILTIN_VEC_EXT_V16QI: 10461 case ALTIVEC_BUILTIN_VEC_EXT_V4SF: 10462 case VSX_BUILTIN_VEC_EXT_V2DF: 10463 case VSX_BUILTIN_VEC_EXT_V2DI: 10464 return altivec_expand_vec_ext_builtin (exp, target); 10465 10466 default: 10467 break; 10468 /* Fall through. */ 10469 } 10470 10471 /* Expand abs* operations. */ 10472 d = bdesc_abs; 10473 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++) 10474 if (d->code == fcode) 10475 return altivec_expand_abs_builtin (d->icode, exp, target); 10476 10477 /* Expand the AltiVec predicates. */ 10478 dp = bdesc_altivec_preds; 10479 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++) 10480 if (dp->code == fcode) 10481 return altivec_expand_predicate_builtin (dp->icode, exp, target); 10482 10483 /* LV* are funky. We initialized them differently. */ 10484 switch (fcode) 10485 { 10486 case ALTIVEC_BUILTIN_LVSL: 10487 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl, 10488 exp, target, false); 10489 case ALTIVEC_BUILTIN_LVSR: 10490 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr, 10491 exp, target, false); 10492 case ALTIVEC_BUILTIN_LVEBX: 10493 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx, 10494 exp, target, false); 10495 case ALTIVEC_BUILTIN_LVEHX: 10496 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx, 10497 exp, target, false); 10498 case ALTIVEC_BUILTIN_LVEWX: 10499 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx, 10500 exp, target, false); 10501 case ALTIVEC_BUILTIN_LVXL: 10502 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl, 10503 exp, target, false); 10504 case ALTIVEC_BUILTIN_LVX: 10505 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si, 10506 exp, target, false); 10507 case ALTIVEC_BUILTIN_LVLX: 10508 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx, 10509 exp, target, true); 10510 case ALTIVEC_BUILTIN_LVLXL: 10511 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl, 10512 exp, target, true); 10513 case ALTIVEC_BUILTIN_LVRX: 10514 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx, 10515 exp, target, true); 10516 case ALTIVEC_BUILTIN_LVRXL: 10517 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl, 10518 exp, target, true); 10519 case VSX_BUILTIN_LXVD2X_V2DF: 10520 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df, 10521 exp, target, false); 10522 case VSX_BUILTIN_LXVD2X_V2DI: 10523 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2di, 10524 exp, target, false); 10525 case VSX_BUILTIN_LXVW4X_V4SF: 10526 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4sf, 10527 exp, target, false); 10528 case VSX_BUILTIN_LXVW4X_V4SI: 10529 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4si, 10530 exp, target, false); 10531 case VSX_BUILTIN_LXVW4X_V8HI: 10532 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v8hi, 10533 exp, target, false); 10534 case VSX_BUILTIN_LXVW4X_V16QI: 10535 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi, 10536 exp, target, false); 10537 break; 10538 default: 10539 break; 10540 /* Fall through. */ 10541 } 10542 10543 *expandedp = false; 10544 return NULL_RTX; 10545} 10546 10547/* Expand the builtin in EXP and store the result in TARGET. Store 10548 true in *EXPANDEDP if we found a builtin to expand. */ 10549static rtx 10550paired_expand_builtin (tree exp, rtx target, bool * expandedp) 10551{ 10552 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 10553 unsigned int fcode = DECL_FUNCTION_CODE (fndecl); 10554 const struct builtin_description *d; 10555 size_t i; 10556 10557 *expandedp = true; 10558 10559 switch (fcode) 10560 { 10561 case PAIRED_BUILTIN_STX: 10562 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp); 10563 case PAIRED_BUILTIN_LX: 10564 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target); 10565 default: 10566 break; 10567 /* Fall through. */ 10568 } 10569 10570 /* Expand the paired predicates. */ 10571 d = bdesc_paired_preds; 10572 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++) 10573 if (d->code == fcode) 10574 return paired_expand_predicate_builtin (d->icode, exp, target); 10575 10576 *expandedp = false; 10577 return NULL_RTX; 10578} 10579 10580/* Binops that need to be initialized manually, but can be expanded 10581 automagically by rs6000_expand_binop_builtin. */ 10582static struct builtin_description bdesc_2arg_spe[] = 10583{ 10584 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX }, 10585 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX }, 10586 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX }, 10587 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX }, 10588 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX }, 10589 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX }, 10590 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX }, 10591 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX }, 10592 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX }, 10593 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX }, 10594 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX }, 10595 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD }, 10596 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW }, 10597 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH }, 10598 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE }, 10599 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU }, 10600 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS }, 10601 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT }, 10602 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT }, 10603 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT }, 10604 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT }, 10605 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT } 10606}; 10607 10608/* Expand the builtin in EXP and store the result in TARGET. Store 10609 true in *EXPANDEDP if we found a builtin to expand. 10610 10611 This expands the SPE builtins that are not simple unary and binary 10612 operations. */ 10613static rtx 10614spe_expand_builtin (tree exp, rtx target, bool *expandedp) 10615{ 10616 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 10617 tree arg1, arg0; 10618 unsigned int fcode = DECL_FUNCTION_CODE (fndecl); 10619 enum insn_code icode; 10620 enum machine_mode tmode, mode0; 10621 rtx pat, op0; 10622 struct builtin_description *d; 10623 size_t i; 10624 10625 *expandedp = true; 10626 10627 /* Syntax check for a 5-bit unsigned immediate. */ 10628 switch (fcode) 10629 { 10630 case SPE_BUILTIN_EVSTDD: 10631 case SPE_BUILTIN_EVSTDH: 10632 case SPE_BUILTIN_EVSTDW: 10633 case SPE_BUILTIN_EVSTWHE: 10634 case SPE_BUILTIN_EVSTWHO: 10635 case SPE_BUILTIN_EVSTWWE: 10636 case SPE_BUILTIN_EVSTWWO: 10637 arg1 = CALL_EXPR_ARG (exp, 2); 10638 if (TREE_CODE (arg1) != INTEGER_CST 10639 || TREE_INT_CST_LOW (arg1) & ~0x1f) 10640 { 10641 error ("argument 2 must be a 5-bit unsigned literal"); 10642 return const0_rtx; 10643 } 10644 break; 10645 default: 10646 break; 10647 } 10648 10649 /* The evsplat*i instructions are not quite generic. */ 10650 switch (fcode) 10651 { 10652 case SPE_BUILTIN_EVSPLATFI: 10653 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi, 10654 exp, target); 10655 case SPE_BUILTIN_EVSPLATI: 10656 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati, 10657 exp, target); 10658 default: 10659 break; 10660 } 10661 10662 d = (struct builtin_description *) bdesc_2arg_spe; 10663 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d) 10664 if (d->code == fcode) 10665 return rs6000_expand_binop_builtin (d->icode, exp, target); 10666 10667 d = (struct builtin_description *) bdesc_spe_predicates; 10668 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d) 10669 if (d->code == fcode) 10670 return spe_expand_predicate_builtin (d->icode, exp, target); 10671 10672 d = (struct builtin_description *) bdesc_spe_evsel; 10673 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d) 10674 if (d->code == fcode) 10675 return spe_expand_evsel_builtin (d->icode, exp, target); 10676 10677 switch (fcode) 10678 { 10679 case SPE_BUILTIN_EVSTDDX: 10680 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp); 10681 case SPE_BUILTIN_EVSTDHX: 10682 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp); 10683 case SPE_BUILTIN_EVSTDWX: 10684 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp); 10685 case SPE_BUILTIN_EVSTWHEX: 10686 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp); 10687 case SPE_BUILTIN_EVSTWHOX: 10688 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp); 10689 case SPE_BUILTIN_EVSTWWEX: 10690 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp); 10691 case SPE_BUILTIN_EVSTWWOX: 10692 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp); 10693 case SPE_BUILTIN_EVSTDD: 10694 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp); 10695 case SPE_BUILTIN_EVSTDH: 10696 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp); 10697 case SPE_BUILTIN_EVSTDW: 10698 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp); 10699 case SPE_BUILTIN_EVSTWHE: 10700 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp); 10701 case SPE_BUILTIN_EVSTWHO: 10702 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp); 10703 case SPE_BUILTIN_EVSTWWE: 10704 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp); 10705 case SPE_BUILTIN_EVSTWWO: 10706 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp); 10707 case SPE_BUILTIN_MFSPEFSCR: 10708 icode = CODE_FOR_spe_mfspefscr; 10709 tmode = insn_data[icode].operand[0].mode; 10710 10711 if (target == 0 10712 || GET_MODE (target) != tmode 10713 || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) 10714 target = gen_reg_rtx (tmode); 10715 10716 pat = GEN_FCN (icode) (target); 10717 if (! pat) 10718 return 0; 10719 emit_insn (pat); 10720 return target; 10721 case SPE_BUILTIN_MTSPEFSCR: 10722 icode = CODE_FOR_spe_mtspefscr; 10723 arg0 = CALL_EXPR_ARG (exp, 0); 10724 op0 = expand_normal (arg0); 10725 mode0 = insn_data[icode].operand[0].mode; 10726 10727 if (arg0 == error_mark_node) 10728 return const0_rtx; 10729 10730 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0)) 10731 op0 = copy_to_mode_reg (mode0, op0); 10732 10733 pat = GEN_FCN (icode) (op0); 10734 if (pat) 10735 emit_insn (pat); 10736 return NULL_RTX; 10737 default: 10738 break; 10739 } 10740 10741 *expandedp = false; 10742 return NULL_RTX; 10743} 10744 10745static rtx 10746paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target) 10747{ 10748 rtx pat, scratch, tmp; 10749 tree form = CALL_EXPR_ARG (exp, 0); 10750 tree arg0 = CALL_EXPR_ARG (exp, 1); 10751 tree arg1 = CALL_EXPR_ARG (exp, 2); 10752 rtx op0 = expand_normal (arg0); 10753 rtx op1 = expand_normal (arg1); 10754 enum machine_mode mode0 = insn_data[icode].operand[1].mode; 10755 enum machine_mode mode1 = insn_data[icode].operand[2].mode; 10756 int form_int; 10757 enum rtx_code code; 10758 10759 if (TREE_CODE (form) != INTEGER_CST) 10760 { 10761 error ("argument 1 of __builtin_paired_predicate must be a constant"); 10762 return const0_rtx; 10763 } 10764 else 10765 form_int = TREE_INT_CST_LOW (form); 10766 10767 gcc_assert (mode0 == mode1); 10768 10769 if (arg0 == error_mark_node || arg1 == error_mark_node) 10770 return const0_rtx; 10771 10772 if (target == 0 10773 || GET_MODE (target) != SImode 10774 || !(*insn_data[icode].operand[0].predicate) (target, SImode)) 10775 target = gen_reg_rtx (SImode); 10776 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0)) 10777 op0 = copy_to_mode_reg (mode0, op0); 10778 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1)) 10779 op1 = copy_to_mode_reg (mode1, op1); 10780 10781 scratch = gen_reg_rtx (CCFPmode); 10782 10783 pat = GEN_FCN (icode) (scratch, op0, op1); 10784 if (!pat) 10785 return const0_rtx; 10786 10787 emit_insn (pat); 10788 10789 switch (form_int) 10790 { 10791 /* LT bit. */ 10792 case 0: 10793 code = LT; 10794 break; 10795 /* GT bit. */ 10796 case 1: 10797 code = GT; 10798 break; 10799 /* EQ bit. */ 10800 case 2: 10801 code = EQ; 10802 break; 10803 /* UN bit. */ 10804 case 3: 10805 emit_insn (gen_move_from_CR_ov_bit (target, scratch)); 10806 return target; 10807 default: 10808 error ("argument 1 of __builtin_paired_predicate is out of range"); 10809 return const0_rtx; 10810 } 10811 10812 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx); 10813 emit_move_insn (target, tmp); 10814 return target; 10815} 10816 10817static rtx 10818spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target) 10819{ 10820 rtx pat, scratch, tmp; 10821 tree form = CALL_EXPR_ARG (exp, 0); 10822 tree arg0 = CALL_EXPR_ARG (exp, 1); 10823 tree arg1 = CALL_EXPR_ARG (exp, 2); 10824 rtx op0 = expand_normal (arg0); 10825 rtx op1 = expand_normal (arg1); 10826 enum machine_mode mode0 = insn_data[icode].operand[1].mode; 10827 enum machine_mode mode1 = insn_data[icode].operand[2].mode; 10828 int form_int; 10829 enum rtx_code code; 10830 10831 if (TREE_CODE (form) != INTEGER_CST) 10832 { 10833 error ("argument 1 of __builtin_spe_predicate must be a constant"); 10834 return const0_rtx; 10835 } 10836 else 10837 form_int = TREE_INT_CST_LOW (form); 10838 10839 gcc_assert (mode0 == mode1); 10840 10841 if (arg0 == error_mark_node || arg1 == error_mark_node) 10842 return const0_rtx; 10843 10844 if (target == 0 10845 || GET_MODE (target) != SImode 10846 || ! (*insn_data[icode].operand[0].predicate) (target, SImode)) 10847 target = gen_reg_rtx (SImode); 10848 10849 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) 10850 op0 = copy_to_mode_reg (mode0, op0); 10851 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1)) 10852 op1 = copy_to_mode_reg (mode1, op1); 10853 10854 scratch = gen_reg_rtx (CCmode); 10855 10856 pat = GEN_FCN (icode) (scratch, op0, op1); 10857 if (! pat) 10858 return const0_rtx; 10859 emit_insn (pat); 10860 10861 /* There are 4 variants for each predicate: _any_, _all_, _upper_, 10862 _lower_. We use one compare, but look in different bits of the 10863 CR for each variant. 10864 10865 There are 2 elements in each SPE simd type (upper/lower). The CR 10866 bits are set as follows: 10867 10868 BIT0 | BIT 1 | BIT 2 | BIT 3 10869 U | L | (U | L) | (U & L) 10870 10871 So, for an "all" relationship, BIT 3 would be set. 10872 For an "any" relationship, BIT 2 would be set. Etc. 10873 10874 Following traditional nomenclature, these bits map to: 10875 10876 BIT0 | BIT 1 | BIT 2 | BIT 3 10877 LT | GT | EQ | OV 10878 10879 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits. 10880 */ 10881 10882 switch (form_int) 10883 { 10884 /* All variant. OV bit. */ 10885 case 0: 10886 /* We need to get to the OV bit, which is the ORDERED bit. We 10887 could generate (ordered:SI (reg:CC xx) (const_int 0)), but 10888 that's ugly and will make validate_condition_mode die. 10889 So let's just use another pattern. */ 10890 emit_insn (gen_move_from_CR_ov_bit (target, scratch)); 10891 return target; 10892 /* Any variant. EQ bit. */ 10893 case 1: 10894 code = EQ; 10895 break; 10896 /* Upper variant. LT bit. */ 10897 case 2: 10898 code = LT; 10899 break; 10900 /* Lower variant. GT bit. */ 10901 case 3: 10902 code = GT; 10903 break; 10904 default: 10905 error ("argument 1 of __builtin_spe_predicate is out of range"); 10906 return const0_rtx; 10907 } 10908 10909 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx); 10910 emit_move_insn (target, tmp); 10911 10912 return target; 10913} 10914 10915/* The evsel builtins look like this: 10916 10917 e = __builtin_spe_evsel_OP (a, b, c, d); 10918 10919 and work like this: 10920 10921 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper]; 10922 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower]; 10923*/ 10924 10925static rtx 10926spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target) 10927{ 10928 rtx pat, scratch; 10929 tree arg0 = CALL_EXPR_ARG (exp, 0); 10930 tree arg1 = CALL_EXPR_ARG (exp, 1); 10931 tree arg2 = CALL_EXPR_ARG (exp, 2); 10932 tree arg3 = CALL_EXPR_ARG (exp, 3); 10933 rtx op0 = expand_normal (arg0); 10934 rtx op1 = expand_normal (arg1); 10935 rtx op2 = expand_normal (arg2); 10936 rtx op3 = expand_normal (arg3); 10937 enum machine_mode mode0 = insn_data[icode].operand[1].mode; 10938 enum machine_mode mode1 = insn_data[icode].operand[2].mode; 10939 10940 gcc_assert (mode0 == mode1); 10941 10942 if (arg0 == error_mark_node || arg1 == error_mark_node 10943 || arg2 == error_mark_node || arg3 == error_mark_node) 10944 return const0_rtx; 10945 10946 if (target == 0 10947 || GET_MODE (target) != mode0 10948 || ! (*insn_data[icode].operand[0].predicate) (target, mode0)) 10949 target = gen_reg_rtx (mode0); 10950 10951 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) 10952 op0 = copy_to_mode_reg (mode0, op0); 10953 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1)) 10954 op1 = copy_to_mode_reg (mode0, op1); 10955 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1)) 10956 op2 = copy_to_mode_reg (mode0, op2); 10957 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1)) 10958 op3 = copy_to_mode_reg (mode0, op3); 10959 10960 /* Generate the compare. */ 10961 scratch = gen_reg_rtx (CCmode); 10962 pat = GEN_FCN (icode) (scratch, op0, op1); 10963 if (! pat) 10964 return const0_rtx; 10965 emit_insn (pat); 10966 10967 if (mode0 == V2SImode) 10968 emit_insn (gen_spe_evsel (target, op2, op3, scratch)); 10969 else 10970 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch)); 10971 10972 return target; 10973} 10974 10975/* Expand an expression EXP that calls a built-in function, 10976 with result going to TARGET if that's convenient 10977 (and in mode MODE if that's convenient). 10978 SUBTARGET may be used as the target for computing one of EXP's operands. 10979 IGNORE is nonzero if the value is to be ignored. */ 10980 10981static rtx 10982rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, 10983 enum machine_mode mode ATTRIBUTE_UNUSED, 10984 int ignore ATTRIBUTE_UNUSED) 10985{ 10986 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 10987 unsigned int fcode = DECL_FUNCTION_CODE (fndecl); 10988 const struct builtin_description *d; 10989 size_t i; 10990 rtx ret; 10991 bool success; 10992 10993 if (fcode == RS6000_BUILTIN_RECIP) 10994 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target); 10995 10996 if (fcode == RS6000_BUILTIN_RECIPF) 10997 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target); 10998 10999 if (fcode == RS6000_BUILTIN_RSQRTF) 11000 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target); 11001 11002 if (fcode == RS6000_BUILTIN_BSWAP_HI) 11003 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target); 11004 11005 if (fcode == POWER7_BUILTIN_BPERMD) 11006 return rs6000_expand_binop_builtin (((TARGET_64BIT) 11007 ? CODE_FOR_bpermd_di 11008 : CODE_FOR_bpermd_si), exp, target); 11009 11010 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD 11011 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE) 11012 { 11013 int icode = (int) CODE_FOR_altivec_lvsr; 11014 enum machine_mode tmode = insn_data[icode].operand[0].mode; 11015 enum machine_mode mode = insn_data[icode].operand[1].mode; 11016 tree arg; 11017 rtx op, addr, pat; 11018 11019 gcc_assert (TARGET_ALTIVEC); 11020 11021 arg = CALL_EXPR_ARG (exp, 0); 11022 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE); 11023 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL); 11024 addr = memory_address (mode, op); 11025 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE) 11026 op = addr; 11027 else 11028 { 11029 /* For the load case need to negate the address. */ 11030 op = gen_reg_rtx (GET_MODE (addr)); 11031 emit_insn (gen_rtx_SET (VOIDmode, op, 11032 gen_rtx_NEG (GET_MODE (addr), addr))); 11033 } 11034 op = gen_rtx_MEM (mode, op); 11035 11036 if (target == 0 11037 || GET_MODE (target) != tmode 11038 || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) 11039 target = gen_reg_rtx (tmode); 11040 11041 /*pat = gen_altivec_lvsr (target, op);*/ 11042 pat = GEN_FCN (icode) (target, op); 11043 if (!pat) 11044 return 0; 11045 emit_insn (pat); 11046 11047 return target; 11048 } 11049 11050 /* FIXME: There's got to be a nicer way to handle this case than 11051 constructing a new CALL_EXPR. */ 11052 if (fcode == ALTIVEC_BUILTIN_VCFUX 11053 || fcode == ALTIVEC_BUILTIN_VCFSX 11054 || fcode == ALTIVEC_BUILTIN_VCTUXS 11055 || fcode == ALTIVEC_BUILTIN_VCTSXS) 11056 { 11057 if (call_expr_nargs (exp) == 1) 11058 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp), 11059 2, CALL_EXPR_ARG (exp, 0), integer_zero_node); 11060 } 11061 11062 if (TARGET_ALTIVEC) 11063 { 11064 ret = altivec_expand_builtin (exp, target, &success); 11065 11066 if (success) 11067 return ret; 11068 } 11069 if (TARGET_SPE) 11070 { 11071 ret = spe_expand_builtin (exp, target, &success); 11072 11073 if (success) 11074 return ret; 11075 } 11076 if (TARGET_PAIRED_FLOAT) 11077 { 11078 ret = paired_expand_builtin (exp, target, &success); 11079 11080 if (success) 11081 return ret; 11082 } 11083 11084 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT); 11085 11086 /* Handle simple unary operations. */ 11087 d = (struct builtin_description *) bdesc_1arg; 11088 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++) 11089 if (d->code == fcode) 11090 return rs6000_expand_unop_builtin (d->icode, exp, target); 11091 11092 /* Handle simple binary operations. */ 11093 d = (struct builtin_description *) bdesc_2arg; 11094 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++) 11095 if (d->code == fcode) 11096 return rs6000_expand_binop_builtin (d->icode, exp, target); 11097 11098 /* Handle simple ternary operations. */ 11099 d = bdesc_3arg; 11100 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++) 11101 if (d->code == fcode) 11102 return rs6000_expand_ternop_builtin (d->icode, exp, target); 11103 11104 gcc_unreachable (); 11105} 11106 11107static void 11108rs6000_init_builtins (void) 11109{ 11110 tree tdecl; 11111 11112 V2SI_type_node = build_vector_type (intSI_type_node, 2); 11113 V2SF_type_node = build_vector_type (float_type_node, 2); 11114 V2DI_type_node = build_vector_type (intDI_type_node, 2); 11115 V2DF_type_node = build_vector_type (double_type_node, 2); 11116 V4HI_type_node = build_vector_type (intHI_type_node, 4); 11117 V4SI_type_node = build_vector_type (intSI_type_node, 4); 11118 V4SF_type_node = build_vector_type (float_type_node, 4); 11119 V8HI_type_node = build_vector_type (intHI_type_node, 8); 11120 V16QI_type_node = build_vector_type (intQI_type_node, 16); 11121 11122 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16); 11123 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8); 11124 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4); 11125 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2); 11126 11127 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2); 11128 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2); 11129 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node); 11130 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4); 11131 11132 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...' 11133 types, especially in C++ land. Similarly, 'vector pixel' is distinct from 11134 'vector unsigned short'. */ 11135 11136 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node); 11137 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node); 11138 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node); 11139 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node); 11140 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node); 11141 11142 long_integer_type_internal_node = long_integer_type_node; 11143 long_unsigned_type_internal_node = long_unsigned_type_node; 11144 long_long_integer_type_internal_node = long_long_integer_type_node; 11145 long_long_unsigned_type_internal_node = long_long_unsigned_type_node; 11146 intQI_type_internal_node = intQI_type_node; 11147 uintQI_type_internal_node = unsigned_intQI_type_node; 11148 intHI_type_internal_node = intHI_type_node; 11149 uintHI_type_internal_node = unsigned_intHI_type_node; 11150 intSI_type_internal_node = intSI_type_node; 11151 uintSI_type_internal_node = unsigned_intSI_type_node; 11152 intDI_type_internal_node = intDI_type_node; 11153 uintDI_type_internal_node = unsigned_intDI_type_node; 11154 float_type_internal_node = float_type_node; 11155 double_type_internal_node = double_type_node; 11156 void_type_internal_node = void_type_node; 11157 11158 /* Initialize the modes for builtin_function_type, mapping a machine mode to 11159 tree type node. */ 11160 builtin_mode_to_type[QImode][0] = integer_type_node; 11161 builtin_mode_to_type[HImode][0] = integer_type_node; 11162 builtin_mode_to_type[SImode][0] = intSI_type_node; 11163 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node; 11164 builtin_mode_to_type[DImode][0] = intDI_type_node; 11165 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node; 11166 builtin_mode_to_type[SFmode][0] = float_type_node; 11167 builtin_mode_to_type[DFmode][0] = double_type_node; 11168 builtin_mode_to_type[V2SImode][0] = V2SI_type_node; 11169 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node; 11170 builtin_mode_to_type[V2DImode][0] = V2DI_type_node; 11171 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node; 11172 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node; 11173 builtin_mode_to_type[V4HImode][0] = V4HI_type_node; 11174 builtin_mode_to_type[V4SImode][0] = V4SI_type_node; 11175 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node; 11176 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node; 11177 builtin_mode_to_type[V8HImode][0] = V8HI_type_node; 11178 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node; 11179 builtin_mode_to_type[V16QImode][0] = V16QI_type_node; 11180 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node; 11181 11182 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, 11183 get_identifier ("__bool char"), 11184 bool_char_type_node); 11185 TYPE_NAME (bool_char_type_node) = tdecl; 11186 (*lang_hooks.decls.pushdecl) (tdecl); 11187 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, 11188 get_identifier ("__bool short"), 11189 bool_short_type_node); 11190 TYPE_NAME (bool_short_type_node) = tdecl; 11191 (*lang_hooks.decls.pushdecl) (tdecl); 11192 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, 11193 get_identifier ("__bool int"), 11194 bool_int_type_node); 11195 TYPE_NAME (bool_int_type_node) = tdecl; 11196 (*lang_hooks.decls.pushdecl) (tdecl); 11197 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"), 11198 pixel_type_node); 11199 TYPE_NAME (pixel_type_node) = tdecl; 11200 (*lang_hooks.decls.pushdecl) (tdecl); 11201 11202 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16); 11203 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8); 11204 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4); 11205 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2); 11206 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8); 11207 11208 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, 11209 get_identifier ("__vector unsigned char"), 11210 unsigned_V16QI_type_node); 11211 TYPE_NAME (unsigned_V16QI_type_node) = tdecl; 11212 (*lang_hooks.decls.pushdecl) (tdecl); 11213 tdecl = build_decl (BUILTINS_LOCATION, 11214 TYPE_DECL, get_identifier ("__vector signed char"), 11215 V16QI_type_node); 11216 TYPE_NAME (V16QI_type_node) = tdecl; 11217 (*lang_hooks.decls.pushdecl) (tdecl); 11218 tdecl = build_decl (BUILTINS_LOCATION, 11219 TYPE_DECL, get_identifier ("__vector __bool char"), 11220 bool_V16QI_type_node); 11221 TYPE_NAME ( bool_V16QI_type_node) = tdecl; 11222 (*lang_hooks.decls.pushdecl) (tdecl); 11223 11224 tdecl = build_decl (BUILTINS_LOCATION, 11225 TYPE_DECL, get_identifier ("__vector unsigned short"), 11226 unsigned_V8HI_type_node); 11227 TYPE_NAME (unsigned_V8HI_type_node) = tdecl; 11228 (*lang_hooks.decls.pushdecl) (tdecl); 11229 tdecl = build_decl (BUILTINS_LOCATION, 11230 TYPE_DECL, get_identifier ("__vector signed short"), 11231 V8HI_type_node); 11232 TYPE_NAME (V8HI_type_node) = tdecl; 11233 (*lang_hooks.decls.pushdecl) (tdecl); 11234 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, 11235 get_identifier ("__vector __bool short"), 11236 bool_V8HI_type_node); 11237 TYPE_NAME (bool_V8HI_type_node) = tdecl; 11238 (*lang_hooks.decls.pushdecl) (tdecl); 11239 11240 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, 11241 get_identifier ("__vector unsigned int"), 11242 unsigned_V4SI_type_node); 11243 TYPE_NAME (unsigned_V4SI_type_node) = tdecl; 11244 (*lang_hooks.decls.pushdecl) (tdecl); 11245 tdecl = build_decl (BUILTINS_LOCATION, 11246 TYPE_DECL, get_identifier ("__vector signed int"), 11247 V4SI_type_node); 11248 TYPE_NAME (V4SI_type_node) = tdecl; 11249 (*lang_hooks.decls.pushdecl) (tdecl); 11250 tdecl = build_decl (BUILTINS_LOCATION, 11251 TYPE_DECL, get_identifier ("__vector __bool int"), 11252 bool_V4SI_type_node); 11253 TYPE_NAME (bool_V4SI_type_node) = tdecl; 11254 (*lang_hooks.decls.pushdecl) (tdecl); 11255 11256 tdecl = build_decl (BUILTINS_LOCATION, 11257 TYPE_DECL, get_identifier ("__vector float"), 11258 V4SF_type_node); 11259 TYPE_NAME (V4SF_type_node) = tdecl; 11260 (*lang_hooks.decls.pushdecl) (tdecl); 11261 tdecl = build_decl (BUILTINS_LOCATION, 11262 TYPE_DECL, get_identifier ("__vector __pixel"), 11263 pixel_V8HI_type_node); 11264 TYPE_NAME (pixel_V8HI_type_node) = tdecl; 11265 (*lang_hooks.decls.pushdecl) (tdecl); 11266 11267 if (TARGET_VSX) 11268 { 11269 tdecl = build_decl (BUILTINS_LOCATION, 11270 TYPE_DECL, get_identifier ("__vector double"), 11271 V2DF_type_node); 11272 TYPE_NAME (V2DF_type_node) = tdecl; 11273 (*lang_hooks.decls.pushdecl) (tdecl); 11274 11275 tdecl = build_decl (BUILTINS_LOCATION, 11276 TYPE_DECL, get_identifier ("__vector long"), 11277 V2DI_type_node); 11278 TYPE_NAME (V2DI_type_node) = tdecl; 11279 (*lang_hooks.decls.pushdecl) (tdecl); 11280 11281 tdecl = build_decl (BUILTINS_LOCATION, 11282 TYPE_DECL, get_identifier ("__vector unsigned long"), 11283 unsigned_V2DI_type_node); 11284 TYPE_NAME (unsigned_V2DI_type_node) = tdecl; 11285 (*lang_hooks.decls.pushdecl) (tdecl); 11286 11287 tdecl = build_decl (BUILTINS_LOCATION, 11288 TYPE_DECL, get_identifier ("__vector __bool long"), 11289 bool_V2DI_type_node); 11290 TYPE_NAME (bool_V2DI_type_node) = tdecl; 11291 (*lang_hooks.decls.pushdecl) (tdecl); 11292 } 11293 11294 if (TARGET_PAIRED_FLOAT) 11295 paired_init_builtins (); 11296 if (TARGET_SPE) 11297 spe_init_builtins (); 11298 if (TARGET_ALTIVEC) 11299 altivec_init_builtins (); 11300 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX) 11301 rs6000_common_init_builtins (); 11302 if (TARGET_PPC_GFXOPT) 11303 { 11304 tree ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode, 11305 RS6000_BUILTIN_RECIPF, 11306 "__builtin_recipdivf"); 11307 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype, 11308 RS6000_BUILTIN_RECIPF); 11309 11310 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode, 11311 RS6000_BUILTIN_RSQRTF, 11312 "__builtin_rsqrtf"); 11313 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype, 11314 RS6000_BUILTIN_RSQRTF); 11315 } 11316 if (TARGET_POPCNTB) 11317 { 11318 tree ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode, 11319 RS6000_BUILTIN_RECIP, 11320 "__builtin_recipdiv"); 11321 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype, 11322 RS6000_BUILTIN_RECIP); 11323 11324 } 11325 if (TARGET_POPCNTD) 11326 { 11327 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode; 11328 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode, 11329 POWER7_BUILTIN_BPERMD, 11330 "__builtin_bpermd"); 11331 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype, 11332 POWER7_BUILTIN_BPERMD); 11333 } 11334 if (TARGET_POWERPC) 11335 { 11336 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */ 11337 tree ftype = build_function_type_list (unsigned_intHI_type_node, 11338 unsigned_intHI_type_node, 11339 NULL_TREE); 11340 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype, 11341 RS6000_BUILTIN_BSWAP_HI); 11342 } 11343 11344#if TARGET_XCOFF 11345 /* AIX libm provides clog as __clog. */ 11346 if (built_in_decls [BUILT_IN_CLOG]) 11347 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog"); 11348#endif 11349 11350#ifdef SUBTARGET_INIT_BUILTINS 11351 SUBTARGET_INIT_BUILTINS; 11352#endif 11353} 11354 11355/* Returns the rs6000 builtin decl for CODE. */ 11356 11357static tree 11358rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED) 11359{ 11360 if (code >= RS6000_BUILTIN_COUNT) 11361 return error_mark_node; 11362 11363 return rs6000_builtin_decls[code]; 11364} 11365 11366/* Search through a set of builtins and enable the mask bits. 11367 DESC is an array of builtins. 11368 SIZE is the total number of builtins. 11369 START is the builtin enum at which to start. 11370 END is the builtin enum at which to end. */ 11371static void 11372enable_mask_for_builtins (struct builtin_description *desc, int size, 11373 enum rs6000_builtins start, 11374 enum rs6000_builtins end) 11375{ 11376 int i; 11377 11378 for (i = 0; i < size; ++i) 11379 if (desc[i].code == start) 11380 break; 11381 11382 if (i == size) 11383 return; 11384 11385 for (; i < size; ++i) 11386 { 11387 /* Flip all the bits on. */ 11388 desc[i].mask = target_flags; 11389 if (desc[i].code == end) 11390 break; 11391 } 11392} 11393 11394static void 11395spe_init_builtins (void) 11396{ 11397 tree endlink = void_list_node; 11398 tree puint_type_node = build_pointer_type (unsigned_type_node); 11399 tree pushort_type_node = build_pointer_type (short_unsigned_type_node); 11400 struct builtin_description *d; 11401 size_t i; 11402 11403 tree v2si_ftype_4_v2si 11404 = build_function_type 11405 (opaque_V2SI_type_node, 11406 tree_cons (NULL_TREE, opaque_V2SI_type_node, 11407 tree_cons (NULL_TREE, opaque_V2SI_type_node, 11408 tree_cons (NULL_TREE, opaque_V2SI_type_node, 11409 tree_cons (NULL_TREE, opaque_V2SI_type_node, 11410 endlink))))); 11411 11412 tree v2sf_ftype_4_v2sf 11413 = build_function_type 11414 (opaque_V2SF_type_node, 11415 tree_cons (NULL_TREE, opaque_V2SF_type_node, 11416 tree_cons (NULL_TREE, opaque_V2SF_type_node, 11417 tree_cons (NULL_TREE, opaque_V2SF_type_node, 11418 tree_cons (NULL_TREE, opaque_V2SF_type_node, 11419 endlink))))); 11420 11421 tree int_ftype_int_v2si_v2si 11422 = build_function_type 11423 (integer_type_node, 11424 tree_cons (NULL_TREE, integer_type_node, 11425 tree_cons (NULL_TREE, opaque_V2SI_type_node, 11426 tree_cons (NULL_TREE, opaque_V2SI_type_node, 11427 endlink)))); 11428 11429 tree int_ftype_int_v2sf_v2sf 11430 = build_function_type 11431 (integer_type_node, 11432 tree_cons (NULL_TREE, integer_type_node, 11433 tree_cons (NULL_TREE, opaque_V2SF_type_node, 11434 tree_cons (NULL_TREE, opaque_V2SF_type_node, 11435 endlink)))); 11436 11437 tree void_ftype_v2si_puint_int 11438 = build_function_type (void_type_node, 11439 tree_cons (NULL_TREE, opaque_V2SI_type_node, 11440 tree_cons (NULL_TREE, puint_type_node, 11441 tree_cons (NULL_TREE, 11442 integer_type_node, 11443 endlink)))); 11444 11445 tree void_ftype_v2si_puint_char 11446 = build_function_type (void_type_node, 11447 tree_cons (NULL_TREE, opaque_V2SI_type_node, 11448 tree_cons (NULL_TREE, puint_type_node, 11449 tree_cons (NULL_TREE, 11450 char_type_node, 11451 endlink)))); 11452 11453 tree void_ftype_v2si_pv2si_int 11454 = build_function_type (void_type_node, 11455 tree_cons (NULL_TREE, opaque_V2SI_type_node, 11456 tree_cons (NULL_TREE, opaque_p_V2SI_type_node, 11457 tree_cons (NULL_TREE, 11458 integer_type_node, 11459 endlink)))); 11460 11461 tree void_ftype_v2si_pv2si_char 11462 = build_function_type (void_type_node, 11463 tree_cons (NULL_TREE, opaque_V2SI_type_node, 11464 tree_cons (NULL_TREE, opaque_p_V2SI_type_node, 11465 tree_cons (NULL_TREE, 11466 char_type_node, 11467 endlink)))); 11468 11469 tree void_ftype_int 11470 = build_function_type (void_type_node, 11471 tree_cons (NULL_TREE, integer_type_node, endlink)); 11472 11473 tree int_ftype_void 11474 = build_function_type (integer_type_node, endlink); 11475 11476 tree v2si_ftype_pv2si_int 11477 = build_function_type (opaque_V2SI_type_node, 11478 tree_cons (NULL_TREE, opaque_p_V2SI_type_node, 11479 tree_cons (NULL_TREE, integer_type_node, 11480 endlink))); 11481 11482 tree v2si_ftype_puint_int 11483 = build_function_type (opaque_V2SI_type_node, 11484 tree_cons (NULL_TREE, puint_type_node, 11485 tree_cons (NULL_TREE, integer_type_node, 11486 endlink))); 11487 11488 tree v2si_ftype_pushort_int 11489 = build_function_type (opaque_V2SI_type_node, 11490 tree_cons (NULL_TREE, pushort_type_node, 11491 tree_cons (NULL_TREE, integer_type_node, 11492 endlink))); 11493 11494 tree v2si_ftype_signed_char 11495 = build_function_type (opaque_V2SI_type_node, 11496 tree_cons (NULL_TREE, signed_char_type_node, 11497 endlink)); 11498 11499 /* The initialization of the simple binary and unary builtins is 11500 done in rs6000_common_init_builtins, but we have to enable the 11501 mask bits here manually because we have run out of `target_flags' 11502 bits. We really need to redesign this mask business. */ 11503 11504 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg, 11505 ARRAY_SIZE (bdesc_2arg), 11506 SPE_BUILTIN_EVADDW, 11507 SPE_BUILTIN_EVXOR); 11508 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg, 11509 ARRAY_SIZE (bdesc_1arg), 11510 SPE_BUILTIN_EVABS, 11511 SPE_BUILTIN_EVSUBFUSIAAW); 11512 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates, 11513 ARRAY_SIZE (bdesc_spe_predicates), 11514 SPE_BUILTIN_EVCMPEQ, 11515 SPE_BUILTIN_EVFSTSTLT); 11516 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel, 11517 ARRAY_SIZE (bdesc_spe_evsel), 11518 SPE_BUILTIN_EVSEL_CMPGTS, 11519 SPE_BUILTIN_EVSEL_FSTSTEQ); 11520 11521 (*lang_hooks.decls.pushdecl) 11522 (build_decl (BUILTINS_LOCATION, TYPE_DECL, 11523 get_identifier ("__ev64_opaque__"), 11524 opaque_V2SI_type_node)); 11525 11526 /* Initialize irregular SPE builtins. */ 11527 11528 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR); 11529 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR); 11530 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX); 11531 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX); 11532 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX); 11533 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX); 11534 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX); 11535 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX); 11536 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX); 11537 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD); 11538 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH); 11539 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW); 11540 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE); 11541 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO); 11542 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE); 11543 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO); 11544 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI); 11545 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI); 11546 11547 /* Loads. */ 11548 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX); 11549 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX); 11550 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX); 11551 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX); 11552 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX); 11553 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX); 11554 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX); 11555 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX); 11556 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX); 11557 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX); 11558 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX); 11559 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD); 11560 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW); 11561 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH); 11562 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT); 11563 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT); 11564 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT); 11565 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE); 11566 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS); 11567 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU); 11568 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT); 11569 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT); 11570 11571 /* Predicates. */ 11572 d = (struct builtin_description *) bdesc_spe_predicates; 11573 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++) 11574 { 11575 tree type; 11576 11577 switch (insn_data[d->icode].operand[1].mode) 11578 { 11579 case V2SImode: 11580 type = int_ftype_int_v2si_v2si; 11581 break; 11582 case V2SFmode: 11583 type = int_ftype_int_v2sf_v2sf; 11584 break; 11585 default: 11586 gcc_unreachable (); 11587 } 11588 11589 def_builtin (d->mask, d->name, type, d->code); 11590 } 11591 11592 /* Evsel predicates. */ 11593 d = (struct builtin_description *) bdesc_spe_evsel; 11594 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++) 11595 { 11596 tree type; 11597 11598 switch (insn_data[d->icode].operand[1].mode) 11599 { 11600 case V2SImode: 11601 type = v2si_ftype_4_v2si; 11602 break; 11603 case V2SFmode: 11604 type = v2sf_ftype_4_v2sf; 11605 break; 11606 default: 11607 gcc_unreachable (); 11608 } 11609 11610 def_builtin (d->mask, d->name, type, d->code); 11611 } 11612} 11613 11614static void 11615paired_init_builtins (void) 11616{ 11617 const struct builtin_description *d; 11618 size_t i; 11619 tree endlink = void_list_node; 11620 11621 tree int_ftype_int_v2sf_v2sf 11622 = build_function_type 11623 (integer_type_node, 11624 tree_cons (NULL_TREE, integer_type_node, 11625 tree_cons (NULL_TREE, V2SF_type_node, 11626 tree_cons (NULL_TREE, V2SF_type_node, 11627 endlink)))); 11628 tree pcfloat_type_node = 11629 build_pointer_type (build_qualified_type 11630 (float_type_node, TYPE_QUAL_CONST)); 11631 11632 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node, 11633 long_integer_type_node, 11634 pcfloat_type_node, 11635 NULL_TREE); 11636 tree void_ftype_v2sf_long_pcfloat = 11637 build_function_type_list (void_type_node, 11638 V2SF_type_node, 11639 long_integer_type_node, 11640 pcfloat_type_node, 11641 NULL_TREE); 11642 11643 11644 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat, 11645 PAIRED_BUILTIN_LX); 11646 11647 11648 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat, 11649 PAIRED_BUILTIN_STX); 11650 11651 /* Predicates. */ 11652 d = bdesc_paired_preds; 11653 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++) 11654 { 11655 tree type; 11656 11657 switch (insn_data[d->icode].operand[1].mode) 11658 { 11659 case V2SFmode: 11660 type = int_ftype_int_v2sf_v2sf; 11661 break; 11662 default: 11663 gcc_unreachable (); 11664 } 11665 11666 def_builtin (d->mask, d->name, type, d->code); 11667 } 11668} 11669 11670static void 11671altivec_init_builtins (void) 11672{ 11673 const struct builtin_description *d; 11674 const struct builtin_description_predicates *dp; 11675 size_t i; 11676 tree ftype; 11677 11678 tree pvoid_type_node = build_pointer_type (void_type_node); 11679 11680 tree pcvoid_type_node 11681 = build_pointer_type (build_qualified_type (void_type_node, 11682 TYPE_QUAL_CONST)); 11683 11684 tree int_ftype_opaque 11685 = build_function_type_list (integer_type_node, 11686 opaque_V4SI_type_node, NULL_TREE); 11687 tree opaque_ftype_opaque 11688 = build_function_type (integer_type_node, 11689 NULL_TREE); 11690 tree opaque_ftype_opaque_int 11691 = build_function_type_list (opaque_V4SI_type_node, 11692 opaque_V4SI_type_node, integer_type_node, NULL_TREE); 11693 tree opaque_ftype_opaque_opaque_int 11694 = build_function_type_list (opaque_V4SI_type_node, 11695 opaque_V4SI_type_node, opaque_V4SI_type_node, 11696 integer_type_node, NULL_TREE); 11697 tree int_ftype_int_opaque_opaque 11698 = build_function_type_list (integer_type_node, 11699 integer_type_node, opaque_V4SI_type_node, 11700 opaque_V4SI_type_node, NULL_TREE); 11701 tree int_ftype_int_v4si_v4si 11702 = build_function_type_list (integer_type_node, 11703 integer_type_node, V4SI_type_node, 11704 V4SI_type_node, NULL_TREE); 11705 tree void_ftype_v4si 11706 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE); 11707 tree v8hi_ftype_void 11708 = build_function_type (V8HI_type_node, void_list_node); 11709 tree void_ftype_void 11710 = build_function_type (void_type_node, void_list_node); 11711 tree void_ftype_int 11712 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE); 11713 11714 tree opaque_ftype_long_pcvoid 11715 = build_function_type_list (opaque_V4SI_type_node, 11716 long_integer_type_node, pcvoid_type_node, 11717 NULL_TREE); 11718 tree v16qi_ftype_long_pcvoid 11719 = build_function_type_list (V16QI_type_node, 11720 long_integer_type_node, pcvoid_type_node, 11721 NULL_TREE); 11722 tree v8hi_ftype_long_pcvoid 11723 = build_function_type_list (V8HI_type_node, 11724 long_integer_type_node, pcvoid_type_node, 11725 NULL_TREE); 11726 tree v4si_ftype_long_pcvoid 11727 = build_function_type_list (V4SI_type_node, 11728 long_integer_type_node, pcvoid_type_node, 11729 NULL_TREE); 11730 tree v4sf_ftype_long_pcvoid 11731 = build_function_type_list (V4SF_type_node, 11732 long_integer_type_node, pcvoid_type_node, 11733 NULL_TREE); 11734 tree v2df_ftype_long_pcvoid 11735 = build_function_type_list (V2DF_type_node, 11736 long_integer_type_node, pcvoid_type_node, 11737 NULL_TREE); 11738 tree v2di_ftype_long_pcvoid 11739 = build_function_type_list (V2DI_type_node, 11740 long_integer_type_node, pcvoid_type_node, 11741 NULL_TREE); 11742 11743 tree void_ftype_opaque_long_pvoid 11744 = build_function_type_list (void_type_node, 11745 opaque_V4SI_type_node, long_integer_type_node, 11746 pvoid_type_node, NULL_TREE); 11747 tree void_ftype_v4si_long_pvoid 11748 = build_function_type_list (void_type_node, 11749 V4SI_type_node, long_integer_type_node, 11750 pvoid_type_node, NULL_TREE); 11751 tree void_ftype_v16qi_long_pvoid 11752 = build_function_type_list (void_type_node, 11753 V16QI_type_node, long_integer_type_node, 11754 pvoid_type_node, NULL_TREE); 11755 tree void_ftype_v8hi_long_pvoid 11756 = build_function_type_list (void_type_node, 11757 V8HI_type_node, long_integer_type_node, 11758 pvoid_type_node, NULL_TREE); 11759 tree void_ftype_v4sf_long_pvoid 11760 = build_function_type_list (void_type_node, 11761 V4SF_type_node, long_integer_type_node, 11762 pvoid_type_node, NULL_TREE); 11763 tree void_ftype_v2df_long_pvoid 11764 = build_function_type_list (void_type_node, 11765 V2DF_type_node, long_integer_type_node, 11766 pvoid_type_node, NULL_TREE); 11767 tree void_ftype_v2di_long_pvoid 11768 = build_function_type_list (void_type_node, 11769 V2DI_type_node, long_integer_type_node, 11770 pvoid_type_node, NULL_TREE); 11771 tree int_ftype_int_v8hi_v8hi 11772 = build_function_type_list (integer_type_node, 11773 integer_type_node, V8HI_type_node, 11774 V8HI_type_node, NULL_TREE); 11775 tree int_ftype_int_v16qi_v16qi 11776 = build_function_type_list (integer_type_node, 11777 integer_type_node, V16QI_type_node, 11778 V16QI_type_node, NULL_TREE); 11779 tree int_ftype_int_v4sf_v4sf 11780 = build_function_type_list (integer_type_node, 11781 integer_type_node, V4SF_type_node, 11782 V4SF_type_node, NULL_TREE); 11783 tree int_ftype_int_v2df_v2df 11784 = build_function_type_list (integer_type_node, 11785 integer_type_node, V2DF_type_node, 11786 V2DF_type_node, NULL_TREE); 11787 tree v4si_ftype_v4si 11788 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE); 11789 tree v8hi_ftype_v8hi 11790 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE); 11791 tree v16qi_ftype_v16qi 11792 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE); 11793 tree v4sf_ftype_v4sf 11794 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE); 11795 tree v2df_ftype_v2df 11796 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE); 11797 tree void_ftype_pcvoid_int_int 11798 = build_function_type_list (void_type_node, 11799 pcvoid_type_node, integer_type_node, 11800 integer_type_node, NULL_TREE); 11801 11802 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR); 11803 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR); 11804 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL); 11805 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS); 11806 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL); 11807 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR); 11808 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX); 11809 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX); 11810 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX); 11811 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL); 11812 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX); 11813 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX); 11814 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX); 11815 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL); 11816 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX); 11817 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX); 11818 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD); 11819 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE); 11820 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL); 11821 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL); 11822 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR); 11823 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX); 11824 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX); 11825 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX); 11826 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST); 11827 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE); 11828 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL); 11829 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX); 11830 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX); 11831 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX); 11832 11833 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid, 11834 VSX_BUILTIN_LXVD2X_V2DF); 11835 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2di", v2di_ftype_long_pcvoid, 11836 VSX_BUILTIN_LXVD2X_V2DI); 11837 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4sf", v4sf_ftype_long_pcvoid, 11838 VSX_BUILTIN_LXVW4X_V4SF); 11839 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4si", v4si_ftype_long_pcvoid, 11840 VSX_BUILTIN_LXVW4X_V4SI); 11841 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v8hi", 11842 v8hi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V8HI); 11843 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v16qi", 11844 v16qi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V16QI); 11845 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2df", 11846 void_ftype_v2df_long_pvoid, VSX_BUILTIN_STXVD2X_V2DF); 11847 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2di", 11848 void_ftype_v2di_long_pvoid, VSX_BUILTIN_STXVD2X_V2DI); 11849 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4sf", 11850 void_ftype_v4sf_long_pvoid, VSX_BUILTIN_STXVW4X_V4SF); 11851 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4si", 11852 void_ftype_v4si_long_pvoid, VSX_BUILTIN_STXVW4X_V4SI); 11853 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v8hi", 11854 void_ftype_v8hi_long_pvoid, VSX_BUILTIN_STXVW4X_V8HI); 11855 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v16qi", 11856 void_ftype_v16qi_long_pvoid, VSX_BUILTIN_STXVW4X_V16QI); 11857 def_builtin (MASK_VSX, "__builtin_vec_vsx_ld", opaque_ftype_long_pcvoid, 11858 VSX_BUILTIN_VEC_LD); 11859 def_builtin (MASK_VSX, "__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid, 11860 VSX_BUILTIN_VEC_ST); 11861 11862 if (rs6000_cpu == PROCESSOR_CELL) 11863 { 11864 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX); 11865 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL); 11866 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX); 11867 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL); 11868 11869 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX); 11870 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL); 11871 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX); 11872 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL); 11873 11874 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX); 11875 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL); 11876 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX); 11877 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL); 11878 11879 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX); 11880 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL); 11881 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX); 11882 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL); 11883 } 11884 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP); 11885 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS); 11886 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE); 11887 11888 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD); 11889 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT); 11890 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT); 11891 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT); 11892 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW); 11893 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH); 11894 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB); 11895 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF); 11896 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX); 11897 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX); 11898 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS); 11899 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU); 11900 11901 /* Add the DST variants. */ 11902 d = bdesc_dst; 11903 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++) 11904 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code); 11905 11906 /* Initialize the predicates. */ 11907 dp = bdesc_altivec_preds; 11908 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++) 11909 { 11910 enum machine_mode mode1; 11911 tree type; 11912 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST 11913 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST) 11914 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST 11915 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST)); 11916 11917 if (is_overloaded) 11918 mode1 = VOIDmode; 11919 else 11920 mode1 = insn_data[dp->icode].operand[1].mode; 11921 11922 switch (mode1) 11923 { 11924 case VOIDmode: 11925 type = int_ftype_int_opaque_opaque; 11926 break; 11927 case V4SImode: 11928 type = int_ftype_int_v4si_v4si; 11929 break; 11930 case V8HImode: 11931 type = int_ftype_int_v8hi_v8hi; 11932 break; 11933 case V16QImode: 11934 type = int_ftype_int_v16qi_v16qi; 11935 break; 11936 case V4SFmode: 11937 type = int_ftype_int_v4sf_v4sf; 11938 break; 11939 case V2DFmode: 11940 type = int_ftype_int_v2df_v2df; 11941 break; 11942 default: 11943 gcc_unreachable (); 11944 } 11945 11946 def_builtin (dp->mask, dp->name, type, dp->code); 11947 } 11948 11949 /* Initialize the abs* operators. */ 11950 d = bdesc_abs; 11951 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++) 11952 { 11953 enum machine_mode mode0; 11954 tree type; 11955 11956 mode0 = insn_data[d->icode].operand[0].mode; 11957 11958 switch (mode0) 11959 { 11960 case V4SImode: 11961 type = v4si_ftype_v4si; 11962 break; 11963 case V8HImode: 11964 type = v8hi_ftype_v8hi; 11965 break; 11966 case V16QImode: 11967 type = v16qi_ftype_v16qi; 11968 break; 11969 case V4SFmode: 11970 type = v4sf_ftype_v4sf; 11971 break; 11972 case V2DFmode: 11973 type = v2df_ftype_v2df; 11974 break; 11975 default: 11976 gcc_unreachable (); 11977 } 11978 11979 def_builtin (d->mask, d->name, type, d->code); 11980 } 11981 11982 if (TARGET_ALTIVEC) 11983 { 11984 tree decl; 11985 11986 /* Initialize target builtin that implements 11987 targetm.vectorize.builtin_mask_for_load. */ 11988 11989 decl = add_builtin_function ("__builtin_altivec_mask_for_load", 11990 v16qi_ftype_long_pcvoid, 11991 ALTIVEC_BUILTIN_MASK_FOR_LOAD, 11992 BUILT_IN_MD, NULL, NULL_TREE); 11993 TREE_READONLY (decl) = 1; 11994 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */ 11995 altivec_builtin_mask_for_load = decl; 11996 } 11997 11998 /* Access to the vec_init patterns. */ 11999 ftype = build_function_type_list (V4SI_type_node, integer_type_node, 12000 integer_type_node, integer_type_node, 12001 integer_type_node, NULL_TREE); 12002 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype, 12003 ALTIVEC_BUILTIN_VEC_INIT_V4SI); 12004 12005 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node, 12006 short_integer_type_node, 12007 short_integer_type_node, 12008 short_integer_type_node, 12009 short_integer_type_node, 12010 short_integer_type_node, 12011 short_integer_type_node, 12012 short_integer_type_node, NULL_TREE); 12013 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype, 12014 ALTIVEC_BUILTIN_VEC_INIT_V8HI); 12015 12016 ftype = build_function_type_list (V16QI_type_node, char_type_node, 12017 char_type_node, char_type_node, 12018 char_type_node, char_type_node, 12019 char_type_node, char_type_node, 12020 char_type_node, char_type_node, 12021 char_type_node, char_type_node, 12022 char_type_node, char_type_node, 12023 char_type_node, char_type_node, 12024 char_type_node, NULL_TREE); 12025 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype, 12026 ALTIVEC_BUILTIN_VEC_INIT_V16QI); 12027 12028 ftype = build_function_type_list (V4SF_type_node, float_type_node, 12029 float_type_node, float_type_node, 12030 float_type_node, NULL_TREE); 12031 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype, 12032 ALTIVEC_BUILTIN_VEC_INIT_V4SF); 12033 12034 if (TARGET_VSX) 12035 { 12036 ftype = build_function_type_list (V2DF_type_node, double_type_node, 12037 double_type_node, NULL_TREE); 12038 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype, 12039 VSX_BUILTIN_VEC_INIT_V2DF); 12040 12041 ftype = build_function_type_list (V2DI_type_node, intDI_type_node, 12042 intDI_type_node, NULL_TREE); 12043 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype, 12044 VSX_BUILTIN_VEC_INIT_V2DI); 12045 } 12046 12047 /* Access to the vec_set patterns. */ 12048 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node, 12049 intSI_type_node, 12050 integer_type_node, NULL_TREE); 12051 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype, 12052 ALTIVEC_BUILTIN_VEC_SET_V4SI); 12053 12054 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node, 12055 intHI_type_node, 12056 integer_type_node, NULL_TREE); 12057 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype, 12058 ALTIVEC_BUILTIN_VEC_SET_V8HI); 12059 12060 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node, 12061 intQI_type_node, 12062 integer_type_node, NULL_TREE); 12063 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype, 12064 ALTIVEC_BUILTIN_VEC_SET_V16QI); 12065 12066 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node, 12067 float_type_node, 12068 integer_type_node, NULL_TREE); 12069 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype, 12070 ALTIVEC_BUILTIN_VEC_SET_V4SF); 12071 12072 if (TARGET_VSX) 12073 { 12074 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node, 12075 double_type_node, 12076 integer_type_node, NULL_TREE); 12077 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype, 12078 VSX_BUILTIN_VEC_SET_V2DF); 12079 12080 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node, 12081 intDI_type_node, 12082 integer_type_node, NULL_TREE); 12083 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype, 12084 VSX_BUILTIN_VEC_SET_V2DI); 12085 } 12086 12087 /* Access to the vec_extract patterns. */ 12088 ftype = build_function_type_list (intSI_type_node, V4SI_type_node, 12089 integer_type_node, NULL_TREE); 12090 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype, 12091 ALTIVEC_BUILTIN_VEC_EXT_V4SI); 12092 12093 ftype = build_function_type_list (intHI_type_node, V8HI_type_node, 12094 integer_type_node, NULL_TREE); 12095 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype, 12096 ALTIVEC_BUILTIN_VEC_EXT_V8HI); 12097 12098 ftype = build_function_type_list (intQI_type_node, V16QI_type_node, 12099 integer_type_node, NULL_TREE); 12100 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype, 12101 ALTIVEC_BUILTIN_VEC_EXT_V16QI); 12102 12103 ftype = build_function_type_list (float_type_node, V4SF_type_node, 12104 integer_type_node, NULL_TREE); 12105 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype, 12106 ALTIVEC_BUILTIN_VEC_EXT_V4SF); 12107 12108 if (TARGET_VSX) 12109 { 12110 ftype = build_function_type_list (double_type_node, V2DF_type_node, 12111 integer_type_node, NULL_TREE); 12112 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype, 12113 VSX_BUILTIN_VEC_EXT_V2DF); 12114 12115 ftype = build_function_type_list (intDI_type_node, V2DI_type_node, 12116 integer_type_node, NULL_TREE); 12117 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype, 12118 VSX_BUILTIN_VEC_EXT_V2DI); 12119 } 12120} 12121 12122/* Hash function for builtin functions with up to 3 arguments and a return 12123 type. */ 12124static unsigned 12125builtin_hash_function (const void *hash_entry) 12126{ 12127 unsigned ret = 0; 12128 int i; 12129 const struct builtin_hash_struct *bh = 12130 (const struct builtin_hash_struct *) hash_entry; 12131 12132 for (i = 0; i < 4; i++) 12133 { 12134 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]); 12135 ret = (ret * 2) + bh->uns_p[i]; 12136 } 12137 12138 return ret; 12139} 12140 12141/* Compare builtin hash entries H1 and H2 for equivalence. */ 12142static int 12143builtin_hash_eq (const void *h1, const void *h2) 12144{ 12145 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1; 12146 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2; 12147 12148 return ((p1->mode[0] == p2->mode[0]) 12149 && (p1->mode[1] == p2->mode[1]) 12150 && (p1->mode[2] == p2->mode[2]) 12151 && (p1->mode[3] == p2->mode[3]) 12152 && (p1->uns_p[0] == p2->uns_p[0]) 12153 && (p1->uns_p[1] == p2->uns_p[1]) 12154 && (p1->uns_p[2] == p2->uns_p[2]) 12155 && (p1->uns_p[3] == p2->uns_p[3])); 12156} 12157 12158/* Map types for builtin functions with an explicit return type and up to 3 12159 arguments. Functions with fewer than 3 arguments use VOIDmode as the type 12160 of the argument. */ 12161static tree 12162builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0, 12163 enum machine_mode mode_arg1, enum machine_mode mode_arg2, 12164 enum rs6000_builtins builtin, const char *name) 12165{ 12166 struct builtin_hash_struct h; 12167 struct builtin_hash_struct *h2; 12168 void **found; 12169 int num_args = 3; 12170 int i; 12171 tree ret_type = NULL_TREE; 12172 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE }; 12173 tree args; 12174 12175 /* Create builtin_hash_table. */ 12176 if (builtin_hash_table == NULL) 12177 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function, 12178 builtin_hash_eq, NULL); 12179 12180 h.type = NULL_TREE; 12181 h.mode[0] = mode_ret; 12182 h.mode[1] = mode_arg0; 12183 h.mode[2] = mode_arg1; 12184 h.mode[3] = mode_arg2; 12185 h.uns_p[0] = 0; 12186 h.uns_p[1] = 0; 12187 h.uns_p[2] = 0; 12188 h.uns_p[3] = 0; 12189 12190 /* If the builtin is a type that produces unsigned results or takes unsigned 12191 arguments, and it is returned as a decl for the vectorizer (such as 12192 widening multiplies, permute), make sure the arguments and return value 12193 are type correct. */ 12194 switch (builtin) 12195 { 12196 /* unsigned 2 argument functions. */ 12197 case ALTIVEC_BUILTIN_VMULEUB_UNS: 12198 case ALTIVEC_BUILTIN_VMULEUH_UNS: 12199 case ALTIVEC_BUILTIN_VMULOUB_UNS: 12200 case ALTIVEC_BUILTIN_VMULOUH_UNS: 12201 h.uns_p[0] = 1; 12202 h.uns_p[1] = 1; 12203 h.uns_p[2] = 1; 12204 break; 12205 12206 /* unsigned 3 argument functions. */ 12207 case ALTIVEC_BUILTIN_VPERM_16QI_UNS: 12208 case ALTIVEC_BUILTIN_VPERM_8HI_UNS: 12209 case ALTIVEC_BUILTIN_VPERM_4SI_UNS: 12210 case ALTIVEC_BUILTIN_VPERM_2DI_UNS: 12211 case ALTIVEC_BUILTIN_VSEL_16QI_UNS: 12212 case ALTIVEC_BUILTIN_VSEL_8HI_UNS: 12213 case ALTIVEC_BUILTIN_VSEL_4SI_UNS: 12214 case ALTIVEC_BUILTIN_VSEL_2DI_UNS: 12215 case VSX_BUILTIN_VPERM_16QI_UNS: 12216 case VSX_BUILTIN_VPERM_8HI_UNS: 12217 case VSX_BUILTIN_VPERM_4SI_UNS: 12218 case VSX_BUILTIN_VPERM_2DI_UNS: 12219 case VSX_BUILTIN_XXSEL_16QI_UNS: 12220 case VSX_BUILTIN_XXSEL_8HI_UNS: 12221 case VSX_BUILTIN_XXSEL_4SI_UNS: 12222 case VSX_BUILTIN_XXSEL_2DI_UNS: 12223 h.uns_p[0] = 1; 12224 h.uns_p[1] = 1; 12225 h.uns_p[2] = 1; 12226 h.uns_p[3] = 1; 12227 break; 12228 12229 /* signed permute functions with unsigned char mask. */ 12230 case ALTIVEC_BUILTIN_VPERM_16QI: 12231 case ALTIVEC_BUILTIN_VPERM_8HI: 12232 case ALTIVEC_BUILTIN_VPERM_4SI: 12233 case ALTIVEC_BUILTIN_VPERM_4SF: 12234 case ALTIVEC_BUILTIN_VPERM_2DI: 12235 case ALTIVEC_BUILTIN_VPERM_2DF: 12236 case VSX_BUILTIN_VPERM_16QI: 12237 case VSX_BUILTIN_VPERM_8HI: 12238 case VSX_BUILTIN_VPERM_4SI: 12239 case VSX_BUILTIN_VPERM_4SF: 12240 case VSX_BUILTIN_VPERM_2DI: 12241 case VSX_BUILTIN_VPERM_2DF: 12242 h.uns_p[3] = 1; 12243 break; 12244 12245 /* unsigned args, signed return. */ 12246 case VSX_BUILTIN_XVCVUXDDP_UNS: 12247 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF: 12248 h.uns_p[1] = 1; 12249 break; 12250 12251 /* signed args, unsigned return. */ 12252 case VSX_BUILTIN_XVCVDPUXDS_UNS: 12253 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI: 12254 h.uns_p[0] = 1; 12255 break; 12256 12257 default: 12258 break; 12259 } 12260 12261 /* Figure out how many args are present. */ 12262 while (num_args > 0 && h.mode[num_args] == VOIDmode) 12263 num_args--; 12264 12265 if (num_args == 0) 12266 fatal_error ("internal error: builtin function %s had no type", name); 12267 12268 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]]; 12269 if (!ret_type && h.uns_p[0]) 12270 ret_type = builtin_mode_to_type[h.mode[0]][0]; 12271 12272 if (!ret_type) 12273 fatal_error ("internal error: builtin function %s had an unexpected " 12274 "return type %s", name, GET_MODE_NAME (h.mode[0])); 12275 12276 for (i = 0; i < num_args; i++) 12277 { 12278 int m = (int) h.mode[i+1]; 12279 int uns_p = h.uns_p[i+1]; 12280 12281 arg_type[i] = builtin_mode_to_type[m][uns_p]; 12282 if (!arg_type[i] && uns_p) 12283 arg_type[i] = builtin_mode_to_type[m][0]; 12284 12285 if (!arg_type[i]) 12286 fatal_error ("internal error: builtin function %s, argument %d " 12287 "had unexpected argument type %s", name, i, 12288 GET_MODE_NAME (m)); 12289 } 12290 12291 found = htab_find_slot (builtin_hash_table, &h, INSERT); 12292 if (*found == NULL) 12293 { 12294 h2 = GGC_NEW (struct builtin_hash_struct); 12295 *h2 = h; 12296 *found = (void *)h2; 12297 args = void_list_node; 12298 12299 for (i = num_args - 1; i >= 0; i--) 12300 args = tree_cons (NULL_TREE, arg_type[i], args); 12301 12302 h2->type = build_function_type (ret_type, args); 12303 } 12304 12305 return ((struct builtin_hash_struct *)(*found))->type; 12306} 12307 12308static void 12309rs6000_common_init_builtins (void) 12310{ 12311 const struct builtin_description *d; 12312 size_t i; 12313 12314 tree opaque_ftype_opaque = NULL_TREE; 12315 tree opaque_ftype_opaque_opaque = NULL_TREE; 12316 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE; 12317 tree v2si_ftype_qi = NULL_TREE; 12318 tree v2si_ftype_v2si_qi = NULL_TREE; 12319 tree v2si_ftype_int_qi = NULL_TREE; 12320 12321 if (!TARGET_PAIRED_FLOAT) 12322 { 12323 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node; 12324 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node; 12325 } 12326 12327 /* Add the ternary operators. */ 12328 d = bdesc_3arg; 12329 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++) 12330 { 12331 tree type; 12332 int mask = d->mask; 12333 12334 if ((mask != 0 && (mask & target_flags) == 0) 12335 || (mask == 0 && !TARGET_PAIRED_FLOAT)) 12336 continue; 12337 12338 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST 12339 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST) 12340 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST 12341 && d->code <= VSX_BUILTIN_OVERLOADED_LAST)) 12342 { 12343 if (! (type = opaque_ftype_opaque_opaque_opaque)) 12344 type = opaque_ftype_opaque_opaque_opaque 12345 = build_function_type_list (opaque_V4SI_type_node, 12346 opaque_V4SI_type_node, 12347 opaque_V4SI_type_node, 12348 opaque_V4SI_type_node, 12349 NULL_TREE); 12350 } 12351 else 12352 { 12353 enum insn_code icode = d->icode; 12354 if (d->name == 0 || icode == CODE_FOR_nothing) 12355 continue; 12356 12357 type = builtin_function_type (insn_data[icode].operand[0].mode, 12358 insn_data[icode].operand[1].mode, 12359 insn_data[icode].operand[2].mode, 12360 insn_data[icode].operand[3].mode, 12361 d->code, d->name); 12362 } 12363 12364 def_builtin (d->mask, d->name, type, d->code); 12365 } 12366 12367 /* Add the binary operators. */ 12368 d = bdesc_2arg; 12369 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++) 12370 { 12371 enum machine_mode mode0, mode1, mode2; 12372 tree type; 12373 int mask = d->mask; 12374 12375 if ((mask != 0 && (mask & target_flags) == 0) 12376 || (mask == 0 && !TARGET_PAIRED_FLOAT)) 12377 continue; 12378 12379 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST 12380 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST) 12381 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST 12382 && d->code <= VSX_BUILTIN_OVERLOADED_LAST)) 12383 { 12384 if (! (type = opaque_ftype_opaque_opaque)) 12385 type = opaque_ftype_opaque_opaque 12386 = build_function_type_list (opaque_V4SI_type_node, 12387 opaque_V4SI_type_node, 12388 opaque_V4SI_type_node, 12389 NULL_TREE); 12390 } 12391 else 12392 { 12393 enum insn_code icode = d->icode; 12394 if (d->name == 0 || icode == CODE_FOR_nothing) 12395 continue; 12396 12397 mode0 = insn_data[icode].operand[0].mode; 12398 mode1 = insn_data[icode].operand[1].mode; 12399 mode2 = insn_data[icode].operand[2].mode; 12400 12401 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode) 12402 { 12403 if (! (type = v2si_ftype_v2si_qi)) 12404 type = v2si_ftype_v2si_qi 12405 = build_function_type_list (opaque_V2SI_type_node, 12406 opaque_V2SI_type_node, 12407 char_type_node, 12408 NULL_TREE); 12409 } 12410 12411 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT 12412 && mode2 == QImode) 12413 { 12414 if (! (type = v2si_ftype_int_qi)) 12415 type = v2si_ftype_int_qi 12416 = build_function_type_list (opaque_V2SI_type_node, 12417 integer_type_node, 12418 char_type_node, 12419 NULL_TREE); 12420 } 12421 12422 else 12423 type = builtin_function_type (mode0, mode1, mode2, VOIDmode, 12424 d->code, d->name); 12425 } 12426 12427 def_builtin (d->mask, d->name, type, d->code); 12428 } 12429 12430 /* Add the simple unary operators. */ 12431 d = (struct builtin_description *) bdesc_1arg; 12432 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++) 12433 { 12434 enum machine_mode mode0, mode1; 12435 tree type; 12436 int mask = d->mask; 12437 12438 if ((mask != 0 && (mask & target_flags) == 0) 12439 || (mask == 0 && !TARGET_PAIRED_FLOAT)) 12440 continue; 12441 12442 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST 12443 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST) 12444 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST 12445 && d->code <= VSX_BUILTIN_OVERLOADED_LAST)) 12446 { 12447 if (! (type = opaque_ftype_opaque)) 12448 type = opaque_ftype_opaque 12449 = build_function_type_list (opaque_V4SI_type_node, 12450 opaque_V4SI_type_node, 12451 NULL_TREE); 12452 } 12453 else 12454 { 12455 enum insn_code icode = d->icode; 12456 if (d->name == 0 || icode == CODE_FOR_nothing) 12457 continue; 12458 12459 mode0 = insn_data[icode].operand[0].mode; 12460 mode1 = insn_data[icode].operand[1].mode; 12461 12462 if (mode0 == V2SImode && mode1 == QImode) 12463 { 12464 if (! (type = v2si_ftype_qi)) 12465 type = v2si_ftype_qi 12466 = build_function_type_list (opaque_V2SI_type_node, 12467 char_type_node, 12468 NULL_TREE); 12469 } 12470 12471 else 12472 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode, 12473 d->code, d->name); 12474 } 12475 12476 def_builtin (d->mask, d->name, type, d->code); 12477 } 12478} 12479 12480static void 12481rs6000_init_libfuncs (void) 12482{ 12483 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF 12484 && !TARGET_POWER2 && !TARGET_POWERPC) 12485 { 12486 /* AIX library routines for float->int conversion. */ 12487 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc"); 12488 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc"); 12489 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc"); 12490 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc"); 12491 } 12492 12493 if (!TARGET_IEEEQUAD) 12494 /* AIX/Darwin/64-bit Linux quad floating point routines. */ 12495 if (!TARGET_XL_COMPAT) 12496 { 12497 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd"); 12498 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub"); 12499 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul"); 12500 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv"); 12501 12502 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE))) 12503 { 12504 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg"); 12505 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq"); 12506 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne"); 12507 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt"); 12508 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge"); 12509 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt"); 12510 set_optab_libfunc (le_optab, TFmode, "__gcc_qle"); 12511 12512 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq"); 12513 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq"); 12514 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos"); 12515 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod"); 12516 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi"); 12517 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou"); 12518 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq"); 12519 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq"); 12520 } 12521 12522 if (!(TARGET_HARD_FLOAT && TARGET_FPRS)) 12523 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord"); 12524 } 12525 else 12526 { 12527 set_optab_libfunc (add_optab, TFmode, "_xlqadd"); 12528 set_optab_libfunc (sub_optab, TFmode, "_xlqsub"); 12529 set_optab_libfunc (smul_optab, TFmode, "_xlqmul"); 12530 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv"); 12531 } 12532 else 12533 { 12534 /* 32-bit SVR4 quad floating point routines. */ 12535 12536 set_optab_libfunc (add_optab, TFmode, "_q_add"); 12537 set_optab_libfunc (sub_optab, TFmode, "_q_sub"); 12538 set_optab_libfunc (neg_optab, TFmode, "_q_neg"); 12539 set_optab_libfunc (smul_optab, TFmode, "_q_mul"); 12540 set_optab_libfunc (sdiv_optab, TFmode, "_q_div"); 12541 if (TARGET_PPC_GPOPT || TARGET_POWER2) 12542 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt"); 12543 12544 set_optab_libfunc (eq_optab, TFmode, "_q_feq"); 12545 set_optab_libfunc (ne_optab, TFmode, "_q_fne"); 12546 set_optab_libfunc (gt_optab, TFmode, "_q_fgt"); 12547 set_optab_libfunc (ge_optab, TFmode, "_q_fge"); 12548 set_optab_libfunc (lt_optab, TFmode, "_q_flt"); 12549 set_optab_libfunc (le_optab, TFmode, "_q_fle"); 12550 12551 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq"); 12552 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq"); 12553 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos"); 12554 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod"); 12555 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi"); 12556 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou"); 12557 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq"); 12558 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq"); 12559 } 12560} 12561 12562 12563/* Expand a block clear operation, and return 1 if successful. Return 0 12564 if we should let the compiler generate normal code. 12565 12566 operands[0] is the destination 12567 operands[1] is the length 12568 operands[3] is the alignment */ 12569 12570int 12571expand_block_clear (rtx operands[]) 12572{ 12573 rtx orig_dest = operands[0]; 12574 rtx bytes_rtx = operands[1]; 12575 rtx align_rtx = operands[3]; 12576 bool constp = (GET_CODE (bytes_rtx) == CONST_INT); 12577 HOST_WIDE_INT align; 12578 HOST_WIDE_INT bytes; 12579 int offset; 12580 int clear_bytes; 12581 int clear_step; 12582 12583 /* If this is not a fixed size move, just call memcpy */ 12584 if (! constp) 12585 return 0; 12586 12587 /* This must be a fixed size alignment */ 12588 gcc_assert (GET_CODE (align_rtx) == CONST_INT); 12589 align = INTVAL (align_rtx) * BITS_PER_UNIT; 12590 12591 /* Anything to clear? */ 12592 bytes = INTVAL (bytes_rtx); 12593 if (bytes <= 0) 12594 return 1; 12595 12596 /* Use the builtin memset after a point, to avoid huge code bloat. 12597 When optimize_size, avoid any significant code bloat; calling 12598 memset is about 4 instructions, so allow for one instruction to 12599 load zero and three to do clearing. */ 12600 if (TARGET_ALTIVEC && align >= 128) 12601 clear_step = 16; 12602 else if (TARGET_POWERPC64 && align >= 32) 12603 clear_step = 8; 12604 else if (TARGET_SPE && align >= 64) 12605 clear_step = 8; 12606 else 12607 clear_step = 4; 12608 12609 if (optimize_size && bytes > 3 * clear_step) 12610 return 0; 12611 if (! optimize_size && bytes > 8 * clear_step) 12612 return 0; 12613 12614 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes) 12615 { 12616 enum machine_mode mode = BLKmode; 12617 rtx dest; 12618 12619 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128) 12620 { 12621 clear_bytes = 16; 12622 mode = V4SImode; 12623 } 12624 else if (bytes >= 8 && TARGET_SPE && align >= 64) 12625 { 12626 clear_bytes = 8; 12627 mode = V2SImode; 12628 } 12629 else if (bytes >= 8 && TARGET_POWERPC64 12630 /* 64-bit loads and stores require word-aligned 12631 displacements. */ 12632 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32))) 12633 { 12634 clear_bytes = 8; 12635 mode = DImode; 12636 } 12637 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT)) 12638 { /* move 4 bytes */ 12639 clear_bytes = 4; 12640 mode = SImode; 12641 } 12642 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT)) 12643 { /* move 2 bytes */ 12644 clear_bytes = 2; 12645 mode = HImode; 12646 } 12647 else /* move 1 byte at a time */ 12648 { 12649 clear_bytes = 1; 12650 mode = QImode; 12651 } 12652 12653 dest = adjust_address (orig_dest, mode, offset); 12654 12655 emit_move_insn (dest, CONST0_RTX (mode)); 12656 } 12657 12658 return 1; 12659} 12660 12661 12662/* Expand a block move operation, and return 1 if successful. Return 0 12663 if we should let the compiler generate normal code. 12664 12665 operands[0] is the destination 12666 operands[1] is the source 12667 operands[2] is the length 12668 operands[3] is the alignment */ 12669 12670#define MAX_MOVE_REG 4 12671 12672int 12673expand_block_move (rtx operands[]) 12674{ 12675 rtx orig_dest = operands[0]; 12676 rtx orig_src = operands[1]; 12677 rtx bytes_rtx = operands[2]; 12678 rtx align_rtx = operands[3]; 12679 int constp = (GET_CODE (bytes_rtx) == CONST_INT); 12680 int align; 12681 int bytes; 12682 int offset; 12683 int move_bytes; 12684 rtx stores[MAX_MOVE_REG]; 12685 int num_reg = 0; 12686 12687 /* If this is not a fixed size move, just call memcpy */ 12688 if (! constp) 12689 return 0; 12690 12691 /* This must be a fixed size alignment */ 12692 gcc_assert (GET_CODE (align_rtx) == CONST_INT); 12693 align = INTVAL (align_rtx) * BITS_PER_UNIT; 12694 12695 /* Anything to move? */ 12696 bytes = INTVAL (bytes_rtx); 12697 if (bytes <= 0) 12698 return 1; 12699 12700 /* store_one_arg depends on expand_block_move to handle at least the size of 12701 reg_parm_stack_space. */ 12702 if (bytes > (TARGET_POWERPC64 ? 64 : 32)) 12703 return 0; 12704 12705 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes) 12706 { 12707 union { 12708 rtx (*movmemsi) (rtx, rtx, rtx, rtx); 12709 rtx (*mov) (rtx, rtx); 12710 } gen_func; 12711 enum machine_mode mode = BLKmode; 12712 rtx src, dest; 12713 12714 /* Altivec first, since it will be faster than a string move 12715 when it applies, and usually not significantly larger. */ 12716 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128) 12717 { 12718 move_bytes = 16; 12719 mode = V4SImode; 12720 gen_func.mov = gen_movv4si; 12721 } 12722 else if (TARGET_SPE && bytes >= 8 && align >= 64) 12723 { 12724 move_bytes = 8; 12725 mode = V2SImode; 12726 gen_func.mov = gen_movv2si; 12727 } 12728 else if (TARGET_STRING 12729 && bytes > 24 /* move up to 32 bytes at a time */ 12730 && ! fixed_regs[5] 12731 && ! fixed_regs[6] 12732 && ! fixed_regs[7] 12733 && ! fixed_regs[8] 12734 && ! fixed_regs[9] 12735 && ! fixed_regs[10] 12736 && ! fixed_regs[11] 12737 && ! fixed_regs[12]) 12738 { 12739 move_bytes = (bytes > 32) ? 32 : bytes; 12740 gen_func.movmemsi = gen_movmemsi_8reg; 12741 } 12742 else if (TARGET_STRING 12743 && bytes > 16 /* move up to 24 bytes at a time */ 12744 && ! fixed_regs[5] 12745 && ! fixed_regs[6] 12746 && ! fixed_regs[7] 12747 && ! fixed_regs[8] 12748 && ! fixed_regs[9] 12749 && ! fixed_regs[10]) 12750 { 12751 move_bytes = (bytes > 24) ? 24 : bytes; 12752 gen_func.movmemsi = gen_movmemsi_6reg; 12753 } 12754 else if (TARGET_STRING 12755 && bytes > 8 /* move up to 16 bytes at a time */ 12756 && ! fixed_regs[5] 12757 && ! fixed_regs[6] 12758 && ! fixed_regs[7] 12759 && ! fixed_regs[8]) 12760 { 12761 move_bytes = (bytes > 16) ? 16 : bytes; 12762 gen_func.movmemsi = gen_movmemsi_4reg; 12763 } 12764 else if (bytes >= 8 && TARGET_POWERPC64 12765 /* 64-bit loads and stores require word-aligned 12766 displacements. */ 12767 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32))) 12768 { 12769 move_bytes = 8; 12770 mode = DImode; 12771 gen_func.mov = gen_movdi; 12772 } 12773 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64) 12774 { /* move up to 8 bytes at a time */ 12775 move_bytes = (bytes > 8) ? 8 : bytes; 12776 gen_func.movmemsi = gen_movmemsi_2reg; 12777 } 12778 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT)) 12779 { /* move 4 bytes */ 12780 move_bytes = 4; 12781 mode = SImode; 12782 gen_func.mov = gen_movsi; 12783 } 12784 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT)) 12785 { /* move 2 bytes */ 12786 move_bytes = 2; 12787 mode = HImode; 12788 gen_func.mov = gen_movhi; 12789 } 12790 else if (TARGET_STRING && bytes > 1) 12791 { /* move up to 4 bytes at a time */ 12792 move_bytes = (bytes > 4) ? 4 : bytes; 12793 gen_func.movmemsi = gen_movmemsi_1reg; 12794 } 12795 else /* move 1 byte at a time */ 12796 { 12797 move_bytes = 1; 12798 mode = QImode; 12799 gen_func.mov = gen_movqi; 12800 } 12801 12802 src = adjust_address (orig_src, mode, offset); 12803 dest = adjust_address (orig_dest, mode, offset); 12804 12805 if (mode != BLKmode) 12806 { 12807 rtx tmp_reg = gen_reg_rtx (mode); 12808 12809 emit_insn ((*gen_func.mov) (tmp_reg, src)); 12810 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg); 12811 } 12812 12813 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes) 12814 { 12815 int i; 12816 for (i = 0; i < num_reg; i++) 12817 emit_insn (stores[i]); 12818 num_reg = 0; 12819 } 12820 12821 if (mode == BLKmode) 12822 { 12823 /* Move the address into scratch registers. The movmemsi 12824 patterns require zero offset. */ 12825 if (!REG_P (XEXP (src, 0))) 12826 { 12827 rtx src_reg = copy_addr_to_reg (XEXP (src, 0)); 12828 src = replace_equiv_address (src, src_reg); 12829 } 12830 set_mem_size (src, GEN_INT (move_bytes)); 12831 12832 if (!REG_P (XEXP (dest, 0))) 12833 { 12834 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0)); 12835 dest = replace_equiv_address (dest, dest_reg); 12836 } 12837 set_mem_size (dest, GEN_INT (move_bytes)); 12838 12839 emit_insn ((*gen_func.movmemsi) (dest, src, 12840 GEN_INT (move_bytes & 31), 12841 align_rtx)); 12842 } 12843 } 12844 12845 return 1; 12846} 12847 12848 12849/* Return a string to perform a load_multiple operation. 12850 operands[0] is the vector. 12851 operands[1] is the source address. 12852 operands[2] is the first destination register. */ 12853 12854const char * 12855rs6000_output_load_multiple (rtx operands[3]) 12856{ 12857 /* We have to handle the case where the pseudo used to contain the address 12858 is assigned to one of the output registers. */ 12859 int i, j; 12860 int words = XVECLEN (operands[0], 0); 12861 rtx xop[10]; 12862 12863 if (XVECLEN (operands[0], 0) == 1) 12864 return "{l|lwz} %2,0(%1)"; 12865 12866 for (i = 0; i < words; i++) 12867 if (refers_to_regno_p (REGNO (operands[2]) + i, 12868 REGNO (operands[2]) + i + 1, operands[1], 0)) 12869 { 12870 if (i == words-1) 12871 { 12872 xop[0] = GEN_INT (4 * (words-1)); 12873 xop[1] = operands[1]; 12874 xop[2] = operands[2]; 12875 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop); 12876 return ""; 12877 } 12878 else if (i == 0) 12879 { 12880 xop[0] = GEN_INT (4 * (words-1)); 12881 xop[1] = operands[1]; 12882 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1); 12883 output_asm_insn ("{cal %1,4(%1)|addi %1,%1,4}\n\t{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,-4(%1)", xop); 12884 return ""; 12885 } 12886 else 12887 { 12888 for (j = 0; j < words; j++) 12889 if (j != i) 12890 { 12891 xop[0] = GEN_INT (j * 4); 12892 xop[1] = operands[1]; 12893 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j); 12894 output_asm_insn ("{l|lwz} %2,%0(%1)", xop); 12895 } 12896 xop[0] = GEN_INT (i * 4); 12897 xop[1] = operands[1]; 12898 output_asm_insn ("{l|lwz} %1,%0(%1)", xop); 12899 return ""; 12900 } 12901 } 12902 12903 return "{lsi|lswi} %2,%1,%N0"; 12904} 12905 12906 12907/* A validation routine: say whether CODE, a condition code, and MODE 12908 match. The other alternatives either don't make sense or should 12909 never be generated. */ 12910 12911void 12912validate_condition_mode (enum rtx_code code, enum machine_mode mode) 12913{ 12914 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE 12915 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE) 12916 && GET_MODE_CLASS (mode) == MODE_CC); 12917 12918 /* These don't make sense. */ 12919 gcc_assert ((code != GT && code != LT && code != GE && code != LE) 12920 || mode != CCUNSmode); 12921 12922 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU) 12923 || mode == CCUNSmode); 12924 12925 gcc_assert (mode == CCFPmode 12926 || (code != ORDERED && code != UNORDERED 12927 && code != UNEQ && code != LTGT 12928 && code != UNGT && code != UNLT 12929 && code != UNGE && code != UNLE)); 12930 12931 /* These should never be generated except for 12932 flag_finite_math_only. */ 12933 gcc_assert (mode != CCFPmode 12934 || flag_finite_math_only 12935 || (code != LE && code != GE 12936 && code != UNEQ && code != LTGT 12937 && code != UNGT && code != UNLT)); 12938 12939 /* These are invalid; the information is not there. */ 12940 gcc_assert (mode != CCEQmode || code == EQ || code == NE); 12941} 12942 12943 12944/* Return 1 if ANDOP is a mask that has no bits on that are not in the 12945 mask required to convert the result of a rotate insn into a shift 12946 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */ 12947 12948int 12949includes_lshift_p (rtx shiftop, rtx andop) 12950{ 12951 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0; 12952 12953 shift_mask <<= INTVAL (shiftop); 12954 12955 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0; 12956} 12957 12958/* Similar, but for right shift. */ 12959 12960int 12961includes_rshift_p (rtx shiftop, rtx andop) 12962{ 12963 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0; 12964 12965 shift_mask >>= INTVAL (shiftop); 12966 12967 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0; 12968} 12969 12970/* Return 1 if ANDOP is a mask suitable for use with an rldic insn 12971 to perform a left shift. It must have exactly SHIFTOP least 12972 significant 0's, then one or more 1's, then zero or more 0's. */ 12973 12974int 12975includes_rldic_lshift_p (rtx shiftop, rtx andop) 12976{ 12977 if (GET_CODE (andop) == CONST_INT) 12978 { 12979 HOST_WIDE_INT c, lsb, shift_mask; 12980 12981 c = INTVAL (andop); 12982 if (c == 0 || c == ~0) 12983 return 0; 12984 12985 shift_mask = ~0; 12986 shift_mask <<= INTVAL (shiftop); 12987 12988 /* Find the least significant one bit. */ 12989 lsb = c & -c; 12990 12991 /* It must coincide with the LSB of the shift mask. */ 12992 if (-lsb != shift_mask) 12993 return 0; 12994 12995 /* Invert to look for the next transition (if any). */ 12996 c = ~c; 12997 12998 /* Remove the low group of ones (originally low group of zeros). */ 12999 c &= -lsb; 13000 13001 /* Again find the lsb, and check we have all 1's above. */ 13002 lsb = c & -c; 13003 return c == -lsb; 13004 } 13005 else if (GET_CODE (andop) == CONST_DOUBLE 13006 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode)) 13007 { 13008 HOST_WIDE_INT low, high, lsb; 13009 HOST_WIDE_INT shift_mask_low, shift_mask_high; 13010 13011 low = CONST_DOUBLE_LOW (andop); 13012 if (HOST_BITS_PER_WIDE_INT < 64) 13013 high = CONST_DOUBLE_HIGH (andop); 13014 13015 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0)) 13016 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0))) 13017 return 0; 13018 13019 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0) 13020 { 13021 shift_mask_high = ~0; 13022 if (INTVAL (shiftop) > 32) 13023 shift_mask_high <<= INTVAL (shiftop) - 32; 13024 13025 lsb = high & -high; 13026 13027 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32) 13028 return 0; 13029 13030 high = ~high; 13031 high &= -lsb; 13032 13033 lsb = high & -high; 13034 return high == -lsb; 13035 } 13036 13037 shift_mask_low = ~0; 13038 shift_mask_low <<= INTVAL (shiftop); 13039 13040 lsb = low & -low; 13041 13042 if (-lsb != shift_mask_low) 13043 return 0; 13044 13045 if (HOST_BITS_PER_WIDE_INT < 64) 13046 high = ~high; 13047 low = ~low; 13048 low &= -lsb; 13049 13050 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0) 13051 { 13052 lsb = high & -high; 13053 return high == -lsb; 13054 } 13055 13056 lsb = low & -low; 13057 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0); 13058 } 13059 else 13060 return 0; 13061} 13062 13063/* Return 1 if ANDOP is a mask suitable for use with an rldicr insn 13064 to perform a left shift. It must have SHIFTOP or more least 13065 significant 0's, with the remainder of the word 1's. */ 13066 13067int 13068includes_rldicr_lshift_p (rtx shiftop, rtx andop) 13069{ 13070 if (GET_CODE (andop) == CONST_INT) 13071 { 13072 HOST_WIDE_INT c, lsb, shift_mask; 13073 13074 shift_mask = ~0; 13075 shift_mask <<= INTVAL (shiftop); 13076 c = INTVAL (andop); 13077 13078 /* Find the least significant one bit. */ 13079 lsb = c & -c; 13080 13081 /* It must be covered by the shift mask. 13082 This test also rejects c == 0. */ 13083 if ((lsb & shift_mask) == 0) 13084 return 0; 13085 13086 /* Check we have all 1's above the transition, and reject all 1's. */ 13087 return c == -lsb && lsb != 1; 13088 } 13089 else if (GET_CODE (andop) == CONST_DOUBLE 13090 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode)) 13091 { 13092 HOST_WIDE_INT low, lsb, shift_mask_low; 13093 13094 low = CONST_DOUBLE_LOW (andop); 13095 13096 if (HOST_BITS_PER_WIDE_INT < 64) 13097 { 13098 HOST_WIDE_INT high, shift_mask_high; 13099 13100 high = CONST_DOUBLE_HIGH (andop); 13101 13102 if (low == 0) 13103 { 13104 shift_mask_high = ~0; 13105 if (INTVAL (shiftop) > 32) 13106 shift_mask_high <<= INTVAL (shiftop) - 32; 13107 13108 lsb = high & -high; 13109 13110 if ((lsb & shift_mask_high) == 0) 13111 return 0; 13112 13113 return high == -lsb; 13114 } 13115 if (high != ~0) 13116 return 0; 13117 } 13118 13119 shift_mask_low = ~0; 13120 shift_mask_low <<= INTVAL (shiftop); 13121 13122 lsb = low & -low; 13123 13124 if ((lsb & shift_mask_low) == 0) 13125 return 0; 13126 13127 return low == -lsb && lsb != 1; 13128 } 13129 else 13130 return 0; 13131} 13132 13133/* Return 1 if operands will generate a valid arguments to rlwimi 13134instruction for insert with right shift in 64-bit mode. The mask may 13135not start on the first bit or stop on the last bit because wrap-around 13136effects of instruction do not correspond to semantics of RTL insn. */ 13137 13138int 13139insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop) 13140{ 13141 if (INTVAL (startop) > 32 13142 && INTVAL (startop) < 64 13143 && INTVAL (sizeop) > 1 13144 && INTVAL (sizeop) + INTVAL (startop) < 64 13145 && INTVAL (shiftop) > 0 13146 && INTVAL (sizeop) + INTVAL (shiftop) < 32 13147 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop)) 13148 return 1; 13149 13150 return 0; 13151} 13152 13153/* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates 13154 for lfq and stfq insns iff the registers are hard registers. */ 13155 13156int 13157registers_ok_for_quad_peep (rtx reg1, rtx reg2) 13158{ 13159 /* We might have been passed a SUBREG. */ 13160 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG) 13161 return 0; 13162 13163 /* We might have been passed non floating point registers. */ 13164 if (!FP_REGNO_P (REGNO (reg1)) 13165 || !FP_REGNO_P (REGNO (reg2))) 13166 return 0; 13167 13168 return (REGNO (reg1) == REGNO (reg2) - 1); 13169} 13170 13171/* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn. 13172 addr1 and addr2 must be in consecutive memory locations 13173 (addr2 == addr1 + 8). */ 13174 13175int 13176mems_ok_for_quad_peep (rtx mem1, rtx mem2) 13177{ 13178 rtx addr1, addr2; 13179 unsigned int reg1, reg2; 13180 int offset1, offset2; 13181 13182 /* The mems cannot be volatile. */ 13183 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2)) 13184 return 0; 13185 13186 addr1 = XEXP (mem1, 0); 13187 addr2 = XEXP (mem2, 0); 13188 13189 /* Extract an offset (if used) from the first addr. */ 13190 if (GET_CODE (addr1) == PLUS) 13191 { 13192 /* If not a REG, return zero. */ 13193 if (GET_CODE (XEXP (addr1, 0)) != REG) 13194 return 0; 13195 else 13196 { 13197 reg1 = REGNO (XEXP (addr1, 0)); 13198 /* The offset must be constant! */ 13199 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT) 13200 return 0; 13201 offset1 = INTVAL (XEXP (addr1, 1)); 13202 } 13203 } 13204 else if (GET_CODE (addr1) != REG) 13205 return 0; 13206 else 13207 { 13208 reg1 = REGNO (addr1); 13209 /* This was a simple (mem (reg)) expression. Offset is 0. */ 13210 offset1 = 0; 13211 } 13212 13213 /* And now for the second addr. */ 13214 if (GET_CODE (addr2) == PLUS) 13215 { 13216 /* If not a REG, return zero. */ 13217 if (GET_CODE (XEXP (addr2, 0)) != REG) 13218 return 0; 13219 else 13220 { 13221 reg2 = REGNO (XEXP (addr2, 0)); 13222 /* The offset must be constant. */ 13223 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT) 13224 return 0; 13225 offset2 = INTVAL (XEXP (addr2, 1)); 13226 } 13227 } 13228 else if (GET_CODE (addr2) != REG) 13229 return 0; 13230 else 13231 { 13232 reg2 = REGNO (addr2); 13233 /* This was a simple (mem (reg)) expression. Offset is 0. */ 13234 offset2 = 0; 13235 } 13236 13237 /* Both of these must have the same base register. */ 13238 if (reg1 != reg2) 13239 return 0; 13240 13241 /* The offset for the second addr must be 8 more than the first addr. */ 13242 if (offset2 != offset1 + 8) 13243 return 0; 13244 13245 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq 13246 instructions. */ 13247 return 1; 13248} 13249 13250 13251rtx 13252rs6000_secondary_memory_needed_rtx (enum machine_mode mode) 13253{ 13254 static bool eliminated = false; 13255 rtx ret; 13256 13257 if (mode != SDmode) 13258 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0); 13259 else 13260 { 13261 rtx mem = cfun->machine->sdmode_stack_slot; 13262 gcc_assert (mem != NULL_RTX); 13263 13264 if (!eliminated) 13265 { 13266 mem = eliminate_regs (mem, VOIDmode, NULL_RTX); 13267 cfun->machine->sdmode_stack_slot = mem; 13268 eliminated = true; 13269 } 13270 ret = mem; 13271 } 13272 13273 if (TARGET_DEBUG_ADDR) 13274 { 13275 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n", 13276 GET_MODE_NAME (mode)); 13277 if (!ret) 13278 fprintf (stderr, "\tNULL_RTX\n"); 13279 else 13280 debug_rtx (ret); 13281 } 13282 13283 return ret; 13284} 13285 13286static tree 13287rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) 13288{ 13289 /* Don't walk into types. */ 13290 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp)) 13291 { 13292 *walk_subtrees = 0; 13293 return NULL_TREE; 13294 } 13295 13296 switch (TREE_CODE (*tp)) 13297 { 13298 case VAR_DECL: 13299 case PARM_DECL: 13300 case FIELD_DECL: 13301 case RESULT_DECL: 13302 case SSA_NAME: 13303 case REAL_CST: 13304 case INDIRECT_REF: 13305 case ALIGN_INDIRECT_REF: 13306 case MISALIGNED_INDIRECT_REF: 13307 case VIEW_CONVERT_EXPR: 13308 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode) 13309 return *tp; 13310 break; 13311 default: 13312 break; 13313 } 13314 13315 return NULL_TREE; 13316} 13317 13318enum reload_reg_type { 13319 GPR_REGISTER_TYPE, 13320 VECTOR_REGISTER_TYPE, 13321 OTHER_REGISTER_TYPE 13322}; 13323 13324static enum reload_reg_type 13325rs6000_reload_register_type (enum reg_class rclass) 13326{ 13327 switch (rclass) 13328 { 13329 case GENERAL_REGS: 13330 case BASE_REGS: 13331 return GPR_REGISTER_TYPE; 13332 13333 case FLOAT_REGS: 13334 case ALTIVEC_REGS: 13335 case VSX_REGS: 13336 return VECTOR_REGISTER_TYPE; 13337 13338 default: 13339 return OTHER_REGISTER_TYPE; 13340 } 13341} 13342 13343/* Inform reload about cases where moving X with a mode MODE to a register in 13344 RCLASS requires an extra scratch or immediate register. Return the class 13345 needed for the immediate register. 13346 13347 For VSX and Altivec, we may need a register to convert sp+offset into 13348 reg+sp. */ 13349 13350static enum reg_class 13351rs6000_secondary_reload (bool in_p, 13352 rtx x, 13353 enum reg_class rclass, 13354 enum machine_mode mode, 13355 secondary_reload_info *sri) 13356{ 13357 enum reg_class ret = ALL_REGS; 13358 enum insn_code icode; 13359 bool default_p = false; 13360 13361 sri->icode = CODE_FOR_nothing; 13362 13363 /* Convert vector loads and stores into gprs to use an additional base 13364 register. */ 13365 icode = rs6000_vector_reload[mode][in_p != false]; 13366 if (icode != CODE_FOR_nothing) 13367 { 13368 ret = NO_REGS; 13369 sri->icode = CODE_FOR_nothing; 13370 sri->extra_cost = 0; 13371 13372 if (GET_CODE (x) == MEM) 13373 { 13374 rtx addr = XEXP (x, 0); 13375 13376 /* Loads to and stores from gprs can do reg+offset, and wouldn't need 13377 an extra register in that case, but it would need an extra 13378 register if the addressing is reg+reg or (reg+reg)&(-16). */ 13379 if (rclass == GENERAL_REGS || rclass == BASE_REGS) 13380 { 13381 if (!legitimate_indirect_address_p (addr, false) 13382 && !rs6000_legitimate_offset_address_p (TImode, addr, false)) 13383 { 13384 sri->icode = icode; 13385 /* account for splitting the loads, and converting the 13386 address from reg+reg to reg. */ 13387 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5) 13388 + ((GET_CODE (addr) == AND) ? 1 : 0)); 13389 } 13390 } 13391 /* Loads to and stores from vector registers can only do reg+reg 13392 addressing. Altivec registers can also do (reg+reg)&(-16). */ 13393 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS 13394 || rclass == FLOAT_REGS || rclass == NO_REGS) 13395 { 13396 if (!VECTOR_MEM_ALTIVEC_P (mode) 13397 && GET_CODE (addr) == AND 13398 && GET_CODE (XEXP (addr, 1)) == CONST_INT 13399 && INTVAL (XEXP (addr, 1)) == -16 13400 && (legitimate_indirect_address_p (XEXP (addr, 0), false) 13401 || legitimate_indexed_address_p (XEXP (addr, 0), false))) 13402 { 13403 sri->icode = icode; 13404 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS) 13405 ? 2 : 1); 13406 } 13407 else if (!legitimate_indirect_address_p (addr, false) 13408 && (rclass == NO_REGS 13409 || !legitimate_indexed_address_p (addr, false))) 13410 { 13411 sri->icode = icode; 13412 sri->extra_cost = 1; 13413 } 13414 else 13415 icode = CODE_FOR_nothing; 13416 } 13417 /* Any other loads, including to pseudo registers which haven't been 13418 assigned to a register yet, default to require a scratch 13419 register. */ 13420 else 13421 { 13422 sri->icode = icode; 13423 sri->extra_cost = 2; 13424 } 13425 } 13426 else if (REG_P (x)) 13427 { 13428 int regno = true_regnum (x); 13429 13430 icode = CODE_FOR_nothing; 13431 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER) 13432 default_p = true; 13433 else 13434 { 13435 enum reg_class xclass = REGNO_REG_CLASS (regno); 13436 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass); 13437 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass); 13438 13439 /* If memory is needed, use default_secondary_reload to create the 13440 stack slot. */ 13441 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE) 13442 default_p = true; 13443 else 13444 ret = NO_REGS; 13445 } 13446 } 13447 else 13448 default_p = true; 13449 } 13450 else 13451 default_p = true; 13452 13453 if (default_p) 13454 ret = default_secondary_reload (in_p, x, rclass, mode, sri); 13455 13456 gcc_assert (ret != ALL_REGS); 13457 13458 if (TARGET_DEBUG_ADDR) 13459 { 13460 fprintf (stderr, 13461 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, " 13462 "mode = %s", 13463 reg_class_names[ret], 13464 in_p ? "true" : "false", 13465 reg_class_names[rclass], 13466 GET_MODE_NAME (mode)); 13467 13468 if (default_p) 13469 fprintf (stderr, ", default secondary reload"); 13470 13471 if (sri->icode != CODE_FOR_nothing) 13472 fprintf (stderr, ", reload func = %s, extra cost = %d\n", 13473 insn_data[sri->icode].name, sri->extra_cost); 13474 else 13475 fprintf (stderr, "\n"); 13476 13477 debug_rtx (x); 13478 } 13479 13480 return ret; 13481} 13482 13483/* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset 13484 to SP+reg addressing. */ 13485 13486void 13487rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p) 13488{ 13489 int regno = true_regnum (reg); 13490 enum machine_mode mode = GET_MODE (reg); 13491 enum reg_class rclass; 13492 rtx addr; 13493 rtx and_op2 = NULL_RTX; 13494 rtx addr_op1; 13495 rtx addr_op2; 13496 rtx scratch_or_premodify = scratch; 13497 rtx and_rtx; 13498 rtx cc_clobber; 13499 13500 if (TARGET_DEBUG_ADDR) 13501 { 13502 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n", 13503 store_p ? "store" : "load"); 13504 fprintf (stderr, "reg:\n"); 13505 debug_rtx (reg); 13506 fprintf (stderr, "mem:\n"); 13507 debug_rtx (mem); 13508 fprintf (stderr, "scratch:\n"); 13509 debug_rtx (scratch); 13510 } 13511 13512 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER); 13513 gcc_assert (GET_CODE (mem) == MEM); 13514 rclass = REGNO_REG_CLASS (regno); 13515 addr = XEXP (mem, 0); 13516 13517 switch (rclass) 13518 { 13519 /* GPRs can handle reg + small constant, all other addresses need to use 13520 the scratch register. */ 13521 case GENERAL_REGS: 13522 case BASE_REGS: 13523 if (GET_CODE (addr) == AND) 13524 { 13525 and_op2 = XEXP (addr, 1); 13526 addr = XEXP (addr, 0); 13527 } 13528 13529 if (GET_CODE (addr) == PRE_MODIFY) 13530 { 13531 scratch_or_premodify = XEXP (addr, 0); 13532 gcc_assert (REG_P (scratch_or_premodify)); 13533 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS); 13534 addr = XEXP (addr, 1); 13535 } 13536 13537 if (GET_CODE (addr) == PLUS 13538 && (!rs6000_legitimate_offset_address_p (TImode, addr, false) 13539 || and_op2 != NULL_RTX)) 13540 { 13541 addr_op1 = XEXP (addr, 0); 13542 addr_op2 = XEXP (addr, 1); 13543 gcc_assert (legitimate_indirect_address_p (addr_op1, false)); 13544 13545 if (!REG_P (addr_op2) 13546 && (GET_CODE (addr_op2) != CONST_INT 13547 || !satisfies_constraint_I (addr_op2))) 13548 { 13549 if (TARGET_DEBUG_ADDR) 13550 { 13551 fprintf (stderr, 13552 "\nMove plus addr to register %s, mode = %s: ", 13553 rs6000_reg_names[REGNO (scratch)], 13554 GET_MODE_NAME (mode)); 13555 debug_rtx (addr_op2); 13556 } 13557 rs6000_emit_move (scratch, addr_op2, Pmode); 13558 addr_op2 = scratch; 13559 } 13560 13561 emit_insn (gen_rtx_SET (VOIDmode, 13562 scratch_or_premodify, 13563 gen_rtx_PLUS (Pmode, 13564 addr_op1, 13565 addr_op2))); 13566 13567 addr = scratch_or_premodify; 13568 scratch_or_premodify = scratch; 13569 } 13570 else if (!legitimate_indirect_address_p (addr, false) 13571 && !rs6000_legitimate_offset_address_p (TImode, addr, false)) 13572 { 13573 if (TARGET_DEBUG_ADDR) 13574 { 13575 fprintf (stderr, "\nMove addr to register %s, mode = %s: ", 13576 rs6000_reg_names[REGNO (scratch_or_premodify)], 13577 GET_MODE_NAME (mode)); 13578 debug_rtx (addr); 13579 } 13580 rs6000_emit_move (scratch_or_premodify, addr, Pmode); 13581 addr = scratch_or_premodify; 13582 scratch_or_premodify = scratch; 13583 } 13584 break; 13585 13586 /* Float/Altivec registers can only handle reg+reg addressing. Move 13587 other addresses into a scratch register. */ 13588 case FLOAT_REGS: 13589 case VSX_REGS: 13590 case ALTIVEC_REGS: 13591 13592 /* With float regs, we need to handle the AND ourselves, since we can't 13593 use the Altivec instruction with an implicit AND -16. Allow scalar 13594 loads to float registers to use reg+offset even if VSX. */ 13595 if (GET_CODE (addr) == AND 13596 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16 13597 || GET_CODE (XEXP (addr, 1)) != CONST_INT 13598 || INTVAL (XEXP (addr, 1)) != -16 13599 || !VECTOR_MEM_ALTIVEC_P (mode))) 13600 { 13601 and_op2 = XEXP (addr, 1); 13602 addr = XEXP (addr, 0); 13603 } 13604 13605 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it 13606 as the address later. */ 13607 if (GET_CODE (addr) == PRE_MODIFY 13608 && (!VECTOR_MEM_VSX_P (mode) 13609 || and_op2 != NULL_RTX 13610 || !legitimate_indexed_address_p (XEXP (addr, 1), false))) 13611 { 13612 scratch_or_premodify = XEXP (addr, 0); 13613 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify, 13614 false)); 13615 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS); 13616 addr = XEXP (addr, 1); 13617 } 13618 13619 if (legitimate_indirect_address_p (addr, false) /* reg */ 13620 || legitimate_indexed_address_p (addr, false) /* reg+reg */ 13621 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */ 13622 || (GET_CODE (addr) == AND /* Altivec memory */ 13623 && GET_CODE (XEXP (addr, 1)) == CONST_INT 13624 && INTVAL (XEXP (addr, 1)) == -16 13625 && VECTOR_MEM_ALTIVEC_P (mode)) 13626 || (rclass == FLOAT_REGS /* legacy float mem */ 13627 && GET_MODE_SIZE (mode) == 8 13628 && and_op2 == NULL_RTX 13629 && scratch_or_premodify == scratch 13630 && rs6000_legitimate_offset_address_p (mode, addr, false))) 13631 ; 13632 13633 else if (GET_CODE (addr) == PLUS) 13634 { 13635 addr_op1 = XEXP (addr, 0); 13636 addr_op2 = XEXP (addr, 1); 13637 gcc_assert (REG_P (addr_op1)); 13638 13639 if (TARGET_DEBUG_ADDR) 13640 { 13641 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ", 13642 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode)); 13643 debug_rtx (addr_op2); 13644 } 13645 rs6000_emit_move (scratch, addr_op2, Pmode); 13646 emit_insn (gen_rtx_SET (VOIDmode, 13647 scratch_or_premodify, 13648 gen_rtx_PLUS (Pmode, 13649 addr_op1, 13650 scratch))); 13651 addr = scratch_or_premodify; 13652 scratch_or_premodify = scratch; 13653 } 13654 13655 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST 13656 || GET_CODE (addr) == CONST_INT || REG_P (addr)) 13657 { 13658 if (TARGET_DEBUG_ADDR) 13659 { 13660 fprintf (stderr, "\nMove addr to register %s, mode = %s: ", 13661 rs6000_reg_names[REGNO (scratch_or_premodify)], 13662 GET_MODE_NAME (mode)); 13663 debug_rtx (addr); 13664 } 13665 13666 rs6000_emit_move (scratch_or_premodify, addr, Pmode); 13667 addr = scratch_or_premodify; 13668 scratch_or_premodify = scratch; 13669 } 13670 13671 else 13672 gcc_unreachable (); 13673 13674 break; 13675 13676 default: 13677 gcc_unreachable (); 13678 } 13679 13680 /* If the original address involved a pre-modify that we couldn't use the VSX 13681 memory instruction with update, and we haven't taken care of already, 13682 store the address in the pre-modify register and use that as the 13683 address. */ 13684 if (scratch_or_premodify != scratch && scratch_or_premodify != addr) 13685 { 13686 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr)); 13687 addr = scratch_or_premodify; 13688 } 13689 13690 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC 13691 memory instruction, recreate the AND now, including the clobber which is 13692 generated by the general ANDSI3/ANDDI3 patterns for the 13693 andi. instruction. */ 13694 if (and_op2 != NULL_RTX) 13695 { 13696 if (! legitimate_indirect_address_p (addr, false)) 13697 { 13698 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr)); 13699 addr = scratch; 13700 } 13701 13702 if (TARGET_DEBUG_ADDR) 13703 { 13704 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ", 13705 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode)); 13706 debug_rtx (and_op2); 13707 } 13708 13709 and_rtx = gen_rtx_SET (VOIDmode, 13710 scratch, 13711 gen_rtx_AND (Pmode, 13712 addr, 13713 and_op2)); 13714 13715 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode)); 13716 emit_insn (gen_rtx_PARALLEL (VOIDmode, 13717 gen_rtvec (2, and_rtx, cc_clobber))); 13718 addr = scratch; 13719 } 13720 13721 /* Adjust the address if it changed. */ 13722 if (addr != XEXP (mem, 0)) 13723 { 13724 mem = change_address (mem, mode, addr); 13725 if (TARGET_DEBUG_ADDR) 13726 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n"); 13727 } 13728 13729 /* Now create the move. */ 13730 if (store_p) 13731 emit_insn (gen_rtx_SET (VOIDmode, mem, reg)); 13732 else 13733 emit_insn (gen_rtx_SET (VOIDmode, reg, mem)); 13734 13735 return; 13736} 13737 13738/* Target hook to return the cover classes for Integrated Register Allocator. 13739 Cover classes is a set of non-intersected register classes covering all hard 13740 registers used for register allocation purpose. Any move between two 13741 registers of a cover class should be cheaper than load or store of the 13742 registers. The value is array of register classes with LIM_REG_CLASSES used 13743 as the end marker. 13744 13745 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to 13746 account for the Altivec and Floating registers being subsets of the VSX 13747 register set under VSX, but distinct register sets on pre-VSX machines. */ 13748 13749static const enum reg_class * 13750rs6000_ira_cover_classes (void) 13751{ 13752 static const enum reg_class cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX; 13753 static const enum reg_class cover_vsx[] = IRA_COVER_CLASSES_VSX; 13754 13755 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx; 13756} 13757 13758/* Allocate a 64-bit stack slot to be used for copying SDmode 13759 values through if this function has any SDmode references. */ 13760 13761static void 13762rs6000_alloc_sdmode_stack_slot (void) 13763{ 13764 tree t; 13765 basic_block bb; 13766 gimple_stmt_iterator gsi; 13767 13768 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX); 13769 13770 FOR_EACH_BB (bb) 13771 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) 13772 { 13773 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL); 13774 if (ret) 13775 { 13776 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0); 13777 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack, 13778 SDmode, 0); 13779 return; 13780 } 13781 } 13782 13783 /* Check for any SDmode parameters of the function. */ 13784 for (t = DECL_ARGUMENTS (cfun->decl); t; t = TREE_CHAIN (t)) 13785 { 13786 if (TREE_TYPE (t) == error_mark_node) 13787 continue; 13788 13789 if (TYPE_MODE (TREE_TYPE (t)) == SDmode 13790 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode) 13791 { 13792 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0); 13793 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack, 13794 SDmode, 0); 13795 return; 13796 } 13797 } 13798} 13799 13800static void 13801rs6000_instantiate_decls (void) 13802{ 13803 if (cfun->machine->sdmode_stack_slot != NULL_RTX) 13804 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot); 13805} 13806 13807/* Given an rtx X being reloaded into a reg required to be 13808 in class CLASS, return the class of reg to actually use. 13809 In general this is just CLASS; but on some machines 13810 in some cases it is preferable to use a more restrictive class. 13811 13812 On the RS/6000, we have to return NO_REGS when we want to reload a 13813 floating-point CONST_DOUBLE to force it to be copied to memory. 13814 13815 We also don't want to reload integer values into floating-point 13816 registers if we can at all help it. In fact, this can 13817 cause reload to die, if it tries to generate a reload of CTR 13818 into a FP register and discovers it doesn't have the memory location 13819 required. 13820 13821 ??? Would it be a good idea to have reload do the converse, that is 13822 try to reload floating modes into FP registers if possible? 13823 */ 13824 13825static enum reg_class 13826rs6000_preferred_reload_class (rtx x, enum reg_class rclass) 13827{ 13828 enum machine_mode mode = GET_MODE (x); 13829 13830 if (VECTOR_UNIT_VSX_P (mode) 13831 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass)) 13832 return rclass; 13833 13834 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode) 13835 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS) 13836 && easy_vector_constant (x, mode)) 13837 return ALTIVEC_REGS; 13838 13839 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS)) 13840 return NO_REGS; 13841 13842 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS) 13843 return GENERAL_REGS; 13844 13845 /* For VSX, prefer the traditional registers for DF if the address is of the 13846 form reg+offset because we can use the non-VSX loads. Prefer the Altivec 13847 registers if Altivec is handling the vector operations (i.e. V16QI, V8HI, 13848 and V4SI). */ 13849 if (rclass == VSX_REGS && VECTOR_MEM_VSX_P (mode)) 13850 { 13851 if (mode == DFmode && GET_CODE (x) == MEM) 13852 { 13853 rtx addr = XEXP (x, 0); 13854 13855 if (legitimate_indirect_address_p (addr, false)) /* reg */ 13856 return VSX_REGS; 13857 13858 if (legitimate_indexed_address_p (addr, false)) /* reg+reg */ 13859 return VSX_REGS; 13860 13861 if (GET_CODE (addr) == PRE_MODIFY 13862 && legitimate_indexed_address_p (XEXP (addr, 0), false)) 13863 return VSX_REGS; 13864 13865 return FLOAT_REGS; 13866 } 13867 13868 if (VECTOR_UNIT_ALTIVEC_P (mode)) 13869 return ALTIVEC_REGS; 13870 13871 return rclass; 13872 } 13873 13874 return rclass; 13875} 13876 13877/* Debug version of rs6000_preferred_reload_class. */ 13878static enum reg_class 13879rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass) 13880{ 13881 enum reg_class ret = rs6000_preferred_reload_class (x, rclass); 13882 13883 fprintf (stderr, 13884 "\nrs6000_preferred_reload_class, return %s, rclass = %s, " 13885 "mode = %s, x:\n", 13886 reg_class_names[ret], reg_class_names[rclass], 13887 GET_MODE_NAME (GET_MODE (x))); 13888 debug_rtx (x); 13889 13890 return ret; 13891} 13892 13893/* If we are copying between FP or AltiVec registers and anything else, we need 13894 a memory location. The exception is when we are targeting ppc64 and the 13895 move to/from fpr to gpr instructions are available. Also, under VSX, you 13896 can copy vector registers from the FP register set to the Altivec register 13897 set and vice versa. */ 13898 13899static bool 13900rs6000_secondary_memory_needed (enum reg_class class1, 13901 enum reg_class class2, 13902 enum machine_mode mode) 13903{ 13904 if (class1 == class2) 13905 return false; 13906 13907 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS, 13908 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy 13909 between these classes. But we need memory for other things that can go in 13910 FLOAT_REGS like SFmode. */ 13911 if (TARGET_VSX 13912 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode)) 13913 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS 13914 || class1 == FLOAT_REGS)) 13915 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS 13916 && class2 != FLOAT_REGS); 13917 13918 if (class1 == VSX_REGS || class2 == VSX_REGS) 13919 return true; 13920 13921 if (class1 == FLOAT_REGS 13922 && (!TARGET_MFPGPR || !TARGET_POWERPC64 13923 || ((mode != DFmode) 13924 && (mode != DDmode) 13925 && (mode != DImode)))) 13926 return true; 13927 13928 if (class2 == FLOAT_REGS 13929 && (!TARGET_MFPGPR || !TARGET_POWERPC64 13930 || ((mode != DFmode) 13931 && (mode != DDmode) 13932 && (mode != DImode)))) 13933 return true; 13934 13935 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS) 13936 return true; 13937 13938 return false; 13939} 13940 13941/* Debug version of rs6000_secondary_memory_needed. */ 13942static bool 13943rs6000_debug_secondary_memory_needed (enum reg_class class1, 13944 enum reg_class class2, 13945 enum machine_mode mode) 13946{ 13947 bool ret = rs6000_secondary_memory_needed (class1, class2, mode); 13948 13949 fprintf (stderr, 13950 "rs6000_secondary_memory_needed, return: %s, class1 = %s, " 13951 "class2 = %s, mode = %s\n", 13952 ret ? "true" : "false", reg_class_names[class1], 13953 reg_class_names[class2], GET_MODE_NAME (mode)); 13954 13955 return ret; 13956} 13957 13958/* Return the register class of a scratch register needed to copy IN into 13959 or out of a register in RCLASS in MODE. If it can be done directly, 13960 NO_REGS is returned. */ 13961 13962static enum reg_class 13963rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode, 13964 rtx in) 13965{ 13966 int regno; 13967 13968 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN 13969#if TARGET_MACHO 13970 && MACHOPIC_INDIRECT 13971#endif 13972 )) 13973 { 13974 /* We cannot copy a symbolic operand directly into anything 13975 other than BASE_REGS for TARGET_ELF. So indicate that a 13976 register from BASE_REGS is needed as an intermediate 13977 register. 13978 13979 On Darwin, pic addresses require a load from memory, which 13980 needs a base register. */ 13981 if (rclass != BASE_REGS 13982 && (GET_CODE (in) == SYMBOL_REF 13983 || GET_CODE (in) == HIGH 13984 || GET_CODE (in) == LABEL_REF 13985 || GET_CODE (in) == CONST)) 13986 return BASE_REGS; 13987 } 13988 13989 if (GET_CODE (in) == REG) 13990 { 13991 regno = REGNO (in); 13992 if (regno >= FIRST_PSEUDO_REGISTER) 13993 { 13994 regno = true_regnum (in); 13995 if (regno >= FIRST_PSEUDO_REGISTER) 13996 regno = -1; 13997 } 13998 } 13999 else if (GET_CODE (in) == SUBREG) 14000 { 14001 regno = true_regnum (in); 14002 if (regno >= FIRST_PSEUDO_REGISTER) 14003 regno = -1; 14004 } 14005 else 14006 regno = -1; 14007 14008 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS 14009 into anything. */ 14010 if (rclass == GENERAL_REGS || rclass == BASE_REGS 14011 || (regno >= 0 && INT_REGNO_P (regno))) 14012 return NO_REGS; 14013 14014 /* Constants, memory, and FP registers can go into FP registers. */ 14015 if ((regno == -1 || FP_REGNO_P (regno)) 14016 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS)) 14017 return (mode != SDmode) ? NO_REGS : GENERAL_REGS; 14018 14019 /* Memory, and FP/altivec registers can go into fp/altivec registers under 14020 VSX. */ 14021 if (TARGET_VSX 14022 && (regno == -1 || VSX_REGNO_P (regno)) 14023 && VSX_REG_CLASS_P (rclass)) 14024 return NO_REGS; 14025 14026 /* Memory, and AltiVec registers can go into AltiVec registers. */ 14027 if ((regno == -1 || ALTIVEC_REGNO_P (regno)) 14028 && rclass == ALTIVEC_REGS) 14029 return NO_REGS; 14030 14031 /* We can copy among the CR registers. */ 14032 if ((rclass == CR_REGS || rclass == CR0_REGS) 14033 && regno >= 0 && CR_REGNO_P (regno)) 14034 return NO_REGS; 14035 14036 /* Otherwise, we need GENERAL_REGS. */ 14037 return GENERAL_REGS; 14038} 14039 14040/* Debug version of rs6000_secondary_reload_class. */ 14041static enum reg_class 14042rs6000_debug_secondary_reload_class (enum reg_class rclass, 14043 enum machine_mode mode, rtx in) 14044{ 14045 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in); 14046 fprintf (stderr, 14047 "\nrs6000_secondary_reload_class, return %s, rclass = %s, " 14048 "mode = %s, input rtx:\n", 14049 reg_class_names[ret], reg_class_names[rclass], 14050 GET_MODE_NAME (mode)); 14051 debug_rtx (in); 14052 14053 return ret; 14054} 14055 14056/* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */ 14057 14058static bool 14059rs6000_cannot_change_mode_class (enum machine_mode from, 14060 enum machine_mode to, 14061 enum reg_class rclass) 14062{ 14063 unsigned from_size = GET_MODE_SIZE (from); 14064 unsigned to_size = GET_MODE_SIZE (to); 14065 14066 if (from_size != to_size) 14067 { 14068 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS; 14069 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD) 14070 && reg_classes_intersect_p (xclass, rclass)); 14071 } 14072 14073 if (TARGET_E500_DOUBLE 14074 && ((((to) == DFmode) + ((from) == DFmode)) == 1 14075 || (((to) == TFmode) + ((from) == TFmode)) == 1 14076 || (((to) == DDmode) + ((from) == DDmode)) == 1 14077 || (((to) == TDmode) + ((from) == TDmode)) == 1 14078 || (((to) == DImode) + ((from) == DImode)) == 1)) 14079 return true; 14080 14081 /* Since the VSX register set includes traditional floating point registers 14082 and altivec registers, just check for the size being different instead of 14083 trying to check whether the modes are vector modes. Otherwise it won't 14084 allow say DF and DI to change classes. */ 14085 if (TARGET_VSX && VSX_REG_CLASS_P (rclass)) 14086 return (from_size != 8 && from_size != 16); 14087 14088 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS 14089 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1) 14090 return true; 14091 14092 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1 14093 && reg_classes_intersect_p (GENERAL_REGS, rclass)) 14094 return true; 14095 14096 return false; 14097} 14098 14099/* Debug version of rs6000_cannot_change_mode_class. */ 14100static bool 14101rs6000_debug_cannot_change_mode_class (enum machine_mode from, 14102 enum machine_mode to, 14103 enum reg_class rclass) 14104{ 14105 bool ret = rs6000_cannot_change_mode_class (from, to, rclass); 14106 14107 fprintf (stderr, 14108 "rs6000_cannot_change_mode_class, return %s, from = %s, " 14109 "to = %s, rclass = %s\n", 14110 ret ? "true" : "false", 14111 GET_MODE_NAME (from), GET_MODE_NAME (to), 14112 reg_class_names[rclass]); 14113 14114 return ret; 14115} 14116 14117/* Given a comparison operation, return the bit number in CCR to test. We 14118 know this is a valid comparison. 14119 14120 SCC_P is 1 if this is for an scc. That means that %D will have been 14121 used instead of %C, so the bits will be in different places. 14122 14123 Return -1 if OP isn't a valid comparison for some reason. */ 14124 14125int 14126ccr_bit (rtx op, int scc_p) 14127{ 14128 enum rtx_code code = GET_CODE (op); 14129 enum machine_mode cc_mode; 14130 int cc_regnum; 14131 int base_bit; 14132 rtx reg; 14133 14134 if (!COMPARISON_P (op)) 14135 return -1; 14136 14137 reg = XEXP (op, 0); 14138 14139 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg))); 14140 14141 cc_mode = GET_MODE (reg); 14142 cc_regnum = REGNO (reg); 14143 base_bit = 4 * (cc_regnum - CR0_REGNO); 14144 14145 validate_condition_mode (code, cc_mode); 14146 14147 /* When generating a sCOND operation, only positive conditions are 14148 allowed. */ 14149 gcc_assert (!scc_p 14150 || code == EQ || code == GT || code == LT || code == UNORDERED 14151 || code == GTU || code == LTU); 14152 14153 switch (code) 14154 { 14155 case NE: 14156 return scc_p ? base_bit + 3 : base_bit + 2; 14157 case EQ: 14158 return base_bit + 2; 14159 case GT: case GTU: case UNLE: 14160 return base_bit + 1; 14161 case LT: case LTU: case UNGE: 14162 return base_bit; 14163 case ORDERED: case UNORDERED: 14164 return base_bit + 3; 14165 14166 case GE: case GEU: 14167 /* If scc, we will have done a cror to put the bit in the 14168 unordered position. So test that bit. For integer, this is ! LT 14169 unless this is an scc insn. */ 14170 return scc_p ? base_bit + 3 : base_bit; 14171 14172 case LE: case LEU: 14173 return scc_p ? base_bit + 3 : base_bit + 1; 14174 14175 default: 14176 gcc_unreachable (); 14177 } 14178} 14179 14180/* Return the GOT register. */ 14181 14182rtx 14183rs6000_got_register (rtx value ATTRIBUTE_UNUSED) 14184{ 14185 /* The second flow pass currently (June 1999) can't update 14186 regs_ever_live without disturbing other parts of the compiler, so 14187 update it here to make the prolog/epilogue code happy. */ 14188 if (!can_create_pseudo_p () 14189 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)) 14190 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true); 14191 14192 crtl->uses_pic_offset_table = 1; 14193 14194 return pic_offset_table_rtx; 14195} 14196 14197/* Function to init struct machine_function. 14198 This will be called, via a pointer variable, 14199 from push_function_context. */ 14200 14201static struct machine_function * 14202rs6000_init_machine_status (void) 14203{ 14204 return GGC_CNEW (machine_function); 14205} 14206 14207/* These macros test for integers and extract the low-order bits. */ 14208#define INT_P(X) \ 14209((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \ 14210 && GET_MODE (X) == VOIDmode) 14211 14212#define INT_LOWPART(X) \ 14213 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X)) 14214 14215int 14216extract_MB (rtx op) 14217{ 14218 int i; 14219 unsigned long val = INT_LOWPART (op); 14220 14221 /* If the high bit is zero, the value is the first 1 bit we find 14222 from the left. */ 14223 if ((val & 0x80000000) == 0) 14224 { 14225 gcc_assert (val & 0xffffffff); 14226 14227 i = 1; 14228 while (((val <<= 1) & 0x80000000) == 0) 14229 ++i; 14230 return i; 14231 } 14232 14233 /* If the high bit is set and the low bit is not, or the mask is all 14234 1's, the value is zero. */ 14235 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff) 14236 return 0; 14237 14238 /* Otherwise we have a wrap-around mask. Look for the first 0 bit 14239 from the right. */ 14240 i = 31; 14241 while (((val >>= 1) & 1) != 0) 14242 --i; 14243 14244 return i; 14245} 14246 14247int 14248extract_ME (rtx op) 14249{ 14250 int i; 14251 unsigned long val = INT_LOWPART (op); 14252 14253 /* If the low bit is zero, the value is the first 1 bit we find from 14254 the right. */ 14255 if ((val & 1) == 0) 14256 { 14257 gcc_assert (val & 0xffffffff); 14258 14259 i = 30; 14260 while (((val >>= 1) & 1) == 0) 14261 --i; 14262 14263 return i; 14264 } 14265 14266 /* If the low bit is set and the high bit is not, or the mask is all 14267 1's, the value is 31. */ 14268 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff) 14269 return 31; 14270 14271 /* Otherwise we have a wrap-around mask. Look for the first 0 bit 14272 from the left. */ 14273 i = 0; 14274 while (((val <<= 1) & 0x80000000) != 0) 14275 ++i; 14276 14277 return i; 14278} 14279 14280/* Locate some local-dynamic symbol still in use by this function 14281 so that we can print its name in some tls_ld pattern. */ 14282 14283static const char * 14284rs6000_get_some_local_dynamic_name (void) 14285{ 14286 rtx insn; 14287 14288 if (cfun->machine->some_ld_name) 14289 return cfun->machine->some_ld_name; 14290 14291 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn)) 14292 if (INSN_P (insn) 14293 && for_each_rtx (&PATTERN (insn), 14294 rs6000_get_some_local_dynamic_name_1, 0)) 14295 return cfun->machine->some_ld_name; 14296 14297 gcc_unreachable (); 14298} 14299 14300/* Helper function for rs6000_get_some_local_dynamic_name. */ 14301 14302static int 14303rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED) 14304{ 14305 rtx x = *px; 14306 14307 if (GET_CODE (x) == SYMBOL_REF) 14308 { 14309 const char *str = XSTR (x, 0); 14310 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC) 14311 { 14312 cfun->machine->some_ld_name = str; 14313 return 1; 14314 } 14315 } 14316 14317 return 0; 14318} 14319 14320/* Write out a function code label. */ 14321 14322void 14323rs6000_output_function_entry (FILE *file, const char *fname) 14324{ 14325 if (fname[0] != '.') 14326 { 14327 switch (DEFAULT_ABI) 14328 { 14329 default: 14330 gcc_unreachable (); 14331 14332 case ABI_AIX: 14333 if (DOT_SYMBOLS) 14334 putc ('.', file); 14335 else 14336 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L."); 14337 break; 14338 14339 case ABI_V4: 14340 case ABI_DARWIN: 14341 break; 14342 } 14343 } 14344 if (TARGET_AIX) 14345 RS6000_OUTPUT_BASENAME (file, fname); 14346 else 14347 assemble_name (file, fname); 14348} 14349 14350/* Print an operand. Recognize special options, documented below. */ 14351 14352#if TARGET_ELF 14353#define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel") 14354#define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13) 14355#else 14356#define SMALL_DATA_RELOC "sda21" 14357#define SMALL_DATA_REG 0 14358#endif 14359 14360void 14361print_operand (FILE *file, rtx x, int code) 14362{ 14363 int i; 14364 HOST_WIDE_INT val; 14365 unsigned HOST_WIDE_INT uval; 14366 14367 switch (code) 14368 { 14369 case '.': 14370 /* Write out an instruction after the call which may be replaced 14371 with glue code by the loader. This depends on the AIX version. */ 14372 asm_fprintf (file, RS6000_CALL_GLUE); 14373 return; 14374 14375 /* %a is output_address. */ 14376 14377 case 'A': 14378 /* If X is a constant integer whose low-order 5 bits are zero, 14379 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug 14380 in the AIX assembler where "sri" with a zero shift count 14381 writes a trash instruction. */ 14382 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0) 14383 putc ('l', file); 14384 else 14385 putc ('r', file); 14386 return; 14387 14388 case 'b': 14389 /* If constant, low-order 16 bits of constant, unsigned. 14390 Otherwise, write normally. */ 14391 if (INT_P (x)) 14392 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff); 14393 else 14394 print_operand (file, x, 0); 14395 return; 14396 14397 case 'B': 14398 /* If the low-order bit is zero, write 'r'; otherwise, write 'l' 14399 for 64-bit mask direction. */ 14400 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file); 14401 return; 14402 14403 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise 14404 output_operand. */ 14405 14406 case 'c': 14407 /* X is a CR register. Print the number of the GT bit of the CR. */ 14408 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x))) 14409 output_operand_lossage ("invalid %%c value"); 14410 else 14411 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1); 14412 return; 14413 14414 case 'D': 14415 /* Like 'J' but get to the GT bit only. */ 14416 gcc_assert (GET_CODE (x) == REG); 14417 14418 /* Bit 1 is GT bit. */ 14419 i = 4 * (REGNO (x) - CR0_REGNO) + 1; 14420 14421 /* Add one for shift count in rlinm for scc. */ 14422 fprintf (file, "%d", i + 1); 14423 return; 14424 14425 case 'E': 14426 /* X is a CR register. Print the number of the EQ bit of the CR */ 14427 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x))) 14428 output_operand_lossage ("invalid %%E value"); 14429 else 14430 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2); 14431 return; 14432 14433 case 'f': 14434 /* X is a CR register. Print the shift count needed to move it 14435 to the high-order four bits. */ 14436 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x))) 14437 output_operand_lossage ("invalid %%f value"); 14438 else 14439 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO)); 14440 return; 14441 14442 case 'F': 14443 /* Similar, but print the count for the rotate in the opposite 14444 direction. */ 14445 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x))) 14446 output_operand_lossage ("invalid %%F value"); 14447 else 14448 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO)); 14449 return; 14450 14451 case 'G': 14452 /* X is a constant integer. If it is negative, print "m", 14453 otherwise print "z". This is to make an aze or ame insn. */ 14454 if (GET_CODE (x) != CONST_INT) 14455 output_operand_lossage ("invalid %%G value"); 14456 else if (INTVAL (x) >= 0) 14457 putc ('z', file); 14458 else 14459 putc ('m', file); 14460 return; 14461 14462 case 'h': 14463 /* If constant, output low-order five bits. Otherwise, write 14464 normally. */ 14465 if (INT_P (x)) 14466 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31); 14467 else 14468 print_operand (file, x, 0); 14469 return; 14470 14471 case 'H': 14472 /* If constant, output low-order six bits. Otherwise, write 14473 normally. */ 14474 if (INT_P (x)) 14475 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63); 14476 else 14477 print_operand (file, x, 0); 14478 return; 14479 14480 case 'I': 14481 /* Print `i' if this is a constant, else nothing. */ 14482 if (INT_P (x)) 14483 putc ('i', file); 14484 return; 14485 14486 case 'j': 14487 /* Write the bit number in CCR for jump. */ 14488 i = ccr_bit (x, 0); 14489 if (i == -1) 14490 output_operand_lossage ("invalid %%j code"); 14491 else 14492 fprintf (file, "%d", i); 14493 return; 14494 14495 case 'J': 14496 /* Similar, but add one for shift count in rlinm for scc and pass 14497 scc flag to `ccr_bit'. */ 14498 i = ccr_bit (x, 1); 14499 if (i == -1) 14500 output_operand_lossage ("invalid %%J code"); 14501 else 14502 /* If we want bit 31, write a shift count of zero, not 32. */ 14503 fprintf (file, "%d", i == 31 ? 0 : i + 1); 14504 return; 14505 14506 case 'k': 14507 /* X must be a constant. Write the 1's complement of the 14508 constant. */ 14509 if (! INT_P (x)) 14510 output_operand_lossage ("invalid %%k value"); 14511 else 14512 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x)); 14513 return; 14514 14515 case 'K': 14516 /* X must be a symbolic constant on ELF. Write an 14517 expression suitable for an 'addi' that adds in the low 16 14518 bits of the MEM. */ 14519 if (GET_CODE (x) != CONST) 14520 { 14521 print_operand_address (file, x); 14522 fputs ("@l", file); 14523 } 14524 else 14525 { 14526 if (GET_CODE (XEXP (x, 0)) != PLUS 14527 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF 14528 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF) 14529 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT) 14530 output_operand_lossage ("invalid %%K value"); 14531 print_operand_address (file, XEXP (XEXP (x, 0), 0)); 14532 fputs ("@l", file); 14533 /* For GNU as, there must be a non-alphanumeric character 14534 between 'l' and the number. The '-' is added by 14535 print_operand() already. */ 14536 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0) 14537 fputs ("+", file); 14538 print_operand (file, XEXP (XEXP (x, 0), 1), 0); 14539 } 14540 return; 14541 14542 /* %l is output_asm_label. */ 14543 14544 case 'L': 14545 /* Write second word of DImode or DFmode reference. Works on register 14546 or non-indexed memory only. */ 14547 if (GET_CODE (x) == REG) 14548 fputs (reg_names[REGNO (x) + 1], file); 14549 else if (GET_CODE (x) == MEM) 14550 { 14551 /* Handle possible auto-increment. Since it is pre-increment and 14552 we have already done it, we can just use an offset of word. */ 14553 if (GET_CODE (XEXP (x, 0)) == PRE_INC 14554 || GET_CODE (XEXP (x, 0)) == PRE_DEC) 14555 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 14556 UNITS_PER_WORD)); 14557 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY) 14558 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 14559 UNITS_PER_WORD)); 14560 else 14561 output_address (XEXP (adjust_address_nv (x, SImode, 14562 UNITS_PER_WORD), 14563 0)); 14564 14565 if (small_data_operand (x, GET_MODE (x))) 14566 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC, 14567 reg_names[SMALL_DATA_REG]); 14568 } 14569 return; 14570 14571 case 'm': 14572 /* MB value for a mask operand. */ 14573 if (! mask_operand (x, SImode)) 14574 output_operand_lossage ("invalid %%m value"); 14575 14576 fprintf (file, "%d", extract_MB (x)); 14577 return; 14578 14579 case 'M': 14580 /* ME value for a mask operand. */ 14581 if (! mask_operand (x, SImode)) 14582 output_operand_lossage ("invalid %%M value"); 14583 14584 fprintf (file, "%d", extract_ME (x)); 14585 return; 14586 14587 /* %n outputs the negative of its operand. */ 14588 14589 case 'N': 14590 /* Write the number of elements in the vector times 4. */ 14591 if (GET_CODE (x) != PARALLEL) 14592 output_operand_lossage ("invalid %%N value"); 14593 else 14594 fprintf (file, "%d", XVECLEN (x, 0) * 4); 14595 return; 14596 14597 case 'O': 14598 /* Similar, but subtract 1 first. */ 14599 if (GET_CODE (x) != PARALLEL) 14600 output_operand_lossage ("invalid %%O value"); 14601 else 14602 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4); 14603 return; 14604 14605 case 'p': 14606 /* X is a CONST_INT that is a power of two. Output the logarithm. */ 14607 if (! INT_P (x) 14608 || INT_LOWPART (x) < 0 14609 || (i = exact_log2 (INT_LOWPART (x))) < 0) 14610 output_operand_lossage ("invalid %%p value"); 14611 else 14612 fprintf (file, "%d", i); 14613 return; 14614 14615 case 'P': 14616 /* The operand must be an indirect memory reference. The result 14617 is the register name. */ 14618 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG 14619 || REGNO (XEXP (x, 0)) >= 32) 14620 output_operand_lossage ("invalid %%P value"); 14621 else 14622 fputs (reg_names[REGNO (XEXP (x, 0))], file); 14623 return; 14624 14625 case 'q': 14626 /* This outputs the logical code corresponding to a boolean 14627 expression. The expression may have one or both operands 14628 negated (if one, only the first one). For condition register 14629 logical operations, it will also treat the negated 14630 CR codes as NOTs, but not handle NOTs of them. */ 14631 { 14632 const char *const *t = 0; 14633 const char *s; 14634 enum rtx_code code = GET_CODE (x); 14635 static const char * const tbl[3][3] = { 14636 { "and", "andc", "nor" }, 14637 { "or", "orc", "nand" }, 14638 { "xor", "eqv", "xor" } }; 14639 14640 if (code == AND) 14641 t = tbl[0]; 14642 else if (code == IOR) 14643 t = tbl[1]; 14644 else if (code == XOR) 14645 t = tbl[2]; 14646 else 14647 output_operand_lossage ("invalid %%q value"); 14648 14649 if (GET_CODE (XEXP (x, 0)) != NOT) 14650 s = t[0]; 14651 else 14652 { 14653 if (GET_CODE (XEXP (x, 1)) == NOT) 14654 s = t[2]; 14655 else 14656 s = t[1]; 14657 } 14658 14659 fputs (s, file); 14660 } 14661 return; 14662 14663 case 'Q': 14664 if (TARGET_MFCRF) 14665 fputc (',', file); 14666 /* FALLTHRU */ 14667 else 14668 return; 14669 14670 case 'R': 14671 /* X is a CR register. Print the mask for `mtcrf'. */ 14672 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x))) 14673 output_operand_lossage ("invalid %%R value"); 14674 else 14675 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO)); 14676 return; 14677 14678 case 's': 14679 /* Low 5 bits of 32 - value */ 14680 if (! INT_P (x)) 14681 output_operand_lossage ("invalid %%s value"); 14682 else 14683 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31); 14684 return; 14685 14686 case 'S': 14687 /* PowerPC64 mask position. All 0's is excluded. 14688 CONST_INT 32-bit mask is considered sign-extended so any 14689 transition must occur within the CONST_INT, not on the boundary. */ 14690 if (! mask64_operand (x, DImode)) 14691 output_operand_lossage ("invalid %%S value"); 14692 14693 uval = INT_LOWPART (x); 14694 14695 if (uval & 1) /* Clear Left */ 14696 { 14697#if HOST_BITS_PER_WIDE_INT > 64 14698 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1; 14699#endif 14700 i = 64; 14701 } 14702 else /* Clear Right */ 14703 { 14704 uval = ~uval; 14705#if HOST_BITS_PER_WIDE_INT > 64 14706 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1; 14707#endif 14708 i = 63; 14709 } 14710 while (uval != 0) 14711 --i, uval >>= 1; 14712 gcc_assert (i >= 0); 14713 fprintf (file, "%d", i); 14714 return; 14715 14716 case 't': 14717 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */ 14718 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode); 14719 14720 /* Bit 3 is OV bit. */ 14721 i = 4 * (REGNO (x) - CR0_REGNO) + 3; 14722 14723 /* If we want bit 31, write a shift count of zero, not 32. */ 14724 fprintf (file, "%d", i == 31 ? 0 : i + 1); 14725 return; 14726 14727 case 'T': 14728 /* Print the symbolic name of a branch target register. */ 14729 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO 14730 && REGNO (x) != CTR_REGNO)) 14731 output_operand_lossage ("invalid %%T value"); 14732 else if (REGNO (x) == LR_REGNO) 14733 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file); 14734 else 14735 fputs ("ctr", file); 14736 return; 14737 14738 case 'u': 14739 /* High-order 16 bits of constant for use in unsigned operand. */ 14740 if (! INT_P (x)) 14741 output_operand_lossage ("invalid %%u value"); 14742 else 14743 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 14744 (INT_LOWPART (x) >> 16) & 0xffff); 14745 return; 14746 14747 case 'v': 14748 /* High-order 16 bits of constant for use in signed operand. */ 14749 if (! INT_P (x)) 14750 output_operand_lossage ("invalid %%v value"); 14751 else 14752 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 14753 (INT_LOWPART (x) >> 16) & 0xffff); 14754 return; 14755 14756 case 'U': 14757 /* Print `u' if this has an auto-increment or auto-decrement. */ 14758 if (GET_CODE (x) == MEM 14759 && (GET_CODE (XEXP (x, 0)) == PRE_INC 14760 || GET_CODE (XEXP (x, 0)) == PRE_DEC 14761 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY)) 14762 putc ('u', file); 14763 return; 14764 14765 case 'V': 14766 /* Print the trap code for this operand. */ 14767 switch (GET_CODE (x)) 14768 { 14769 case EQ: 14770 fputs ("eq", file); /* 4 */ 14771 break; 14772 case NE: 14773 fputs ("ne", file); /* 24 */ 14774 break; 14775 case LT: 14776 fputs ("lt", file); /* 16 */ 14777 break; 14778 case LE: 14779 fputs ("le", file); /* 20 */ 14780 break; 14781 case GT: 14782 fputs ("gt", file); /* 8 */ 14783 break; 14784 case GE: 14785 fputs ("ge", file); /* 12 */ 14786 break; 14787 case LTU: 14788 fputs ("llt", file); /* 2 */ 14789 break; 14790 case LEU: 14791 fputs ("lle", file); /* 6 */ 14792 break; 14793 case GTU: 14794 fputs ("lgt", file); /* 1 */ 14795 break; 14796 case GEU: 14797 fputs ("lge", file); /* 5 */ 14798 break; 14799 default: 14800 gcc_unreachable (); 14801 } 14802 break; 14803 14804 case 'w': 14805 /* If constant, low-order 16 bits of constant, signed. Otherwise, write 14806 normally. */ 14807 if (INT_P (x)) 14808 fprintf (file, HOST_WIDE_INT_PRINT_DEC, 14809 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000); 14810 else 14811 print_operand (file, x, 0); 14812 return; 14813 14814 case 'W': 14815 /* MB value for a PowerPC64 rldic operand. */ 14816 val = (GET_CODE (x) == CONST_INT 14817 ? INTVAL (x) : CONST_DOUBLE_HIGH (x)); 14818 14819 if (val < 0) 14820 i = -1; 14821 else 14822 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++) 14823 if ((val <<= 1) < 0) 14824 break; 14825 14826#if HOST_BITS_PER_WIDE_INT == 32 14827 if (GET_CODE (x) == CONST_INT && i >= 0) 14828 i += 32; /* zero-extend high-part was all 0's */ 14829 else if (GET_CODE (x) == CONST_DOUBLE && i == 32) 14830 { 14831 val = CONST_DOUBLE_LOW (x); 14832 14833 gcc_assert (val); 14834 if (val < 0) 14835 --i; 14836 else 14837 for ( ; i < 64; i++) 14838 if ((val <<= 1) < 0) 14839 break; 14840 } 14841#endif 14842 14843 fprintf (file, "%d", i + 1); 14844 return; 14845 14846 case 'x': 14847 /* X is a FPR or Altivec register used in a VSX context. */ 14848 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x))) 14849 output_operand_lossage ("invalid %%x value"); 14850 else 14851 { 14852 int reg = REGNO (x); 14853 int vsx_reg = (FP_REGNO_P (reg) 14854 ? reg - 32 14855 : reg - FIRST_ALTIVEC_REGNO + 32); 14856 14857#ifdef TARGET_REGNAMES 14858 if (TARGET_REGNAMES) 14859 fprintf (file, "%%vs%d", vsx_reg); 14860 else 14861#endif 14862 fprintf (file, "%d", vsx_reg); 14863 } 14864 return; 14865 14866 case 'X': 14867 if (GET_CODE (x) == MEM 14868 && (legitimate_indexed_address_p (XEXP (x, 0), 0) 14869 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY 14870 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0)))) 14871 putc ('x', file); 14872 return; 14873 14874 case 'Y': 14875 /* Like 'L', for third word of TImode */ 14876 if (GET_CODE (x) == REG) 14877 fputs (reg_names[REGNO (x) + 2], file); 14878 else if (GET_CODE (x) == MEM) 14879 { 14880 if (GET_CODE (XEXP (x, 0)) == PRE_INC 14881 || GET_CODE (XEXP (x, 0)) == PRE_DEC) 14882 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8)); 14883 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY) 14884 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8)); 14885 else 14886 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0)); 14887 if (small_data_operand (x, GET_MODE (x))) 14888 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC, 14889 reg_names[SMALL_DATA_REG]); 14890 } 14891 return; 14892 14893 case 'z': 14894 /* X is a SYMBOL_REF. Write out the name preceded by a 14895 period and without any trailing data in brackets. Used for function 14896 names. If we are configured for System V (or the embedded ABI) on 14897 the PowerPC, do not emit the period, since those systems do not use 14898 TOCs and the like. */ 14899 gcc_assert (GET_CODE (x) == SYMBOL_REF); 14900 14901 /* Mark the decl as referenced so that cgraph will output the 14902 function. */ 14903 if (SYMBOL_REF_DECL (x)) 14904 mark_decl_referenced (SYMBOL_REF_DECL (x)); 14905 14906 /* For macho, check to see if we need a stub. */ 14907 if (TARGET_MACHO) 14908 { 14909 const char *name = XSTR (x, 0); 14910#if TARGET_MACHO 14911 if (MACHOPIC_INDIRECT 14912 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION) 14913 name = machopic_indirection_name (x, /*stub_p=*/true); 14914#endif 14915 assemble_name (file, name); 14916 } 14917 else if (!DOT_SYMBOLS) 14918 assemble_name (file, XSTR (x, 0)); 14919 else 14920 rs6000_output_function_entry (file, XSTR (x, 0)); 14921 return; 14922 14923 case 'Z': 14924 /* Like 'L', for last word of TImode. */ 14925 if (GET_CODE (x) == REG) 14926 fputs (reg_names[REGNO (x) + 3], file); 14927 else if (GET_CODE (x) == MEM) 14928 { 14929 if (GET_CODE (XEXP (x, 0)) == PRE_INC 14930 || GET_CODE (XEXP (x, 0)) == PRE_DEC) 14931 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12)); 14932 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY) 14933 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12)); 14934 else 14935 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0)); 14936 if (small_data_operand (x, GET_MODE (x))) 14937 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC, 14938 reg_names[SMALL_DATA_REG]); 14939 } 14940 return; 14941 14942 /* Print AltiVec or SPE memory operand. */ 14943 case 'y': 14944 { 14945 rtx tmp; 14946 14947 gcc_assert (GET_CODE (x) == MEM); 14948 14949 tmp = XEXP (x, 0); 14950 14951 /* Ugly hack because %y is overloaded. */ 14952 if ((TARGET_SPE || TARGET_E500_DOUBLE) 14953 && (GET_MODE_SIZE (GET_MODE (x)) == 8 14954 || GET_MODE (x) == TFmode 14955 || GET_MODE (x) == TImode)) 14956 { 14957 /* Handle [reg]. */ 14958 if (GET_CODE (tmp) == REG) 14959 { 14960 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]); 14961 break; 14962 } 14963 /* Handle [reg+UIMM]. */ 14964 else if (GET_CODE (tmp) == PLUS && 14965 GET_CODE (XEXP (tmp, 1)) == CONST_INT) 14966 { 14967 int x; 14968 14969 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG); 14970 14971 x = INTVAL (XEXP (tmp, 1)); 14972 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]); 14973 break; 14974 } 14975 14976 /* Fall through. Must be [reg+reg]. */ 14977 } 14978 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x)) 14979 && GET_CODE (tmp) == AND 14980 && GET_CODE (XEXP (tmp, 1)) == CONST_INT 14981 && INTVAL (XEXP (tmp, 1)) == -16) 14982 tmp = XEXP (tmp, 0); 14983 else if (VECTOR_MEM_VSX_P (GET_MODE (x)) 14984 && GET_CODE (tmp) == PRE_MODIFY) 14985 tmp = XEXP (tmp, 1); 14986 if (GET_CODE (tmp) == REG) 14987 fprintf (file, "0,%s", reg_names[REGNO (tmp)]); 14988 else 14989 { 14990 if (!GET_CODE (tmp) == PLUS 14991 || !REG_P (XEXP (tmp, 0)) 14992 || !REG_P (XEXP (tmp, 1))) 14993 { 14994 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint"); 14995 break; 14996 } 14997 14998 if (REGNO (XEXP (tmp, 0)) == 0) 14999 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ], 15000 reg_names[ REGNO (XEXP (tmp, 0)) ]); 15001 else 15002 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ], 15003 reg_names[ REGNO (XEXP (tmp, 1)) ]); 15004 } 15005 break; 15006 } 15007 15008 case 0: 15009 if (GET_CODE (x) == REG) 15010 fprintf (file, "%s", reg_names[REGNO (x)]); 15011 else if (GET_CODE (x) == MEM) 15012 { 15013 /* We need to handle PRE_INC and PRE_DEC here, since we need to 15014 know the width from the mode. */ 15015 if (GET_CODE (XEXP (x, 0)) == PRE_INC) 15016 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)), 15017 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]); 15018 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC) 15019 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)), 15020 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]); 15021 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY) 15022 output_address (XEXP (XEXP (x, 0), 1)); 15023 else 15024 output_address (XEXP (x, 0)); 15025 } 15026 else 15027 output_addr_const (file, x); 15028 return; 15029 15030 case '&': 15031 assemble_name (file, rs6000_get_some_local_dynamic_name ()); 15032 return; 15033 15034 default: 15035 output_operand_lossage ("invalid %%xn code"); 15036 } 15037} 15038 15039/* Print the address of an operand. */ 15040 15041void 15042print_operand_address (FILE *file, rtx x) 15043{ 15044 if (GET_CODE (x) == REG) 15045 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]); 15046 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST 15047 || GET_CODE (x) == LABEL_REF) 15048 { 15049 output_addr_const (file, x); 15050 if (small_data_operand (x, GET_MODE (x))) 15051 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC, 15052 reg_names[SMALL_DATA_REG]); 15053 else 15054 gcc_assert (!TARGET_TOC); 15055 } 15056 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG) 15057 { 15058 gcc_assert (REG_P (XEXP (x, 0))); 15059 if (REGNO (XEXP (x, 0)) == 0) 15060 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ], 15061 reg_names[ REGNO (XEXP (x, 0)) ]); 15062 else 15063 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ], 15064 reg_names[ REGNO (XEXP (x, 1)) ]); 15065 } 15066 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT) 15067 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)", 15068 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]); 15069#if TARGET_ELF 15070 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG 15071 && CONSTANT_P (XEXP (x, 1))) 15072 { 15073 output_addr_const (file, XEXP (x, 1)); 15074 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]); 15075 } 15076#endif 15077#if TARGET_MACHO 15078 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG 15079 && CONSTANT_P (XEXP (x, 1))) 15080 { 15081 fprintf (file, "lo16("); 15082 output_addr_const (file, XEXP (x, 1)); 15083 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]); 15084 } 15085#endif 15086 else if (legitimate_constant_pool_address_p (x)) 15087 { 15088 output_addr_const (file, XEXP (x, 1)); 15089 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]); 15090 } 15091 else 15092 gcc_unreachable (); 15093} 15094 15095/* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */ 15096 15097bool 15098rs6000_output_addr_const_extra (FILE *file, rtx x) 15099{ 15100 if (GET_CODE (x) == UNSPEC) 15101 switch (XINT (x, 1)) 15102 { 15103 case UNSPEC_TOCREL: 15104 x = XVECEXP (x, 0, 0); 15105 gcc_assert (GET_CODE (x) == SYMBOL_REF); 15106 output_addr_const (file, x); 15107 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC)) 15108 { 15109 putc ('-', file); 15110 assemble_name (file, toc_label_name); 15111 } 15112 else if (TARGET_ELF) 15113 fputs ("@toc", file); 15114 return true; 15115 15116#if TARGET_MACHO 15117 case UNSPEC_MACHOPIC_OFFSET: 15118 output_addr_const (file, XVECEXP (x, 0, 0)); 15119 putc ('-', file); 15120 machopic_output_function_base_name (file); 15121 return true; 15122#endif 15123 } 15124 return false; 15125} 15126 15127/* Target hook for assembling integer objects. The PowerPC version has 15128 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP 15129 is defined. It also needs to handle DI-mode objects on 64-bit 15130 targets. */ 15131 15132static bool 15133rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p) 15134{ 15135#ifdef RELOCATABLE_NEEDS_FIXUP 15136 /* Special handling for SI values. */ 15137 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p) 15138 { 15139 static int recurse = 0; 15140 15141 /* For -mrelocatable, we mark all addresses that need to be fixed up 15142 in the .fixup section. */ 15143 if (TARGET_RELOCATABLE 15144 && in_section != toc_section 15145 && in_section != text_section 15146 && !unlikely_text_section_p (in_section) 15147 && !recurse 15148 && GET_CODE (x) != CONST_INT 15149 && GET_CODE (x) != CONST_DOUBLE 15150 && CONSTANT_P (x)) 15151 { 15152 char buf[256]; 15153 15154 recurse = 1; 15155 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno); 15156 fixuplabelno++; 15157 ASM_OUTPUT_LABEL (asm_out_file, buf); 15158 fprintf (asm_out_file, "\t.long\t("); 15159 output_addr_const (asm_out_file, x); 15160 fprintf (asm_out_file, ")@fixup\n"); 15161 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n"); 15162 ASM_OUTPUT_ALIGN (asm_out_file, 2); 15163 fprintf (asm_out_file, "\t.long\t"); 15164 assemble_name (asm_out_file, buf); 15165 fprintf (asm_out_file, "\n\t.previous\n"); 15166 recurse = 0; 15167 return true; 15168 } 15169 /* Remove initial .'s to turn a -mcall-aixdesc function 15170 address into the address of the descriptor, not the function 15171 itself. */ 15172 else if (GET_CODE (x) == SYMBOL_REF 15173 && XSTR (x, 0)[0] == '.' 15174 && DEFAULT_ABI == ABI_AIX) 15175 { 15176 const char *name = XSTR (x, 0); 15177 while (*name == '.') 15178 name++; 15179 15180 fprintf (asm_out_file, "\t.long\t%s\n", name); 15181 return true; 15182 } 15183 } 15184#endif /* RELOCATABLE_NEEDS_FIXUP */ 15185 return default_assemble_integer (x, size, aligned_p); 15186} 15187 15188#ifdef HAVE_GAS_HIDDEN 15189/* Emit an assembler directive to set symbol visibility for DECL to 15190 VISIBILITY_TYPE. */ 15191 15192static void 15193rs6000_assemble_visibility (tree decl, int vis) 15194{ 15195 /* Functions need to have their entry point symbol visibility set as 15196 well as their descriptor symbol visibility. */ 15197 if (DEFAULT_ABI == ABI_AIX 15198 && DOT_SYMBOLS 15199 && TREE_CODE (decl) == FUNCTION_DECL) 15200 { 15201 static const char * const visibility_types[] = { 15202 NULL, "internal", "hidden", "protected" 15203 }; 15204 15205 const char *name, *type; 15206 15207 name = ((* targetm.strip_name_encoding) 15208 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)))); 15209 type = visibility_types[vis]; 15210 15211 fprintf (asm_out_file, "\t.%s\t%s\n", type, name); 15212 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name); 15213 } 15214 else 15215 default_assemble_visibility (decl, vis); 15216} 15217#endif 15218 15219enum rtx_code 15220rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code) 15221{ 15222 /* Reversal of FP compares takes care -- an ordered compare 15223 becomes an unordered compare and vice versa. */ 15224 if (mode == CCFPmode 15225 && (!flag_finite_math_only 15226 || code == UNLT || code == UNLE || code == UNGT || code == UNGE 15227 || code == UNEQ || code == LTGT)) 15228 return reverse_condition_maybe_unordered (code); 15229 else 15230 return reverse_condition (code); 15231} 15232 15233/* Generate a compare for CODE. Return a brand-new rtx that 15234 represents the result of the compare. */ 15235 15236static rtx 15237rs6000_generate_compare (rtx cmp, enum machine_mode mode) 15238{ 15239 enum machine_mode comp_mode; 15240 rtx compare_result; 15241 enum rtx_code code = GET_CODE (cmp); 15242 rtx op0 = XEXP (cmp, 0); 15243 rtx op1 = XEXP (cmp, 1); 15244 15245 if (FLOAT_MODE_P (mode)) 15246 comp_mode = CCFPmode; 15247 else if (code == GTU || code == LTU 15248 || code == GEU || code == LEU) 15249 comp_mode = CCUNSmode; 15250 else if ((code == EQ || code == NE) 15251 && GET_CODE (op0) == SUBREG 15252 && GET_CODE (op1) == SUBREG 15253 && SUBREG_PROMOTED_UNSIGNED_P (op0) 15254 && SUBREG_PROMOTED_UNSIGNED_P (op1)) 15255 /* These are unsigned values, perhaps there will be a later 15256 ordering compare that can be shared with this one. 15257 Unfortunately we cannot detect the signedness of the operands 15258 for non-subregs. */ 15259 comp_mode = CCUNSmode; 15260 else 15261 comp_mode = CCmode; 15262 15263 /* First, the compare. */ 15264 compare_result = gen_reg_rtx (comp_mode); 15265 15266 /* E500 FP compare instructions on the GPRs. Yuck! */ 15267 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) 15268 && FLOAT_MODE_P (mode)) 15269 { 15270 rtx cmp, or_result, compare_result2; 15271 enum machine_mode op_mode = GET_MODE (op0); 15272 15273 if (op_mode == VOIDmode) 15274 op_mode = GET_MODE (op1); 15275 15276 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only. 15277 This explains the following mess. */ 15278 15279 switch (code) 15280 { 15281 case EQ: case UNEQ: case NE: case LTGT: 15282 switch (op_mode) 15283 { 15284 case SFmode: 15285 cmp = (flag_finite_math_only && !flag_trapping_math) 15286 ? gen_tstsfeq_gpr (compare_result, op0, op1) 15287 : gen_cmpsfeq_gpr (compare_result, op0, op1); 15288 break; 15289 15290 case DFmode: 15291 cmp = (flag_finite_math_only && !flag_trapping_math) 15292 ? gen_tstdfeq_gpr (compare_result, op0, op1) 15293 : gen_cmpdfeq_gpr (compare_result, op0, op1); 15294 break; 15295 15296 case TFmode: 15297 cmp = (flag_finite_math_only && !flag_trapping_math) 15298 ? gen_tsttfeq_gpr (compare_result, op0, op1) 15299 : gen_cmptfeq_gpr (compare_result, op0, op1); 15300 break; 15301 15302 default: 15303 gcc_unreachable (); 15304 } 15305 break; 15306 15307 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU: 15308 switch (op_mode) 15309 { 15310 case SFmode: 15311 cmp = (flag_finite_math_only && !flag_trapping_math) 15312 ? gen_tstsfgt_gpr (compare_result, op0, op1) 15313 : gen_cmpsfgt_gpr (compare_result, op0, op1); 15314 break; 15315 15316 case DFmode: 15317 cmp = (flag_finite_math_only && !flag_trapping_math) 15318 ? gen_tstdfgt_gpr (compare_result, op0, op1) 15319 : gen_cmpdfgt_gpr (compare_result, op0, op1); 15320 break; 15321 15322 case TFmode: 15323 cmp = (flag_finite_math_only && !flag_trapping_math) 15324 ? gen_tsttfgt_gpr (compare_result, op0, op1) 15325 : gen_cmptfgt_gpr (compare_result, op0, op1); 15326 break; 15327 15328 default: 15329 gcc_unreachable (); 15330 } 15331 break; 15332 15333 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU: 15334 switch (op_mode) 15335 { 15336 case SFmode: 15337 cmp = (flag_finite_math_only && !flag_trapping_math) 15338 ? gen_tstsflt_gpr (compare_result, op0, op1) 15339 : gen_cmpsflt_gpr (compare_result, op0, op1); 15340 break; 15341 15342 case DFmode: 15343 cmp = (flag_finite_math_only && !flag_trapping_math) 15344 ? gen_tstdflt_gpr (compare_result, op0, op1) 15345 : gen_cmpdflt_gpr (compare_result, op0, op1); 15346 break; 15347 15348 case TFmode: 15349 cmp = (flag_finite_math_only && !flag_trapping_math) 15350 ? gen_tsttflt_gpr (compare_result, op0, op1) 15351 : gen_cmptflt_gpr (compare_result, op0, op1); 15352 break; 15353 15354 default: 15355 gcc_unreachable (); 15356 } 15357 break; 15358 default: 15359 gcc_unreachable (); 15360 } 15361 15362 /* Synthesize LE and GE from LT/GT || EQ. */ 15363 if (code == LE || code == GE || code == LEU || code == GEU) 15364 { 15365 emit_insn (cmp); 15366 15367 switch (code) 15368 { 15369 case LE: code = LT; break; 15370 case GE: code = GT; break; 15371 case LEU: code = LT; break; 15372 case GEU: code = GT; break; 15373 default: gcc_unreachable (); 15374 } 15375 15376 compare_result2 = gen_reg_rtx (CCFPmode); 15377 15378 /* Do the EQ. */ 15379 switch (op_mode) 15380 { 15381 case SFmode: 15382 cmp = (flag_finite_math_only && !flag_trapping_math) 15383 ? gen_tstsfeq_gpr (compare_result2, op0, op1) 15384 : gen_cmpsfeq_gpr (compare_result2, op0, op1); 15385 break; 15386 15387 case DFmode: 15388 cmp = (flag_finite_math_only && !flag_trapping_math) 15389 ? gen_tstdfeq_gpr (compare_result2, op0, op1) 15390 : gen_cmpdfeq_gpr (compare_result2, op0, op1); 15391 break; 15392 15393 case TFmode: 15394 cmp = (flag_finite_math_only && !flag_trapping_math) 15395 ? gen_tsttfeq_gpr (compare_result2, op0, op1) 15396 : gen_cmptfeq_gpr (compare_result2, op0, op1); 15397 break; 15398 15399 default: 15400 gcc_unreachable (); 15401 } 15402 emit_insn (cmp); 15403 15404 /* OR them together. */ 15405 or_result = gen_reg_rtx (CCFPmode); 15406 cmp = gen_e500_cr_ior_compare (or_result, compare_result, 15407 compare_result2); 15408 compare_result = or_result; 15409 code = EQ; 15410 } 15411 else 15412 { 15413 if (code == NE || code == LTGT) 15414 code = NE; 15415 else 15416 code = EQ; 15417 } 15418 15419 emit_insn (cmp); 15420 } 15421 else 15422 { 15423 /* Generate XLC-compatible TFmode compare as PARALLEL with extra 15424 CLOBBERs to match cmptf_internal2 pattern. */ 15425 if (comp_mode == CCFPmode && TARGET_XL_COMPAT 15426 && GET_MODE (op0) == TFmode 15427 && !TARGET_IEEEQUAD 15428 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128) 15429 emit_insn (gen_rtx_PARALLEL (VOIDmode, 15430 gen_rtvec (9, 15431 gen_rtx_SET (VOIDmode, 15432 compare_result, 15433 gen_rtx_COMPARE (comp_mode, op0, op1)), 15434 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)), 15435 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)), 15436 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)), 15437 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)), 15438 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)), 15439 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)), 15440 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)), 15441 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode))))); 15442 else if (GET_CODE (op1) == UNSPEC 15443 && XINT (op1, 1) == UNSPEC_SP_TEST) 15444 { 15445 rtx op1b = XVECEXP (op1, 0, 0); 15446 comp_mode = CCEQmode; 15447 compare_result = gen_reg_rtx (CCEQmode); 15448 if (TARGET_64BIT) 15449 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b)); 15450 else 15451 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b)); 15452 } 15453 else 15454 emit_insn (gen_rtx_SET (VOIDmode, compare_result, 15455 gen_rtx_COMPARE (comp_mode, op0, op1))); 15456 } 15457 15458 /* Some kinds of FP comparisons need an OR operation; 15459 under flag_finite_math_only we don't bother. */ 15460 if (FLOAT_MODE_P (mode) 15461 && !flag_finite_math_only 15462 && !(TARGET_HARD_FLOAT && !TARGET_FPRS) 15463 && (code == LE || code == GE 15464 || code == UNEQ || code == LTGT 15465 || code == UNGT || code == UNLT)) 15466 { 15467 enum rtx_code or1, or2; 15468 rtx or1_rtx, or2_rtx, compare2_rtx; 15469 rtx or_result = gen_reg_rtx (CCEQmode); 15470 15471 switch (code) 15472 { 15473 case LE: or1 = LT; or2 = EQ; break; 15474 case GE: or1 = GT; or2 = EQ; break; 15475 case UNEQ: or1 = UNORDERED; or2 = EQ; break; 15476 case LTGT: or1 = LT; or2 = GT; break; 15477 case UNGT: or1 = UNORDERED; or2 = GT; break; 15478 case UNLT: or1 = UNORDERED; or2 = LT; break; 15479 default: gcc_unreachable (); 15480 } 15481 validate_condition_mode (or1, comp_mode); 15482 validate_condition_mode (or2, comp_mode); 15483 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx); 15484 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx); 15485 compare2_rtx = gen_rtx_COMPARE (CCEQmode, 15486 gen_rtx_IOR (SImode, or1_rtx, or2_rtx), 15487 const_true_rtx); 15488 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx)); 15489 15490 compare_result = or_result; 15491 code = EQ; 15492 } 15493 15494 validate_condition_mode (code, GET_MODE (compare_result)); 15495 15496 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx); 15497} 15498 15499 15500/* Emit the RTL for an sCOND pattern. */ 15501 15502void 15503rs6000_emit_sISEL (enum machine_mode mode, rtx operands[]) 15504{ 15505 rtx condition_rtx; 15506 enum machine_mode op_mode; 15507 enum rtx_code cond_code; 15508 rtx result = operands[0]; 15509 15510 condition_rtx = rs6000_generate_compare (operands[1], mode); 15511 cond_code = GET_CODE (condition_rtx); 15512 15513 op_mode = GET_MODE (XEXP (operands[1], 0)); 15514 if (op_mode == VOIDmode) 15515 op_mode = GET_MODE (XEXP (operands[1], 1)); 15516 15517 if (TARGET_POWERPC64 && GET_MODE (result) == DImode) 15518 { 15519 PUT_MODE (condition_rtx, DImode); 15520 if (cond_code == GEU || cond_code == GTU || cond_code == LEU 15521 || cond_code == LTU) 15522 emit_insn (gen_isel_unsigned_di (result, condition_rtx, 15523 force_reg (DImode, const1_rtx), 15524 force_reg (DImode, const0_rtx), 15525 XEXP (condition_rtx, 0))); 15526 else 15527 emit_insn (gen_isel_signed_di (result, condition_rtx, 15528 force_reg (DImode, const1_rtx), 15529 force_reg (DImode, const0_rtx), 15530 XEXP (condition_rtx, 0))); 15531 } 15532 else 15533 { 15534 PUT_MODE (condition_rtx, SImode); 15535 if (cond_code == GEU || cond_code == GTU || cond_code == LEU 15536 || cond_code == LTU) 15537 emit_insn (gen_isel_unsigned_si (result, condition_rtx, 15538 force_reg (SImode, const1_rtx), 15539 force_reg (SImode, const0_rtx), 15540 XEXP (condition_rtx, 0))); 15541 else 15542 emit_insn (gen_isel_signed_si (result, condition_rtx, 15543 force_reg (SImode, const1_rtx), 15544 force_reg (SImode, const0_rtx), 15545 XEXP (condition_rtx, 0))); 15546 } 15547} 15548 15549void 15550rs6000_emit_sCOND (enum machine_mode mode, rtx operands[]) 15551{ 15552 rtx condition_rtx; 15553 enum machine_mode op_mode; 15554 enum rtx_code cond_code; 15555 rtx result = operands[0]; 15556 15557 if (TARGET_ISEL && (mode == SImode || mode == DImode)) 15558 { 15559 rs6000_emit_sISEL (mode, operands); 15560 return; 15561 } 15562 15563 condition_rtx = rs6000_generate_compare (operands[1], mode); 15564 cond_code = GET_CODE (condition_rtx); 15565 15566 if (FLOAT_MODE_P (mode) 15567 && !TARGET_FPRS && TARGET_HARD_FLOAT) 15568 { 15569 rtx t; 15570 15571 PUT_MODE (condition_rtx, SImode); 15572 t = XEXP (condition_rtx, 0); 15573 15574 gcc_assert (cond_code == NE || cond_code == EQ); 15575 15576 if (cond_code == NE) 15577 emit_insn (gen_e500_flip_gt_bit (t, t)); 15578 15579 emit_insn (gen_move_from_CR_gt_bit (result, t)); 15580 return; 15581 } 15582 15583 if (cond_code == NE 15584 || cond_code == GE || cond_code == LE 15585 || cond_code == GEU || cond_code == LEU 15586 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE) 15587 { 15588 rtx not_result = gen_reg_rtx (CCEQmode); 15589 rtx not_op, rev_cond_rtx; 15590 enum machine_mode cc_mode; 15591 15592 cc_mode = GET_MODE (XEXP (condition_rtx, 0)); 15593 15594 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code), 15595 SImode, XEXP (condition_rtx, 0), const0_rtx); 15596 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx); 15597 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op)); 15598 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx); 15599 } 15600 15601 op_mode = GET_MODE (XEXP (operands[1], 0)); 15602 if (op_mode == VOIDmode) 15603 op_mode = GET_MODE (XEXP (operands[1], 1)); 15604 15605 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode))) 15606 { 15607 PUT_MODE (condition_rtx, DImode); 15608 convert_move (result, condition_rtx, 0); 15609 } 15610 else 15611 { 15612 PUT_MODE (condition_rtx, SImode); 15613 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx)); 15614 } 15615} 15616 15617/* Emit a branch of kind CODE to location LOC. */ 15618 15619void 15620rs6000_emit_cbranch (enum machine_mode mode, rtx operands[]) 15621{ 15622 rtx condition_rtx, loc_ref; 15623 15624 condition_rtx = rs6000_generate_compare (operands[0], mode); 15625 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]); 15626 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, 15627 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx, 15628 loc_ref, pc_rtx))); 15629} 15630 15631/* Return the string to output a conditional branch to LABEL, which is 15632 the operand number of the label, or -1 if the branch is really a 15633 conditional return. 15634 15635 OP is the conditional expression. XEXP (OP, 0) is assumed to be a 15636 condition code register and its mode specifies what kind of 15637 comparison we made. 15638 15639 REVERSED is nonzero if we should reverse the sense of the comparison. 15640 15641 INSN is the insn. */ 15642 15643char * 15644output_cbranch (rtx op, const char *label, int reversed, rtx insn) 15645{ 15646 static char string[64]; 15647 enum rtx_code code = GET_CODE (op); 15648 rtx cc_reg = XEXP (op, 0); 15649 enum machine_mode mode = GET_MODE (cc_reg); 15650 int cc_regno = REGNO (cc_reg) - CR0_REGNO; 15651 int need_longbranch = label != NULL && get_attr_length (insn) == 8; 15652 int really_reversed = reversed ^ need_longbranch; 15653 char *s = string; 15654 const char *ccode; 15655 const char *pred; 15656 rtx note; 15657 15658 validate_condition_mode (code, mode); 15659 15660 /* Work out which way this really branches. We could use 15661 reverse_condition_maybe_unordered here always but this 15662 makes the resulting assembler clearer. */ 15663 if (really_reversed) 15664 { 15665 /* Reversal of FP compares takes care -- an ordered compare 15666 becomes an unordered compare and vice versa. */ 15667 if (mode == CCFPmode) 15668 code = reverse_condition_maybe_unordered (code); 15669 else 15670 code = reverse_condition (code); 15671 } 15672 15673 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode) 15674 { 15675 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely 15676 to the GT bit. */ 15677 switch (code) 15678 { 15679 case EQ: 15680 /* Opposite of GT. */ 15681 code = GT; 15682 break; 15683 15684 case NE: 15685 code = UNLE; 15686 break; 15687 15688 default: 15689 gcc_unreachable (); 15690 } 15691 } 15692 15693 switch (code) 15694 { 15695 /* Not all of these are actually distinct opcodes, but 15696 we distinguish them for clarity of the resulting assembler. */ 15697 case NE: case LTGT: 15698 ccode = "ne"; break; 15699 case EQ: case UNEQ: 15700 ccode = "eq"; break; 15701 case GE: case GEU: 15702 ccode = "ge"; break; 15703 case GT: case GTU: case UNGT: 15704 ccode = "gt"; break; 15705 case LE: case LEU: 15706 ccode = "le"; break; 15707 case LT: case LTU: case UNLT: 15708 ccode = "lt"; break; 15709 case UNORDERED: ccode = "un"; break; 15710 case ORDERED: ccode = "nu"; break; 15711 case UNGE: ccode = "nl"; break; 15712 case UNLE: ccode = "ng"; break; 15713 default: 15714 gcc_unreachable (); 15715 } 15716 15717 /* Maybe we have a guess as to how likely the branch is. 15718 The old mnemonics don't have a way to specify this information. */ 15719 pred = ""; 15720 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX); 15721 if (note != NULL_RTX) 15722 { 15723 /* PROB is the difference from 50%. */ 15724 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2; 15725 15726 /* Only hint for highly probable/improbable branches on newer 15727 cpus as static prediction overrides processor dynamic 15728 prediction. For older cpus we may as well always hint, but 15729 assume not taken for branches that are very close to 50% as a 15730 mispredicted taken branch is more expensive than a 15731 mispredicted not-taken branch. */ 15732 if (rs6000_always_hint 15733 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48 15734 && br_prob_note_reliable_p (note))) 15735 { 15736 if (abs (prob) > REG_BR_PROB_BASE / 20 15737 && ((prob > 0) ^ need_longbranch)) 15738 pred = "+"; 15739 else 15740 pred = "-"; 15741 } 15742 } 15743 15744 if (label == NULL) 15745 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred); 15746 else 15747 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred); 15748 15749 /* We need to escape any '%' characters in the reg_names string. 15750 Assume they'd only be the first character.... */ 15751 if (reg_names[cc_regno + CR0_REGNO][0] == '%') 15752 *s++ = '%'; 15753 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]); 15754 15755 if (label != NULL) 15756 { 15757 /* If the branch distance was too far, we may have to use an 15758 unconditional branch to go the distance. */ 15759 if (need_longbranch) 15760 s += sprintf (s, ",$+8\n\tb %s", label); 15761 else 15762 s += sprintf (s, ",%s", label); 15763 } 15764 15765 return string; 15766} 15767 15768/* Return the string to flip the GT bit on a CR. */ 15769char * 15770output_e500_flip_gt_bit (rtx dst, rtx src) 15771{ 15772 static char string[64]; 15773 int a, b; 15774 15775 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst)) 15776 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src))); 15777 15778 /* GT bit. */ 15779 a = 4 * (REGNO (dst) - CR0_REGNO) + 1; 15780 b = 4 * (REGNO (src) - CR0_REGNO) + 1; 15781 15782 sprintf (string, "crnot %d,%d", a, b); 15783 return string; 15784} 15785 15786/* Return insn for VSX or Altivec comparisons. */ 15787 15788static rtx 15789rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1) 15790{ 15791 rtx mask; 15792 enum machine_mode mode = GET_MODE (op0); 15793 15794 switch (code) 15795 { 15796 default: 15797 break; 15798 15799 case GE: 15800 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT) 15801 return NULL_RTX; 15802 15803 case EQ: 15804 case GT: 15805 case GTU: 15806 mask = gen_reg_rtx (mode); 15807 emit_insn (gen_rtx_SET (VOIDmode, 15808 mask, 15809 gen_rtx_fmt_ee (code, mode, op0, op1))); 15810 return mask; 15811 } 15812 15813 return NULL_RTX; 15814} 15815 15816/* Emit vector compare for operands OP0 and OP1 using code RCODE. 15817 DMODE is expected destination mode. This is a recursive function. */ 15818 15819static rtx 15820rs6000_emit_vector_compare (enum rtx_code rcode, 15821 rtx op0, rtx op1, 15822 enum machine_mode dmode) 15823{ 15824 rtx mask; 15825 bool swap_operands = false; 15826 bool try_again = false; 15827 15828 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode)); 15829 gcc_assert (GET_MODE (op0) == GET_MODE (op1)); 15830 15831 /* See if the comparison works as is. */ 15832 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1); 15833 if (mask) 15834 return mask; 15835 15836 switch (rcode) 15837 { 15838 case LT: 15839 rcode = GT; 15840 swap_operands = true; 15841 try_again = true; 15842 break; 15843 case LTU: 15844 rcode = GTU; 15845 swap_operands = true; 15846 try_again = true; 15847 break; 15848 case NE: 15849 case UNLE: 15850 case UNLT: 15851 case UNGE: 15852 case UNGT: 15853 /* Invert condition and try again. 15854 e.g., A != B becomes ~(A==B). */ 15855 { 15856 enum rtx_code rev_code; 15857 enum insn_code nor_code; 15858 rtx mask2; 15859 15860 rev_code = reverse_condition_maybe_unordered (rcode); 15861 if (rev_code == UNKNOWN) 15862 return NULL_RTX; 15863 15864 nor_code = optab_handler (one_cmpl_optab, (int)dmode)->insn_code; 15865 if (nor_code == CODE_FOR_nothing) 15866 return NULL_RTX; 15867 15868 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode); 15869 if (!mask2) 15870 return NULL_RTX; 15871 15872 mask = gen_reg_rtx (dmode); 15873 emit_insn (GEN_FCN (nor_code) (mask, mask2)); 15874 return mask; 15875 } 15876 break; 15877 case GE: 15878 case GEU: 15879 case LE: 15880 case LEU: 15881 /* Try GT/GTU/LT/LTU OR EQ */ 15882 { 15883 rtx c_rtx, eq_rtx; 15884 enum insn_code ior_code; 15885 enum rtx_code new_code; 15886 15887 switch (rcode) 15888 { 15889 case GE: 15890 new_code = GT; 15891 break; 15892 15893 case GEU: 15894 new_code = GTU; 15895 break; 15896 15897 case LE: 15898 new_code = LT; 15899 break; 15900 15901 case LEU: 15902 new_code = LTU; 15903 break; 15904 15905 default: 15906 gcc_unreachable (); 15907 } 15908 15909 ior_code = optab_handler (ior_optab, (int)dmode)->insn_code; 15910 if (ior_code == CODE_FOR_nothing) 15911 return NULL_RTX; 15912 15913 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode); 15914 if (!c_rtx) 15915 return NULL_RTX; 15916 15917 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode); 15918 if (!eq_rtx) 15919 return NULL_RTX; 15920 15921 mask = gen_reg_rtx (dmode); 15922 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx)); 15923 return mask; 15924 } 15925 break; 15926 default: 15927 return NULL_RTX; 15928 } 15929 15930 if (try_again) 15931 { 15932 if (swap_operands) 15933 { 15934 rtx tmp; 15935 tmp = op0; 15936 op0 = op1; 15937 op1 = tmp; 15938 } 15939 15940 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1); 15941 if (mask) 15942 return mask; 15943 } 15944 15945 /* You only get two chances. */ 15946 return NULL_RTX; 15947} 15948 15949/* Emit vector conditional expression. DEST is destination. OP_TRUE and 15950 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two 15951 operands for the relation operation COND. */ 15952 15953int 15954rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false, 15955 rtx cond, rtx cc_op0, rtx cc_op1) 15956{ 15957 enum machine_mode dest_mode = GET_MODE (dest); 15958 enum rtx_code rcode = GET_CODE (cond); 15959 enum machine_mode cc_mode = CCmode; 15960 rtx mask; 15961 rtx cond2; 15962 rtx tmp; 15963 bool invert_move = false; 15964 15965 if (VECTOR_UNIT_NONE_P (dest_mode)) 15966 return 0; 15967 15968 switch (rcode) 15969 { 15970 /* Swap operands if we can, and fall back to doing the operation as 15971 specified, and doing a NOR to invert the test. */ 15972 case NE: 15973 case UNLE: 15974 case UNLT: 15975 case UNGE: 15976 case UNGT: 15977 /* Invert condition and try again. 15978 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */ 15979 invert_move = true; 15980 rcode = reverse_condition_maybe_unordered (rcode); 15981 if (rcode == UNKNOWN) 15982 return 0; 15983 break; 15984 15985 /* Mark unsigned tests with CCUNSmode. */ 15986 case GTU: 15987 case GEU: 15988 case LTU: 15989 case LEU: 15990 cc_mode = CCUNSmode; 15991 break; 15992 15993 default: 15994 break; 15995 } 15996 15997 /* Get the vector mask for the given relational operations. */ 15998 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode); 15999 16000 if (!mask) 16001 return 0; 16002 16003 if (invert_move) 16004 { 16005 tmp = op_true; 16006 op_true = op_false; 16007 op_false = tmp; 16008 } 16009 16010 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx); 16011 emit_insn (gen_rtx_SET (VOIDmode, 16012 dest, 16013 gen_rtx_IF_THEN_ELSE (dest_mode, 16014 cond2, 16015 op_true, 16016 op_false))); 16017 return 1; 16018} 16019 16020/* Emit a conditional move: move TRUE_COND to DEST if OP of the 16021 operands of the last comparison is nonzero/true, FALSE_COND if it 16022 is zero/false. Return 0 if the hardware has no such operation. */ 16023 16024int 16025rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond) 16026{ 16027 enum rtx_code code = GET_CODE (op); 16028 rtx op0 = XEXP (op, 0); 16029 rtx op1 = XEXP (op, 1); 16030 REAL_VALUE_TYPE c1; 16031 enum machine_mode compare_mode = GET_MODE (op0); 16032 enum machine_mode result_mode = GET_MODE (dest); 16033 rtx temp; 16034 bool is_against_zero; 16035 16036 /* These modes should always match. */ 16037 if (GET_MODE (op1) != compare_mode 16038 /* In the isel case however, we can use a compare immediate, so 16039 op1 may be a small constant. */ 16040 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode))) 16041 return 0; 16042 if (GET_MODE (true_cond) != result_mode) 16043 return 0; 16044 if (GET_MODE (false_cond) != result_mode) 16045 return 0; 16046 16047 /* First, work out if the hardware can do this at all, or 16048 if it's too slow.... */ 16049 if (!FLOAT_MODE_P (compare_mode)) 16050 { 16051 if (TARGET_ISEL) 16052 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond); 16053 return 0; 16054 } 16055 else if (TARGET_HARD_FLOAT && !TARGET_FPRS 16056 && SCALAR_FLOAT_MODE_P (compare_mode)) 16057 return 0; 16058 16059 is_against_zero = op1 == CONST0_RTX (compare_mode); 16060 16061 /* A floating-point subtract might overflow, underflow, or produce 16062 an inexact result, thus changing the floating-point flags, so it 16063 can't be generated if we care about that. It's safe if one side 16064 of the construct is zero, since then no subtract will be 16065 generated. */ 16066 if (SCALAR_FLOAT_MODE_P (compare_mode) 16067 && flag_trapping_math && ! is_against_zero) 16068 return 0; 16069 16070 /* Eliminate half of the comparisons by switching operands, this 16071 makes the remaining code simpler. */ 16072 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE 16073 || code == LTGT || code == LT || code == UNLE) 16074 { 16075 code = reverse_condition_maybe_unordered (code); 16076 temp = true_cond; 16077 true_cond = false_cond; 16078 false_cond = temp; 16079 } 16080 16081 /* UNEQ and LTGT take four instructions for a comparison with zero, 16082 it'll probably be faster to use a branch here too. */ 16083 if (code == UNEQ && HONOR_NANS (compare_mode)) 16084 return 0; 16085 16086 if (GET_CODE (op1) == CONST_DOUBLE) 16087 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1); 16088 16089 /* We're going to try to implement comparisons by performing 16090 a subtract, then comparing against zero. Unfortunately, 16091 Inf - Inf is NaN which is not zero, and so if we don't 16092 know that the operand is finite and the comparison 16093 would treat EQ different to UNORDERED, we can't do it. */ 16094 if (HONOR_INFINITIES (compare_mode) 16095 && code != GT && code != UNGE 16096 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1)) 16097 /* Constructs of the form (a OP b ? a : b) are safe. */ 16098 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond)) 16099 || (! rtx_equal_p (op0, true_cond) 16100 && ! rtx_equal_p (op1, true_cond)))) 16101 return 0; 16102 16103 /* At this point we know we can use fsel. */ 16104 16105 /* Reduce the comparison to a comparison against zero. */ 16106 if (! is_against_zero) 16107 { 16108 temp = gen_reg_rtx (compare_mode); 16109 emit_insn (gen_rtx_SET (VOIDmode, temp, 16110 gen_rtx_MINUS (compare_mode, op0, op1))); 16111 op0 = temp; 16112 op1 = CONST0_RTX (compare_mode); 16113 } 16114 16115 /* If we don't care about NaNs we can reduce some of the comparisons 16116 down to faster ones. */ 16117 if (! HONOR_NANS (compare_mode)) 16118 switch (code) 16119 { 16120 case GT: 16121 code = LE; 16122 temp = true_cond; 16123 true_cond = false_cond; 16124 false_cond = temp; 16125 break; 16126 case UNGE: 16127 code = GE; 16128 break; 16129 case UNEQ: 16130 code = EQ; 16131 break; 16132 default: 16133 break; 16134 } 16135 16136 /* Now, reduce everything down to a GE. */ 16137 switch (code) 16138 { 16139 case GE: 16140 break; 16141 16142 case LE: 16143 temp = gen_reg_rtx (compare_mode); 16144 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0))); 16145 op0 = temp; 16146 break; 16147 16148 case ORDERED: 16149 temp = gen_reg_rtx (compare_mode); 16150 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0))); 16151 op0 = temp; 16152 break; 16153 16154 case EQ: 16155 temp = gen_reg_rtx (compare_mode); 16156 emit_insn (gen_rtx_SET (VOIDmode, temp, 16157 gen_rtx_NEG (compare_mode, 16158 gen_rtx_ABS (compare_mode, op0)))); 16159 op0 = temp; 16160 break; 16161 16162 case UNGE: 16163 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */ 16164 temp = gen_reg_rtx (result_mode); 16165 emit_insn (gen_rtx_SET (VOIDmode, temp, 16166 gen_rtx_IF_THEN_ELSE (result_mode, 16167 gen_rtx_GE (VOIDmode, 16168 op0, op1), 16169 true_cond, false_cond))); 16170 false_cond = true_cond; 16171 true_cond = temp; 16172 16173 temp = gen_reg_rtx (compare_mode); 16174 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0))); 16175 op0 = temp; 16176 break; 16177 16178 case GT: 16179 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */ 16180 temp = gen_reg_rtx (result_mode); 16181 emit_insn (gen_rtx_SET (VOIDmode, temp, 16182 gen_rtx_IF_THEN_ELSE (result_mode, 16183 gen_rtx_GE (VOIDmode, 16184 op0, op1), 16185 true_cond, false_cond))); 16186 true_cond = false_cond; 16187 false_cond = temp; 16188 16189 temp = gen_reg_rtx (compare_mode); 16190 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0))); 16191 op0 = temp; 16192 break; 16193 16194 default: 16195 gcc_unreachable (); 16196 } 16197 16198 emit_insn (gen_rtx_SET (VOIDmode, dest, 16199 gen_rtx_IF_THEN_ELSE (result_mode, 16200 gen_rtx_GE (VOIDmode, 16201 op0, op1), 16202 true_cond, false_cond))); 16203 return 1; 16204} 16205 16206/* Same as above, but for ints (isel). */ 16207 16208static int 16209rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond) 16210{ 16211 rtx condition_rtx, cr; 16212 enum machine_mode mode = GET_MODE (dest); 16213 16214 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode)) 16215 return 0; 16216 16217 /* We still have to do the compare, because isel doesn't do a 16218 compare, it just looks at the CRx bits set by a previous compare 16219 instruction. */ 16220 condition_rtx = rs6000_generate_compare (op, mode); 16221 cr = XEXP (condition_rtx, 0); 16222 16223 if (mode == SImode) 16224 { 16225 if (GET_MODE (cr) == CCmode) 16226 emit_insn (gen_isel_signed_si (dest, condition_rtx, 16227 true_cond, false_cond, cr)); 16228 else 16229 emit_insn (gen_isel_unsigned_si (dest, condition_rtx, 16230 true_cond, false_cond, cr)); 16231 } 16232 else 16233 { 16234 if (GET_MODE (cr) == CCmode) 16235 emit_insn (gen_isel_signed_di (dest, condition_rtx, 16236 true_cond, false_cond, cr)); 16237 else 16238 emit_insn (gen_isel_unsigned_di (dest, condition_rtx, 16239 true_cond, false_cond, cr)); 16240 } 16241 16242 return 1; 16243} 16244 16245const char * 16246output_isel (rtx *operands) 16247{ 16248 enum rtx_code code; 16249 16250 code = GET_CODE (operands[1]); 16251 if (code == GE || code == GEU || code == LE || code == LEU || code == NE) 16252 { 16253 PUT_CODE (operands[1], reverse_condition (code)); 16254 return "isel %0,%3,%2,%j1"; 16255 } 16256 else 16257 return "isel %0,%2,%3,%j1"; 16258} 16259 16260void 16261rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1) 16262{ 16263 enum machine_mode mode = GET_MODE (op0); 16264 enum rtx_code c; 16265 rtx target; 16266 16267 /* VSX/altivec have direct min/max insns. */ 16268 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)) 16269 { 16270 emit_insn (gen_rtx_SET (VOIDmode, 16271 dest, 16272 gen_rtx_fmt_ee (code, mode, op0, op1))); 16273 return; 16274 } 16275 16276 if (code == SMAX || code == SMIN) 16277 c = GE; 16278 else 16279 c = GEU; 16280 16281 if (code == SMAX || code == UMAX) 16282 target = emit_conditional_move (dest, c, op0, op1, mode, 16283 op0, op1, mode, 0); 16284 else 16285 target = emit_conditional_move (dest, c, op0, op1, mode, 16286 op1, op0, mode, 0); 16287 gcc_assert (target); 16288 if (target != dest) 16289 emit_move_insn (dest, target); 16290} 16291 16292/* Emit instructions to perform a load-reserved/store-conditional operation. 16293 The operation performed is an atomic 16294 (set M (CODE:MODE M OP)) 16295 If not NULL, BEFORE is atomically set to M before the operation, and 16296 AFTER is set to M after the operation (that is, (CODE:MODE M OP)). 16297 If SYNC_P then a memory barrier is emitted before the operation. 16298 Either OP or M may be wrapped in a NOT operation. */ 16299 16300void 16301rs6000_emit_sync (enum rtx_code code, enum machine_mode mode, 16302 rtx m, rtx op, rtx before_param, rtx after_param, 16303 bool sync_p) 16304{ 16305 enum machine_mode used_mode; 16306 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after; 16307 rtx used_m; 16308 rtvec vec; 16309 HOST_WIDE_INT imask = GET_MODE_MASK (mode); 16310 rtx shift = NULL_RTX; 16311 16312 if (sync_p) 16313 emit_insn (gen_lwsync ()); 16314 16315 used_m = m; 16316 16317 /* If this is smaller than SImode, we'll have to use SImode with 16318 adjustments. */ 16319 if (mode == QImode || mode == HImode) 16320 { 16321 rtx newop, oldop; 16322 16323 if (MEM_ALIGN (used_m) >= 32) 16324 { 16325 int ishift = 0; 16326 if (BYTES_BIG_ENDIAN) 16327 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode); 16328 16329 shift = GEN_INT (ishift); 16330 used_m = change_address (used_m, SImode, 0); 16331 } 16332 else 16333 { 16334 rtx addrSI, aligned_addr; 16335 int shift_mask = mode == QImode ? 0x18 : 0x10; 16336 16337 addrSI = gen_lowpart_common (SImode, 16338 force_reg (Pmode, XEXP (used_m, 0))); 16339 addrSI = force_reg (SImode, addrSI); 16340 shift = gen_reg_rtx (SImode); 16341 16342 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3), 16343 GEN_INT (shift_mask))); 16344 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask))); 16345 16346 aligned_addr = expand_binop (Pmode, and_optab, 16347 XEXP (used_m, 0), 16348 GEN_INT (-4), NULL_RTX, 16349 1, OPTAB_LIB_WIDEN); 16350 used_m = change_address (used_m, SImode, aligned_addr); 16351 set_mem_align (used_m, 32); 16352 } 16353 /* It's safe to keep the old alias set of USED_M, because 16354 the operation is atomic and only affects the original 16355 USED_M. */ 16356 m = used_m; 16357 16358 if (GET_CODE (op) == NOT) 16359 { 16360 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode); 16361 oldop = gen_rtx_NOT (SImode, oldop); 16362 } 16363 else 16364 oldop = lowpart_subreg (SImode, op, mode); 16365 16366 switch (code) 16367 { 16368 case IOR: 16369 case XOR: 16370 newop = expand_binop (SImode, and_optab, 16371 oldop, GEN_INT (imask), NULL_RTX, 16372 1, OPTAB_LIB_WIDEN); 16373 emit_insn (gen_ashlsi3 (newop, newop, shift)); 16374 break; 16375 16376 case NOT: /* NAND */ 16377 newop = expand_binop (SImode, ior_optab, 16378 oldop, GEN_INT (~imask), NULL_RTX, 16379 1, OPTAB_LIB_WIDEN); 16380 emit_insn (gen_rotlsi3 (newop, newop, shift)); 16381 break; 16382 16383 case AND: 16384 newop = expand_binop (SImode, ior_optab, 16385 oldop, GEN_INT (~imask), NULL_RTX, 16386 1, OPTAB_LIB_WIDEN); 16387 emit_insn (gen_rotlsi3 (newop, newop, shift)); 16388 break; 16389 16390 case PLUS: 16391 case MINUS: 16392 { 16393 rtx mask; 16394 16395 newop = expand_binop (SImode, and_optab, 16396 oldop, GEN_INT (imask), NULL_RTX, 16397 1, OPTAB_LIB_WIDEN); 16398 emit_insn (gen_ashlsi3 (newop, newop, shift)); 16399 16400 mask = gen_reg_rtx (SImode); 16401 emit_move_insn (mask, GEN_INT (imask)); 16402 emit_insn (gen_ashlsi3 (mask, mask, shift)); 16403 16404 if (code == PLUS) 16405 newop = gen_rtx_PLUS (SImode, m, newop); 16406 else 16407 newop = gen_rtx_MINUS (SImode, m, newop); 16408 newop = gen_rtx_AND (SImode, newop, mask); 16409 newop = gen_rtx_IOR (SImode, newop, 16410 gen_rtx_AND (SImode, 16411 gen_rtx_NOT (SImode, mask), 16412 m)); 16413 break; 16414 } 16415 16416 default: 16417 gcc_unreachable (); 16418 } 16419 16420 op = newop; 16421 used_mode = SImode; 16422 before = gen_reg_rtx (used_mode); 16423 after = gen_reg_rtx (used_mode); 16424 } 16425 else 16426 { 16427 used_mode = mode; 16428 before = before_param; 16429 after = after_param; 16430 16431 if (before == NULL_RTX) 16432 before = gen_reg_rtx (used_mode); 16433 if (after == NULL_RTX) 16434 after = gen_reg_rtx (used_mode); 16435 } 16436 16437 if ((code == PLUS || code == MINUS) 16438 && used_mode != mode) 16439 the_op = op; /* Computed above. */ 16440 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT) 16441 the_op = gen_rtx_fmt_ee (code, used_mode, op, m); 16442 else if (code == NOT) 16443 the_op = gen_rtx_fmt_ee (IOR, used_mode, 16444 gen_rtx_NOT (used_mode, m), 16445 gen_rtx_NOT (used_mode, op)); 16446 else 16447 the_op = gen_rtx_fmt_ee (code, used_mode, m, op); 16448 16449 set_after = gen_rtx_SET (VOIDmode, after, the_op); 16450 set_before = gen_rtx_SET (VOIDmode, before, used_m); 16451 set_atomic = gen_rtx_SET (VOIDmode, used_m, 16452 gen_rtx_UNSPEC (used_mode, 16453 gen_rtvec (1, the_op), 16454 UNSPEC_SYNC_OP)); 16455 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode)); 16456 16457 if ((code == PLUS || code == MINUS) && used_mode != mode) 16458 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch, 16459 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode))); 16460 else 16461 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch); 16462 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec)); 16463 16464 /* Shift and mask the return values properly. */ 16465 if (used_mode != mode && before_param) 16466 { 16467 emit_insn (gen_lshrsi3 (before, before, shift)); 16468 convert_move (before_param, before, 1); 16469 } 16470 16471 if (used_mode != mode && after_param) 16472 { 16473 emit_insn (gen_lshrsi3 (after, after, shift)); 16474 convert_move (after_param, after, 1); 16475 } 16476 16477 /* The previous sequence will end with a branch that's dependent on 16478 the conditional store, so placing an isync will ensure that no 16479 other instructions (especially, no load or store instructions) 16480 can start before the atomic operation completes. */ 16481 if (sync_p) 16482 emit_insn (gen_isync ()); 16483} 16484 16485/* A subroutine of the atomic operation splitters. Jump to LABEL if 16486 COND is true. Mark the jump as unlikely to be taken. */ 16487 16488static void 16489emit_unlikely_jump (rtx cond, rtx label) 16490{ 16491 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1); 16492 rtx x; 16493 16494 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx); 16495 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x)); 16496 add_reg_note (x, REG_BR_PROB, very_unlikely); 16497} 16498 16499/* A subroutine of the atomic operation splitters. Emit a load-locked 16500 instruction in MODE. */ 16501 16502static void 16503emit_load_locked (enum machine_mode mode, rtx reg, rtx mem) 16504{ 16505 rtx (*fn) (rtx, rtx) = NULL; 16506 if (mode == SImode) 16507 fn = gen_load_locked_si; 16508 else if (mode == DImode) 16509 fn = gen_load_locked_di; 16510 emit_insn (fn (reg, mem)); 16511} 16512 16513/* A subroutine of the atomic operation splitters. Emit a store-conditional 16514 instruction in MODE. */ 16515 16516static void 16517emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val) 16518{ 16519 rtx (*fn) (rtx, rtx, rtx) = NULL; 16520 if (mode == SImode) 16521 fn = gen_store_conditional_si; 16522 else if (mode == DImode) 16523 fn = gen_store_conditional_di; 16524 16525 /* Emit sync before stwcx. to address PPC405 Erratum. */ 16526 if (PPC405_ERRATUM77) 16527 emit_insn (gen_memory_barrier ()); 16528 16529 emit_insn (fn (res, mem, val)); 16530} 16531 16532/* Expand an atomic fetch-and-operate pattern. CODE is the binary operation 16533 to perform. MEM is the memory on which to operate. VAL is the second 16534 operand of the binary operator. BEFORE and AFTER are optional locations to 16535 return the value of MEM either before of after the operation. SCRATCH is 16536 a scratch register. */ 16537 16538void 16539rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val, 16540 rtx before, rtx after, rtx scratch) 16541{ 16542 enum machine_mode mode = GET_MODE (mem); 16543 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO); 16544 16545 emit_insn (gen_lwsync ()); 16546 16547 label = gen_label_rtx (); 16548 emit_label (label); 16549 label = gen_rtx_LABEL_REF (VOIDmode, label); 16550 16551 if (before == NULL_RTX) 16552 before = scratch; 16553 emit_load_locked (mode, before, mem); 16554 16555 if (code == NOT) 16556 x = gen_rtx_IOR (mode, 16557 gen_rtx_NOT (mode, before), 16558 gen_rtx_NOT (mode, val)); 16559 else if (code == AND) 16560 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND); 16561 else 16562 x = gen_rtx_fmt_ee (code, mode, before, val); 16563 16564 if (after != NULL_RTX) 16565 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x))); 16566 emit_insn (gen_rtx_SET (VOIDmode, scratch, x)); 16567 16568 emit_store_conditional (mode, cond, mem, scratch); 16569 16570 x = gen_rtx_NE (VOIDmode, cond, const0_rtx); 16571 emit_unlikely_jump (x, label); 16572 16573 emit_insn (gen_isync ()); 16574} 16575 16576/* Expand an atomic compare and swap operation. MEM is the memory on which 16577 to operate. OLDVAL is the old value to be compared. NEWVAL is the new 16578 value to be stored. SCRATCH is a scratch GPR. */ 16579 16580void 16581rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval, 16582 rtx scratch) 16583{ 16584 enum machine_mode mode = GET_MODE (mem); 16585 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO); 16586 16587 emit_insn (gen_lwsync ()); 16588 16589 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ()); 16590 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ()); 16591 emit_label (XEXP (label1, 0)); 16592 16593 emit_load_locked (mode, retval, mem); 16594 16595 x = gen_rtx_COMPARE (CCmode, retval, oldval); 16596 emit_insn (gen_rtx_SET (VOIDmode, cond, x)); 16597 16598 x = gen_rtx_NE (VOIDmode, cond, const0_rtx); 16599 emit_unlikely_jump (x, label2); 16600 16601 emit_move_insn (scratch, newval); 16602 emit_store_conditional (mode, cond, mem, scratch); 16603 16604 x = gen_rtx_NE (VOIDmode, cond, const0_rtx); 16605 emit_unlikely_jump (x, label1); 16606 16607 emit_insn (gen_isync ()); 16608 emit_label (XEXP (label2, 0)); 16609} 16610 16611/* Expand an atomic test and set operation. MEM is the memory on which 16612 to operate. VAL is the value set. SCRATCH is a scratch GPR. */ 16613 16614void 16615rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch) 16616{ 16617 enum machine_mode mode = GET_MODE (mem); 16618 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO); 16619 16620 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ()); 16621 emit_label (XEXP (label, 0)); 16622 16623 emit_load_locked (mode, retval, mem); 16624 emit_move_insn (scratch, val); 16625 emit_store_conditional (mode, cond, mem, scratch); 16626 16627 x = gen_rtx_NE (VOIDmode, cond, const0_rtx); 16628 emit_unlikely_jump (x, label); 16629 16630 emit_insn (gen_isync ()); 16631} 16632 16633void 16634rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval) 16635{ 16636 enum machine_mode mode = GET_MODE (mem); 16637 rtx addrSI, align, wdst, shift, mask; 16638 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10; 16639 HOST_WIDE_INT imask = GET_MODE_MASK (mode); 16640 16641 /* Shift amount for subword relative to aligned word. */ 16642 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0)); 16643 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI)); 16644 shift = gen_reg_rtx (SImode); 16645 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3), 16646 GEN_INT (shift_mask))); 16647 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask))); 16648 16649 /* Shift and mask old value into position within word. */ 16650 oldval = convert_modes (SImode, mode, oldval, 1); 16651 oldval = expand_binop (SImode, and_optab, 16652 oldval, GEN_INT (imask), NULL_RTX, 16653 1, OPTAB_LIB_WIDEN); 16654 emit_insn (gen_ashlsi3 (oldval, oldval, shift)); 16655 16656 /* Shift and mask new value into position within word. */ 16657 newval = convert_modes (SImode, mode, newval, 1); 16658 newval = expand_binop (SImode, and_optab, 16659 newval, GEN_INT (imask), NULL_RTX, 16660 1, OPTAB_LIB_WIDEN); 16661 emit_insn (gen_ashlsi3 (newval, newval, shift)); 16662 16663 /* Mask for insertion. */ 16664 mask = gen_reg_rtx (SImode); 16665 emit_move_insn (mask, GEN_INT (imask)); 16666 emit_insn (gen_ashlsi3 (mask, mask, shift)); 16667 16668 /* Address of aligned word containing subword. */ 16669 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4), 16670 NULL_RTX, 1, OPTAB_LIB_WIDEN); 16671 mem = change_address (mem, SImode, align); 16672 set_mem_align (mem, 32); 16673 MEM_VOLATILE_P (mem) = 1; 16674 16675 wdst = gen_reg_rtx (SImode); 16676 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask, 16677 oldval, newval, mem)); 16678 16679 /* Shift the result back. */ 16680 emit_insn (gen_lshrsi3 (wdst, wdst, shift)); 16681 16682 emit_move_insn (dst, gen_lowpart (mode, wdst)); 16683} 16684 16685void 16686rs6000_split_compare_and_swapqhi (rtx dest, rtx mask, 16687 rtx oldval, rtx newval, rtx mem, 16688 rtx scratch) 16689{ 16690 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO); 16691 16692 emit_insn (gen_lwsync ()); 16693 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ()); 16694 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ()); 16695 emit_label (XEXP (label1, 0)); 16696 16697 emit_load_locked (SImode, scratch, mem); 16698 16699 /* Mask subword within loaded value for comparison with oldval. 16700 Use UNSPEC_AND to avoid clobber.*/ 16701 emit_insn (gen_rtx_SET (SImode, dest, 16702 gen_rtx_UNSPEC (SImode, 16703 gen_rtvec (2, scratch, mask), 16704 UNSPEC_AND))); 16705 16706 x = gen_rtx_COMPARE (CCmode, dest, oldval); 16707 emit_insn (gen_rtx_SET (VOIDmode, cond, x)); 16708 16709 x = gen_rtx_NE (VOIDmode, cond, const0_rtx); 16710 emit_unlikely_jump (x, label2); 16711 16712 /* Clear subword within loaded value for insertion of new value. */ 16713 emit_insn (gen_rtx_SET (SImode, scratch, 16714 gen_rtx_AND (SImode, 16715 gen_rtx_NOT (SImode, mask), scratch))); 16716 emit_insn (gen_iorsi3 (scratch, scratch, newval)); 16717 emit_store_conditional (SImode, cond, mem, scratch); 16718 16719 x = gen_rtx_NE (VOIDmode, cond, const0_rtx); 16720 emit_unlikely_jump (x, label1); 16721 16722 emit_insn (gen_isync ()); 16723 emit_label (XEXP (label2, 0)); 16724} 16725 16726 16727 /* Emit instructions to move SRC to DST. Called by splitters for 16728 multi-register moves. It will emit at most one instruction for 16729 each register that is accessed; that is, it won't emit li/lis pairs 16730 (or equivalent for 64-bit code). One of SRC or DST must be a hard 16731 register. */ 16732 16733void 16734rs6000_split_multireg_move (rtx dst, rtx src) 16735{ 16736 /* The register number of the first register being moved. */ 16737 int reg; 16738 /* The mode that is to be moved. */ 16739 enum machine_mode mode; 16740 /* The mode that the move is being done in, and its size. */ 16741 enum machine_mode reg_mode; 16742 int reg_mode_size; 16743 /* The number of registers that will be moved. */ 16744 int nregs; 16745 16746 reg = REG_P (dst) ? REGNO (dst) : REGNO (src); 16747 mode = GET_MODE (dst); 16748 nregs = hard_regno_nregs[reg][mode]; 16749 if (FP_REGNO_P (reg)) 16750 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : 16751 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode); 16752 else if (ALTIVEC_REGNO_P (reg)) 16753 reg_mode = V16QImode; 16754 else if (TARGET_E500_DOUBLE && mode == TFmode) 16755 reg_mode = DFmode; 16756 else 16757 reg_mode = word_mode; 16758 reg_mode_size = GET_MODE_SIZE (reg_mode); 16759 16760 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode)); 16761 16762 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst))) 16763 { 16764 /* Move register range backwards, if we might have destructive 16765 overlap. */ 16766 int i; 16767 for (i = nregs - 1; i >= 0; i--) 16768 emit_insn (gen_rtx_SET (VOIDmode, 16769 simplify_gen_subreg (reg_mode, dst, mode, 16770 i * reg_mode_size), 16771 simplify_gen_subreg (reg_mode, src, mode, 16772 i * reg_mode_size))); 16773 } 16774 else 16775 { 16776 int i; 16777 int j = -1; 16778 bool used_update = false; 16779 rtx restore_basereg = NULL_RTX; 16780 16781 if (MEM_P (src) && INT_REGNO_P (reg)) 16782 { 16783 rtx breg; 16784 16785 if (GET_CODE (XEXP (src, 0)) == PRE_INC 16786 || GET_CODE (XEXP (src, 0)) == PRE_DEC) 16787 { 16788 rtx delta_rtx; 16789 breg = XEXP (XEXP (src, 0), 0); 16790 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC 16791 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src))) 16792 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src)))); 16793 emit_insn (gen_add3_insn (breg, breg, delta_rtx)); 16794 src = replace_equiv_address (src, breg); 16795 } 16796 else if (! rs6000_offsettable_memref_p (src)) 16797 { 16798 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY) 16799 { 16800 rtx basereg = XEXP (XEXP (src, 0), 0); 16801 if (TARGET_UPDATE) 16802 { 16803 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0); 16804 emit_insn (gen_rtx_SET (VOIDmode, ndst, 16805 gen_rtx_MEM (reg_mode, XEXP (src, 0)))); 16806 used_update = true; 16807 } 16808 else 16809 emit_insn (gen_rtx_SET (VOIDmode, basereg, 16810 XEXP (XEXP (src, 0), 1))); 16811 src = replace_equiv_address (src, basereg); 16812 } 16813 else 16814 { 16815 rtx basereg = gen_rtx_REG (Pmode, reg); 16816 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0))); 16817 src = replace_equiv_address (src, basereg); 16818 } 16819 } 16820 16821 breg = XEXP (src, 0); 16822 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM) 16823 breg = XEXP (breg, 0); 16824 16825 /* If the base register we are using to address memory is 16826 also a destination reg, then change that register last. */ 16827 if (REG_P (breg) 16828 && REGNO (breg) >= REGNO (dst) 16829 && REGNO (breg) < REGNO (dst) + nregs) 16830 j = REGNO (breg) - REGNO (dst); 16831 } 16832 else if (MEM_P (dst) && INT_REGNO_P (reg)) 16833 { 16834 rtx breg; 16835 16836 if (GET_CODE (XEXP (dst, 0)) == PRE_INC 16837 || GET_CODE (XEXP (dst, 0)) == PRE_DEC) 16838 { 16839 rtx delta_rtx; 16840 breg = XEXP (XEXP (dst, 0), 0); 16841 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC 16842 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst))) 16843 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst)))); 16844 16845 /* We have to update the breg before doing the store. 16846 Use store with update, if available. */ 16847 16848 if (TARGET_UPDATE) 16849 { 16850 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0); 16851 emit_insn (TARGET_32BIT 16852 ? (TARGET_POWERPC64 16853 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc) 16854 : gen_movsi_update (breg, breg, delta_rtx, nsrc)) 16855 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc)); 16856 used_update = true; 16857 } 16858 else 16859 emit_insn (gen_add3_insn (breg, breg, delta_rtx)); 16860 dst = replace_equiv_address (dst, breg); 16861 } 16862 else if (!rs6000_offsettable_memref_p (dst) 16863 && GET_CODE (XEXP (dst, 0)) != LO_SUM) 16864 { 16865 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY) 16866 { 16867 rtx basereg = XEXP (XEXP (dst, 0), 0); 16868 if (TARGET_UPDATE) 16869 { 16870 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0); 16871 emit_insn (gen_rtx_SET (VOIDmode, 16872 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc)); 16873 used_update = true; 16874 } 16875 else 16876 emit_insn (gen_rtx_SET (VOIDmode, basereg, 16877 XEXP (XEXP (dst, 0), 1))); 16878 dst = replace_equiv_address (dst, basereg); 16879 } 16880 else 16881 { 16882 rtx basereg = XEXP (XEXP (dst, 0), 0); 16883 rtx offsetreg = XEXP (XEXP (dst, 0), 1); 16884 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS 16885 && REG_P (basereg) 16886 && REG_P (offsetreg) 16887 && REGNO (basereg) != REGNO (offsetreg)); 16888 if (REGNO (basereg) == 0) 16889 { 16890 rtx tmp = offsetreg; 16891 offsetreg = basereg; 16892 basereg = tmp; 16893 } 16894 emit_insn (gen_add3_insn (basereg, basereg, offsetreg)); 16895 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg); 16896 dst = replace_equiv_address (dst, basereg); 16897 } 16898 } 16899 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM) 16900 gcc_assert (rs6000_offsettable_memref_p (dst)); 16901 } 16902 16903 for (i = 0; i < nregs; i++) 16904 { 16905 /* Calculate index to next subword. */ 16906 ++j; 16907 if (j == nregs) 16908 j = 0; 16909 16910 /* If compiler already emitted move of first word by 16911 store with update, no need to do anything. */ 16912 if (j == 0 && used_update) 16913 continue; 16914 16915 emit_insn (gen_rtx_SET (VOIDmode, 16916 simplify_gen_subreg (reg_mode, dst, mode, 16917 j * reg_mode_size), 16918 simplify_gen_subreg (reg_mode, src, mode, 16919 j * reg_mode_size))); 16920 } 16921 if (restore_basereg != NULL_RTX) 16922 emit_insn (restore_basereg); 16923 } 16924} 16925 16926 16927/* This page contains routines that are used to determine what the 16928 function prologue and epilogue code will do and write them out. */ 16929 16930/* Return the first fixed-point register that is required to be 16931 saved. 32 if none. */ 16932 16933int 16934first_reg_to_save (void) 16935{ 16936 int first_reg; 16937 16938 /* Find lowest numbered live register. */ 16939 for (first_reg = 13; first_reg <= 31; first_reg++) 16940 if (df_regs_ever_live_p (first_reg) 16941 && (! call_used_regs[first_reg] 16942 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM 16943 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0) 16944 || (DEFAULT_ABI == ABI_DARWIN && flag_pic) 16945 || (TARGET_TOC && TARGET_MINIMAL_TOC))))) 16946 break; 16947 16948#if TARGET_MACHO 16949 if (flag_pic 16950 && crtl->uses_pic_offset_table 16951 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM) 16952 return RS6000_PIC_OFFSET_TABLE_REGNUM; 16953#endif 16954 16955 return first_reg; 16956} 16957 16958/* Similar, for FP regs. */ 16959 16960int 16961first_fp_reg_to_save (void) 16962{ 16963 int first_reg; 16964 16965 /* Find lowest numbered live register. */ 16966 for (first_reg = 14 + 32; first_reg <= 63; first_reg++) 16967 if (df_regs_ever_live_p (first_reg)) 16968 break; 16969 16970 return first_reg; 16971} 16972 16973/* Similar, for AltiVec regs. */ 16974 16975static int 16976first_altivec_reg_to_save (void) 16977{ 16978 int i; 16979 16980 /* Stack frame remains as is unless we are in AltiVec ABI. */ 16981 if (! TARGET_ALTIVEC_ABI) 16982 return LAST_ALTIVEC_REGNO + 1; 16983 16984 /* On Darwin, the unwind routines are compiled without 16985 TARGET_ALTIVEC, and use save_world to save/restore the 16986 altivec registers when necessary. */ 16987 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return 16988 && ! TARGET_ALTIVEC) 16989 return FIRST_ALTIVEC_REGNO + 20; 16990 16991 /* Find lowest numbered live register. */ 16992 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i) 16993 if (df_regs_ever_live_p (i)) 16994 break; 16995 16996 return i; 16997} 16998 16999/* Return a 32-bit mask of the AltiVec registers we need to set in 17000 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in 17001 the 32-bit word is 0. */ 17002 17003static unsigned int 17004compute_vrsave_mask (void) 17005{ 17006 unsigned int i, mask = 0; 17007 17008 /* On Darwin, the unwind routines are compiled without 17009 TARGET_ALTIVEC, and use save_world to save/restore the 17010 call-saved altivec registers when necessary. */ 17011 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return 17012 && ! TARGET_ALTIVEC) 17013 mask |= 0xFFF; 17014 17015 /* First, find out if we use _any_ altivec registers. */ 17016 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i) 17017 if (df_regs_ever_live_p (i)) 17018 mask |= ALTIVEC_REG_BIT (i); 17019 17020 if (mask == 0) 17021 return mask; 17022 17023 /* Next, remove the argument registers from the set. These must 17024 be in the VRSAVE mask set by the caller, so we don't need to add 17025 them in again. More importantly, the mask we compute here is 17026 used to generate CLOBBERs in the set_vrsave insn, and we do not 17027 wish the argument registers to die. */ 17028 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i) 17029 mask &= ~ALTIVEC_REG_BIT (i); 17030 17031 /* Similarly, remove the return value from the set. */ 17032 { 17033 bool yes = false; 17034 diddle_return_value (is_altivec_return_reg, &yes); 17035 if (yes) 17036 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN); 17037 } 17038 17039 return mask; 17040} 17041 17042/* For a very restricted set of circumstances, we can cut down the 17043 size of prologues/epilogues by calling our own save/restore-the-world 17044 routines. */ 17045 17046static void 17047compute_save_world_info (rs6000_stack_t *info_ptr) 17048{ 17049 info_ptr->world_save_p = 1; 17050 info_ptr->world_save_p 17051 = (WORLD_SAVE_P (info_ptr) 17052 && DEFAULT_ABI == ABI_DARWIN 17053 && ! (cfun->calls_setjmp && flag_exceptions) 17054 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO 17055 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO 17056 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO 17057 && info_ptr->cr_save_p); 17058 17059 /* This will not work in conjunction with sibcalls. Make sure there 17060 are none. (This check is expensive, but seldom executed.) */ 17061 if (WORLD_SAVE_P (info_ptr)) 17062 { 17063 rtx insn; 17064 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn)) 17065 if ( GET_CODE (insn) == CALL_INSN 17066 && SIBLING_CALL_P (insn)) 17067 { 17068 info_ptr->world_save_p = 0; 17069 break; 17070 } 17071 } 17072 17073 if (WORLD_SAVE_P (info_ptr)) 17074 { 17075 /* Even if we're not touching VRsave, make sure there's room on the 17076 stack for it, if it looks like we're calling SAVE_WORLD, which 17077 will attempt to save it. */ 17078 info_ptr->vrsave_size = 4; 17079 17080 /* If we are going to save the world, we need to save the link register too. */ 17081 info_ptr->lr_save_p = 1; 17082 17083 /* "Save" the VRsave register too if we're saving the world. */ 17084 if (info_ptr->vrsave_mask == 0) 17085 info_ptr->vrsave_mask = compute_vrsave_mask (); 17086 17087 /* Because the Darwin register save/restore routines only handle 17088 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency 17089 check. */ 17090 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO 17091 && (info_ptr->first_altivec_reg_save 17092 >= FIRST_SAVED_ALTIVEC_REGNO)); 17093 } 17094 return; 17095} 17096 17097 17098static void 17099is_altivec_return_reg (rtx reg, void *xyes) 17100{ 17101 bool *yes = (bool *) xyes; 17102 if (REGNO (reg) == ALTIVEC_ARG_RETURN) 17103 *yes = true; 17104} 17105 17106 17107/* Calculate the stack information for the current function. This is 17108 complicated by having two separate calling sequences, the AIX calling 17109 sequence and the V.4 calling sequence. 17110 17111 AIX (and Darwin/Mac OS X) stack frames look like: 17112 32-bit 64-bit 17113 SP----> +---------------------------------------+ 17114 | back chain to caller | 0 0 17115 +---------------------------------------+ 17116 | saved CR | 4 8 (8-11) 17117 +---------------------------------------+ 17118 | saved LR | 8 16 17119 +---------------------------------------+ 17120 | reserved for compilers | 12 24 17121 +---------------------------------------+ 17122 | reserved for binders | 16 32 17123 +---------------------------------------+ 17124 | saved TOC pointer | 20 40 17125 +---------------------------------------+ 17126 | Parameter save area (P) | 24 48 17127 +---------------------------------------+ 17128 | Alloca space (A) | 24+P etc. 17129 +---------------------------------------+ 17130 | Local variable space (L) | 24+P+A 17131 +---------------------------------------+ 17132 | Float/int conversion temporary (X) | 24+P+A+L 17133 +---------------------------------------+ 17134 | Save area for AltiVec registers (W) | 24+P+A+L+X 17135 +---------------------------------------+ 17136 | AltiVec alignment padding (Y) | 24+P+A+L+X+W 17137 +---------------------------------------+ 17138 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y 17139 +---------------------------------------+ 17140 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z 17141 +---------------------------------------+ 17142 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G 17143 +---------------------------------------+ 17144 old SP->| back chain to caller's caller | 17145 +---------------------------------------+ 17146 17147 The required alignment for AIX configurations is two words (i.e., 8 17148 or 16 bytes). 17149 17150 17151 V.4 stack frames look like: 17152 17153 SP----> +---------------------------------------+ 17154 | back chain to caller | 0 17155 +---------------------------------------+ 17156 | caller's saved LR | 4 17157 +---------------------------------------+ 17158 | Parameter save area (P) | 8 17159 +---------------------------------------+ 17160 | Alloca space (A) | 8+P 17161 +---------------------------------------+ 17162 | Varargs save area (V) | 8+P+A 17163 +---------------------------------------+ 17164 | Local variable space (L) | 8+P+A+V 17165 +---------------------------------------+ 17166 | Float/int conversion temporary (X) | 8+P+A+V+L 17167 +---------------------------------------+ 17168 | Save area for AltiVec registers (W) | 8+P+A+V+L+X 17169 +---------------------------------------+ 17170 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W 17171 +---------------------------------------+ 17172 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y 17173 +---------------------------------------+ 17174 | SPE: area for 64-bit GP registers | 17175 +---------------------------------------+ 17176 | SPE alignment padding | 17177 +---------------------------------------+ 17178 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z 17179 +---------------------------------------+ 17180 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C 17181 +---------------------------------------+ 17182 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G 17183 +---------------------------------------+ 17184 old SP->| back chain to caller's caller | 17185 +---------------------------------------+ 17186 17187 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is 17188 given. (But note below and in sysv4.h that we require only 8 and 17189 may round up the size of our stack frame anyways. The historical 17190 reason is early versions of powerpc-linux which didn't properly 17191 align the stack at program startup. A happy side-effect is that 17192 -mno-eabi libraries can be used with -meabi programs.) 17193 17194 The EABI configuration defaults to the V.4 layout. However, 17195 the stack alignment requirements may differ. If -mno-eabi is not 17196 given, the required stack alignment is 8 bytes; if -mno-eabi is 17197 given, the required alignment is 16 bytes. (But see V.4 comment 17198 above.) */ 17199 17200#ifndef ABI_STACK_BOUNDARY 17201#define ABI_STACK_BOUNDARY STACK_BOUNDARY 17202#endif 17203 17204static rs6000_stack_t * 17205rs6000_stack_info (void) 17206{ 17207 static rs6000_stack_t info; 17208 rs6000_stack_t *info_ptr = &info; 17209 int reg_size = TARGET_32BIT ? 4 : 8; 17210 int ehrd_size; 17211 int save_align; 17212 int first_gp; 17213 HOST_WIDE_INT non_fixed_size; 17214 17215 memset (&info, 0, sizeof (info)); 17216 17217 if (TARGET_SPE) 17218 { 17219 /* Cache value so we don't rescan instruction chain over and over. */ 17220 if (cfun->machine->insn_chain_scanned_p == 0) 17221 cfun->machine->insn_chain_scanned_p 17222 = spe_func_has_64bit_regs_p () + 1; 17223 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1; 17224 } 17225 17226 /* Select which calling sequence. */ 17227 info_ptr->abi = DEFAULT_ABI; 17228 17229 /* Calculate which registers need to be saved & save area size. */ 17230 info_ptr->first_gp_reg_save = first_reg_to_save (); 17231 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM, 17232 even if it currently looks like we won't. Reload may need it to 17233 get at a constant; if so, it will have already created a constant 17234 pool entry for it. */ 17235 if (((TARGET_TOC && TARGET_MINIMAL_TOC) 17236 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4) 17237 || (flag_pic && DEFAULT_ABI == ABI_DARWIN)) 17238 && crtl->uses_const_pool 17239 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM) 17240 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM; 17241 else 17242 first_gp = info_ptr->first_gp_reg_save; 17243 17244 info_ptr->gp_size = reg_size * (32 - first_gp); 17245 17246 /* For the SPE, we have an additional upper 32-bits on each GPR. 17247 Ideally we should save the entire 64-bits only when the upper 17248 half is used in SIMD instructions. Since we only record 17249 registers live (not the size they are used in), this proves 17250 difficult because we'd have to traverse the instruction chain at 17251 the right time, taking reload into account. This is a real pain, 17252 so we opt to save the GPRs in 64-bits always if but one register 17253 gets used in 64-bits. Otherwise, all the registers in the frame 17254 get saved in 32-bits. 17255 17256 So... since when we save all GPRs (except the SP) in 64-bits, the 17257 traditional GP save area will be empty. */ 17258 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0) 17259 info_ptr->gp_size = 0; 17260 17261 info_ptr->first_fp_reg_save = first_fp_reg_to_save (); 17262 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save); 17263 17264 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save (); 17265 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1 17266 - info_ptr->first_altivec_reg_save); 17267 17268 /* Does this function call anything? */ 17269 info_ptr->calls_p = (! current_function_is_leaf 17270 || cfun->machine->ra_needs_full_frame); 17271 17272 /* Determine if we need to save the link register. */ 17273 if ((DEFAULT_ABI == ABI_AIX 17274 && crtl->profile 17275 && !TARGET_PROFILE_KERNEL) 17276#ifdef TARGET_RELOCATABLE 17277 || (TARGET_RELOCATABLE && (get_pool_size () != 0)) 17278#endif 17279 || (info_ptr->first_fp_reg_save != 64 17280 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save)) 17281 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca) 17282 || info_ptr->calls_p 17283 || rs6000_ra_ever_killed ()) 17284 { 17285 info_ptr->lr_save_p = 1; 17286 df_set_regs_ever_live (LR_REGNO, true); 17287 } 17288 17289 /* Determine if we need to save the condition code registers. */ 17290 if (df_regs_ever_live_p (CR2_REGNO) 17291 || df_regs_ever_live_p (CR3_REGNO) 17292 || df_regs_ever_live_p (CR4_REGNO)) 17293 { 17294 info_ptr->cr_save_p = 1; 17295 if (DEFAULT_ABI == ABI_V4) 17296 info_ptr->cr_size = reg_size; 17297 } 17298 17299 /* If the current function calls __builtin_eh_return, then we need 17300 to allocate stack space for registers that will hold data for 17301 the exception handler. */ 17302 if (crtl->calls_eh_return) 17303 { 17304 unsigned int i; 17305 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i) 17306 continue; 17307 17308 /* SPE saves EH registers in 64-bits. */ 17309 ehrd_size = i * (TARGET_SPE_ABI 17310 && info_ptr->spe_64bit_regs_used != 0 17311 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD); 17312 } 17313 else 17314 ehrd_size = 0; 17315 17316 /* Determine various sizes. */ 17317 info_ptr->reg_size = reg_size; 17318 info_ptr->fixed_size = RS6000_SAVE_AREA; 17319 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8); 17320 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size, 17321 TARGET_ALTIVEC ? 16 : 8); 17322 if (FRAME_GROWS_DOWNWARD) 17323 info_ptr->vars_size 17324 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size 17325 + info_ptr->parm_size, 17326 ABI_STACK_BOUNDARY / BITS_PER_UNIT) 17327 - (info_ptr->fixed_size + info_ptr->vars_size 17328 + info_ptr->parm_size); 17329 17330 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0) 17331 info_ptr->spe_gp_size = 8 * (32 - first_gp); 17332 else 17333 info_ptr->spe_gp_size = 0; 17334 17335 if (TARGET_ALTIVEC_ABI) 17336 info_ptr->vrsave_mask = compute_vrsave_mask (); 17337 else 17338 info_ptr->vrsave_mask = 0; 17339 17340 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask) 17341 info_ptr->vrsave_size = 4; 17342 else 17343 info_ptr->vrsave_size = 0; 17344 17345 compute_save_world_info (info_ptr); 17346 17347 /* Calculate the offsets. */ 17348 switch (DEFAULT_ABI) 17349 { 17350 case ABI_NONE: 17351 default: 17352 gcc_unreachable (); 17353 17354 case ABI_AIX: 17355 case ABI_DARWIN: 17356 info_ptr->fp_save_offset = - info_ptr->fp_size; 17357 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size; 17358 17359 if (TARGET_ALTIVEC_ABI) 17360 { 17361 info_ptr->vrsave_save_offset 17362 = info_ptr->gp_save_offset - info_ptr->vrsave_size; 17363 17364 /* Align stack so vector save area is on a quadword boundary. 17365 The padding goes above the vectors. */ 17366 if (info_ptr->altivec_size != 0) 17367 info_ptr->altivec_padding_size 17368 = info_ptr->vrsave_save_offset & 0xF; 17369 else 17370 info_ptr->altivec_padding_size = 0; 17371 17372 info_ptr->altivec_save_offset 17373 = info_ptr->vrsave_save_offset 17374 - info_ptr->altivec_padding_size 17375 - info_ptr->altivec_size; 17376 gcc_assert (info_ptr->altivec_size == 0 17377 || info_ptr->altivec_save_offset % 16 == 0); 17378 17379 /* Adjust for AltiVec case. */ 17380 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size; 17381 } 17382 else 17383 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size; 17384 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */ 17385 info_ptr->lr_save_offset = 2*reg_size; 17386 break; 17387 17388 case ABI_V4: 17389 info_ptr->fp_save_offset = - info_ptr->fp_size; 17390 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size; 17391 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size; 17392 17393 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0) 17394 { 17395 /* Align stack so SPE GPR save area is aligned on a 17396 double-word boundary. */ 17397 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0) 17398 info_ptr->spe_padding_size 17399 = 8 - (-info_ptr->cr_save_offset % 8); 17400 else 17401 info_ptr->spe_padding_size = 0; 17402 17403 info_ptr->spe_gp_save_offset 17404 = info_ptr->cr_save_offset 17405 - info_ptr->spe_padding_size 17406 - info_ptr->spe_gp_size; 17407 17408 /* Adjust for SPE case. */ 17409 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset; 17410 } 17411 else if (TARGET_ALTIVEC_ABI) 17412 { 17413 info_ptr->vrsave_save_offset 17414 = info_ptr->cr_save_offset - info_ptr->vrsave_size; 17415 17416 /* Align stack so vector save area is on a quadword boundary. */ 17417 if (info_ptr->altivec_size != 0) 17418 info_ptr->altivec_padding_size 17419 = 16 - (-info_ptr->vrsave_save_offset % 16); 17420 else 17421 info_ptr->altivec_padding_size = 0; 17422 17423 info_ptr->altivec_save_offset 17424 = info_ptr->vrsave_save_offset 17425 - info_ptr->altivec_padding_size 17426 - info_ptr->altivec_size; 17427 17428 /* Adjust for AltiVec case. */ 17429 info_ptr->ehrd_offset = info_ptr->altivec_save_offset; 17430 } 17431 else 17432 info_ptr->ehrd_offset = info_ptr->cr_save_offset; 17433 info_ptr->ehrd_offset -= ehrd_size; 17434 info_ptr->lr_save_offset = reg_size; 17435 break; 17436 } 17437 17438 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8; 17439 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size 17440 + info_ptr->gp_size 17441 + info_ptr->altivec_size 17442 + info_ptr->altivec_padding_size 17443 + info_ptr->spe_gp_size 17444 + info_ptr->spe_padding_size 17445 + ehrd_size 17446 + info_ptr->cr_size 17447 + info_ptr->vrsave_size, 17448 save_align); 17449 17450 non_fixed_size = (info_ptr->vars_size 17451 + info_ptr->parm_size 17452 + info_ptr->save_size); 17453 17454 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size, 17455 ABI_STACK_BOUNDARY / BITS_PER_UNIT); 17456 17457 /* Determine if we need to allocate any stack frame: 17458 17459 For AIX we need to push the stack if a frame pointer is needed 17460 (because the stack might be dynamically adjusted), if we are 17461 debugging, if we make calls, or if the sum of fp_save, gp_save, 17462 and local variables are more than the space needed to save all 17463 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8 17464 + 18*8 = 288 (GPR13 reserved). 17465 17466 For V.4 we don't have the stack cushion that AIX uses, but assume 17467 that the debugger can handle stackless frames. */ 17468 17469 if (info_ptr->calls_p) 17470 info_ptr->push_p = 1; 17471 17472 else if (DEFAULT_ABI == ABI_V4) 17473 info_ptr->push_p = non_fixed_size != 0; 17474 17475 else if (frame_pointer_needed) 17476 info_ptr->push_p = 1; 17477 17478 else if (TARGET_XCOFF && write_symbols != NO_DEBUG) 17479 info_ptr->push_p = 1; 17480 17481 else 17482 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288); 17483 17484 /* Zero offsets if we're not saving those registers. */ 17485 if (info_ptr->fp_size == 0) 17486 info_ptr->fp_save_offset = 0; 17487 17488 if (info_ptr->gp_size == 0) 17489 info_ptr->gp_save_offset = 0; 17490 17491 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0) 17492 info_ptr->altivec_save_offset = 0; 17493 17494 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0) 17495 info_ptr->vrsave_save_offset = 0; 17496 17497 if (! TARGET_SPE_ABI 17498 || info_ptr->spe_64bit_regs_used == 0 17499 || info_ptr->spe_gp_size == 0) 17500 info_ptr->spe_gp_save_offset = 0; 17501 17502 if (! info_ptr->lr_save_p) 17503 info_ptr->lr_save_offset = 0; 17504 17505 if (! info_ptr->cr_save_p) 17506 info_ptr->cr_save_offset = 0; 17507 17508 return info_ptr; 17509} 17510 17511/* Return true if the current function uses any GPRs in 64-bit SIMD 17512 mode. */ 17513 17514static bool 17515spe_func_has_64bit_regs_p (void) 17516{ 17517 rtx insns, insn; 17518 17519 /* Functions that save and restore all the call-saved registers will 17520 need to save/restore the registers in 64-bits. */ 17521 if (crtl->calls_eh_return 17522 || cfun->calls_setjmp 17523 || crtl->has_nonlocal_goto) 17524 return true; 17525 17526 insns = get_insns (); 17527 17528 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn)) 17529 { 17530 if (INSN_P (insn)) 17531 { 17532 rtx i; 17533 17534 /* FIXME: This should be implemented with attributes... 17535 17536 (set_attr "spe64" "true")....then, 17537 if (get_spe64(insn)) return true; 17538 17539 It's the only reliable way to do the stuff below. */ 17540 17541 i = PATTERN (insn); 17542 if (GET_CODE (i) == SET) 17543 { 17544 enum machine_mode mode = GET_MODE (SET_SRC (i)); 17545 17546 if (SPE_VECTOR_MODE (mode)) 17547 return true; 17548 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode)) 17549 return true; 17550 } 17551 } 17552 } 17553 17554 return false; 17555} 17556 17557static void 17558debug_stack_info (rs6000_stack_t *info) 17559{ 17560 const char *abi_string; 17561 17562 if (! info) 17563 info = rs6000_stack_info (); 17564 17565 fprintf (stderr, "\nStack information for function %s:\n", 17566 ((current_function_decl && DECL_NAME (current_function_decl)) 17567 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl)) 17568 : "<unknown>")); 17569 17570 switch (info->abi) 17571 { 17572 default: abi_string = "Unknown"; break; 17573 case ABI_NONE: abi_string = "NONE"; break; 17574 case ABI_AIX: abi_string = "AIX"; break; 17575 case ABI_DARWIN: abi_string = "Darwin"; break; 17576 case ABI_V4: abi_string = "V.4"; break; 17577 } 17578 17579 fprintf (stderr, "\tABI = %5s\n", abi_string); 17580 17581 if (TARGET_ALTIVEC_ABI) 17582 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n"); 17583 17584 if (TARGET_SPE_ABI) 17585 fprintf (stderr, "\tSPE ABI extensions enabled.\n"); 17586 17587 if (info->first_gp_reg_save != 32) 17588 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save); 17589 17590 if (info->first_fp_reg_save != 64) 17591 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save); 17592 17593 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO) 17594 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n", 17595 info->first_altivec_reg_save); 17596 17597 if (info->lr_save_p) 17598 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p); 17599 17600 if (info->cr_save_p) 17601 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p); 17602 17603 if (info->vrsave_mask) 17604 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask); 17605 17606 if (info->push_p) 17607 fprintf (stderr, "\tpush_p = %5d\n", info->push_p); 17608 17609 if (info->calls_p) 17610 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p); 17611 17612 if (info->gp_save_offset) 17613 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset); 17614 17615 if (info->fp_save_offset) 17616 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset); 17617 17618 if (info->altivec_save_offset) 17619 fprintf (stderr, "\taltivec_save_offset = %5d\n", 17620 info->altivec_save_offset); 17621 17622 if (info->spe_gp_save_offset) 17623 fprintf (stderr, "\tspe_gp_save_offset = %5d\n", 17624 info->spe_gp_save_offset); 17625 17626 if (info->vrsave_save_offset) 17627 fprintf (stderr, "\tvrsave_save_offset = %5d\n", 17628 info->vrsave_save_offset); 17629 17630 if (info->lr_save_offset) 17631 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset); 17632 17633 if (info->cr_save_offset) 17634 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset); 17635 17636 if (info->varargs_save_offset) 17637 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset); 17638 17639 if (info->total_size) 17640 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n", 17641 info->total_size); 17642 17643 if (info->vars_size) 17644 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n", 17645 info->vars_size); 17646 17647 if (info->parm_size) 17648 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size); 17649 17650 if (info->fixed_size) 17651 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size); 17652 17653 if (info->gp_size) 17654 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size); 17655 17656 if (info->spe_gp_size) 17657 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size); 17658 17659 if (info->fp_size) 17660 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size); 17661 17662 if (info->altivec_size) 17663 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size); 17664 17665 if (info->vrsave_size) 17666 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size); 17667 17668 if (info->altivec_padding_size) 17669 fprintf (stderr, "\taltivec_padding_size= %5d\n", 17670 info->altivec_padding_size); 17671 17672 if (info->spe_padding_size) 17673 fprintf (stderr, "\tspe_padding_size = %5d\n", 17674 info->spe_padding_size); 17675 17676 if (info->cr_size) 17677 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size); 17678 17679 if (info->save_size) 17680 fprintf (stderr, "\tsave_size = %5d\n", info->save_size); 17681 17682 if (info->reg_size != 4) 17683 fprintf (stderr, "\treg_size = %5d\n", info->reg_size); 17684 17685 fprintf (stderr, "\n"); 17686} 17687 17688rtx 17689rs6000_return_addr (int count, rtx frame) 17690{ 17691 /* Currently we don't optimize very well between prolog and body 17692 code and for PIC code the code can be actually quite bad, so 17693 don't try to be too clever here. */ 17694 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic)) 17695 { 17696 cfun->machine->ra_needs_full_frame = 1; 17697 17698 return 17699 gen_rtx_MEM 17700 (Pmode, 17701 memory_address 17702 (Pmode, 17703 plus_constant (copy_to_reg 17704 (gen_rtx_MEM (Pmode, 17705 memory_address (Pmode, frame))), 17706 RETURN_ADDRESS_OFFSET))); 17707 } 17708 17709 cfun->machine->ra_need_lr = 1; 17710 return get_hard_reg_initial_val (Pmode, LR_REGNO); 17711} 17712 17713/* Say whether a function is a candidate for sibcall handling or not. 17714 We do not allow indirect calls to be optimized into sibling calls. 17715 Also, we can't do it if there are any vector parameters; there's 17716 nowhere to put the VRsave code so it works; note that functions with 17717 vector parameters are required to have a prototype, so the argument 17718 type info must be available here. (The tail recursion case can work 17719 with vector parameters, but there's no way to distinguish here.) */ 17720static bool 17721rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED) 17722{ 17723 tree type; 17724 if (decl) 17725 { 17726 if (TARGET_ALTIVEC_VRSAVE) 17727 { 17728 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl)); 17729 type; type = TREE_CHAIN (type)) 17730 { 17731 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE) 17732 return false; 17733 } 17734 } 17735 if (DEFAULT_ABI == ABI_DARWIN 17736 || ((*targetm.binds_local_p) (decl) 17737 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl)))) 17738 { 17739 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl)); 17740 17741 if (!lookup_attribute ("longcall", attr_list) 17742 || lookup_attribute ("shortcall", attr_list)) 17743 return true; 17744 } 17745 } 17746 return false; 17747} 17748 17749/* NULL if INSN insn is valid within a low-overhead loop. 17750 Otherwise return why doloop cannot be applied. 17751 PowerPC uses the COUNT register for branch on table instructions. */ 17752 17753static const char * 17754rs6000_invalid_within_doloop (const_rtx insn) 17755{ 17756 if (CALL_P (insn)) 17757 return "Function call in the loop."; 17758 17759 if (JUMP_P (insn) 17760 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC 17761 || GET_CODE (PATTERN (insn)) == ADDR_VEC)) 17762 return "Computed branch in the loop."; 17763 17764 return NULL; 17765} 17766 17767static int 17768rs6000_ra_ever_killed (void) 17769{ 17770 rtx top; 17771 rtx reg; 17772 rtx insn; 17773 17774 if (cfun->is_thunk) 17775 return 0; 17776 17777 if (cfun->machine->lr_save_state) 17778 return cfun->machine->lr_save_state - 1; 17779 17780 /* regs_ever_live has LR marked as used if any sibcalls are present, 17781 but this should not force saving and restoring in the 17782 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall 17783 clobbers LR, so that is inappropriate. */ 17784 17785 /* Also, the prologue can generate a store into LR that 17786 doesn't really count, like this: 17787 17788 move LR->R0 17789 bcl to set PIC register 17790 move LR->R31 17791 move R0->LR 17792 17793 When we're called from the epilogue, we need to avoid counting 17794 this as a store. */ 17795 17796 push_topmost_sequence (); 17797 top = get_insns (); 17798 pop_topmost_sequence (); 17799 reg = gen_rtx_REG (Pmode, LR_REGNO); 17800 17801 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn)) 17802 { 17803 if (INSN_P (insn)) 17804 { 17805 if (CALL_P (insn)) 17806 { 17807 if (!SIBLING_CALL_P (insn)) 17808 return 1; 17809 } 17810 else if (find_regno_note (insn, REG_INC, LR_REGNO)) 17811 return 1; 17812 else if (set_of (reg, insn) != NULL_RTX 17813 && !prologue_epilogue_contains (insn)) 17814 return 1; 17815 } 17816 } 17817 return 0; 17818} 17819 17820/* Emit instructions needed to load the TOC register. 17821 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is 17822 a constant pool; or for SVR4 -fpic. */ 17823 17824void 17825rs6000_emit_load_toc_table (int fromprolog) 17826{ 17827 rtx dest; 17828 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM); 17829 17830 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic) 17831 { 17832 char buf[30]; 17833 rtx lab, tmp1, tmp2, got; 17834 17835 lab = gen_label_rtx (); 17836 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (lab)); 17837 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); 17838 if (flag_pic == 2) 17839 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name); 17840 else 17841 got = rs6000_got_sym (); 17842 tmp1 = tmp2 = dest; 17843 if (!fromprolog) 17844 { 17845 tmp1 = gen_reg_rtx (Pmode); 17846 tmp2 = gen_reg_rtx (Pmode); 17847 } 17848 emit_insn (gen_load_toc_v4_PIC_1 (lab)); 17849 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO)); 17850 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab)); 17851 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab)); 17852 } 17853 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1) 17854 { 17855 emit_insn (gen_load_toc_v4_pic_si ()); 17856 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO)); 17857 } 17858 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2) 17859 { 17860 char buf[30]; 17861 rtx temp0 = (fromprolog 17862 ? gen_rtx_REG (Pmode, 0) 17863 : gen_reg_rtx (Pmode)); 17864 17865 if (fromprolog) 17866 { 17867 rtx symF, symL; 17868 17869 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); 17870 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); 17871 17872 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno); 17873 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); 17874 17875 emit_insn (gen_load_toc_v4_PIC_1 (symF)); 17876 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO)); 17877 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF)); 17878 } 17879 else 17880 { 17881 rtx tocsym, lab; 17882 17883 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name); 17884 lab = gen_label_rtx (); 17885 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab)); 17886 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO)); 17887 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest)); 17888 } 17889 emit_insn (gen_addsi3 (dest, temp0, dest)); 17890 } 17891 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC) 17892 { 17893 /* This is for AIX code running in non-PIC ELF32. */ 17894 char buf[30]; 17895 rtx realsym; 17896 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1); 17897 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); 17898 17899 emit_insn (gen_elf_high (dest, realsym)); 17900 emit_insn (gen_elf_low (dest, dest, realsym)); 17901 } 17902 else 17903 { 17904 gcc_assert (DEFAULT_ABI == ABI_AIX); 17905 17906 if (TARGET_32BIT) 17907 emit_insn (gen_load_toc_aix_si (dest)); 17908 else 17909 emit_insn (gen_load_toc_aix_di (dest)); 17910 } 17911} 17912 17913/* Emit instructions to restore the link register after determining where 17914 its value has been stored. */ 17915 17916void 17917rs6000_emit_eh_reg_restore (rtx source, rtx scratch) 17918{ 17919 rs6000_stack_t *info = rs6000_stack_info (); 17920 rtx operands[2]; 17921 17922 operands[0] = source; 17923 operands[1] = scratch; 17924 17925 if (info->lr_save_p) 17926 { 17927 rtx frame_rtx = stack_pointer_rtx; 17928 HOST_WIDE_INT sp_offset = 0; 17929 rtx tmp; 17930 17931 if (frame_pointer_needed 17932 || cfun->calls_alloca 17933 || info->total_size > 32767) 17934 { 17935 tmp = gen_frame_mem (Pmode, frame_rtx); 17936 emit_move_insn (operands[1], tmp); 17937 frame_rtx = operands[1]; 17938 } 17939 else if (info->push_p) 17940 sp_offset = info->total_size; 17941 17942 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset); 17943 tmp = gen_frame_mem (Pmode, tmp); 17944 emit_move_insn (tmp, operands[0]); 17945 } 17946 else 17947 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]); 17948 17949 /* Freeze lr_save_p. We've just emitted rtl that depends on the 17950 state of lr_save_p so any change from here on would be a bug. In 17951 particular, stop rs6000_ra_ever_killed from considering the SET 17952 of lr we may have added just above. */ 17953 cfun->machine->lr_save_state = info->lr_save_p + 1; 17954} 17955 17956static GTY(()) alias_set_type set = -1; 17957 17958alias_set_type 17959get_TOC_alias_set (void) 17960{ 17961 if (set == -1) 17962 set = new_alias_set (); 17963 return set; 17964} 17965 17966/* This returns nonzero if the current function uses the TOC. This is 17967 determined by the presence of (use (unspec ... UNSPEC_TOC)), which 17968 is generated by the ABI_V4 load_toc_* patterns. */ 17969#if TARGET_ELF 17970static int 17971uses_TOC (void) 17972{ 17973 rtx insn; 17974 17975 for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 17976 if (INSN_P (insn)) 17977 { 17978 rtx pat = PATTERN (insn); 17979 int i; 17980 17981 if (GET_CODE (pat) == PARALLEL) 17982 for (i = 0; i < XVECLEN (pat, 0); i++) 17983 { 17984 rtx sub = XVECEXP (pat, 0, i); 17985 if (GET_CODE (sub) == USE) 17986 { 17987 sub = XEXP (sub, 0); 17988 if (GET_CODE (sub) == UNSPEC 17989 && XINT (sub, 1) == UNSPEC_TOC) 17990 return 1; 17991 } 17992 } 17993 } 17994 return 0; 17995} 17996#endif 17997 17998rtx 17999create_TOC_reference (rtx symbol) 18000{ 18001 if (TARGET_DEBUG_ADDR) 18002 { 18003 if (GET_CODE (symbol) == SYMBOL_REF) 18004 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n", 18005 XSTR (symbol, 0)); 18006 else 18007 { 18008 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n", 18009 GET_RTX_NAME (GET_CODE (symbol))); 18010 debug_rtx (symbol); 18011 } 18012 } 18013 18014 if (!can_create_pseudo_p ()) 18015 df_set_regs_ever_live (TOC_REGISTER, true); 18016 return gen_rtx_PLUS (Pmode, 18017 gen_rtx_REG (Pmode, TOC_REGISTER), 18018 gen_rtx_CONST (Pmode, 18019 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol), UNSPEC_TOCREL))); 18020} 18021 18022/* Issue assembly directives that create a reference to the given DWARF 18023 FRAME_TABLE_LABEL from the current function section. */ 18024void 18025rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label) 18026{ 18027 fprintf (asm_out_file, "\t.ref %s\n", 18028 TARGET_STRIP_NAME_ENCODING (frame_table_label)); 18029} 18030 18031/* This ties together stack memory (MEM with an alias set of frame_alias_set) 18032 and the change to the stack pointer. */ 18033 18034static void 18035rs6000_emit_stack_tie (void) 18036{ 18037 rtx mem = gen_frame_mem (BLKmode, 18038 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM)); 18039 18040 emit_insn (gen_stack_tie (mem)); 18041} 18042 18043/* Emit the correct code for allocating stack space, as insns. 18044 If COPY_REG, make sure a copy of the old frame is left there. 18045 The generated code may use hard register 0 as a temporary. */ 18046 18047static void 18048rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg) 18049{ 18050 rtx insn; 18051 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM); 18052 rtx tmp_reg = gen_rtx_REG (Pmode, 0); 18053 rtx todec = gen_int_mode (-size, Pmode); 18054 rtx par, set, mem; 18055 18056 if (INTVAL (todec) != -size) 18057 { 18058 warning (0, "stack frame too large"); 18059 emit_insn (gen_trap ()); 18060 return; 18061 } 18062 18063 if (crtl->limit_stack) 18064 { 18065 if (REG_P (stack_limit_rtx) 18066 && REGNO (stack_limit_rtx) > 1 18067 && REGNO (stack_limit_rtx) <= 31) 18068 { 18069 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size))); 18070 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg, 18071 const0_rtx)); 18072 } 18073 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF 18074 && TARGET_32BIT 18075 && DEFAULT_ABI == ABI_V4) 18076 { 18077 rtx toload = gen_rtx_CONST (VOIDmode, 18078 gen_rtx_PLUS (Pmode, 18079 stack_limit_rtx, 18080 GEN_INT (size))); 18081 18082 emit_insn (gen_elf_high (tmp_reg, toload)); 18083 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload)); 18084 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg, 18085 const0_rtx)); 18086 } 18087 else 18088 warning (0, "stack limit expression is not supported"); 18089 } 18090 18091 if (copy_reg) 18092 emit_move_insn (copy_reg, stack_reg); 18093 18094 if (size > 32767) 18095 { 18096 /* Need a note here so that try_split doesn't get confused. */ 18097 if (get_last_insn () == NULL_RTX) 18098 emit_note (NOTE_INSN_DELETED); 18099 insn = emit_move_insn (tmp_reg, todec); 18100 try_split (PATTERN (insn), insn, 0); 18101 todec = tmp_reg; 18102 } 18103 18104 insn = emit_insn (TARGET_32BIT 18105 ? gen_movsi_update_stack (stack_reg, stack_reg, 18106 todec, stack_reg) 18107 : gen_movdi_di_update_stack (stack_reg, stack_reg, 18108 todec, stack_reg)); 18109 /* Since we didn't use gen_frame_mem to generate the MEM, grab 18110 it now and set the alias set/attributes. The above gen_*_update 18111 calls will generate a PARALLEL with the MEM set being the first 18112 operation. */ 18113 par = PATTERN (insn); 18114 gcc_assert (GET_CODE (par) == PARALLEL); 18115 set = XVECEXP (par, 0, 0); 18116 gcc_assert (GET_CODE (set) == SET); 18117 mem = SET_DEST (set); 18118 gcc_assert (MEM_P (mem)); 18119 MEM_NOTRAP_P (mem) = 1; 18120 set_mem_alias_set (mem, get_frame_alias_set ()); 18121 18122 RTX_FRAME_RELATED_P (insn) = 1; 18123 add_reg_note (insn, REG_FRAME_RELATED_EXPR, 18124 gen_rtx_SET (VOIDmode, stack_reg, 18125 gen_rtx_PLUS (Pmode, stack_reg, 18126 GEN_INT (-size)))); 18127} 18128 18129/* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced 18130 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2 18131 is not NULL. It would be nice if dwarf2out_frame_debug_expr could 18132 deduce these equivalences by itself so it wasn't necessary to hold 18133 its hand so much. */ 18134 18135static void 18136rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val, 18137 rtx reg2, rtx rreg) 18138{ 18139 rtx real, temp; 18140 18141 /* copy_rtx will not make unique copies of registers, so we need to 18142 ensure we don't have unwanted sharing here. */ 18143 if (reg == reg2) 18144 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg)); 18145 18146 if (reg == rreg) 18147 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg)); 18148 18149 real = copy_rtx (PATTERN (insn)); 18150 18151 if (reg2 != NULL_RTX) 18152 real = replace_rtx (real, reg2, rreg); 18153 18154 real = replace_rtx (real, reg, 18155 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, 18156 STACK_POINTER_REGNUM), 18157 GEN_INT (val))); 18158 18159 /* We expect that 'real' is either a SET or a PARALLEL containing 18160 SETs (and possibly other stuff). In a PARALLEL, all the SETs 18161 are important so they all have to be marked RTX_FRAME_RELATED_P. */ 18162 18163 if (GET_CODE (real) == SET) 18164 { 18165 rtx set = real; 18166 18167 temp = simplify_rtx (SET_SRC (set)); 18168 if (temp) 18169 SET_SRC (set) = temp; 18170 temp = simplify_rtx (SET_DEST (set)); 18171 if (temp) 18172 SET_DEST (set) = temp; 18173 if (GET_CODE (SET_DEST (set)) == MEM) 18174 { 18175 temp = simplify_rtx (XEXP (SET_DEST (set), 0)); 18176 if (temp) 18177 XEXP (SET_DEST (set), 0) = temp; 18178 } 18179 } 18180 else 18181 { 18182 int i; 18183 18184 gcc_assert (GET_CODE (real) == PARALLEL); 18185 for (i = 0; i < XVECLEN (real, 0); i++) 18186 if (GET_CODE (XVECEXP (real, 0, i)) == SET) 18187 { 18188 rtx set = XVECEXP (real, 0, i); 18189 18190 temp = simplify_rtx (SET_SRC (set)); 18191 if (temp) 18192 SET_SRC (set) = temp; 18193 temp = simplify_rtx (SET_DEST (set)); 18194 if (temp) 18195 SET_DEST (set) = temp; 18196 if (GET_CODE (SET_DEST (set)) == MEM) 18197 { 18198 temp = simplify_rtx (XEXP (SET_DEST (set), 0)); 18199 if (temp) 18200 XEXP (SET_DEST (set), 0) = temp; 18201 } 18202 RTX_FRAME_RELATED_P (set) = 1; 18203 } 18204 } 18205 18206 RTX_FRAME_RELATED_P (insn) = 1; 18207 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real); 18208} 18209 18210/* Returns an insn that has a vrsave set operation with the 18211 appropriate CLOBBERs. */ 18212 18213static rtx 18214generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep) 18215{ 18216 int nclobs, i; 18217 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1]; 18218 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO); 18219 18220 clobs[0] 18221 = gen_rtx_SET (VOIDmode, 18222 vrsave, 18223 gen_rtx_UNSPEC_VOLATILE (SImode, 18224 gen_rtvec (2, reg, vrsave), 18225 UNSPECV_SET_VRSAVE)); 18226 18227 nclobs = 1; 18228 18229 /* We need to clobber the registers in the mask so the scheduler 18230 does not move sets to VRSAVE before sets of AltiVec registers. 18231 18232 However, if the function receives nonlocal gotos, reload will set 18233 all call saved registers live. We will end up with: 18234 18235 (set (reg 999) (mem)) 18236 (parallel [ (set (reg vrsave) (unspec blah)) 18237 (clobber (reg 999))]) 18238 18239 The clobber will cause the store into reg 999 to be dead, and 18240 flow will attempt to delete an epilogue insn. In this case, we 18241 need an unspec use/set of the register. */ 18242 18243 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i) 18244 if (info->vrsave_mask & ALTIVEC_REG_BIT (i)) 18245 { 18246 if (!epiloguep || call_used_regs [i]) 18247 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode, 18248 gen_rtx_REG (V4SImode, i)); 18249 else 18250 { 18251 rtx reg = gen_rtx_REG (V4SImode, i); 18252 18253 clobs[nclobs++] 18254 = gen_rtx_SET (VOIDmode, 18255 reg, 18256 gen_rtx_UNSPEC (V4SImode, 18257 gen_rtvec (1, reg), 27)); 18258 } 18259 } 18260 18261 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs)); 18262 18263 for (i = 0; i < nclobs; ++i) 18264 XVECEXP (insn, 0, i) = clobs[i]; 18265 18266 return insn; 18267} 18268 18269/* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes. 18270 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */ 18271 18272static void 18273emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode, 18274 unsigned int regno, int offset, HOST_WIDE_INT total_size) 18275{ 18276 rtx reg, offset_rtx, insn, mem, addr, int_rtx; 18277 rtx replacea, replaceb; 18278 18279 int_rtx = GEN_INT (offset); 18280 18281 /* Some cases that need register indexed addressing. */ 18282 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode)) 18283 || (TARGET_VSX && VSX_VECTOR_MODE (mode)) 18284 || (TARGET_E500_DOUBLE && mode == DFmode) 18285 || (TARGET_SPE_ABI 18286 && SPE_VECTOR_MODE (mode) 18287 && !SPE_CONST_OFFSET_OK (offset))) 18288 { 18289 /* Whomever calls us must make sure r11 is available in the 18290 flow path of instructions in the prologue. */ 18291 offset_rtx = gen_rtx_REG (Pmode, 11); 18292 emit_move_insn (offset_rtx, int_rtx); 18293 18294 replacea = offset_rtx; 18295 replaceb = int_rtx; 18296 } 18297 else 18298 { 18299 offset_rtx = int_rtx; 18300 replacea = NULL_RTX; 18301 replaceb = NULL_RTX; 18302 } 18303 18304 reg = gen_rtx_REG (mode, regno); 18305 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx); 18306 mem = gen_frame_mem (mode, addr); 18307 18308 insn = emit_move_insn (mem, reg); 18309 18310 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb); 18311} 18312 18313/* Emit an offset memory reference suitable for a frame store, while 18314 converting to a valid addressing mode. */ 18315 18316static rtx 18317gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset) 18318{ 18319 rtx int_rtx, offset_rtx; 18320 18321 int_rtx = GEN_INT (offset); 18322 18323 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode)) 18324 || (TARGET_E500_DOUBLE && mode == DFmode)) 18325 { 18326 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH); 18327 emit_move_insn (offset_rtx, int_rtx); 18328 } 18329 else 18330 offset_rtx = int_rtx; 18331 18332 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx)); 18333} 18334 18335/* Look for user-defined global regs. We should not save and restore these, 18336 and cannot use stmw/lmw if there are any in its range. */ 18337 18338static bool 18339no_global_regs_above (int first, bool gpr) 18340{ 18341 int i; 18342 int last = gpr ? 32 : 64; 18343 for (i = first; i < last; i++) 18344 if (global_regs[i]) 18345 return false; 18346 return true; 18347} 18348 18349#ifndef TARGET_FIX_AND_CONTINUE 18350#define TARGET_FIX_AND_CONTINUE 0 18351#endif 18352 18353/* It's really GPR 13 and FPR 14, but we need the smaller of the two. */ 18354#define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO 18355#define LAST_SAVRES_REGISTER 31 18356#define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1) 18357 18358static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8]; 18359 18360/* Temporary holding space for an out-of-line register save/restore 18361 routine name. */ 18362static char savres_routine_name[30]; 18363 18364/* Return the name for an out-of-line register save/restore routine. 18365 We are saving/restoring GPRs if GPR is true. */ 18366 18367static char * 18368rs6000_savres_routine_name (rs6000_stack_t *info, int regno, 18369 bool savep, bool gpr, bool lr) 18370{ 18371 const char *prefix = ""; 18372 const char *suffix = ""; 18373 18374 /* Different targets are supposed to define 18375 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed 18376 routine name could be defined with: 18377 18378 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX) 18379 18380 This is a nice idea in practice, but in reality, things are 18381 complicated in several ways: 18382 18383 - ELF targets have save/restore routines for GPRs. 18384 18385 - SPE targets use different prefixes for 32/64-bit registers, and 18386 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen. 18387 18388 - PPC64 ELF targets have routines for save/restore of GPRs that 18389 differ in what they do with the link register, so having a set 18390 prefix doesn't work. (We only use one of the save routines at 18391 the moment, though.) 18392 18393 - PPC32 elf targets have "exit" versions of the restore routines 18394 that restore the link register and can save some extra space. 18395 These require an extra suffix. (There are also "tail" versions 18396 of the restore routines and "GOT" versions of the save routines, 18397 but we don't generate those at present. Same problems apply, 18398 though.) 18399 18400 We deal with all this by synthesizing our own prefix/suffix and 18401 using that for the simple sprintf call shown above. */ 18402 if (TARGET_SPE) 18403 { 18404 /* No floating point saves on the SPE. */ 18405 gcc_assert (gpr); 18406 18407 if (savep) 18408 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_"; 18409 else 18410 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_"; 18411 18412 if (lr) 18413 suffix = "_x"; 18414 } 18415 else if (DEFAULT_ABI == ABI_V4) 18416 { 18417 if (TARGET_64BIT) 18418 goto aix_names; 18419 18420 if (gpr) 18421 prefix = savep ? "_savegpr_" : "_restgpr_"; 18422 else 18423 prefix = savep ? "_savefpr_" : "_restfpr_"; 18424 18425 if (lr) 18426 suffix = "_x"; 18427 } 18428 else if (DEFAULT_ABI == ABI_AIX) 18429 { 18430#if !defined(POWERPC_LINUX) && !defined(POWERPC_NETBSD) 18431 /* No out-of-line save/restore routines for GPRs on AIX. */ 18432 gcc_assert (!TARGET_AIX || !gpr); 18433#endif 18434 18435 aix_names: 18436 if (gpr) 18437 prefix = (savep 18438 ? (lr ? "_savegpr0_" : "_savegpr1_") 18439 : (lr ? "_restgpr0_" : "_restgpr1_")); 18440#if defined(POWERPC_LINUX) || defined(POWERPC_NETBSD) 18441 else if (lr) 18442 prefix = (savep ? "_savefpr_" : "_restfpr_"); 18443#endif 18444 else 18445 { 18446 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX; 18447 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX; 18448 } 18449 } 18450 else if (DEFAULT_ABI == ABI_DARWIN) 18451 sorry ("Out-of-line save/restore routines not supported on Darwin"); 18452 18453 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix); 18454 18455 return savres_routine_name; 18456} 18457 18458/* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine. 18459 We are saving/restoring GPRs if GPR is true. */ 18460 18461static rtx 18462rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep, 18463 bool gpr, bool lr) 18464{ 18465 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32); 18466 rtx sym; 18467 int select = ((savep ? 1 : 0) << 2 18468 | ((TARGET_SPE_ABI 18469 /* On the SPE, we never have any FPRs, but we do have 18470 32/64-bit versions of the routines. */ 18471 ? (info->spe_64bit_regs_used ? 1 : 0) 18472 : (gpr ? 1 : 0)) << 1) 18473 | (lr ? 1: 0)); 18474 18475 /* Don't generate bogus routine names. */ 18476 gcc_assert (FIRST_SAVRES_REGISTER <= regno 18477 && regno <= LAST_SAVRES_REGISTER); 18478 18479 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]; 18480 18481 if (sym == NULL) 18482 { 18483 char *name; 18484 18485 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr); 18486 18487 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select] 18488 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name)); 18489 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION; 18490 } 18491 18492 return sym; 18493} 18494 18495/* Emit a sequence of insns, including a stack tie if needed, for 18496 resetting the stack pointer. If SAVRES is true, then don't reset the 18497 stack pointer, but move the base of the frame into r11 for use by 18498 out-of-line register restore routines. */ 18499 18500static rtx 18501rs6000_emit_stack_reset (rs6000_stack_t *info, 18502 rtx sp_reg_rtx, rtx frame_reg_rtx, 18503 int sp_offset, bool savres) 18504{ 18505 /* This blockage is needed so that sched doesn't decide to move 18506 the sp change before the register restores. */ 18507 if (frame_reg_rtx != sp_reg_rtx 18508 || (TARGET_SPE_ABI 18509 && info->spe_64bit_regs_used != 0 18510 && info->first_gp_reg_save != 32)) 18511 rs6000_emit_stack_tie (); 18512 18513 if (frame_reg_rtx != sp_reg_rtx) 18514 { 18515 if (sp_offset != 0) 18516 { 18517 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx; 18518 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, 18519 GEN_INT (sp_offset))); 18520 } 18521 else if (!savres) 18522 return emit_move_insn (sp_reg_rtx, frame_reg_rtx); 18523 } 18524 else if (sp_offset != 0) 18525 { 18526 /* If we are restoring registers out-of-line, we will be using the 18527 "exit" variants of the restore routines, which will reset the 18528 stack for us. But we do need to point r11 into the right place 18529 for those routines. */ 18530 rtx dest_reg = (savres 18531 ? gen_rtx_REG (Pmode, 11) 18532 : sp_reg_rtx); 18533 18534 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx, 18535 GEN_INT (sp_offset))); 18536 if (!savres) 18537 return insn; 18538 } 18539 return NULL_RTX; 18540} 18541 18542/* Construct a parallel rtx describing the effect of a call to an 18543 out-of-line register save/restore routine. */ 18544 18545static rtx 18546rs6000_make_savres_rtx (rs6000_stack_t *info, 18547 rtx frame_reg_rtx, int save_area_offset, 18548 enum machine_mode reg_mode, 18549 bool savep, bool gpr, bool lr) 18550{ 18551 int i; 18552 int offset, start_reg, end_reg, n_regs; 18553 int reg_size = GET_MODE_SIZE (reg_mode); 18554 rtx sym; 18555 rtvec p; 18556 18557 offset = 0; 18558 start_reg = (gpr 18559 ? info->first_gp_reg_save 18560 : info->first_fp_reg_save); 18561 end_reg = gpr ? 32 : 64; 18562 n_regs = end_reg - start_reg; 18563 p = rtvec_alloc ((lr ? 4 : 3) + n_regs); 18564 18565 if (!savep && lr) 18566 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode); 18567 18568 RTVEC_ELT (p, offset++) 18569 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65)); 18570 18571 sym = rs6000_savres_routine_sym (info, savep, gpr, lr); 18572 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym); 18573 RTVEC_ELT (p, offset++) 18574 = gen_rtx_USE (VOIDmode, 18575 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11 18576 : gpr && !lr ? 12 18577 : 1)); 18578 18579 for (i = 0; i < end_reg - start_reg; i++) 18580 { 18581 rtx addr, reg, mem; 18582 reg = gen_rtx_REG (reg_mode, start_reg + i); 18583 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 18584 GEN_INT (save_area_offset + reg_size*i)); 18585 mem = gen_frame_mem (reg_mode, addr); 18586 18587 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, 18588 savep ? mem : reg, 18589 savep ? reg : mem); 18590 } 18591 18592 if (savep && lr) 18593 { 18594 rtx addr, reg, mem; 18595 reg = gen_rtx_REG (Pmode, 0); 18596 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 18597 GEN_INT (info->lr_save_offset)); 18598 mem = gen_frame_mem (Pmode, addr); 18599 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg); 18600 } 18601 18602 return gen_rtx_PARALLEL (VOIDmode, p); 18603} 18604 18605/* Determine whether the gp REG is really used. */ 18606 18607static bool 18608rs6000_reg_live_or_pic_offset_p (int reg) 18609{ 18610 return ((df_regs_ever_live_p (reg) 18611 && (!call_used_regs[reg] 18612 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM 18613 && TARGET_TOC && TARGET_MINIMAL_TOC))) 18614 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM 18615 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0) 18616 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)))); 18617} 18618 18619enum { 18620 SAVRES_MULTIPLE = 0x1, 18621 SAVRES_INLINE_FPRS = 0x2, 18622 SAVRES_INLINE_GPRS = 0x4, 18623 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8, 18624 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10, 18625 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20 18626}; 18627 18628/* Determine the strategy for savings/restoring registers. */ 18629 18630static int 18631rs6000_savres_strategy (rs6000_stack_t *info, bool savep, 18632 int using_static_chain_p, int sibcall) 18633{ 18634 bool using_multiple_p; 18635 bool common; 18636 bool savres_fprs_inline; 18637 bool savres_gprs_inline; 18638 bool noclobber_global_gprs 18639 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true); 18640 int strategy; 18641 18642 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64 18643 && (!TARGET_SPE_ABI 18644 || info->spe_64bit_regs_used == 0) 18645 && info->first_gp_reg_save < 31 18646 && noclobber_global_gprs); 18647 /* Don't bother to try to save things out-of-line if r11 is occupied 18648 by the static chain. It would require too much fiddling and the 18649 static chain is rarely used anyway. */ 18650 common = (using_static_chain_p 18651 || sibcall 18652 || crtl->calls_eh_return 18653 || !info->lr_save_p 18654 || cfun->machine->ra_need_lr 18655 || info->total_size > 32767); 18656 savres_fprs_inline = (common 18657 || info->first_fp_reg_save == 64 18658 || !no_global_regs_above (info->first_fp_reg_save, 18659 /*gpr=*/false) 18660 /* The out-of-line FP routines use 18661 double-precision stores; we can't use those 18662 routines if we don't have such stores. */ 18663 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT) 18664 || FP_SAVE_INLINE (info->first_fp_reg_save)); 18665 savres_gprs_inline = (common 18666 /* Saving CR interferes with the exit routines 18667 used on the SPE, so just punt here. */ 18668 || (!savep 18669 && TARGET_SPE_ABI 18670 && info->spe_64bit_regs_used != 0 18671 && info->cr_save_p != 0) 18672 || info->first_gp_reg_save == 32 18673 || !noclobber_global_gprs 18674 || GP_SAVE_INLINE (info->first_gp_reg_save)); 18675 18676 if (savep) 18677 /* If we are going to use store multiple, then don't even bother 18678 with the out-of-line routines, since the store-multiple instruction 18679 will always be smaller. */ 18680 savres_gprs_inline = savres_gprs_inline || using_multiple_p; 18681 else 18682 { 18683 /* The situation is more complicated with load multiple. We'd 18684 prefer to use the out-of-line routines for restores, since the 18685 "exit" out-of-line routines can handle the restore of LR and 18686 the frame teardown. But we can only use the out-of-line 18687 routines if we know that we've used store multiple or 18688 out-of-line routines in the prologue, i.e. if we've saved all 18689 the registers from first_gp_reg_save. Otherwise, we risk 18690 loading garbage from the stack. Furthermore, we can only use 18691 the "exit" out-of-line gpr restore if we haven't saved any 18692 fprs. */ 18693 bool saved_all = !savres_gprs_inline || using_multiple_p; 18694 18695 if (saved_all && info->first_fp_reg_save != 64) 18696 /* We can't use the exit routine; use load multiple if it's 18697 available. */ 18698 savres_gprs_inline = savres_gprs_inline || using_multiple_p; 18699 } 18700 18701 strategy = (using_multiple_p 18702 | (savres_fprs_inline << 1) 18703 | (savres_gprs_inline << 2)); 18704#if defined(POWERPC_LINUX) || defined(POWERPC_NETBSD) 18705 if (TARGET_64BIT) 18706 { 18707 if (!savres_fprs_inline) 18708 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR; 18709 else if (!savres_gprs_inline && info->first_fp_reg_save == 64) 18710 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR; 18711 } 18712#else 18713 if (TARGET_AIX && !savres_fprs_inline) 18714 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR; 18715#endif 18716 return strategy; 18717} 18718 18719/* Emit function prologue as insns. */ 18720 18721void 18722rs6000_emit_prologue (void) 18723{ 18724 rs6000_stack_t *info = rs6000_stack_info (); 18725 enum machine_mode reg_mode = Pmode; 18726 int reg_size = TARGET_32BIT ? 4 : 8; 18727 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM); 18728 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12); 18729 rtx frame_reg_rtx = sp_reg_rtx; 18730 rtx cr_save_rtx = NULL_RTX; 18731 rtx insn; 18732 int strategy; 18733 int saving_FPRs_inline; 18734 int saving_GPRs_inline; 18735 int using_store_multiple; 18736 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE 18737 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM) 18738 && call_used_regs[STATIC_CHAIN_REGNUM]); 18739 HOST_WIDE_INT sp_offset = 0; 18740 18741 if (TARGET_FIX_AND_CONTINUE) 18742 { 18743 /* gdb on darwin arranges to forward a function from the old 18744 address by modifying the first 5 instructions of the function 18745 to branch to the overriding function. This is necessary to 18746 permit function pointers that point to the old function to 18747 actually forward to the new function. */ 18748 emit_insn (gen_nop ()); 18749 emit_insn (gen_nop ()); 18750 emit_insn (gen_nop ()); 18751 emit_insn (gen_nop ()); 18752 emit_insn (gen_nop ()); 18753 } 18754 18755 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0) 18756 { 18757 reg_mode = V2SImode; 18758 reg_size = 8; 18759 } 18760 18761 strategy = rs6000_savres_strategy (info, /*savep=*/true, 18762 /*static_chain_p=*/using_static_chain_p, 18763 /*sibcall=*/0); 18764 using_store_multiple = strategy & SAVRES_MULTIPLE; 18765 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS; 18766 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS; 18767 18768 /* For V.4, update stack before we do any saving and set back pointer. */ 18769 if (! WORLD_SAVE_P (info) 18770 && info->push_p 18771 && (DEFAULT_ABI == ABI_V4 18772 || crtl->calls_eh_return)) 18773 { 18774 bool need_r11 = (TARGET_SPE 18775 ? (!saving_GPRs_inline 18776 && info->spe_64bit_regs_used == 0) 18777 : (!saving_FPRs_inline || !saving_GPRs_inline)); 18778 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL; 18779 18780 if (info->total_size < 32767) 18781 sp_offset = info->total_size; 18782 else if (need_r11) 18783 frame_reg_rtx = copy_reg; 18784 else if (info->cr_save_p 18785 || info->lr_save_p 18786 || info->first_fp_reg_save < 64 18787 || info->first_gp_reg_save < 32 18788 || info->altivec_size != 0 18789 || info->vrsave_mask != 0 18790 || crtl->calls_eh_return) 18791 { 18792 copy_reg = frame_ptr_rtx; 18793 frame_reg_rtx = copy_reg; 18794 } 18795 else 18796 { 18797 /* The prologue won't be saving any regs so there is no need 18798 to set up a frame register to access any frame save area. 18799 We also won't be using sp_offset anywhere below, but set 18800 the correct value anyway to protect against future 18801 changes to this function. */ 18802 sp_offset = info->total_size; 18803 } 18804 rs6000_emit_allocate_stack (info->total_size, copy_reg); 18805 if (frame_reg_rtx != sp_reg_rtx) 18806 rs6000_emit_stack_tie (); 18807 } 18808 18809 /* Handle world saves specially here. */ 18810 if (WORLD_SAVE_P (info)) 18811 { 18812 int i, j, sz; 18813 rtx treg; 18814 rtvec p; 18815 rtx reg0; 18816 18817 /* save_world expects lr in r0. */ 18818 reg0 = gen_rtx_REG (Pmode, 0); 18819 if (info->lr_save_p) 18820 { 18821 insn = emit_move_insn (reg0, 18822 gen_rtx_REG (Pmode, LR_REGNO)); 18823 RTX_FRAME_RELATED_P (insn) = 1; 18824 } 18825 18826 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of 18827 assumptions about the offsets of various bits of the stack 18828 frame. */ 18829 gcc_assert (info->gp_save_offset == -220 18830 && info->fp_save_offset == -144 18831 && info->lr_save_offset == 8 18832 && info->cr_save_offset == 4 18833 && info->push_p 18834 && info->lr_save_p 18835 && (!crtl->calls_eh_return 18836 || info->ehrd_offset == -432) 18837 && info->vrsave_save_offset == -224 18838 && info->altivec_save_offset == -416); 18839 18840 treg = gen_rtx_REG (SImode, 11); 18841 emit_move_insn (treg, GEN_INT (-info->total_size)); 18842 18843 /* SAVE_WORLD takes the caller's LR in R0 and the frame size 18844 in R11. It also clobbers R12, so beware! */ 18845 18846 /* Preserve CR2 for save_world prologues */ 18847 sz = 5; 18848 sz += 32 - info->first_gp_reg_save; 18849 sz += 64 - info->first_fp_reg_save; 18850 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1; 18851 p = rtvec_alloc (sz); 18852 j = 0; 18853 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode, 18854 gen_rtx_REG (SImode, 18855 LR_REGNO)); 18856 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode, 18857 gen_rtx_SYMBOL_REF (Pmode, 18858 "*save_world")); 18859 /* We do floats first so that the instruction pattern matches 18860 properly. */ 18861 for (i = 0; i < 64 - info->first_fp_reg_save; i++) 18862 { 18863 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) 18864 ? DFmode : SFmode), 18865 info->first_fp_reg_save + i); 18866 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 18867 GEN_INT (info->fp_save_offset 18868 + sp_offset + 8 * i)); 18869 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) 18870 ? DFmode : SFmode), addr); 18871 18872 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg); 18873 } 18874 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++) 18875 { 18876 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i); 18877 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 18878 GEN_INT (info->altivec_save_offset 18879 + sp_offset + 16 * i)); 18880 rtx mem = gen_frame_mem (V4SImode, addr); 18881 18882 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg); 18883 } 18884 for (i = 0; i < 32 - info->first_gp_reg_save; i++) 18885 { 18886 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i); 18887 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 18888 GEN_INT (info->gp_save_offset 18889 + sp_offset + reg_size * i)); 18890 rtx mem = gen_frame_mem (reg_mode, addr); 18891 18892 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg); 18893 } 18894 18895 { 18896 /* CR register traditionally saved as CR2. */ 18897 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO); 18898 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 18899 GEN_INT (info->cr_save_offset 18900 + sp_offset)); 18901 rtx mem = gen_frame_mem (reg_mode, addr); 18902 18903 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg); 18904 } 18905 /* Explain about use of R0. */ 18906 if (info->lr_save_p) 18907 { 18908 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 18909 GEN_INT (info->lr_save_offset 18910 + sp_offset)); 18911 rtx mem = gen_frame_mem (reg_mode, addr); 18912 18913 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0); 18914 } 18915 /* Explain what happens to the stack pointer. */ 18916 { 18917 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg); 18918 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval); 18919 } 18920 18921 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); 18922 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, 18923 treg, GEN_INT (-info->total_size)); 18924 sp_offset = info->total_size; 18925 } 18926 18927 /* If we use the link register, get it into r0. */ 18928 if (!WORLD_SAVE_P (info) && info->lr_save_p) 18929 { 18930 rtx addr, reg, mem; 18931 18932 insn = emit_move_insn (gen_rtx_REG (Pmode, 0), 18933 gen_rtx_REG (Pmode, LR_REGNO)); 18934 RTX_FRAME_RELATED_P (insn) = 1; 18935 18936 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR 18937 | SAVRES_NOINLINE_FPRS_SAVES_LR))) 18938 { 18939 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 18940 GEN_INT (info->lr_save_offset + sp_offset)); 18941 reg = gen_rtx_REG (Pmode, 0); 18942 mem = gen_rtx_MEM (Pmode, addr); 18943 /* This should not be of rs6000_sr_alias_set, because of 18944 __builtin_return_address. */ 18945 18946 insn = emit_move_insn (mem, reg); 18947 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, 18948 NULL_RTX, NULL_RTX); 18949 } 18950 } 18951 18952 /* If we need to save CR, put it into r12 or r11. */ 18953 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx) 18954 { 18955 rtx set; 18956 18957 cr_save_rtx 18958 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline 18959 ? 11 : 12); 18960 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx)); 18961 RTX_FRAME_RELATED_P (insn) = 1; 18962 /* Now, there's no way that dwarf2out_frame_debug_expr is going 18963 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'. 18964 But that's OK. All we have to do is specify that _one_ condition 18965 code register is saved in this stack slot. The thrower's epilogue 18966 will then restore all the call-saved registers. 18967 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */ 18968 set = gen_rtx_SET (VOIDmode, cr_save_rtx, 18969 gen_rtx_REG (SImode, CR2_REGNO)); 18970 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set); 18971 } 18972 18973 /* Do any required saving of fpr's. If only one or two to save, do 18974 it ourselves. Otherwise, call function. */ 18975 if (!WORLD_SAVE_P (info) && saving_FPRs_inline) 18976 { 18977 int i; 18978 for (i = 0; i < 64 - info->first_fp_reg_save; i++) 18979 if ((df_regs_ever_live_p (info->first_fp_reg_save+i) 18980 && ! call_used_regs[info->first_fp_reg_save+i])) 18981 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, 18982 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) 18983 ? DFmode : SFmode, 18984 info->first_fp_reg_save + i, 18985 info->fp_save_offset + sp_offset + 8 * i, 18986 info->total_size); 18987 } 18988 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64) 18989 { 18990 rtx par; 18991 18992 par = rs6000_make_savres_rtx (info, frame_reg_rtx, 18993 info->fp_save_offset + sp_offset, 18994 DFmode, 18995 /*savep=*/true, /*gpr=*/false, 18996 /*lr=*/(strategy 18997 & SAVRES_NOINLINE_FPRS_SAVES_LR) 18998 != 0); 18999 insn = emit_insn (par); 19000 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, 19001 NULL_RTX, NULL_RTX); 19002 } 19003 19004 /* Save GPRs. This is done as a PARALLEL if we are using 19005 the store-multiple instructions. */ 19006 if (!WORLD_SAVE_P (info) 19007 && TARGET_SPE_ABI 19008 && info->spe_64bit_regs_used != 0 19009 && info->first_gp_reg_save != 32) 19010 { 19011 int i; 19012 rtx spe_save_area_ptr; 19013 19014 /* Determine whether we can address all of the registers that need 19015 to be saved with an offset from the stack pointer that fits in 19016 the small const field for SPE memory instructions. */ 19017 int spe_regs_addressable_via_sp 19018 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset 19019 + (32 - info->first_gp_reg_save - 1) * reg_size) 19020 && saving_GPRs_inline); 19021 int spe_offset; 19022 19023 if (spe_regs_addressable_via_sp) 19024 { 19025 spe_save_area_ptr = frame_reg_rtx; 19026 spe_offset = info->spe_gp_save_offset + sp_offset; 19027 } 19028 else 19029 { 19030 /* Make r11 point to the start of the SPE save area. We need 19031 to be careful here if r11 is holding the static chain. If 19032 it is, then temporarily save it in r0. We would use r0 as 19033 our base register here, but using r0 as a base register in 19034 loads and stores means something different from what we 19035 would like. */ 19036 int ool_adjust = (saving_GPRs_inline 19037 ? 0 19038 : (info->first_gp_reg_save 19039 - (FIRST_SAVRES_REGISTER+1))*8); 19040 HOST_WIDE_INT offset = (info->spe_gp_save_offset 19041 + sp_offset - ool_adjust); 19042 19043 if (using_static_chain_p) 19044 { 19045 rtx r0 = gen_rtx_REG (Pmode, 0); 19046 gcc_assert (info->first_gp_reg_save > 11); 19047 19048 emit_move_insn (r0, gen_rtx_REG (Pmode, 11)); 19049 } 19050 19051 spe_save_area_ptr = gen_rtx_REG (Pmode, 11); 19052 insn = emit_insn (gen_addsi3 (spe_save_area_ptr, 19053 frame_reg_rtx, 19054 GEN_INT (offset))); 19055 /* We need to make sure the move to r11 gets noted for 19056 properly outputting unwind information. */ 19057 if (!saving_GPRs_inline) 19058 rs6000_frame_related (insn, frame_reg_rtx, offset, 19059 NULL_RTX, NULL_RTX); 19060 spe_offset = 0; 19061 } 19062 19063 if (saving_GPRs_inline) 19064 { 19065 for (i = 0; i < 32 - info->first_gp_reg_save; i++) 19066 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i)) 19067 { 19068 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i); 19069 rtx offset, addr, mem; 19070 19071 /* We're doing all this to ensure that the offset fits into 19072 the immediate offset of 'evstdd'. */ 19073 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset)); 19074 19075 offset = GEN_INT (reg_size * i + spe_offset); 19076 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset); 19077 mem = gen_rtx_MEM (V2SImode, addr); 19078 19079 insn = emit_move_insn (mem, reg); 19080 19081 rs6000_frame_related (insn, spe_save_area_ptr, 19082 info->spe_gp_save_offset 19083 + sp_offset + reg_size * i, 19084 offset, const0_rtx); 19085 } 19086 } 19087 else 19088 { 19089 rtx par; 19090 19091 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11), 19092 0, reg_mode, 19093 /*savep=*/true, /*gpr=*/true, 19094 /*lr=*/false); 19095 insn = emit_insn (par); 19096 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, 19097 NULL_RTX, NULL_RTX); 19098 } 19099 19100 19101 /* Move the static chain pointer back. */ 19102 if (using_static_chain_p && !spe_regs_addressable_via_sp) 19103 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0)); 19104 } 19105 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline) 19106 { 19107 rtx par; 19108 19109 /* Need to adjust r11 (r12) if we saved any FPRs. */ 19110 if (info->first_fp_reg_save != 64) 19111 { 19112 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX 19113 ? 12 : 11); 19114 rtx offset = GEN_INT (sp_offset 19115 + (-8 * (64-info->first_fp_reg_save))); 19116 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset)); 19117 } 19118 19119 par = rs6000_make_savres_rtx (info, frame_reg_rtx, 19120 info->gp_save_offset + sp_offset, 19121 reg_mode, 19122 /*savep=*/true, /*gpr=*/true, 19123 /*lr=*/(strategy 19124 & SAVRES_NOINLINE_GPRS_SAVES_LR) 19125 != 0); 19126 insn = emit_insn (par); 19127 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, 19128 NULL_RTX, NULL_RTX); 19129 } 19130 else if (!WORLD_SAVE_P (info) && using_store_multiple) 19131 { 19132 rtvec p; 19133 int i; 19134 p = rtvec_alloc (32 - info->first_gp_reg_save); 19135 for (i = 0; i < 32 - info->first_gp_reg_save; i++) 19136 { 19137 rtx addr, reg, mem; 19138 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i); 19139 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 19140 GEN_INT (info->gp_save_offset 19141 + sp_offset 19142 + reg_size * i)); 19143 mem = gen_frame_mem (reg_mode, addr); 19144 19145 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg); 19146 } 19147 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); 19148 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, 19149 NULL_RTX, NULL_RTX); 19150 } 19151 else if (!WORLD_SAVE_P (info)) 19152 { 19153 int i; 19154 for (i = 0; i < 32 - info->first_gp_reg_save; i++) 19155 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i)) 19156 { 19157 rtx addr, reg, mem; 19158 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i); 19159 19160 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 19161 GEN_INT (info->gp_save_offset 19162 + sp_offset 19163 + reg_size * i)); 19164 mem = gen_frame_mem (reg_mode, addr); 19165 19166 insn = emit_move_insn (mem, reg); 19167 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, 19168 NULL_RTX, NULL_RTX); 19169 } 19170 } 19171 19172 /* ??? There's no need to emit actual instructions here, but it's the 19173 easiest way to get the frame unwind information emitted. */ 19174 if (crtl->calls_eh_return) 19175 { 19176 unsigned int i, regno; 19177 19178 for (i = 0; ; ++i) 19179 { 19180 regno = EH_RETURN_DATA_REGNO (i); 19181 if (regno == INVALID_REGNUM) 19182 break; 19183 19184 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno, 19185 info->ehrd_offset + sp_offset 19186 + reg_size * (int) i, 19187 info->total_size); 19188 } 19189 } 19190 19191 /* In AIX ABI we need to make sure r2 is really saved. */ 19192 if (TARGET_AIX && crtl->calls_eh_return) 19193 { 19194 rtx tmp_reg, tmp_reg_si, hi, lo, compare_result, toc_save_done, jump; 19195 long toc_restore_insn; 19196 19197 gcc_assert (frame_reg_rtx == frame_ptr_rtx 19198 || frame_reg_rtx == sp_reg_rtx); 19199 tmp_reg = gen_rtx_REG (Pmode, 11); 19200 tmp_reg_si = gen_rtx_REG (SImode, 11); 19201 if (using_static_chain_p) 19202 emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg); 19203 gcc_assert (saving_GPRs_inline && saving_FPRs_inline); 19204 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO)); 19205 /* Peek at instruction to which this function returns. If it's 19206 restoring r2, then we know we've already saved r2. We can't 19207 unconditionally save r2 because the value we have will already 19208 be updated if we arrived at this function via a plt call or 19209 toc adjusting stub. */ 19210 emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg)); 19211 toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028; 19212 hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode); 19213 emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi)); 19214 compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO); 19215 validate_condition_mode (EQ, CCUNSmode); 19216 lo = gen_int_mode (toc_restore_insn & 0xffff, SImode); 19217 emit_insn (gen_rtx_SET (VOIDmode, compare_result, 19218 gen_rtx_COMPARE (CCUNSmode, tmp_reg_si, lo))); 19219 toc_save_done = gen_label_rtx (); 19220 jump = gen_rtx_IF_THEN_ELSE (VOIDmode, 19221 gen_rtx_EQ (VOIDmode, compare_result, 19222 const0_rtx), 19223 gen_rtx_LABEL_REF (VOIDmode, toc_save_done), 19224 pc_rtx); 19225 jump = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, jump)); 19226 JUMP_LABEL (jump) = toc_save_done; 19227 LABEL_NUSES (toc_save_done) += 1; 19228 19229 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, 2, 19230 sp_offset + 5 * reg_size, info->total_size); 19231 emit_label (toc_save_done); 19232 if (using_static_chain_p) 19233 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0)); 19234 } 19235 19236 /* Save CR if we use any that must be preserved. */ 19237 if (!WORLD_SAVE_P (info) && info->cr_save_p) 19238 { 19239 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 19240 GEN_INT (info->cr_save_offset + sp_offset)); 19241 rtx mem = gen_frame_mem (SImode, addr); 19242 /* See the large comment above about why CR2_REGNO is used. */ 19243 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO); 19244 19245 /* If r12 was used to hold the original sp, copy cr into r0 now 19246 that it's free. */ 19247 if (REGNO (frame_reg_rtx) == 12) 19248 { 19249 rtx set; 19250 19251 cr_save_rtx = gen_rtx_REG (SImode, 0); 19252 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx)); 19253 RTX_FRAME_RELATED_P (insn) = 1; 19254 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg); 19255 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set); 19256 } 19257 insn = emit_move_insn (mem, cr_save_rtx); 19258 19259 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, 19260 NULL_RTX, NULL_RTX); 19261 } 19262 19263 /* Update stack and set back pointer unless this is V.4, 19264 for which it was done previously. */ 19265 if (!WORLD_SAVE_P (info) && info->push_p 19266 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return)) 19267 { 19268 rtx copy_reg = NULL; 19269 19270 if (info->total_size < 32767) 19271 sp_offset = info->total_size; 19272 else if (info->altivec_size != 0 19273 || info->vrsave_mask != 0) 19274 { 19275 copy_reg = frame_ptr_rtx; 19276 frame_reg_rtx = copy_reg; 19277 } 19278 else 19279 sp_offset = info->total_size; 19280 rs6000_emit_allocate_stack (info->total_size, copy_reg); 19281 if (frame_reg_rtx != sp_reg_rtx) 19282 rs6000_emit_stack_tie (); 19283 } 19284 19285 /* Set frame pointer, if needed. */ 19286 if (frame_pointer_needed) 19287 { 19288 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM), 19289 sp_reg_rtx); 19290 RTX_FRAME_RELATED_P (insn) = 1; 19291 } 19292 19293 /* Save AltiVec registers if needed. Save here because the red zone does 19294 not include AltiVec registers. */ 19295 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0) 19296 { 19297 int i; 19298 19299 /* There should be a non inline version of this, for when we 19300 are saving lots of vector registers. */ 19301 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i) 19302 if (info->vrsave_mask & ALTIVEC_REG_BIT (i)) 19303 { 19304 rtx areg, savereg, mem; 19305 int offset; 19306 19307 offset = info->altivec_save_offset + sp_offset 19308 + 16 * (i - info->first_altivec_reg_save); 19309 19310 savereg = gen_rtx_REG (V4SImode, i); 19311 19312 areg = gen_rtx_REG (Pmode, 0); 19313 emit_move_insn (areg, GEN_INT (offset)); 19314 19315 /* AltiVec addressing mode is [reg+reg]. */ 19316 mem = gen_frame_mem (V4SImode, 19317 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg)); 19318 19319 insn = emit_move_insn (mem, savereg); 19320 19321 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, 19322 areg, GEN_INT (offset)); 19323 } 19324 } 19325 19326 /* VRSAVE is a bit vector representing which AltiVec registers 19327 are used. The OS uses this to determine which vector 19328 registers to save on a context switch. We need to save 19329 VRSAVE on the stack frame, add whatever AltiVec registers we 19330 used in this function, and do the corresponding magic in the 19331 epilogue. */ 19332 19333 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE 19334 && info->vrsave_mask != 0) 19335 { 19336 rtx reg, mem, vrsave; 19337 int offset; 19338 19339 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12 19340 as frame_reg_rtx and r11 as the static chain pointer for 19341 nested functions. */ 19342 reg = gen_rtx_REG (SImode, 0); 19343 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO); 19344 if (TARGET_MACHO) 19345 emit_insn (gen_get_vrsave_internal (reg)); 19346 else 19347 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave)); 19348 19349 if (!WORLD_SAVE_P (info)) 19350 { 19351 /* Save VRSAVE. */ 19352 offset = info->vrsave_save_offset + sp_offset; 19353 mem = gen_frame_mem (SImode, 19354 gen_rtx_PLUS (Pmode, frame_reg_rtx, 19355 GEN_INT (offset))); 19356 insn = emit_move_insn (mem, reg); 19357 } 19358 19359 /* Include the registers in the mask. */ 19360 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask))); 19361 19362 insn = emit_insn (generate_set_vrsave (reg, info, 0)); 19363 } 19364 19365 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */ 19366 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0) 19367 || (DEFAULT_ABI == ABI_V4 19368 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT)) 19369 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))) 19370 { 19371 /* If emit_load_toc_table will use the link register, we need to save 19372 it. We use R12 for this purpose because emit_load_toc_table 19373 can use register 0. This allows us to use a plain 'blr' to return 19374 from the procedure more often. */ 19375 int save_LR_around_toc_setup = (TARGET_ELF 19376 && DEFAULT_ABI != ABI_AIX 19377 && flag_pic 19378 && ! info->lr_save_p 19379 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0); 19380 if (save_LR_around_toc_setup) 19381 { 19382 rtx lr = gen_rtx_REG (Pmode, LR_REGNO); 19383 19384 insn = emit_move_insn (frame_ptr_rtx, lr); 19385 RTX_FRAME_RELATED_P (insn) = 1; 19386 19387 rs6000_emit_load_toc_table (TRUE); 19388 19389 insn = emit_move_insn (lr, frame_ptr_rtx); 19390 RTX_FRAME_RELATED_P (insn) = 1; 19391 } 19392 else 19393 rs6000_emit_load_toc_table (TRUE); 19394 } 19395 19396#if TARGET_MACHO 19397 if (DEFAULT_ABI == ABI_DARWIN 19398 && flag_pic && crtl->uses_pic_offset_table) 19399 { 19400 rtx lr = gen_rtx_REG (Pmode, LR_REGNO); 19401 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME); 19402 19403 /* Save and restore LR locally around this call (in R0). */ 19404 if (!info->lr_save_p) 19405 emit_move_insn (gen_rtx_REG (Pmode, 0), lr); 19406 19407 emit_insn (gen_load_macho_picbase (src)); 19408 19409 emit_move_insn (gen_rtx_REG (Pmode, 19410 RS6000_PIC_OFFSET_TABLE_REGNUM), 19411 lr); 19412 19413 if (!info->lr_save_p) 19414 emit_move_insn (lr, gen_rtx_REG (Pmode, 0)); 19415 } 19416#endif 19417} 19418 19419/* Write function prologue. */ 19420 19421static void 19422rs6000_output_function_prologue (FILE *file, 19423 HOST_WIDE_INT size ATTRIBUTE_UNUSED) 19424{ 19425 rs6000_stack_t *info = rs6000_stack_info (); 19426 19427 if (TARGET_DEBUG_STACK) 19428 debug_stack_info (info); 19429 19430 /* Write .extern for any function we will call to save and restore 19431 fp values. */ 19432 if (info->first_fp_reg_save < 64 19433 && !FP_SAVE_INLINE (info->first_fp_reg_save)) 19434 { 19435 char *name; 19436 int regno = info->first_fp_reg_save - 32; 19437 19438 name = rs6000_savres_routine_name (info, regno, /*savep=*/true, 19439 /*gpr=*/false, /*lr=*/false); 19440 fprintf (file, "\t.extern %s\n", name); 19441 19442 name = rs6000_savres_routine_name (info, regno, /*savep=*/false, 19443 /*gpr=*/false, /*lr=*/true); 19444 fprintf (file, "\t.extern %s\n", name); 19445 } 19446 19447 /* Write .extern for AIX common mode routines, if needed. */ 19448 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined) 19449 { 19450 fputs ("\t.extern __mulh\n", file); 19451 fputs ("\t.extern __mull\n", file); 19452 fputs ("\t.extern __divss\n", file); 19453 fputs ("\t.extern __divus\n", file); 19454 fputs ("\t.extern __quoss\n", file); 19455 fputs ("\t.extern __quous\n", file); 19456 common_mode_defined = 1; 19457 } 19458 19459 if (! HAVE_prologue) 19460 { 19461 rtx prologue; 19462 19463 start_sequence (); 19464 19465 /* A NOTE_INSN_DELETED is supposed to be at the start and end of 19466 the "toplevel" insn chain. */ 19467 emit_note (NOTE_INSN_DELETED); 19468 rs6000_emit_prologue (); 19469 emit_note (NOTE_INSN_DELETED); 19470 19471 /* Expand INSN_ADDRESSES so final() doesn't crash. */ 19472 { 19473 rtx insn; 19474 unsigned addr = 0; 19475 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn)) 19476 { 19477 INSN_ADDRESSES_NEW (insn, addr); 19478 addr += 4; 19479 } 19480 } 19481 19482 prologue = get_insns (); 19483 end_sequence (); 19484 19485 if (TARGET_DEBUG_STACK) 19486 debug_rtx_list (prologue, 100); 19487 19488 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb), 19489 ENTRY_BLOCK_PTR); 19490 } 19491 19492 rs6000_pic_labelno++; 19493} 19494 19495/* Non-zero if vmx regs are restored before the frame pop, zero if 19496 we restore after the pop when possible. */ 19497#define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0 19498 19499/* Reload CR from REG. */ 19500 19501static void 19502rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple) 19503{ 19504 int count = 0; 19505 int i; 19506 19507 if (using_mfcr_multiple) 19508 { 19509 for (i = 0; i < 8; i++) 19510 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i]) 19511 count++; 19512 gcc_assert (count); 19513 } 19514 19515 if (using_mfcr_multiple && count > 1) 19516 { 19517 rtvec p; 19518 int ndx; 19519 19520 p = rtvec_alloc (count); 19521 19522 ndx = 0; 19523 for (i = 0; i < 8; i++) 19524 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i]) 19525 { 19526 rtvec r = rtvec_alloc (2); 19527 RTVEC_ELT (r, 0) = reg; 19528 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i)); 19529 RTVEC_ELT (p, ndx) = 19530 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i), 19531 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR)); 19532 ndx++; 19533 } 19534 emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); 19535 gcc_assert (ndx == count); 19536 } 19537 else 19538 for (i = 0; i < 8; i++) 19539 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i]) 19540 { 19541 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode, 19542 CR0_REGNO+i), 19543 reg)); 19544 } 19545} 19546 19547/* Return true if OFFSET from stack pointer can be clobbered by signals. 19548 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes 19549 below stack pointer not cloberred by signals. */ 19550 19551static inline bool 19552offset_below_red_zone_p (HOST_WIDE_INT offset) 19553{ 19554 return offset < (DEFAULT_ABI == ABI_V4 19555 ? 0 19556 : TARGET_32BIT ? -220 : -288); 19557} 19558 19559/* Emit function epilogue as insns. */ 19560 19561void 19562rs6000_emit_epilogue (int sibcall) 19563{ 19564 rs6000_stack_t *info; 19565 int restoring_GPRs_inline; 19566 int restoring_FPRs_inline; 19567 int using_load_multiple; 19568 int using_mtcr_multiple; 19569 int use_backchain_to_restore_sp; 19570 int restore_lr; 19571 int strategy; 19572 int sp_offset = 0; 19573 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1); 19574 rtx frame_reg_rtx = sp_reg_rtx; 19575 rtx cfa_restores = NULL_RTX; 19576 rtx insn; 19577 rtx cr_save_reg = NULL_RTX; 19578 enum machine_mode reg_mode = Pmode; 19579 int reg_size = TARGET_32BIT ? 4 : 8; 19580 int i; 19581 19582 info = rs6000_stack_info (); 19583 19584 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0) 19585 { 19586 reg_mode = V2SImode; 19587 reg_size = 8; 19588 } 19589 19590 strategy = rs6000_savres_strategy (info, /*savep=*/false, 19591 /*static_chain_p=*/0, sibcall); 19592 using_load_multiple = strategy & SAVRES_MULTIPLE; 19593 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS; 19594 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS; 19595 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601 19596 || rs6000_cpu == PROCESSOR_PPC603 19597 || rs6000_cpu == PROCESSOR_PPC750 19598 || optimize_size); 19599 /* Restore via the backchain when we have a large frame, since this 19600 is more efficient than an addis, addi pair. The second condition 19601 here will not trigger at the moment; We don't actually need a 19602 frame pointer for alloca, but the generic parts of the compiler 19603 give us one anyway. */ 19604 use_backchain_to_restore_sp = (info->total_size > 32767 19605 || info->total_size 19606 + (info->lr_save_p ? info->lr_save_offset : 0) 19607 > 32767 19608 || (cfun->calls_alloca 19609 && !frame_pointer_needed)); 19610 restore_lr = (info->lr_save_p 19611 && (restoring_FPRs_inline 19612 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR)) 19613 && (restoring_GPRs_inline 19614 || info->first_fp_reg_save < 64)); 19615 19616 if (WORLD_SAVE_P (info)) 19617 { 19618 int i, j; 19619 char rname[30]; 19620 const char *alloc_rname; 19621 rtvec p; 19622 19623 /* eh_rest_world_r10 will return to the location saved in the LR 19624 stack slot (which is not likely to be our caller.) 19625 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8. 19626 rest_world is similar, except any R10 parameter is ignored. 19627 The exception-handling stuff that was here in 2.95 is no 19628 longer necessary. */ 19629 19630 p = rtvec_alloc (9 19631 + 1 19632 + 32 - info->first_gp_reg_save 19633 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save 19634 + 63 + 1 - info->first_fp_reg_save); 19635 19636 strcpy (rname, ((crtl->calls_eh_return) ? 19637 "*eh_rest_world_r10" : "*rest_world")); 19638 alloc_rname = ggc_strdup (rname); 19639 19640 j = 0; 19641 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode); 19642 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode, 19643 gen_rtx_REG (Pmode, 19644 LR_REGNO)); 19645 RTVEC_ELT (p, j++) 19646 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname)); 19647 /* The instruction pattern requires a clobber here; 19648 it is shared with the restVEC helper. */ 19649 RTVEC_ELT (p, j++) 19650 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11)); 19651 19652 { 19653 /* CR register traditionally saved as CR2. */ 19654 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO); 19655 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 19656 GEN_INT (info->cr_save_offset)); 19657 rtx mem = gen_frame_mem (reg_mode, addr); 19658 19659 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem); 19660 } 19661 19662 for (i = 0; i < 32 - info->first_gp_reg_save; i++) 19663 { 19664 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i); 19665 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 19666 GEN_INT (info->gp_save_offset 19667 + reg_size * i)); 19668 rtx mem = gen_frame_mem (reg_mode, addr); 19669 19670 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem); 19671 } 19672 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++) 19673 { 19674 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i); 19675 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 19676 GEN_INT (info->altivec_save_offset 19677 + 16 * i)); 19678 rtx mem = gen_frame_mem (V4SImode, addr); 19679 19680 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem); 19681 } 19682 for (i = 0; info->first_fp_reg_save + i <= 63; i++) 19683 { 19684 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) 19685 ? DFmode : SFmode), 19686 info->first_fp_reg_save + i); 19687 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 19688 GEN_INT (info->fp_save_offset 19689 + 8 * i)); 19690 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) 19691 ? DFmode : SFmode), addr); 19692 19693 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem); 19694 } 19695 RTVEC_ELT (p, j++) 19696 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0)); 19697 RTVEC_ELT (p, j++) 19698 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12)); 19699 RTVEC_ELT (p, j++) 19700 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7)); 19701 RTVEC_ELT (p, j++) 19702 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8)); 19703 RTVEC_ELT (p, j++) 19704 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10)); 19705 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p)); 19706 19707 return; 19708 } 19709 19710 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */ 19711 if (info->push_p) 19712 sp_offset = info->total_size; 19713 19714 /* Restore AltiVec registers if we must do so before adjusting the 19715 stack. */ 19716 if (TARGET_ALTIVEC_ABI 19717 && info->altivec_size != 0 19718 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 19719 || (DEFAULT_ABI != ABI_V4 19720 && offset_below_red_zone_p (info->altivec_save_offset)))) 19721 { 19722 int i; 19723 19724 if (use_backchain_to_restore_sp) 19725 { 19726 frame_reg_rtx = gen_rtx_REG (Pmode, 11); 19727 emit_move_insn (frame_reg_rtx, 19728 gen_rtx_MEM (Pmode, sp_reg_rtx)); 19729 sp_offset = 0; 19730 } 19731 else if (frame_pointer_needed) 19732 frame_reg_rtx = hard_frame_pointer_rtx; 19733 19734 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i) 19735 if (info->vrsave_mask & ALTIVEC_REG_BIT (i)) 19736 { 19737 rtx addr, areg, mem, reg; 19738 19739 areg = gen_rtx_REG (Pmode, 0); 19740 emit_move_insn 19741 (areg, GEN_INT (info->altivec_save_offset 19742 + sp_offset 19743 + 16 * (i - info->first_altivec_reg_save))); 19744 19745 /* AltiVec addressing mode is [reg+reg]. */ 19746 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg); 19747 mem = gen_frame_mem (V4SImode, addr); 19748 19749 reg = gen_rtx_REG (V4SImode, i); 19750 emit_move_insn (reg, mem); 19751 if (offset_below_red_zone_p (info->altivec_save_offset 19752 + (i - info->first_altivec_reg_save) 19753 * 16)) 19754 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, 19755 cfa_restores); 19756 } 19757 } 19758 19759 /* Restore VRSAVE if we must do so before adjusting the stack. */ 19760 if (TARGET_ALTIVEC 19761 && TARGET_ALTIVEC_VRSAVE 19762 && info->vrsave_mask != 0 19763 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 19764 || (DEFAULT_ABI != ABI_V4 19765 && offset_below_red_zone_p (info->vrsave_save_offset)))) 19766 { 19767 rtx addr, mem, reg; 19768 19769 if (frame_reg_rtx == sp_reg_rtx) 19770 { 19771 if (use_backchain_to_restore_sp) 19772 { 19773 frame_reg_rtx = gen_rtx_REG (Pmode, 11); 19774 emit_move_insn (frame_reg_rtx, 19775 gen_rtx_MEM (Pmode, sp_reg_rtx)); 19776 sp_offset = 0; 19777 } 19778 else if (frame_pointer_needed) 19779 frame_reg_rtx = hard_frame_pointer_rtx; 19780 } 19781 19782 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 19783 GEN_INT (info->vrsave_save_offset + sp_offset)); 19784 mem = gen_frame_mem (SImode, addr); 19785 reg = gen_rtx_REG (SImode, 12); 19786 emit_move_insn (reg, mem); 19787 19788 emit_insn (generate_set_vrsave (reg, info, 1)); 19789 } 19790 19791 insn = NULL_RTX; 19792 /* If we have a large stack frame, restore the old stack pointer 19793 using the backchain. */ 19794 if (use_backchain_to_restore_sp) 19795 { 19796 if (frame_reg_rtx == sp_reg_rtx) 19797 { 19798 /* Under V.4, don't reset the stack pointer until after we're done 19799 loading the saved registers. */ 19800 if (DEFAULT_ABI == ABI_V4) 19801 frame_reg_rtx = gen_rtx_REG (Pmode, 11); 19802 19803 insn = emit_move_insn (frame_reg_rtx, 19804 gen_rtx_MEM (Pmode, sp_reg_rtx)); 19805 sp_offset = 0; 19806 } 19807 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 19808 && DEFAULT_ABI == ABI_V4) 19809 /* frame_reg_rtx has been set up by the altivec restore. */ 19810 ; 19811 else 19812 { 19813 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx); 19814 frame_reg_rtx = sp_reg_rtx; 19815 } 19816 } 19817 /* If we have a frame pointer, we can restore the old stack pointer 19818 from it. */ 19819 else if (frame_pointer_needed) 19820 { 19821 frame_reg_rtx = sp_reg_rtx; 19822 if (DEFAULT_ABI == ABI_V4) 19823 frame_reg_rtx = gen_rtx_REG (Pmode, 11); 19824 /* Prevent reordering memory accesses against stack pointer restore. */ 19825 else if (cfun->calls_alloca 19826 || offset_below_red_zone_p (-info->total_size)) 19827 { 19828 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx); 19829 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx); 19830 MEM_NOTRAP_P (mem1) = 1; 19831 MEM_NOTRAP_P (mem2) = 1; 19832 emit_insn (gen_frame_tie (mem1, mem2)); 19833 } 19834 19835 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx, 19836 GEN_INT (info->total_size))); 19837 sp_offset = 0; 19838 } 19839 else if (info->push_p 19840 && DEFAULT_ABI != ABI_V4 19841 && !crtl->calls_eh_return) 19842 { 19843 /* Prevent reordering memory accesses against stack pointer restore. */ 19844 if (cfun->calls_alloca 19845 || offset_below_red_zone_p (-info->total_size)) 19846 { 19847 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx); 19848 MEM_NOTRAP_P (mem) = 1; 19849 emit_insn (gen_stack_tie (mem)); 19850 } 19851 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, 19852 GEN_INT (info->total_size))); 19853 sp_offset = 0; 19854 } 19855 if (insn && frame_reg_rtx == sp_reg_rtx) 19856 { 19857 if (cfa_restores) 19858 { 19859 REG_NOTES (insn) = cfa_restores; 19860 cfa_restores = NULL_RTX; 19861 } 19862 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx); 19863 RTX_FRAME_RELATED_P (insn) = 1; 19864 } 19865 19866 /* Restore AltiVec registers if we have not done so already. */ 19867 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 19868 && TARGET_ALTIVEC_ABI 19869 && info->altivec_size != 0 19870 && (DEFAULT_ABI == ABI_V4 19871 || !offset_below_red_zone_p (info->altivec_save_offset))) 19872 { 19873 int i; 19874 19875 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i) 19876 if (info->vrsave_mask & ALTIVEC_REG_BIT (i)) 19877 { 19878 rtx addr, areg, mem, reg; 19879 19880 areg = gen_rtx_REG (Pmode, 0); 19881 emit_move_insn 19882 (areg, GEN_INT (info->altivec_save_offset 19883 + sp_offset 19884 + 16 * (i - info->first_altivec_reg_save))); 19885 19886 /* AltiVec addressing mode is [reg+reg]. */ 19887 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg); 19888 mem = gen_frame_mem (V4SImode, addr); 19889 19890 reg = gen_rtx_REG (V4SImode, i); 19891 emit_move_insn (reg, mem); 19892 if (DEFAULT_ABI == ABI_V4) 19893 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, 19894 cfa_restores); 19895 } 19896 } 19897 19898 /* Restore VRSAVE if we have not done so already. */ 19899 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 19900 && TARGET_ALTIVEC 19901 && TARGET_ALTIVEC_VRSAVE 19902 && info->vrsave_mask != 0 19903 && (DEFAULT_ABI == ABI_V4 19904 || !offset_below_red_zone_p (info->vrsave_save_offset))) 19905 { 19906 rtx addr, mem, reg; 19907 19908 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 19909 GEN_INT (info->vrsave_save_offset + sp_offset)); 19910 mem = gen_frame_mem (SImode, addr); 19911 reg = gen_rtx_REG (SImode, 12); 19912 emit_move_insn (reg, mem); 19913 19914 emit_insn (generate_set_vrsave (reg, info, 1)); 19915 } 19916 19917 /* Get the old lr if we saved it. If we are restoring registers 19918 out-of-line, then the out-of-line routines can do this for us. */ 19919 if (restore_lr && restoring_GPRs_inline) 19920 { 19921 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx, 19922 info->lr_save_offset + sp_offset); 19923 19924 emit_move_insn (gen_rtx_REG (Pmode, 0), mem); 19925 } 19926 19927 /* Get the old cr if we saved it. */ 19928 if (info->cr_save_p) 19929 { 19930 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 19931 GEN_INT (info->cr_save_offset + sp_offset)); 19932 rtx mem = gen_frame_mem (SImode, addr); 19933 19934 cr_save_reg = gen_rtx_REG (SImode, 19935 DEFAULT_ABI == ABI_AIX 19936 && !restoring_GPRs_inline 19937 && info->first_fp_reg_save < 64 19938 ? 11 : 12); 19939 emit_move_insn (cr_save_reg, mem); 19940 } 19941 19942 /* Set LR here to try to overlap restores below. LR is always saved 19943 above incoming stack, so it never needs REG_CFA_RESTORE. */ 19944 if (restore_lr && restoring_GPRs_inline) 19945 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), 19946 gen_rtx_REG (Pmode, 0)); 19947 19948 /* Load exception handler data registers, if needed. */ 19949 if (crtl->calls_eh_return) 19950 { 19951 unsigned int i, regno; 19952 19953 if (TARGET_AIX) 19954 { 19955 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 19956 GEN_INT (sp_offset + 5 * reg_size)); 19957 rtx mem = gen_frame_mem (reg_mode, addr); 19958 19959 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem); 19960 } 19961 19962 for (i = 0; ; ++i) 19963 { 19964 rtx mem; 19965 19966 regno = EH_RETURN_DATA_REGNO (i); 19967 if (regno == INVALID_REGNUM) 19968 break; 19969 19970 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx, 19971 info->ehrd_offset + sp_offset 19972 + reg_size * (int) i); 19973 19974 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem); 19975 } 19976 } 19977 19978 /* Restore GPRs. This is done as a PARALLEL if we are using 19979 the load-multiple instructions. */ 19980 if (TARGET_SPE_ABI 19981 && info->spe_64bit_regs_used != 0 19982 && info->first_gp_reg_save != 32) 19983 { 19984 /* Determine whether we can address all of the registers that need 19985 to be saved with an offset from the stack pointer that fits in 19986 the small const field for SPE memory instructions. */ 19987 int spe_regs_addressable_via_sp 19988 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset 19989 + (32 - info->first_gp_reg_save - 1) * reg_size) 19990 && restoring_GPRs_inline); 19991 int spe_offset; 19992 19993 if (spe_regs_addressable_via_sp) 19994 spe_offset = info->spe_gp_save_offset + sp_offset; 19995 else 19996 { 19997 rtx old_frame_reg_rtx = frame_reg_rtx; 19998 /* Make r11 point to the start of the SPE save area. We worried about 19999 not clobbering it when we were saving registers in the prologue. 20000 There's no need to worry here because the static chain is passed 20001 anew to every function. */ 20002 int ool_adjust = (restoring_GPRs_inline 20003 ? 0 20004 : (info->first_gp_reg_save 20005 - (FIRST_SAVRES_REGISTER+1))*8); 20006 20007 if (frame_reg_rtx == sp_reg_rtx) 20008 frame_reg_rtx = gen_rtx_REG (Pmode, 11); 20009 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx, 20010 GEN_INT (info->spe_gp_save_offset 20011 + sp_offset 20012 - ool_adjust))); 20013 /* Keep the invariant that frame_reg_rtx + sp_offset points 20014 at the top of the stack frame. */ 20015 sp_offset = -info->spe_gp_save_offset; 20016 20017 spe_offset = 0; 20018 } 20019 20020 if (restoring_GPRs_inline) 20021 { 20022 for (i = 0; i < 32 - info->first_gp_reg_save; i++) 20023 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i)) 20024 { 20025 rtx offset, addr, mem, reg; 20026 20027 /* We're doing all this to ensure that the immediate offset 20028 fits into the immediate field of 'evldd'. */ 20029 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i)); 20030 20031 offset = GEN_INT (spe_offset + reg_size * i); 20032 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset); 20033 mem = gen_rtx_MEM (V2SImode, addr); 20034 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i); 20035 20036 insn = emit_move_insn (reg, mem); 20037 if (DEFAULT_ABI == ABI_V4) 20038 { 20039 if (frame_pointer_needed 20040 && info->first_gp_reg_save + i 20041 == HARD_FRAME_POINTER_REGNUM) 20042 { 20043 add_reg_note (insn, REG_CFA_DEF_CFA, 20044 plus_constant (frame_reg_rtx, 20045 sp_offset)); 20046 RTX_FRAME_RELATED_P (insn) = 1; 20047 } 20048 20049 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, 20050 cfa_restores); 20051 } 20052 } 20053 } 20054 else 20055 { 20056 rtx par; 20057 20058 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11), 20059 0, reg_mode, 20060 /*savep=*/false, /*gpr=*/true, 20061 /*lr=*/true); 20062 emit_jump_insn (par); 20063 /* We don't want anybody else emitting things after we jumped 20064 back. */ 20065 return; 20066 } 20067 } 20068 else if (!restoring_GPRs_inline) 20069 { 20070 /* We are jumping to an out-of-line function. */ 20071 bool can_use_exit = info->first_fp_reg_save == 64; 20072 rtx par; 20073 20074 /* Emit stack reset code if we need it. */ 20075 if (can_use_exit) 20076 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx, 20077 sp_offset, can_use_exit); 20078 else 20079 { 20080 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX 20081 ? 12 : 11), 20082 frame_reg_rtx, 20083 GEN_INT (sp_offset - info->fp_size))); 20084 if (REGNO (frame_reg_rtx) == 11) 20085 sp_offset += info->fp_size; 20086 } 20087 20088 par = rs6000_make_savres_rtx (info, frame_reg_rtx, 20089 info->gp_save_offset, reg_mode, 20090 /*savep=*/false, /*gpr=*/true, 20091 /*lr=*/can_use_exit); 20092 20093 if (can_use_exit) 20094 { 20095 if (info->cr_save_p) 20096 { 20097 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple); 20098 if (DEFAULT_ABI == ABI_V4) 20099 cfa_restores 20100 = alloc_reg_note (REG_CFA_RESTORE, 20101 gen_rtx_REG (SImode, CR2_REGNO), 20102 cfa_restores); 20103 } 20104 20105 emit_jump_insn (par); 20106 20107 /* We don't want anybody else emitting things after we jumped 20108 back. */ 20109 return; 20110 } 20111 20112 insn = emit_insn (par); 20113 if (DEFAULT_ABI == ABI_V4) 20114 { 20115 if (frame_pointer_needed) 20116 { 20117 add_reg_note (insn, REG_CFA_DEF_CFA, 20118 plus_constant (frame_reg_rtx, sp_offset)); 20119 RTX_FRAME_RELATED_P (insn) = 1; 20120 } 20121 20122 for (i = info->first_gp_reg_save; i < 32; i++) 20123 cfa_restores 20124 = alloc_reg_note (REG_CFA_RESTORE, 20125 gen_rtx_REG (reg_mode, i), cfa_restores); 20126 } 20127 } 20128 else if (using_load_multiple) 20129 { 20130 rtvec p; 20131 p = rtvec_alloc (32 - info->first_gp_reg_save); 20132 for (i = 0; i < 32 - info->first_gp_reg_save; i++) 20133 { 20134 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 20135 GEN_INT (info->gp_save_offset 20136 + sp_offset 20137 + reg_size * i)); 20138 rtx mem = gen_frame_mem (reg_mode, addr); 20139 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i); 20140 20141 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem); 20142 if (DEFAULT_ABI == ABI_V4) 20143 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, 20144 cfa_restores); 20145 } 20146 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); 20147 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed) 20148 { 20149 add_reg_note (insn, REG_CFA_DEF_CFA, 20150 plus_constant (frame_reg_rtx, sp_offset)); 20151 RTX_FRAME_RELATED_P (insn) = 1; 20152 } 20153 } 20154 else 20155 { 20156 for (i = 0; i < 32 - info->first_gp_reg_save; i++) 20157 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i)) 20158 { 20159 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 20160 GEN_INT (info->gp_save_offset 20161 + sp_offset 20162 + reg_size * i)); 20163 rtx mem = gen_frame_mem (reg_mode, addr); 20164 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i); 20165 20166 insn = emit_move_insn (reg, mem); 20167 if (DEFAULT_ABI == ABI_V4) 20168 { 20169 if (frame_pointer_needed 20170 && info->first_gp_reg_save + i 20171 == HARD_FRAME_POINTER_REGNUM) 20172 { 20173 add_reg_note (insn, REG_CFA_DEF_CFA, 20174 plus_constant (frame_reg_rtx, sp_offset)); 20175 RTX_FRAME_RELATED_P (insn) = 1; 20176 } 20177 20178 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, 20179 cfa_restores); 20180 } 20181 } 20182 } 20183 20184 if (restore_lr && !restoring_GPRs_inline) 20185 { 20186 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx, 20187 info->lr_save_offset + sp_offset); 20188 20189 emit_move_insn (gen_rtx_REG (Pmode, 0), mem); 20190 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), 20191 gen_rtx_REG (Pmode, 0)); 20192 } 20193 20194 /* Restore fpr's if we need to do it without calling a function. */ 20195 if (restoring_FPRs_inline) 20196 for (i = 0; i < 64 - info->first_fp_reg_save; i++) 20197 if ((df_regs_ever_live_p (info->first_fp_reg_save+i) 20198 && ! call_used_regs[info->first_fp_reg_save+i])) 20199 { 20200 rtx addr, mem, reg; 20201 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 20202 GEN_INT (info->fp_save_offset 20203 + sp_offset 20204 + 8 * i)); 20205 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) 20206 ? DFmode : SFmode), addr); 20207 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) 20208 ? DFmode : SFmode), 20209 info->first_fp_reg_save + i); 20210 20211 emit_move_insn (reg, mem); 20212 if (DEFAULT_ABI == ABI_V4) 20213 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, 20214 cfa_restores); 20215 } 20216 20217 /* If we saved cr, restore it here. Just those that were used. */ 20218 if (info->cr_save_p) 20219 { 20220 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple); 20221 if (DEFAULT_ABI == ABI_V4) 20222 cfa_restores 20223 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO), 20224 cfa_restores); 20225 } 20226 20227 /* If this is V.4, unwind the stack pointer after all of the loads 20228 have been done. */ 20229 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx, 20230 sp_offset, !restoring_FPRs_inline); 20231 if (insn) 20232 { 20233 if (cfa_restores) 20234 { 20235 REG_NOTES (insn) = cfa_restores; 20236 cfa_restores = NULL_RTX; 20237 } 20238 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx); 20239 RTX_FRAME_RELATED_P (insn) = 1; 20240 } 20241 20242 if (crtl->calls_eh_return) 20243 { 20244 rtx sa = EH_RETURN_STACKADJ_RTX; 20245 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa)); 20246 } 20247 20248 if (!sibcall) 20249 { 20250 rtvec p; 20251 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0; 20252 if (! restoring_FPRs_inline) 20253 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save); 20254 else 20255 p = rtvec_alloc (2); 20256 20257 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode); 20258 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr) 20259 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65)) 20260 : gen_rtx_CLOBBER (VOIDmode, 20261 gen_rtx_REG (Pmode, 65))); 20262 20263 /* If we have to restore more than two FP registers, branch to the 20264 restore function. It will return to our caller. */ 20265 if (! restoring_FPRs_inline) 20266 { 20267 int i; 20268 rtx sym; 20269 20270 sym = rs6000_savres_routine_sym (info, 20271 /*savep=*/false, 20272 /*gpr=*/false, 20273 /*lr=*/lr); 20274 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym); 20275 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode, 20276 gen_rtx_REG (Pmode, 20277 DEFAULT_ABI == ABI_AIX 20278 ? 1 : 11)); 20279 for (i = 0; i < 64 - info->first_fp_reg_save; i++) 20280 { 20281 rtx addr, mem; 20282 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx, 20283 GEN_INT (info->fp_save_offset + 8*i)); 20284 mem = gen_frame_mem (DFmode, addr); 20285 20286 RTVEC_ELT (p, i+4) = 20287 gen_rtx_SET (VOIDmode, 20288 gen_rtx_REG (DFmode, info->first_fp_reg_save + i), 20289 mem); 20290 } 20291 } 20292 20293 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p)); 20294 } 20295} 20296 20297/* Write function epilogue. */ 20298 20299static void 20300rs6000_output_function_epilogue (FILE *file, 20301 HOST_WIDE_INT size ATTRIBUTE_UNUSED) 20302{ 20303 if (! HAVE_epilogue) 20304 { 20305 rtx insn = get_last_insn (); 20306 /* If the last insn was a BARRIER, we don't have to write anything except 20307 the trace table. */ 20308 if (GET_CODE (insn) == NOTE) 20309 insn = prev_nonnote_insn (insn); 20310 if (insn == 0 || GET_CODE (insn) != BARRIER) 20311 { 20312 /* This is slightly ugly, but at least we don't have two 20313 copies of the epilogue-emitting code. */ 20314 start_sequence (); 20315 20316 /* A NOTE_INSN_DELETED is supposed to be at the start 20317 and end of the "toplevel" insn chain. */ 20318 emit_note (NOTE_INSN_DELETED); 20319 rs6000_emit_epilogue (FALSE); 20320 emit_note (NOTE_INSN_DELETED); 20321 20322 /* Expand INSN_ADDRESSES so final() doesn't crash. */ 20323 { 20324 rtx insn; 20325 unsigned addr = 0; 20326 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn)) 20327 { 20328 INSN_ADDRESSES_NEW (insn, addr); 20329 addr += 4; 20330 } 20331 } 20332 20333 if (TARGET_DEBUG_STACK) 20334 debug_rtx_list (get_insns (), 100); 20335 final (get_insns (), file, FALSE); 20336 end_sequence (); 20337 } 20338 } 20339 20340#if TARGET_MACHO 20341 macho_branch_islands (); 20342 /* Mach-O doesn't support labels at the end of objects, so if 20343 it looks like we might want one, insert a NOP. */ 20344 { 20345 rtx insn = get_last_insn (); 20346 while (insn 20347 && NOTE_P (insn) 20348 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL) 20349 insn = PREV_INSN (insn); 20350 if (insn 20351 && (LABEL_P (insn) 20352 || (NOTE_P (insn) 20353 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL))) 20354 fputs ("\tnop\n", file); 20355 } 20356#endif 20357 20358 /* Output a traceback table here. See /usr/include/sys/debug.h for info 20359 on its format. 20360 20361 We don't output a traceback table if -finhibit-size-directive was 20362 used. The documentation for -finhibit-size-directive reads 20363 ``don't output a @code{.size} assembler directive, or anything 20364 else that would cause trouble if the function is split in the 20365 middle, and the two halves are placed at locations far apart in 20366 memory.'' The traceback table has this property, since it 20367 includes the offset from the start of the function to the 20368 traceback table itself. 20369 20370 System V.4 Powerpc's (and the embedded ABI derived from it) use a 20371 different traceback table. */ 20372 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive 20373 && rs6000_traceback != traceback_none && !cfun->is_thunk) 20374 { 20375 const char *fname = NULL; 20376 const char *language_string = lang_hooks.name; 20377 int fixed_parms = 0, float_parms = 0, parm_info = 0; 20378 int i; 20379 int optional_tbtab; 20380 rs6000_stack_t *info = rs6000_stack_info (); 20381 20382 if (rs6000_traceback == traceback_full) 20383 optional_tbtab = 1; 20384 else if (rs6000_traceback == traceback_part) 20385 optional_tbtab = 0; 20386 else 20387 optional_tbtab = !optimize_size && !TARGET_ELF; 20388 20389 if (optional_tbtab) 20390 { 20391 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); 20392 while (*fname == '.') /* V.4 encodes . in the name */ 20393 fname++; 20394 20395 /* Need label immediately before tbtab, so we can compute 20396 its offset from the function start. */ 20397 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT"); 20398 ASM_OUTPUT_LABEL (file, fname); 20399 } 20400 20401 /* The .tbtab pseudo-op can only be used for the first eight 20402 expressions, since it can't handle the possibly variable 20403 length fields that follow. However, if you omit the optional 20404 fields, the assembler outputs zeros for all optional fields 20405 anyways, giving each variable length field is minimum length 20406 (as defined in sys/debug.h). Thus we can not use the .tbtab 20407 pseudo-op at all. */ 20408 20409 /* An all-zero word flags the start of the tbtab, for debuggers 20410 that have to find it by searching forward from the entry 20411 point or from the current pc. */ 20412 fputs ("\t.long 0\n", file); 20413 20414 /* Tbtab format type. Use format type 0. */ 20415 fputs ("\t.byte 0,", file); 20416 20417 /* Language type. Unfortunately, there does not seem to be any 20418 official way to discover the language being compiled, so we 20419 use language_string. 20420 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9. 20421 Java is 13. Objective-C is 14. Objective-C++ isn't assigned 20422 a number, so for now use 9. LTO isn't assigned a number either, 20423 so for now use 0. */ 20424 if (! strcmp (language_string, "GNU C") 20425 || ! strcmp (language_string, "GNU GIMPLE")) 20426 i = 0; 20427 else if (! strcmp (language_string, "GNU F77") 20428 || ! strcmp (language_string, "GNU Fortran")) 20429 i = 1; 20430 else if (! strcmp (language_string, "GNU Pascal")) 20431 i = 2; 20432 else if (! strcmp (language_string, "GNU Ada")) 20433 i = 3; 20434 else if (! strcmp (language_string, "GNU C++") 20435 || ! strcmp (language_string, "GNU Objective-C++")) 20436 i = 9; 20437 else if (! strcmp (language_string, "GNU Java")) 20438 i = 13; 20439 else if (! strcmp (language_string, "GNU Objective-C")) 20440 i = 14; 20441 else 20442 gcc_unreachable (); 20443 fprintf (file, "%d,", i); 20444 20445 /* 8 single bit fields: global linkage (not set for C extern linkage, 20446 apparently a PL/I convention?), out-of-line epilogue/prologue, offset 20447 from start of procedure stored in tbtab, internal function, function 20448 has controlled storage, function has no toc, function uses fp, 20449 function logs/aborts fp operations. */ 20450 /* Assume that fp operations are used if any fp reg must be saved. */ 20451 fprintf (file, "%d,", 20452 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1)); 20453 20454 /* 6 bitfields: function is interrupt handler, name present in 20455 proc table, function calls alloca, on condition directives 20456 (controls stack walks, 3 bits), saves condition reg, saves 20457 link reg. */ 20458 /* The `function calls alloca' bit seems to be set whenever reg 31 is 20459 set up as a frame pointer, even when there is no alloca call. */ 20460 fprintf (file, "%d,", 20461 ((optional_tbtab << 6) 20462 | ((optional_tbtab & frame_pointer_needed) << 5) 20463 | (info->cr_save_p << 1) 20464 | (info->lr_save_p))); 20465 20466 /* 3 bitfields: saves backchain, fixup code, number of fpr saved 20467 (6 bits). */ 20468 fprintf (file, "%d,", 20469 (info->push_p << 7) | (64 - info->first_fp_reg_save)); 20470 20471 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */ 20472 fprintf (file, "%d,", (32 - first_reg_to_save ())); 20473 20474 if (optional_tbtab) 20475 { 20476 /* Compute the parameter info from the function decl argument 20477 list. */ 20478 tree decl; 20479 int next_parm_info_bit = 31; 20480 20481 for (decl = DECL_ARGUMENTS (current_function_decl); 20482 decl; decl = TREE_CHAIN (decl)) 20483 { 20484 rtx parameter = DECL_INCOMING_RTL (decl); 20485 enum machine_mode mode = GET_MODE (parameter); 20486 20487 if (GET_CODE (parameter) == REG) 20488 { 20489 if (SCALAR_FLOAT_MODE_P (mode)) 20490 { 20491 int bits; 20492 20493 float_parms++; 20494 20495 switch (mode) 20496 { 20497 case SFmode: 20498 case SDmode: 20499 bits = 0x2; 20500 break; 20501 20502 case DFmode: 20503 case DDmode: 20504 case TFmode: 20505 case TDmode: 20506 bits = 0x3; 20507 break; 20508 20509 default: 20510 gcc_unreachable (); 20511 } 20512 20513 /* If only one bit will fit, don't or in this entry. */ 20514 if (next_parm_info_bit > 0) 20515 parm_info |= (bits << (next_parm_info_bit - 1)); 20516 next_parm_info_bit -= 2; 20517 } 20518 else 20519 { 20520 fixed_parms += ((GET_MODE_SIZE (mode) 20521 + (UNITS_PER_WORD - 1)) 20522 / UNITS_PER_WORD); 20523 next_parm_info_bit -= 1; 20524 } 20525 } 20526 } 20527 } 20528 20529 /* Number of fixed point parameters. */ 20530 /* This is actually the number of words of fixed point parameters; thus 20531 an 8 byte struct counts as 2; and thus the maximum value is 8. */ 20532 fprintf (file, "%d,", fixed_parms); 20533 20534 /* 2 bitfields: number of floating point parameters (7 bits), parameters 20535 all on stack. */ 20536 /* This is actually the number of fp registers that hold parameters; 20537 and thus the maximum value is 13. */ 20538 /* Set parameters on stack bit if parameters are not in their original 20539 registers, regardless of whether they are on the stack? Xlc 20540 seems to set the bit when not optimizing. */ 20541 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize))); 20542 20543 if (! optional_tbtab) 20544 return; 20545 20546 /* Optional fields follow. Some are variable length. */ 20547 20548 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float, 20549 11 double float. */ 20550 /* There is an entry for each parameter in a register, in the order that 20551 they occur in the parameter list. Any intervening arguments on the 20552 stack are ignored. If the list overflows a long (max possible length 20553 34 bits) then completely leave off all elements that don't fit. */ 20554 /* Only emit this long if there was at least one parameter. */ 20555 if (fixed_parms || float_parms) 20556 fprintf (file, "\t.long %d\n", parm_info); 20557 20558 /* Offset from start of code to tb table. */ 20559 fputs ("\t.long ", file); 20560 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT"); 20561 if (TARGET_AIX) 20562 RS6000_OUTPUT_BASENAME (file, fname); 20563 else 20564 assemble_name (file, fname); 20565 putc ('-', file); 20566 rs6000_output_function_entry (file, fname); 20567 putc ('\n', file); 20568 20569 /* Interrupt handler mask. */ 20570 /* Omit this long, since we never set the interrupt handler bit 20571 above. */ 20572 20573 /* Number of CTL (controlled storage) anchors. */ 20574 /* Omit this long, since the has_ctl bit is never set above. */ 20575 20576 /* Displacement into stack of each CTL anchor. */ 20577 /* Omit this list of longs, because there are no CTL anchors. */ 20578 20579 /* Length of function name. */ 20580 if (*fname == '*') 20581 ++fname; 20582 fprintf (file, "\t.short %d\n", (int) strlen (fname)); 20583 20584 /* Function name. */ 20585 assemble_string (fname, strlen (fname)); 20586 20587 /* Register for alloca automatic storage; this is always reg 31. 20588 Only emit this if the alloca bit was set above. */ 20589 if (frame_pointer_needed) 20590 fputs ("\t.byte 31\n", file); 20591 20592 fputs ("\t.align 2\n", file); 20593 } 20594} 20595 20596/* A C compound statement that outputs the assembler code for a thunk 20597 function, used to implement C++ virtual function calls with 20598 multiple inheritance. The thunk acts as a wrapper around a virtual 20599 function, adjusting the implicit object parameter before handing 20600 control off to the real function. 20601 20602 First, emit code to add the integer DELTA to the location that 20603 contains the incoming first argument. Assume that this argument 20604 contains a pointer, and is the one used to pass the `this' pointer 20605 in C++. This is the incoming argument *before* the function 20606 prologue, e.g. `%o0' on a sparc. The addition must preserve the 20607 values of all other incoming arguments. 20608 20609 After the addition, emit code to jump to FUNCTION, which is a 20610 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does 20611 not touch the return address. Hence returning from FUNCTION will 20612 return to whoever called the current `thunk'. 20613 20614 The effect must be as if FUNCTION had been called directly with the 20615 adjusted first argument. This macro is responsible for emitting 20616 all of the code for a thunk function; output_function_prologue() 20617 and output_function_epilogue() are not invoked. 20618 20619 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already 20620 been extracted from it.) It might possibly be useful on some 20621 targets, but probably not. 20622 20623 If you do not define this macro, the target-independent code in the 20624 C++ frontend will generate a less efficient heavyweight thunk that 20625 calls FUNCTION instead of jumping to it. The generic approach does 20626 not support varargs. */ 20627 20628static void 20629rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, 20630 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset, 20631 tree function) 20632{ 20633 rtx this_rtx, insn, funexp; 20634 20635 reload_completed = 1; 20636 epilogue_completed = 1; 20637 20638 /* Mark the end of the (empty) prologue. */ 20639 emit_note (NOTE_INSN_PROLOGUE_END); 20640 20641 /* Find the "this" pointer. If the function returns a structure, 20642 the structure return pointer is in r3. */ 20643 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function)) 20644 this_rtx = gen_rtx_REG (Pmode, 4); 20645 else 20646 this_rtx = gen_rtx_REG (Pmode, 3); 20647 20648 /* Apply the constant offset, if required. */ 20649 if (delta) 20650 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta))); 20651 20652 /* Apply the offset from the vtable, if required. */ 20653 if (vcall_offset) 20654 { 20655 rtx vcall_offset_rtx = GEN_INT (vcall_offset); 20656 rtx tmp = gen_rtx_REG (Pmode, 12); 20657 20658 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx)); 20659 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000) 20660 { 20661 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx)); 20662 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp)); 20663 } 20664 else 20665 { 20666 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx); 20667 20668 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc)); 20669 } 20670 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp)); 20671 } 20672 20673 /* Generate a tail call to the target function. */ 20674 if (!TREE_USED (function)) 20675 { 20676 assemble_external (function); 20677 TREE_USED (function) = 1; 20678 } 20679 funexp = XEXP (DECL_RTL (function), 0); 20680 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp); 20681 20682#if TARGET_MACHO 20683 if (MACHOPIC_INDIRECT) 20684 funexp = machopic_indirect_call_target (funexp); 20685#endif 20686 20687 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must 20688 generate sibcall RTL explicitly. */ 20689 insn = emit_call_insn ( 20690 gen_rtx_PARALLEL (VOIDmode, 20691 gen_rtvec (4, 20692 gen_rtx_CALL (VOIDmode, 20693 funexp, const0_rtx), 20694 gen_rtx_USE (VOIDmode, const0_rtx), 20695 gen_rtx_USE (VOIDmode, 20696 gen_rtx_REG (SImode, 20697 LR_REGNO)), 20698 gen_rtx_RETURN (VOIDmode)))); 20699 SIBLING_CALL_P (insn) = 1; 20700 emit_barrier (); 20701 20702 /* Run just enough of rest_of_compilation to get the insns emitted. 20703 There's not really enough bulk here to make other passes such as 20704 instruction scheduling worth while. Note that use_thunk calls 20705 assemble_start_function and assemble_end_function. */ 20706 insn = get_insns (); 20707 insn_locators_alloc (); 20708 shorten_branches (insn); 20709 final_start_function (insn, file, 1); 20710 final (insn, file, 1); 20711 final_end_function (); 20712 20713 reload_completed = 0; 20714 epilogue_completed = 0; 20715} 20716 20717/* A quick summary of the various types of 'constant-pool tables' 20718 under PowerPC: 20719 20720 Target Flags Name One table per 20721 AIX (none) AIX TOC object file 20722 AIX -mfull-toc AIX TOC object file 20723 AIX -mminimal-toc AIX minimal TOC translation unit 20724 SVR4/EABI (none) SVR4 SDATA object file 20725 SVR4/EABI -fpic SVR4 pic object file 20726 SVR4/EABI -fPIC SVR4 PIC translation unit 20727 SVR4/EABI -mrelocatable EABI TOC function 20728 SVR4/EABI -maix AIX TOC object file 20729 SVR4/EABI -maix -mminimal-toc 20730 AIX minimal TOC translation unit 20731 20732 Name Reg. Set by entries contains: 20733 made by addrs? fp? sum? 20734 20735 AIX TOC 2 crt0 as Y option option 20736 AIX minimal TOC 30 prolog gcc Y Y option 20737 SVR4 SDATA 13 crt0 gcc N Y N 20738 SVR4 pic 30 prolog ld Y not yet N 20739 SVR4 PIC 30 prolog gcc Y option option 20740 EABI TOC 30 prolog gcc Y option option 20741 20742*/ 20743 20744/* Hash functions for the hash table. */ 20745 20746static unsigned 20747rs6000_hash_constant (rtx k) 20748{ 20749 enum rtx_code code = GET_CODE (k); 20750 enum machine_mode mode = GET_MODE (k); 20751 unsigned result = (code << 3) ^ mode; 20752 const char *format; 20753 int flen, fidx; 20754 20755 format = GET_RTX_FORMAT (code); 20756 flen = strlen (format); 20757 fidx = 0; 20758 20759 switch (code) 20760 { 20761 case LABEL_REF: 20762 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0)); 20763 20764 case CONST_DOUBLE: 20765 if (mode != VOIDmode) 20766 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result; 20767 flen = 2; 20768 break; 20769 20770 case CODE_LABEL: 20771 fidx = 3; 20772 break; 20773 20774 default: 20775 break; 20776 } 20777 20778 for (; fidx < flen; fidx++) 20779 switch (format[fidx]) 20780 { 20781 case 's': 20782 { 20783 unsigned i, len; 20784 const char *str = XSTR (k, fidx); 20785 len = strlen (str); 20786 result = result * 613 + len; 20787 for (i = 0; i < len; i++) 20788 result = result * 613 + (unsigned) str[i]; 20789 break; 20790 } 20791 case 'u': 20792 case 'e': 20793 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx)); 20794 break; 20795 case 'i': 20796 case 'n': 20797 result = result * 613 + (unsigned) XINT (k, fidx); 20798 break; 20799 case 'w': 20800 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT)) 20801 result = result * 613 + (unsigned) XWINT (k, fidx); 20802 else 20803 { 20804 size_t i; 20805 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++) 20806 result = result * 613 + (unsigned) (XWINT (k, fidx) 20807 >> CHAR_BIT * i); 20808 } 20809 break; 20810 case '0': 20811 break; 20812 default: 20813 gcc_unreachable (); 20814 } 20815 20816 return result; 20817} 20818 20819static unsigned 20820toc_hash_function (const void *hash_entry) 20821{ 20822 const struct toc_hash_struct *thc = 20823 (const struct toc_hash_struct *) hash_entry; 20824 return rs6000_hash_constant (thc->key) ^ thc->key_mode; 20825} 20826 20827/* Compare H1 and H2 for equivalence. */ 20828 20829static int 20830toc_hash_eq (const void *h1, const void *h2) 20831{ 20832 rtx r1 = ((const struct toc_hash_struct *) h1)->key; 20833 rtx r2 = ((const struct toc_hash_struct *) h2)->key; 20834 20835 if (((const struct toc_hash_struct *) h1)->key_mode 20836 != ((const struct toc_hash_struct *) h2)->key_mode) 20837 return 0; 20838 20839 return rtx_equal_p (r1, r2); 20840} 20841 20842/* These are the names given by the C++ front-end to vtables, and 20843 vtable-like objects. Ideally, this logic should not be here; 20844 instead, there should be some programmatic way of inquiring as 20845 to whether or not an object is a vtable. */ 20846 20847#define VTABLE_NAME_P(NAME) \ 20848 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \ 20849 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \ 20850 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \ 20851 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \ 20852 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0) 20853 20854#ifdef NO_DOLLAR_IN_LABEL 20855/* Return a GGC-allocated character string translating dollar signs in 20856 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */ 20857 20858const char * 20859rs6000_xcoff_strip_dollar (const char *name) 20860{ 20861 char *strip, *p; 20862 int len; 20863 20864 p = strchr (name, '$'); 20865 20866 if (p == 0 || p == name) 20867 return name; 20868 20869 len = strlen (name); 20870 strip = (char *) alloca (len + 1); 20871 strcpy (strip, name); 20872 p = strchr (strip, '$'); 20873 while (p) 20874 { 20875 *p = '_'; 20876 p = strchr (p + 1, '$'); 20877 } 20878 20879 return ggc_alloc_string (strip, len); 20880} 20881#endif 20882 20883void 20884rs6000_output_symbol_ref (FILE *file, rtx x) 20885{ 20886 /* Currently C++ toc references to vtables can be emitted before it 20887 is decided whether the vtable is public or private. If this is 20888 the case, then the linker will eventually complain that there is 20889 a reference to an unknown section. Thus, for vtables only, 20890 we emit the TOC reference to reference the symbol and not the 20891 section. */ 20892 const char *name = XSTR (x, 0); 20893 20894 if (VTABLE_NAME_P (name)) 20895 { 20896 RS6000_OUTPUT_BASENAME (file, name); 20897 } 20898 else 20899 assemble_name (file, name); 20900} 20901 20902/* Output a TOC entry. We derive the entry name from what is being 20903 written. */ 20904 20905void 20906output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode) 20907{ 20908 char buf[256]; 20909 const char *name = buf; 20910 rtx base = x; 20911 HOST_WIDE_INT offset = 0; 20912 20913 gcc_assert (!TARGET_NO_TOC); 20914 20915 /* When the linker won't eliminate them, don't output duplicate 20916 TOC entries (this happens on AIX if there is any kind of TOC, 20917 and on SVR4 under -fPIC or -mrelocatable). Don't do this for 20918 CODE_LABELs. */ 20919 if (TARGET_TOC && GET_CODE (x) != LABEL_REF) 20920 { 20921 struct toc_hash_struct *h; 20922 void * * found; 20923 20924 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS 20925 time because GGC is not initialized at that point. */ 20926 if (toc_hash_table == NULL) 20927 toc_hash_table = htab_create_ggc (1021, toc_hash_function, 20928 toc_hash_eq, NULL); 20929 20930 h = GGC_NEW (struct toc_hash_struct); 20931 h->key = x; 20932 h->key_mode = mode; 20933 h->labelno = labelno; 20934 20935 found = htab_find_slot (toc_hash_table, h, INSERT); 20936 if (*found == NULL) 20937 *found = h; 20938 else /* This is indeed a duplicate. 20939 Set this label equal to that label. */ 20940 { 20941 fputs ("\t.set ", file); 20942 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC"); 20943 fprintf (file, "%d,", labelno); 20944 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC"); 20945 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **) 20946 found)->labelno)); 20947 return; 20948 } 20949 } 20950 20951 /* If we're going to put a double constant in the TOC, make sure it's 20952 aligned properly when strict alignment is on. */ 20953 if (GET_CODE (x) == CONST_DOUBLE 20954 && STRICT_ALIGNMENT 20955 && GET_MODE_BITSIZE (mode) >= 64 20956 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) { 20957 ASM_OUTPUT_ALIGN (file, 3); 20958 } 20959 20960 (*targetm.asm_out.internal_label) (file, "LC", labelno); 20961 20962 /* Handle FP constants specially. Note that if we have a minimal 20963 TOC, things we put here aren't actually in the TOC, so we can allow 20964 FP constants. */ 20965 if (GET_CODE (x) == CONST_DOUBLE && 20966 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode)) 20967 { 20968 REAL_VALUE_TYPE rv; 20969 long k[4]; 20970 20971 REAL_VALUE_FROM_CONST_DOUBLE (rv, x); 20972 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x))) 20973 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k); 20974 else 20975 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k); 20976 20977 if (TARGET_64BIT) 20978 { 20979 if (TARGET_MINIMAL_TOC) 20980 fputs (DOUBLE_INT_ASM_OP, file); 20981 else 20982 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],", 20983 k[0] & 0xffffffff, k[1] & 0xffffffff, 20984 k[2] & 0xffffffff, k[3] & 0xffffffff); 20985 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n", 20986 k[0] & 0xffffffff, k[1] & 0xffffffff, 20987 k[2] & 0xffffffff, k[3] & 0xffffffff); 20988 return; 20989 } 20990 else 20991 { 20992 if (TARGET_MINIMAL_TOC) 20993 fputs ("\t.long ", file); 20994 else 20995 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],", 20996 k[0] & 0xffffffff, k[1] & 0xffffffff, 20997 k[2] & 0xffffffff, k[3] & 0xffffffff); 20998 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n", 20999 k[0] & 0xffffffff, k[1] & 0xffffffff, 21000 k[2] & 0xffffffff, k[3] & 0xffffffff); 21001 return; 21002 } 21003 } 21004 else if (GET_CODE (x) == CONST_DOUBLE && 21005 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode)) 21006 { 21007 REAL_VALUE_TYPE rv; 21008 long k[2]; 21009 21010 REAL_VALUE_FROM_CONST_DOUBLE (rv, x); 21011 21012 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x))) 21013 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k); 21014 else 21015 REAL_VALUE_TO_TARGET_DOUBLE (rv, k); 21016 21017 if (TARGET_64BIT) 21018 { 21019 if (TARGET_MINIMAL_TOC) 21020 fputs (DOUBLE_INT_ASM_OP, file); 21021 else 21022 fprintf (file, "\t.tc FD_%lx_%lx[TC],", 21023 k[0] & 0xffffffff, k[1] & 0xffffffff); 21024 fprintf (file, "0x%lx%08lx\n", 21025 k[0] & 0xffffffff, k[1] & 0xffffffff); 21026 return; 21027 } 21028 else 21029 { 21030 if (TARGET_MINIMAL_TOC) 21031 fputs ("\t.long ", file); 21032 else 21033 fprintf (file, "\t.tc FD_%lx_%lx[TC],", 21034 k[0] & 0xffffffff, k[1] & 0xffffffff); 21035 fprintf (file, "0x%lx,0x%lx\n", 21036 k[0] & 0xffffffff, k[1] & 0xffffffff); 21037 return; 21038 } 21039 } 21040 else if (GET_CODE (x) == CONST_DOUBLE && 21041 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode)) 21042 { 21043 REAL_VALUE_TYPE rv; 21044 long l; 21045 21046 REAL_VALUE_FROM_CONST_DOUBLE (rv, x); 21047 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x))) 21048 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l); 21049 else 21050 REAL_VALUE_TO_TARGET_SINGLE (rv, l); 21051 21052 if (TARGET_64BIT) 21053 { 21054 if (TARGET_MINIMAL_TOC) 21055 fputs (DOUBLE_INT_ASM_OP, file); 21056 else 21057 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff); 21058 fprintf (file, "0x%lx00000000\n", l & 0xffffffff); 21059 return; 21060 } 21061 else 21062 { 21063 if (TARGET_MINIMAL_TOC) 21064 fputs ("\t.long ", file); 21065 else 21066 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff); 21067 fprintf (file, "0x%lx\n", l & 0xffffffff); 21068 return; 21069 } 21070 } 21071 else if (GET_MODE (x) == VOIDmode 21072 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)) 21073 { 21074 unsigned HOST_WIDE_INT low; 21075 HOST_WIDE_INT high; 21076 21077 if (GET_CODE (x) == CONST_DOUBLE) 21078 { 21079 low = CONST_DOUBLE_LOW (x); 21080 high = CONST_DOUBLE_HIGH (x); 21081 } 21082 else 21083#if HOST_BITS_PER_WIDE_INT == 32 21084 { 21085 low = INTVAL (x); 21086 high = (low & 0x80000000) ? ~0 : 0; 21087 } 21088#else 21089 { 21090 low = INTVAL (x) & 0xffffffff; 21091 high = (HOST_WIDE_INT) INTVAL (x) >> 32; 21092 } 21093#endif 21094 21095 /* TOC entries are always Pmode-sized, but since this 21096 is a bigendian machine then if we're putting smaller 21097 integer constants in the TOC we have to pad them. 21098 (This is still a win over putting the constants in 21099 a separate constant pool, because then we'd have 21100 to have both a TOC entry _and_ the actual constant.) 21101 21102 For a 32-bit target, CONST_INT values are loaded and shifted 21103 entirely within `low' and can be stored in one TOC entry. */ 21104 21105 /* It would be easy to make this work, but it doesn't now. */ 21106 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode)); 21107 21108 if (POINTER_SIZE > GET_MODE_BITSIZE (mode)) 21109 { 21110#if HOST_BITS_PER_WIDE_INT == 32 21111 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode), 21112 POINTER_SIZE, &low, &high, 0); 21113#else 21114 low |= high << 32; 21115 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode); 21116 high = (HOST_WIDE_INT) low >> 32; 21117 low &= 0xffffffff; 21118#endif 21119 } 21120 21121 if (TARGET_64BIT) 21122 { 21123 if (TARGET_MINIMAL_TOC) 21124 fputs (DOUBLE_INT_ASM_OP, file); 21125 else 21126 fprintf (file, "\t.tc ID_%lx_%lx[TC],", 21127 (long) high & 0xffffffff, (long) low & 0xffffffff); 21128 fprintf (file, "0x%lx%08lx\n", 21129 (long) high & 0xffffffff, (long) low & 0xffffffff); 21130 return; 21131 } 21132 else 21133 { 21134 if (POINTER_SIZE < GET_MODE_BITSIZE (mode)) 21135 { 21136 if (TARGET_MINIMAL_TOC) 21137 fputs ("\t.long ", file); 21138 else 21139 fprintf (file, "\t.tc ID_%lx_%lx[TC],", 21140 (long) high & 0xffffffff, (long) low & 0xffffffff); 21141 fprintf (file, "0x%lx,0x%lx\n", 21142 (long) high & 0xffffffff, (long) low & 0xffffffff); 21143 } 21144 else 21145 { 21146 if (TARGET_MINIMAL_TOC) 21147 fputs ("\t.long ", file); 21148 else 21149 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff); 21150 fprintf (file, "0x%lx\n", (long) low & 0xffffffff); 21151 } 21152 return; 21153 } 21154 } 21155 21156 if (GET_CODE (x) == CONST) 21157 { 21158 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS 21159 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT); 21160 21161 base = XEXP (XEXP (x, 0), 0); 21162 offset = INTVAL (XEXP (XEXP (x, 0), 1)); 21163 } 21164 21165 switch (GET_CODE (base)) 21166 { 21167 case SYMBOL_REF: 21168 name = XSTR (base, 0); 21169 break; 21170 21171 case LABEL_REF: 21172 ASM_GENERATE_INTERNAL_LABEL (buf, "L", 21173 CODE_LABEL_NUMBER (XEXP (base, 0))); 21174 break; 21175 21176 case CODE_LABEL: 21177 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base)); 21178 break; 21179 21180 default: 21181 gcc_unreachable (); 21182 } 21183 21184 if (TARGET_MINIMAL_TOC) 21185 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file); 21186 else 21187 { 21188 fputs ("\t.tc ", file); 21189 RS6000_OUTPUT_BASENAME (file, name); 21190 21191 if (offset < 0) 21192 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset); 21193 else if (offset) 21194 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset); 21195 21196 fputs ("[TC],", file); 21197 } 21198 21199 /* Currently C++ toc references to vtables can be emitted before it 21200 is decided whether the vtable is public or private. If this is 21201 the case, then the linker will eventually complain that there is 21202 a TOC reference to an unknown section. Thus, for vtables only, 21203 we emit the TOC reference to reference the symbol and not the 21204 section. */ 21205 if (VTABLE_NAME_P (name)) 21206 { 21207 RS6000_OUTPUT_BASENAME (file, name); 21208 if (offset < 0) 21209 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset); 21210 else if (offset > 0) 21211 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset); 21212 } 21213 else 21214 output_addr_const (file, x); 21215 putc ('\n', file); 21216} 21217 21218/* Output an assembler pseudo-op to write an ASCII string of N characters 21219 starting at P to FILE. 21220 21221 On the RS/6000, we have to do this using the .byte operation and 21222 write out special characters outside the quoted string. 21223 Also, the assembler is broken; very long strings are truncated, 21224 so we must artificially break them up early. */ 21225 21226void 21227output_ascii (FILE *file, const char *p, int n) 21228{ 21229 char c; 21230 int i, count_string; 21231 const char *for_string = "\t.byte \""; 21232 const char *for_decimal = "\t.byte "; 21233 const char *to_close = NULL; 21234 21235 count_string = 0; 21236 for (i = 0; i < n; i++) 21237 { 21238 c = *p++; 21239 if (c >= ' ' && c < 0177) 21240 { 21241 if (for_string) 21242 fputs (for_string, file); 21243 putc (c, file); 21244 21245 /* Write two quotes to get one. */ 21246 if (c == '"') 21247 { 21248 putc (c, file); 21249 ++count_string; 21250 } 21251 21252 for_string = NULL; 21253 for_decimal = "\"\n\t.byte "; 21254 to_close = "\"\n"; 21255 ++count_string; 21256 21257 if (count_string >= 512) 21258 { 21259 fputs (to_close, file); 21260 21261 for_string = "\t.byte \""; 21262 for_decimal = "\t.byte "; 21263 to_close = NULL; 21264 count_string = 0; 21265 } 21266 } 21267 else 21268 { 21269 if (for_decimal) 21270 fputs (for_decimal, file); 21271 fprintf (file, "%d", c); 21272 21273 for_string = "\n\t.byte \""; 21274 for_decimal = ", "; 21275 to_close = "\n"; 21276 count_string = 0; 21277 } 21278 } 21279 21280 /* Now close the string if we have written one. Then end the line. */ 21281 if (to_close) 21282 fputs (to_close, file); 21283} 21284 21285/* Generate a unique section name for FILENAME for a section type 21286 represented by SECTION_DESC. Output goes into BUF. 21287 21288 SECTION_DESC can be any string, as long as it is different for each 21289 possible section type. 21290 21291 We name the section in the same manner as xlc. The name begins with an 21292 underscore followed by the filename (after stripping any leading directory 21293 names) with the last period replaced by the string SECTION_DESC. If 21294 FILENAME does not contain a period, SECTION_DESC is appended to the end of 21295 the name. */ 21296 21297void 21298rs6000_gen_section_name (char **buf, const char *filename, 21299 const char *section_desc) 21300{ 21301 const char *q, *after_last_slash, *last_period = 0; 21302 char *p; 21303 int len; 21304 21305 after_last_slash = filename; 21306 for (q = filename; *q; q++) 21307 { 21308 if (*q == '/') 21309 after_last_slash = q + 1; 21310 else if (*q == '.') 21311 last_period = q; 21312 } 21313 21314 len = strlen (after_last_slash) + strlen (section_desc) + 2; 21315 *buf = (char *) xmalloc (len); 21316 21317 p = *buf; 21318 *p++ = '_'; 21319 21320 for (q = after_last_slash; *q; q++) 21321 { 21322 if (q == last_period) 21323 { 21324 strcpy (p, section_desc); 21325 p += strlen (section_desc); 21326 break; 21327 } 21328 21329 else if (ISALNUM (*q)) 21330 *p++ = *q; 21331 } 21332 21333 if (last_period == 0) 21334 strcpy (p, section_desc); 21335 else 21336 *p = '\0'; 21337} 21338 21339/* Emit profile function. */ 21340 21341void 21342output_profile_hook (int labelno ATTRIBUTE_UNUSED) 21343{ 21344 /* Non-standard profiling for kernels, which just saves LR then calls 21345 _mcount without worrying about arg saves. The idea is to change 21346 the function prologue as little as possible as it isn't easy to 21347 account for arg save/restore code added just for _mcount. */ 21348 if (TARGET_PROFILE_KERNEL) 21349 return; 21350 21351 if (DEFAULT_ABI == ABI_AIX) 21352 { 21353#ifndef NO_PROFILE_COUNTERS 21354# define NO_PROFILE_COUNTERS 0 21355#endif 21356 if (NO_PROFILE_COUNTERS) 21357 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 21358 LCT_NORMAL, VOIDmode, 0); 21359 else 21360 { 21361 char buf[30]; 21362 const char *label_name; 21363 rtx fun; 21364 21365 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno); 21366 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf)); 21367 fun = gen_rtx_SYMBOL_REF (Pmode, label_name); 21368 21369 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 21370 LCT_NORMAL, VOIDmode, 1, fun, Pmode); 21371 } 21372 } 21373 else if (DEFAULT_ABI == ABI_DARWIN) 21374 { 21375 const char *mcount_name = RS6000_MCOUNT; 21376 int caller_addr_regno = LR_REGNO; 21377 21378 /* Be conservative and always set this, at least for now. */ 21379 crtl->uses_pic_offset_table = 1; 21380 21381#if TARGET_MACHO 21382 /* For PIC code, set up a stub and collect the caller's address 21383 from r0, which is where the prologue puts it. */ 21384 if (MACHOPIC_INDIRECT 21385 && crtl->uses_pic_offset_table) 21386 caller_addr_regno = 0; 21387#endif 21388 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name), 21389 LCT_NORMAL, VOIDmode, 1, 21390 gen_rtx_REG (Pmode, caller_addr_regno), Pmode); 21391 } 21392} 21393 21394/* Write function profiler code. */ 21395 21396void 21397output_function_profiler (FILE *file, int labelno) 21398{ 21399 char buf[100]; 21400 21401 switch (DEFAULT_ABI) 21402 { 21403 default: 21404 gcc_unreachable (); 21405 21406 case ABI_V4: 21407 if (!TARGET_32BIT) 21408 { 21409 warning (0, "no profiling of 64-bit code for this ABI"); 21410 return; 21411 } 21412 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno); 21413 fprintf (file, "\tmflr %s\n", reg_names[0]); 21414 if (NO_PROFILE_COUNTERS) 21415 { 21416 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n", 21417 reg_names[0], reg_names[1]); 21418 } 21419 else if (TARGET_SECURE_PLT && flag_pic) 21420 { 21421 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n", 21422 reg_names[0], reg_names[1]); 21423 asm_fprintf (file, "\tmflr %s\n", reg_names[12]); 21424 asm_fprintf (file, "\t{cau|addis} %s,%s,", 21425 reg_names[12], reg_names[12]); 21426 assemble_name (file, buf); 21427 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]); 21428 assemble_name (file, buf); 21429 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]); 21430 } 21431 else if (flag_pic == 1) 21432 { 21433 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file); 21434 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n", 21435 reg_names[0], reg_names[1]); 21436 asm_fprintf (file, "\tmflr %s\n", reg_names[12]); 21437 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]); 21438 assemble_name (file, buf); 21439 asm_fprintf (file, "@got(%s)\n", reg_names[12]); 21440 } 21441 else if (flag_pic > 1) 21442 { 21443 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n", 21444 reg_names[0], reg_names[1]); 21445 /* Now, we need to get the address of the label. */ 21446 fputs ("\tbcl 20,31,1f\n\t.long ", file); 21447 assemble_name (file, buf); 21448 fputs ("-.\n1:", file); 21449 asm_fprintf (file, "\tmflr %s\n", reg_names[11]); 21450 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n", 21451 reg_names[0], reg_names[11]); 21452 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n", 21453 reg_names[0], reg_names[0], reg_names[11]); 21454 } 21455 else 21456 { 21457 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]); 21458 assemble_name (file, buf); 21459 fputs ("@ha\n", file); 21460 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n", 21461 reg_names[0], reg_names[1]); 21462 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]); 21463 assemble_name (file, buf); 21464 asm_fprintf (file, "@l(%s)\n", reg_names[12]); 21465 } 21466 21467 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */ 21468 fprintf (file, "\tbl %s%s\n", 21469 RS6000_MCOUNT, flag_pic ? "@plt" : ""); 21470 break; 21471 21472 case ABI_AIX: 21473 case ABI_DARWIN: 21474 if (!TARGET_PROFILE_KERNEL) 21475 { 21476 /* Don't do anything, done in output_profile_hook (). */ 21477 } 21478 else 21479 { 21480 gcc_assert (!TARGET_32BIT); 21481 21482 asm_fprintf (file, "\tmflr %s\n", reg_names[0]); 21483 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]); 21484 21485 if (cfun->static_chain_decl != NULL) 21486 { 21487 asm_fprintf (file, "\tstd %s,24(%s)\n", 21488 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]); 21489 fprintf (file, "\tbl %s\n", RS6000_MCOUNT); 21490 asm_fprintf (file, "\tld %s,24(%s)\n", 21491 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]); 21492 } 21493 else 21494 fprintf (file, "\tbl %s\n", RS6000_MCOUNT); 21495 } 21496 break; 21497 } 21498} 21499 21500 21501 21502/* The following variable value is the last issued insn. */ 21503 21504static rtx last_scheduled_insn; 21505 21506/* The following variable helps to balance issuing of load and 21507 store instructions */ 21508 21509static int load_store_pendulum; 21510 21511/* Power4 load update and store update instructions are cracked into a 21512 load or store and an integer insn which are executed in the same cycle. 21513 Branches have their own dispatch slot which does not count against the 21514 GCC issue rate, but it changes the program flow so there are no other 21515 instructions to issue in this cycle. */ 21516 21517static int 21518rs6000_variable_issue_1 (rtx insn, int more) 21519{ 21520 last_scheduled_insn = insn; 21521 if (GET_CODE (PATTERN (insn)) == USE 21522 || GET_CODE (PATTERN (insn)) == CLOBBER) 21523 { 21524 cached_can_issue_more = more; 21525 return cached_can_issue_more; 21526 } 21527 21528 if (insn_terminates_group_p (insn, current_group)) 21529 { 21530 cached_can_issue_more = 0; 21531 return cached_can_issue_more; 21532 } 21533 21534 /* If no reservation, but reach here */ 21535 if (recog_memoized (insn) < 0) 21536 return more; 21537 21538 if (rs6000_sched_groups) 21539 { 21540 if (is_microcoded_insn (insn)) 21541 cached_can_issue_more = 0; 21542 else if (is_cracked_insn (insn)) 21543 cached_can_issue_more = more > 2 ? more - 2 : 0; 21544 else 21545 cached_can_issue_more = more - 1; 21546 21547 return cached_can_issue_more; 21548 } 21549 21550 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn)) 21551 return 0; 21552 21553 cached_can_issue_more = more - 1; 21554 return cached_can_issue_more; 21555} 21556 21557static int 21558rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more) 21559{ 21560 int r = rs6000_variable_issue_1 (insn, more); 21561 if (verbose) 21562 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r); 21563 return r; 21564} 21565 21566/* Adjust the cost of a scheduling dependency. Return the new cost of 21567 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */ 21568 21569static int 21570rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost) 21571{ 21572 enum attr_type attr_type; 21573 21574 if (! recog_memoized (insn)) 21575 return 0; 21576 21577 switch (REG_NOTE_KIND (link)) 21578 { 21579 case REG_DEP_TRUE: 21580 { 21581 /* Data dependency; DEP_INSN writes a register that INSN reads 21582 some cycles later. */ 21583 21584 /* Separate a load from a narrower, dependent store. */ 21585 if (rs6000_sched_groups 21586 && GET_CODE (PATTERN (insn)) == SET 21587 && GET_CODE (PATTERN (dep_insn)) == SET 21588 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM 21589 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM 21590 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1))) 21591 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0))))) 21592 return cost + 14; 21593 21594 attr_type = get_attr_type (insn); 21595 21596 switch (attr_type) 21597 { 21598 case TYPE_JMPREG: 21599 /* Tell the first scheduling pass about the latency between 21600 a mtctr and bctr (and mtlr and br/blr). The first 21601 scheduling pass will not know about this latency since 21602 the mtctr instruction, which has the latency associated 21603 to it, will be generated by reload. */ 21604 return TARGET_POWER ? 5 : 4; 21605 case TYPE_BRANCH: 21606 /* Leave some extra cycles between a compare and its 21607 dependent branch, to inhibit expensive mispredicts. */ 21608 if ((rs6000_cpu_attr == CPU_PPC603 21609 || rs6000_cpu_attr == CPU_PPC604 21610 || rs6000_cpu_attr == CPU_PPC604E 21611 || rs6000_cpu_attr == CPU_PPC620 21612 || rs6000_cpu_attr == CPU_PPC630 21613 || rs6000_cpu_attr == CPU_PPC750 21614 || rs6000_cpu_attr == CPU_PPC7400 21615 || rs6000_cpu_attr == CPU_PPC7450 21616 || rs6000_cpu_attr == CPU_POWER4 21617 || rs6000_cpu_attr == CPU_POWER5 21618 || rs6000_cpu_attr == CPU_POWER7 21619 || rs6000_cpu_attr == CPU_CELL) 21620 && recog_memoized (dep_insn) 21621 && (INSN_CODE (dep_insn) >= 0)) 21622 21623 switch (get_attr_type (dep_insn)) 21624 { 21625 case TYPE_CMP: 21626 case TYPE_COMPARE: 21627 case TYPE_DELAYED_COMPARE: 21628 case TYPE_IMUL_COMPARE: 21629 case TYPE_LMUL_COMPARE: 21630 case TYPE_FPCOMPARE: 21631 case TYPE_CR_LOGICAL: 21632 case TYPE_DELAYED_CR: 21633 return cost + 2; 21634 default: 21635 break; 21636 } 21637 break; 21638 21639 case TYPE_STORE: 21640 case TYPE_STORE_U: 21641 case TYPE_STORE_UX: 21642 case TYPE_FPSTORE: 21643 case TYPE_FPSTORE_U: 21644 case TYPE_FPSTORE_UX: 21645 if ((rs6000_cpu == PROCESSOR_POWER6) 21646 && recog_memoized (dep_insn) 21647 && (INSN_CODE (dep_insn) >= 0)) 21648 { 21649 21650 if (GET_CODE (PATTERN (insn)) != SET) 21651 /* If this happens, we have to extend this to schedule 21652 optimally. Return default for now. */ 21653 return cost; 21654 21655 /* Adjust the cost for the case where the value written 21656 by a fixed point operation is used as the address 21657 gen value on a store. */ 21658 switch (get_attr_type (dep_insn)) 21659 { 21660 case TYPE_LOAD: 21661 case TYPE_LOAD_U: 21662 case TYPE_LOAD_UX: 21663 case TYPE_CNTLZ: 21664 { 21665 if (! store_data_bypass_p (dep_insn, insn)) 21666 return 4; 21667 break; 21668 } 21669 case TYPE_LOAD_EXT: 21670 case TYPE_LOAD_EXT_U: 21671 case TYPE_LOAD_EXT_UX: 21672 case TYPE_VAR_SHIFT_ROTATE: 21673 case TYPE_VAR_DELAYED_COMPARE: 21674 { 21675 if (! store_data_bypass_p (dep_insn, insn)) 21676 return 6; 21677 break; 21678 } 21679 case TYPE_INTEGER: 21680 case TYPE_COMPARE: 21681 case TYPE_FAST_COMPARE: 21682 case TYPE_EXTS: 21683 case TYPE_SHIFT: 21684 case TYPE_INSERT_WORD: 21685 case TYPE_INSERT_DWORD: 21686 case TYPE_FPLOAD_U: 21687 case TYPE_FPLOAD_UX: 21688 case TYPE_STORE_U: 21689 case TYPE_STORE_UX: 21690 case TYPE_FPSTORE_U: 21691 case TYPE_FPSTORE_UX: 21692 { 21693 if (! store_data_bypass_p (dep_insn, insn)) 21694 return 3; 21695 break; 21696 } 21697 case TYPE_IMUL: 21698 case TYPE_IMUL2: 21699 case TYPE_IMUL3: 21700 case TYPE_LMUL: 21701 case TYPE_IMUL_COMPARE: 21702 case TYPE_LMUL_COMPARE: 21703 { 21704 if (! store_data_bypass_p (dep_insn, insn)) 21705 return 17; 21706 break; 21707 } 21708 case TYPE_IDIV: 21709 { 21710 if (! store_data_bypass_p (dep_insn, insn)) 21711 return 45; 21712 break; 21713 } 21714 case TYPE_LDIV: 21715 { 21716 if (! store_data_bypass_p (dep_insn, insn)) 21717 return 57; 21718 break; 21719 } 21720 default: 21721 break; 21722 } 21723 } 21724 break; 21725 21726 case TYPE_LOAD: 21727 case TYPE_LOAD_U: 21728 case TYPE_LOAD_UX: 21729 case TYPE_LOAD_EXT: 21730 case TYPE_LOAD_EXT_U: 21731 case TYPE_LOAD_EXT_UX: 21732 if ((rs6000_cpu == PROCESSOR_POWER6) 21733 && recog_memoized (dep_insn) 21734 && (INSN_CODE (dep_insn) >= 0)) 21735 { 21736 21737 /* Adjust the cost for the case where the value written 21738 by a fixed point instruction is used within the address 21739 gen portion of a subsequent load(u)(x) */ 21740 switch (get_attr_type (dep_insn)) 21741 { 21742 case TYPE_LOAD: 21743 case TYPE_LOAD_U: 21744 case TYPE_LOAD_UX: 21745 case TYPE_CNTLZ: 21746 { 21747 if (set_to_load_agen (dep_insn, insn)) 21748 return 4; 21749 break; 21750 } 21751 case TYPE_LOAD_EXT: 21752 case TYPE_LOAD_EXT_U: 21753 case TYPE_LOAD_EXT_UX: 21754 case TYPE_VAR_SHIFT_ROTATE: 21755 case TYPE_VAR_DELAYED_COMPARE: 21756 { 21757 if (set_to_load_agen (dep_insn, insn)) 21758 return 6; 21759 break; 21760 } 21761 case TYPE_INTEGER: 21762 case TYPE_COMPARE: 21763 case TYPE_FAST_COMPARE: 21764 case TYPE_EXTS: 21765 case TYPE_SHIFT: 21766 case TYPE_INSERT_WORD: 21767 case TYPE_INSERT_DWORD: 21768 case TYPE_FPLOAD_U: 21769 case TYPE_FPLOAD_UX: 21770 case TYPE_STORE_U: 21771 case TYPE_STORE_UX: 21772 case TYPE_FPSTORE_U: 21773 case TYPE_FPSTORE_UX: 21774 { 21775 if (set_to_load_agen (dep_insn, insn)) 21776 return 3; 21777 break; 21778 } 21779 case TYPE_IMUL: 21780 case TYPE_IMUL2: 21781 case TYPE_IMUL3: 21782 case TYPE_LMUL: 21783 case TYPE_IMUL_COMPARE: 21784 case TYPE_LMUL_COMPARE: 21785 { 21786 if (set_to_load_agen (dep_insn, insn)) 21787 return 17; 21788 break; 21789 } 21790 case TYPE_IDIV: 21791 { 21792 if (set_to_load_agen (dep_insn, insn)) 21793 return 45; 21794 break; 21795 } 21796 case TYPE_LDIV: 21797 { 21798 if (set_to_load_agen (dep_insn, insn)) 21799 return 57; 21800 break; 21801 } 21802 default: 21803 break; 21804 } 21805 } 21806 break; 21807 21808 case TYPE_FPLOAD: 21809 if ((rs6000_cpu == PROCESSOR_POWER6) 21810 && recog_memoized (dep_insn) 21811 && (INSN_CODE (dep_insn) >= 0) 21812 && (get_attr_type (dep_insn) == TYPE_MFFGPR)) 21813 return 2; 21814 21815 default: 21816 break; 21817 } 21818 21819 /* Fall out to return default cost. */ 21820 } 21821 break; 21822 21823 case REG_DEP_OUTPUT: 21824 /* Output dependency; DEP_INSN writes a register that INSN writes some 21825 cycles later. */ 21826 if ((rs6000_cpu == PROCESSOR_POWER6) 21827 && recog_memoized (dep_insn) 21828 && (INSN_CODE (dep_insn) >= 0)) 21829 { 21830 attr_type = get_attr_type (insn); 21831 21832 switch (attr_type) 21833 { 21834 case TYPE_FP: 21835 if (get_attr_type (dep_insn) == TYPE_FP) 21836 return 1; 21837 break; 21838 case TYPE_FPLOAD: 21839 if (get_attr_type (dep_insn) == TYPE_MFFGPR) 21840 return 2; 21841 break; 21842 default: 21843 break; 21844 } 21845 } 21846 case REG_DEP_ANTI: 21847 /* Anti dependency; DEP_INSN reads a register that INSN writes some 21848 cycles later. */ 21849 return 0; 21850 21851 default: 21852 gcc_unreachable (); 21853 } 21854 21855 return cost; 21856} 21857 21858/* Debug version of rs6000_adjust_cost. */ 21859 21860static int 21861rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost) 21862{ 21863 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost); 21864 21865 if (ret != cost) 21866 { 21867 const char *dep; 21868 21869 switch (REG_NOTE_KIND (link)) 21870 { 21871 default: dep = "unknown depencency"; break; 21872 case REG_DEP_TRUE: dep = "data dependency"; break; 21873 case REG_DEP_OUTPUT: dep = "output dependency"; break; 21874 case REG_DEP_ANTI: dep = "anti depencency"; break; 21875 } 21876 21877 fprintf (stderr, 21878 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, " 21879 "%s, insn:\n", ret, cost, dep); 21880 21881 debug_rtx (insn); 21882 } 21883 21884 return ret; 21885} 21886 21887/* The function returns a true if INSN is microcoded. 21888 Return false otherwise. */ 21889 21890static bool 21891is_microcoded_insn (rtx insn) 21892{ 21893 if (!insn || !NONDEBUG_INSN_P (insn) 21894 || GET_CODE (PATTERN (insn)) == USE 21895 || GET_CODE (PATTERN (insn)) == CLOBBER) 21896 return false; 21897 21898 if (rs6000_cpu_attr == CPU_CELL) 21899 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS; 21900 21901 if (rs6000_sched_groups) 21902 { 21903 enum attr_type type = get_attr_type (insn); 21904 if (type == TYPE_LOAD_EXT_U 21905 || type == TYPE_LOAD_EXT_UX 21906 || type == TYPE_LOAD_UX 21907 || type == TYPE_STORE_UX 21908 || type == TYPE_MFCR) 21909 return true; 21910 } 21911 21912 return false; 21913} 21914 21915/* The function returns true if INSN is cracked into 2 instructions 21916 by the processor (and therefore occupies 2 issue slots). */ 21917 21918static bool 21919is_cracked_insn (rtx insn) 21920{ 21921 if (!insn || !NONDEBUG_INSN_P (insn) 21922 || GET_CODE (PATTERN (insn)) == USE 21923 || GET_CODE (PATTERN (insn)) == CLOBBER) 21924 return false; 21925 21926 if (rs6000_sched_groups) 21927 { 21928 enum attr_type type = get_attr_type (insn); 21929 if (type == TYPE_LOAD_U || type == TYPE_STORE_U 21930 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U 21931 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX 21932 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR 21933 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE 21934 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE 21935 || type == TYPE_IDIV || type == TYPE_LDIV 21936 || type == TYPE_INSERT_WORD) 21937 return true; 21938 } 21939 21940 return false; 21941} 21942 21943/* The function returns true if INSN can be issued only from 21944 the branch slot. */ 21945 21946static bool 21947is_branch_slot_insn (rtx insn) 21948{ 21949 if (!insn || !NONDEBUG_INSN_P (insn) 21950 || GET_CODE (PATTERN (insn)) == USE 21951 || GET_CODE (PATTERN (insn)) == CLOBBER) 21952 return false; 21953 21954 if (rs6000_sched_groups) 21955 { 21956 enum attr_type type = get_attr_type (insn); 21957 if (type == TYPE_BRANCH || type == TYPE_JMPREG) 21958 return true; 21959 return false; 21960 } 21961 21962 return false; 21963} 21964 21965/* The function returns true if out_inst sets a value that is 21966 used in the address generation computation of in_insn */ 21967static bool 21968set_to_load_agen (rtx out_insn, rtx in_insn) 21969{ 21970 rtx out_set, in_set; 21971 21972 /* For performance reasons, only handle the simple case where 21973 both loads are a single_set. */ 21974 out_set = single_set (out_insn); 21975 if (out_set) 21976 { 21977 in_set = single_set (in_insn); 21978 if (in_set) 21979 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set)); 21980 } 21981 21982 return false; 21983} 21984 21985/* The function returns true if the target storage location of 21986 out_insn is adjacent to the target storage location of in_insn */ 21987/* Return 1 if memory locations are adjacent. */ 21988 21989static bool 21990adjacent_mem_locations (rtx insn1, rtx insn2) 21991{ 21992 21993 rtx a = get_store_dest (PATTERN (insn1)); 21994 rtx b = get_store_dest (PATTERN (insn2)); 21995 21996 if ((GET_CODE (XEXP (a, 0)) == REG 21997 || (GET_CODE (XEXP (a, 0)) == PLUS 21998 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT)) 21999 && (GET_CODE (XEXP (b, 0)) == REG 22000 || (GET_CODE (XEXP (b, 0)) == PLUS 22001 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT))) 22002 { 22003 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff; 22004 rtx reg0, reg1; 22005 22006 if (GET_CODE (XEXP (a, 0)) == PLUS) 22007 { 22008 reg0 = XEXP (XEXP (a, 0), 0); 22009 val0 = INTVAL (XEXP (XEXP (a, 0), 1)); 22010 } 22011 else 22012 reg0 = XEXP (a, 0); 22013 22014 if (GET_CODE (XEXP (b, 0)) == PLUS) 22015 { 22016 reg1 = XEXP (XEXP (b, 0), 0); 22017 val1 = INTVAL (XEXP (XEXP (b, 0), 1)); 22018 } 22019 else 22020 reg1 = XEXP (b, 0); 22021 22022 val_diff = val1 - val0; 22023 22024 return ((REGNO (reg0) == REGNO (reg1)) 22025 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a))) 22026 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b))))); 22027 } 22028 22029 return false; 22030} 22031 22032/* A C statement (sans semicolon) to update the integer scheduling 22033 priority INSN_PRIORITY (INSN). Increase the priority to execute the 22034 INSN earlier, reduce the priority to execute INSN later. Do not 22035 define this macro if you do not need to adjust the scheduling 22036 priorities of insns. */ 22037 22038static int 22039rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority) 22040{ 22041 /* On machines (like the 750) which have asymmetric integer units, 22042 where one integer unit can do multiply and divides and the other 22043 can't, reduce the priority of multiply/divide so it is scheduled 22044 before other integer operations. */ 22045 22046#if 0 22047 if (! INSN_P (insn)) 22048 return priority; 22049 22050 if (GET_CODE (PATTERN (insn)) == USE) 22051 return priority; 22052 22053 switch (rs6000_cpu_attr) { 22054 case CPU_PPC750: 22055 switch (get_attr_type (insn)) 22056 { 22057 default: 22058 break; 22059 22060 case TYPE_IMUL: 22061 case TYPE_IDIV: 22062 fprintf (stderr, "priority was %#x (%d) before adjustment\n", 22063 priority, priority); 22064 if (priority >= 0 && priority < 0x01000000) 22065 priority >>= 3; 22066 break; 22067 } 22068 } 22069#endif 22070 22071 if (insn_must_be_first_in_group (insn) 22072 && reload_completed 22073 && current_sched_info->sched_max_insns_priority 22074 && rs6000_sched_restricted_insns_priority) 22075 { 22076 22077 /* Prioritize insns that can be dispatched only in the first 22078 dispatch slot. */ 22079 if (rs6000_sched_restricted_insns_priority == 1) 22080 /* Attach highest priority to insn. This means that in 22081 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations 22082 precede 'priority' (critical path) considerations. */ 22083 return current_sched_info->sched_max_insns_priority; 22084 else if (rs6000_sched_restricted_insns_priority == 2) 22085 /* Increase priority of insn by a minimal amount. This means that in 22086 haifa-sched.c:ready_sort(), only 'priority' (critical path) 22087 considerations precede dispatch-slot restriction considerations. */ 22088 return (priority + 1); 22089 } 22090 22091 if (rs6000_cpu == PROCESSOR_POWER6 22092 && ((load_store_pendulum == -2 && is_load_insn (insn)) 22093 || (load_store_pendulum == 2 && is_store_insn (insn)))) 22094 /* Attach highest priority to insn if the scheduler has just issued two 22095 stores and this instruction is a load, or two loads and this instruction 22096 is a store. Power6 wants loads and stores scheduled alternately 22097 when possible */ 22098 return current_sched_info->sched_max_insns_priority; 22099 22100 return priority; 22101} 22102 22103/* Return true if the instruction is nonpipelined on the Cell. */ 22104static bool 22105is_nonpipeline_insn (rtx insn) 22106{ 22107 enum attr_type type; 22108 if (!insn || !NONDEBUG_INSN_P (insn) 22109 || GET_CODE (PATTERN (insn)) == USE 22110 || GET_CODE (PATTERN (insn)) == CLOBBER) 22111 return false; 22112 22113 type = get_attr_type (insn); 22114 if (type == TYPE_IMUL 22115 || type == TYPE_IMUL2 22116 || type == TYPE_IMUL3 22117 || type == TYPE_LMUL 22118 || type == TYPE_IDIV 22119 || type == TYPE_LDIV 22120 || type == TYPE_SDIV 22121 || type == TYPE_DDIV 22122 || type == TYPE_SSQRT 22123 || type == TYPE_DSQRT 22124 || type == TYPE_MFCR 22125 || type == TYPE_MFCRF 22126 || type == TYPE_MFJMPR) 22127 { 22128 return true; 22129 } 22130 return false; 22131} 22132 22133 22134/* Return how many instructions the machine can issue per cycle. */ 22135 22136static int 22137rs6000_issue_rate (void) 22138{ 22139 /* Unless scheduling for register pressure, use issue rate of 1 for 22140 first scheduling pass to decrease degradation. */ 22141 if (!reload_completed && !flag_sched_pressure) 22142 return 1; 22143 22144 switch (rs6000_cpu_attr) { 22145 case CPU_RIOS1: /* ? */ 22146 case CPU_RS64A: 22147 case CPU_PPC601: /* ? */ 22148 case CPU_PPC7450: 22149 return 3; 22150 case CPU_PPC440: 22151 case CPU_PPC603: 22152 case CPU_PPC750: 22153 case CPU_PPC7400: 22154 case CPU_PPC8540: 22155 case CPU_CELL: 22156 case CPU_PPCE300C2: 22157 case CPU_PPCE300C3: 22158 case CPU_PPCE500MC: 22159 case CPU_PPCE500MC64: 22160 return 2; 22161 case CPU_RIOS2: 22162 case CPU_PPC476: 22163 case CPU_PPC604: 22164 case CPU_PPC604E: 22165 case CPU_PPC620: 22166 case CPU_PPC630: 22167 return 4; 22168 case CPU_POWER4: 22169 case CPU_POWER5: 22170 case CPU_POWER6: 22171 case CPU_POWER7: 22172 return 5; 22173 default: 22174 return 1; 22175 } 22176} 22177 22178/* Return how many instructions to look ahead for better insn 22179 scheduling. */ 22180 22181static int 22182rs6000_use_sched_lookahead (void) 22183{ 22184 if (rs6000_cpu_attr == CPU_PPC8540) 22185 return 4; 22186 if (rs6000_cpu_attr == CPU_CELL) 22187 return (reload_completed ? 8 : 0); 22188 return 0; 22189} 22190 22191/* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */ 22192static int 22193rs6000_use_sched_lookahead_guard (rtx insn) 22194{ 22195 if (rs6000_cpu_attr != CPU_CELL) 22196 return 1; 22197 22198 if (insn == NULL_RTX || !INSN_P (insn)) 22199 abort (); 22200 22201 if (!reload_completed 22202 || is_nonpipeline_insn (insn) 22203 || is_microcoded_insn (insn)) 22204 return 0; 22205 22206 return 1; 22207} 22208 22209/* Determine is PAT refers to memory. */ 22210 22211static bool 22212is_mem_ref (rtx pat) 22213{ 22214 const char * fmt; 22215 int i, j; 22216 bool ret = false; 22217 22218 /* stack_tie does not produce any real memory traffic. */ 22219 if (GET_CODE (pat) == UNSPEC 22220 && XINT (pat, 1) == UNSPEC_TIE) 22221 return false; 22222 22223 if (GET_CODE (pat) == MEM) 22224 return true; 22225 22226 /* Recursively process the pattern. */ 22227 fmt = GET_RTX_FORMAT (GET_CODE (pat)); 22228 22229 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--) 22230 { 22231 if (fmt[i] == 'e') 22232 ret |= is_mem_ref (XEXP (pat, i)); 22233 else if (fmt[i] == 'E') 22234 for (j = XVECLEN (pat, i) - 1; j >= 0; j--) 22235 ret |= is_mem_ref (XVECEXP (pat, i, j)); 22236 } 22237 22238 return ret; 22239} 22240 22241/* Determine if PAT is a PATTERN of a load insn. */ 22242 22243static bool 22244is_load_insn1 (rtx pat) 22245{ 22246 if (!pat || pat == NULL_RTX) 22247 return false; 22248 22249 if (GET_CODE (pat) == SET) 22250 return is_mem_ref (SET_SRC (pat)); 22251 22252 if (GET_CODE (pat) == PARALLEL) 22253 { 22254 int i; 22255 22256 for (i = 0; i < XVECLEN (pat, 0); i++) 22257 if (is_load_insn1 (XVECEXP (pat, 0, i))) 22258 return true; 22259 } 22260 22261 return false; 22262} 22263 22264/* Determine if INSN loads from memory. */ 22265 22266static bool 22267is_load_insn (rtx insn) 22268{ 22269 if (!insn || !INSN_P (insn)) 22270 return false; 22271 22272 if (GET_CODE (insn) == CALL_INSN) 22273 return false; 22274 22275 return is_load_insn1 (PATTERN (insn)); 22276} 22277 22278/* Determine if PAT is a PATTERN of a store insn. */ 22279 22280static bool 22281is_store_insn1 (rtx pat) 22282{ 22283 if (!pat || pat == NULL_RTX) 22284 return false; 22285 22286 if (GET_CODE (pat) == SET) 22287 return is_mem_ref (SET_DEST (pat)); 22288 22289 if (GET_CODE (pat) == PARALLEL) 22290 { 22291 int i; 22292 22293 for (i = 0; i < XVECLEN (pat, 0); i++) 22294 if (is_store_insn1 (XVECEXP (pat, 0, i))) 22295 return true; 22296 } 22297 22298 return false; 22299} 22300 22301/* Determine if INSN stores to memory. */ 22302 22303static bool 22304is_store_insn (rtx insn) 22305{ 22306 if (!insn || !INSN_P (insn)) 22307 return false; 22308 22309 return is_store_insn1 (PATTERN (insn)); 22310} 22311 22312/* Return the dest of a store insn. */ 22313 22314static rtx 22315get_store_dest (rtx pat) 22316{ 22317 gcc_assert (is_store_insn1 (pat)); 22318 22319 if (GET_CODE (pat) == SET) 22320 return SET_DEST (pat); 22321 else if (GET_CODE (pat) == PARALLEL) 22322 { 22323 int i; 22324 22325 for (i = 0; i < XVECLEN (pat, 0); i++) 22326 { 22327 rtx inner_pat = XVECEXP (pat, 0, i); 22328 if (GET_CODE (inner_pat) == SET 22329 && is_mem_ref (SET_DEST (inner_pat))) 22330 return inner_pat; 22331 } 22332 } 22333 /* We shouldn't get here, because we should have either a simple 22334 store insn or a store with update which are covered above. */ 22335 gcc_unreachable(); 22336} 22337 22338/* Returns whether the dependence between INSN and NEXT is considered 22339 costly by the given target. */ 22340 22341static bool 22342rs6000_is_costly_dependence (dep_t dep, int cost, int distance) 22343{ 22344 rtx insn; 22345 rtx next; 22346 22347 /* If the flag is not enabled - no dependence is considered costly; 22348 allow all dependent insns in the same group. 22349 This is the most aggressive option. */ 22350 if (rs6000_sched_costly_dep == no_dep_costly) 22351 return false; 22352 22353 /* If the flag is set to 1 - a dependence is always considered costly; 22354 do not allow dependent instructions in the same group. 22355 This is the most conservative option. */ 22356 if (rs6000_sched_costly_dep == all_deps_costly) 22357 return true; 22358 22359 insn = DEP_PRO (dep); 22360 next = DEP_CON (dep); 22361 22362 if (rs6000_sched_costly_dep == store_to_load_dep_costly 22363 && is_load_insn (next) 22364 && is_store_insn (insn)) 22365 /* Prevent load after store in the same group. */ 22366 return true; 22367 22368 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly 22369 && is_load_insn (next) 22370 && is_store_insn (insn) 22371 && DEP_TYPE (dep) == REG_DEP_TRUE) 22372 /* Prevent load after store in the same group if it is a true 22373 dependence. */ 22374 return true; 22375 22376 /* The flag is set to X; dependences with latency >= X are considered costly, 22377 and will not be scheduled in the same group. */ 22378 if (rs6000_sched_costly_dep <= max_dep_latency 22379 && ((cost - distance) >= (int)rs6000_sched_costly_dep)) 22380 return true; 22381 22382 return false; 22383} 22384 22385/* Return the next insn after INSN that is found before TAIL is reached, 22386 skipping any "non-active" insns - insns that will not actually occupy 22387 an issue slot. Return NULL_RTX if such an insn is not found. */ 22388 22389static rtx 22390get_next_active_insn (rtx insn, rtx tail) 22391{ 22392 if (insn == NULL_RTX || insn == tail) 22393 return NULL_RTX; 22394 22395 while (1) 22396 { 22397 insn = NEXT_INSN (insn); 22398 if (insn == NULL_RTX || insn == tail) 22399 return NULL_RTX; 22400 22401 if (CALL_P (insn) 22402 || JUMP_P (insn) 22403 || (NONJUMP_INSN_P (insn) 22404 && GET_CODE (PATTERN (insn)) != USE 22405 && GET_CODE (PATTERN (insn)) != CLOBBER 22406 && INSN_CODE (insn) != CODE_FOR_stack_tie)) 22407 break; 22408 } 22409 return insn; 22410} 22411 22412/* We are about to begin issuing insns for this clock cycle. */ 22413 22414static int 22415rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose, 22416 rtx *ready ATTRIBUTE_UNUSED, 22417 int *pn_ready ATTRIBUTE_UNUSED, 22418 int clock_var ATTRIBUTE_UNUSED) 22419{ 22420 int n_ready = *pn_ready; 22421 22422 if (sched_verbose) 22423 fprintf (dump, "// rs6000_sched_reorder :\n"); 22424 22425 /* Reorder the ready list, if the second to last ready insn 22426 is a nonepipeline insn. */ 22427 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1) 22428 { 22429 if (is_nonpipeline_insn (ready[n_ready - 1]) 22430 && (recog_memoized (ready[n_ready - 2]) > 0)) 22431 /* Simply swap first two insns. */ 22432 { 22433 rtx tmp = ready[n_ready - 1]; 22434 ready[n_ready - 1] = ready[n_ready - 2]; 22435 ready[n_ready - 2] = tmp; 22436 } 22437 } 22438 22439 if (rs6000_cpu == PROCESSOR_POWER6) 22440 load_store_pendulum = 0; 22441 22442 return rs6000_issue_rate (); 22443} 22444 22445/* Like rs6000_sched_reorder, but called after issuing each insn. */ 22446 22447static int 22448rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready, 22449 int *pn_ready, int clock_var ATTRIBUTE_UNUSED) 22450{ 22451 if (sched_verbose) 22452 fprintf (dump, "// rs6000_sched_reorder2 :\n"); 22453 22454 /* For Power6, we need to handle some special cases to try and keep the 22455 store queue from overflowing and triggering expensive flushes. 22456 22457 This code monitors how load and store instructions are being issued 22458 and skews the ready list one way or the other to increase the likelihood 22459 that a desired instruction is issued at the proper time. 22460 22461 A couple of things are done. First, we maintain a "load_store_pendulum" 22462 to track the current state of load/store issue. 22463 22464 - If the pendulum is at zero, then no loads or stores have been 22465 issued in the current cycle so we do nothing. 22466 22467 - If the pendulum is 1, then a single load has been issued in this 22468 cycle and we attempt to locate another load in the ready list to 22469 issue with it. 22470 22471 - If the pendulum is -2, then two stores have already been 22472 issued in this cycle, so we increase the priority of the first load 22473 in the ready list to increase it's likelihood of being chosen first 22474 in the next cycle. 22475 22476 - If the pendulum is -1, then a single store has been issued in this 22477 cycle and we attempt to locate another store in the ready list to 22478 issue with it, preferring a store to an adjacent memory location to 22479 facilitate store pairing in the store queue. 22480 22481 - If the pendulum is 2, then two loads have already been 22482 issued in this cycle, so we increase the priority of the first store 22483 in the ready list to increase it's likelihood of being chosen first 22484 in the next cycle. 22485 22486 - If the pendulum < -2 or > 2, then do nothing. 22487 22488 Note: This code covers the most common scenarios. There exist non 22489 load/store instructions which make use of the LSU and which 22490 would need to be accounted for to strictly model the behavior 22491 of the machine. Those instructions are currently unaccounted 22492 for to help minimize compile time overhead of this code. 22493 */ 22494 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn) 22495 { 22496 int pos; 22497 int i; 22498 rtx tmp; 22499 22500 if (is_store_insn (last_scheduled_insn)) 22501 /* Issuing a store, swing the load_store_pendulum to the left */ 22502 load_store_pendulum--; 22503 else if (is_load_insn (last_scheduled_insn)) 22504 /* Issuing a load, swing the load_store_pendulum to the right */ 22505 load_store_pendulum++; 22506 else 22507 return cached_can_issue_more; 22508 22509 /* If the pendulum is balanced, or there is only one instruction on 22510 the ready list, then all is well, so return. */ 22511 if ((load_store_pendulum == 0) || (*pn_ready <= 1)) 22512 return cached_can_issue_more; 22513 22514 if (load_store_pendulum == 1) 22515 { 22516 /* A load has been issued in this cycle. Scan the ready list 22517 for another load to issue with it */ 22518 pos = *pn_ready-1; 22519 22520 while (pos >= 0) 22521 { 22522 if (is_load_insn (ready[pos])) 22523 { 22524 /* Found a load. Move it to the head of the ready list, 22525 and adjust it's priority so that it is more likely to 22526 stay there */ 22527 tmp = ready[pos]; 22528 for (i=pos; i<*pn_ready-1; i++) 22529 ready[i] = ready[i + 1]; 22530 ready[*pn_ready-1] = tmp; 22531 22532 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp)) 22533 INSN_PRIORITY (tmp)++; 22534 break; 22535 } 22536 pos--; 22537 } 22538 } 22539 else if (load_store_pendulum == -2) 22540 { 22541 /* Two stores have been issued in this cycle. Increase the 22542 priority of the first load in the ready list to favor it for 22543 issuing in the next cycle. */ 22544 pos = *pn_ready-1; 22545 22546 while (pos >= 0) 22547 { 22548 if (is_load_insn (ready[pos]) 22549 && !sel_sched_p () 22550 && INSN_PRIORITY_KNOWN (ready[pos])) 22551 { 22552 INSN_PRIORITY (ready[pos])++; 22553 22554 /* Adjust the pendulum to account for the fact that a load 22555 was found and increased in priority. This is to prevent 22556 increasing the priority of multiple loads */ 22557 load_store_pendulum--; 22558 22559 break; 22560 } 22561 pos--; 22562 } 22563 } 22564 else if (load_store_pendulum == -1) 22565 { 22566 /* A store has been issued in this cycle. Scan the ready list for 22567 another store to issue with it, preferring a store to an adjacent 22568 memory location */ 22569 int first_store_pos = -1; 22570 22571 pos = *pn_ready-1; 22572 22573 while (pos >= 0) 22574 { 22575 if (is_store_insn (ready[pos])) 22576 { 22577 /* Maintain the index of the first store found on the 22578 list */ 22579 if (first_store_pos == -1) 22580 first_store_pos = pos; 22581 22582 if (is_store_insn (last_scheduled_insn) 22583 && adjacent_mem_locations (last_scheduled_insn,ready[pos])) 22584 { 22585 /* Found an adjacent store. Move it to the head of the 22586 ready list, and adjust it's priority so that it is 22587 more likely to stay there */ 22588 tmp = ready[pos]; 22589 for (i=pos; i<*pn_ready-1; i++) 22590 ready[i] = ready[i + 1]; 22591 ready[*pn_ready-1] = tmp; 22592 22593 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp)) 22594 INSN_PRIORITY (tmp)++; 22595 22596 first_store_pos = -1; 22597 22598 break; 22599 }; 22600 } 22601 pos--; 22602 } 22603 22604 if (first_store_pos >= 0) 22605 { 22606 /* An adjacent store wasn't found, but a non-adjacent store was, 22607 so move the non-adjacent store to the front of the ready 22608 list, and adjust its priority so that it is more likely to 22609 stay there. */ 22610 tmp = ready[first_store_pos]; 22611 for (i=first_store_pos; i<*pn_ready-1; i++) 22612 ready[i] = ready[i + 1]; 22613 ready[*pn_ready-1] = tmp; 22614 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp)) 22615 INSN_PRIORITY (tmp)++; 22616 } 22617 } 22618 else if (load_store_pendulum == 2) 22619 { 22620 /* Two loads have been issued in this cycle. Increase the priority 22621 of the first store in the ready list to favor it for issuing in 22622 the next cycle. */ 22623 pos = *pn_ready-1; 22624 22625 while (pos >= 0) 22626 { 22627 if (is_store_insn (ready[pos]) 22628 && !sel_sched_p () 22629 && INSN_PRIORITY_KNOWN (ready[pos])) 22630 { 22631 INSN_PRIORITY (ready[pos])++; 22632 22633 /* Adjust the pendulum to account for the fact that a store 22634 was found and increased in priority. This is to prevent 22635 increasing the priority of multiple stores */ 22636 load_store_pendulum++; 22637 22638 break; 22639 } 22640 pos--; 22641 } 22642 } 22643 } 22644 22645 return cached_can_issue_more; 22646} 22647 22648/* Return whether the presence of INSN causes a dispatch group termination 22649 of group WHICH_GROUP. 22650 22651 If WHICH_GROUP == current_group, this function will return true if INSN 22652 causes the termination of the current group (i.e, the dispatch group to 22653 which INSN belongs). This means that INSN will be the last insn in the 22654 group it belongs to. 22655 22656 If WHICH_GROUP == previous_group, this function will return true if INSN 22657 causes the termination of the previous group (i.e, the dispatch group that 22658 precedes the group to which INSN belongs). This means that INSN will be 22659 the first insn in the group it belongs to). */ 22660 22661static bool 22662insn_terminates_group_p (rtx insn, enum group_termination which_group) 22663{ 22664 bool first, last; 22665 22666 if (! insn) 22667 return false; 22668 22669 first = insn_must_be_first_in_group (insn); 22670 last = insn_must_be_last_in_group (insn); 22671 22672 if (first && last) 22673 return true; 22674 22675 if (which_group == current_group) 22676 return last; 22677 else if (which_group == previous_group) 22678 return first; 22679 22680 return false; 22681} 22682 22683 22684static bool 22685insn_must_be_first_in_group (rtx insn) 22686{ 22687 enum attr_type type; 22688 22689 if (!insn 22690 || GET_CODE (insn) == NOTE 22691 || DEBUG_INSN_P (insn) 22692 || GET_CODE (PATTERN (insn)) == USE 22693 || GET_CODE (PATTERN (insn)) == CLOBBER) 22694 return false; 22695 22696 switch (rs6000_cpu) 22697 { 22698 case PROCESSOR_POWER5: 22699 if (is_cracked_insn (insn)) 22700 return true; 22701 case PROCESSOR_POWER4: 22702 if (is_microcoded_insn (insn)) 22703 return true; 22704 22705 if (!rs6000_sched_groups) 22706 return false; 22707 22708 type = get_attr_type (insn); 22709 22710 switch (type) 22711 { 22712 case TYPE_MFCR: 22713 case TYPE_MFCRF: 22714 case TYPE_MTCR: 22715 case TYPE_DELAYED_CR: 22716 case TYPE_CR_LOGICAL: 22717 case TYPE_MTJMPR: 22718 case TYPE_MFJMPR: 22719 case TYPE_IDIV: 22720 case TYPE_LDIV: 22721 case TYPE_LOAD_L: 22722 case TYPE_STORE_C: 22723 case TYPE_ISYNC: 22724 case TYPE_SYNC: 22725 return true; 22726 default: 22727 break; 22728 } 22729 break; 22730 case PROCESSOR_POWER6: 22731 type = get_attr_type (insn); 22732 22733 switch (type) 22734 { 22735 case TYPE_INSERT_DWORD: 22736 case TYPE_EXTS: 22737 case TYPE_CNTLZ: 22738 case TYPE_SHIFT: 22739 case TYPE_VAR_SHIFT_ROTATE: 22740 case TYPE_TRAP: 22741 case TYPE_IMUL: 22742 case TYPE_IMUL2: 22743 case TYPE_IMUL3: 22744 case TYPE_LMUL: 22745 case TYPE_IDIV: 22746 case TYPE_INSERT_WORD: 22747 case TYPE_DELAYED_COMPARE: 22748 case TYPE_IMUL_COMPARE: 22749 case TYPE_LMUL_COMPARE: 22750 case TYPE_FPCOMPARE: 22751 case TYPE_MFCR: 22752 case TYPE_MTCR: 22753 case TYPE_MFJMPR: 22754 case TYPE_MTJMPR: 22755 case TYPE_ISYNC: 22756 case TYPE_SYNC: 22757 case TYPE_LOAD_L: 22758 case TYPE_STORE_C: 22759 case TYPE_LOAD_U: 22760 case TYPE_LOAD_UX: 22761 case TYPE_LOAD_EXT_UX: 22762 case TYPE_STORE_U: 22763 case TYPE_STORE_UX: 22764 case TYPE_FPLOAD_U: 22765 case TYPE_FPLOAD_UX: 22766 case TYPE_FPSTORE_U: 22767 case TYPE_FPSTORE_UX: 22768 return true; 22769 default: 22770 break; 22771 } 22772 break; 22773 case PROCESSOR_POWER7: 22774 type = get_attr_type (insn); 22775 22776 switch (type) 22777 { 22778 case TYPE_CR_LOGICAL: 22779 case TYPE_MFCR: 22780 case TYPE_MFCRF: 22781 case TYPE_MTCR: 22782 case TYPE_IDIV: 22783 case TYPE_LDIV: 22784 case TYPE_COMPARE: 22785 case TYPE_DELAYED_COMPARE: 22786 case TYPE_VAR_DELAYED_COMPARE: 22787 case TYPE_ISYNC: 22788 case TYPE_LOAD_L: 22789 case TYPE_STORE_C: 22790 case TYPE_LOAD_U: 22791 case TYPE_LOAD_UX: 22792 case TYPE_LOAD_EXT: 22793 case TYPE_LOAD_EXT_U: 22794 case TYPE_LOAD_EXT_UX: 22795 case TYPE_STORE_U: 22796 case TYPE_STORE_UX: 22797 case TYPE_FPLOAD_U: 22798 case TYPE_FPLOAD_UX: 22799 case TYPE_FPSTORE_U: 22800 case TYPE_FPSTORE_UX: 22801 case TYPE_MFJMPR: 22802 case TYPE_MTJMPR: 22803 return true; 22804 default: 22805 break; 22806 } 22807 break; 22808 default: 22809 break; 22810 } 22811 22812 return false; 22813} 22814 22815static bool 22816insn_must_be_last_in_group (rtx insn) 22817{ 22818 enum attr_type type; 22819 22820 if (!insn 22821 || GET_CODE (insn) == NOTE 22822 || DEBUG_INSN_P (insn) 22823 || GET_CODE (PATTERN (insn)) == USE 22824 || GET_CODE (PATTERN (insn)) == CLOBBER) 22825 return false; 22826 22827 switch (rs6000_cpu) { 22828 case PROCESSOR_POWER4: 22829 case PROCESSOR_POWER5: 22830 if (is_microcoded_insn (insn)) 22831 return true; 22832 22833 if (is_branch_slot_insn (insn)) 22834 return true; 22835 22836 break; 22837 case PROCESSOR_POWER6: 22838 type = get_attr_type (insn); 22839 22840 switch (type) 22841 { 22842 case TYPE_EXTS: 22843 case TYPE_CNTLZ: 22844 case TYPE_SHIFT: 22845 case TYPE_VAR_SHIFT_ROTATE: 22846 case TYPE_TRAP: 22847 case TYPE_IMUL: 22848 case TYPE_IMUL2: 22849 case TYPE_IMUL3: 22850 case TYPE_LMUL: 22851 case TYPE_IDIV: 22852 case TYPE_DELAYED_COMPARE: 22853 case TYPE_IMUL_COMPARE: 22854 case TYPE_LMUL_COMPARE: 22855 case TYPE_FPCOMPARE: 22856 case TYPE_MFCR: 22857 case TYPE_MTCR: 22858 case TYPE_MFJMPR: 22859 case TYPE_MTJMPR: 22860 case TYPE_ISYNC: 22861 case TYPE_SYNC: 22862 case TYPE_LOAD_L: 22863 case TYPE_STORE_C: 22864 return true; 22865 default: 22866 break; 22867 } 22868 break; 22869 case PROCESSOR_POWER7: 22870 type = get_attr_type (insn); 22871 22872 switch (type) 22873 { 22874 case TYPE_ISYNC: 22875 case TYPE_SYNC: 22876 case TYPE_LOAD_L: 22877 case TYPE_STORE_C: 22878 case TYPE_LOAD_EXT_U: 22879 case TYPE_LOAD_EXT_UX: 22880 case TYPE_STORE_UX: 22881 return true; 22882 default: 22883 break; 22884 } 22885 break; 22886 default: 22887 break; 22888 } 22889 22890 return false; 22891} 22892 22893/* Return true if it is recommended to keep NEXT_INSN "far" (in a separate 22894 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */ 22895 22896static bool 22897is_costly_group (rtx *group_insns, rtx next_insn) 22898{ 22899 int i; 22900 int issue_rate = rs6000_issue_rate (); 22901 22902 for (i = 0; i < issue_rate; i++) 22903 { 22904 sd_iterator_def sd_it; 22905 dep_t dep; 22906 rtx insn = group_insns[i]; 22907 22908 if (!insn) 22909 continue; 22910 22911 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep) 22912 { 22913 rtx next = DEP_CON (dep); 22914 22915 if (next == next_insn 22916 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0)) 22917 return true; 22918 } 22919 } 22920 22921 return false; 22922} 22923 22924/* Utility of the function redefine_groups. 22925 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS 22926 in the same dispatch group. If so, insert nops before NEXT_INSN, in order 22927 to keep it "far" (in a separate group) from GROUP_INSNS, following 22928 one of the following schemes, depending on the value of the flag 22929 -minsert_sched_nops = X: 22930 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed 22931 in order to force NEXT_INSN into a separate group. 22932 (2) X < sched_finish_regroup_exact: insert exactly X nops. 22933 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop 22934 insertion (has a group just ended, how many vacant issue slots remain in the 22935 last group, and how many dispatch groups were encountered so far). */ 22936 22937static int 22938force_new_group (int sched_verbose, FILE *dump, rtx *group_insns, 22939 rtx next_insn, bool *group_end, int can_issue_more, 22940 int *group_count) 22941{ 22942 rtx nop; 22943 bool force; 22944 int issue_rate = rs6000_issue_rate (); 22945 bool end = *group_end; 22946 int i; 22947 22948 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn)) 22949 return can_issue_more; 22950 22951 if (rs6000_sched_insert_nops > sched_finish_regroup_exact) 22952 return can_issue_more; 22953 22954 force = is_costly_group (group_insns, next_insn); 22955 if (!force) 22956 return can_issue_more; 22957 22958 if (sched_verbose > 6) 22959 fprintf (dump,"force: group count = %d, can_issue_more = %d\n", 22960 *group_count ,can_issue_more); 22961 22962 if (rs6000_sched_insert_nops == sched_finish_regroup_exact) 22963 { 22964 if (*group_end) 22965 can_issue_more = 0; 22966 22967 /* Since only a branch can be issued in the last issue_slot, it is 22968 sufficient to insert 'can_issue_more - 1' nops if next_insn is not 22969 a branch. If next_insn is a branch, we insert 'can_issue_more' nops; 22970 in this case the last nop will start a new group and the branch 22971 will be forced to the new group. */ 22972 if (can_issue_more && !is_branch_slot_insn (next_insn)) 22973 can_issue_more--; 22974 22975 while (can_issue_more > 0) 22976 { 22977 nop = gen_nop (); 22978 emit_insn_before (nop, next_insn); 22979 can_issue_more--; 22980 } 22981 22982 *group_end = true; 22983 return 0; 22984 } 22985 22986 if (rs6000_sched_insert_nops < sched_finish_regroup_exact) 22987 { 22988 int n_nops = rs6000_sched_insert_nops; 22989 22990 /* Nops can't be issued from the branch slot, so the effective 22991 issue_rate for nops is 'issue_rate - 1'. */ 22992 if (can_issue_more == 0) 22993 can_issue_more = issue_rate; 22994 can_issue_more--; 22995 if (can_issue_more == 0) 22996 { 22997 can_issue_more = issue_rate - 1; 22998 (*group_count)++; 22999 end = true; 23000 for (i = 0; i < issue_rate; i++) 23001 { 23002 group_insns[i] = 0; 23003 } 23004 } 23005 23006 while (n_nops > 0) 23007 { 23008 nop = gen_nop (); 23009 emit_insn_before (nop, next_insn); 23010 if (can_issue_more == issue_rate - 1) /* new group begins */ 23011 end = false; 23012 can_issue_more--; 23013 if (can_issue_more == 0) 23014 { 23015 can_issue_more = issue_rate - 1; 23016 (*group_count)++; 23017 end = true; 23018 for (i = 0; i < issue_rate; i++) 23019 { 23020 group_insns[i] = 0; 23021 } 23022 } 23023 n_nops--; 23024 } 23025 23026 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */ 23027 can_issue_more++; 23028 23029 /* Is next_insn going to start a new group? */ 23030 *group_end 23031 = (end 23032 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn)) 23033 || (can_issue_more <= 2 && is_cracked_insn (next_insn)) 23034 || (can_issue_more < issue_rate && 23035 insn_terminates_group_p (next_insn, previous_group))); 23036 if (*group_end && end) 23037 (*group_count)--; 23038 23039 if (sched_verbose > 6) 23040 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n", 23041 *group_count, can_issue_more); 23042 return can_issue_more; 23043 } 23044 23045 return can_issue_more; 23046} 23047 23048/* This function tries to synch the dispatch groups that the compiler "sees" 23049 with the dispatch groups that the processor dispatcher is expected to 23050 form in practice. It tries to achieve this synchronization by forcing the 23051 estimated processor grouping on the compiler (as opposed to the function 23052 'pad_goups' which tries to force the scheduler's grouping on the processor). 23053 23054 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and 23055 examines the (estimated) dispatch groups that will be formed by the processor 23056 dispatcher. It marks these group boundaries to reflect the estimated 23057 processor grouping, overriding the grouping that the scheduler had marked. 23058 Depending on the value of the flag '-minsert-sched-nops' this function can 23059 force certain insns into separate groups or force a certain distance between 23060 them by inserting nops, for example, if there exists a "costly dependence" 23061 between the insns. 23062 23063 The function estimates the group boundaries that the processor will form as 23064 follows: It keeps track of how many vacant issue slots are available after 23065 each insn. A subsequent insn will start a new group if one of the following 23066 4 cases applies: 23067 - no more vacant issue slots remain in the current dispatch group. 23068 - only the last issue slot, which is the branch slot, is vacant, but the next 23069 insn is not a branch. 23070 - only the last 2 or less issue slots, including the branch slot, are vacant, 23071 which means that a cracked insn (which occupies two issue slots) can't be 23072 issued in this group. 23073 - less than 'issue_rate' slots are vacant, and the next insn always needs to 23074 start a new group. */ 23075 23076static int 23077redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail) 23078{ 23079 rtx insn, next_insn; 23080 int issue_rate; 23081 int can_issue_more; 23082 int slot, i; 23083 bool group_end; 23084 int group_count = 0; 23085 rtx *group_insns; 23086 23087 /* Initialize. */ 23088 issue_rate = rs6000_issue_rate (); 23089 group_insns = XALLOCAVEC (rtx, issue_rate); 23090 for (i = 0; i < issue_rate; i++) 23091 { 23092 group_insns[i] = 0; 23093 } 23094 can_issue_more = issue_rate; 23095 slot = 0; 23096 insn = get_next_active_insn (prev_head_insn, tail); 23097 group_end = false; 23098 23099 while (insn != NULL_RTX) 23100 { 23101 slot = (issue_rate - can_issue_more); 23102 group_insns[slot] = insn; 23103 can_issue_more = 23104 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more); 23105 if (insn_terminates_group_p (insn, current_group)) 23106 can_issue_more = 0; 23107 23108 next_insn = get_next_active_insn (insn, tail); 23109 if (next_insn == NULL_RTX) 23110 return group_count + 1; 23111 23112 /* Is next_insn going to start a new group? */ 23113 group_end 23114 = (can_issue_more == 0 23115 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn)) 23116 || (can_issue_more <= 2 && is_cracked_insn (next_insn)) 23117 || (can_issue_more < issue_rate && 23118 insn_terminates_group_p (next_insn, previous_group))); 23119 23120 can_issue_more = force_new_group (sched_verbose, dump, group_insns, 23121 next_insn, &group_end, can_issue_more, 23122 &group_count); 23123 23124 if (group_end) 23125 { 23126 group_count++; 23127 can_issue_more = 0; 23128 for (i = 0; i < issue_rate; i++) 23129 { 23130 group_insns[i] = 0; 23131 } 23132 } 23133 23134 if (GET_MODE (next_insn) == TImode && can_issue_more) 23135 PUT_MODE (next_insn, VOIDmode); 23136 else if (!can_issue_more && GET_MODE (next_insn) != TImode) 23137 PUT_MODE (next_insn, TImode); 23138 23139 insn = next_insn; 23140 if (can_issue_more == 0) 23141 can_issue_more = issue_rate; 23142 } /* while */ 23143 23144 return group_count; 23145} 23146 23147/* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the 23148 dispatch group boundaries that the scheduler had marked. Pad with nops 23149 any dispatch groups which have vacant issue slots, in order to force the 23150 scheduler's grouping on the processor dispatcher. The function 23151 returns the number of dispatch groups found. */ 23152 23153static int 23154pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail) 23155{ 23156 rtx insn, next_insn; 23157 rtx nop; 23158 int issue_rate; 23159 int can_issue_more; 23160 int group_end; 23161 int group_count = 0; 23162 23163 /* Initialize issue_rate. */ 23164 issue_rate = rs6000_issue_rate (); 23165 can_issue_more = issue_rate; 23166 23167 insn = get_next_active_insn (prev_head_insn, tail); 23168 next_insn = get_next_active_insn (insn, tail); 23169 23170 while (insn != NULL_RTX) 23171 { 23172 can_issue_more = 23173 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more); 23174 23175 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode); 23176 23177 if (next_insn == NULL_RTX) 23178 break; 23179 23180 if (group_end) 23181 { 23182 /* If the scheduler had marked group termination at this location 23183 (between insn and next_insn), and neither insn nor next_insn will 23184 force group termination, pad the group with nops to force group 23185 termination. */ 23186 if (can_issue_more 23187 && (rs6000_sched_insert_nops == sched_finish_pad_groups) 23188 && !insn_terminates_group_p (insn, current_group) 23189 && !insn_terminates_group_p (next_insn, previous_group)) 23190 { 23191 if (!is_branch_slot_insn (next_insn)) 23192 can_issue_more--; 23193 23194 while (can_issue_more) 23195 { 23196 nop = gen_nop (); 23197 emit_insn_before (nop, next_insn); 23198 can_issue_more--; 23199 } 23200 } 23201 23202 can_issue_more = issue_rate; 23203 group_count++; 23204 } 23205 23206 insn = next_insn; 23207 next_insn = get_next_active_insn (insn, tail); 23208 } 23209 23210 return group_count; 23211} 23212 23213/* We're beginning a new block. Initialize data structures as necessary. */ 23214 23215static void 23216rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED, 23217 int sched_verbose ATTRIBUTE_UNUSED, 23218 int max_ready ATTRIBUTE_UNUSED) 23219{ 23220 last_scheduled_insn = NULL_RTX; 23221 load_store_pendulum = 0; 23222} 23223 23224/* The following function is called at the end of scheduling BB. 23225 After reload, it inserts nops at insn group bundling. */ 23226 23227static void 23228rs6000_sched_finish (FILE *dump, int sched_verbose) 23229{ 23230 int n_groups; 23231 23232 if (sched_verbose) 23233 fprintf (dump, "=== Finishing schedule.\n"); 23234 23235 if (reload_completed && rs6000_sched_groups) 23236 { 23237 /* Do not run sched_finish hook when selective scheduling enabled. */ 23238 if (sel_sched_p ()) 23239 return; 23240 23241 if (rs6000_sched_insert_nops == sched_finish_none) 23242 return; 23243 23244 if (rs6000_sched_insert_nops == sched_finish_pad_groups) 23245 n_groups = pad_groups (dump, sched_verbose, 23246 current_sched_info->prev_head, 23247 current_sched_info->next_tail); 23248 else 23249 n_groups = redefine_groups (dump, sched_verbose, 23250 current_sched_info->prev_head, 23251 current_sched_info->next_tail); 23252 23253 if (sched_verbose >= 6) 23254 { 23255 fprintf (dump, "ngroups = %d\n", n_groups); 23256 print_rtl (dump, current_sched_info->prev_head); 23257 fprintf (dump, "Done finish_sched\n"); 23258 } 23259 } 23260} 23261 23262struct _rs6000_sched_context 23263{ 23264 short cached_can_issue_more; 23265 rtx last_scheduled_insn; 23266 int load_store_pendulum; 23267}; 23268 23269typedef struct _rs6000_sched_context rs6000_sched_context_def; 23270typedef rs6000_sched_context_def *rs6000_sched_context_t; 23271 23272/* Allocate store for new scheduling context. */ 23273static void * 23274rs6000_alloc_sched_context (void) 23275{ 23276 return xmalloc (sizeof (rs6000_sched_context_def)); 23277} 23278 23279/* If CLEAN_P is true then initializes _SC with clean data, 23280 and from the global context otherwise. */ 23281static void 23282rs6000_init_sched_context (void *_sc, bool clean_p) 23283{ 23284 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc; 23285 23286 if (clean_p) 23287 { 23288 sc->cached_can_issue_more = 0; 23289 sc->last_scheduled_insn = NULL_RTX; 23290 sc->load_store_pendulum = 0; 23291 } 23292 else 23293 { 23294 sc->cached_can_issue_more = cached_can_issue_more; 23295 sc->last_scheduled_insn = last_scheduled_insn; 23296 sc->load_store_pendulum = load_store_pendulum; 23297 } 23298} 23299 23300/* Sets the global scheduling context to the one pointed to by _SC. */ 23301static void 23302rs6000_set_sched_context (void *_sc) 23303{ 23304 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc; 23305 23306 gcc_assert (sc != NULL); 23307 23308 cached_can_issue_more = sc->cached_can_issue_more; 23309 last_scheduled_insn = sc->last_scheduled_insn; 23310 load_store_pendulum = sc->load_store_pendulum; 23311} 23312 23313/* Free _SC. */ 23314static void 23315rs6000_free_sched_context (void *_sc) 23316{ 23317 gcc_assert (_sc != NULL); 23318 23319 free (_sc); 23320} 23321 23322 23323/* Length in units of the trampoline for entering a nested function. */ 23324 23325int 23326rs6000_trampoline_size (void) 23327{ 23328 int ret = 0; 23329 23330 switch (DEFAULT_ABI) 23331 { 23332 default: 23333 gcc_unreachable (); 23334 23335 case ABI_AIX: 23336 ret = (TARGET_32BIT) ? 12 : 24; 23337 break; 23338 23339 case ABI_DARWIN: 23340 case ABI_V4: 23341 ret = (TARGET_32BIT) ? 40 : 48; 23342 break; 23343 } 23344 23345 return ret; 23346} 23347 23348/* Emit RTL insns to initialize the variable parts of a trampoline. 23349 FNADDR is an RTX for the address of the function's pure code. 23350 CXT is an RTX for the static chain value for the function. */ 23351 23352static void 23353rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt) 23354{ 23355 int regsize = (TARGET_32BIT) ? 4 : 8; 23356 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0); 23357 rtx ctx_reg = force_reg (Pmode, cxt); 23358 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0)); 23359 23360 switch (DEFAULT_ABI) 23361 { 23362 default: 23363 gcc_unreachable (); 23364 23365 /* Under AIX, just build the 3 word function descriptor */ 23366 case ABI_AIX: 23367 { 23368 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr)); 23369 rtx fn_reg = gen_reg_rtx (Pmode); 23370 rtx toc_reg = gen_reg_rtx (Pmode); 23371 23372 /* Macro to shorten the code expansions below. */ 23373# define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET) 23374 23375 m_tramp = replace_equiv_address (m_tramp, addr); 23376 23377 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0)); 23378 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize)); 23379 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg); 23380 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg); 23381 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg); 23382 23383# undef MEM_PLUS 23384 } 23385 break; 23386 23387 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */ 23388 case ABI_DARWIN: 23389 case ABI_V4: 23390 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"), 23391 LCT_NORMAL, VOIDmode, 4, 23392 addr, Pmode, 23393 GEN_INT (rs6000_trampoline_size ()), SImode, 23394 fnaddr, Pmode, 23395 ctx_reg, Pmode); 23396 break; 23397 } 23398} 23399 23400 23401/* Handle the "altivec" attribute. The attribute may have 23402 arguments as follows: 23403 23404 __attribute__((altivec(vector__))) 23405 __attribute__((altivec(pixel__))) (always followed by 'unsigned short') 23406 __attribute__((altivec(bool__))) (always followed by 'unsigned') 23407 23408 and may appear more than once (e.g., 'vector bool char') in a 23409 given declaration. */ 23410 23411static tree 23412rs6000_handle_altivec_attribute (tree *node, 23413 tree name ATTRIBUTE_UNUSED, 23414 tree args, 23415 int flags ATTRIBUTE_UNUSED, 23416 bool *no_add_attrs) 23417{ 23418 tree type = *node, result = NULL_TREE; 23419 enum machine_mode mode; 23420 int unsigned_p; 23421 char altivec_type 23422 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args) 23423 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE) 23424 ? *IDENTIFIER_POINTER (TREE_VALUE (args)) 23425 : '?'); 23426 23427 while (POINTER_TYPE_P (type) 23428 || TREE_CODE (type) == FUNCTION_TYPE 23429 || TREE_CODE (type) == METHOD_TYPE 23430 || TREE_CODE (type) == ARRAY_TYPE) 23431 type = TREE_TYPE (type); 23432 23433 mode = TYPE_MODE (type); 23434 23435 /* Check for invalid AltiVec type qualifiers. */ 23436 if (type == long_double_type_node) 23437 error ("use of %<long double%> in AltiVec types is invalid"); 23438 else if (type == boolean_type_node) 23439 error ("use of boolean types in AltiVec types is invalid"); 23440 else if (TREE_CODE (type) == COMPLEX_TYPE) 23441 error ("use of %<complex%> in AltiVec types is invalid"); 23442 else if (DECIMAL_FLOAT_MODE_P (mode)) 23443 error ("use of decimal floating point types in AltiVec types is invalid"); 23444 else if (!TARGET_VSX) 23445 { 23446 if (type == long_unsigned_type_node || type == long_integer_type_node) 23447 { 23448 if (TARGET_64BIT) 23449 error ("use of %<long%> in AltiVec types is invalid for " 23450 "64-bit code without -mvsx"); 23451 else if (rs6000_warn_altivec_long) 23452 warning (0, "use of %<long%> in AltiVec types is deprecated; " 23453 "use %<int%>"); 23454 } 23455 else if (type == long_long_unsigned_type_node 23456 || type == long_long_integer_type_node) 23457 error ("use of %<long long%> in AltiVec types is invalid without " 23458 "-mvsx"); 23459 else if (type == double_type_node) 23460 error ("use of %<double%> in AltiVec types is invalid without -mvsx"); 23461 } 23462 23463 switch (altivec_type) 23464 { 23465 case 'v': 23466 unsigned_p = TYPE_UNSIGNED (type); 23467 switch (mode) 23468 { 23469 case DImode: 23470 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node); 23471 break; 23472 case SImode: 23473 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node); 23474 break; 23475 case HImode: 23476 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node); 23477 break; 23478 case QImode: 23479 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node); 23480 break; 23481 case SFmode: result = V4SF_type_node; break; 23482 case DFmode: result = V2DF_type_node; break; 23483 /* If the user says 'vector int bool', we may be handed the 'bool' 23484 attribute _before_ the 'vector' attribute, and so select the 23485 proper type in the 'b' case below. */ 23486 case V4SImode: case V8HImode: case V16QImode: case V4SFmode: 23487 case V2DImode: case V2DFmode: 23488 result = type; 23489 default: break; 23490 } 23491 break; 23492 case 'b': 23493 switch (mode) 23494 { 23495 case DImode: case V2DImode: result = bool_V2DI_type_node; break; 23496 case SImode: case V4SImode: result = bool_V4SI_type_node; break; 23497 case HImode: case V8HImode: result = bool_V8HI_type_node; break; 23498 case QImode: case V16QImode: result = bool_V16QI_type_node; 23499 default: break; 23500 } 23501 break; 23502 case 'p': 23503 switch (mode) 23504 { 23505 case V8HImode: result = pixel_V8HI_type_node; 23506 default: break; 23507 } 23508 default: break; 23509 } 23510 23511 /* Propagate qualifiers attached to the element type 23512 onto the vector type. */ 23513 if (result && result != type && TYPE_QUALS (type)) 23514 result = build_qualified_type (result, TYPE_QUALS (type)); 23515 23516 *no_add_attrs = true; /* No need to hang on to the attribute. */ 23517 23518 if (result) 23519 *node = lang_hooks.types.reconstruct_complex_type (*node, result); 23520 23521 return NULL_TREE; 23522} 23523 23524/* AltiVec defines four built-in scalar types that serve as vector 23525 elements; we must teach the compiler how to mangle them. */ 23526 23527static const char * 23528rs6000_mangle_type (const_tree type) 23529{ 23530 type = TYPE_MAIN_VARIANT (type); 23531 23532 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE 23533 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE) 23534 return NULL; 23535 23536 if (type == bool_char_type_node) return "U6__boolc"; 23537 if (type == bool_short_type_node) return "U6__bools"; 23538 if (type == pixel_type_node) return "u7__pixel"; 23539 if (type == bool_int_type_node) return "U6__booli"; 23540 if (type == bool_long_type_node) return "U6__booll"; 23541 23542 /* Mangle IBM extended float long double as `g' (__float128) on 23543 powerpc*-linux where long-double-64 previously was the default. */ 23544 if (TYPE_MAIN_VARIANT (type) == long_double_type_node 23545 && TARGET_ELF 23546 && TARGET_LONG_DOUBLE_128 23547 && !TARGET_IEEEQUAD) 23548 return "g"; 23549 23550 /* For all other types, use normal C++ mangling. */ 23551 return NULL; 23552} 23553 23554/* Handle a "longcall" or "shortcall" attribute; arguments as in 23555 struct attribute_spec.handler. */ 23556 23557static tree 23558rs6000_handle_longcall_attribute (tree *node, tree name, 23559 tree args ATTRIBUTE_UNUSED, 23560 int flags ATTRIBUTE_UNUSED, 23561 bool *no_add_attrs) 23562{ 23563 if (TREE_CODE (*node) != FUNCTION_TYPE 23564 && TREE_CODE (*node) != FIELD_DECL 23565 && TREE_CODE (*node) != TYPE_DECL) 23566 { 23567 warning (OPT_Wattributes, "%qE attribute only applies to functions", 23568 name); 23569 *no_add_attrs = true; 23570 } 23571 23572 return NULL_TREE; 23573} 23574 23575/* Set longcall attributes on all functions declared when 23576 rs6000_default_long_calls is true. */ 23577static void 23578rs6000_set_default_type_attributes (tree type) 23579{ 23580 if (rs6000_default_long_calls 23581 && (TREE_CODE (type) == FUNCTION_TYPE 23582 || TREE_CODE (type) == METHOD_TYPE)) 23583 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"), 23584 NULL_TREE, 23585 TYPE_ATTRIBUTES (type)); 23586 23587#if TARGET_MACHO 23588 darwin_set_default_type_attributes (type); 23589#endif 23590} 23591 23592/* Return a reference suitable for calling a function with the 23593 longcall attribute. */ 23594 23595rtx 23596rs6000_longcall_ref (rtx call_ref) 23597{ 23598 const char *call_name; 23599 tree node; 23600 23601 if (GET_CODE (call_ref) != SYMBOL_REF) 23602 return call_ref; 23603 23604 /* System V adds '.' to the internal name, so skip them. */ 23605 call_name = XSTR (call_ref, 0); 23606 if (*call_name == '.') 23607 { 23608 while (*call_name == '.') 23609 call_name++; 23610 23611 node = get_identifier (call_name); 23612 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node)); 23613 } 23614 23615 return force_reg (Pmode, call_ref); 23616} 23617 23618#ifndef TARGET_USE_MS_BITFIELD_LAYOUT 23619#define TARGET_USE_MS_BITFIELD_LAYOUT 0 23620#endif 23621 23622/* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in 23623 struct attribute_spec.handler. */ 23624static tree 23625rs6000_handle_struct_attribute (tree *node, tree name, 23626 tree args ATTRIBUTE_UNUSED, 23627 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs) 23628{ 23629 tree *type = NULL; 23630 if (DECL_P (*node)) 23631 { 23632 if (TREE_CODE (*node) == TYPE_DECL) 23633 type = &TREE_TYPE (*node); 23634 } 23635 else 23636 type = node; 23637 23638 if (!(type && (TREE_CODE (*type) == RECORD_TYPE 23639 || TREE_CODE (*type) == UNION_TYPE))) 23640 { 23641 warning (OPT_Wattributes, "%qE attribute ignored", name); 23642 *no_add_attrs = true; 23643 } 23644 23645 else if ((is_attribute_p ("ms_struct", name) 23646 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type))) 23647 || ((is_attribute_p ("gcc_struct", name) 23648 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type))))) 23649 { 23650 warning (OPT_Wattributes, "%qE incompatible attribute ignored", 23651 name); 23652 *no_add_attrs = true; 23653 } 23654 23655 return NULL_TREE; 23656} 23657 23658static bool 23659rs6000_ms_bitfield_layout_p (const_tree record_type) 23660{ 23661 return (TARGET_USE_MS_BITFIELD_LAYOUT && 23662 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type))) 23663 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type)); 23664} 23665 23666#ifdef USING_ELFOS_H 23667 23668/* A get_unnamed_section callback, used for switching to toc_section. */ 23669 23670static void 23671rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED) 23672{ 23673 if (DEFAULT_ABI == ABI_AIX 23674 && TARGET_MINIMAL_TOC 23675 && !TARGET_RELOCATABLE) 23676 { 23677 if (!toc_initialized) 23678 { 23679 toc_initialized = 1; 23680 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP); 23681 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0); 23682 fprintf (asm_out_file, "\t.tc "); 23683 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],"); 23684 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1"); 23685 fprintf (asm_out_file, "\n"); 23686 23687 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); 23688 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1"); 23689 fprintf (asm_out_file, " = .+32768\n"); 23690 } 23691 else 23692 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); 23693 } 23694 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE) 23695 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP); 23696 else 23697 { 23698 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); 23699 if (!toc_initialized) 23700 { 23701 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1"); 23702 fprintf (asm_out_file, " = .+32768\n"); 23703 toc_initialized = 1; 23704 } 23705 } 23706} 23707 23708/* Implement TARGET_ASM_INIT_SECTIONS. */ 23709 23710static void 23711rs6000_elf_asm_init_sections (void) 23712{ 23713 toc_section 23714 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL); 23715 23716 sdata2_section 23717 = get_unnamed_section (SECTION_WRITE, output_section_asm_op, 23718 SDATA2_SECTION_ASM_OP); 23719} 23720 23721/* Implement TARGET_SELECT_RTX_SECTION. */ 23722 23723static section * 23724rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x, 23725 unsigned HOST_WIDE_INT align) 23726{ 23727 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode)) 23728 return toc_section; 23729 else 23730 return default_elf_select_rtx_section (mode, x, align); 23731} 23732 23733/* For a SYMBOL_REF, set generic flags and then perform some 23734 target-specific processing. 23735 23736 When the AIX ABI is requested on a non-AIX system, replace the 23737 function name with the real name (with a leading .) rather than the 23738 function descriptor name. This saves a lot of overriding code to 23739 read the prefixes. */ 23740 23741static void 23742rs6000_elf_encode_section_info (tree decl, rtx rtl, int first) 23743{ 23744 default_encode_section_info (decl, rtl, first); 23745 23746 if (first 23747 && TREE_CODE (decl) == FUNCTION_DECL 23748 && !TARGET_AIX 23749 && DEFAULT_ABI == ABI_AIX) 23750 { 23751 rtx sym_ref = XEXP (rtl, 0); 23752 size_t len = strlen (XSTR (sym_ref, 0)); 23753 char *str = XALLOCAVEC (char, len + 2); 23754 str[0] = '.'; 23755 memcpy (str + 1, XSTR (sym_ref, 0), len + 1); 23756 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1); 23757 } 23758} 23759 23760static inline bool 23761compare_section_name (const char *section, const char *templ) 23762{ 23763 int len; 23764 23765 len = strlen (templ); 23766 return (strncmp (section, templ, len) == 0 23767 && (section[len] == 0 || section[len] == '.')); 23768} 23769 23770bool 23771rs6000_elf_in_small_data_p (const_tree decl) 23772{ 23773 if (rs6000_sdata == SDATA_NONE) 23774 return false; 23775 23776 /* We want to merge strings, so we never consider them small data. */ 23777 if (TREE_CODE (decl) == STRING_CST) 23778 return false; 23779 23780 /* Functions are never in the small data area. */ 23781 if (TREE_CODE (decl) == FUNCTION_DECL) 23782 return false; 23783 23784 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl)) 23785 { 23786 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl)); 23787 if (compare_section_name (section, ".sdata") 23788 || compare_section_name (section, ".sdata2") 23789 || compare_section_name (section, ".gnu.linkonce.s") 23790 || compare_section_name (section, ".sbss") 23791 || compare_section_name (section, ".sbss2") 23792 || compare_section_name (section, ".gnu.linkonce.sb") 23793 || strcmp (section, ".PPC.EMB.sdata0") == 0 23794 || strcmp (section, ".PPC.EMB.sbss0") == 0) 23795 return true; 23796 } 23797 else 23798 { 23799 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl)); 23800 23801 if (size > 0 23802 && (unsigned HOST_WIDE_INT) size <= g_switch_value 23803 /* If it's not public, and we're not going to reference it there, 23804 there's no need to put it in the small data section. */ 23805 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl))) 23806 return true; 23807 } 23808 23809 return false; 23810} 23811 23812#endif /* USING_ELFOS_H */ 23813 23814/* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */ 23815 23816static bool 23817rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x) 23818{ 23819 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode); 23820} 23821 23822/* Return a REG that occurs in ADDR with coefficient 1. 23823 ADDR can be effectively incremented by incrementing REG. 23824 23825 r0 is special and we must not select it as an address 23826 register by this routine since our caller will try to 23827 increment the returned register via an "la" instruction. */ 23828 23829rtx 23830find_addr_reg (rtx addr) 23831{ 23832 while (GET_CODE (addr) == PLUS) 23833 { 23834 if (GET_CODE (XEXP (addr, 0)) == REG 23835 && REGNO (XEXP (addr, 0)) != 0) 23836 addr = XEXP (addr, 0); 23837 else if (GET_CODE (XEXP (addr, 1)) == REG 23838 && REGNO (XEXP (addr, 1)) != 0) 23839 addr = XEXP (addr, 1); 23840 else if (CONSTANT_P (XEXP (addr, 0))) 23841 addr = XEXP (addr, 1); 23842 else if (CONSTANT_P (XEXP (addr, 1))) 23843 addr = XEXP (addr, 0); 23844 else 23845 gcc_unreachable (); 23846 } 23847 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0); 23848 return addr; 23849} 23850 23851void 23852rs6000_fatal_bad_address (rtx op) 23853{ 23854 fatal_insn ("bad address", op); 23855} 23856 23857#if TARGET_MACHO 23858 23859static tree branch_island_list = 0; 23860 23861/* Remember to generate a branch island for far calls to the given 23862 function. */ 23863 23864static void 23865add_compiler_branch_island (tree label_name, tree function_name, 23866 int line_number) 23867{ 23868 tree branch_island = build_tree_list (function_name, label_name); 23869 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number); 23870 TREE_CHAIN (branch_island) = branch_island_list; 23871 branch_island_list = branch_island; 23872} 23873 23874#define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND) 23875#define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND) 23876#define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \ 23877 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND)) 23878 23879/* Generate far-jump branch islands for everything on the 23880 branch_island_list. Invoked immediately after the last instruction 23881 of the epilogue has been emitted; the branch-islands must be 23882 appended to, and contiguous with, the function body. Mach-O stubs 23883 are generated in machopic_output_stub(). */ 23884 23885static void 23886macho_branch_islands (void) 23887{ 23888 char tmp_buf[512]; 23889 tree branch_island; 23890 23891 for (branch_island = branch_island_list; 23892 branch_island; 23893 branch_island = TREE_CHAIN (branch_island)) 23894 { 23895 const char *label = 23896 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island)); 23897 const char *name = 23898 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island)); 23899 char name_buf[512]; 23900 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */ 23901 if (name[0] == '*' || name[0] == '&') 23902 strcpy (name_buf, name+1); 23903 else 23904 { 23905 name_buf[0] = '_'; 23906 strcpy (name_buf+1, name); 23907 } 23908 strcpy (tmp_buf, "\n"); 23909 strcat (tmp_buf, label); 23910#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) 23911 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) 23912 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island)); 23913#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */ 23914 if (flag_pic) 23915 { 23916 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,"); 23917 strcat (tmp_buf, label); 23918 strcat (tmp_buf, "_pic\n"); 23919 strcat (tmp_buf, label); 23920 strcat (tmp_buf, "_pic:\n\tmflr r11\n"); 23921 23922 strcat (tmp_buf, "\taddis r11,r11,ha16("); 23923 strcat (tmp_buf, name_buf); 23924 strcat (tmp_buf, " - "); 23925 strcat (tmp_buf, label); 23926 strcat (tmp_buf, "_pic)\n"); 23927 23928 strcat (tmp_buf, "\tmtlr r0\n"); 23929 23930 strcat (tmp_buf, "\taddi r12,r11,lo16("); 23931 strcat (tmp_buf, name_buf); 23932 strcat (tmp_buf, " - "); 23933 strcat (tmp_buf, label); 23934 strcat (tmp_buf, "_pic)\n"); 23935 23936 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n"); 23937 } 23938 else 23939 { 23940 strcat (tmp_buf, ":\nlis r12,hi16("); 23941 strcat (tmp_buf, name_buf); 23942 strcat (tmp_buf, ")\n\tori r12,r12,lo16("); 23943 strcat (tmp_buf, name_buf); 23944 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr"); 23945 } 23946 output_asm_insn (tmp_buf, 0); 23947#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) 23948 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) 23949 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island)); 23950#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */ 23951 } 23952 23953 branch_island_list = 0; 23954} 23955 23956/* NO_PREVIOUS_DEF checks in the link list whether the function name is 23957 already there or not. */ 23958 23959static int 23960no_previous_def (tree function_name) 23961{ 23962 tree branch_island; 23963 for (branch_island = branch_island_list; 23964 branch_island; 23965 branch_island = TREE_CHAIN (branch_island)) 23966 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island)) 23967 return 0; 23968 return 1; 23969} 23970 23971/* GET_PREV_LABEL gets the label name from the previous definition of 23972 the function. */ 23973 23974static tree 23975get_prev_label (tree function_name) 23976{ 23977 tree branch_island; 23978 for (branch_island = branch_island_list; 23979 branch_island; 23980 branch_island = TREE_CHAIN (branch_island)) 23981 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island)) 23982 return BRANCH_ISLAND_LABEL_NAME (branch_island); 23983 return 0; 23984} 23985 23986#ifndef DARWIN_LINKER_GENERATES_ISLANDS 23987#define DARWIN_LINKER_GENERATES_ISLANDS 0 23988#endif 23989 23990/* KEXTs still need branch islands. */ 23991#define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \ 23992 || flag_mkernel || flag_apple_kext) 23993 23994/* INSN is either a function call or a millicode call. It may have an 23995 unconditional jump in its delay slot. 23996 23997 CALL_DEST is the routine we are calling. */ 23998 23999char * 24000output_call (rtx insn, rtx *operands, int dest_operand_number, 24001 int cookie_operand_number) 24002{ 24003 static char buf[256]; 24004 if (DARWIN_GENERATE_ISLANDS 24005 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF 24006 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG)) 24007 { 24008 tree labelname; 24009 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0)); 24010 24011 if (no_previous_def (funname)) 24012 { 24013 rtx label_rtx = gen_label_rtx (); 24014 char *label_buf, temp_buf[256]; 24015 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L", 24016 CODE_LABEL_NUMBER (label_rtx)); 24017 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf; 24018 labelname = get_identifier (label_buf); 24019 add_compiler_branch_island (labelname, funname, insn_line (insn)); 24020 } 24021 else 24022 labelname = get_prev_label (funname); 24023 24024 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl' 24025 instruction will reach 'foo', otherwise link as 'bl L42'". 24026 "L42" should be a 'branch island', that will do a far jump to 24027 'foo'. Branch islands are generated in 24028 macho_branch_islands(). */ 24029 sprintf (buf, "jbsr %%z%d,%.246s", 24030 dest_operand_number, IDENTIFIER_POINTER (labelname)); 24031 } 24032 else 24033 sprintf (buf, "bl %%z%d", dest_operand_number); 24034 return buf; 24035} 24036 24037/* Generate PIC and indirect symbol stubs. */ 24038 24039void 24040machopic_output_stub (FILE *file, const char *symb, const char *stub) 24041{ 24042 unsigned int length; 24043 char *symbol_name, *lazy_ptr_name; 24044 char *local_label_0; 24045 static int label = 0; 24046 24047 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */ 24048 symb = (*targetm.strip_name_encoding) (symb); 24049 24050 24051 length = strlen (symb); 24052 symbol_name = XALLOCAVEC (char, length + 32); 24053 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length); 24054 24055 lazy_ptr_name = XALLOCAVEC (char, length + 32); 24056 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length); 24057 24058 if (flag_pic == 2) 24059 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]); 24060 else 24061 switch_to_section (darwin_sections[machopic_symbol_stub1_section]); 24062 24063 if (flag_pic == 2) 24064 { 24065 fprintf (file, "\t.align 5\n"); 24066 24067 fprintf (file, "%s:\n", stub); 24068 fprintf (file, "\t.indirect_symbol %s\n", symbol_name); 24069 24070 label++; 24071 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\"")); 24072 sprintf (local_label_0, "\"L%011d$spb\"", label); 24073 24074 fprintf (file, "\tmflr r0\n"); 24075 fprintf (file, "\tbcl 20,31,%s\n", local_label_0); 24076 fprintf (file, "%s:\n\tmflr r11\n", local_label_0); 24077 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n", 24078 lazy_ptr_name, local_label_0); 24079 fprintf (file, "\tmtlr r0\n"); 24080 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n", 24081 (TARGET_64BIT ? "ldu" : "lwzu"), 24082 lazy_ptr_name, local_label_0); 24083 fprintf (file, "\tmtctr r12\n"); 24084 fprintf (file, "\tbctr\n"); 24085 } 24086 else 24087 { 24088 fprintf (file, "\t.align 4\n"); 24089 24090 fprintf (file, "%s:\n", stub); 24091 fprintf (file, "\t.indirect_symbol %s\n", symbol_name); 24092 24093 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name); 24094 fprintf (file, "\t%s r12,lo16(%s)(r11)\n", 24095 (TARGET_64BIT ? "ldu" : "lwzu"), 24096 lazy_ptr_name); 24097 fprintf (file, "\tmtctr r12\n"); 24098 fprintf (file, "\tbctr\n"); 24099 } 24100 24101 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]); 24102 fprintf (file, "%s:\n", lazy_ptr_name); 24103 fprintf (file, "\t.indirect_symbol %s\n", symbol_name); 24104 fprintf (file, "%sdyld_stub_binding_helper\n", 24105 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t")); 24106} 24107 24108/* Legitimize PIC addresses. If the address is already 24109 position-independent, we return ORIG. Newly generated 24110 position-independent addresses go into a reg. This is REG if non 24111 zero, otherwise we allocate register(s) as necessary. */ 24112 24113#define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000) 24114 24115rtx 24116rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, 24117 rtx reg) 24118{ 24119 rtx base, offset; 24120 24121 if (reg == NULL && ! reload_in_progress && ! reload_completed) 24122 reg = gen_reg_rtx (Pmode); 24123 24124 if (GET_CODE (orig) == CONST) 24125 { 24126 rtx reg_temp; 24127 24128 if (GET_CODE (XEXP (orig, 0)) == PLUS 24129 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx) 24130 return orig; 24131 24132 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS); 24133 24134 /* Use a different reg for the intermediate value, as 24135 it will be marked UNCHANGING. */ 24136 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode); 24137 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0), 24138 Pmode, reg_temp); 24139 offset = 24140 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1), 24141 Pmode, reg); 24142 24143 if (GET_CODE (offset) == CONST_INT) 24144 { 24145 if (SMALL_INT (offset)) 24146 return plus_constant (base, INTVAL (offset)); 24147 else if (! reload_in_progress && ! reload_completed) 24148 offset = force_reg (Pmode, offset); 24149 else 24150 { 24151 rtx mem = force_const_mem (Pmode, orig); 24152 return machopic_legitimize_pic_address (mem, Pmode, reg); 24153 } 24154 } 24155 return gen_rtx_PLUS (Pmode, base, offset); 24156 } 24157 24158 /* Fall back on generic machopic code. */ 24159 return machopic_legitimize_pic_address (orig, mode, reg); 24160} 24161 24162/* Output a .machine directive for the Darwin assembler, and call 24163 the generic start_file routine. */ 24164 24165static void 24166rs6000_darwin_file_start (void) 24167{ 24168 static const struct 24169 { 24170 const char *arg; 24171 const char *name; 24172 int if_set; 24173 } mapping[] = { 24174 { "ppc64", "ppc64", MASK_64BIT }, 24175 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 }, 24176 { "power4", "ppc970", 0 }, 24177 { "G5", "ppc970", 0 }, 24178 { "7450", "ppc7450", 0 }, 24179 { "7400", "ppc7400", MASK_ALTIVEC }, 24180 { "G4", "ppc7400", 0 }, 24181 { "750", "ppc750", 0 }, 24182 { "740", "ppc750", 0 }, 24183 { "G3", "ppc750", 0 }, 24184 { "604e", "ppc604e", 0 }, 24185 { "604", "ppc604", 0 }, 24186 { "603e", "ppc603", 0 }, 24187 { "603", "ppc603", 0 }, 24188 { "601", "ppc601", 0 }, 24189 { NULL, "ppc", 0 } }; 24190 const char *cpu_id = ""; 24191 size_t i; 24192 24193 rs6000_file_start (); 24194 darwin_file_start (); 24195 24196 /* Determine the argument to -mcpu=. Default to G3 if not specified. */ 24197 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++) 24198 if (rs6000_select[i].set_arch_p && rs6000_select[i].string 24199 && rs6000_select[i].string[0] != '\0') 24200 cpu_id = rs6000_select[i].string; 24201 24202 /* Look through the mapping array. Pick the first name that either 24203 matches the argument, has a bit set in IF_SET that is also set 24204 in the target flags, or has a NULL name. */ 24205 24206 i = 0; 24207 while (mapping[i].arg != NULL 24208 && strcmp (mapping[i].arg, cpu_id) != 0 24209 && (mapping[i].if_set & target_flags) == 0) 24210 i++; 24211 24212 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name); 24213} 24214 24215#endif /* TARGET_MACHO */ 24216 24217#if TARGET_ELF 24218static int 24219rs6000_elf_reloc_rw_mask (void) 24220{ 24221 if (flag_pic) 24222 return 3; 24223 else if (DEFAULT_ABI == ABI_AIX) 24224 return 2; 24225 else 24226 return 0; 24227} 24228 24229/* Record an element in the table of global constructors. SYMBOL is 24230 a SYMBOL_REF of the function to be called; PRIORITY is a number 24231 between 0 and MAX_INIT_PRIORITY. 24232 24233 This differs from default_named_section_asm_out_constructor in 24234 that we have special handling for -mrelocatable. */ 24235 24236static void 24237rs6000_elf_asm_out_constructor (rtx symbol, int priority) 24238{ 24239 const char *section = ".ctors"; 24240 char buf[16]; 24241 24242 if (priority != DEFAULT_INIT_PRIORITY) 24243 { 24244 sprintf (buf, ".ctors.%.5u", 24245 /* Invert the numbering so the linker puts us in the proper 24246 order; constructors are run from right to left, and the 24247 linker sorts in increasing order. */ 24248 MAX_INIT_PRIORITY - priority); 24249 section = buf; 24250 } 24251 24252 switch_to_section (get_section (section, SECTION_WRITE, NULL)); 24253 assemble_align (POINTER_SIZE); 24254 24255 if (TARGET_RELOCATABLE) 24256 { 24257 fputs ("\t.long (", asm_out_file); 24258 output_addr_const (asm_out_file, symbol); 24259 fputs (")@fixup\n", asm_out_file); 24260 } 24261 else 24262 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1); 24263} 24264 24265static void 24266rs6000_elf_asm_out_destructor (rtx symbol, int priority) 24267{ 24268 const char *section = ".dtors"; 24269 char buf[16]; 24270 24271 if (priority != DEFAULT_INIT_PRIORITY) 24272 { 24273 sprintf (buf, ".dtors.%.5u", 24274 /* Invert the numbering so the linker puts us in the proper 24275 order; constructors are run from right to left, and the 24276 linker sorts in increasing order. */ 24277 MAX_INIT_PRIORITY - priority); 24278 section = buf; 24279 } 24280 24281 switch_to_section (get_section (section, SECTION_WRITE, NULL)); 24282 assemble_align (POINTER_SIZE); 24283 24284 if (TARGET_RELOCATABLE) 24285 { 24286 fputs ("\t.long (", asm_out_file); 24287 output_addr_const (asm_out_file, symbol); 24288 fputs (")@fixup\n", asm_out_file); 24289 } 24290 else 24291 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1); 24292} 24293 24294void 24295rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl) 24296{ 24297 if (TARGET_64BIT) 24298 { 24299 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file); 24300 ASM_OUTPUT_LABEL (file, name); 24301 fputs (DOUBLE_INT_ASM_OP, file); 24302 rs6000_output_function_entry (file, name); 24303 fputs (",.TOC.@tocbase,0\n\t.previous\n", file); 24304 if (DOT_SYMBOLS) 24305 { 24306 fputs ("\t.size\t", file); 24307 assemble_name (file, name); 24308 fputs (",24\n\t.type\t.", file); 24309 assemble_name (file, name); 24310 fputs (",@function\n", file); 24311 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl)) 24312 { 24313 fputs ("\t.globl\t.", file); 24314 assemble_name (file, name); 24315 putc ('\n', file); 24316 } 24317 } 24318 else 24319 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function"); 24320 ASM_DECLARE_RESULT (file, DECL_RESULT (decl)); 24321 rs6000_output_function_entry (file, name); 24322 fputs (":\n", file); 24323 return; 24324 } 24325 24326 if (TARGET_RELOCATABLE 24327 && !TARGET_SECURE_PLT 24328 && (get_pool_size () != 0 || crtl->profile) 24329 && uses_TOC ()) 24330 { 24331 char buf[256]; 24332 24333 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno); 24334 24335 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1); 24336 fprintf (file, "\t.long "); 24337 assemble_name (file, buf); 24338 putc ('-', file); 24339 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); 24340 assemble_name (file, buf); 24341 putc ('\n', file); 24342 } 24343 24344 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function"); 24345 ASM_DECLARE_RESULT (file, DECL_RESULT (decl)); 24346 24347 if (DEFAULT_ABI == ABI_AIX) 24348 { 24349 const char *desc_name, *orig_name; 24350 24351 orig_name = (*targetm.strip_name_encoding) (name); 24352 desc_name = orig_name; 24353 while (*desc_name == '.') 24354 desc_name++; 24355 24356 if (TREE_PUBLIC (decl)) 24357 fprintf (file, "\t.globl %s\n", desc_name); 24358 24359 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); 24360 fprintf (file, "%s:\n", desc_name); 24361 fprintf (file, "\t.long %s\n", orig_name); 24362 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file); 24363 if (DEFAULT_ABI == ABI_AIX) 24364 fputs ("\t.long 0\n", file); 24365 fprintf (file, "\t.previous\n"); 24366 } 24367 ASM_OUTPUT_LABEL (file, name); 24368} 24369 24370static void 24371rs6000_elf_end_indicate_exec_stack (void) 24372{ 24373 if (TARGET_32BIT) 24374 file_end_indicate_exec_stack (); 24375} 24376#endif 24377 24378#if TARGET_XCOFF 24379static void 24380rs6000_xcoff_asm_output_anchor (rtx symbol) 24381{ 24382 char buffer[100]; 24383 24384 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC, 24385 SYMBOL_REF_BLOCK_OFFSET (symbol)); 24386 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer); 24387} 24388 24389static void 24390rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name) 24391{ 24392 fputs (GLOBAL_ASM_OP, stream); 24393 RS6000_OUTPUT_BASENAME (stream, name); 24394 putc ('\n', stream); 24395} 24396 24397/* A get_unnamed_decl callback, used for read-only sections. PTR 24398 points to the section string variable. */ 24399 24400static void 24401rs6000_xcoff_output_readonly_section_asm_op (const void *directive) 24402{ 24403 fprintf (asm_out_file, "\t.csect %s[RO],%s\n", 24404 *(const char *const *) directive, 24405 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR); 24406} 24407 24408/* Likewise for read-write sections. */ 24409 24410static void 24411rs6000_xcoff_output_readwrite_section_asm_op (const void *directive) 24412{ 24413 fprintf (asm_out_file, "\t.csect %s[RW],%s\n", 24414 *(const char *const *) directive, 24415 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR); 24416} 24417 24418/* A get_unnamed_section callback, used for switching to toc_section. */ 24419 24420static void 24421rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED) 24422{ 24423 if (TARGET_MINIMAL_TOC) 24424 { 24425 /* toc_section is always selected at least once from 24426 rs6000_xcoff_file_start, so this is guaranteed to 24427 always be defined once and only once in each file. */ 24428 if (!toc_initialized) 24429 { 24430 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file); 24431 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file); 24432 toc_initialized = 1; 24433 } 24434 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n", 24435 (TARGET_32BIT ? "" : ",3")); 24436 } 24437 else 24438 fputs ("\t.toc\n", asm_out_file); 24439} 24440 24441/* Implement TARGET_ASM_INIT_SECTIONS. */ 24442 24443static void 24444rs6000_xcoff_asm_init_sections (void) 24445{ 24446 read_only_data_section 24447 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op, 24448 &xcoff_read_only_section_name); 24449 24450 private_data_section 24451 = get_unnamed_section (SECTION_WRITE, 24452 rs6000_xcoff_output_readwrite_section_asm_op, 24453 &xcoff_private_data_section_name); 24454 24455 read_only_private_data_section 24456 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op, 24457 &xcoff_private_data_section_name); 24458 24459 toc_section 24460 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL); 24461 24462 readonly_data_section = read_only_data_section; 24463 exception_section = data_section; 24464} 24465 24466static int 24467rs6000_xcoff_reloc_rw_mask (void) 24468{ 24469 return 3; 24470} 24471 24472static void 24473rs6000_xcoff_asm_named_section (const char *name, unsigned int flags, 24474 tree decl ATTRIBUTE_UNUSED) 24475{ 24476 int smclass; 24477 static const char * const suffix[3] = { "PR", "RO", "RW" }; 24478 24479 if (flags & SECTION_CODE) 24480 smclass = 0; 24481 else if (flags & SECTION_WRITE) 24482 smclass = 2; 24483 else 24484 smclass = 1; 24485 24486 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n", 24487 (flags & SECTION_CODE) ? "." : "", 24488 name, suffix[smclass], flags & SECTION_ENTSIZE); 24489} 24490 24491static section * 24492rs6000_xcoff_select_section (tree decl, int reloc, 24493 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED) 24494{ 24495 if (decl_readonly_section (decl, reloc)) 24496 { 24497 if (TREE_PUBLIC (decl)) 24498 return read_only_data_section; 24499 else 24500 return read_only_private_data_section; 24501 } 24502 else 24503 { 24504 if (TREE_PUBLIC (decl)) 24505 return data_section; 24506 else 24507 return private_data_section; 24508 } 24509} 24510 24511static void 24512rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED) 24513{ 24514 const char *name; 24515 24516 /* Use select_section for private and uninitialized data. */ 24517 if (!TREE_PUBLIC (decl) 24518 || DECL_COMMON (decl) 24519 || DECL_INITIAL (decl) == NULL_TREE 24520 || DECL_INITIAL (decl) == error_mark_node 24521 || (flag_zero_initialized_in_bss 24522 && initializer_zerop (DECL_INITIAL (decl)))) 24523 return; 24524 24525 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); 24526 name = (*targetm.strip_name_encoding) (name); 24527 DECL_SECTION_NAME (decl) = build_string (strlen (name), name); 24528} 24529 24530/* Select section for constant in constant pool. 24531 24532 On RS/6000, all constants are in the private read-only data area. 24533 However, if this is being placed in the TOC it must be output as a 24534 toc entry. */ 24535 24536static section * 24537rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x, 24538 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED) 24539{ 24540 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode)) 24541 return toc_section; 24542 else 24543 return read_only_private_data_section; 24544} 24545 24546/* Remove any trailing [DS] or the like from the symbol name. */ 24547 24548static const char * 24549rs6000_xcoff_strip_name_encoding (const char *name) 24550{ 24551 size_t len; 24552 if (*name == '*') 24553 name++; 24554 len = strlen (name); 24555 if (name[len - 1] == ']') 24556 return ggc_alloc_string (name, len - 4); 24557 else 24558 return name; 24559} 24560 24561/* Section attributes. AIX is always PIC. */ 24562 24563static unsigned int 24564rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc) 24565{ 24566 unsigned int align; 24567 unsigned int flags = default_section_type_flags (decl, name, reloc); 24568 24569 /* Align to at least UNIT size. */ 24570 if (flags & SECTION_CODE) 24571 align = MIN_UNITS_PER_WORD; 24572 else 24573 /* Increase alignment of large objects if not already stricter. */ 24574 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT), 24575 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD 24576 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD); 24577 24578 return flags | (exact_log2 (align) & SECTION_ENTSIZE); 24579} 24580 24581/* Output at beginning of assembler file. 24582 24583 Initialize the section names for the RS/6000 at this point. 24584 24585 Specify filename, including full path, to assembler. 24586 24587 We want to go into the TOC section so at least one .toc will be emitted. 24588 Also, in order to output proper .bs/.es pairs, we need at least one static 24589 [RW] section emitted. 24590 24591 Finally, declare mcount when profiling to make the assembler happy. */ 24592 24593static void 24594rs6000_xcoff_file_start (void) 24595{ 24596 rs6000_gen_section_name (&xcoff_bss_section_name, 24597 main_input_filename, ".bss_"); 24598 rs6000_gen_section_name (&xcoff_private_data_section_name, 24599 main_input_filename, ".rw_"); 24600 rs6000_gen_section_name (&xcoff_read_only_section_name, 24601 main_input_filename, ".ro_"); 24602 24603 fputs ("\t.file\t", asm_out_file); 24604 output_quoted_string (asm_out_file, main_input_filename); 24605 fputc ('\n', asm_out_file); 24606 if (write_symbols != NO_DEBUG) 24607 switch_to_section (private_data_section); 24608 switch_to_section (text_section); 24609 if (profile_flag) 24610 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT); 24611 rs6000_file_start (); 24612} 24613 24614/* Output at end of assembler file. 24615 On the RS/6000, referencing data should automatically pull in text. */ 24616 24617static void 24618rs6000_xcoff_file_end (void) 24619{ 24620 switch_to_section (text_section); 24621 fputs ("_section_.text:\n", asm_out_file); 24622 switch_to_section (data_section); 24623 fputs (TARGET_32BIT 24624 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n", 24625 asm_out_file); 24626} 24627#endif /* TARGET_XCOFF */ 24628 24629/* Compute a (partial) cost for rtx X. Return true if the complete 24630 cost has been computed, and false if subexpressions should be 24631 scanned. In either case, *TOTAL contains the cost result. */ 24632 24633static bool 24634rs6000_rtx_costs (rtx x, int code, int outer_code, int *total, 24635 bool speed) 24636{ 24637 enum machine_mode mode = GET_MODE (x); 24638 24639 switch (code) 24640 { 24641 /* On the RS/6000, if it is valid in the insn, it is free. */ 24642 case CONST_INT: 24643 if (((outer_code == SET 24644 || outer_code == PLUS 24645 || outer_code == MINUS) 24646 && (satisfies_constraint_I (x) 24647 || satisfies_constraint_L (x))) 24648 || (outer_code == AND 24649 && (satisfies_constraint_K (x) 24650 || (mode == SImode 24651 ? satisfies_constraint_L (x) 24652 : satisfies_constraint_J (x)) 24653 || mask_operand (x, mode) 24654 || (mode == DImode 24655 && mask64_operand (x, DImode)))) 24656 || ((outer_code == IOR || outer_code == XOR) 24657 && (satisfies_constraint_K (x) 24658 || (mode == SImode 24659 ? satisfies_constraint_L (x) 24660 : satisfies_constraint_J (x)))) 24661 || outer_code == ASHIFT 24662 || outer_code == ASHIFTRT 24663 || outer_code == LSHIFTRT 24664 || outer_code == ROTATE 24665 || outer_code == ROTATERT 24666 || outer_code == ZERO_EXTRACT 24667 || (outer_code == MULT 24668 && satisfies_constraint_I (x)) 24669 || ((outer_code == DIV || outer_code == UDIV 24670 || outer_code == MOD || outer_code == UMOD) 24671 && exact_log2 (INTVAL (x)) >= 0) 24672 || (outer_code == COMPARE 24673 && (satisfies_constraint_I (x) 24674 || satisfies_constraint_K (x))) 24675 || (outer_code == EQ 24676 && (satisfies_constraint_I (x) 24677 || satisfies_constraint_K (x) 24678 || (mode == SImode 24679 ? satisfies_constraint_L (x) 24680 : satisfies_constraint_J (x)))) 24681 || (outer_code == GTU 24682 && satisfies_constraint_I (x)) 24683 || (outer_code == LTU 24684 && satisfies_constraint_P (x))) 24685 { 24686 *total = 0; 24687 return true; 24688 } 24689 else if ((outer_code == PLUS 24690 && reg_or_add_cint_operand (x, VOIDmode)) 24691 || (outer_code == MINUS 24692 && reg_or_sub_cint_operand (x, VOIDmode)) 24693 || ((outer_code == SET 24694 || outer_code == IOR 24695 || outer_code == XOR) 24696 && (INTVAL (x) 24697 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0)) 24698 { 24699 *total = COSTS_N_INSNS (1); 24700 return true; 24701 } 24702 /* FALLTHRU */ 24703 24704 case CONST_DOUBLE: 24705 if (mode == DImode && code == CONST_DOUBLE) 24706 { 24707 if ((outer_code == IOR || outer_code == XOR) 24708 && CONST_DOUBLE_HIGH (x) == 0 24709 && (CONST_DOUBLE_LOW (x) 24710 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0) 24711 { 24712 *total = 0; 24713 return true; 24714 } 24715 else if ((outer_code == AND && and64_2_operand (x, DImode)) 24716 || ((outer_code == SET 24717 || outer_code == IOR 24718 || outer_code == XOR) 24719 && CONST_DOUBLE_HIGH (x) == 0)) 24720 { 24721 *total = COSTS_N_INSNS (1); 24722 return true; 24723 } 24724 } 24725 /* FALLTHRU */ 24726 24727 case CONST: 24728 case HIGH: 24729 case SYMBOL_REF: 24730 case MEM: 24731 /* When optimizing for size, MEM should be slightly more expensive 24732 than generating address, e.g., (plus (reg) (const)). 24733 L1 cache latency is about two instructions. */ 24734 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2); 24735 return true; 24736 24737 case LABEL_REF: 24738 *total = 0; 24739 return true; 24740 24741 case PLUS: 24742 if (mode == DFmode) 24743 { 24744 if (GET_CODE (XEXP (x, 0)) == MULT) 24745 { 24746 /* FNMA accounted in outer NEG. */ 24747 if (outer_code == NEG) 24748 *total = rs6000_cost->dmul - rs6000_cost->fp; 24749 else 24750 *total = rs6000_cost->dmul; 24751 } 24752 else 24753 *total = rs6000_cost->fp; 24754 } 24755 else if (mode == SFmode) 24756 { 24757 /* FNMA accounted in outer NEG. */ 24758 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT) 24759 *total = 0; 24760 else 24761 *total = rs6000_cost->fp; 24762 } 24763 else 24764 *total = COSTS_N_INSNS (1); 24765 return false; 24766 24767 case MINUS: 24768 if (mode == DFmode) 24769 { 24770 if (GET_CODE (XEXP (x, 0)) == MULT 24771 || GET_CODE (XEXP (x, 1)) == MULT) 24772 { 24773 /* FNMA accounted in outer NEG. */ 24774 if (outer_code == NEG) 24775 *total = rs6000_cost->dmul - rs6000_cost->fp; 24776 else 24777 *total = rs6000_cost->dmul; 24778 } 24779 else 24780 *total = rs6000_cost->fp; 24781 } 24782 else if (mode == SFmode) 24783 { 24784 /* FNMA accounted in outer NEG. */ 24785 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT) 24786 *total = 0; 24787 else 24788 *total = rs6000_cost->fp; 24789 } 24790 else 24791 *total = COSTS_N_INSNS (1); 24792 return false; 24793 24794 case MULT: 24795 if (GET_CODE (XEXP (x, 1)) == CONST_INT 24796 && satisfies_constraint_I (XEXP (x, 1))) 24797 { 24798 if (INTVAL (XEXP (x, 1)) >= -256 24799 && INTVAL (XEXP (x, 1)) <= 255) 24800 *total = rs6000_cost->mulsi_const9; 24801 else 24802 *total = rs6000_cost->mulsi_const; 24803 } 24804 /* FMA accounted in outer PLUS/MINUS. */ 24805 else if ((mode == DFmode || mode == SFmode) 24806 && (outer_code == PLUS || outer_code == MINUS)) 24807 *total = 0; 24808 else if (mode == DFmode) 24809 *total = rs6000_cost->dmul; 24810 else if (mode == SFmode) 24811 *total = rs6000_cost->fp; 24812 else if (mode == DImode) 24813 *total = rs6000_cost->muldi; 24814 else 24815 *total = rs6000_cost->mulsi; 24816 return false; 24817 24818 case DIV: 24819 case MOD: 24820 if (FLOAT_MODE_P (mode)) 24821 { 24822 *total = mode == DFmode ? rs6000_cost->ddiv 24823 : rs6000_cost->sdiv; 24824 return false; 24825 } 24826 /* FALLTHRU */ 24827 24828 case UDIV: 24829 case UMOD: 24830 if (GET_CODE (XEXP (x, 1)) == CONST_INT 24831 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0) 24832 { 24833 if (code == DIV || code == MOD) 24834 /* Shift, addze */ 24835 *total = COSTS_N_INSNS (2); 24836 else 24837 /* Shift */ 24838 *total = COSTS_N_INSNS (1); 24839 } 24840 else 24841 { 24842 if (GET_MODE (XEXP (x, 1)) == DImode) 24843 *total = rs6000_cost->divdi; 24844 else 24845 *total = rs6000_cost->divsi; 24846 } 24847 /* Add in shift and subtract for MOD. */ 24848 if (code == MOD || code == UMOD) 24849 *total += COSTS_N_INSNS (2); 24850 return false; 24851 24852 case CTZ: 24853 case FFS: 24854 *total = COSTS_N_INSNS (4); 24855 return false; 24856 24857 case POPCOUNT: 24858 *total = COSTS_N_INSNS (6); 24859 return false; 24860 24861 case NOT: 24862 if (outer_code == AND || outer_code == IOR || outer_code == XOR) 24863 { 24864 *total = 0; 24865 return false; 24866 } 24867 /* FALLTHRU */ 24868 24869 case AND: 24870 case CLZ: 24871 case IOR: 24872 case XOR: 24873 case ZERO_EXTRACT: 24874 *total = COSTS_N_INSNS (1); 24875 return false; 24876 24877 case ASHIFT: 24878 case ASHIFTRT: 24879 case LSHIFTRT: 24880 case ROTATE: 24881 case ROTATERT: 24882 /* Handle mul_highpart. */ 24883 if (outer_code == TRUNCATE 24884 && GET_CODE (XEXP (x, 0)) == MULT) 24885 { 24886 if (mode == DImode) 24887 *total = rs6000_cost->muldi; 24888 else 24889 *total = rs6000_cost->mulsi; 24890 return true; 24891 } 24892 else if (outer_code == AND) 24893 *total = 0; 24894 else 24895 *total = COSTS_N_INSNS (1); 24896 return false; 24897 24898 case SIGN_EXTEND: 24899 case ZERO_EXTEND: 24900 if (GET_CODE (XEXP (x, 0)) == MEM) 24901 *total = 0; 24902 else 24903 *total = COSTS_N_INSNS (1); 24904 return false; 24905 24906 case COMPARE: 24907 case NEG: 24908 case ABS: 24909 if (!FLOAT_MODE_P (mode)) 24910 { 24911 *total = COSTS_N_INSNS (1); 24912 return false; 24913 } 24914 /* FALLTHRU */ 24915 24916 case FLOAT: 24917 case UNSIGNED_FLOAT: 24918 case FIX: 24919 case UNSIGNED_FIX: 24920 case FLOAT_TRUNCATE: 24921 *total = rs6000_cost->fp; 24922 return false; 24923 24924 case FLOAT_EXTEND: 24925 if (mode == DFmode) 24926 *total = 0; 24927 else 24928 *total = rs6000_cost->fp; 24929 return false; 24930 24931 case UNSPEC: 24932 switch (XINT (x, 1)) 24933 { 24934 case UNSPEC_FRSP: 24935 *total = rs6000_cost->fp; 24936 return true; 24937 24938 default: 24939 break; 24940 } 24941 break; 24942 24943 case CALL: 24944 case IF_THEN_ELSE: 24945 if (!speed) 24946 { 24947 *total = COSTS_N_INSNS (1); 24948 return true; 24949 } 24950 else if (FLOAT_MODE_P (mode) 24951 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS) 24952 { 24953 *total = rs6000_cost->fp; 24954 return false; 24955 } 24956 break; 24957 24958 case EQ: 24959 case GTU: 24960 case LTU: 24961 /* Carry bit requires mode == Pmode. 24962 NEG or PLUS already counted so only add one. */ 24963 if (mode == Pmode 24964 && (outer_code == NEG || outer_code == PLUS)) 24965 { 24966 *total = COSTS_N_INSNS (1); 24967 return true; 24968 } 24969 if (outer_code == SET) 24970 { 24971 if (XEXP (x, 1) == const0_rtx) 24972 { 24973 if (TARGET_ISEL && !TARGET_MFCRF) 24974 *total = COSTS_N_INSNS (8); 24975 else 24976 *total = COSTS_N_INSNS (2); 24977 return true; 24978 } 24979 else if (mode == Pmode) 24980 { 24981 *total = COSTS_N_INSNS (3); 24982 return false; 24983 } 24984 } 24985 /* FALLTHRU */ 24986 24987 case GT: 24988 case LT: 24989 case UNORDERED: 24990 if (outer_code == SET && (XEXP (x, 1) == const0_rtx)) 24991 { 24992 if (TARGET_ISEL && !TARGET_MFCRF) 24993 *total = COSTS_N_INSNS (8); 24994 else 24995 *total = COSTS_N_INSNS (2); 24996 return true; 24997 } 24998 /* CC COMPARE. */ 24999 if (outer_code == COMPARE) 25000 { 25001 *total = 0; 25002 return true; 25003 } 25004 break; 25005 25006 default: 25007 break; 25008 } 25009 25010 return false; 25011} 25012 25013/* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */ 25014 25015static bool 25016rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total, 25017 bool speed) 25018{ 25019 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed); 25020 25021 fprintf (stderr, 25022 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, " 25023 "total = %d, speed = %s, x:\n", 25024 ret ? "complete" : "scan inner", 25025 GET_RTX_NAME (code), 25026 GET_RTX_NAME (outer_code), 25027 *total, 25028 speed ? "true" : "false"); 25029 25030 debug_rtx (x); 25031 25032 return ret; 25033} 25034 25035/* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */ 25036 25037static int 25038rs6000_debug_address_cost (rtx x, bool speed) 25039{ 25040 int ret = TARGET_ADDRESS_COST (x, speed); 25041 25042 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n", 25043 ret, speed ? "true" : "false"); 25044 debug_rtx (x); 25045 25046 return ret; 25047} 25048 25049 25050/* A C expression returning the cost of moving data from a register of class 25051 CLASS1 to one of CLASS2. */ 25052 25053int 25054rs6000_register_move_cost (enum machine_mode mode, 25055 enum reg_class from, enum reg_class to) 25056{ 25057 int ret; 25058 25059 /* Moves from/to GENERAL_REGS. */ 25060 if (reg_classes_intersect_p (to, GENERAL_REGS) 25061 || reg_classes_intersect_p (from, GENERAL_REGS)) 25062 { 25063 if (! reg_classes_intersect_p (to, GENERAL_REGS)) 25064 from = to; 25065 25066 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS) 25067 ret = (rs6000_memory_move_cost (mode, from, 0) 25068 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0)); 25069 25070 /* It's more expensive to move CR_REGS than CR0_REGS because of the 25071 shift. */ 25072 else if (from == CR_REGS) 25073 ret = 4; 25074 25075 /* Power6 has slower LR/CTR moves so make them more expensive than 25076 memory in order to bias spills to memory .*/ 25077 else if (rs6000_cpu == PROCESSOR_POWER6 25078 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS)) 25079 ret = 6 * hard_regno_nregs[0][mode]; 25080 25081 else 25082 /* A move will cost one instruction per GPR moved. */ 25083 ret = 2 * hard_regno_nregs[0][mode]; 25084 } 25085 25086 /* If we have VSX, we can easily move between FPR or Altivec registers. */ 25087 else if (VECTOR_UNIT_VSX_P (mode) 25088 && reg_classes_intersect_p (to, VSX_REGS) 25089 && reg_classes_intersect_p (from, VSX_REGS)) 25090 ret = 2 * hard_regno_nregs[32][mode]; 25091 25092 /* Moving between two similar registers is just one instruction. */ 25093 else if (reg_classes_intersect_p (to, from)) 25094 ret = (mode == TFmode || mode == TDmode) ? 4 : 2; 25095 25096 /* Everything else has to go through GENERAL_REGS. */ 25097 else 25098 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to) 25099 + rs6000_register_move_cost (mode, from, GENERAL_REGS)); 25100 25101 if (TARGET_DEBUG_COST) 25102 fprintf (stderr, 25103 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n", 25104 ret, GET_MODE_NAME (mode), reg_class_names[from], 25105 reg_class_names[to]); 25106 25107 return ret; 25108} 25109 25110/* A C expressions returning the cost of moving data of MODE from a register to 25111 or from memory. */ 25112 25113int 25114rs6000_memory_move_cost (enum machine_mode mode, enum reg_class rclass, 25115 int in ATTRIBUTE_UNUSED) 25116{ 25117 int ret; 25118 25119 if (reg_classes_intersect_p (rclass, GENERAL_REGS)) 25120 ret = 4 * hard_regno_nregs[0][mode]; 25121 else if (reg_classes_intersect_p (rclass, FLOAT_REGS)) 25122 ret = 4 * hard_regno_nregs[32][mode]; 25123 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS)) 25124 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode]; 25125 else 25126 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS); 25127 25128 if (TARGET_DEBUG_COST) 25129 fprintf (stderr, 25130 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n", 25131 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in); 25132 25133 return ret; 25134} 25135 25136/* Returns a code for a target-specific builtin that implements 25137 reciprocal of the function, or NULL_TREE if not available. */ 25138 25139static tree 25140rs6000_builtin_reciprocal (unsigned int fn, bool md_fn, 25141 bool sqrt ATTRIBUTE_UNUSED) 25142{ 25143 if (! (TARGET_RECIP && TARGET_PPC_GFXOPT && !optimize_size 25144 && flag_finite_math_only && !flag_trapping_math 25145 && flag_unsafe_math_optimizations)) 25146 return NULL_TREE; 25147 25148 if (md_fn) 25149 return NULL_TREE; 25150 else 25151 switch (fn) 25152 { 25153 case BUILT_IN_SQRTF: 25154 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF]; 25155 25156 default: 25157 return NULL_TREE; 25158 } 25159} 25160 25161/* Newton-Raphson approximation of single-precision floating point divide n/d. 25162 Assumes no trapping math and finite arguments. */ 25163 25164void 25165rs6000_emit_swdivsf (rtx dst, rtx n, rtx d) 25166{ 25167 rtx x0, e0, e1, y1, u0, v0, one; 25168 25169 x0 = gen_reg_rtx (SFmode); 25170 e0 = gen_reg_rtx (SFmode); 25171 e1 = gen_reg_rtx (SFmode); 25172 y1 = gen_reg_rtx (SFmode); 25173 u0 = gen_reg_rtx (SFmode); 25174 v0 = gen_reg_rtx (SFmode); 25175 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode)); 25176 25177 /* x0 = 1./d estimate */ 25178 emit_insn (gen_rtx_SET (VOIDmode, x0, 25179 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d), 25180 UNSPEC_FRES))); 25181 /* e0 = 1. - d * x0 */ 25182 emit_insn (gen_rtx_SET (VOIDmode, e0, 25183 gen_rtx_MINUS (SFmode, one, 25184 gen_rtx_MULT (SFmode, d, x0)))); 25185 /* e1 = e0 + e0 * e0 */ 25186 emit_insn (gen_rtx_SET (VOIDmode, e1, 25187 gen_rtx_PLUS (SFmode, 25188 gen_rtx_MULT (SFmode, e0, e0), e0))); 25189 /* y1 = x0 + e1 * x0 */ 25190 emit_insn (gen_rtx_SET (VOIDmode, y1, 25191 gen_rtx_PLUS (SFmode, 25192 gen_rtx_MULT (SFmode, e1, x0), x0))); 25193 /* u0 = n * y1 */ 25194 emit_insn (gen_rtx_SET (VOIDmode, u0, 25195 gen_rtx_MULT (SFmode, n, y1))); 25196 /* v0 = n - d * u0 */ 25197 emit_insn (gen_rtx_SET (VOIDmode, v0, 25198 gen_rtx_MINUS (SFmode, n, 25199 gen_rtx_MULT (SFmode, d, u0)))); 25200 /* dst = u0 + v0 * y1 */ 25201 emit_insn (gen_rtx_SET (VOIDmode, dst, 25202 gen_rtx_PLUS (SFmode, 25203 gen_rtx_MULT (SFmode, v0, y1), u0))); 25204} 25205 25206/* Newton-Raphson approximation of double-precision floating point divide n/d. 25207 Assumes no trapping math and finite arguments. */ 25208 25209void 25210rs6000_emit_swdivdf (rtx dst, rtx n, rtx d) 25211{ 25212 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one; 25213 25214 x0 = gen_reg_rtx (DFmode); 25215 e0 = gen_reg_rtx (DFmode); 25216 e1 = gen_reg_rtx (DFmode); 25217 e2 = gen_reg_rtx (DFmode); 25218 y1 = gen_reg_rtx (DFmode); 25219 y2 = gen_reg_rtx (DFmode); 25220 y3 = gen_reg_rtx (DFmode); 25221 u0 = gen_reg_rtx (DFmode); 25222 v0 = gen_reg_rtx (DFmode); 25223 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode)); 25224 25225 /* x0 = 1./d estimate */ 25226 emit_insn (gen_rtx_SET (VOIDmode, x0, 25227 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d), 25228 UNSPEC_FRES))); 25229 /* e0 = 1. - d * x0 */ 25230 emit_insn (gen_rtx_SET (VOIDmode, e0, 25231 gen_rtx_MINUS (DFmode, one, 25232 gen_rtx_MULT (SFmode, d, x0)))); 25233 /* y1 = x0 + e0 * x0 */ 25234 emit_insn (gen_rtx_SET (VOIDmode, y1, 25235 gen_rtx_PLUS (DFmode, 25236 gen_rtx_MULT (DFmode, e0, x0), x0))); 25237 /* e1 = e0 * e0 */ 25238 emit_insn (gen_rtx_SET (VOIDmode, e1, 25239 gen_rtx_MULT (DFmode, e0, e0))); 25240 /* y2 = y1 + e1 * y1 */ 25241 emit_insn (gen_rtx_SET (VOIDmode, y2, 25242 gen_rtx_PLUS (DFmode, 25243 gen_rtx_MULT (DFmode, e1, y1), y1))); 25244 /* e2 = e1 * e1 */ 25245 emit_insn (gen_rtx_SET (VOIDmode, e2, 25246 gen_rtx_MULT (DFmode, e1, e1))); 25247 /* y3 = y2 + e2 * y2 */ 25248 emit_insn (gen_rtx_SET (VOIDmode, y3, 25249 gen_rtx_PLUS (DFmode, 25250 gen_rtx_MULT (DFmode, e2, y2), y2))); 25251 /* u0 = n * y3 */ 25252 emit_insn (gen_rtx_SET (VOIDmode, u0, 25253 gen_rtx_MULT (DFmode, n, y3))); 25254 /* v0 = n - d * u0 */ 25255 emit_insn (gen_rtx_SET (VOIDmode, v0, 25256 gen_rtx_MINUS (DFmode, n, 25257 gen_rtx_MULT (DFmode, d, u0)))); 25258 /* dst = u0 + v0 * y3 */ 25259 emit_insn (gen_rtx_SET (VOIDmode, dst, 25260 gen_rtx_PLUS (DFmode, 25261 gen_rtx_MULT (DFmode, v0, y3), u0))); 25262} 25263 25264 25265/* Newton-Raphson approximation of single-precision floating point rsqrt. 25266 Assumes no trapping math and finite arguments. */ 25267 25268void 25269rs6000_emit_swrsqrtsf (rtx dst, rtx src) 25270{ 25271 rtx x0, x1, x2, y1, u0, u1, u2, v0, v1, v2, t0, 25272 half, one, halfthree, c1, cond, label; 25273 25274 x0 = gen_reg_rtx (SFmode); 25275 x1 = gen_reg_rtx (SFmode); 25276 x2 = gen_reg_rtx (SFmode); 25277 y1 = gen_reg_rtx (SFmode); 25278 u0 = gen_reg_rtx (SFmode); 25279 u1 = gen_reg_rtx (SFmode); 25280 u2 = gen_reg_rtx (SFmode); 25281 v0 = gen_reg_rtx (SFmode); 25282 v1 = gen_reg_rtx (SFmode); 25283 v2 = gen_reg_rtx (SFmode); 25284 t0 = gen_reg_rtx (SFmode); 25285 halfthree = gen_reg_rtx (SFmode); 25286 cond = gen_rtx_REG (CCFPmode, CR1_REGNO); 25287 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ()); 25288 25289 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */ 25290 emit_insn (gen_rtx_SET (VOIDmode, t0, 25291 gen_rtx_MULT (SFmode, src, src))); 25292 25293 emit_insn (gen_rtx_SET (VOIDmode, cond, 25294 gen_rtx_COMPARE (CCFPmode, t0, src))); 25295 c1 = gen_rtx_EQ (VOIDmode, cond, const0_rtx); 25296 emit_unlikely_jump (c1, label); 25297 25298 half = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf, SFmode)); 25299 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode)); 25300 25301 /* halfthree = 1.5 = 1.0 + 0.5 */ 25302 emit_insn (gen_rtx_SET (VOIDmode, halfthree, 25303 gen_rtx_PLUS (SFmode, one, half))); 25304 25305 /* x0 = rsqrt estimate */ 25306 emit_insn (gen_rtx_SET (VOIDmode, x0, 25307 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, src), 25308 UNSPEC_RSQRT))); 25309 25310 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */ 25311 emit_insn (gen_rtx_SET (VOIDmode, y1, 25312 gen_rtx_MINUS (SFmode, 25313 gen_rtx_MULT (SFmode, src, halfthree), 25314 src))); 25315 25316 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */ 25317 emit_insn (gen_rtx_SET (VOIDmode, u0, 25318 gen_rtx_MULT (SFmode, x0, x0))); 25319 emit_insn (gen_rtx_SET (VOIDmode, v0, 25320 gen_rtx_MINUS (SFmode, 25321 halfthree, 25322 gen_rtx_MULT (SFmode, y1, u0)))); 25323 emit_insn (gen_rtx_SET (VOIDmode, x1, 25324 gen_rtx_MULT (SFmode, x0, v0))); 25325 25326 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */ 25327 emit_insn (gen_rtx_SET (VOIDmode, u1, 25328 gen_rtx_MULT (SFmode, x1, x1))); 25329 emit_insn (gen_rtx_SET (VOIDmode, v1, 25330 gen_rtx_MINUS (SFmode, 25331 halfthree, 25332 gen_rtx_MULT (SFmode, y1, u1)))); 25333 emit_insn (gen_rtx_SET (VOIDmode, x2, 25334 gen_rtx_MULT (SFmode, x1, v1))); 25335 25336 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */ 25337 emit_insn (gen_rtx_SET (VOIDmode, u2, 25338 gen_rtx_MULT (SFmode, x2, x2))); 25339 emit_insn (gen_rtx_SET (VOIDmode, v2, 25340 gen_rtx_MINUS (SFmode, 25341 halfthree, 25342 gen_rtx_MULT (SFmode, y1, u2)))); 25343 emit_insn (gen_rtx_SET (VOIDmode, dst, 25344 gen_rtx_MULT (SFmode, x2, v2))); 25345 25346 emit_label (XEXP (label, 0)); 25347} 25348 25349/* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD 25350 (Power7) targets. DST is the target, and SRC is the argument operand. */ 25351 25352void 25353rs6000_emit_popcount (rtx dst, rtx src) 25354{ 25355 enum machine_mode mode = GET_MODE (dst); 25356 rtx tmp1, tmp2; 25357 25358 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */ 25359 if (TARGET_POPCNTD) 25360 { 25361 if (mode == SImode) 25362 emit_insn (gen_popcntwsi2 (dst, src)); 25363 else 25364 emit_insn (gen_popcntddi2 (dst, src)); 25365 return; 25366 } 25367 25368 tmp1 = gen_reg_rtx (mode); 25369 25370 if (mode == SImode) 25371 { 25372 emit_insn (gen_popcntbsi2 (tmp1, src)); 25373 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101), 25374 NULL_RTX, 0); 25375 tmp2 = force_reg (SImode, tmp2); 25376 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24))); 25377 } 25378 else 25379 { 25380 emit_insn (gen_popcntbdi2 (tmp1, src)); 25381 tmp2 = expand_mult (DImode, tmp1, 25382 GEN_INT ((HOST_WIDE_INT) 25383 0x01010101 << 32 | 0x01010101), 25384 NULL_RTX, 0); 25385 tmp2 = force_reg (DImode, tmp2); 25386 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56))); 25387 } 25388} 25389 25390 25391/* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the 25392 target, and SRC is the argument operand. */ 25393 25394void 25395rs6000_emit_parity (rtx dst, rtx src) 25396{ 25397 enum machine_mode mode = GET_MODE (dst); 25398 rtx tmp; 25399 25400 tmp = gen_reg_rtx (mode); 25401 if (mode == SImode) 25402 { 25403 /* Is mult+shift >= shift+xor+shift+xor? */ 25404 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3)) 25405 { 25406 rtx tmp1, tmp2, tmp3, tmp4; 25407 25408 tmp1 = gen_reg_rtx (SImode); 25409 emit_insn (gen_popcntbsi2 (tmp1, src)); 25410 25411 tmp2 = gen_reg_rtx (SImode); 25412 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16))); 25413 tmp3 = gen_reg_rtx (SImode); 25414 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2)); 25415 25416 tmp4 = gen_reg_rtx (SImode); 25417 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8))); 25418 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4)); 25419 } 25420 else 25421 rs6000_emit_popcount (tmp, src); 25422 emit_insn (gen_andsi3 (dst, tmp, const1_rtx)); 25423 } 25424 else 25425 { 25426 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */ 25427 if (rs6000_cost->muldi >= COSTS_N_INSNS (5)) 25428 { 25429 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6; 25430 25431 tmp1 = gen_reg_rtx (DImode); 25432 emit_insn (gen_popcntbdi2 (tmp1, src)); 25433 25434 tmp2 = gen_reg_rtx (DImode); 25435 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32))); 25436 tmp3 = gen_reg_rtx (DImode); 25437 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2)); 25438 25439 tmp4 = gen_reg_rtx (DImode); 25440 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16))); 25441 tmp5 = gen_reg_rtx (DImode); 25442 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4)); 25443 25444 tmp6 = gen_reg_rtx (DImode); 25445 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8))); 25446 emit_insn (gen_xordi3 (tmp, tmp5, tmp6)); 25447 } 25448 else 25449 rs6000_emit_popcount (tmp, src); 25450 emit_insn (gen_anddi3 (dst, tmp, const1_rtx)); 25451 } 25452} 25453 25454/* Return an RTX representing where to find the function value of a 25455 function returning MODE. */ 25456static rtx 25457rs6000_complex_function_value (enum machine_mode mode) 25458{ 25459 unsigned int regno; 25460 rtx r1, r2; 25461 enum machine_mode inner = GET_MODE_INNER (mode); 25462 unsigned int inner_bytes = GET_MODE_SIZE (inner); 25463 25464 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS) 25465 regno = FP_ARG_RETURN; 25466 else 25467 { 25468 regno = GP_ARG_RETURN; 25469 25470 /* 32-bit is OK since it'll go in r3/r4. */ 25471 if (TARGET_32BIT && inner_bytes >= 4) 25472 return gen_rtx_REG (mode, regno); 25473 } 25474 25475 if (inner_bytes >= 8) 25476 return gen_rtx_REG (mode, regno); 25477 25478 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno), 25479 const0_rtx); 25480 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1), 25481 GEN_INT (inner_bytes)); 25482 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2)); 25483} 25484 25485/* Target hook for TARGET_FUNCTION_VALUE. 25486 25487 On the SPE, both FPs and vectors are returned in r3. 25488 25489 On RS/6000 an integer value is in r3 and a floating-point value is in 25490 fp1, unless -msoft-float. */ 25491 25492rtx 25493rs6000_function_value (const_tree valtype, 25494 const_tree fn_decl_or_type ATTRIBUTE_UNUSED, 25495 bool outgoing ATTRIBUTE_UNUSED) 25496{ 25497 enum machine_mode mode; 25498 unsigned int regno; 25499 25500 /* Special handling for structs in darwin64. */ 25501 if (rs6000_darwin64_abi 25502 && TYPE_MODE (valtype) == BLKmode 25503 && TREE_CODE (valtype) == RECORD_TYPE 25504 && int_size_in_bytes (valtype) > 0) 25505 { 25506 CUMULATIVE_ARGS valcum; 25507 rtx valret; 25508 25509 valcum.words = 0; 25510 valcum.fregno = FP_ARG_MIN_REG; 25511 valcum.vregno = ALTIVEC_ARG_MIN_REG; 25512 /* Do a trial code generation as if this were going to be passed as 25513 an argument; if any part goes in memory, we return NULL. */ 25514 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true); 25515 if (valret) 25516 return valret; 25517 /* Otherwise fall through to standard ABI rules. */ 25518 } 25519 25520 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode) 25521 { 25522 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */ 25523 return gen_rtx_PARALLEL (DImode, 25524 gen_rtvec (2, 25525 gen_rtx_EXPR_LIST (VOIDmode, 25526 gen_rtx_REG (SImode, GP_ARG_RETURN), 25527 const0_rtx), 25528 gen_rtx_EXPR_LIST (VOIDmode, 25529 gen_rtx_REG (SImode, 25530 GP_ARG_RETURN + 1), 25531 GEN_INT (4)))); 25532 } 25533 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode) 25534 { 25535 return gen_rtx_PARALLEL (DCmode, 25536 gen_rtvec (4, 25537 gen_rtx_EXPR_LIST (VOIDmode, 25538 gen_rtx_REG (SImode, GP_ARG_RETURN), 25539 const0_rtx), 25540 gen_rtx_EXPR_LIST (VOIDmode, 25541 gen_rtx_REG (SImode, 25542 GP_ARG_RETURN + 1), 25543 GEN_INT (4)), 25544 gen_rtx_EXPR_LIST (VOIDmode, 25545 gen_rtx_REG (SImode, 25546 GP_ARG_RETURN + 2), 25547 GEN_INT (8)), 25548 gen_rtx_EXPR_LIST (VOIDmode, 25549 gen_rtx_REG (SImode, 25550 GP_ARG_RETURN + 3), 25551 GEN_INT (12)))); 25552 } 25553 25554 mode = TYPE_MODE (valtype); 25555 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD) 25556 || POINTER_TYPE_P (valtype)) 25557 mode = TARGET_32BIT ? SImode : DImode; 25558 25559 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS) 25560 /* _Decimal128 must use an even/odd register pair. */ 25561 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN; 25562 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS 25563 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT)) 25564 regno = FP_ARG_RETURN; 25565 else if (TREE_CODE (valtype) == COMPLEX_TYPE 25566 && targetm.calls.split_complex_arg) 25567 return rs6000_complex_function_value (mode); 25568 else if (TREE_CODE (valtype) == VECTOR_TYPE 25569 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI 25570 && ALTIVEC_VECTOR_MODE (mode)) 25571 regno = ALTIVEC_ARG_RETURN; 25572 else if (TREE_CODE (valtype) == VECTOR_TYPE 25573 && TARGET_VSX && TARGET_ALTIVEC_ABI 25574 && VSX_VECTOR_MODE (mode)) 25575 regno = ALTIVEC_ARG_RETURN; 25576 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT 25577 && (mode == DFmode || mode == DCmode 25578 || mode == TFmode || mode == TCmode)) 25579 return spe_build_register_parallel (mode, GP_ARG_RETURN); 25580 else 25581 regno = GP_ARG_RETURN; 25582 25583 return gen_rtx_REG (mode, regno); 25584} 25585 25586/* Define how to find the value returned by a library function 25587 assuming the value has mode MODE. */ 25588rtx 25589rs6000_libcall_value (enum machine_mode mode) 25590{ 25591 unsigned int regno; 25592 25593 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode) 25594 { 25595 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */ 25596 return gen_rtx_PARALLEL (DImode, 25597 gen_rtvec (2, 25598 gen_rtx_EXPR_LIST (VOIDmode, 25599 gen_rtx_REG (SImode, GP_ARG_RETURN), 25600 const0_rtx), 25601 gen_rtx_EXPR_LIST (VOIDmode, 25602 gen_rtx_REG (SImode, 25603 GP_ARG_RETURN + 1), 25604 GEN_INT (4)))); 25605 } 25606 25607 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS) 25608 /* _Decimal128 must use an even/odd register pair. */ 25609 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN; 25610 else if (SCALAR_FLOAT_MODE_P (mode) 25611 && TARGET_HARD_FLOAT && TARGET_FPRS 25612 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT)) 25613 regno = FP_ARG_RETURN; 25614 else if (ALTIVEC_VECTOR_MODE (mode) 25615 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI) 25616 regno = ALTIVEC_ARG_RETURN; 25617 else if (VSX_VECTOR_MODE (mode) 25618 && TARGET_VSX && TARGET_ALTIVEC_ABI) 25619 regno = ALTIVEC_ARG_RETURN; 25620 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg) 25621 return rs6000_complex_function_value (mode); 25622 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT 25623 && (mode == DFmode || mode == DCmode 25624 || mode == TFmode || mode == TCmode)) 25625 return spe_build_register_parallel (mode, GP_ARG_RETURN); 25626 else 25627 regno = GP_ARG_RETURN; 25628 25629 return gen_rtx_REG (mode, regno); 25630} 25631 25632 25633/* Given FROM and TO register numbers, say whether this elimination is allowed. 25634 Frame pointer elimination is automatically handled. 25635 25636 For the RS/6000, if frame pointer elimination is being done, we would like 25637 to convert ap into fp, not sp. 25638 25639 We need r30 if -mminimal-toc was specified, and there are constant pool 25640 references. */ 25641 25642bool 25643rs6000_can_eliminate (const int from, const int to) 25644{ 25645 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM 25646 ? ! frame_pointer_needed 25647 : from == RS6000_PIC_OFFSET_TABLE_REGNUM 25648 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0 25649 : true); 25650} 25651 25652/* Define the offset between two registers, FROM to be eliminated and its 25653 replacement TO, at the start of a routine. */ 25654HOST_WIDE_INT 25655rs6000_initial_elimination_offset (int from, int to) 25656{ 25657 rs6000_stack_t *info = rs6000_stack_info (); 25658 HOST_WIDE_INT offset; 25659 25660 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM) 25661 offset = info->push_p ? 0 : -info->total_size; 25662 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM) 25663 { 25664 offset = info->push_p ? 0 : -info->total_size; 25665 if (FRAME_GROWS_DOWNWARD) 25666 offset += info->fixed_size + info->vars_size + info->parm_size; 25667 } 25668 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM) 25669 offset = FRAME_GROWS_DOWNWARD 25670 ? info->fixed_size + info->vars_size + info->parm_size 25671 : 0; 25672 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM) 25673 offset = info->total_size; 25674 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM) 25675 offset = info->push_p ? info->total_size : 0; 25676 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM) 25677 offset = 0; 25678 else 25679 gcc_unreachable (); 25680 25681 return offset; 25682} 25683 25684static rtx 25685rs6000_dwarf_register_span (rtx reg) 25686{ 25687 rtx parts[8]; 25688 int i, words; 25689 unsigned regno = REGNO (reg); 25690 enum machine_mode mode = GET_MODE (reg); 25691 25692 if (TARGET_SPE 25693 && regno < 32 25694 && (SPE_VECTOR_MODE (GET_MODE (reg)) 25695 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) 25696 && mode != SFmode && mode != SDmode && mode != SCmode))) 25697 ; 25698 else 25699 return NULL_RTX; 25700 25701 regno = REGNO (reg); 25702 25703 /* The duality of the SPE register size wreaks all kinds of havoc. 25704 This is a way of distinguishing r0 in 32-bits from r0 in 25705 64-bits. */ 25706 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD; 25707 gcc_assert (words <= 4); 25708 for (i = 0; i < words; i++, regno++) 25709 { 25710 if (BYTES_BIG_ENDIAN) 25711 { 25712 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200); 25713 parts[2 * i + 1] = gen_rtx_REG (SImode, regno); 25714 } 25715 else 25716 { 25717 parts[2 * i] = gen_rtx_REG (SImode, regno); 25718 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200); 25719 } 25720 } 25721 25722 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts)); 25723} 25724 25725/* Fill in sizes for SPE register high parts in table used by unwinder. */ 25726 25727static void 25728rs6000_init_dwarf_reg_sizes_extra (tree address) 25729{ 25730 if (TARGET_SPE) 25731 { 25732 int i; 25733 enum machine_mode mode = TYPE_MODE (char_type_node); 25734 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL); 25735 rtx mem = gen_rtx_MEM (BLKmode, addr); 25736 rtx value = gen_int_mode (4, mode); 25737 25738 for (i = 1201; i < 1232; i++) 25739 { 25740 int column = DWARF_REG_TO_UNWIND_COLUMN (i); 25741 HOST_WIDE_INT offset 25742 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode); 25743 25744 emit_move_insn (adjust_address (mem, mode, offset), value); 25745 } 25746 } 25747} 25748 25749/* Map internal gcc register numbers to DWARF2 register numbers. */ 25750 25751unsigned int 25752rs6000_dbx_register_number (unsigned int regno) 25753{ 25754 if (regno <= 63 || write_symbols != DWARF2_DEBUG) 25755 return regno; 25756 if (regno == MQ_REGNO) 25757 return 100; 25758 if (regno == LR_REGNO) 25759 return 108; 25760 if (regno == CTR_REGNO) 25761 return 109; 25762 if (CR_REGNO_P (regno)) 25763 return regno - CR0_REGNO + 86; 25764 if (regno == XER_REGNO) 25765 return 101; 25766 if (ALTIVEC_REGNO_P (regno)) 25767 return regno - FIRST_ALTIVEC_REGNO + 1124; 25768 if (regno == VRSAVE_REGNO) 25769 return 356; 25770 if (regno == VSCR_REGNO) 25771 return 67; 25772 if (regno == SPE_ACC_REGNO) 25773 return 99; 25774 if (regno == SPEFSCR_REGNO) 25775 return 612; 25776 /* SPE high reg number. We get these values of regno from 25777 rs6000_dwarf_register_span. */ 25778 gcc_assert (regno >= 1200 && regno < 1232); 25779 return regno; 25780} 25781 25782/* target hook eh_return_filter_mode */ 25783static enum machine_mode 25784rs6000_eh_return_filter_mode (void) 25785{ 25786 return TARGET_32BIT ? SImode : word_mode; 25787} 25788 25789/* Target hook for scalar_mode_supported_p. */ 25790static bool 25791rs6000_scalar_mode_supported_p (enum machine_mode mode) 25792{ 25793 if (DECIMAL_FLOAT_MODE_P (mode)) 25794 return default_decimal_float_supported_p (); 25795 else 25796 return default_scalar_mode_supported_p (mode); 25797} 25798 25799/* Target hook for vector_mode_supported_p. */ 25800static bool 25801rs6000_vector_mode_supported_p (enum machine_mode mode) 25802{ 25803 25804 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode)) 25805 return true; 25806 25807 if (TARGET_SPE && SPE_VECTOR_MODE (mode)) 25808 return true; 25809 25810 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)) 25811 return true; 25812 25813 else 25814 return false; 25815} 25816 25817/* Target hook for invalid_arg_for_unprototyped_fn. */ 25818static const char * 25819invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val) 25820{ 25821 return (!rs6000_darwin64_abi 25822 && typelist == 0 25823 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE 25824 && (funcdecl == NULL_TREE 25825 || (TREE_CODE (funcdecl) == FUNCTION_DECL 25826 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD))) 25827 ? N_("AltiVec argument passed to unprototyped function") 25828 : NULL; 25829} 25830 25831/* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register 25832 setup by using __stack_chk_fail_local hidden function instead of 25833 calling __stack_chk_fail directly. Otherwise it is better to call 25834 __stack_chk_fail directly. */ 25835 25836static tree 25837rs6000_stack_protect_fail (void) 25838{ 25839 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic) 25840 ? default_hidden_stack_protect_fail () 25841 : default_external_stack_protect_fail (); 25842} 25843 25844void 25845rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED, 25846 int num_operands ATTRIBUTE_UNUSED) 25847{ 25848 if (rs6000_warn_cell_microcode) 25849 { 25850 const char *temp; 25851 int insn_code_number = recog_memoized (insn); 25852 location_t location = locator_location (INSN_LOCATOR (insn)); 25853 25854 /* Punt on insns we cannot recognize. */ 25855 if (insn_code_number < 0) 25856 return; 25857 25858 temp = get_insn_template (insn_code_number, insn); 25859 25860 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS) 25861 warning_at (location, OPT_mwarn_cell_microcode, 25862 "emitting microcode insn %s\t[%s] #%d", 25863 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn)); 25864 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL) 25865 warning_at (location, OPT_mwarn_cell_microcode, 25866 "emitting conditional microcode insn %s\t[%s] #%d", 25867 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn)); 25868 } 25869} 25870 25871/* Given a memory reference, if it is not in the form for altivec memory 25872 reference instructions (i.e. reg or reg+reg addressing with AND of -16), 25873 convert to the altivec format. */ 25874 25875rtx 25876rs6000_address_for_altivec (rtx x) 25877{ 25878 gcc_assert (MEM_P (x)); 25879 if (!altivec_indexed_or_indirect_operand (x, GET_MODE (x))) 25880 { 25881 rtx addr = XEXP (x, 0); 25882 int strict_p = (reload_in_progress || reload_completed); 25883 25884 if (!legitimate_indexed_address_p (addr, strict_p) 25885 && !legitimate_indirect_address_p (addr, strict_p)) 25886 addr = copy_to_mode_reg (Pmode, addr); 25887 25888 addr = gen_rtx_AND (Pmode, addr, GEN_INT (-16)); 25889 x = change_address (x, GET_MODE (x), addr); 25890 } 25891 25892 return x; 25893} 25894 25895 25896#include "gt-rs6000.h" 25897