Alien-TinyCCx

 view release on metacpan or  search on metacpan

src/tests/tcctest.c  view on Meta::CPAN

  s.b2 = 0;
  glob3 = 43;
  compare_comparisons (&s);
}

int fcompare (double a, double b, int code)
{
  switch (code) {
    case 0: return a == b;
    case 1: return a != b;
    case 2: return a < b;
    case 3: return a >= b;
    case 4: return a > b;
    case 5: return a <= b;
  }
}

void math_cmp_test(void)
{
  double nan = 0.0/0.0;
  double one = 1.0;
  double two = 2.0;
  int comp = 0;
#define bug(a,b,op,iop,part) printf("Test broken: %s %s %s %s %d\n", #a, #b, #op, #iop, part)

  /* This asserts that "a op b" is _not_ true, but "a iop b" is true.
     And it does this in various ways so that all code generation paths
     are checked (generating inverted tests, or non-inverted tests, or
     producing a 0/1 value without jumps (that's done in the fcompare
     function).  */
#define FCMP(a,b,op,iop,code) \
  if (fcompare (a,b,code))    \
    bug (a,b,op,iop,1); \
  if (a op b) \
    bug (a,b,op,iop,2); \
  if (a iop b) \
    ; \
  else \
    bug (a,b,op,iop,3); \
  if ((a op b) || comp) \
    bug (a,b,op,iop,4); \
  if ((a iop b) || comp) \
    ; \
  else \
    bug (a,b,op,iop,5);

  /* Equality tests.  */
  FCMP(nan, nan, ==, !=, 0);
  FCMP(one, two, ==, !=, 0);
  FCMP(one, one, !=, ==, 1);
  /* Non-equality is a bit special.  */
  if (!fcompare (nan, nan, 1))
    bug (nan, nan, !=, ==, 6);

  /* Relational tests on numbers.  */
  FCMP(two, one, <, >=, 2);
  FCMP(one, two, >=, <, 3);
  FCMP(one, two, >, <=, 4);
  FCMP(two, one, <=, >, 5);

  /* Relational tests on NaNs.  Note that the inverse op here is
     always !=, there's no operator in C that is equivalent to !(a < b),
     when NaNs are involved, same for the other relational ops.  */
  FCMP(nan, nan, <, !=, 2);
  FCMP(nan, nan, >=, !=, 3);
  FCMP(nan, nan, >, !=, 4);
  FCMP(nan, nan, <=, !=, 5);
}

double get100 () { return 100.0; }

void callsave_test(void)
{
#if defined __i386__ || defined __x86_64__ || defined __arm__
  int i, s; double *d; double t;
  s = sizeof (double);
  printf ("callsavetest: %d\n", s);
  d = alloca (sizeof(double));
  d[0] = 10.0;
  /* x86-64 had a bug were the next call to get100 would evict
     the lvalue &d[0] as VT_LLOCAL, and the reload would be done
     in int type, not pointer type.  When alloca returns a pointer
     with the high 32 bit set (which is likely on x86-64) the access
     generates a segfault.  */
  i = d[0] > get100 ();
  printf ("%d\n", i);
#endif
}


void bfa3(ptrdiff_t str_offset)
{
    printf("bfa3: %s\n", (char *)__builtin_frame_address(3) + str_offset);
}
void bfa2(ptrdiff_t str_offset)
{
    printf("bfa2: %s\n", (char *)__builtin_frame_address(2) + str_offset);
    bfa3(str_offset);
}
void bfa1(ptrdiff_t str_offset)
{
    printf("bfa1: %s\n", (char *)__builtin_frame_address(1) + str_offset);
    bfa2(str_offset);
}

void builtin_frame_address_test(void)
{
/* builtin_frame_address fails on ARM with gcc which make test3 fail */
#ifndef __arm__
    char str[] = "__builtin_frame_address";
    char *fp0 = __builtin_frame_address(0);

    printf("str: %s\n", str);
    bfa1(str-fp0);
#endif
}

char via_volatile (char i)
{
  char volatile vi;
  vi = i;
  return vi;
}



( run in 1.150 second using v1.01-cache-2.11-cpan-13bb782fe5a )