• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 #include <stdio.h>
3 #include <string.h>
4 
5 typedef  unsigned long long int  ULong;
6 typedef  unsigned int            UInt;
7 
s32_to_f32_imm1(int x)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 
s32_to_f32_imm32(int x)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 
try_s32_to_f32(int x)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 
u32_to_f32_imm1(int x)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 
u32_to_f32_imm32(int x)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 
try_u32_to_f32(unsigned int x)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 
s32_to_f64_imm1(int x)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 
s32_to_f64_imm32(int x)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 
try_s32_to_f64(int x)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 
u32_to_f64_imm1(int x)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 
u32_to_f64_imm32(int x)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 
try_u32_to_f64(int x)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 
f64_to_s32_imm1(double d)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 
f64_to_s32_imm32(double d)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 
try_f64_to_s32(double d)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 
f64_to_u32_imm1(double d)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 
f64_to_u32_imm32(double d)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 
try_f64_to_u32(double d)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 
f32_to_s32_imm1(float f)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 
f32_to_s32_imm32(float f)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 
try_f32_to_s32(float f)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 
f32_to_u32_imm1(float f)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 
f32_to_u32_imm32(float f)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 
try_f32_to_u32(float f)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 
main(void)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