Changeset 331 for EcnlProtoTool/trunk/tcc-0.9.27/tests/tcctest.c
- Timestamp:
- Jan 21, 2018, 12:10:09 AM (6 years ago)
- Location:
- EcnlProtoTool/trunk/tcc-0.9.27
- Files:
-
- 1 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/tcc-0.9.27/tests/tcctest.c
r321 r331 2 2 * TCC auto test program 3 3 */ 4 #include " ../config.h"4 #include "config.h" 5 5 6 6 #if GCC_MAJOR >= 3 … … 15 15 #define CORRECT_CR_HANDLING 16 16 17 #endif 18 19 #if defined(_WIN32) 20 #define LONG_LONG_FORMAT "%lld" 21 #define ULONG_LONG_FORMAT "%llu" 22 #else 23 #define LONG_LONG_FORMAT "%Ld" 24 #define ULONG_LONG_FORMAT "%Lu" 25 #endif 26 27 // MinGW has 80-bit rather than 64-bit long double which isn't compatible with TCC or MSVC 28 #if defined(_WIN32) && defined(__GNUC__) 29 #define LONG_DOUBLE double 30 #define LONG_DOUBLE_LITERAL(x) x 31 #else 32 #define LONG_DOUBLE long double 33 #define LONG_DOUBLE_LITERAL(x) x ## L 17 34 #endif 18 35 … … 28 45 #define TCCLIB_INC1 <tcclib 29 46 #define TCCLIB_INC2 h> 30 #define TCCLIB_INC3 "tcclib "47 #define TCCLIB_INC3 "tcclib.h" 31 48 32 49 #include TCCLIB_INC … … 36 53 #include TCCLIB_INC1.h> 37 54 38 /* gcc 3.2 does not accept that (bug ?) */ 39 //#include TCCLIB_INC3 ".h" 55 #include TCCLIB_INC3 40 56 41 57 #include <tcclib.h> … … 43 59 #include "tcclib.h" 44 60 61 #include "tcctest.h" 62 63 /* Test two more ways to include a file named like a pp-number */ 64 #define INC(name) <tests/name.h> 65 #define funnyname 42test.h 66 #define incdir tests/ 67 #define incname < incdir funnyname > 68 #define __stringify(x) #x 69 #define stringify(x) __stringify(x) 70 #include INC(42test) 71 #include incname 72 #include stringify(funnyname) 73 74 void intdiv_test(); 45 75 void string_test(); 46 76 void expr_test(); … … 59 89 void expr_ptr_test(); 60 90 void bool_test(); 91 void optimize_out(); 61 92 void expr2_test(); 62 93 void constant_expr_test(); … … 91 122 void callsave_test(void); 92 123 void builtin_frame_address_test(void); 124 void attrib_test(void); 93 125 94 126 int fib(int n); … … 96 128 void forward_ref(void); 97 129 int isid(int c); 130 131 /* Line joining happens before tokenization, so the following 132 must be parsed as ellipsis. */ 133 void funny_line_continuation (int, ..\ 134 . ); 135 136 char via_volatile (char); 98 137 99 138 #define A 2 … … 138 177 #endif 139 178 179 #ifdef __TINYC__ 180 /* We try to handle this syntax. Make at least sure it doesn't segfault. */ 181 char invalid_function_def()[] {} 182 #endif 183 140 184 #define __INT64_C(c) c ## LL 141 185 #define INT64_MIN (-__INT64_C(9223372036854775807)-1) … … 150 194 #define wq_spin_lock spin_lock 151 195 #define TEST2() wq_spin_lock(a) 196 197 #define UINT_MAX ((unsigned) -1) 198 199 void intdiv_test(void) 200 { 201 printf("18/21=%u\n", 18/21); 202 printf("18%%21=%u\n", 18%21); 203 printf("41/21=%u\n", 41/21); 204 printf("41%%21=%u\n", 41%21); 205 printf("42/21=%u\n", 42/21); 206 printf("42%%21=%u\n", 42%21); 207 printf("43/21=%u\n", 43/21); 208 printf("43%%21=%u\n", 43%21); 209 printf("126/21=%u\n", 126/21); 210 printf("126%%21=%u\n", 126%21); 211 printf("131/21=%u\n", 131/21); 212 printf("131%%21=%u\n", 131%21); 213 printf("(UINT_MAX/2+3)/2=%u\n", (UINT_MAX/2+3)/2); 214 printf("(UINT_MAX/2+3)%%2=%u\n", (UINT_MAX/2+3)%2); 215 216 printf("18/-21=%u\n", 18/-21); 217 printf("18%%-21=%u\n", 18%-21); 218 printf("41/-21=%u\n", 41/-21); 219 printf("41%%-21=%u\n", 41%-21); 220 printf("42/-21=%u\n", 42/-21); 221 printf("42%%-21=%u\n", 42%-21); 222 printf("43/-21=%u\n", 43/-21); 223 printf("43%%-21=%u\n", 43%-21); 224 printf("126/-21=%u\n", 126/-21); 225 printf("126%%-21=%u\n", 126%-21); 226 printf("131/-21=%u\n", 131/-21); 227 printf("131%%-21=%u\n", 131%-21); 228 printf("(UINT_MAX/2+3)/-2=%u\n", (UINT_MAX/2+3)/-2); 229 printf("(UINT_MAX/2+3)%%-2=%u\n", (UINT_MAX/2+3)%-2); 230 231 printf("-18/21=%u\n", -18/21); 232 printf("-18%%21=%u\n", -18%21); 233 printf("-41/21=%u\n", -41/21); 234 printf("-41%%21=%u\n", -41%21); 235 printf("-42/21=%u\n", -42/21); 236 printf("-42%%21=%u\n", -42%21); 237 printf("-43/21=%u\n", -43/21); 238 printf("-43%%21=%u\n", -43%21); 239 printf("-126/21=%u\n", -126/21); 240 printf("-126%%21=%u\n", -126%21); 241 printf("-131/21=%u\n", -131/21); 242 printf("-131%%21=%u\n", -131%21); 243 printf("-(UINT_MAX/2+3)/2=%u\n", (0-(UINT_MAX/2+3))/2); 244 printf("-(UINT_MAX/2+3)%%2=%u\n", (0-(UINT_MAX/2+3))%2); 245 246 printf("-18/-21=%u\n", -18/-21); 247 printf("-18%%-21=%u\n", -18%-21); 248 printf("-41/-21=%u\n", -41/-21); 249 printf("-41%%-21=%u\n", -41%-21); 250 printf("-42/-21=%u\n", -42/-21); 251 printf("-42%%-21=%u\n", -42%-21); 252 printf("-43/-21=%u\n", -43/-21); 253 printf("-43%%-21=%u\n", -43%-21); 254 printf("-126/-21=%u\n", -126/-21); 255 printf("-126%%-21=%u\n", -126%-21); 256 printf("-131/-21=%u\n", -131/-21); 257 printf("-131%%-21=%u\n", -131%-21); 258 printf("-(UINT_MAX/2+3)/-2=%u\n", (0-(UINT_MAX/2+3))/-2); 259 printf("-(UINT_MAX/2+3)%%-2=%u\n", (0-(UINT_MAX/2+3))%-2); 260 } 152 261 153 262 void macro_test(void) … … 236 345 printf("__LINE__=%d __FILE__=%s\n", 237 346 __LINE__, __FILE__); 347 #if 0 238 348 #line 200 239 349 printf("__LINE__=%d __FILE__=%s\n", … … 243 353 __LINE__, __FILE__); 244 354 #line 227 "tcctest.c" 355 #endif 245 356 246 357 /* not strictly preprocessor, but we test it there */ … … 257 368 258 369 /* complicated macros in glibc */ 259 printf("INT64_MIN= %Ld\n", INT64_MIN);370 printf("INT64_MIN=" LONG_LONG_FORMAT "\n", INT64_MIN); 260 371 { 261 372 int a; … … 276 387 MF_t("hi"); 277 388 278 /* test macro substitu ion inside args (should not eat stream) */389 /* test macro substitution inside args (should not eat stream) */ 279 390 printf("qq=%d\n", qq(qq)(2)); 280 391 … … 296 407 TEST2(); 297 408 298 /* And again when the name and parenthes are separated by a409 /* And again when the name and parentheses are separated by a 299 410 comment. */ 300 411 TEST2 /* the comment */ (); 412 413 printf("%s\n", get_basefile_from_header()); 414 printf("%s\n", __BASE_FILE__); 415 printf("%s\n", get_file_from_header()); 416 printf("%s\n", __FILE__); 417 418 /* Check that funnily named include was in fact included */ 419 have_included_42test_h = 1; 420 have_included_42test_h_second = 1; 421 have_included_42test_h_third = 1; 301 422 } 302 423 … … 490 611 }; 491 612 613 struct S_enum { 614 enum {E6 = 42, E7, E8} e:8; 615 }; 616 617 enum ELong { 618 /* This is either 0 on L32 machines, or a large number 619 on L64 machines. We should be able to store this. */ 620 EL_large = ((unsigned long)0xf000 << 31) << 1, 621 }; 622 623 enum { BIASU = -1U<<31 }; 624 enum { BIASS = -1 << 31 }; 625 626 static int getint(int i) 627 { 628 if (i) 629 return 0; 630 else 631 return (int)(-1U << 31); 632 } 633 492 634 void enum_test() 493 635 { 494 636 enum test b1; 637 /* The following should give no warning */ 638 unsigned *p = &b1; 639 struct S_enum s = {E7}; 640 printf("enum: %d\n", s.e); 495 641 printf("enum:\n%d %d %d %d %d %d\n", 496 642 E0, E1, E2, E3, E4, E5); 497 643 b1 = 1; 498 644 printf("b1=%d\n", b1); 645 printf("enum large: %ld\n", EL_large); 646 647 if (getint(0) == BIASU) 648 printf("enum unsigned: ok\n"); 649 else 650 printf("enum unsigned: wrong\n"); 651 if (getint(0) == BIASS) 652 printf("enum unsigned: ok\n"); 653 else 654 printf("enum unsigned: wrong\n"); 499 655 } 500 656 … … 552 708 553 709 struct struct1 st1, st2; 710 711 struct empty_mem { 712 /* nothing */ ; 713 int x; 714 }; 554 715 555 716 int main(int argc, char **argv) … … 571 732 expr_ptr_test(); 572 733 bool_test(); 734 optimize_out(); 573 735 expr2_test(); 574 736 constant_expr_test(); … … 605 767 callsave_test(); 606 768 builtin_frame_address_test(); 769 intdiv_test(); 770 if (via_volatile (42) != 42) 771 printf ("via_volatile broken\n"); 772 attrib_test(); 607 773 return 0; 608 774 } … … 816 982 printf("%d\n", sp[j].i); 817 983 } 984 #ifdef __LP64__ 985 i = 1; 986 p = (int*)0x100000000UL + i; 987 i = ((long)p) >> 32; 988 printf("largeptr: %p %d\n", p, i); 989 #endif 818 990 } 819 991 … … 862 1034 }; 863 1035 1036 struct __attribute__((aligned(16))) aligntest5 1037 { 1038 int i; 1039 }; 1040 struct aligntest6 1041 { 1042 int i; 1043 } __attribute__((aligned(16))); 1044 struct aligntest7 1045 { 1046 int i; 1047 }; 1048 struct aligntest5 altest5[2]; 1049 struct aligntest6 altest6[2]; 1050 int pad1; 1051 /* altest7 is correctly aligned to 16 bytes also with TCC, 1052 but __alignof__ returns the wrong result (4) because we 1053 can't store the alignment yet when specified on symbols 1054 directly (it's stored in the type so we'd need to make 1055 a copy of it). -- FIXED */ 1056 struct aligntest7 altest7[2] __attribute__((aligned(16))); 1057 1058 struct aligntest8 1059 { 1060 int i; 1061 } __attribute__((aligned(4096))); 1062 1063 struct Large { 1064 unsigned long flags; 1065 union { 1066 void *u1; 1067 int *u2; 1068 }; 1069 1070 struct { 1071 union { 1072 unsigned long index; 1073 void *freelist; 1074 }; 1075 union { 1076 unsigned long counters; 1077 struct { 1078 int bla; 1079 }; 1080 }; 1081 }; 1082 1083 union { 1084 struct { 1085 long u3; 1086 long u4; 1087 }; 1088 void *u5; 1089 struct { 1090 unsigned long compound_head; 1091 unsigned int compound_dtor; 1092 unsigned int compound_order; 1093 }; 1094 }; 1095 } __attribute__((aligned(2 * sizeof(long)))); 1096 1097 typedef unsigned long long __attribute__((aligned(4))) unaligned_u64; 1098 1099 struct aligntest9 { 1100 unsigned int buf_nr; 1101 unaligned_u64 start_lba; 1102 }; 1103 1104 struct aligntest10 { 1105 unsigned int buf_nr; 1106 unsigned long long start_lba; 1107 }; 1108 864 1109 void struct_test() 865 1110 { 866 1111 struct1 *s; 867 1112 union union2 u; 1113 struct Large ls; 868 1114 869 1115 printf("struct:\n"); … … 873 1119 sizeof(union union1), 874 1120 sizeof(union union2)); 1121 printf("offsets: %d\n", (int)((char*)&st1.u.v1 - (char*)&st1)); 875 1122 st1.f1 = 1; 876 1123 st1.f2 = 2; … … 901 1148 printf("aligntest4 sizeof=%d alignof=%d\n", 902 1149 sizeof(struct aligntest4), __alignof__(struct aligntest4)); 1150 printf("aligntest5 sizeof=%d alignof=%d\n", 1151 sizeof(struct aligntest5), __alignof__(struct aligntest5)); 1152 printf("aligntest6 sizeof=%d alignof=%d\n", 1153 sizeof(struct aligntest6), __alignof__(struct aligntest6)); 1154 printf("aligntest7 sizeof=%d alignof=%d\n", 1155 sizeof(struct aligntest7), __alignof__(struct aligntest7)); 1156 printf("aligntest8 sizeof=%d alignof=%d\n", 1157 sizeof(struct aligntest8), __alignof__(struct aligntest8)); 1158 printf("aligntest9 sizeof=%d alignof=%d\n", 1159 sizeof(struct aligntest9), __alignof__(struct aligntest9)); 1160 printf("aligntest10 sizeof=%d alignof=%d\n", 1161 sizeof(struct aligntest10), __alignof__(struct aligntest10)); 1162 printf("altest5 sizeof=%d alignof=%d\n", 1163 sizeof(altest5), __alignof__(altest5)); 1164 printf("altest6 sizeof=%d alignof=%d\n", 1165 sizeof(altest6), __alignof__(altest6)); 1166 printf("altest7 sizeof=%d alignof=%d\n", 1167 sizeof(altest7), __alignof__(altest7)); 903 1168 904 1169 /* empty structures (GCC extension) */ 905 1170 printf("sizeof(struct empty) = %d\n", sizeof(struct empty)); 906 1171 printf("alignof(struct empty) = %d\n", __alignof__(struct empty)); 1172 1173 printf("Large: sizeof=%d\n", sizeof(ls)); 1174 memset(&ls, 0, sizeof(ls)); 1175 ls.compound_head = 42; 1176 printf("Large: offsetof(compound_head)=%d\n", (int)((char*)&ls.compound_head - (char*)&ls)); 907 1177 } 908 1178 … … 954 1224 } 955 1225 1226 static unsigned int calc_vm_flags(unsigned int prot) 1227 { 1228 unsigned int prot_bits; 1229 /* This used to segfault in some revisions: */ 1230 prot_bits = ((0x1==0x00000001)?(prot&0x1):(prot&0x1)?0x00000001:0); 1231 return prot_bits; 1232 } 1233 956 1234 void bool_test() 957 1235 { … … 1026 1304 printf("error %d\n", i); 1027 1305 } 1306 printf ("bits = 0x%x\n", calc_vm_flags (0x1)); 1307 } 1308 1309 extern int undefined_function(void); 1310 extern int defined_function(void); 1311 1312 static inline void refer_to_undefined(void) 1313 { 1314 undefined_function(); 1315 } 1316 1317 void optimize_out(void) 1318 { 1319 int i = 0 ? undefined_function() : defined_function(); 1320 printf ("oo:%d\n", i); 1321 int j = 1 ? defined_function() : undefined_function(); 1322 printf ("oo:%d\n", j); 1323 if (0) 1324 printf("oo:%d\n", undefined_function()); 1325 else 1326 printf("oo:%d\n", defined_function()); 1327 if (1) 1328 printf("oo:%d\n", defined_function()); 1329 else 1330 printf("oo:%d\n", undefined_function()); 1331 while (1) { 1332 printf("oow:%d\n", defined_function()); 1333 break; 1334 printf("oow:%d\n", undefined_function()); 1335 } 1336 j = 1; 1337 /* Following is a switch without {} block intentionally. */ 1338 switch (j) 1339 case 1: break; 1340 printf ("oos:%d\n", defined_function()); 1341 /* The following break shouldn't lead to disabled code after 1342 the while. */ 1343 while (1) 1344 break; 1345 printf ("ool1:%d\n", defined_function()); 1346 /* Same for the other types of loops. */ 1347 do 1348 break; 1349 while (1); 1350 printf ("ool2:%d\n", defined_function()); 1351 for (;;) 1352 break; 1353 printf ("ool3:%d\n", defined_function()); 1354 /* Normal {} blocks without controlling statements 1355 shouldn't reactivate code emission */ 1356 while (1) { 1357 { 1358 break; 1359 } 1360 printf ("ool4:%d\n", undefined_function()); 1361 } 1362 j = 1; 1363 while (j) { 1364 if (j == 0) 1365 break; /* this break shouldn't disable code outside the if. */ 1366 printf("ool5:%d\n", defined_function()); 1367 j--; 1368 } 1369 1370 j = 1; 1371 while (j) { 1372 if (1) 1373 j--; 1374 else 1375 breakhere: break; 1376 printf("ool6:%d\n", defined_function()); 1377 goto breakhere; 1378 } 1379 1380 /* Test that constants in logical && are optimized: */ 1381 i = 0 && undefined_function(); 1382 i = defined_function() && 0 && undefined_function(); 1383 if (0 && undefined_function()) 1384 undefined_function(); 1385 if (defined_function() && 0) 1386 undefined_function(); 1387 if (0 && 0) 1388 undefined_function(); 1389 if (defined_function() && 0 && undefined_function()) 1390 undefined_function(); 1391 /* The same for || : */ 1392 i = 1 || undefined_function(); 1393 i = defined_function() || 1 || undefined_function(); 1394 if (1 || undefined_function()) 1395 ; 1396 else 1397 undefined_function(); 1398 if (defined_function() || 1) 1399 ; 1400 else 1401 undefined_function(); 1402 if (1 || 1) 1403 ; 1404 else 1405 undefined_function(); 1406 if (defined_function() || 1 || undefined_function()) 1407 ; 1408 else 1409 undefined_function(); 1410 1411 if (defined_function() && 0) 1412 refer_to_undefined(); 1413 1414 if (0) { 1415 (void)sizeof( ({ 1416 do { } while (0); 1417 0; 1418 }) ); 1419 undefined_function(); 1420 } 1421 1422 /* Leave the "if(1)return; printf()" in this order and last in the function */ 1423 if (1) 1424 return; 1425 printf ("oor:%d\n", undefined_function()); 1426 } 1427 1428 int defined_function(void) 1429 { 1430 static int i = 40; 1431 return i++; 1028 1432 } 1029 1433 … … 1340 1744 }; 1341 1745 1746 typedef int arrtype1[]; 1747 arrtype1 sinit19 = {1}; 1748 arrtype1 sinit20 = {2,3}; 1749 typedef int arrtype2[3]; 1750 arrtype2 sinit21 = {4}; 1751 arrtype2 sinit22 = {5,6,7}; 1752 1753 /* Address comparisons of non-weak symbols with zero can be const-folded */ 1754 int sinit23[2] = { "astring" ? sizeof("astring") : -1, 1755 &sinit23 ? 42 : -1 }; 1756 1757 extern int external_inited = 42; 1758 1342 1759 void init_test(void) 1343 1760 { … … 1354 1771 struct linit16 { int a1, a2, a3, a4; } linit16 = { 1, .a3 = 2 }; 1355 1772 int linit17 = sizeof(linit17); 1773 int zero = 0; 1774 /* Addresses on non-weak symbols are non-zero, but not the access itself */ 1775 int linit18[2] = {&zero ? 1 : -1, zero ? -1 : 1 }; 1356 1776 1357 1777 printf("init_test:\n"); … … 1440 1860 printf("cix2: %d %d\n", cix21.b[2], cix22.b[5]); 1441 1861 printf("sizeof cix20 %d, cix21 %d, sizeof cix22 %d\n", sizeof cix20, sizeof cix21, sizeof cix22); 1442 } 1443 1862 1863 printf("arrtype1: %d %d %d\n", sinit19[0], sinit20[0], sinit20[1]); 1864 printf("arrtype2: %d %d\n", sizeof(sinit19), sizeof(sinit20)); 1865 printf("arrtype3: %d %d %d\n", sinit21[0], sinit21[1], sinit21[2]); 1866 printf("arrtype4: %d %d %d\n", sinit22[0], sinit22[1], sinit22[2]); 1867 printf("arrtype5: %d %d\n", sizeof(sinit21), sizeof(sinit22)); 1868 printf("arrtype6: %d\n", sizeof(arrtype2)); 1869 1870 printf("sinit23= %d %d\n", sinit23[0], sinit23[1]); 1871 printf("linit18= %d %d\n", linit18[0], linit18[1]); 1872 } 1873 1874 void switch_uc(unsigned char uc) 1875 { 1876 switch (uc) { 1877 case 0xfb ... 0xfe: 1878 printf("ucsw:1\n"); 1879 break; 1880 case 0xff: 1881 printf("ucsw:2\n"); 1882 break; 1883 case 0 ... 5: 1884 printf("ucsw:3\n"); 1885 break; 1886 default: 1887 printf("ucsw: broken!\n"); 1888 } 1889 } 1890 1891 void switch_sc(signed char sc) 1892 { 1893 switch (sc) { 1894 case -5 ... -2: 1895 printf("scsw:1\n"); 1896 break; 1897 case -1: 1898 printf("scsw:2\n"); 1899 break; 1900 case 0 ... 5: 1901 printf("scsw:3\n"); 1902 break; 1903 default: 1904 printf("scsw: broken!\n"); 1905 } 1906 } 1444 1907 1445 1908 void switch_test() 1446 1909 { 1447 1910 int i; 1911 unsigned long long ull; 1912 long long ll; 1448 1913 1449 1914 for(i=0;i<15;i++) { … … 1462 1927 printf("b"); 1463 1928 break; 1929 case 0xc33c6b9fU: 1930 case 0x7c9eeeb9U: 1931 break; 1464 1932 } 1465 1933 } 1466 1934 printf("\n"); 1935 1936 for (i = 1; i <= 5; i++) { 1937 ull = (unsigned long long)i << 61; 1938 switch (ull) { 1939 case 1ULL << 61: 1940 printf("ullsw:1\n"); 1941 break; 1942 case 2ULL << 61: 1943 printf("ullsw:2\n"); 1944 break; 1945 case 3ULL << 61: 1946 printf("ullsw:3\n"); 1947 break; 1948 case 4ULL << 61: 1949 printf("ullsw:4\n"); 1950 break; 1951 case 5ULL << 61: 1952 printf("ullsw:5\n"); 1953 break; 1954 default: 1955 printf("ullsw: broken!\n"); 1956 } 1957 } 1958 1959 for (i = 1; i <= 5; i++) { 1960 ll = (long long)i << 61; 1961 switch (ll) { 1962 case 1LL << 61: 1963 printf("llsw:1\n"); 1964 break; 1965 case 2LL << 61: 1966 printf("llsw:2\n"); 1967 break; 1968 case 3LL << 61: 1969 printf("llsw:3\n"); 1970 break; 1971 case 4LL << 61: 1972 printf("llsw:4\n"); 1973 break; 1974 case 5LL << 61: 1975 printf("llsw:5\n"); 1976 break; 1977 default: 1978 printf("llsw: broken!\n"); 1979 } 1980 } 1981 1982 for (i = -5; i <= 5; i++) { 1983 switch_uc((unsigned char)i); 1984 } 1985 1986 for (i = -5; i <= 5; i++) { 1987 switch_sc ((signed char)i); 1988 } 1467 1989 } 1468 1990 … … 1525 2047 printf("st1.f2 != -1\n"); 1526 2048 1527 /* bit sizes below must be bigger than 32 since GCC doesn't allow1528 long-long bitfields whose size is not bigger than int */1529 2049 struct sbf2 { 1530 2050 long long f1 : 45; … … 1539 2059 st2.f2++; 1540 2060 printf("%lld %lld %lld\n", st2.f1, st2.f2, st2.f3); 2061 2062 #if 0 2063 Disabled for now until further clarification re GCC compatibility 2064 struct sbf3 { 2065 int f1 : 7; 2066 int f2 : 1; 2067 char f3; 2068 int f4 : 8; 2069 int f5 : 1; 2070 int f6 : 16; 2071 } st3; 2072 printf("sizeof(st3) = %d\n", sizeof(st3)); 2073 #endif 2074 2075 struct sbf4 { 2076 int x : 31; 2077 char y : 2; 2078 } st4; 2079 st4.y = 1; 2080 printf("st4.y == %d\n", st4.y); 2081 struct sbf5 { 2082 int a; 2083 char b; 2084 int x : 12, y : 4, : 0, : 4, z : 3; 2085 char c; 2086 } st5 = { 1, 2, 3, 4, -3, 6 }; 2087 printf("st5 = %d %d %d %d %d %d\n", st5.a, st5.b, st5.x, st5.y, st5.z, st5.c); 2088 struct sbf6 { 2089 short x : 12; 2090 unsigned char y : 2; 2091 } st6; 2092 st6.y = 1; 2093 printf("st6.y == %d\n", st6.y); 1541 2094 } 1542 2095 … … 1550 2103 /* declare strto* functions as they are C99 */ 1551 2104 double strtod(const char *nptr, char **endptr); 2105 2106 #if defined(_WIN32) 2107 float strtof(const char *nptr, char **endptr) {return (float)strtod(nptr, endptr);} 2108 LONG_DOUBLE strtold(const char *nptr, char **endptr) {return (LONG_DOUBLE)strtod(nptr, endptr);} 2109 #else 1552 2110 float strtof(const char *nptr, char **endptr); 1553 long double strtold(const char *nptr, char **endptr); 1554 1555 #define FTEST(prefix, type, fmt)\ 2111 LONG_DOUBLE strtold(const char *nptr, char **endptr); 2112 #endif 2113 2114 #define FTEST(prefix, typename, type, fmt)\ 1556 2115 void prefix ## cmp(type a, type b)\ 1557 2116 {\ … … 1581 2140 float fa;\ 1582 2141 double da;\ 1583 long doublela;\2142 LONG_DOUBLE la;\ 1584 2143 int ia;\ 2144 long long llia;\ 1585 2145 unsigned int ua;\ 2146 unsigned long long llua;\ 1586 2147 type b;\ 1587 2148 fa = a;\ … … 1590 2151 printf("ftof: %f %f %Lf\n", fa, da, la);\ 1591 2152 ia = (int)a;\ 2153 llia = (long long)a;\ 2154 a = (a >= 0) ? a : -a;\ 1592 2155 ua = (unsigned int)a;\ 1593 printf("ftoi: %d %u\n", ia, ua);\ 2156 llua = (unsigned long long)a;\ 2157 printf("ftoi: %d %u %lld %llu\n", ia, ua, llia, llua);\ 1594 2158 ia = -1234;\ 1595 2159 ua = 0x81234500;\ 2160 llia = -0x123456789012345LL;\ 2161 llua = 0xf123456789012345LLU;\ 1596 2162 b = ia;\ 1597 2163 printf("itof: " fmt "\n", b);\ 1598 2164 b = ua;\ 1599 2165 printf("utof: " fmt "\n", b);\ 2166 b = llia;\ 2167 printf("lltof: " fmt "\n", b);\ 2168 b = llua;\ 2169 printf("ulltof: " fmt "\n", b);\ 1600 2170 }\ 1601 2171 \ 1602 2172 float prefix ## retf(type a) { return a; }\ 1603 2173 double prefix ## retd(type a) { return a; }\ 1604 long doubleprefix ## retld(type a) { return a; }\2174 LONG_DOUBLE prefix ## retld(type a) { return a; }\ 1605 2175 \ 1606 2176 void prefix ## call(void)\ … … 1612 2182 }\ 1613 2183 \ 2184 void prefix ## signed_zeros(void) \ 2185 {\ 2186 type x = 0.0, y = -0.0, n, p;\ 2187 if (x == y)\ 2188 printf ("Test 1.0 / x != 1.0 / y returns %d (should be 1).\n",\ 2189 1.0 / x != 1.0 / y);\ 2190 else\ 2191 printf ("x != y; this is wrong!\n");\ 2192 \ 2193 n = -x;\ 2194 if (x == n)\ 2195 printf ("Test 1.0 / x != 1.0 / -x returns %d (should be 1).\n",\ 2196 1.0 / x != 1.0 / n);\ 2197 else\ 2198 printf ("x != -x; this is wrong!\n");\ 2199 \ 2200 p = +y;\ 2201 if (x == p)\ 2202 printf ("Test 1.0 / x != 1.0 / +y returns %d (should be 1).\n",\ 2203 1.0 / x != 1.0 / p);\ 2204 else\ 2205 printf ("x != +y; this is wrong!\n");\ 2206 p = -y;\ 2207 if (x == p)\ 2208 printf ("Test 1.0 / x != 1.0 / -y returns %d (should be 0).\n",\ 2209 1.0 / x != 1.0 / p);\ 2210 else\ 2211 printf ("x != -y; this is wrong!\n");\ 2212 }\ 1614 2213 void prefix ## test(void)\ 1615 2214 {\ 1616 printf("testing '%s'\n", #type );\2215 printf("testing '%s'\n", #typename);\ 1617 2216 prefix ## cmp(1, 2.5);\ 1618 2217 prefix ## cmp(2, 1.5);\ … … 1621 2220 prefix ## fcast(-2334.6);\ 1622 2221 prefix ## call();\ 1623 } 1624 1625 FTEST(f, float, "%f") 1626 FTEST(d, double, "%f") 1627 FTEST(ld, long double, "%Lf") 2222 prefix ## signed_zeros();\ 2223 } 2224 2225 FTEST(f, float, float, "%f") 2226 FTEST(d, double, double, "%f") 2227 FTEST(ld, long double, LONG_DOUBLE, "%Lf") 1628 2228 1629 2229 double ftab1[3] = { 1.2, 3.4, -5.6 }; … … 1632 2232 void float_test(void) 1633 2233 { 2234 #if !defined(__arm__) || defined(__ARM_PCS_VFP) 1634 2235 float fa, fb; 1635 2236 double da, db; … … 1640 2241 printf("sizeof(float) = %d\n", sizeof(float)); 1641 2242 printf("sizeof(double) = %d\n", sizeof(double)); 1642 printf("sizeof(long double) = %d\n", sizeof( long double));2243 printf("sizeof(long double) = %d\n", sizeof(LONG_DOUBLE)); 1643 2244 ftest(); 1644 2245 dtest(); … … 1657 2258 db = b; 1658 2259 printf("db = %f\n", db); 2260 #endif 1659 2261 } 1660 2262 … … 1675 2277 void (*func)(int); 1676 2278 } st1; 2279 long diff; 1677 2280 1678 2281 printf("funcptr:\n"); … … 1690 2293 printf("sizeof3 = %d\n", sizeof(&funcptr_test)); 1691 2294 printf("sizeof4 = %d\n", sizeof &funcptr_test); 2295 a = 0; 2296 func = num + a; 2297 diff = func - num; 2298 func(42); 2299 (func + diff)(42); 2300 (num + a)(43); 1692 2301 } 1693 2302 … … 1699 2308 ub = b; 1700 2309 /* arith */ 1701 printf("arith: %Ld %Ld %Ld\n",2310 printf("arith: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", 1702 2311 a + b, 1703 2312 a - b, … … 1705 2314 1706 2315 if (b != 0) { 1707 printf("arith1: %Ld %Ld\n",2316 printf("arith1: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", 1708 2317 a / b, 1709 2318 a % b); … … 1711 2320 1712 2321 /* binary */ 1713 printf("bin: %Ld %Ld %Ld\n",2322 printf("bin: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", 1714 2323 a & b, 1715 2324 a | b, … … 1736 2345 a++; 1737 2346 b++; 1738 printf("arith2: %Ld %Ld\n", a, b);1739 printf("arith2: %Ld %Ld\n", a++, b++);1740 printf("arith2: %Ld %Ld\n", --a, --b);1741 printf("arith2: %Ld %Ld\n", a, b);2347 printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b); 2348 printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a++, b++); 2349 printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", --a, --b); 2350 printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b); 1742 2351 b = ub = 0; 1743 2352 printf("not: %d %d %d %d\n", !a, !ua, !b, !ub); … … 1746 2355 void llshift(long long a, int b) 1747 2356 { 1748 printf("shift: %Ld %Ld %Ld\n",2357 printf("shift: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", 1749 2358 (unsigned long long)a >> b, 1750 2359 a >> b, 1751 2360 a << b); 1752 printf("shiftc: %Ld %Ld %Ld\n",2361 printf("shiftc: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", 1753 2362 (unsigned long long)a >> 3, 1754 2363 a >> 3, 1755 2364 a << 3); 1756 printf("shiftc: %Ld %Ld %Ld\n",2365 printf("shiftc: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", 1757 2366 (unsigned long long)a >> 35, 1758 2367 a >> 35, … … 1764 2373 float fa; 1765 2374 double da; 1766 long doublelda;2375 LONG_DOUBLE lda; 1767 2376 long long la, lb, lc; 1768 2377 unsigned long long ula, ulb, ulc; … … 1771 2380 la = (la << 20) | 0x12345; 1772 2381 ula = ula << 33; 1773 printf("la= %Ld ula=%Lu\n", la, ula);2382 printf("la=" LONG_LONG_FORMAT " ula=" ULONG_LONG_FORMAT "\n", la, ula); 1774 2383 1775 2384 fa = la; … … 1781 2390 lb = da; 1782 2391 lc = lda; 1783 printf("ftoll: %Ld %Ld %Ld\n", la, lb, lc);2392 printf("ftoll: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", la, lb, lc); 1784 2393 1785 2394 fa = ula; … … 1791 2400 ulb = da; 1792 2401 ulc = lda; 1793 printf("ftoull: %Lu %Lu %Lu\n", ula, ulb, ulc);2402 printf("ftoull: " ULONG_LONG_FORMAT " " ULONG_LONG_FORMAT " " ULONG_LONG_FORMAT "\n", ula, ulb, ulc); 1794 2403 } 1795 2404 … … 1807 2416 { 1808 2417 return ((long long int)v->item); 2418 } 2419 2420 long long llfunc2(long long x, long long y, int z) 2421 { 2422 return x * y * z; 1809 2423 } 1810 2424 … … 1820 2434 a = ia; 1821 2435 b = ua; 1822 printf( "%Ld %Ld\n", a, b);1823 printf( "%Ld %Ld %Ld%Lx\n",2436 printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b); 2437 printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %Lx\n", 1824 2438 (long long)1, 1825 2439 (long long)-2, … … 1827 2441 0x1234567812345679); 1828 2442 a = llfunc1(-3); 1829 printf( "%Ld\n", a);2443 printf(LONG_LONG_FORMAT "\n", a); 1830 2444 1831 2445 lloptest(1000, 23); … … 1855 2469 lloptest(0x80000000, 0); 1856 2470 1857 /* another long long spill test */1858 2471 { 1859 long long *p, v ;2472 long long *p, v, **pp; 1860 2473 v = 1; 1861 2474 p = &v; 1862 2475 p[0]++; 1863 printf("%lld\n", *p); 2476 printf("another long long spill test : %lld\n", *p); 2477 pp = &p; 2478 2479 v = llfunc2(**pp, **pp, ia); 2480 printf("a long long function (arm-)reg-args test : %lld\n", v); 1864 2481 } 1865 1866 2482 a = 68719476720LL; 1867 2483 b = 4294967295LL; 1868 2484 printf("%d %d %d %d\n", a > b, a < b, a >= b, a <= b); 1869 2485 1870 printf("%Ld\n", 0x123456789LLU); 2486 printf(LONG_LONG_FORMAT "\n", 0x123456789LLU); 2487 2488 /* long long pointer deref in argument passing test */ 2489 a = 0x123; 2490 long long *p = &a; 2491 llshift(*p, 5); 1871 2492 } 1872 2493 1873 2494 void manyarg_test(void) 1874 2495 { 1875 long doubleld = 1234567891234LL;2496 LONG_DOUBLE ld = 1234567891234LL; 1876 2497 printf("manyarg_test:\n"); 1877 2498 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n", … … 1879 2500 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0); 1880 2501 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f " 1881 "%Ld %Ld%f %f\n",2502 LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f\n", 1882 2503 1, 2, 3, 4, 5, 6, 7, 8, 1883 2504 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, … … 1885 2506 42.0, 43.0); 1886 2507 printf("%Lf %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f " 1887 "%Ld %Ld%f %f\n",2508 LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f\n", 1888 2509 ld, 1, 2, 3, 4, 5, 6, 7, 8, 1889 2510 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, 1890 2511 1234567891234LL, 987654321986LL, 1891 2512 42.0, 43.0); 1892 /* XXX: known bug of x86-64 */1893 #ifndef __x86_64__1894 2513 printf("%d %d %d %d %d %d %d %d %Lf\n", 1895 2514 1, 2, 3, 4, 5, 6, 7, 8, ld); 1896 2515 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f " 1897 "%Ld %Ld%f %f %Lf\n",2516 LONG_LONG_FORMAT " " LONG_LONG_FORMAT "%f %f %Lf\n", 1898 2517 1, 2, 3, 4, 5, 6, 7, 8, 1899 2518 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, … … 1901 2520 42.0, 43.0, ld); 1902 2521 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f " 1903 "%Lf %Ld %Ld%f %f %Lf\n",2522 "%Lf " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f %Lf\n", 1904 2523 1, 2, 3, 4, 5, 6, 7, 8, 1905 2524 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, 1906 2525 ld, 1234567891234LL, 987654321986LL, 1907 2526 42.0, 43.0, ld); 1908 #endif1909 2527 } 1910 2528 … … 1916 2534 double d; 1917 2535 long long ll; 1918 long doubleld;2536 LONG_DOUBLE ld; 1919 2537 1920 2538 va_start(aq, fmt); … … 1942 2560 case 'l': 1943 2561 ll = va_arg(ap, long long); 1944 printf( "%Ld", ll);2562 printf(LONG_LONG_FORMAT, ll); 1945 2563 break; 1946 2564 case 'F': 1947 ld = va_arg(ap, long double);2565 ld = va_arg(ap, LONG_DOUBLE); 1948 2566 printf("%Lf", ld); 1949 2567 break; … … 1978 2596 } 1979 2597 2598 void stdarg_for_libc(const char *fmt, ...) 2599 { 2600 va_list args; 2601 va_start(args, fmt); 2602 vprintf(fmt, args); 2603 va_end(args); 2604 } 2605 1980 2606 void stdarg_test(void) 1981 2607 { 1982 long doubleld = 1234567891234LL;2608 LONG_DOUBLE ld = 1234567891234LL; 1983 2609 struct myspace bob; 1984 2610 … … 1986 2612 vprintf1("%f %d %f\n", 1.0, 2, 3.0); 1987 2613 vprintf1("%l %l %d %f\n", 1234567891234LL, 987654321986LL, 3, 1234.0); 1988 vprintf1("%F %F %F\n", 1.2L, 2.3L, 3.4L); 1989 #ifdef __x86_64__ 1990 /* a bug of x86's TCC */ 2614 vprintf1("%F %F %F\n", LONG_DOUBLE_LITERAL(1.2), LONG_DOUBLE_LITERAL(2.3), LONG_DOUBLE_LITERAL(3.4)); 1991 2615 vprintf1("%d %f %l %F %d %f %l %F\n", 1992 1, 1.2, 3L, 4.5L, 6, 7.8, 9L, 0.1L); 1993 #endif 2616 1, 1.2, 3LL, LONG_DOUBLE_LITERAL(4.5), 6, 7.8, 9LL, LONG_DOUBLE_LITERAL(0.1)); 1994 2617 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f\n", 1995 2618 1, 2, 3, 4, 5, 6, 7, 8, … … 2027 2650 bob.profile = 42; 2028 2651 stdarg_for_struct(bob, bob, bob, bob.profile); 2652 stdarg_for_libc("stdarg_for_libc: %s %.2f %d\n", "string", 1.23, 456); 2029 2653 } 2030 2654 … … 2072 2696 int *rel2 = &reltab[2]; 2073 2697 2698 #ifdef _WIN64 2699 void relocation_test(void) {} 2700 #else 2701 void getmyaddress(void) 2702 { 2703 printf("in getmyaddress\n"); 2704 } 2705 2706 #ifdef __LP64__ 2707 long __pa_symbol(void) 2708 { 2709 /* This 64bit constant was handled incorrectly, it was used as addend 2710 (which can hold 64bit just fine) in connection with a symbol, 2711 and TCC generates wrong code for that (displacements are 32bit only). 2712 This effectively is "+ 0x80000000", and if addresses of globals 2713 are below 2GB the result should be a number without high 32 bits set. */ 2714 return ((long)(((unsigned long)(&rel1))) - (0xffffffff80000000UL)); 2715 } 2716 #endif 2717 2718 unsigned long theaddress = (unsigned long)getmyaddress; 2074 2719 void relocation_test(void) 2075 2720 { 2721 void (*fptr)(void) = (void (*)(void))theaddress; 2076 2722 printf("*rel1=%d\n", *rel1); 2077 2723 printf("*rel2=%d\n", *rel2); 2078 } 2724 fptr(); 2725 #ifdef __LP64__ 2726 printf("pa_symbol=0x%lx\n", __pa_symbol() >> 63); 2727 #endif 2728 } 2729 #endif 2079 2730 2080 2731 void old_style_f(a,b,c) … … 2105 2756 void alloca_test() 2106 2757 { 2107 #if defined __i386__ || defined __x86_64__ 2758 #if defined __i386__ || defined __x86_64__ || defined __arm__ 2108 2759 char *p = alloca(16); 2109 2760 strcpy(p,"123456789012345"); … … 2138 2789 tab1_ptr = tab1; 2139 2790 tab2_ptr = tab2; 2140 printf("Test C99 VLA 2 (ptrs sub stract): ");2791 printf("Test C99 VLA 2 (ptrs subtract): "); 2141 2792 printf("%s\n", (tab2 - tab1 == (tab2_ptr - tab1_ptr) / (sizeof(int) * 2)) ? "PASSED" : "FAILED"); 2142 2793 printf("Test C99 VLA 3 (ptr add): "); … … 2174 2825 } 2175 2826 2827 #ifndef __TINYC__ 2176 2828 typedef __SIZE_TYPE__ uintptr_t; 2829 #endif 2177 2830 2178 2831 void sizeof_test(void) … … 2218 2871 printf("__alignof__(unsigned char) = %d\n", __alignof__(unsigned char)); 2219 2872 printf("__alignof__(func) = %d\n", __alignof__ sizeof_test()); 2873 2874 /* sizes of VLAs need to be evaluated even inside sizeof: */ 2875 a = 2; 2876 printf("sizeof(char[1+2*a]) = %d\n", sizeof(char[1+2*a])); 2877 /* And checking if sizeof compound literal works. Parenthesized: */ 2878 printf("sizeof( (struct {int i; int j;}){4,5} ) = %d\n", 2879 sizeof( (struct {int i; int j;}){4,5} )); 2880 /* And as direct sizeof argument (as unary expression): */ 2881 printf("sizeof (struct {short i; short j;}){4,5} = %d\n", 2882 sizeof (struct {short i; short j;}){4,5} ); 2883 2884 /* sizeof(x && y) should be sizeof(int), even if constant 2885 evaluating is possible. */ 2886 printf("sizeof(t && 0) = %d\n", sizeof(t && 0)); 2887 printf("sizeof(1 && 1) = %d\n", sizeof(1 && 1)); 2888 printf("sizeof(t || 1) = %d\n", sizeof(t || 1)); 2889 printf("sizeof(0 || 0) = %d\n", sizeof(0 || 0)); 2220 2890 } 2221 2891 … … 2232 2902 } 2233 2903 2904 2905 struct hlist_node; 2906 struct hlist_head { 2907 struct hlist_node *first, *last; 2908 }; 2909 2910 void consume_ulong (unsigned long i) 2911 { 2912 i = 0; 2913 } 2914 2234 2915 void statement_expr_test(void) 2235 2916 { 2236 2917 int a, i; 2237 2918 2919 /* Basic stmt expr test */ 2238 2920 a = 0; 2239 2921 for(i=0;i<10;i++) { … … 2247 2929 printf("a=%d\n", a); 2248 2930 2931 /* Test that symbols aren't freed prematurely. 2932 With SYM_DEBUG valgrind will show a read from a freed 2933 symbol, and tcc will show an (invalid) warning on the initialization 2934 of 'ptr' below, if symbols are popped after the stmt expr. */ 2935 void *v = (void*)39; 2936 typeof(({ 2937 (struct hlist_node *)v; 2938 })) x; 2939 typeof (x) 2940 ptr = (struct hlist_node *)v; 2941 2942 /* This part used to segfault when symbols were popped prematurely. 2943 The symbols for the static local would be overwritten with 2944 helper symbols from the pre-processor expansions in between. */ 2945 #define some_attr __attribute__((aligned(1))) 2946 #define tps(str) ({ \ 2947 static const char *t some_attr = str; \ 2948 t; \ 2949 }) 2950 printf ("stmtexpr: %s %s\n", 2951 tps("somerandomlongstring"), 2952 tps("anotherlongstring")); 2953 2954 /* Test that the three decls of 't' don't interact. */ 2955 int t = 40; 2956 int b = ({ int t = 41; t; }); 2957 int c = ({ int t = 42; t; }); 2958 2959 /* Test that aggregate return values work. */ 2960 struct hlist_head h 2961 = ({ 2962 typedef struct hlist_head T; 2963 long pre = 48; 2964 T t = { (void*)43, (void*)44 }; 2965 long post = 49; 2966 t; 2967 }); 2968 printf ("stmtexpr: %d %d %d\n", t, b, c); 2969 printf ("stmtexpr: %ld %ld\n", (long)h.first, (long)h.last); 2970 2971 /* Test that we can give out addresses of local labels. */ 2972 consume_ulong(({ __label__ __here; __here: (unsigned long)&&__here; })); 2249 2973 } 2250 2974 … … 2280 3004 2281 3005 /* inline assembler test */ 2282 #if def __i386__3006 #if defined(__i386__) || defined(__x86_64__) 2283 3007 2284 3008 /* from linux kernel */ 2285 3009 static char * strncat1(char * dest,const char * src,size_t count) 2286 3010 { 2287 intd0, d1, d2, d3;3011 long d0, d1, d2, d3; 2288 3012 __asm__ __volatile__( 2289 3013 "repne\n\t" 2290 3014 "scasb\n\t" 2291 "dec l%1\n\t"2292 "mov l%8,%3\n"2293 "1:\tdec l%3\n\t"3015 "dec %1\n\t" 3016 "mov %8,%3\n" 3017 "1:\tdec %3\n\t" 2294 3018 "js 2f\n\t" 2295 3019 "lodsb\n\t" … … 2297 3021 "testb %%al,%%al\n\t" 2298 3022 "jne 1b\n" 2299 "2:\txor l%2,%2\n\t"3023 "2:\txor %2,%2\n\t" 2300 3024 "stosb" 2301 3025 : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3) … … 2307 3031 static char * strncat2(char * dest,const char * src,size_t count) 2308 3032 { 2309 intd0, d1, d2, d3;3033 long d0, d1, d2, d3; 2310 3034 __asm__ __volatile__( 2311 3035 "repne scasb\n\t" /* one-line repne prefix + string op */ 2312 "dec l%1\n\t"2313 "mov l%8,%3\n"2314 "1:\tdec l%3\n\t"3036 "dec %1\n\t" 3037 "mov %8,%3\n" 3038 "1:\tdec %3\n\t" 2315 3039 "js 2f\n\t" 2316 3040 "lodsb\n\t" … … 2318 3042 "testb %%al,%%al\n\t" 2319 3043 "jne 1b\n" 2320 "2:\txor l%2,%2\n\t"3044 "2:\txor %2,%2\n\t" 2321 3045 "stosb" 2322 3046 : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3) … … 2328 3052 static inline void * memcpy1(void * to, const void * from, size_t n) 2329 3053 { 2330 intd0, d1, d2;3054 long d0, d1, d2; 2331 3055 __asm__ __volatile__( 2332 3056 "rep ; movsl\n\t" … … 2346 3070 static inline void * memcpy2(void * to, const void * from, size_t n) 2347 3071 { 2348 intd0, d1, d2;3072 long d0, d1, d2; 2349 3073 __asm__ __volatile__( 2350 3074 "rep movsl\n\t" /* one-line rep prefix + string op */ … … 2369 3093 static __inline__ void sigdelset1(unsigned int *set, int _sig) 2370 3094 { 2371 asm("btrl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc" );3095 asm("btrl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc", "flags"); 2372 3096 } 2373 3097 … … 2377 3101 "rorl $16,%0\n\t" /* swap words */ 2378 3102 "xchgb %b0,%h0" /* swap higher bytes */ 2379 :"= q" (x)3103 :"=" "q" (x) 2380 3104 : "0" (x)); 2381 3105 return x; … … 2385 3109 { 2386 3110 unsigned long long res; 3111 #ifdef __x86_64__ 3112 /* Using the A constraint is wrong (it means rdx:rax, which is too large) 3113 but still test the 32bit->64bit mull. */ 3114 unsigned int resh, resl; 3115 __asm__("mull %2" : "=a" (resl), "=d" (resh) : "a" (a), "r" (b)); 3116 res = ((unsigned long long)resh << 32) | resl; 3117 #else 2387 3118 __asm__("mull %2" : "=A" (res) : "a" (a), "r" (b)); 3119 #endif 2388 3120 return res; 2389 3121 } … … 2392 3124 { 2393 3125 unsigned long long res; 3126 #ifdef __x86_64__ 3127 /* Using the A constraint is wrong, and increments are tested 3128 elsewhere. */ 3129 res = a + 1; 3130 #else 2394 3131 __asm__("addl $1, %%eax ; adcl $0, %%edx" : "=A" (res) : "A" (a)); 3132 #endif 2395 3133 return res; 2396 3134 } 2397 3135 3136 struct struct123 { 3137 int a; 3138 int b; 3139 }; 3140 struct struct1231 { 3141 unsigned long addr; 3142 }; 3143 3144 unsigned long mconstraint_test(struct struct1231 *r) 3145 { 3146 unsigned long ret; 3147 unsigned int a[2]; 3148 a[0] = 0; 3149 __asm__ volatile ("lea %2,%0; movl 4(%0),%k0; addl %2,%k0; movl $51,%2; movl $52,4%2; movl $63,%1" 3150 : "=&r" (ret), "=m" (a) 3151 : "m" (*(struct struct123 *)r->addr)); 3152 return ret + a[0]; 3153 } 3154 3155 #ifdef __x86_64__ 3156 int fls64(unsigned long long x) 3157 { 3158 int bitpos = -1; 3159 asm("bsrq %1,%q0" 3160 : "+r" (bitpos) 3161 : "rm" (x)); 3162 return bitpos + 1; 3163 } 3164 #endif 3165 3166 void other_constraints_test(void) 3167 { 3168 unsigned long ret; 3169 int var; 3170 #ifndef _WIN64 3171 __asm__ volatile ("mov %P1,%0" : "=r" (ret) : "p" (&var)); 3172 printf ("oc1: %d\n", ret == (unsigned long)&var); 3173 #endif 3174 } 3175 3176 #ifndef _WIN32 3177 /* Test global asm blocks playing with aliases. */ 3178 void base_func(void) 3179 { 3180 printf ("asmc: base\n"); 3181 } 3182 3183 extern void override_func1 (void); 3184 extern void override_func2 (void); 3185 3186 asm(".weak override_func1\n.set override_func1, base_func"); 3187 asm(".set override_func1, base_func"); 3188 asm(".set override_func2, base_func"); 3189 3190 void override_func2 (void) 3191 { 3192 printf ("asmc: override2\n"); 3193 } 3194 3195 /* This checks a construct used by the linux kernel to encode 3196 references to strings by PC relative references. */ 3197 extern int bug_table[] __attribute__((section("__bug_table"))); 3198 char * get_asm_string (void) 3199 { 3200 extern int some_symbol; 3201 asm volatile (".globl some_symbol\n" 3202 "jmp .+6\n" 3203 "1:\n" 3204 "some_symbol: .long 0\n" 3205 ".pushsection __bug_table, \"a\"\n" 3206 ".globl bug_table\n" 3207 "bug_table:\n" 3208 /* The first entry (1b-2b) is unused in this test, 3209 but we include it to check if cross-section 3210 PC-relative references work. */ 3211 "2:\t.long 1b - 2b, %c0 - 2b\n" 3212 ".popsection\n" : : "i" ("A string")); 3213 char * str = ((char*)bug_table) + bug_table[1]; 3214 return str; 3215 } 3216 3217 /* This checks another constructs with local labels. */ 3218 extern unsigned char alld_stuff[]; 3219 asm(".data\n" 3220 ".byte 41\n" 3221 "alld_stuff:\n" 3222 "661:\n" 3223 ".byte 42\n" 3224 "662:\n" 3225 ".pushsection .data.ignore\n" 3226 ".long 661b - .\n" /* This reference to 661 generates an external sym 3227 which shouldn't somehow overwrite the offset that's 3228 already determined for it. */ 3229 ".popsection\n" 3230 ".byte 662b - 661b\n" /* So that this value is undeniably 1. */); 3231 3232 void asm_local_label_diff (void) 3233 { 3234 printf ("asm_local_label_diff: %d %d\n", alld_stuff[0], alld_stuff[1]); 3235 } 3236 3237 /* This checks that static local variables are available from assembler. */ 3238 void asm_local_statics (void) 3239 { 3240 static int localint = 41; 3241 asm("incl %0" : "+m" (localint)); 3242 printf ("asm_local_statics: %d\n", localint); 3243 } 3244 #endif 3245 3246 static 2398 3247 unsigned int set; 2399 3248 3249 void fancy_copy (unsigned *in, unsigned *out) 3250 { 3251 asm volatile ("" : "=r" (*out) : "0" (*in)); 3252 } 3253 3254 void fancy_copy2 (unsigned *in, unsigned *out) 3255 { 3256 asm volatile ("mov %0,(%1)" : : "r" (*in), "r" (out) : "memory"); 3257 } 3258 3259 #if defined __x86_64__ && !defined _WIN64 3260 void clobber_r12(void) 3261 { 3262 asm volatile("mov $1, %%r12" ::: "r12"); 3263 } 3264 #endif 3265 3266 void test_high_clobbers(void) 3267 { 3268 #if defined __x86_64__ && !defined _WIN64 3269 register long val asm("r12"); 3270 long val2; 3271 /* This tests if asm clobbers correctly save/restore callee saved 3272 registers if they are clobbered and if it's the high 8 x86-64 3273 registers. This is fragile for GCC as the constraints do not 3274 correctly capture the data flow, but good enough for us. */ 3275 asm volatile("mov $0x4542, %%r12" : "=r" (val):: "memory"); 3276 clobber_r12(); 3277 asm volatile("mov %%r12, %0" : "=r" (val2) : "r" (val): "memory"); 3278 printf("asmhc: 0x%x\n", val2); 3279 #endif 3280 } 3281 3282 static long cpu_number; 3283 void trace_console(long len, long len2) 3284 { 3285 #ifdef __x86_64__ 3286 /* This generated invalid code when the emission of the switch 3287 table isn't disabled. The asms are necessary to show the bug, 3288 normal statements don't work (they need to generate some code 3289 even under nocode_wanted, which normal statements don't do, 3290 but asms do). Also at least these number of cases is necessary 3291 to generate enough "random" bytes. They ultimately are enough 3292 to create invalid instruction patterns to which the first 3293 skip-to-decision-table jump jumps. If decision table emission 3294 is disabled all of this is no problem. 3295 3296 It also is necessary that the switches are in a statement expression 3297 (which has the property of not being enterable from outside. no 3298 matter what). */ 3299 if (0 3300 && 3301 ({ 3302 long pscr_ret__; 3303 switch(len) { 3304 case 4: 3305 { 3306 long pfo_ret__; 3307 switch (len2) { 3308 case 8: printf("bla"); pfo_ret__ = 42; break; 3309 } 3310 pscr_ret__ = pfo_ret__; 3311 } 3312 break; 3313 case 8: 3314 { 3315 long pfo_ret__; 3316 switch (len2) { 3317 case 1:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break; 3318 case 2:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break; 3319 case 4:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break; 3320 case 8:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break; 3321 default: printf("impossible\n"); 3322 } 3323 pscr_ret__ = pfo_ret__; 3324 }; 3325 break; 3326 } 3327 pscr_ret__; 3328 })) 3329 { 3330 printf("huh?\n"); 3331 } 3332 #endif 3333 } 3334 3335 void test_asm_dead_code(void) 3336 { 3337 long rdi; 3338 /* Try to make sure that xdi contains a zero, and hence will 3339 lead to a segfault if the next asm is evaluated without 3340 arguments being set up. */ 3341 asm volatile ("" : "=D" (rdi) : "0" (0)); 3342 (void)sizeof (({ 3343 int var; 3344 /* This shouldn't trigger a segfault, either the argument 3345 registers need to be set up and the asm emitted despite 3346 this being in an unevaluated context, or both the argument 3347 setup _and_ the asm emission need to be suppressed. The latter 3348 is better. Disabling asm code gen when suppression is on 3349 also fixes the above trace_console bug, but that came earlier 3350 than asm suppression. */ 3351 asm volatile ("movl $0,(%0)" : : "D" (&var) : "memory"); 3352 var; 3353 })); 3354 } 3355 3356 void test_asm_call(void) 3357 { 3358 #if defined __x86_64__ && !defined _WIN64 3359 static char str[] = "PATH"; 3360 char *s; 3361 /* This tests if a reference to an undefined symbol from an asm 3362 block, which isn't otherwise referenced in this file, is correctly 3363 regarded as global symbol, so that it's resolved by other object files 3364 or libraries. We chose getenv here, which isn't used anywhere else 3365 in this file. (If we used e.g. printf, which is used we already 3366 would have a global symbol entry, not triggering the bug which is 3367 tested here). */ 3368 /* two pushes so stack remains aligned */ 3369 asm volatile ("push %%rdi; push %%rdi; mov %0, %%rdi;" 3370 #if 1 && !defined(__TINYC__) && (defined(__PIC__) || defined(__PIE__)) 3371 "call getenv@plt;" 3372 #else 3373 "call getenv;" 3374 #endif 3375 "pop %%rdi; pop %%rdi" 3376 : "=a" (s) : "r" (str)); 3377 printf("asmd: %s\n", s); 3378 #endif 3379 } 3380 3381 #if defined __x86_64__ 3382 # define RX "(%rip)" 3383 #else 3384 # define RX 3385 #endif 3386 3387 void asm_dot_test(void) 3388 { 3389 int x; 3390 for (x = 1;; ++x) { 3391 int r = x; 3392 switch (x) { 3393 case 1: 3394 asm(".text; lea S"RX",%eax; lea ."RX",%ecx; sub %ecx,%eax; S=.; jmp p0"); 3395 case 2: 3396 asm(".text; jmp .+6; .int 123; mov .-4"RX",%eax; jmp p0"); 3397 case 3: 3398 asm(".data; Y=.; .int 999; X=Y; .int 456; X=.-4"); 3399 asm(".text; mov X"RX",%eax; jmp p0"); 3400 case 4: 3401 asm(".data; X=.; .int 789; Y=.; .int 999"); 3402 asm(".text; mov X"RX",%eax; X=Y; jmp p0"); 3403 case 0: 3404 asm(".text; p0=.; mov %%eax,%0;" : "=m"(r)); break; 3405 } 3406 if (r == x) 3407 break; 3408 printf("asm_dot_test %d: %d\n", x, r); 3409 } 3410 } 3411 2400 3412 void asm_test(void) 2401 3413 { 2402 3414 char buf[128]; 2403 unsigned int val; 3415 unsigned int val, val2; 3416 struct struct123 s1; 3417 struct struct1231 s2 = { (unsigned long)&s1 }; 3418 /* Hide the outer base_func, but check later that the inline 3419 asm block gets the outer one. */ 3420 int base_func = 42; 3421 void override_func3 (void); 3422 unsigned long asmret; 3423 #ifdef BOOL_ISOC99 3424 _Bool somebool; 3425 #endif 3426 register int regvar asm("%esi"); 2404 3427 2405 3428 printf("inline asm:\n"); 3429 3430 // parse 0x1E-1 as 3 tokens in asm mode 3431 asm volatile ("mov $0x1E-1,%eax"); 3432 2406 3433 /* test the no operand case */ 2407 3434 asm volatile ("xorl %eax, %eax"); … … 2419 3446 printf("inc64=0x%Lx\n", inc64(0x12345678ffffffff)); 2420 3447 3448 s1.a = 42; 3449 s1.b = 43; 3450 printf("mconstraint: %d", mconstraint_test(&s2)); 3451 printf(" %d %d\n", s1.a, s1.b); 3452 other_constraints_test(); 2421 3453 set = 0xff; 2422 3454 sigdelset1(&set, 2); … … 2427 3459 label2: 2428 3460 __asm__("btsl %1,%0" : "=m"(set) : "Ir"(20) : "cc"); 2429 #ifdef __GNUC__ // works strange with GCC 4.32430 set=0x1080fd;2431 #endif2432 3461 printf("set=0x%x\n", set); 2433 3462 val = 0x01020304; 2434 3463 printf("swab32(0x%08x) = 0x%0x\n", val, swab32(val)); 3464 #ifndef _WIN32 3465 override_func1(); 3466 override_func2(); 3467 /* The base_func ref from the following inline asm should find 3468 the global one, not the local decl from this function. */ 3469 asm volatile(".weak override_func3\n.set override_func3, base_func"); 3470 override_func3(); 3471 printf("asmstr: %s\n", get_asm_string()); 3472 asm_local_label_diff(); 3473 asm_local_statics(); 3474 #endif 3475 /* Check that we can also load structs of appropriate layout 3476 into registers. */ 3477 asm volatile("" : "=r" (asmret) : "0"(s2)); 3478 if (asmret != s2.addr) 3479 printf("asmstr: failed\n"); 3480 #ifdef BOOL_ISOC99 3481 /* Check that the typesize correctly sets the register size to 3482 8 bit. */ 3483 asm volatile("cmp %1,%2; sete %0" : "=a"(somebool) : "r"(1), "r"(2)); 3484 if (!somebool) 3485 printf("asmbool: failed\n"); 3486 #endif 3487 val = 43; 3488 fancy_copy (&val, &val2); 3489 printf ("fancycpy(%d)=%d\n", val, val2); 3490 val = 44; 3491 fancy_copy2 (&val, &val2); 3492 printf ("fancycpy2(%d)=%d\n", val, val2); 3493 asm volatile ("mov $0x4243, %%esi" : "=r" (regvar)); 3494 printf ("regvar=%x\n", regvar); 3495 test_high_clobbers(); 3496 trace_console(8, 8); 3497 test_asm_dead_code(); 3498 test_asm_call(); 3499 asm_dot_test(); 2435 3500 return; 2436 3501 label1: … … 2456 3521 void builtin_test(void) 2457 3522 { 3523 short s; 3524 int i; 3525 long long ll; 2458 3526 #if GCC_MAJOR >= 3 2459 3527 COMPAT_TYPE(int, int); … … 2466 3534 COMPAT_TYPE(int *, const int *); 2467 3535 COMPAT_TYPE(char *, unsigned char *); 3536 COMPAT_TYPE(char *, signed char *); 3537 COMPAT_TYPE(char *, char *); 2468 3538 /* space is needed because tcc preprocessor introduces a space between each token */ 2469 3539 COMPAT_TYPE(char * *, void *); … … 2473 3543 printf("res = %d\n", __builtin_constant_p(&constant_p_var)); 2474 3544 printf("res = %d\n", __builtin_constant_p(constant_p_var)); 3545 printf("res = %d\n", __builtin_constant_p(100000 / constant_p_var)); 3546 s = 1; 3547 ll = 2; 3548 i = __builtin_choose_expr (1 != 0, ll, s); 3549 printf("bce: %d\n", i); 3550 i = __builtin_choose_expr (1 != 1, ll, s); 3551 printf("bce: %d\n", i); 3552 i = sizeof (__builtin_choose_expr (1, ll, s)); 3553 printf("bce: %d\n", i); 3554 i = sizeof (__builtin_choose_expr (0, ll, s)); 3555 printf("bce: %d\n", i); 3556 3557 //printf("bera: %p\n", __builtin_extract_return_addr((void*)43)); 2475 3558 } 2476 3559 … … 2525 3608 printf("weak_asm_v2=%d\n",&weak_asm_v2 != NULL); 2526 3609 printf("weak_asm_v3=%d\n",&weak_asm_v3 != NULL); 3610 printf("some_lib_func=%d\n", &some_lib_func ? some_lib_func() : 0); 2527 3611 } 2528 3612 … … 2678 3762 void callsave_test(void) 2679 3763 { 2680 #if defined __i386__ || defined __x86_64__ 3764 #if defined __i386__ || defined __x86_64__ || defined __arm__ 2681 3765 int i, s; double *d; double t; 2682 3766 s = sizeof (double); … … 2707 3791 { 2708 3792 printf("bfa1: %s\n", (char *)__builtin_frame_address(1) + str_offset); 2709 #if defined(__arm__) && !defined(__GNUC__)2710 3793 bfa2(str_offset); 2711 #endif2712 3794 } 2713 3795 2714 3796 void builtin_frame_address_test(void) 2715 3797 { 3798 /* builtin_frame_address fails on ARM with gcc which make test3 fail */ 3799 #ifndef __arm__ 2716 3800 char str[] = "__builtin_frame_address"; 2717 3801 char *fp0 = __builtin_frame_address(0); … … 2719 3803 printf("str: %s\n", str); 2720 3804 bfa1(str-fp0); 2721 } 3805 #endif 3806 } 3807 3808 char via_volatile (char i) 3809 { 3810 char volatile vi; 3811 vi = i; 3812 return vi; 3813 } 3814 3815 struct __attribute__((__packed__)) Spacked { 3816 char a; 3817 short b; 3818 int c; 3819 }; 3820 struct Spacked spacked; 3821 typedef struct __attribute__((__packed__)) { 3822 char a; 3823 short b; 3824 int c; 3825 } Spacked2; 3826 Spacked2 spacked2; 3827 typedef struct Spacked3_s { 3828 char a; 3829 short b; 3830 int c; 3831 } __attribute__((__packed__)) Spacked3; 3832 Spacked3 spacked3; 3833 struct gate_struct64 { 3834 unsigned short offset_low; 3835 unsigned short segment; 3836 unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1; 3837 unsigned short offset_middle; 3838 unsigned offset_high; 3839 unsigned zero1; 3840 } __attribute__((packed)); 3841 typedef struct gate_struct64 gate_desc; 3842 gate_desc a_gate_desc; 3843 void attrib_test(void) 3844 { 3845 #ifndef _WIN32 3846 printf("attr: %d %d %d %d\n", sizeof(struct Spacked), 3847 sizeof(spacked), sizeof(Spacked2), sizeof(spacked2)); 3848 printf("attr: %d %d\n", sizeof(Spacked3), sizeof(spacked3)); 3849 printf("attr: %d %d\n", sizeof(gate_desc), sizeof(a_gate_desc)); 3850 #endif 3851 } 3852 extern __attribute__((__unused__)) char * __attribute__((__unused__)) * 3853 strange_attrib_placement (void); 3854 3855 void * __attribute__((__unused__)) get_void_ptr (void *a) 3856 { 3857 return a; 3858 } 3859 3860 /* This part checks for a bug in TOK_GET (used for inline expansion), 3861 where the large long long constant left the the high bits set for 3862 the integer constant token. */ 3863 static inline 3864 int __get_order(unsigned long long size) 3865 { 3866 int order; 3867 size -= 0xffff880000000000ULL; // this const left high bits set in the token 3868 { 3869 struct S { int i : 1; } s; // constructed for this '1' 3870 } 3871 order = size; 3872 return order; 3873 } 3874 3875 /* This just forces the above inline function to be actually emitted. */ 3876 int force_get_order(unsigned long s) 3877 { 3878 return __get_order(s); 3879 }
Note:
See TracChangeset
for help on using the changeset viewer.