- Use runtime function for conversion - Also initialize fp with tcc -run on windows This fixes a bug where double x = 1.0; double y = 1.0000000000000001; double z = x < y ? 0 : sqrt (x*x - y*y); caused a bad sqrt because rounding precision for the x < y comparison was different to the one used within the sqrt function. This also fixes a bug where printf("%d, %d", (int)pow(10, 2), (int)pow(10, 2)); would print 100, 99
Unified · Split
| @@ -338,6 +338,15 @@ static void gadd_sp(int val) · 337 unmodified lines | |||
| 338 | } | 338 | } |
| 339 | } | 339 | } |
| 340 | 340 | ||
| 341 | static void gen_static_call(int v) | ||
| 342 | { | ||
| 343 | Sym *sym; | ||
| 344 | |||
| 345 | sym = external_global_sym(v, &func_old_type, 0); | ||
| 346 | oad(0xe8, -4); | ||
| 347 | greloc(cur_text_section, sym, ind-4, R_386_PC32); | ||
| 348 | } | ||
| 349 | |||
| 341 | /* 'is_jmp' is '1' if it is a jump */ | 350 | /* 'is_jmp' is '1' if it is a jump */ |
| 342 | static void gcall_or_jmp(int is_jmp) | 351 | static void gcall_or_jmp(int is_jmp) |
| 343 | { | 352 | { |
| @@ -570,6 +579,12 @@ ST_FUNC void gfunc_prolog(CType *func_type) · 226 unmodified lines | |||
| 570 | func_bound_offset = lbounds_section->data_offset; | 579 | func_bound_offset = lbounds_section->data_offset; |
| 571 | } | 580 | } |
| 572 | #endif | 581 | #endif |
| 582 | |||
| 583 | #ifndef TCC_TARGET_PE | ||
| 584 | if (0 == strcmp(funcname, "main")) | ||
| 585 | gen_static_call(TOK___tcc_fpinit); | ||
| 586 | #endif | ||
| 587 | |||
| 573 | } | 588 | } |
| 574 | 589 | ||
| 575 | /* generate function epilog */ | 590 | /* generate function epilog */ |
| @@ -582,7 +597,7 @@ ST_FUNC void gfunc_epilog(void) · 6 unmodified lines | |||
| 582 | && func_bound_offset != lbounds_section->data_offset) { | 597 | && func_bound_offset != lbounds_section->data_offset) { |
| 583 | int saved_ind; | 598 | int saved_ind; |
| 584 | int *bounds_ptr; | 599 | int *bounds_ptr; |
| 585 | Sym *sym, *sym_data; | 600 | Sym *sym_data; |
| 586 | /* add end of table info */ | 601 | /* add end of table info */ |
| 587 | bounds_ptr = section_ptr_add(lbounds_section, sizeof(int)); | 602 | bounds_ptr = section_ptr_add(lbounds_section, sizeof(int)); |
| 588 | *bounds_ptr = 0; | 603 | *bounds_ptr = 0; |
| @@ -594,20 +609,16 @@ ST_FUNC void gfunc_epilog(void) · 5 unmodified lines | |||
| 594 | greloc(cur_text_section, sym_data, | 609 | greloc(cur_text_section, sym_data, |
| 595 | ind + 1, R_386_32); | 610 | ind + 1, R_386_32); |
| 596 | oad(0xb8, 0); /* mov %eax, xxx */ | 611 | oad(0xb8, 0); /* mov %eax, xxx */ |
| 597 | sym = external_global_sym(TOK___bound_local_new, &func_old_type, 0); | 612 | gen_static_call(TOK___bound_local_new); |
| 598 | greloc(cur_text_section, sym, | 613 | |
| 599 | ind + 1, R_386_PC32); | ||
| 600 | oad(0xe8, -4); | ||
| 601 | ind = saved_ind; | 614 | ind = saved_ind; |
| 602 | /* generate bound check local freeing */ | 615 | /* generate bound check local freeing */ |
| 603 | o(0x5250); /* save returned value, if any */ | 616 | o(0x5250); /* save returned value, if any */ |
| 604 | greloc(cur_text_section, sym_data, | 617 | greloc(cur_text_section, sym_data, |
| 605 | ind + 1, R_386_32); | 618 | ind + 1, R_386_32); |
| 606 | oad(0xb8, 0); /* mov %eax, xxx */ | 619 | oad(0xb8, 0); /* mov %eax, xxx */ |
| 607 | sym = external_global_sym(TOK___bound_local_delete, &func_old_type, 0); | 620 | gen_static_call(TOK___bound_local_delete); |
| 608 | greloc(cur_text_section, sym, | 621 | |
| 609 | ind + 1, R_386_PC32); | ||
| 610 | oad(0xe8, -4); | ||
| 611 | o(0x585a); /* restore returned value, if any */ | 622 | o(0x585a); /* restore returned value, if any */ |
| 612 | } | 623 | } |
| 613 | #endif | 624 | #endif |
| @@ -626,10 +637,8 @@ ST_FUNC void gfunc_epilog(void) · 12 unmodified lines | |||
| 626 | ind = func_sub_sp_offset - FUNC_PROLOG_SIZE; | 637 | ind = func_sub_sp_offset - FUNC_PROLOG_SIZE; |
| 627 | #ifdef TCC_TARGET_PE | 638 | #ifdef TCC_TARGET_PE |
| 628 | if (v >= 4096) { | 639 | if (v >= 4096) { |
| 629 | Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0); | ||
| 630 | oad(0xb8, v); /* mov stacksize, %eax */ | 640 | oad(0xb8, v); /* mov stacksize, %eax */ |
| 631 | oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */ | 641 | gen_static_call(TOK___chkstk); /* call __chkstk, (does the stackframe too) */ |
| 632 | greloc(cur_text_section, sym, ind-4, R_386_PC32); | ||
| 633 | } else | 642 | } else |
| 634 | #endif | 643 | #endif |
| 635 | { | 644 | { |
| @@ -992,52 +1001,13 @@ ST_FUNC void gen_cvt_itof(int t) · 356 unmodified lines | |||
| 992 | /* XXX: handle long long case */ | 1001 | /* XXX: handle long long case */ |
| 993 | ST_FUNC void gen_cvt_ftoi(int t) | 1002 | ST_FUNC void gen_cvt_ftoi(int t) |
| 994 | { | 1003 | { |
| 995 | int r, r2, size; | ||
| 996 | Sym *sym; | ||
| 997 | CType ushort_type; | ||
| 998 | |||
| 999 | ushort_type.t = VT_SHORT | VT_UNSIGNED; | ||
| 1000 | ushort_type.ref = 0; | ||
| 1001 | |||
| 1002 | gv(RC_FLOAT); | 1004 | gv(RC_FLOAT); |
| 1003 | if (t != VT_INT) | 1005 | save_reg(TREG_EAX); |
| 1004 | size = 8; | 1006 | save_reg(TREG_EDX); |
| 1005 | else | 1007 | gen_static_call(TOK___tcc_cvt_ftol); |
| 1006 | size = 4; | 1008 | vtop->r = TREG_EAX; /* mark reg as used */ |
| 1007 | 1009 | if (t == VT_LLONG) | |
| 1008 | o(0x2dd9); /* ldcw xxx */ | 1010 | vtop->r2 = TREG_EDX; |
| 1009 | sym = external_global_sym(TOK___tcc_int_fpu_control, | ||
| 1010 | &ushort_type, VT_LVAL); | ||
| 1011 | greloc(cur_text_section, sym, | ||
| 1012 | ind, R_386_32); | ||
| 1013 | gen_le32(0); | ||
| 1014 | |||
| 1015 | oad(0xec81, size); /* sub $xxx, %esp */ | ||
| 1016 | if (size == 4) | ||
| 1017 | o(0x1cdb); /* fistpl */ | ||
| 1018 | else | ||
| 1019 | o(0x3cdf); /* fistpll */ | ||
| 1020 | o(0x24); | ||
| 1021 | o(0x2dd9); /* ldcw xxx */ | ||
| 1022 | sym = external_global_sym(TOK___tcc_fpu_control, | ||
| 1023 | &ushort_type, VT_LVAL); | ||
| 1024 | greloc(cur_text_section, sym, | ||
| 1025 | ind, R_386_32); | ||
| 1026 | gen_le32(0); | ||
| 1027 | |||
| 1028 | r = get_reg(RC_INT); | ||
| 1029 | o(0x58 + r); /* pop r */ | ||
| 1030 | if (size == 8) { | ||
| 1031 | if (t == VT_LLONG) { | ||
| 1032 | vtop->r = r; /* mark reg as used */ | ||
| 1033 | r2 = get_reg(RC_INT); | ||
| 1034 | o(0x58 + r2); /* pop r2 */ | ||
| 1035 | vtop->r2 = r2; | ||
| 1036 | } else { | ||
| 1037 | o(0x04c483); /* add $4, %esp */ | ||
| 1038 | } | ||
| 1039 | } | ||
| 1040 | vtop->r = r; | ||
| 1041 | } | 1011 | } |
| 1042 | 1012 | ||
| 1043 | /* convert from one floating point type to another */ | 1013 | /* convert from one floating point type to another */ |
| @@ -1060,18 +1030,13 @@ ST_FUNC void ggoto(void) · 16 unmodified lines | |||
| 1060 | /* generate a bounded pointer addition */ | 1030 | /* generate a bounded pointer addition */ |
| 1061 | ST_FUNC void gen_bounded_ptr_add(void) | 1031 | ST_FUNC void gen_bounded_ptr_add(void) |
| 1062 | { | 1032 | { |
| 1063 | Sym *sym; | ||
| 1064 | |||
| 1065 | /* prepare fast i386 function call (args in eax and edx) */ | 1033 | /* prepare fast i386 function call (args in eax and edx) */ |
| 1066 | gv2(RC_EAX, RC_EDX); | 1034 | gv2(RC_EAX, RC_EDX); |
| 1067 | /* save all temporary registers */ | 1035 | /* save all temporary registers */ |
| 1068 | vtop -= 2; | 1036 | vtop -= 2; |
| 1069 | save_regs(0); | 1037 | save_regs(0); |
| 1070 | /* do a fast function call */ | 1038 | /* do a fast function call */ |
| 1071 | sym = external_global_sym(TOK___bound_ptr_add, &func_old_type, 0); | 1039 | gen_static_call(TOK___bound_ptr_add); |
| 1072 | greloc(cur_text_section, sym, | ||
| 1073 | ind + 1, R_386_PC32); | ||
| 1074 | oad(0xe8, -4); | ||
| 1075 | /* returned pointer is in eax */ | 1040 | /* returned pointer is in eax */ |
| 1076 | vtop++; | 1041 | vtop++; |
| 1077 | vtop->r = TREG_EAX | VT_BOUNDED; | 1042 | vtop->r = TREG_EAX | VT_BOUNDED; |
| @@ -478,13 +478,24 @@ long long __ashldi3(long long a, int b) · 477 unmodified lines | |||
| 478 | #endif | 478 | #endif |
| 479 | } | 479 | } |
| 480 | 480 | ||
| 481 | #if defined(__i386__) | 481 | #ifndef _WIN32 |
| 482 | /* FPU control word for rounding to nearest mode */ | 482 | void __tcc_fpinit(void) |
| 483 | unsigned short __tcc_fpu_control = 0x137f; | 483 | { |
| 484 | /* FPU control word for round to zero mode for int conversion */ | 484 | unsigned c = 0x137F; |
| 485 | unsigned short __tcc_int_fpu_control = 0x137f | 0x0c00; | 485 | __asm__ __volatile__ ("fldcw %0" : "=m" (c)); |
| 486 | } | ||
| 486 | #endif | 487 | #endif |
| 487 | 488 | long long __tcc_cvt_ftol(long double x) | |
| 489 | { | ||
| 490 | unsigned c0, c1; | ||
| 491 | long long ret; | ||
| 492 | __asm__ __volatile__ ("fnstcw %0" : "=m" (c0)); | ||
| 493 | c1 = c0 | 0x0C00; | ||
| 494 | __asm__ __volatile__ ("fldcw %0" : "=m" (c1)); | ||
| 495 | __asm__ __volatile__ ("fistpll %0" : "=m" (ret)); | ||
| 496 | __asm__ __volatile__ ("fldcw %0" : "=m" (c0)); | ||
| 497 | return ret; | ||
| 498 | } | ||
| 488 | #endif /* !__x86_64__ */ | 499 | #endif /* !__x86_64__ */ |
| 489 | 500 | ||
| 490 | /* XXX: fix tcc's code generator to do this instead */ | 501 | /* XXX: fix tcc's code generator to do this instead */ |
| @@ -78,21 +78,13 @@ ST_FUNC void asm_global_instr(void) · 77 unmodified lines | |||
| 78 | #endif | 78 | #endif |
| 79 | 79 | ||
| 80 | /********************************************************/ | 80 | /********************************************************/ |
| 81 | |||
| 82 | #ifdef _WIN32 | 81 | #ifdef _WIN32 |
| 83 | // GCC appears to use '/' for relative paths and '\\' for absolute paths on Windows | ||
| 84 | static char *normalize_slashes(char *path) | 82 | static char *normalize_slashes(char *path) |
| 85 | { | 83 | { |
| 86 | char *p; | 84 | char *p; |
| 87 | if (path[1] == ':') { | 85 | for (p = path; *p; ++p) |
| 88 | for (p = path+2; *p; ++p) | 86 | if (*p == '\\') |
| 89 | if (*p == '/') | 87 | *p = '/'; |
| 90 | *p = '\\'; | ||
| 91 | } else { | ||
| 92 | for (p = path; *p; ++p) | ||
| 93 | if (*p == '\\') | ||
| 94 | *p = '/'; | ||
| 95 | } | ||
| 96 | return path; | 88 | return path; |
| 97 | } | 89 | } |
| 98 | 90 | ||
| @@ -1036,6 +1028,7 @@ LIBTCCAPI TCCState *tcc_new(void) · 937 unmodified lines | |||
| 1036 | #ifdef TCC_TARGET_I386 | 1028 | #ifdef TCC_TARGET_I386 |
| 1037 | s->seg_size = 32; | 1029 | s->seg_size = 32; |
| 1038 | #endif | 1030 | #endif |
| 1031 | s->runtime_main = "main"; | ||
| 1039 | return s; | 1032 | return s; |
| 1040 | } | 1033 | } |
| 1041 | 1034 | ||
| @@ -665,6 +665,7 @@ struct TCCState { · 664 unmodified lines | |||
| 665 | #endif | 665 | #endif |
| 666 | 666 | ||
| 667 | #ifdef TCC_IS_NATIVE | 667 | #ifdef TCC_IS_NATIVE |
| 668 | const char *runtime_main; | ||
| 668 | /* for tcc_relocate */ | 669 | /* for tcc_relocate */ |
| 669 | void *runtime_mem; | 670 | void *runtime_mem; |
| 670 | # ifdef HAVE_SELINUX | 671 | # ifdef HAVE_SELINUX |
| @@ -1726,7 +1726,6 @@ ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack) · 1725 unmodified lines | |||
| 1726 | static void pe_add_runtime(TCCState *s1, struct pe_info *pe) | 1726 | static void pe_add_runtime(TCCState *s1, struct pe_info *pe) |
| 1727 | { | 1727 | { |
| 1728 | const char *start_symbol; | 1728 | const char *start_symbol; |
| 1729 | ADDR3264 addr = 0; | ||
| 1730 | int pe_type = 0; | 1729 | int pe_type = 0; |
| 1731 | 1730 | ||
| 1732 | if (find_elf_sym(symtab_section, PE_STDSYM("WinMain","@16"))) | 1731 | if (find_elf_sym(symtab_section, PE_STDSYM("WinMain","@16"))) |
| @@ -1742,16 +1741,13 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe) · 9 unmodified lines | |||
| 1742 | 1741 | ||
| 1743 | start_symbol = | 1742 | start_symbol = |
| 1744 | TCC_OUTPUT_MEMORY == s1->output_type | 1743 | TCC_OUTPUT_MEMORY == s1->output_type |
| 1745 | ? PE_GUI == pe_type ? "__runwinmain" : "_main" | 1744 | ? PE_GUI == pe_type ? "__runwinmain" : "__runmain" |
| 1746 | : PE_DLL == pe_type ? PE_STDSYM("__dllstart","@12") | 1745 | : PE_DLL == pe_type ? PE_STDSYM("__dllstart","@12") |
| 1747 | : PE_GUI == pe_type ? "__winstart" : "__start" | 1746 | : PE_GUI == pe_type ? "__winstart" : "__start" |
| 1748 | ; | 1747 | ; |
| 1749 | 1748 | ||
| 1750 | if (!s1->leading_underscore || strchr(start_symbol, '@')) { | 1749 | if (!s1->leading_underscore || strchr(start_symbol, '@')) |
| 1751 | ++start_symbol; | 1750 | ++start_symbol; |
| 1752 | if (start_symbol[0] != '_') | ||
| 1753 | start_symbol = NULL; | ||
| 1754 | } | ||
| 1755 | 1751 | ||
| 1756 | /* grab the startup code from libtcc1 */ | 1752 | /* grab the startup code from libtcc1 */ |
| 1757 | if (start_symbol) | 1753 | if (start_symbol) |
| @@ -1776,21 +1772,13 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe) · 18 unmodified lines | |||
| 1776 | } | 1772 | } |
| 1777 | } | 1773 | } |
| 1778 | 1774 | ||
| 1779 | if (TCC_OUTPUT_MEMORY == s1->output_type) | 1775 | if (TCC_OUTPUT_MEMORY == s1->output_type) { |
| 1780 | pe_type = PE_RUN; | 1776 | pe_type = PE_RUN; |
| 1781 | 1777 | s1->runtime_main = start_symbol; | |
| 1782 | if (start_symbol) { | ||
| 1783 | addr = get_elf_sym_addr(s1, start_symbol, 1); | ||
| 1784 | if (PE_RUN == pe_type && addr) | ||
| 1785 | /* for -run GUI's, put '_runwinmain' instead of 'main' */ | ||
| 1786 | add_elf_sym(symtab_section, | ||
| 1787 | addr, 0, | ||
| 1788 | ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, | ||
| 1789 | text_section->sh_num, "main"); | ||
| 1790 | } | 1778 | } |
| 1791 | 1779 | ||
| 1792 | pe->type = pe_type; | 1780 | pe->type = pe_type; |
| 1793 | pe->start_addr = addr; | 1781 | pe->start_addr = (DWORD)tcc_get_symbol_err(s1, start_symbol); |
| 1794 | } | 1782 | } |
| 1795 | 1783 | ||
| 1796 | ST_FUNC int pe_output_file(TCCState * s1, const char *filename) | 1784 | ST_FUNC int pe_output_file(TCCState * s1, const char *filename) |
| @@ -97,7 +97,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 96 unmodified lines | |||
| 97 | if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0) | 97 | if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0) |
| 98 | return -1; | 98 | return -1; |
| 99 | 99 | ||
| 100 | prog_main = tcc_get_symbol_err(s1, "main"); | 100 | prog_main = tcc_get_symbol_err(s1, s1->runtime_main); |
| 101 | 101 | ||
| 102 | #ifdef CONFIG_TCC_BACKTRACE | 102 | #ifdef CONFIG_TCC_BACKTRACE |
| 103 | if (s1->do_debug) { | 103 | if (s1->do_debug) { |
| @@ -194,8 +194,8 @@ · 193 unmodified lines | |||
| 194 | DEF(TOK__remu, "_remu") | 194 | DEF(TOK__remu, "_remu") |
| 195 | #endif | 195 | #endif |
| 196 | #ifdef TCC_TARGET_I386 | 196 | #ifdef TCC_TARGET_I386 |
| 197 | DEF(TOK___tcc_int_fpu_control, "__tcc_int_fpu_control") | 197 | DEF(TOK___tcc_fpinit, "__tcc_fpinit") |
| 198 | DEF(TOK___tcc_fpu_control, "__tcc_fpu_control") | 198 | DEF(TOK___tcc_cvt_ftol, "__tcc_cvt_ftol") |
| 199 | #endif | 199 | #endif |
| 200 | #ifdef TCC_ARM_EABI | 200 | #ifdef TCC_ARM_EABI |
| 201 | DEF(TOK___ashrdi3, "__aeabi_lasr") | 201 | DEF(TOK___ashrdi3, "__aeabi_lasr") |
| @@ -968,15 +968,15 @@ extern "C" { · 967 unmodified lines | |||
| 968 | LONG64 InterlockedExchangeAdd64(LONG64 volatile *Addend,LONG64 Value); | 968 | LONG64 InterlockedExchangeAdd64(LONG64 volatile *Addend,LONG64 Value); |
| 969 | LONG64 InterlockedCompareExchange64(LONG64 volatile *Destination,LONG64 ExChange,LONG64 Comperand); | 969 | LONG64 InterlockedCompareExchange64(LONG64 volatile *Destination,LONG64 ExChange,LONG64 Comperand); |
| 970 | #else | 970 | #else |
| 971 | LONG InterlockedIncrement(LONG volatile *lpAddend); | 971 | LONG WINAPI InterlockedIncrement(LONG volatile *lpAddend); |
| 972 | LONG InterlockedDecrement(LONG volatile *lpAddend); | 972 | LONG WINAPI InterlockedDecrement(LONG volatile *lpAddend); |
| 973 | LONG InterlockedExchange(LONG volatile *Target,LONG Value); | 973 | LONG WINAPI InterlockedExchange(LONG volatile *Target,LONG Value); |
| 974 | 974 | ||
| 975 | #define InterlockedExchangePointer(Target,Value) (PVOID)InterlockedExchange((PLONG)(Target),(LONG)(Value)) | 975 | #define InterlockedExchangePointer(Target,Value) (PVOID)InterlockedExchange((PLONG)(Target),(LONG)(Value)) |
| 976 | 976 | ||
| 977 | LONG InterlockedExchangeAdd(LONG volatile *Addend,LONG Value); | 977 | LONG WINAPI InterlockedExchangeAdd(LONG volatile *Addend,LONG Value); |
| 978 | LONG InterlockedCompareExchange(LONG volatile *Destination,LONG Exchange,LONG Comperand); | 978 | LONG WINAPI InterlockedCompareExchange(LONG volatile *Destination,LONG Exchange,LONG Comperand); |
| 979 | LONGLONG InterlockedCompareExchange64(LONGLONG volatile *Destination,LONGLONG Exchange,LONGLONG Comperand); | 979 | LONGLONG WINAPI InterlockedCompareExchange64(LONGLONG volatile *Destination,LONGLONG Exchange,LONGLONG Comperand); |
| 980 | 980 | ||
| 981 | __CRT_INLINE LONGLONG InterlockedAnd64 (LONGLONG volatile *Destination,LONGLONG Value) { | 981 | __CRT_INLINE LONGLONG InterlockedAnd64 (LONGLONG volatile *Destination,LONGLONG Value) { |
| 982 | LONGLONG Old; | 982 | LONGLONG Old; |
| @@ -31,4 +31,10 @@ int _start(void) · 30 unmodified lines | |||
| 31 | exit(ret); | 31 | exit(ret); |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | int _runmain(int argc, char **argv) | ||
| 35 | { | ||
| 36 | _controlfp(0x10000, 0x30000); | ||
| 37 | return main(argc, argv, NULL); | ||
| 38 | } | ||
| 39 | |||
| 34 | // ============================================= | 40 | // ============================================= |
| @@ -59,6 +59,6 @@ int _runwinmain(int argc, char **argv) · 58 unmodified lines | |||
| 59 | szCmd = ""; | 59 | szCmd = ""; |
| 60 | else if (szCmd > p && szCmd[-1] == '\"') | 60 | else if (szCmd > p && szCmd[-1] == '\"') |
| 61 | --szCmd; | 61 | --szCmd; |
| 62 | _controlfp(0x10000, 0x30000); | ||
| 62 | return WinMain(GetModuleHandle(NULL), NULL, szCmd, SW_SHOWDEFAULT); | 63 | return WinMain(GetModuleHandle(NULL), NULL, szCmd, SW_SHOWDEFAULT); |
| 63 | } | 64 | } |
| 64 | |||
| @@ -18,6 +18,12 @@ · 17 unmodified lines | |||
| 18 | system PATH. | 18 | system PATH. |
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | Include and library search paths | ||
| 22 | -------------------------------- | ||
| 23 | On windows, the standard "include" and "lib" directories are searched | ||
| 24 | relatively from the location of the executables (tcc.exe, libtcc.dll). | ||
| 25 | |||
| 26 | |||
| 21 | Examples: | 27 | Examples: |
| 22 | --------- | 28 | --------- |
| 23 | Open a console window (DOS box) and 'cd' to the examples directory. | 29 | Open a console window (DOS box) and 'cd' to the examples directory. |