1 
2 #include <stdio.h>
3 #include <string.h>
4 
5 typedef  unsigned long long int  ULong;
6 
s32_to_f32_imm1(int x)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 
s32_to_f32_imm32(int x)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 
try_s32_to_f32(int x)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 
u32_to_f32_imm1(int x)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 
u32_to_f32_imm32(int x)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 
try_u32_to_f32(unsigned int x)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 
s32_to_f64_imm1(int x)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 
s32_to_f64_imm32(int x)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 
try_s32_to_f64(int x)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 
u32_to_f64_imm1(int x)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 
u32_to_f64_imm32(int x)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 
try_u32_to_f64(int x)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 
f64_to_s32_imm1(double d)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 
f64_to_s32_imm32(double d)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 
try_f64_to_s32(double d)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 
f64_to_u32_imm1(double d)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 
f64_to_u32_imm32(double d)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 
try_f64_to_u32(double d)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 
main(void)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