Unified · Split
| @@ -23,15 +23,21 @@ · 22 unmodified lines | ||
| 23 | 23 | /* preprocessor debug */ |
| 24 | 24 | //#define PP_DEBUG |
| 25 | 25 | |
| 26 | −#define TEXT_SIZE 50000 | |
| 27 | −#define DATA_SIZE 50000 | |
| 26 | +/* these sizes are dummy for unix, because malloc() does not use | |
| 27 | + memory when the pages are not used */ | |
| 28 | +#define TEXT_SIZE (4*1024*1024) | |
| 29 | +#define DATA_SIZE (4*1024*1024) | |
| 30 | + | |
| 28 | 31 | #define INCLUDE_STACK_SIZE 32 |
| 29 | 32 | #define IFDEF_STACK_SIZE 64 |
| 30 | 33 | #define VSTACK_SIZE 64 |
| 31 | 34 | #define STRING_MAX_SIZE 1024 |
| 32 | 35 | #define INCLUDE_PATHS_MAX 32 |
| 33 | 36 | |
| 37 | +/* number of available temporary registers */ | |
| 34 | 38 | #define NB_REGS 3 |
| 39 | +/* defined if function parameters must be evaluated in revert order */ | |
| 40 | +#define INVERT_FUNC_PARAMS | |
| 35 | 41 | |
| 36 | 42 | /* token symbol management */ |
| 37 | 43 | typedef struct TokenSym { |
| @@ -107,8 +113,9 @@ int nb_include_paths; · 69 unmodified lines | ||
| 107 | 113 | #define VT_FORWARD 0x0020 /* value is forward reference |
| 108 | 114 | (only used for functions) */ |
| 109 | 115 | |
| 116 | +/* types */ | |
| 110 | 117 | #define VT_VOID 0x00040 |
| 111 | −#define VT_BYTE 0x00080 /* byte type */ | |
| 118 | +#define VT_BYTE 0x00080 /* signed byte type */ | |
| 112 | 119 | #define VT_PTR 0x00100 /* pointer increment */ |
| 113 | 120 | #define VT_UNSIGNED 0x00200 /* unsigned type */ |
| 114 | 121 | #define VT_ARRAY 0x00400 /* array type (only used in parsing) */ |
| @@ -116,17 +123,15 @@ int nb_include_paths; · 1 unmodified line | ||
| 116 | 123 | #define VT_FUNC 0x01000 /* function type */ |
| 117 | 124 | #define VT_STRUCT 0x002000 /* struct/union definition */ |
| 118 | 125 | #define VT_TYPEDEF 0x004000 /* typedef definition */ |
| 119 | −#define VT_EXTERN 0x008000 /* extern definition */ | |
| 120 | −#define VT_STATIC 0x010000 /* static variable */ | |
| 121 | −#define VT_STRUCT_SHIFT 17 /* structure/enum name shift (12 bits lefts) */ | |
| 126 | +#define VT_EXTERN 0x008000 /* extern definition */ | |
| 127 | +#define VT_STATIC 0x010000 /* static variable */ | |
| 128 | +#define VT_SHORT 0x020000 /* short type */ | |
| 129 | +#define VT_STRUCT_SHIFT 18 /* structure/enum name shift (14 bits left) */ | |
| 122 | 130 | |
| 123 | 131 | #define VT_TYPE 0xffffffc0 /* type mask */ |
| 124 | 132 | #define VT_TYPEN 0x0000003f /* ~VT_TYPE */ |
| 125 | 133 | #define VT_FUNCN -4097 /* ~VT_FUNC */ |
| 126 | 134 | |
| 127 | − | |
| 128 | −/* Special infos */ | |
| 129 | − | |
| 130 | 135 | /* token values */ |
| 131 | 136 | |
| 132 | 137 | /* warning: the following compare tokens depend on i386 asm code */ |
| @@ -516,7 +521,6 @@ void minp() · 383 unmodified lines | ||
| 516 | 521 | } |
| 517 | 522 | |
| 518 | 523 | /* same as minp, but also skip comments */ |
| 519 | −/* XXX: skip strings & chars */ | |
| 520 | 524 | void cinp() |
| 521 | 525 | { |
| 522 | 526 | int c; |
| @@ -1196,6 +1200,12 @@ void macro_subst(int **tok_str, int *tok_len, · 673 unmodified lines | ||
| 1196 | 1200 | expect(")"); |
| 1197 | 1201 | /* now subst each arg */ |
| 1198 | 1202 | mstr = macro_arg_subst(nested_list, mstr, args); |
| 1203 | + /* free memory */ | |
| 1204 | + sa = args; | |
| 1205 | + while (sa) { | |
| 1206 | + free((int *)sa->c); | |
| 1207 | + sa = sa->prev; | |
| 1208 | + } | |
| 1199 | 1209 | sym_pop(&args, NULL); |
| 1200 | 1210 | mstr_allocated = 1; |
| 1201 | 1211 | } |
| @@ -1335,6 +1345,12 @@ void load(r, ft, fc) · 133 unmodified lines | ||
| 1335 | 1345 | } |
| 1336 | 1346 | if ((ft & VT_TYPE) == VT_BYTE) |
| 1337 | 1347 | o(0xbe0f); /* movsbl */ |
| 1348 | + else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) | |
| 1349 | + o(0xb60f); /* movzbl */ | |
| 1350 | + else if ((ft & VT_TYPE) == VT_SHORT) | |
| 1351 | + o(0xbf0f); /* movswl */ | |
| 1352 | + else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) | |
| 1353 | + o(0xb70f); /* movzwl */ | |
| 1338 | 1354 | else |
| 1339 | 1355 | o(0x8b); /* movl */ |
| 1340 | 1356 | if (v == VT_CONST) { |
| @@ -1376,6 +1392,9 @@ void store(r, ft, fc) · 35 unmodified lines | ||
| 1376 | 1392 | |
| 1377 | 1393 | fr = ft & VT_VALMASK; |
| 1378 | 1394 | b = (ft & VT_TYPE) == VT_BYTE; |
| 1395 | + /* XXX: incorrect if reg to reg */ | |
| 1396 | + if (ft & VT_SHORT) | |
| 1397 | + o(0x66); | |
| 1379 | 1398 | o(0x89 - b); |
| 1380 | 1399 | if (fr == VT_CONST) { |
| 1381 | 1400 | oad(0x05 + r * 8, fc); /* mov r,xxx */ |
| @@ -1388,6 +1407,11 @@ void store(r, ft, fc) · 6 unmodified lines | ||
| 1388 | 1407 | } |
| 1389 | 1408 | } |
| 1390 | 1409 | |
| 1410 | +void gfunc_param(void) | |
| 1411 | +{ | |
| 1412 | + o(0x50 + gv()); /* push r */ | |
| 1413 | +} | |
| 1414 | + | |
| 1391 | 1415 | int gjmp(t) |
| 1392 | 1416 | { |
| 1393 | 1417 | return psym(0xe9, t); |
| @@ -1797,6 +1821,9 @@ int type_size(int t, int *a) · 403 unmodified lines | ||
| 1797 | 1821 | (t & VT_ENUM)) { |
| 1798 | 1822 | *a = 4; |
| 1799 | 1823 | return 4; |
| 1824 | + } else if (t & VT_SHORT) { | |
| 1825 | + *a = 2; | |
| 1826 | + return 2; | |
| 1800 | 1827 | } else { |
| 1801 | 1828 | *a = 1; |
| 1802 | 1829 | return 1; |
| @@ -1967,7 +1994,9 @@ int ist(void) · 164 unmodified lines | ||
| 1967 | 1994 | t |= VT_BYTE; |
| 1968 | 1995 | } else if (tok == TOK_VOID) { |
| 1969 | 1996 | t |= VT_VOID; |
| 1970 | − } else if (tok == TOK_INT | tok == TOK_SHORT | | |
| 1997 | + } else if (tok == TOK_SHORT) { | |
| 1998 | + t |= VT_SHORT; | |
| 1999 | + } else if (tok == TOK_INT | | |
| 1971 | 2000 | (tok >= TOK_CONST & tok <= TOK_INLINE)) { |
| 1972 | 2001 | /* ignored types */ |
| 1973 | 2002 | } else if (tok == TOK_FLOAT || tok == TOK_DOUBLE) { |
| @@ -2308,28 +2337,64 @@ void unary() · 334 unmodified lines | ||
| 2308 | 2337 | ft = vt; |
| 2309 | 2338 | fc = vc; |
| 2310 | 2339 | next(); |
| 2340 | +#ifdef INVERT_FUNC_PARAMS | |
| 2341 | + { | |
| 2342 | + int *str, len, parlevel, *saved_macro_ptr; | |
| 2343 | + Sym *args; | |
| 2344 | + | |
| 2345 | + /* read each argument and store it on a stack */ | |
| 2346 | + /* XXX: merge it with macro args ? */ | |
| 2347 | + args = NULL; | |
| 2348 | + while (tok != ')') { | |
| 2349 | + len = 0; | |
| 2350 | + str = NULL; | |
| 2351 | + parlevel = 0; | |
| 2352 | + while ((parlevel > 0 || (tok != ')' && tok != ',')) && | |
| 2353 | + tok != -1) { | |
| 2354 | + if (tok == '(') | |
| 2355 | + parlevel++; | |
| 2356 | + else if (tok == ')') | |
| 2357 | + parlevel--; | |
| 2358 | + tok_add2(&str, &len, tok, tokc); | |
| 2359 | + next(); | |
| 2360 | + } | |
| 2361 | + tok_add(&str, &len, -1); /* end of file added */ | |
| 2362 | + tok_add(&str, &len, 0); | |
| 2363 | + sym_push1(&args, 0, 0, (int)str); | |
| 2364 | + if (tok != ',') | |
| 2365 | + break; | |
| 2366 | + next(); | |
| 2367 | + } | |
| 2368 | + if (tok != ')') | |
| 2369 | + expect(")"); | |
| 2370 | + | |
| 2371 | + /* now generate code in reverse order by reading the stack */ | |
| 2372 | + saved_macro_ptr = macro_ptr; | |
| 2373 | + t = 0; | |
| 2374 | + while (args) { | |
| 2375 | + t += 4; | |
| 2376 | + macro_ptr = (int *)args->c; | |
| 2377 | + next(); | |
| 2378 | + expr_eq(); | |
| 2379 | + gfunc_param(); | |
| 2380 | + free((int *)args->c); | |
| 2381 | + sym_pop(&args, args->prev); | |
| 2382 | + } | |
| 2383 | + macro_ptr = saved_macro_ptr; | |
| 2384 | + /* restore token */ | |
| 2385 | + tok = ')'; | |
| 2386 | + } | |
| 2387 | +#else | |
| 2311 | 2388 | t = 0; |
| 2312 | 2389 | while (tok != ')') { |
| 2313 | − t = t + 4; | |
| 2390 | + t += 4; | |
| 2314 | 2391 | expr_eq(); |
| 2315 | − r = gv(); | |
| 2316 | − o(0x50 + r); /* push r */ | |
| 2392 | + gfunc_param(); | |
| 2317 | 2393 | if (tok == ',') |
| 2318 | 2394 | next(); |
| 2319 | 2395 | } |
| 2396 | +#endif | |
| 2320 | 2397 | skip(')'); |
| 2321 | − /* horrible, but needed : convert to native ordering (could | |
| 2322 | − parse parameters in reverse order, but would cost more | |
| 2323 | − code) */ | |
| 2324 | − n = 0; | |
| 2325 | − p = t - 4; | |
| 2326 | − while (n < p) { | |
| 2327 | − oad(0x24848b, p); /* mov x(%esp,1), %eax */ | |
| 2328 | − oad(0x248487, n); /* xchg x(%esp,1), %eax */ | |
| 2329 | − oad(0x248489, p); /* mov %eax, x(%esp,1) */ | |
| 2330 | − n = n + 4; | |
| 2331 | − p = p - 4; | |
| 2332 | − } | |
| 2333 | 2398 | if ((ft & VT_VALMASK) == VT_CONST) { |
| 2334 | 2399 | /* forward reference */ |
| 2335 | 2400 | if (ft & VT_FORWARD) { |
| @@ -2450,7 +2515,7 @@ void eor() · 114 unmodified lines | ||
| 2450 | 2515 | /* XXX: better constant handling */ |
| 2451 | 2516 | void expr_eq() |
| 2452 | 2517 | { |
| 2453 | − int t, u, c; | |
| 2518 | + int t, u, c, r1, r2; | |
| 2454 | 2519 | |
| 2455 | 2520 | if (const_wanted) { |
| 2456 | 2521 | sum(10); |
| @@ -2470,12 +2535,14 @@ void expr_eq() · 13 unmodified lines | ||
| 2470 | 2535 | next(); |
| 2471 | 2536 | t = gtst(1, 0); |
| 2472 | 2537 | expr(); |
| 2473 | − gv(); | |
| 2538 | + r1 = gv(); | |
| 2474 | 2539 | skip(':'); |
| 2475 | 2540 | u = gjmp(0); |
| 2476 | 2541 | gsym(t); |
| 2477 | 2542 | expr_eq(); |
| 2478 | − gv(); | |
| 2543 | + r2 = gv(); | |
| 2544 | + move_reg(r1, r2); | |
| 2545 | + vt = (vt & VT_TYPE) | r1; | |
| 2479 | 2546 | gsym(u); |
| 2480 | 2547 | } |
| 2481 | 2548 | } |
| @@ -2835,7 +2902,8 @@ int main(int argc, char **argv) · 353 unmodified lines | ||
| 2835 | 2902 | optind = 1; |
| 2836 | 2903 | while (1) { |
| 2837 | 2904 | if (optind >= argc) { |
| 2838 | − printf("usage: tcc [-Idir] [-Dsym] [-llib] infile [infile_arg...]\n"); | |
| 2905 | + printf("tcc version 0.9 - Tiny C Compiler - Copyright (C) 2001 Fabrice Bellard\n" | |
| 2906 | + "usage: tcc [-Idir] [-Dsym] [-llib] infile [infile_arg...]\n"); | |
| 2839 | 2907 | return 1; |
| 2840 | 2908 | } |
| 2841 | 2909 | r = argv[optind]; |
| @@ -2890,7 +2958,7 @@ int main(int argc, char **argv) · 48 unmodified lines | ||
| 2890 | 2958 | s = sym_find(TOK_MAIN); |
| 2891 | 2959 | if (!s) |
| 2892 | 2960 | error("main() not defined"); |
| 2893 | − t = s->c; | |
| 2961 | + t = (int (*)())s->c; | |
| 2894 | 2962 | #ifdef PROFILE |
| 2895 | 2963 | return 1; |
| 2896 | 2964 | #else |