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