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 typedef  unsigned int            UInt;
      7 
      8 __attribute__((noinline)) float s32_to_f32_imm1(int x)
      9 {
     10     float y;
     11     __asm__ ("vcvt.f32.s32 %0, %1, #1" : "=w"(y) : "0"(x));
     12     return y;
     13 }
     14 
     15 __attribute__((noinline)) float s32_to_f32_imm32(int x)
     16 {
     17     float y;
     18     __asm__ ("vcvt.f32.s32 %0, %1, #32" : "=w"(y) : "0"(x));
     19     return y;
     20 }
     21 
     22 void try_s32_to_f32 ( int x )
     23 {
     24   float f32 = s32_to_f32_imm32(x);
     25   printf("s32_to_f32_imm32:  %11d  ->  %18.14e\n", x, (double)f32);
     26   f32 = s32_to_f32_imm1(x);
     27   printf("s32_to_f32_imm1:   %11d  ->  %18.14e\n", x, (double)f32);
     28 }
     29 
     30 
     31 
     32 __attribute__((noinline)) float u32_to_f32_imm1(int x)
     33 {
     34     float y;
     35     __asm__ ("vcvt.f32.u32 %0, %1, #1" : "=w"(y) : "0"(x));
     36     return y;
     37 }
     38 
     39 __attribute__((noinline)) float u32_to_f32_imm32(int x)
     40 {
     41     float y;
     42     __asm__ ("vcvt.f32.u32 %0, %1, #32" : "=w"(y) : "0"(x));
     43     return y;
     44 }
     45 
     46 void try_u32_to_f32 ( unsigned int x )
     47 {
     48   float f32 = u32_to_f32_imm32(x);
     49   printf("u32_to_f32_imm32:  %11u  ->  %18.14e\n", x, (double)f32);
     50   f32 = u32_to_f32_imm1(x);
     51   printf("u32_to_f32_imm1:   %11u  ->  %18.14e\n", x, (double)f32);
     52 }
     53 
     54 
     55 
     56 __attribute__((noinline)) double s32_to_f64_imm1(int x)
     57 {
     58     double block[2];
     59     memset(block, 0x55, sizeof(block));
     60     __asm__ __volatile__(
     61        "mov r8, %1"               "\n\t"
     62        "vldr d14, [%0, #8]"       "\n\t" // d14 <- junk
     63        "vmov s1, r8"              "\n\t"
     64        "vcvt.f64.s32 d14,d14,#1"  "\n\t"
     65        "vstr d14, [%0]"           "\n\t"
     66        : : /*IN*/"r"(&block[0]), "r"(x) : /*TRASH*/"r8","s28","d14","memory"
     67     );
     68     return block[0];
     69 }
     70 
     71 __attribute__((noinline)) double s32_to_f64_imm32(int x)
     72 {
     73     double block[2];
     74     memset(block, 0x55, sizeof(block));
     75     __asm__ __volatile__(
     76        "mov r8, %1"                "\n\t"
     77        "vldr d14, [%0, #8]"        "\n\t" // d14 <- junk
     78        "vmov s28, r8"              "\n\t"
     79        "vcvt.f64.s32 d14,d14,#32"  "\n\t"
     80        "vstr d14, [%0]"            "\n\t"
     81        : : /*IN*/"r"(&block[0]), "r"(x) : /*TRASH*/"r8","s28","d14","memory"
     82     );
     83     return block[0];
     84 }
     85 
     86 void try_s32_to_f64 ( int x )
     87 {
     88   double f64 = s32_to_f64_imm32(x);
     89   printf("s32_to_f64_imm32:  %11d  ->  %18.14e\n", x, f64);
     90   f64 = s32_to_f64_imm1(x);
     91   printf("s32_to_f64_imm1:   %11d  ->  %18.14e\n", x, f64);
     92 }
     93 
     94 
     95 
     96 __attribute__((noinline)) double u32_to_f64_imm1(int x)
     97 {
     98     double block[2];
     99     memset(block, 0x55, sizeof(block));
    100     __asm__ __volatile__(
    101        "mov r8, %1"               "\n\t"
    102        "vldr d14, [%0, #8]"       "\n\t" // d14 <- junk
    103        "vmov s28, r8"             "\n\t"
    104        "vcvt.f64.u32 d14,d14,#1"  "\n\t"
    105        "vstr d14, [%0]"           "\n\t"
    106        : : /*IN*/"r"(&block[0]), "r"(x) : /*TRASH*/"r8","s28","d14","memory"
    107     );
    108     return block[0];
    109 }
    110 
    111 __attribute__((noinline)) double u32_to_f64_imm32(int x)
    112 {
    113     double block[2];
    114     memset(block, 0x55, sizeof(block));
    115     __asm__ __volatile__(
    116        "mov r8, %1"                "\n\t"
    117        "vldr d14, [%0, #8]"        "\n\t" // d14 <- junk
    118        "vmov s28, r8"              "\n\t"
    119        "vcvt.f64.u32 d14,d14,#32"  "\n\t"
    120        "vstr d14, [%0]"            "\n\t"
    121        : : /*IN*/"r"(&block[0]), "r"(x) : /*TRASH*/"r8","s28","d14","memory"
    122     );
    123     return block[0];
    124 }
    125 
    126 void try_u32_to_f64 ( int x )
    127 {
    128   double f64 = u32_to_f64_imm32(x);
    129   printf("u32_to_f64_imm32:  %11d  ->  %18.14e\n", x, f64);
    130   f64 = u32_to_f64_imm1(x);
    131   printf("u32_to_f64_imm1:   %11d  ->  %18.14e\n", x, f64);
    132 }
    133 
    134 
    135 
    136 __attribute__((noinline)) ULong f64_to_s32_imm1 ( double d )
    137 {
    138   double block[5];
    139   memset(block, 0x55, sizeof(block));
    140   block[1] = d;
    141   __asm__ __volatile__(
    142     "mov r8, %0"               "\n\t"
    143     "vldr d14, [r8, #8]"       "\n\t"
    144     "vcvt.s32.f64 d14,d14,#1"  "\n\t"
    145     "vstr d14, [r8,#24]"       "\n\t"
    146     : : /*IN*/"r"(&block[0]) : /*TRASH*/"d14","r8","memory"
    147   );
    148   return *(ULong*)(&block[3]);
    149 }
    150 
    151 __attribute__((noinline)) ULong f64_to_s32_imm32 ( double d )
    152 {
    153   double block[5];
    154   memset(block, 0x55, sizeof(block));
    155   block[1] = d;
    156   __asm__ __volatile__(
    157     "mov r8, %0"                "\n\t"
    158     "vldr d14, [r8, #8]"        "\n\t"
    159     "vcvt.s32.f64 d14,d14,#32"  "\n\t"
    160     "vstr d14, [r8,#24]"        "\n\t"
    161     : : /*IN*/"r"(&block[0]) : /*TRASH*/"d14","r8","memory"
    162   );
    163   return *(ULong*)(&block[3]);
    164 }
    165 
    166 void try_f64_to_s32 ( double d )
    167 {
    168   ULong res = f64_to_s32_imm32(d);
    169   printf("f64_to_s32_imm32:  %18.14e  ->  0x%016llx\n", d, res);
    170   res = f64_to_s32_imm1(d);
    171   printf("f64_to_s32_imm1:   %18.14e  ->  0x%016llx\n", d, res);
    172 }
    173 
    174 
    175 
    176 __attribute__((noinline)) ULong f64_to_u32_imm1 ( double d )
    177 {
    178   double block[5];
    179   memset(block, 0x55, sizeof(block));
    180   block[1] = d;
    181   __asm__ __volatile__(
    182     "mov r8, %0"               "\n\t"
    183     "vldr d14, [r8, #8]"       "\n\t"
    184     "vcvt.u32.f64 d14,d14,#1"  "\n\t"
    185     "vstr d14, [r8,#24]"       "\n\t"
    186     : : /*IN*/"r"(&block[0]) : /*TRASH*/"d14","r8","memory"
    187   );
    188   return *(ULong*)(&block[3]);
    189 }
    190 
    191 __attribute__((noinline)) ULong f64_to_u32_imm32 ( double d )
    192 {
    193   double block[5];
    194   memset(block, 0x55, sizeof(block));
    195   block[1] = d;
    196   __asm__ __volatile__(
    197     "mov r8, %0"                "\n\t"
    198     "vldr d14, [r8, #8]"        "\n\t"
    199     "vcvt.u32.f64 d14,d14,#32"  "\n\t"
    200     "vstr d14, [r8,#24]"        "\n\t"
    201     : : /*IN*/"r"(&block[0]) : /*TRASH*/"d14","r8","memory"
    202   );
    203   return *(ULong*)(&block[3]);
    204 }
    205 
    206 void try_f64_to_u32 ( double d )
    207 {
    208   ULong res = f64_to_u32_imm32(d);
    209   printf("f64_to_u32_imm32:  %18.14e  ->  0x%016llx\n", d, res);
    210   res = f64_to_u32_imm1(d);
    211   printf("f64_to_u32_imm1:   %18.14e  ->  0x%016llx\n", d, res);
    212 }
    213 
    214 
    215 
    216 __attribute__((noinline)) UInt f32_to_s32_imm1 ( float f )
    217 {
    218   float block[5];
    219   memset(block, 0x55, sizeof(block));
    220   block[1] = f;
    221   __asm__ __volatile__(
    222     "mov r8, %0"               "\n\t"
    223     "vldr s14, [r8, #4]"       "\n\t"
    224     "vcvt.s32.f32 s14,s14,#1"  "\n\t"
    225     "vstr s14, [r8,#12]"       "\n\t"
    226     : : /*IN*/"r"(&block[0]) : /*TRASH*/"s14","r8","memory"
    227   );
    228   return *(UInt*)(&block[3]);
    229 }
    230 
    231 __attribute__((noinline)) UInt f32_to_s32_imm32 ( float f )
    232 {
    233   float block[5];
    234   memset(block, 0x55, sizeof(block));
    235   block[1] = f;
    236   __asm__ __volatile__(
    237     "mov r8, %0"               "\n\t"
    238     "vldr s14, [r8, #4]"       "\n\t"
    239     "vcvt.s32.f32 s14,s14,#32" "\n\t"
    240     "vstr s14, [r8,#12]"       "\n\t"
    241     : : /*IN*/"r"(&block[0]) : /*TRASH*/"s14","r8","memory"
    242   );
    243   return *(UInt*)(&block[3]);
    244 }
    245 
    246 void try_f32_to_s32 ( float f )
    247 {
    248   UInt res = f32_to_s32_imm32(f);
    249   printf("f32_to_s32_imm32:  %18.14e  ->  0x%08x\n", (double)f, res);
    250   res = f32_to_s32_imm1(f);
    251   printf("f32_to_s32_imm1:   %18.14e  ->  0x%08x\n", (double)f, res);
    252 }
    253 
    254 
    255 
    256 __attribute__((noinline)) UInt f32_to_u32_imm1 ( float f )
    257 {
    258   float block[5];
    259   memset(block, 0x55, sizeof(block));
    260   block[1] = f;
    261   __asm__ __volatile__(
    262     "mov r8, %0"               "\n\t"
    263     "vldr s14, [r8, #4]"       "\n\t"
    264     "vcvt.u32.f32 s14,s14,#1"  "\n\t"
    265     "vstr s14, [r8,#12]"       "\n\t"
    266     : : /*IN*/"r"(&block[0]) : /*TRASH*/"s14","r8","memory"
    267   );
    268   return *(UInt*)(&block[3]);
    269 }
    270 
    271 __attribute__((noinline)) UInt f32_to_u32_imm32 ( float f )
    272 {
    273   float block[5];
    274   memset(block, 0x55, sizeof(block));
    275   block[1] = f;
    276   __asm__ __volatile__(
    277     "mov r8, %0"               "\n\t"
    278     "vldr s14, [r8, #4]"       "\n\t"
    279     "vcvt.u32.f32 s14,s14,#32" "\n\t"
    280     "vstr s14, [r8,#12]"       "\n\t"
    281     : : /*IN*/"r"(&block[0]) : /*TRASH*/"s14","r8","memory"
    282   );
    283   return *(UInt*)(&block[3]);
    284 }
    285 
    286 void try_f32_to_u32 ( float f )
    287 {
    288   UInt res = f32_to_u32_imm32(f);
    289   printf("f32_to_u32_imm32:  %18.14e  ->  0x%08x\n", (double)f, res);
    290   res = f32_to_u32_imm1(f);
    291   printf("f32_to_u32_imm1:   %18.14e  ->  0x%08x\n", (double)f, res);
    292 }
    293 
    294 
    295 
    296 int main ( void  )
    297 {
    298   int i;
    299   double d;
    300 
    301   try_s32_to_f32(0);
    302   try_s32_to_f32(1);
    303   for (i = 100; i < 200; i++) {
    304      try_s32_to_f32(i);
    305   }
    306   try_s32_to_f32(0x7FFFFFFE);
    307   try_s32_to_f32(0x7FFFFFFF);
    308   try_s32_to_f32(0x80000000);
    309   try_s32_to_f32(0x80000001);
    310   try_s32_to_f32(0xFFFFFFFE);
    311   try_s32_to_f32(0xFFFFFFFF);
    312 
    313   printf("\n");
    314 
    315   try_u32_to_f32(0);
    316   try_u32_to_f32(1);
    317   for (i = 100; i < 200; i++) {
    318      try_u32_to_f32(i);
    319   }
    320   try_u32_to_f32(0x7FFFFFFE);
    321   try_u32_to_f32(0x7FFFFFFF);
    322   try_u32_to_f32(0x80000000);
    323   try_u32_to_f32(0x80000001);
    324   try_u32_to_f32(0xFFFFFFFE);
    325   try_u32_to_f32(0xFFFFFFFF);
    326 
    327   printf("\n");
    328 
    329   try_s32_to_f64(0);
    330   try_s32_to_f64(1);
    331   for (i = 100; i < 200; i++) {
    332      try_s32_to_f64(i);
    333   }
    334   try_s32_to_f64(0x7FFFFFFE);
    335   try_s32_to_f64(0x7FFFFFFF);
    336   try_s32_to_f64(0x80000000);
    337   try_s32_to_f64(0x80000001);
    338   try_s32_to_f64(0xFFFFFFFE);
    339   try_s32_to_f64(0xFFFFFFFF);
    340 
    341   printf("\n");
    342 
    343   try_u32_to_f64(0);
    344   try_u32_to_f64(1);
    345   for (i = 100; i < 200; i++) {
    346      try_u32_to_f64(i);
    347   }
    348   try_u32_to_f64(0x7FFFFFFE);
    349   try_u32_to_f64(0x7FFFFFFF);
    350   try_u32_to_f64(0x80000000);
    351   try_u32_to_f64(0x80000001);
    352   try_u32_to_f64(0xFFFFFFFE);
    353   try_u32_to_f64(0xFFFFFFFF);
    354 
    355   printf("\n");
    356   try_f64_to_s32(0.0);
    357   try_f64_to_s32(1.0);
    358   try_f64_to_s32(-1.0);
    359   try_f64_to_s32(0.0 / 0.0);
    360   for (d = -100000.01; d < 100000.0; d += 10000.0) {
    361      try_f64_to_s32(d);
    362   }
    363 
    364   printf("\n");
    365   try_f64_to_u32(0.0);
    366   try_f64_to_u32(1.0);
    367   try_f64_to_u32(-1.0);
    368   try_f64_to_u32(0.0 / 0.0);
    369   for (d = -100000.01; d < 100000.0; d += 10000.0) {
    370      try_f64_to_u32(d);
    371   }
    372 
    373   printf("\n");
    374   try_f32_to_s32(0.0);
    375   try_f32_to_s32(1.0);
    376   try_f32_to_s32(-1.0);
    377   try_f32_to_s32(0.0 / 0.0);
    378   for (d = -100000.01; d < 100000.0; d += 10000.0) {
    379      try_f32_to_s32((float)d);
    380   }
    381 
    382   printf("\n");
    383   try_f32_to_u32(0.0);
    384   try_f32_to_u32(1.0);
    385   try_f32_to_u32(-1.0);
    386   try_f32_to_u32(0.0 / 0.0);
    387   for (d = -100000.01; d < 100000.0; d += 10000.0) {
    388      try_f32_to_u32((float)d);
    389   }
    390 
    391   return 0;
    392 }
    393