/*
 * 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);
}
