summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authormeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>2016-01-13 20:07:12 +0000
committermeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>2016-01-13 20:07:12 +0000
commit398368d888c817c66f4a273535fe2a2cc8c1715b (patch)
tree3e9e41b127e139ff3b252fcbc1363a8af5c6916b /gcc/config
parentbda05c57770fdc3b48c608d01d3aa74b17382731 (diff)
downloadgcc-398368d888c817c66f4a273535fe2a2cc8c1715b.tar.gz
[gcc]
2016-01-13 Michael Meissner <meissner@linux.vnet.ibm.com> * config/rs6000/rs6000-builtin.def (BU_FLOAT128_2): Add support for pack/unpack functions for __ibm128. (PACK_IF): Likewise. (UNPACK_IF): Likewise. * config/rs6000/rs6000.c (rs6000_builtin_mask_calculate): Add support for __ibm128 pack/unpack functions. (rs6000_invalid_builtin): Likewise. (rs6000_init_builtins): Likewise. (rs6000_opt_masks): Likewise. * config/rs6000/rs6000.h (MASK_FLOAT128): Add short name. (RS6000_BTM_FLOAT128): Add support for __ibm128 pack/unpack functions (RS6000_BTM_COMMON): Likewise. * config/rs6000/rs6000.md (f128_vsx): New mode attribute. (unpack<mode>): Use FMOVE128_FPR iterator instead of FMOVE128, to disallow __builtin_{pack,unpack}_longdouble if long double is IEEE 128-bit floating point. Add support for the double values to be in Altivec registers for TF/IF packing and unpacking, but restrict TD packing sub-fields to be FPR registers. Don't allow overlapped register support for packing. Allow pack inputs to be memory locations. Don't build generator functions for unpack<mode>_dm and unpack<mode>_nodm. (unpack<mode>_dm): Likewise. (unpack<mode>_nodm): Likewise. (pack<mode>): Likewise. * config/rs6000/rs6000-builtin.def (__builtin_pack_ibm128): Add built-in functions to pack/unpack explicit __ibm128 values. (__builtin_unpack_ibm128): Likewise. * doc/extend.texi (PowerPC Built-in Functions): Document __builtin_pack_ibm128 and __builtin_unpack_ibm128. [libgcc] 2016-01-13 Michael Meissner <meissner@linux.vnet.ibm.com> Steven Munroe <munroesj@linux.vnet.ibm.com> Tulio Magno Quites Machado Filho <tulioqm@br.ibm.com> * config/rs6000/sfp-exceptions.c: New file to provide exception support for IEEE 128-bit floating point. * config/rs6000/float128-hw.c: New file for ISA 3.0 IEEE 128-bit floating point hardware support. * config/rs6000/floattikf.c: New files for IEEE 128-bit floating point conversions. * config/rs6000/fixunskfti.c: Likewise. * config/rs6000/fixkfti.c: Likewise. * config/rs6000/floatuntikf.c: Likewise. * config/rs6000/extendkftf2-sw.c: Likewise. * config/rs6000/trunctfkf2-sw.c: Likewise. * config/rs6000/float128-ifunc.c: New file to pick either IEEE 128-bit floating point software emulation or use ISA 3.0 hardware support if it is available. * config/rs6000/quad-float128.h: New file to support IEEE 128-bit floating point. * config/rs6000/t-float128: New Makefile fragments to enable building __float128 emulation support. * config/rs6000/t-float128-hw: Likewise. * config/rs6000/float128-sed: New file to convert TF names to KF names for PowerPC IEEE 128-bit floating point support. * config/rs6000/sfp-machine.h (_FP_W_TYPE_SIZE): Use 64-bit types when building on 64-bit systems, or when VSX is enabled. (_FP_W_TYPE): Likewise. (_FP_WS_TYPE): Likewise. (_FP_I_TYPE): Likewise. (TItype): Define on 64-bit systems. (UTItype): Likewise. (TI_BITS): Likewise. (_FP_MUL_MEAT_D): Add support for using 64-bit types. (_FP_MUL_MEAT_Q): Likewise. (_FP_DIV_MEAT_D): Likewise. (_FP_DIV_MEAT_Q): Likewise. (_FP_NANFRAC_D): Likewise. (_FP_NANFRAC_Q): Likewise. (ISA_BIT): Add exception support if we are being compiled on a machine with hardware floating point support to build the IEEE 128-bit emulation functions. (FP_EX_INVALID): Likewise. (FP_EX_OVERFLOW): Likewise. (FP_EX_UNDERFLOW): Likewise. (FP_EX_DIVZERO): Likewise. (FP_EX_INEXACT): Likewise. (FP_EX_ALL): Likewise. (__sfp_handle_exceptions): Likewise. (FP_HANDLE_EXCEPTIONS): Likewise. (FP_RND_NEAREST): Likewise. (FP_RND_ZERO): Likewise. (FP_RND_PINF): Likewise. (FP_RND_MINF): Likewise. (FP_RND_MASK): Likewise. (_FP_DECL_EX): Likewise. (FP_INIT_ROUNDMODE): Likewise. (FP_ROUNDMODE): Likewise. * configure.ac (powerpc*-*-linux*): Check whether the PowerPC compiler can do __float128. * configure: Regenerate. * libgcc/config.host (powerpc*-*-linux*): If compiler can compile VSX code, enable IEEE 128-bit floating point. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@232346 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/rs6000/rs6000-builtin.def12
-rw-r--r--gcc/config/rs6000/rs6000.c30
-rw-r--r--gcc/config/rs6000/rs6000.h5
-rw-r--r--gcc/config/rs6000/rs6000.md44
4 files changed, 58 insertions, 33 deletions
diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
index 709992b3772..bbb395df37d 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc/config/rs6000/rs6000-builtin.def
@@ -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", CONST, unpacktd)
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)
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 4cd6a1b58cd..a7144fd3870 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -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_builtins fncode)
" -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. */
- 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);
+ 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);
+ 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)
+ {
lang_hooks.types.register_builtin_type (ieee128_float_type_node,
"__float128");
@@ -34223,6 +34228,7 @@ static struct rs6000_opt_mask const rs6000_builtin_mask_names[] =
{ "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
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 6b0e64e693d..c9350084016 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -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. */
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index dbcf583475d..24cb6e7b2a2 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -469,6 +469,9 @@
; 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_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 @@
[(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 @@
(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")