Add support for asm labels for functions, that is the ability to rename a function at assembly level with __asm__ ("newname") appended in function declaration.
Unified · Split
| @@ -72,6 +72,12 @@ ST_DATA void *rt_prog_main; · 71 unmodified lines | ||
| 72 | 72 | #endif /* ALL_IN_ONE */ |
| 73 | 73 | |
| 74 | 74 | /********************************************************/ |
| 75 | +#ifndef CONFIG_TCC_ASM_LABEL | |
| 76 | +ST_FUNC void asm_label_instr(CString *) | |
| 77 | +{ | |
| 78 | + error("inline asm() not supported"); | |
| 79 | +} | |
| 80 | +#endif | |
| 75 | 81 | #ifndef CONFIG_TCC_ASM |
| 76 | 82 | ST_FUNC void asm_instr(void) |
| 77 | 83 | { |
| @@ -436,7 +442,10 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section, · 358 unmodified lines | ||
| 436 | 442 | } |
| 437 | 443 | |
| 438 | 444 | if (!sym->c) { |
| 439 | − name = get_tok_str(sym->v, NULL); | |
| 445 | + if (sym->a) | |
| 446 | + name = get_tok_str(sym->a, NULL); | |
| 447 | + else | |
| 448 | + name = get_tok_str(sym->v, NULL); | |
| 440 | 449 | #ifdef CONFIG_TCC_BCHECK |
| 441 | 450 | if (tcc_state->do_bounds_check) { |
| 442 | 451 | char buf[32]; |
| @@ -118,6 +118,7 @@ · 117 unmodified lines | ||
| 118 | 118 | #if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67) |
| 119 | 119 | #define CONFIG_TCC_ASM |
| 120 | 120 | #endif |
| 121 | +#define CONFIG_TCC_ASM_LABEL | |
| 121 | 122 | |
| 122 | 123 | /* object format selection */ |
| 123 | 124 | #if defined(TCC_TARGET_C67) |
| @@ -211,6 +212,7 @@ typedef struct SValue { · 87 unmodified lines | ||
| 211 | 212 | /* symbol management */ |
| 212 | 213 | typedef struct Sym { |
| 213 | 214 | int v; /* symbol token */ |
| 215 | + int a; /* asm symbol token */ | |
| 214 | 216 | long r; /* associated register */ |
| 215 | 217 | union { |
| 216 | 218 | long c; /* associated number */ |
| @@ -1189,6 +1191,7 @@ ST_FUNC int tcc_load_coff(TCCState * s1, int fd); · 972 unmodified lines | ||
| 1189 | 1191 | |
| 1190 | 1192 | /* ------------ tccasm.c ------------ */ |
| 1191 | 1193 | ST_FUNC void asm_instr(void); |
| 1194 | +ST_FUNC void asm_label_instr(CString *); | |
| 1192 | 1195 | ST_FUNC void asm_global_instr(void); |
| 1193 | 1196 | |
| 1194 | 1197 | #ifdef CONFIG_TCC_ASM |
| @@ -18,6 +18,8 @@ · 17 unmodified lines | ||
| 18 | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 19 | 19 | */ |
| 20 | 20 | |
| 21 | +#ifdef CONFIG_TCC_ASM | |
| 22 | + | |
| 21 | 23 | #include "tcc.h" |
| 22 | 24 | |
| 23 | 25 | ST_FUNC int asm_get_local_label_name(TCCState *s1, unsigned int n) |
| @@ -991,6 +993,8 @@ static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr, · 967 unmodified lines | ||
| 991 | 993 | } |
| 992 | 994 | } |
| 993 | 995 | |
| 996 | +#endif | |
| 997 | + | |
| 994 | 998 | static void parse_asm_str(CString *astr) |
| 995 | 999 | { |
| 996 | 1000 | skip('('); |
| @@ -1006,6 +1010,20 @@ static void parse_asm_str(CString *astr) · 9 unmodified lines | ||
| 1006 | 1010 | cstr_ccat(astr, '\0'); |
| 1007 | 1011 | } |
| 1008 | 1012 | |
| 1013 | +/* Parse an asm label and return the label | |
| 1014 | + * Don't forget to free the CString in the caller! */ | |
| 1015 | +static void asm_label_instr(CString *astr) | |
| 1016 | +{ | |
| 1017 | + next(); | |
| 1018 | + parse_asm_str(astr); | |
| 1019 | + skip(')'); | |
| 1020 | +#ifdef ASM_DEBUG | |
| 1021 | + printf("asm_alias: \"%s\"\n", (char *)astr->data); | |
| 1022 | +#endif | |
| 1023 | +} | |
| 1024 | + | |
| 1025 | +#ifdef CONFIG_TCC_ASM | |
| 1026 | + | |
| 1009 | 1027 | /* parse the GCC asm() instruction */ |
| 1010 | 1028 | ST_FUNC void asm_instr(void) |
| 1011 | 1029 | { |
| @@ -1136,3 +1154,5 @@ ST_FUNC void asm_global_instr(void) · 124 unmodified lines | ||
| 1136 | 1154 | |
| 1137 | 1155 | cstr_free(&astr); |
| 1138 | 1156 | } |
| 1157 | + | |
| 1158 | +#endif | |
| @@ -136,6 +136,7 @@ ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c) · 135 unmodified lines | ||
| 136 | 136 | { |
| 137 | 137 | Sym *s; |
| 138 | 138 | s = sym_malloc(); |
| 139 | + s->a = 0; | |
| 139 | 140 | s->v = v; |
| 140 | 141 | s->type.t = t; |
| 141 | 142 | s->type.ref = NULL; |
| @@ -368,6 +369,8 @@ static Sym *external_sym(int v, CType *type, int r) · 226 unmodified lines | ||
| 368 | 369 | if (!s) { |
| 369 | 370 | /* push forward reference */ |
| 370 | 371 | s = sym_push(v, type, r | VT_CONST | VT_SYM, 0); |
| 372 | + if (type && type->ref && type->ref->a) | |
| 373 | + s->a = type->ref->a; | |
| 371 | 374 | s->type.t |= VT_EXTERN; |
| 372 | 375 | } else if (s->type.ref == func_old_type.ref) { |
| 373 | 376 | s->type.ref = type->ref; |
| @@ -2996,6 +2999,8 @@ static void post_type(CType *type, AttributeDef *ad) · 2622 unmodified lines | ||
| 2996 | 2999 | CType pt; |
| 2997 | 3000 | |
| 2998 | 3001 | if (tok == '(') { |
| 3002 | + TokenSym *ts = NULL; | |
| 3003 | + | |
| 2999 | 3004 | /* function declaration */ |
| 3000 | 3005 | next(); |
| 3001 | 3006 | l = 0; |
| @@ -3051,10 +3056,19 @@ static void post_type(CType *type, AttributeDef *ad) · 49 unmodified lines | ||
| 3051 | 3056 | /* NOTE: const is ignored in returned type as it has a special |
| 3052 | 3057 | meaning in gcc / C++ */ |
| 3053 | 3058 | type->t &= ~(VT_STORAGE | VT_CONSTANT); |
| 3059 | + if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) { | |
| 3060 | + CString astr; | |
| 3061 | + | |
| 3062 | + asm_label_instr(&astr); | |
| 3063 | + ts = tok_alloc(astr.data, strlen(astr.data)); | |
| 3064 | + cstr_free(&astr); | |
| 3065 | + } | |
| 3054 | 3066 | post_type(type, ad); |
| 3055 | 3067 | /* we push a anonymous symbol which will contain the function prototype */ |
| 3056 | 3068 | ad->func_args = arg_size; |
| 3057 | 3069 | s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l); |
| 3070 | + if (ts != NULL) | |
| 3071 | + s->a = ts->tok; | |
| 3058 | 3072 | s->next = first; |
| 3059 | 3073 | type->t = t1 | VT_FUNC; |
| 3060 | 3074 | type->ref = s; |
| @@ -5228,7 +5242,10 @@ static void gen_function(Sym *sym) · 2167 unmodified lines | ||
| 5228 | 5242 | ind = cur_text_section->data_offset; |
| 5229 | 5243 | /* NOTE: we patch the symbol size later */ |
| 5230 | 5244 | put_extern_sym(sym, cur_text_section, ind, 0); |
| 5231 | − funcname = get_tok_str(sym->v, NULL); | |
| 5245 | + if (sym->a) | |
| 5246 | + funcname = get_tok_str(sym->a, NULL); | |
| 5247 | + else | |
| 5248 | + funcname = get_tok_str(sym->v, NULL); | |
| 5232 | 5249 | func_ind = ind; |
| 5233 | 5250 | /* put debug symbol */ |
| 5234 | 5251 | if (tcc_state->do_debug) |
| @@ -5308,6 +5325,12 @@ ST_FUNC void decl(int l) · 73 unmodified lines | ||
| 5308 | 5325 | Sym *sym; |
| 5309 | 5326 | AttributeDef ad; |
| 5310 | 5327 | |
| 5328 | + /* | |
| 5329 | + * type.ref must be either a valid reference or NULL for external_sym to | |
| 5330 | + * work. As type = btype is executed before external_sym is call, setting | |
| 5331 | + * btype.ref to 0 is enough. | |
| 5332 | + */ | |
| 5333 | + btype.ref = 0; | |
| 5311 | 5334 | while (1) { |
| 5312 | 5335 | if (!parse_btype(&btype, &ad)) { |
| 5313 | 5336 | /* skip redundant ';' */ |