===================================================================
@@ -647,6 +647,15 @@
| RS6000_BTC_BINARY), \
CODE_FOR_ ## ICODE) /* ICODE */
+/* __float128 floating point builtins. */
+#define BU_FLOAT128_2(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_FLOAT128, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_BINARY), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
#endif
/* Insure 0 is not a legitimate index. */
@@ -1642,6 +1651,9 @@ BU_DFP_MISC_2 (UNPACK_TD, "unpack_dec128
BU_LDBL128_2 (PACK_TF, "pack_longdouble", CONST, packtf)
BU_LDBL128_2 (UNPACK_TF, "unpack_longdouble", CONST, unpacktf)
+BU_FLOAT128_2 (PACK_IF, "pack_ibm128", CONST, packif)
+BU_FLOAT128_2 (UNPACK_IF, "unpack_ibm128", CONST, unpackif)
+
BU_P7_MISC_2 (PACK_V1TI, "pack_vector_int128", CONST, packv1ti)
BU_P7_MISC_2 (UNPACK_V1TI, "unpack_vector_int128", CONST, unpackv1ti)
===================================================================
@@ -3521,7 +3521,8 @@ rs6000_builtin_mask_calculate (void)
| ((TARGET_HTM) ? RS6000_BTM_HTM : 0)
| ((TARGET_DFP) ? RS6000_BTM_DFP : 0)
| ((TARGET_HARD_FLOAT) ? RS6000_BTM_HARD_FLOAT : 0)
- | ((TARGET_LONG_DOUBLE_128) ? RS6000_BTM_LDBL128 : 0));
+ | ((TARGET_LONG_DOUBLE_128) ? RS6000_BTM_LDBL128 : 0)
+ | ((TARGET_FLOAT128) ? RS6000_BTM_FLOAT128 : 0));
}
/* Implement TARGET_MD_ASM_ADJUST. All asm statements are considered
@@ -14605,6 +14606,8 @@ rs6000_invalid_builtin (enum rs6000_buil
" -mlong-double-128 options", name);
else if ((fnmask & RS6000_BTM_HARD_FLOAT) != 0)
error ("Builtin function %s requires the -mhard-float option", name);
+ else if ((fnmask & RS6000_BTM_FLOAT128) != 0)
+ error ("Builtin function %s requires the -mfloat128 options", name);
else
error ("Builtin function %s is not supported with the current options",
name);
@@ -14894,19 +14897,21 @@ rs6000_init_builtins (void)
IFmode is the IBM extended 128-bit format that is a pair of doubles.
TFmode will be either IEEE 128-bit floating point or the IBM double-double
format that uses a pair of doubles, depending on the switches and
- defaults. */
+ defaults. Always create the types even if we don't register the keywords
+ to allow built-in functions using these types to be created. */
+
+ ibm128_float_type_node = make_node (REAL_TYPE);
+ TYPE_PRECISION (ibm128_float_type_node) = 128;
+ layout_type (ibm128_float_type_node);
+ SET_TYPE_MODE (ibm128_float_type_node, IFmode);
+
+ ieee128_float_type_node = make_node (REAL_TYPE);
+ TYPE_PRECISION (ieee128_float_type_node) = 128;
+ layout_type (ieee128_float_type_node);
+ SET_TYPE_MODE (ieee128_float_type_node, KFmode);
+
if (TARGET_FLOAT128)
{
- ibm128_float_type_node = make_node (REAL_TYPE);
- TYPE_PRECISION (ibm128_float_type_node) = 128;
- layout_type (ibm128_float_type_node);
- SET_TYPE_MODE (ibm128_float_type_node, IFmode);
-
- ieee128_float_type_node = make_node (REAL_TYPE);
- TYPE_PRECISION (ieee128_float_type_node) = 128;
- layout_type (ieee128_float_type_node);
- SET_TYPE_MODE (ieee128_float_type_node, KFmode);
-
lang_hooks.types.register_builtin_type (ieee128_float_type_node,
"__float128");
@@ -34223,6 +34228,7 @@ static struct rs6000_opt_mask const rs60
{ "hard-dfp", RS6000_BTM_DFP, false, false },
{ "hard-float", RS6000_BTM_HARD_FLOAT, false, false },
{ "long-double-128", RS6000_BTM_LDBL128, false, false },
+ { "float128", RS6000_BTM_FLOAT128, false, false },
};
/* Option variables that we want to support inside attribute((target)) and
===================================================================
@@ -605,6 +605,7 @@ extern int rs6000_vector_align[];
#define MASK_DLMZB OPTION_MASK_DLMZB
#define MASK_EABI OPTION_MASK_EABI
#define MASK_FPRND OPTION_MASK_FPRND
+#define MASK_FLOAT128 OPTION_MASK_FLOAT128
#define MASK_P8_FUSION OPTION_MASK_P8_FUSION
#define MASK_HARD_FLOAT OPTION_MASK_HARD_FLOAT
#define MASK_HTM OPTION_MASK_HTM
@@ -2670,6 +2671,7 @@ extern int frame_pointer_needed;
#define RS6000_BTM_DFP MASK_DFP /* Decimal floating point. */
#define RS6000_BTM_HARD_FLOAT MASK_SOFT_FLOAT /* Hardware floating point. */
#define RS6000_BTM_LDBL128 MASK_MULTIPLE /* 128-bit long double. */
+#define RS6000_BTM_FLOAT128 MASK_FLOAT128 /* IEEE 128-bit fp. */
#define RS6000_BTM_COMMON (RS6000_BTM_ALTIVEC \
| RS6000_BTM_VSX \
@@ -2684,7 +2686,8 @@ extern int frame_pointer_needed;
| RS6000_BTM_CELL \
| RS6000_BTM_DFP \
| RS6000_BTM_HARD_FLOAT \
- | RS6000_BTM_LDBL128)
+ | RS6000_BTM_LDBL128 \
+ | RS6000_BTM_FLOAT128)
/* Define builtin enum index. */
===================================================================
@@ -469,6 +469,9 @@ (define_mode_attr f64_av [(DF "wv") (DD
; Definitions for 64-bit access to ISA 3.0 (power9) vector
(define_mode_attr f64_p9 [(DF "wb") (DD "wn")])
+; Definitions for 128-bit IBM extended double word pack/unpack
+(define_mode_attr f128_vsx [(TF "ws") (IF "ws") (TD "d")])
+
; These modes do not fit in integer registers in 32-bit mode.
; but on e500v2, the gpr are 64 bit registers
(define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
@@ -13109,16 +13112,16 @@ (define_mode_attr FP128_64 [(TF "DF")
(define_expand "unpack<mode>"
[(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
(unspec:<FP128_64>
- [(match_operand:FMOVE128 1 "register_operand" "")
+ [(match_operand:FMOVE128_FPR 1 "register_operand" "")
(match_operand:QI 2 "const_0_to_1_operand" "")]
UNSPEC_UNPACK_128BIT))]
"FLOAT128_2REG_P (<MODE>mode)"
"")
-(define_insn_and_split "unpack<mode>_dm"
- [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
+(define_insn_and_split "*unpack<mode>_dm"
+ [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=<f128_vsx>,m,<f128_vsx>,r,m")
(unspec:<FP128_64>
- [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
+ [(match_operand:FMOVE128_FPR 1 "register_operand" "d,d,r,d,r")
(match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
UNSPEC_UNPACK_128BIT))]
"TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
@@ -13139,10 +13142,10 @@ (define_insn_and_split "unpack<mode>_dm"
[(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
(set_attr "length" "4")])
-(define_insn_and_split "unpack<mode>_nodm"
- [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
+(define_insn_and_split "*unpack<mode>_nodm"
+ [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=<f128_vsx>,m")
(unspec:<FP128_64>
- [(match_operand:FMOVE128 1 "register_operand" "d,d")
+ [(match_operand:FMOVE128_FPR 1 "register_operand" "d,d")
(match_operand:QI 2 "const_0_to_1_operand" "i,i")]
UNSPEC_UNPACK_128BIT))]
"(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
@@ -13164,30 +13167,31 @@ (define_insn_and_split "unpack<mode>_nod
(set_attr "length" "4")])
(define_insn_and_split "pack<mode>"
- [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
- (unspec:FMOVE128
- [(match_operand:<FP128_64> 1 "register_operand" "0,d")
- (match_operand:<FP128_64> 2 "register_operand" "d,d")]
+ [(set (match_operand:FMOVE128_FPR 0 "register_operand" "=&d,&d,&d,&d")
+ (unspec:FMOVE128_FPR
+ [(match_operand:<FP128_64> 1 "input_operand" "<f128_vsx>,<f128_vsx>,m,m")
+ (match_operand:<FP128_64> 2 "input_operand" "<f128_vsx>,m,<f128_vsx>,m")]
UNSPEC_PACK_128BIT))]
"FLOAT128_2REG_P (<MODE>mode)"
- "@
- fmr %L0,%2
- #"
- "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
+ "#"
+ "&& reload_completed"
[(set (match_dup 3) (match_dup 1))
(set (match_dup 4) (match_dup 2))]
{
- unsigned dest_hi = REGNO (operands[0]);
+ rtx op0 = operands[0];
+ rtx op1 = operands[1];
+ rtx op2 = operands[2];
+ unsigned dest_hi = REGNO (op0);
unsigned dest_lo = dest_hi + 1;
- gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
- gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
+ gcc_assert (!REG_P (op1) || !IN_RANGE (REGNO (op1), dest_hi, dest_lo));
+ gcc_assert (!REG_P (op2) || !IN_RANGE (REGNO (op2), dest_hi, dest_lo));
operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
}
- [(set_attr "type" "fp,fp")
- (set_attr "length" "4,8")])
+ [(set_attr "type" "fp,fpload,fpload,fpload")
+ (set_attr "length" "8")])
(define_insn "unpack<mode>"
[(set (match_operand:DI 0 "register_operand" "=d,d")
===================================================================
@@ -13512,6 +13512,8 @@ uint64_t __builtin_ppc_get_timebase ();
unsigned long __builtin_ppc_mftb ();
double __builtin_unpack_longdouble (long double, int);
long double __builtin_pack_longdouble (double, double);
+double __builtin_unpack_ibm128 (__ibm128, int);
+__ibm128 __builtin_pack_ibm128 (double, double);
@end smallexample
The @code{vec_rsqrt}, @code{__builtin_rsqrt}, and