C++程序  |  393行  |  9.58 KB


#include <stdio.h>
#include <string.h>

typedef  unsigned long long int  ULong;
typedef  unsigned int            UInt;

__attribute__((noinline)) float s32_to_f32_imm1(int x)
{
    float y;
    __asm__ ("vcvt.f32.s32 %0, %1, #1" : "=w"(y) : "0"(x));
    return y;
}

__attribute__((noinline)) float s32_to_f32_imm32(int x)
{
    float y;
    __asm__ ("vcvt.f32.s32 %0, %1, #32" : "=w"(y) : "0"(x));
    return y;
}

void try_s32_to_f32 ( int x )
{
  float f32 = s32_to_f32_imm32(x);
  printf("s32_to_f32_imm32:  %11d  ->  %18.14e\n", x, (double)f32);
  f32 = s32_to_f32_imm1(x);
  printf("s32_to_f32_imm1:   %11d  ->  %18.14e\n", x, (double)f32);
}



__attribute__((noinline)) float u32_to_f32_imm1(int x)
{
    float y;
    __asm__ ("vcvt.f32.u32 %0, %1, #1" : "=w"(y) : "0"(x));
    return y;
}

__attribute__((noinline)) float u32_to_f32_imm32(int x)
{
    float y;
    __asm__ ("vcvt.f32.u32 %0, %1, #32" : "=w"(y) : "0"(x));
    return y;
}

void try_u32_to_f32 ( unsigned int x )
{
  float f32 = u32_to_f32_imm32(x);
  printf("u32_to_f32_imm32:  %11u  ->  %18.14e\n", x, (double)f32);
  f32 = u32_to_f32_imm1(x);
  printf("u32_to_f32_imm1:   %11u  ->  %18.14e\n", x, (double)f32);
}



__attribute__((noinline)) double s32_to_f64_imm1(int x)
{
    double block[2];
    memset(block, 0x55, sizeof(block));
    __asm__ __volatile__(
       "mov r8, %1"               "\n\t"
       "vldr d14, [%0, #8]"       "\n\t" // d14 <- junk
       "vmov s1, r8"              "\n\t"
       "vcvt.f64.s32 d14,d14,#1"  "\n\t"
       "vstr d14, [%0]"           "\n\t"
       : : /*IN*/"r"(&block[0]), "r"(x) : /*TRASH*/"r8","s28","d14","memory"
    );
    return block[0];
}

__attribute__((noinline)) double s32_to_f64_imm32(int x)
{
    double block[2];
    memset(block, 0x55, sizeof(block));
    __asm__ __volatile__(
       "mov r8, %1"                "\n\t"
       "vldr d14, [%0, #8]"        "\n\t" // d14 <- junk
       "vmov s28, r8"              "\n\t"
       "vcvt.f64.s32 d14,d14,#32"  "\n\t"
       "vstr d14, [%0]"            "\n\t"
       : : /*IN*/"r"(&block[0]), "r"(x) : /*TRASH*/"r8","s28","d14","memory"
    );
    return block[0];
}

void try_s32_to_f64 ( int x )
{
  double f64 = s32_to_f64_imm32(x);
  printf("s32_to_f64_imm32:  %11d  ->  %18.14e\n", x, f64);
  f64 = s32_to_f64_imm1(x);
  printf("s32_to_f64_imm1:   %11d  ->  %18.14e\n", x, f64);
}



__attribute__((noinline)) double u32_to_f64_imm1(int x)
{
    double block[2];
    memset(block, 0x55, sizeof(block));
    __asm__ __volatile__(
       "mov r8, %1"               "\n\t"
       "vldr d14, [%0, #8]"       "\n\t" // d14 <- junk
       "vmov s28, r8"             "\n\t"
       "vcvt.f64.u32 d14,d14,#1"  "\n\t"
       "vstr d14, [%0]"           "\n\t"
       : : /*IN*/"r"(&block[0]), "r"(x) : /*TRASH*/"r8","s28","d14","memory"
    );
    return block[0];
}

__attribute__((noinline)) double u32_to_f64_imm32(int x)
{
    double block[2];
    memset(block, 0x55, sizeof(block));
    __asm__ __volatile__(
       "mov r8, %1"                "\n\t"
       "vldr d14, [%0, #8]"        "\n\t" // d14 <- junk
       "vmov s28, r8"              "\n\t"
       "vcvt.f64.u32 d14,d14,#32"  "\n\t"
       "vstr d14, [%0]"            "\n\t"
       : : /*IN*/"r"(&block[0]), "r"(x) : /*TRASH*/"r8","s28","d14","memory"
    );
    return block[0];
}

void try_u32_to_f64 ( int x )
{
  double f64 = u32_to_f64_imm32(x);
  printf("u32_to_f64_imm32:  %11d  ->  %18.14e\n", x, f64);
  f64 = u32_to_f64_imm1(x);
  printf("u32_to_f64_imm1:   %11d  ->  %18.14e\n", x, f64);
}



__attribute__((noinline)) ULong f64_to_s32_imm1 ( double d )
{
  double block[5];
  memset(block, 0x55, sizeof(block));
  block[1] = d;
  __asm__ __volatile__(
    "mov r8, %0"               "\n\t"
    "vldr d14, [r8, #8]"       "\n\t"
    "vcvt.s32.f64 d14,d14,#1"  "\n\t"
    "vstr d14, [r8,#24]"       "\n\t"
    : : /*IN*/"r"(&block[0]) : /*TRASH*/"d14","r8","memory"
  );
  return *(ULong*)(&block[3]);
}

__attribute__((noinline)) ULong f64_to_s32_imm32 ( double d )
{
  double block[5];
  memset(block, 0x55, sizeof(block));
  block[1] = d;
  __asm__ __volatile__(
    "mov r8, %0"                "\n\t"
    "vldr d14, [r8, #8]"        "\n\t"
    "vcvt.s32.f64 d14,d14,#32"  "\n\t"
    "vstr d14, [r8,#24]"        "\n\t"
    : : /*IN*/"r"(&block[0]) : /*TRASH*/"d14","r8","memory"
  );
  return *(ULong*)(&block[3]);
}

void try_f64_to_s32 ( double d )
{
  ULong res = f64_to_s32_imm32(d);
  printf("f64_to_s32_imm32:  %18.14e  ->  0x%016llx\n", d, res);
  res = f64_to_s32_imm1(d);
  printf("f64_to_s32_imm1:   %18.14e  ->  0x%016llx\n", d, res);
}



__attribute__((noinline)) ULong f64_to_u32_imm1 ( double d )
{
  double block[5];
  memset(block, 0x55, sizeof(block));
  block[1] = d;
  __asm__ __volatile__(
    "mov r8, %0"               "\n\t"
    "vldr d14, [r8, #8]"       "\n\t"
    "vcvt.u32.f64 d14,d14,#1"  "\n\t"
    "vstr d14, [r8,#24]"       "\n\t"
    : : /*IN*/"r"(&block[0]) : /*TRASH*/"d14","r8","memory"
  );
  return *(ULong*)(&block[3]);
}

__attribute__((noinline)) ULong f64_to_u32_imm32 ( double d )
{
  double block[5];
  memset(block, 0x55, sizeof(block));
  block[1] = d;
  __asm__ __volatile__(
    "mov r8, %0"                "\n\t"
    "vldr d14, [r8, #8]"        "\n\t"
    "vcvt.u32.f64 d14,d14,#32"  "\n\t"
    "vstr d14, [r8,#24]"        "\n\t"
    : : /*IN*/"r"(&block[0]) : /*TRASH*/"d14","r8","memory"
  );
  return *(ULong*)(&block[3]);
}

void try_f64_to_u32 ( double d )
{
  ULong res = f64_to_u32_imm32(d);
  printf("f64_to_u32_imm32:  %18.14e  ->  0x%016llx\n", d, res);
  res = f64_to_u32_imm1(d);
  printf("f64_to_u32_imm1:   %18.14e  ->  0x%016llx\n", d, res);
}



__attribute__((noinline)) UInt f32_to_s32_imm1 ( float f )
{
  float block[5];
  memset(block, 0x55, sizeof(block));
  block[1] = f;
  __asm__ __volatile__(
    "mov r8, %0"               "\n\t"
    "vldr s14, [r8, #4]"       "\n\t"
    "vcvt.s32.f32 s14,s14,#1"  "\n\t"
    "vstr s14, [r8,#12]"       "\n\t"
    : : /*IN*/"r"(&block[0]) : /*TRASH*/"s14","r8","memory"
  );
  return *(UInt*)(&block[3]);
}

__attribute__((noinline)) UInt f32_to_s32_imm32 ( float f )
{
  float block[5];
  memset(block, 0x55, sizeof(block));
  block[1] = f;
  __asm__ __volatile__(
    "mov r8, %0"               "\n\t"
    "vldr s14, [r8, #4]"       "\n\t"
    "vcvt.s32.f32 s14,s14,#32" "\n\t"
    "vstr s14, [r8,#12]"       "\n\t"
    : : /*IN*/"r"(&block[0]) : /*TRASH*/"s14","r8","memory"
  );
  return *(UInt*)(&block[3]);
}

void try_f32_to_s32 ( float f )
{
  UInt res = f32_to_s32_imm32(f);
  printf("f32_to_s32_imm32:  %18.14e  ->  0x%08x\n", (double)f, res);
  res = f32_to_s32_imm1(f);
  printf("f32_to_s32_imm1:   %18.14e  ->  0x%08x\n", (double)f, res);
}



__attribute__((noinline)) UInt f32_to_u32_imm1 ( float f )
{
  float block[5];
  memset(block, 0x55, sizeof(block));
  block[1] = f;
  __asm__ __volatile__(
    "mov r8, %0"               "\n\t"
    "vldr s14, [r8, #4]"       "\n\t"
    "vcvt.u32.f32 s14,s14,#1"  "\n\t"
    "vstr s14, [r8,#12]"       "\n\t"
    : : /*IN*/"r"(&block[0]) : /*TRASH*/"s14","r8","memory"
  );
  return *(UInt*)(&block[3]);
}

__attribute__((noinline)) UInt f32_to_u32_imm32 ( float f )
{
  float block[5];
  memset(block, 0x55, sizeof(block));
  block[1] = f;
  __asm__ __volatile__(
    "mov r8, %0"               "\n\t"
    "vldr s14, [r8, #4]"       "\n\t"
    "vcvt.u32.f32 s14,s14,#32" "\n\t"
    "vstr s14, [r8,#12]"       "\n\t"
    : : /*IN*/"r"(&block[0]) : /*TRASH*/"s14","r8","memory"
  );
  return *(UInt*)(&block[3]);
}

void try_f32_to_u32 ( float f )
{
  UInt res = f32_to_u32_imm32(f);
  printf("f32_to_u32_imm32:  %18.14e  ->  0x%08x\n", (double)f, res);
  res = f32_to_u32_imm1(f);
  printf("f32_to_u32_imm1:   %18.14e  ->  0x%08x\n", (double)f, res);
}



int main ( void  )
{
  int i;
  double d;

  try_s32_to_f32(0);
  try_s32_to_f32(1);
  for (i = 100; i < 200; i++) {
     try_s32_to_f32(i);
  }
  try_s32_to_f32(0x7FFFFFFE);
  try_s32_to_f32(0x7FFFFFFF);
  try_s32_to_f32(0x80000000);
  try_s32_to_f32(0x80000001);
  try_s32_to_f32(0xFFFFFFFE);
  try_s32_to_f32(0xFFFFFFFF);

  printf("\n");

  try_u32_to_f32(0);
  try_u32_to_f32(1);
  for (i = 100; i < 200; i++) {
     try_u32_to_f32(i);
  }
  try_u32_to_f32(0x7FFFFFFE);
  try_u32_to_f32(0x7FFFFFFF);
  try_u32_to_f32(0x80000000);
  try_u32_to_f32(0x80000001);
  try_u32_to_f32(0xFFFFFFFE);
  try_u32_to_f32(0xFFFFFFFF);

  printf("\n");

  try_s32_to_f64(0);
  try_s32_to_f64(1);
  for (i = 100; i < 200; i++) {
     try_s32_to_f64(i);
  }
  try_s32_to_f64(0x7FFFFFFE);
  try_s32_to_f64(0x7FFFFFFF);
  try_s32_to_f64(0x80000000);
  try_s32_to_f64(0x80000001);
  try_s32_to_f64(0xFFFFFFFE);
  try_s32_to_f64(0xFFFFFFFF);

  printf("\n");

  try_u32_to_f64(0);
  try_u32_to_f64(1);
  for (i = 100; i < 200; i++) {
     try_u32_to_f64(i);
  }
  try_u32_to_f64(0x7FFFFFFE);
  try_u32_to_f64(0x7FFFFFFF);
  try_u32_to_f64(0x80000000);
  try_u32_to_f64(0x80000001);
  try_u32_to_f64(0xFFFFFFFE);
  try_u32_to_f64(0xFFFFFFFF);

  printf("\n");
  try_f64_to_s32(0.0);
  try_f64_to_s32(1.0);
  try_f64_to_s32(-1.0);
  try_f64_to_s32(0.0 / 0.0);
  for (d = -100000.01; d < 100000.0; d += 10000.0) {
     try_f64_to_s32(d);
  }

  printf("\n");
  try_f64_to_u32(0.0);
  try_f64_to_u32(1.0);
  try_f64_to_u32(-1.0);
  try_f64_to_u32(0.0 / 0.0);
  for (d = -100000.01; d < 100000.0; d += 10000.0) {
     try_f64_to_u32(d);
  }

  printf("\n");
  try_f32_to_s32(0.0);
  try_f32_to_s32(1.0);
  try_f32_to_s32(-1.0);
  try_f32_to_s32(0.0 / 0.0);
  for (d = -100000.01; d < 100000.0; d += 10000.0) {
     try_f32_to_s32((float)d);
  }

  printf("\n");
  try_f32_to_u32(0.0);
  try_f32_to_u32(1.0);
  try_f32_to_u32(-1.0);
  try_f32_to_u32(0.0 / 0.0);
  for (d = -100000.01; d < 100000.0; d += 10000.0) {
     try_f32_to_u32((float)d);
  }

  return 0;
}