Unified · Split
| @@ -23,15 +23,21 @@ · 22 unmodified lines | |||
| 23 | /* preprocessor debug */ | 23 | /* preprocessor debug */ |
| 24 | //#define PP_DEBUG | 24 | //#define PP_DEBUG |
| 25 | 25 | ||
| 26 | #define TEXT_SIZE 50000 | 26 | /* these sizes are dummy for unix, because malloc() does not use |
| 27 | #define DATA_SIZE 50000 | 27 | memory when the pages are not used */ |
| 28 | #define TEXT_SIZE (4*1024*1024) | ||
| 29 | #define DATA_SIZE (4*1024*1024) | ||
| 30 | |||
| 28 | #define INCLUDE_STACK_SIZE 32 | 31 | #define INCLUDE_STACK_SIZE 32 |
| 29 | #define IFDEF_STACK_SIZE 64 | 32 | #define IFDEF_STACK_SIZE 64 |
| 30 | #define VSTACK_SIZE 64 | 33 | #define VSTACK_SIZE 64 |
| 31 | #define STRING_MAX_SIZE 1024 | 34 | #define STRING_MAX_SIZE 1024 |
| 32 | #define INCLUDE_PATHS_MAX 32 | 35 | #define INCLUDE_PATHS_MAX 32 |
| 33 | 36 | ||
| 37 | /* number of available temporary registers */ | ||
| 34 | #define NB_REGS 3 | 38 | #define NB_REGS 3 |
| 39 | /* defined if function parameters must be evaluated in revert order */ | ||
| 40 | #define INVERT_FUNC_PARAMS | ||
| 35 | 41 | ||
| 36 | /* token symbol management */ | 42 | /* token symbol management */ |
| 37 | typedef struct TokenSym { | 43 | typedef struct TokenSym { |
| @@ -107,8 +113,9 @@ int nb_include_paths; · 69 unmodified lines | |||
| 107 | #define VT_FORWARD 0x0020 /* value is forward reference | 113 | #define VT_FORWARD 0x0020 /* value is forward reference |
| 108 | (only used for functions) */ | 114 | (only used for functions) */ |
| 109 | 115 | ||
| 116 | /* types */ | ||
| 110 | #define VT_VOID 0x00040 | 117 | #define VT_VOID 0x00040 |
| 111 | #define VT_BYTE 0x00080 /* byte type */ | 118 | #define VT_BYTE 0x00080 /* signed byte type */ |
| 112 | #define VT_PTR 0x00100 /* pointer increment */ | 119 | #define VT_PTR 0x00100 /* pointer increment */ |
| 113 | #define VT_UNSIGNED 0x00200 /* unsigned type */ | 120 | #define VT_UNSIGNED 0x00200 /* unsigned type */ |
| 114 | #define VT_ARRAY 0x00400 /* array type (only used in parsing) */ | 121 | #define VT_ARRAY 0x00400 /* array type (only used in parsing) */ |
| @@ -116,17 +123,15 @@ int nb_include_paths; · 1 unmodified line | |||
| 116 | #define VT_FUNC 0x01000 /* function type */ | 123 | #define VT_FUNC 0x01000 /* function type */ |
| 117 | #define VT_STRUCT 0x002000 /* struct/union definition */ | 124 | #define VT_STRUCT 0x002000 /* struct/union definition */ |
| 118 | #define VT_TYPEDEF 0x004000 /* typedef definition */ | 125 | #define VT_TYPEDEF 0x004000 /* typedef definition */ |
| 119 | #define VT_EXTERN 0x008000 /* extern definition */ | 126 | #define VT_EXTERN 0x008000 /* extern definition */ |
| 120 | #define VT_STATIC 0x010000 /* static variable */ | 127 | #define VT_STATIC 0x010000 /* static variable */ |
| 121 | #define VT_STRUCT_SHIFT 17 /* structure/enum name shift (12 bits lefts) */ | 128 | #define VT_SHORT 0x020000 /* short type */ |
| 129 | #define VT_STRUCT_SHIFT 18 /* structure/enum name shift (14 bits left) */ | ||
| 122 | 130 | ||
| 123 | #define VT_TYPE 0xffffffc0 /* type mask */ | 131 | #define VT_TYPE 0xffffffc0 /* type mask */ |
| 124 | #define VT_TYPEN 0x0000003f /* ~VT_TYPE */ | 132 | #define VT_TYPEN 0x0000003f /* ~VT_TYPE */ |
| 125 | #define VT_FUNCN -4097 /* ~VT_FUNC */ | 133 | #define VT_FUNCN -4097 /* ~VT_FUNC */ |
| 126 | 134 | ||
| 127 | |||
| 128 | /* Special infos */ | ||
| 129 | |||
| 130 | /* token values */ | 135 | /* token values */ |
| 131 | 136 | ||
| 132 | /* warning: the following compare tokens depend on i386 asm code */ | 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 | /* same as minp, but also skip comments */ | 523 | /* same as minp, but also skip comments */ |
| 519 | /* XXX: skip strings & chars */ | ||
| 520 | void cinp() | 524 | void cinp() |
| 521 | { | 525 | { |
| 522 | int c; | 526 | int c; |
| @@ -1196,6 +1200,12 @@ void macro_subst(int **tok_str, int *tok_len, · 673 unmodified lines | |||
| 1196 | expect(")"); | 1200 | expect(")"); |
| 1197 | /* now subst each arg */ | 1201 | /* now subst each arg */ |
| 1198 | mstr = macro_arg_subst(nested_list, mstr, args); | 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 | sym_pop(&args, NULL); | 1209 | sym_pop(&args, NULL); |
| 1200 | mstr_allocated = 1; | 1210 | mstr_allocated = 1; |
| 1201 | } | 1211 | } |
| @@ -1335,6 +1345,12 @@ void load(r, ft, fc) · 133 unmodified lines | |||
| 1335 | } | 1345 | } |
| 1336 | if ((ft & VT_TYPE) == VT_BYTE) | 1346 | if ((ft & VT_TYPE) == VT_BYTE) |
| 1337 | o(0xbe0f); /* movsbl */ | 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 | else | 1354 | else |
| 1339 | o(0x8b); /* movl */ | 1355 | o(0x8b); /* movl */ |
| 1340 | if (v == VT_CONST) { | 1356 | if (v == VT_CONST) { |
| @@ -1376,6 +1392,9 @@ void store(r, ft, fc) · 35 unmodified lines | |||
| 1376 | 1392 | ||
| 1377 | fr = ft & VT_VALMASK; | 1393 | fr = ft & VT_VALMASK; |
| 1378 | b = (ft & VT_TYPE) == VT_BYTE; | 1394 | b = (ft & VT_TYPE) == VT_BYTE; |
| 1395 | /* XXX: incorrect if reg to reg */ | ||
| 1396 | if (ft & VT_SHORT) | ||
| 1397 | o(0x66); | ||
| 1379 | o(0x89 - b); | 1398 | o(0x89 - b); |
| 1380 | if (fr == VT_CONST) { | 1399 | if (fr == VT_CONST) { |
| 1381 | oad(0x05 + r * 8, fc); /* mov r,xxx */ | 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 | int gjmp(t) | 1415 | int gjmp(t) |
| 1392 | { | 1416 | { |
| 1393 | return psym(0xe9, t); | 1417 | return psym(0xe9, t); |
| @@ -1797,6 +1821,9 @@ int type_size(int t, int *a) · 403 unmodified lines | |||
| 1797 | (t & VT_ENUM)) { | 1821 | (t & VT_ENUM)) { |
| 1798 | *a = 4; | 1822 | *a = 4; |
| 1799 | return 4; | 1823 | return 4; |
| 1824 | } else if (t & VT_SHORT) { | ||
| 1825 | *a = 2; | ||
| 1826 | return 2; | ||
| 1800 | } else { | 1827 | } else { |
| 1801 | *a = 1; | 1828 | *a = 1; |
| 1802 | return 1; | 1829 | return 1; |
| @@ -1967,7 +1994,9 @@ int ist(void) · 164 unmodified lines | |||
| 1967 | t |= VT_BYTE; | 1994 | t |= VT_BYTE; |
| 1968 | } else if (tok == TOK_VOID) { | 1995 | } else if (tok == TOK_VOID) { |
| 1969 | t |= VT_VOID; | 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 | (tok >= TOK_CONST & tok <= TOK_INLINE)) { | 2000 | (tok >= TOK_CONST & tok <= TOK_INLINE)) { |
| 1972 | /* ignored types */ | 2001 | /* ignored types */ |
| 1973 | } else if (tok == TOK_FLOAT || tok == TOK_DOUBLE) { | 2002 | } else if (tok == TOK_FLOAT || tok == TOK_DOUBLE) { |
| @@ -2308,28 +2337,64 @@ void unary() · 334 unmodified lines | |||
| 2308 | ft = vt; | 2337 | ft = vt; |
| 2309 | fc = vc; | 2338 | fc = vc; |
| 2310 | next(); | 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 | t = 0; | 2388 | t = 0; |
| 2312 | while (tok != ')') { | 2389 | while (tok != ')') { |
| 2313 | t = t + 4; | 2390 | t += 4; |
| 2314 | expr_eq(); | 2391 | expr_eq(); |
| 2315 | r = gv(); | 2392 | gfunc_param(); |
| 2316 | o(0x50 + r); /* push r */ | ||
| 2317 | if (tok == ',') | 2393 | if (tok == ',') |
| 2318 | next(); | 2394 | next(); |
| 2319 | } | 2395 | } |
| 2396 | #endif | ||
| 2320 | skip(')'); | 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 | if ((ft & VT_VALMASK) == VT_CONST) { | 2398 | if ((ft & VT_VALMASK) == VT_CONST) { |
| 2334 | /* forward reference */ | 2399 | /* forward reference */ |
| 2335 | if (ft & VT_FORWARD) { | 2400 | if (ft & VT_FORWARD) { |
| @@ -2450,7 +2515,7 @@ void eor() · 114 unmodified lines | |||
| 2450 | /* XXX: better constant handling */ | 2515 | /* XXX: better constant handling */ |
| 2451 | void expr_eq() | 2516 | void expr_eq() |
| 2452 | { | 2517 | { |
| 2453 | int t, u, c; | 2518 | int t, u, c, r1, r2; |
| 2454 | 2519 | ||
| 2455 | if (const_wanted) { | 2520 | if (const_wanted) { |
| 2456 | sum(10); | 2521 | sum(10); |
| @@ -2470,12 +2535,14 @@ void expr_eq() · 13 unmodified lines | |||
| 2470 | next(); | 2535 | next(); |
| 2471 | t = gtst(1, 0); | 2536 | t = gtst(1, 0); |
| 2472 | expr(); | 2537 | expr(); |
| 2473 | gv(); | 2538 | r1 = gv(); |
| 2474 | skip(':'); | 2539 | skip(':'); |
| 2475 | u = gjmp(0); | 2540 | u = gjmp(0); |
| 2476 | gsym(t); | 2541 | gsym(t); |
| 2477 | expr_eq(); | 2542 | expr_eq(); |
| 2478 | gv(); | 2543 | r2 = gv(); |
| 2544 | move_reg(r1, r2); | ||
| 2545 | vt = (vt & VT_TYPE) | r1; | ||
| 2479 | gsym(u); | 2546 | gsym(u); |
| 2480 | } | 2547 | } |
| 2481 | } | 2548 | } |
| @@ -2835,7 +2902,8 @@ int main(int argc, char **argv) · 353 unmodified lines | |||
| 2835 | optind = 1; | 2902 | optind = 1; |
| 2836 | while (1) { | 2903 | while (1) { |
| 2837 | if (optind >= argc) { | 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 | return 1; | 2907 | return 1; |
| 2840 | } | 2908 | } |
| 2841 | r = argv[optind]; | 2909 | r = argv[optind]; |
| @@ -2890,7 +2958,7 @@ int main(int argc, char **argv) · 48 unmodified lines | |||
| 2890 | s = sym_find(TOK_MAIN); | 2958 | s = sym_find(TOK_MAIN); |
| 2891 | if (!s) | 2959 | if (!s) |
| 2892 | error("main() not defined"); | 2960 | error("main() not defined"); |
| 2893 | t = s->c; | 2961 | t = (int (*)())s->c; |
| 2894 | #ifdef PROFILE | 2962 | #ifdef PROFILE |
| 2895 | return 1; | 2963 | return 1; |
| 2896 | #else | 2964 | #else |