diff mbox

, PowerPC IEEE 128-bit fp, #11-rev3 (enable libgcc conversions)

Message ID 20160111185547.GA27662@ibm-tiger.the-meissners.org
State New
Headers show

Commit Message

Michael Meissner Jan. 11, 2016, 6:55 p.m. UTC
I fixed the #ifdef to use __NO_FPRS__ (thanks for the heads up on that).  I
also believe I fixed the various formatting issues.  These two patches build on
a big endian power7 host and little endian power8 host with no regressions in
the testsuite (the gcc patch is included here, but it hasn't changed since the
previous version of this patch).  Are they ok to be checked in?

[gcc]
2016-01-11  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-11  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.

Comments

Joseph Myers Jan. 12, 2016, 12:18 a.m. UTC | #1
On Mon, 11 Jan 2016, Michael Meissner wrote:

> I fixed the #ifdef to use __NO_FPRS__ (thanks for the heads up on that).  I
> also believe I fixed the various formatting issues.  These two patches build on
> a big endian power7 host and little endian power8 host with no regressions in
> the testsuite (the gcc patch is included here, but it hasn't changed since the
> previous version of this patch).  Are they ok to be checked in?

Are you sure you sent the right patch version?  I don't see those fixes in 
this one.
diff mbox

Patch

Index: gcc/config/rs6000/rs6000-builtin.def
===================================================================
--- gcc/config/rs6000/rs6000-builtin.def	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000)	(revision 232093)
+++ gcc/config/rs6000/rs6000-builtin.def	(.../gcc/config/rs6000)	(working copy)
@@ -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)
 
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000)	(revision 232093)
+++ gcc/config/rs6000/rs6000.c	(.../gcc/config/rs6000)	(working copy)
@@ -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
Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000)	(revision 232093)
+++ gcc/config/rs6000/rs6000.h	(.../gcc/config/rs6000)	(working copy)
@@ -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.  */
 
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000)	(revision 232093)
+++ gcc/config/rs6000/rs6000.md	(.../gcc/config/rs6000)	(working copy)
@@ -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")
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi	(.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/doc)	(revision 232093)
+++ gcc/doc/extend.texi	(.../gcc/doc)	(working copy)
@@ -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