Daniel Dunbar | 60eea55 | 2010-01-21 17:10:39 +0000 | [diff] [blame] | 1 | /* This file tests that we can succesfully call each compiler-rt function. It is |
| 2 | designed to check that the runtime libraries are available for linking and |
| 3 | that they contain the expected contents. It is not designed to test the |
| 4 | correctness of the individual functions in compiler-rt. |
| 5 | |
| 6 | This test is assumed to be run on a 10.6 machine. The two environment |
| 7 | variables below should be set to 10.4 and 10.5 machines which can be directly |
| 8 | ssh/rsync'd to in order to actually test the executables can run on the |
| 9 | desired targets. |
| 10 | */ |
| 11 | |
| 12 | // RUN: export TENFOUR_X86_MACHINE=localhost |
| 13 | // RUN: export TENFIVE_X86_MACHINE=localhost |
Daniel Dunbar | fee1137 | 2010-01-23 00:26:38 +0000 | [diff] [blame] | 14 | // RUN: export ARM_MACHINE=localhost |
| 15 | // RUN: export ARM_SYSROOT=$(xcodebuild -sdk iphoneos -version Path) |
| 16 | |
| 17 | // RUN: echo iPhoneOS, ARM, v6, thumb |
| 18 | // RUN: %clang -isysroot $ARM_SYSROOT -arch armv6 -mthumb -c %s -o %t.o |
| 19 | // RUN: %clang -isysroot $ARM_SYSROOT -arch armv6 -mthumb -v -Wl,-t,-v -o %t %t.o 1>&2 |
| 20 | // RUN: rsync -arv %t $ARM_MACHINE:/tmp/a.out |
| 21 | // RUN: ssh $ARM_MACHINE /tmp/a.out |
| 22 | // RUN: echo |
| 23 | |
| 24 | // RUN: echo iPhoneOS, ARM, v6, no-thumb |
| 25 | // RUN: %clang -isysroot $ARM_SYSROOT -arch armv6 -mno-thumb -c %s -o %t.o |
| 26 | // RUN: %clang -isysroot $ARM_SYSROOT -arch armv6 -mno-thumb -v -Wl,-t,-v -o %t %t.o 1>&2 |
| 27 | // RUN: rsync -arv %t $ARM_MACHINE:/tmp/a.out |
| 28 | // RUN: ssh $ARM_MACHINE /tmp/a.out |
| 29 | // RUN: echo |
| 30 | |
| 31 | // RUN: echo iPhoneOS, ARM, v7, thumb |
| 32 | // RUN: %clang -isysroot $ARM_SYSROOT -arch armv7 -mthumb -c %s -o %t.o |
| 33 | // RUN: %clang -isysroot $ARM_SYSROOT -arch armv7 -mthumb -v -Wl,-t,-v -o %t %t.o 1>&2 |
| 34 | // RUN: rsync -arv %t $ARM_MACHINE:/tmp/a.out |
| 35 | // RUN: ssh $ARM_MACHINE /tmp/a.out |
| 36 | // RUN: echo |
| 37 | |
| 38 | // RUN: echo iPhoneOS, ARM, v7, no-thumb |
| 39 | // RUN: %clang -isysroot $ARM_SYSROOT -arch armv7 -mno-thumb -c %s -o %t.o |
| 40 | // RUN: %clang -isysroot $ARM_SYSROOT -arch armv7 -mno-thumb -v -Wl,-t,-v -o %t %t.o 1>&2 |
| 41 | // RUN: rsync -arv %t $ARM_MACHINE:/tmp/a.out |
| 42 | // RUN: ssh $ARM_MACHINE /tmp/a.out |
| 43 | // RUN: echo |
Daniel Dunbar | 60eea55 | 2010-01-21 17:10:39 +0000 | [diff] [blame] | 44 | |
| 45 | // RUN: echo 10.4, i386 |
| 46 | // RUN: %clang -arch i386 -mmacosx-version-min=10.4 -c %s -o %t.o |
| 47 | // RUN: %clang -arch i386 -mmacosx-version-min=10.4 -v -Wl,-t,-v -o %t %t.o 1>&2 |
| 48 | // RUN: %t |
| 49 | // RUN: echo |
| 50 | |
| 51 | // RUN: rsync -arv %t $TENFOUR_X86_MACHINE:/tmp/a.out |
| 52 | // RUN: ssh $TENFOUR_X86_MACHINE /tmp/a.out |
| 53 | // RUN: echo |
| 54 | |
| 55 | // RUX: rsync -arv %t $TENFIVE_X86_MACHINE:/tmp/a.out |
| 56 | // RUX: ssh $TENFIVE_X86_MACHINE /tmp/a.out |
| 57 | // RUN: echo |
| 58 | |
| 59 | // RUN: echo 10.5, i386 |
| 60 | // RUN: %clang -arch i386 -mmacosx-version-min=10.5 -c %s -o %t.o |
| 61 | // RUN: %clang -arch i386 -mmacosx-version-min=10.5 -v -Wl,-t,-v -o %t %t.o 1>&2 |
| 62 | // RUN: %t |
| 63 | // RUN: echo |
| 64 | |
| 65 | // RUN: rsync -arv %t $TENFIVE_X86_MACHINE:/tmp/a.out |
| 66 | // RUN: ssh $TENFIVE_X86_MACHINE /tmp/a.out |
| 67 | // RUN: echo |
| 68 | |
| 69 | // RUN: echo 10.6, i386 |
| 70 | // RUN: %clang -arch i386 -mmacosx-version-min=10.6 -c %s -o %t.o |
| 71 | // RUN: %clang -arch i386 -mmacosx-version-min=10.6 -v -Wl,-t,-v -o %t %t.o 1>&2 |
| 72 | // RUN: %t |
| 73 | // RUN: echo |
| 74 | |
| 75 | // RUN: echo 10.4, x86_64 |
| 76 | // RUN: %clang -arch x86_64 -mmacosx-version-min=10.4 -c %s -o %t.o |
| 77 | // RUN: %clang -arch x86_64 -mmacosx-version-min=10.4 -v -Wl,-t,-v -o %t %t.o 1>&2 |
| 78 | // RUN: %t |
| 79 | // RUN: echo |
| 80 | |
| 81 | // RUN: rsync -arv %t $TENFOUR_X86_MACHINE:/tmp/a.out |
| 82 | // RUN: ssh $TENFOUR_X86_MACHINE /tmp/a.out |
| 83 | // RUN: echo |
| 84 | |
| 85 | // RUN: rsync -arv %t $TENFIVE_X86_MACHINE:/tmp/a.out |
| 86 | // RUN: ssh $TENFIVE_X86_MACHINE /tmp/a.out |
| 87 | // RUN: echo |
| 88 | |
| 89 | // RUN: echo 10.5, x86_64 |
| 90 | // RUN: %clang -arch x86_64 -mmacosx-version-min=10.5 -c %s -o %t.o |
| 91 | // RUN: %clang -arch x86_64 -mmacosx-version-min=10.5 -v -Wl,-t,-v -o %t %t.o 1>&2 |
| 92 | // RUN: %t |
| 93 | // RUN: echo |
| 94 | |
| 95 | // RUN: rsync -arv %t $TENFIVE_X86_MACHINE:/tmp/a.out |
| 96 | // RUN: ssh $TENFIVE_X86_MACHINE /tmp/a.out |
| 97 | // RUN: echo |
| 98 | |
| 99 | // RUN: echo 10.6, x86_64 |
| 100 | // RUN: %clang -arch x86_64 -mmacosx-version-min=10.6 -c %s -o %t.o |
| 101 | // RUN: %clang -arch x86_64 -mmacosx-version-min=10.6 -v -Wl,-t,-v -o %t %t.o 1>&2 |
| 102 | // RUN: %t |
| 103 | // RUN: echo |
| 104 | |
| 105 | #include <assert.h> |
| 106 | #include <stdio.h> |
| 107 | #include <sys/utsname.h> |
| 108 | |
| 109 | typedef int si_int; |
| 110 | typedef unsigned su_int; |
| 111 | |
| 112 | typedef long long di_int; |
| 113 | typedef unsigned long long du_int; |
| 114 | |
| 115 | // Integral bit manipulation |
| 116 | |
| 117 | di_int __ashldi3(di_int a, si_int b); // a << b |
| 118 | di_int __ashrdi3(di_int a, si_int b); // a >> b arithmetic (sign fill) |
| 119 | di_int __lshrdi3(di_int a, si_int b); // a >> b logical (zero fill) |
| 120 | |
| 121 | si_int __clzsi2(si_int a); // count leading zeros |
| 122 | si_int __clzdi2(di_int a); // count leading zeros |
| 123 | si_int __ctzsi2(si_int a); // count trailing zeros |
| 124 | si_int __ctzdi2(di_int a); // count trailing zeros |
| 125 | |
| 126 | si_int __ffsdi2(di_int a); // find least significant 1 bit |
| 127 | |
| 128 | si_int __paritysi2(si_int a); // bit parity |
| 129 | si_int __paritydi2(di_int a); // bit parity |
| 130 | |
| 131 | si_int __popcountsi2(si_int a); // bit population |
| 132 | si_int __popcountdi2(di_int a); // bit population |
| 133 | |
| 134 | // Integral arithmetic |
| 135 | |
| 136 | di_int __negdi2 (di_int a); // -a |
| 137 | di_int __muldi3 (di_int a, di_int b); // a * b |
| 138 | di_int __divdi3 (di_int a, di_int b); // a / b signed |
| 139 | du_int __udivdi3 (du_int a, du_int b); // a / b unsigned |
| 140 | di_int __moddi3 (di_int a, di_int b); // a % b signed |
| 141 | du_int __umoddi3 (du_int a, du_int b); // a % b unsigned |
| 142 | du_int __udivmoddi4(du_int a, du_int b, du_int* rem); // a / b, *rem = a % b |
| 143 | |
| 144 | // Integral arithmetic with trapping overflow |
| 145 | |
| 146 | si_int __absvsi2(si_int a); // abs(a) |
| 147 | di_int __absvdi2(di_int a); // abs(a) |
| 148 | |
| 149 | si_int __negvsi2(si_int a); // -a |
| 150 | di_int __negvdi2(di_int a); // -a |
| 151 | |
| 152 | si_int __addvsi3(si_int a, si_int b); // a + b |
| 153 | di_int __addvdi3(di_int a, di_int b); // a + b |
| 154 | |
| 155 | si_int __subvsi3(si_int a, si_int b); // a - b |
| 156 | di_int __subvdi3(di_int a, di_int b); // a - b |
| 157 | |
| 158 | si_int __mulvsi3(si_int a, si_int b); // a * b |
| 159 | di_int __mulvdi3(di_int a, di_int b); // a * b |
| 160 | |
| 161 | // Integral comparison: a < b -> 0 |
| 162 | // a == b -> 1 |
| 163 | // a > b -> 2 |
| 164 | |
| 165 | si_int __cmpdi2 (di_int a, di_int b); |
| 166 | si_int __ucmpdi2(du_int a, du_int b); |
| 167 | |
| 168 | // Integral / floating point conversion |
| 169 | |
| 170 | di_int __fixsfdi( float a); |
| 171 | di_int __fixdfdi( double a); |
| 172 | di_int __fixxfdi(long double a); |
| 173 | |
| 174 | su_int __fixunssfsi( float a); |
| 175 | su_int __fixunsdfsi( double a); |
| 176 | su_int __fixunsxfsi(long double a); |
| 177 | |
| 178 | du_int __fixunssfdi( float a); |
| 179 | du_int __fixunsdfdi( double a); |
| 180 | du_int __fixunsxfdi(long double a); |
| 181 | |
| 182 | float __floatdisf(di_int a); |
| 183 | double __floatdidf(di_int a); |
| 184 | long double __floatdixf(di_int a); |
| 185 | |
| 186 | float __floatundisf(du_int a); |
| 187 | double __floatundidf(du_int a); |
| 188 | long double __floatundixf(du_int a); |
| 189 | |
| 190 | // Floating point raised to integer power |
| 191 | |
| 192 | float __powisf2( float a, si_int b); // a ^ b |
| 193 | double __powidf2( double a, si_int b); // a ^ b |
| 194 | long double __powixf2(long double a, si_int b); // a ^ b |
| 195 | |
| 196 | // Complex arithmetic |
| 197 | |
| 198 | // (a + ib) * (c + id) |
| 199 | |
| 200 | float _Complex __mulsc3( float a, float b, float c, float d); |
| 201 | double _Complex __muldc3(double a, double b, double c, double d); |
| 202 | long double _Complex __mulxc3(long double a, long double b, |
| 203 | long double c, long double d); |
| 204 | |
| 205 | // (a + ib) / (c + id) |
| 206 | |
| 207 | float _Complex __divsc3( float a, float b, float c, float d); |
| 208 | double _Complex __divdc3(double a, double b, double c, double d); |
| 209 | long double _Complex __divxc3(long double a, long double b, |
| 210 | long double c, long double d); |
| 211 | |
Daniel Dunbar | fee1137 | 2010-01-23 00:26:38 +0000 | [diff] [blame] | 212 | #ifndef __arm |
| 213 | #define HAS_LONG_DOUBLE |
| 214 | #endif |
| 215 | |
Daniel Dunbar | 60eea55 | 2010-01-21 17:10:39 +0000 | [diff] [blame] | 216 | int main(int argc, char **argv) { |
| 217 | du_int du_tmp; |
| 218 | struct utsname name; |
Daniel Dunbar | fee1137 | 2010-01-23 00:26:38 +0000 | [diff] [blame] | 219 | #ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ |
| 220 | const char *target_name = "OS X"; |
| 221 | unsigned target_version = __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__; |
| 222 | unsigned target_maj = target_version / 100; |
| 223 | unsigned target_min = (target_version / 10) % 10; |
| 224 | unsigned target_micro = target_version % 10; |
| 225 | #else |
| 226 | const char *target_name = "iPhoneOS"; |
| 227 | unsigned target_version = __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__; |
| 228 | unsigned target_maj = target_version / 10000; |
| 229 | unsigned target_min = (target_version / 100) % 100; |
| 230 | unsigned target_micro = target_version % 100; |
| 231 | #endif |
Daniel Dunbar | 60eea55 | 2010-01-21 17:10:39 +0000 | [diff] [blame] | 232 | |
| 233 | if (uname(&name)) |
| 234 | return 1; |
| 235 | |
| 236 | fprintf(stderr, "%s: clang_rt test:\n", argv[0]); |
Daniel Dunbar | fee1137 | 2010-01-23 00:26:38 +0000 | [diff] [blame] | 237 | fprintf(stderr, " target : %s %d.%d.%d\n\n", target_name, |
| 238 | target_maj, target_min, target_micro); |
Daniel Dunbar | 60eea55 | 2010-01-21 17:10:39 +0000 | [diff] [blame] | 239 | fprintf(stderr, " sysname : %s\n", name.sysname); |
| 240 | fprintf(stderr, " nodename: %s\n", name.nodename); |
| 241 | fprintf(stderr, " release : %s\n", name.release); |
| 242 | fprintf(stderr, " version : %s\n", name.version); |
| 243 | fprintf(stderr, " machine : %s\n", name.machine); |
| 244 | |
| 245 | assert(__ashldi3(1, 1) == 2); |
| 246 | assert(__ashrdi3(2, 1) == 1); |
| 247 | assert(__lshrdi3(2, 1) == 1); |
| 248 | assert(__clzsi2(1) == 31); |
| 249 | assert(__clzdi2(1) == 63); |
| 250 | assert(__ctzsi2(2) == 1); |
| 251 | assert(__ctzdi2(2) == 1); |
| 252 | assert(__ffsdi2(12) == 3); |
| 253 | assert(__paritysi2(13) == 1); |
| 254 | assert(__paritydi2(13) == 1); |
| 255 | assert(__popcountsi2(13) == 3); |
| 256 | assert(__popcountdi2(13) == 3); |
| 257 | assert(__negdi2(3) == -3); |
| 258 | assert(__muldi3(2,2) == 4); |
| 259 | assert(__divdi3(-4,2) == -2); |
| 260 | assert(__udivdi3(4,2) == 2); |
| 261 | assert(__moddi3(3,2) == 1); |
| 262 | assert(__umoddi3(3,2) == 1); |
| 263 | assert(__udivmoddi4(5,2,&du_tmp) == 2 && du_tmp == 1); |
| 264 | assert(__absvsi2(-2) == 2); |
| 265 | assert(__absvdi2(-2) == 2); |
| 266 | assert(__negvsi2(2) == -2); |
| 267 | assert(__negvdi2(2) == -2); |
| 268 | assert(__addvsi3(2, 3) == 5); |
| 269 | assert(__addvdi3(2, 3) == 5); |
| 270 | assert(__subvsi3(2, 3) == -1); |
| 271 | assert(__subvdi3(2, 3) == -1); |
| 272 | assert(__mulvsi3(2, 3) == 6); |
| 273 | assert(__mulvdi3(2, 3) == 6); |
| 274 | assert(__cmpdi2(3, 2) == 2); |
| 275 | assert(__ucmpdi2(3, 2) == 2); |
| 276 | assert(__fixsfdi(2.0) == 2); |
| 277 | assert(__fixdfdi(2.0) == 2); |
Daniel Dunbar | 60eea55 | 2010-01-21 17:10:39 +0000 | [diff] [blame] | 278 | assert(__fixunssfsi(2.0) == 2); |
| 279 | assert(__fixunsdfsi(2.0) == 2); |
Daniel Dunbar | 60eea55 | 2010-01-21 17:10:39 +0000 | [diff] [blame] | 280 | assert(__fixunssfdi(2.0) == 2); |
| 281 | assert(__fixunsdfdi(2.0) == 2); |
Daniel Dunbar | 60eea55 | 2010-01-21 17:10:39 +0000 | [diff] [blame] | 282 | assert(__floatdisf(2) == 2.0); |
| 283 | assert(__floatdidf(2) == 2.0); |
Daniel Dunbar | 60eea55 | 2010-01-21 17:10:39 +0000 | [diff] [blame] | 284 | assert(__floatundisf(2) == 2.0); |
| 285 | assert(__floatundidf(2) == 2.0); |
Daniel Dunbar | 60eea55 | 2010-01-21 17:10:39 +0000 | [diff] [blame] | 286 | assert(__powisf2(2.0, 2) == 4.0); |
| 287 | assert(__powidf2(2.0, 2) == 4.0); |
Daniel Dunbar | fee1137 | 2010-01-23 00:26:38 +0000 | [diff] [blame] | 288 | |
| 289 | // FIXME: Clang/LLVM seems to be miscompiling _Complex currently, probably an |
| 290 | // ABI issue. |
| 291 | #ifndef __arm |
| 292 | { |
| 293 | _Complex float a = __mulsc3(1.0, 2.0, 4.0, 8.0); |
| 294 | _Complex float b = (-12.0 + 16.0j); |
| 295 | fprintf(stderr, "a: (%f + %f), b: (%f + %f)\n", |
| 296 | __real a, __imag a, __real b, __imag b); |
| 297 | } |
Daniel Dunbar | 60eea55 | 2010-01-21 17:10:39 +0000 | [diff] [blame] | 298 | assert(__mulsc3(1.0, 2.0, 4.0, 8.0) == (-12.0 + 16.0j)); |
| 299 | assert(__muldc3(1.0, 2.0, 4.0, 8.0) == (-12.0 + 16.0j)); |
Daniel Dunbar | 60eea55 | 2010-01-21 17:10:39 +0000 | [diff] [blame] | 300 | assert(__divsc3(1.0, 2.0, 4.0, 8.0) == (0.25 + 0j)); |
| 301 | assert(__divdc3(1.0, 2.0, 4.0, 8.0) == (0.25 + 0j)); |
Daniel Dunbar | fee1137 | 2010-01-23 00:26:38 +0000 | [diff] [blame] | 302 | #endif |
| 303 | |
| 304 | #ifdef HAS_LONG_DOUBLE |
Daniel Dunbar | 60eea55 | 2010-01-21 17:10:39 +0000 | [diff] [blame] | 305 | assert(__divxc3(1.0, 2.0, 4.0, 8.0) == (0.25 + 0j)); |
Daniel Dunbar | fee1137 | 2010-01-23 00:26:38 +0000 | [diff] [blame] | 306 | assert(__fixunsxfdi(2.0) == 2); |
| 307 | assert(__fixunsxfsi(2.0) == 2); |
| 308 | assert(__fixxfdi(2.0) == 2); |
| 309 | assert(__floatdixf(2) == 2.0); |
| 310 | assert(__floatundixf(2) == 2); |
| 311 | assert(__mulxc3(1.0, 2.0, 4.0, 8.0) == (-12.0 + 16.0j)); |
| 312 | assert(__powixf2(2.0, 2) == 4.0); |
| 313 | #endif |
| 314 | |
| 315 | // Test some calls which are used on armv6/thumb. The calls/prototypes are |
| 316 | // fake, it would be nice to test correctness, but mostly we just want to |
| 317 | // make sure we resolve symbols correctly. |
| 318 | #if defined(__arm) && defined(__ARM_ARCH_6K__) && defined(__thumb__) |
| 319 | if (argc == 100) { |
| 320 | extern void __restore_vfp_d8_d15_regs(void), __save_vfp_d8_d15_regs(void); |
| 321 | extern void __switch8(void), __switchu8(void), |
| 322 | __switch16(void), __switch32(void); |
| 323 | extern void __addsf3vfp(void); |
| 324 | |
| 325 | __addsf3vfp(); |
| 326 | __restore_vfp_d8_d15_regs(); |
| 327 | __save_vfp_d8_d15_regs(); |
| 328 | __switch8(); |
| 329 | __switchu8(); |
| 330 | __switch16(); |
| 331 | __switch32(); |
| 332 | } |
| 333 | #endif |
Daniel Dunbar | 60eea55 | 2010-01-21 17:10:39 +0000 | [diff] [blame] | 334 | |
| 335 | fprintf(stderr, " OK!\n"); |
| 336 | |
| 337 | return 0; |
| 338 | } |