diff --git a/libtcc.c b/libtcc.c index 1a68f34..a9920c3 100644 --- a/libtcc.c +++ b/libtcc.c @@ -72,6 +72,12 @@ ST_DATA void *rt_prog_main; #endif /* ALL_IN_ONE */ /********************************************************/ +#ifndef CONFIG_TCC_ASM_LABEL +ST_FUNC void asm_label_instr(CString *) +{ + error("inline asm() not supported"); +} +#endif #ifndef CONFIG_TCC_ASM ST_FUNC void asm_instr(void) { @@ -436,7 +442,10 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section, } if (!sym->c) { - name = get_tok_str(sym->v, NULL); + if (sym->a) + name = get_tok_str(sym->a, NULL); + else + name = get_tok_str(sym->v, NULL); #ifdef CONFIG_TCC_BCHECK if (tcc_state->do_bounds_check) { char buf[32]; diff --git a/tcc.h b/tcc.h index bb3eb9f..30458a2 100644 --- a/tcc.h +++ b/tcc.h @@ -118,6 +118,7 @@ #if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67) #define CONFIG_TCC_ASM #endif +#define CONFIG_TCC_ASM_LABEL /* object format selection */ #if defined(TCC_TARGET_C67) @@ -211,6 +212,7 @@ typedef struct SValue { /* symbol management */ typedef struct Sym { int v; /* symbol token */ + int a; /* asm symbol token */ long r; /* associated register */ union { long c; /* associated number */ @@ -1189,6 +1191,7 @@ ST_FUNC int tcc_load_coff(TCCState * s1, int fd); /* ------------ tccasm.c ------------ */ ST_FUNC void asm_instr(void); +ST_FUNC void asm_label_instr(CString *); ST_FUNC void asm_global_instr(void); #ifdef CONFIG_TCC_ASM diff --git a/tccasm.c b/tccasm.c index 28c9fad..20d1fbc 100644 --- a/tccasm.c +++ b/tccasm.c @@ -18,6 +18,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifdef CONFIG_TCC_ASM + #include "tcc.h" 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, } } +#endif + static void parse_asm_str(CString *astr) { skip('('); @@ -1006,6 +1010,20 @@ static void parse_asm_str(CString *astr) cstr_ccat(astr, '\0'); } +/* Parse an asm label and return the label + * Don't forget to free the CString in the caller! */ +static void asm_label_instr(CString *astr) +{ + next(); + parse_asm_str(astr); + skip(')'); +#ifdef ASM_DEBUG + printf("asm_alias: \"%s\"\n", (char *)astr->data); +#endif +} + +#ifdef CONFIG_TCC_ASM + /* parse the GCC asm() instruction */ ST_FUNC void asm_instr(void) { @@ -1136,3 +1154,5 @@ ST_FUNC void asm_global_instr(void) cstr_free(&astr); } + +#endif diff --git a/tccgen.c b/tccgen.c index fecaedf..656c334 100644 --- a/tccgen.c +++ b/tccgen.c @@ -136,6 +136,7 @@ ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c) { Sym *s; s = sym_malloc(); + s->a = 0; s->v = v; s->type.t = t; s->type.ref = NULL; @@ -368,6 +369,8 @@ static Sym *external_sym(int v, CType *type, int r) if (!s) { /* push forward reference */ s = sym_push(v, type, r | VT_CONST | VT_SYM, 0); + if (type && type->ref && type->ref->a) + s->a = type->ref->a; s->type.t |= VT_EXTERN; } else if (s->type.ref == func_old_type.ref) { s->type.ref = type->ref; @@ -2996,6 +2999,8 @@ static void post_type(CType *type, AttributeDef *ad) CType pt; if (tok == '(') { + TokenSym *ts = NULL; + /* function declaration */ next(); l = 0; @@ -3051,10 +3056,19 @@ static void post_type(CType *type, AttributeDef *ad) /* NOTE: const is ignored in returned type as it has a special meaning in gcc / C++ */ type->t &= ~(VT_STORAGE | VT_CONSTANT); + if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) { + CString astr; + + asm_label_instr(&astr); + ts = tok_alloc(astr.data, strlen(astr.data)); + cstr_free(&astr); + } post_type(type, ad); /* we push a anonymous symbol which will contain the function prototype */ ad->func_args = arg_size; s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l); + if (ts != NULL) + s->a = ts->tok; s->next = first; type->t = t1 | VT_FUNC; type->ref = s; @@ -5228,7 +5242,10 @@ static void gen_function(Sym *sym) ind = cur_text_section->data_offset; /* NOTE: we patch the symbol size later */ put_extern_sym(sym, cur_text_section, ind, 0); - funcname = get_tok_str(sym->v, NULL); + if (sym->a) + funcname = get_tok_str(sym->a, NULL); + else + funcname = get_tok_str(sym->v, NULL); func_ind = ind; /* put debug symbol */ if (tcc_state->do_debug) @@ -5308,6 +5325,12 @@ ST_FUNC void decl(int l) Sym *sym; AttributeDef ad; + /* + * type.ref must be either a valid reference or NULL for external_sym to + * work. As type = btype is executed before external_sym is call, setting + * btype.ref to 0 is enough. + */ + btype.ref = 0; while (1) { if (!parse_btype(&btype, &ad)) { /* skip redundant ';' */