1 2 #include <stdio.h> 3 #include <string.h> 4 5 typedef unsigned long long int ULong; 6 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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