mirror of
git://repo.or.cz/tinycc.git
synced 2026-06-21 20:34:18 +08:00
cleanups & stuff
libtcc.c:
- free 'elfint' string
- acceot -O and -Os
- accept -gstabs (to override dwarf when default)
- better -Wp,...
tccpp.c:
- #line cleanup
also warn with "extra tokens after directive"
tccgen.c & xxx_gen.c:
- force CPU flags to register earlier
tccelf.c:
- tcc_load_object: align size only for code sections
data/bss objects are always put with their specfic type align
(in decl_initializer_alloc())
x86/64 doesn't need aligned code
from c6afdff7ab
tccpe.c:
- enable dllimport for "_imp__<sym>" also from assembler
x86_64-gen.c & lib/libtcc1.c:
- simpler fneg without libtcc1 reference
tests2/134_double_to_signed.c:
- a tcc compiled by msvc won't pass this test
This commit is contained in:
parent
f075851f9d
commit
006174449e
14
arm-gen.c
14
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();
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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)
|
||||
|
||||
44
libtcc.c
44
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<num> (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;
|
||||
|
||||
@ -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;
|
||||
|
||||
3
tcc.c
3
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;
|
||||
|
||||
6
tcc.h
6
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);
|
||||
|
||||
9
tccelf.c
9
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: ;
|
||||
}
|
||||
|
||||
|
||||
3
tccgen.c
3
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;
|
||||
|
||||
8
tccpe.c
8
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;
|
||||
|
||||
25
tccpp.c
25
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:
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
26
x86_64-gen.c
26
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;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user