Currently for a signbit operation instructions tc{f,d,x}b + ipm + srl are emitted. If the source operand is a MEM, then a load precedes the sequence. A faster implementation is by issuing a load either from a REG or MEM into a GPR followed by a shift.
In spirit of the signbit function of the C standard, the signbit optab only guarantees that the resulting value is nonzero if the signbit is set. The common code implementation computes a value where the signbit is stored in the most significant bit, i.e., all other bits are just masked out, whereas the current implementation of s390 results in a value where the signbit is stored in the least significant bit. Although, there is no guarantee where the signbit is stored, keep the current behaviour and, therefore, implement the signbit optab manually. Since z10, instruction lgdr can be effectively used for a 64-bit FPR-to-GPR load. However, there exists no 32-bit pendant. Thus, for target z10 make use of post-reload splitters which emit either a 64-bit or a 32-bit load depending on whether the source operand is a REG or a MEM and a corresponding 63 or 31-bit shift. We can do without post-reload splitter in case of vector extensions since there we also have a 32-bit VR-to-GPR load via instruction vlgvf. gcc/ChangeLog: * config/s390/s390.md (signbit_tdc): Rename expander. (signbit<mode>2): New expander. (signbit<mode>2_z10): New expander. gcc/testsuite/ChangeLog: * gcc.target/s390/isfinite-isinf-isnormal-signbit-2.c: Adapt scan assembler directives. * gcc.target/s390/isfinite-isinf-isnormal-signbit-3.c: Ditto. * gcc.target/s390/signbit-1.c: New test. * gcc.target/s390/signbit-2.c: New test. * gcc.target/s390/signbit-3.c: New test. * gcc.target/s390/signbit-4.c: New test. * gcc.target/s390/signbit-5.c: New test. * gcc.target/s390/signbit.h: New test. --- gcc/config/s390/s390.md | 83 +++++++++- .../s390/isfinite-isinf-isnormal-signbit-2.c | 6 +- .../s390/isfinite-isinf-isnormal-signbit-3.c | 6 +- gcc/testsuite/gcc.target/s390/signbit-1.c | 40 +++++ gcc/testsuite/gcc.target/s390/signbit-2.c | 40 +++++ gcc/testsuite/gcc.target/s390/signbit-3.c | 152 ++++++++++++++++++ gcc/testsuite/gcc.target/s390/signbit-4.c | 55 +++++++ gcc/testsuite/gcc.target/s390/signbit-5.c | 35 ++++ gcc/testsuite/gcc.target/s390/signbit.h | 36 +++++ 9 files changed, 448 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.target/s390/signbit-1.c create mode 100644 gcc/testsuite/gcc.target/s390/signbit-2.c create mode 100644 gcc/testsuite/gcc.target/s390/signbit-3.c create mode 100644 gcc/testsuite/gcc.target/s390/signbit-4.c create mode 100644 gcc/testsuite/gcc.target/s390/signbit-5.c create mode 100644 gcc/testsuite/gcc.target/s390/signbit.h diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 02bc149b0fb..1edbfde4a98 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -121,6 +121,7 @@ ; Test Data Class (TDC) UNSPEC_TDC_INSN + UNSPEC_SIGNBIT ; Byte-wise Population Count UNSPEC_POPCNT @@ -513,7 +514,7 @@ S390_TDC_INFINITY S390_TDC_NORMAL_BFP]) -(define_int_attr tdc_insn [(S390_TDC_SIGNBIT_SET "signbit") +(define_int_attr tdc_insn [(S390_TDC_SIGNBIT_SET "signbit_tdc") (S390_TDC_FINITE "isfinite") (S390_TDC_INFINITY "isinf") (S390_TDC_NORMAL_BFP "isnormal") @@ -3782,6 +3783,86 @@ (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))] "TARGET_HARD_DFP") +(define_mode_iterator SIGNBIT_SINGLE [(SF "TARGET_HARD_FLOAT") + (SD "TARGET_HARD_DFP")]) +(define_expand "signbit<mode>2" + [(match_operand:SI 0 "register_operand") + (match_operand:SIGNBIT_SINGLE 1 "nonimmediate_operand")] + "" +{ + if (TARGET_VX && TARGET_64BIT) + { + emit_insn (gen_rtx_SET (operands[0], simplify_gen_subreg (SImode, operands[1], <MODE>mode, 0))); + emit_insn (gen_rtx_SET (operands[0], gen_rtx_LSHIFTRT (SImode, operands[0], GEN_INT (31)))); + } + else if (TARGET_Z10 && TARGET_64BIT) + emit_insn (gen_signbit<mode>2_z10 (operands[0], operands[1])); + else + emit_insn (gen_signbit_tdc<mode>2 (operands[0], force_reg (<MODE>mode, operands[1]))); + DONE; +}) + +(define_insn "signbit<mode>2_z10" + [(set (match_operand:SI 0 "register_operand" "=d") + (unspec:SI [(match_operand:SIGNBIT_SINGLE 1 "nonimmediate_operand" "fRT")] + UNSPEC_SIGNBIT))] + "TARGET_Z10 && TARGET_64BIT" + "#") + +(define_split + [(set (match_operand:SI 0 "register_operand") + (unspec:SI [(match_operand:SIGNBIT_SINGLE 1 "register_operand")] + UNSPEC_SIGNBIT))] + "TARGET_Z10 && TARGET_64BIT && reload_completed" + [(set (match_dup 0) (match_dup 1)) + (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 63)))] +{ + operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); + operands[1] = gen_rtx_REG (DImode, REGNO (operands[1])); +}) + +(define_split + [(set (match_operand:SI 0 "register_operand") + (unspec:SI [(match_operand:SIGNBIT_SINGLE 1 "memory_operand")] + UNSPEC_SIGNBIT))] + "TARGET_Z10 && TARGET_64BIT && reload_completed" + [(set (match_dup 0) (match_dup 1)) + (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))] +{ + operands[1] = change_address (operands[1], SImode, 0); +}) + +(define_mode_iterator SIGNBIT_DBL_TETRA [(DF "TARGET_HARD_FLOAT") + (TF "TARGET_HARD_FLOAT") + (DD "TARGET_HARD_DFP") + (TD "TARGET_HARD_DFP")]) +(define_expand "signbit<mode>2" + [(match_operand:SI 0 "register_operand") + (match_operand:SIGNBIT_DBL_TETRA 1 "nonimmediate_operand")] + "" +{ + if (TARGET_Z10 && TARGET_64BIT) + { + rtx reg_di = gen_reg_rtx (DImode); + if (<MODE>mode == TFmode || <MODE>mode == TDmode) + { + rtx reg_ti = gen_reg_rtx (TImode); + emit_insn (gen_rtx_SET (reg_ti, simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0))); + emit_insn (gen_rtx_SET (reg_di, simplify_gen_subreg (DImode, reg_ti, TImode, 0))); + } + else + emit_insn (gen_rtx_SET (reg_di, simplify_gen_subreg (DImode, operands[1], <MODE>mode, 0))); + emit_insn (gen_rtx_SET (reg_di, gen_rtx_LSHIFTRT (DImode, reg_di, GEN_INT (63)))); + rtx subreg = gen_rtx_SUBREG (SImode, reg_di, 4); + SUBREG_PROMOTED_VAR_P (subreg) = 1; + SUBREG_PROMOTED_SET (subreg, SRP_SIGNED_AND_UNSIGNED); + emit_insn (gen_rtx_SET (operands[0], subreg)); + } + else + emit_insn (gen_signbit_tdc<mode>2 (operands[0], force_reg (<MODE>mode, operands[1]))); + DONE; +}) + ; This extracts CC into a GPR properly shifted. The actual IPM ; instruction will be issued by reload. The constraint of operand 1 ; forces reload to use a GPR. So reload will issue a movcc insn for diff --git a/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-2.c b/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-2.c index 2ff5a37c0f0..e1c7806ad96 100644 --- a/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-2.c +++ b/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-2.c @@ -3,8 +3,10 @@ #include "isfinite-isinf-isnormal-signbit.h" -/* { dg-final { scan-assembler-times {tcxb\t%f[0-9]+,1365} 1 } } SIGNBIT long double */ -/* { dg-final { scan-assembler-times {tdcxt\t%f[0-9]+,1365} 1 } } SIGNBIT _Decimal128 */ +/* { dg-final { scan-assembler-times {tcxb\t%f[0-9]+,1365} 0 { target lp64 } } } SIGNBIT long double */ +/* { dg-final { scan-assembler-times {tdcxt\t%f[0-9]+,1365} 0 { target lp64 } } } SIGNBIT _Decimal128 */ +/* { dg-final { scan-assembler-times {tcxb\t%f[0-9]+,1365} 1 { target { ! lp64 } } } } SIGNBIT long double */ +/* { dg-final { scan-assembler-times {tdcxt\t%f[0-9]+,1365} 1 { target { ! lp64 } } } } SIGNBIT _Decimal128 */ /* { dg-final { scan-assembler-times {tcxb\t%f[0-9]+,4032} 1 } } ISFINITE long double */ /* { dg-final { scan-assembler-times {tdcxt\t%f[0-9]+,4032} 1 } } ISFINITE _Decimal128 */ /* { dg-final { scan-assembler-times {tcxb\t%f[0-9]+,48} 1 } } ISINF long double */ diff --git a/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-3.c b/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-3.c index 8f67553c7da..5c9986d0600 100644 --- a/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-3.c +++ b/gcc/testsuite/gcc.target/s390/isfinite-isinf-isnormal-signbit-3.c @@ -3,8 +3,10 @@ #include "isfinite-isinf-isnormal-signbit.h" -/* { dg-final { scan-assembler-times {wftcixb\t%v[0-9]+,%v[0-9]+,1365} 1 } } */ -/* { dg-final { scan-assembler-times {tdcxt\t%f[0-9]+,1365} 1 } } */ +/* { dg-final { scan-assembler-times {wftcixb\t%v[0-9]+,%v[0-9]+,1365} 0 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {tdcxt\t%f[0-9]+,1365} 0 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {wftcixb\t%v[0-9]+,%v[0-9]+,1365} 1 { target { ! lp64 } } } } */ +/* { dg-final { scan-assembler-times {tdcxt\t%f[0-9]+,1365} 1 { target { ! lp64 } } } } */ /* { dg-final { scan-assembler-times {wftcixb\t%v[0-9]+,%v[0-9]+,4032} 1 } } */ /* { dg-final { scan-assembler-times {tdcxt\t%f[0-9]+,4032} 1 } } */ /* { dg-final { scan-assembler-times {wftcixb\t%v[0-9]+,%v[0-9]+,48} 1 } } */ diff --git a/gcc/testsuite/gcc.target/s390/signbit-1.c b/gcc/testsuite/gcc.target/s390/signbit-1.c new file mode 100644 index 00000000000..45f608a3f28 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/signbit-1.c @@ -0,0 +1,40 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -march=z900 -save-temps" } */ +/* { dg-final { scan-assembler-times {\ttceb\t} 2 } } */ +/* { dg-final { scan-assembler-times {\ttcdb\t} 2 } } */ +/* { dg-final { scan-assembler-times {\ttcxb\t} 2 } } */ + +/* Binary Floating-Point */ + +__attribute__ ((noipa)) +int signbit_float_reg (float x) { return __builtin_signbit (x); } +__attribute__ ((noipa)) +int signbit_float_mem (float *x) { return __builtin_signbit (*x); } +__attribute__ ((noipa)) +int signbit_double_reg (double x) { return __builtin_signbit (x); } +__attribute__ ((noipa)) +int signbit_double_mem (double *x) { return __builtin_signbit (*x); } + +__attribute__ ((noipa)) +int +signbit_longdouble_reg (long double x) +{ + __asm__ ("" : "+f" (x)); + return __builtin_signbit (x); +} + +__attribute__ ((noipa)) +int signbit_longdouble_mem (long double *x) { return __builtin_signbit (*x); } + +#include "signbit.h" +TEST (float, float, __builtin_inff(), __builtin_nanf("42"), 0.f, 42.f) +TEST (double, double, __builtin_inf(), __builtin_nan("42"), 0., 42.) +TEST (longdouble, long double, __builtin_infl(), __builtin_nanl("42"), 0.L, 42.L) + +int +main (void) +{ + test_float (); + test_double (); + test_longdouble (); +} diff --git a/gcc/testsuite/gcc.target/s390/signbit-2.c b/gcc/testsuite/gcc.target/s390/signbit-2.c new file mode 100644 index 00000000000..488c477c891 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/signbit-2.c @@ -0,0 +1,40 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -march=z9-ec -mzarch -save-temps" } */ +/* { dg-final { scan-assembler-times {\ttdcet\t} 2 } } */ +/* { dg-final { scan-assembler-times {\ttdcdt\t} 2 } } */ +/* { dg-final { scan-assembler-times {\ttdcxt\t} 2 } } */ + +/* Decimal Floating-Point */ + +__attribute__ ((noipa)) +int signbit_dec32_reg (_Decimal32 x) { return __builtin_signbit (x); } +__attribute__ ((noipa)) +int signbit_dec32_mem (_Decimal32 *x) { return __builtin_signbit (*x); } +__attribute__ ((noipa)) +int signbit_dec64_reg (_Decimal64 x) { return __builtin_signbit (x); } +__attribute__ ((noipa)) +int signbit_dec64_mem (_Decimal64 *x) { return __builtin_signbit (*x); } + +__attribute__ ((noipa)) +int +signbit_dec128_reg (_Decimal128 x) +{ + __asm__ ("" : "+f" (x)); + return __builtin_signbit (x); +} + +__attribute__ ((noipa)) +int signbit_dec128_mem (_Decimal128 *x) { return __builtin_signbit (*x); } + +#include "signbit.h" +TEST (dec32, _Decimal32, __builtin_infd32(), __builtin_nand32("42"), 0.df, 42.df) +TEST (dec64, _Decimal64, __builtin_infd64(), __builtin_nand64("42"), 0.dd, 42.dd) +TEST (dec128, _Decimal128, __builtin_infd128(), __builtin_nand128("42"), 0.dl, 42.dl) + +int +main (void) +{ + test_dec32 (); + test_dec64 (); + test_dec128 (); +} diff --git a/gcc/testsuite/gcc.target/s390/signbit-3.c b/gcc/testsuite/gcc.target/s390/signbit-3.c new file mode 100644 index 00000000000..2fad58bf3be --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/signbit-3.c @@ -0,0 +1,152 @@ +/* { dg-do run { target lp64 } } */ +/* { dg-options "-O2 -march=z10 -save-temps" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* Binary Floating-Point */ + +/* +** signbit_float_reg: +** lgdr (%r[0-9]+),%f0 +** srlg (%r[0-9]+),\1,63 +** lgfr %r2,\2 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_float_reg (float x) { return __builtin_signbit (x); } + +/* +** signbit_float_mem: +** l (%r[0-9]+),0\(%r2\) +** srl \1,31 +** lgfr %r2,\1 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_float_mem (float *x) { return __builtin_signbit (*x); } + +/* +** signbit_double_reg: +** lgdr (%r[0-9]+),%f0 +** srlg %r2,\1,63 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_double_reg (double x) { return __builtin_signbit (x); } + +/* +** signbit_double_mem: +** lg (%r[0-9]+),0\(%r2\) +** srlg %r2,\1,63 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_double_mem (double *x) { return __builtin_signbit (*x); } + +/* +** signbit_longdouble_reg: +** ld %f0,0\(%r2\) +** ld %f2,8\(%r2\) +** lgdr (%r[0-9]+),%f0 +** srlg %r2,\1,63 +** br %r14 +*/ +__attribute__ ((noipa)) +int +signbit_longdouble_reg (long double x) +{ + __asm__ ("" : "+f" (x)); + return __builtin_signbit (x); +} + +/* +** signbit_longdouble_mem: +** lg (%r[0-9]+),0\(%r2\) +** srlg %r2,\1,63 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_longdouble_mem (long double *x) { return __builtin_signbit (*x); } + +/* Decimal Floating-Point */ + +/* +** signbit_dec32_reg: +** lgdr (%r[0-9]+),%f0 +** srlg (%r[0-9]+),\1,63 +** lgfr %r2,\2 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_dec32_reg (_Decimal32 x) { return __builtin_signbit (x); } + +/* +** signbit_dec32_mem: +** l (%r[0-9]+),0\(%r2\) +** srl \1,31 +** lgfr %r2,\1 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_dec32_mem (_Decimal32 *x) { return __builtin_signbit (*x); } + +/* +** signbit_dec64_reg: +** lgdr (%r[0-9]+),%f0 +** srlg %r2,\1,63 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_dec64_reg (_Decimal64 x) { return __builtin_signbit (x); } + +/* +** signbit_dec64_mem: +** lg (%r[0-9]+),0\(%r2\) +** srlg %r2,\1,63 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_dec64_mem (_Decimal64 *x) { return __builtin_signbit (*x); } + +/* +** signbit_dec128_reg: +** ld %f0,0\(%r2\) +** ld %f2,8\(%r2\) +** lgdr (%r[0-9]+),%f0 +** srlg %r2,\1,63 +** br %r14 +*/ +__attribute__ ((noipa)) +int +signbit_dec128_reg (_Decimal128 x) +{ + __asm__ ("" : "+f" (x)); + return __builtin_signbit (x); +} + +/* +** signbit_dec128_mem: +** lg (%r[0-9]+),0\(%r2\) +** srlg %r2,\1,63 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_dec128_mem (_Decimal128 *x) { return __builtin_signbit (*x); } + +#include "signbit.h" +TEST (float, float, __builtin_inff(), __builtin_nanf("42"), 0.f, 42.f) +TEST (double, double, __builtin_inf(), __builtin_nan("42"), 0., 42.) +TEST (longdouble, long double, __builtin_infl(), __builtin_nanl("42"), 0.L, 42.L) +TEST (dec32, _Decimal32, __builtin_infd32(), __builtin_nand32("42"), 0.df, 42.df) +TEST (dec64, _Decimal64, __builtin_infd64(), __builtin_nand64("42"), 0.dd, 42.dd) +TEST (dec128, _Decimal128, __builtin_infd128(), __builtin_nand128("42"), 0.dl, 42.dl) + +int +main (void) +{ + test_float (); + test_double (); + test_longdouble (); + test_dec32 (); + test_dec64 (); + test_dec128 (); +} diff --git a/gcc/testsuite/gcc.target/s390/signbit-4.c b/gcc/testsuite/gcc.target/s390/signbit-4.c new file mode 100644 index 00000000000..2cb743edc3a --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/signbit-4.c @@ -0,0 +1,55 @@ +/* { dg-do run { target lp64 } } */ +/* { dg-require-effective-target s390_vx } */ +/* { dg-options "-O2 -march=z13 -save-temps" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* Binary Floating-Point */ + +/* +** signbit_float_reg: +** vlgvf (%r[0-9]+),%v0,0 +** risbgn %r2,\1,64-1,128\+63,32\+1 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_float_reg (float x) { return __builtin_signbit (x); } + +/* +** signbit_float_mem: +** l (%r[0-9]+),0\(%r2\) +** risbgn %r2,\1,64-1,128\+63,32\+1 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_float_mem (float *x) { return __builtin_signbit (*x); } + +/* Decimal Floating-Point */ + +/* +** signbit_dec32_reg: +** vlgvf (%r[0-9]+),%v0,0 +** risbgn %r2,\1,64-1,128\+63,32\+1 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_dec32_reg (_Decimal32 x) { return __builtin_signbit (x); } + +/* +** signbit_dec32_mem: +** l (%r[0-9]+),0\(%r2\) +** risbgn %r2,\1,64-1,128\+63,32\+1 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_dec32_mem (_Decimal32 *x) { return __builtin_signbit (*x); } + +#include "signbit.h" +TEST (float, float, __builtin_inff(), __builtin_nanf("42"), 0.f, 42.f) +TEST (dec32, _Decimal32, __builtin_infd32(), __builtin_nand32("42"), 0.df, 42.df) + +int +main (void) +{ + test_float (); + test_dec32 (); +} diff --git a/gcc/testsuite/gcc.target/s390/signbit-5.c b/gcc/testsuite/gcc.target/s390/signbit-5.c new file mode 100644 index 00000000000..68403275f7c --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/signbit-5.c @@ -0,0 +1,35 @@ +/* { dg-do run { target lp64 } } */ +/* { dg-options "-O2 -march=z14 -save-temps" } */ + +/* +** signbit_longdouble_reg: +** ld %f0,0(%r2);ld %f2,8+0(%r2) +** lgdr (%r[0-9]+),%f0 +** srlg %r2,\1,63 +** br %r14 +*/ +__attribute__ ((noipa)) +int +signbit_longdouble_reg (long double x) +{ + __asm__ ("" : "+f" (x)); + return __builtin_signbit (x); +} + +/* +** signbit_longdouble_mem: +** lg (%r[0-9]+),0\(%r2\) +** srlg %r2,\1,63 +** br %r14 +*/ +__attribute__ ((noipa)) +int signbit_longdouble_mem (long double *x) { return __builtin_signbit (*x); } + +#include "signbit.h" +TEST (longdouble, long double, __builtin_infl(), __builtin_nanl("42"), 0.L, 42.L) + +int +main (void) +{ + test_longdouble (); +} diff --git a/gcc/testsuite/gcc.target/s390/signbit.h b/gcc/testsuite/gcc.target/s390/signbit.h new file mode 100644 index 00000000000..730e387752c --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/signbit.h @@ -0,0 +1,36 @@ +#define TEST(T, U, I, N, C0, C42) \ + void test_##T (void) \ + { \ + U tmp; \ + int x; \ + \ + x = signbit_##T##_reg(C42); \ + x += signbit_##T##_reg(C0); \ + x += signbit_##T##_reg(I); \ + x += signbit_##T##_reg(N); \ + tmp = C42; \ + x += signbit_##T##_mem(&tmp); \ + tmp = C0; \ + x += signbit_##T##_mem(&tmp); \ + tmp = I; \ + x += signbit_##T##_mem(&tmp); \ + tmp = N; \ + x += signbit_##T##_mem(&tmp); \ + if (x != 0) \ + __builtin_abort(); \ + \ + x = signbit_##T##_reg(-C42); \ + x += signbit_##T##_reg(-C0); \ + x += signbit_##T##_reg(-I); \ + x += signbit_##T##_reg(-N); \ + tmp = -C42; \ + x += signbit_##T##_mem(&tmp); \ + tmp = -C0; \ + x += signbit_##T##_mem(&tmp); \ + tmp = -I; \ + x += signbit_##T##_mem(&tmp); \ + tmp = -N; \ + x += signbit_##T##_mem(&tmp); \ + if (x != 8) \ + __builtin_abort(); \ + } -- 2.49.0