From 4a42b0d95e5e376aedfc8e95e8555110c7a7293a Mon Sep 17 00:00:00 2001 From: grischka Date: Mon, 23 Nov 2020 20:15:16 +0100 Subject: [PATCH] tidy support for helper function such as memmove tcc.h, tccgen.c: Introduce Sym *external_helper_sym(int v); to create an external reference with no specific type. This avoids type conflicts if the symbol is used from C too. the other files: use it. --- arm-gen.c | 10 ++++----- arm64-gen.c | 12 +++++------ c67-gen.c | 6 +++--- i386-gen.c | 10 ++++----- riscv64-gen.c | 12 +++++------ tcc.h | 3 ++- tccgen.c | 58 +++++++++++++++++++++++++-------------------------- x86_64-gen.c | 6 +++--- 8 files changed, 59 insertions(+), 58 deletions(-) diff --git a/arm-gen.c b/arm-gen.c index 20ceac4e..91b62c67 100644 --- a/arm-gen.c +++ b/arm-gen.c @@ -785,7 +785,7 @@ static void gcall_or_jmp(int is_jmp) static void gen_bounds_call(int v) { - Sym *sym = external_global_sym(v, &func_old_type); + Sym *sym = external_helper_sym(v); greloc(cur_text_section, sym, ind, R_ARM_PC24); o(0xebfffffe); @@ -1717,7 +1717,7 @@ done: vtop--; break; case 3: - vpush_global_sym(&func_old_type, func); + vpush_helper_func(func); vrott(3); gfunc_call(2); vpushi(0); @@ -2137,7 +2137,7 @@ ST_FUNC void gen_cvt_itof(int t) func=TOK___floatdidf; } if(func_type) { - vpush_global_sym(func_type, func); + vpushsym(func_type, external_helper_sym(func)); vswap(); gfunc_call(1); vpushi(0); @@ -2196,7 +2196,7 @@ void gen_cvt_ftoi(int t) func=TOK___fixdfdi; } if(func) { - vpush_global_sym(&func_old_type, func); + vpush_helper_func(func); vswap(); gfunc_call(1); vpushi(0); @@ -2277,7 +2277,7 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) { vtop->r = TREG_R0; o(0xe1a0000d | (vtop->r << 12)); // mov r0,sp vswap(); - vpush_global_sym(&func_old_type, TOK___bound_new_region); + vpush_helper_func(TOK___bound_new_region); vrott(3); gfunc_call(2); func_bound_add_epilog = 1; diff --git a/arm64-gen.c b/arm64-gen.c index ed09afef..61ca1e36 100644 --- a/arm64-gen.c +++ b/arm64-gen.c @@ -662,7 +662,7 @@ static void arm64_gen_bl_or_b(int b) static void gen_bounds_call(int v) { - Sym *sym = external_global_sym(v, &func_old_type); + Sym *sym = external_helper_sym(v); greloca(cur_text_section, sym, ind, R_AARCH64_CALL26, 0); o(0x94000000); // bl @@ -1782,7 +1782,7 @@ ST_FUNC void gen_opf(int op) case TOK_GT: func = TOK___gttf2; cond = 13; break; default: assert(0); break; } - vpush_global_sym(&func_old_type, func); + vpush_helper_func(func); vrott(3); gfunc_call(2); vpushi(0); @@ -1885,7 +1885,7 @@ ST_FUNC void gen_cvt_itof(int t) int func = (f & VT_BTYPE) == VT_LLONG ? (f & VT_UNSIGNED ? TOK___floatunditf : TOK___floatditf) : (f & VT_UNSIGNED ? TOK___floatunsitf : TOK___floatsitf); - vpush_global_sym(&func_old_type, func); + vpush_helper_func(func); vrott(2); gfunc_call(1); vpushi(0); @@ -1913,7 +1913,7 @@ ST_FUNC void gen_cvt_ftoi(int t) int func = (t & VT_BTYPE) == VT_LLONG ? (t & VT_UNSIGNED ? TOK___fixunstfdi : TOK___fixtfdi) : (t & VT_UNSIGNED ? TOK___fixunstfsi : TOK___fixtfsi); - vpush_global_sym(&func_old_type, func); + vpush_helper_func(func); vrott(2); gfunc_call(1); vpushi(0); @@ -1947,7 +1947,7 @@ ST_FUNC void gen_cvt_ftof(int t) int func = (t == VT_LDOUBLE) ? (f == VT_FLOAT ? TOK___extendsftf2 : TOK___extenddftf2) : (t == VT_FLOAT ? TOK___trunctfsf2 : TOK___trunctfdf2); - vpush_global_sym(&func_old_type, func); + vpush_helper_func(func); vrott(2); gfunc_call(1); vpushi(0); @@ -2061,7 +2061,7 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) { vtop->r = TREG_R(0); o(0x910003e0 | vtop->r); // mov r0,sp vswap(); - vpush_global_sym(&func_old_type, TOK___bound_new_region); + vpush_helper_func(TOK___bound_new_region); vrott(3); gfunc_call(2); func_bound_add_epilog = 1; diff --git a/c67-gen.c b/c67-gen.c index 2498aed7..3f963617 100644 --- a/c67-gen.c +++ b/c67-gen.c @@ -2254,7 +2254,7 @@ void gen_opi(int op) call_func: vswap(); /* call generic idiv function */ - vpush_global_sym(&func_old_type, t); + vpush_helper_func(t); vrott(3); gfunc_call(2); vpushi(0); @@ -2385,7 +2385,7 @@ void gen_opf(int op) // must call intrinsic DP floating point divide vswap(); /* call generic idiv function */ - vpush_global_sym(&func_old_type, TOK__divd); + vpush_helper_func(TOK__divd); vrott(3); gfunc_call(2); vpushi(0); @@ -2396,7 +2396,7 @@ void gen_opf(int op) // must call intrinsic SP floating point divide vswap(); /* call generic idiv function */ - vpush_global_sym(&func_old_type, TOK__divf); + vpush_helper_func(TOK__divf); vrott(3); gfunc_call(2); vpushi(0); diff --git a/i386-gen.c b/i386-gen.c index 8a0fb355..d2727980 100644 --- a/i386-gen.c +++ b/i386-gen.c @@ -345,7 +345,7 @@ static void gen_static_call(int v) { Sym *sym; - sym = external_global_sym(v, &func_old_type); + sym = external_helper_sym(v); oad(0xe8, -4); greloc(cur_text_section, sym, ind-4, R_386_PC32); } @@ -985,11 +985,11 @@ ST_FUNC void gen_cvt_ftoi(int t) { int bt = vtop->type.t & VT_BTYPE; if (bt == VT_FLOAT) - vpush_global_sym(&func_old_type, TOK___fixsfdi); + vpush_helper_func(TOK___fixsfdi); else if (bt == VT_LDOUBLE) - vpush_global_sym(&func_old_type, TOK___fixxfdi); + vpush_helper_func(TOK___fixxfdi); else - vpush_global_sym(&func_old_type, TOK___fixdfdi); + vpush_helper_func(TOK___fixdfdi); vswap(); gfunc_call(1); vpushi(0); @@ -1099,7 +1099,7 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) { #endif if (use_call) { - vpush_global_sym(&func_old_type, TOK_alloca); + vpush_helper_func(TOK_alloca); vswap(); /* Move alloca ref past allocation size */ gfunc_call(1); } diff --git a/riscv64-gen.c b/riscv64-gen.c index 33e049ac..413adc30 100644 --- a/riscv64-gen.c +++ b/riscv64-gen.c @@ -402,7 +402,7 @@ static void gcall_or_jmp(int docall) static void gen_bounds_call(int v) { - Sym *sym = external_global_sym(v, &func_old_type); + Sym *sym = external_helper_sym(v); greloca(cur_text_section, sym, ind, R_RISCV_CALL_PLT, 0); o(0x17 | (1 << 7)); // auipc TR, 0 %call(func) @@ -1125,7 +1125,7 @@ ST_FUNC void gen_opf(int op) case TOK_GT: func = TOK___gttf2; cond = 13; break; default: assert(0); break; } - vpush_global_sym(&func_old_type, func); + vpush_helper_func(func); vrott(3); gfunc_call(2); vpushi(0); @@ -1213,7 +1213,7 @@ ST_FUNC void gen_cvt_itof(int t) int func = l ? (u ? TOK___floatunditf : TOK___floatditf) : (u ? TOK___floatunsitf : TOK___floatsitf); - vpush_global_sym(&func_old_type, func); + vpush_helper_func(func); vrott(2); gfunc_call(1); vpushi(0); @@ -1239,7 +1239,7 @@ ST_FUNC void gen_cvt_ftoi(int t) int func = l ? (u ? TOK___fixunstfdi : TOK___fixtfdi) : (u ? TOK___fixunstfsi : TOK___fixtfsi); - vpush_global_sym(&func_old_type, func); + vpush_helper_func(func); vrott(2); gfunc_call(1); vpushi(0); @@ -1281,7 +1281,7 @@ ST_FUNC void gen_cvt_ftof(int dt) vtop->r2 = 1 + vtop->r; } } - vpush_global_sym(&func_old_type, func); + vpush_helper_func(func); gcall_or_jmp(1); vtop -= 2; vpushi(0); @@ -1342,7 +1342,7 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) vtop->r = TREG_R(0); o(0x00010513); /* mv a0,sp */ vswap(); - vpush_global_sym(&func_old_type, TOK___bound_new_region); + vpush_helper_func(TOK___bound_new_region); vrott(3); gfunc_call(2); func_bound_add_epilog = 1; diff --git a/tcc.h b/tcc.h index ccb3b603..3c130ec0 100644 --- a/tcc.h +++ b/tcc.h @@ -1437,10 +1437,11 @@ ST_FUNC void vpushi(int v); ST_FUNC ElfSym *elfsym(Sym *); ST_FUNC void update_storage(Sym *sym); ST_FUNC Sym *external_global_sym(int v, CType *type); +ST_FUNC Sym *external_helper_sym(int v); +ST_FUNC void vpush_helper_func(int v); ST_FUNC void vset(CType *type, int r, int v); ST_FUNC void vset_VT_CMP(int op); ST_FUNC void vswap(void); -ST_FUNC void vpush_global_sym(CType *type, int v); ST_FUNC void vrote(SValue *e, int n); ST_FUNC void vrott(int n); ST_FUNC void vrotb(int n); diff --git a/tccgen.c b/tccgen.c index 3b2201ca..61c538e6 100644 --- a/tccgen.c +++ b/tccgen.c @@ -80,7 +80,7 @@ ST_DATA int func_var; /* true if current function is variadic (used by return in ST_DATA int func_vc; static int last_line_num, new_file, func_ind; /* debug info control */ ST_DATA const char *funcname; -ST_DATA CType int_type, func_old_type, char_type, char_pointer_type, func_mem_move, void_type, void_ptr_type; +ST_DATA CType int_type, func_old_type, char_type, char_pointer_type; static CString initstr; #if PTR_SIZE == 4 @@ -800,14 +800,6 @@ ST_FUNC void tccgen_init(TCCState *s1) char_pointer_type = char_type; mk_pointer(&char_pointer_type); - void_type.t = VT_VOID; - void_ptr_type = void_type; - mk_pointer(&void_ptr_type); - func_mem_move.t = VT_FUNC; - func_mem_move.ref = sym_push(SYM_FIELD, &void_ptr_type, 0, 0); - func_mem_move.ref->f.func_call = FUNC_CDECL; - func_mem_move.ref->f.func_type = FUNC_OLD; - func_old_type.t = VT_FUNC; func_old_type.ref = sym_push(SYM_FIELD, &int_type, 0, 0); func_old_type.ref->f.func_call = FUNC_CDECL; @@ -1493,6 +1485,20 @@ ST_FUNC Sym *external_global_sym(int v, CType *type) return s; } +/* create an external reference with no specific type similar to asm labels. + This avoids type conflicts if the symbol is used from C too */ +ST_FUNC Sym *external_helper_sym(int v) +{ + CType ct = { VT_ASM, NULL }; + return external_global_sym(v, &ct); +} + +/* push a reference to an helper function (such as memmove) */ +ST_FUNC void vpush_helper_func(int v) +{ + vpushsym(&func_old_type, external_helper_sym(v)); +} + /* Merge symbol attributes. */ static void merge_symattr(struct SymAttr *sa, struct SymAttr *sa1) { @@ -1681,12 +1687,6 @@ static Sym *external_sym(int v, CType *type, int r, AttributeDef *ad) return s; } -/* push a reference to global symbol v */ -ST_FUNC void vpush_global_sym(CType *type, int v) -{ - vpushsym(type, external_global_sym(v, type)); -} - /* save registers up to (vtop - n) stack entry */ ST_FUNC void save_regs(int n) { @@ -1904,7 +1904,7 @@ static void gen_bounded_ptr_add(void) vpushv(&vtop[-1]); vrott(3); } - vpush_global_sym(&func_old_type, TOK___bound_ptr_add); + vpush_helper_func(TOK___bound_ptr_add); vrott(3); gfunc_call(2); vtop -= save; @@ -1941,7 +1941,7 @@ static void gen_bounded_ptr_deref(void) /* may happen with struct member access */ return; } - sym = external_global_sym(func, &func_old_type); + sym = external_helper_sym(func); if (!sym->c) put_extern_sym(sym, NULL, 0, 0); /* patch relocation */ @@ -1998,7 +1998,7 @@ ST_FUNC void gbound_args(int nb_args) || v == TOK___sigsetjmp #endif ) { - vpush_global_sym(&func_old_type, TOK___bound_setjmp); + vpush_helper_func(TOK___bound_setjmp); vpushv(sv + 1); gfunc_call(1); func_bound_add_epilog = 1; @@ -2415,7 +2415,7 @@ static void gen_opl(int op) #endif gen_func: /* call generic long long function */ - vpush_global_sym(&func_old_type, func); + vpush_helper_func(func); vrott(3); gfunc_call(2); vpushi(0); @@ -3379,13 +3379,13 @@ static void gen_cvt_itof1(int t) (VT_LLONG | VT_UNSIGNED)) { if (t == VT_FLOAT) - vpush_global_sym(&func_old_type, TOK___floatundisf); + vpush_helper_func(TOK___floatundisf); #if LDOUBLE_SIZE != 8 else if (t == VT_LDOUBLE) - vpush_global_sym(&func_old_type, TOK___floatundixf); + vpush_helper_func(TOK___floatundixf); #endif else - vpush_global_sym(&func_old_type, TOK___floatundidf); + vpush_helper_func(TOK___floatundidf); vrott(2); gfunc_call(1); vpushi(0); @@ -3407,13 +3407,13 @@ static void gen_cvt_ftoi1(int t) /* not handled natively */ st = vtop->type.t & VT_BTYPE; if (st == VT_FLOAT) - vpush_global_sym(&func_old_type, TOK___fixunssfdi); + vpush_helper_func(TOK___fixunssfdi); #if LDOUBLE_SIZE != 8 else if (st == VT_LDOUBLE) - vpush_global_sym(&func_old_type, TOK___fixunsxfdi); + vpush_helper_func(TOK___fixunsxfdi); #endif else - vpush_global_sym(&func_old_type, TOK___fixunsdfdi); + vpush_helper_func(TOK___fixunsdfdi); vrott(2); gfunc_call(1); vpushi(0); @@ -3904,13 +3904,13 @@ ST_FUNC void vstore(void) /* address of memcpy() */ #ifdef TCC_ARM_EABI if(!(align & 7)) - vpush_global_sym(&func_old_type, TOK_memmove8); + vpush_helper_func(TOK_memmove8); else if(!(align & 3)) - vpush_global_sym(&func_old_type, TOK_memmove4); + vpush_helper_func(TOK_memmove4); else #endif /* Use memmove, rather than memcpy, as dest and src may be same: */ - vpush_global_sym(&func_mem_move, TOK_memmove); + vpush_helper_func(TOK_memmove); vswap(); /* source */ @@ -7363,7 +7363,7 @@ static void init_putz(init_params *p, unsigned long c, int size) if (p->sec) { /* nothing to do because globals are already set to zero */ } else { - vpush_global_sym(&func_old_type, TOK_memset); + vpush_helper_func(TOK_memset); vseti(VT_LOCAL, c); #ifdef TCC_TARGET_ARM vpushs(size); diff --git a/x86_64-gen.c b/x86_64-gen.c index 44ff3e51..57e24718 100644 --- a/x86_64-gen.c +++ b/x86_64-gen.c @@ -653,7 +653,7 @@ static void gcall_or_jmp(int is_jmp) static void gen_bounds_call(int v) { - Sym *sym = external_global_sym(v, &func_old_type); + Sym *sym = external_helper_sym(v); oad(0xe8, 0); #ifdef TCC_TARGET_PE greloca(cur_text_section, sym, ind-4, R_X86_64_PC32, -4); @@ -1022,7 +1022,7 @@ void gfunc_epilog(void) v = -loc; if (v >= 4096) { - Sym *sym = external_global_sym(TOK___chkstk, &func_old_type); + Sym *sym = external_helper_sym(TOK___chkstk); oad(0xb8, v); /* mov stacksize, %eax */ oad(0xe8, 0); /* call __chkstk, (does the stackframe too) */ greloca(cur_text_section, sym, ind-4, R_X86_64_PC32, -4); @@ -2209,7 +2209,7 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) { #endif if (use_call) { - vpush_global_sym(&func_old_type, TOK_alloca); + vpush_helper_func(TOK_alloca); vswap(); /* Move alloca ref past allocation size */ gfunc_call(1); }