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 | #endif /* ALL_IN_ONE */ | 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 | #ifndef CONFIG_TCC_ASM | 81 | #ifndef CONFIG_TCC_ASM |
| 76 | ST_FUNC void asm_instr(void) | 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 | if (!sym->c) { | 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 | #ifdef CONFIG_TCC_BCHECK | 449 | #ifdef CONFIG_TCC_BCHECK |
| 441 | if (tcc_state->do_bounds_check) { | 450 | if (tcc_state->do_bounds_check) { |
| 442 | char buf[32]; | 451 | char buf[32]; |
| @@ -118,6 +118,7 @@ · 117 unmodified lines | |||
| 118 | #if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67) | 118 | #if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67) |
| 119 | #define CONFIG_TCC_ASM | 119 | #define CONFIG_TCC_ASM |
| 120 | #endif | 120 | #endif |
| 121 | #define CONFIG_TCC_ASM_LABEL | ||
| 121 | 122 | ||
| 122 | /* object format selection */ | 123 | /* object format selection */ |
| 123 | #if defined(TCC_TARGET_C67) | 124 | #if defined(TCC_TARGET_C67) |
| @@ -211,6 +212,7 @@ typedef struct SValue { · 87 unmodified lines | |||
| 211 | /* symbol management */ | 212 | /* symbol management */ |
| 212 | typedef struct Sym { | 213 | typedef struct Sym { |
| 213 | int v; /* symbol token */ | 214 | int v; /* symbol token */ |
| 215 | int a; /* asm symbol token */ | ||
| 214 | long r; /* associated register */ | 216 | long r; /* associated register */ |
| 215 | union { | 217 | union { |
| 216 | long c; /* associated number */ | 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 | /* ------------ tccasm.c ------------ */ | 1192 | /* ------------ tccasm.c ------------ */ |
| 1191 | ST_FUNC void asm_instr(void); | 1193 | ST_FUNC void asm_instr(void); |
| 1194 | ST_FUNC void asm_label_instr(CString *); | ||
| 1192 | ST_FUNC void asm_global_instr(void); | 1195 | ST_FUNC void asm_global_instr(void); |
| 1193 | 1196 | ||
| 1194 | #ifdef CONFIG_TCC_ASM | 1197 | #ifdef CONFIG_TCC_ASM |
| @@ -18,6 +18,8 @@ · 17 unmodified lines | |||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 19 | */ | 19 | */ |
| 20 | 20 | ||
| 21 | #ifdef CONFIG_TCC_ASM | ||
| 22 | |||
| 21 | #include "tcc.h" | 23 | #include "tcc.h" |
| 22 | 24 | ||
| 23 | ST_FUNC int asm_get_local_label_name(TCCState *s1, unsigned int n) | 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 | static void parse_asm_str(CString *astr) | 998 | static void parse_asm_str(CString *astr) |
| 995 | { | 999 | { |
| 996 | skip('('); | 1000 | skip('('); |
| @@ -1006,6 +1010,20 @@ static void parse_asm_str(CString *astr) · 9 unmodified lines | |||
| 1006 | cstr_ccat(astr, '\0'); | 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 | /* parse the GCC asm() instruction */ | 1027 | /* parse the GCC asm() instruction */ |
| 1010 | ST_FUNC void asm_instr(void) | 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 | cstr_free(&astr); | 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 | Sym *s; | 137 | Sym *s; |
| 138 | s = sym_malloc(); | 138 | s = sym_malloc(); |
| 139 | s->a = 0; | ||
| 139 | s->v = v; | 140 | s->v = v; |
| 140 | s->type.t = t; | 141 | s->type.t = t; |
| 141 | s->type.ref = NULL; | 142 | s->type.ref = NULL; |
| @@ -368,6 +369,8 @@ static Sym *external_sym(int v, CType *type, int r) · 226 unmodified lines | |||
| 368 | if (!s) { | 369 | if (!s) { |
| 369 | /* push forward reference */ | 370 | /* push forward reference */ |
| 370 | s = sym_push(v, type, r | VT_CONST | VT_SYM, 0); | 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 | s->type.t |= VT_EXTERN; | 374 | s->type.t |= VT_EXTERN; |
| 372 | } else if (s->type.ref == func_old_type.ref) { | 375 | } else if (s->type.ref == func_old_type.ref) { |
| 373 | s->type.ref = type->ref; | 376 | s->type.ref = type->ref; |
| @@ -2996,6 +2999,8 @@ static void post_type(CType *type, AttributeDef *ad) · 2622 unmodified lines | |||
| 2996 | CType pt; | 2999 | CType pt; |
| 2997 | 3000 | ||
| 2998 | if (tok == '(') { | 3001 | if (tok == '(') { |
| 3002 | TokenSym *ts = NULL; | ||
| 3003 | |||
| 2999 | /* function declaration */ | 3004 | /* function declaration */ |
| 3000 | next(); | 3005 | next(); |
| 3001 | l = 0; | 3006 | l = 0; |
| @@ -3051,10 +3056,19 @@ static void post_type(CType *type, AttributeDef *ad) · 49 unmodified lines | |||
| 3051 | /* NOTE: const is ignored in returned type as it has a special | 3056 | /* NOTE: const is ignored in returned type as it has a special |
| 3052 | meaning in gcc / C++ */ | 3057 | meaning in gcc / C++ */ |
| 3053 | type->t &= ~(VT_STORAGE | VT_CONSTANT); | 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 | post_type(type, ad); | 3066 | post_type(type, ad); |
| 3055 | /* we push a anonymous symbol which will contain the function prototype */ | 3067 | /* we push a anonymous symbol which will contain the function prototype */ |
| 3056 | ad->func_args = arg_size; | 3068 | ad->func_args = arg_size; |
| 3057 | s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l); | 3069 | s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l); |
| 3070 | if (ts != NULL) | ||
| 3071 | s->a = ts->tok; | ||
| 3058 | s->next = first; | 3072 | s->next = first; |
| 3059 | type->t = t1 | VT_FUNC; | 3073 | type->t = t1 | VT_FUNC; |
| 3060 | type->ref = s; | 3074 | type->ref = s; |
| @@ -5228,7 +5242,10 @@ static void gen_function(Sym *sym) · 2167 unmodified lines | |||
| 5228 | ind = cur_text_section->data_offset; | 5242 | ind = cur_text_section->data_offset; |
| 5229 | /* NOTE: we patch the symbol size later */ | 5243 | /* NOTE: we patch the symbol size later */ |
| 5230 | put_extern_sym(sym, cur_text_section, ind, 0); | 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 | func_ind = ind; | 5249 | func_ind = ind; |
| 5233 | /* put debug symbol */ | 5250 | /* put debug symbol */ |
| 5234 | if (tcc_state->do_debug) | 5251 | if (tcc_state->do_debug) |
| @@ -5308,6 +5325,12 @@ ST_FUNC void decl(int l) · 73 unmodified lines | |||
| 5308 | Sym *sym; | 5325 | Sym *sym; |
| 5309 | AttributeDef ad; | 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 | while (1) { | 5334 | while (1) { |
| 5312 | if (!parse_btype(&btype, &ad)) { | 5335 | if (!parse_btype(&btype, &ad)) { |
| 5313 | /* skip redundant ';' */ | 5336 | /* skip redundant ';' */ |