re PR target/70381 (On powerpc, -mfloat128 is on by default for all VSX systems)
[gcc] 2016-04-11 Michael Meissner <meissner@linux.vnet.ibm.com> PR target/70381 * config/rs6000/rs6000.c (rs6000_opt_masks): Disable using the target attribute and pragma from changing the -mfloat128 and -mfloat128-hardware options. * doc/extend.texi (Additional Floating Types): Document PowerPC __float128 restrictions. [libgcc] 2016-04-11 Michael Meissner <meissner@linux.vnet.ibm.com> PR target/70381 * configure.ac (powerpc*-*-linux*): Rework tests to build __float128 emulation routines to not depend on using #pragma GCC target to enable -mfloat128. * configure: Regnerate. [gcc/testsuite] 2016-04-11 Michael Meissner <meissner@linux.vnet.ibm.com> PR target/70381 * gcc.target/powerpc/float128-1.c: New tests to make sure the __float128 emulator is built and runs. * gcc.target/powerpc/float128-1.c: Likewise. * lib/target-supports.exp (check_ppc_float128_sw_available): Rework tests for __float128 software and hardware availability. Fix exit condition to return 0 on success. From-SVN: r234884
This commit is contained in:
parent
a9c2f3d9af
commit
35fbda430d
|
@ -1,3 +1,13 @@
|
|||
2016-04-11 Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||
|
||||
PR target/70381
|
||||
* config/rs6000/rs6000.c (rs6000_opt_masks): Disable using the
|
||||
target attribute and pragma from changing the -mfloat128
|
||||
and -mfloat128-hardware options.
|
||||
|
||||
* doc/extend.texi (Additional Floating Types): Document PowerPC
|
||||
__float128 restrictions.
|
||||
|
||||
2016-04-11 James Greenhalgh <james.greenhalgh@arm.com>
|
||||
|
||||
PR target/70133
|
||||
|
|
|
@ -34381,8 +34381,8 @@ static struct rs6000_opt_mask const rs6000_opt_masks[] =
|
|||
{ "dlmzb", OPTION_MASK_DLMZB, false, true },
|
||||
{ "efficient-unaligned-vsx", OPTION_MASK_EFFICIENT_UNALIGNED_VSX,
|
||||
false, true },
|
||||
{ "float128", OPTION_MASK_FLOAT128, false, true },
|
||||
{ "float128-hardware", OPTION_MASK_FLOAT128_HW, false, true },
|
||||
{ "float128", OPTION_MASK_FLOAT128, false, false },
|
||||
{ "float128-hardware", OPTION_MASK_FLOAT128_HW, false, false },
|
||||
{ "fprnd", OPTION_MASK_FPRND, false, true },
|
||||
{ "hard-dfp", OPTION_MASK_DFP, false, true },
|
||||
{ "htm", OPTION_MASK_HTM, false, true },
|
||||
|
|
|
@ -954,9 +954,13 @@ typedef _Complex float __attribute__((mode(TC))) _Complex128;
|
|||
typedef _Complex float __attribute__((mode(XC))) _Complex80;
|
||||
@end smallexample
|
||||
|
||||
On PowerPC 64-bit Linux systems there are currently problems in using
|
||||
the complex @code{__float128} type. When these problems are fixed,
|
||||
you would use:
|
||||
In order to use @code{__float128} and @code{__ibm128} on PowerPC Linux
|
||||
systems, you must use the @option{-mfloat128}. It is expected in
|
||||
future versions of GCC that @code{__float128} will be enabled
|
||||
automatically. In addition, there are currently problems in using the
|
||||
complex @code{__float128} type. When these problems are fixed, you
|
||||
would use the following syntax to declare @code{_Complex128} to be a
|
||||
complex @code{__float128} type:
|
||||
|
||||
@smallexample
|
||||
typedef _Complex float __attribute__((mode(KC))) _Complex128;
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
2016-04-11 Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||
|
||||
PR target/70381
|
||||
* gcc.target/powerpc/float128-1.c: New tests to make sure the
|
||||
__float128 emulator is built and runs.
|
||||
* gcc.target/powerpc/float128-1.c: Likewise.
|
||||
|
||||
* lib/target-supports.exp (check_ppc_float128_sw_available):
|
||||
Rework tests for __float128 software and hardware
|
||||
availability. Fix exit condition to return 0 on success.
|
||||
|
||||
2016-04-11 James Greenhalgh <james.greenhalgh@arm.com>
|
||||
|
||||
PR target/70133
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
/* { dg-do run { target { powerpc*-*-linux* } } } */
|
||||
/* { dg-require-effective-target ppc_float128_sw } */
|
||||
/* { dg-options "-mcpu=power7 -O2 -mfloat128 -static-libgcc" } */
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#if !defined(__FLOAT128__) || !defined(_ARCH_PPC)
|
||||
static __float128
|
||||
pass_through (__float128 x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
__float128 (*no_optimize) (__float128) = pass_through;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
__attribute__((__noinline__))
|
||||
static void
|
||||
print_f128 (__float128 x)
|
||||
{
|
||||
unsigned sign;
|
||||
unsigned exponent;
|
||||
uint64_t mantissa1;
|
||||
uint64_t mantissa2;
|
||||
uint64_t upper;
|
||||
uint64_t lower;
|
||||
|
||||
#if defined(_ARCH_PPC) && defined(__BIG_ENDIAN__)
|
||||
struct ieee128 {
|
||||
uint64_t upper;
|
||||
uint64_t lower;
|
||||
};
|
||||
|
||||
#elif (defined(_ARCH_PPC) && defined(__LITTLE_ENDIAN__)) || defined(__x86_64__)
|
||||
struct ieee128 {
|
||||
uint64_t lower;
|
||||
uint64_t upper;
|
||||
};
|
||||
|
||||
#else
|
||||
#error "Unknown system"
|
||||
#endif
|
||||
|
||||
union {
|
||||
__float128 f128;
|
||||
struct ieee128 s128;
|
||||
} u;
|
||||
|
||||
u.f128 = x;
|
||||
upper = u.s128.upper;
|
||||
lower = u.s128.lower;
|
||||
|
||||
sign = (unsigned)((upper >> 63) & 1);
|
||||
exponent = (unsigned)((upper >> 48) & ((((uint64_t)1) << 16) - 1));
|
||||
mantissa1 = (upper & ((((uint64_t)1) << 48) - 1));
|
||||
mantissa2 = lower;
|
||||
|
||||
printf ("%c 0x%.4x 0x%.12" PRIx64 " 0x%.16" PRIx64,
|
||||
sign ? '-' : '+',
|
||||
exponent,
|
||||
mantissa1,
|
||||
mantissa2);
|
||||
}
|
||||
#endif
|
||||
|
||||
__attribute__((__noinline__))
|
||||
static void
|
||||
do_test (__float128 expected, __float128 got, const char *name)
|
||||
{
|
||||
int equal_p = (expected == got);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("Test %s, expected: ", name);
|
||||
print_f128 (expected);
|
||||
printf (" %5g, got: ", (double) expected);
|
||||
print_f128 (got);
|
||||
printf (" %5g, result %s\n",
|
||||
(double) got,
|
||||
(equal_p) ? "equal" : "not equal");
|
||||
#endif
|
||||
|
||||
if (!equal_p)
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
__float128 one = 1.0q;
|
||||
__float128 two = 2.0q;
|
||||
__float128 three = 3.0q;
|
||||
__float128 four = 4.0q;
|
||||
__float128 five = 5.0q;
|
||||
__float128 add_result = (1.0q + 2.0q);
|
||||
__float128 mul_result = ((1.0q + 2.0q) * 3.0q);
|
||||
__float128 div_result = (((1.0q + 2.0q) * 3.0q) / 4.0q);
|
||||
__float128 sub_result = ((((1.0q + 2.0q) * 3.0q) / 4.0q) - 5.0q);
|
||||
__float128 neg_result = - sub_result;
|
||||
__float128 add_xresult;
|
||||
__float128 mul_xresult;
|
||||
__float128 div_xresult;
|
||||
__float128 sub_xresult;
|
||||
__float128 neg_xresult;
|
||||
|
||||
#if defined(__FLOAT128__) && defined(_ARCH_PPC)
|
||||
__asm__ (" #prevent constant folding, %x0" : "+wa" (one));
|
||||
__asm__ (" #prevent constant folding, %x0" : "+wa" (two));
|
||||
__asm__ (" #prevent constant folding, %x0" : "+wa" (three));
|
||||
__asm__ (" #prevent constant folding, %x0" : "+wa" (four));
|
||||
__asm__ (" #prevent constant folding, %x0" : "+wa" (five));
|
||||
|
||||
#else
|
||||
one = no_optimize (one);
|
||||
two = no_optimize (two);
|
||||
three = no_optimize (three);
|
||||
four = no_optimize (four);
|
||||
five = no_optimize (five);
|
||||
#endif
|
||||
|
||||
add_xresult = (one + two);
|
||||
do_test (add_result, add_xresult, "add");
|
||||
|
||||
mul_xresult = add_xresult * three;
|
||||
do_test (mul_result, mul_xresult, "mul");
|
||||
|
||||
div_xresult = mul_xresult / four;
|
||||
do_test (div_result, div_xresult, "div");
|
||||
|
||||
sub_xresult = div_xresult - five;
|
||||
do_test (sub_result, sub_xresult, "sub");
|
||||
|
||||
neg_xresult = - sub_xresult;
|
||||
do_test (neg_result, neg_xresult, "neg");
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("Passed\n");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,226 @@
|
|||
/* { dg-do run { target { powerpc*-*-linux* } } } */
|
||||
/* { dg-require-effective-target ppc_float128_sw } */
|
||||
/* { dg-options "-mcpu=power7 -O2 -mfloat128 -static-libgcc" } */
|
||||
|
||||
/*
|
||||
* Test program to make sure we are getting more precision than the 53 bits we
|
||||
* get with IEEE double.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef TYPE
|
||||
#define TYPE __float128
|
||||
#endif
|
||||
|
||||
#ifndef NO_INLINE
|
||||
#define NO_INLINE __attribute__((__noinline__))
|
||||
#endif
|
||||
|
||||
static TYPE power_of_two (ssize_t) NO_INLINE;
|
||||
static TYPE calc1 (TYPE) NO_INLINE;
|
||||
static TYPE calc2 (TYPE) NO_INLINE;
|
||||
static TYPE calc3 (TYPE) NO_INLINE;
|
||||
|
||||
#ifndef POWER2
|
||||
#define POWER2 60
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Print TYPE in hex.
|
||||
*/
|
||||
|
||||
|
||||
#if defined(DEBUG) || defined(DEBUG2)
|
||||
static void print_hex (const char *prefix, TYPE, const char *suffix) NO_INLINE;
|
||||
|
||||
#if defined (__i386__) || defined (__x86_64__) || defined (__LITTLE_ENDIAN__)
|
||||
#define ENDIAN_REVERSE(N, MAX) ((MAX) - 1 - (N))
|
||||
|
||||
#else
|
||||
#define ENDIAN_REVERSE(N, MAX) (N)
|
||||
#endif
|
||||
|
||||
static void
|
||||
print_hex (const char *prefix, TYPE value, const char *suffix)
|
||||
{
|
||||
union {
|
||||
TYPE f128;
|
||||
unsigned char uc[sizeof (TYPE)];
|
||||
} u;
|
||||
|
||||
size_t i;
|
||||
|
||||
u.f128 = value;
|
||||
printf ("%s0x", prefix);
|
||||
for (i = 0; i < sizeof (TYPE); i++)
|
||||
printf ("%.2x", u.uc[ ENDIAN_REVERSE (i, sizeof (TYPE)) ]);
|
||||
|
||||
printf (", %24.2Lf%s", (long double)value, suffix);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Return a power of two.
|
||||
*/
|
||||
|
||||
static TYPE
|
||||
power_of_two (ssize_t num)
|
||||
{
|
||||
TYPE ret = (TYPE) 1.0;
|
||||
ssize_t i;
|
||||
|
||||
if (num >= 0)
|
||||
{
|
||||
for (i = 0; i < num; i++)
|
||||
ret *= (TYPE) 2.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ssize_t num2 = -num;
|
||||
for (i = 0; i < num2; i++)
|
||||
ret /= (TYPE) 2.0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("power_of_two (%2ld) = ", (long) num);
|
||||
print_hex ("", ret, "\n");
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#ifdef ADDSUB
|
||||
static TYPE add (TYPE a, TYPE b) NO_INLINE;
|
||||
static TYPE sub (TYPE a, TYPE b) NO_INLINE;
|
||||
|
||||
static TYPE
|
||||
add (TYPE a, TYPE b)
|
||||
{
|
||||
TYPE c;
|
||||
#ifdef DEBUG
|
||||
print_hex ("add, arg1 = ", a, "\n");
|
||||
print_hex ("add, arg2 = ", b, "\n");
|
||||
#endif
|
||||
c = a + b;
|
||||
#ifdef DEBUG
|
||||
print_hex ("add, result = ", c, "\n");
|
||||
#endif
|
||||
return c;
|
||||
}
|
||||
|
||||
static TYPE
|
||||
sub (TYPE a, TYPE b)
|
||||
{
|
||||
TYPE c;
|
||||
#ifdef DEBUG
|
||||
print_hex ("sub, arg1 = ", a, "\n");
|
||||
print_hex ("sub, arg2 = ", b, "\n");
|
||||
#endif
|
||||
c = a - b;
|
||||
#ifdef DEBUG
|
||||
print_hex ("sub, result = ", c, "\n");
|
||||
#endif
|
||||
return c;
|
||||
}
|
||||
|
||||
#else
|
||||
#define add(x, y) ((x) + (y))
|
||||
#define sub(x, y) ((x) - (y))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Various calculations. Add in 2**POWER2, and subtract 2**(POWER2-1) twice, and we should
|
||||
* get the original value.
|
||||
*/
|
||||
|
||||
static TYPE
|
||||
calc1 (TYPE num)
|
||||
{
|
||||
TYPE num2 = add (power_of_two (POWER2), num);
|
||||
TYPE ret;
|
||||
|
||||
#ifdef DEBUG
|
||||
print_hex ("calc1 (before call) = ", num2, "\n");
|
||||
#endif
|
||||
|
||||
ret = calc2 (num2);
|
||||
|
||||
#ifdef DEBUG
|
||||
print_hex ("calc1 (after call) = ", ret, "\n");
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static TYPE
|
||||
calc2 (TYPE num)
|
||||
{
|
||||
TYPE num2 = sub (num, power_of_two (POWER2-1));
|
||||
TYPE ret;
|
||||
|
||||
#ifdef DEBUG
|
||||
print_hex ("calc2 (before call) = ", num2, "\n");
|
||||
#endif
|
||||
|
||||
ret = calc3 (num2);
|
||||
|
||||
#ifdef DEBUG
|
||||
print_hex ("calc2 (after call) = ", ret, "\n");
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static TYPE
|
||||
calc3 (TYPE num)
|
||||
{
|
||||
TYPE ret = sub (num, (((TYPE) 2.0) * power_of_two (POWER2-2)));
|
||||
|
||||
#ifdef DEBUG
|
||||
print_hex ("calc3 = ", ret, "\n");
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
TYPE input, output;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("Testing, %ld bytes\n", (long) sizeof (TYPE));
|
||||
#endif
|
||||
|
||||
input = power_of_two (-1);
|
||||
if ((double)input != 0.5)
|
||||
{
|
||||
#if defined(DEBUG) || defined(DEBUG2)
|
||||
print_hex ("Input should be 0.5: ", output, "\n");
|
||||
return 1;
|
||||
#else
|
||||
__builtin_abort ();
|
||||
#endif
|
||||
}
|
||||
|
||||
output = calc1 (input);
|
||||
if ((double)output != 0.5)
|
||||
{
|
||||
#if defined(DEBUG) || defined(DEBUG2)
|
||||
print_hex ("Output should be 0.5: ", output, "\n");
|
||||
return 1;
|
||||
#else
|
||||
__builtin_abort ();
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1740,7 +1740,7 @@ proc check_ppc_float128_sw_available { } {
|
|||
int main()
|
||||
{
|
||||
__float128 z = x + y;
|
||||
return (z == 3.0q);
|
||||
return (z != 3.0q);
|
||||
}
|
||||
} $options
|
||||
}
|
||||
|
@ -1759,7 +1759,7 @@ proc check_ppc_float128_hw_available { } {
|
|||
|| [istarget *-*-darwin*]} {
|
||||
expr 0
|
||||
} else {
|
||||
set options "-mfloat128-hardware"
|
||||
set options "-mfloat128 -mvsx -mfloat128-hardware -mpower9-vector"
|
||||
check_runtime_nocache ppc_float128_hw_available {
|
||||
volatile __float128 x = 1.0q;
|
||||
volatile __float128 y = 2.0q;
|
||||
|
@ -1769,7 +1769,7 @@ proc check_ppc_float128_hw_available { } {
|
|||
__float128 w = -1.0q;
|
||||
|
||||
__asm__ ("xsaddqp %0,%1,%2" : "+v" (w) : "v" (x), "v" (y));
|
||||
return ((z == 3.0q) && (z == w);
|
||||
return ((z != 3.0q) || (z != w);
|
||||
}
|
||||
} $options
|
||||
}
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
2016-04-11 Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||
|
||||
PR target/70381
|
||||
* configure.ac (powerpc*-*-linux*): Rework tests to build
|
||||
__float128 emulation routines to not depend on using #pragma GCC
|
||||
target to enable -mfloat128.
|
||||
* configure: Regnerate.
|
||||
|
||||
2016-04-04 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
PR target/67172
|
||||
|
|
|
@ -4767,16 +4767,20 @@ esac
|
|||
esac
|
||||
|
||||
case ${host} in
|
||||
# At present, we cannot turn -mfloat128 on via #pragma GCC target,
|
||||
# so just check if we have VSX (ISA 2.06) support to build the
|
||||
# software libraries, and whether the assembler can handle xsaddqp
|
||||
# for hardware support.
|
||||
powerpc*-*-linux*)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the PowerPC compiler can do __float128" >&5
|
||||
$as_echo_n "checking whether the PowerPC compiler can do __float128... " >&6; }
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PowerPC ISA 2.06 to build __float128 libraries" >&5
|
||||
$as_echo_n "checking for PowerPC ISA 2.06 to build __float128 libraries... " >&6; }
|
||||
if test "${libgcc_cv_powerpc_float128+set}" = set; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#pragma GCC target ("vsx,float128")
|
||||
__float128 add (__float128 *a) { return *a + *(a+1); }
|
||||
#pragma GCC target ("vsx")
|
||||
vector double dadd (vector double a, vector double b) { return a + b; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
libgcc_cv_powerpc_float128=yes
|
||||
|
@ -4788,21 +4792,21 @@ fi
|
|||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgcc_cv_powerpc_float128" >&5
|
||||
$as_echo "$libgcc_cv_powerpc_float128" >&6; }
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the PowerPC compiler can do hardware __float128" >&5
|
||||
$as_echo_n "checking whether the PowerPC compiler can do hardware __float128... " >&6; }
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PowerPC ISA 3.0 to build hardware __float128 libraries" >&5
|
||||
$as_echo_n "checking for PowerPC ISA 3.0 to build hardware __float128 libraries... " >&6; }
|
||||
if test "${libgcc_cv_powerpc_float128_hw+set}" = set; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#pragma GCC target ("cpu=power9,float128,float128-hardware")
|
||||
#pragma GCC target ("vsx,power9-vector")
|
||||
#include <sys/auxv.h>
|
||||
#ifndef AT_PLATFORM
|
||||
#error "AT_PLATFORM is not defined"
|
||||
#endif
|
||||
__float128 add (__float128 a, __float128 b)
|
||||
vector unsigned char (vector unsigned char a, vector unsigned char b)
|
||||
{
|
||||
__float128 ret;
|
||||
vector unsigned char ret;
|
||||
__asm__ ("xsaddqp %0,%1,%2" : "=v" (ret) : "v" (a), "v" (b));
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -374,26 +374,30 @@ esac
|
|||
esac
|
||||
|
||||
case ${host} in
|
||||
# At present, we cannot turn -mfloat128 on via #pragma GCC target,
|
||||
# so just check if we have VSX (ISA 2.06) support to build the
|
||||
# software libraries, and whether the assembler can handle xsaddqp
|
||||
# for hardware support.
|
||||
powerpc*-*-linux*)
|
||||
AC_CACHE_CHECK([whether the PowerPC compiler can do __float128],
|
||||
AC_CACHE_CHECK([for PowerPC ISA 2.06 to build __float128 libraries],
|
||||
[libgcc_cv_powerpc_float128],
|
||||
[AC_COMPILE_IFELSE(
|
||||
[#pragma GCC target ("vsx,float128")
|
||||
__float128 add (__float128 *a) { return *a + *(a+1); }],
|
||||
[#pragma GCC target ("vsx")
|
||||
vector double dadd (vector double a, vector double b) { return a + b; }],
|
||||
[libgcc_cv_powerpc_float128=yes],
|
||||
[libgcc_cv_powerpc_float128=no])])
|
||||
|
||||
AC_CACHE_CHECK([whether the PowerPC compiler can do hardware __float128],
|
||||
AC_CACHE_CHECK([for PowerPC ISA 3.0 to build hardware __float128 libraries],
|
||||
[libgcc_cv_powerpc_float128_hw],
|
||||
[AC_COMPILE_IFELSE(
|
||||
[#pragma GCC target ("cpu=power9,float128,float128-hardware")
|
||||
[#pragma GCC target ("vsx,power9-vector")
|
||||
#include <sys/auxv.h>
|
||||
#ifndef AT_PLATFORM
|
||||
#error "AT_PLATFORM is not defined"
|
||||
#endif
|
||||
__float128 add (__float128 a, __float128 b)
|
||||
vector unsigned char (vector unsigned char a, vector unsigned char b)
|
||||
{
|
||||
__float128 ret;
|
||||
vector unsigned char ret;
|
||||
__asm__ ("xsaddqp %0,%1,%2" : "=v" (ret) : "v" (a), "v" (b));
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue