1 /* Subroutines used to generate function calls and handle built-in
2 instructions on IBM RS/6000.
3 Copyright (C) 1991-2019 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published
9 by the Free Software Foundation; either version 3, or (at your
10 option) any later version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #define IN_TARGET_CODE 1
25 #include "coretypes.h"
35 #include "stringpool.h"
42 #include "diagnostic-core.h"
43 #include "insn-attr.h"
46 #include "fold-const.h"
48 #include "stor-layout.h"
50 #include "print-tree.h"
55 #include "common/common-target.h"
56 #include "langhooks.h"
58 #include "gimple-fold.h"
59 #include "gimple-iterator.h"
60 #include "gimple-ssa.h"
62 #include "tree-vector-builder.h"
64 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
67 #include "tree-ssa-propagate.h"
69 #include "tree-ssanames.h"
70 #include "targhooks.h"
72 #include "rs6000-internal.h"
75 #include "gstab.h" /* for N_SLINE */
76 #include "dbxout.h" /* dbxout_ */
79 #ifndef TARGET_PROFILE_KERNEL
80 #define TARGET_PROFILE_KERNEL 0
83 #ifdef HAVE_AS_GNU_ATTRIBUTE
84 # ifndef HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE
85 # define HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE 0
89 #ifndef TARGET_NO_PROTOTYPE
90 #define TARGET_NO_PROTOTYPE 0
93 struct builtin_description
95 const HOST_WIDE_INT mask
;
96 const enum insn_code icode
;
97 const char *const name
;
98 const enum rs6000_builtins code
;
101 /* Used by __builtin_cpu_is(), mapping from PLATFORM names to values. */
107 { "power9", PPC_PLATFORM_POWER9
},
108 { "power8", PPC_PLATFORM_POWER8
},
109 { "power7", PPC_PLATFORM_POWER7
},
110 { "power6x", PPC_PLATFORM_POWER6X
},
111 { "power6", PPC_PLATFORM_POWER6
},
112 { "power5+", PPC_PLATFORM_POWER5_PLUS
},
113 { "power5", PPC_PLATFORM_POWER5
},
114 { "ppc970", PPC_PLATFORM_PPC970
},
115 { "power4", PPC_PLATFORM_POWER4
},
116 { "ppca2", PPC_PLATFORM_PPCA2
},
117 { "ppc476", PPC_PLATFORM_PPC476
},
118 { "ppc464", PPC_PLATFORM_PPC464
},
119 { "ppc440", PPC_PLATFORM_PPC440
},
120 { "ppc405", PPC_PLATFORM_PPC405
},
121 { "ppc-cell-be", PPC_PLATFORM_CELL_BE
}
124 /* Used by __builtin_cpu_supports(), mapping from HWCAP names to masks. */
130 } cpu_supports_info
[] = {
131 /* AT_HWCAP masks. */
132 { "4xxmac", PPC_FEATURE_HAS_4xxMAC
, 0 },
133 { "altivec", PPC_FEATURE_HAS_ALTIVEC
, 0 },
134 { "arch_2_05", PPC_FEATURE_ARCH_2_05
, 0 },
135 { "arch_2_06", PPC_FEATURE_ARCH_2_06
, 0 },
136 { "archpmu", PPC_FEATURE_PERFMON_COMPAT
, 0 },
137 { "booke", PPC_FEATURE_BOOKE
, 0 },
138 { "cellbe", PPC_FEATURE_CELL_BE
, 0 },
139 { "dfp", PPC_FEATURE_HAS_DFP
, 0 },
140 { "efpdouble", PPC_FEATURE_HAS_EFP_DOUBLE
, 0 },
141 { "efpsingle", PPC_FEATURE_HAS_EFP_SINGLE
, 0 },
142 { "fpu", PPC_FEATURE_HAS_FPU
, 0 },
143 { "ic_snoop", PPC_FEATURE_ICACHE_SNOOP
, 0 },
144 { "mmu", PPC_FEATURE_HAS_MMU
, 0 },
145 { "notb", PPC_FEATURE_NO_TB
, 0 },
146 { "pa6t", PPC_FEATURE_PA6T
, 0 },
147 { "power4", PPC_FEATURE_POWER4
, 0 },
148 { "power5", PPC_FEATURE_POWER5
, 0 },
149 { "power5+", PPC_FEATURE_POWER5_PLUS
, 0 },
150 { "power6x", PPC_FEATURE_POWER6_EXT
, 0 },
151 { "ppc32", PPC_FEATURE_32
, 0 },
152 { "ppc601", PPC_FEATURE_601_INSTR
, 0 },
153 { "ppc64", PPC_FEATURE_64
, 0 },
154 { "ppcle", PPC_FEATURE_PPC_LE
, 0 },
155 { "smt", PPC_FEATURE_SMT
, 0 },
156 { "spe", PPC_FEATURE_HAS_SPE
, 0 },
157 { "true_le", PPC_FEATURE_TRUE_LE
, 0 },
158 { "ucache", PPC_FEATURE_UNIFIED_CACHE
, 0 },
159 { "vsx", PPC_FEATURE_HAS_VSX
, 0 },
161 /* AT_HWCAP2 masks. */
162 { "arch_2_07", PPC_FEATURE2_ARCH_2_07
, 1 },
163 { "dscr", PPC_FEATURE2_HAS_DSCR
, 1 },
164 { "ebb", PPC_FEATURE2_HAS_EBB
, 1 },
165 { "htm", PPC_FEATURE2_HAS_HTM
, 1 },
166 { "htm-nosc", PPC_FEATURE2_HTM_NOSC
, 1 },
167 { "htm-no-suspend", PPC_FEATURE2_HTM_NO_SUSPEND
, 1 },
168 { "isel", PPC_FEATURE2_HAS_ISEL
, 1 },
169 { "tar", PPC_FEATURE2_HAS_TAR
, 1 },
170 { "vcrypto", PPC_FEATURE2_HAS_VEC_CRYPTO
, 1 },
171 { "arch_3_00", PPC_FEATURE2_ARCH_3_00
, 1 },
172 { "ieee128", PPC_FEATURE2_HAS_IEEE128
, 1 },
173 { "darn", PPC_FEATURE2_DARN
, 1 },
174 { "scv", PPC_FEATURE2_SCV
, 1 }
177 static void altivec_init_builtins (void);
178 static tree
builtin_function_type (machine_mode
, machine_mode
,
179 machine_mode
, machine_mode
,
180 enum rs6000_builtins
, const char *name
);
181 static void rs6000_common_init_builtins (void);
182 static void htm_init_builtins (void);
185 /* Hash table to keep track of the argument types for builtin functions. */
187 struct GTY((for_user
)) builtin_hash_struct
190 machine_mode mode
[4]; /* return value + 3 arguments. */
191 unsigned char uns_p
[4]; /* and whether the types are unsigned. */
194 struct builtin_hasher
: ggc_ptr_hash
<builtin_hash_struct
>
196 static hashval_t
hash (builtin_hash_struct
*);
197 static bool equal (builtin_hash_struct
*, builtin_hash_struct
*);
200 static GTY (()) hash_table
<builtin_hasher
> *builtin_hash_table
;
202 /* Hash function for builtin functions with up to 3 arguments and a return
205 builtin_hasher::hash (builtin_hash_struct
*bh
)
210 for (i
= 0; i
< 4; i
++)
212 ret
= (ret
* (unsigned)MAX_MACHINE_MODE
) + ((unsigned)bh
->mode
[i
]);
213 ret
= (ret
* 2) + bh
->uns_p
[i
];
219 /* Compare builtin hash entries H1 and H2 for equivalence. */
221 builtin_hasher::equal (builtin_hash_struct
*p1
, builtin_hash_struct
*p2
)
223 return ((p1
->mode
[0] == p2
->mode
[0])
224 && (p1
->mode
[1] == p2
->mode
[1])
225 && (p1
->mode
[2] == p2
->mode
[2])
226 && (p1
->mode
[3] == p2
->mode
[3])
227 && (p1
->uns_p
[0] == p2
->uns_p
[0])
228 && (p1
->uns_p
[1] == p2
->uns_p
[1])
229 && (p1
->uns_p
[2] == p2
->uns_p
[2])
230 && (p1
->uns_p
[3] == p2
->uns_p
[3]));
234 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
235 #undef RS6000_BUILTIN_0
236 #undef RS6000_BUILTIN_1
237 #undef RS6000_BUILTIN_2
238 #undef RS6000_BUILTIN_3
239 #undef RS6000_BUILTIN_A
240 #undef RS6000_BUILTIN_D
241 #undef RS6000_BUILTIN_H
242 #undef RS6000_BUILTIN_P
243 #undef RS6000_BUILTIN_X
245 #define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE) \
246 { NAME, ICODE, MASK, ATTR },
248 #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) \
249 { NAME, ICODE, MASK, ATTR },
251 #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) \
252 { NAME, ICODE, MASK, ATTR },
254 #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) \
255 { NAME, ICODE, MASK, ATTR },
257 #define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE) \
258 { NAME, ICODE, MASK, ATTR },
260 #define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE) \
261 { NAME, ICODE, MASK, ATTR },
263 #define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE) \
264 { NAME, ICODE, MASK, ATTR },
266 #define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE) \
267 { NAME, ICODE, MASK, ATTR },
269 #define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE) \
270 { NAME, ICODE, MASK, ATTR },
272 struct rs6000_builtin_info_type
{
274 const enum insn_code icode
;
275 const HOST_WIDE_INT mask
;
279 const struct rs6000_builtin_info_type rs6000_builtin_info
[] =
281 #include "rs6000-builtin.def"
284 #undef RS6000_BUILTIN_0
285 #undef RS6000_BUILTIN_1
286 #undef RS6000_BUILTIN_2
287 #undef RS6000_BUILTIN_3
288 #undef RS6000_BUILTIN_A
289 #undef RS6000_BUILTIN_D
290 #undef RS6000_BUILTIN_H
291 #undef RS6000_BUILTIN_P
292 #undef RS6000_BUILTIN_X
295 /* Nonzero if we can use a floating-point register to pass this arg. */
296 #define USE_FP_FOR_ARG_P(CUM,MODE) \
297 (SCALAR_FLOAT_MODE_NOT_VECTOR_P (MODE) \
298 && (CUM)->fregno <= FP_ARG_MAX_REG \
299 && TARGET_HARD_FLOAT)
301 /* Nonzero if we can use an AltiVec register to pass this arg. */
302 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,NAMED) \
303 (ALTIVEC_OR_VSX_VECTOR_MODE (MODE) \
304 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
305 && TARGET_ALTIVEC_ABI \
308 /* Walk down the type tree of TYPE counting consecutive base elements.
309 If *MODEP is VOIDmode, then set it to the first valid floating point
310 or vector type. If a non-floating point or vector type is found, or
311 if a floating point or vector type that doesn't match a non-VOIDmode
312 *MODEP is found, then return -1, otherwise return the count in the
316 rs6000_aggregate_candidate (const_tree type
, machine_mode
*modep
)
321 switch (TREE_CODE (type
))
324 mode
= TYPE_MODE (type
);
325 if (!SCALAR_FLOAT_MODE_P (mode
))
328 if (*modep
== VOIDmode
)
337 mode
= TYPE_MODE (TREE_TYPE (type
));
338 if (!SCALAR_FLOAT_MODE_P (mode
))
341 if (*modep
== VOIDmode
)
350 if (!TARGET_ALTIVEC_ABI
|| !TARGET_ALTIVEC
)
353 /* Use V4SImode as representative of all 128-bit vector types. */
354 size
= int_size_in_bytes (type
);
364 if (*modep
== VOIDmode
)
367 /* Vector modes are considered to be opaque: two vectors are
368 equivalent for the purposes of being homogeneous aggregates
369 if they are the same size. */
378 tree index
= TYPE_DOMAIN (type
);
380 /* Can't handle incomplete types nor sizes that are not
382 if (!COMPLETE_TYPE_P (type
)
383 || TREE_CODE (TYPE_SIZE (type
)) != INTEGER_CST
)
386 count
= rs6000_aggregate_candidate (TREE_TYPE (type
), modep
);
389 || !TYPE_MAX_VALUE (index
)
390 || !tree_fits_uhwi_p (TYPE_MAX_VALUE (index
))
391 || !TYPE_MIN_VALUE (index
)
392 || !tree_fits_uhwi_p (TYPE_MIN_VALUE (index
))
396 count
*= (1 + tree_to_uhwi (TYPE_MAX_VALUE (index
))
397 - tree_to_uhwi (TYPE_MIN_VALUE (index
)));
399 /* There must be no padding. */
400 if (wi::to_wide (TYPE_SIZE (type
))
401 != count
* GET_MODE_BITSIZE (*modep
))
413 /* Can't handle incomplete types nor sizes that are not
415 if (!COMPLETE_TYPE_P (type
)
416 || TREE_CODE (TYPE_SIZE (type
)) != INTEGER_CST
)
419 for (field
= TYPE_FIELDS (type
); field
; field
= TREE_CHAIN (field
))
421 if (TREE_CODE (field
) != FIELD_DECL
)
424 sub_count
= rs6000_aggregate_candidate (TREE_TYPE (field
), modep
);
430 /* There must be no padding. */
431 if (wi::to_wide (TYPE_SIZE (type
))
432 != count
* GET_MODE_BITSIZE (*modep
))
439 case QUAL_UNION_TYPE
:
441 /* These aren't very interesting except in a degenerate case. */
446 /* Can't handle incomplete types nor sizes that are not
448 if (!COMPLETE_TYPE_P (type
)
449 || TREE_CODE (TYPE_SIZE (type
)) != INTEGER_CST
)
452 for (field
= TYPE_FIELDS (type
); field
; field
= TREE_CHAIN (field
))
454 if (TREE_CODE (field
) != FIELD_DECL
)
457 sub_count
= rs6000_aggregate_candidate (TREE_TYPE (field
), modep
);
460 count
= count
> sub_count
? count
: sub_count
;
463 /* There must be no padding. */
464 if (wi::to_wide (TYPE_SIZE (type
))
465 != count
* GET_MODE_BITSIZE (*modep
))
478 /* If an argument, whose type is described by TYPE and MODE, is a homogeneous
479 float or vector aggregate that shall be passed in FP/vector registers
480 according to the ELFv2 ABI, return the homogeneous element mode in
481 *ELT_MODE and the number of elements in *N_ELTS, and return TRUE.
483 Otherwise, set *ELT_MODE to MODE and *N_ELTS to 1, and return FALSE. */
486 rs6000_discover_homogeneous_aggregate (machine_mode mode
, const_tree type
,
487 machine_mode
*elt_mode
,
490 /* Note that we do not accept complex types at the top level as
491 homogeneous aggregates; these types are handled via the
492 targetm.calls.split_complex_arg mechanism. Complex types
493 can be elements of homogeneous aggregates, however. */
494 if (TARGET_HARD_FLOAT
&& DEFAULT_ABI
== ABI_ELFv2
&& type
495 && AGGREGATE_TYPE_P (type
))
497 machine_mode field_mode
= VOIDmode
;
498 int field_count
= rs6000_aggregate_candidate (type
, &field_mode
);
502 int reg_size
= ALTIVEC_OR_VSX_VECTOR_MODE (field_mode
) ? 16 : 8;
503 int field_size
= ROUND_UP (GET_MODE_SIZE (field_mode
), reg_size
);
505 /* The ELFv2 ABI allows homogeneous aggregates to occupy
506 up to AGGR_ARG_NUM_REG registers. */
507 if (field_count
* field_size
<= AGGR_ARG_NUM_REG
* reg_size
)
510 *elt_mode
= field_mode
;
512 *n_elts
= field_count
;
525 /* Return a nonzero value to say to return the function value in
526 memory, just as large structures are always returned. TYPE will be
527 the data type of the value, and FNTYPE will be the type of the
528 function doing the returning, or @code{NULL} for libcalls.
530 The AIX ABI for the RS/6000 specifies that all structures are
531 returned in memory. The Darwin ABI does the same.
533 For the Darwin 64 Bit ABI, a function result can be returned in
534 registers or in memory, depending on the size of the return data
535 type. If it is returned in registers, the value occupies the same
536 registers as it would if it were the first and only function
537 argument. Otherwise, the function places its result in memory at
538 the location pointed to by GPR3.
540 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
541 but a draft put them in memory, and GCC used to implement the draft
542 instead of the final standard. Therefore, aix_struct_return
543 controls this instead of DEFAULT_ABI; V.4 targets needing backward
544 compatibility can change DRAFT_V4_STRUCT_RET to override the
545 default, and -m switches get the final word. See
546 rs6000_option_override_internal for more details.
548 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
549 long double support is enabled. These values are returned in memory.
551 int_size_in_bytes returns -1 for variable size objects, which go in
552 memory always. The cast to unsigned makes -1 > 8. */
555 rs6000_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
557 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
559 && rs6000_darwin64_abi
560 && TREE_CODE (type
) == RECORD_TYPE
561 && int_size_in_bytes (type
) > 0)
563 CUMULATIVE_ARGS valcum
;
567 valcum
.fregno
= FP_ARG_MIN_REG
;
568 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
569 /* Do a trial code generation as if this were going to be passed
570 as an argument; if any part goes in memory, we return NULL. */
571 valret
= rs6000_darwin64_record_arg (&valcum
, type
, true, true);
574 /* Otherwise fall through to more conventional ABI rules. */
577 /* The ELFv2 ABI returns homogeneous VFP aggregates in registers */
578 if (rs6000_discover_homogeneous_aggregate (TYPE_MODE (type
), type
,
582 /* The ELFv2 ABI returns aggregates up to 16B in registers */
583 if (DEFAULT_ABI
== ABI_ELFv2
&& AGGREGATE_TYPE_P (type
)
584 && (unsigned HOST_WIDE_INT
) int_size_in_bytes (type
) <= 16)
587 if (AGGREGATE_TYPE_P (type
)
588 && (aix_struct_return
589 || (unsigned HOST_WIDE_INT
) int_size_in_bytes (type
) > 8))
592 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
593 modes only exist for GCC vector types if -maltivec. */
594 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
595 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
598 /* Return synthetic vectors in memory. */
599 if (TREE_CODE (type
) == VECTOR_TYPE
600 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
602 static bool warned_for_return_big_vectors
= false;
603 if (!warned_for_return_big_vectors
)
605 warning (OPT_Wpsabi
, "GCC vector returned by reference: "
606 "non-standard ABI extension with no compatibility "
608 warned_for_return_big_vectors
= true;
613 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
614 && FLOAT128_IEEE_P (TYPE_MODE (type
)))
620 /* Specify whether values returned in registers should be at the most
621 significant end of a register. We want aggregates returned by
622 value to match the way aggregates are passed to functions. */
625 rs6000_return_in_msb (const_tree valtype
)
627 return (DEFAULT_ABI
== ABI_ELFv2
629 && AGGREGATE_TYPE_P (valtype
)
630 && (rs6000_function_arg_padding (TYPE_MODE (valtype
), valtype
)
634 #ifdef HAVE_AS_GNU_ATTRIBUTE
635 /* Return TRUE if a call to function FNDECL may be one that
636 potentially affects the function calling ABI of the object file. */
639 call_ABI_of_interest (tree fndecl
)
641 if (rs6000_gnu_attr
&& symtab
->state
== EXPANSION
)
643 struct cgraph_node
*c_node
;
645 /* Libcalls are always interesting. */
646 if (fndecl
== NULL_TREE
)
649 /* Any call to an external function is interesting. */
650 if (DECL_EXTERNAL (fndecl
))
653 /* Interesting functions that we are emitting in this object file. */
654 c_node
= cgraph_node::get (fndecl
);
655 c_node
= c_node
->ultimate_alias_target ();
656 return !c_node
->only_called_directly_p ();
662 /* Initialize a variable CUM of type CUMULATIVE_ARGS
663 for a call to a function whose data type is FNTYPE.
664 For a library call, FNTYPE is 0 and RETURN_MODE the return value mode.
666 For incoming args we set the number of arguments in the prototype large
667 so we never return a PARALLEL. */
670 init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
,
671 rtx libname ATTRIBUTE_UNUSED
, int incoming
,
672 int libcall
, int n_named_args
,
674 machine_mode return_mode ATTRIBUTE_UNUSED
)
676 static CUMULATIVE_ARGS zero_cumulative
;
678 *cum
= zero_cumulative
;
680 cum
->fregno
= FP_ARG_MIN_REG
;
681 cum
->vregno
= ALTIVEC_ARG_MIN_REG
;
682 cum
->prototype
= (fntype
&& prototype_p (fntype
));
683 cum
->call_cookie
= ((DEFAULT_ABI
== ABI_V4
&& libcall
)
684 ? CALL_LIBCALL
: CALL_NORMAL
);
685 cum
->sysv_gregno
= GP_ARG_MIN_REG
;
686 cum
->stdarg
= stdarg_p (fntype
);
687 cum
->libcall
= libcall
;
689 cum
->nargs_prototype
= 0;
690 if (incoming
|| cum
->prototype
)
691 cum
->nargs_prototype
= n_named_args
;
693 /* Check for a longcall attribute. */
694 if ((!fntype
&& rs6000_default_long_calls
)
696 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype
))
697 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype
))))
698 cum
->call_cookie
|= CALL_LONG
;
699 else if (DEFAULT_ABI
!= ABI_DARWIN
)
701 bool is_local
= (fndecl
702 && !DECL_EXTERNAL (fndecl
)
703 && !DECL_WEAK (fndecl
)
704 && (*targetm
.binds_local_p
) (fndecl
));
710 && lookup_attribute ("noplt", TYPE_ATTRIBUTES (fntype
)))
711 cum
->call_cookie
|= CALL_LONG
;
716 && lookup_attribute ("plt", TYPE_ATTRIBUTES (fntype
))))
717 cum
->call_cookie
|= CALL_LONG
;
721 if (TARGET_DEBUG_ARG
)
723 fprintf (stderr
, "\ninit_cumulative_args:");
726 tree ret_type
= TREE_TYPE (fntype
);
727 fprintf (stderr
, " ret code = %s,",
728 get_tree_code_name (TREE_CODE (ret_type
)));
731 if (cum
->call_cookie
& CALL_LONG
)
732 fprintf (stderr
, " longcall,");
734 fprintf (stderr
, " proto = %d, nargs = %d\n",
735 cum
->prototype
, cum
->nargs_prototype
);
738 #ifdef HAVE_AS_GNU_ATTRIBUTE
739 if (TARGET_ELF
&& (TARGET_64BIT
|| DEFAULT_ABI
== ABI_V4
))
741 cum
->escapes
= call_ABI_of_interest (fndecl
);
748 return_type
= TREE_TYPE (fntype
);
749 return_mode
= TYPE_MODE (return_type
);
752 return_type
= lang_hooks
.types
.type_for_mode (return_mode
, 0);
754 if (return_type
!= NULL
)
756 if (TREE_CODE (return_type
) == RECORD_TYPE
757 && TYPE_TRANSPARENT_AGGR (return_type
))
759 return_type
= TREE_TYPE (first_field (return_type
));
760 return_mode
= TYPE_MODE (return_type
);
762 if (AGGREGATE_TYPE_P (return_type
)
763 && ((unsigned HOST_WIDE_INT
) int_size_in_bytes (return_type
)
765 rs6000_returns_struct
= true;
767 if (SCALAR_FLOAT_MODE_P (return_mode
))
769 rs6000_passes_float
= true;
770 if ((HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE
|| TARGET_64BIT
)
771 && (FLOAT128_IBM_P (return_mode
)
772 || FLOAT128_IEEE_P (return_mode
)
773 || (return_type
!= NULL
774 && (TYPE_MAIN_VARIANT (return_type
)
775 == long_double_type_node
))))
776 rs6000_passes_long_double
= true;
778 /* Note if we passed or return a IEEE 128-bit type. We changed
779 the mangling for these types, and we may need to make an alias
780 with the old mangling. */
781 if (FLOAT128_IEEE_P (return_mode
))
782 rs6000_passes_ieee128
= true;
784 if (ALTIVEC_OR_VSX_VECTOR_MODE (return_mode
))
785 rs6000_passes_vector
= true;
792 && TARGET_ALTIVEC_ABI
793 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype
))))
795 error ("cannot return value in vector register because"
796 " altivec instructions are disabled, use %qs"
797 " to enable them", "-maltivec");
802 /* On rs6000, function arguments are promoted, as are function return
806 rs6000_promote_function_mode (const_tree type ATTRIBUTE_UNUSED
,
808 int *punsignedp ATTRIBUTE_UNUSED
,
811 PROMOTE_MODE (mode
, *punsignedp
, type
);
816 /* Return true if TYPE must be passed on the stack and not in registers. */
819 rs6000_must_pass_in_stack (const function_arg_info
&arg
)
821 if (DEFAULT_ABI
== ABI_AIX
|| DEFAULT_ABI
== ABI_ELFv2
|| TARGET_64BIT
)
822 return must_pass_in_stack_var_size (arg
);
824 return must_pass_in_stack_var_size_or_pad (arg
);
828 is_complex_IBM_long_double (machine_mode mode
)
830 return mode
== ICmode
|| (mode
== TCmode
&& FLOAT128_IBM_P (TCmode
));
833 /* Whether ABI_V4 passes MODE args to a function in floating point
837 abi_v4_pass_in_fpr (machine_mode mode
, bool named
)
839 if (!TARGET_HARD_FLOAT
)
843 if (mode
== SFmode
&& named
)
845 /* ABI_V4 passes complex IBM long double in 8 gprs.
846 Stupid, but we can't change the ABI now. */
847 if (is_complex_IBM_long_double (mode
))
849 if (FLOAT128_2REG_P (mode
))
851 if (DECIMAL_FLOAT_MODE_P (mode
))
856 /* Implement TARGET_FUNCTION_ARG_PADDING.
858 For the AIX ABI structs are always stored left shifted in their
862 rs6000_function_arg_padding (machine_mode mode
, const_tree type
)
864 #ifndef AGGREGATE_PADDING_FIXED
865 #define AGGREGATE_PADDING_FIXED 0
867 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
868 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
871 if (!AGGREGATE_PADDING_FIXED
)
873 /* GCC used to pass structures of the same size as integer types as
874 if they were in fact integers, ignoring TARGET_FUNCTION_ARG_PADDING.
875 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
876 passed padded downward, except that -mstrict-align further
877 muddied the water in that multi-component structures of 2 and 4
878 bytes in size were passed padded upward.
880 The following arranges for best compatibility with previous
881 versions of gcc, but removes the -mstrict-align dependency. */
882 if (BYTES_BIG_ENDIAN
)
884 HOST_WIDE_INT size
= 0;
888 if (type
&& TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
)
889 size
= int_size_in_bytes (type
);
892 size
= GET_MODE_SIZE (mode
);
894 if (size
== 1 || size
== 2 || size
== 4)
900 if (AGGREGATES_PAD_UPWARD_ALWAYS
)
902 if (type
!= 0 && AGGREGATE_TYPE_P (type
))
906 /* Fall back to the default. */
907 return default_function_arg_padding (mode
, type
);
910 /* If defined, a C expression that gives the alignment boundary, in bits,
911 of an argument with the specified mode and type. If it is not defined,
912 PARM_BOUNDARY is used for all arguments.
914 V.4 wants long longs and doubles to be double word aligned. Just
915 testing the mode size is a boneheaded way to do this as it means
916 that other types such as complex int are also double word aligned.
917 However, we're stuck with this because changing the ABI might break
918 existing library interfaces.
920 Quadword align Altivec/VSX vectors.
921 Quadword align large synthetic vector types. */
924 rs6000_function_arg_boundary (machine_mode mode
, const_tree type
)
926 machine_mode elt_mode
;
929 rs6000_discover_homogeneous_aggregate (mode
, type
, &elt_mode
, &n_elts
);
931 if (DEFAULT_ABI
== ABI_V4
932 && (GET_MODE_SIZE (mode
) == 8
933 || (TARGET_HARD_FLOAT
934 && !is_complex_IBM_long_double (mode
)
935 && FLOAT128_2REG_P (mode
))))
937 else if (FLOAT128_VECTOR_P (mode
))
939 else if (type
&& TREE_CODE (type
) == VECTOR_TYPE
940 && int_size_in_bytes (type
) >= 8
941 && int_size_in_bytes (type
) < 16)
943 else if (ALTIVEC_OR_VSX_VECTOR_MODE (elt_mode
)
944 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
945 && int_size_in_bytes (type
) >= 16))
948 /* Aggregate types that need > 8 byte alignment are quadword-aligned
949 in the parameter area in the ELFv2 ABI, and in the AIX ABI unless
950 -mcompat-align-parm is used. */
951 if (((DEFAULT_ABI
== ABI_AIX
&& !rs6000_compat_align_parm
)
952 || DEFAULT_ABI
== ABI_ELFv2
)
953 && type
&& TYPE_ALIGN (type
) > 64)
955 /* "Aggregate" means any AGGREGATE_TYPE except for single-element
956 or homogeneous float/vector aggregates here. We already handled
957 vector aggregates above, but still need to check for float here. */
958 bool aggregate_p
= (AGGREGATE_TYPE_P (type
)
959 && !SCALAR_FLOAT_MODE_P (elt_mode
));
961 /* We used to check for BLKmode instead of the above aggregate type
962 check. Warn when this results in any difference to the ABI. */
963 if (aggregate_p
!= (mode
== BLKmode
))
966 if (!warned
&& warn_psabi
)
969 inform (input_location
,
970 "the ABI of passing aggregates with %d-byte alignment"
971 " has changed in GCC 5",
972 (int) TYPE_ALIGN (type
) / BITS_PER_UNIT
);
980 /* Similar for the Darwin64 ABI. Note that for historical reasons we
981 implement the "aggregate type" check as a BLKmode check here; this
982 means certain aggregate types are in fact not aligned. */
983 if (TARGET_MACHO
&& rs6000_darwin64_abi
985 && type
&& TYPE_ALIGN (type
) > 64)
988 return PARM_BOUNDARY
;
991 /* The offset in words to the start of the parameter save area. */
994 rs6000_parm_offset (void)
996 return (DEFAULT_ABI
== ABI_V4
? 2
997 : DEFAULT_ABI
== ABI_ELFv2
? 4
1001 /* For a function parm of MODE and TYPE, return the starting word in
1002 the parameter area. NWORDS of the parameter area are already used. */
1005 rs6000_parm_start (machine_mode mode
, const_tree type
,
1006 unsigned int nwords
)
1010 align
= rs6000_function_arg_boundary (mode
, type
) / PARM_BOUNDARY
- 1;
1011 return nwords
+ (-(rs6000_parm_offset () + nwords
) & align
);
1014 /* Compute the size (in words) of a function argument. */
1016 static unsigned long
1017 rs6000_arg_size (machine_mode mode
, const_tree type
)
1021 if (mode
!= BLKmode
)
1022 size
= GET_MODE_SIZE (mode
);
1024 size
= int_size_in_bytes (type
);
1027 return (size
+ 3) >> 2;
1029 return (size
+ 7) >> 3;
1032 /* Use this to flush pending int fields. */
1035 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*cum
,
1036 HOST_WIDE_INT bitpos
, int final
)
1038 unsigned int startbit
, endbit
;
1039 int intregs
, intoffset
;
1041 /* Handle the situations where a float is taking up the first half
1042 of the GPR, and the other half is empty (typically due to
1043 alignment restrictions). We can detect this by a 8-byte-aligned
1044 int field, or by seeing that this is the final flush for this
1045 argument. Count the word and continue on. */
1046 if (cum
->floats_in_gpr
== 1
1047 && (cum
->intoffset
% 64 == 0
1048 || (cum
->intoffset
== -1 && final
)))
1051 cum
->floats_in_gpr
= 0;
1054 if (cum
->intoffset
== -1)
1057 intoffset
= cum
->intoffset
;
1058 cum
->intoffset
= -1;
1059 cum
->floats_in_gpr
= 0;
1061 if (intoffset
% BITS_PER_WORD
!= 0)
1063 unsigned int bits
= BITS_PER_WORD
- intoffset
% BITS_PER_WORD
;
1064 if (!int_mode_for_size (bits
, 0).exists ())
1066 /* We couldn't find an appropriate mode, which happens,
1067 e.g., in packed structs when there are 3 bytes to load.
1068 Back intoffset back to the beginning of the word in this
1070 intoffset
= ROUND_DOWN (intoffset
, BITS_PER_WORD
);
1074 startbit
= ROUND_DOWN (intoffset
, BITS_PER_WORD
);
1075 endbit
= ROUND_UP (bitpos
, BITS_PER_WORD
);
1076 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
1077 cum
->words
+= intregs
;
1078 /* words should be unsigned. */
1079 if ((unsigned)cum
->words
< (endbit
/BITS_PER_WORD
))
1081 int pad
= (endbit
/BITS_PER_WORD
) - cum
->words
;
1086 /* The darwin64 ABI calls for us to recurse down through structs,
1087 looking for elements passed in registers. Unfortunately, we have
1088 to track int register count here also because of misalignments
1089 in powerpc alignment mode. */
1092 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*cum
,
1094 HOST_WIDE_INT startbitpos
)
1098 for (f
= TYPE_FIELDS (type
); f
; f
= DECL_CHAIN (f
))
1099 if (TREE_CODE (f
) == FIELD_DECL
)
1101 HOST_WIDE_INT bitpos
= startbitpos
;
1102 tree ftype
= TREE_TYPE (f
);
1104 if (ftype
== error_mark_node
)
1106 mode
= TYPE_MODE (ftype
);
1108 if (DECL_SIZE (f
) != 0
1109 && tree_fits_uhwi_p (bit_position (f
)))
1110 bitpos
+= int_bit_position (f
);
1112 /* ??? FIXME: else assume zero offset. */
1114 if (TREE_CODE (ftype
) == RECORD_TYPE
)
1115 rs6000_darwin64_record_arg_advance_recurse (cum
, ftype
, bitpos
);
1116 else if (USE_FP_FOR_ARG_P (cum
, mode
))
1118 unsigned n_fpregs
= (GET_MODE_SIZE (mode
) + 7) >> 3;
1119 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
, 0);
1120 cum
->fregno
+= n_fpregs
;
1121 /* Single-precision floats present a special problem for
1122 us, because they are smaller than an 8-byte GPR, and so
1123 the structure-packing rules combined with the standard
1124 varargs behavior mean that we want to pack float/float
1125 and float/int combinations into a single register's
1126 space. This is complicated by the arg advance flushing,
1127 which works on arbitrarily large groups of int-type
1131 if (cum
->floats_in_gpr
== 1)
1133 /* Two floats in a word; count the word and reset
1136 cum
->floats_in_gpr
= 0;
1138 else if (bitpos
% 64 == 0)
1140 /* A float at the beginning of an 8-byte word;
1141 count it and put off adjusting cum->words until
1142 we see if a arg advance flush is going to do it
1144 cum
->floats_in_gpr
++;
1148 /* The float is at the end of a word, preceded
1149 by integer fields, so the arg advance flush
1150 just above has already set cum->words and
1151 everything is taken care of. */
1155 cum
->words
+= n_fpregs
;
1157 else if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, 1))
1159 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
, 0);
1163 else if (cum
->intoffset
== -1)
1164 cum
->intoffset
= bitpos
;
1168 /* Check for an item that needs to be considered specially under the darwin 64
1169 bit ABI. These are record types where the mode is BLK or the structure is
1172 rs6000_darwin64_struct_check_p (machine_mode mode
, const_tree type
)
1174 return rs6000_darwin64_abi
1175 && ((mode
== BLKmode
1176 && TREE_CODE (type
) == RECORD_TYPE
1177 && int_size_in_bytes (type
) > 0)
1178 || (type
&& TREE_CODE (type
) == RECORD_TYPE
1179 && int_size_in_bytes (type
) == 8)) ? 1 : 0;
1182 /* Update the data in CUM to advance over an argument
1183 of mode MODE and data type TYPE.
1184 (TYPE is null for libcalls where that information may not be available.)
1186 Note that for args passed by reference, function_arg will be called
1187 with MODE and TYPE set to that of the pointer to the arg, not the arg
1191 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS
*cum
, machine_mode mode
,
1192 const_tree type
, bool named
, int depth
)
1194 machine_mode elt_mode
;
1197 rs6000_discover_homogeneous_aggregate (mode
, type
, &elt_mode
, &n_elts
);
1199 /* Only tick off an argument if we're not recursing. */
1201 cum
->nargs_prototype
--;
1203 #ifdef HAVE_AS_GNU_ATTRIBUTE
1204 if (TARGET_ELF
&& (TARGET_64BIT
|| DEFAULT_ABI
== ABI_V4
)
1207 if (SCALAR_FLOAT_MODE_P (mode
))
1209 rs6000_passes_float
= true;
1210 if ((HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE
|| TARGET_64BIT
)
1211 && (FLOAT128_IBM_P (mode
)
1212 || FLOAT128_IEEE_P (mode
)
1214 && TYPE_MAIN_VARIANT (type
) == long_double_type_node
)))
1215 rs6000_passes_long_double
= true;
1217 /* Note if we passed or return a IEEE 128-bit type. We changed the
1218 mangling for these types, and we may need to make an alias with
1219 the old mangling. */
1220 if (FLOAT128_IEEE_P (mode
))
1221 rs6000_passes_ieee128
= true;
1223 if (named
&& ALTIVEC_OR_VSX_VECTOR_MODE (mode
))
1224 rs6000_passes_vector
= true;
1228 if (TARGET_ALTIVEC_ABI
1229 && (ALTIVEC_OR_VSX_VECTOR_MODE (elt_mode
)
1230 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
1231 && int_size_in_bytes (type
) == 16)))
1235 if (USE_ALTIVEC_FOR_ARG_P (cum
, elt_mode
, named
))
1237 cum
->vregno
+= n_elts
;
1239 if (!TARGET_ALTIVEC
)
1240 error ("cannot pass argument in vector register because"
1241 " altivec instructions are disabled, use %qs"
1242 " to enable them", "-maltivec");
1244 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
1245 even if it is going to be passed in a vector register.
1246 Darwin does the same for variable-argument functions. */
1247 if (((DEFAULT_ABI
== ABI_AIX
|| DEFAULT_ABI
== ABI_ELFv2
)
1249 || (cum
->stdarg
&& DEFAULT_ABI
!= ABI_V4
))
1259 /* Vector parameters must be 16-byte aligned. In 32-bit
1260 mode this means we need to take into account the offset
1261 to the parameter save area. In 64-bit mode, they just
1262 have to start on an even word, since the parameter save
1263 area is 16-byte aligned. */
1265 align
= -(rs6000_parm_offset () + cum
->words
) & 3;
1267 align
= cum
->words
& 1;
1268 cum
->words
+= align
+ rs6000_arg_size (mode
, type
);
1270 if (TARGET_DEBUG_ARG
)
1272 fprintf (stderr
, "function_adv: words = %2d, align=%d, ",
1274 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s\n",
1275 cum
->nargs_prototype
, cum
->prototype
,
1276 GET_MODE_NAME (mode
));
1280 else if (TARGET_MACHO
&& rs6000_darwin64_struct_check_p (mode
, type
))
1282 int size
= int_size_in_bytes (type
);
1283 /* Variable sized types have size == -1 and are
1284 treated as if consisting entirely of ints.
1285 Pad to 16 byte boundary if needed. */
1286 if (TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
1287 && (cum
->words
% 2) != 0)
1289 /* For varargs, we can just go up by the size of the struct. */
1291 cum
->words
+= (size
+ 7) / 8;
1294 /* It is tempting to say int register count just goes up by
1295 sizeof(type)/8, but this is wrong in a case such as
1296 { int; double; int; } [powerpc alignment]. We have to
1297 grovel through the fields for these too. */
1299 cum
->floats_in_gpr
= 0;
1300 rs6000_darwin64_record_arg_advance_recurse (cum
, type
, 0);
1301 rs6000_darwin64_record_arg_advance_flush (cum
,
1302 size
* BITS_PER_UNIT
, 1);
1304 if (TARGET_DEBUG_ARG
)
1306 fprintf (stderr
, "function_adv: words = %2d, align=%d, size=%d",
1307 cum
->words
, TYPE_ALIGN (type
), size
);
1309 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
1310 cum
->nargs_prototype
, cum
->prototype
,
1311 GET_MODE_NAME (mode
));
1314 else if (DEFAULT_ABI
== ABI_V4
)
1316 if (abi_v4_pass_in_fpr (mode
, named
))
1318 /* _Decimal128 must use an even/odd register pair. This assumes
1319 that the register number is odd when fregno is odd. */
1320 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
1323 if (cum
->fregno
+ (FLOAT128_2REG_P (mode
) ? 1 : 0)
1324 <= FP_ARG_V4_MAX_REG
)
1325 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
1328 cum
->fregno
= FP_ARG_V4_MAX_REG
+ 1;
1329 if (mode
== DFmode
|| FLOAT128_IBM_P (mode
)
1330 || mode
== DDmode
|| mode
== TDmode
)
1331 cum
->words
+= cum
->words
& 1;
1332 cum
->words
+= rs6000_arg_size (mode
, type
);
1337 int n_words
= rs6000_arg_size (mode
, type
);
1338 int gregno
= cum
->sysv_gregno
;
1340 /* Long long is put in (r3,r4), (r5,r6), (r7,r8) or (r9,r10).
1341 As does any other 2 word item such as complex int due to a
1342 historical mistake. */
1344 gregno
+= (1 - gregno
) & 1;
1346 /* Multi-reg args are not split between registers and stack. */
1347 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
1349 /* Long long is aligned on the stack. So are other 2 word
1350 items such as complex int due to a historical mistake. */
1352 cum
->words
+= cum
->words
& 1;
1353 cum
->words
+= n_words
;
1356 /* Note: continuing to accumulate gregno past when we've started
1357 spilling to the stack indicates the fact that we've started
1358 spilling to the stack to expand_builtin_saveregs. */
1359 cum
->sysv_gregno
= gregno
+ n_words
;
1362 if (TARGET_DEBUG_ARG
)
1364 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
1365 cum
->words
, cum
->fregno
);
1366 fprintf (stderr
, "gregno = %2d, nargs = %4d, proto = %d, ",
1367 cum
->sysv_gregno
, cum
->nargs_prototype
, cum
->prototype
);
1368 fprintf (stderr
, "mode = %4s, named = %d\n",
1369 GET_MODE_NAME (mode
), named
);
1374 int n_words
= rs6000_arg_size (mode
, type
);
1375 int start_words
= cum
->words
;
1376 int align_words
= rs6000_parm_start (mode
, type
, start_words
);
1378 cum
->words
= align_words
+ n_words
;
1380 if (SCALAR_FLOAT_MODE_P (elt_mode
) && TARGET_HARD_FLOAT
)
1382 /* _Decimal128 must be passed in an even/odd float register pair.
1383 This assumes that the register number is odd when fregno is
1385 if (elt_mode
== TDmode
&& (cum
->fregno
% 2) == 1)
1387 cum
->fregno
+= n_elts
* ((GET_MODE_SIZE (elt_mode
) + 7) >> 3);
1390 if (TARGET_DEBUG_ARG
)
1392 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
1393 cum
->words
, cum
->fregno
);
1394 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s, ",
1395 cum
->nargs_prototype
, cum
->prototype
, GET_MODE_NAME (mode
));
1396 fprintf (stderr
, "named = %d, align = %d, depth = %d\n",
1397 named
, align_words
- start_words
, depth
);
1403 rs6000_function_arg_advance (cumulative_args_t cum
,
1404 const function_arg_info
&arg
)
1406 rs6000_function_arg_advance_1 (get_cumulative_args (cum
),
1407 arg
.mode
, arg
.type
, arg
.named
, 0);
1410 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
1411 structure between cum->intoffset and bitpos to integer registers. */
1414 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*cum
,
1415 HOST_WIDE_INT bitpos
, rtx rvec
[], int *k
)
1419 unsigned int startbit
, endbit
;
1420 int this_regno
, intregs
, intoffset
;
1423 if (cum
->intoffset
== -1)
1426 intoffset
= cum
->intoffset
;
1427 cum
->intoffset
= -1;
1429 /* If this is the trailing part of a word, try to only load that
1430 much into the register. Otherwise load the whole register. Note
1431 that in the latter case we may pick up unwanted bits. It's not a
1432 problem at the moment but may wish to revisit. */
1434 if (intoffset
% BITS_PER_WORD
!= 0)
1436 unsigned int bits
= BITS_PER_WORD
- intoffset
% BITS_PER_WORD
;
1437 if (!int_mode_for_size (bits
, 0).exists (&mode
))
1439 /* We couldn't find an appropriate mode, which happens,
1440 e.g., in packed structs when there are 3 bytes to load.
1441 Back intoffset back to the beginning of the word in this
1443 intoffset
= ROUND_DOWN (intoffset
, BITS_PER_WORD
);
1450 startbit
= ROUND_DOWN (intoffset
, BITS_PER_WORD
);
1451 endbit
= ROUND_UP (bitpos
, BITS_PER_WORD
);
1452 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
1453 this_regno
= cum
->words
+ intoffset
/ BITS_PER_WORD
;
1455 if (intregs
> 0 && intregs
> GP_ARG_NUM_REG
- this_regno
)
1458 intregs
= MIN (intregs
, GP_ARG_NUM_REG
- this_regno
);
1462 intoffset
/= BITS_PER_UNIT
;
1465 regno
= GP_ARG_MIN_REG
+ this_regno
;
1466 reg
= gen_rtx_REG (mode
, regno
);
1468 gen_rtx_EXPR_LIST (VOIDmode
, reg
, GEN_INT (intoffset
));
1471 intoffset
= (intoffset
| (UNITS_PER_WORD
-1)) + 1;
1475 while (intregs
> 0);
1478 /* Recursive workhorse for the following. */
1481 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*cum
, const_tree type
,
1482 HOST_WIDE_INT startbitpos
, rtx rvec
[],
1487 for (f
= TYPE_FIELDS (type
); f
; f
= DECL_CHAIN (f
))
1488 if (TREE_CODE (f
) == FIELD_DECL
)
1490 HOST_WIDE_INT bitpos
= startbitpos
;
1491 tree ftype
= TREE_TYPE (f
);
1493 if (ftype
== error_mark_node
)
1495 mode
= TYPE_MODE (ftype
);
1497 if (DECL_SIZE (f
) != 0
1498 && tree_fits_uhwi_p (bit_position (f
)))
1499 bitpos
+= int_bit_position (f
);
1501 /* ??? FIXME: else assume zero offset. */
1503 if (TREE_CODE (ftype
) == RECORD_TYPE
)
1504 rs6000_darwin64_record_arg_recurse (cum
, ftype
, bitpos
, rvec
, k
);
1505 else if (cum
->named
&& USE_FP_FOR_ARG_P (cum
, mode
))
1507 unsigned n_fpreg
= (GET_MODE_SIZE (mode
) + 7) >> 3;
1511 case E_SCmode
: mode
= SFmode
; break;
1512 case E_DCmode
: mode
= DFmode
; break;
1513 case E_TCmode
: mode
= TFmode
; break;
1517 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
1518 if (cum
->fregno
+ n_fpreg
> FP_ARG_MAX_REG
+ 1)
1520 gcc_assert (cum
->fregno
== FP_ARG_MAX_REG
1521 && (mode
== TFmode
|| mode
== TDmode
));
1522 /* Long double or _Decimal128 split over regs and memory. */
1523 mode
= DECIMAL_FLOAT_MODE_P (mode
) ? DDmode
: DFmode
;
1527 = gen_rtx_EXPR_LIST (VOIDmode
,
1528 gen_rtx_REG (mode
, cum
->fregno
++),
1529 GEN_INT (bitpos
/ BITS_PER_UNIT
));
1530 if (FLOAT128_2REG_P (mode
))
1533 else if (cum
->named
&& USE_ALTIVEC_FOR_ARG_P (cum
, mode
, 1))
1535 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
1537 = gen_rtx_EXPR_LIST (VOIDmode
,
1538 gen_rtx_REG (mode
, cum
->vregno
++),
1539 GEN_INT (bitpos
/ BITS_PER_UNIT
));
1541 else if (cum
->intoffset
== -1)
1542 cum
->intoffset
= bitpos
;
1546 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
1547 the register(s) to be used for each field and subfield of a struct
1548 being passed by value, along with the offset of where the
1549 register's value may be found in the block. FP fields go in FP
1550 register, vector fields go in vector registers, and everything
1551 else goes in int registers, packed as in memory.
1553 This code is also used for function return values. RETVAL indicates
1554 whether this is the case.
1556 Much of this is taken from the SPARC V9 port, which has a similar
1557 calling convention. */
1560 rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*orig_cum
, const_tree type
,
1561 bool named
, bool retval
)
1563 rtx rvec
[FIRST_PSEUDO_REGISTER
];
1564 int k
= 1, kbase
= 1;
1565 HOST_WIDE_INT typesize
= int_size_in_bytes (type
);
1566 /* This is a copy; modifications are not visible to our caller. */
1567 CUMULATIVE_ARGS copy_cum
= *orig_cum
;
1568 CUMULATIVE_ARGS
*cum
= ©_cum
;
1570 /* Pad to 16 byte boundary if needed. */
1571 if (!retval
&& TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
1572 && (cum
->words
% 2) != 0)
1579 /* Put entries into rvec[] for individual FP and vector fields, and
1580 for the chunks of memory that go in int regs. Note we start at
1581 element 1; 0 is reserved for an indication of using memory, and
1582 may or may not be filled in below. */
1583 rs6000_darwin64_record_arg_recurse (cum
, type
, /* startbit pos= */ 0, rvec
, &k
);
1584 rs6000_darwin64_record_arg_flush (cum
, typesize
* BITS_PER_UNIT
, rvec
, &k
);
1586 /* If any part of the struct went on the stack put all of it there.
1587 This hack is because the generic code for
1588 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
1589 parts of the struct are not at the beginning. */
1593 return NULL_RTX
; /* doesn't go in registers at all */
1595 rvec
[0] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
1597 if (k
> 1 || cum
->use_stack
)
1598 return gen_rtx_PARALLEL (BLKmode
, gen_rtvec_v (k
- kbase
, &rvec
[kbase
]));
1603 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
1606 rs6000_mixed_function_arg (machine_mode mode
, const_tree type
,
1611 rtx rvec
[GP_ARG_NUM_REG
+ 1];
1613 if (align_words
>= GP_ARG_NUM_REG
)
1616 n_units
= rs6000_arg_size (mode
, type
);
1618 /* Optimize the simple case where the arg fits in one gpr, except in
1619 the case of BLKmode due to assign_parms assuming that registers are
1620 BITS_PER_WORD wide. */
1622 || (n_units
== 1 && mode
!= BLKmode
))
1623 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
1626 if (align_words
+ n_units
> GP_ARG_NUM_REG
)
1627 /* Not all of the arg fits in gprs. Say that it goes in memory too,
1628 using a magic NULL_RTX component.
1629 This is not strictly correct. Only some of the arg belongs in
1630 memory, not all of it. However, the normal scheme using
1631 function_arg_partial_nregs can result in unusual subregs, eg.
1632 (subreg:SI (reg:DF) 4), which are not handled well. The code to
1633 store the whole arg to memory is often more efficient than code
1634 to store pieces, and we know that space is available in the right
1635 place for the whole arg. */
1636 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
1641 rtx r
= gen_rtx_REG (SImode
, GP_ARG_MIN_REG
+ align_words
);
1642 rtx off
= GEN_INT (i
++ * 4);
1643 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
1645 while (++align_words
< GP_ARG_NUM_REG
&& --n_units
!= 0);
1647 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
1650 /* We have an argument of MODE and TYPE that goes into FPRs or VRs,
1651 but must also be copied into the parameter save area starting at
1652 offset ALIGN_WORDS. Fill in RVEC with the elements corresponding
1653 to the GPRs and/or memory. Return the number of elements used. */
1656 rs6000_psave_function_arg (machine_mode mode
, const_tree type
,
1657 int align_words
, rtx
*rvec
)
1661 if (align_words
< GP_ARG_NUM_REG
)
1663 int n_words
= rs6000_arg_size (mode
, type
);
1665 if (align_words
+ n_words
> GP_ARG_NUM_REG
1667 || (TARGET_32BIT
&& TARGET_POWERPC64
))
1669 /* If this is partially on the stack, then we only
1670 include the portion actually in registers here. */
1671 machine_mode rmode
= TARGET_32BIT
? SImode
: DImode
;
1674 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
1676 /* Not all of the arg fits in gprs. Say that it goes in memory
1677 too, using a magic NULL_RTX component. Also see comment in
1678 rs6000_mixed_function_arg for why the normal
1679 function_arg_partial_nregs scheme doesn't work in this case. */
1680 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
1685 rtx r
= gen_rtx_REG (rmode
, GP_ARG_MIN_REG
+ align_words
);
1686 rtx off
= GEN_INT (i
++ * GET_MODE_SIZE (rmode
));
1687 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
1689 while (++align_words
< GP_ARG_NUM_REG
&& --n_words
!= 0);
1693 /* The whole arg fits in gprs. */
1694 rtx r
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
1695 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
1700 /* It's entirely in memory. */
1701 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
1707 /* RVEC is a vector of K components of an argument of mode MODE.
1708 Construct the final function_arg return value from it. */
1711 rs6000_finish_function_arg (machine_mode mode
, rtx
*rvec
, int k
)
1713 gcc_assert (k
>= 1);
1715 /* Avoid returning a PARALLEL in the trivial cases. */
1718 if (XEXP (rvec
[0], 0) == NULL_RTX
)
1721 if (GET_MODE (XEXP (rvec
[0], 0)) == mode
)
1722 return XEXP (rvec
[0], 0);
1725 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
1728 /* Determine where to put an argument to a function.
1729 Value is zero to push the argument on the stack,
1730 or a hard register in which to store the argument.
1732 CUM is a variable of type CUMULATIVE_ARGS which gives info about
1733 the preceding args and about the function being called. It is
1734 not modified in this routine.
1735 ARG is a description of the argument.
1737 On RS/6000 the first eight words of non-FP are normally in registers
1738 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
1739 Under V.4, the first 8 FP args are in registers.
1741 If this is floating-point and no prototype is specified, we use
1742 both an FP and integer register (or possibly FP reg and stack). Library
1743 functions (when CALL_LIBCALL is set) always have the proper types for args,
1744 so we can pass the FP value just in one register. emit_library_function
1745 doesn't support PARALLEL anyway.
1747 Note that for args passed by reference, function_arg will be called
1748 with ARG describing the pointer to the arg, not the arg itself. */
1751 rs6000_function_arg (cumulative_args_t cum_v
, const function_arg_info
&arg
)
1753 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
1754 tree type
= arg
.type
;
1755 machine_mode mode
= arg
.mode
;
1756 bool named
= arg
.named
;
1757 enum rs6000_abi abi
= DEFAULT_ABI
;
1758 machine_mode elt_mode
;
1761 /* Return a marker to indicate whether CR1 needs to set or clear the
1762 bit that V.4 uses to say fp args were passed in registers.
1763 Assume that we don't need the marker for software floating point,
1764 or compiler generated library calls. */
1765 if (arg
.end_marker_p ())
1768 && (cum
->call_cookie
& CALL_LIBCALL
) == 0
1770 || (cum
->nargs_prototype
< 0
1771 && (cum
->prototype
|| TARGET_NO_PROTOTYPE
)))
1772 && TARGET_HARD_FLOAT
)
1773 return GEN_INT (cum
->call_cookie
1774 | ((cum
->fregno
== FP_ARG_MIN_REG
)
1775 ? CALL_V4_SET_FP_ARGS
1776 : CALL_V4_CLEAR_FP_ARGS
));
1778 return GEN_INT (cum
->call_cookie
& ~CALL_LIBCALL
);
1781 rs6000_discover_homogeneous_aggregate (mode
, type
, &elt_mode
, &n_elts
);
1783 if (TARGET_MACHO
&& rs6000_darwin64_struct_check_p (mode
, type
))
1785 rtx rslt
= rs6000_darwin64_record_arg (cum
, type
, named
, /*retval= */false);
1786 if (rslt
!= NULL_RTX
)
1788 /* Else fall through to usual handling. */
1791 if (USE_ALTIVEC_FOR_ARG_P (cum
, elt_mode
, named
))
1793 rtx rvec
[GP_ARG_NUM_REG
+ AGGR_ARG_NUM_REG
+ 1];
1797 /* Do we also need to pass this argument in the parameter save area?
1798 Library support functions for IEEE 128-bit are assumed to not need the
1799 value passed both in GPRs and in vector registers. */
1800 if (TARGET_64BIT
&& !cum
->prototype
1801 && (!cum
->libcall
|| !FLOAT128_VECTOR_P (elt_mode
)))
1803 int align_words
= ROUND_UP (cum
->words
, 2);
1804 k
= rs6000_psave_function_arg (mode
, type
, align_words
, rvec
);
1807 /* Describe where this argument goes in the vector registers. */
1808 for (i
= 0; i
< n_elts
&& cum
->vregno
+ i
<= ALTIVEC_ARG_MAX_REG
; i
++)
1810 r
= gen_rtx_REG (elt_mode
, cum
->vregno
+ i
);
1811 off
= GEN_INT (i
* GET_MODE_SIZE (elt_mode
));
1812 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
1815 return rs6000_finish_function_arg (mode
, rvec
, k
);
1817 else if (TARGET_ALTIVEC_ABI
1818 && (ALTIVEC_OR_VSX_VECTOR_MODE (mode
)
1819 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
1820 && int_size_in_bytes (type
) == 16)))
1822 if (named
|| abi
== ABI_V4
)
1826 /* Vector parameters to varargs functions under AIX or Darwin
1827 get passed in memory and possibly also in GPRs. */
1828 int align
, align_words
, n_words
;
1829 machine_mode part_mode
;
1831 /* Vector parameters must be 16-byte aligned. In 32-bit
1832 mode this means we need to take into account the offset
1833 to the parameter save area. In 64-bit mode, they just
1834 have to start on an even word, since the parameter save
1835 area is 16-byte aligned. */
1837 align
= -(rs6000_parm_offset () + cum
->words
) & 3;
1839 align
= cum
->words
& 1;
1840 align_words
= cum
->words
+ align
;
1842 /* Out of registers? Memory, then. */
1843 if (align_words
>= GP_ARG_NUM_REG
)
1846 if (TARGET_32BIT
&& TARGET_POWERPC64
)
1847 return rs6000_mixed_function_arg (mode
, type
, align_words
);
1849 /* The vector value goes in GPRs. Only the part of the
1850 value in GPRs is reported here. */
1852 n_words
= rs6000_arg_size (mode
, type
);
1853 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
1854 /* Fortunately, there are only two possibilities, the value
1855 is either wholly in GPRs or half in GPRs and half not. */
1858 return gen_rtx_REG (part_mode
, GP_ARG_MIN_REG
+ align_words
);
1862 else if (abi
== ABI_V4
)
1864 if (abi_v4_pass_in_fpr (mode
, named
))
1866 /* _Decimal128 must use an even/odd register pair. This assumes
1867 that the register number is odd when fregno is odd. */
1868 if (mode
== TDmode
&& (cum
->fregno
% 2) == 1)
1871 if (cum
->fregno
+ (FLOAT128_2REG_P (mode
) ? 1 : 0)
1872 <= FP_ARG_V4_MAX_REG
)
1873 return gen_rtx_REG (mode
, cum
->fregno
);
1879 int n_words
= rs6000_arg_size (mode
, type
);
1880 int gregno
= cum
->sysv_gregno
;
1882 /* Long long is put in (r3,r4), (r5,r6), (r7,r8) or (r9,r10).
1883 As does any other 2 word item such as complex int due to a
1884 historical mistake. */
1886 gregno
+= (1 - gregno
) & 1;
1888 /* Multi-reg args are not split between registers and stack. */
1889 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
1892 if (TARGET_32BIT
&& TARGET_POWERPC64
)
1893 return rs6000_mixed_function_arg (mode
, type
,
1894 gregno
- GP_ARG_MIN_REG
);
1895 return gen_rtx_REG (mode
, gregno
);
1900 int align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
1902 /* _Decimal128 must be passed in an even/odd float register pair.
1903 This assumes that the register number is odd when fregno is odd. */
1904 if (elt_mode
== TDmode
&& (cum
->fregno
% 2) == 1)
1907 if (USE_FP_FOR_ARG_P (cum
, elt_mode
)
1908 && !(TARGET_AIX
&& !TARGET_ELF
1909 && type
!= NULL
&& AGGREGATE_TYPE_P (type
)))
1911 rtx rvec
[GP_ARG_NUM_REG
+ AGGR_ARG_NUM_REG
+ 1];
1914 unsigned long n_fpreg
= (GET_MODE_SIZE (elt_mode
) + 7) >> 3;
1917 /* Do we also need to pass this argument in the parameter
1919 if (type
&& (cum
->nargs_prototype
<= 0
1920 || ((DEFAULT_ABI
== ABI_AIX
|| DEFAULT_ABI
== ABI_ELFv2
)
1922 && align_words
>= GP_ARG_NUM_REG
)))
1923 k
= rs6000_psave_function_arg (mode
, type
, align_words
, rvec
);
1925 /* Describe where this argument goes in the fprs. */
1926 for (i
= 0; i
< n_elts
1927 && cum
->fregno
+ i
* n_fpreg
<= FP_ARG_MAX_REG
; i
++)
1929 /* Check if the argument is split over registers and memory.
1930 This can only ever happen for long double or _Decimal128;
1931 complex types are handled via split_complex_arg. */
1932 machine_mode fmode
= elt_mode
;
1933 if (cum
->fregno
+ (i
+ 1) * n_fpreg
> FP_ARG_MAX_REG
+ 1)
1935 gcc_assert (FLOAT128_2REG_P (fmode
));
1936 fmode
= DECIMAL_FLOAT_MODE_P (fmode
) ? DDmode
: DFmode
;
1939 r
= gen_rtx_REG (fmode
, cum
->fregno
+ i
* n_fpreg
);
1940 off
= GEN_INT (i
* GET_MODE_SIZE (elt_mode
));
1941 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
1944 /* If there were not enough FPRs to hold the argument, the rest
1945 usually goes into memory. However, if the current position
1946 is still within the register parameter area, a portion may
1947 actually have to go into GPRs.
1949 Note that it may happen that the portion of the argument
1950 passed in the first "half" of the first GPR was already
1951 passed in the last FPR as well.
1953 For unnamed arguments, we already set up GPRs to cover the
1954 whole argument in rs6000_psave_function_arg, so there is
1955 nothing further to do at this point. */
1956 fpr_words
= (i
* GET_MODE_SIZE (elt_mode
)) / (TARGET_32BIT
? 4 : 8);
1957 if (i
< n_elts
&& align_words
+ fpr_words
< GP_ARG_NUM_REG
1958 && cum
->nargs_prototype
> 0)
1962 machine_mode rmode
= TARGET_32BIT
? SImode
: DImode
;
1963 int n_words
= rs6000_arg_size (mode
, type
);
1965 align_words
+= fpr_words
;
1966 n_words
-= fpr_words
;
1970 r
= gen_rtx_REG (rmode
, GP_ARG_MIN_REG
+ align_words
);
1971 off
= GEN_INT (fpr_words
++ * GET_MODE_SIZE (rmode
));
1972 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
1974 while (++align_words
< GP_ARG_NUM_REG
&& --n_words
!= 0);
1976 if (!warned
&& warn_psabi
)
1979 inform (input_location
,
1980 "the ABI of passing homogeneous %<float%> aggregates"
1981 " has changed in GCC 5");
1985 return rs6000_finish_function_arg (mode
, rvec
, k
);
1987 else if (align_words
< GP_ARG_NUM_REG
)
1989 if (TARGET_32BIT
&& TARGET_POWERPC64
)
1990 return rs6000_mixed_function_arg (mode
, type
, align_words
);
1992 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
1999 /* For an arg passed partly in registers and partly in memory, this is
2000 the number of bytes passed in registers. For args passed entirely in
2001 registers or entirely in memory, zero. When an arg is described by a
2002 PARALLEL, perhaps using more than one register type, this function
2003 returns the number of bytes used by the first element of the PARALLEL. */
2006 rs6000_arg_partial_bytes (cumulative_args_t cum_v
,
2007 const function_arg_info
&arg
)
2009 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
2010 bool passed_in_gprs
= true;
2013 machine_mode elt_mode
;
2016 rs6000_discover_homogeneous_aggregate (arg
.mode
, arg
.type
,
2017 &elt_mode
, &n_elts
);
2019 if (DEFAULT_ABI
== ABI_V4
)
2022 if (USE_ALTIVEC_FOR_ARG_P (cum
, elt_mode
, arg
.named
))
2024 /* If we are passing this arg in the fixed parameter save area (gprs or
2025 memory) as well as VRs, we do not use the partial bytes mechanism;
2026 instead, rs6000_function_arg will return a PARALLEL including a memory
2027 element as necessary. Library support functions for IEEE 128-bit are
2028 assumed to not need the value passed both in GPRs and in vector
2030 if (TARGET_64BIT
&& !cum
->prototype
2031 && (!cum
->libcall
|| !FLOAT128_VECTOR_P (elt_mode
)))
2034 /* Otherwise, we pass in VRs only. Check for partial copies. */
2035 passed_in_gprs
= false;
2036 if (cum
->vregno
+ n_elts
> ALTIVEC_ARG_MAX_REG
+ 1)
2037 ret
= (ALTIVEC_ARG_MAX_REG
+ 1 - cum
->vregno
) * 16;
2040 /* In this complicated case we just disable the partial_nregs code. */
2041 if (TARGET_MACHO
&& rs6000_darwin64_struct_check_p (arg
.mode
, arg
.type
))
2044 align_words
= rs6000_parm_start (arg
.mode
, arg
.type
, cum
->words
);
2046 if (USE_FP_FOR_ARG_P (cum
, elt_mode
)
2047 && !(TARGET_AIX
&& !TARGET_ELF
&& arg
.aggregate_type_p ()))
2049 unsigned long n_fpreg
= (GET_MODE_SIZE (elt_mode
) + 7) >> 3;
2051 /* If we are passing this arg in the fixed parameter save area
2052 (gprs or memory) as well as FPRs, we do not use the partial
2053 bytes mechanism; instead, rs6000_function_arg will return a
2054 PARALLEL including a memory element as necessary. */
2056 && (cum
->nargs_prototype
<= 0
2057 || ((DEFAULT_ABI
== ABI_AIX
|| DEFAULT_ABI
== ABI_ELFv2
)
2059 && align_words
>= GP_ARG_NUM_REG
)))
2062 /* Otherwise, we pass in FPRs only. Check for partial copies. */
2063 passed_in_gprs
= false;
2064 if (cum
->fregno
+ n_elts
* n_fpreg
> FP_ARG_MAX_REG
+ 1)
2066 /* Compute number of bytes / words passed in FPRs. If there
2067 is still space available in the register parameter area
2068 *after* that amount, a part of the argument will be passed
2069 in GPRs. In that case, the total amount passed in any
2070 registers is equal to the amount that would have been passed
2071 in GPRs if everything were passed there, so we fall back to
2072 the GPR code below to compute the appropriate value. */
2073 int fpr
= ((FP_ARG_MAX_REG
+ 1 - cum
->fregno
)
2074 * MIN (8, GET_MODE_SIZE (elt_mode
)));
2075 int fpr_words
= fpr
/ (TARGET_32BIT
? 4 : 8);
2077 if (align_words
+ fpr_words
< GP_ARG_NUM_REG
)
2078 passed_in_gprs
= true;
2085 && align_words
< GP_ARG_NUM_REG
2086 && GP_ARG_NUM_REG
< align_words
+ rs6000_arg_size (arg
.mode
, arg
.type
))
2087 ret
= (GP_ARG_NUM_REG
- align_words
) * (TARGET_32BIT
? 4 : 8);
2089 if (ret
!= 0 && TARGET_DEBUG_ARG
)
2090 fprintf (stderr
, "rs6000_arg_partial_bytes: %d\n", ret
);
2095 /* A C expression that indicates when an argument must be passed by
2096 reference. If nonzero for an argument, a copy of that argument is
2097 made in memory and a pointer to the argument is passed instead of
2098 the argument itself. The pointer is passed in whatever way is
2099 appropriate for passing a pointer to that type.
2101 Under V.4, aggregates and long double are passed by reference.
2103 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
2104 reference unless the AltiVec vector extension ABI is in force.
2106 As an extension to all ABIs, variable sized types are passed by
2110 rs6000_pass_by_reference (cumulative_args_t
, const function_arg_info
&arg
)
2115 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
2116 && FLOAT128_IEEE_P (TYPE_MODE (arg
.type
)))
2118 if (TARGET_DEBUG_ARG
)
2119 fprintf (stderr
, "function_arg_pass_by_reference: V4 IEEE 128-bit\n");
2123 if (DEFAULT_ABI
== ABI_V4
&& AGGREGATE_TYPE_P (arg
.type
))
2125 if (TARGET_DEBUG_ARG
)
2126 fprintf (stderr
, "function_arg_pass_by_reference: V4 aggregate\n");
2130 if (int_size_in_bytes (arg
.type
) < 0)
2132 if (TARGET_DEBUG_ARG
)
2133 fprintf (stderr
, "function_arg_pass_by_reference: variable size\n");
2137 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
2138 modes only exist for GCC vector types if -maltivec. */
2139 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (arg
.mode
))
2141 if (TARGET_DEBUG_ARG
)
2142 fprintf (stderr
, "function_arg_pass_by_reference: AltiVec\n");
2146 /* Pass synthetic vectors in memory. */
2147 if (TREE_CODE (arg
.type
) == VECTOR_TYPE
2148 && int_size_in_bytes (arg
.type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
2150 static bool warned_for_pass_big_vectors
= false;
2151 if (TARGET_DEBUG_ARG
)
2152 fprintf (stderr
, "function_arg_pass_by_reference: synthetic vector\n");
2153 if (!warned_for_pass_big_vectors
)
2155 warning (OPT_Wpsabi
, "GCC vector passed by reference: "
2156 "non-standard ABI extension with no compatibility "
2158 warned_for_pass_big_vectors
= true;
2166 /* Process parameter of type TYPE after ARGS_SO_FAR parameters were
2167 already processes. Return true if the parameter must be passed
2168 (fully or partially) on the stack. */
2171 rs6000_parm_needs_stack (cumulative_args_t args_so_far
, tree type
)
2178 if (type
== NULL
|| type
== error_mark_node
)
2181 /* Handle types with no storage requirement. */
2182 if (TYPE_MODE (type
) == VOIDmode
)
2185 /* Handle complex types. */
2186 if (TREE_CODE (type
) == COMPLEX_TYPE
)
2187 return (rs6000_parm_needs_stack (args_so_far
, TREE_TYPE (type
))
2188 || rs6000_parm_needs_stack (args_so_far
, TREE_TYPE (type
)));
2190 /* Handle transparent aggregates. */
2191 if ((TREE_CODE (type
) == UNION_TYPE
|| TREE_CODE (type
) == RECORD_TYPE
)
2192 && TYPE_TRANSPARENT_AGGR (type
))
2193 type
= TREE_TYPE (first_field (type
));
2195 /* See if this arg was passed by invisible reference. */
2196 if (pass_by_reference (get_cumulative_args (args_so_far
),
2197 function_arg_info (type
, /*named=*/true)))
2198 type
= build_pointer_type (type
);
2200 /* Find mode as it is passed by the ABI. */
2201 unsignedp
= TYPE_UNSIGNED (type
);
2202 mode
= promote_mode (type
, TYPE_MODE (type
), &unsignedp
);
2204 /* If we must pass in stack, we need a stack. */
2205 function_arg_info
arg (type
, mode
, /*named=*/true);
2206 if (rs6000_must_pass_in_stack (arg
))
2209 /* If there is no incoming register, we need a stack. */
2210 entry_parm
= rs6000_function_arg (args_so_far
, arg
);
2211 if (entry_parm
== NULL
)
2214 /* Likewise if we need to pass both in registers and on the stack. */
2215 if (GET_CODE (entry_parm
) == PARALLEL
2216 && XEXP (XVECEXP (entry_parm
, 0, 0), 0) == NULL_RTX
)
2219 /* Also true if we're partially in registers and partially not. */
2220 if (rs6000_arg_partial_bytes (args_so_far
, arg
) != 0)
2223 /* Update info on where next arg arrives in registers. */
2224 rs6000_function_arg_advance (args_so_far
, arg
);
2228 /* Return true if FUN has no prototype, has a variable argument
2229 list, or passes any parameter in memory. */
2232 rs6000_function_parms_need_stack (tree fun
, bool incoming
)
2234 tree fntype
, result
;
2235 CUMULATIVE_ARGS args_so_far_v
;
2236 cumulative_args_t args_so_far
;
2239 /* Must be a libcall, all of which only use reg parms. */
2244 fntype
= TREE_TYPE (fun
);
2246 /* Varargs functions need the parameter save area. */
2247 if ((!incoming
&& !prototype_p (fntype
)) || stdarg_p (fntype
))
2250 INIT_CUMULATIVE_INCOMING_ARGS (args_so_far_v
, fntype
, NULL_RTX
);
2251 args_so_far
= pack_cumulative_args (&args_so_far_v
);
2253 /* When incoming, we will have been passed the function decl.
2254 It is necessary to use the decl to handle K&R style functions,
2255 where TYPE_ARG_TYPES may not be available. */
2258 gcc_assert (DECL_P (fun
));
2259 result
= DECL_RESULT (fun
);
2262 result
= TREE_TYPE (fntype
);
2264 if (result
&& aggregate_value_p (result
, fntype
))
2266 if (!TYPE_P (result
))
2267 result
= TREE_TYPE (result
);
2268 result
= build_pointer_type (result
);
2269 rs6000_parm_needs_stack (args_so_far
, result
);
2276 for (parm
= DECL_ARGUMENTS (fun
);
2277 parm
&& parm
!= void_list_node
;
2278 parm
= TREE_CHAIN (parm
))
2279 if (rs6000_parm_needs_stack (args_so_far
, TREE_TYPE (parm
)))
2284 function_args_iterator args_iter
;
2287 FOREACH_FUNCTION_ARGS (fntype
, arg_type
, args_iter
)
2288 if (rs6000_parm_needs_stack (args_so_far
, arg_type
))
2295 /* Return the size of the REG_PARM_STACK_SPACE are for FUN. This is
2296 usually a constant depending on the ABI. However, in the ELFv2 ABI
2297 the register parameter area is optional when calling a function that
2298 has a prototype is scope, has no variable argument list, and passes
2299 all parameters in registers. */
2302 rs6000_reg_parm_stack_space (tree fun
, bool incoming
)
2304 int reg_parm_stack_space
;
2306 switch (DEFAULT_ABI
)
2309 reg_parm_stack_space
= 0;
2314 reg_parm_stack_space
= TARGET_64BIT
? 64 : 32;
2318 /* ??? Recomputing this every time is a bit expensive. Is there
2319 a place to cache this information? */
2320 if (rs6000_function_parms_need_stack (fun
, incoming
))
2321 reg_parm_stack_space
= TARGET_64BIT
? 64 : 32;
2323 reg_parm_stack_space
= 0;
2327 return reg_parm_stack_space
;
2331 rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
)
2334 machine_mode reg_mode
= TARGET_32BIT
? SImode
: DImode
;
2339 for (i
= 0; i
< nregs
; i
++)
2341 rtx tem
= adjust_address_nv (x
, reg_mode
, i
* GET_MODE_SIZE (reg_mode
));
2342 if (reload_completed
)
2344 if (! strict_memory_address_p (reg_mode
, XEXP (tem
, 0)))
2347 tem
= simplify_gen_subreg (reg_mode
, x
, BLKmode
,
2348 i
* GET_MODE_SIZE (reg_mode
));
2351 tem
= replace_equiv_address (tem
, XEXP (tem
, 0));
2355 emit_move_insn (tem
, gen_rtx_REG (reg_mode
, regno
+ i
));
2359 /* Perform any needed actions needed for a function that is receiving a
2360 variable number of arguments.
2364 ARG is the last named argument.
2366 PRETEND_SIZE is a variable that should be set to the amount of stack
2367 that must be pushed by the prolog to pretend that our caller pushed
2370 Normally, this macro will push all remaining incoming registers on the
2371 stack and set PRETEND_SIZE to the length of the registers pushed. */
2374 setup_incoming_varargs (cumulative_args_t cum
,
2375 const function_arg_info
&arg
,
2376 int *pretend_size ATTRIBUTE_UNUSED
, int no_rtl
)
2378 CUMULATIVE_ARGS next_cum
;
2379 int reg_size
= TARGET_32BIT
? 4 : 8;
2380 rtx save_area
= NULL_RTX
, mem
;
2381 int first_reg_offset
;
2384 /* Skip the last named argument. */
2385 next_cum
= *get_cumulative_args (cum
);
2386 rs6000_function_arg_advance_1 (&next_cum
, arg
.mode
, arg
.type
, arg
.named
, 0);
2388 if (DEFAULT_ABI
== ABI_V4
)
2390 first_reg_offset
= next_cum
.sysv_gregno
- GP_ARG_MIN_REG
;
2394 int gpr_reg_num
= 0, gpr_size
= 0, fpr_size
= 0;
2395 HOST_WIDE_INT offset
= 0;
2397 /* Try to optimize the size of the varargs save area.
2398 The ABI requires that ap.reg_save_area is doubleword
2399 aligned, but we don't need to allocate space for all
2400 the bytes, only those to which we actually will save
2402 if (cfun
->va_list_gpr_size
&& first_reg_offset
< GP_ARG_NUM_REG
)
2403 gpr_reg_num
= GP_ARG_NUM_REG
- first_reg_offset
;
2404 if (TARGET_HARD_FLOAT
2405 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
2406 && cfun
->va_list_fpr_size
)
2409 fpr_size
= (next_cum
.fregno
- FP_ARG_MIN_REG
)
2410 * UNITS_PER_FP_WORD
;
2411 if (cfun
->va_list_fpr_size
2412 < FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
2413 fpr_size
+= cfun
->va_list_fpr_size
* UNITS_PER_FP_WORD
;
2415 fpr_size
+= (FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
2416 * UNITS_PER_FP_WORD
;
2420 offset
= -((first_reg_offset
* reg_size
) & ~7);
2421 if (!fpr_size
&& gpr_reg_num
> cfun
->va_list_gpr_size
)
2423 gpr_reg_num
= cfun
->va_list_gpr_size
;
2424 if (reg_size
== 4 && (first_reg_offset
& 1))
2427 gpr_size
= (gpr_reg_num
* reg_size
+ 7) & ~7;
2430 offset
= - (int) (next_cum
.fregno
- FP_ARG_MIN_REG
)
2432 - (int) (GP_ARG_NUM_REG
* reg_size
);
2434 if (gpr_size
+ fpr_size
)
2437 = assign_stack_local (BLKmode
, gpr_size
+ fpr_size
, 64);
2438 gcc_assert (MEM_P (reg_save_area
));
2439 reg_save_area
= XEXP (reg_save_area
, 0);
2440 if (GET_CODE (reg_save_area
) == PLUS
)
2442 gcc_assert (XEXP (reg_save_area
, 0)
2443 == virtual_stack_vars_rtx
);
2444 gcc_assert (CONST_INT_P (XEXP (reg_save_area
, 1)));
2445 offset
+= INTVAL (XEXP (reg_save_area
, 1));
2448 gcc_assert (reg_save_area
== virtual_stack_vars_rtx
);
2451 cfun
->machine
->varargs_save_offset
= offset
;
2452 save_area
= plus_constant (Pmode
, virtual_stack_vars_rtx
, offset
);
2457 first_reg_offset
= next_cum
.words
;
2458 save_area
= crtl
->args
.internal_arg_pointer
;
2460 if (targetm
.calls
.must_pass_in_stack (arg
))
2461 first_reg_offset
+= rs6000_arg_size (TYPE_MODE (arg
.type
), arg
.type
);
2464 set
= get_varargs_alias_set ();
2465 if (! no_rtl
&& first_reg_offset
< GP_ARG_NUM_REG
2466 && cfun
->va_list_gpr_size
)
2468 int n_gpr
, nregs
= GP_ARG_NUM_REG
- first_reg_offset
;
2470 if (va_list_gpr_counter_field
)
2471 /* V4 va_list_gpr_size counts number of registers needed. */
2472 n_gpr
= cfun
->va_list_gpr_size
;
2474 /* char * va_list instead counts number of bytes needed. */
2475 n_gpr
= (cfun
->va_list_gpr_size
+ reg_size
- 1) / reg_size
;
2480 mem
= gen_rtx_MEM (BLKmode
,
2481 plus_constant (Pmode
, save_area
,
2482 first_reg_offset
* reg_size
));
2483 MEM_NOTRAP_P (mem
) = 1;
2484 set_mem_alias_set (mem
, set
);
2485 set_mem_align (mem
, BITS_PER_WORD
);
2487 rs6000_move_block_from_reg (GP_ARG_MIN_REG
+ first_reg_offset
, mem
,
2491 /* Save FP registers if needed. */
2492 if (DEFAULT_ABI
== ABI_V4
2493 && TARGET_HARD_FLOAT
2495 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
2496 && cfun
->va_list_fpr_size
)
2498 int fregno
= next_cum
.fregno
, nregs
;
2499 rtx cr1
= gen_rtx_REG (CCmode
, CR1_REGNO
);
2500 rtx lab
= gen_label_rtx ();
2501 int off
= (GP_ARG_NUM_REG
* reg_size
) + ((fregno
- FP_ARG_MIN_REG
)
2502 * UNITS_PER_FP_WORD
);
2505 (gen_rtx_SET (pc_rtx
,
2506 gen_rtx_IF_THEN_ELSE (VOIDmode
,
2507 gen_rtx_NE (VOIDmode
, cr1
,
2509 gen_rtx_LABEL_REF (VOIDmode
, lab
),
2513 fregno
<= FP_ARG_V4_MAX_REG
&& nregs
< cfun
->va_list_fpr_size
;
2514 fregno
++, off
+= UNITS_PER_FP_WORD
, nregs
++)
2516 mem
= gen_rtx_MEM (TARGET_HARD_FLOAT
? DFmode
: SFmode
,
2517 plus_constant (Pmode
, save_area
, off
));
2518 MEM_NOTRAP_P (mem
) = 1;
2519 set_mem_alias_set (mem
, set
);
2520 set_mem_align (mem
, GET_MODE_ALIGNMENT (
2521 TARGET_HARD_FLOAT
? DFmode
: SFmode
));
2522 emit_move_insn (mem
, gen_rtx_REG (
2523 TARGET_HARD_FLOAT
? DFmode
: SFmode
, fregno
));
2530 /* Create the va_list data type. */
2533 rs6000_build_builtin_va_list (void)
2535 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
, record
, type_decl
;
2537 /* For AIX, prefer 'char *' because that's what the system
2538 header files like. */
2539 if (DEFAULT_ABI
!= ABI_V4
)
2540 return build_pointer_type (char_type_node
);
2542 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
2543 type_decl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
2544 get_identifier ("__va_list_tag"), record
);
2546 f_gpr
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, get_identifier ("gpr"),
2547 unsigned_char_type_node
);
2548 f_fpr
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, get_identifier ("fpr"),
2549 unsigned_char_type_node
);
2550 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
2552 f_res
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
2553 get_identifier ("reserved"), short_unsigned_type_node
);
2554 f_ovf
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
2555 get_identifier ("overflow_arg_area"),
2557 f_sav
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
2558 get_identifier ("reg_save_area"),
2561 va_list_gpr_counter_field
= f_gpr
;
2562 va_list_fpr_counter_field
= f_fpr
;
2564 DECL_FIELD_CONTEXT (f_gpr
) = record
;
2565 DECL_FIELD_CONTEXT (f_fpr
) = record
;
2566 DECL_FIELD_CONTEXT (f_res
) = record
;
2567 DECL_FIELD_CONTEXT (f_ovf
) = record
;
2568 DECL_FIELD_CONTEXT (f_sav
) = record
;
2570 TYPE_STUB_DECL (record
) = type_decl
;
2571 TYPE_NAME (record
) = type_decl
;
2572 TYPE_FIELDS (record
) = f_gpr
;
2573 DECL_CHAIN (f_gpr
) = f_fpr
;
2574 DECL_CHAIN (f_fpr
) = f_res
;
2575 DECL_CHAIN (f_res
) = f_ovf
;
2576 DECL_CHAIN (f_ovf
) = f_sav
;
2578 layout_type (record
);
2580 /* The correct type is an array type of one element. */
2581 return build_array_type (record
, build_index_type (size_zero_node
));
2584 /* Implement va_start. */
2587 rs6000_va_start (tree valist
, rtx nextarg
)
2589 HOST_WIDE_INT words
, n_gpr
, n_fpr
;
2590 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
2591 tree gpr
, fpr
, ovf
, sav
, t
;
2593 /* Only SVR4 needs something special. */
2594 if (DEFAULT_ABI
!= ABI_V4
)
2596 std_expand_builtin_va_start (valist
, nextarg
);
2600 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
2601 f_fpr
= DECL_CHAIN (f_gpr
);
2602 f_res
= DECL_CHAIN (f_fpr
);
2603 f_ovf
= DECL_CHAIN (f_res
);
2604 f_sav
= DECL_CHAIN (f_ovf
);
2606 valist
= build_simple_mem_ref (valist
);
2607 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
2608 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), unshare_expr (valist
),
2610 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), unshare_expr (valist
),
2612 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), unshare_expr (valist
),
2615 /* Count number of gp and fp argument registers used. */
2616 words
= crtl
->args
.info
.words
;
2617 n_gpr
= MIN (crtl
->args
.info
.sysv_gregno
- GP_ARG_MIN_REG
,
2619 n_fpr
= MIN (crtl
->args
.info
.fregno
- FP_ARG_MIN_REG
,
2622 if (TARGET_DEBUG_ARG
)
2623 fprintf (stderr
, "va_start: words = " HOST_WIDE_INT_PRINT_DEC
", n_gpr = "
2624 HOST_WIDE_INT_PRINT_DEC
", n_fpr = " HOST_WIDE_INT_PRINT_DEC
"\n",
2625 words
, n_gpr
, n_fpr
);
2627 if (cfun
->va_list_gpr_size
)
2629 t
= build2 (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
,
2630 build_int_cst (NULL_TREE
, n_gpr
));
2631 TREE_SIDE_EFFECTS (t
) = 1;
2632 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2635 if (cfun
->va_list_fpr_size
)
2637 t
= build2 (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
,
2638 build_int_cst (NULL_TREE
, n_fpr
));
2639 TREE_SIDE_EFFECTS (t
) = 1;
2640 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2642 #ifdef HAVE_AS_GNU_ATTRIBUTE
2643 if (call_ABI_of_interest (cfun
->decl
))
2644 rs6000_passes_float
= true;
2648 /* Find the overflow area. */
2649 t
= make_tree (TREE_TYPE (ovf
), crtl
->args
.internal_arg_pointer
);
2651 t
= fold_build_pointer_plus_hwi (t
, words
* MIN_UNITS_PER_WORD
);
2652 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
2653 TREE_SIDE_EFFECTS (t
) = 1;
2654 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2656 /* If there were no va_arg invocations, don't set up the register
2658 if (!cfun
->va_list_gpr_size
2659 && !cfun
->va_list_fpr_size
2660 && n_gpr
< GP_ARG_NUM_REG
2661 && n_fpr
< FP_ARG_V4_MAX_REG
)
2664 /* Find the register save area. */
2665 t
= make_tree (TREE_TYPE (sav
), virtual_stack_vars_rtx
);
2666 if (cfun
->machine
->varargs_save_offset
)
2667 t
= fold_build_pointer_plus_hwi (t
, cfun
->machine
->varargs_save_offset
);
2668 t
= build2 (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
2669 TREE_SIDE_EFFECTS (t
) = 1;
2670 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2673 /* Implement va_arg. */
2676 rs6000_gimplify_va_arg (tree valist
, tree type
, gimple_seq
*pre_p
,
2679 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
2680 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
2681 int size
, rsize
, n_reg
, sav_ofs
, sav_scale
;
2682 tree lab_false
, lab_over
, addr
;
2684 tree ptrtype
= build_pointer_type_for_mode (type
, ptr_mode
, true);
2688 if (pass_va_arg_by_reference (type
))
2690 t
= rs6000_gimplify_va_arg (valist
, ptrtype
, pre_p
, post_p
);
2691 return build_va_arg_indirect_ref (t
);
2694 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
2695 earlier version of gcc, with the property that it always applied alignment
2696 adjustments to the va-args (even for zero-sized types). The cheapest way
2697 to deal with this is to replicate the effect of the part of
2698 std_gimplify_va_arg_expr that carries out the align adjust, for the case
2700 We don't need to check for pass-by-reference because of the test above.
2701 We can return a simplifed answer, since we know there's no offset to add. */
2704 && rs6000_darwin64_abi
)
2705 || DEFAULT_ABI
== ABI_ELFv2
2706 || (DEFAULT_ABI
== ABI_AIX
&& !rs6000_compat_align_parm
))
2707 && integer_zerop (TYPE_SIZE (type
)))
2709 unsigned HOST_WIDE_INT align
, boundary
;
2710 tree valist_tmp
= get_initialized_tmp_var (valist
, pre_p
, NULL
);
2711 align
= PARM_BOUNDARY
/ BITS_PER_UNIT
;
2712 boundary
= rs6000_function_arg_boundary (TYPE_MODE (type
), type
);
2713 if (boundary
> MAX_SUPPORTED_STACK_ALIGNMENT
)
2714 boundary
= MAX_SUPPORTED_STACK_ALIGNMENT
;
2715 boundary
/= BITS_PER_UNIT
;
2716 if (boundary
> align
)
2719 /* This updates arg ptr by the amount that would be necessary
2720 to align the zero-sized (but not zero-alignment) item. */
2721 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
2722 fold_build_pointer_plus_hwi (valist_tmp
, boundary
- 1));
2723 gimplify_and_add (t
, pre_p
);
2725 t
= fold_convert (sizetype
, valist_tmp
);
2726 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
2727 fold_convert (TREE_TYPE (valist
),
2728 fold_build2 (BIT_AND_EXPR
, sizetype
, t
,
2729 size_int (-boundary
))));
2730 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
, t
);
2731 gimplify_and_add (t
, pre_p
);
2733 /* Since it is zero-sized there's no increment for the item itself. */
2734 valist_tmp
= fold_convert (build_pointer_type (type
), valist_tmp
);
2735 return build_va_arg_indirect_ref (valist_tmp
);
2738 if (DEFAULT_ABI
!= ABI_V4
)
2740 if (targetm
.calls
.split_complex_arg
&& TREE_CODE (type
) == COMPLEX_TYPE
)
2742 tree elem_type
= TREE_TYPE (type
);
2743 machine_mode elem_mode
= TYPE_MODE (elem_type
);
2744 int elem_size
= GET_MODE_SIZE (elem_mode
);
2746 if (elem_size
< UNITS_PER_WORD
)
2748 tree real_part
, imag_part
;
2749 gimple_seq post
= NULL
;
2751 real_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
2753 /* Copy the value into a temporary, lest the formal temporary
2754 be reused out from under us. */
2755 real_part
= get_initialized_tmp_var (real_part
, pre_p
, &post
);
2756 gimple_seq_add_seq (pre_p
, post
);
2758 imag_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
2761 return build2 (COMPLEX_EXPR
, type
, real_part
, imag_part
);
2765 return std_gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
2768 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
2769 f_fpr
= DECL_CHAIN (f_gpr
);
2770 f_res
= DECL_CHAIN (f_fpr
);
2771 f_ovf
= DECL_CHAIN (f_res
);
2772 f_sav
= DECL_CHAIN (f_ovf
);
2774 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
2775 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), unshare_expr (valist
),
2777 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), unshare_expr (valist
),
2779 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), unshare_expr (valist
),
2782 size
= int_size_in_bytes (type
);
2783 rsize
= (size
+ 3) / 4;
2784 int pad
= 4 * rsize
- size
;
2787 machine_mode mode
= TYPE_MODE (type
);
2788 if (abi_v4_pass_in_fpr (mode
, false))
2790 /* FP args go in FP registers, if present. */
2792 n_reg
= (size
+ 7) / 8;
2793 sav_ofs
= (TARGET_HARD_FLOAT
? 8 : 4) * 4;
2794 sav_scale
= (TARGET_HARD_FLOAT
? 8 : 4);
2795 if (mode
!= SFmode
&& mode
!= SDmode
)
2800 /* Otherwise into GP registers. */
2809 /* Pull the value out of the saved registers.... */
2812 addr
= create_tmp_var (ptr_type_node
, "addr");
2814 /* AltiVec vectors never go in registers when -mabi=altivec. */
2815 if (TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
2819 lab_false
= create_artificial_label (input_location
);
2820 lab_over
= create_artificial_label (input_location
);
2822 /* Long long is aligned in the registers. As are any other 2 gpr
2823 item such as complex int due to a historical mistake. */
2825 if (n_reg
== 2 && reg
== gpr
)
2828 u
= build2 (BIT_AND_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
2829 build_int_cst (TREE_TYPE (reg
), n_reg
- 1));
2830 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
),
2831 unshare_expr (reg
), u
);
2833 /* _Decimal128 is passed in even/odd fpr pairs; the stored
2834 reg number is 0 for f1, so we want to make it odd. */
2835 else if (reg
== fpr
&& mode
== TDmode
)
2837 t
= build2 (BIT_IOR_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
2838 build_int_cst (TREE_TYPE (reg
), 1));
2839 u
= build2 (MODIFY_EXPR
, void_type_node
, unshare_expr (reg
), t
);
2842 t
= fold_convert (TREE_TYPE (reg
), size_int (8 - n_reg
+ 1));
2843 t
= build2 (GE_EXPR
, boolean_type_node
, u
, t
);
2844 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
2845 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
2846 gimplify_and_add (t
, pre_p
);
2850 t
= fold_build_pointer_plus_hwi (sav
, sav_ofs
);
2852 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
), unshare_expr (reg
),
2853 build_int_cst (TREE_TYPE (reg
), n_reg
));
2854 u
= fold_convert (sizetype
, u
);
2855 u
= build2 (MULT_EXPR
, sizetype
, u
, size_int (sav_scale
));
2856 t
= fold_build_pointer_plus (t
, u
);
2858 /* _Decimal32 varargs are located in the second word of the 64-bit
2859 FP register for 32-bit binaries. */
2860 if (TARGET_32BIT
&& TARGET_HARD_FLOAT
&& mode
== SDmode
)
2861 t
= fold_build_pointer_plus_hwi (t
, size
);
2863 /* Args are passed right-aligned. */
2864 if (BYTES_BIG_ENDIAN
)
2865 t
= fold_build_pointer_plus_hwi (t
, pad
);
2867 gimplify_assign (addr
, t
, pre_p
);
2869 gimple_seq_add_stmt (pre_p
, gimple_build_goto (lab_over
));
2871 stmt
= gimple_build_label (lab_false
);
2872 gimple_seq_add_stmt (pre_p
, stmt
);
2874 if ((n_reg
== 2 && !regalign
) || n_reg
> 2)
2876 /* Ensure that we don't find any more args in regs.
2877 Alignment has taken care of for special cases. */
2878 gimplify_assign (reg
, build_int_cst (TREE_TYPE (reg
), 8), pre_p
);
2882 /* ... otherwise out of the overflow area. */
2884 /* Care for on-stack alignment if needed. */
2888 t
= fold_build_pointer_plus_hwi (t
, align
- 1);
2889 t
= build2 (BIT_AND_EXPR
, TREE_TYPE (t
), t
,
2890 build_int_cst (TREE_TYPE (t
), -align
));
2893 /* Args are passed right-aligned. */
2894 if (BYTES_BIG_ENDIAN
)
2895 t
= fold_build_pointer_plus_hwi (t
, pad
);
2897 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
2899 gimplify_assign (unshare_expr (addr
), t
, pre_p
);
2901 t
= fold_build_pointer_plus_hwi (t
, size
);
2902 gimplify_assign (unshare_expr (ovf
), t
, pre_p
);
2906 stmt
= gimple_build_label (lab_over
);
2907 gimple_seq_add_stmt (pre_p
, stmt
);
2910 if (STRICT_ALIGNMENT
2911 && (TYPE_ALIGN (type
)
2912 > (unsigned) BITS_PER_UNIT
* (align
< 4 ? 4 : align
)))
2914 /* The value (of type complex double, for example) may not be
2915 aligned in memory in the saved registers, so copy via a
2916 temporary. (This is the same code as used for SPARC.) */
2917 tree tmp
= create_tmp_var (type
, "va_arg_tmp");
2918 tree dest_addr
= build_fold_addr_expr (tmp
);
2920 tree copy
= build_call_expr (builtin_decl_implicit (BUILT_IN_MEMCPY
),
2921 3, dest_addr
, addr
, size_int (rsize
* 4));
2922 TREE_ADDRESSABLE (tmp
) = 1;
2924 gimplify_and_add (copy
, pre_p
);
2928 addr
= fold_convert (ptrtype
, addr
);
2929 return build_va_arg_indirect_ref (addr
);
2935 def_builtin (const char *name
, tree type
, enum rs6000_builtins code
)
2938 unsigned classify
= rs6000_builtin_info
[(int)code
].attr
;
2939 const char *attr_string
= "";
2941 gcc_assert (name
!= NULL
);
2942 gcc_assert (IN_RANGE ((int)code
, 0, (int)RS6000_BUILTIN_COUNT
));
2944 if (rs6000_builtin_decls
[(int)code
])
2945 fatal_error (input_location
,
2946 "internal error: builtin function %qs already processed",
2949 rs6000_builtin_decls
[(int)code
] = t
=
2950 add_builtin_function (name
, type
, (int)code
, BUILT_IN_MD
, NULL
, NULL_TREE
);
2952 /* Set any special attributes. */
2953 if ((classify
& RS6000_BTC_CONST
) != 0)
2955 /* const function, function only depends on the inputs. */
2956 TREE_READONLY (t
) = 1;
2957 TREE_NOTHROW (t
) = 1;
2958 attr_string
= ", const";
2960 else if ((classify
& RS6000_BTC_PURE
) != 0)
2962 /* pure function, function can read global memory, but does not set any
2964 DECL_PURE_P (t
) = 1;
2965 TREE_NOTHROW (t
) = 1;
2966 attr_string
= ", pure";
2968 else if ((classify
& RS6000_BTC_FP
) != 0)
2970 /* Function is a math function. If rounding mode is on, then treat the
2971 function as not reading global memory, but it can have arbitrary side
2972 effects. If it is off, then assume the function is a const function.
2973 This mimics the ATTR_MATHFN_FPROUNDING attribute in
2974 builtin-attribute.def that is used for the math functions. */
2975 TREE_NOTHROW (t
) = 1;
2976 if (flag_rounding_math
)
2978 DECL_PURE_P (t
) = 1;
2979 DECL_IS_NOVOPS (t
) = 1;
2980 attr_string
= ", fp, pure";
2984 TREE_READONLY (t
) = 1;
2985 attr_string
= ", fp, const";
2988 else if ((classify
& RS6000_BTC_ATTR_MASK
) != 0)
2991 if (TARGET_DEBUG_BUILTIN
)
2992 fprintf (stderr
, "rs6000_builtin, code = %4d, %s%s\n",
2993 (int)code
, name
, attr_string
);
2996 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
2998 #undef RS6000_BUILTIN_0
2999 #undef RS6000_BUILTIN_1
3000 #undef RS6000_BUILTIN_2
3001 #undef RS6000_BUILTIN_3
3002 #undef RS6000_BUILTIN_A
3003 #undef RS6000_BUILTIN_D
3004 #undef RS6000_BUILTIN_H
3005 #undef RS6000_BUILTIN_P
3006 #undef RS6000_BUILTIN_X
3008 #define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
3009 #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
3010 #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
3011 #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) \
3012 { MASK, ICODE, NAME, ENUM },
3014 #define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
3015 #define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
3016 #define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
3017 #define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
3018 #define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
3020 static const struct builtin_description bdesc_3arg
[] =
3022 #include "rs6000-builtin.def"
3025 /* DST operations: void foo (void *, const int, const char). */
3027 #undef RS6000_BUILTIN_0
3028 #undef RS6000_BUILTIN_1
3029 #undef RS6000_BUILTIN_2
3030 #undef RS6000_BUILTIN_3
3031 #undef RS6000_BUILTIN_A
3032 #undef RS6000_BUILTIN_D
3033 #undef RS6000_BUILTIN_H
3034 #undef RS6000_BUILTIN_P
3035 #undef RS6000_BUILTIN_X
3037 #define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
3038 #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
3039 #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
3040 #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
3041 #define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
3042 #define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE) \
3043 { MASK, ICODE, NAME, ENUM },
3045 #define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
3046 #define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
3047 #define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
3049 static const struct builtin_description bdesc_dst
[] =
3051 #include "rs6000-builtin.def"
3054 /* Simple binary operations: VECc = foo (VECa, VECb). */
3056 #undef RS6000_BUILTIN_0
3057 #undef RS6000_BUILTIN_1
3058 #undef RS6000_BUILTIN_2
3059 #undef RS6000_BUILTIN_3
3060 #undef RS6000_BUILTIN_A
3061 #undef RS6000_BUILTIN_D
3062 #undef RS6000_BUILTIN_H
3063 #undef RS6000_BUILTIN_P
3064 #undef RS6000_BUILTIN_X
3066 #define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
3067 #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
3068 #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) \
3069 { MASK, ICODE, NAME, ENUM },
3071 #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
3072 #define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
3073 #define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
3074 #define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
3075 #define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
3076 #define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
3078 static const struct builtin_description bdesc_2arg
[] =
3080 #include "rs6000-builtin.def"
3083 #undef RS6000_BUILTIN_0
3084 #undef RS6000_BUILTIN_1
3085 #undef RS6000_BUILTIN_2
3086 #undef RS6000_BUILTIN_3
3087 #undef RS6000_BUILTIN_A
3088 #undef RS6000_BUILTIN_D
3089 #undef RS6000_BUILTIN_H
3090 #undef RS6000_BUILTIN_P
3091 #undef RS6000_BUILTIN_X
3093 #define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
3094 #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
3095 #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
3096 #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
3097 #define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
3098 #define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
3099 #define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
3100 #define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE) \
3101 { MASK, ICODE, NAME, ENUM },
3103 #define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
3105 /* AltiVec predicates. */
3107 static const struct builtin_description bdesc_altivec_preds
[] =
3109 #include "rs6000-builtin.def"
3112 /* ABS* operations. */
3114 #undef RS6000_BUILTIN_0
3115 #undef RS6000_BUILTIN_1
3116 #undef RS6000_BUILTIN_2
3117 #undef RS6000_BUILTIN_3
3118 #undef RS6000_BUILTIN_A
3119 #undef RS6000_BUILTIN_D
3120 #undef RS6000_BUILTIN_H
3121 #undef RS6000_BUILTIN_P
3122 #undef RS6000_BUILTIN_X
3124 #define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
3125 #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
3126 #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
3127 #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
3128 #define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE) \
3129 { MASK, ICODE, NAME, ENUM },
3131 #define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
3132 #define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
3133 #define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
3134 #define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
3136 static const struct builtin_description bdesc_abs
[] =
3138 #include "rs6000-builtin.def"
3141 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
3144 #undef RS6000_BUILTIN_0
3145 #undef RS6000_BUILTIN_1
3146 #undef RS6000_BUILTIN_2
3147 #undef RS6000_BUILTIN_3
3148 #undef RS6000_BUILTIN_A
3149 #undef RS6000_BUILTIN_D
3150 #undef RS6000_BUILTIN_H
3151 #undef RS6000_BUILTIN_P
3152 #undef RS6000_BUILTIN_X
3154 #define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
3155 #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) \
3156 { MASK, ICODE, NAME, ENUM },
3158 #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
3159 #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
3160 #define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
3161 #define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
3162 #define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
3163 #define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
3164 #define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
3166 static const struct builtin_description bdesc_1arg
[] =
3168 #include "rs6000-builtin.def"
3171 /* Simple no-argument operations: result = __builtin_darn_32 () */
3173 #undef RS6000_BUILTIN_0
3174 #undef RS6000_BUILTIN_1
3175 #undef RS6000_BUILTIN_2
3176 #undef RS6000_BUILTIN_3
3177 #undef RS6000_BUILTIN_A
3178 #undef RS6000_BUILTIN_D
3179 #undef RS6000_BUILTIN_H
3180 #undef RS6000_BUILTIN_P
3181 #undef RS6000_BUILTIN_X
3183 #define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE) \
3184 { MASK, ICODE, NAME, ENUM },
3186 #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
3187 #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
3188 #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
3189 #define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
3190 #define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
3191 #define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
3192 #define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
3193 #define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
3195 static const struct builtin_description bdesc_0arg
[] =
3197 #include "rs6000-builtin.def"
3201 #undef RS6000_BUILTIN_0
3202 #undef RS6000_BUILTIN_1
3203 #undef RS6000_BUILTIN_2
3204 #undef RS6000_BUILTIN_3
3205 #undef RS6000_BUILTIN_A
3206 #undef RS6000_BUILTIN_D
3207 #undef RS6000_BUILTIN_H
3208 #undef RS6000_BUILTIN_P
3209 #undef RS6000_BUILTIN_X
3211 #define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
3212 #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
3213 #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
3214 #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
3215 #define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
3216 #define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
3217 #define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE) \
3218 { MASK, ICODE, NAME, ENUM },
3220 #define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
3221 #define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
3223 static const struct builtin_description bdesc_htm
[] =
3225 #include "rs6000-builtin.def"
3228 #undef RS6000_BUILTIN_0
3229 #undef RS6000_BUILTIN_1
3230 #undef RS6000_BUILTIN_2
3231 #undef RS6000_BUILTIN_3
3232 #undef RS6000_BUILTIN_A
3233 #undef RS6000_BUILTIN_D
3234 #undef RS6000_BUILTIN_H
3235 #undef RS6000_BUILTIN_P
3237 /* Return true if a builtin function is overloaded. */
3239 rs6000_overloaded_builtin_p (enum rs6000_builtins fncode
)
3241 return (rs6000_builtin_info
[(int)fncode
].attr
& RS6000_BTC_OVERLOADED
) != 0;
3245 rs6000_overloaded_builtin_name (enum rs6000_builtins fncode
)
3247 return rs6000_builtin_info
[(int)fncode
].name
;
3250 /* Expand an expression EXP that calls a builtin without arguments. */
3252 rs6000_expand_zeroop_builtin (enum insn_code icode
, rtx target
)
3255 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
3257 if (icode
== CODE_FOR_nothing
)
3258 /* Builtin not supported on this processor. */
3261 if (icode
== CODE_FOR_rs6000_mffsl
3262 && rs6000_isa_flags
& OPTION_MASK_SOFT_FLOAT
)
3264 error ("%<__builtin_mffsl%> not supported with %<-msoft-float%>");
3269 || GET_MODE (target
) != tmode
3270 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
3271 target
= gen_reg_rtx (tmode
);
3273 pat
= GEN_FCN (icode
) (target
);
3283 rs6000_expand_mtfsf_builtin (enum insn_code icode
, tree exp
)
3286 tree arg0
= CALL_EXPR_ARG (exp
, 0);
3287 tree arg1
= CALL_EXPR_ARG (exp
, 1);
3288 rtx op0
= expand_normal (arg0
);
3289 rtx op1
= expand_normal (arg1
);
3290 machine_mode mode0
= insn_data
[icode
].operand
[0].mode
;
3291 machine_mode mode1
= insn_data
[icode
].operand
[1].mode
;
3293 if (icode
== CODE_FOR_nothing
)
3294 /* Builtin not supported on this processor. */
3297 /* If we got invalid arguments bail out before generating bad rtl. */
3298 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
3301 if (!CONST_INT_P (op0
)
3302 || INTVAL (op0
) > 255
3303 || INTVAL (op0
) < 0)
3305 error ("argument 1 must be an 8-bit field value");
3309 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
3310 op0
= copy_to_mode_reg (mode0
, op0
);
3312 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
3313 op1
= copy_to_mode_reg (mode1
, op1
);
3315 pat
= GEN_FCN (icode
) (op0
, op1
);
3324 rs6000_expand_mtfsb_builtin (enum insn_code icode
, tree exp
)
3327 tree arg0
= CALL_EXPR_ARG (exp
, 0);
3328 rtx op0
= expand_normal (arg0
);
3330 if (icode
== CODE_FOR_nothing
)
3331 /* Builtin not supported on this processor. */
3334 if (rs6000_isa_flags
& OPTION_MASK_SOFT_FLOAT
)
3336 error ("%<__builtin_mtfsb0%> and %<__builtin_mtfsb1%> not supported with "
3337 "%<-msoft-float%>");
3341 /* If we got invalid arguments bail out before generating bad rtl. */
3342 if (arg0
== error_mark_node
)
3345 /* Only allow bit numbers 0 to 31. */
3346 if (!u5bit_cint_operand (op0
, VOIDmode
))
3348 error ("Argument must be a constant between 0 and 31.");
3352 pat
= GEN_FCN (icode
) (op0
);
3361 rs6000_expand_set_fpscr_rn_builtin (enum insn_code icode
, tree exp
)
3364 tree arg0
= CALL_EXPR_ARG (exp
, 0);
3365 rtx op0
= expand_normal (arg0
);
3366 machine_mode mode0
= insn_data
[icode
].operand
[0].mode
;
3368 if (icode
== CODE_FOR_nothing
)
3369 /* Builtin not supported on this processor. */
3372 if (rs6000_isa_flags
& OPTION_MASK_SOFT_FLOAT
)
3374 error ("%<__builtin_set_fpscr_rn%> not supported with %<-msoft-float%>");
3378 /* If we got invalid arguments bail out before generating bad rtl. */
3379 if (arg0
== error_mark_node
)
3382 /* If the argument is a constant, check the range. Argument can only be a
3383 2-bit value. Unfortunately, can't check the range of the value at
3384 compile time if the argument is a variable. The least significant two
3385 bits of the argument, regardless of type, are used to set the rounding
3386 mode. All other bits are ignored. */
3387 if (CONST_INT_P (op0
) && !const_0_to_3_operand(op0
, VOIDmode
))
3389 error ("Argument must be a value between 0 and 3.");
3393 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
3394 op0
= copy_to_mode_reg (mode0
, op0
);
3396 pat
= GEN_FCN (icode
) (op0
);
3404 rs6000_expand_set_fpscr_drn_builtin (enum insn_code icode
, tree exp
)
3407 tree arg0
= CALL_EXPR_ARG (exp
, 0);
3408 rtx op0
= expand_normal (arg0
);
3409 machine_mode mode0
= insn_data
[icode
].operand
[0].mode
;
3412 /* Builtin not supported in 32-bit mode. */
3413 fatal_error (input_location
,
3414 "%<__builtin_set_fpscr_drn%> is not supported "
3417 if (rs6000_isa_flags
& OPTION_MASK_SOFT_FLOAT
)
3419 error ("%<__builtin_set_fpscr_drn%> not supported with %<-msoft-float%>");
3423 if (icode
== CODE_FOR_nothing
)
3424 /* Builtin not supported on this processor. */
3427 /* If we got invalid arguments bail out before generating bad rtl. */
3428 if (arg0
== error_mark_node
)
3431 /* If the argument is a constant, check the range. Agrument can only be a
3432 3-bit value. Unfortunately, can't check the range of the value at
3433 compile time if the argument is a variable. The least significant two
3434 bits of the argument, regardless of type, are used to set the rounding
3435 mode. All other bits are ignored. */
3436 if (CONST_INT_P (op0
) && !const_0_to_7_operand(op0
, VOIDmode
))
3438 error ("Argument must be a value between 0 and 7.");
3442 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
3443 op0
= copy_to_mode_reg (mode0
, op0
);
3445 pat
= GEN_FCN (icode
) (op0
);
3454 rs6000_expand_unop_builtin (enum insn_code icode
, tree exp
, rtx target
)
3457 tree arg0
= CALL_EXPR_ARG (exp
, 0);
3458 rtx op0
= expand_normal (arg0
);
3459 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
3460 machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
3462 if (icode
== CODE_FOR_nothing
)
3463 /* Builtin not supported on this processor. */
3466 /* If we got invalid arguments bail out before generating bad rtl. */
3467 if (arg0
== error_mark_node
)
3470 if (icode
== CODE_FOR_altivec_vspltisb
3471 || icode
== CODE_FOR_altivec_vspltish
3472 || icode
== CODE_FOR_altivec_vspltisw
)
3474 /* Only allow 5-bit *signed* literals. */
3475 if (!CONST_INT_P (op0
)
3476 || INTVAL (op0
) > 15
3477 || INTVAL (op0
) < -16)
3479 error ("argument 1 must be a 5-bit signed literal");
3480 return CONST0_RTX (tmode
);
3485 || GET_MODE (target
) != tmode
3486 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
3487 target
= gen_reg_rtx (tmode
);
3489 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
3490 op0
= copy_to_mode_reg (mode0
, op0
);
3492 pat
= GEN_FCN (icode
) (target
, op0
);
3501 altivec_expand_abs_builtin (enum insn_code icode
, tree exp
, rtx target
)
3503 rtx pat
, scratch1
, scratch2
;
3504 tree arg0
= CALL_EXPR_ARG (exp
, 0);
3505 rtx op0
= expand_normal (arg0
);
3506 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
3507 machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
3509 /* If we have invalid arguments, bail out before generating bad rtl. */
3510 if (arg0
== error_mark_node
)
3514 || GET_MODE (target
) != tmode
3515 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
3516 target
= gen_reg_rtx (tmode
);
3518 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
3519 op0
= copy_to_mode_reg (mode0
, op0
);
3521 scratch1
= gen_reg_rtx (mode0
);
3522 scratch2
= gen_reg_rtx (mode0
);
3524 pat
= GEN_FCN (icode
) (target
, op0
, scratch1
, scratch2
);
3533 rs6000_expand_binop_builtin (enum insn_code icode
, tree exp
, rtx target
)
3536 tree arg0
= CALL_EXPR_ARG (exp
, 0);
3537 tree arg1
= CALL_EXPR_ARG (exp
, 1);
3538 rtx op0
= expand_normal (arg0
);
3539 rtx op1
= expand_normal (arg1
);
3540 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
3541 machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
3542 machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
3544 if (icode
== CODE_FOR_nothing
)
3545 /* Builtin not supported on this processor. */
3548 /* If we got invalid arguments bail out before generating bad rtl. */
3549 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
3552 if (icode
== CODE_FOR_unpackv1ti
3553 || icode
== CODE_FOR_unpackkf
3554 || icode
== CODE_FOR_unpacktf
3555 || icode
== CODE_FOR_unpackif
3556 || icode
== CODE_FOR_unpacktd
)
3558 /* Only allow 1-bit unsigned literals. */
3560 if (TREE_CODE (arg1
) != INTEGER_CST
3561 || !IN_RANGE (TREE_INT_CST_LOW (arg1
), 0, 1))
3563 error ("argument 2 must be a 1-bit unsigned literal");
3564 return CONST0_RTX (tmode
);
3567 else if (icode
== CODE_FOR_altivec_vspltw
)
3569 /* Only allow 2-bit unsigned literals. */
3571 if (TREE_CODE (arg1
) != INTEGER_CST
3572 || TREE_INT_CST_LOW (arg1
) & ~3)
3574 error ("argument 2 must be a 2-bit unsigned literal");
3575 return CONST0_RTX (tmode
);
3578 else if (icode
== CODE_FOR_altivec_vsplth
)
3580 /* Only allow 3-bit unsigned literals. */
3582 if (TREE_CODE (arg1
) != INTEGER_CST
3583 || TREE_INT_CST_LOW (arg1
) & ~7)
3585 error ("argument 2 must be a 3-bit unsigned literal");
3586 return CONST0_RTX (tmode
);
3589 else if (icode
== CODE_FOR_altivec_vspltb
)
3591 /* Only allow 4-bit unsigned literals. */
3593 if (TREE_CODE (arg1
) != INTEGER_CST
3594 || TREE_INT_CST_LOW (arg1
) & ~15)
3596 error ("argument 2 must be a 4-bit unsigned literal");
3597 return CONST0_RTX (tmode
);
3600 else if (icode
== CODE_FOR_altivec_vcfux
3601 || icode
== CODE_FOR_altivec_vcfsx
3602 || icode
== CODE_FOR_altivec_vctsxs
3603 || icode
== CODE_FOR_altivec_vctuxs
)
3605 /* Only allow 5-bit unsigned literals. */
3607 if (TREE_CODE (arg1
) != INTEGER_CST
3608 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
3610 error ("argument 2 must be a 5-bit unsigned literal");
3611 return CONST0_RTX (tmode
);
3614 else if (icode
== CODE_FOR_dfptstsfi_eq_dd
3615 || icode
== CODE_FOR_dfptstsfi_lt_dd
3616 || icode
== CODE_FOR_dfptstsfi_gt_dd
3617 || icode
== CODE_FOR_dfptstsfi_unordered_dd
3618 || icode
== CODE_FOR_dfptstsfi_eq_td
3619 || icode
== CODE_FOR_dfptstsfi_lt_td
3620 || icode
== CODE_FOR_dfptstsfi_gt_td
3621 || icode
== CODE_FOR_dfptstsfi_unordered_td
)
3623 /* Only allow 6-bit unsigned literals. */
3625 if (TREE_CODE (arg0
) != INTEGER_CST
3626 || !IN_RANGE (TREE_INT_CST_LOW (arg0
), 0, 63))
3628 error ("argument 1 must be a 6-bit unsigned literal");
3629 return CONST0_RTX (tmode
);
3632 else if (icode
== CODE_FOR_xststdcqp_kf
3633 || icode
== CODE_FOR_xststdcqp_tf
3634 || icode
== CODE_FOR_xststdcdp
3635 || icode
== CODE_FOR_xststdcsp
3636 || icode
== CODE_FOR_xvtstdcdp
3637 || icode
== CODE_FOR_xvtstdcsp
)
3639 /* Only allow 7-bit unsigned literals. */
3641 if (TREE_CODE (arg1
) != INTEGER_CST
3642 || !IN_RANGE (TREE_INT_CST_LOW (arg1
), 0, 127))
3644 error ("argument 2 must be a 7-bit unsigned literal");
3645 return CONST0_RTX (tmode
);
3650 || GET_MODE (target
) != tmode
3651 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
3652 target
= gen_reg_rtx (tmode
);
3654 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
3655 op0
= copy_to_mode_reg (mode0
, op0
);
3656 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
3657 op1
= copy_to_mode_reg (mode1
, op1
);
3659 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
3668 altivec_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
3671 tree cr6_form
= CALL_EXPR_ARG (exp
, 0);
3672 tree arg0
= CALL_EXPR_ARG (exp
, 1);
3673 tree arg1
= CALL_EXPR_ARG (exp
, 2);
3674 rtx op0
= expand_normal (arg0
);
3675 rtx op1
= expand_normal (arg1
);
3676 machine_mode tmode
= SImode
;
3677 machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
3678 machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
3681 if (TREE_CODE (cr6_form
) != INTEGER_CST
)
3683 error ("argument 1 of %qs must be a constant",
3684 "__builtin_altivec_predicate");
3688 cr6_form_int
= TREE_INT_CST_LOW (cr6_form
);
3690 gcc_assert (mode0
== mode1
);
3692 /* If we have invalid arguments, bail out before generating bad rtl. */
3693 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
3697 || GET_MODE (target
) != tmode
3698 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
3699 target
= gen_reg_rtx (tmode
);
3701 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
3702 op0
= copy_to_mode_reg (mode0
, op0
);
3703 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
3704 op1
= copy_to_mode_reg (mode1
, op1
);
3706 /* Note that for many of the relevant operations (e.g. cmpne or
3707 cmpeq) with float or double operands, it makes more sense for the
3708 mode of the allocated scratch register to select a vector of
3709 integer. But the choice to copy the mode of operand 0 was made
3710 long ago and there are no plans to change it. */
3711 scratch
= gen_reg_rtx (mode0
);
3713 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
3718 /* The vec_any* and vec_all* predicates use the same opcodes for two
3719 different operations, but the bits in CR6 will be different
3720 depending on what information we want. So we have to play tricks
3721 with CR6 to get the right bits out.
3723 If you think this is disgusting, look at the specs for the
3724 AltiVec predicates. */
3726 switch (cr6_form_int
)
3729 emit_insn (gen_cr6_test_for_zero (target
));
3732 emit_insn (gen_cr6_test_for_zero_reverse (target
));
3735 emit_insn (gen_cr6_test_for_lt (target
));
3738 emit_insn (gen_cr6_test_for_lt_reverse (target
));
3741 error ("argument 1 of %qs is out of range",
3742 "__builtin_altivec_predicate");
3750 swap_endian_selector_for_mode (machine_mode mode
)
3752 unsigned int swap1
[16] = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0};
3753 unsigned int swap2
[16] = {7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8};
3754 unsigned int swap4
[16] = {3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12};
3755 unsigned int swap8
[16] = {1,0,3,2,5,4,7,6,9,8,11,10,13,12,15,14};
3757 unsigned int *swaparray
, i
;
3780 for (i
= 0; i
< 16; ++i
)
3781 perm
[i
] = GEN_INT (swaparray
[i
]);
3783 return force_reg (V16QImode
, gen_rtx_CONST_VECTOR (V16QImode
,
3784 gen_rtvec_v (16, perm
)));
3788 altivec_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
, bool blk
)
3791 tree arg0
= CALL_EXPR_ARG (exp
, 0);
3792 tree arg1
= CALL_EXPR_ARG (exp
, 1);
3793 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
3794 machine_mode mode0
= Pmode
;
3795 machine_mode mode1
= Pmode
;
3796 rtx op0
= expand_normal (arg0
);
3797 rtx op1
= expand_normal (arg1
);
3799 if (icode
== CODE_FOR_nothing
)
3800 /* Builtin not supported on this processor. */
3803 /* If we got invalid arguments bail out before generating bad rtl. */
3804 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
3808 || GET_MODE (target
) != tmode
3809 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
3810 target
= gen_reg_rtx (tmode
);
3812 op1
= copy_to_mode_reg (mode1
, op1
);
3814 /* For LVX, express the RTL accurately by ANDing the address with -16.
3815 LVXL and LVE*X expand to use UNSPECs to hide their special behavior,
3816 so the raw address is fine. */
3817 if (icode
== CODE_FOR_altivec_lvx_v1ti
3818 || icode
== CODE_FOR_altivec_lvx_v2df
3819 || icode
== CODE_FOR_altivec_lvx_v2di
3820 || icode
== CODE_FOR_altivec_lvx_v4sf
3821 || icode
== CODE_FOR_altivec_lvx_v4si
3822 || icode
== CODE_FOR_altivec_lvx_v8hi
3823 || icode
== CODE_FOR_altivec_lvx_v16qi
)
3826 if (op0
== const0_rtx
)
3830 op0
= copy_to_mode_reg (mode0
, op0
);
3831 rawaddr
= gen_rtx_PLUS (Pmode
, op1
, op0
);
3833 addr
= gen_rtx_AND (Pmode
, rawaddr
, gen_rtx_CONST_INT (Pmode
, -16));
3834 addr
= gen_rtx_MEM (blk
? BLKmode
: tmode
, addr
);
3836 emit_insn (gen_rtx_SET (target
, addr
));
3840 if (op0
== const0_rtx
)
3841 addr
= gen_rtx_MEM (blk
? BLKmode
: tmode
, op1
);
3844 op0
= copy_to_mode_reg (mode0
, op0
);
3845 addr
= gen_rtx_MEM (blk
? BLKmode
: tmode
,
3846 gen_rtx_PLUS (Pmode
, op1
, op0
));
3849 pat
= GEN_FCN (icode
) (target
, addr
);
3859 altivec_expand_stxvl_builtin (enum insn_code icode
, tree exp
)
3862 tree arg0
= CALL_EXPR_ARG (exp
, 0);
3863 tree arg1
= CALL_EXPR_ARG (exp
, 1);
3864 tree arg2
= CALL_EXPR_ARG (exp
, 2);
3865 rtx op0
= expand_normal (arg0
);
3866 rtx op1
= expand_normal (arg1
);
3867 rtx op2
= expand_normal (arg2
);
3868 machine_mode mode0
= insn_data
[icode
].operand
[0].mode
;
3869 machine_mode mode1
= insn_data
[icode
].operand
[1].mode
;
3870 machine_mode mode2
= insn_data
[icode
].operand
[2].mode
;
3872 if (icode
== CODE_FOR_nothing
)
3873 /* Builtin not supported on this processor. */
3876 /* If we got invalid arguments bail out before generating bad rtl. */
3877 if (arg0
== error_mark_node
3878 || arg1
== error_mark_node
3879 || arg2
== error_mark_node
)
3882 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
3883 op0
= copy_to_mode_reg (mode0
, op0
);
3884 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
3885 op1
= copy_to_mode_reg (mode1
, op1
);
3886 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
3887 op2
= copy_to_mode_reg (mode2
, op2
);
3889 pat
= GEN_FCN (icode
) (op0
, op1
, op2
);
3897 altivec_expand_stv_builtin (enum insn_code icode
, tree exp
)
3899 tree arg0
= CALL_EXPR_ARG (exp
, 0);
3900 tree arg1
= CALL_EXPR_ARG (exp
, 1);
3901 tree arg2
= CALL_EXPR_ARG (exp
, 2);
3902 rtx op0
= expand_normal (arg0
);
3903 rtx op1
= expand_normal (arg1
);
3904 rtx op2
= expand_normal (arg2
);
3905 rtx pat
, addr
, rawaddr
;
3906 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
3907 machine_mode smode
= insn_data
[icode
].operand
[1].mode
;
3908 machine_mode mode1
= Pmode
;
3909 machine_mode mode2
= Pmode
;
3911 /* Invalid arguments. Bail before doing anything stoopid! */
3912 if (arg0
== error_mark_node
3913 || arg1
== error_mark_node
3914 || arg2
== error_mark_node
)
3917 op2
= copy_to_mode_reg (mode2
, op2
);
3919 /* For STVX, express the RTL accurately by ANDing the address with -16.
3920 STVXL and STVE*X expand to use UNSPECs to hide their special behavior,
3921 so the raw address is fine. */
3922 if (icode
== CODE_FOR_altivec_stvx_v2df
3923 || icode
== CODE_FOR_altivec_stvx_v2di
3924 || icode
== CODE_FOR_altivec_stvx_v4sf
3925 || icode
== CODE_FOR_altivec_stvx_v4si
3926 || icode
== CODE_FOR_altivec_stvx_v8hi
3927 || icode
== CODE_FOR_altivec_stvx_v16qi
)
3929 if (op1
== const0_rtx
)
3933 op1
= copy_to_mode_reg (mode1
, op1
);
3934 rawaddr
= gen_rtx_PLUS (Pmode
, op2
, op1
);
3937 addr
= gen_rtx_AND (Pmode
, rawaddr
, gen_rtx_CONST_INT (Pmode
, -16));
3938 addr
= gen_rtx_MEM (tmode
, addr
);
3940 op0
= copy_to_mode_reg (tmode
, op0
);
3942 emit_insn (gen_rtx_SET (addr
, op0
));
3946 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, smode
))
3947 op0
= copy_to_mode_reg (smode
, op0
);
3949 if (op1
== const0_rtx
)
3950 addr
= gen_rtx_MEM (tmode
, op2
);
3953 op1
= copy_to_mode_reg (mode1
, op1
);
3954 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op2
, op1
));
3957 pat
= GEN_FCN (icode
) (addr
, op0
);
3965 /* Return the appropriate SPR number associated with the given builtin. */
3966 static inline HOST_WIDE_INT
3967 htm_spr_num (enum rs6000_builtins code
)
3969 if (code
== HTM_BUILTIN_GET_TFHAR
3970 || code
== HTM_BUILTIN_SET_TFHAR
)
3972 else if (code
== HTM_BUILTIN_GET_TFIAR
3973 || code
== HTM_BUILTIN_SET_TFIAR
)
3975 else if (code
== HTM_BUILTIN_GET_TEXASR
3976 || code
== HTM_BUILTIN_SET_TEXASR
)
3978 gcc_assert (code
== HTM_BUILTIN_GET_TEXASRU
3979 || code
== HTM_BUILTIN_SET_TEXASRU
);
3983 /* Return the correct ICODE value depending on whether we are
3984 setting or reading the HTM SPRs. */
3985 static inline enum insn_code
3986 rs6000_htm_spr_icode (bool nonvoid
)
3989 return (TARGET_POWERPC64
) ? CODE_FOR_htm_mfspr_di
: CODE_FOR_htm_mfspr_si
;
3991 return (TARGET_POWERPC64
) ? CODE_FOR_htm_mtspr_di
: CODE_FOR_htm_mtspr_si
;
3994 /* Expand the HTM builtin in EXP and store the result in TARGET.
3995 Store true in *EXPANDEDP if we found a builtin to expand. */
3997 htm_expand_builtin (tree exp
, rtx target
, bool * expandedp
)
3999 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
4000 bool nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
4001 enum rs6000_builtins fcode
4002 = (enum rs6000_builtins
) DECL_MD_FUNCTION_CODE (fndecl
);
4003 const struct builtin_description
*d
;
4008 if (!TARGET_POWERPC64
4009 && (fcode
== HTM_BUILTIN_TABORTDC
4010 || fcode
== HTM_BUILTIN_TABORTDCI
))
4012 size_t uns_fcode
= (size_t)fcode
;
4013 const char *name
= rs6000_builtin_info
[uns_fcode
].name
;
4014 error ("builtin %qs is only valid in 64-bit mode", name
);
4018 /* Expand the HTM builtins. */
4020 for (i
= 0; i
< ARRAY_SIZE (bdesc_htm
); i
++, d
++)
4021 if (d
->code
== fcode
)
4023 rtx op
[MAX_HTM_OPERANDS
], pat
;
4026 call_expr_arg_iterator iter
;
4027 unsigned attr
= rs6000_builtin_info
[fcode
].attr
;
4028 enum insn_code icode
= d
->icode
;
4029 const struct insn_operand_data
*insn_op
;
4030 bool uses_spr
= (attr
& RS6000_BTC_SPR
);
4034 icode
= rs6000_htm_spr_icode (nonvoid
);
4035 insn_op
= &insn_data
[icode
].operand
[0];
4039 machine_mode tmode
= (uses_spr
) ? insn_op
->mode
: E_SImode
;
4041 || GET_MODE (target
) != tmode
4042 || (uses_spr
&& !(*insn_op
->predicate
) (target
, tmode
)))
4043 target
= gen_reg_rtx (tmode
);
4045 op
[nopnds
++] = target
;
4048 FOR_EACH_CALL_EXPR_ARG (arg
, iter
, exp
)
4050 if (arg
== error_mark_node
|| nopnds
>= MAX_HTM_OPERANDS
)
4053 insn_op
= &insn_data
[icode
].operand
[nopnds
];
4055 op
[nopnds
] = expand_normal (arg
);
4057 if (!(*insn_op
->predicate
) (op
[nopnds
], insn_op
->mode
))
4059 if (!strcmp (insn_op
->constraint
, "n"))
4061 int arg_num
= (nonvoid
) ? nopnds
: nopnds
+ 1;
4062 if (!CONST_INT_P (op
[nopnds
]))
4063 error ("argument %d must be an unsigned literal", arg_num
);
4065 error ("argument %d is an unsigned literal that is "
4066 "out of range", arg_num
);
4069 op
[nopnds
] = copy_to_mode_reg (insn_op
->mode
, op
[nopnds
]);
4075 /* Handle the builtins for extended mnemonics. These accept
4076 no arguments, but map to builtins that take arguments. */
4079 case HTM_BUILTIN_TENDALL
: /* Alias for: tend. 1 */
4080 case HTM_BUILTIN_TRESUME
: /* Alias for: tsr. 1 */
4081 op
[nopnds
++] = GEN_INT (1);
4083 attr
|= RS6000_BTC_UNARY
;
4085 case HTM_BUILTIN_TSUSPEND
: /* Alias for: tsr. 0 */
4086 op
[nopnds
++] = GEN_INT (0);
4088 attr
|= RS6000_BTC_UNARY
;
4094 /* If this builtin accesses SPRs, then pass in the appropriate
4095 SPR number and SPR regno as the last two operands. */
4098 machine_mode mode
= (TARGET_POWERPC64
) ? DImode
: SImode
;
4099 op
[nopnds
++] = gen_rtx_CONST_INT (mode
, htm_spr_num (fcode
));
4101 /* If this builtin accesses a CR, then pass in a scratch
4102 CR as the last operand. */
4103 else if (attr
& RS6000_BTC_CR
)
4104 { cr
= gen_reg_rtx (CCmode
);
4110 int expected_nopnds
= 0;
4111 if ((attr
& RS6000_BTC_TYPE_MASK
) == RS6000_BTC_UNARY
)
4112 expected_nopnds
= 1;
4113 else if ((attr
& RS6000_BTC_TYPE_MASK
) == RS6000_BTC_BINARY
)
4114 expected_nopnds
= 2;
4115 else if ((attr
& RS6000_BTC_TYPE_MASK
) == RS6000_BTC_TERNARY
)
4116 expected_nopnds
= 3;
4117 if (!(attr
& RS6000_BTC_VOID
))
4118 expected_nopnds
+= 1;
4120 expected_nopnds
+= 1;
4122 gcc_assert (nopnds
== expected_nopnds
4123 && nopnds
<= MAX_HTM_OPERANDS
);
4129 pat
= GEN_FCN (icode
) (op
[0]);
4132 pat
= GEN_FCN (icode
) (op
[0], op
[1]);
4135 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2]);
4138 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2], op
[3]);
4147 if (attr
& RS6000_BTC_CR
)
4149 if (fcode
== HTM_BUILTIN_TBEGIN
)
4151 /* Emit code to set TARGET to true or false depending on
4152 whether the tbegin. instruction successfully or failed
4153 to start a transaction. We do this by placing the 1's
4154 complement of CR's EQ bit into TARGET. */
4155 rtx scratch
= gen_reg_rtx (SImode
);
4156 emit_insn (gen_rtx_SET (scratch
,
4157 gen_rtx_EQ (SImode
, cr
,
4159 emit_insn (gen_rtx_SET (target
,
4160 gen_rtx_XOR (SImode
, scratch
,
4165 /* Emit code to copy the 4-bit condition register field
4166 CR into the least significant end of register TARGET. */
4167 rtx scratch1
= gen_reg_rtx (SImode
);
4168 rtx scratch2
= gen_reg_rtx (SImode
);
4169 rtx subreg
= simplify_gen_subreg (CCmode
, scratch1
, SImode
, 0);
4170 emit_insn (gen_movcc (subreg
, cr
));
4171 emit_insn (gen_lshrsi3 (scratch2
, scratch1
, GEN_INT (28)));
4172 emit_insn (gen_andsi3 (target
, scratch2
, GEN_INT (0xf)));
4185 /* Expand the CPU builtin in FCODE and store the result in TARGET. */
4188 cpu_expand_builtin (enum rs6000_builtins fcode
, tree exp ATTRIBUTE_UNUSED
,
4191 /* __builtin_cpu_init () is a nop, so expand to nothing. */
4192 if (fcode
== RS6000_BUILTIN_CPU_INIT
)
4195 if (target
== 0 || GET_MODE (target
) != SImode
)
4196 target
= gen_reg_rtx (SImode
);
4198 #ifdef TARGET_LIBC_PROVIDES_HWCAP_IN_TCB
4199 tree arg
= TREE_OPERAND (CALL_EXPR_ARG (exp
, 0), 0);
4200 /* Target clones creates an ARRAY_REF instead of STRING_CST, convert it back
4202 if (TREE_CODE (arg
) == ARRAY_REF
4203 && TREE_CODE (TREE_OPERAND (arg
, 0)) == STRING_CST
4204 && TREE_CODE (TREE_OPERAND (arg
, 1)) == INTEGER_CST
4205 && compare_tree_int (TREE_OPERAND (arg
, 1), 0) == 0)
4206 arg
= TREE_OPERAND (arg
, 0);
4208 if (TREE_CODE (arg
) != STRING_CST
)
4210 error ("builtin %qs only accepts a string argument",
4211 rs6000_builtin_info
[(size_t) fcode
].name
);
4215 if (fcode
== RS6000_BUILTIN_CPU_IS
)
4217 const char *cpu
= TREE_STRING_POINTER (arg
);
4218 rtx cpuid
= NULL_RTX
;
4219 for (size_t i
= 0; i
< ARRAY_SIZE (cpu_is_info
); i
++)
4220 if (strcmp (cpu
, cpu_is_info
[i
].cpu
) == 0)
4222 /* The CPUID value in the TCB is offset by _DL_FIRST_PLATFORM. */
4223 cpuid
= GEN_INT (cpu_is_info
[i
].cpuid
+ _DL_FIRST_PLATFORM
);
4226 if (cpuid
== NULL_RTX
)
4228 /* Invalid CPU argument. */
4229 error ("cpu %qs is an invalid argument to builtin %qs",
4230 cpu
, rs6000_builtin_info
[(size_t) fcode
].name
);
4234 rtx platform
= gen_reg_rtx (SImode
);
4235 rtx tcbmem
= gen_const_mem (SImode
,
4236 gen_rtx_PLUS (Pmode
,
4237 gen_rtx_REG (Pmode
, TLS_REGNUM
),
4238 GEN_INT (TCB_PLATFORM_OFFSET
)));
4239 emit_move_insn (platform
, tcbmem
);
4240 emit_insn (gen_eqsi3 (target
, platform
, cpuid
));
4242 else if (fcode
== RS6000_BUILTIN_CPU_SUPPORTS
)
4244 const char *hwcap
= TREE_STRING_POINTER (arg
);
4245 rtx mask
= NULL_RTX
;
4247 for (size_t i
= 0; i
< ARRAY_SIZE (cpu_supports_info
); i
++)
4248 if (strcmp (hwcap
, cpu_supports_info
[i
].hwcap
) == 0)
4250 mask
= GEN_INT (cpu_supports_info
[i
].mask
);
4251 hwcap_offset
= TCB_HWCAP_OFFSET (cpu_supports_info
[i
].id
);
4254 if (mask
== NULL_RTX
)
4256 /* Invalid HWCAP argument. */
4257 error ("%s %qs is an invalid argument to builtin %qs",
4258 "hwcap", hwcap
, rs6000_builtin_info
[(size_t) fcode
].name
);
4262 rtx tcb_hwcap
= gen_reg_rtx (SImode
);
4263 rtx tcbmem
= gen_const_mem (SImode
,
4264 gen_rtx_PLUS (Pmode
,
4265 gen_rtx_REG (Pmode
, TLS_REGNUM
),
4266 GEN_INT (hwcap_offset
)));
4267 emit_move_insn (tcb_hwcap
, tcbmem
);
4268 rtx scratch1
= gen_reg_rtx (SImode
);
4269 emit_insn (gen_rtx_SET (scratch1
, gen_rtx_AND (SImode
, tcb_hwcap
, mask
)));
4270 rtx scratch2
= gen_reg_rtx (SImode
);
4271 emit_insn (gen_eqsi3 (scratch2
, scratch1
, const0_rtx
));
4272 emit_insn (gen_rtx_SET (target
, gen_rtx_XOR (SImode
, scratch2
, const1_rtx
)));
4277 /* Record that we have expanded a CPU builtin, so that we can later
4278 emit a reference to the special symbol exported by LIBC to ensure we
4279 do not link against an old LIBC that doesn't support this feature. */
4280 cpu_builtin_p
= true;
4283 warning (0, "builtin %qs needs GLIBC (2.23 and newer) that exports hardware "
4284 "capability bits", rs6000_builtin_info
[(size_t) fcode
].name
);
4286 /* For old LIBCs, always return FALSE. */
4287 emit_move_insn (target
, GEN_INT (0));
4288 #endif /* TARGET_LIBC_PROVIDES_HWCAP_IN_TCB */
4294 rs6000_expand_ternop_builtin (enum insn_code icode
, tree exp
, rtx target
)
4297 tree arg0
= CALL_EXPR_ARG (exp
, 0);
4298 tree arg1
= CALL_EXPR_ARG (exp
, 1);
4299 tree arg2
= CALL_EXPR_ARG (exp
, 2);
4300 rtx op0
= expand_normal (arg0
);
4301 rtx op1
= expand_normal (arg1
);
4302 rtx op2
= expand_normal (arg2
);
4303 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
4304 machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
4305 machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
4306 machine_mode mode2
= insn_data
[icode
].operand
[3].mode
;
4308 if (icode
== CODE_FOR_nothing
)
4309 /* Builtin not supported on this processor. */
4312 /* If we got invalid arguments bail out before generating bad rtl. */
4313 if (arg0
== error_mark_node
4314 || arg1
== error_mark_node
4315 || arg2
== error_mark_node
)
4318 /* Check and prepare argument depending on the instruction code.
4320 Note that a switch statement instead of the sequence of tests
4321 would be incorrect as many of the CODE_FOR values could be
4322 CODE_FOR_nothing and that would yield multiple alternatives
4323 with identical values. We'd never reach here at runtime in
4325 if (icode
== CODE_FOR_altivec_vsldoi_v4sf
4326 || icode
== CODE_FOR_altivec_vsldoi_v2df
4327 || icode
== CODE_FOR_altivec_vsldoi_v4si
4328 || icode
== CODE_FOR_altivec_vsldoi_v8hi
4329 || icode
== CODE_FOR_altivec_vsldoi_v16qi
)
4331 /* Only allow 4-bit unsigned literals. */
4333 if (TREE_CODE (arg2
) != INTEGER_CST
4334 || TREE_INT_CST_LOW (arg2
) & ~0xf)
4336 error ("argument 3 must be a 4-bit unsigned literal");
4337 return CONST0_RTX (tmode
);
4340 else if (icode
== CODE_FOR_vsx_xxpermdi_v2df
4341 || icode
== CODE_FOR_vsx_xxpermdi_v2di
4342 || icode
== CODE_FOR_vsx_xxpermdi_v2df_be
4343 || icode
== CODE_FOR_vsx_xxpermdi_v2di_be
4344 || icode
== CODE_FOR_vsx_xxpermdi_v1ti
4345 || icode
== CODE_FOR_vsx_xxpermdi_v4sf
4346 || icode
== CODE_FOR_vsx_xxpermdi_v4si
4347 || icode
== CODE_FOR_vsx_xxpermdi_v8hi
4348 || icode
== CODE_FOR_vsx_xxpermdi_v16qi
4349 || icode
== CODE_FOR_vsx_xxsldwi_v16qi
4350 || icode
== CODE_FOR_vsx_xxsldwi_v8hi
4351 || icode
== CODE_FOR_vsx_xxsldwi_v4si
4352 || icode
== CODE_FOR_vsx_xxsldwi_v4sf
4353 || icode
== CODE_FOR_vsx_xxsldwi_v2di
4354 || icode
== CODE_FOR_vsx_xxsldwi_v2df
)
4356 /* Only allow 2-bit unsigned literals. */
4358 if (TREE_CODE (arg2
) != INTEGER_CST
4359 || TREE_INT_CST_LOW (arg2
) & ~0x3)
4361 error ("argument 3 must be a 2-bit unsigned literal");
4362 return CONST0_RTX (tmode
);
4365 else if (icode
== CODE_FOR_vsx_set_v2df
4366 || icode
== CODE_FOR_vsx_set_v2di
4367 || icode
== CODE_FOR_bcdadd
4368 || icode
== CODE_FOR_bcdadd_lt
4369 || icode
== CODE_FOR_bcdadd_eq
4370 || icode
== CODE_FOR_bcdadd_gt
4371 || icode
== CODE_FOR_bcdsub
4372 || icode
== CODE_FOR_bcdsub_lt
4373 || icode
== CODE_FOR_bcdsub_eq
4374 || icode
== CODE_FOR_bcdsub_gt
)
4376 /* Only allow 1-bit unsigned literals. */
4378 if (TREE_CODE (arg2
) != INTEGER_CST
4379 || TREE_INT_CST_LOW (arg2
) & ~0x1)
4381 error ("argument 3 must be a 1-bit unsigned literal");
4382 return CONST0_RTX (tmode
);
4385 else if (icode
== CODE_FOR_dfp_ddedpd_dd
4386 || icode
== CODE_FOR_dfp_ddedpd_td
)
4388 /* Only allow 2-bit unsigned literals where the value is 0 or 2. */
4390 if (TREE_CODE (arg0
) != INTEGER_CST
4391 || TREE_INT_CST_LOW (arg2
) & ~0x3)
4393 error ("argument 1 must be 0 or 2");
4394 return CONST0_RTX (tmode
);
4397 else if (icode
== CODE_FOR_dfp_denbcd_dd
4398 || icode
== CODE_FOR_dfp_denbcd_td
)
4400 /* Only allow 1-bit unsigned literals. */
4402 if (TREE_CODE (arg0
) != INTEGER_CST
4403 || TREE_INT_CST_LOW (arg0
) & ~0x1)
4405 error ("argument 1 must be a 1-bit unsigned literal");
4406 return CONST0_RTX (tmode
);
4409 else if (icode
== CODE_FOR_dfp_dscli_dd
4410 || icode
== CODE_FOR_dfp_dscli_td
4411 || icode
== CODE_FOR_dfp_dscri_dd
4412 || icode
== CODE_FOR_dfp_dscri_td
)
4414 /* Only allow 6-bit unsigned literals. */
4416 if (TREE_CODE (arg1
) != INTEGER_CST
4417 || TREE_INT_CST_LOW (arg1
) & ~0x3f)
4419 error ("argument 2 must be a 6-bit unsigned literal");
4420 return CONST0_RTX (tmode
);
4423 else if (icode
== CODE_FOR_crypto_vshasigmaw
4424 || icode
== CODE_FOR_crypto_vshasigmad
)
4426 /* Check whether the 2nd and 3rd arguments are integer constants and in
4427 range and prepare arguments. */
4429 if (TREE_CODE (arg1
) != INTEGER_CST
|| wi::geu_p (wi::to_wide (arg1
), 2))
4431 error ("argument 2 must be 0 or 1");
4432 return CONST0_RTX (tmode
);
4436 if (TREE_CODE (arg2
) != INTEGER_CST
4437 || wi::geu_p (wi::to_wide (arg2
), 16))
4439 error ("argument 3 must be in the range [0, 15]");
4440 return CONST0_RTX (tmode
);
4445 || GET_MODE (target
) != tmode
4446 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
4447 target
= gen_reg_rtx (tmode
);
4449 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
4450 op0
= copy_to_mode_reg (mode0
, op0
);
4451 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
4452 op1
= copy_to_mode_reg (mode1
, op1
);
4453 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
4454 op2
= copy_to_mode_reg (mode2
, op2
);
4456 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
4465 /* Expand the dst builtins. */
4467 altivec_expand_dst_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
4470 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
4471 enum rs6000_builtins fcode
4472 = (enum rs6000_builtins
) DECL_MD_FUNCTION_CODE (fndecl
);
4473 tree arg0
, arg1
, arg2
;
4474 machine_mode mode0
, mode1
;
4475 rtx pat
, op0
, op1
, op2
;
4476 const struct builtin_description
*d
;
4481 /* Handle DST variants. */
4483 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
4484 if (d
->code
== fcode
)
4486 arg0
= CALL_EXPR_ARG (exp
, 0);
4487 arg1
= CALL_EXPR_ARG (exp
, 1);
4488 arg2
= CALL_EXPR_ARG (exp
, 2);
4489 op0
= expand_normal (arg0
);
4490 op1
= expand_normal (arg1
);
4491 op2
= expand_normal (arg2
);
4492 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
4493 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
4495 /* Invalid arguments, bail out before generating bad rtl. */
4496 if (arg0
== error_mark_node
4497 || arg1
== error_mark_node
4498 || arg2
== error_mark_node
)
4503 if (TREE_CODE (arg2
) != INTEGER_CST
4504 || TREE_INT_CST_LOW (arg2
) & ~0x3)
4506 error ("argument to %qs must be a 2-bit unsigned literal", d
->name
);
4510 if (! (*insn_data
[d
->icode
].operand
[0].predicate
) (op0
, mode0
))
4511 op0
= copy_to_mode_reg (Pmode
, op0
);
4512 if (! (*insn_data
[d
->icode
].operand
[1].predicate
) (op1
, mode1
))
4513 op1
= copy_to_mode_reg (mode1
, op1
);
4515 pat
= GEN_FCN (d
->icode
) (op0
, op1
, op2
);
4525 /* Expand vec_init builtin. */
4527 altivec_expand_vec_init_builtin (tree type
, tree exp
, rtx target
)
4529 machine_mode tmode
= TYPE_MODE (type
);
4530 machine_mode inner_mode
= GET_MODE_INNER (tmode
);
4531 int i
, n_elt
= GET_MODE_NUNITS (tmode
);
4533 gcc_assert (VECTOR_MODE_P (tmode
));
4534 gcc_assert (n_elt
== call_expr_nargs (exp
));
4536 if (!target
|| !register_operand (target
, tmode
))
4537 target
= gen_reg_rtx (tmode
);
4539 /* If we have a vector compromised of a single element, such as V1TImode, do
4540 the initialization directly. */
4541 if (n_elt
== 1 && GET_MODE_SIZE (tmode
) == GET_MODE_SIZE (inner_mode
))
4543 rtx x
= expand_normal (CALL_EXPR_ARG (exp
, 0));
4544 emit_move_insn (target
, gen_lowpart (tmode
, x
));
4548 rtvec v
= rtvec_alloc (n_elt
);
4550 for (i
= 0; i
< n_elt
; ++i
)
4552 rtx x
= expand_normal (CALL_EXPR_ARG (exp
, i
));
4553 RTVEC_ELT (v
, i
) = gen_lowpart (inner_mode
, x
);
4556 rs6000_expand_vector_init (target
, gen_rtx_PARALLEL (tmode
, v
));
4562 /* Return the integer constant in ARG. Constrain it to be in the range
4563 of the subparts of VEC_TYPE; issue an error if not. */
4566 get_element_number (tree vec_type
, tree arg
)
4568 unsigned HOST_WIDE_INT elt
, max
= TYPE_VECTOR_SUBPARTS (vec_type
) - 1;
4570 if (!tree_fits_uhwi_p (arg
)
4571 || (elt
= tree_to_uhwi (arg
), elt
> max
))
4573 error ("selector must be an integer constant in the range [0, %wi]", max
);
4580 /* Expand vec_set builtin. */
4582 altivec_expand_vec_set_builtin (tree exp
)
4584 machine_mode tmode
, mode1
;
4585 tree arg0
, arg1
, arg2
;
4589 arg0
= CALL_EXPR_ARG (exp
, 0);
4590 arg1
= CALL_EXPR_ARG (exp
, 1);
4591 arg2
= CALL_EXPR_ARG (exp
, 2);
4593 tmode
= TYPE_MODE (TREE_TYPE (arg0
));
4594 mode1
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
4595 gcc_assert (VECTOR_MODE_P (tmode
));
4597 op0
= expand_expr (arg0
, NULL_RTX
, tmode
, EXPAND_NORMAL
);
4598 op1
= expand_expr (arg1
, NULL_RTX
, mode1
, EXPAND_NORMAL
);
4599 elt
= get_element_number (TREE_TYPE (arg0
), arg2
);
4601 if (GET_MODE (op1
) != mode1
&& GET_MODE (op1
) != VOIDmode
)
4602 op1
= convert_modes (mode1
, GET_MODE (op1
), op1
, true);
4604 op0
= force_reg (tmode
, op0
);
4605 op1
= force_reg (mode1
, op1
);
4607 rs6000_expand_vector_set (op0
, op1
, elt
);
4612 /* Expand vec_ext builtin. */
4614 altivec_expand_vec_ext_builtin (tree exp
, rtx target
)
4616 machine_mode tmode
, mode0
;
4621 arg0
= CALL_EXPR_ARG (exp
, 0);
4622 arg1
= CALL_EXPR_ARG (exp
, 1);
4624 op0
= expand_normal (arg0
);
4625 op1
= expand_normal (arg1
);
4627 if (TREE_CODE (arg1
) == INTEGER_CST
)
4629 unsigned HOST_WIDE_INT elt
;
4630 unsigned HOST_WIDE_INT size
= TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0
));
4631 unsigned int truncated_selector
;
4632 /* Even if !tree_fits_uhwi_p (arg1)), TREE_INT_CST_LOW (arg0)
4633 returns low-order bits of INTEGER_CST for modulo indexing. */
4634 elt
= TREE_INT_CST_LOW (arg1
);
4635 truncated_selector
= elt
% size
;
4636 op1
= GEN_INT (truncated_selector
);
4639 tmode
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
4640 mode0
= TYPE_MODE (TREE_TYPE (arg0
));
4641 gcc_assert (VECTOR_MODE_P (mode0
));
4643 op0
= force_reg (mode0
, op0
);
4645 if (optimize
|| !target
|| !register_operand (target
, tmode
))
4646 target
= gen_reg_rtx (tmode
);
4648 rs6000_expand_vector_extract (target
, op0
, op1
);
4653 /* Expand the builtin in EXP and store the result in TARGET. Store
4654 true in *EXPANDEDP if we found a builtin to expand. */
4656 altivec_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
4658 const struct builtin_description
*d
;
4660 enum insn_code icode
;
4661 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
4662 tree arg0
, arg1
, arg2
;
4664 machine_mode tmode
, mode0
;
4665 enum rs6000_builtins fcode
4666 = (enum rs6000_builtins
) DECL_MD_FUNCTION_CODE (fndecl
);
4668 if (rs6000_overloaded_builtin_p (fcode
))
4671 error ("unresolved overload for Altivec builtin %qF", fndecl
);
4673 /* Given it is invalid, just generate a normal call. */
4674 return expand_call (exp
, target
, false);
4677 target
= altivec_expand_dst_builtin (exp
, target
, expandedp
);
4685 case ALTIVEC_BUILTIN_STVX_V2DF
:
4686 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v2df
, exp
);
4687 case ALTIVEC_BUILTIN_STVX_V2DI
:
4688 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v2di
, exp
);
4689 case ALTIVEC_BUILTIN_STVX_V4SF
:
4690 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4sf
, exp
);
4691 case ALTIVEC_BUILTIN_STVX
:
4692 case ALTIVEC_BUILTIN_STVX_V4SI
:
4693 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si
, exp
);
4694 case ALTIVEC_BUILTIN_STVX_V8HI
:
4695 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v8hi
, exp
);
4696 case ALTIVEC_BUILTIN_STVX_V16QI
:
4697 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v16qi
, exp
);
4698 case ALTIVEC_BUILTIN_STVEBX
:
4699 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx
, exp
);
4700 case ALTIVEC_BUILTIN_STVEHX
:
4701 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx
, exp
);
4702 case ALTIVEC_BUILTIN_STVEWX
:
4703 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx
, exp
);
4704 case ALTIVEC_BUILTIN_STVXL_V2DF
:
4705 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl_v2df
, exp
);
4706 case ALTIVEC_BUILTIN_STVXL_V2DI
:
4707 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl_v2di
, exp
);
4708 case ALTIVEC_BUILTIN_STVXL_V4SF
:
4709 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl_v4sf
, exp
);
4710 case ALTIVEC_BUILTIN_STVXL
:
4711 case ALTIVEC_BUILTIN_STVXL_V4SI
:
4712 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl_v4si
, exp
);
4713 case ALTIVEC_BUILTIN_STVXL_V8HI
:
4714 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl_v8hi
, exp
);
4715 case ALTIVEC_BUILTIN_STVXL_V16QI
:
4716 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl_v16qi
, exp
);
4718 case ALTIVEC_BUILTIN_STVLX
:
4719 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx
, exp
);
4720 case ALTIVEC_BUILTIN_STVLXL
:
4721 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl
, exp
);
4722 case ALTIVEC_BUILTIN_STVRX
:
4723 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx
, exp
);
4724 case ALTIVEC_BUILTIN_STVRXL
:
4725 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl
, exp
);
4727 case P9V_BUILTIN_STXVL
:
4728 return altivec_expand_stxvl_builtin (CODE_FOR_stxvl
, exp
);
4730 case P9V_BUILTIN_XST_LEN_R
:
4731 return altivec_expand_stxvl_builtin (CODE_FOR_xst_len_r
, exp
);
4733 case VSX_BUILTIN_STXVD2X_V1TI
:
4734 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v1ti
, exp
);
4735 case VSX_BUILTIN_STXVD2X_V2DF
:
4736 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df
, exp
);
4737 case VSX_BUILTIN_STXVD2X_V2DI
:
4738 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2di
, exp
);
4739 case VSX_BUILTIN_STXVW4X_V4SF
:
4740 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4sf
, exp
);
4741 case VSX_BUILTIN_STXVW4X_V4SI
:
4742 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4si
, exp
);
4743 case VSX_BUILTIN_STXVW4X_V8HI
:
4744 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v8hi
, exp
);
4745 case VSX_BUILTIN_STXVW4X_V16QI
:
4746 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi
, exp
);
4748 /* For the following on big endian, it's ok to use any appropriate
4749 unaligned-supporting store, so use a generic expander. For
4750 little-endian, the exact element-reversing instruction must
4752 case VSX_BUILTIN_ST_ELEMREV_V1TI
:
4754 enum insn_code code
= (BYTES_BIG_ENDIAN
? CODE_FOR_vsx_store_v1ti
4755 : CODE_FOR_vsx_st_elemrev_v1ti
);
4756 return altivec_expand_stv_builtin (code
, exp
);
4758 case VSX_BUILTIN_ST_ELEMREV_V2DF
:
4760 enum insn_code code
= (BYTES_BIG_ENDIAN
? CODE_FOR_vsx_store_v2df
4761 : CODE_FOR_vsx_st_elemrev_v2df
);
4762 return altivec_expand_stv_builtin (code
, exp
);
4764 case VSX_BUILTIN_ST_ELEMREV_V2DI
:
4766 enum insn_code code
= (BYTES_BIG_ENDIAN
? CODE_FOR_vsx_store_v2di
4767 : CODE_FOR_vsx_st_elemrev_v2di
);
4768 return altivec_expand_stv_builtin (code
, exp
);
4770 case VSX_BUILTIN_ST_ELEMREV_V4SF
:
4772 enum insn_code code
= (BYTES_BIG_ENDIAN
? CODE_FOR_vsx_store_v4sf
4773 : CODE_FOR_vsx_st_elemrev_v4sf
);
4774 return altivec_expand_stv_builtin (code
, exp
);
4776 case VSX_BUILTIN_ST_ELEMREV_V4SI
:
4778 enum insn_code code
= (BYTES_BIG_ENDIAN
? CODE_FOR_vsx_store_v4si
4779 : CODE_FOR_vsx_st_elemrev_v4si
);
4780 return altivec_expand_stv_builtin (code
, exp
);
4782 case VSX_BUILTIN_ST_ELEMREV_V8HI
:
4784 enum insn_code code
= (BYTES_BIG_ENDIAN
? CODE_FOR_vsx_store_v8hi
4785 : CODE_FOR_vsx_st_elemrev_v8hi
);
4786 return altivec_expand_stv_builtin (code
, exp
);
4788 case VSX_BUILTIN_ST_ELEMREV_V16QI
:
4790 enum insn_code code
= (BYTES_BIG_ENDIAN
? CODE_FOR_vsx_store_v16qi
4791 : CODE_FOR_vsx_st_elemrev_v16qi
);
4792 return altivec_expand_stv_builtin (code
, exp
);
4795 case ALTIVEC_BUILTIN_MFVSCR
:
4796 icode
= CODE_FOR_altivec_mfvscr
;
4797 tmode
= insn_data
[icode
].operand
[0].mode
;
4800 || GET_MODE (target
) != tmode
4801 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
4802 target
= gen_reg_rtx (tmode
);
4804 pat
= GEN_FCN (icode
) (target
);
4810 case ALTIVEC_BUILTIN_MTVSCR
:
4811 icode
= CODE_FOR_altivec_mtvscr
;
4812 arg0
= CALL_EXPR_ARG (exp
, 0);
4813 op0
= expand_normal (arg0
);
4814 mode0
= insn_data
[icode
].operand
[0].mode
;
4816 /* If we got invalid arguments bail out before generating bad rtl. */
4817 if (arg0
== error_mark_node
)
4820 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
4821 op0
= copy_to_mode_reg (mode0
, op0
);
4823 pat
= GEN_FCN (icode
) (op0
);
4828 case ALTIVEC_BUILTIN_DSSALL
:
4829 emit_insn (gen_altivec_dssall ());
4832 case ALTIVEC_BUILTIN_DSS
:
4833 icode
= CODE_FOR_altivec_dss
;
4834 arg0
= CALL_EXPR_ARG (exp
, 0);
4836 op0
= expand_normal (arg0
);
4837 mode0
= insn_data
[icode
].operand
[0].mode
;
4839 /* If we got invalid arguments bail out before generating bad rtl. */
4840 if (arg0
== error_mark_node
)
4843 if (TREE_CODE (arg0
) != INTEGER_CST
4844 || TREE_INT_CST_LOW (arg0
) & ~0x3)
4846 error ("argument to %qs must be a 2-bit unsigned literal", "dss");
4850 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
4851 op0
= copy_to_mode_reg (mode0
, op0
);
4853 emit_insn (gen_altivec_dss (op0
));
4856 case ALTIVEC_BUILTIN_VEC_INIT_V4SI
:
4857 case ALTIVEC_BUILTIN_VEC_INIT_V8HI
:
4858 case ALTIVEC_BUILTIN_VEC_INIT_V16QI
:
4859 case ALTIVEC_BUILTIN_VEC_INIT_V4SF
:
4860 case VSX_BUILTIN_VEC_INIT_V2DF
:
4861 case VSX_BUILTIN_VEC_INIT_V2DI
:
4862 case VSX_BUILTIN_VEC_INIT_V1TI
:
4863 return altivec_expand_vec_init_builtin (TREE_TYPE (exp
), exp
, target
);
4865 case ALTIVEC_BUILTIN_VEC_SET_V4SI
:
4866 case ALTIVEC_BUILTIN_VEC_SET_V8HI
:
4867 case ALTIVEC_BUILTIN_VEC_SET_V16QI
:
4868 case ALTIVEC_BUILTIN_VEC_SET_V4SF
:
4869 case VSX_BUILTIN_VEC_SET_V2DF
:
4870 case VSX_BUILTIN_VEC_SET_V2DI
:
4871 case VSX_BUILTIN_VEC_SET_V1TI
:
4872 return altivec_expand_vec_set_builtin (exp
);
4874 case ALTIVEC_BUILTIN_VEC_EXT_V4SI
:
4875 case ALTIVEC_BUILTIN_VEC_EXT_V8HI
:
4876 case ALTIVEC_BUILTIN_VEC_EXT_V16QI
:
4877 case ALTIVEC_BUILTIN_VEC_EXT_V4SF
:
4878 case VSX_BUILTIN_VEC_EXT_V2DF
:
4879 case VSX_BUILTIN_VEC_EXT_V2DI
:
4880 case VSX_BUILTIN_VEC_EXT_V1TI
:
4881 return altivec_expand_vec_ext_builtin (exp
, target
);
4883 case P9V_BUILTIN_VEC_EXTRACT4B
:
4884 arg1
= CALL_EXPR_ARG (exp
, 1);
4887 /* Generate a normal call if it is invalid. */
4888 if (arg1
== error_mark_node
)
4889 return expand_call (exp
, target
, false);
4891 if (TREE_CODE (arg1
) != INTEGER_CST
|| TREE_INT_CST_LOW (arg1
) > 12)
4893 error ("second argument to %qs must be [0, 12]", "vec_vextract4b");
4894 return expand_call (exp
, target
, false);
4898 case P9V_BUILTIN_VEC_INSERT4B
:
4899 arg2
= CALL_EXPR_ARG (exp
, 2);
4902 /* Generate a normal call if it is invalid. */
4903 if (arg2
== error_mark_node
)
4904 return expand_call (exp
, target
, false);
4906 if (TREE_CODE (arg2
) != INTEGER_CST
|| TREE_INT_CST_LOW (arg2
) > 12)
4908 error ("third argument to %qs must be [0, 12]", "vec_vinsert4b");
4909 return expand_call (exp
, target
, false);
4918 /* Expand abs* operations. */
4920 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
4921 if (d
->code
== fcode
)
4922 return altivec_expand_abs_builtin (d
->icode
, exp
, target
);
4924 /* Expand the AltiVec predicates. */
4925 d
= bdesc_altivec_preds
;
4926 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, d
++)
4927 if (d
->code
== fcode
)
4928 return altivec_expand_predicate_builtin (d
->icode
, exp
, target
);
4930 /* LV* are funky. We initialized them differently. */
4933 case ALTIVEC_BUILTIN_LVSL
:
4934 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl
,
4935 exp
, target
, false);
4936 case ALTIVEC_BUILTIN_LVSR
:
4937 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr
,
4938 exp
, target
, false);
4939 case ALTIVEC_BUILTIN_LVEBX
:
4940 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx
,
4941 exp
, target
, false);
4942 case ALTIVEC_BUILTIN_LVEHX
:
4943 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx
,
4944 exp
, target
, false);
4945 case ALTIVEC_BUILTIN_LVEWX
:
4946 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx
,
4947 exp
, target
, false);
4948 case ALTIVEC_BUILTIN_LVXL_V2DF
:
4949 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl_v2df
,
4950 exp
, target
, false);
4951 case ALTIVEC_BUILTIN_LVXL_V2DI
:
4952 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl_v2di
,
4953 exp
, target
, false);
4954 case ALTIVEC_BUILTIN_LVXL_V4SF
:
4955 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl_v4sf
,
4956 exp
, target
, false);
4957 case ALTIVEC_BUILTIN_LVXL
:
4958 case ALTIVEC_BUILTIN_LVXL_V4SI
:
4959 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl_v4si
,
4960 exp
, target
, false);
4961 case ALTIVEC_BUILTIN_LVXL_V8HI
:
4962 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl_v8hi
,
4963 exp
, target
, false);
4964 case ALTIVEC_BUILTIN_LVXL_V16QI
:
4965 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl_v16qi
,
4966 exp
, target
, false);
4967 case ALTIVEC_BUILTIN_LVX_V1TI
:
4968 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v1ti
,
4969 exp
, target
, false);
4970 case ALTIVEC_BUILTIN_LVX_V2DF
:
4971 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v2df
,
4972 exp
, target
, false);
4973 case ALTIVEC_BUILTIN_LVX_V2DI
:
4974 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v2di
,
4975 exp
, target
, false);
4976 case ALTIVEC_BUILTIN_LVX_V4SF
:
4977 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4sf
,
4978 exp
, target
, false);
4979 case ALTIVEC_BUILTIN_LVX
:
4980 case ALTIVEC_BUILTIN_LVX_V4SI
:
4981 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si
,
4982 exp
, target
, false);
4983 case ALTIVEC_BUILTIN_LVX_V8HI
:
4984 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v8hi
,
4985 exp
, target
, false);
4986 case ALTIVEC_BUILTIN_LVX_V16QI
:
4987 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v16qi
,
4988 exp
, target
, false);
4989 case ALTIVEC_BUILTIN_LVLX
:
4990 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx
,
4992 case ALTIVEC_BUILTIN_LVLXL
:
4993 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl
,
4995 case ALTIVEC_BUILTIN_LVRX
:
4996 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx
,
4998 case ALTIVEC_BUILTIN_LVRXL
:
4999 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl
,
5001 case VSX_BUILTIN_LXVD2X_V1TI
:
5002 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v1ti
,
5003 exp
, target
, false);
5004 case VSX_BUILTIN_LXVD2X_V2DF
:
5005 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df
,
5006 exp
, target
, false);
5007 case VSX_BUILTIN_LXVD2X_V2DI
:
5008 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2di
,
5009 exp
, target
, false);
5010 case VSX_BUILTIN_LXVW4X_V4SF
:
5011 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4sf
,
5012 exp
, target
, false);
5013 case VSX_BUILTIN_LXVW4X_V4SI
:
5014 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4si
,
5015 exp
, target
, false);
5016 case VSX_BUILTIN_LXVW4X_V8HI
:
5017 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v8hi
,
5018 exp
, target
, false);
5019 case VSX_BUILTIN_LXVW4X_V16QI
:
5020 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi
,
5021 exp
, target
, false);
5022 /* For the following on big endian, it's ok to use any appropriate
5023 unaligned-supporting load, so use a generic expander. For
5024 little-endian, the exact element-reversing instruction must
5026 case VSX_BUILTIN_LD_ELEMREV_V2DF
:
5028 enum insn_code code
= (BYTES_BIG_ENDIAN
? CODE_FOR_vsx_load_v2df
5029 : CODE_FOR_vsx_ld_elemrev_v2df
);
5030 return altivec_expand_lv_builtin (code
, exp
, target
, false);
5032 case VSX_BUILTIN_LD_ELEMREV_V1TI
:
5034 enum insn_code code
= (BYTES_BIG_ENDIAN
? CODE_FOR_vsx_load_v1ti
5035 : CODE_FOR_vsx_ld_elemrev_v1ti
);
5036 return altivec_expand_lv_builtin (code
, exp
, target
, false);
5038 case VSX_BUILTIN_LD_ELEMREV_V2DI
:
5040 enum insn_code code
= (BYTES_BIG_ENDIAN
? CODE_FOR_vsx_load_v2di
5041 : CODE_FOR_vsx_ld_elemrev_v2di
);
5042 return altivec_expand_lv_builtin (code
, exp
, target
, false);
5044 case VSX_BUILTIN_LD_ELEMREV_V4SF
:
5046 enum insn_code code
= (BYTES_BIG_ENDIAN
? CODE_FOR_vsx_load_v4sf
5047 : CODE_FOR_vsx_ld_elemrev_v4sf
);
5048 return altivec_expand_lv_builtin (code
, exp
, target
, false);
5050 case VSX_BUILTIN_LD_ELEMREV_V4SI
:
5052 enum insn_code code
= (BYTES_BIG_ENDIAN
? CODE_FOR_vsx_load_v4si
5053 : CODE_FOR_vsx_ld_elemrev_v4si
);
5054 return altivec_expand_lv_builtin (code
, exp
, target
, false);
5056 case VSX_BUILTIN_LD_ELEMREV_V8HI
:
5058 enum insn_code code
= (BYTES_BIG_ENDIAN
? CODE_FOR_vsx_load_v8hi
5059 : CODE_FOR_vsx_ld_elemrev_v8hi
);
5060 return altivec_expand_lv_builtin (code
, exp
, target
, false);
5062 case VSX_BUILTIN_LD_ELEMREV_V16QI
:
5064 enum insn_code code
= (BYTES_BIG_ENDIAN
? CODE_FOR_vsx_load_v16qi
5065 : CODE_FOR_vsx_ld_elemrev_v16qi
);
5066 return altivec_expand_lv_builtin (code
, exp
, target
, false);
5078 /* Check whether a builtin function is supported in this target
5081 rs6000_builtin_is_supported_p (enum rs6000_builtins fncode
)
5083 HOST_WIDE_INT fnmask
= rs6000_builtin_info
[fncode
].mask
;
5084 if ((fnmask
& rs6000_builtin_mask
) != fnmask
)
5090 /* Raise an error message for a builtin function that is called without the
5091 appropriate target options being set. */
5094 rs6000_invalid_builtin (enum rs6000_builtins fncode
)
5096 size_t uns_fncode
= (size_t) fncode
;
5097 const char *name
= rs6000_builtin_info
[uns_fncode
].name
;
5098 HOST_WIDE_INT fnmask
= rs6000_builtin_info
[uns_fncode
].mask
;
5100 gcc_assert (name
!= NULL
);
5101 if ((fnmask
& RS6000_BTM_CELL
) != 0)
5102 error ("%qs is only valid for the cell processor", name
);
5103 else if ((fnmask
& RS6000_BTM_VSX
) != 0)
5104 error ("%qs requires the %qs option", name
, "-mvsx");
5105 else if ((fnmask
& RS6000_BTM_HTM
) != 0)
5106 error ("%qs requires the %qs option", name
, "-mhtm");
5107 else if ((fnmask
& RS6000_BTM_ALTIVEC
) != 0)
5108 error ("%qs requires the %qs option", name
, "-maltivec");
5109 else if ((fnmask
& (RS6000_BTM_DFP
| RS6000_BTM_P8_VECTOR
))
5110 == (RS6000_BTM_DFP
| RS6000_BTM_P8_VECTOR
))
5111 error ("%qs requires the %qs and %qs options", name
, "-mhard-dfp",
5113 else if ((fnmask
& RS6000_BTM_DFP
) != 0)
5114 error ("%qs requires the %qs option", name
, "-mhard-dfp");
5115 else if ((fnmask
& RS6000_BTM_P8_VECTOR
) != 0)
5116 error ("%qs requires the %qs option", name
, "-mpower8-vector");
5117 else if ((fnmask
& (RS6000_BTM_P9_VECTOR
| RS6000_BTM_64BIT
))
5118 == (RS6000_BTM_P9_VECTOR
| RS6000_BTM_64BIT
))
5119 error ("%qs requires the %qs and %qs options", name
, "-mcpu=power9",
5121 else if ((fnmask
& RS6000_BTM_P9_VECTOR
) != 0)
5122 error ("%qs requires the %qs option", name
, "-mcpu=power9");
5123 else if ((fnmask
& (RS6000_BTM_P9_MISC
| RS6000_BTM_64BIT
))
5124 == (RS6000_BTM_P9_MISC
| RS6000_BTM_64BIT
))
5125 error ("%qs requires the %qs and %qs options", name
, "-mcpu=power9",
5127 else if ((fnmask
& RS6000_BTM_P9_MISC
) == RS6000_BTM_P9_MISC
)
5128 error ("%qs requires the %qs option", name
, "-mcpu=power9");
5129 else if ((fnmask
& RS6000_BTM_LDBL128
) == RS6000_BTM_LDBL128
)
5131 if (!TARGET_HARD_FLOAT
)
5132 error ("%qs requires the %qs option", name
, "-mhard-float");
5134 error ("%qs requires the %qs option", name
,
5135 TARGET_IEEEQUAD
? "-mabi=ibmlongdouble" : "-mlong-double-128");
5137 else if ((fnmask
& RS6000_BTM_HARD_FLOAT
) != 0)
5138 error ("%qs requires the %qs option", name
, "-mhard-float");
5139 else if ((fnmask
& RS6000_BTM_FLOAT128_HW
) != 0)
5140 error ("%qs requires ISA 3.0 IEEE 128-bit floating point", name
);
5141 else if ((fnmask
& RS6000_BTM_FLOAT128
) != 0)
5142 error ("%qs requires the %qs option", name
, "%<-mfloat128%>");
5143 else if ((fnmask
& (RS6000_BTM_POPCNTD
| RS6000_BTM_POWERPC64
))
5144 == (RS6000_BTM_POPCNTD
| RS6000_BTM_POWERPC64
))
5145 error ("%qs requires the %qs (or newer), and %qs or %qs options",
5146 name
, "-mcpu=power7", "-m64", "-mpowerpc64");
5148 error ("%qs is not supported with the current options", name
);
5151 /* Target hook for early folding of built-ins, shamelessly stolen
5155 rs6000_fold_builtin (tree fndecl ATTRIBUTE_UNUSED
,
5156 int n_args ATTRIBUTE_UNUSED
,
5157 tree
*args ATTRIBUTE_UNUSED
,
5158 bool ignore ATTRIBUTE_UNUSED
)
5160 #ifdef SUBTARGET_FOLD_BUILTIN
5161 return SUBTARGET_FOLD_BUILTIN (fndecl
, n_args
, args
, ignore
);
5167 /* Helper function to sort out which built-ins may be valid without having
5170 rs6000_builtin_valid_without_lhs (enum rs6000_builtins fn_code
)
5174 case ALTIVEC_BUILTIN_STVX_V16QI
:
5175 case ALTIVEC_BUILTIN_STVX_V8HI
:
5176 case ALTIVEC_BUILTIN_STVX_V4SI
:
5177 case ALTIVEC_BUILTIN_STVX_V4SF
:
5178 case ALTIVEC_BUILTIN_STVX_V2DI
:
5179 case ALTIVEC_BUILTIN_STVX_V2DF
:
5180 case VSX_BUILTIN_STXVW4X_V16QI
:
5181 case VSX_BUILTIN_STXVW4X_V8HI
:
5182 case VSX_BUILTIN_STXVW4X_V4SF
:
5183 case VSX_BUILTIN_STXVW4X_V4SI
:
5184 case VSX_BUILTIN_STXVD2X_V2DF
:
5185 case VSX_BUILTIN_STXVD2X_V2DI
:
5192 /* Helper function to handle the gimple folding of a vector compare
5193 operation. This sets up true/false vectors, and uses the
5194 VEC_COND_EXPR operation.
5195 CODE indicates which comparison is to be made. (EQ, GT, ...).
5196 TYPE indicates the type of the result. */
5198 fold_build_vec_cmp (tree_code code
, tree type
,
5199 tree arg0
, tree arg1
)
5201 tree cmp_type
= build_same_sized_truth_vector_type (type
);
5202 tree zero_vec
= build_zero_cst (type
);
5203 tree minus_one_vec
= build_minus_one_cst (type
);
5204 tree cmp
= fold_build2 (code
, cmp_type
, arg0
, arg1
);
5205 return fold_build3 (VEC_COND_EXPR
, type
, cmp
, minus_one_vec
, zero_vec
);
5208 /* Helper function to handle the in-between steps for the
5209 vector compare built-ins. */
5211 fold_compare_helper (gimple_stmt_iterator
*gsi
, tree_code code
, gimple
*stmt
)
5213 tree arg0
= gimple_call_arg (stmt
, 0);
5214 tree arg1
= gimple_call_arg (stmt
, 1);
5215 tree lhs
= gimple_call_lhs (stmt
);
5216 tree cmp
= fold_build_vec_cmp (code
, TREE_TYPE (lhs
), arg0
, arg1
);
5217 gimple
*g
= gimple_build_assign (lhs
, cmp
);
5218 gimple_set_location (g
, gimple_location (stmt
));
5219 gsi_replace (gsi
, g
, true);
5222 /* Helper function to map V2DF and V4SF types to their
5223 integral equivalents (V2DI and V4SI). */
5224 tree
map_to_integral_tree_type (tree input_tree_type
)
5226 if (INTEGRAL_TYPE_P (TREE_TYPE (input_tree_type
)))
5227 return input_tree_type
;
5230 if (types_compatible_p (TREE_TYPE (input_tree_type
),
5231 TREE_TYPE (V2DF_type_node
)))
5232 return V2DI_type_node
;
5233 else if (types_compatible_p (TREE_TYPE (input_tree_type
),
5234 TREE_TYPE (V4SF_type_node
)))
5235 return V4SI_type_node
;
5241 /* Helper function to handle the vector merge[hl] built-ins. The
5242 implementation difference between h and l versions for this code are in
5243 the values used when building of the permute vector for high word versus
5244 low word merge. The variance is keyed off the use_high parameter. */
5246 fold_mergehl_helper (gimple_stmt_iterator
*gsi
, gimple
*stmt
, int use_high
)
5248 tree arg0
= gimple_call_arg (stmt
, 0);
5249 tree arg1
= gimple_call_arg (stmt
, 1);
5250 tree lhs
= gimple_call_lhs (stmt
);
5251 tree lhs_type
= TREE_TYPE (lhs
);
5252 int n_elts
= TYPE_VECTOR_SUBPARTS (lhs_type
);
5253 int midpoint
= n_elts
/ 2;
5259 /* The permute_type will match the lhs for integral types. For double and
5260 float types, the permute type needs to map to the V2 or V4 type that
5263 permute_type
= map_to_integral_tree_type (lhs_type
);
5264 tree_vector_builder
elts (permute_type
, VECTOR_CST_NELTS (arg0
), 1);
5266 for (int i
= 0; i
< midpoint
; i
++)
5268 elts
.safe_push (build_int_cst (TREE_TYPE (permute_type
),
5270 elts
.safe_push (build_int_cst (TREE_TYPE (permute_type
),
5271 offset
+ n_elts
+ i
));
5274 tree permute
= elts
.build ();
5276 gimple
*g
= gimple_build_assign (lhs
, VEC_PERM_EXPR
, arg0
, arg1
, permute
);
5277 gimple_set_location (g
, gimple_location (stmt
));
5278 gsi_replace (gsi
, g
, true);
5281 /* Helper function to handle the vector merge[eo] built-ins. */
5283 fold_mergeeo_helper (gimple_stmt_iterator
*gsi
, gimple
*stmt
, int use_odd
)
5285 tree arg0
= gimple_call_arg (stmt
, 0);
5286 tree arg1
= gimple_call_arg (stmt
, 1);
5287 tree lhs
= gimple_call_lhs (stmt
);
5288 tree lhs_type
= TREE_TYPE (lhs
);
5289 int n_elts
= TYPE_VECTOR_SUBPARTS (lhs_type
);
5291 /* The permute_type will match the lhs for integral types. For double and
5292 float types, the permute type needs to map to the V2 or V4 type that
5295 permute_type
= map_to_integral_tree_type (lhs_type
);
5297 tree_vector_builder
elts (permute_type
, VECTOR_CST_NELTS (arg0
), 1);
5299 /* Build the permute vector. */
5300 for (int i
= 0; i
< n_elts
/ 2; i
++)
5302 elts
.safe_push (build_int_cst (TREE_TYPE (permute_type
),
5304 elts
.safe_push (build_int_cst (TREE_TYPE (permute_type
),
5305 2*i
+ use_odd
+ n_elts
));
5308 tree permute
= elts
.build ();
5310 gimple
*g
= gimple_build_assign (lhs
, VEC_PERM_EXPR
, arg0
, arg1
, permute
);
5311 gimple_set_location (g
, gimple_location (stmt
));
5312 gsi_replace (gsi
, g
, true);
5315 /* Fold a machine-dependent built-in in GIMPLE. (For folding into
5316 a constant, use rs6000_fold_builtin.) */
5319 rs6000_gimple_fold_builtin (gimple_stmt_iterator
*gsi
)
5321 gimple
*stmt
= gsi_stmt (*gsi
);
5322 tree fndecl
= gimple_call_fndecl (stmt
);
5323 gcc_checking_assert (fndecl
&& DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
);
5324 enum rs6000_builtins fn_code
5325 = (enum rs6000_builtins
) DECL_MD_FUNCTION_CODE (fndecl
);
5326 tree arg0
, arg1
, lhs
, temp
;
5327 enum tree_code bcode
;
5330 size_t uns_fncode
= (size_t) fn_code
;
5331 enum insn_code icode
= rs6000_builtin_info
[uns_fncode
].icode
;
5332 const char *fn_name1
= rs6000_builtin_info
[uns_fncode
].name
;
5333 const char *fn_name2
= (icode
!= CODE_FOR_nothing
)
5334 ? get_insn_name ((int) icode
)
5337 if (TARGET_DEBUG_BUILTIN
)
5338 fprintf (stderr
, "rs6000_gimple_fold_builtin %d %s %s\n",
5339 fn_code
, fn_name1
, fn_name2
);
5341 if (!rs6000_fold_gimple
)
5344 /* Prevent gimple folding for code that does not have a LHS, unless it is
5345 allowed per the rs6000_builtin_valid_without_lhs helper function. */
5346 if (!gimple_call_lhs (stmt
) && !rs6000_builtin_valid_without_lhs (fn_code
))
5349 /* Don't fold invalid builtins, let rs6000_expand_builtin diagnose it. */
5350 HOST_WIDE_INT mask
= rs6000_builtin_info
[uns_fncode
].mask
;
5351 bool func_valid_p
= (rs6000_builtin_mask
& mask
) == mask
;
5357 /* Flavors of vec_add. We deliberately don't expand
5358 P8V_BUILTIN_VADDUQM as it gets lowered from V1TImode to
5359 TImode, resulting in much poorer code generation. */
5360 case ALTIVEC_BUILTIN_VADDUBM
:
5361 case ALTIVEC_BUILTIN_VADDUHM
:
5362 case ALTIVEC_BUILTIN_VADDUWM
:
5363 case P8V_BUILTIN_VADDUDM
:
5364 case ALTIVEC_BUILTIN_VADDFP
:
5365 case VSX_BUILTIN_XVADDDP
:
5368 arg0
= gimple_call_arg (stmt
, 0);
5369 arg1
= gimple_call_arg (stmt
, 1);
5370 lhs
= gimple_call_lhs (stmt
);
5371 if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (lhs
)))
5372 && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (TREE_TYPE (lhs
))))
5374 /* Ensure the binary operation is performed in a type
5375 that wraps if it is integral type. */
5376 gimple_seq stmts
= NULL
;
5377 tree type
= unsigned_type_for (TREE_TYPE (lhs
));
5378 tree uarg0
= gimple_build (&stmts
, VIEW_CONVERT_EXPR
,
5380 tree uarg1
= gimple_build (&stmts
, VIEW_CONVERT_EXPR
,
5382 tree res
= gimple_build (&stmts
, gimple_location (stmt
), bcode
,
5383 type
, uarg0
, uarg1
);
5384 gsi_insert_seq_before (gsi
, stmts
, GSI_SAME_STMT
);
5385 g
= gimple_build_assign (lhs
, VIEW_CONVERT_EXPR
,
5386 build1 (VIEW_CONVERT_EXPR
,
5387 TREE_TYPE (lhs
), res
));
5388 gsi_replace (gsi
, g
, true);
5391 g
= gimple_build_assign (lhs
, bcode
, arg0
, arg1
);
5392 gimple_set_location (g
, gimple_location (stmt
));
5393 gsi_replace (gsi
, g
, true);
5395 /* Flavors of vec_sub. We deliberately don't expand
5396 P8V_BUILTIN_VSUBUQM. */
5397 case ALTIVEC_BUILTIN_VSUBUBM
:
5398 case ALTIVEC_BUILTIN_VSUBUHM
:
5399 case ALTIVEC_BUILTIN_VSUBUWM
:
5400 case P8V_BUILTIN_VSUBUDM
:
5401 case ALTIVEC_BUILTIN_VSUBFP
:
5402 case VSX_BUILTIN_XVSUBDP
:
5405 case VSX_BUILTIN_XVMULSP
:
5406 case VSX_BUILTIN_XVMULDP
:
5407 arg0
= gimple_call_arg (stmt
, 0);
5408 arg1
= gimple_call_arg (stmt
, 1);
5409 lhs
= gimple_call_lhs (stmt
);
5410 g
= gimple_build_assign (lhs
, MULT_EXPR
, arg0
, arg1
);
5411 gimple_set_location (g
, gimple_location (stmt
));
5412 gsi_replace (gsi
, g
, true);
5414 /* Even element flavors of vec_mul (signed). */
5415 case ALTIVEC_BUILTIN_VMULESB
:
5416 case ALTIVEC_BUILTIN_VMULESH
:
5417 case P8V_BUILTIN_VMULESW
:
5418 /* Even element flavors of vec_mul (unsigned). */
5419 case ALTIVEC_BUILTIN_VMULEUB
:
5420 case ALTIVEC_BUILTIN_VMULEUH
:
5421 case P8V_BUILTIN_VMULEUW
:
5422 arg0
= gimple_call_arg (stmt
, 0);
5423 arg1
= gimple_call_arg (stmt
, 1);
5424 lhs
= gimple_call_lhs (stmt
);
5425 g
= gimple_build_assign (lhs
, VEC_WIDEN_MULT_EVEN_EXPR
, arg0
, arg1
);
5426 gimple_set_location (g
, gimple_location (stmt
));
5427 gsi_replace (gsi
, g
, true);
5429 /* Odd element flavors of vec_mul (signed). */
5430 case ALTIVEC_BUILTIN_VMULOSB
:
5431 case ALTIVEC_BUILTIN_VMULOSH
:
5432 case P8V_BUILTIN_VMULOSW
:
5433 /* Odd element flavors of vec_mul (unsigned). */
5434 case ALTIVEC_BUILTIN_VMULOUB
:
5435 case ALTIVEC_BUILTIN_VMULOUH
:
5436 case P8V_BUILTIN_VMULOUW
:
5437 arg0
= gimple_call_arg (stmt
, 0);
5438 arg1
= gimple_call_arg (stmt
, 1);
5439 lhs
= gimple_call_lhs (stmt
);
5440 g
= gimple_build_assign (lhs
, VEC_WIDEN_MULT_ODD_EXPR
, arg0
, arg1
);
5441 gimple_set_location (g
, gimple_location (stmt
));
5442 gsi_replace (gsi
, g
, true);
5444 /* Flavors of vec_div (Integer). */
5445 case VSX_BUILTIN_DIV_V2DI
:
5446 case VSX_BUILTIN_UDIV_V2DI
:
5447 arg0
= gimple_call_arg (stmt
, 0);
5448 arg1
= gimple_call_arg (stmt
, 1);
5449 lhs
= gimple_call_lhs (stmt
);
5450 g
= gimple_build_assign (lhs
, TRUNC_DIV_EXPR
, arg0
, arg1
);
5451 gimple_set_location (g
, gimple_location (stmt
));
5452 gsi_replace (gsi
, g
, true);
5454 /* Flavors of vec_div (Float). */
5455 case VSX_BUILTIN_XVDIVSP
:
5456 case VSX_BUILTIN_XVDIVDP
:
5457 arg0
= gimple_call_arg (stmt
, 0);
5458 arg1
= gimple_call_arg (stmt
, 1);
5459 lhs
= gimple_call_lhs (stmt
);
5460 g
= gimple_build_assign (lhs
, RDIV_EXPR
, arg0
, arg1
);
5461 gimple_set_location (g
, gimple_location (stmt
));
5462 gsi_replace (gsi
, g
, true);
5464 /* Flavors of vec_and. */
5465 case ALTIVEC_BUILTIN_VAND
:
5466 arg0
= gimple_call_arg (stmt
, 0);
5467 arg1
= gimple_call_arg (stmt
, 1);
5468 lhs
= gimple_call_lhs (stmt
);
5469 g
= gimple_build_assign (lhs
, BIT_AND_EXPR
, arg0
, arg1
);
5470 gimple_set_location (g
, gimple_location (stmt
));
5471 gsi_replace (gsi
, g
, true);
5473 /* Flavors of vec_andc. */
5474 case ALTIVEC_BUILTIN_VANDC
:
5475 arg0
= gimple_call_arg (stmt
, 0);
5476 arg1
= gimple_call_arg (stmt
, 1);
5477 lhs
= gimple_call_lhs (stmt
);
5478 temp
= create_tmp_reg_or_ssa_name (TREE_TYPE (arg1
));
5479 g
= gimple_build_assign (temp
, BIT_NOT_EXPR
, arg1
);
5480 gimple_set_location (g
, gimple_location (stmt
));
5481 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
5482 g
= gimple_build_assign (lhs
, BIT_AND_EXPR
, arg0
, temp
);
5483 gimple_set_location (g
, gimple_location (stmt
));
5484 gsi_replace (gsi
, g
, true);
5486 /* Flavors of vec_nand. */
5487 case P8V_BUILTIN_VEC_NAND
:
5488 case P8V_BUILTIN_NAND_V16QI
:
5489 case P8V_BUILTIN_NAND_V8HI
:
5490 case P8V_BUILTIN_NAND_V4SI
:
5491 case P8V_BUILTIN_NAND_V4SF
:
5492 case P8V_BUILTIN_NAND_V2DF
:
5493 case P8V_BUILTIN_NAND_V2DI
:
5494 arg0
= gimple_call_arg (stmt
, 0);
5495 arg1
= gimple_call_arg (stmt
, 1);
5496 lhs
= gimple_call_lhs (stmt
);
5497 temp
= create_tmp_reg_or_ssa_name (TREE_TYPE (arg1
));
5498 g
= gimple_build_assign (temp
, BIT_AND_EXPR
, arg0
, arg1
);
5499 gimple_set_location (g
, gimple_location (stmt
));
5500 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
5501 g
= gimple_build_assign (lhs
, BIT_NOT_EXPR
, temp
);
5502 gimple_set_location (g
, gimple_location (stmt
));
5503 gsi_replace (gsi
, g
, true);
5505 /* Flavors of vec_or. */
5506 case ALTIVEC_BUILTIN_VOR
:
5507 arg0
= gimple_call_arg (stmt
, 0);
5508 arg1
= gimple_call_arg (stmt
, 1);
5509 lhs
= gimple_call_lhs (stmt
);
5510 g
= gimple_build_assign (lhs
, BIT_IOR_EXPR
, arg0
, arg1
);
5511 gimple_set_location (g
, gimple_location (stmt
));
5512 gsi_replace (gsi
, g
, true);
5514 /* flavors of vec_orc. */
5515 case P8V_BUILTIN_ORC_V16QI
:
5516 case P8V_BUILTIN_ORC_V8HI
:
5517 case P8V_BUILTIN_ORC_V4SI
:
5518 case P8V_BUILTIN_ORC_V4SF
:
5519 case P8V_BUILTIN_ORC_V2DF
:
5520 case P8V_BUILTIN_ORC_V2DI
:
5521 arg0
= gimple_call_arg (stmt
, 0);
5522 arg1
= gimple_call_arg (stmt
, 1);
5523 lhs
= gimple_call_lhs (stmt
);
5524 temp
= create_tmp_reg_or_ssa_name (TREE_TYPE (arg1
));
5525 g
= gimple_build_assign (temp
, BIT_NOT_EXPR
, arg1
);
5526 gimple_set_location (g
, gimple_location (stmt
));
5527 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
5528 g
= gimple_build_assign (lhs
, BIT_IOR_EXPR
, arg0
, temp
);
5529 gimple_set_location (g
, gimple_location (stmt
));
5530 gsi_replace (gsi
, g
, true);
5532 /* Flavors of vec_xor. */
5533 case ALTIVEC_BUILTIN_VXOR
:
5534 arg0
= gimple_call_arg (stmt
, 0);
5535 arg1
= gimple_call_arg (stmt
, 1);
5536 lhs
= gimple_call_lhs (stmt
);
5537 g
= gimple_build_assign (lhs
, BIT_XOR_EXPR
, arg0
, arg1
);
5538 gimple_set_location (g
, gimple_location (stmt
));
5539 gsi_replace (gsi
, g
, true);
5541 /* Flavors of vec_nor. */
5542 case ALTIVEC_BUILTIN_VNOR
:
5543 arg0
= gimple_call_arg (stmt
, 0);
5544 arg1
= gimple_call_arg (stmt
, 1);
5545 lhs
= gimple_call_lhs (stmt
);
5546 temp
= create_tmp_reg_or_ssa_name (TREE_TYPE (arg1
));
5547 g
= gimple_build_assign (temp
, BIT_IOR_EXPR
, arg0
, arg1
);
5548 gimple_set_location (g
, gimple_location (stmt
));
5549 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
5550 g
= gimple_build_assign (lhs
, BIT_NOT_EXPR
, temp
);
5551 gimple_set_location (g
, gimple_location (stmt
));
5552 gsi_replace (gsi
, g
, true);
5554 /* flavors of vec_abs. */
5555 case ALTIVEC_BUILTIN_ABS_V16QI
:
5556 case ALTIVEC_BUILTIN_ABS_V8HI
:
5557 case ALTIVEC_BUILTIN_ABS_V4SI
:
5558 case ALTIVEC_BUILTIN_ABS_V4SF
:
5559 case P8V_BUILTIN_ABS_V2DI
:
5560 case VSX_BUILTIN_XVABSDP
:
5561 arg0
= gimple_call_arg (stmt
, 0);
5562 if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (arg0
)))
5563 && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (TREE_TYPE (arg0
))))
5565 lhs
= gimple_call_lhs (stmt
);
5566 g
= gimple_build_assign (lhs
, ABS_EXPR
, arg0
);
5567 gimple_set_location (g
, gimple_location (stmt
));
5568 gsi_replace (gsi
, g
, true);
5570 /* flavors of vec_min. */
5571 case VSX_BUILTIN_XVMINDP
:
5572 case P8V_BUILTIN_VMINSD
:
5573 case P8V_BUILTIN_VMINUD
:
5574 case ALTIVEC_BUILTIN_VMINSB
:
5575 case ALTIVEC_BUILTIN_VMINSH
:
5576 case ALTIVEC_BUILTIN_VMINSW
:
5577 case ALTIVEC_BUILTIN_VMINUB
:
5578 case ALTIVEC_BUILTIN_VMINUH
:
5579 case ALTIVEC_BUILTIN_VMINUW
:
5580 case ALTIVEC_BUILTIN_VMINFP
:
5581 arg0
= gimple_call_arg (stmt
, 0);
5582 arg1
= gimple_call_arg (stmt
, 1);
5583 lhs
= gimple_call_lhs (stmt
);
5584 g
= gimple_build_assign (lhs
, MIN_EXPR
, arg0
, arg1
);
5585 gimple_set_location (g
, gimple_location (stmt
));
5586 gsi_replace (gsi
, g
, true);
5588 /* flavors of vec_max. */
5589 case VSX_BUILTIN_XVMAXDP
:
5590 case P8V_BUILTIN_VMAXSD
:
5591 case P8V_BUILTIN_VMAXUD
:
5592 case ALTIVEC_BUILTIN_VMAXSB
:
5593 case ALTIVEC_BUILTIN_VMAXSH
:
5594 case ALTIVEC_BUILTIN_VMAXSW
:
5595 case ALTIVEC_BUILTIN_VMAXUB
:
5596 case ALTIVEC_BUILTIN_VMAXUH
:
5597 case ALTIVEC_BUILTIN_VMAXUW
:
5598 case ALTIVEC_BUILTIN_VMAXFP
:
5599 arg0
= gimple_call_arg (stmt
, 0);
5600 arg1
= gimple_call_arg (stmt
, 1);
5601 lhs
= gimple_call_lhs (stmt
);
5602 g
= gimple_build_assign (lhs
, MAX_EXPR
, arg0
, arg1
);
5603 gimple_set_location (g
, gimple_location (stmt
));
5604 gsi_replace (gsi
, g
, true);
5606 /* Flavors of vec_eqv. */
5607 case P8V_BUILTIN_EQV_V16QI
:
5608 case P8V_BUILTIN_EQV_V8HI
:
5609 case P8V_BUILTIN_EQV_V4SI
:
5610 case P8V_BUILTIN_EQV_V4SF
:
5611 case P8V_BUILTIN_EQV_V2DF
:
5612 case P8V_BUILTIN_EQV_V2DI
:
5613 arg0
= gimple_call_arg (stmt
, 0);
5614 arg1
= gimple_call_arg (stmt
, 1);
5615 lhs
= gimple_call_lhs (stmt
);
5616 temp
= create_tmp_reg_or_ssa_name (TREE_TYPE (arg1
));
5617 g
= gimple_build_assign (temp
, BIT_XOR_EXPR
, arg0
, arg1
);
5618 gimple_set_location (g
, gimple_location (stmt
));
5619 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
5620 g
= gimple_build_assign (lhs
, BIT_NOT_EXPR
, temp
);
5621 gimple_set_location (g
, gimple_location (stmt
));
5622 gsi_replace (gsi
, g
, true);
5624 /* Flavors of vec_rotate_left. */
5625 case ALTIVEC_BUILTIN_VRLB
:
5626 case ALTIVEC_BUILTIN_VRLH
:
5627 case ALTIVEC_BUILTIN_VRLW
:
5628 case P8V_BUILTIN_VRLD
:
5629 arg0
= gimple_call_arg (stmt
, 0);
5630 arg1
= gimple_call_arg (stmt
, 1);
5631 lhs
= gimple_call_lhs (stmt
);
5632 g
= gimple_build_assign (lhs
, LROTATE_EXPR
, arg0
, arg1
);
5633 gimple_set_location (g
, gimple_location (stmt
));
5634 gsi_replace (gsi
, g
, true);
5636 /* Flavors of vector shift right algebraic.
5637 vec_sra{b,h,w} -> vsra{b,h,w}. */
5638 case ALTIVEC_BUILTIN_VSRAB
:
5639 case ALTIVEC_BUILTIN_VSRAH
:
5640 case ALTIVEC_BUILTIN_VSRAW
:
5641 case P8V_BUILTIN_VSRAD
:
5643 arg0
= gimple_call_arg (stmt
, 0);
5644 arg1
= gimple_call_arg (stmt
, 1);
5645 lhs
= gimple_call_lhs (stmt
);
5646 tree arg1_type
= TREE_TYPE (arg1
);
5647 tree unsigned_arg1_type
= unsigned_type_for (TREE_TYPE (arg1
));
5648 tree unsigned_element_type
= unsigned_type_for (TREE_TYPE (arg1_type
));
5649 location_t loc
= gimple_location (stmt
);
5650 /* Force arg1 into the range valid matching the arg0 type. */
5651 /* Build a vector consisting of the max valid bit-size values. */
5652 int n_elts
= VECTOR_CST_NELTS (arg1
);
5653 tree element_size
= build_int_cst (unsigned_element_type
,
5655 tree_vector_builder
elts (unsigned_arg1_type
, n_elts
, 1);
5656 for (int i
= 0; i
< n_elts
; i
++)
5657 elts
.safe_push (element_size
);
5658 tree modulo_tree
= elts
.build ();
5659 /* Modulo the provided shift value against that vector. */
5660 gimple_seq stmts
= NULL
;
5661 tree unsigned_arg1
= gimple_build (&stmts
, VIEW_CONVERT_EXPR
,
5662 unsigned_arg1_type
, arg1
);
5663 tree new_arg1
= gimple_build (&stmts
, loc
, TRUNC_MOD_EXPR
,
5664 unsigned_arg1_type
, unsigned_arg1
,
5666 gsi_insert_seq_before (gsi
, stmts
, GSI_SAME_STMT
);
5667 /* And finally, do the shift. */
5668 g
= gimple_build_assign (lhs
, RSHIFT_EXPR
, arg0
, new_arg1
);
5669 gimple_set_location (g
, loc
);
5670 gsi_replace (gsi
, g
, true);
5673 /* Flavors of vector shift left.
5674 builtin_altivec_vsl{b,h,w} -> vsl{b,h,w}. */
5675 case ALTIVEC_BUILTIN_VSLB
:
5676 case ALTIVEC_BUILTIN_VSLH
:
5677 case ALTIVEC_BUILTIN_VSLW
:
5678 case P8V_BUILTIN_VSLD
:
5681 gimple_seq stmts
= NULL
;
5682 arg0
= gimple_call_arg (stmt
, 0);
5683 tree arg0_type
= TREE_TYPE (arg0
);
5684 if (INTEGRAL_TYPE_P (TREE_TYPE (arg0_type
))
5685 && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0_type
)))
5687 arg1
= gimple_call_arg (stmt
, 1);
5688 tree arg1_type
= TREE_TYPE (arg1
);
5689 tree unsigned_arg1_type
= unsigned_type_for (TREE_TYPE (arg1
));
5690 tree unsigned_element_type
= unsigned_type_for (TREE_TYPE (arg1_type
));
5691 loc
= gimple_location (stmt
);
5692 lhs
= gimple_call_lhs (stmt
);
5693 /* Force arg1 into the range valid matching the arg0 type. */
5694 /* Build a vector consisting of the max valid bit-size values. */
5695 int n_elts
= VECTOR_CST_NELTS (arg1
);
5696 int tree_size_in_bits
= TREE_INT_CST_LOW (size_in_bytes (arg1_type
))
5698 tree element_size
= build_int_cst (unsigned_element_type
,
5699 tree_size_in_bits
/ n_elts
);
5700 tree_vector_builder
elts (unsigned_type_for (arg1_type
), n_elts
, 1);
5701 for (int i
= 0; i
< n_elts
; i
++)
5702 elts
.safe_push (element_size
);
5703 tree modulo_tree
= elts
.build ();
5704 /* Modulo the provided shift value against that vector. */
5705 tree unsigned_arg1
= gimple_build (&stmts
, VIEW_CONVERT_EXPR
,
5706 unsigned_arg1_type
, arg1
);
5707 tree new_arg1
= gimple_build (&stmts
, loc
, TRUNC_MOD_EXPR
,
5708 unsigned_arg1_type
, unsigned_arg1
,
5710 gsi_insert_seq_before (gsi
, stmts
, GSI_SAME_STMT
);
5711 /* And finally, do the shift. */
5712 g
= gimple_build_assign (lhs
, LSHIFT_EXPR
, arg0
, new_arg1
);
5713 gimple_set_location (g
, gimple_location (stmt
));
5714 gsi_replace (gsi
, g
, true);
5717 /* Flavors of vector shift right. */
5718 case ALTIVEC_BUILTIN_VSRB
:
5719 case ALTIVEC_BUILTIN_VSRH
:
5720 case ALTIVEC_BUILTIN_VSRW
:
5721 case P8V_BUILTIN_VSRD
:
5723 arg0
= gimple_call_arg (stmt
, 0);
5724 arg1
= gimple_call_arg (stmt
, 1);
5725 lhs
= gimple_call_lhs (stmt
);
5726 tree arg1_type
= TREE_TYPE (arg1
);
5727 tree unsigned_arg1_type
= unsigned_type_for (TREE_TYPE (arg1
));
5728 tree unsigned_element_type
= unsigned_type_for (TREE_TYPE (arg1_type
));
5729 location_t loc
= gimple_location (stmt
);
5730 gimple_seq stmts
= NULL
;
5731 /* Convert arg0 to unsigned. */
5733 = gimple_build (&stmts
, VIEW_CONVERT_EXPR
,
5734 unsigned_type_for (TREE_TYPE (arg0
)), arg0
);
5735 /* Force arg1 into the range valid matching the arg0 type. */
5736 /* Build a vector consisting of the max valid bit-size values. */
5737 int n_elts
= VECTOR_CST_NELTS (arg1
);
5738 tree element_size
= build_int_cst (unsigned_element_type
,
5740 tree_vector_builder
elts (unsigned_arg1_type
, n_elts
, 1);
5741 for (int i
= 0; i
< n_elts
; i
++)
5742 elts
.safe_push (element_size
);
5743 tree modulo_tree
= elts
.build ();
5744 /* Modulo the provided shift value against that vector. */
5745 tree unsigned_arg1
= gimple_build (&stmts
, VIEW_CONVERT_EXPR
,
5746 unsigned_arg1_type
, arg1
);
5747 tree new_arg1
= gimple_build (&stmts
, loc
, TRUNC_MOD_EXPR
,
5748 unsigned_arg1_type
, unsigned_arg1
,
5752 = gimple_build (&stmts
, RSHIFT_EXPR
,
5753 TREE_TYPE (arg0_unsigned
), arg0_unsigned
, new_arg1
);
5754 /* Convert result back to the lhs type. */
5755 res
= gimple_build (&stmts
, VIEW_CONVERT_EXPR
, TREE_TYPE (lhs
), res
);
5756 gsi_insert_seq_before (gsi
, stmts
, GSI_SAME_STMT
);
5757 update_call_from_tree (gsi
, res
);
5761 case ALTIVEC_BUILTIN_LVX_V16QI
:
5762 case ALTIVEC_BUILTIN_LVX_V8HI
:
5763 case ALTIVEC_BUILTIN_LVX_V4SI
:
5764 case ALTIVEC_BUILTIN_LVX_V4SF
:
5765 case ALTIVEC_BUILTIN_LVX_V2DI
:
5766 case ALTIVEC_BUILTIN_LVX_V2DF
:
5767 case ALTIVEC_BUILTIN_LVX_V1TI
:
5769 arg0
= gimple_call_arg (stmt
, 0); // offset
5770 arg1
= gimple_call_arg (stmt
, 1); // address
5771 lhs
= gimple_call_lhs (stmt
);
5772 location_t loc
= gimple_location (stmt
);
5773 /* Since arg1 may be cast to a different type, just use ptr_type_node
5774 here instead of trying to enforce TBAA on pointer types. */
5775 tree arg1_type
= ptr_type_node
;
5776 tree lhs_type
= TREE_TYPE (lhs
);
5777 /* POINTER_PLUS_EXPR wants the offset to be of type 'sizetype'. Create
5778 the tree using the value from arg0. The resulting type will match
5779 the type of arg1. */
5780 gimple_seq stmts
= NULL
;
5781 tree temp_offset
= gimple_convert (&stmts
, loc
, sizetype
, arg0
);
5782 tree temp_addr
= gimple_build (&stmts
, loc
, POINTER_PLUS_EXPR
,
5783 arg1_type
, arg1
, temp_offset
);
5784 /* Mask off any lower bits from the address. */
5785 tree aligned_addr
= gimple_build (&stmts
, loc
, BIT_AND_EXPR
,
5786 arg1_type
, temp_addr
,
5787 build_int_cst (arg1_type
, -16));
5788 gsi_insert_seq_before (gsi
, stmts
, GSI_SAME_STMT
);
5789 if (!is_gimple_mem_ref_addr (aligned_addr
))
5791 tree t
= make_ssa_name (TREE_TYPE (aligned_addr
));
5792 gimple
*g
= gimple_build_assign (t
, aligned_addr
);
5793 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
5796 /* Use the build2 helper to set up the mem_ref. The MEM_REF could also
5797 take an offset, but since we've already incorporated the offset
5798 above, here we just pass in a zero. */
5800 = gimple_build_assign (lhs
, build2 (MEM_REF
, lhs_type
, aligned_addr
,
5801 build_int_cst (arg1_type
, 0)));
5802 gimple_set_location (g
, loc
);
5803 gsi_replace (gsi
, g
, true);
5806 /* Vector stores. */
5807 case ALTIVEC_BUILTIN_STVX_V16QI
:
5808 case ALTIVEC_BUILTIN_STVX_V8HI
:
5809 case ALTIVEC_BUILTIN_STVX_V4SI
:
5810 case ALTIVEC_BUILTIN_STVX_V4SF
:
5811 case ALTIVEC_BUILTIN_STVX_V2DI
:
5812 case ALTIVEC_BUILTIN_STVX_V2DF
:
5814 arg0
= gimple_call_arg (stmt
, 0); /* Value to be stored. */
5815 arg1
= gimple_call_arg (stmt
, 1); /* Offset. */
5816 tree arg2
= gimple_call_arg (stmt
, 2); /* Store-to address. */
5817 location_t loc
= gimple_location (stmt
);
5818 tree arg0_type
= TREE_TYPE (arg0
);
5819 /* Use ptr_type_node (no TBAA) for the arg2_type.
5820 FIXME: (Richard) "A proper fix would be to transition this type as
5821 seen from the frontend to GIMPLE, for example in a similar way we
5822 do for MEM_REFs by piggy-backing that on an extra argument, a
5823 constant zero pointer of the alias pointer type to use (which would
5824 also serve as a type indicator of the store itself). I'd use a
5825 target specific internal function for this (not sure if we can have
5826 those target specific, but I guess if it's folded away then that's
5827 fine) and get away with the overload set." */
5828 tree arg2_type
= ptr_type_node
;
5829 /* POINTER_PLUS_EXPR wants the offset to be of type 'sizetype'. Create
5830 the tree using the value from arg0. The resulting type will match
5831 the type of arg2. */
5832 gimple_seq stmts
= NULL
;
5833 tree temp_offset
= gimple_convert (&stmts
, loc
, sizetype
, arg1
);
5834 tree temp_addr
= gimple_build (&stmts
, loc
, POINTER_PLUS_EXPR
,
5835 arg2_type
, arg2
, temp_offset
);
5836 /* Mask off any lower bits from the address. */
5837 tree aligned_addr
= gimple_build (&stmts
, loc
, BIT_AND_EXPR
,
5838 arg2_type
, temp_addr
,
5839 build_int_cst (arg2_type
, -16));
5840 gsi_insert_seq_before (gsi
, stmts
, GSI_SAME_STMT
);
5841 if (!is_gimple_mem_ref_addr (aligned_addr
))
5843 tree t
= make_ssa_name (TREE_TYPE (aligned_addr
));
5844 gimple
*g
= gimple_build_assign (t
, aligned_addr
);
5845 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
5848 /* The desired gimple result should be similar to:
5849 MEM[(__vector floatD.1407 *)_1] = vf1D.2697; */
5851 = gimple_build_assign (build2 (MEM_REF
, arg0_type
, aligned_addr
,
5852 build_int_cst (arg2_type
, 0)), arg0
);
5853 gimple_set_location (g
, loc
);
5854 gsi_replace (gsi
, g
, true);
5858 /* unaligned Vector loads. */
5859 case VSX_BUILTIN_LXVW4X_V16QI
:
5860 case VSX_BUILTIN_LXVW4X_V8HI
:
5861 case VSX_BUILTIN_LXVW4X_V4SF
:
5862 case VSX_BUILTIN_LXVW4X_V4SI
:
5863 case VSX_BUILTIN_LXVD2X_V2DF
:
5864 case VSX_BUILTIN_LXVD2X_V2DI
:
5866 arg0
= gimple_call_arg (stmt
, 0); // offset
5867 arg1
= gimple_call_arg (stmt
, 1); // address
5868 lhs
= gimple_call_lhs (stmt
);
5869 location_t loc
= gimple_location (stmt
);
5870 /* Since arg1 may be cast to a different type, just use ptr_type_node
5871 here instead of trying to enforce TBAA on pointer types. */
5872 tree arg1_type
= ptr_type_node
;
5873 tree lhs_type
= TREE_TYPE (lhs
);
5874 /* In GIMPLE the type of the MEM_REF specifies the alignment. The
5875 required alignment (power) is 4 bytes regardless of data type. */
5876 tree align_ltype
= build_aligned_type (lhs_type
, 4);
5877 /* POINTER_PLUS_EXPR wants the offset to be of type 'sizetype'. Create
5878 the tree using the value from arg0. The resulting type will match
5879 the type of arg1. */
5880 gimple_seq stmts
= NULL
;
5881 tree temp_offset
= gimple_convert (&stmts
, loc
, sizetype
, arg0
);
5882 tree temp_addr
= gimple_build (&stmts
, loc
, POINTER_PLUS_EXPR
,
5883 arg1_type
, arg1
, temp_offset
);
5884 gsi_insert_seq_before (gsi
, stmts
, GSI_SAME_STMT
);
5885 if (!is_gimple_mem_ref_addr (temp_addr
))
5887 tree t
= make_ssa_name (TREE_TYPE (temp_addr
));
5888 gimple
*g
= gimple_build_assign (t
, temp_addr
);
5889 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
5892 /* Use the build2 helper to set up the mem_ref. The MEM_REF could also
5893 take an offset, but since we've already incorporated the offset
5894 above, here we just pass in a zero. */
5896 g
= gimple_build_assign (lhs
, build2 (MEM_REF
, align_ltype
, temp_addr
,
5897 build_int_cst (arg1_type
, 0)));
5898 gimple_set_location (g
, loc
);
5899 gsi_replace (gsi
, g
, true);
5903 /* unaligned Vector stores. */
5904 case VSX_BUILTIN_STXVW4X_V16QI
:
5905 case VSX_BUILTIN_STXVW4X_V8HI
:
5906 case VSX_BUILTIN_STXVW4X_V4SF
:
5907 case VSX_BUILTIN_STXVW4X_V4SI
:
5908 case VSX_BUILTIN_STXVD2X_V2DF
:
5909 case VSX_BUILTIN_STXVD2X_V2DI
:
5911 arg0
= gimple_call_arg (stmt
, 0); /* Value to be stored. */
5912 arg1
= gimple_call_arg (stmt
, 1); /* Offset. */
5913 tree arg2
= gimple_call_arg (stmt
, 2); /* Store-to address. */
5914 location_t loc
= gimple_location (stmt
);
5915 tree arg0_type
= TREE_TYPE (arg0
);
5916 /* Use ptr_type_node (no TBAA) for the arg2_type. */
5917 tree arg2_type
= ptr_type_node
;
5918 /* In GIMPLE the type of the MEM_REF specifies the alignment. The
5919 required alignment (power) is 4 bytes regardless of data type. */
5920 tree align_stype
= build_aligned_type (arg0_type
, 4);
5921 /* POINTER_PLUS_EXPR wants the offset to be of type 'sizetype'. Create
5922 the tree using the value from arg1. */
5923 gimple_seq stmts
= NULL
;
5924 tree temp_offset
= gimple_convert (&stmts
, loc
, sizetype
, arg1
);
5925 tree temp_addr
= gimple_build (&stmts
, loc
, POINTER_PLUS_EXPR
,
5926 arg2_type
, arg2
, temp_offset
);
5927 gsi_insert_seq_before (gsi
, stmts
, GSI_SAME_STMT
);
5928 if (!is_gimple_mem_ref_addr (temp_addr
))
5930 tree t
= make_ssa_name (TREE_TYPE (temp_addr
));
5931 gimple
*g
= gimple_build_assign (t
, temp_addr
);
5932 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
5936 g
= gimple_build_assign (build2 (MEM_REF
, align_stype
, temp_addr
,
5937 build_int_cst (arg2_type
, 0)), arg0
);
5938 gimple_set_location (g
, loc
);
5939 gsi_replace (gsi
, g
, true);
5943 /* Vector Fused multiply-add (fma). */
5944 case ALTIVEC_BUILTIN_VMADDFP
:
5945 case VSX_BUILTIN_XVMADDDP
:
5946 case ALTIVEC_BUILTIN_VMLADDUHM
:
5948 arg0
= gimple_call_arg (stmt
, 0);
5949 arg1
= gimple_call_arg (stmt
, 1);
5950 tree arg2
= gimple_call_arg (stmt
, 2);
5951 lhs
= gimple_call_lhs (stmt
);
5952 gcall
*g
= gimple_build_call_internal (IFN_FMA
, 3, arg0
, arg1
, arg2
);
5953 gimple_call_set_lhs (g
, lhs
);
5954 gimple_call_set_nothrow (g
, true);
5955 gimple_set_location (g
, gimple_location (stmt
));
5956 gsi_replace (gsi
, g
, true);
5960 /* Vector compares; EQ, NE, GE, GT, LE. */
5961 case ALTIVEC_BUILTIN_VCMPEQUB
:
5962 case ALTIVEC_BUILTIN_VCMPEQUH
:
5963 case ALTIVEC_BUILTIN_VCMPEQUW
:
5964 case P8V_BUILTIN_VCMPEQUD
:
5965 fold_compare_helper (gsi
, EQ_EXPR
, stmt
);
5968 case P9V_BUILTIN_CMPNEB
:
5969 case P9V_BUILTIN_CMPNEH
:
5970 case P9V_BUILTIN_CMPNEW
:
5971 fold_compare_helper (gsi
, NE_EXPR
, stmt
);
5974 case VSX_BUILTIN_CMPGE_16QI
:
5975 case VSX_BUILTIN_CMPGE_U16QI
:
5976 case VSX_BUILTIN_CMPGE_8HI
:
5977 case VSX_BUILTIN_CMPGE_U8HI
:
5978 case VSX_BUILTIN_CMPGE_4SI
:
5979 case VSX_BUILTIN_CMPGE_U4SI
:
5980 case VSX_BUILTIN_CMPGE_2DI
:
5981 case VSX_BUILTIN_CMPGE_U2DI
:
5982 fold_compare_helper (gsi
, GE_EXPR
, stmt
);
5985 case ALTIVEC_BUILTIN_VCMPGTSB
:
5986 case ALTIVEC_BUILTIN_VCMPGTUB
:
5987 case ALTIVEC_BUILTIN_VCMPGTSH
:
5988 case ALTIVEC_BUILTIN_VCMPGTUH
:
5989 case ALTIVEC_BUILTIN_VCMPGTSW
:
5990 case ALTIVEC_BUILTIN_VCMPGTUW
:
5991 case P8V_BUILTIN_VCMPGTUD
:
5992 case P8V_BUILTIN_VCMPGTSD
:
5993 fold_compare_helper (gsi
, GT_EXPR
, stmt
);
5996 case VSX_BUILTIN_CMPLE_16QI
:
5997 case VSX_BUILTIN_CMPLE_U16QI
:
5998 case VSX_BUILTIN_CMPLE_8HI
:
5999 case VSX_BUILTIN_CMPLE_U8HI
:
6000 case VSX_BUILTIN_CMPLE_4SI
:
6001 case VSX_BUILTIN_CMPLE_U4SI
:
6002 case VSX_BUILTIN_CMPLE_2DI
:
6003 case VSX_BUILTIN_CMPLE_U2DI
:
6004 fold_compare_helper (gsi
, LE_EXPR
, stmt
);
6007 /* flavors of vec_splat_[us]{8,16,32}. */
6008 case ALTIVEC_BUILTIN_VSPLTISB
:
6009 case ALTIVEC_BUILTIN_VSPLTISH
:
6010 case ALTIVEC_BUILTIN_VSPLTISW
:
6012 arg0
= gimple_call_arg (stmt
, 0);
6013 lhs
= gimple_call_lhs (stmt
);
6015 /* Only fold the vec_splat_*() if the lower bits of arg 0 is a
6016 5-bit signed constant in range -16 to +15. */
6017 if (TREE_CODE (arg0
) != INTEGER_CST
6018 || !IN_RANGE (TREE_INT_CST_LOW (arg0
), -16, 15))
6020 gimple_seq stmts
= NULL
;
6021 location_t loc
= gimple_location (stmt
);
6022 tree splat_value
= gimple_convert (&stmts
, loc
,
6023 TREE_TYPE (TREE_TYPE (lhs
)), arg0
);
6024 gsi_insert_seq_before (gsi
, stmts
, GSI_SAME_STMT
);
6025 tree splat_tree
= build_vector_from_val (TREE_TYPE (lhs
), splat_value
);
6026 g
= gimple_build_assign (lhs
, splat_tree
);
6027 gimple_set_location (g
, gimple_location (stmt
));
6028 gsi_replace (gsi
, g
, true);
6032 /* Flavors of vec_splat. */
6033 /* a = vec_splat (b, 0x3) becomes a = { b[3],b[3],b[3],...}; */
6034 case ALTIVEC_BUILTIN_VSPLTB
:
6035 case ALTIVEC_BUILTIN_VSPLTH
:
6036 case ALTIVEC_BUILTIN_VSPLTW
:
6037 case VSX_BUILTIN_XXSPLTD_V2DI
:
6038 case VSX_BUILTIN_XXSPLTD_V2DF
:
6040 arg0
= gimple_call_arg (stmt
, 0); /* input vector. */
6041 arg1
= gimple_call_arg (stmt
, 1); /* index into arg0. */
6042 /* Only fold the vec_splat_*() if arg1 is both a constant value and
6043 is a valid index into the arg0 vector. */
6044 unsigned int n_elts
= VECTOR_CST_NELTS (arg0
);
6045 if (TREE_CODE (arg1
) != INTEGER_CST
6046 || TREE_INT_CST_LOW (arg1
) > (n_elts
-1))
6048 lhs
= gimple_call_lhs (stmt
);
6049 tree lhs_type
= TREE_TYPE (lhs
);
6050 tree arg0_type
= TREE_TYPE (arg0
);
6052 if (TREE_CODE (arg0
) == VECTOR_CST
)
6053 splat
= VECTOR_CST_ELT (arg0
, TREE_INT_CST_LOW (arg1
));
6056 /* Determine (in bits) the length and start location of the
6057 splat value for a call to the tree_vec_extract helper. */
6058 int splat_elem_size
= TREE_INT_CST_LOW (size_in_bytes (arg0_type
))
6059 * BITS_PER_UNIT
/ n_elts
;
6060 int splat_start_bit
= TREE_INT_CST_LOW (arg1
) * splat_elem_size
;
6061 tree len
= build_int_cst (bitsizetype
, splat_elem_size
);
6062 tree start
= build_int_cst (bitsizetype
, splat_start_bit
);
6063 splat
= tree_vec_extract (gsi
, TREE_TYPE (lhs_type
), arg0
,
6066 /* And finally, build the new vector. */
6067 tree splat_tree
= build_vector_from_val (lhs_type
, splat
);
6068 g
= gimple_build_assign (lhs
, splat_tree
);
6069 gimple_set_location (g
, gimple_location (stmt
));
6070 gsi_replace (gsi
, g
, true);
6074 /* vec_mergel (integrals). */
6075 case ALTIVEC_BUILTIN_VMRGLH
:
6076 case ALTIVEC_BUILTIN_VMRGLW
:
6077 case VSX_BUILTIN_XXMRGLW_4SI
:
6078 case ALTIVEC_BUILTIN_VMRGLB
:
6079 case VSX_BUILTIN_VEC_MERGEL_V2DI
:
6080 case VSX_BUILTIN_XXMRGLW_4SF
:
6081 case VSX_BUILTIN_VEC_MERGEL_V2DF
:
6082 fold_mergehl_helper (gsi
, stmt
, 1);
6084 /* vec_mergeh (integrals). */
6085 case ALTIVEC_BUILTIN_VMRGHH
:
6086 case ALTIVEC_BUILTIN_VMRGHW
:
6087 case VSX_BUILTIN_XXMRGHW_4SI
:
6088 case ALTIVEC_BUILTIN_VMRGHB
:
6089 case VSX_BUILTIN_VEC_MERGEH_V2DI
:
6090 case VSX_BUILTIN_XXMRGHW_4SF
:
6091 case VSX_BUILTIN_VEC_MERGEH_V2DF
:
6092 fold_mergehl_helper (gsi
, stmt
, 0);
6095 /* Flavors of vec_mergee. */
6096 case P8V_BUILTIN_VMRGEW_V4SI
:
6097 case P8V_BUILTIN_VMRGEW_V2DI
:
6098 case P8V_BUILTIN_VMRGEW_V4SF
:
6099 case P8V_BUILTIN_VMRGEW_V2DF
:
6100 fold_mergeeo_helper (gsi
, stmt
, 0);
6102 /* Flavors of vec_mergeo. */
6103 case P8V_BUILTIN_VMRGOW_V4SI
:
6104 case P8V_BUILTIN_VMRGOW_V2DI
:
6105 case P8V_BUILTIN_VMRGOW_V4SF
:
6106 case P8V_BUILTIN_VMRGOW_V2DF
:
6107 fold_mergeeo_helper (gsi
, stmt
, 1);
6110 /* d = vec_pack (a, b) */
6111 case P8V_BUILTIN_VPKUDUM
:
6112 case ALTIVEC_BUILTIN_VPKUHUM
:
6113 case ALTIVEC_BUILTIN_VPKUWUM
:
6115 arg0
= gimple_call_arg (stmt
, 0);
6116 arg1
= gimple_call_arg (stmt
, 1);
6117 lhs
= gimple_call_lhs (stmt
);
6118 gimple
*g
= gimple_build_assign (lhs
, VEC_PACK_TRUNC_EXPR
, arg0
, arg1
);
6119 gimple_set_location (g
, gimple_location (stmt
));
6120 gsi_replace (gsi
, g
, true);
6124 /* d = vec_unpackh (a) */
6125 /* Note that the UNPACK_{HI,LO}_EXPR used in the gimple_build_assign call
6126 in this code is sensitive to endian-ness, and needs to be inverted to
6127 handle both LE and BE targets. */
6128 case ALTIVEC_BUILTIN_VUPKHSB
:
6129 case ALTIVEC_BUILTIN_VUPKHSH
:
6130 case P8V_BUILTIN_VUPKHSW
:
6132 arg0
= gimple_call_arg (stmt
, 0);
6133 lhs
= gimple_call_lhs (stmt
);
6134 if (BYTES_BIG_ENDIAN
)
6135 g
= gimple_build_assign (lhs
, VEC_UNPACK_HI_EXPR
, arg0
);
6137 g
= gimple_build_assign (lhs
, VEC_UNPACK_LO_EXPR
, arg0
);
6138 gimple_set_location (g
, gimple_location (stmt
));
6139 gsi_replace (gsi
, g
, true);
6142 /* d = vec_unpackl (a) */
6143 case ALTIVEC_BUILTIN_VUPKLSB
:
6144 case ALTIVEC_BUILTIN_VUPKLSH
:
6145 case P8V_BUILTIN_VUPKLSW
:
6147 arg0
= gimple_call_arg (stmt
, 0);
6148 lhs
= gimple_call_lhs (stmt
);
6149 if (BYTES_BIG_ENDIAN
)
6150 g
= gimple_build_assign (lhs
, VEC_UNPACK_LO_EXPR
, arg0
);
6152 g
= gimple_build_assign (lhs
, VEC_UNPACK_HI_EXPR
, arg0
);
6153 gimple_set_location (g
, gimple_location (stmt
));
6154 gsi_replace (gsi
, g
, true);
6157 /* There is no gimple type corresponding with pixel, so just return. */
6158 case ALTIVEC_BUILTIN_VUPKHPX
:
6159 case ALTIVEC_BUILTIN_VUPKLPX
:
6163 case ALTIVEC_BUILTIN_VPERM_16QI
:
6164 case ALTIVEC_BUILTIN_VPERM_8HI
:
6165 case ALTIVEC_BUILTIN_VPERM_4SI
:
6166 case ALTIVEC_BUILTIN_VPERM_2DI
:
6167 case ALTIVEC_BUILTIN_VPERM_4SF
:
6168 case ALTIVEC_BUILTIN_VPERM_2DF
:
6170 arg0
= gimple_call_arg (stmt
, 0);
6171 arg1
= gimple_call_arg (stmt
, 1);
6172 tree permute
= gimple_call_arg (stmt
, 2);
6173 lhs
= gimple_call_lhs (stmt
);
6174 location_t loc
= gimple_location (stmt
);
6175 gimple_seq stmts
= NULL
;
6176 // convert arg0 and arg1 to match the type of the permute
6177 // for the VEC_PERM_EXPR operation.
6178 tree permute_type
= (TREE_TYPE (permute
));
6179 tree arg0_ptype
= gimple_convert (&stmts
, loc
, permute_type
, arg0
);
6180 tree arg1_ptype
= gimple_convert (&stmts
, loc
, permute_type
, arg1
);
6181 tree lhs_ptype
= gimple_build (&stmts
, loc
, VEC_PERM_EXPR
,
6182 permute_type
, arg0_ptype
, arg1_ptype
,
6184 // Convert the result back to the desired lhs type upon completion.
6185 tree temp
= gimple_convert (&stmts
, loc
, TREE_TYPE (lhs
), lhs_ptype
);
6186 gsi_insert_seq_before (gsi
, stmts
, GSI_SAME_STMT
);
6187 g
= gimple_build_assign (lhs
, temp
);
6188 gimple_set_location (g
, loc
);
6189 gsi_replace (gsi
, g
, true);
6194 if (TARGET_DEBUG_BUILTIN
)
6195 fprintf (stderr
, "gimple builtin intrinsic not matched:%d %s %s\n",
6196 fn_code
, fn_name1
, fn_name2
);
6203 /* Expand an expression EXP that calls a built-in function,
6204 with result going to TARGET if that's convenient
6205 (and in mode MODE if that's convenient).
6206 SUBTARGET may be used as the target for computing one of EXP's operands.
6207 IGNORE is nonzero if the value is to be ignored. */
6210 rs6000_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
6211 machine_mode mode ATTRIBUTE_UNUSED
,
6212 int ignore ATTRIBUTE_UNUSED
)
6214 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
6215 enum rs6000_builtins fcode
6216 = (enum rs6000_builtins
) DECL_MD_FUNCTION_CODE (fndecl
);
6217 size_t uns_fcode
= (size_t)fcode
;
6218 const struct builtin_description
*d
;
6222 HOST_WIDE_INT mask
= rs6000_builtin_info
[uns_fcode
].mask
;
6223 bool func_valid_p
= ((rs6000_builtin_mask
& mask
) == mask
);
6224 enum insn_code icode
= rs6000_builtin_info
[uns_fcode
].icode
;
6226 /* We have two different modes (KFmode, TFmode) that are the IEEE 128-bit
6227 floating point type, depending on whether long double is the IBM extended
6228 double (KFmode) or long double is IEEE 128-bit (TFmode). It is simpler if
6229 we only define one variant of the built-in function, and switch the code
6230 when defining it, rather than defining two built-ins and using the
6231 overload table in rs6000-c.c to switch between the two. If we don't have
6232 the proper assembler, don't do this switch because CODE_FOR_*kf* and
6233 CODE_FOR_*tf* will be CODE_FOR_nothing. */
6234 if (FLOAT128_IEEE_P (TFmode
))
6240 case CODE_FOR_sqrtkf2_odd
: icode
= CODE_FOR_sqrttf2_odd
; break;
6241 case CODE_FOR_trunckfdf2_odd
: icode
= CODE_FOR_trunctfdf2_odd
; break;
6242 case CODE_FOR_addkf3_odd
: icode
= CODE_FOR_addtf3_odd
; break;
6243 case CODE_FOR_subkf3_odd
: icode
= CODE_FOR_subtf3_odd
; break;
6244 case CODE_FOR_mulkf3_odd
: icode
= CODE_FOR_multf3_odd
; break;
6245 case CODE_FOR_divkf3_odd
: icode
= CODE_FOR_divtf3_odd
; break;
6246 case CODE_FOR_fmakf4_odd
: icode
= CODE_FOR_fmatf4_odd
; break;
6247 case CODE_FOR_xsxexpqp_kf
: icode
= CODE_FOR_xsxexpqp_tf
; break;
6248 case CODE_FOR_xsxsigqp_kf
: icode
= CODE_FOR_xsxsigqp_tf
; break;
6249 case CODE_FOR_xststdcnegqp_kf
: icode
= CODE_FOR_xststdcnegqp_tf
; break;
6250 case CODE_FOR_xsiexpqp_kf
: icode
= CODE_FOR_xsiexpqp_tf
; break;
6251 case CODE_FOR_xsiexpqpf_kf
: icode
= CODE_FOR_xsiexpqpf_tf
; break;
6252 case CODE_FOR_xststdcqp_kf
: icode
= CODE_FOR_xststdcqp_tf
; break;
6255 if (TARGET_DEBUG_BUILTIN
)
6257 const char *name1
= rs6000_builtin_info
[uns_fcode
].name
;
6258 const char *name2
= (icode
!= CODE_FOR_nothing
)
6259 ? get_insn_name ((int) icode
)
6263 switch (rs6000_builtin_info
[uns_fcode
].attr
& RS6000_BTC_TYPE_MASK
)
6265 default: name3
= "unknown"; break;
6266 case RS6000_BTC_SPECIAL
: name3
= "special"; break;
6267 case RS6000_BTC_UNARY
: name3
= "unary"; break;
6268 case RS6000_BTC_BINARY
: name3
= "binary"; break;
6269 case RS6000_BTC_TERNARY
: name3
= "ternary"; break;
6270 case RS6000_BTC_PREDICATE
: name3
= "predicate"; break;
6271 case RS6000_BTC_ABS
: name3
= "abs"; break;
6272 case RS6000_BTC_DST
: name3
= "dst"; break;
6277 "rs6000_expand_builtin, %s (%d), insn = %s (%d), type=%s%s\n",
6278 (name1
) ? name1
: "---", fcode
,
6279 (name2
) ? name2
: "---", (int) icode
,
6281 func_valid_p
? "" : ", not valid");
6286 rs6000_invalid_builtin (fcode
);
6288 /* Given it is invalid, just generate a normal call. */
6289 return expand_call (exp
, target
, ignore
);
6294 case RS6000_BUILTIN_RECIP
:
6295 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3
, exp
, target
);
6297 case RS6000_BUILTIN_RECIPF
:
6298 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3
, exp
, target
);
6300 case RS6000_BUILTIN_RSQRTF
:
6301 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2
, exp
, target
);
6303 case RS6000_BUILTIN_RSQRT
:
6304 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2
, exp
, target
);
6306 case POWER7_BUILTIN_BPERMD
:
6307 return rs6000_expand_binop_builtin (((TARGET_64BIT
)
6308 ? CODE_FOR_bpermd_di
6309 : CODE_FOR_bpermd_si
), exp
, target
);
6311 case RS6000_BUILTIN_GET_TB
:
6312 return rs6000_expand_zeroop_builtin (CODE_FOR_rs6000_get_timebase
,
6315 case RS6000_BUILTIN_MFTB
:
6316 return rs6000_expand_zeroop_builtin (((TARGET_64BIT
)
6317 ? CODE_FOR_rs6000_mftb_di
6318 : CODE_FOR_rs6000_mftb_si
),
6321 case RS6000_BUILTIN_MFFS
:
6322 return rs6000_expand_zeroop_builtin (CODE_FOR_rs6000_mffs
, target
);
6324 case RS6000_BUILTIN_MTFSB0
:
6325 return rs6000_expand_mtfsb_builtin (CODE_FOR_rs6000_mtfsb0
, exp
);
6327 case RS6000_BUILTIN_MTFSB1
:
6328 return rs6000_expand_mtfsb_builtin (CODE_FOR_rs6000_mtfsb1
, exp
);
6330 case RS6000_BUILTIN_SET_FPSCR_RN
:
6331 return rs6000_expand_set_fpscr_rn_builtin (CODE_FOR_rs6000_set_fpscr_rn
,
6334 case RS6000_BUILTIN_SET_FPSCR_DRN
:
6336 rs6000_expand_set_fpscr_drn_builtin (CODE_FOR_rs6000_set_fpscr_drn
,
6339 case RS6000_BUILTIN_MFFSL
:
6340 return rs6000_expand_zeroop_builtin (CODE_FOR_rs6000_mffsl
, target
);
6342 case RS6000_BUILTIN_MTFSF
:
6343 return rs6000_expand_mtfsf_builtin (CODE_FOR_rs6000_mtfsf
, exp
);
6345 case RS6000_BUILTIN_CPU_INIT
:
6346 case RS6000_BUILTIN_CPU_IS
:
6347 case RS6000_BUILTIN_CPU_SUPPORTS
:
6348 return cpu_expand_builtin (fcode
, exp
, target
);
6350 case MISC_BUILTIN_SPEC_BARRIER
:
6352 emit_insn (gen_speculation_barrier ());
6356 case ALTIVEC_BUILTIN_MASK_FOR_LOAD
:
6357 case ALTIVEC_BUILTIN_MASK_FOR_STORE
:
6359 int icode2
= (BYTES_BIG_ENDIAN
? (int) CODE_FOR_altivec_lvsr_direct
6360 : (int) CODE_FOR_altivec_lvsl_direct
);
6361 machine_mode tmode
= insn_data
[icode2
].operand
[0].mode
;
6362 machine_mode mode
= insn_data
[icode2
].operand
[1].mode
;
6366 gcc_assert (TARGET_ALTIVEC
);
6368 arg
= CALL_EXPR_ARG (exp
, 0);
6369 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg
)));
6370 op
= expand_expr (arg
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
6371 addr
= memory_address (mode
, op
);
6372 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
6376 /* For the load case need to negate the address. */
6377 op
= gen_reg_rtx (GET_MODE (addr
));
6378 emit_insn (gen_rtx_SET (op
, gen_rtx_NEG (GET_MODE (addr
), addr
)));
6380 op
= gen_rtx_MEM (mode
, op
);
6383 || GET_MODE (target
) != tmode
6384 || ! (*insn_data
[icode2
].operand
[0].predicate
) (target
, tmode
))
6385 target
= gen_reg_rtx (tmode
);
6387 pat
= GEN_FCN (icode2
) (target
, op
);
6395 case ALTIVEC_BUILTIN_VCFUX
:
6396 case ALTIVEC_BUILTIN_VCFSX
:
6397 case ALTIVEC_BUILTIN_VCTUXS
:
6398 case ALTIVEC_BUILTIN_VCTSXS
:
6399 /* FIXME: There's got to be a nicer way to handle this case than
6400 constructing a new CALL_EXPR. */
6401 if (call_expr_nargs (exp
) == 1)
6403 exp
= build_call_nary (TREE_TYPE (exp
), CALL_EXPR_FN (exp
),
6404 2, CALL_EXPR_ARG (exp
, 0), integer_zero_node
);
6408 /* For the pack and unpack int128 routines, fix up the builtin so it
6409 uses the correct IBM128 type. */
6410 case MISC_BUILTIN_PACK_IF
:
6411 if (TARGET_LONG_DOUBLE_128
&& !TARGET_IEEEQUAD
)
6413 icode
= CODE_FOR_packtf
;
6414 fcode
= MISC_BUILTIN_PACK_TF
;
6415 uns_fcode
= (size_t)fcode
;
6419 case MISC_BUILTIN_UNPACK_IF
:
6420 if (TARGET_LONG_DOUBLE_128
&& !TARGET_IEEEQUAD
)
6422 icode
= CODE_FOR_unpacktf
;
6423 fcode
= MISC_BUILTIN_UNPACK_TF
;
6424 uns_fcode
= (size_t)fcode
;
6434 ret
= altivec_expand_builtin (exp
, target
, &success
);
6441 ret
= htm_expand_builtin (exp
, target
, &success
);
6447 unsigned attr
= rs6000_builtin_info
[uns_fcode
].attr
& RS6000_BTC_TYPE_MASK
;
6448 /* RS6000_BTC_SPECIAL represents no-operand operators. */
6449 gcc_assert (attr
== RS6000_BTC_UNARY
6450 || attr
== RS6000_BTC_BINARY
6451 || attr
== RS6000_BTC_TERNARY
6452 || attr
== RS6000_BTC_SPECIAL
);
6454 /* Handle simple unary operations. */
6456 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
6457 if (d
->code
== fcode
)
6458 return rs6000_expand_unop_builtin (icode
, exp
, target
);
6460 /* Handle simple binary operations. */
6462 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
6463 if (d
->code
== fcode
)
6464 return rs6000_expand_binop_builtin (icode
, exp
, target
);
6466 /* Handle simple ternary operations. */
6468 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
6469 if (d
->code
== fcode
)
6470 return rs6000_expand_ternop_builtin (icode
, exp
, target
);
6472 /* Handle simple no-argument operations. */
6474 for (i
= 0; i
< ARRAY_SIZE (bdesc_0arg
); i
++, d
++)
6475 if (d
->code
== fcode
)
6476 return rs6000_expand_zeroop_builtin (icode
, target
);
6481 /* Create a builtin vector type with a name. Taking care not to give
6482 the canonical type a name. */
6485 rs6000_vector_type (const char *name
, tree elt_type
, unsigned num_elts
)
6487 tree result
= build_vector_type (elt_type
, num_elts
);
6489 /* Copy so we don't give the canonical type a name. */
6490 result
= build_variant_type_copy (result
);
6492 add_builtin_type (name
, result
);
6498 rs6000_init_builtins (void)
6504 if (TARGET_DEBUG_BUILTIN
)
6505 fprintf (stderr
, "rs6000_init_builtins%s%s\n",
6506 (TARGET_ALTIVEC
) ? ", altivec" : "",
6507 (TARGET_VSX
) ? ", vsx" : "");
6509 V2DI_type_node
= rs6000_vector_type (TARGET_POWERPC64
? "__vector long"
6510 : "__vector long long",
6511 intDI_type_node
, 2);
6512 V2DF_type_node
= rs6000_vector_type ("__vector double", double_type_node
, 2);
6513 V4SI_type_node
= rs6000_vector_type ("__vector signed int",
6514 intSI_type_node
, 4);
6515 V4SF_type_node
= rs6000_vector_type ("__vector float", float_type_node
, 4);
6516 V8HI_type_node
= rs6000_vector_type ("__vector signed short",
6517 intHI_type_node
, 8);
6518 V16QI_type_node
= rs6000_vector_type ("__vector signed char",
6519 intQI_type_node
, 16);
6521 unsigned_V16QI_type_node
= rs6000_vector_type ("__vector unsigned char",
6522 unsigned_intQI_type_node
, 16);
6523 unsigned_V8HI_type_node
= rs6000_vector_type ("__vector unsigned short",
6524 unsigned_intHI_type_node
, 8);
6525 unsigned_V4SI_type_node
= rs6000_vector_type ("__vector unsigned int",
6526 unsigned_intSI_type_node
, 4);
6527 unsigned_V2DI_type_node
= rs6000_vector_type (TARGET_POWERPC64
6528 ? "__vector unsigned long"
6529 : "__vector unsigned long long",
6530 unsigned_intDI_type_node
, 2);
6532 opaque_V4SI_type_node
= build_opaque_vector_type (intSI_type_node
, 4);
6535 = build_pointer_type (build_qualified_type (char_type_node
,
6538 /* We use V1TI mode as a special container to hold __int128_t items that
6539 must live in VSX registers. */
6540 if (intTI_type_node
)
6542 V1TI_type_node
= rs6000_vector_type ("__vector __int128",
6543 intTI_type_node
, 1);
6544 unsigned_V1TI_type_node
6545 = rs6000_vector_type ("__vector unsigned __int128",
6546 unsigned_intTI_type_node
, 1);
6549 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
6550 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
6551 'vector unsigned short'. */
6553 bool_char_type_node
= build_distinct_type_copy (unsigned_intQI_type_node
);
6554 bool_short_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
6555 bool_int_type_node
= build_distinct_type_copy (unsigned_intSI_type_node
);
6556 bool_long_long_type_node
= build_distinct_type_copy (unsigned_intDI_type_node
);
6557 pixel_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
6559 long_integer_type_internal_node
= long_integer_type_node
;
6560 long_unsigned_type_internal_node
= long_unsigned_type_node
;
6561 long_long_integer_type_internal_node
= long_long_integer_type_node
;
6562 long_long_unsigned_type_internal_node
= long_long_unsigned_type_node
;
6563 intQI_type_internal_node
= intQI_type_node
;
6564 uintQI_type_internal_node
= unsigned_intQI_type_node
;
6565 intHI_type_internal_node
= intHI_type_node
;
6566 uintHI_type_internal_node
= unsigned_intHI_type_node
;
6567 intSI_type_internal_node
= intSI_type_node
;
6568 uintSI_type_internal_node
= unsigned_intSI_type_node
;
6569 intDI_type_internal_node
= intDI_type_node
;
6570 uintDI_type_internal_node
= unsigned_intDI_type_node
;
6571 intTI_type_internal_node
= intTI_type_node
;
6572 uintTI_type_internal_node
= unsigned_intTI_type_node
;
6573 float_type_internal_node
= float_type_node
;
6574 double_type_internal_node
= double_type_node
;
6575 long_double_type_internal_node
= long_double_type_node
;
6576 dfloat64_type_internal_node
= dfloat64_type_node
;
6577 dfloat128_type_internal_node
= dfloat128_type_node
;
6578 void_type_internal_node
= void_type_node
;
6580 /* 128-bit floating point support. KFmode is IEEE 128-bit floating point.
6581 IFmode is the IBM extended 128-bit format that is a pair of doubles.
6582 TFmode will be either IEEE 128-bit floating point or the IBM double-double
6583 format that uses a pair of doubles, depending on the switches and
6586 If we don't support for either 128-bit IBM double double or IEEE 128-bit
6587 floating point, we need make sure the type is non-zero or else self-test
6588 fails during bootstrap.
6590 Always create __ibm128 as a separate type, even if the current long double
6591 format is IBM extended double.
6593 For IEEE 128-bit floating point, always create the type __ieee128. If the
6594 user used -mfloat128, rs6000-c.c will create a define from __float128 to
6596 if (TARGET_FLOAT128_TYPE
)
6598 if (!TARGET_IEEEQUAD
&& TARGET_LONG_DOUBLE_128
)
6599 ibm128_float_type_node
= long_double_type_node
;
6602 ibm128_float_type_node
= make_node (REAL_TYPE
);
6603 TYPE_PRECISION (ibm128_float_type_node
) = 128;
6604 SET_TYPE_MODE (ibm128_float_type_node
, IFmode
);
6605 layout_type (ibm128_float_type_node
);
6608 lang_hooks
.types
.register_builtin_type (ibm128_float_type_node
,
6611 if (TARGET_IEEEQUAD
&& TARGET_LONG_DOUBLE_128
)
6612 ieee128_float_type_node
= long_double_type_node
;
6614 ieee128_float_type_node
= float128_type_node
;
6616 lang_hooks
.types
.register_builtin_type (ieee128_float_type_node
,
6621 ieee128_float_type_node
= ibm128_float_type_node
= long_double_type_node
;
6623 /* Initialize the modes for builtin_function_type, mapping a machine mode to
6625 builtin_mode_to_type
[QImode
][0] = integer_type_node
;
6626 builtin_mode_to_type
[HImode
][0] = integer_type_node
;
6627 builtin_mode_to_type
[SImode
][0] = intSI_type_node
;
6628 builtin_mode_to_type
[SImode
][1] = unsigned_intSI_type_node
;
6629 builtin_mode_to_type
[DImode
][0] = intDI_type_node
;
6630 builtin_mode_to_type
[DImode
][1] = unsigned_intDI_type_node
;
6631 builtin_mode_to_type
[TImode
][0] = intTI_type_node
;
6632 builtin_mode_to_type
[TImode
][1] = unsigned_intTI_type_node
;
6633 builtin_mode_to_type
[SFmode
][0] = float_type_node
;
6634 builtin_mode_to_type
[DFmode
][0] = double_type_node
;
6635 builtin_mode_to_type
[IFmode
][0] = ibm128_float_type_node
;
6636 builtin_mode_to_type
[KFmode
][0] = ieee128_float_type_node
;
6637 builtin_mode_to_type
[TFmode
][0] = long_double_type_node
;
6638 builtin_mode_to_type
[DDmode
][0] = dfloat64_type_node
;
6639 builtin_mode_to_type
[TDmode
][0] = dfloat128_type_node
;
6640 builtin_mode_to_type
[V1TImode
][0] = V1TI_type_node
;
6641 builtin_mode_to_type
[V1TImode
][1] = unsigned_V1TI_type_node
;
6642 builtin_mode_to_type
[V2DImode
][0] = V2DI_type_node
;
6643 builtin_mode_to_type
[V2DImode
][1] = unsigned_V2DI_type_node
;
6644 builtin_mode_to_type
[V2DFmode
][0] = V2DF_type_node
;
6645 builtin_mode_to_type
[V4SImode
][0] = V4SI_type_node
;
6646 builtin_mode_to_type
[V4SImode
][1] = unsigned_V4SI_type_node
;
6647 builtin_mode_to_type
[V4SFmode
][0] = V4SF_type_node
;
6648 builtin_mode_to_type
[V8HImode
][0] = V8HI_type_node
;
6649 builtin_mode_to_type
[V8HImode
][1] = unsigned_V8HI_type_node
;
6650 builtin_mode_to_type
[V16QImode
][0] = V16QI_type_node
;
6651 builtin_mode_to_type
[V16QImode
][1] = unsigned_V16QI_type_node
;
6653 tdecl
= add_builtin_type ("__bool char", bool_char_type_node
);
6654 TYPE_NAME (bool_char_type_node
) = tdecl
;
6656 tdecl
= add_builtin_type ("__bool short", bool_short_type_node
);
6657 TYPE_NAME (bool_short_type_node
) = tdecl
;
6659 tdecl
= add_builtin_type ("__bool int", bool_int_type_node
);
6660 TYPE_NAME (bool_int_type_node
) = tdecl
;
6662 tdecl
= add_builtin_type ("__pixel", pixel_type_node
);
6663 TYPE_NAME (pixel_type_node
) = tdecl
;
6665 bool_V16QI_type_node
= rs6000_vector_type ("__vector __bool char",
6666 bool_char_type_node
, 16);
6667 bool_V8HI_type_node
= rs6000_vector_type ("__vector __bool short",
6668 bool_short_type_node
, 8);
6669 bool_V4SI_type_node
= rs6000_vector_type ("__vector __bool int",
6670 bool_int_type_node
, 4);
6671 bool_V2DI_type_node
= rs6000_vector_type (TARGET_POWERPC64
6672 ? "__vector __bool long"
6673 : "__vector __bool long long",
6674 bool_long_long_type_node
, 2);
6675 pixel_V8HI_type_node
= rs6000_vector_type ("__vector __pixel",
6676 pixel_type_node
, 8);
6678 /* Create Altivec and VSX builtins on machines with at least the
6679 general purpose extensions (970 and newer) to allow the use of
6680 the target attribute. */
6681 if (TARGET_EXTRA_BUILTINS
)
6682 altivec_init_builtins ();
6684 htm_init_builtins ();
6686 if (TARGET_EXTRA_BUILTINS
)
6687 rs6000_common_init_builtins ();
6689 ftype
= builtin_function_type (DFmode
, DFmode
, DFmode
, VOIDmode
,
6690 RS6000_BUILTIN_RECIP
, "__builtin_recipdiv");
6691 def_builtin ("__builtin_recipdiv", ftype
, RS6000_BUILTIN_RECIP
);
6693 ftype
= builtin_function_type (SFmode
, SFmode
, SFmode
, VOIDmode
,
6694 RS6000_BUILTIN_RECIPF
, "__builtin_recipdivf");
6695 def_builtin ("__builtin_recipdivf", ftype
, RS6000_BUILTIN_RECIPF
);
6697 ftype
= builtin_function_type (DFmode
, DFmode
, VOIDmode
, VOIDmode
,
6698 RS6000_BUILTIN_RSQRT
, "__builtin_rsqrt");
6699 def_builtin ("__builtin_rsqrt", ftype
, RS6000_BUILTIN_RSQRT
);
6701 ftype
= builtin_function_type (SFmode
, SFmode
, VOIDmode
, VOIDmode
,
6702 RS6000_BUILTIN_RSQRTF
, "__builtin_rsqrtf");
6703 def_builtin ("__builtin_rsqrtf", ftype
, RS6000_BUILTIN_RSQRTF
);
6705 mode
= (TARGET_64BIT
) ? DImode
: SImode
;
6706 ftype
= builtin_function_type (mode
, mode
, mode
, VOIDmode
,
6707 POWER7_BUILTIN_BPERMD
, "__builtin_bpermd");
6708 def_builtin ("__builtin_bpermd", ftype
, POWER7_BUILTIN_BPERMD
);
6710 ftype
= build_function_type_list (unsigned_intDI_type_node
,
6712 def_builtin ("__builtin_ppc_get_timebase", ftype
, RS6000_BUILTIN_GET_TB
);
6715 ftype
= build_function_type_list (unsigned_intDI_type_node
,
6718 ftype
= build_function_type_list (unsigned_intSI_type_node
,
6720 def_builtin ("__builtin_ppc_mftb", ftype
, RS6000_BUILTIN_MFTB
);
6722 ftype
= build_function_type_list (double_type_node
, NULL_TREE
);
6723 def_builtin ("__builtin_mffs", ftype
, RS6000_BUILTIN_MFFS
);
6725 ftype
= build_function_type_list (double_type_node
, NULL_TREE
);
6726 def_builtin ("__builtin_mffsl", ftype
, RS6000_BUILTIN_MFFSL
);
6728 ftype
= build_function_type_list (void_type_node
,
6731 def_builtin ("__builtin_mtfsb0", ftype
, RS6000_BUILTIN_MTFSB0
);
6733 ftype
= build_function_type_list (void_type_node
,
6736 def_builtin ("__builtin_mtfsb1", ftype
, RS6000_BUILTIN_MTFSB1
);
6738 ftype
= build_function_type_list (void_type_node
,
6741 def_builtin ("__builtin_set_fpscr_rn", ftype
, RS6000_BUILTIN_SET_FPSCR_RN
);
6743 ftype
= build_function_type_list (void_type_node
,
6746 def_builtin ("__builtin_set_fpscr_drn", ftype
, RS6000_BUILTIN_SET_FPSCR_DRN
);
6748 ftype
= build_function_type_list (void_type_node
,
6749 intSI_type_node
, double_type_node
,
6751 def_builtin ("__builtin_mtfsf", ftype
, RS6000_BUILTIN_MTFSF
);
6753 ftype
= build_function_type_list (void_type_node
, NULL_TREE
);
6754 def_builtin ("__builtin_cpu_init", ftype
, RS6000_BUILTIN_CPU_INIT
);
6755 def_builtin ("__builtin_ppc_speculation_barrier", ftype
,
6756 MISC_BUILTIN_SPEC_BARRIER
);
6758 ftype
= build_function_type_list (bool_int_type_node
, const_ptr_type_node
,
6760 def_builtin ("__builtin_cpu_is", ftype
, RS6000_BUILTIN_CPU_IS
);
6761 def_builtin ("__builtin_cpu_supports", ftype
, RS6000_BUILTIN_CPU_SUPPORTS
);
6763 /* AIX libm provides clog as __clog. */
6765 (tdecl
= builtin_decl_explicit (BUILT_IN_CLOG
)) != NULL_TREE
)
6766 set_user_assembler_name (tdecl
, "__clog");
6768 #ifdef SUBTARGET_INIT_BUILTINS
6769 SUBTARGET_INIT_BUILTINS
;
6773 /* Returns the rs6000 builtin decl for CODE. */
6776 rs6000_builtin_decl (unsigned code
, bool initialize_p ATTRIBUTE_UNUSED
)
6778 HOST_WIDE_INT fnmask
;
6780 if (code
>= RS6000_BUILTIN_COUNT
)
6781 return error_mark_node
;
6783 fnmask
= rs6000_builtin_info
[code
].mask
;
6784 if ((fnmask
& rs6000_builtin_mask
) != fnmask
)
6786 rs6000_invalid_builtin ((enum rs6000_builtins
)code
);
6787 return error_mark_node
;
6790 return rs6000_builtin_decls
[code
];
6794 altivec_init_builtins (void)
6796 const struct builtin_description
*d
;
6800 HOST_WIDE_INT builtin_mask
= rs6000_builtin_mask
;
6802 tree pvoid_type_node
= build_pointer_type (void_type_node
);
6804 tree pcvoid_type_node
6805 = build_pointer_type (build_qualified_type (void_type_node
,
6808 tree int_ftype_opaque
6809 = build_function_type_list (integer_type_node
,
6810 opaque_V4SI_type_node
, NULL_TREE
);
6811 tree opaque_ftype_opaque
6812 = build_function_type_list (integer_type_node
, NULL_TREE
);
6813 tree opaque_ftype_opaque_int
6814 = build_function_type_list (opaque_V4SI_type_node
,
6815 opaque_V4SI_type_node
, integer_type_node
, NULL_TREE
);
6816 tree opaque_ftype_opaque_opaque_int
6817 = build_function_type_list (opaque_V4SI_type_node
,
6818 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
6819 integer_type_node
, NULL_TREE
);
6820 tree opaque_ftype_opaque_opaque_opaque
6821 = build_function_type_list (opaque_V4SI_type_node
,
6822 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
6823 opaque_V4SI_type_node
, NULL_TREE
);
6824 tree opaque_ftype_opaque_opaque
6825 = build_function_type_list (opaque_V4SI_type_node
,
6826 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
6828 tree int_ftype_int_opaque_opaque
6829 = build_function_type_list (integer_type_node
,
6830 integer_type_node
, opaque_V4SI_type_node
,
6831 opaque_V4SI_type_node
, NULL_TREE
);
6832 tree int_ftype_int_v4si_v4si
6833 = build_function_type_list (integer_type_node
,
6834 integer_type_node
, V4SI_type_node
,
6835 V4SI_type_node
, NULL_TREE
);
6836 tree int_ftype_int_v2di_v2di
6837 = build_function_type_list (integer_type_node
,
6838 integer_type_node
, V2DI_type_node
,
6839 V2DI_type_node
, NULL_TREE
);
6840 tree void_ftype_v4si
6841 = build_function_type_list (void_type_node
, V4SI_type_node
, NULL_TREE
);
6842 tree v8hi_ftype_void
6843 = build_function_type_list (V8HI_type_node
, NULL_TREE
);
6844 tree void_ftype_void
6845 = build_function_type_list (void_type_node
, NULL_TREE
);
6847 = build_function_type_list (void_type_node
, integer_type_node
, NULL_TREE
);
6849 tree opaque_ftype_long_pcvoid
6850 = build_function_type_list (opaque_V4SI_type_node
,
6851 long_integer_type_node
, pcvoid_type_node
,
6853 tree v16qi_ftype_long_pcvoid
6854 = build_function_type_list (V16QI_type_node
,
6855 long_integer_type_node
, pcvoid_type_node
,
6857 tree v8hi_ftype_long_pcvoid
6858 = build_function_type_list (V8HI_type_node
,
6859 long_integer_type_node
, pcvoid_type_node
,
6861 tree v4si_ftype_long_pcvoid
6862 = build_function_type_list (V4SI_type_node
,
6863 long_integer_type_node
, pcvoid_type_node
,
6865 tree v4sf_ftype_long_pcvoid
6866 = build_function_type_list (V4SF_type_node
,
6867 long_integer_type_node
, pcvoid_type_node
,
6869 tree v2df_ftype_long_pcvoid
6870 = build_function_type_list (V2DF_type_node
,
6871 long_integer_type_node
, pcvoid_type_node
,
6873 tree v2di_ftype_long_pcvoid
6874 = build_function_type_list (V2DI_type_node
,
6875 long_integer_type_node
, pcvoid_type_node
,
6877 tree v1ti_ftype_long_pcvoid
6878 = build_function_type_list (V1TI_type_node
,
6879 long_integer_type_node
, pcvoid_type_node
,
6882 tree void_ftype_opaque_long_pvoid
6883 = build_function_type_list (void_type_node
,
6884 opaque_V4SI_type_node
, long_integer_type_node
,
6885 pvoid_type_node
, NULL_TREE
);
6886 tree void_ftype_v4si_long_pvoid
6887 = build_function_type_list (void_type_node
,
6888 V4SI_type_node
, long_integer_type_node
,
6889 pvoid_type_node
, NULL_TREE
);
6890 tree void_ftype_v16qi_long_pvoid
6891 = build_function_type_list (void_type_node
,
6892 V16QI_type_node
, long_integer_type_node
,
6893 pvoid_type_node
, NULL_TREE
);
6895 tree void_ftype_v16qi_pvoid_long
6896 = build_function_type_list (void_type_node
,
6897 V16QI_type_node
, pvoid_type_node
,
6898 long_integer_type_node
, NULL_TREE
);
6900 tree void_ftype_v8hi_long_pvoid
6901 = build_function_type_list (void_type_node
,
6902 V8HI_type_node
, long_integer_type_node
,
6903 pvoid_type_node
, NULL_TREE
);
6904 tree void_ftype_v4sf_long_pvoid
6905 = build_function_type_list (void_type_node
,
6906 V4SF_type_node
, long_integer_type_node
,
6907 pvoid_type_node
, NULL_TREE
);
6908 tree void_ftype_v2df_long_pvoid
6909 = build_function_type_list (void_type_node
,
6910 V2DF_type_node
, long_integer_type_node
,
6911 pvoid_type_node
, NULL_TREE
);
6912 tree void_ftype_v1ti_long_pvoid
6913 = build_function_type_list (void_type_node
,
6914 V1TI_type_node
, long_integer_type_node
,
6915 pvoid_type_node
, NULL_TREE
);
6916 tree void_ftype_v2di_long_pvoid
6917 = build_function_type_list (void_type_node
,
6918 V2DI_type_node
, long_integer_type_node
,
6919 pvoid_type_node
, NULL_TREE
);
6920 tree int_ftype_int_v8hi_v8hi
6921 = build_function_type_list (integer_type_node
,
6922 integer_type_node
, V8HI_type_node
,
6923 V8HI_type_node
, NULL_TREE
);
6924 tree int_ftype_int_v16qi_v16qi
6925 = build_function_type_list (integer_type_node
,
6926 integer_type_node
, V16QI_type_node
,
6927 V16QI_type_node
, NULL_TREE
);
6928 tree int_ftype_int_v4sf_v4sf
6929 = build_function_type_list (integer_type_node
,
6930 integer_type_node
, V4SF_type_node
,
6931 V4SF_type_node
, NULL_TREE
);
6932 tree int_ftype_int_v2df_v2df
6933 = build_function_type_list (integer_type_node
,
6934 integer_type_node
, V2DF_type_node
,
6935 V2DF_type_node
, NULL_TREE
);
6936 tree v2di_ftype_v2di
6937 = build_function_type_list (V2DI_type_node
, V2DI_type_node
, NULL_TREE
);
6938 tree v4si_ftype_v4si
6939 = build_function_type_list (V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
6940 tree v8hi_ftype_v8hi
6941 = build_function_type_list (V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
6942 tree v16qi_ftype_v16qi
6943 = build_function_type_list (V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
6944 tree v4sf_ftype_v4sf
6945 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
6946 tree v2df_ftype_v2df
6947 = build_function_type_list (V2DF_type_node
, V2DF_type_node
, NULL_TREE
);
6948 tree void_ftype_pcvoid_int_int
6949 = build_function_type_list (void_type_node
,
6950 pcvoid_type_node
, integer_type_node
,
6951 integer_type_node
, NULL_TREE
);
6953 def_builtin ("__builtin_altivec_mtvscr", void_ftype_v4si
, ALTIVEC_BUILTIN_MTVSCR
);
6954 def_builtin ("__builtin_altivec_mfvscr", v8hi_ftype_void
, ALTIVEC_BUILTIN_MFVSCR
);
6955 def_builtin ("__builtin_altivec_dssall", void_ftype_void
, ALTIVEC_BUILTIN_DSSALL
);
6956 def_builtin ("__builtin_altivec_dss", void_ftype_int
, ALTIVEC_BUILTIN_DSS
);
6957 def_builtin ("__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSL
);
6958 def_builtin ("__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSR
);
6959 def_builtin ("__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEBX
);
6960 def_builtin ("__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEHX
);
6961 def_builtin ("__builtin_altivec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEWX
);
6962 def_builtin ("__builtin_altivec_lvxl", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVXL
);
6963 def_builtin ("__builtin_altivec_lvxl_v2df", v2df_ftype_long_pcvoid
,
6964 ALTIVEC_BUILTIN_LVXL_V2DF
);
6965 def_builtin ("__builtin_altivec_lvxl_v2di", v2di_ftype_long_pcvoid
,
6966 ALTIVEC_BUILTIN_LVXL_V2DI
);
6967 def_builtin ("__builtin_altivec_lvxl_v4sf", v4sf_ftype_long_pcvoid
,
6968 ALTIVEC_BUILTIN_LVXL_V4SF
);
6969 def_builtin ("__builtin_altivec_lvxl_v4si", v4si_ftype_long_pcvoid
,
6970 ALTIVEC_BUILTIN_LVXL_V4SI
);
6971 def_builtin ("__builtin_altivec_lvxl_v8hi", v8hi_ftype_long_pcvoid
,
6972 ALTIVEC_BUILTIN_LVXL_V8HI
);
6973 def_builtin ("__builtin_altivec_lvxl_v16qi", v16qi_ftype_long_pcvoid
,
6974 ALTIVEC_BUILTIN_LVXL_V16QI
);
6975 def_builtin ("__builtin_altivec_lvx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVX
);
6976 def_builtin ("__builtin_altivec_lvx_v1ti", v1ti_ftype_long_pcvoid
,
6977 ALTIVEC_BUILTIN_LVX_V1TI
);
6978 def_builtin ("__builtin_altivec_lvx_v2df", v2df_ftype_long_pcvoid
,
6979 ALTIVEC_BUILTIN_LVX_V2DF
);
6980 def_builtin ("__builtin_altivec_lvx_v2di", v2di_ftype_long_pcvoid
,
6981 ALTIVEC_BUILTIN_LVX_V2DI
);
6982 def_builtin ("__builtin_altivec_lvx_v4sf", v4sf_ftype_long_pcvoid
,
6983 ALTIVEC_BUILTIN_LVX_V4SF
);
6984 def_builtin ("__builtin_altivec_lvx_v4si", v4si_ftype_long_pcvoid
,
6985 ALTIVEC_BUILTIN_LVX_V4SI
);
6986 def_builtin ("__builtin_altivec_lvx_v8hi", v8hi_ftype_long_pcvoid
,
6987 ALTIVEC_BUILTIN_LVX_V8HI
);
6988 def_builtin ("__builtin_altivec_lvx_v16qi", v16qi_ftype_long_pcvoid
,
6989 ALTIVEC_BUILTIN_LVX_V16QI
);
6990 def_builtin ("__builtin_altivec_stvx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVX
);
6991 def_builtin ("__builtin_altivec_stvx_v2df", void_ftype_v2df_long_pvoid
,
6992 ALTIVEC_BUILTIN_STVX_V2DF
);
6993 def_builtin ("__builtin_altivec_stvx_v2di", void_ftype_v2di_long_pvoid
,
6994 ALTIVEC_BUILTIN_STVX_V2DI
);
6995 def_builtin ("__builtin_altivec_stvx_v4sf", void_ftype_v4sf_long_pvoid
,
6996 ALTIVEC_BUILTIN_STVX_V4SF
);
6997 def_builtin ("__builtin_altivec_stvx_v4si", void_ftype_v4si_long_pvoid
,
6998 ALTIVEC_BUILTIN_STVX_V4SI
);
6999 def_builtin ("__builtin_altivec_stvx_v8hi", void_ftype_v8hi_long_pvoid
,
7000 ALTIVEC_BUILTIN_STVX_V8HI
);
7001 def_builtin ("__builtin_altivec_stvx_v16qi", void_ftype_v16qi_long_pvoid
,
7002 ALTIVEC_BUILTIN_STVX_V16QI
);
7003 def_builtin ("__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVEWX
);
7004 def_builtin ("__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVXL
);
7005 def_builtin ("__builtin_altivec_stvxl_v2df", void_ftype_v2df_long_pvoid
,
7006 ALTIVEC_BUILTIN_STVXL_V2DF
);
7007 def_builtin ("__builtin_altivec_stvxl_v2di", void_ftype_v2di_long_pvoid
,
7008 ALTIVEC_BUILTIN_STVXL_V2DI
);
7009 def_builtin ("__builtin_altivec_stvxl_v4sf", void_ftype_v4sf_long_pvoid
,
7010 ALTIVEC_BUILTIN_STVXL_V4SF
);
7011 def_builtin ("__builtin_altivec_stvxl_v4si", void_ftype_v4si_long_pvoid
,
7012 ALTIVEC_BUILTIN_STVXL_V4SI
);
7013 def_builtin ("__builtin_altivec_stvxl_v8hi", void_ftype_v8hi_long_pvoid
,
7014 ALTIVEC_BUILTIN_STVXL_V8HI
);
7015 def_builtin ("__builtin_altivec_stvxl_v16qi", void_ftype_v16qi_long_pvoid
,
7016 ALTIVEC_BUILTIN_STVXL_V16QI
);
7017 def_builtin ("__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVEBX
);
7018 def_builtin ("__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid
, ALTIVEC_BUILTIN_STVEHX
);
7019 def_builtin ("__builtin_vec_ld", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LD
);
7020 def_builtin ("__builtin_vec_lde", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDE
);
7021 def_builtin ("__builtin_vec_ldl", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDL
);
7022 def_builtin ("__builtin_vec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSL
);
7023 def_builtin ("__builtin_vec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSR
);
7024 def_builtin ("__builtin_vec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEBX
);
7025 def_builtin ("__builtin_vec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEHX
);
7026 def_builtin ("__builtin_vec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEWX
);
7027 def_builtin ("__builtin_vec_st", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_ST
);
7028 def_builtin ("__builtin_vec_ste", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STE
);
7029 def_builtin ("__builtin_vec_stl", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STL
);
7030 def_builtin ("__builtin_vec_stvewx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEWX
);
7031 def_builtin ("__builtin_vec_stvebx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEBX
);
7032 def_builtin ("__builtin_vec_stvehx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEHX
);
7034 def_builtin ("__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid
,
7035 VSX_BUILTIN_LXVD2X_V2DF
);
7036 def_builtin ("__builtin_vsx_lxvd2x_v2di", v2di_ftype_long_pcvoid
,
7037 VSX_BUILTIN_LXVD2X_V2DI
);
7038 def_builtin ("__builtin_vsx_lxvw4x_v4sf", v4sf_ftype_long_pcvoid
,
7039 VSX_BUILTIN_LXVW4X_V4SF
);
7040 def_builtin ("__builtin_vsx_lxvw4x_v4si", v4si_ftype_long_pcvoid
,
7041 VSX_BUILTIN_LXVW4X_V4SI
);
7042 def_builtin ("__builtin_vsx_lxvw4x_v8hi", v8hi_ftype_long_pcvoid
,
7043 VSX_BUILTIN_LXVW4X_V8HI
);
7044 def_builtin ("__builtin_vsx_lxvw4x_v16qi", v16qi_ftype_long_pcvoid
,
7045 VSX_BUILTIN_LXVW4X_V16QI
);
7046 def_builtin ("__builtin_vsx_stxvd2x_v2df", void_ftype_v2df_long_pvoid
,
7047 VSX_BUILTIN_STXVD2X_V2DF
);
7048 def_builtin ("__builtin_vsx_stxvd2x_v2di", void_ftype_v2di_long_pvoid
,
7049 VSX_BUILTIN_STXVD2X_V2DI
);
7050 def_builtin ("__builtin_vsx_stxvw4x_v4sf", void_ftype_v4sf_long_pvoid
,
7051 VSX_BUILTIN_STXVW4X_V4SF
);
7052 def_builtin ("__builtin_vsx_stxvw4x_v4si", void_ftype_v4si_long_pvoid
,
7053 VSX_BUILTIN_STXVW4X_V4SI
);
7054 def_builtin ("__builtin_vsx_stxvw4x_v8hi", void_ftype_v8hi_long_pvoid
,
7055 VSX_BUILTIN_STXVW4X_V8HI
);
7056 def_builtin ("__builtin_vsx_stxvw4x_v16qi", void_ftype_v16qi_long_pvoid
,
7057 VSX_BUILTIN_STXVW4X_V16QI
);
7059 def_builtin ("__builtin_vsx_ld_elemrev_v2df", v2df_ftype_long_pcvoid
,
7060 VSX_BUILTIN_LD_ELEMREV_V2DF
);
7061 def_builtin ("__builtin_vsx_ld_elemrev_v2di", v2di_ftype_long_pcvoid
,
7062 VSX_BUILTIN_LD_ELEMREV_V2DI
);
7063 def_builtin ("__builtin_vsx_ld_elemrev_v4sf", v4sf_ftype_long_pcvoid
,
7064 VSX_BUILTIN_LD_ELEMREV_V4SF
);
7065 def_builtin ("__builtin_vsx_ld_elemrev_v4si", v4si_ftype_long_pcvoid
,
7066 VSX_BUILTIN_LD_ELEMREV_V4SI
);
7067 def_builtin ("__builtin_vsx_ld_elemrev_v8hi", v8hi_ftype_long_pcvoid
,
7068 VSX_BUILTIN_LD_ELEMREV_V8HI
);
7069 def_builtin ("__builtin_vsx_ld_elemrev_v16qi", v16qi_ftype_long_pcvoid
,
7070 VSX_BUILTIN_LD_ELEMREV_V16QI
);
7071 def_builtin ("__builtin_vsx_st_elemrev_v2df", void_ftype_v2df_long_pvoid
,
7072 VSX_BUILTIN_ST_ELEMREV_V2DF
);
7073 def_builtin ("__builtin_vsx_st_elemrev_v1ti", void_ftype_v1ti_long_pvoid
,
7074 VSX_BUILTIN_ST_ELEMREV_V1TI
);
7075 def_builtin ("__builtin_vsx_st_elemrev_v2di", void_ftype_v2di_long_pvoid
,
7076 VSX_BUILTIN_ST_ELEMREV_V2DI
);
7077 def_builtin ("__builtin_vsx_st_elemrev_v4sf", void_ftype_v4sf_long_pvoid
,
7078 VSX_BUILTIN_ST_ELEMREV_V4SF
);
7079 def_builtin ("__builtin_vsx_st_elemrev_v4si", void_ftype_v4si_long_pvoid
,
7080 VSX_BUILTIN_ST_ELEMREV_V4SI
);
7081 def_builtin ("__builtin_vsx_st_elemrev_v8hi", void_ftype_v8hi_long_pvoid
,
7082 VSX_BUILTIN_ST_ELEMREV_V8HI
);
7083 def_builtin ("__builtin_vsx_st_elemrev_v16qi", void_ftype_v16qi_long_pvoid
,
7084 VSX_BUILTIN_ST_ELEMREV_V16QI
);
7086 def_builtin ("__builtin_vec_vsx_ld", opaque_ftype_long_pcvoid
,
7087 VSX_BUILTIN_VEC_LD
);
7088 def_builtin ("__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid
,
7089 VSX_BUILTIN_VEC_ST
);
7090 def_builtin ("__builtin_vec_xl", opaque_ftype_long_pcvoid
,
7091 VSX_BUILTIN_VEC_XL
);
7092 def_builtin ("__builtin_vec_xl_be", opaque_ftype_long_pcvoid
,
7093 VSX_BUILTIN_VEC_XL_BE
);
7094 def_builtin ("__builtin_vec_xst", void_ftype_opaque_long_pvoid
,
7095 VSX_BUILTIN_VEC_XST
);
7096 def_builtin ("__builtin_vec_xst_be", void_ftype_opaque_long_pvoid
,
7097 VSX_BUILTIN_VEC_XST_BE
);
7099 def_builtin ("__builtin_vec_step", int_ftype_opaque
, ALTIVEC_BUILTIN_VEC_STEP
);
7100 def_builtin ("__builtin_vec_splats", opaque_ftype_opaque
, ALTIVEC_BUILTIN_VEC_SPLATS
);
7101 def_builtin ("__builtin_vec_promote", opaque_ftype_opaque
, ALTIVEC_BUILTIN_VEC_PROMOTE
);
7103 def_builtin ("__builtin_vec_sld", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_SLD
);
7104 def_builtin ("__builtin_vec_splat", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_SPLAT
);
7105 def_builtin ("__builtin_vec_extract", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_EXTRACT
);
7106 def_builtin ("__builtin_vec_insert", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_INSERT
);
7107 def_builtin ("__builtin_vec_vspltw", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTW
);
7108 def_builtin ("__builtin_vec_vsplth", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTH
);
7109 def_builtin ("__builtin_vec_vspltb", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTB
);
7110 def_builtin ("__builtin_vec_ctf", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTF
);
7111 def_builtin ("__builtin_vec_vcfsx", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFSX
);
7112 def_builtin ("__builtin_vec_vcfux", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFUX
);
7113 def_builtin ("__builtin_vec_cts", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTS
);
7114 def_builtin ("__builtin_vec_ctu", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTU
);
7116 def_builtin ("__builtin_vec_adde", opaque_ftype_opaque_opaque_opaque
,
7117 ALTIVEC_BUILTIN_VEC_ADDE
);
7118 def_builtin ("__builtin_vec_addec", opaque_ftype_opaque_opaque_opaque
,
7119 ALTIVEC_BUILTIN_VEC_ADDEC
);
7120 def_builtin ("__builtin_vec_cmpne", opaque_ftype_opaque_opaque
,
7121 ALTIVEC_BUILTIN_VEC_CMPNE
);
7122 def_builtin ("__builtin_vec_mul", opaque_ftype_opaque_opaque
,
7123 ALTIVEC_BUILTIN_VEC_MUL
);
7124 def_builtin ("__builtin_vec_sube", opaque_ftype_opaque_opaque_opaque
,
7125 ALTIVEC_BUILTIN_VEC_SUBE
);
7126 def_builtin ("__builtin_vec_subec", opaque_ftype_opaque_opaque_opaque
,
7127 ALTIVEC_BUILTIN_VEC_SUBEC
);
7129 /* Cell builtins. */
7130 def_builtin ("__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVLX
);
7131 def_builtin ("__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVLXL
);
7132 def_builtin ("__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVRX
);
7133 def_builtin ("__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVRXL
);
7135 def_builtin ("__builtin_vec_lvlx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVLX
);
7136 def_builtin ("__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVLXL
);
7137 def_builtin ("__builtin_vec_lvrx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVRX
);
7138 def_builtin ("__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVRXL
);
7140 def_builtin ("__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVLX
);
7141 def_builtin ("__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVLXL
);
7142 def_builtin ("__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVRX
);
7143 def_builtin ("__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVRXL
);
7145 def_builtin ("__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVLX
);
7146 def_builtin ("__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVLXL
);
7147 def_builtin ("__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVRX
);
7148 def_builtin ("__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVRXL
);
7150 if (TARGET_P9_VECTOR
)
7152 def_builtin ("__builtin_altivec_stxvl", void_ftype_v16qi_pvoid_long
,
7154 def_builtin ("__builtin_xst_len_r", void_ftype_v16qi_pvoid_long
,
7155 P9V_BUILTIN_XST_LEN_R
);
7158 /* Add the DST variants. */
7160 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
7162 HOST_WIDE_INT mask
= d
->mask
;
7164 /* It is expected that these dst built-in functions may have
7165 d->icode equal to CODE_FOR_nothing. */
7166 if ((mask
& builtin_mask
) != mask
)
7168 if (TARGET_DEBUG_BUILTIN
)
7169 fprintf (stderr
, "altivec_init_builtins, skip dst %s\n",
7173 def_builtin (d
->name
, void_ftype_pcvoid_int_int
, d
->code
);
7176 /* Initialize the predicates. */
7177 d
= bdesc_altivec_preds
;
7178 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, d
++)
7182 HOST_WIDE_INT mask
= d
->mask
;
7184 if ((mask
& builtin_mask
) != mask
)
7186 if (TARGET_DEBUG_BUILTIN
)
7187 fprintf (stderr
, "altivec_init_builtins, skip predicate %s\n",
7192 if (rs6000_overloaded_builtin_p (d
->code
))
7196 /* Cannot define builtin if the instruction is disabled. */
7197 gcc_assert (d
->icode
!= CODE_FOR_nothing
);
7198 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
7204 type
= int_ftype_int_opaque_opaque
;
7207 type
= int_ftype_int_v2di_v2di
;
7210 type
= int_ftype_int_v4si_v4si
;
7213 type
= int_ftype_int_v8hi_v8hi
;
7216 type
= int_ftype_int_v16qi_v16qi
;
7219 type
= int_ftype_int_v4sf_v4sf
;
7222 type
= int_ftype_int_v2df_v2df
;
7228 def_builtin (d
->name
, type
, d
->code
);
7231 /* Initialize the abs* operators. */
7233 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
7237 HOST_WIDE_INT mask
= d
->mask
;
7239 if ((mask
& builtin_mask
) != mask
)
7241 if (TARGET_DEBUG_BUILTIN
)
7242 fprintf (stderr
, "altivec_init_builtins, skip abs %s\n",
7247 /* Cannot define builtin if the instruction is disabled. */
7248 gcc_assert (d
->icode
!= CODE_FOR_nothing
);
7249 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
7254 type
= v2di_ftype_v2di
;
7257 type
= v4si_ftype_v4si
;
7260 type
= v8hi_ftype_v8hi
;
7263 type
= v16qi_ftype_v16qi
;
7266 type
= v4sf_ftype_v4sf
;
7269 type
= v2df_ftype_v2df
;
7275 def_builtin (d
->name
, type
, d
->code
);
7278 /* Initialize target builtin that implements
7279 targetm.vectorize.builtin_mask_for_load. */
7281 decl
= add_builtin_function ("__builtin_altivec_mask_for_load",
7282 v16qi_ftype_long_pcvoid
,
7283 ALTIVEC_BUILTIN_MASK_FOR_LOAD
,
7284 BUILT_IN_MD
, NULL
, NULL_TREE
);
7285 TREE_READONLY (decl
) = 1;
7286 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
7287 altivec_builtin_mask_for_load
= decl
;
7289 /* Access to the vec_init patterns. */
7290 ftype
= build_function_type_list (V4SI_type_node
, integer_type_node
,
7291 integer_type_node
, integer_type_node
,
7292 integer_type_node
, NULL_TREE
);
7293 def_builtin ("__builtin_vec_init_v4si", ftype
, ALTIVEC_BUILTIN_VEC_INIT_V4SI
);
7295 ftype
= build_function_type_list (V8HI_type_node
, short_integer_type_node
,
7296 short_integer_type_node
,
7297 short_integer_type_node
,
7298 short_integer_type_node
,
7299 short_integer_type_node
,
7300 short_integer_type_node
,
7301 short_integer_type_node
,
7302 short_integer_type_node
, NULL_TREE
);
7303 def_builtin ("__builtin_vec_init_v8hi", ftype
, ALTIVEC_BUILTIN_VEC_INIT_V8HI
);
7305 ftype
= build_function_type_list (V16QI_type_node
, char_type_node
,
7306 char_type_node
, char_type_node
,
7307 char_type_node
, char_type_node
,
7308 char_type_node
, char_type_node
,
7309 char_type_node
, char_type_node
,
7310 char_type_node
, char_type_node
,
7311 char_type_node
, char_type_node
,
7312 char_type_node
, char_type_node
,
7313 char_type_node
, NULL_TREE
);
7314 def_builtin ("__builtin_vec_init_v16qi", ftype
,
7315 ALTIVEC_BUILTIN_VEC_INIT_V16QI
);
7317 ftype
= build_function_type_list (V4SF_type_node
, float_type_node
,
7318 float_type_node
, float_type_node
,
7319 float_type_node
, NULL_TREE
);
7320 def_builtin ("__builtin_vec_init_v4sf", ftype
, ALTIVEC_BUILTIN_VEC_INIT_V4SF
);
7323 ftype
= build_function_type_list (V2DF_type_node
, double_type_node
,
7324 double_type_node
, NULL_TREE
);
7325 def_builtin ("__builtin_vec_init_v2df", ftype
, VSX_BUILTIN_VEC_INIT_V2DF
);
7327 ftype
= build_function_type_list (V2DI_type_node
, intDI_type_node
,
7328 intDI_type_node
, NULL_TREE
);
7329 def_builtin ("__builtin_vec_init_v2di", ftype
, VSX_BUILTIN_VEC_INIT_V2DI
);
7331 /* Access to the vec_set patterns. */
7332 ftype
= build_function_type_list (V4SI_type_node
, V4SI_type_node
,
7334 integer_type_node
, NULL_TREE
);
7335 def_builtin ("__builtin_vec_set_v4si", ftype
, ALTIVEC_BUILTIN_VEC_SET_V4SI
);
7337 ftype
= build_function_type_list (V8HI_type_node
, V8HI_type_node
,
7339 integer_type_node
, NULL_TREE
);
7340 def_builtin ("__builtin_vec_set_v8hi", ftype
, ALTIVEC_BUILTIN_VEC_SET_V8HI
);
7342 ftype
= build_function_type_list (V16QI_type_node
, V16QI_type_node
,
7344 integer_type_node
, NULL_TREE
);
7345 def_builtin ("__builtin_vec_set_v16qi", ftype
, ALTIVEC_BUILTIN_VEC_SET_V16QI
);
7347 ftype
= build_function_type_list (V4SF_type_node
, V4SF_type_node
,
7349 integer_type_node
, NULL_TREE
);
7350 def_builtin ("__builtin_vec_set_v4sf", ftype
, ALTIVEC_BUILTIN_VEC_SET_V4SF
);
7352 ftype
= build_function_type_list (V2DF_type_node
, V2DF_type_node
,
7354 integer_type_node
, NULL_TREE
);
7355 def_builtin ("__builtin_vec_set_v2df", ftype
, VSX_BUILTIN_VEC_SET_V2DF
);
7357 ftype
= build_function_type_list (V2DI_type_node
, V2DI_type_node
,
7359 integer_type_node
, NULL_TREE
);
7360 def_builtin ("__builtin_vec_set_v2di", ftype
, VSX_BUILTIN_VEC_SET_V2DI
);
7362 /* Access to the vec_extract patterns. */
7363 ftype
= build_function_type_list (intSI_type_node
, V4SI_type_node
,
7364 integer_type_node
, NULL_TREE
);
7365 def_builtin ("__builtin_vec_ext_v4si", ftype
, ALTIVEC_BUILTIN_VEC_EXT_V4SI
);
7367 ftype
= build_function_type_list (intHI_type_node
, V8HI_type_node
,
7368 integer_type_node
, NULL_TREE
);
7369 def_builtin ("__builtin_vec_ext_v8hi", ftype
, ALTIVEC_BUILTIN_VEC_EXT_V8HI
);
7371 ftype
= build_function_type_list (intQI_type_node
, V16QI_type_node
,
7372 integer_type_node
, NULL_TREE
);
7373 def_builtin ("__builtin_vec_ext_v16qi", ftype
, ALTIVEC_BUILTIN_VEC_EXT_V16QI
);
7375 ftype
= build_function_type_list (float_type_node
, V4SF_type_node
,
7376 integer_type_node
, NULL_TREE
);
7377 def_builtin ("__builtin_vec_ext_v4sf", ftype
, ALTIVEC_BUILTIN_VEC_EXT_V4SF
);
7379 ftype
= build_function_type_list (double_type_node
, V2DF_type_node
,
7380 integer_type_node
, NULL_TREE
);
7381 def_builtin ("__builtin_vec_ext_v2df", ftype
, VSX_BUILTIN_VEC_EXT_V2DF
);
7383 ftype
= build_function_type_list (intDI_type_node
, V2DI_type_node
,
7384 integer_type_node
, NULL_TREE
);
7385 def_builtin ("__builtin_vec_ext_v2di", ftype
, VSX_BUILTIN_VEC_EXT_V2DI
);
7390 tree v1ti_ftype_long_pcvoid
7391 = build_function_type_list (V1TI_type_node
,
7392 long_integer_type_node
, pcvoid_type_node
,
7394 tree void_ftype_v1ti_long_pvoid
7395 = build_function_type_list (void_type_node
,
7396 V1TI_type_node
, long_integer_type_node
,
7397 pvoid_type_node
, NULL_TREE
);
7398 def_builtin ("__builtin_vsx_ld_elemrev_v1ti", v1ti_ftype_long_pcvoid
,
7399 VSX_BUILTIN_LD_ELEMREV_V1TI
);
7400 def_builtin ("__builtin_vsx_lxvd2x_v1ti", v1ti_ftype_long_pcvoid
,
7401 VSX_BUILTIN_LXVD2X_V1TI
);
7402 def_builtin ("__builtin_vsx_stxvd2x_v1ti", void_ftype_v1ti_long_pvoid
,
7403 VSX_BUILTIN_STXVD2X_V1TI
);
7404 ftype
= build_function_type_list (V1TI_type_node
, intTI_type_node
,
7405 NULL_TREE
, NULL_TREE
);
7406 def_builtin ("__builtin_vec_init_v1ti", ftype
, VSX_BUILTIN_VEC_INIT_V1TI
);
7407 ftype
= build_function_type_list (V1TI_type_node
, V1TI_type_node
,
7409 integer_type_node
, NULL_TREE
);
7410 def_builtin ("__builtin_vec_set_v1ti", ftype
, VSX_BUILTIN_VEC_SET_V1TI
);
7411 ftype
= build_function_type_list (intTI_type_node
, V1TI_type_node
,
7412 integer_type_node
, NULL_TREE
);
7413 def_builtin ("__builtin_vec_ext_v1ti", ftype
, VSX_BUILTIN_VEC_EXT_V1TI
);
7419 htm_init_builtins (void)
7421 HOST_WIDE_INT builtin_mask
= rs6000_builtin_mask
;
7422 const struct builtin_description
*d
;
7426 for (i
= 0; i
< ARRAY_SIZE (bdesc_htm
); i
++, d
++)
7428 tree op
[MAX_HTM_OPERANDS
], type
;
7429 HOST_WIDE_INT mask
= d
->mask
;
7430 unsigned attr
= rs6000_builtin_info
[d
->code
].attr
;
7431 bool void_func
= (attr
& RS6000_BTC_VOID
);
7432 int attr_args
= (attr
& RS6000_BTC_TYPE_MASK
);
7438 /* It is expected that these htm built-in functions may have
7439 d->icode equal to CODE_FOR_nothing. */
7441 if (TARGET_32BIT
&& TARGET_POWERPC64
)
7442 gpr_type_node
= long_long_unsigned_type_node
;
7444 gpr_type_node
= long_unsigned_type_node
;
7446 if (attr
& RS6000_BTC_SPR
)
7448 rettype
= gpr_type_node
;
7449 argtype
= gpr_type_node
;
7451 else if (d
->code
== HTM_BUILTIN_TABORTDC
7452 || d
->code
== HTM_BUILTIN_TABORTDCI
)
7454 rettype
= unsigned_type_node
;
7455 argtype
= gpr_type_node
;
7459 rettype
= unsigned_type_node
;
7460 argtype
= unsigned_type_node
;
7463 if ((mask
& builtin_mask
) != mask
)
7465 if (TARGET_DEBUG_BUILTIN
)
7466 fprintf (stderr
, "htm_builtin, skip binary %s\n", d
->name
);
7472 if (TARGET_DEBUG_BUILTIN
)
7473 fprintf (stderr
, "htm_builtin, bdesc_htm[%ld] no name\n",
7478 op
[nopnds
++] = (void_func
) ? void_type_node
: rettype
;
7480 if (attr_args
== RS6000_BTC_UNARY
)
7481 op
[nopnds
++] = argtype
;
7482 else if (attr_args
== RS6000_BTC_BINARY
)
7484 op
[nopnds
++] = argtype
;
7485 op
[nopnds
++] = argtype
;
7487 else if (attr_args
== RS6000_BTC_TERNARY
)
7489 op
[nopnds
++] = argtype
;
7490 op
[nopnds
++] = argtype
;
7491 op
[nopnds
++] = argtype
;
7497 type
= build_function_type_list (op
[0], NULL_TREE
);
7500 type
= build_function_type_list (op
[0], op
[1], NULL_TREE
);
7503 type
= build_function_type_list (op
[0], op
[1], op
[2], NULL_TREE
);
7506 type
= build_function_type_list (op
[0], op
[1], op
[2], op
[3],
7513 def_builtin (d
->name
, type
, d
->code
);
7517 /* Map types for builtin functions with an explicit return type and up to 3
7518 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
7521 builtin_function_type (machine_mode mode_ret
, machine_mode mode_arg0
,
7522 machine_mode mode_arg1
, machine_mode mode_arg2
,
7523 enum rs6000_builtins builtin
, const char *name
)
7525 struct builtin_hash_struct h
;
7526 struct builtin_hash_struct
*h2
;
7529 tree ret_type
= NULL_TREE
;
7530 tree arg_type
[3] = { NULL_TREE
, NULL_TREE
, NULL_TREE
};
7532 /* Create builtin_hash_table. */
7533 if (builtin_hash_table
== NULL
)
7534 builtin_hash_table
= hash_table
<builtin_hasher
>::create_ggc (1500);
7537 h
.mode
[0] = mode_ret
;
7538 h
.mode
[1] = mode_arg0
;
7539 h
.mode
[2] = mode_arg1
;
7540 h
.mode
[3] = mode_arg2
;
7546 /* If the builtin is a type that produces unsigned results or takes unsigned
7547 arguments, and it is returned as a decl for the vectorizer (such as
7548 widening multiplies, permute), make sure the arguments and return value
7549 are type correct. */
7552 /* unsigned 1 argument functions. */
7553 case CRYPTO_BUILTIN_VSBOX
:
7554 case CRYPTO_BUILTIN_VSBOX_BE
:
7555 case P8V_BUILTIN_VGBBD
:
7556 case MISC_BUILTIN_CDTBCD
:
7557 case MISC_BUILTIN_CBCDTD
:
7562 /* unsigned 2 argument functions. */
7563 case ALTIVEC_BUILTIN_VMULEUB
:
7564 case ALTIVEC_BUILTIN_VMULEUH
:
7565 case P8V_BUILTIN_VMULEUW
:
7566 case ALTIVEC_BUILTIN_VMULOUB
:
7567 case ALTIVEC_BUILTIN_VMULOUH
:
7568 case P8V_BUILTIN_VMULOUW
:
7569 case CRYPTO_BUILTIN_VCIPHER
:
7570 case CRYPTO_BUILTIN_VCIPHER_BE
:
7571 case CRYPTO_BUILTIN_VCIPHERLAST
:
7572 case CRYPTO_BUILTIN_VCIPHERLAST_BE
:
7573 case CRYPTO_BUILTIN_VNCIPHER
:
7574 case CRYPTO_BUILTIN_VNCIPHER_BE
:
7575 case CRYPTO_BUILTIN_VNCIPHERLAST
:
7576 case CRYPTO_BUILTIN_VNCIPHERLAST_BE
:
7577 case CRYPTO_BUILTIN_VPMSUMB
:
7578 case CRYPTO_BUILTIN_VPMSUMH
:
7579 case CRYPTO_BUILTIN_VPMSUMW
:
7580 case CRYPTO_BUILTIN_VPMSUMD
:
7581 case CRYPTO_BUILTIN_VPMSUM
:
7582 case MISC_BUILTIN_ADDG6S
:
7583 case MISC_BUILTIN_DIVWEU
:
7584 case MISC_BUILTIN_DIVDEU
:
7585 case VSX_BUILTIN_UDIV_V2DI
:
7586 case ALTIVEC_BUILTIN_VMAXUB
:
7587 case ALTIVEC_BUILTIN_VMINUB
:
7588 case ALTIVEC_BUILTIN_VMAXUH
:
7589 case ALTIVEC_BUILTIN_VMINUH
:
7590 case ALTIVEC_BUILTIN_VMAXUW
:
7591 case ALTIVEC_BUILTIN_VMINUW
:
7592 case P8V_BUILTIN_VMAXUD
:
7593 case P8V_BUILTIN_VMINUD
:
7599 /* unsigned 3 argument functions. */
7600 case ALTIVEC_BUILTIN_VPERM_16QI_UNS
:
7601 case ALTIVEC_BUILTIN_VPERM_8HI_UNS
:
7602 case ALTIVEC_BUILTIN_VPERM_4SI_UNS
:
7603 case ALTIVEC_BUILTIN_VPERM_2DI_UNS
:
7604 case ALTIVEC_BUILTIN_VSEL_16QI_UNS
:
7605 case ALTIVEC_BUILTIN_VSEL_8HI_UNS
:
7606 case ALTIVEC_BUILTIN_VSEL_4SI_UNS
:
7607 case ALTIVEC_BUILTIN_VSEL_2DI_UNS
:
7608 case VSX_BUILTIN_VPERM_16QI_UNS
:
7609 case VSX_BUILTIN_VPERM_8HI_UNS
:
7610 case VSX_BUILTIN_VPERM_4SI_UNS
:
7611 case VSX_BUILTIN_VPERM_2DI_UNS
:
7612 case VSX_BUILTIN_XXSEL_16QI_UNS
:
7613 case VSX_BUILTIN_XXSEL_8HI_UNS
:
7614 case VSX_BUILTIN_XXSEL_4SI_UNS
:
7615 case VSX_BUILTIN_XXSEL_2DI_UNS
:
7616 case CRYPTO_BUILTIN_VPERMXOR
:
7617 case CRYPTO_BUILTIN_VPERMXOR_V2DI
:
7618 case CRYPTO_BUILTIN_VPERMXOR_V4SI
:
7619 case CRYPTO_BUILTIN_VPERMXOR_V8HI
:
7620 case CRYPTO_BUILTIN_VPERMXOR_V16QI
:
7621 case CRYPTO_BUILTIN_VSHASIGMAW
:
7622 case CRYPTO_BUILTIN_VSHASIGMAD
:
7623 case CRYPTO_BUILTIN_VSHASIGMA
:
7630 /* signed permute functions with unsigned char mask. */
7631 case ALTIVEC_BUILTIN_VPERM_16QI
:
7632 case ALTIVEC_BUILTIN_VPERM_8HI
:
7633 case ALTIVEC_BUILTIN_VPERM_4SI
:
7634 case ALTIVEC_BUILTIN_VPERM_4SF
:
7635 case ALTIVEC_BUILTIN_VPERM_2DI
:
7636 case ALTIVEC_BUILTIN_VPERM_2DF
:
7637 case VSX_BUILTIN_VPERM_16QI
:
7638 case VSX_BUILTIN_VPERM_8HI
:
7639 case VSX_BUILTIN_VPERM_4SI
:
7640 case VSX_BUILTIN_VPERM_4SF
:
7641 case VSX_BUILTIN_VPERM_2DI
:
7642 case VSX_BUILTIN_VPERM_2DF
:
7646 /* unsigned args, signed return. */
7647 case VSX_BUILTIN_XVCVUXDSP
:
7648 case VSX_BUILTIN_XVCVUXDDP_UNS
:
7649 case ALTIVEC_BUILTIN_UNSFLOAT_V4SI_V4SF
:
7653 /* signed args, unsigned return. */
7654 case VSX_BUILTIN_XVCVDPUXDS_UNS
:
7655 case ALTIVEC_BUILTIN_FIXUNS_V4SF_V4SI
:
7656 case MISC_BUILTIN_UNPACK_TD
:
7657 case MISC_BUILTIN_UNPACK_V1TI
:
7661 /* unsigned arguments, bool return (compares). */
7662 case ALTIVEC_BUILTIN_VCMPEQUB
:
7663 case ALTIVEC_BUILTIN_VCMPEQUH
:
7664 case ALTIVEC_BUILTIN_VCMPEQUW
:
7665 case P8V_BUILTIN_VCMPEQUD
:
7666 case VSX_BUILTIN_CMPGE_U16QI
:
7667 case VSX_BUILTIN_CMPGE_U8HI
:
7668 case VSX_BUILTIN_CMPGE_U4SI
:
7669 case VSX_BUILTIN_CMPGE_U2DI
:
7670 case ALTIVEC_BUILTIN_VCMPGTUB
:
7671 case ALTIVEC_BUILTIN_VCMPGTUH
:
7672 case ALTIVEC_BUILTIN_VCMPGTUW
:
7673 case P8V_BUILTIN_VCMPGTUD
:
7678 /* unsigned arguments for 128-bit pack instructions. */
7679 case MISC_BUILTIN_PACK_TD
:
7680 case MISC_BUILTIN_PACK_V1TI
:
7685 /* unsigned second arguments (vector shift right). */
7686 case ALTIVEC_BUILTIN_VSRB
:
7687 case ALTIVEC_BUILTIN_VSRH
:
7688 case ALTIVEC_BUILTIN_VSRW
:
7689 case P8V_BUILTIN_VSRD
:
7697 /* Figure out how many args are present. */
7698 while (num_args
> 0 && h
.mode
[num_args
] == VOIDmode
)
7701 ret_type
= builtin_mode_to_type
[h
.mode
[0]][h
.uns_p
[0]];
7702 if (!ret_type
&& h
.uns_p
[0])
7703 ret_type
= builtin_mode_to_type
[h
.mode
[0]][0];
7706 fatal_error (input_location
,
7707 "internal error: builtin function %qs had an unexpected "
7708 "return type %qs", name
, GET_MODE_NAME (h
.mode
[0]));
7710 for (i
= 0; i
< (int) ARRAY_SIZE (arg_type
); i
++)
7711 arg_type
[i
] = NULL_TREE
;
7713 for (i
= 0; i
< num_args
; i
++)
7715 int m
= (int) h
.mode
[i
+1];
7716 int uns_p
= h
.uns_p
[i
+1];
7718 arg_type
[i
] = builtin_mode_to_type
[m
][uns_p
];
7719 if (!arg_type
[i
] && uns_p
)
7720 arg_type
[i
] = builtin_mode_to_type
[m
][0];
7723 fatal_error (input_location
,
7724 "internal error: builtin function %qs, argument %d "
7725 "had unexpected argument type %qs", name
, i
,
7729 builtin_hash_struct
**found
= builtin_hash_table
->find_slot (&h
, INSERT
);
7732 h2
= ggc_alloc
<builtin_hash_struct
> ();
7736 h2
->type
= build_function_type_list (ret_type
, arg_type
[0], arg_type
[1],
7737 arg_type
[2], NULL_TREE
);
7740 return (*found
)->type
;
7744 rs6000_common_init_builtins (void)
7746 const struct builtin_description
*d
;
7749 tree opaque_ftype_opaque
= NULL_TREE
;
7750 tree opaque_ftype_opaque_opaque
= NULL_TREE
;
7751 tree opaque_ftype_opaque_opaque_opaque
= NULL_TREE
;
7752 HOST_WIDE_INT builtin_mask
= rs6000_builtin_mask
;
7754 /* Create Altivec and VSX builtins on machines with at least the
7755 general purpose extensions (970 and newer) to allow the use of
7756 the target attribute. */
7758 if (TARGET_EXTRA_BUILTINS
)
7759 builtin_mask
|= RS6000_BTM_COMMON
;
7761 /* Add the ternary operators. */
7763 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
7766 HOST_WIDE_INT mask
= d
->mask
;
7768 if ((mask
& builtin_mask
) != mask
)
7770 if (TARGET_DEBUG_BUILTIN
)
7771 fprintf (stderr
, "rs6000_builtin, skip ternary %s\n", d
->name
);
7775 if (rs6000_overloaded_builtin_p (d
->code
))
7777 if (! (type
= opaque_ftype_opaque_opaque_opaque
))
7778 type
= opaque_ftype_opaque_opaque_opaque
7779 = build_function_type_list (opaque_V4SI_type_node
,
7780 opaque_V4SI_type_node
,
7781 opaque_V4SI_type_node
,
7782 opaque_V4SI_type_node
,
7787 enum insn_code icode
= d
->icode
;
7790 if (TARGET_DEBUG_BUILTIN
)
7791 fprintf (stderr
, "rs6000_builtin, bdesc_3arg[%ld] no name\n",
7797 if (icode
== CODE_FOR_nothing
)
7799 if (TARGET_DEBUG_BUILTIN
)
7800 fprintf (stderr
, "rs6000_builtin, skip ternary %s (no code)\n",
7806 type
= builtin_function_type (insn_data
[icode
].operand
[0].mode
,
7807 insn_data
[icode
].operand
[1].mode
,
7808 insn_data
[icode
].operand
[2].mode
,
7809 insn_data
[icode
].operand
[3].mode
,
7813 def_builtin (d
->name
, type
, d
->code
);
7816 /* Add the binary operators. */
7818 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
7820 machine_mode mode0
, mode1
, mode2
;
7822 HOST_WIDE_INT mask
= d
->mask
;
7824 if ((mask
& builtin_mask
) != mask
)
7826 if (TARGET_DEBUG_BUILTIN
)
7827 fprintf (stderr
, "rs6000_builtin, skip binary %s\n", d
->name
);
7831 if (rs6000_overloaded_builtin_p (d
->code
))
7833 if (! (type
= opaque_ftype_opaque_opaque
))
7834 type
= opaque_ftype_opaque_opaque
7835 = build_function_type_list (opaque_V4SI_type_node
,
7836 opaque_V4SI_type_node
,
7837 opaque_V4SI_type_node
,
7842 enum insn_code icode
= d
->icode
;
7845 if (TARGET_DEBUG_BUILTIN
)
7846 fprintf (stderr
, "rs6000_builtin, bdesc_2arg[%ld] no name\n",
7852 if (icode
== CODE_FOR_nothing
)
7854 if (TARGET_DEBUG_BUILTIN
)
7855 fprintf (stderr
, "rs6000_builtin, skip binary %s (no code)\n",
7861 mode0
= insn_data
[icode
].operand
[0].mode
;
7862 mode1
= insn_data
[icode
].operand
[1].mode
;
7863 mode2
= insn_data
[icode
].operand
[2].mode
;
7865 type
= builtin_function_type (mode0
, mode1
, mode2
, VOIDmode
,
7869 def_builtin (d
->name
, type
, d
->code
);
7872 /* Add the simple unary operators. */
7874 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
7876 machine_mode mode0
, mode1
;
7878 HOST_WIDE_INT mask
= d
->mask
;
7880 if ((mask
& builtin_mask
) != mask
)
7882 if (TARGET_DEBUG_BUILTIN
)
7883 fprintf (stderr
, "rs6000_builtin, skip unary %s\n", d
->name
);
7887 if (rs6000_overloaded_builtin_p (d
->code
))
7889 if (! (type
= opaque_ftype_opaque
))
7890 type
= opaque_ftype_opaque
7891 = build_function_type_list (opaque_V4SI_type_node
,
7892 opaque_V4SI_type_node
,
7897 enum insn_code icode
= d
->icode
;
7900 if (TARGET_DEBUG_BUILTIN
)
7901 fprintf (stderr
, "rs6000_builtin, bdesc_1arg[%ld] no name\n",
7907 if (icode
== CODE_FOR_nothing
)
7909 if (TARGET_DEBUG_BUILTIN
)
7910 fprintf (stderr
, "rs6000_builtin, skip unary %s (no code)\n",
7916 mode0
= insn_data
[icode
].operand
[0].mode
;
7917 mode1
= insn_data
[icode
].operand
[1].mode
;
7919 type
= builtin_function_type (mode0
, mode1
, VOIDmode
, VOIDmode
,
7923 def_builtin (d
->name
, type
, d
->code
);
7926 /* Add the simple no-argument operators. */
7928 for (i
= 0; i
< ARRAY_SIZE (bdesc_0arg
); i
++, d
++)
7932 HOST_WIDE_INT mask
= d
->mask
;
7934 if ((mask
& builtin_mask
) != mask
)
7936 if (TARGET_DEBUG_BUILTIN
)
7937 fprintf (stderr
, "rs6000_builtin, skip no-argument %s\n", d
->name
);
7940 if (rs6000_overloaded_builtin_p (d
->code
))
7942 if (!opaque_ftype_opaque
)
7944 = build_function_type_list (opaque_V4SI_type_node
, NULL_TREE
);
7945 type
= opaque_ftype_opaque
;
7949 enum insn_code icode
= d
->icode
;
7952 if (TARGET_DEBUG_BUILTIN
)
7953 fprintf (stderr
, "rs6000_builtin, bdesc_0arg[%lu] no name\n",
7957 if (icode
== CODE_FOR_nothing
)
7959 if (TARGET_DEBUG_BUILTIN
)
7961 "rs6000_builtin, skip no-argument %s (no code)\n",
7965 mode0
= insn_data
[icode
].operand
[0].mode
;
7966 type
= builtin_function_type (mode0
, VOIDmode
, VOIDmode
, VOIDmode
,
7969 def_builtin (d
->name
, type
, d
->code
);
7973 /* Return the internal arg pointer used for function incoming
7974 arguments. When -fsplit-stack, the arg pointer is r12 so we need
7975 to copy it to a pseudo in order for it to be preserved over calls
7976 and suchlike. We'd really like to use a pseudo here for the
7977 internal arg pointer but data-flow analysis is not prepared to
7978 accept pseudos as live at the beginning of a function. */
7981 rs6000_internal_arg_pointer (void)
7983 if (flag_split_stack
7984 && (lookup_attribute ("no_split_stack", DECL_ATTRIBUTES (cfun
->decl
))
7988 if (cfun
->machine
->split_stack_arg_pointer
== NULL_RTX
)
7992 cfun
->machine
->split_stack_arg_pointer
= gen_reg_rtx (Pmode
);
7993 REG_POINTER (cfun
->machine
->split_stack_arg_pointer
) = 1;
7995 /* Put the pseudo initialization right after the note at the
7996 beginning of the function. */
7997 pat
= gen_rtx_SET (cfun
->machine
->split_stack_arg_pointer
,
7998 gen_rtx_REG (Pmode
, 12));
7999 push_topmost_sequence ();
8000 emit_insn_after (pat
, get_insns ());
8001 pop_topmost_sequence ();
8003 rtx ret
= plus_constant (Pmode
, cfun
->machine
->split_stack_arg_pointer
,
8004 FIRST_PARM_OFFSET (current_function_decl
));
8005 return copy_to_reg (ret
);
8007 return virtual_incoming_args_rtx
;
8011 /* A C compound statement that outputs the assembler code for a thunk
8012 function, used to implement C++ virtual function calls with
8013 multiple inheritance. The thunk acts as a wrapper around a virtual
8014 function, adjusting the implicit object parameter before handing
8015 control off to the real function.
8017 First, emit code to add the integer DELTA to the location that
8018 contains the incoming first argument. Assume that this argument
8019 contains a pointer, and is the one used to pass the `this' pointer
8020 in C++. This is the incoming argument *before* the function
8021 prologue, e.g. `%o0' on a sparc. The addition must preserve the
8022 values of all other incoming arguments.
8024 After the addition, emit code to jump to FUNCTION, which is a
8025 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
8026 not touch the return address. Hence returning from FUNCTION will
8027 return to whoever called the current `thunk'.
8029 The effect must be as if FUNCTION had been called directly with the
8030 adjusted first argument. This macro is responsible for emitting
8031 all of the code for a thunk function; output_function_prologue()
8032 and output_function_epilogue() are not invoked.
8034 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
8035 been extracted from it.) It might possibly be useful on some
8036 targets, but probably not.
8038 If you do not define this macro, the target-independent code in the
8039 C++ frontend will generate a less efficient heavyweight thunk that
8040 calls FUNCTION instead of jumping to it. The generic approach does
8041 not support varargs. */
8044 rs6000_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
8045 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
8048 const char *fnname
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl
));
8049 rtx this_rtx
, funexp
;
8052 reload_completed
= 1;
8053 epilogue_completed
= 1;
8055 /* Mark the end of the (empty) prologue. */
8056 emit_note (NOTE_INSN_PROLOGUE_END
);
8058 /* Find the "this" pointer. If the function returns a structure,
8059 the structure return pointer is in r3. */
8060 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
8061 this_rtx
= gen_rtx_REG (Pmode
, 4);
8063 this_rtx
= gen_rtx_REG (Pmode
, 3);
8065 /* Apply the constant offset, if required. */
8067 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, GEN_INT (delta
)));
8069 /* Apply the offset from the vtable, if required. */
8072 rtx vcall_offset_rtx
= GEN_INT (vcall_offset
);
8073 rtx tmp
= gen_rtx_REG (Pmode
, 12);
8075 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, this_rtx
));
8076 if (((unsigned HOST_WIDE_INT
) vcall_offset
) + 0x8000 >= 0x10000)
8078 emit_insn (gen_add3_insn (tmp
, tmp
, vcall_offset_rtx
));
8079 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, tmp
));
8083 rtx loc
= gen_rtx_PLUS (Pmode
, tmp
, vcall_offset_rtx
);
8085 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, loc
));
8087 emit_insn (gen_add3_insn (this_rtx
, this_rtx
, tmp
));
8090 /* Generate a tail call to the target function. */
8091 if (!TREE_USED (function
))
8093 assemble_external (function
);
8094 TREE_USED (function
) = 1;
8096 funexp
= XEXP (DECL_RTL (function
), 0);
8097 funexp
= gen_rtx_MEM (FUNCTION_MODE
, funexp
);
8099 insn
= emit_call_insn (gen_sibcall (funexp
, const0_rtx
, const0_rtx
));
8100 SIBLING_CALL_P (insn
) = 1;
8103 /* Run just enough of rest_of_compilation to get the insns emitted.
8104 There's not really enough bulk here to make other passes such as
8105 instruction scheduling worth while. */
8106 insn
= get_insns ();
8107 shorten_branches (insn
);
8108 assemble_start_function (thunk_fndecl
, fnname
);
8109 final_start_function (insn
, file
, 1);
8110 final (insn
, file
, 1);
8111 final_end_function ();
8112 assemble_end_function (thunk_fndecl
, fnname
);
8114 reload_completed
= 0;
8115 epilogue_completed
= 0;
8118 #include "gt-rs6000-call.h"