Christophe Lyon via Gcc-patches <gcc-patches@gcc.gnu.org> writes: > These tests exercise exception handling with Decimal Floating-Point > type. > > dfp-1.C and dfp-2.C check that thrown objects of such types are > properly caught, whether when using C++ classes (decimalXX) or via GCC > mode attributes. > > dfp-saves-aarch64.C checks that such objects are properly restored, > and has to use the mode attribute trick because objects of decimalXX > class type cannot be assigned to a register variable. > > 2022-05-03 Christophe Lyon <christophe.l...@arm.com> > > gcc/testsuite/ > * g++.dg/eh/dfp-1.C: New test. > * g++.dg/eh/dfp-2.C: New test. > * g++.dg/eh/dfp-saves-aarch64.C: New test. > --- > gcc/testsuite/g++.dg/eh/dfp-1.C | 54 +++++++++++++++++++++ > gcc/testsuite/g++.dg/eh/dfp-2.C | 54 +++++++++++++++++++++ > gcc/testsuite/g++.dg/eh/dfp-saves-aarch64.C | 49 +++++++++++++++++++ > 3 files changed, 157 insertions(+) > create mode 100644 gcc/testsuite/g++.dg/eh/dfp-1.C > create mode 100644 gcc/testsuite/g++.dg/eh/dfp-2.C > create mode 100644 gcc/testsuite/g++.dg/eh/dfp-saves-aarch64.C > > diff --git a/gcc/testsuite/g++.dg/eh/dfp-1.C b/gcc/testsuite/g++.dg/eh/dfp-1.C > new file mode 100644 > index 00000000000..b0da13a4cc5 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/eh/dfp-1.C > @@ -0,0 +1,54 @@ > +// { dg-do run } > +// { dg-require-effective-target dfp } > + > +extern "C" void abort (); > + > +#include <decimal/decimal> > + > +using namespace std::decimal; > + > +int > +foo (double fp) > +{ > + if (fp < 32.0) > + throw (decimal32)32; > + if (fp < 64.0) > + throw (decimal64)64; > + if (fp < 128.0) > + throw (decimal128)128; > + return 0; > +} > + > +int bar (double fp) > +{ > + try > + { > + foo (fp); > + abort (); > + } > + catch (decimal32 df) > + { > + if (df != (decimal32)32) > + abort (); > + } > + catch (decimal64 dd) > + { > + if (dd != (decimal64)64) > + abort (); > + } > + catch (decimal128 dl) > + { > + if (dl != (decimal128)128) > + abort (); > + } > + return 0; > +} > + > +int > +main () > +{ > + bar (10.0); > + bar (20.0); > + bar (100.0); > + return 0; > +} > diff --git a/gcc/testsuite/g++.dg/eh/dfp-2.C b/gcc/testsuite/g++.dg/eh/dfp-2.C > new file mode 100644 > index 00000000000..aff0e03d1d9 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/eh/dfp-2.C > @@ -0,0 +1,54 @@ > +// { dg-do run } > +// { dg-require-effective-target dfp } > + > +extern "C" void abort (); > + > +typedef float dec32 __attribute__((mode(SD))); > +typedef float dec64 __attribute__((mode(DD))); > +typedef float dec128 __attribute__((mode(TD))); > + > +int > +foo (double fp) > +{ > + if (fp < 32.0) > + throw (dec32)32; > + if (fp < 64.0) > + throw (dec64)64; > + if (fp < 128.0) > + throw (dec128)128; > + return 0; > +} > + > +int bar (double fp) > +{ > + try > + { > + foo (fp); > + abort (); > + } > + catch (dec32 df) > + { > + if (df != (dec32)32) > + abort (); > + } > + catch (dec64 dd) > + { > + if (dd != (dec64)64) > + abort (); > + } > + catch (dec128 dl) > + { > + if (dl != (dec128)128) > + abort (); > + } > + return 0; > +} > + > +int > +main () > +{ > + bar (10.0); > + bar (20.0); > + bar (100.0); > + return 0; > +} > diff --git a/gcc/testsuite/g++.dg/eh/dfp-saves-aarch64.C > b/gcc/testsuite/g++.dg/eh/dfp-saves-aarch64.C > new file mode 100644 > index 00000000000..79f6697dd10 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/eh/dfp-saves-aarch64.C > @@ -0,0 +1,49 @@ > +// { dg-do run { target aarch64*-*-* } } > +// { dg-require-effective-target dfp } > + > +/* Test unwinding of AArch64 register saves. */ > +/* We cannot use #include <decimal/decimal> because it defines > + decimal* types as classes, which we cannot be assigned to register
Typo: s/which we cannot/which cannot/. OK with that change, thanks. Richard > + variables. Hence the use the mode attribute trick. */ > + > +#ifdef __aarch64__ > + > +typedef float dec64 __attribute__((mode(DD))); > + > +extern "C" void abort (void); > +extern "C" void exit (int); > + > +void > +foo (void) > +{ > + register dec64 v10 asm("v10") = 0; > + register dec64 v11 asm("v11") = 1; > + register dec64 v12 asm("v12") = 2; > + register dec64 v13 asm("v13") = 3; > + asm volatile ("" : "+w" (v10), "+w" (v11), "+w" (v12), "+w" (v13)); > + throw ""; > +} > + > +int > +main (void) > +{ > + register dec64 v10 asm("v10") = 10; > + register dec64 v11 asm("v11") = 11; > + register dec64 v12 asm("v12") = 12; > + register dec64 v13 asm("v13") = 13; > + asm volatile ("" : "+w" (v10), "+w" (v11), "+w" (v12), "+w" (v13)); > + try { > + foo (); > + } catch (...) { > + asm volatile ("" : "+w" (v10), "+w" (v11), "+w" (v12), "+w" (v13)); > + if (v10 != 10 || v11 != 11 || v12 != 12 || v13 != 13) > + abort (); > + } > + exit (0); > +} > +#else > +int > +main (void) > +{ > +} > +#endif