Home | History | Annotate | Download | only in arm
      1 
      2 #include <stdio.h>
      3 #include <string.h>
      4 
      5 typedef  unsigned long long int  ULong;
      6 
      7 __attribute__((noinline)) float s32_to_f32_imm1(int x)
      8 {
      9     float y;
     10     __asm__ ("vcvt.f32.s32 %0, %1, #1" : "=w"(y) : "0"(x));
     11     return y;
     12 }
     13 
     14 __attribute__((noinline)) float s32_to_f32_imm32(int x)
     15 {
     16     float y;
     17     __asm__ ("vcvt.f32.s32 %0, %1, #32" : "=w"(y) : "0"(x));
     18     return y;
     19 }
     20 
     21 void try_s32_to_f32 ( int x )
     22 {
     23   float f32 = s32_to_f32_imm32(x);
     24   printf("s32_to_f32_imm32:  %11d  ->  %18.14e\n", x, (double)f32);
     25   f32 = s32_to_f32_imm1(x);
     26   printf("s32_to_f32_imm1:   %11d  ->  %18.14e\n", x, (double)f32);
     27 }
     28 
     29 
     30 
     31 __attribute__((noinline)) float u32_to_f32_imm1(int x)
     32 {
     33     float y;
     34     __asm__ ("vcvt.f32.u32 %0, %1, #1" : "=w"(y) : "0"(x));
     35     return y;
     36 }
     37 
     38 __attribute__((noinline)) float u32_to_f32_imm32(int x)
     39 {
     40     float y;
     41     __asm__ ("vcvt.f32.u32 %0, %1, #32" : "=w"(y) : "0"(x));
     42     return y;
     43 }
     44 
     45 void try_u32_to_f32 ( unsigned int x )
     46 {
     47   float f32 = u32_to_f32_imm32(x);
     48   printf("u32_to_f32_imm32:  %11u  ->  %18.14e\n", x, (double)f32);
     49   f32 = u32_to_f32_imm1(x);
     50   printf("u32_to_f32_imm1:   %11u  ->  %18.14e\n", x, (double)f32);
     51 }
     52 
     53 
     54 
     55 __attribute__((noinline)) double s32_to_f64_imm1(int x)
     56 {
     57     double block[2];
     58     memset(block, 0x55, sizeof(block));
     59     __asm__ __volatile__(
     60        "mov r8, %1"               "\n\t"
     61        "vldr d14, [%0, #8]"       "\n\t" // d14 <- junk
     62        "vmov s1, r8"              "\n\t"
     63        "vcvt.f64.s32 d14,d14,#1"  "\n\t"
     64        "vstr d14, [%0]"           "\n\t"
     65        : : /*IN*/"r"(&block[0]), "r"(x) : /*TRASH*/"r8","s28","d14","memory"
     66     );
     67     return block[0];
     68 }
     69 
     70 __attribute__((noinline)) double s32_to_f64_imm32(int x)
     71 {
     72     double block[2];
     73     memset(block, 0x55, sizeof(block));
     74     __asm__ __volatile__(
     75        "mov r8, %1"                "\n\t"
     76        "vldr d14, [%0, #8]"        "\n\t" // d14 <- junk
     77        "vmov s28, r8"              "\n\t"
     78        "vcvt.f64.s32 d14,d14,#32"  "\n\t"
     79        "vstr d14, [%0]"            "\n\t"
     80        : : /*IN*/"r"(&block[0]), "r"(x) : /*TRASH*/"r8","s28","d14","memory"
     81     );
     82     return block[0];
     83 }
     84 
     85 void try_s32_to_f64 ( int x )
     86 {
     87   double f64 = s32_to_f64_imm32(x);
     88   printf("s32_to_f64_imm32:  %11d  ->  %18.14e\n", x, f64);
     89   f64 = s32_to_f64_imm1(x);
     90   printf("s32_to_f64_imm1:   %11d  ->  %18.14e\n", x, f64);
     91 }
     92 
     93 
     94 
     95 __attribute__((noinline)) double u32_to_f64_imm1(int x)
     96 {
     97     double block[2];
     98     memset(block, 0x55, sizeof(block));
     99     __asm__ __volatile__(
    100        "mov r8, %1"               "\n\t"
    101        "vldr d14, [%0, #8]"       "\n\t" // d14 <- junk
    102        "vmov s28, r8"             "\n\t"
    103        "vcvt.f64.u32 d14,d14,#1"  "\n\t"
    104        "vstr d14, [%0]"           "\n\t"
    105        : : /*IN*/"r"(&block[0]), "r"(x) : /*TRASH*/"r8","s28","d14","memory"
    106     );
    107     return block[0];
    108 }
    109 
    110 __attribute__((noinline)) double u32_to_f64_imm32(int x)
    111 {
    112     double block[2];
    113     memset(block, 0x55, sizeof(block));
    114     __asm__ __volatile__(
    115        "mov r8, %1"                "\n\t"
    116        "vldr d14, [%0, #8]"        "\n\t" // d14 <- junk
    117        "vmov s28, r8"              "\n\t"
    118        "vcvt.f64.u32 d14,d14,#32"  "\n\t"
    119        "vstr d14, [%0]"            "\n\t"
    120        : : /*IN*/"r"(&block[0]), "r"(x) : /*TRASH*/"r8","s28","d14","memory"
    121     );
    122     return block[0];
    123 }
    124 
    125 void try_u32_to_f64 ( int x )
    126 {
    127   double f64 = u32_to_f64_imm32(x);
    128   printf("u32_to_f64_imm32:  %11d  ->  %18.14e\n", x, f64);
    129   f64 = u32_to_f64_imm1(x);
    130   printf("u32_to_f64_imm1:   %11d  ->  %18.14e\n", x, f64);
    131 }
    132 
    133 
    134 
    135 __attribute__((noinline)) ULong f64_to_s32_imm1 ( double d )
    136 {
    137   double block[5];
    138   memset(block, 0x55, sizeof(block));
    139   block[1] = d;
    140   __asm__ __volatile__(
    141     "mov r8, %0"               "\n\t"
    142     "vldr d14, [r8, #8]"       "\n\t"
    143     "vcvt.s32.f64 d14,d14,#1"  "\n\t"
    144     "vstr d14, [r8,#24]"       "\n\t"
    145     : : /*IN*/"r"(&block[0]) : /*TRASH*/"d14","r8","memory"
    146   );
    147   return *(ULong*)(&block[3]);
    148 }
    149 
    150 __attribute__((noinline)) ULong f64_to_s32_imm32 ( double d )
    151 {
    152   double block[5];
    153   memset(block, 0x55, sizeof(block));
    154   block[1] = d;
    155   __asm__ __volatile__(
    156     "mov r8, %0"                "\n\t"
    157     "vldr d14, [r8, #8]"        "\n\t"
    158     "vcvt.s32.f64 d14,d14,#32"  "\n\t"
    159     "vstr d14, [r8,#24]"        "\n\t"
    160     : : /*IN*/"r"(&block[0]) : /*TRASH*/"d14","r8","memory"
    161   );
    162   return *(ULong*)(&block[3]);
    163 }
    164 
    165 void try_f64_to_s32 ( double d )
    166 {
    167   ULong res = f64_to_s32_imm32(d);
    168   printf("f64_to_s32_imm32:  %18.14e  ->  0x%016llx\n", d, res);
    169   res = f64_to_s32_imm1(d);
    170   printf("f64_to_s32_imm1:   %18.14e  ->  0x%016llx\n", d, res);
    171 }
    172 
    173 
    174 
    175 __attribute__((noinline)) ULong f64_to_u32_imm1 ( double d )
    176 {
    177   double block[5];
    178   memset(block, 0x55, sizeof(block));
    179   block[1] = d;
    180   __asm__ __volatile__(
    181     "mov r8, %0"               "\n\t"
    182     "vldr d14, [r8, #8]"       "\n\t"
    183     "vcvt.u32.f64 d14,d14,#1"  "\n\t"
    184     "vstr d14, [r8,#24]"       "\n\t"
    185     : : /*IN*/"r"(&block[0]) : /*TRASH*/"d14","r8","memory"
    186   );
    187   return *(ULong*)(&block[3]);
    188 }
    189 
    190 __attribute__((noinline)) ULong f64_to_u32_imm32 ( double d )
    191 {
    192   double block[5];
    193   memset(block, 0x55, sizeof(block));
    194   block[1] = d;
    195   __asm__ __volatile__(
    196     "mov r8, %0"                "\n\t"
    197     "vldr d14, [r8, #8]"        "\n\t"
    198     "vcvt.u32.f64 d14,d14,#32"  "\n\t"
    199     "vstr d14, [r8,#24]"        "\n\t"
    200     : : /*IN*/"r"(&block[0]) : /*TRASH*/"d14","r8","memory"
    201   );
    202   return *(ULong*)(&block[3]);
    203 }
    204 
    205 void try_f64_to_u32 ( double d )
    206 {
    207   ULong res = f64_to_u32_imm32(d);
    208   printf("f64_to_u32_imm32:  %18.14e  ->  0x%016llx\n", d, res);
    209   res = f64_to_u32_imm1(d);
    210   printf("f64_to_u32_imm1:   %18.14e  ->  0x%016llx\n", d, res);
    211 }
    212 
    213 
    214 
    215 int main ( void  )
    216 {
    217   int i;
    218   double d;
    219 
    220   try_s32_to_f32(0);
    221   try_s32_to_f32(1);
    222   for (i = 100; i < 200; i++) {
    223      try_s32_to_f32(i);
    224   }
    225   try_s32_to_f32(0x7FFFFFFE);
    226   try_s32_to_f32(0x7FFFFFFF);
    227   try_s32_to_f32(0x80000000);
    228   try_s32_to_f32(0x80000001);
    229   try_s32_to_f32(0xFFFFFFFE);
    230   try_s32_to_f32(0xFFFFFFFF);
    231 
    232   printf("\n");
    233 
    234   try_u32_to_f32(0);
    235   try_u32_to_f32(1);
    236   for (i = 100; i < 200; i++) {
    237      try_u32_to_f32(i);
    238   }
    239   try_u32_to_f32(0x7FFFFFFE);
    240   try_u32_to_f32(0x7FFFFFFF);
    241   try_u32_to_f32(0x80000000);
    242   try_u32_to_f32(0x80000001);
    243   try_u32_to_f32(0xFFFFFFFE);
    244   try_u32_to_f32(0xFFFFFFFF);
    245 
    246   printf("\n");
    247 
    248   try_s32_to_f64(0);
    249   try_s32_to_f64(1);
    250   for (i = 100; i < 200; i++) {
    251      try_s32_to_f64(i);
    252   }
    253   try_s32_to_f64(0x7FFFFFFE);
    254   try_s32_to_f64(0x7FFFFFFF);
    255   try_s32_to_f64(0x80000000);
    256   try_s32_to_f64(0x80000001);
    257   try_s32_to_f64(0xFFFFFFFE);
    258   try_s32_to_f64(0xFFFFFFFF);
    259 
    260   printf("\n");
    261 
    262   try_u32_to_f64(0);
    263   try_u32_to_f64(1);
    264   for (i = 100; i < 200; i++) {
    265      try_u32_to_f64(i);
    266   }
    267   try_u32_to_f64(0x7FFFFFFE);
    268   try_u32_to_f64(0x7FFFFFFF);
    269   try_u32_to_f64(0x80000000);
    270   try_u32_to_f64(0x80000001);
    271   try_u32_to_f64(0xFFFFFFFE);
    272   try_u32_to_f64(0xFFFFFFFF);
    273 
    274   printf("\n");
    275   try_f64_to_s32(0.0);
    276   try_f64_to_s32(1.0);
    277   try_f64_to_s32(-1.0);
    278   try_f64_to_s32(0.0 / 0.0);
    279   for (d = -100000.01; d < 100000.0; d += 10000.0) {
    280      try_f64_to_s32(d);
    281   }
    282 
    283   printf("\n");
    284   try_f64_to_u32(0.0);
    285   try_f64_to_u32(1.0);
    286   try_f64_to_u32(-1.0);
    287   try_f64_to_u32(0.0 / 0.0);
    288   for (d = -100000.01; d < 100000.0; d += 10000.0) {
    289      try_f64_to_u32(d);
    290   }
    291 
    292   return 0;
    293 }
    294