aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libtcc.c11
-rw-r--r--tcc.h3
-rw-r--r--tccasm.c20
-rw-r--r--tccgen.c25
4 files changed, 57 insertions, 2 deletions
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 ';' */