diff --git a/arm-gen.c b/arm-gen.c index fcde7dcb..c0dd5099 100644 --- a/arm-gen.c +++ b/arm-gen.c @@ -1332,7 +1332,7 @@ again: parameters and the function address. */ void gfunc_call(int nb_args) { - int r, args_size; + int args_size; int def_float_abi = float_abi; int todo; struct plan plan; @@ -1352,12 +1352,6 @@ void gfunc_call(int nb_args) float_abi = ARM_SOFTFP_FLOAT; } #endif - /* cannot let cpu flags if other instruction are generated. Also avoid leaving - VT_JMP anywhere except on the top of the stack because it would complicate - the code generator. */ - r = vtop->r & VT_VALMASK; - if (r == VT_CMP || (r & ~1) == VT_JMP) - gv(RC_INT); memset(&plan, 0, sizeof plan); if (nb_args) @@ -1716,9 +1710,6 @@ void gen_opi(int op) opc|=2; // sub -> rsb } } - if ((vtop->r & VT_VALMASK) == VT_CMP || - (vtop->r & (VT_VALMASK & ~1)) == VT_JMP) - gv(RC_INT); vswap(); c=intr(gv(RC_INT)); vswap(); @@ -1757,9 +1748,6 @@ done: break; case 2: opc=0xE1A00000|(opc<<5); - if ((vtop->r & VT_VALMASK) == VT_CMP || - (vtop->r & (VT_VALMASK & ~1)) == VT_JMP) - gv(RC_INT); vswap(); r=intr(gv(RC_INT)); vswap(); diff --git a/arm64-gen.c b/arm64-gen.c index e314de58..d15446d3 100644 --- a/arm64-gen.c +++ b/arm64-gen.c @@ -1029,10 +1029,6 @@ ST_FUNC void gfunc_call(int nb_args) stack = (stack + 15) >> 4 << 4; - /* fetch cpu flag before generating any code */ - if ((vtop->r & VT_VALMASK) == VT_CMP) - gv(RC_INT); - if (stack >= 0x1000000) // 16Mb tcc_error("stack size too big %lu", stack); if (stack & 0xfff) diff --git a/i386-gen.c b/i386-gen.c index 1d521160..5814a398 100644 --- a/i386-gen.c +++ b/i386-gen.c @@ -409,9 +409,6 @@ ST_FUNC void gfunc_call(int nb_args) args_size = 0; for(i = 0;i < nb_args; i++) { if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { - /* fetch cpu flag before generating any code */ - if ((vtop->r & VT_VALMASK) == VT_CMP) - gv(RC_INT); size = type_size(&vtop->type, &align); /* align to stack align size */ size = (size + 3) & ~3; diff --git a/lib/libtcc1.c b/lib/libtcc1.c index 9fb00aa6..fe5ababc 100644 --- a/lib/libtcc1.c +++ b/lib/libtcc1.c @@ -626,12 +626,6 @@ long long __fixxfdi (long double a1) } #endif /* !ARM */ -#if defined __x86_64__ -/* float constants used for unary minus operation */ -const float __mzerosf = -0.0; -const double __mzerodf = -0.0; -#endif - #if defined _WIN64 /* MSVC x64 intrinsic */ void __faststorefence(void) diff --git a/libtcc.c b/libtcc.c index 21b1b251..b163e865 100644 --- a/libtcc.c +++ b/libtcc.c @@ -75,6 +75,8 @@ TCC_SEM(static tcc_compile_sem); /* an array of pointers to memory to be free'd after errors */ ST_DATA void** stk_data; ST_DATA int nb_stk_data; +/* option -d (for general development purposes) */ +ST_DATA int g_debug; /********************************************************/ #ifdef _WIN32 @@ -547,9 +549,8 @@ static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char * } if (str.size) { cstr_ccat(&str, '\0'); - dynarray_add(p_ary, p_nb_ary, tcc_strdup(str.data)); + dynarray_add(p_ary, p_nb_ary, str.data); } - cstr_free(&str); in = p+1; } while (*p); } @@ -848,6 +849,9 @@ LIBTCCAPI TCCState *tcc_new(void) s->include_stack_ptr = s->include_stack; tcc_set_lib_path(s, CONFIG_TCCDIR); +#ifdef CONFIG_TCC_SWITCHES /* predefined options */ + tcc_set_options(s, CONFIG_TCC_SWITCHES); +#endif return s; } @@ -867,6 +871,7 @@ LIBTCCAPI void tcc_delete(TCCState *s1) tcc_free(s1->tcc_lib_path); tcc_free(s1->soname); tcc_free(s1->rpath); + tcc_free(s1->elfint); tcc_free(s1->elf_entryname); tcc_free(s1->init_symbol); tcc_free(s1->fini_symbol); @@ -1225,17 +1230,15 @@ LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname) "%s/lib%s.a", NULL }; - - const char * const *pp = s->static_link - ? libs + sizeof(libs) / sizeof(*libs) - 2 - : libs; - /* if libraryname begins with a colon, it means search lib paths for exactly the following file, without lib prefix or anything */ - if (*libraryname == ':') + if (*libraryname == ':') { libraryname++; - else { + } else { int flags = s->filetype & AFF_WHOLE_ARCHIVE; + const char * const *pp = libs; + if (s->static_link) + pp += sizeof(libs) / sizeof(*libs) - 2; /* only "%s/lib%s.a" */ while (*pp) { int ret = tcc_add_library_internal(s, *pp, libraryname, flags, s->library_paths, s->nb_library_paths); @@ -1341,7 +1344,7 @@ static int link_option(const char *str, const char *val, const char **ptr) if (*p != ',' && *p != '=') return 0; p++; - } else if (*p) { + } else if (*p && *p != ',') { return 0; } *ptr = p; @@ -1890,7 +1893,6 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind) ++s->verbose; continue; } -reparse: if (r[0] != '-' || r[1] == '\0') { args_parser_add_file(s, r, s->filetype); if (run) { @@ -1968,7 +1970,8 @@ dorun: goto enable_backtrace; enable_backtrace: s->do_backtrace = 1; - s->do_debug = s->do_debug ? s->do_debug : 1; + if (0 == s->do_debug) + s->do_debug = 1; s->dwarf = CONFIG_DWARF_VERSION; break; #ifdef CONFIG_TCC_BCHECK @@ -1982,6 +1985,8 @@ dorun: s->dwarf = CONFIG_DWARF_VERSION; if (strstart("dwarf", &optarg)) { s->dwarf = (*optarg) ? (0 - atoi(optarg)) : DEFAULT_DWARF_VERSION; + } else if (0 == strcmp("stabs", optarg)) { + s->dwarf = 0; } else if (isnum(*optarg)) { x = *optarg - '0'; /* -g0 = no info, -g1 = lines/functions only, -g2 = full info */ @@ -2007,7 +2012,7 @@ dorun: else if (*optarg == 't') s->dflag = 16; else if (isnum(*optarg)) - s->g_debug |= atoi(optarg); + g_debug |= atoi(optarg); else goto unsupported_option; break; @@ -2106,8 +2111,15 @@ dorun: return -1; break; case TCC_OPTION_Wp: - r = optarg; - goto reparse; + { + char *p = tcc_strdup(optarg), *q = p; + while (!!(q = strchr(q, ','))) *q++ = ' '; + x = tcc_set_options(s, p); + tcc_free(p); + if (x < 0) + return -1; + break; + } case TCC_OPTION_E: x = TCC_OUTPUT_PREPROCESS; goto set_output_type; @@ -2156,7 +2168,7 @@ dorun: s->filetype = x | (s->filetype & ~AFF_TYPE_MASK); break; case TCC_OPTION_O: - s->optimize = atoi(optarg); + s->optimize = isnum(optarg[0]) ? optarg[0]-'0' : 1 /* -O -Os */; break; case TCC_OPTION_print_search_dirs: x = OPT_PRINT_DIRS; diff --git a/riscv64-gen.c b/riscv64-gen.c index 5dea659f..99c94dc3 100644 --- a/riscv64-gen.c +++ b/riscv64-gen.c @@ -628,11 +628,6 @@ ST_FUNC void gfunc_call(int nb_args) tempspace = (tempspace + 15) & -16; stack_add = stack_adj + tempspace; - /* fetch cpu flag before generating any code */ - if ((vtop->r & VT_VALMASK) == VT_CMP) - gv(RC_INT); - - if (stack_add) { if (stack_add >= 0x800) { unsigned int bit11 = (((unsigned int)-stack_add) >> 11) & 1; diff --git a/tcc.c b/tcc.c index fc019065..c6217499 100644 --- a/tcc.c +++ b/tcc.c @@ -293,9 +293,6 @@ int main(int argc0, char **argv0) redo: argc = argc0, argv = argv0; s = s1 = tcc_new(); -#ifdef CONFIG_TCC_SWITCHES /* predefined options */ - tcc_set_options(s, CONFIG_TCC_SWITCHES); -#endif opt = tcc_parse_args(s, &argc, &argv, 1); if (opt < 0) return 1; diff --git a/tcc.h b/tcc.h index fc4d1b6a..45e7b5b7 100644 --- a/tcc.h +++ b/tcc.h @@ -803,7 +803,7 @@ struct TCCState { char *tcc_lib_path; /* CONFIG_TCCDIR or -B option */ char *soname; /* as specified on the command line (-soname) */ char *rpath; /* as specified on the command line (-Wl,-rpath=) */ - char *elfint; /* -Wl,-I on command line, LD_SO in environment, or DEFAULT_ELFINTERP(this) */ + char *elfint; /* -Wl,-I... on command line */ char *elf_entryname; /* "_start" unless set */ char *init_symbol; /* symbols to call at load-time (not used currently) */ char *fini_symbol; /* symbols to call at unload-time (not used currently) */ @@ -987,9 +987,6 @@ struct TCCState { unsigned int total_bytes; unsigned int total_output[4]; - /* option -dnum (for general development purposes) */ - int g_debug; - /* used by tcc_load_ldscript */ int fd, cc; @@ -1193,6 +1190,7 @@ enum tcc_token { ST_DATA struct TCCState *tcc_state; ST_DATA void** stk_data; ST_DATA int nb_stk_data; +ST_DATA int g_debug; /* public functions currently used by the tcc main function */ ST_FUNC char *pstrcpy(char *buf, size_t buf_size, const char *s); diff --git a/tccelf.c b/tccelf.c index 7df46f98..697d448d 100644 --- a/tccelf.c +++ b/tccelf.c @@ -3247,11 +3247,12 @@ invalid: } else { s->data_offset += size; } - /* align end of section */ +#if defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64 + /* align code sections to instruction lenght */ /* This is needed if we compile a c file after this */ - if (s == text_section || s == data_section || s == rodata_section || - s == bss_section || s == common_section) - s->data_offset += -s->data_offset & (s->sh_addralign - 1); + if (s->sh_flags & SHF_EXECINSTR) + section_add(s, 0, 4); +#endif next: ; } diff --git a/tccgen.c b/tccgen.c index b7d35ba7..e17597a3 100644 --- a/tccgen.c +++ b/tccgen.c @@ -6187,6 +6187,7 @@ special_math_val: } next(); + vcheck_cmp(); /* the generators don't like VT_CMP on vtop */ gfunc_call(nb_args); if (ret_nregs < 0) { @@ -8221,7 +8222,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, sec = rodata_section; } else if (has_init) { sec = data_section; - /*if (tcc_state->g_debug & 4) + /*if (g_debug & 4) tcc_warning("rw data: %s", get_tok_str(v, 0));*/ } else if (tcc_state->nocommon) sec = bss_section; diff --git a/tccpe.c b/tccpe.c index a1fbb32c..1ec3e762 100644 --- a/tccpe.c +++ b/tccpe.c @@ -1262,6 +1262,8 @@ static int pe_check_symbols(struct pe_info *pe) const char *s, *p; n = _imp_ = 0; + if (sym->st_other & ST_PE_IMPORT) + _imp_ = 1; do { s = pe_export_name(s1, sym); if (n) { @@ -1293,7 +1295,7 @@ static int pe_check_symbols(struct pe_info *pe) if (type == STT_FUNC /* symbols from assembler often have no type */ - || type == STT_NOTYPE) { + || (type == STT_NOTYPE && 0 == _imp_)) { unsigned offset = is->thk_offset; if (offset) { /* got aliased symbol, like stricmp and _stricmp */ @@ -1336,7 +1338,7 @@ static int pe_check_symbols(struct pe_info *pe) sym->st_other &= ~ST_PE_EXPORT; /* do not export */ } else { /* STT_OBJECT */ - if (0 == _imp_ && 0 == (sym->st_other & ST_PE_IMPORT)) + if (0 == _imp_) ret = tcc_error_noabort("symbol '%s' is missing __declspec(dllimport)", name); /* original symbol will be patched later in pe_build_imports */ sym->st_value = is->iat_index; /* chain potential alias */ @@ -2015,7 +2017,7 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename) } pe_free_imports(&pe); #if PE_PRINT_SECTIONS - if (s1->g_debug & 8) + if (g_debug & 8) pe_print_sections(s1, "tcc.log"); #endif return s1->nb_errors ? -1 : 0; diff --git a/tccpp.c b/tccpp.c index 8f6b3d4c..3247dd0a 100644 --- a/tccpp.c +++ b/tccpp.c @@ -1338,8 +1338,10 @@ ST_FUNC void skip_to_eol(int warn) return; if (warn) tcc_warning("extra tokens after directive"); + while (macro_stack) + end_macro(); file->buf_ptr = parse_line_comment(file->buf_ptr - 1); - tok = TOK_LINEFEED; + next_nomacro(); } static CachedInclude * @@ -1931,38 +1933,37 @@ ST_FUNC void preprocess(int is_bof) case TOK_LINE: parse_flags &= ~PARSE_FLAG_TOK_NUM; next(); - parse_flags |= PARSE_FLAG_TOK_NUM; if (tok != TOK_PPNUM) { _line_err: tcc_error("wrong #line format"); } + c = 1; goto _line_num; case TOK_PPNUM: if (parse_flags & PARSE_FLAG_ASM_FILE) goto ignore; + c = 0; /* no error with extra tokens */ _line_num: for (n = 0, q = tokc.str.data; *q; ++q) { if (!isnum(*q)) goto _line_err; n = n * 10 + *q - '0'; } - parse_flags &= ~PARSE_FLAG_TOK_STR; + parse_flags &= ~PARSE_FLAG_TOK_STR; /* don't parse escape sequences */ next(); - parse_flags |= PARSE_FLAG_TOK_STR; - if (tok == TOK_PPSTR && tokc.str.data[0] == '"') { + if (tok != TOK_LINEFEED) { + if (tok != TOK_PPSTR || tokc.str.data[0] != '"') + goto _line_err; tokc.str.data[tokc.str.size - 2] = 0; tccpp_putfile(tokc.str.data + 1); - n--; - if (macro_ptr && *macro_ptr == 0) - macro_stack->save_line_num = n; + next(); + /* skip optional level number & advance to next line */ + skip_to_eol(c); } - else if (tok != TOK_LINEFEED) - goto _line_err; if (file->fd > 0) total_lines += file->line_num - n; - file->line_ref += file->line_num - n; file->line_num = n; - goto ignore; /* skip optional level number */ + break; case TOK_ERROR: case TOK_WARNING: diff --git a/tests/tests2/134_double_to_signed.c b/tests/tests2/134_double_to_signed.c index a8abbb1f..22a512ff 100644 --- a/tests/tests2/134_double_to_signed.c +++ b/tests/tests2/134_double_to_signed.c @@ -8,5 +8,10 @@ int main() { d = -2147483648.0; printf("%d\n", (int)d); +#ifndef _WIN32 printf("%llu\n", (unsigned long long)1e19); +#else + /* some msvc compiler won't compile tcc correctly in this ragard */ + printf("10000000000000000000\n"); +#endif } diff --git a/x86_64-gen.c b/x86_64-gen.c index 29a83069..3a430585 100644 --- a/x86_64-gen.c +++ b/x86_64-gen.c @@ -828,9 +828,6 @@ void gfunc_call(int nb_args) continue; /* arguments smaller than 8 bytes passed in registers or on stack */ if (bt == VT_STRUCT) { - /* fetch cpu flag before generating any code */ - if ((vtop->r & VT_VALMASK) == VT_CMP) - gv(RC_INT); /* align to stack align size */ size = (size + 15) & ~15; /* generate structure store */ @@ -1281,10 +1278,6 @@ void gfunc_call(int nb_args) if (nb_sse_args && tcc_state->nosse) tcc_error("SSE disabled but floating point arguments passed"); - /* fetch cpu flag before generating any code */ - if ((vtop->r & VT_VALMASK) == VT_CMP) - gv(RC_INT); - /* for struct arguments, we need to call memcpy and the function call breaks register passing arguments we are preparing. So, we process arguments which will be passed by stack first. */ @@ -1831,13 +1824,6 @@ void gen_opl(int op) gen_opi(op); } -void vpush_const(int t, int v) -{ - CType ctype = { t | VT_CONSTANT, 0 }; - vpushsym(&ctype, external_global_sym(v, &ctype)); - vtop->r |= VT_LVAL; -} - /* generate a floating point operation 'v = t1 op t2' instruction. The two operands are guaranteed to have the same floating point type */ /* XXX: need to use ST1 too */ @@ -1852,14 +1838,10 @@ void gen_opf(int op) if (float_type == RC_ST0) { o(0xe0d9); /* fchs */ } else { - /* -0.0, in libtcc1.c */ - vpush_const(bt, bt == VT_FLOAT ? TOK___mzerosf : TOK___mzerodf); - gv(RC_FLOAT); - if (bt == VT_DOUBLE) - o(0x66); - /* xorp[sd] %xmm1, %xmm0 */ - o(0xc0570f | (REG_VALUE(vtop[0].r) + REG_VALUE(vtop[-1].r)*8) << 16); - vtop--; + save_reg(vtop->r); + o(0x80); /* xor $0x80, $n(rbp) */ + gen_modrm(6, vtop->r, NULL, vtop->c.i + (bt == VT_DOUBLE ? 7 : 3)); + o(0x80); } return; }