mirror of
https://github.com/mirror/tinycc.git
synced 2025-01-15 05:20:06 +08:00
Add support of asm label for functions.
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.
This commit is contained in:
parent
a7fb00e887
commit
9b09fc376e
11
libtcc.c
11
libtcc.c
@ -72,6 +72,12 @@ ST_DATA void *rt_prog_main;
|
|||||||
#endif /* ALL_IN_ONE */
|
#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
|
#ifndef CONFIG_TCC_ASM
|
||||||
ST_FUNC void asm_instr(void)
|
ST_FUNC void asm_instr(void)
|
||||||
{
|
{
|
||||||
@ -436,7 +442,10 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!sym->c) {
|
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
|
#ifdef CONFIG_TCC_BCHECK
|
||||||
if (tcc_state->do_bounds_check) {
|
if (tcc_state->do_bounds_check) {
|
||||||
char buf[32];
|
char buf[32];
|
||||||
|
3
tcc.h
3
tcc.h
@ -118,6 +118,7 @@
|
|||||||
#if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67)
|
#if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67)
|
||||||
#define CONFIG_TCC_ASM
|
#define CONFIG_TCC_ASM
|
||||||
#endif
|
#endif
|
||||||
|
#define CONFIG_TCC_ASM_LABEL
|
||||||
|
|
||||||
/* object format selection */
|
/* object format selection */
|
||||||
#if defined(TCC_TARGET_C67)
|
#if defined(TCC_TARGET_C67)
|
||||||
@ -211,6 +212,7 @@ typedef struct SValue {
|
|||||||
/* symbol management */
|
/* symbol management */
|
||||||
typedef struct Sym {
|
typedef struct Sym {
|
||||||
int v; /* symbol token */
|
int v; /* symbol token */
|
||||||
|
int a; /* asm symbol token */
|
||||||
long r; /* associated register */
|
long r; /* associated register */
|
||||||
union {
|
union {
|
||||||
long c; /* associated number */
|
long c; /* associated number */
|
||||||
@ -1189,6 +1191,7 @@ ST_FUNC int tcc_load_coff(TCCState * s1, int fd);
|
|||||||
|
|
||||||
/* ------------ tccasm.c ------------ */
|
/* ------------ tccasm.c ------------ */
|
||||||
ST_FUNC void asm_instr(void);
|
ST_FUNC void asm_instr(void);
|
||||||
|
ST_FUNC void asm_label_instr(CString *);
|
||||||
ST_FUNC void asm_global_instr(void);
|
ST_FUNC void asm_global_instr(void);
|
||||||
|
|
||||||
#ifdef CONFIG_TCC_ASM
|
#ifdef CONFIG_TCC_ASM
|
||||||
|
20
tccasm.c
20
tccasm.c
@ -18,6 +18,8 @@
|
|||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_TCC_ASM
|
||||||
|
|
||||||
#include "tcc.h"
|
#include "tcc.h"
|
||||||
|
|
||||||
ST_FUNC int asm_get_local_label_name(TCCState *s1, unsigned int n)
|
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)
|
static void parse_asm_str(CString *astr)
|
||||||
{
|
{
|
||||||
skip('(');
|
skip('(');
|
||||||
@ -1006,6 +1010,20 @@ static void parse_asm_str(CString *astr)
|
|||||||
cstr_ccat(astr, '\0');
|
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 */
|
/* parse the GCC asm() instruction */
|
||||||
ST_FUNC void asm_instr(void)
|
ST_FUNC void asm_instr(void)
|
||||||
{
|
{
|
||||||
@ -1136,3 +1154,5 @@ ST_FUNC void asm_global_instr(void)
|
|||||||
|
|
||||||
cstr_free(&astr);
|
cstr_free(&astr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
25
tccgen.c
25
tccgen.c
@ -136,6 +136,7 @@ ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
|
|||||||
{
|
{
|
||||||
Sym *s;
|
Sym *s;
|
||||||
s = sym_malloc();
|
s = sym_malloc();
|
||||||
|
s->a = 0;
|
||||||
s->v = v;
|
s->v = v;
|
||||||
s->type.t = t;
|
s->type.t = t;
|
||||||
s->type.ref = NULL;
|
s->type.ref = NULL;
|
||||||
@ -368,6 +369,8 @@ static Sym *external_sym(int v, CType *type, int r)
|
|||||||
if (!s) {
|
if (!s) {
|
||||||
/* push forward reference */
|
/* push forward reference */
|
||||||
s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
|
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;
|
s->type.t |= VT_EXTERN;
|
||||||
} else if (s->type.ref == func_old_type.ref) {
|
} else if (s->type.ref == func_old_type.ref) {
|
||||||
s->type.ref = type->ref;
|
s->type.ref = type->ref;
|
||||||
@ -2996,6 +2999,8 @@ static void post_type(CType *type, AttributeDef *ad)
|
|||||||
CType pt;
|
CType pt;
|
||||||
|
|
||||||
if (tok == '(') {
|
if (tok == '(') {
|
||||||
|
TokenSym *ts = NULL;
|
||||||
|
|
||||||
/* function declaration */
|
/* function declaration */
|
||||||
next();
|
next();
|
||||||
l = 0;
|
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
|
/* NOTE: const is ignored in returned type as it has a special
|
||||||
meaning in gcc / C++ */
|
meaning in gcc / C++ */
|
||||||
type->t &= ~(VT_STORAGE | VT_CONSTANT);
|
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);
|
post_type(type, ad);
|
||||||
/* we push a anonymous symbol which will contain the function prototype */
|
/* we push a anonymous symbol which will contain the function prototype */
|
||||||
ad->func_args = arg_size;
|
ad->func_args = arg_size;
|
||||||
s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
|
s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
|
||||||
|
if (ts != NULL)
|
||||||
|
s->a = ts->tok;
|
||||||
s->next = first;
|
s->next = first;
|
||||||
type->t = t1 | VT_FUNC;
|
type->t = t1 | VT_FUNC;
|
||||||
type->ref = s;
|
type->ref = s;
|
||||||
@ -5228,7 +5242,10 @@ static void gen_function(Sym *sym)
|
|||||||
ind = cur_text_section->data_offset;
|
ind = cur_text_section->data_offset;
|
||||||
/* NOTE: we patch the symbol size later */
|
/* NOTE: we patch the symbol size later */
|
||||||
put_extern_sym(sym, cur_text_section, ind, 0);
|
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;
|
func_ind = ind;
|
||||||
/* put debug symbol */
|
/* put debug symbol */
|
||||||
if (tcc_state->do_debug)
|
if (tcc_state->do_debug)
|
||||||
@ -5308,6 +5325,12 @@ ST_FUNC void decl(int l)
|
|||||||
Sym *sym;
|
Sym *sym;
|
||||||
AttributeDef ad;
|
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) {
|
while (1) {
|
||||||
if (!parse_btype(&btype, &ad)) {
|
if (!parse_btype(&btype, &ad)) {
|
||||||
/* skip redundant ';' */
|
/* skip redundant ';' */
|
||||||
|
Loading…
Reference in New Issue
Block a user