History

fix github CI & stuff

workflows/build.yml: - win32/64: install mingw32/64 gcc on msys (because the default gcc installed elsewhere seems to use ucrt, producing incompatible fp printf formats.) tccgen.c: - cleanup funcs: save any lvalues from return expressions. Also use get_temp_local_var() which however was causing a problem on i386 because its gfunc_call() removes the arguments from vstack and by that defeats the 'in-use' tracking of get_temp_local_var(). Fixed by: i386/arm/arm64/x86_64-gen.c: - in gfunc_call(): save_regs before anything else, fixes problems seen in arm64/i386 tccpp.c: - allow arm asm specific use of '#' in macros libtcc.c: - organize -M options, and: tccpe.c: - move the subsystem option parsing from libtcc.c tccelf.c: - improved error handling in tcc_load_ldscript() lib/atomic.S: - TCC_TARGET_... not defined when building the lib - endbrNN security feature not supported by TCC tests/tests2/136_atomic_gcc_style.c: - never use standard assert() in tests

grischka committed 1 year ago

Commit 9670d101 parent 28d7fb815 files · +133 −95Browse files

Unified · Split

15 files
  1. .github/workflows/build.yml +20 −8
  2. Makefile +5 −2
  3. arm-gen.c +2 −4
  4. arm64-gen.c +2 −4
  5. i386-gen.c +3 −1
  6. lib/atomic.S +10 −10
  7. libtcc.c +15 −35
  8. tcc.h +1 −0
  9. tccelf.c +16 −13
  10. tccgen.c +6 −6
  11. tccpe.c +29 −1
  12. tccpp.c +5 −0
  13. tests/tests2/136_atomic_gcc_style.c +4 −1
  14. tests/tests2/136_atomic_gcc_style.expect +10 −0
  15. x86_64-gen.c +5 −10
.github/workflows/build.yml+20−8
@@ -29,29 +29,41 @@ jobs: · 28 unmodified lines
2929 - name: make & test tcc (aarch64-osx)
3030 run: ./configure && make && make test -k
3131
32− test-x86-win32:
33− runs-on: windows-2022
34− timeout-minutes: 6
32+ test-x86_64-win32:
33+ runs-on: windows-2025
34+ timeout-minutes: 4
3535 steps:
3636 - uses: actions/checkout@v4
3737 - name: make & test tcc (x86_64-win32)
3838 shell: cmd
3939 run: |
40+ echo ::group:: setup msys mingw64-gcc
4041 set MSYS2_PATH_TYPE=inherit
4142 set MSYSTEM=MINGW64
4243 set CHERE_INVOKING=yes
44+ C:\msys64\usr\bin\bash -l -c "pacman -S --noconfirm mingw-w64-x86_64-gcc"
45+ echo ::endgroup::
4346 C:\msys64\usr\bin\bash -l -c "./configure && make && make test -k"
47+
48+ test-i386-win32:
49+ runs-on: windows-2025
50+ timeout-minutes: 4
51+ steps:
52+ - uses: actions/checkout@v4
4453 - name: make & test tcc (i386-win32)
4554 shell: cmd
4655 run: |
56+ echo ::group:: setup msys mingw32-gcc
4757 set MSYS2_PATH_TYPE=inherit
4858 set MSYSTEM=MINGW32
4959 set CHERE_INVOKING=yes
50− C:\msys64\usr\bin\bash -l -c "./configure && make clean all && make test -k"
60+ C:\msys64\usr\bin\bash -l -c "pacman -S --noconfirm mingw-w64-i686-gcc"
61+ echo ::endgroup::
62+ C:\msys64\usr\bin\bash -l -c "./configure && make all && make test -k"
5163
5264 test-armv7-linux:
5365 runs-on: ubuntu-22.04
54− timeout-minutes: 6
66+ timeout-minutes: 8
5567 steps:
5668 - uses: actions/checkout@v4
5769 - uses: uraimo/run-on-arch-action@v3
@@ -69,14 +81,14 @@ jobs: · 11 unmodified lines
6981
7082 test-aarch64-linux:
7183 runs-on: ubuntu-22.04
72− timeout-minutes: 6
84+ timeout-minutes: 8
7385 steps:
7486 - uses: actions/checkout@v4
7587 - uses: uraimo/run-on-arch-action@v3
7688 name: make & test tcc (aarch64-linux)
7789 with:
7890 arch: aarch64
79− distro: ubuntu22.04
91+ distro: ubuntu24.04
8092 githubToken: ${{ github.token }}
8193 install: |
8294 apt-get update -q -y
@@ -87,7 +99,7 @@ jobs: · 4 unmodified lines
8799
88100 test-riscv64-linux:
89101 runs-on: ubuntu-22.04
90− timeout-minutes: 6
102+ timeout-minutes: 8
91103 steps:
92104 - uses: actions/checkout@v4
93105 - uses: uraimo/run-on-arch-action@v3
Makefile+5−2
@@ -252,8 +252,11 @@ LDFLAGS += -g · 251 unmodified lines
252252 endif
253253
254254 # convert "include/tccdefs.h" to "tccdefs_.h"
255−%_.h : include/%.h conftest.c
256− $S$(CC) -DC2STR $(filter %.c,$^) -o c2str.exe && ./c2str.exe $< $@
255+%_.h : include/%.h c2str.exe
256+ $S./c2str.exe $< $@
257+
258+c2str.exe : conftest.c
259+ $S$(CC) -DC2STR $< -o $@
257260
258261 # target specific object rule
259262 $(X)%.o : %.c $(LIBTCC_INC)
arm-gen.c+2−4
@@ -1311,10 +1311,6 @@ again: · 1310 unmodified lines
13111311 if (++pass < 2)
13121312 goto again;
13131313
1314− /* Manually free remaining registers since next parameters are loaded
1315− * manually, without the help of gv(int). */
1316− save_regs(nb_args);
1317−
13181314 if(todo) {
13191315 o(0xE8BD0000|todo); /* pop {todo} */
13201316 for(pplan = plan->clsplans[CORE_STRUCT_CLASS]; pplan; pplan = pplan->prev) {
@@ -1354,6 +1350,8 @@ void gfunc_call(int nb_args) · 33 unmodified lines
13541350 gbound_args(nb_args);
13551351 #endif
13561352
1353+ save_regs(nb_args + 1);
1354+
13571355 #ifdef TCC_ARM_EABI
13581356 if (float_abi == ARM_HARD_FLOAT) {
13591357 variadic = (vtop[-nb_args].type.ref->f.func_type == FUNC_ELLIPSIS);
arm64-gen.c+2−4
@@ -997,6 +997,8 @@ ST_FUNC void gfunc_call(int nb_args) · 996 unmodified lines
997997 int variadic = (vtop[-nb_args].type.ref->f.func_type == FUNC_ELLIPSIS);
998998 int var_nb_arg = n_func_args(&vtop[-nb_args].type);
999999
1000+ save_regs(nb_args + 1);
1001+
10001002 #ifdef CONFIG_TCC_BCHECK
10011003 if (tcc_state->do_bounds_check)
10021004 gbound_args(nb_args);
@@ -1101,9 +1103,6 @@ ST_FUNC void gfunc_call(int nb_args) · 98 unmodified lines
11011103 // value in floating-point registers
11021104 if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
11031105 uint32_t j, sz, n = arm64_hfa(&vtop->type, &sz);
1104− // save regs because struct may overwrite previous func call result
1105− save_regs(0);
1106−
11071106 vtop->type.t = VT_PTR;
11081107 gaddrof();
11091108 gv(RC_R30);
@@ -1129,7 +1128,6 @@ ST_FUNC void gfunc_call(int nb_args) · 19 unmodified lines
11291128 vswap();
11301129 }
11311130
1132− save_regs(0);
11331131 arm64_gen_bl_or_b(0);
11341132 --vtop;
11351133 if (stack & 0xfff)
i386-gen.c+3−1
@@ -406,6 +406,8 @@ ST_FUNC void gfunc_call(int nb_args) · 405 unmodified lines
406406 gbound_args(nb_args);
407407 #endif
408408
409+ save_regs(nb_args + 1);
410+
409411 args_size = 0;
410412 for(i = 0;i < nb_args; i++) {
411413 if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
@@ -463,7 +465,7 @@ ST_FUNC void gfunc_call(int nb_args) · 51 unmodified lines
463465 }
464466 vtop--;
465467 }
466− save_regs(0); /* save used temporary registers */
468+
467469 func_sym = vtop->type.ref;
468470 func_call = func_sym->f.func_call;
469471 /* fast call case */
lib/atomic.S+10−10
@@ -23,8 +23,10 @@ · 22 unmodified lines
2323
2424 /* ---------------------------------------------- */
2525 #if defined __i386__
26+
27+#define endbr32
28+
2629 .text
27− .align 2
2830
2931 .global _(__atomic_load_1)
3032 .type _(__atomic_load_1), %function
@@ -297,9 +299,11 @@ _(atomic_flag_clear_explicit): · 266 unmodified lines
297299 #endif //__i386__
298300
299301 /* ---------------------------------------------- */
300−#if defined __x86_64__ && !defined TCC_TARGET_PE
302+#if defined __x86_64__ && !defined _WIN32
303+
304+#define endbr64
305+
301306 .text
302− .align 2
303307
304308 .global _(__atomic_load_1)
305309 .type _(__atomic_load_1), %function
@@ -508,12 +512,11 @@ _(atomic_flag_clear_explicit): · 202 unmodified lines
508512 ret
509513 .size _(atomic_flag_clear_explicit), .-_(atomic_flag_clear_explicit)
510514
511−#endif //__x86_64__ && !TCC_TARGET_PE
515+#endif //__x86_64__ && !_WIN32
512516
513517 /* ---------------------------------------------- */
514−#if defined __x86_64__ && defined TCC_TARGET_PE
518+#if defined __x86_64__ && defined _WIN32
515519 .text
516− .align 2
517520
518521 .global _(__atomic_load_1)
519522 .type _(__atomic_load_1), %function
@@ -700,12 +703,11 @@ _(atomic_flag_clear_explicit): · 180 unmodified lines
700703 ret
701704 .size _(atomic_flag_clear_explicit), .-_(atomic_flag_clear_explicit)
702705
703−#endif //__x86_64__ && TCC_TARGET_PE
706+#endif //__x86_64__ && _WIN32
704707
705708 /* ---------------------------------------------- */
706709 #if defined __arm__
707710 .text
708− .align 2
709711 #ifndef __TINYC__
710712 .arch armv6k
711713 .syntax unified
@@ -1496,7 +1498,6 @@ _(atomic_flag_clear_explicit): · 784 unmodified lines
14961498 /* ---------------------------------------------- */
14971499 #if defined __aarch64__
14981500 .text
1499− .align 2
15001501
15011502 .global _(__atomic_load_1)
15021503 .type _(__atomic_load_1), %function
@@ -2115,7 +2116,6 @@ _(atomic_flag_clear_explicit): · 612 unmodified lines
21152116 /* ---------------------------------------------- */
21162117 #if defined __riscv
21172118 .text
2118− .align 2
21192119
21202120 .global _(__atomic_load_1)
21212121 .type _(__atomic_load_1), %function
libtcc.c+15−35
@@ -1465,31 +1465,9 @@ static int tcc_set_linker(TCCState *s, const char *optarg) · 1464 unmodified lines
14651465 } else if (link_option(&o, "stack=")) {
14661466 s->pe_stack_size = strtoul(o.arg, &end, 10);
14671467 } else if (link_option(&o, "subsystem=")) {
1468−#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1469− if (0==strcmp("native", o.arg)) {
1470− s->pe_subsystem = 1;
1471− } else if (0==strcmp("console", o.arg)) {
1472− s->pe_subsystem = 3;
1473− } else if (0==strcmp("gui", o.arg) || 0==strcmp("windows", o.arg)) {
1474− s->pe_subsystem = 2;
1475− } else if (0==strcmp("posix", o.arg)) {
1476− s->pe_subsystem = 7;
1477− } else if (0==strcmp("efiapp", o.arg)) {
1478− s->pe_subsystem = 10;
1479− } else if (0==strcmp("efiboot", o.arg)) {
1480− s->pe_subsystem = 11;
1481− } else if (0==strcmp("efiruntime", o.arg)) {
1482− s->pe_subsystem = 12;
1483− } else if (0==strcmp("efirom", o.arg)) {
1484− s->pe_subsystem = 13;
1485−#elif defined(TCC_TARGET_ARM)
1486− if (0==strcmp("wince", o.arg)) {
1487− s->pe_subsystem = 9;
1488−#endif
1489− } else
1468+ if (pe_setsubsy(s, o.arg) < 0)
14901469 goto err;
1491−#endif /* PE */
1492−#ifdef TCC_TARGET_MACHO
1470+#elif defined TCC_TARGET_MACHO
14931471 } else if (link_option(&o, "all_load")) {
14941472 s->filetype |= AFF_WHOLE_ARCHIVE;
14951473 } else if (link_option(&o, "force_load=")) {
@@ -1653,11 +1631,10 @@ static const TCCOption tcc_options[] = { · 157 unmodified lines
16531631 { "w", TCC_OPTION_w, 0 },
16541632 { "E", TCC_OPTION_E, 0},
16551633 { "M", TCC_OPTION_M, 0},
1656− { "MD", TCC_OPTION_MD, 0},
1657− { "MF", TCC_OPTION_MF, TCC_OPTION_HAS_ARG },
16581634 { "MM", TCC_OPTION_MM, 0},
1659− { "MMD,", TCC_OPTION_MMD, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
1660− { "MMD", TCC_OPTION_MMD, 0},
1635+ { "MD", TCC_OPTION_MD, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
1636+ { "MMD", TCC_OPTION_MMD, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
1637+ { "MF", TCC_OPTION_MF, TCC_OPTION_HAS_ARG },
16611638 { "MP", TCC_OPTION_MP, 0},
16621639 { "x", TCC_OPTION_x, TCC_OPTION_HAS_ARG },
16631640 /* tcctools */
@@ -2075,6 +2052,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv) · 411 unmodified lines
20752052 case TCC_OPTION_P:
20762053 s->Pflag = atoi(optarg) + 1;
20772054 break;
2055+
20782056 case TCC_OPTION_M:
20792057 s->include_sys_deps = 1;
20802058 // fall through
@@ -2084,29 +2062,31 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv) · 3 unmodified lines
20842062 if (!s->deps_outfile)
20852063 tcc_set_str(&s->deps_outfile, "-");
20862064 break;
2065+ case TCC_OPTION_MD:
2066+ s->include_sys_deps = 1;
2067+ // fall through
20872068 case TCC_OPTION_MMD:
20882069 s->gen_deps = 1;
20892070 /* usually, only "-MMD" is used */
20902071 /* but the Linux Kernel uses "-MMD,depfile" */
2091− if ((optarg) && (*optarg != '\0'))
2092− tcc_set_str(&s->deps_outfile, optarg);
2093− break;
2094− case TCC_OPTION_MD:
2095− s->gen_deps = 1;
2096− s->include_sys_deps = 1;
2097− break;
2072+ if (*optarg != ',')
2073+ break;
2074+ ++optarg;
2075+ // fall through
20982076 case TCC_OPTION_MF:
20992077 tcc_set_str(&s->deps_outfile, optarg);
21002078 break;
21012079 case TCC_OPTION_MP:
21022080 s->gen_phony_deps = 1;
21032081 break;
2082+
21042083 case TCC_OPTION_dumpmachine:
21052084 printf("%s\n", dumpmachine_str);
21062085 exit(0);
21072086 case TCC_OPTION_dumpversion:
21082087 printf ("%s\n", TCC_VERSION);
21092088 exit(0);
2089+
21102090 case TCC_OPTION_x:
21112091 x = 0;
21122092 if (*optarg == 'c')
tcc.h+1−0
@@ -1790,6 +1790,7 @@ ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str); · 1789 unmodified lines
17901790 ST_FUNC int pe_load_file(struct TCCState *s1, int fd, const char *filename);
17911791 ST_FUNC int pe_output_file(TCCState * s1, const char *filename);
17921792 ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value);
1793+ST_FUNC int pe_setsubsy(TCCState *s1, const char *arg);
17931794 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
17941795 #endif
17951796 #ifdef TCC_TARGET_X86_64
tccelf.c+16−13
@@ -3937,7 +3937,7 @@ static int ld_add_file(TCCState *s1, const char filename[]) · 3936 unmodified lines
39373937 {
39383938 if (filename[0] == '-' && filename[1] == 'l')
39393939 return tcc_add_library(s1, filename + 2);
3940− {
3940+ if (CONFIG_SYSROOT[0] != '\0' || !IS_ABSPATH(filename)) {
39413941 /* lookup via library paths */
39423942 int ret = tcc_add_dll(s1, tcc_basename(filename), 0);
39433943 if (ret != FILE_NOT_FOUND)
@@ -3981,19 +3981,19 @@ repeat: · 37 unmodified lines
39813981 } else if (t != LD_TOK_NAME) {
39823982 return tcc_error_noabort("unexpected token '%c'", t);
39833983 } else if (!strcmp(filename, "AS_NEEDED")) {
3984− ret = ld_add_file_list(s1, filename);
3984+ ret |= ld_add_file_list(s1, filename);
39853985 } else if (c == 'I' || c == 'G' || c == 'A') {
3986− ret = ld_add_file(s1, filename);
3986+ ret |= !!ld_add_file(s1, filename);
39873987 }
3988− if (ret)
3989− return -1;
3988+ if (ret < 0)
3989+ return ret;
39903990 t = ld_next(s1, filename, sizeof(filename));
39913991 if (t == ',')
39923992 t = ld_next(s1, filename, sizeof(filename));
39933993 }
3994− if (c == 'G' && new_undef_sym(s1, sym_offset))
3994+ if (c == 'G' && ret == 0 && new_undef_sym(s1, sym_offset))
39953995 goto repeat;
3996− return 0;
3996+ return ret;
39973997 }
39983998
39993999 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
@@ -4001,7 +4001,7 @@ repeat: · 1 unmodified line
40014001 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
40024002 {
40034003 char cmd[64];
4004− int t, ret = FILE_NOT_RECOGNIZED;
4004+ int t, ret = 0, noscript = 1;
40054005 unsigned char *text_ptr, *saved_ptr;
40064006
40074007 saved_ptr = s1->ld_p;
@@ -4012,19 +4012,22 @@ ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd) · 4 unmodified lines
40124012 break;
40134013 if (!strcmp(cmd, "INPUT") ||
40144014 !strcmp(cmd, "GROUP")) {
4015− ret = ld_add_file_list(s1, cmd);
4015+ ret |= ld_add_file_list(s1, cmd);
40164016 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
40174017 !strcmp(cmd, "TARGET")) {
40184018 /* ignore some commands */
4019− ret = ld_add_file_list(s1, cmd);
4020− } else if (0 == ret) {
4019+ ret |= ld_add_file_list(s1, cmd);
4020+ } else if (noscript) {
4021+ ret = FILE_NOT_RECOGNIZED;
4022+ } else {
40214023 ret = tcc_error_noabort("unexpected '%s'", cmd);
40224024 }
4023− if (ret)
4025+ if (ret < 0)
40244026 break;
4027+ noscript = 0;
40254028 }
40264029 tcc_free(text_ptr);
40274030 s1->ld_p = saved_ptr;
4028− return ret;
4031+ return ret < 0 ? ret : -ret;
40294032 }
40304033 #endif /* !ELF_OBJ_ONLY */
tccgen.c+6−6
@@ -6839,15 +6839,15 @@ static void end_switch(void) · 6838 unmodified lines
68396839 /* ------------------------------------------------------------------------- */
68406840 /* __attribute__((cleanup(fn))) */
68416841
6842−/* save SValue of symbol to local stack */
6843−static void save_cleanup_sym(Sym *s)
6842+/* protect symbol lvalues from further modification */
6843+static void save_lvalues(void)
68446844 {
68456845 SValue *sv = vtop;
68466846 while (sv >= vstack) {
6847− if (sv->sym == s) {
6847+ if (sv->sym && (sv->r & VT_LVAL)) {
68486848 int align, size = type_size(&sv->type, &align);
6849− loc = (loc - size) & -align;
6850− vset(&sv->type, VT_LOCAL | VT_LVAL, loc);
6849+ int r2, l = get_temp_local_var(size, align, &r2);
6850+ vset(&sv->type, VT_LOCAL | VT_LVAL, l), vtop->r2 = r2;
68516851 vpushv(sv), *sv = vtop[-1], vstore(), --vtop;
68526852 }
68536853 --sv;
@@ -6860,7 +6860,7 @@ static void try_call_scope_cleanup(Sym *stop) · 6 unmodified lines
68606860 for (; cls != stop; cls = cls->next) {
68616861 Sym *fs = cls->cleanup_func;
68626862 Sym *vs = cls->prev_tok;
6863− save_cleanup_sym(vs);
6863+ save_lvalues();
68646864 vpushsym(&fs->type, fs);
68656865 vset(&vs->type, vs->r, vs->c);
68666866 vtop->sym = vs;
tccpe.c+29−1
@@ -1254,7 +1254,7 @@ static int pe_check_symbols(struct pe_info *pe) · 1253 unmodified lines
12541254 if (sym->st_shndx == SHN_UNDEF) {
12551255 const char *name = (char*)symtab_section->link->data + sym->st_name;
12561256 unsigned type = ELFW(ST_TYPE)(sym->st_info);
1257− int imp_sym;
1257+ int imp_sym = 0;
12581258 struct import_symbol *is;
12591259
12601260 int _imp_, n;
@@ -1928,6 +1928,34 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe) · 667 unmodified lines
19281928 pe->type = pe_type;
19291929 }
19301930
1931+ST_FUNC int pe_setsubsy(TCCState *s1, const char *arg)
1932+{
1933+ static const struct subsy { const char* p; int v; } x[] = {
1934+#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1935+ { "native", 1 },
1936+ { "gui", 2 },
1937+ { "windows", 2 },
1938+ { "console", 3 },
1939+ { "posix", 7 },
1940+ { "efiapp", 10 },
1941+ { "efiboot", 11 },
1942+ { "efiruntime", 12 },
1943+ { "efirom", 13 },
1944+#elif defined(TCC_TARGET_ARM)
1945+ { "wince", 9 },
1946+#endif
1947+ { 0, -1 }};
1948+ const struct subsy *y;
1949+ for (y = x;; ++y) {
1950+ if (!y->p)
1951+ return -1;
1952+ if (0 == strcmp(y->p, arg)) {
1953+ s1->pe_subsystem = y->v;
1954+ return 0;
1955+ }
1956+ }
1957+}
1958+
19311959 static void pe_set_options(TCCState * s1, struct pe_info *pe)
19321960 {
19331961 if (PE_DLL == pe->type) {
tccpp.c+5−0
@@ -3076,6 +3076,11 @@ static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args) · 3075 unmodified lines
30763076 cval.str.size = tokcstr.size;
30773077 cval.str.data = tokcstr.data;
30783078 tok_str_add2(&str, TOK_PPSTR, &cval);
3079+#ifdef TCC_TARGET_ARM
3080+ } else if ((parse_flags & PARSE_FLAG_ASM_FILE) && t == TOK_PPNUM) {
3081+ /* for example: mov r1,#0 */
3082+ --macro_str, tok_str_add(&str, '#');
3083+#endif
30793084 } else {
30803085 expect("macro parameter after '#'");
30813086 }
tests/tests2/136_atomic_gcc_style.c+4−1
@@ -1,8 +1,11 @@
11 #include <stdatomic.h>
22 #include <stdbool.h>
3−#include <assert.h>
43 #include <stdio.h>
54
5+// standard assert would popup a dialog box on windows
6+#define assert(x) \
7+ printf("assert \"%s\" : %s\n", #x, (x) ? "yes" : "no");
8+
69 int main() {
710 // Test 1: Basic functionality of __atomic_store_n and __atomic_load_n
811 {
tests/tests2/136_atomic_gcc_style.expect+10−0
@@ -1 +1,11 @@
1+assert "loaded == 42" : yes
2+assert "success" : yes
3+assert "atomic_var == 200" : yes
4+assert "expected == 100" : yes
5+assert "!success" : yes
6+assert "atomic_var == 100" : yes
7+assert "expected == 100" : yes
8+assert "atomic_var == 60" : yes
9+assert "loaded_ptr == NULL" : yes
10+assert "__atomic_load_n(&atomic_var, __ATOMIC_RELAXED) == 10" : yes
111 All atomic tests passed!
x86_64-gen.c+5−10
@@ -809,6 +809,8 @@ void gfunc_call(int nb_args) · 808 unmodified lines
809809 gbound_args(nb_args);
810810 #endif
811811
812+ save_regs(nb_args);
813+
812814 args_size = (nb_args < REGN ? REGN : nb_args) * PTR_SIZE;
813815 arg = nb_args;
814816
@@ -906,7 +908,7 @@ void gfunc_call(int nb_args) · 91 unmodified lines
906908 }
907909 vtop--;
908910 }
909− save_regs(0);
911+
910912 /* Copy R10 and R11 into RCX and RDX, respectively */
911913 if (nb_args > 0) {
912914 o(0xd1894c); /* mov %r10, %rcx */
@@ -1249,6 +1251,8 @@ void gfunc_call(int nb_args) · 336 unmodified lines
12491251 gbound_args(nb_args);
12501252 #endif
12511253
1254+ save_regs(nb_args);
1255+
12521256 /* calculate the number of integer/float register arguments, remember
12531257 arguments to be passed via stack (in onstack[]), and also remember
12541258 if we have to align the stack pointer to 16 (onstack[i] == 2). Needs
@@ -1364,9 +1368,6 @@ void gfunc_call(int nb_args) · 109 unmodified lines
13641368
13651369 tcc_free(onstack);
13661370
1367− /* XXX This should be superfluous. */
1368− save_regs(0); /* save used temporary registers */
1369−
13701371 /* then, we prepare register passing arguments.
13711372 Note that we cannot set RDX and RCX in this loop because gv()
13721373 may break these temporary registers. Let's use R10 and R11
@@ -1416,12 +1417,6 @@ void gfunc_call(int nb_args) · 43 unmodified lines
14161417 assert(gen_reg == 0);
14171418 assert(sse_reg == 0);
14181419
1419− /* We shouldn't have many operands on the stack anymore, but the
1420− call address itself is still there, and it might be in %eax
1421− (or edx/ecx) currently, which the below writes would clobber.
1422− So evict all remaining operands here. */
1423− save_regs(0);
1424−
14251420 /* Copy R10 and R11 into RDX and RCX, respectively */
14261421 if (nb_reg_args > 2) {
14271422 o(0xd2894c); /* mov %r10, %rdx */

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