Message ID | 20230901032242.57839-1-chenxiaolong@loongson.cn |
---|---|
State | New |
Headers | show |
Series | [v6] LoongArch:Implement 128-bit floating point functions in gcc. | expand |
Hi,RuoYao: I have merged the V6 patch into trunk(r14-3635). If the generic optimization of copysignf128 cannot be solved, we will mention the optimization code under the architecture again. Thanks! 在 2023/9/1 上午11:22, chenxiaolong 写道: > Brief version history of patch set: > > v1 -> v2: > According to the GNU code specification, adjust the format of the > function implementation with "q" as the suffix function. > > v2 - >v3: > > 1.On the LoongArch architecture, refer to the functionality of 64-bit > functions and modify the underlying implementation of __builtin_{nanq, nansq} > functions in libgcc. > > 2.Modify the function's instruction template to use some instructions such > as "bstrins.d" to implement the 128-bit __builtin_{fabsq, copysignq} function > instead of calling libgcc library support, so as to better play the machine's > performance. > > v3 -> v4: > > 1.The above v1,v2, and v3 all implement 128-bit floating-point functions > with "q" as the suffix, but it is an older implementation. The v4 version > completely abandoned the old implementation by associating the 128-bit > floating-point function with the "q" suffix with the "f128" function that > already existed in GCC. > > 2.Modify the code so that both "__float128" and "_Float128" function types > can be supported in compiler gcc. > > 3.Associating a function with the suffix "q" to the "f128" function allows > two different forms of the function to produce the same effect, For example, > __builtin_{huge_{valq/valf128},{infq/inff128},{nanq/nanf128},{nansq/nansf128}, > {fabsq/fabsf128}}. > > 4.For the _builtin_copysignq function, do not call the new "f128" > implementation, but use the "bstrins" and other instructions in the machine > description file to implement the function function, the result is that the > number of assembly instructions can be reduced and the function optimization > to achieve the optimal effect. > > v4 -> v5: > > Removed the v4 implementation of the __builtin_fabsf128() function added > to LoongArch.md. > > v5 -> v6: > > 1.Modify the test cases in the math-float-128.c file. > > 2.Removed the v5 implementation of the __builtin_copysignf128() function > added to LoongArch.md. > > During implementation, float128_type_node is bound with the type "__float128" > so that the compiler can correctly identify the type of the function. The > "q" suffix is associated with the "f128" function, which makes GCC more > flexible to support different user input cases, implementing functions such > as __builtin_{huge_valq, infq, fabsq, copysignq, nanq, nansq}. > > gcc/ChangeLog: > > * config/loongarch/loongarch-builtins.cc (loongarch_init_builtins): > Associate the __float128 type to float128_type_node so that it can > be recognized by the compiler. > * config/loongarch/loongarch-c.cc (loongarch_cpu_cpp_builtins): > Add the flag "FLOAT128_TYPE" to gcc and associate a function > with the suffix "q" to "f128". > * doc/extend.texi:Added support for 128-bit floating-point functions on > the LoongArch architecture. > > gcc/testsuite/ChangeLog: > > * gcc.target/loongarch/math-float-128.c: New test. > --- > gcc/config/loongarch/loongarch-builtins.cc | 5 ++ > gcc/config/loongarch/loongarch-c.cc | 11 +++ > gcc/doc/extend.texi | 20 ++++- > .../gcc.target/loongarch/math-float-128.c | 81 +++++++++++++++++++ > 4 files changed, 114 insertions(+), 3 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/loongarch/math-float-128.c > > diff --git a/gcc/config/loongarch/loongarch-builtins.cc b/gcc/config/loongarch/loongarch-builtins.cc > index b929f224dfa..58b612bf445 100644 > --- a/gcc/config/loongarch/loongarch-builtins.cc > +++ b/gcc/config/loongarch/loongarch-builtins.cc > @@ -256,6 +256,11 @@ loongarch_init_builtins (void) > unsigned int i; > tree type; > > + /* Register the type float128_type_node as a built-in type and > + give it an alias "__float128". */ > + (*lang_hooks.types.register_builtin_type) (float128_type_node, > + "__float128"); > + > /* Iterate through all of the bdesc arrays, initializing all of the > builtin functions. */ > for (i = 0; i < ARRAY_SIZE (loongarch_builtins); i++) > diff --git a/gcc/config/loongarch/loongarch-c.cc b/gcc/config/loongarch/loongarch-c.cc > index 67911b78f28..6ffbf748316 100644 > --- a/gcc/config/loongarch/loongarch-c.cc > +++ b/gcc/config/loongarch/loongarch-c.cc > @@ -99,6 +99,17 @@ loongarch_cpu_cpp_builtins (cpp_reader *pfile) > else > builtin_define ("__loongarch_frlen=0"); > > + /* Add support for FLOAT128_TYPE on the LoongArch architecture. */ > + builtin_define ("__FLOAT128_TYPE__"); > + > + /* Map the old _Float128 'q' builtins into the new 'f128' builtins. */ > + builtin_define ("__builtin_fabsq=__builtin_fabsf128"); > + builtin_define ("__builtin_copysignq=__builtin_copysignf128"); > + builtin_define ("__builtin_nanq=__builtin_nanf128"); > + builtin_define ("__builtin_nansq=__builtin_nansf128"); > + builtin_define ("__builtin_infq=__builtin_inff128"); > + builtin_define ("__builtin_huge_valq=__builtin_huge_valf128"); > + > /* Native Data Sizes. */ > builtin_define_with_int_value ("_LOONGARCH_SZINT", INT_TYPE_SIZE); > builtin_define_with_int_value ("_LOONGARCH_SZLONG", LONG_TYPE_SIZE); > diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi > index 80dd2a84b0b..947c05babc9 100644 > --- a/gcc/doc/extend.texi > +++ b/gcc/doc/extend.texi > @@ -1093,10 +1093,10 @@ types. > As an extension, GNU C and GNU C++ support additional floating > types, which are not supported by all targets. > @itemize @bullet > -@item @code{__float128} is available on i386, x86_64, IA-64, and > -hppa HP-UX, as well as on PowerPC GNU/Linux targets that enable > +@item @code{__float128} is available on i386, x86_64, IA-64, LoongArch > +and hppa HP-UX, as well as on PowerPC GNU/Linux targets that enable > the vector scalar (VSX) instruction set. @code{__float128} supports > -the 128-bit floating type. On i386, x86_64, PowerPC, and IA-64 > +the 128-bit floating type. On i386, x86_64, PowerPC, LoongArch and IA-64, > other than HP-UX, @code{__float128} is an alias for @code{_Float128}. > On hppa and IA-64 HP-UX, @code{__float128} is an alias for @code{long > double}. > @@ -16657,6 +16657,20 @@ function you need to include @code{larchintrin.h}. > void __break (imm0_32767) > @end smallexample > > +Additional built-in functions are available for LoongArch family > +processors to efficiently use 128-bit floating-point (__float128) > +values. > + > +The following are the basic built-in functions supported. > +@smallexample > +__float128 __builtin_fabsq (__float128); > +__float128 __builtin_copysignq (__float128, __float128); > +__float128 __builtin_infq (void); > +__float128 __builtin_huge_valq (void); > +__float128 __builtin_nanq (void); > +__float128 __builtin_nansq (void); > +@end smallexample > + > @node MIPS DSP Built-in Functions > @subsection MIPS DSP Built-in Functions > > diff --git a/gcc/testsuite/gcc.target/loongarch/math-float-128.c b/gcc/testsuite/gcc.target/loongarch/math-float-128.c > new file mode 100644 > index 00000000000..387566a57c9 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/loongarch/math-float-128.c > @@ -0,0 +1,81 @@ > +/* { dg-do compile } */ > +/* { dg-options " -march=loongarch64 -O2 " } */ > +/* { dg-final { scan-assembler-not "my_fabsq2:.*\\bl\t%plt\\(__builtin_fabsq\\).*my_fabsq2" } } */ > +/* { dg-final { scan-assembler-not "my_copysignq2:.*\\bl\t%plt\\(__builtin_copysignq\\).*my_copysignq2" } } */ > +/* { dg-final { scan-assembler-not "my_infq2:.*\\bl\t%plt\\(__builtin_infq\\).*my_infq2" } } */ > +/* { dg-final { scan-assembler-not "my_huge_valq2:.*\\bl\t%plt\\(__builtin_huge_valq\\).*my_huge_valq2" } } */ > +/* { dg-final { scan-assembler-not "my_nanq2:.*\\bl\t%plt\\(__builtin_nanq\\).*my_nanq2" } } */ > +/* { dg-final { scan-assembler-not "my_nansq2:.*\\bl\t%plt\\(__builtin_nansq\\).*my_nansq2" } } */ > + > +__float128 > +my_fabsq1 (__float128 a) > +{ > + return __builtin_fabsq (a); > +} > + > +_Float128 > +my_fabsq2 (_Float128 a) > +{ > + return __builtin_fabsq (a); > +} > + > +__float128 > +my_copysignq1 (__float128 a, __float128 b) > +{ > + return __builtin_copysignq (a, b); > +} > + > +_Float128 > +my_copysignq2 (_Float128 a, _Float128 b) > +{ > + return __builtin_copysignq (a, b); > +} > + > +__float128 > +my_infq1 (void) > +{ > + return __builtin_infq (); > +} > + > +_Float128 > +my_infq2 (void) > +{ > + return __builtin_infq (); > +} > + > +__float128 > +my_huge_valq1 (void) > +{ > + return __builtin_huge_valq (); > +} > + > +_Float128 > +my_huge_valq2 (void) > +{ > + return __builtin_huge_valq (); > +} > + > +__float128 > +my_nanq1 (void) > +{ > + return __builtin_nanq (""); > +} > + > +_Float128 > +my_nanq2 (void) > +{ > + return __builtin_nanq (""); > +} > + > +__float128 > +my_nansq1 (void) > +{ > + return __builtin_nansq (""); > +} > + > +_Float128 > +my_nansq2 (void) > +{ > + return __builtin_nansq (""); > +} > +
diff --git a/gcc/config/loongarch/loongarch-builtins.cc b/gcc/config/loongarch/loongarch-builtins.cc index b929f224dfa..58b612bf445 100644 --- a/gcc/config/loongarch/loongarch-builtins.cc +++ b/gcc/config/loongarch/loongarch-builtins.cc @@ -256,6 +256,11 @@ loongarch_init_builtins (void) unsigned int i; tree type; + /* Register the type float128_type_node as a built-in type and + give it an alias "__float128". */ + (*lang_hooks.types.register_builtin_type) (float128_type_node, + "__float128"); + /* Iterate through all of the bdesc arrays, initializing all of the builtin functions. */ for (i = 0; i < ARRAY_SIZE (loongarch_builtins); i++) diff --git a/gcc/config/loongarch/loongarch-c.cc b/gcc/config/loongarch/loongarch-c.cc index 67911b78f28..6ffbf748316 100644 --- a/gcc/config/loongarch/loongarch-c.cc +++ b/gcc/config/loongarch/loongarch-c.cc @@ -99,6 +99,17 @@ loongarch_cpu_cpp_builtins (cpp_reader *pfile) else builtin_define ("__loongarch_frlen=0"); + /* Add support for FLOAT128_TYPE on the LoongArch architecture. */ + builtin_define ("__FLOAT128_TYPE__"); + + /* Map the old _Float128 'q' builtins into the new 'f128' builtins. */ + builtin_define ("__builtin_fabsq=__builtin_fabsf128"); + builtin_define ("__builtin_copysignq=__builtin_copysignf128"); + builtin_define ("__builtin_nanq=__builtin_nanf128"); + builtin_define ("__builtin_nansq=__builtin_nansf128"); + builtin_define ("__builtin_infq=__builtin_inff128"); + builtin_define ("__builtin_huge_valq=__builtin_huge_valf128"); + /* Native Data Sizes. */ builtin_define_with_int_value ("_LOONGARCH_SZINT", INT_TYPE_SIZE); builtin_define_with_int_value ("_LOONGARCH_SZLONG", LONG_TYPE_SIZE); diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 80dd2a84b0b..947c05babc9 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -1093,10 +1093,10 @@ types. As an extension, GNU C and GNU C++ support additional floating types, which are not supported by all targets. @itemize @bullet -@item @code{__float128} is available on i386, x86_64, IA-64, and -hppa HP-UX, as well as on PowerPC GNU/Linux targets that enable +@item @code{__float128} is available on i386, x86_64, IA-64, LoongArch +and hppa HP-UX, as well as on PowerPC GNU/Linux targets that enable the vector scalar (VSX) instruction set. @code{__float128} supports -the 128-bit floating type. On i386, x86_64, PowerPC, and IA-64 +the 128-bit floating type. On i386, x86_64, PowerPC, LoongArch and IA-64, other than HP-UX, @code{__float128} is an alias for @code{_Float128}. On hppa and IA-64 HP-UX, @code{__float128} is an alias for @code{long double}. @@ -16657,6 +16657,20 @@ function you need to include @code{larchintrin.h}. void __break (imm0_32767) @end smallexample +Additional built-in functions are available for LoongArch family +processors to efficiently use 128-bit floating-point (__float128) +values. + +The following are the basic built-in functions supported. +@smallexample +__float128 __builtin_fabsq (__float128); +__float128 __builtin_copysignq (__float128, __float128); +__float128 __builtin_infq (void); +__float128 __builtin_huge_valq (void); +__float128 __builtin_nanq (void); +__float128 __builtin_nansq (void); +@end smallexample + @node MIPS DSP Built-in Functions @subsection MIPS DSP Built-in Functions diff --git a/gcc/testsuite/gcc.target/loongarch/math-float-128.c b/gcc/testsuite/gcc.target/loongarch/math-float-128.c new file mode 100644 index 00000000000..387566a57c9 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/math-float-128.c @@ -0,0 +1,81 @@ +/* { dg-do compile } */ +/* { dg-options " -march=loongarch64 -O2 " } */ +/* { dg-final { scan-assembler-not "my_fabsq2:.*\\bl\t%plt\\(__builtin_fabsq\\).*my_fabsq2" } } */ +/* { dg-final { scan-assembler-not "my_copysignq2:.*\\bl\t%plt\\(__builtin_copysignq\\).*my_copysignq2" } } */ +/* { dg-final { scan-assembler-not "my_infq2:.*\\bl\t%plt\\(__builtin_infq\\).*my_infq2" } } */ +/* { dg-final { scan-assembler-not "my_huge_valq2:.*\\bl\t%plt\\(__builtin_huge_valq\\).*my_huge_valq2" } } */ +/* { dg-final { scan-assembler-not "my_nanq2:.*\\bl\t%plt\\(__builtin_nanq\\).*my_nanq2" } } */ +/* { dg-final { scan-assembler-not "my_nansq2:.*\\bl\t%plt\\(__builtin_nansq\\).*my_nansq2" } } */ + +__float128 +my_fabsq1 (__float128 a) +{ + return __builtin_fabsq (a); +} + +_Float128 +my_fabsq2 (_Float128 a) +{ + return __builtin_fabsq (a); +} + +__float128 +my_copysignq1 (__float128 a, __float128 b) +{ + return __builtin_copysignq (a, b); +} + +_Float128 +my_copysignq2 (_Float128 a, _Float128 b) +{ + return __builtin_copysignq (a, b); +} + +__float128 +my_infq1 (void) +{ + return __builtin_infq (); +} + +_Float128 +my_infq2 (void) +{ + return __builtin_infq (); +} + +__float128 +my_huge_valq1 (void) +{ + return __builtin_huge_valq (); +} + +_Float128 +my_huge_valq2 (void) +{ + return __builtin_huge_valq (); +} + +__float128 +my_nanq1 (void) +{ + return __builtin_nanq (""); +} + +_Float128 +my_nanq2 (void) +{ + return __builtin_nanq (""); +} + +__float128 +my_nansq1 (void) +{ + return __builtin_nansq (""); +} + +_Float128 +my_nansq2 (void) +{ + return __builtin_nansq (""); +} +