/* * Check that denormalised values are respected when they appear as input to * floating point operations copy, add, sub, abs, neg and convert s<->d * * The Cirrus Logic MaverickCrunch FPU truncates all denorms to 0 when they are * present as inputs to these operations. * * We check by doing math on the tiniest values. */ typedef unsigned long long ull; typedef unsigned long ul; union fl { float f; ul l; } uf; union dl { double d; ull ll; } ud; /* Construct a float/double from literal bit pattern */ #define ultof(ul) ( uf.l = (ul), uf.f ) #define ulltod(ull) ( ud.ll = (ull), ud.d ) int failed = 0; check_float() { register float one asm ("mvf3") = ultof(0x00000001UL); register float minus_one asm ("mvf4") = ultof(0x80000001UL); if (-one != minus_one) failed++; if (-minus_one != one) failed++; } check_double() { register double one asm ("mvd3") = ulltod(0x0000000000000001ULL); register double minus_one asm ("mvd4") = ulltod(0x8000000000000001ULL); if (-one != minus_one) failed++; if (-minus_one != one) failed++; } int main() { check_float(); check_double(); if (failed) abort (); else exit (0); }