History

arm64-win32 review: fix problems and pass tests

tccpe.c: - fix arm64 unwind codes (to make native set/longjmp() work) sizeof(RUNTIME_FUNCTION) is 8 on arm64 in the first place no need to note stack slots if we don't save any registers anyway arm64-gen.c: - fix long double reg-move - fix arm64_hfa() for structs with float arrays - gfunc_prolog(): setup stackframe eariler (simplifies unwind codes) - new function gv_addr(RC); win32/include/setjmp.h: - provide correct definition for setjmo() (frameoffset = 224) tccasm.c: - support ".quad" with symbol & relocation - support ".size" - fix ". - symbol" arithmetic win32/lib/crt1.c and win32/include/stdlib.h: - do not write to __argc/__argv which reside in msvcrt.dll (msvcrt.dll on arm64 does not like that, crashes on unload) tcc.c,libtcc.c: - new functions tcc_fopen/fclose to avoid different stdio unstances in tcc.exe & libtcc.dll tests & github workflow: - add test-win32.bat to run tests with a tcc compiled by build-tcc.bat - add msvcrt_start.c for gcc/clang to use the same runtime as tcc the problem is that newer gcc as well as clang and cl are linking to newer runtimes (such as UCRT) that have partially different printf format behavior which makes tcctest fail. the solution here is to force these compilers to link with msvcrt.dll just like tcc. Also, there is no gcc on arm64-win32 currently at all. Anyway, this approach to running the github CI tests does not require msys2. But It does rely on gnumake as well as on some 'sh' shell though which seems to be installed somewhere (maybe it is the one from git).

grischka committed 6 months ago

Commit 30afb501 parent 576cd2a33 files · +601 −455Browse files

Unified · Split

33 files
  1. .github/workflows/build.yml +26 −31
  2. Makefile +3 −1
  3. arm64-asm.c +0 −4
  4. arm64-gen.c +23 −25
  5. i386-asm.c +0 −7
  6. lib/Makefile +2 −2
  7. lib/armflush.c +13 −0
  8. lib/bt-dll.c +24 −3
  9. lib/lib-arm64.c +0 −7
  10. lib/libtcc1.c +2 −20
  11. libtcc.c +8 −1
  12. tcc.c +6 −6
  13. tcc.h +15 −6
  14. tccasm.c +30 −11
  15. tcclib.h +2 −0
  16. tccpe.c +24 −45
  17. tccrun.c +2 −0
  18. tcctok.h +4 −3
  19. tests/Makefile +5 −4
  20. tests/libtcc_test_mt.c +8 −12
  21. tests/msvcrt_start.c +164 −0
  22. tests/tcctest.c +18 −19
  23. tests/test-win32.bat +74 −0
  24. tests/tests2/Makefile +7 −16
  25. win32/build-tcc.bat +66 −73
  26. win32/include/_mingw.h +1 −7
  27. win32/include/setjmp.h +11 −21
  28. win32/include/stdlib.h +15 −0
  29. win32/include/winapi/winnt.h +13 −48
  30. win32/lib/chkstk.S +2 −72
  31. win32/lib/crt1.c +6 −3
  32. win32/lib/winex.c +27 −0
  33. x86_64-gen.c +0 −8
.github/workflows/build.yml+26−31
@@ -34,56 +34,51 @@ jobs: · 33 unmodified lines
34 timeout-minutes: 634 timeout-minutes: 6
35 steps:35 steps:
36 - uses: actions/checkout@v436 - uses: actions/checkout@v4
37 - name: make & test tcc (x86_64-win32)37 - name: test (x86_64-win32)
38 shell: cmd
39 run: |
40 echo ::group:: setup msys mingw64-gcc
41 set MSYS2_PATH_TYPE=inherit
42 set MSYSTEM=MINGW64
43 set CHERE_INVOKING=yes
44 C:\msys64\usr\bin\bash -l -c "pacman -S --noconfirm mingw-w64-x86_64-gcc"
45 echo ::endgroup::
46 C:\msys64\usr\bin\bash -l -c "./configure && make && make test -k"
47 - uses: ilammy/msvc-dev-cmd@v1
48 with:
49 arch: amd64
50 - name: build with MSVC (x86_64-win32)
51 shell: cmd38 shell: cmd
52 run: |39 run: |
53 echo ::group:: run build-tcc.bat40 echo ::group:: run build-tcc.bat
54 cd win3241 cd win32
55 call build-tcc.bat -t 64 -c cl42 call "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=amd64
43 call build-tcc.bat -c cl -t x86_64
44 @echo off
56 echo ::endgroup::45 echo ::endgroup::
57 .\tcc -I.. libtcc.dll -v ../tests/libtcc_test.c -o libtest.exe && .\libtest.exe46 cd ..\tests
58 .\tcc -I.. libtcc.dll -run ../tests/libtcc_test.c47 call test-win32.bat all -k
59 48
60 test-i386-win32:49 test-i386-win32:
61 runs-on: windows-202550 runs-on: windows-2025
62 timeout-minutes: 651 timeout-minutes: 6
63 steps:52 steps:
64 - uses: actions/checkout@v453 - uses: actions/checkout@v4
65 - name: make & test tcc (i386-win32)54 - name: test (i386-win32)
66 shell: cmd55 shell: cmd
67 run: |56 run: |
68 echo ::group:: setup msys mingw32-gcc57 echo ::group:: run build-tcc.bat
69 set MSYS2_PATH_TYPE=inherit58 cd win32
70 set MSYSTEM=MINGW3259 call "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=x86
71 set CHERE_INVOKING=yes60 call build-tcc.bat -c cl -t i386
72 C:\msys64\usr\bin\bash -l -c "pacman -S --noconfirm mingw-w64-i686-gcc"61 @echo off
73 echo ::endgroup::62 echo ::endgroup::
74 C:\msys64\usr\bin\bash -l -c "./configure && make && make test -k"63 cd ..\tests
75 - uses: ilammy/msvc-dev-cmd@v164 call test-win32.bat -p c:\mingw32\bin all -k
76 with:65
77 arch: x8666 test-arm64-win32:
78 - name: build with MSVC (i386-win32)67 runs-on: windows-11-arm
68 timeout-minutes: 6
69 steps:
70 - uses: actions/checkout@v4
71 - name: test (arm64-win32)
79 shell: cmd72 shell: cmd
80 run: |73 run: |
81 echo ::group:: run build-tcc.bat74 echo ::group:: run build-tcc.bat
82 cd win3275 cd win32
83 call build-tcc.bat -t 32 -c cl76 call "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=arm64
77 call build-tcc.bat -c cl -t arm64
78 @echo off
84 echo ::endgroup::79 echo ::endgroup::
85 .\tcc -I.. libtcc.dll -v ../tests/libtcc_test.c -o libtest.exe && .\libtest.exe80 cd ..\tests
86 .\tcc -I.. libtcc.dll -run ../tests/libtcc_test.c81 call test-win32.bat -c clang all -k
87 82
88 test-armv7-linux:83 test-armv7-linux:
89 runs-on: ubuntu-22.0484 runs-on: ubuntu-22.04
Makefile+3−1
@@ -31,7 +31,9 @@ ifdef CONFIG_WIN32 · 30 unmodified lines
31 LIBTCCDEF = libtcc.def31 LIBTCCDEF = libtcc.def
32 endif32 endif
33 ifneq ($(CONFIG_debug),yes)33 ifneq ($(CONFIG_debug),yes)
34 LDFLAGS += -s34 ifneq ($(CC_NAME),clang)
35 LDFLAGS += -s
36 endif
35 endif37 endif
36 NATIVE_TARGET = $(if $(findstring arm64,$(ARCH)),arm64-win32,$(ARCH)-win$(if $(findstring arm,$(ARCH)),ce,32))38 NATIVE_TARGET = $(if $(findstring arm64,$(ARCH)),arm64-win32,$(ARCH)-win$(if $(findstring arm,$(ARCH)),ce,32))
37else39else
arm64-asm.c+0−4
@@ -86,11 +86,7 @@ enum { · 85 unmodified lines
86#define TREG_X30 3086#define TREG_X30 30
87#define TREG_SP 3187#define TREG_SP 31
88 88
89#ifdef TCC_TARGET_PE
90#define ARM64_FREG_BASE 19
91#else
92#define ARM64_FREG_BASE 2089#define ARM64_FREG_BASE 20
93#endif
94#define ARM64_FREG_LAST (ARM64_FREG_BASE + 7)90#define ARM64_FREG_LAST (ARM64_FREG_BASE + 7)
95 91
96typedef struct Operand {92typedef struct Operand {
arm64-gen.c+23−25
@@ -579,7 +579,7 @@ ST_FUNC void load(int r, SValue *sv) · 578 unmodified lines
579 if (svr < VT_CONST) {579 if (svr < VT_CONST) {
580 if (IS_FREG(r) && IS_FREG(svr))580 if (IS_FREG(r) && IS_FREG(svr))
581 if (svtt == VT_LDOUBLE)581 if (svtt == VT_LDOUBLE)
582 o(ARM64_MOV_V16B | fltr(r) | fltr(svr) << 5);582 o(ARM64_MOV_V16B | fltr(r) | fltr(svr) * 0x10020);
583 // mov v(r).16b,v(svr).16b583 // mov v(r).16b,v(svr).16b
584 else584 else
585 o(ARM64_FMOV_SCALAR | fltr(r) | fltr(svr) << 5); // fmov d(r),d(svr)585 o(ARM64_FMOV_SCALAR | fltr(r) | fltr(svr) << 5); // fmov d(r),d(svr)
@@ -794,7 +794,7 @@ static int arm64_hfa_aux(CType *type, int *fsize, int num) · 208 unmodified lines
794 return num;794 return num;
795 }795 }
796 }796 }
797 else if ((type->t & VT_ARRAY) && ((type->t & VT_BTYPE) != VT_PTR)) {797 else if (type->t & VT_ARRAY) { /* handle float array within struct */
798 int num1;798 int num1;
799 if (!type->ref->c)799 if (!type->ref->c)
800 return num;800 return num;
@@ -811,8 +811,7 @@ static int arm64_hfa_aux(CType *type, int *fsize, int num) · 10 unmodified lines
811 811
812static int arm64_hfa(CType *type, unsigned *fsize)812static int arm64_hfa(CType *type, unsigned *fsize)
813{813{
814 if ((type->t & VT_BTYPE) == VT_STRUCT ||814 if ((type->t & VT_BTYPE) == VT_STRUCT) {
815 ((type->t & VT_ARRAY) && ((type->t & VT_BTYPE) != VT_PTR))) {
816 int sz = 0;815 int sz = 0;
817 int n = arm64_hfa_aux(type, &sz, 0);816 int n = arm64_hfa_aux(type, &sz, 0);
818 if (0 < n && n <= 4) {817 if (0 < n && n <= 4) {
@@ -1037,6 +1036,13 @@ static void arm64_sub_sp(uint64_t diff) · 218 unmodified lines
1037 }1036 }
1038}1037}
1039 1038
1039static int gv_addr(int r)
1040{
1041 gaddrof();
1042 vtop->type.t = VT_PTR;
1043 return gv(r);
1044}
1045
1040ST_FUNC void gfunc_call(int nb_args)1046ST_FUNC void gfunc_call(int nb_args)
1041{1047{
1042 CType *return_type;1048 CType *return_type;
@@ -1147,9 +1153,7 @@ ST_FUNC void gfunc_call(int nb_args) · 104 unmodified lines
1147 else if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {1153 else if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
1148 int align, size = type_size(&vtop->type, &align);1154 int align, size = type_size(&vtop->type, &align);
1149 if (size) {1155 if (size) {
1150 vtop->type.t = VT_PTR;1156 gv_addr(RC_R(a[i] / 2));
1151 gaddrof();
1152 gv(RC_R(a[i] / 2));
1153 arm64_ldrs(a[i] / 2, size);1157 arm64_ldrs(a[i] / 2, size);
1154 }1158 }
1155 }1159 }
@@ -1165,9 +1169,7 @@ ST_FUNC void gfunc_call(int nb_args) · 9 unmodified lines
1165 uint32_t j, sz, n = arm64_hfa(&vtop->type, &sz);1169 uint32_t j, sz, n = arm64_hfa(&vtop->type, &sz);
1166 if (n > 0) {1170 if (n > 0) {
1167 /* HFA struct - load from memory into float registers */1171 /* HFA struct - load from memory into float registers */
1168 vtop->type.t = VT_PTR;1172 gv_addr(RC_R30);
1169 gaddrof();
1170 gv(RC_R30);
1171 for (j = 0; j < n; j++)1173 for (j = 0; j < n; j++)
1172 o(0x3d4003c0 |1174 o(0x3d4003c0 |
1173 (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |1175 (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |
@@ -1186,7 +1188,7 @@ ST_FUNC void gfunc_call(int nb_args) · 12 unmodified lines
1186 if ((return_type->t & VT_BTYPE) == VT_STRUCT) {1188 if ((return_type->t & VT_BTYPE) == VT_STRUCT) {
1187 if (a[0] == 1) {1189 if (a[0] == 1) {
1188 // indirect return: set x8 and discard the stack value1190 // indirect return: set x8 and discard the stack value
1189 gv(RC_R(8));1191 gv_addr(RC_R(8));
1190 --vtop;1192 --vtop;
1191 }1193 }
1192 else1194 else
@@ -1206,7 +1208,7 @@ ST_FUNC void gfunc_call(int nb_args) · 13 unmodified lines
1206 int bt = rt & VT_BTYPE;1208 int bt = rt & VT_BTYPE;
1207 if (bt == VT_STRUCT && !(a[0] & 1)) {1209 if (bt == VT_STRUCT && !(a[0] & 1)) {
1208 // A struct was returned in registers, so write it out:1210 // A struct was returned in registers, so write it out:
1209 gv(RC_R(8));1211 gv_addr(RC_R(8));
1210 --vtop;1212 --vtop;
1211 if (a[0] == 0) {1213 if (a[0] == 0) {
1212 int align, size = type_size(return_type, &align);1214 int align, size = type_size(return_type, &align);
@@ -1271,6 +1273,7 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 58 unmodified lines
1271 1273
1272 for (sym = func_type->ref; sym; sym = sym->next)1274 for (sym = func_type->ref; sym; sym = sym->next)
1273 ++n;1275 ++n;
1276
1274 pcs_n = n - 1;1277 pcs_n = n - 1;
1275 c = n + variadic;1278 c = n + variadic;
1276 t = tcc_malloc(c * sizeof(*t));1279 t = tcc_malloc(c * sizeof(*t));
@@ -1321,6 +1324,8 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 44 unmodified lines
1321 1324
1322 arm64_func_start_offset = ind;1325 arm64_func_start_offset = ind;
1323 o(0xa9b27bfd); // stp x29,x30,[sp,#-224]!1326 o(0xa9b27bfd); // stp x29,x30,[sp,#-224]!
1327 o(0x910003fd); // mov x29,sp
1328
1324 for (i = 0; i < last_float; i++)1329 for (i = 0; i < last_float; i++)
1325 // stp q0,q1,[sp,#16], stp q2,q3,[sp,#48]1330 // stp q0,q1,[sp,#16], stp q2,q3,[sp,#48]
1326 // stp q4,q5,[sp,#80], stp q6,q7,[sp,#112]1331 // stp q4,q5,[sp,#80], stp q6,q7,[sp,#112]
@@ -1368,7 +1373,6 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 41 unmodified lines
1368 tcc_free(a);1373 tcc_free(a);
1369 tcc_free(t);1374 tcc_free(t);
1370 1375
1371 o(0x910003fd); // mov x29,sp
1372 arm64_func_sub_sp_offset = ind;1376 arm64_func_sub_sp_offset = ind;
1373 /* In gfunc_epilog these will be replaced with stack setup code. */1377 /* In gfunc_epilog these will be replaced with stack setup code. */
1374 for (i = 0; i < ARM64_FUNC_STACK_SETUP_SLOTS; ++i)1378 for (i = 0; i < ARM64_FUNC_STACK_SETUP_SLOTS; ++i)
@@ -1384,8 +1388,7 @@ ST_FUNC void gen_va_start(void) · 9 unmodified lines
1384{1388{
1385 int r;1389 int r;
1386 --vtop; // we don't need the "arg"1390 --vtop; // we don't need the "arg"
1387 gaddrof();1391 r = intr(gv_addr(RC_INT));
1388 r = intr(gv(RC_INT));
1389 1392
1390#ifdef TCC_TARGET_PE1393#ifdef TCC_TARGET_PE
1391 if (arm64_func_va_list_stack) {1394 if (arm64_func_va_list_stack) {
@@ -1433,13 +1436,12 @@ ST_FUNC void gen_va_arg(CType *t) · 41 unmodified lines
1433 uint32_t r0, r1;1436 uint32_t r0, r1;
1434 1437
1435#ifdef TCC_TARGET_PE1438#ifdef TCC_TARGET_PE
1436 int indirect = 0, slot = size + 7 & -8;1439 int indirect = 0, slot = (size + 7) & -8;
1437 1440
1438 if (size > 16)1441 if (size > 16)
1439 indirect = 1, slot = 8;1442 indirect = 1, slot = 8;
1440 1443
1441 gaddrof();1444 r0 = intr(gv_addr(RC_INT));
1442 r0 = intr(gv(RC_INT));
1443 r1 = get_reg(RC_INT);1445 r1 = get_reg(RC_INT);
1444 vtop[0].r = r1 | VT_LVAL;1446 vtop[0].r = r1 | VT_LVAL;
1445 r1 = intr(r1);1447 r1 = intr(r1);
@@ -1459,7 +1461,6 @@ ST_FUNC void gen_va_arg(CType *t) · 13 unmodified lines
1459 o(0x9100001e | r1 << 5 | slot << 10); // add x30,x(r1),#(slot)1461 o(0x9100001e | r1 << 5 | slot << 10); // add x30,x(r1),#(slot)
1460 o(0xf900001e | r0 << 5); // str x30,[x(r0)] // ap += slot1462 o(0xf900001e | r0 << 5); // str x30,[x(r0)] // ap += slot
1461 }1463 }
1462
1463 if (indirect)1464 if (indirect)
1464 o(ARM64_LDR_X | ARM64_RN(r1) | r1); // ldr x(r1),[x(r1)]1465 o(ARM64_LDR_X | ARM64_RN(r1) | r1); // ldr x(r1),[x(r1)]
1465 1466
@@ -1469,8 +1470,7 @@ ST_FUNC void gen_va_arg(CType *t) · 3 unmodified lines
1469 if (!is_float(t->t))1470 if (!is_float(t->t))
1470 hfa = arm64_hfa(t, &fsize);1471 hfa = arm64_hfa(t, &fsize);
1471 1472
1472 gaddrof();1473 r0 = intr(gv_addr(RC_INT));
1473 r0 = intr(gv(RC_INT));
1474 r1 = get_reg(RC_INT);1474 r1 = get_reg(RC_INT);
1475 vtop[0].r = r1 | VT_LVAL;1475 vtop[0].r = r1 | VT_LVAL;
1476 r1 = intr(r1);1476 r1 = intr(r1);
@@ -1570,8 +1570,7 @@ ST_FUNC void gfunc_return(CType *func_type) · 93 unmodified lines
1570 case 0:1570 case 0:
1571 if ((func_type->t & VT_BTYPE) == VT_STRUCT) {1571 if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
1572 int align, size = type_size(func_type, &align);1572 int align, size = type_size(func_type, &align);
1573 gaddrof();1573 gv_addr(RC_R(0));
1574 gv(RC_R(0));
1575 arm64_ldrs(0, size);1574 arm64_ldrs(0, size);
1576 }1575 }
1577 else1576 else
@@ -1590,8 +1589,7 @@ ST_FUNC void gfunc_return(CType *func_type) · 12 unmodified lines
1590 if ((func_type->t & VT_BTYPE) == VT_STRUCT) {1589 if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
1591 /* HFA struct return - load from the address on vtop into float registers */1590 /* HFA struct return - load from the address on vtop into float registers */
1592 uint32_t j, sz, n = arm64_hfa(func_type, &sz);1591 uint32_t j, sz, n = arm64_hfa(func_type, &sz);
1593 gaddrof();1592 gv_addr(RC_R(0));
1594 gv(RC_R(0));
1595 for (j = 0; j < n; j++)1593 for (j = 0; j < n; j++)
1596 o(0x3d400000 |1594 o(0x3d400000 |
1597 (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |1595 (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |
i386-asm.c+0−7
@@ -494,13 +494,6 @@ ST_FUNC void gen_expr32(ExprValue *pe) · 493 unmodified lines
494 gen_addr32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);494 gen_addr32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
495}495}
496 496
497#ifdef TCC_TARGET_X86_64
498ST_FUNC void gen_expr64(ExprValue *pe)
499{
500 gen_addr64(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
501}
502#endif
503
504/* XXX: unify with C code output ? */497/* XXX: unify with C code output ? */
505static void gen_disp32(ExprValue *pe)498static void gen_disp32(ExprValue *pe)
506{499{
lib/Makefile+2−2
@@ -41,7 +41,7 @@ ARM_O = libtcc1.o armeabi.o armflush.o $(COMMON_O) · 40 unmodified lines
41ARM64_O = lib-arm64.o $(COMMON_O)41ARM64_O = lib-arm64.o $(COMMON_O)
42RISCV64_O = lib-arm64.o $(COMMON_O)42RISCV64_O = lib-arm64.o $(COMMON_O)
43COMMON_O = stdatomic.o atomic.o builtin.o alloca.o alloca-bt.o43COMMON_O = stdatomic.o atomic.o builtin.o alloca.o alloca-bt.o
44WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o44WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o winex.o
45LIN_O = dsohandle.o45LIN_O = dsohandle.o
46OSX_O =46OSX_O =
47 47
@@ -63,7 +63,7 @@ OBJ-x86_64 = $(X86_64_O) va_list.o $(LIN_O) · 15 unmodified lines
63OBJ-x86_64-osx = $(X86_64_O) va_list.o $(OSX_O)63OBJ-x86_64-osx = $(X86_64_O) va_list.o $(OSX_O)
64OBJ-i386-win32 = $(I386_O) chkstk.o $(WIN_O)64OBJ-i386-win32 = $(I386_O) chkstk.o $(WIN_O)
65OBJ-x86_64-win32 = $(X86_64_O) chkstk.o $(WIN_O)65OBJ-x86_64-win32 = $(X86_64_O) chkstk.o $(WIN_O)
66OBJ-arm64 = $(ARM64_O) $(LIN_O)66OBJ-arm64 = $(ARM64_O) armflush.o $(LIN_O)
67OBJ-arm64-osx = $(ARM64_O) $(OSX_O)67OBJ-arm64-osx = $(ARM64_O) $(OSX_O)
68OBJ-arm64-win32 = $(ARM64_O) chkstk.o $(WIN_O)68OBJ-arm64-win32 = $(ARM64_O) chkstk.o $(WIN_O)
69OBJ-arm = $(ARM_O) $(LIN_O)69OBJ-arm = $(ARM_O) $(LIN_O)
lib/armflush.c+13−0
@@ -4,6 +4,9 @@ · 3 unmodified lines
4 intrinsic with gcc. However tcc in order to compile4 intrinsic with gcc. However tcc in order to compile
5 itself needs this function */5 itself needs this function */
6 6
7/* ------------------------------------------------------------- */
8#if defined __arm__
9
7#ifdef __TINYC__10#ifdef __TINYC__
8 11
9/* syscall wrapper */12/* syscall wrapper */
@@ -49,3 +52,13 @@ void __clear_cache(void *beginning, void *end) · 39 unmodified lines
49 * However, there is no ARM asm parser in tcc so we use it for now */52 * However, there is no ARM asm parser in tcc so we use it for now */
50 syscall(__ARM_NR_cacheflush, beginning, end, 0);53 syscall(__ARM_NR_cacheflush, beginning, end, 0);
51}54}
55
56/* ------------------------------------------------------------- */
57#elif defined __aarch64__
58void __clear_cache(void *beg, void *end)
59{
60 __arm64_clear_cache(beg, end);
61}
62
63/* ------------------------------------------------------------- */
64#endif
lib/bt-dll.c+24−3
@@ -34,7 +34,11 @@ · 33 unmodified lines
34 REDIR(__bound_strncmp) \34 REDIR(__bound_strncmp) \
35 REDIR(__bound_strcat) \35 REDIR(__bound_strcat) \
36 REDIR(__bound_strchr) \36 REDIR(__bound_strchr) \
37 REDIR(__bound_strdup)37 REDIR(__bound_strdup) \
38 REDIR(__bound_strncat) \
39 REDIR(__bound_strrchr) \
40 REDIR(__bound_setjmp) \
41 REDIR(__bound_longjmp)
38 42
39#ifdef __leading_underscore43#ifdef __leading_underscore
40#define _(s) "_"#s44#define _(s) "_"#s
@@ -45,11 +49,28 @@ · 4 unmodified lines
45#define REDIR(s) void *s;49#define REDIR(s) void *s;
46static struct { REDIR_ALL } all_ptrs;50static struct { REDIR_ALL } all_ptrs;
47#undef REDIR51#undef REDIR
52
48#define REDIR(s) #s"\0"53#define REDIR(s) #s"\0"
49static const char all_names[] = REDIR_ALL;54static const char all_names[] = REDIR_ALL;
50#undef REDIR55#undef REDIR
51#define REDIR(s) __asm__(".global " _(s) ";" _(s) ": jmp *%0" : : "m" (all_ptrs.s) );56
52static void all_jmps() { REDIR_ALL }57#if __aarch64__
58# define REDIR(s) \
59 __asm__(".global "_(s)";"_(s)":"); \
60 __asm__(".int 0x58000090"); /* ldr x16, [pc, #16] */ \
61 __asm__(".int 0xf9400210"); /* ldr x16, [x16] */ \
62 __asm__(".int 0xd61f0200"); /* br x16 */ \
63 __asm__(".int 0xd503201f"); /* nop for alignment */ \
64 __asm__(".quad all_ptrs + (. - all_jmps - 16) / 24 * 8"); \
65 __asm__(".type "_(s)",function\n.size "_(s)",.-"_(s));
66
67 __asm__(".text\n.align 8\nall_jmps:");
68 REDIR_ALL
69#else
70# define REDIR(s) \
71 __asm__(".global "_(s)";"_(s)":"); goto *all_ptrs.s;
72 static void all_jmps() { REDIR_ALL }
73#endif
53#undef REDIR74#undef REDIR
54 75
55void __bt_init_dll(int bcheck)76void __bt_init_dll(int bcheck)
lib/lib-arm64.c+0−7
@@ -23,13 +23,6 @@ typedef unsigned long long uint64_t; · 22 unmodified lines
23#include <string.h>23#include <string.h>
24#endif24#endif
25 25
26#if !defined __riscv && !defined __APPLE__
27void __clear_cache(void *beg, void *end)
28{
29 __arm64_clear_cache(beg, end);
30}
31#endif
32
33typedef union {26typedef union {
34 struct { uint64_t x0, x1; };27 struct { uint64_t x0, x1; };
35 long double f;28 long double f;
lib/libtcc1.c+2−20
@@ -107,10 +107,9 @@ union float_long { · 106 unmodified lines
107};107};
108 108
109/* XXX: we don't support several builtin supports for now */109/* XXX: we don't support several builtin supports for now */
110#if !defined __x86_64__ && !defined __arm__ && !defined __riscv && !defined __aarch64__110#if defined __i386__
111 111
112/* XXX: use gcc/tcc intrinsic ? */112/* XXX: use gcc/tcc intrinsic ? */
113#if defined __i386__
114#define sub_ddmmss(sh, sl, ah, al, bh, bl) \113#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
115 __asm__ ("subl %5,%1\n\tsbbl %3,%0" \114 __asm__ ("subl %5,%1\n\tsbbl %3,%0" \
116 : "=r" ((USItype) (sh)), \115 : "=r" ((USItype) (sh)), \
@@ -139,9 +138,6 @@ union float_long { · 22 unmodified lines
139 : "=r" (__cbtmp) : "rm" ((USItype) (x))); \138 : "=r" (__cbtmp) : "rm" ((USItype) (x))); \
140 (count) = __cbtmp ^ 31; \139 (count) = __cbtmp ^ 31; \
141 } while (0)140 } while (0)
142#else
143#error unsupported CPU type
144#endif
145 141
146/* most of this code is taken from libgcc2.c from gcc */142/* most of this code is taken from libgcc2.c from gcc */
147 143
@@ -478,7 +474,7 @@ long long __ashldi3(long long a, int b) · 330 unmodified lines
478#endif474#endif
479}475}
480 476
481#endif /* !__x86_64__ */477#endif /* __i386__ */
482 478
483/* XXX: fix tcc's code generator to do this instead */479/* XXX: fix tcc's code generator to do this instead */
484float __floatundisf(unsigned long long a)480float __floatundisf(unsigned long long a)
@@ -625,17 +621,3 @@ long long __fixxfdi (long double a1) · 140 unmodified lines
625 return s ? ret : -ret;621 return s ? ret : -ret;
626}622}
627#endif /* !ARM */623#endif /* !ARM */
628
629#if defined _WIN64
630/* MSVC x64 intrinsic */
631void __faststorefence(void)
632{
633#if defined(__aarch64__)
634 /* ARM64: Data Memory Barrier (Inner Shareable) */
635 __asm__("dmb ish");
636#else
637 /* x86-64: lock prefix to flush store buffer */
638 __asm__("lock; orl $0,(%%rsp)" ::: "memory");
639#endif
640}
641#endif
libtcc.c+8−1
@@ -124,8 +124,15 @@ static void tcc_add_systemdir(TCCState *s) · 123 unmodified lines
124 tcc_add_library_path(s, normalize_slashes(buf));124 tcc_add_library_path(s, normalize_slashes(buf));
125}125}
126#endif126#endif
127/* for tcc -E : On windows (depending on compiler) a FILE*
128 must be created by the same module where it is used. */
129PUB_FUNC FILE *tcc_fopen(const char *f, const char *m) {
130 return fopen(f, m);
131}
132PUB_FUNC int tcc_fclose(FILE *f) {
133 return fclose(f);
134}
127#endif135#endif
128
129/********************************************************/136/********************************************************/
130 137
131PUB_FUNC void tcc_enter_state(TCCState *s1)138PUB_FUNC void tcc_enter_state(TCCState *s1)
tcc.c+6−6
@@ -293,7 +293,7 @@ int main(int argc, char **argv) · 292 unmodified lines
293 const char *first_file;293 const char *first_file;
294 int argc0 = argc;294 int argc0 = argc;
295 char **argv0 = argv;295 char **argv0 = argv;
296 FILE *ppfp = stdout;296 FILE *ppfp = NULL;
297 297
298redo:298redo:
299 argc = argc0, argv = argv0;299 argc = argc0, argv = argv0;
@@ -335,7 +335,7 @@ redo: · 35 unmodified lines
335 tcc_error_noabort("no input files");335 tcc_error_noabort("no input files");
336 } else if (s->output_type == TCC_OUTPUT_PREPROCESS) {336 } else if (s->output_type == TCC_OUTPUT_PREPROCESS) {
337 if (s->outfile && 0!=strcmp("-",s->outfile)) {337 if (s->outfile && 0!=strcmp("-",s->outfile)) {
338 ppfp = fopen(s->outfile, "wb");338 ppfp = tcc_fopen(s->outfile, "wb");
339 if (!ppfp)339 if (!ppfp)
340 tcc_error_noabort("could not write '%s'", s->outfile);340 tcc_error_noabort("could not write '%s'", s->outfile);
341 }341 }
@@ -355,8 +355,8 @@ redo: · 13 unmodified lines
355 if (s->output_type == 0)355 if (s->output_type == 0)
356 s->output_type = TCC_OUTPUT_EXE;356 s->output_type = TCC_OUTPUT_EXE;
357 tcc_set_output_type(s, s->output_type);357 tcc_set_output_type(s, s->output_type);
358 s->ppfp = ppfp;358 if (ppfp)
359 359 s->ppfp = ppfp;
360 if ((s->output_type == TCC_OUTPUT_MEMORY360 if ((s->output_type == TCC_OUTPUT_MEMORY
361 || s->output_type == TCC_OUTPUT_PREPROCESS)361 || s->output_type == TCC_OUTPUT_PREPROCESS)
362 && (s->dflag & 16)) { /* -dt option */362 && (s->dflag & 16)) { /* -dt option */
@@ -422,7 +422,7 @@ redo: · 59 unmodified lines
422 tcc_delete(s);422 tcc_delete(s);
423 if (!done)423 if (!done)
424 goto redo;424 goto redo;
425 if (ppfp && ppfp != stdout)425 if (ppfp)
426 fclose(ppfp);426 tcc_fclose(ppfp);
427 return ret;427 return ret;
428}428}
tcc.h+15−6
@@ -52,6 +52,9 @@ extern long double strtold (const char *__nptr, char **__endptr); · 51 unmodified lines
52 52
53#ifdef _WIN3253#ifdef _WIN32
54# define WIN32_LEAN_AND_MEAN 154# define WIN32_LEAN_AND_MEAN 1
55# ifndef _WIN32_WINNT
56# define _WIN32_WINNT 0x502 /* AddVectoredExceptionHandler */
57# endif
55# include <windows.h>58# include <windows.h>
56# include <io.h> /* open, close etc. */59# include <io.h> /* open, close etc. */
57# include <direct.h> /* getcwd */60# include <direct.h> /* getcwd */
@@ -86,6 +89,9 @@ extern long double strtold (const char *__nptr, char **__endptr); · 28 unmodified lines
86# define __x86_64__ 189# define __x86_64__ 1
87# endif90# endif
88# endif91# endif
92# if defined(_M_ARM64) && !defined(__aarch64__)
93# define __aarch64__ 1
94# endif
89# ifndef va_copy95# ifndef va_copy
90# define va_copy(a,b) a = b96# define va_copy(a,b) a = b
91# endif97# endif
@@ -228,8 +234,7 @@ extern long double strtold (const char *__nptr, char **__endptr); · 136 unmodified lines
228/* No ten-byte long doubles on window and macos except in234/* No ten-byte long doubles on window and macos except in
229 cross-compilers made by a mingw-GCC */235 cross-compilers made by a mingw-GCC */
230#if defined TCC_TARGET_PE \236#if defined TCC_TARGET_PE \
231 || (defined TCC_TARGET_MACHO && defined TCC_TARGET_ARM64) \237 || (defined TCC_TARGET_MACHO && defined TCC_TARGET_ARM64)
232 || (defined _WIN32 && !defined __GNUC__)
233# define TCC_USING_DOUBLE_FOR_LDOUBLE 1238# define TCC_USING_DOUBLE_FOR_LDOUBLE 1
234#endif239#endif
235 240
@@ -1312,6 +1317,11 @@ PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time); · 1076 unmodified lines
1312PUB_FUNC int tcc_parse_args(TCCState *s, int *argc, char ***argv);1317PUB_FUNC int tcc_parse_args(TCCState *s, int *argc, char ***argv);
1313#ifdef _WIN321318#ifdef _WIN32
1314ST_FUNC char *normalize_slashes(char *path);1319ST_FUNC char *normalize_slashes(char *path);
1320PUB_FUNC FILE *tcc_fopen(const char *f, const char *m);
1321PUB_FUNC int tcc_fclose(FILE *f);
1322#else
1323# define tcc_fopen fopen
1324# define tcc_fclose fclose
1315#endif1325#endif
1316ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname, int level);1326ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname, int level);
1317ST_FUNC char *tcc_load_text(int fd);1327ST_FUNC char *tcc_load_text(int fd);
@@ -1683,7 +1693,6 @@ ST_FUNC void gen_increment_tcov (SValue *sv); · 365 unmodified lines
1683 1693
1684/* ------------ x86_64-gen.c ------------ */1694/* ------------ x86_64-gen.c ------------ */
1685#ifdef TCC_TARGET_X86_641695#ifdef TCC_TARGET_X86_64
1686ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c);
1687ST_FUNC void gen_opl(int op);1696ST_FUNC void gen_opl(int op);
1688#ifdef TCC_TARGET_PE1697#ifdef TCC_TARGET_PE
1689ST_FUNC void gen_vla_result(int addr);1698ST_FUNC void gen_vla_result(int addr);
@@ -1742,11 +1751,11 @@ ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, const char *n · 52 unmodified lines
1742ST_FUNC Sym* get_asm_sym(int name, Sym *csym);1751ST_FUNC Sym* get_asm_sym(int name, Sym *csym);
1743ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe);1752ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe);
1744ST_FUNC int asm_int_expr(TCCState *s1);1753ST_FUNC int asm_int_expr(TCCState *s1);
1745/* ------------ i386-asm.c ------------ */1754#if PTR_SIZE == 8
1746ST_FUNC void gen_expr32(ExprValue *pe);
1747#ifdef TCC_TARGET_X86_64
1748ST_FUNC void gen_expr64(ExprValue *pe);1755ST_FUNC void gen_expr64(ExprValue *pe);
1749#endif1756#endif
1757/* ------------ i386-asm.c ------------ */
1758ST_FUNC void gen_expr32(ExprValue *pe);
1750ST_FUNC void asm_opcode(TCCState *s1, int opcode);1759ST_FUNC void asm_opcode(TCCState *s1, int opcode);
1751ST_FUNC int asm_parse_regvar(int t);1760ST_FUNC int asm_parse_regvar(int t);
1752ST_FUNC void asm_compute_constraints(ASMOperand *operands, int nb_operands, int nb_outputs, const uint8_t *clobber_regs, int *pout_reg);1761ST_FUNC void asm_compute_constraints(ASMOperand *operands, int nb_operands, int nb_outputs, const uint8_t *clobber_regs, int *pout_reg);
tccasm.c+30−11
@@ -25,6 +25,26 @@ · 24 unmodified lines
25static Section *last_text_section; /* to handle .previous asm directive */25static Section *last_text_section; /* to handle .previous asm directive */
26static int asmgoto_n;26static int asmgoto_n;
27 27
28static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global);
29static Sym* asm_new_label(TCCState *s1, int label, int is_local);
30static Sym* asm_new_label1(TCCState *s1, int label, int is_local, int sh_num, int value);
31
32#if PTR_SIZE == 8
33/* output constant with relocation if 'r & VT_SYM' is true */
34ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c)
35{
36 if (r & VT_SYM)
37 greloca(cur_text_section, sym, ind, R_DATA_PTR, c), c=0;
38 gen_le32(c);
39 gen_le32(c>>32);
40}
41
42ST_FUNC void gen_expr64(ExprValue *pe)
43{
44 gen_addr64(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
45}
46#endif
47
28static int asm_get_prefix_name(TCCState *s1, const char *prefix, unsigned int n)48static int asm_get_prefix_name(TCCState *s1, const char *prefix, unsigned int n)
29{49{
30 char buf[64];50 char buf[64];
@@ -37,10 +57,6 @@ ST_FUNC int asm_get_local_label_name(TCCState *s1, unsigned int n) · 6 unmodified lines
37 return asm_get_prefix_name(s1, "L..", n);57 return asm_get_prefix_name(s1, "L..", n);
38}58}
39 59
40static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global);
41static Sym* asm_new_label(TCCState *s1, int label, int is_local);
42static Sym* asm_new_label1(TCCState *s1, int label, int is_local, int sh_num, int value);
43
44/* If a C name has an _ prepended then only asm labels that start60/* If a C name has an _ prepended then only asm labels that start
45 with _ are representable in C, by removing the first _. ASM names61 with _ are representable in C, by removing the first _. ASM names
46 without _ at the beginning don't correspond to C names, but we use62 without _ at the beginning don't correspond to C names, but we use
@@ -328,12 +344,12 @@ static inline void asm_expr_sum(TCCState *s1, ExprValue *pe) · 281 unmodified lines
328 if (esym1 && esym1->st_shndx == esym2->st_shndx344 if (esym1 && esym1->st_shndx == esym2->st_shndx
329 && esym1->st_shndx != SHN_UNDEF) {345 && esym1->st_shndx != SHN_UNDEF) {
330 /* we also accept defined symbols in the same section */346 /* we also accept defined symbols in the same section */
331 pe->v += esym1->st_value - esym2->st_value;347 pe->v += (int)(esym1->st_value - esym2->st_value);
332 pe->sym = NULL;348 pe->sym = NULL;
333 } else if (esym2->st_shndx == cur_text_section->sh_num) {349 } else if (esym2->st_shndx == cur_text_section->sh_num) {
334 /* When subtracting a defined symbol in current section350 /* When subtracting a defined symbol in current section
335 this actually makes the value PC-relative. */351 this actually makes the value PC-relative. */
336 pe->v += 0 - esym2->st_value;352 pe->v += (int)(0 - esym2->st_value);
337 pe->pcrel = 1;353 pe->pcrel = 1;
338 e2.sym = NULL;354 e2.sym = NULL;
339 } else {355 } else {
@@ -543,7 +559,7 @@ static void asm_parse_directive(TCCState *s1, int global) · 203 unmodified lines
543 ind += size;559 ind += size;
544 break;560 break;
545 case TOK_ASMDIR_quad:561 case TOK_ASMDIR_quad:
546#ifdef TCC_TARGET_X86_64562#if PTR_SIZE == 8
547 size = 8;563 size = 8;
548 goto asm_data;564 goto asm_data;
549#else565#else
@@ -592,7 +608,7 @@ static void asm_parse_directive(TCCState *s1, int global) · 42 unmodified lines
592 if (sec->sh_type != SHT_NOBITS) {608 if (sec->sh_type != SHT_NOBITS) {
593 if (size == 4) {609 if (size == 4) {
594 gen_expr32(&e);610 gen_expr32(&e);
595#ifdef TCC_TARGET_X86_64611#if PTR_SIZE == 8
596 } else if (size == 8) {612 } else if (size == 8) {
597 gen_expr64(&e);613 gen_expr64(&e);
598#endif614#endif
@@ -812,6 +828,7 @@ static void asm_parse_directive(TCCState *s1, int global) · 213 unmodified lines
812 case TOK_ASMDIR_size:828 case TOK_ASMDIR_size:
813 { 829 {
814 Sym *sym;830 Sym *sym;
831 ElfSym *esym;
815 832
816 next();833 next();
817 if (tok < TOK_IDENT)834 if (tok < TOK_IDENT)
@@ -823,8 +840,10 @@ static void asm_parse_directive(TCCState *s1, int global) · 5 unmodified lines
823 tcc_warning_c(warn_unsupported)("ignoring .size %s,*", get_tok_str(tok, NULL));840 tcc_warning_c(warn_unsupported)("ignoring .size %s,*", get_tok_str(tok, NULL));
824 next();841 next();
825 skip(',');842 skip(',');
826 while (tok != TOK_LINEFEED && tok != ';' && tok != CH_EOF) {843 n = asm_int_expr(s1);
827 next();844 esym = elfsym(sym);
845 if (esym) {
846 esym->st_size = n;
828 }847 }
829 }848 }
830 break;849 break;
@@ -952,7 +971,7 @@ static void asm_parse_directive(TCCState *s1, int global) · 121 unmodified lines
952 }971 }
953 break;972 break;
954#endif973#endif
955#ifdef TCC_TARGET_X86_64974#if PTR_SIZE == 8
956 /* added for compatibility with GAS */975 /* added for compatibility with GAS */
957 case TOK_ASMDIR_code64:976 case TOK_ASMDIR_code64:
958 next();977 next();
tcclib.h+2−0
@@ -19,6 +19,7 @@ int atoi(const char *nptr); · 18 unmodified lines
19long int strtol(const char *nptr, char **endptr, int base);19long int strtol(const char *nptr, char **endptr, int base);
20unsigned long int strtoul(const char *nptr, char **endptr, int base);20unsigned long int strtoul(const char *nptr, char **endptr, int base);
21void exit(int);21void exit(int);
22void *alloca(size_t);
22 23
23/* stdio.h */24/* stdio.h */
24typedef struct __FILE FILE;25typedef struct __FILE FILE;
@@ -39,6 +40,7 @@ int getchar(void); · 14 unmodified lines
39char *gets(char *s);40char *gets(char *s);
40int ungetc(int c, FILE *stream);41int ungetc(int c, FILE *stream);
41int fflush(FILE *stream);42int fflush(FILE *stream);
43int puts(const char *s);
42int putchar (int c);44int putchar (int c);
43 45
44int printf(const char *format, ...);46int printf(const char *format, ...);
tccpe.c+24−45
@@ -1958,6 +1958,7 @@ ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack) · 1957 unmodified lines
1958 for (n = o + sizeof *p; o < n; o += sizeof p->BeginAddress)1958 for (n = o + sizeof *p; o < n; o += sizeof p->BeginAddress)
1959 put_elf_reloc(symtab_section, pd, o, R_XXX_RELATIVE, s1->uw_sym);1959 put_elf_reloc(symtab_section, pd, o, R_XXX_RELATIVE, s1->uw_sym);
1960}1960}
1961
1961#elif defined(TCC_TARGET_ARM64)1962#elif defined(TCC_TARGET_ARM64)
1962/* ARM64 unwind codes:1963/* ARM64 unwind codes:
1963 save_fplr_x: 10iiiiii - stp x29,lr,[sp,#-(i+1)*8]!1964 save_fplr_x: 10iiiiii - stp x29,lr,[sp,#-(i+1)*8]!
@@ -1975,10 +1976,7 @@ static Section *pe_add_unwind_info(TCCState *s1) · 11 unmodified lines
1975 s1->uw_pdata->sh_addralign = 4;1976 s1->uw_pdata->sh_addralign = 4;
1976 }1977 }
1977 s = find_section(s1, ".xdata");1978 s = find_section(s1, ".xdata");
1978 if (NULL == s) {1979 s->sh_addralign = 4;
1979 s = new_section(s1, ".xdata", SHT_PROGBITS, SHF_ALLOC);
1980 s->sh_addralign = 4;
1981 }
1982 if (0 == s1->uw_sym)1980 if (0 == s1->uw_sym)
1983 s1->uw_sym = put_elf_sym(symtab_section, 0, 0, 0, 0,1981 s1->uw_sym = put_elf_sym(symtab_section, 0, 0, 0, 0,
1984 text_section->sh_num, ".uw_text_base");1982 text_section->sh_num, ".uw_text_base");
@@ -1992,31 +1990,22 @@ ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack) · 7 unmodified lines
1992{1990{
1993 TCCState *s1 = tcc_state;1991 TCCState *s1 = tcc_state;
1994 Section *pd, *xd;1992 Section *pd, *xd;
1995 unsigned o, n, d, code_bytes, func_len, stack_slots;1993 unsigned o, d, code_bytes, func_len;
1996 unsigned char *q;1994 unsigned char *q;
1997 uint32_t header;1995 uint32_t header;
1998 struct {1996 struct /* _RUNTIME_FUNCTION */ {
1999 DWORD BeginAddress;1997 DWORD BeginAddress;
2000 DWORD EndAddress;
2001 DWORD UnwindData;1998 DWORD UnwindData;
2002 } *p;1999 } *p;
2003 2000
2001 int epilog;
2002
2004 xd = pe_add_unwind_info(s1);2003 xd = pe_add_unwind_info(s1);
2005 pd = s1->uw_pdata;2004 pd = s1->uw_pdata;
2006 2005
2007 stack = (stack + 15) & ~15;
2008 stack_slots = stack >> 4;
2009 func_len = (end - start) >> 2;2006 func_len = (end - start) >> 2;
2010 code_bytes = 0;2007 code_bytes = 0;
2011 if (stack_slots) {2008 epilog = code_bytes;
2012 if (stack_slots <= 31) {
2013 code_bytes += 1;
2014 } else if (stack_slots <= 0x7ff) {
2015 code_bytes += 2;
2016 } else {
2017 code_bytes += 4;
2018 }
2019 }
2020 code_bytes += 3; /* set_fp, save_fplr_x, end */2009 code_bytes += 3; /* set_fp, save_fplr_x, end */
2021 code_bytes = (code_bytes + 3) & ~3;2010 code_bytes = (code_bytes + 3) & ~3;
2022 2011
@@ -2025,23 +2014,13 @@ ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack) · 2 unmodified lines
2025 q = section_ptr_add(xd, 4 + code_bytes);2014 q = section_ptr_add(xd, 4 + code_bytes);
2026 2015
2027 /* Full ARM64 xdata header: E=1 with one epilog and no exception handler. */2016 /* Full ARM64 xdata header: E=1 with one epilog and no exception handler. */
2028 header = (func_len & 0x3ffff) | (1u << 21) | ((code_bytes >> 2) << 27);2017 header = (func_len & 0x3ffff)
2018 | 1 << 21
2019 | (epilog & 0x1F) << 22
2020 | (code_bytes >> 2) << 27
2021 ;
2029 write32le(q, header);2022 write32le(q, header);
2030 q += 4;2023 q += 4;
2031
2032 if (stack_slots) {
2033 if (stack_slots <= 31) {
2034 *q++ = stack_slots; /* alloc_s */
2035 } else if (stack_slots <= 0x7ff) {
2036 *q++ = 0xC0 | (stack_slots >> 8); /* alloc_m */
2037 *q++ = stack_slots & 0xff;
2038 } else {
2039 *q++ = 0xE0; /* alloc_l */
2040 *q++ = (stack_slots >> 16) & 0xff;
2041 *q++ = (stack_slots >> 8) & 0xff;
2042 *q++ = stack_slots & 0xff;
2043 }
2044 }
2045 *q++ = 0xE1; /* set_fp */2024 *q++ = 0xE1; /* set_fp */
2046 *q++ = 0x9B; /* save_fplr_x: stp x29,lr,[sp,#-224]! */2025 *q++ = 0x9B; /* save_fplr_x: stp x29,lr,[sp,#-224]! */
2047 *q++ = 0xE4; /* end */2026 *q++ = 0xE4; /* end */
@@ -2050,14 +2029,10 @@ ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack) · 2 unmodified lines
2050 2029
2051 o = pd->data_offset;2030 o = pd->data_offset;
2052 p = section_ptr_add(pd, sizeof *p);2031 p = section_ptr_add(pd, sizeof *p);
2053
2054 p->BeginAddress = start;2032 p->BeginAddress = start;
2055 p->EndAddress = end;
2056 p->UnwindData = d;2033 p->UnwindData = d;
2057 2034 put_elf_reloc(symtab_section, pd, o, R_XXX_RELATIVE, s1->uw_sym);
2058 for (n = o + 2 * sizeof p->BeginAddress; o < n; o += sizeof p->BeginAddress)2035 put_elf_reloc(symtab_section, pd, o + 4, R_XXX_RELATIVE, s1->uw_xsym);
2059 put_elf_reloc(symtab_section, pd, o, R_XXX_RELATIVE, s1->uw_sym);
2060 put_elf_reloc(symtab_section, pd, n, R_XXX_RELATIVE, s1->uw_xsym);
2061}2036}
2062#endif2037#endif
2063/* ------------------------------------------------------------- */2038/* ------------------------------------------------------------- */
@@ -2252,20 +2227,22 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename) · 188 unmodified lines
2252 resolve_common_syms(s1);2227 resolve_common_syms(s1);
2253 pe_set_options(s1, &pe);2228 pe_set_options(s1, &pe);
2254 pe_check_symbols(&pe);2229 pe_check_symbols(&pe);
2255
2256 if (s1->nb_errors)2230 if (s1->nb_errors)
2257 ;2231 goto done;
2258 else if (filename) {2232 if (filename) {
2259 pe_assign_addresses(&pe);2233 pe_assign_addresses(&pe);
2260 relocate_syms(s1, s1->symtab, 0);2234 relocate_syms(s1, s1->symtab, 0);
2235 if (s1->nb_errors)
2236 goto done;
2261 s1->pe_imagebase = pe.imagebase;2237 s1->pe_imagebase = pe.imagebase;
2262 relocate_sections(s1);2238 relocate_sections(s1);
2263 pe.start_addr = (DWORD)2239 pe.start_addr = (DWORD)
2264 (get_sym_addr(s1, pe.start_symbol, 1, 1) - pe.imagebase);2240 (get_sym_addr(s1, pe.start_symbol, 1, 1) - pe.imagebase);
2265 if (0 == s1->nb_errors)2241 if (s1->nb_errors)
2266 pe_write(&pe);2242 goto done;
2267 dynarray_reset(&pe.sec_info, &pe.sec_count);2243 pe_write(&pe);
2268 } else {2244 } else {
2245 /* -run */
2269#ifdef TCC_IS_NATIVE2246#ifdef TCC_IS_NATIVE
2270 pe.thunk = data_section;2247 pe.thunk = data_section;
2271 pe_build_imports(&pe);2248 pe_build_imports(&pe);
@@ -2275,6 +2252,8 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename) · 3 unmodified lines
2275#endif2252#endif
2276#endif2253#endif
2277 }2254 }
2255done:
2256 dynarray_reset(&pe.sec_info, &pe.sec_count);
2278 pe_free_imports(&pe);2257 pe_free_imports(&pe);
2279#if PE_PRINT_SECTIONS2258#if PE_PRINT_SECTIONS
2280 if (g_debug & 8)2259 if (g_debug & 8)
tccrun.c+2−0
@@ -434,6 +434,8 @@ redo: · 433 unmodified lines
434 434
435 /* relocate symbols */435 /* relocate symbols */
436 relocate_syms(s1, s1->symtab, 1);436 relocate_syms(s1, s1->symtab, 1);
437 if (s1->nb_errors)
438 goto redo;
437 /* relocate sections */439 /* relocate sections */
438#ifdef TCC_TARGET_PE440#ifdef TCC_TARGET_PE
439 s1->pe_imagebase = mem;441 s1->pe_imagebase = mem;
tcctok.h+4−3
@@ -402,12 +402,13 @@ · 401 unmodified lines
402 DEF_ASMDIR(endr)402 DEF_ASMDIR(endr)
403 DEF_ASMDIR(org)403 DEF_ASMDIR(org)
404 DEF_ASMDIR(quad)404 DEF_ASMDIR(quad)
405#if defined(TCC_TARGET_I386)405#if PTR_SIZE == 4
406 DEF_ASMDIR(code16)406 DEF_ASMDIR(code16)
407 DEF_ASMDIR(code32)407 DEF_ASMDIR(code32)
408#elif defined(TCC_TARGET_X86_64)408#else
409 DEF_ASMDIR(code64)409 DEF_ASMDIR(code64)
410#elif defined(TCC_TARGET_RISCV64)410#endif
411#if defined(TCC_TARGET_RISCV64)
411 DEF_ASMDIR(option)412 DEF_ASMDIR(option)
412#endif413#endif
413 DEF_ASMDIR(short)414 DEF_ASMDIR(short)
tests/Makefile+5−4
@@ -72,9 +72,9 @@ endif · 71 unmodified lines
72RUN_TCC = -run $(TOPSRC)/tcc.c $(TCCFLAGS)72RUN_TCC = -run $(TOPSRC)/tcc.c $(TCCFLAGS)
73DISAS = objdump -d73DISAS = objdump -d
74ifdef CONFIG_OSX74ifdef CONFIG_OSX
75DUMPTCC = (set -x; $(TOP)/tcc -vv; otool -L $(TOP)/tcc; exit 1)75DUMPTCC = (set -x; $(TCC_LOCAL) -vv; otool -L $(TCC_LOCAL); exit 1)
76else76else
77DUMPTCC = (set -x; $(TOP)/tcc -vv; ldd $(TOP)/tcc; exit 1)77DUMPTCC = (set -x; $(TCC_LOCAL) -vv; ldd $(TCC_LOCAL); exit 1)
78endif78endif
79 79
80all test :80all test :
@@ -82,6 +82,7 @@ all test : · 1 unmodified line
82 @$(TCC_LOCAL) -v82 @$(TCC_LOCAL) -v
83 @$(MAKE) --no-print-directory -s clean83 @$(MAKE) --no-print-directory -s clean
84 @$(MAKE) --no-print-directory -s -r _all84 @$(MAKE) --no-print-directory -s -r _all
85 @echo ------- ALL TESTS PASSED --------
85 86
86_all : $(TESTS)87_all : $(TESTS)
87 88
@@ -109,8 +110,8 @@ libtcc_test_mt$(EXESUF): libtcc_test_mt.c · 21 unmodified lines
109 110
110# test.ref - generate using cc111# test.ref - generate using cc
111test.ref: tcctest.c112test.ref: tcctest.c
112 $(CC) -o tcctest.gcc $< $(CFLAGS) -w -O0 -std=gnu99 -fno-omit-frame-pointer113 $(CC) -o tcctest.gcc$(EXESUF) $< $(CFLAGS) -w -O0 -std=gnu99 -fno-omit-frame-pointer
113 ./tcctest.gcc > $@114 ./tcctest.gcc$(EXESUF) > $@
114 115
115# auto test116# auto test
116test1 test1b: tcctest.c test.ref117test1 test1b: tcctest.c test.ref
tests/libtcc_test_mt.c+8−12
@@ -162,6 +162,7 @@ void *reloc_state(TCCState *s, const char *entry) · 161 unmodified lines
162{162{
163 void *func;163 void *func;
164 tcc_add_symbol(s, "add", add);164 tcc_add_symbol(s, "add", add);
165 tcc_add_symbol(s, "printf", printf);
165 if (tcc_relocate(s) < 0) {166 if (tcc_relocate(s) < 0) {
166 fprintf(stderr, __FILE__ ": could not relocate tcc state.\n");167 fprintf(stderr, __FILE__ ": could not relocate tcc state.\n");
167 return NULL;168 return NULL;
@@ -337,16 +338,15 @@ int main(int argc, char **argv) · 169 unmodified lines
337 338
338#else339#else
339#include <tcclib.h>340#include <tcclib.h>
340
341#ifdef _WIN32341#ifdef _WIN32
342# ifdef __i386__342# ifndef _WIN64
343# define LIBTCC_TEST_WINAPI __attribute__((__stdcall__))343 __declspec(stdcall)
344# else
345# define LIBTCC_TEST_WINAPI
346# endif344# endif
347void LIBTCC_TEST_WINAPI Sleep(unsigned int milliseconds);345 void Sleep(unsigned);
346# define sleep_ms Sleep
348#else347#else
349unsigned int sleep(unsigned int seconds);348 int usleep(unsigned long);
349# define sleep_ms(x) usleep((x)*1000);
350#endif350#endif
351 351
352int fib(n)352int fib(n)
@@ -356,11 +356,7 @@ int fib(n) · 3 unmodified lines
356 356
357int main(int argc, char **argv)357int main(int argc, char **argv)
358{358{
359#ifdef _WIN32359 sleep_ms(333);
360 Sleep(1000);
361#else
362 sleep(1);
363#endif
364 printf(" %d", fib(atoi(argv[1])));360 printf(" %d", fib(atoi(argv[1])));
365 return 0;361 return 0;
366}362}
tests/msvcrt_start.c+164−0
@@ -0,0 +1,164 @@
1/* ------------------------------------------------------------- */
2/* minimal startup with runtime linker to msvcrt */
3
4#if 0
5
6#define REDIR_ALL \
7 REDIR(__set_app_type)\
8 REDIR(__getmainargs)\
9 REDIR(_controlfp)\
10 REDIR(_vsnprintf)\
11 REDIR(exit)\
12 \
13 REDIR(puts)\
14 REDIR(printf)\
15 REDIR(putchar)\
16 REDIR(strtod)\
17 REDIR(memset)\
18 REDIR(strcpy)\
19 REDIR(strlen)\
20 REDIR(malloc)\
21 REDIR(free)\
22
23#if defined __i386__ && !defined __TINYC__
24# define __leading_underscore 1
25#endif
26
27#ifdef __leading_underscore
28# define _(s) "_"#s
29#else
30# define _(s) #s
31#endif
32
33#define REDIR(s) void *s;
34static struct { REDIR_ALL } all_ptrs;
35#undef REDIR
36
37#define REDIR(s) #s"\0"
38static const char all_names[] = REDIR_ALL;
39#undef REDIR
40
41#if __aarch64__
42 #if defined __TINYC__
43 # define ALIGN ".align 8"
44 #else
45 # define ALIGN ".align 3" /* .align is power of 2 on non-ELF platforms */
46 #endif
47# define REDIR(s) \
48 __asm__("\n"_(s)":"); \
49 __asm__(".int 0x58000090"); /* ldr x16, [pc, #16] */ \
50 __asm__(".int 0xf9400210"); /* ldr x16, [x16] */ \
51 __asm__(".int 0xd61f0200"); /* br x16 */ \
52 __asm__(".int 0xd503201f"); /* nop for alignment */ \
53 __asm__(".quad all_ptrs + (. - all_jmps - 16) / 24 * 8"); \
54 __asm__(".global "_(s));
55
56 __asm__("\t.text\n\t"ALIGN"\nall_jmps:");
57 REDIR_ALL
58#else
59# define REDIR(s) \
60 __asm__("\n"_(s)":");\
61 __asm__("jmp *%0"::"m"(all_ptrs.s));\
62 __asm__(".global "_(s));
63
64 static void all_jmps() { REDIR_ALL }
65#endif
66#undef REDIR
67
68#if 0
69# include <windows.h>
70#else
71# if __i386__
72# define STDCALL __declspec(stdcall)
73# else
74# define STDCALL
75# endif
76# define DWORD long unsigned
77# define HMODULE void*
78# define HANDLE void*
79S TDCALL HMODULE LoadLibraryA(const char *);
80S TDCALL HMODULE GetProcAddress(HMODULE , char*);
81S TDCALL void ExitProcess(int);
82S TDCALL int WriteFile(HANDLE, const void*, DWORD, DWORD*, void*);
83S TDCALL HANDLE GetStdHandle(DWORD);
84S TDCALL int FlushFileBuffers(HANDLE);
85# define STD_ERROR_HANDLE -12
86#endif
87
88static void eput(const char *s)
89{
90 DWORD n_out;
91 int n = 0;
92 while (s[n])
93 ++n;
94 WriteFile(GetStdHandle(STD_ERROR_HANDLE), s, n, &n_out, 0);
95}
96
97static void rt_reloc()
98{
99 const char *s = all_names;
100 void **p = (void**)&all_ptrs;
101 void *dll = LoadLibraryA("msvcrt.dll");
102 do {
103 char buf[100], *d = buf;
104 *p = (void*)GetProcAddress(dll, (char*)s);
105 *d++ = '_'; do *d++ = *s; while (*s++);
106 if (0 == *p)
107 *p = (void*)GetProcAddress(dll, buf);
108 if (0 == *p) {
109 eput("MSVCRT_START.C: RUNTIME RELOCATION ERROR: '");
110 eput(buf+1);
111 eput("'\n");
112 ExitProcess(-1);
113 }
114 ++p;
115 } while (*s);
116}
117
118#else
119# define rt_reloc()
120#endif
121
122int main(int argc, char **argv, char **env);
123void exit(int);
124void __set_app_type(int apptype);
125
126typedef struct { int newmode; } _startupinfo;
127int __getmainargs(int *pargc, char ***pargv, char ***penv, int globb, _startupinfo*);
128
129void _controlfp(unsigned a, unsigned b);
130#define _MCW_PC 0x00030000 // Precision Control
131#define _PC_53 0x00010000 // 53 bits
132
133int __argc;
134char **__argv;
135char **environ;
136_startupinfo start_info = {0};
137
138void mainCRTStartup(void)
139{
140 rt_reloc();
141#if defined __i386__ || defined __x86_64__
142 _controlfp(_PC_53, _MCW_PC);
143#endif
144 __set_app_type(1);
145 __getmainargs(&__argc, &__argv, &environ, 0, &start_info);
146 exit(main(__argc, __argv, environ));
147}
148
149#include <stdarg.h>
150#define size_t __SIZE_TYPE__
151int printf(const char *, ...);
152int _vsnprintf(char *, size_t, const char *, va_list);
153
154/* undefined on windows-11-arm64 */
155int vprintf(const char *format, va_list ap)
156{
157 char buf[1000];
158 _vsnprintf(buf, sizeof buf, format, ap);
159 return printf("%s", buf);
160}
161
162void __main() {} /* for gcc */
163void _pei386_runtime_relocator(void) {} /* for gcc */
164void __chkstk(unsigned n) {} /* for clang */
tests/tcctest.c+18−19
@@ -81,9 +81,6 @@ typedef __SIZE_TYPE__ uintptr_t; · 80 unmodified lines
81#include incname81#include incname
82#include stringify(funnyname)82#include stringify(funnyname)
83 83
84int puts(const char *s);
85void *alloca(size_t size);
86
87int fib(int n);84int fib(int n);
88void num(int n);85void num(int n);
89void forward_ref(void);86void forward_ref(void);
@@ -287,6 +284,7 @@ comment · 197 unmodified lines
287 284
288 printf("basefromheader %s\n", get_basefile_from_header());285 printf("basefromheader %s\n", get_basefile_from_header());
289 printf("base %s\n", __BASE_FILE__);286 printf("base %s\n", __BASE_FILE__);
287#if !(defined _WIN32 && CC_NAME == CC_clang)
290 {288 {
291 /* Some compilers (clang) prepend './' to __FILE__ from included289 /* Some compilers (clang) prepend './' to __FILE__ from included
292 files. */290 files. */
@@ -295,6 +293,8 @@ comment · 2 unmodified lines
295 fn += 2;293 fn += 2;
296 printf("filefromheader %s\n", fn);294 printf("filefromheader %s\n", fn);
297 }295 }
296#endif
297
298 printf("file %s\n", __FILE__);298 printf("file %s\n", __FILE__);
299 299
300 /* Check that funnily named include was in fact included */300 /* Check that funnily named include was in fact included */
@@ -1095,8 +1095,10 @@ void struct_test() · 794 unmodified lines
1095 sizeof(struct aligntest2), __alignof__(struct aligntest2));1095 sizeof(struct aligntest2), __alignof__(struct aligntest2));
1096 printf("aligntest3 sizeof=%d alignof=%d\n",1096 printf("aligntest3 sizeof=%d alignof=%d\n",
1097 sizeof(struct aligntest3), __alignof__(struct aligntest3));1097 sizeof(struct aligntest3), __alignof__(struct aligntest3));
1098#if !(defined _WIN32 && CC_NAME == CC_clang)
1098 printf("aligntest4 sizeof=%d alignof=%d\n",1099 printf("aligntest4 sizeof=%d alignof=%d\n",
1099 sizeof(struct aligntest4), __alignof__(struct aligntest4));1100 sizeof(struct aligntest4), __alignof__(struct aligntest4));
1101#endif
1100 printf("aligntest5 sizeof=%d alignof=%d\n",1102 printf("aligntest5 sizeof=%d alignof=%d\n",
1101 sizeof(struct aligntest5), __alignof__(struct aligntest5));1103 sizeof(struct aligntest5), __alignof__(struct aligntest5));
1102 printf("aligntest6 sizeof=%d alignof=%d\n",1104 printf("aligntest6 sizeof=%d alignof=%d\n",
@@ -1105,8 +1107,10 @@ void struct_test() · 2 unmodified lines
1105 sizeof(struct aligntest7), __alignof__(struct aligntest7));1107 sizeof(struct aligntest7), __alignof__(struct aligntest7));
1106 printf("aligntest8 sizeof=%d alignof=%d\n",1108 printf("aligntest8 sizeof=%d alignof=%d\n",
1107 sizeof(struct aligntest8), __alignof__(struct aligntest8));1109 sizeof(struct aligntest8), __alignof__(struct aligntest8));
1110#if !(defined _WIN32 && CC_NAME == CC_clang)
1108 printf("aligntest9 sizeof=%d alignof=%d\n",1111 printf("aligntest9 sizeof=%d alignof=%d\n",
1109 sizeof(struct aligntest9), __alignof__(struct aligntest9));1112 sizeof(struct aligntest9), __alignof__(struct aligntest9));
1113#endif
1110 printf("aligntest10 sizeof=%d alignof=%d\n",1114 printf("aligntest10 sizeof=%d alignof=%d\n",
1111 sizeof(struct aligntest10), __alignof__(struct aligntest10));1115 sizeof(struct aligntest10), __alignof__(struct aligntest10));
1112 printf("altest5 sizeof=%d alignof=%d\n",1116 printf("altest5 sizeof=%d alignof=%d\n",
@@ -1117,7 +1121,9 @@ void struct_test() · 4 unmodified lines
1117 sizeof(altest7), __alignof__(altest7));1121 sizeof(altest7), __alignof__(altest7));
1118 1122
1119 /* empty structures (GCC extension) */1123 /* empty structures (GCC extension) */
1124#if !(defined _WIN32 && CC_NAME == CC_clang)
1120 printf("sizeof(struct empty) = %d\n", sizeof(struct empty));1125 printf("sizeof(struct empty) = %d\n", sizeof(struct empty));
1126#endif
1121 printf("alignof(struct empty) = %d\n", __alignof__(struct empty));1127 printf("alignof(struct empty) = %d\n", __alignof__(struct empty));
1122 1128
1123 printf("Large: sizeof=%d\n", sizeof(ls));1129 printf("Large: sizeof=%d\n", sizeof(ls));
@@ -2176,15 +2182,6 @@ float strtof(const char *nptr, char **endptr); · 1052 unmodified lines
2176LONG_DOUBLE strtold(const char *nptr, char **endptr);2182LONG_DOUBLE strtold(const char *nptr, char **endptr);
2177#endif2183#endif
2178 2184
2179#if CC_NAME == CC_clang
2180/* In clang 0.0/0.0 is nan and not -nan.
2181 Also some older clang version do v=-v
2182 as v = -0 - v */
2183static char enable_nan_test = 0;
2184#else
2185static char enable_nan_test = 1;
2186#endif
2187
2188#define FTEST(prefix, typename, type, fmt)\2185#define FTEST(prefix, typename, type, fmt)\
2189void prefix ## cmp(type a, type b)\2186void prefix ## cmp(type a, type b)\
2190{\2187{\
@@ -2240,7 +2237,7 @@ void prefix ## fcast(type a)\ · 49 unmodified lines
2240 b = llia;\2237 b = llia;\
2241 printf("lltof: " fmt "\n", b);\2238 printf("lltof: " fmt "\n", b);\
2242 b = llua;\2239 b = llua;\
2243 printf("ulltof: " fmt "\n", b);\2240 if (CC_NAME != CC_clang) printf("ulltof: " fmt "\n", b);\
2244}\2241}\
2245\2242\
2246float prefix ## retf(type a) { return a; }\2243float prefix ## retf(type a) { return a; }\
@@ -2300,7 +2297,7 @@ void prefix ## test(void)\ · 53 unmodified lines
2300 prefix ## fcast(-2334.6);\2297 prefix ## fcast(-2334.6);\
2301 prefix ## call();\2298 prefix ## call();\
2302 prefix ## signed_zeros();\2299 prefix ## signed_zeros();\
2303 if (enable_nan_test) prefix ## nan();\2300 if (CC_NAME != CC_clang) prefix ## nan();\
2304}2301}
2305 2302
2306FTEST(f, float, float, "%f")2303FTEST(f, float, float, "%f")
@@ -2556,8 +2553,8 @@ void longlong_test(void) · 249 unmodified lines
2556 a = ia;2553 a = ia;
2557 b = ua;2554 b = ua;
2558 printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);2555 printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
2559 printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %Lx\n", 2556 printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " "XLONG_LONG_FORMAT"\n",
2560 (long long)1, 2557 (long long)1,
2561 (long long)-2,2558 (long long)-2,
2562 1LL,2559 1LL,
2563 0x1234567812345679);2560 0x1234567812345679);
@@ -2867,12 +2864,14 @@ void stdarg_test(void) · 303 unmodified lines
2867 stdarg_for_struct(bob, bob2, bob3, bob4, bob, bob, bob.profile);2864 stdarg_for_struct(bob, bob2, bob3, bob4, bob, bob, bob.profile);
2868 stdarg_for_libc("stdarg_for_libc: %s %.2f %d\n", "string", 1.23, 456);2865 stdarg_for_libc("stdarg_for_libc: %s %.2f %d\n", "string", 1.23, 456);
2869 stdarg_syntax(1, 17);2866 stdarg_syntax(1, 17);
2867#if !(defined _WIN32 && CC_NAME == CC_clang) /* broken clang */
2870 stdarg_double_struct(6,-1,pts[0],pts[1],pts[2],pts[3],pts[4],pts[5]);2868 stdarg_double_struct(6,-1,pts[0],pts[1],pts[2],pts[3],pts[4],pts[5]);
2871 stdarg_double_struct(7,1,pts[0],-1.0,pts[1],pts[2],pts[3],pts[4],pts[5]);2869 stdarg_double_struct(7,1,pts[0],-1.0,pts[1],pts[2],pts[3],pts[4],pts[5]);
2872 stdarg_double_struct(7,2,pts[0],pts[1],-1.0,pts[2],pts[3],pts[4],pts[5]);2870 stdarg_double_struct(7,2,pts[0],pts[1],-1.0,pts[2],pts[3],pts[4],pts[5]);
2873 stdarg_double_struct(7,3,pts[0],pts[1],pts[2],-1.0,pts[3],pts[4],pts[5]);2871 stdarg_double_struct(7,3,pts[0],pts[1],pts[2],-1.0,pts[3],pts[4],pts[5]);
2874 stdarg_double_struct(7,4,pts[0],pts[1],pts[2],pts[3],-1.0,pts[4],pts[5]);2872 stdarg_double_struct(7,4,pts[0],pts[1],pts[2],pts[3],-1.0,pts[4],pts[5]);
2875 stdarg_double_struct(7,5,pts[0],pts[1],pts[2],pts[3],pts[4],-1.0,pts[5]);2873 stdarg_double_struct(7,5,pts[0],pts[1],pts[2],pts[3],pts[4],-1.0,pts[5]);
2874#endif
2876}2875}
2877 2876
2878int reltab[3] = { 1, 2, 3 };2877int reltab[3] = { 1, 2, 3 };
@@ -3289,7 +3288,7 @@ void local_label_test(void) · 410 unmodified lines
3289}3288}
3290 3289
3291/* inline assembler test */3290/* inline assembler test */
3292#if defined(__i386__) || defined(__x86_64__)3291#if (defined(__i386__) || defined(__x86_64__)) && !(defined _WIN32 && CC_NAME == CC_clang)
3293 3292
3294typedef __SIZE_TYPE__ word;3293typedef __SIZE_TYPE__ word;
3295 3294
@@ -3551,8 +3550,8 @@ void asm_local_label_diff (void) · 255 unmodified lines
3551{3550{
3552 printf ("asm_local_label_diff: %d %d\n", alld_stuff[0], alld_stuff[1]);3551 printf ("asm_local_label_diff: %d %d\n", alld_stuff[0], alld_stuff[1]);
3553}3552}
3554#endif3553#endif //!__APPLE__
3555#endif3554#endif //!_WIN32
3556 3555
3557/* This checks that static local variables are available from assembler. */3556/* This checks that static local variables are available from assembler. */
3558void asm_local_statics (void)3557void asm_local_statics (void)
tests/test-win32.bat+74−0
@@ -0,0 +1,74 @@
1@echo off
2setlocal
3set CC=gcc
4set TESTS=
5if "%1"=="/?" goto :usage
6goto :p0
7
8:usage
9echo usage: test-win32.bat [options...] [tests...]
10echo options:
11echo -c compiler reference compiler (gcc or clang)
12echo -p path prepend path to PATH
13echo tests tests to run (default all)
14echo requires: make, gcc/clang, and sh in the PATH
15exit /B 1
16
17:p2
18shift
19:p1
20shift
21:p0
22if "%1"=="-c" set CC=%2&&goto p2
23if "%1"=="-p" set PATH=%2;%PATH%&&goto p2
24if not "%1"=="" set TESTS=%TESTS% %1&&goto p1
25if "%TESTS%"=="" set TESTS=all -k
26
27set PATH=%CD%\..\win32;%PATH%
28
29for /f "delims=-" %%a in ('tcc.exe -dumpmachine') do set ARCH=%%a
30set ARCH=%ARCH:aarch=arm%
31set MACH=%ARCH:i386=x86%
32set MACH=%MACH:x86_64=amd64%
33rem echo ARCH:%ARCH% MACHINE:%MACH%
34
35set CRTLIB=c:/windows/system32/msvcrt.dll
36set LIBTCC=libtcc.dll
37set LGCC=-lgcc
38if %CC%==gcc goto :c2
39
40set CRTLIB=msvcrt.lib
41set LIBTCC=libtcc.lib
42set LGCC=
43if exist %CRTLIB% goto :c3
44tcc -impdef msvcrt.dll
45lib >nul /def:msvcrt.def /out:%CRTLIB% /machine:%MACH%
46:c2
47if not exist %CRTLIB% echo test-win32.bat: error: %CRTLIB% not found&&exit /b 1
48:c3
49
50set REF_LINK=-nostdlib msvcrt_start.c %LGCC% -lkernel32 %CRTLIB%
51set CFG_MAK=..\config.mak
52set CFG_H=..\config.h
53
54echo>>%CFG_H% #define CC_NAME CC_%CC%
55echo>>%CFG_H% #define GCC_MAJOR 15
56
57if exist %CFG_MAK% del %CFG_MAK%
58echo>>%CFG_MAK% CC = %CC%.exe
59echo>>%CFG_MAK% CC_NAME = %CC%
60echo>>%CFG_MAK% ARCH = %ARCH%
61echo>>%CFG_MAK% CFLAGS = -Wall -O0
62echo>>%CFG_MAK% LDFLAGS =
63echo>>%CFG_MAK% LIBSUF = .lib
64echo>>%CFG_MAK% prefix = $(TOP)/bin
65echo>>%CFG_MAK% EXESUF = .exe
66echo>>%CFG_MAK% DLLSUF = .dll
67echo>>%CFG_MAK% TARGETOS = WIN32
68echo>>%CFG_MAK% CONFIG_WIN32 = yes
69echo>>%CFG_MAK% TOPSRC = $(TOP)
70echo>>%CFG_MAK% SHELL = sh
71echo>>%CFG_MAK% test.ref: CFLAGS += %REF_LINK%
72
73set GMAKE=make
74%GMAKE% TCC_LOCAL=tcc.exe LIBTCC=win32/%LIBTCC% %TESTS%
tests/tests2/Makefile+7−16
@@ -48,26 +48,16 @@ ifeq (-$(CONFIG_WIN32)-,-yes-) · 47 unmodified lines
48 SKIP += 117_builtins.test # win32 port doesn't define __builtins48 SKIP += 117_builtins.test # win32 port doesn't define __builtins
49 SKIP += 124_atomic_counter.test # No pthread support49 SKIP += 124_atomic_counter.test # No pthread support
50endif50endif
51ifneq (,$(filter arm% riscv%,$(ARCH)))
52 SKIP += 85_asm-outside-function.test
53 SKIP += 98_al_ax_extend.test
54 SKIP += 99_fastcall.test
55 SKIP += 127_asm_goto.test
56endif
57ifeq (,$(filter arm64 aarch64,$(ARCH)))
58 SKIP += 138_arm64_encoding.test
59 SKIP += 139_arm64_errors.test
60endif
61ifneq (,$(findstring win32,$(CROSS_TARGET)))
62 SKIP += 106_versym.test
63 SKIP += 114_bound_signal.test
64 SKIP += 124_atomic_counter.test
65endif
66ifneq (,$(filter OpenBSD FreeBSD NetBSD,$(TARGETOS)))51ifneq (,$(filter OpenBSD FreeBSD NetBSD,$(TARGETOS)))
67 SKIP += 106_versym.test # no pthread_condattr_setpshared52 SKIP += 106_versym.test # no pthread_condattr_setpshared
68 SKIP += 114_bound_signal.test # libc problem signal/fork53 SKIP += 114_bound_signal.test # libc problem signal/fork
69 SKIP += 116_bound_setjmp2.test # No TLS_FUNC/TLS_VAR in bcheck.c54 SKIP += 116_bound_setjmp2.test # No TLS_FUNC/TLS_VAR in bcheck.c
70endif55endif
56ifeq (,$(filter arm64 aarch64,$(ARCH)))
57 SKIP += 138_arm64_encoding.test
58 SKIP += 139_arm64_errors.test
59 SKIP += 140_arm64_extasm.test
60endif
71 61
72# Some tests might need arguments62# Some tests might need arguments
73ARGS =63ARGS =
@@ -88,8 +78,8 @@ endif · 14 unmodified lines
88 78
89# These tests run several snippets from the same file one by one79# These tests run several snippets from the same file one by one
9060_errors_and_warnings.test : FLAGS += -dt8060_errors_and_warnings.test : FLAGS += -dt
91139_arm64_errors.test : FLAGS += -dt
9296_nodata_wanted.test : FLAGS += -dt8196_nodata_wanted.test : FLAGS += -dt
82139_arm64_errors.test : FLAGS += -dt
93 83
94# Always generate certain .expects (don't put these in the GIT),84# Always generate certain .expects (don't put these in the GIT),
95GEN-ALWAYS =85GEN-ALWAYS =
@@ -141,6 +131,7 @@ endif · 45 unmodified lines
141126_bound_global.test: NORUN = true131126_bound_global.test: NORUN = true
142128_run_atexit.test: FLAGS += -dt132128_run_atexit.test: FLAGS += -dt
143132_bound_test.test: FLAGS += -b133132_bound_test.test: FLAGS += -b
134140_arm64_extasm.test: GEN = $(GEN-TCC)
144 135
145# Filter source directory in warnings/errors (out-of-tree builds)136# Filter source directory in warnings/errors (out-of-tree builds)
146FILTER = 2>&1 | sed -e 's,$(SRC)/,,g'137FILTER = 2>&1 | sed -e 's,$(SRC)/,,g'
win32/build-tcc.bat+66−73
@@ -5,13 +5,15 @@ · 4 unmodified lines
5@echo off5@echo off
6setlocal6setlocal
7if (%1)==(-clean) goto :cleanup7if (%1)==(-clean) goto :cleanup
8set CC=gcc8set CC=gcc -O2 -Wall
9set /p VERSION= < ..\VERSION9set /p VERSION= < ..\VERSION
10set TCCDIR=10set TCCDIR=
11set BINDIR=11set BINDIR=
12set DOC=no12set DOC=no
13set XCC=no13set TX=
14set SELF=%~nx0
14goto :a015goto :a0
16
15:a217:a2
16shift18shift
17:a319:a3
@@ -27,20 +29,22 @@ if (%1)==(-v) set VERSION=%~2&& goto :a2 · 9 unmodified lines
27if (%1)==(-i) set TCCDIR=%2&& goto :a229if (%1)==(-i) set TCCDIR=%2&& goto :a2
28if (%1)==(-b) set BINDIR=%2&& goto :a230if (%1)==(-b) set BINDIR=%2&& goto :a2
29if (%1)==(-d) set DOC=yes&& goto :a331if (%1)==(-d) set DOC=yes&& goto :a3
30if (%1)==(-x) set XCC=yes&& goto :a332if (%1)==(-x) set TX=%2&& goto :a2
31if (%1)==() goto :p133if (%1)==() goto :p1
34
32:usage35:usage
33echo usage: build-tcc.bat [ options ... ]36echo usage: build-tcc.bat [ options ... ]
34echo options:37echo options:
35echo -c prog use prog (gcc/tcc/cl) to compile tcc38echo -c prog use prog (gcc/tcc/cl) to compile tcc
36echo -c "prog options" use prog with options to compile tcc39echo -c "prog options" use prog with options to compile tcc
37echo -t 32/64 force 32/64 bit default target40echo -t target set target
41echo -x target build tcc cross-compiler for target
38echo -v "version" set tcc version42echo -v "version" set tcc version
39echo -i tccdir install tcc into tccdir43echo -i tccdir install tcc into tccdir
40echo -b bindir but install tcc.exe and libtcc.dll into bindir44echo -b bindir but install tcc.exe and libtcc.dll into bindir
41echo -d create tcc-doc.html too (needs makeinfo)45echo -d create tcc-doc.html too (needs makeinfo)
42echo -x build the cross compiler too
43echo -clean delete all previously produced files and directories46echo -clean delete all previously produced files and directories
47echo supported targets i386 x86_64 arm64
44exit /B 148exit /B 1
45 49
46@rem ------------------------------------------------------50@rem ------------------------------------------------------
@@ -65,6 +69,7 @@ exit /B 0 · 18 unmodified lines
65if exist %1 rmdir /Q/S %1 && %LOG% %169if exist %1 rmdir /Q/S %1 && %LOG% %1
66exit /B 070exit /B 0
67 71
72@rem ------------------------------------------------------
68:cl73:cl
69@echo off74@echo off
70set CMD=cl75set CMD=cl
@@ -84,36 +89,19 @@ echo on · 13 unmodified lines
84@rem main program89@rem main program
85 90
86:p191:p1
87if not %T%_==_ goto :p292if not _%TX%_==__ set T=%TX%&&set TX=%TX%-win32-
88set T=3293if _%T%_%PROCESSOR_ARCHITECTURE%_==__x86_ set T=i386
89if %PROCESSOR_ARCHITECTURE%_==AMD64_ set T=6494if _%T%_%PROCESSOR_ARCHITECTURE%_==__ARM64_ set T=arm64
90if %PROCESSOR_ARCHITEW6432%_==AMD64_ set T=6495if _%T%_==__ set T=x86_64
91:p296if %T%==i386 set D=-DTCC_TARGET_PE -DTCC_TARGET_I386
92if "%CC:~-3%"=="gcc" set CC=%CC% -O2 -s -static97if %T%==x86_64 set D=-DTCC_TARGET_PE -DTCC_TARGET_X86_64
93if (%BINDIR%)==() set BINDIR=%TCCDIR%98if %T%==arm64 set D=-DTCC_TARGET_PE -DTCC_TARGET_ARM64
94 99if "%D%"=="" echo %SELF%: error: unknown target '%T%'&&exit /B 1
95set D32=-DTCC_TARGET_PE -DTCC_TARGET_I386100
96set D64=-DTCC_TARGET_PE -DTCC_TARGET_X86_64101@if (%CC:~0,3%)==(gcc) set CC=%CC% -s -static
97set P32=i386-win32102@if (%BINDIR%)==() set BINDIR=%TCCDIR%
98set P64=x86_64-win32103
99 104:git_hash
100if %T%==64 goto :t64
101set D=%D32%
102set P=%P32%
103set DX=%D64%
104set PX=%P64%
105set TX=64
106goto :p3
107
108:t64
109set D=%D64%
110set P=%P64%
111set DX=%D32%
112set PX=%P32%
113set TX=32
114goto :p3
115
116:p3
117git.exe --version 2>nul105git.exe --version 2>nul
118if not %ERRORLEVEL%==0 goto :git_done106if not %ERRORLEVEL%==0 goto :git_done
119for /f %%b in ('git.exe rev-parse --abbrev-ref HEAD') do set GITHASH=%%b107for /f %%b in ('git.exe rev-parse --abbrev-ref HEAD') do set GITHASH=%%b
@@ -125,34 +113,37 @@ if %ERRORLEVEL%==1 set GITHASH=%GITHASH%* · 5 unmodified lines
125 113
126:config.h114:config.h
127echo>..\config.h #define TCC_VERSION "%VERSION%"115echo>..\config.h #define TCC_VERSION "%VERSION%"
128if not (%GITHASH%)==() echo>> ..\config.h #define TCC_GITHASH "%GITHASH%"116@if not "%GITHASH%"=="" echo>>..\config.h #define TCC_GITHASH "%GITHASH%"
129@if not (%BINDIR%)==(%TCCDIR%) echo>> ..\config.h #define CONFIG_TCCDIR "%TCCDIR:\=/%"117@if not _%BINDIR%_==_%TCCDIR%_ echo>>..\config.h #define CONFIG_TCCDIR "%TCCDIR:\=/%"
130if %TX%==64 echo>> ..\config.h #ifdef TCC_TARGET_X86_64118@if not _%TX%_==__ @echo>>..\config.h #define CONFIG_TCC_CROSSPREFIX "%TX%"
131if %TX%==32 echo>> ..\config.h #ifdef TCC_TARGET_I386
132echo>> ..\config.h #define CONFIG_TCC_CROSSPREFIX "%PX%-"
133echo>> ..\config.h #endif
134 119
135@rem echo>> ..\config.h #define CONFIG_TCC_PREDEFS 1120@rem echo>> ..\config.h #define CONFIG_TCC_PREDEFS 1
136@rem %CC% -DC2STR ..\conftest.c -o c2str.exe121@rem %CC% -DC2STR ..\conftest.c -o c2str.exe
137@rem .\c2str.exe ../include/tccdefs.h ../tccdefs_.h122@rem .\c2str.exe ../include/tccdefs.h ../tccdefs_.h
138 123
139for %%f in (*tcc.exe *tcc.dll) do @del %%f124@if not _%TX%_==__ goto :tcc_cross
140 125@if not _%TCC_C%_==__ goto :tcc_only
141@if _%TCC_C%_==__ goto compiler_2parts
142@rem if TCC_C was defined then build only tcc.exe
143%CC% -o tcc.exe %TCC_C% %D%
144@if errorlevel 1 goto :the_end
145@goto :compiler_done
146 126
147:compiler_2parts
148@if _%LIBTCC_C%_==__ set LIBTCC_C=..\libtcc.c127@if _%LIBTCC_C%_==__ set LIBTCC_C=..\libtcc.c
128@set IMPLIB=libtcc.dll
129@if "%CC:~0,5%"=="clang" set IMPLIB=libtcc.lib
130
149%CC% -o libtcc.dll -shared %LIBTCC_C% %D% -DLIBTCC_AS_DLL131%CC% -o libtcc.dll -shared %LIBTCC_C% %D% -DLIBTCC_AS_DLL
150@if errorlevel 1 goto :the_end132@if errorlevel 1 goto :the_end
151%CC% -o tcc.exe ..\tcc.c libtcc.dll %D% -DONE_SOURCE"=0"133%CC% -o tcc.exe ..\tcc.c %IMPLIB% %D% -DONE_SOURCE"=0"
152@if errorlevel 1 goto :the_end134@if errorlevel 1 goto :the_end
153if not _%XCC%_==_yes_ goto :compiler_done135@goto :compiler_done
154%CC% -o %PX%-tcc.exe ..\tcc.c %DX%136
137:tcc_only
138%CC% -o tcc.exe %TCC_C% %D%
139@if errorlevel 1 goto :the_end
140@goto :compiler_done
141
142:tcc_cross
143%CC% -o %TX%tcc.exe ..\tcc.c %D%
155@if errorlevel 1 goto :the_end144@if errorlevel 1 goto :the_end
145@goto :compiler_done
146
156:compiler_done147:compiler_done
157@if (%EXES_ONLY%)==(yes) goto :files_done148@if (%EXES_ONLY%)==(yes) goto :files_done
158 149
@@ -168,8 +159,7 @@ if exist libtcc.dll .\tcc -impdef libtcc.dll -o libtcc\libtcc.def · 9 unmodified lines
168@if errorlevel 1 goto :the_end159@if errorlevel 1 goto :the_end
169 160
170:lib161:lib
171call :make_lib %T% || goto :the_end162@call :make_lib %TX% || goto :the_end
172@if exist %PX%-tcc.exe call :make_lib %TX% %PX%- || goto :the_end
173 163
174:tcc-doc.html164:tcc-doc.html
175@if not (%DOC%)==(yes) goto :doc-done165@if not (%DOC%)==(yes) goto :doc-done
@@ -193,23 +183,26 @@ for %%f in (include examples libtcc doc) do @xcopy>nul /s/i/q/y %%f %TCCDIR%\%%f · 17 unmodified lines
193exit /B %ERRORLEVEL%183exit /B %ERRORLEVEL%
194 184
195:make_lib185:make_lib
196.\tcc -B. -m%1 -c ../lib/libtcc1.c186@set LIBTCC1=libtcc1
197.\tcc -B. -m%1 -c lib/crt1.c187@if _%1_==_arm64_ set LIBTCC1=lib-arm64
198.\tcc -B. -m%1 -c lib/crt1w.c188.\%1tcc -B. -c ../lib/%LIBTCC1%.c
199.\tcc -B. -m%1 -c lib/wincrt1.c189.\%1tcc -B. -c lib/crt1.c
200.\tcc -B. -m%1 -c lib/wincrt1w.c190.\%1tcc -B. -c lib/crt1w.c
201.\tcc -B. -m%1 -c lib/dllcrt1.c191.\%1tcc -B. -c lib/wincrt1.c
202.\tcc -B. -m%1 -c lib/dllmain.c192.\%1tcc -B. -c lib/wincrt1w.c
203.\tcc -B. -m%1 -c lib/chkstk.S193.\%1tcc -B. -c lib/dllcrt1.c
204.\tcc -B. -m%1 -c ../lib/alloca.S194.\%1tcc -B. -c lib/dllmain.c
205.\tcc -B. -m%1 -c ../lib/alloca-bt.S195.\%1tcc -B. -c lib/winex.c
206.\tcc -B. -m%1 -c ../lib/stdatomic.c196.\%1tcc -B. -c lib/chkstk.S
207.\tcc -B. -m%1 -c ../lib/atomic.S197.\%1tcc -B. -c ../lib/alloca.S
208.\tcc -B. -m%1 -c ../lib/builtin.c198.\%1tcc -B. -c ../lib/alloca-bt.S
209.\tcc -B. -m%1 -ar lib/%2libtcc1.a libtcc1.o crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o chkstk.o alloca.o alloca-bt.o stdatomic.o atomic.o builtin.o199.\%1tcc -B. -c ../lib/stdatomic.c
210.\tcc -B. -m%1 -c ../lib/bcheck.c -o lib/%2bcheck.o -bt -I..200.\%1tcc -B. -c ../lib/atomic.S
211.\tcc -B. -m%1 -c ../lib/bt-exe.c -o lib/%2bt-exe.o201.\%1tcc -B. -c ../lib/builtin.c
212.\tcc -B. -m%1 -c ../lib/bt-log.c -o lib/%2bt-log.o202.\%1tcc -ar lib/%1libtcc1.a %LIBTCC1%.o crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o winex.o chkstk.o alloca.o alloca-bt.o stdatomic.o atomic.o builtin.o
213.\tcc -B. -m%1 -c ../lib/bt-dll.c -o lib/%2bt-dll.o203.\%1tcc -B. -c ../lib/bcheck.c -o lib/%1bcheck.o -bt -I..
214.\tcc -B. -m%1 -c ../lib/runmain.c -o lib/%2runmain.o204.\%1tcc -B. -c ../lib/bt-exe.c -o lib/%1bt-exe.o
205.\%1tcc -B. -c ../lib/bt-log.c -o lib/%1bt-log.o
206.\%1tcc -B. -c ../lib/bt-dll.c -o lib/%1bt-dll.o
207.\%1tcc -B. -c ../lib/runmain.c -o lib/%1runmain.o
215exit /B %ERRORLEVEL%208exit /B %ERRORLEVEL%
win32/include/_mingw.h+1−7
@@ -70,20 +70,14 @@ · 69 unmodified lines
70 70
71#ifdef _WIN6471#ifdef _WIN64
72#define __stdcall72#define __stdcall
73#if defined(__aarch64__) || defined(_M_ARM64) || defined(_ARM64_)73#if defined(__aarch64__)
74#ifndef _M_ARM64
75#define _M_ARM64 174#define _M_ARM64 1
76#endif
77#ifndef _ARM64_
78#define _ARM64_ 175#define _ARM64_ 1
79#endif
80#else76#else
81#define _AMD64_ 177#define _AMD64_ 1
82#define __x86_64 178#define __x86_64 1
83#define _M_X64 100 /* Visual Studio */79#define _M_X64 100 /* Visual Studio */
84#define _M_AMD64 100 /* Visual Studio */80#define _M_AMD64 100 /* Visual Studio */
85#define USE_MINGW_SETJMP_TWO_ARGS
86#define mingw_getsp tinyc_getbp
87#endif81#endif
88#else82#else
89#define __stdcall __attribute__((__stdcall__))83#define __stdcall __attribute__((__stdcall__))
win32/include/setjmp.h+11−21
@@ -170,7 +170,6 @@ extern "C" { · 169 unmodified lines
170 double D[8];170 double D[8];
171 } _JUMP_BUFFER;171 } _JUMP_BUFFER;
172#else172#else
173
174#define _JBLEN 1173#define _JBLEN 1
175#define _JBTYPE int174#define _JBTYPE int
176#endif175#endif
@@ -179,31 +178,22 @@ extern "C" { · 2 unmodified lines
179#define _JMP_BUF_DEFINED178#define _JMP_BUF_DEFINED
180#endif179#endif
181 180
182 void * __cdecl __attribute__ ((__nothrow__)) mingw_getsp(void);181#pragma pack(pop)
183 182
184#ifdef USE_MINGW_SETJMP_TWO_ARGS183#if defined __aarch64__
185#ifndef _INC_SETJMPEX184 int _setjmpex(jmp_buf _Buf, void *frame);
186#define setjmp(BUF) _setjmp((BUF),mingw_getsp())185 #define setjmp(BUF) _setjmpex((BUF), (char*)__builtin_frame_address(0) + 224)
187 int __cdecl __attribute__ ((__nothrow__)) _setjmp(jmp_buf _Buf,void *_Ctx);186#elif defined __x86_64__
188#else187 int _setjmp(jmp_buf _Buf, void *frame);
189#undef setjmp188 #define setjmp(BUF) _setjmp((BUF), __builtin_frame_address(0))
190#define setjmp(BUF) _setjmpex((BUF),mingw_getsp())189#else /* __i386__ */
191#define setjmpex(BUF) _setjmpex((BUF),mingw_getsp())190 int _setjmp(jmp_buf _Buf);
192 int __cdecl __attribute__ ((__nothrow__)) _setjmpex(jmp_buf _Buf,void *_Ctx);191 #define setjmp _setjmp
193#endif
194#else
195#ifndef _INC_SETJMPEX
196#define setjmp _setjmp
197#endif
198 int __cdecl __attribute__ ((__nothrow__)) setjmp(jmp_buf _Buf);
199#endif192#endif
200 193
201 __declspec(noreturn) __attribute__ ((__nothrow__)) void __cdecl ms_longjmp(jmp_buf _Buf,int _Value)/* throw(...)*/;194__declspec(noreturn) void longjmp(jmp_buf _Buf,int _Value);
202 __declspec(noreturn) __attribute__ ((__nothrow__)) void __cdecl longjmp(jmp_buf _Buf,int _Value);
203 195
204#ifdef __cplusplus196#ifdef __cplusplus
205}197}
206#endif198#endif
207
208#pragma pack(pop)
209#endif199#endif
win32/include/stdlib.h+15−0
@@ -207,6 +207,21 @@ extern "C" { · 206 unmodified lines
207#endif207#endif
208#endif208#endif
209#endif209#endif
210
211#if defined __aarch64__
212/* something does not work using those from msvcrt.dll */
213# undef __argc
214# undef __argv
215# undef __wargv
216# undef _wenviron
217# undef _environ
218extern int __argc;
219extern char **__argv;
220extern wchar_t **__wargv;
221extern char **_environ;
222extern wchar_t **_wenviron;
223#endif
224
210#ifndef _pgmptr225#ifndef _pgmptr
211#ifdef _MSVCRT_226#ifdef _MSVCRT_
212 extern char *_pgmptr;227 extern char *_pgmptr;
win32/include/winapi/winnt.h+13−48
@@ -47,9 +47,6 @@ extern "C" { · 46 unmodified lines
47#endif47#endif
48#endif48#endif
49 49
50#if !defined(I_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(__aarch64__) && !defined(_ARM64_)
51#define _ARM64_
52#endif
53 50
54#ifdef _WIN6451#ifdef _WIN64
55#define MAX_NATURAL_ALIGNMENT sizeof(ULONGLONG)52#define MAX_NATURAL_ALIGNMENT sizeof(ULONGLONG)
@@ -832,8 +829,6 @@ typedef DWORD LCID; · 776 unmodified lines
832 typedef ULONG_PTR KSPIN_LOCK;829 typedef ULONG_PTR KSPIN_LOCK;
833 typedef KSPIN_LOCK *PKSPIN_LOCK;830 typedef KSPIN_LOCK *PKSPIN_LOCK;
834 831
835#if defined(_AMD64_) || defined(_ARM64_)
836
837#if defined(__x86_64) && !defined(RC_INVOKED)832#if defined(__x86_64) && !defined(RC_INVOKED)
838 833
839#ifdef __cplusplus834#ifdef __cplusplus
@@ -1285,7 +1280,6 @@ typedef DWORD LCID; · 445 unmodified lines
1285#ifdef __cplusplus1280#ifdef __cplusplus
1286 }1281 }
1287#endif1282#endif
1288#endif
1289 1283
1290#define EXCEPTION_READ_FAULT 01284#define EXCEPTION_READ_FAULT 0
1291#define EXCEPTION_WRITE_FAULT 11285#define EXCEPTION_WRITE_FAULT 1
@@ -1339,7 +1333,6 @@ typedef DWORD LCID; · 47 unmodified lines
1339 1333
1340#define LEGACY_SAVE_AREA_LENGTH sizeof(XMM_SAVE_AREA32)1334#define LEGACY_SAVE_AREA_LENGTH sizeof(XMM_SAVE_AREA32)
1341 1335
1342#if defined(__x86_64) || defined(_AMD64_)
1343 typedef struct DECLSPEC_ALIGN(16) _CONTEXT {1336 typedef struct DECLSPEC_ALIGN(16) _CONTEXT {
1344 DWORD64 P1Home;1337 DWORD64 P1Home;
1345 DWORD64 P2Home;1338 DWORD64 P2Home;
@@ -1411,7 +1404,6 @@ typedef DWORD LCID; · 65 unmodified lines
1411 DWORD64 LastExceptionToRip;1404 DWORD64 LastExceptionToRip;
1412 DWORD64 LastExceptionFromRip;1405 DWORD64 LastExceptionFromRip;
1413 } CONTEXT,*PCONTEXT;1406 } CONTEXT,*PCONTEXT;
1414#endif /* defined(__x86_64) || defined(_AMD64_) */
1415 1407
1416#define RUNTIME_FUNCTION_INDIRECT 0x11408#define RUNTIME_FUNCTION_INDIRECT 0x1
1417 1409
@@ -1422,41 +1414,24 @@ typedef DWORD LCID; · 4 unmodified lines
1422 } RUNTIME_FUNCTION,*PRUNTIME_FUNCTION;1414 } RUNTIME_FUNCTION,*PRUNTIME_FUNCTION;
1423 1415
1424 typedef PRUNTIME_FUNCTION (*PGET_RUNTIME_FUNCTION_CALLBACK)(DWORD64 ControlPc,PVOID Context);1416 typedef PRUNTIME_FUNCTION (*PGET_RUNTIME_FUNCTION_CALLBACK)(DWORD64 ControlPc,PVOID Context);
1417 typedef DWORD (*POUT_OF_PROCESS_FUNCTION_TABLE_CALLBACK)(HANDLE Process,PVOID TableAddress,PDWORD Entries,PRUNTIME_FUNCTION *Functions);
1425 1418
1426#if defined(_ARM64_) || defined(__aarch64__)1419#define OUT_OF_PROCESS_FUNCTION_TABLE_CALLBACK_EXPORT_NAME "OutOfProcessFunctionTableCallback"
1420#endif /* defined(__x86_64) && !defined(RC_INVOKED) */
1421
1422#if defined(_ARM64_)
1427 1423
1428/* ARM64 Context Definition */1424/* ARM64 Context Definition */
1429#define CONTEXT_ARM64 0x004000001425#define CONTEXT_ARM64 0x00400000
1430
1431#ifndef CONTEXT_CONTROL
1432#define CONTEXT_CONTROL (CONTEXT_ARM64 | 0x00000001L)1426#define CONTEXT_CONTROL (CONTEXT_ARM64 | 0x00000001L)
1433#endif
1434#ifndef CONTEXT_INTEGER
1435#define CONTEXT_INTEGER (CONTEXT_ARM64 | 0x00000002L)1427#define CONTEXT_INTEGER (CONTEXT_ARM64 | 0x00000002L)
1436#endif
1437#ifndef CONTEXT_FLOATING_POINT
1438#define CONTEXT_FLOATING_POINT (CONTEXT_ARM64 | 0x00000004L)1428#define CONTEXT_FLOATING_POINT (CONTEXT_ARM64 | 0x00000004L)
1439#endif
1440#ifndef CONTEXT_DEBUG
1441#define CONTEXT_DEBUG (CONTEXT_ARM64 | 0x00000008L)1429#define CONTEXT_DEBUG (CONTEXT_ARM64 | 0x00000008L)
1442#endif
1443
1444#ifndef CONTEXT_FULL
1445#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT)1430#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT)
1446#endif
1447#ifndef CONTEXT_ALL
1448#define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG)1431#define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG)
1449#endif
1450
1451#ifndef ARM64_MAX_BREAKPOINTS
1452#define ARM64_MAX_BREAKPOINTS 81432#define ARM64_MAX_BREAKPOINTS 8
1453#endif
1454#ifndef ARM64_MAX_WATCHPOINTS
1455#define ARM64_MAX_WATCHPOINTS 21433#define ARM64_MAX_WATCHPOINTS 2
1456#endif
1457 1434
1458#ifndef _ARM64_NT_NEON128_DECLARED
1459#define _ARM64_NT_NEON128_DECLARED
1460 typedef union _ARM64_NT_NEON128 {1435 typedef union _ARM64_NT_NEON128 {
1461 struct {1436 struct {
1462 ULONGLONG Low;1437 ULONGLONG Low;
@@ -1467,10 +1442,7 @@ typedef DWORD LCID; · 4 unmodified lines
1467 WORD H[8];1442 WORD H[8];
1468 BYTE B[16];1443 BYTE B[16];
1469 } ARM64_NT_NEON128,*PARM64_NT_NEON128;1444 } ARM64_NT_NEON128,*PARM64_NT_NEON128;
1470#endif
1471 1445
1472#ifndef _ARM64_CONTEXT_DECLARED
1473#define _ARM64_CONTEXT_DECLARED
1474 typedef struct DECLSPEC_ALIGN(16) _ARM64_NT_CONTEXT {1446 typedef struct DECLSPEC_ALIGN(16) _ARM64_NT_CONTEXT {
1475 ULONG ContextFlags;1447 ULONG ContextFlags;
1476 ULONG Cpsr;1448 ULONG Cpsr;
@@ -1522,27 +1494,20 @@ typedef DWORD LCID; · 45 unmodified lines
1522 } ARM64_NT_CONTEXT,*PARM64_NT_CONTEXT;1494 } ARM64_NT_CONTEXT,*PARM64_NT_CONTEXT;
1523 1495
1524 C_ASSERT(sizeof(ARM64_NT_CONTEXT) == 0x390);1496 C_ASSERT(sizeof(ARM64_NT_CONTEXT) == 0x390);
1525 C_ASSERT(offsetof(ARM64_NT_CONTEXT, ContextFlags) == 0x000);
1526 C_ASSERT(offsetof(ARM64_NT_CONTEXT, X) == 0x008);
1527 C_ASSERT(offsetof(ARM64_NT_CONTEXT, Fp) == 0x0f0);
1528 C_ASSERT(offsetof(ARM64_NT_CONTEXT, Lr) == 0x0f8);
1529 C_ASSERT(offsetof(ARM64_NT_CONTEXT, Sp) == 0x100);
1530 C_ASSERT(offsetof(ARM64_NT_CONTEXT, Pc) == 0x108);
1531 C_ASSERT(offsetof(ARM64_NT_CONTEXT, V) == 0x110);
1532 C_ASSERT(sizeof(((ARM64_NT_CONTEXT *)0)->V[0]) == 16);
1533 C_ASSERT(offsetof(ARM64_NT_CONTEXT, Fpcr) == 0x310);
1534 C_ASSERT(offsetof(ARM64_NT_CONTEXT, Fpsr) == 0x314);
1535 C_ASSERT(offsetof(ARM64_NT_CONTEXT, Bvr) == 0x338);
1536 C_ASSERT(offsetof(ARM64_NT_CONTEXT, Wvr) == 0x380);
1537#endif
1538 1497
1539 typedef ARM64_NT_CONTEXT CONTEXT,*PCONTEXT;1498 typedef ARM64_NT_CONTEXT CONTEXT,*PCONTEXT;
1540 1499
1541#endif /* _ARM64_ || __aarch64__ */1500 typedef struct _RUNTIME_FUNCTION {
1501 DWORD BeginAddress;
1502 DWORD UnwindData;
1503 } RUNTIME_FUNCTION,*PRUNTIME_FUNCTION;
1504
1505 typedef PRUNTIME_FUNCTION (*PGET_RUNTIME_FUNCTION_CALLBACK)(DWORD64 ControlPc,PVOID Context);
1542 typedef DWORD (*POUT_OF_PROCESS_FUNCTION_TABLE_CALLBACK)(HANDLE Process,PVOID TableAddress,PDWORD Entries,PRUNTIME_FUNCTION *Functions);1506 typedef DWORD (*POUT_OF_PROCESS_FUNCTION_TABLE_CALLBACK)(HANDLE Process,PVOID TableAddress,PDWORD Entries,PRUNTIME_FUNCTION *Functions);
1543 1507
1544#define OUT_OF_PROCESS_FUNCTION_TABLE_CALLBACK_EXPORT_NAME "OutOfProcessFunctionTableCallback"1508#endif /* _ARM64_ */
1545 1509
1510#if (defined _ARM64_ || defined _AMD64_) && !defined RC_INVOKED
1546 NTSYSAPI VOID __cdecl RtlRestoreContext (PCONTEXT ContextRecord,struct _EXCEPTION_RECORD *ExceptionRecord);1511 NTSYSAPI VOID __cdecl RtlRestoreContext (PCONTEXT ContextRecord,struct _EXCEPTION_RECORD *ExceptionRecord);
1547 NTSYSAPI BOOLEAN __cdecl RtlAddFunctionTable(PRUNTIME_FUNCTION FunctionTable,DWORD EntryCount,DWORD64 BaseAddress);1512 NTSYSAPI BOOLEAN __cdecl RtlAddFunctionTable(PRUNTIME_FUNCTION FunctionTable,DWORD EntryCount,DWORD64 BaseAddress);
1548 NTSYSAPI BOOLEAN __cdecl RtlInstallFunctionTableCallback(DWORD64 TableIdentifier,DWORD64 BaseAddress,DWORD Length,PGET_RUNTIME_FUNCTION_CALLBACK Callback,PVOID Context,PCWSTR OutOfProcessCallbackDll);1513 NTSYSAPI BOOLEAN __cdecl RtlInstallFunctionTableCallback(DWORD64 TableIdentifier,DWORD64 BaseAddress,DWORD Length,PGET_RUNTIME_FUNCTION_CALLBACK Callback,PVOID Context,PCWSTR OutOfProcessCallbackDll);
win32/lib/chkstk.S+2−72
@@ -9,7 +9,6 @@ · 8 unmodified lines
9 9
10/* ---------------------------------------------- */10/* ---------------------------------------------- */
11#if defined(__aarch64__)11#if defined(__aarch64__)
12/* ---------------------------------------------- */
13 12
14.globl __chkstk13.globl __chkstk
15__chkstk:14__chkstk:
@@ -33,68 +32,8 @@ L_chkstk_tail: · 17 unmodified lines
33L_chkstk_done:32L_chkstk_done:
34 ret33 ret
35 34
36.globl _(tinyc_getbp)
37_(tinyc_getbp):
38 mov x0, x29
39 ret
40
41.globl _(mingw_getsp)
42_(mingw_getsp):
43 mov x0, sp
44 ret
45
46.globl _(__mingw_setjmp)
47_(__mingw_setjmp):
48 /* _JUMP_BUFFER layout matches win32/include/setjmp.h for _ARM64_:
49 0x00 Frame, 0x08 Reserved, 0x10-0x68 X19-X30, 0x70 Sp,
50 0x78 Fpcr/Fpsr, 0x80-0xB8 D8-D15. */
51 str xzr, [x0] /* Frame = 0 */
52 stp x19, x20, [x0, 16]
53 stp x21, x22, [x0, 32]
54 stp x23, x24, [x0, 48]
55 stp x25, x26, [x0, 64]
56 stp x27, x28, [x0, 80]
57 stp x29, x30, [x0, 96]
58 mov x2, sp
59 str x2, [x0, 112] /* Sp */
60 mrs x2, FPCR
61 str w2, [x0, 120] /* Fpcr */
62 mrs x2, FPSR
63 str w2, [x0, 124] /* Fpsr */
64 stp d8, d9, [x0, 128]
65 stp d10, d11, [x0, 144]
66 stp d12, d13, [x0, 160]
67 stp d14, d15, [x0, 176]
68 mov x0, 0
69 ret
70
71.globl _(__mingw_longjmp)
72_(__mingw_longjmp):
73 ldp x19, x20, [x0, 16]
74 ldp x21, x22, [x0, 32]
75 ldp x23, x24, [x0, 48]
76 ldp x25, x26, [x0, 64]
77 ldp x27, x28, [x0, 80]
78 ldp x29, x30, [x0, 96]
79 ldr x2, [x0, 112] /* Sp */
80 mov sp, x2
81 ldr w2, [x0, 120] /* Fpcr */
82 msr FPCR, x2
83 ldr w2, [x0, 124] /* Fpsr */
84 msr FPSR, x2
85 ldp d8, d9, [x0, 128]
86 ldp d10, d11, [x0, 144]
87 ldp d12, d13, [x0, 160]
88 ldp d14, d15, [x0, 176]
89 mov x0, x1
90 cbnz x0, L_longjmp_done
91 mov x0, 1
92L_longjmp_done:
93 ret
94
95/* ---------------------------------------------- */
96#elif !defined(__x86_64__)
97/* ---------------------------------------------- */35/* ---------------------------------------------- */
36#elif defined(__i386__)
98 37
99.globl _(__chkstk)38.globl _(__chkstk)
100_(__chkstk):39_(__chkstk):
@@ -118,8 +57,7 @@ P0: · 17 unmodified lines
118 jmp *4(%eax)57 jmp *4(%eax)
119 58
120/* ---------------------------------------------- */59/* ---------------------------------------------- */
121#else60#else /* __x86_64__ */
122/* ---------------------------------------------- */
123 61
124.globl _(__chkstk)62.globl _(__chkstk)
125_(__chkstk):63_(__chkstk):
@@ -143,14 +81,6 @@ P0: · 17 unmodified lines
143 mov (%rax),%rcx /* restore ecx */81 mov (%rax),%rcx /* restore ecx */
144 jmp *8(%rax)82 jmp *8(%rax)
145 83
146/* ---------------------------------------------- */
147/* setjmp/longjmp support */
148
149.globl _(tinyc_getbp)
150_(tinyc_getbp):
151 mov %rbp,%rax
152 ret
153
154/* ---------------------------------------------- */84/* ---------------------------------------------- */
155#endif85#endif
156/* ---------------------------------------------- */86/* ---------------------------------------------- */
win32/lib/crt1.c+6−3
@@ -75,10 +75,11 @@ __attribute__((weak)) extern int __run_on_exit(); · 74 unmodified lines
75int _runtmain(int argc, /* as tcc passed in */ char **argv)75int _runtmain(int argc, /* as tcc passed in */ char **argv)
76{76{
77 int ret;77 int ret;
78#ifdef UNICODE78#if defined UNICODE || defined __aarch64__
79 _startupinfo start_info = {0};79 _startupinfo start_info = {0};
80 80 __tgetmainargs(&__argc, &__targv, &_tenviron, 0, &start_info);
81 __tgetmainargs(&__argc, &__targv, &_tenviron, _dowildcard, &start_info);81#endif
82#ifdef UNICODE
82 /* may be wrong when tcc has received wildcards (*.c) */83 /* may be wrong when tcc has received wildcards (*.c) */
83 if (argc < __argc) {84 if (argc < __argc) {
84 __targv += __argc - argc;85 __targv += __argc - argc;
@@ -93,6 +94,8 @@ int _runtmain(int argc, /* as tcc passed in */ char **argv) · 8 unmodified lines
93#endif94#endif
94 run_ctors(__argc, __targv, _tenviron);95 run_ctors(__argc, __targv, _tenviron);
95 ret = _tmain(__argc, __targv, _tenviron);96 ret = _tmain(__argc, __targv, _tenviron);
97 fflush(stdout);
98 fflush(stderr);
96 run_dtors();99 run_dtors();
97 __run_on_exit(ret);100 __run_on_exit(ret);
98 return ret;101 return ret;
win32/lib/winex.c+27−0
@@ -0,0 +1,27 @@
1/* ------------------------------------------------------------------------- */
2/* winex.c : extra stuff */
3
4#if __aarch64__
5#include <stdlib.h>
6/* replaces environ from arm64-msvcrt.dll which does not exist */
7char **_environ;
8wchar_t **_wenviron;
9/* those do exist but have problems */
10int __argc;
11char **__argv;
12wchar_t **__wargv;
13#endif
14
15#if __aarch64__ || __x86_64__
16/* MSVC x64 intrinsic */
17void __faststorefence(void)
18{
19#if __aarch64__
20 /* ARM64: Data Memory Barrier (Inner Shareable) */
21 __asm__("dmb ish");
22#elif __x86_64__
23 /* x86-64: lock prefix to flush store buffer */
24 __asm__("lock; orl $0,(%%rsp)" ::: "memory");
25#endif
26}
27#endif
x86_64-gen.c+0−8
@@ -266,14 +266,6 @@ ST_FUNC void gen_addr32(int r, Sym *sym, int c) · 265 unmodified lines
266 gen_le32(c);266 gen_le32(c);
267}267}
268 268
269/* output constant with relocation if 'r & VT_SYM' is true */
270ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c)
271{
272 if (r & VT_SYM)
273 greloca(cur_text_section, sym, ind, R_X86_64_64, c), c=0;
274 gen_le64(c);
275}
276
277/* output constant with relocation if 'r & VT_SYM' is true */269/* output constant with relocation if 'r & VT_SYM' is true */
278ST_FUNC void gen_addrpc32(int r, Sym *sym, int c)270ST_FUNC void gen_addrpc32(int r, Sym *sym, int c)
279{271{

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t