ph_tfpu.c 8.38 KB
//A: '--has-fpack --has-fhalf'
////C: '-daiteq-fpu-type=daifpu_dual_sphp_divsqrt -O3'
//C: '-g -O3 -daiteq-fpu-type=daifpu_php_none'


#define opcode_FABSH(A, RES)                                                   \
  *((half *)&RES) = fabsh(*((half *)&A))

#define opcode_FMOVHU(A, B, RES)                                               \
  RES.h[0]=A.h[0]; RES.h[1]=B.h[0]

#define opcode_FMOVHL(A, B, RES)                                               \
  RES.h[0]=A.h[1]; RES.h[1]=B.h[1]

#define opcode_FMOVHUL(A, B, RES)                                              \
  RES.h[0]=A.h[0]; RES.h[1]=B.h[1]

#define opcode_FMOVHLU(A, B, RES)                                              \
  RES.h[0]=A.h[1]; RES.h[1]=B.h[0]

#define opcode_FSWAPH(A, RES)                                                  \
  RES.h[0]=A.h[1]; RES.h[1]=A.h[0]

#define opcode_FMOVHZU(A, RES)                                                 \
  RES.h[0]=0.0H; RES.h[1]=A.h[0]

#define opcode_FMOVHZL(A, RES)                                                 \
  RES.h[0]=0.0H; RES.h[1]=A.h[1]

#define opcode_FSQRTH(A, RES)                                                  \
  RES.h[0] = sqrth(A.h[0])

#define opcode_FADDH(A, B, RES)                                                \
  RES.h[0] = A.h[0] + B.h[0]
#define opcode_FADDS(A, B, RES)                                                \
  RES.f = A.f + B.f


#define PGMNAME "testfpu"


typedef struct test_item {
  //char opcode[11];
  int opcode;
  unsigned opa;
  unsigned opb;
  unsigned reference;
  unsigned nextgrp;
} test_item_type;

//typedef struct test_item_long {
  //char opcode[11];
  //unsigned opal, opau;
  //unsigned opbl, opbu;
  //unsigned referenceu, referencel;
  //unsigned nextgrp;
//} test_item_long_type;


#if (!defined(GCC))
typedef half phalf __attribute__((ext_vector_type(2)));
typedef float pfloat __attribute__((ext_vector_type(2)));
#else
#define half float
typedef struct phalf {
    half x;
    half y;
} phalf;
typedef struct pfloat {
    float x;
    float y;
} pfloat;
#endif

typedef union fp32 {
/*
  struct {
    half up;
    half dn;
  } sth;
*/
  half h[2];
  phalf ph;
  float f;
  unsigned u;
} fp32;

typedef union fp64 {
/*
  struct {
    float up;
    float dn;
  } stf;
*/
  pfloat ps;
  double d;
  float f[2];
  unsigned u[2];
} fp64;


//#include "vectors_32b.h"
//#include "vectors_64b.h"

enum fpop_enum_type {
  NONE = 0,

  FMOVH,
  FMOVHU,
  FMOVHL,
  FMOVHUL,
  FMOVHLU,
  FSWAPH,
  FMOVHZU,
  FMOVHZL,
  
  FADDH,
  FADDS,

  FABSH,
  FSQRTH,

  MAX_FPOP
};

const test_item_type TEST[] = {
  {FMOVH, 0x12345678, 0x23456789, 0x12340000, 3},
  {FMOVHU, 0x12345678, 0x23456789, 0x12342345, 3},
  {FMOVHL, 0x12345678, 0x23456789, 0x56786789, 3},
  {FMOVHUL, 0x12345678, 0x23456789, 0x12346789, 3},
  {FMOVHLU, 0x12345678, 0x23456789, 0x56782345, 3},
  {FSWAPH, 0x12345678, 0x23456789, 0x56781234, 3},
  {FMOVHZU, 0x12345678, 0x23456789, 0x00001234, 3},
  {FMOVHZL, 0x12345678, 0x23456789, 0x00005678, 3},
  {FADDH, 0x12345678, 0x23456789, 0x00005678, 3},
  {FADDS, 0x12345678, 0x23456789, 0x00005678, 3},
};
#define TEST_SIZE (sizeof(TEST)/(sizeof(test_item_type)))


//const unsigned test_32b[3]={562, 581, TEST_SIZE};

int main(void) {
unsigned i, j, reference, referenceu, referencel;
unsigned long opad, opbd, resultd;
enum fpop_enum_type oper;

volatile fp32 opa, opb, result;

unsigned failcnt;

  failcnt = 0;

  i=0;
  while (i<TEST_SIZE) {

    oper = TEST[i].opcode;

    opa.u = TEST[i].opa;
    opb.u = TEST[i].opb;
    reference = TEST[i].reference;

    if (1)
    {
      //printf("%d %s\n",i,TEST[i].opcode);
//       i_print(i); m_putchar(' '); i_print(oper); m_putchar(0xa);
      result.u = 0;
      switch (oper) {
        //case FITOH:
          //opcode_FITOH(opa, result);
          //break;
        //case FITOS:
          //opcode_FITOS(opa, result);
          //break;
        //case FHTOI:
          //opcode_FHTOI(opa, result);
          //break;
        //case FSTOI:
          //opcode_FSTOI(opa, result);
          //break;
        //case FSTOH:
          //opcode_FSTOH(opa, result);
          //break;
        //case FHTOS:
          //opcode_FHTOS(opa, result);
          //break;
        //case FMOVH:
          //opcode_FMOVH(opa, result);
          //break;
        //case FMOVS:
          //opcode_FMOVS(opa, result);
          //break;
        //case FNEGH:
          //opcode_FNEGH(opa, result);
          //break;
        //case FNEGS:
          //opcode_FNEGS(opa, result);
          //break;
        case FABSH:
          opcode_FABSH(opa, result);
          break;
        //case FABSS:
          //opcode_FABSS(opa, result);
          //break;
        case FMOVHU:
          opcode_FMOVHU(opa, opb, result);
          break;
        case FMOVHL:
          opcode_FMOVHL(opa, opb, result);
          break;
        case FMOVHUL:
          opcode_FMOVHUL(opa, opb, result);
          break;
        case FMOVHLU:
          opcode_FMOVHLU(opa, opb, result);
          break;
        case FSWAPH:
          opcode_FSWAPH(opa, result);
          break;
        case FMOVHZU:
          opcode_FMOVHZU(opa, result);
          break;
        case FMOVHZL:
          opcode_FMOVHZL(opa, result);
          break;
        case FSQRTH:
          opcode_FSQRTH(opa, result);
          break;
        //case FSQRTS:
          //opcode_FSQRTS(opa, result);
          //break;
        case FADDH:
          opcode_FADDH(opa, opb, result);
          break;
        case FADDS:
          opcode_FADDS(opa, opb, result);
          break;
        //case FSUBH:
          //opcode_FSUBH(opa, opb, result);
          //break;
        //case FSUBS:
          //opcode_FSUBS(opa, opb, result);
          //break;
        //case FMULH:
          //opcode_FMULH(opa, opb, result);
          //break;
        //case FMULS:
          //opcode_FMULS(opa, opb, result);
          //break;
        //case FHMULS:
          //opcode_FHMULS(opa, opb, result);
          //break;
        //case FDIVH:
          //opcode_FDIVH(opa, opb, result);
          //break;
        //case FDIVS:
          //opcode_FDIVS(opa, opb, result);
          //break;
        //case FADDPH:
          //opcode_FADDPH(opa, opb, result);
          //break;
        //case FSUBPH:
          //opcode_FSUBPH(opa, opb, result);
          //break;
        //case FADDSUBRPH:
          //opcode_FADDSUBRPH(opa, opb, result);
          //break;
        //case FSUBADDRPH:
          //opcode_FSUBADDRPH(opa, opb, result);
          //break;
        //case FMULPH:
          //opcode_FMULPH(opa, opb, result);
          //break;
        //case FDIVPH:
          //opcode_FDIVPH(opa, opb, result);
          //break;
        //case FSQRTPH:
          //opcode_FSQRTPH(opa, result);
          //break;
        //case FADDRPH:
          //opcode_FADDRPH(opa, opb, result);
          //break;
        //case FSUBRPH:
          //opcode_FSUBRPH(opa, opb, result);
          //break;
        //case FMULRPH:
          //opcode_FMULRPH(opa, opb, result);
          //break;
        //case FDIVRPH:
          //opcode_FDIVRPH(opa, opb, result);
          //break;
        //case FADDXPH:
          //opcode_FADDXPH(opa, opb, result);
          //break;
        //case FSUBXPH:
          //opcode_FSUBXPH(opa, opb, result);
          //break;
        //case FMULXPH:
          //opcode_FMULXPH(opa, opb, result);
          //break;
        //case FDIVXPH:
          //opcode_FDIVXPH(opa, opb, result);
          //break;
        //case FCMPH:
          //opcode_FCMPH(opa, opb, result);
          //break;
        //case FCMPS:
          //opcode_FCMPS(opa, opb, result);
          //break;
        //case FCMPEH:
          //opcode_FCMPEH(opa, opb, result);
          //break;
        //case FCMPES:
          //opcode_FCMPES(opa, opb, result);
          //break;
        //case FCMPPH:
          //opcode_FCMPPH(opa, opb, result);
          //break;
        //case FCMPEPH:
          //opcode_FCMPEPH(opa, opb, result);
          //break;
        default:
          //m_print((unsigned char *)"ILLEGAL SP OPCODE\n");
          break;
      }

      if (result.u != reference) 
      {
        //printf("FPU ERROR - OPCODE %s OPA %08X OPB %08X : EXPECTED %08X ACTUAL %08X\n", TEST[i].opcode, opa.u, opb.u, reference, result.u);
        failcnt++;
      }
      i++;
    }
  }


  //printf("\n\n");
  if (failcnt)
    return failcnt;
    //printf("END OF TEST\n");
  //else
    //printf("TEST COMPLETED WITH ERRORS\n");

  __asm__ volatile (
    "\t ta 1\n"
    "\t nop\n"
    "\t nop\n"
  );

  return 0;
}