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