mirror of
https://github.com/mirror/tinycc.git
synced 2025-02-04 06:30:10 +08:00
be stricter with aliasing
Refactoring (no logical changes): - use memcpy in tccgen.c:ieee_finite(double d) - use union to store attribute flags in Sym Makefile: "CFLAGS+=-fno-strict-aliasing" basically not necessary anymore but I left it for now because gcc sometimes behaves unexpectedly without. Also: - configure: back to mode 100755 - tcc.h: remove unused variables tdata/tbss_section - x86_64-gen.c: adjust gfunc_sret for prototype
This commit is contained in:
parent
2bd0daabbe
commit
3fe2a95d7f
@ -457,7 +457,7 @@ ST_FUNC void gfunc_call(int nb_args)
|
|||||||
}
|
}
|
||||||
save_regs(0); /* save used temporary registers */
|
save_regs(0); /* save used temporary registers */
|
||||||
func_sym = vtop->type.ref;
|
func_sym = vtop->type.ref;
|
||||||
func_call = FUNC_CALL(func_sym->r);
|
func_call = func_sym->a.func_call;
|
||||||
/* fast call case */
|
/* fast call case */
|
||||||
if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) ||
|
if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) ||
|
||||||
func_call == FUNC_FASTCALLW) {
|
func_call == FUNC_FASTCALLW) {
|
||||||
@ -505,7 +505,7 @@ ST_FUNC void gfunc_prolog(CType *func_type)
|
|||||||
CType *type;
|
CType *type;
|
||||||
|
|
||||||
sym = func_type->ref;
|
sym = func_type->ref;
|
||||||
func_call = FUNC_CALL(sym->r);
|
func_call = sym->a.func_call;
|
||||||
addr = 8;
|
addr = 8;
|
||||||
loc = 0;
|
loc = 0;
|
||||||
func_vc = 0;
|
func_vc = 0;
|
||||||
|
8
libtcc.c
8
libtcc.c
@ -493,11 +493,11 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section,
|
|||||||
if (sym->type.t & VT_EXPORT)
|
if (sym->type.t & VT_EXPORT)
|
||||||
other |= 1;
|
other |= 1;
|
||||||
if (sym_type == STT_FUNC && sym->type.ref) {
|
if (sym_type == STT_FUNC && sym->type.ref) {
|
||||||
int attr = sym->type.ref->r;
|
Sym *ref = sym->type.ref;
|
||||||
if (FUNC_EXPORT(attr))
|
if (ref->a.func_export)
|
||||||
other |= 1;
|
other |= 1;
|
||||||
if (FUNC_CALL(attr) == FUNC_STDCALL && can_add_underscore) {
|
if (ref->a.func_call == FUNC_STDCALL && can_add_underscore) {
|
||||||
sprintf(buf1, "_%s@%d", name, FUNC_ARGS(attr) * PTR_SIZE);
|
sprintf(buf1, "_%s@%d", name, ref->a.func_args * PTR_SIZE);
|
||||||
name = buf1;
|
name = buf1;
|
||||||
other |= 2;
|
other |= 2;
|
||||||
can_add_underscore = 0;
|
can_add_underscore = 0;
|
||||||
|
57
tcc.h
57
tcc.h
@ -326,11 +326,35 @@ typedef struct SValue {
|
|||||||
struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST) */
|
struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST) */
|
||||||
} SValue;
|
} SValue;
|
||||||
|
|
||||||
|
struct Attribute {
|
||||||
|
unsigned
|
||||||
|
func_call : 3, /* calling convention (0..5), see below */
|
||||||
|
aligned : 5, /* alignement (0..16) */
|
||||||
|
packed : 1,
|
||||||
|
func_export : 1,
|
||||||
|
func_import : 1,
|
||||||
|
func_args : 5,
|
||||||
|
func_proto : 1,
|
||||||
|
mode : 4,
|
||||||
|
weak : 1,
|
||||||
|
fill : 10; // 10 bits left to fit well in union below
|
||||||
|
};
|
||||||
|
|
||||||
|
/* GNUC attribute definition */
|
||||||
|
typedef struct AttributeDef {
|
||||||
|
struct Attribute a;
|
||||||
|
struct Section *section;
|
||||||
|
int alias_target; /* token */
|
||||||
|
} AttributeDef;
|
||||||
|
|
||||||
/* symbol management */
|
/* symbol management */
|
||||||
typedef struct Sym {
|
typedef struct Sym {
|
||||||
int v; /* symbol token */
|
int v; /* symbol token */
|
||||||
char *asm_label; /* associated asm label */
|
char *asm_label; /* associated asm label */
|
||||||
long r; /* associated register */
|
union {
|
||||||
|
long r; /* associated register */
|
||||||
|
struct Attribute a;
|
||||||
|
};
|
||||||
union {
|
union {
|
||||||
long c; /* associated number */
|
long c; /* associated number */
|
||||||
int *d; /* define token stream */
|
int *d; /* define token stream */
|
||||||
@ -381,34 +405,6 @@ typedef struct DLLReference {
|
|||||||
char name[1];
|
char name[1];
|
||||||
} DLLReference;
|
} DLLReference;
|
||||||
|
|
||||||
/* GNUC attribute definition */
|
|
||||||
typedef struct AttributeDef {
|
|
||||||
unsigned
|
|
||||||
func_call : 3, /* calling convention (0..5), see below */
|
|
||||||
aligned : 5, /* alignement (0..16) */
|
|
||||||
packed : 1,
|
|
||||||
func_export : 1,
|
|
||||||
func_import : 1,
|
|
||||||
func_args : 5,
|
|
||||||
func_proto : 1,
|
|
||||||
mode : 4,
|
|
||||||
weak : 1,
|
|
||||||
fill : 10;
|
|
||||||
struct Section *section;
|
|
||||||
int alias_target; /* token */
|
|
||||||
} AttributeDef;
|
|
||||||
|
|
||||||
/* gr: wrappers for casting sym->r for other purposes */
|
|
||||||
#define FUNC_CALL(r) (((AttributeDef*)&(r))->func_call)
|
|
||||||
#define FUNC_EXPORT(r) (((AttributeDef*)&(r))->func_export)
|
|
||||||
#define FUNC_IMPORT(r) (((AttributeDef*)&(r))->func_import)
|
|
||||||
#define FUNC_ARGS(r) (((AttributeDef*)&(r))->func_args)
|
|
||||||
#define FUNC_PROTO(r) (((AttributeDef*)&(r))->func_proto)
|
|
||||||
#define FUNC_ALIGN(r) (((AttributeDef*)&(r))->aligned)
|
|
||||||
#define FUNC_PACKED(r) (((AttributeDef*)&(r))->packed)
|
|
||||||
#define ATTR_MODE(r) (((AttributeDef*)&(r))->mode)
|
|
||||||
#define INT_ATTR(ad) (*(int*)(ad))
|
|
||||||
|
|
||||||
/* -------------------------------------------------- */
|
/* -------------------------------------------------- */
|
||||||
|
|
||||||
#define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
|
#define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
|
||||||
@ -1142,7 +1138,6 @@ ST_FUNC void expect(const char *msg);
|
|||||||
/* ------------ tccgen.c ------------ */
|
/* ------------ tccgen.c ------------ */
|
||||||
|
|
||||||
ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
|
ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
|
||||||
ST_DATA Section *tdata_section, *tbss_section; /* thread-local storage sections */
|
|
||||||
ST_DATA Section *cur_text_section; /* current section where function code is generated */
|
ST_DATA Section *cur_text_section; /* current section where function code is generated */
|
||||||
#ifdef CONFIG_TCC_ASM
|
#ifdef CONFIG_TCC_ASM
|
||||||
ST_DATA Section *last_text_section; /* to handle .previous asm directive */
|
ST_DATA Section *last_text_section; /* to handle .previous asm directive */
|
||||||
@ -1268,7 +1263,7 @@ ST_FUNC void build_got_entries(TCCState *s1);
|
|||||||
ST_FUNC void tcc_add_runtime(TCCState *s1);
|
ST_FUNC void tcc_add_runtime(TCCState *s1);
|
||||||
|
|
||||||
ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err);
|
ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err);
|
||||||
#ifdef TCC_IS_NATIVE
|
#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
|
||||||
ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name);
|
ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
97
tccgen.c
97
tccgen.c
@ -103,7 +103,8 @@ ST_INLN int is_float(int t)
|
|||||||
/* XXX: endianness dependent */
|
/* XXX: endianness dependent */
|
||||||
ST_FUNC int ieee_finite(double d)
|
ST_FUNC int ieee_finite(double d)
|
||||||
{
|
{
|
||||||
int *p = (int *)&d;
|
int p[4];
|
||||||
|
memcpy(p, &d, sizeof(double));
|
||||||
return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
|
return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2172,7 +2173,7 @@ static int is_compatible_func(CType *type1, CType *type2)
|
|||||||
if (!is_compatible_types(&s1->type, &s2->type))
|
if (!is_compatible_types(&s1->type, &s2->type))
|
||||||
return 0;
|
return 0;
|
||||||
/* check func_call */
|
/* check func_call */
|
||||||
if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
|
if (s1->a.func_call != s2->a.func_call)
|
||||||
return 0;
|
return 0;
|
||||||
/* XXX: not complete */
|
/* XXX: not complete */
|
||||||
if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
|
if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
|
||||||
@ -2659,15 +2660,15 @@ static void parse_attribute(AttributeDef *ad)
|
|||||||
} else {
|
} else {
|
||||||
n = MAX_ALIGN;
|
n = MAX_ALIGN;
|
||||||
}
|
}
|
||||||
ad->aligned = n;
|
ad->a.aligned = n;
|
||||||
break;
|
break;
|
||||||
case TOK_PACKED1:
|
case TOK_PACKED1:
|
||||||
case TOK_PACKED2:
|
case TOK_PACKED2:
|
||||||
ad->packed = 1;
|
ad->a.packed = 1;
|
||||||
break;
|
break;
|
||||||
case TOK_WEAK1:
|
case TOK_WEAK1:
|
||||||
case TOK_WEAK2:
|
case TOK_WEAK2:
|
||||||
ad->weak = 1;
|
ad->a.weak = 1;
|
||||||
break;
|
break;
|
||||||
case TOK_UNUSED1:
|
case TOK_UNUSED1:
|
||||||
case TOK_UNUSED2:
|
case TOK_UNUSED2:
|
||||||
@ -2682,12 +2683,12 @@ static void parse_attribute(AttributeDef *ad)
|
|||||||
case TOK_CDECL1:
|
case TOK_CDECL1:
|
||||||
case TOK_CDECL2:
|
case TOK_CDECL2:
|
||||||
case TOK_CDECL3:
|
case TOK_CDECL3:
|
||||||
ad->func_call = FUNC_CDECL;
|
ad->a.func_call = FUNC_CDECL;
|
||||||
break;
|
break;
|
||||||
case TOK_STDCALL1:
|
case TOK_STDCALL1:
|
||||||
case TOK_STDCALL2:
|
case TOK_STDCALL2:
|
||||||
case TOK_STDCALL3:
|
case TOK_STDCALL3:
|
||||||
ad->func_call = FUNC_STDCALL;
|
ad->a.func_call = FUNC_STDCALL;
|
||||||
break;
|
break;
|
||||||
#ifdef TCC_TARGET_I386
|
#ifdef TCC_TARGET_I386
|
||||||
case TOK_REGPARM1:
|
case TOK_REGPARM1:
|
||||||
@ -2699,26 +2700,26 @@ static void parse_attribute(AttributeDef *ad)
|
|||||||
else if (n < 0)
|
else if (n < 0)
|
||||||
n = 0;
|
n = 0;
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
ad->func_call = FUNC_FASTCALL1 + n - 1;
|
ad->a.func_call = FUNC_FASTCALL1 + n - 1;
|
||||||
skip(')');
|
skip(')');
|
||||||
break;
|
break;
|
||||||
case TOK_FASTCALL1:
|
case TOK_FASTCALL1:
|
||||||
case TOK_FASTCALL2:
|
case TOK_FASTCALL2:
|
||||||
case TOK_FASTCALL3:
|
case TOK_FASTCALL3:
|
||||||
ad->func_call = FUNC_FASTCALLW;
|
ad->a.func_call = FUNC_FASTCALLW;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case TOK_MODE:
|
case TOK_MODE:
|
||||||
skip('(');
|
skip('(');
|
||||||
switch(tok) {
|
switch(tok) {
|
||||||
case TOK_MODE_DI:
|
case TOK_MODE_DI:
|
||||||
ad->mode = VT_LLONG + 1;
|
ad->a.mode = VT_LLONG + 1;
|
||||||
break;
|
break;
|
||||||
case TOK_MODE_HI:
|
case TOK_MODE_HI:
|
||||||
ad->mode = VT_SHORT + 1;
|
ad->a.mode = VT_SHORT + 1;
|
||||||
break;
|
break;
|
||||||
case TOK_MODE_SI:
|
case TOK_MODE_SI:
|
||||||
ad->mode = VT_INT + 1;
|
ad->a.mode = VT_INT + 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
|
tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
|
||||||
@ -2728,10 +2729,10 @@ static void parse_attribute(AttributeDef *ad)
|
|||||||
skip(')');
|
skip(')');
|
||||||
break;
|
break;
|
||||||
case TOK_DLLEXPORT:
|
case TOK_DLLEXPORT:
|
||||||
ad->func_export = 1;
|
ad->a.func_export = 1;
|
||||||
break;
|
break;
|
||||||
case TOK_DLLIMPORT:
|
case TOK_DLLIMPORT:
|
||||||
ad->func_import = 1;
|
ad->a.func_import = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (tcc_state->warn_unsupported)
|
if (tcc_state->warn_unsupported)
|
||||||
@ -2873,10 +2874,10 @@ static void struct_decl(CType *type, int u, int tdef)
|
|||||||
get_tok_str(v, NULL));
|
get_tok_str(v, NULL));
|
||||||
}
|
}
|
||||||
size = type_size(&type1, &align);
|
size = type_size(&type1, &align);
|
||||||
if (ad.aligned) {
|
if (ad.a.aligned) {
|
||||||
if (align < ad.aligned)
|
if (align < ad.a.aligned)
|
||||||
align = ad.aligned;
|
align = ad.a.aligned;
|
||||||
} else if (ad.packed) {
|
} else if (ad.a.packed) {
|
||||||
align = 1;
|
align = 1;
|
||||||
} else if (*tcc_state->pack_stack_ptr) {
|
} else if (*tcc_state->pack_stack_ptr) {
|
||||||
if (align > *tcc_state->pack_stack_ptr)
|
if (align > *tcc_state->pack_stack_ptr)
|
||||||
@ -3118,8 +3119,8 @@ static int parse_btype(CType *type, AttributeDef *ad)
|
|||||||
case TOK_ATTRIBUTE1:
|
case TOK_ATTRIBUTE1:
|
||||||
case TOK_ATTRIBUTE2:
|
case TOK_ATTRIBUTE2:
|
||||||
parse_attribute(ad);
|
parse_attribute(ad);
|
||||||
if (ad->mode) {
|
if (ad->a.mode) {
|
||||||
u = ad->mode -1;
|
u = ad->a.mode -1;
|
||||||
t = (t & ~VT_BTYPE) | u;
|
t = (t & ~VT_BTYPE) | u;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -3143,11 +3144,11 @@ static int parse_btype(CType *type, AttributeDef *ad)
|
|||||||
type->ref = s->type.ref;
|
type->ref = s->type.ref;
|
||||||
if (s->r) {
|
if (s->r) {
|
||||||
/* get attributes from typedef */
|
/* get attributes from typedef */
|
||||||
if (0 == ad->aligned)
|
if (0 == ad->a.aligned)
|
||||||
ad->aligned = FUNC_ALIGN(s->r);
|
ad->a.aligned = s->a.aligned;
|
||||||
if (0 == ad->func_call)
|
if (0 == ad->a.func_call)
|
||||||
ad->func_call = FUNC_CALL(s->r);
|
ad->a.func_call = s->a.func_call;
|
||||||
ad->packed |= FUNC_PACKED(s->r);
|
ad->a.packed |= s->a.packed;
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
typespec_found = 1;
|
typespec_found = 1;
|
||||||
@ -3287,8 +3288,9 @@ static void post_type(CType *type, AttributeDef *ad)
|
|||||||
type->t |= VT_PTR;
|
type->t |= VT_PTR;
|
||||||
}
|
}
|
||||||
/* 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->a.func_args = arg_size;
|
||||||
s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
|
s = sym_push(SYM_FIELD, type, 0, l);
|
||||||
|
s->a = ad->a;
|
||||||
s->next = first;
|
s->next = first;
|
||||||
type->t = VT_FUNC;
|
type->t = VT_FUNC;
|
||||||
type->ref = s;
|
type->ref = s;
|
||||||
@ -5484,10 +5486,10 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
|||||||
if (flexible_array)
|
if (flexible_array)
|
||||||
size += flexible_array->type.ref->c * pointed_size(&flexible_array->type);
|
size += flexible_array->type.ref->c * pointed_size(&flexible_array->type);
|
||||||
/* take into account specified alignment if bigger */
|
/* take into account specified alignment if bigger */
|
||||||
if (ad->aligned) {
|
if (ad->a.aligned) {
|
||||||
if (ad->aligned > align)
|
if (ad->a.aligned > align)
|
||||||
align = ad->aligned;
|
align = ad->a.aligned;
|
||||||
} else if (ad->packed) {
|
} else if (ad->a.packed) {
|
||||||
align = 1;
|
align = 1;
|
||||||
}
|
}
|
||||||
if ((r & VT_VALMASK) == VT_LOCAL) {
|
if ((r & VT_VALMASK) == VT_LOCAL) {
|
||||||
@ -5869,12 +5871,12 @@ static int decl0(int l, int is_for_loop_init)
|
|||||||
parse_attribute(&ad);
|
parse_attribute(&ad);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ad.weak)
|
if (ad.a.weak)
|
||||||
type.t |= VT_WEAK;
|
type.t |= VT_WEAK;
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
if (ad.func_import)
|
if (ad.a.func_import)
|
||||||
type.t |= VT_IMPORT;
|
type.t |= VT_IMPORT;
|
||||||
if (ad.func_export)
|
if (ad.a.func_export)
|
||||||
type.t |= VT_EXPORT;
|
type.t |= VT_EXPORT;
|
||||||
#endif
|
#endif
|
||||||
if (tok == '{') {
|
if (tok == '{') {
|
||||||
@ -5895,22 +5897,22 @@ static int decl0(int l, int is_for_loop_init)
|
|||||||
|
|
||||||
sym = sym_find(v);
|
sym = sym_find(v);
|
||||||
if (sym) {
|
if (sym) {
|
||||||
|
Sym *ref;
|
||||||
if ((sym->type.t & VT_BTYPE) != VT_FUNC)
|
if ((sym->type.t & VT_BTYPE) != VT_FUNC)
|
||||||
goto func_error1;
|
goto func_error1;
|
||||||
|
|
||||||
r = sym->type.ref->r;
|
ref = sym->type.ref;
|
||||||
|
if (0 == ref->a.func_proto)
|
||||||
if (!FUNC_PROTO(r))
|
|
||||||
tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
|
tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
|
||||||
|
|
||||||
/* use func_call from prototype if not defined */
|
/* use func_call from prototype if not defined */
|
||||||
if (FUNC_CALL(r) != FUNC_CDECL
|
if (ref->a.func_call != FUNC_CDECL
|
||||||
&& FUNC_CALL(type.ref->r) == FUNC_CDECL)
|
&& type.ref->a.func_call == FUNC_CDECL)
|
||||||
FUNC_CALL(type.ref->r) = FUNC_CALL(r);
|
type.ref->a.func_call = ref->a.func_call;
|
||||||
|
|
||||||
/* use export from prototype */
|
/* use export from prototype */
|
||||||
if (FUNC_EXPORT(r))
|
if (ref->a.func_export)
|
||||||
FUNC_EXPORT(type.ref->r) = 1;
|
type.ref->a.func_export = 1;
|
||||||
|
|
||||||
/* use static from prototype */
|
/* use static from prototype */
|
||||||
if (sym->type.t & VT_STATIC)
|
if (sym->type.t & VT_STATIC)
|
||||||
@ -5921,7 +5923,7 @@ static int decl0(int l, int is_for_loop_init)
|
|||||||
tcc_error("incompatible types for redefinition of '%s'",
|
tcc_error("incompatible types for redefinition of '%s'",
|
||||||
get_tok_str(v, NULL));
|
get_tok_str(v, NULL));
|
||||||
}
|
}
|
||||||
FUNC_PROTO(type.ref->r) = 0;
|
type.ref->a.func_proto = 0;
|
||||||
/* if symbol is already defined, then put complete type */
|
/* if symbol is already defined, then put complete type */
|
||||||
sym->type = type;
|
sym->type = type;
|
||||||
} else {
|
} else {
|
||||||
@ -5980,15 +5982,16 @@ static int decl0(int l, int is_for_loop_init)
|
|||||||
if (btype.t & VT_TYPEDEF) {
|
if (btype.t & VT_TYPEDEF) {
|
||||||
/* save typedefed type */
|
/* save typedefed type */
|
||||||
/* XXX: test storage specifiers ? */
|
/* XXX: test storage specifiers ? */
|
||||||
sym = sym_push(v, &type, INT_ATTR(&ad), 0);
|
sym = sym_push(v, &type, 0, 0);
|
||||||
|
sym->a = ad.a;
|
||||||
sym->type.t |= VT_TYPEDEF;
|
sym->type.t |= VT_TYPEDEF;
|
||||||
} else {
|
} else {
|
||||||
r = 0;
|
r = 0;
|
||||||
if ((type.t & VT_BTYPE) == VT_FUNC) {
|
if ((type.t & VT_BTYPE) == VT_FUNC) {
|
||||||
/* external function definition */
|
/* external function definition */
|
||||||
/* specific case for func_call attribute */
|
/* specific case for func_call attribute */
|
||||||
ad.func_proto = 1;
|
ad.a.func_proto = 1;
|
||||||
type.ref->r = INT_ATTR(&ad);
|
type.ref->a = ad.a;
|
||||||
} else if (!(type.t & VT_ARRAY)) {
|
} else if (!(type.t & VT_ARRAY)) {
|
||||||
/* not lvalue if array */
|
/* not lvalue if array */
|
||||||
r |= lvalue_type(type.t);
|
r |= lvalue_type(type.t);
|
||||||
@ -6039,7 +6042,7 @@ static int decl0(int l, int is_for_loop_init)
|
|||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
ad.aligned = 0;
|
ad.a.aligned = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
15
x86_64-gen.c
15
x86_64-gen.c
@ -933,7 +933,8 @@ typedef enum X86_64_Mode {
|
|||||||
x86_64_mode_x87
|
x86_64_mode_x87
|
||||||
} X86_64_Mode;
|
} X86_64_Mode;
|
||||||
|
|
||||||
static X86_64_Mode classify_x86_64_merge(X86_64_Mode a, X86_64_Mode b) {
|
static X86_64_Mode classify_x86_64_merge(X86_64_Mode a, X86_64_Mode b)
|
||||||
|
{
|
||||||
if (a == b)
|
if (a == b)
|
||||||
return a;
|
return a;
|
||||||
else if (a == x86_64_mode_none)
|
else if (a == x86_64_mode_none)
|
||||||
@ -950,7 +951,8 @@ static X86_64_Mode classify_x86_64_merge(X86_64_Mode a, X86_64_Mode b) {
|
|||||||
return x86_64_mode_sse;
|
return x86_64_mode_sse;
|
||||||
}
|
}
|
||||||
|
|
||||||
static X86_64_Mode classify_x86_64_inner(CType *ty) {
|
static X86_64_Mode classify_x86_64_inner(CType *ty)
|
||||||
|
{
|
||||||
X86_64_Mode mode;
|
X86_64_Mode mode;
|
||||||
Sym *f;
|
Sym *f;
|
||||||
|
|
||||||
@ -988,7 +990,8 @@ static X86_64_Mode classify_x86_64_inner(CType *ty) {
|
|||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static X86_64_Mode classify_x86_64_arg(CType *ty, CType *ret, int *psize, int *palign, int *reg_count) {
|
static X86_64_Mode classify_x86_64_arg(CType *ty, CType *ret, int *psize, int *palign, int *reg_count)
|
||||||
|
{
|
||||||
X86_64_Mode mode;
|
X86_64_Mode mode;
|
||||||
int size, align, ret_t = 0;
|
int size, align, ret_t = 0;
|
||||||
|
|
||||||
@ -1045,7 +1048,8 @@ static X86_64_Mode classify_x86_64_arg(CType *ty, CType *ret, int *psize, int *p
|
|||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
ST_FUNC int classify_x86_64_va_arg(CType *ty) {
|
ST_FUNC int classify_x86_64_va_arg(CType *ty)
|
||||||
|
{
|
||||||
/* This definition must be synced with stdarg.h */
|
/* This definition must be synced with stdarg.h */
|
||||||
enum __va_arg_type {
|
enum __va_arg_type {
|
||||||
__va_gen_reg, __va_float_reg, __va_stack
|
__va_gen_reg, __va_float_reg, __va_stack
|
||||||
@ -1061,7 +1065,8 @@ ST_FUNC int classify_x86_64_va_arg(CType *ty) {
|
|||||||
|
|
||||||
/* Return the number of registers needed to return the struct, or 0 if
|
/* Return the number of registers needed to return the struct, or 0 if
|
||||||
returning via struct pointer. */
|
returning via struct pointer. */
|
||||||
int gfunc_sret(CType *vt, CType *ret, int *ret_align) {
|
ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align)
|
||||||
|
{
|
||||||
int size, align, reg_count;
|
int size, align, reg_count;
|
||||||
*ret_align = 1; // Never have to re-align return values for x86-64
|
*ret_align = 1; // Never have to re-align return values for x86-64
|
||||||
return (classify_x86_64_arg(vt, ret, &size, &align, ®_count) != x86_64_mode_memory);
|
return (classify_x86_64_arg(vt, ret, &size, &align, ®_count) != x86_64_mode_memory);
|
||||||
|
Loading…
Reference in New Issue
Block a user