added CType structure for type storage - supressed define hash table - added time dump in bench

tcc-xref
bellard 2002-11-18 21:46:44 +00:00
parent 6cd2d5d2c8
commit 9620fd18e4
2 changed files with 666 additions and 538 deletions

View File

@ -185,13 +185,13 @@ void load(int r, SValue *sv)
SValue v1; SValue v1;
fr = sv->r; fr = sv->r;
ft = sv->t; ft = sv->type.t;
fc = sv->c.ul; fc = sv->c.ul;
v = fr & VT_VALMASK; v = fr & VT_VALMASK;
if (fr & VT_LVAL) { if (fr & VT_LVAL) {
if (v == VT_LLOCAL) { if (v == VT_LLOCAL) {
v1.t = VT_INT; v1.type.t = VT_INT;
v1.r = VT_LOCAL | VT_LVAL; v1.r = VT_LOCAL | VT_LVAL;
v1.c.ul = fc; v1.c.ul = fc;
load(r, &v1); load(r, &v1);
@ -248,7 +248,7 @@ void store(int r, SValue *v)
{ {
int fr, bt, ft, fc; int fr, bt, ft, fc;
ft = v->t; ft = v->type.t;
fc = v->c.ul; fc = v->c.ul;
fr = v->r & VT_VALMASK; fr = v->r & VT_VALMASK;
bt = ft & VT_BTYPE; bt = ft & VT_BTYPE;
@ -293,8 +293,8 @@ void gfunc_param(GFuncContext *c)
{ {
int size, align, r; int size, align, r;
if ((vtop->t & VT_BTYPE) == VT_STRUCT) { if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
size = type_size(vtop->t, &align); size = type_size(&vtop->type, &align);
/* align to stack align size */ /* align to stack align size */
size = (size + 3) & ~3; size = (size + 3) & ~3;
/* allocate the necessary size on stack */ /* allocate the necessary size on stack */
@ -303,15 +303,15 @@ void gfunc_param(GFuncContext *c)
r = get_reg(RC_INT); r = get_reg(RC_INT);
o(0x89); /* mov %esp, r */ o(0x89); /* mov %esp, r */
o(0xe0 + r); o(0xe0 + r);
vset(vtop->t, r | VT_LVAL, 0); vset(&vtop->type, r | VT_LVAL, 0);
vswap(); vswap();
vstore(); vstore();
c->args_size += size; c->args_size += size;
} else if (is_float(vtop->t)) { } else if (is_float(vtop->type.t)) {
gv(RC_FLOAT); /* only one float register */ gv(RC_FLOAT); /* only one float register */
if ((vtop->t & VT_BTYPE) == VT_FLOAT) if ((vtop->type.t & VT_BTYPE) == VT_FLOAT)
size = 4; size = 4;
else if ((vtop->t & VT_BTYPE) == VT_DOUBLE) else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
size = 8; size = 8;
else else
size = 12; size = 12;
@ -327,7 +327,7 @@ void gfunc_param(GFuncContext *c)
/* simple type (currently always same size) */ /* simple type (currently always same size) */
/* XXX: implicit cast ? */ /* XXX: implicit cast ? */
r = gv(RC_INT); r = gv(RC_INT);
if ((vtop->t & VT_BTYPE) == VT_LLONG) { if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
size = 8; size = 8;
o(0x50 + vtop->r2); /* push r */ o(0x50 + vtop->r2); /* push r */
} else { } else {
@ -384,31 +384,32 @@ void gfunc_call(GFuncContext *c)
} }
/* generate function prolog of type 't' */ /* generate function prolog of type 't' */
void gfunc_prolog(int t) void gfunc_prolog(CType *func_type)
{ {
int addr, align, size, u, func_call; int addr, align, size, func_call;
Sym *sym; Sym *sym;
CType *type;
sym = sym_find((unsigned)t >> VT_STRUCT_SHIFT); sym = func_type->ref;
func_call = sym->r; func_call = sym->r;
addr = 8; addr = 8;
/* if the function returns a structure, then add an /* if the function returns a structure, then add an
implicit pointer parameter */ implicit pointer parameter */
func_vt = sym->t; func_vt = sym->type;
if ((func_vt & VT_BTYPE) == VT_STRUCT) { if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
func_vc = addr; func_vc = addr;
addr += 4; addr += 4;
} }
/* define parameters */ /* define parameters */
while ((sym = sym->next) != NULL) { while ((sym = sym->next) != NULL) {
u = sym->t; type = &sym->type;
sym_push(sym->v & ~SYM_FIELD, u, sym_push(sym->v & ~SYM_FIELD, type,
VT_LOCAL | VT_LVAL, addr); VT_LOCAL | VT_LVAL, addr);
size = type_size(u, &align); size = type_size(type, &align);
size = (size + 3) & ~3; size = (size + 3) & ~3;
#ifdef FUNC_STRUCT_PARAM_AS_PTR #ifdef FUNC_STRUCT_PARAM_AS_PTR
/* structs are passed as pointer */ /* structs are passed as pointer */
if ((u & VT_BTYPE) == VT_STRUCT) { if ((type->t & VT_BTYPE) == VT_STRUCT) {
size = 4; size = 4;
} }
#endif #endif
@ -442,12 +443,12 @@ void gfunc_epilog(void)
/* generate bound local allocation */ /* generate bound local allocation */
saved_ind = ind; saved_ind = ind;
ind = func_sub_sp_offset + 4; ind = func_sub_sp_offset + 4;
sym_data = get_sym_ref(char_pointer_type, lbounds_section, sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
func_bound_offset, lbounds_section->data_offset); func_bound_offset, lbounds_section->data_offset);
greloc(cur_text_section, sym_data, greloc(cur_text_section, sym_data,
ind + 1, R_386_32); ind + 1, R_386_32);
oad(0xb8, 0); /* mov %eax, xxx */ oad(0xb8, 0); /* mov %eax, xxx */
sym = external_global_sym(TOK___bound_local_new, func_old_type, 0); sym = external_global_sym(TOK___bound_local_new, &func_old_type, 0);
greloc(cur_text_section, sym, greloc(cur_text_section, sym,
ind + 1, R_386_PC32); ind + 1, R_386_PC32);
oad(0xe8, -4); oad(0xe8, -4);
@ -457,7 +458,7 @@ void gfunc_epilog(void)
greloc(cur_text_section, sym_data, greloc(cur_text_section, sym_data,
ind + 1, R_386_32); ind + 1, R_386_32);
oad(0xb8, 0); /* mov %eax, xxx */ oad(0xb8, 0); /* mov %eax, xxx */
sym = external_global_sym(TOK___bound_local_delete, func_old_type, 0); sym = external_global_sym(TOK___bound_local_delete, &func_old_type, 0);
greloc(cur_text_section, sym, greloc(cur_text_section, sym,
ind + 1, R_386_PC32); ind + 1, R_386_PC32);
oad(0xe8, -4); oad(0xe8, -4);
@ -518,7 +519,7 @@ int gtst(int inv, int t)
gsym(vtop->c.i); gsym(vtop->c.i);
} }
} else { } else {
if (is_float(vtop->t)) { if (is_float(vtop->type.t)) {
vpushi(0); vpushi(0);
gen_op(TOK_NE); gen_op(TOK_NE);
} }
@ -572,8 +573,8 @@ void gen_opi(int op)
} }
vtop--; vtop--;
if (op >= TOK_ULT && op <= TOK_GT) { if (op >= TOK_ULT && op <= TOK_GT) {
vtop--; vtop->r = VT_CMP;
vset(VT_INT, VT_CMP, op); vtop->c.i = op;
} }
break; break;
case '-': case '-':
@ -731,7 +732,7 @@ void gen_opf(int op)
vtop->c.i = op; vtop->c.i = op;
} else { } else {
/* no memory reference possible for long double operations */ /* no memory reference possible for long double operations */
if ((vtop->t & VT_BTYPE) == VT_LDOUBLE) { if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
load(REG_ST0, vtop); load(REG_ST0, vtop);
swapped = !swapped; swapped = !swapped;
} }
@ -755,7 +756,7 @@ void gen_opf(int op)
a++; a++;
break; break;
} }
ft = vtop->t; ft = vtop->type.t;
fc = vtop->c.ul; fc = vtop->c.ul;
if ((ft & VT_BTYPE) == VT_LDOUBLE) { if ((ft & VT_BTYPE) == VT_LDOUBLE) {
o(0xde); /* fxxxp %st, %st(1) */ o(0xde); /* fxxxp %st, %st(1) */
@ -766,7 +767,7 @@ void gen_opf(int op)
if ((r & VT_VALMASK) == VT_LLOCAL) { if ((r & VT_VALMASK) == VT_LLOCAL) {
SValue v1; SValue v1;
r = get_reg(RC_INT); r = get_reg(RC_INT);
v1.t = VT_INT; v1.type.t = VT_INT;
v1.r = VT_LOCAL | VT_LVAL; v1.r = VT_LOCAL | VT_LVAL;
v1.c.ul = fc; v1.c.ul = fc;
load(r, &v1); load(r, &v1);
@ -789,14 +790,14 @@ void gen_cvt_itof(int t)
{ {
save_reg(REG_ST0); save_reg(REG_ST0);
gv(RC_INT); gv(RC_INT);
if ((vtop->t & VT_BTYPE) == VT_LLONG) { if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
/* signed long long to float/double/long double (unsigned case /* signed long long to float/double/long double (unsigned case
is handled generically) */ is handled generically) */
o(0x50 + vtop->r2); /* push r2 */ o(0x50 + vtop->r2); /* push r2 */
o(0x50 + (vtop->r & VT_VALMASK)); /* push r */ o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
o(0x242cdf); /* fildll (%esp) */ o(0x242cdf); /* fildll (%esp) */
o(0x08c483); /* add $8, %esp */ o(0x08c483); /* add $8, %esp */
} else if ((vtop->t & (VT_BTYPE | VT_UNSIGNED)) == } else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
(VT_INT | VT_UNSIGNED)) { (VT_INT | VT_UNSIGNED)) {
/* unsigned int to float/double/long double */ /* unsigned int to float/double/long double */
o(0x6a); /* push $0 */ o(0x6a); /* push $0 */
@ -819,6 +820,9 @@ void gen_cvt_ftoi(int t)
{ {
int r, r2, size; int r, r2, size;
Sym *sym; Sym *sym;
CType ushort_type;
ushort_type.t = VT_SHORT | VT_UNSIGNED;
gv(RC_FLOAT); gv(RC_FLOAT);
if (t != VT_INT) if (t != VT_INT)
@ -828,7 +832,7 @@ void gen_cvt_ftoi(int t)
o(0x2dd9); /* ldcw xxx */ o(0x2dd9); /* ldcw xxx */
sym = external_global_sym(TOK___tcc_int_fpu_control, sym = external_global_sym(TOK___tcc_int_fpu_control,
VT_SHORT | VT_UNSIGNED, VT_LVAL); &ushort_type, VT_LVAL);
greloc(cur_text_section, sym, greloc(cur_text_section, sym,
ind, R_386_32); ind, R_386_32);
gen_le32(0); gen_le32(0);
@ -841,7 +845,7 @@ void gen_cvt_ftoi(int t)
o(0x24); o(0x24);
o(0x2dd9); /* ldcw xxx */ o(0x2dd9); /* ldcw xxx */
sym = external_global_sym(TOK___tcc_fpu_control, sym = external_global_sym(TOK___tcc_fpu_control,
VT_SHORT | VT_UNSIGNED, VT_LVAL); &ushort_type, VT_LVAL);
greloc(cur_text_section, sym, greloc(cur_text_section, sym,
ind, R_386_32); ind, R_386_32);
gen_le32(0); gen_le32(0);
@ -889,7 +893,7 @@ void gen_bounded_ptr_add(void)
vtop -= 2; vtop -= 2;
save_regs(0); save_regs(0);
/* do a fast function call */ /* do a fast function call */
sym = external_global_sym(TOK___bound_ptr_add, func_old_type, 0); sym = external_global_sym(TOK___bound_ptr_add, &func_old_type, 0);
greloc(cur_text_section, sym, greloc(cur_text_section, sym,
ind + 1, R_386_PC32); ind + 1, R_386_PC32);
oad(0xe8, -4); oad(0xe8, -4);
@ -911,14 +915,14 @@ void gen_bounded_ptr_deref(void)
size = 0; size = 0;
/* XXX: put that code in generic part of tcc */ /* XXX: put that code in generic part of tcc */
if (!is_float(vtop->t)) { if (!is_float(vtop->type.t)) {
if (vtop->r & VT_LVAL_BYTE) if (vtop->r & VT_LVAL_BYTE)
size = 1; size = 1;
else if (vtop->r & VT_LVAL_SHORT) else if (vtop->r & VT_LVAL_SHORT)
size = 2; size = 2;
} }
if (!size) if (!size)
size = type_size(vtop->t, &align); size = type_size(&vtop->type, &align);
switch(size) { switch(size) {
case 1: func = TOK___bound_ptr_indir1; break; case 1: func = TOK___bound_ptr_indir1; break;
case 2: func = TOK___bound_ptr_indir2; break; case 2: func = TOK___bound_ptr_indir2; break;
@ -935,7 +939,7 @@ void gen_bounded_ptr_deref(void)
/* patch relocation */ /* patch relocation */
/* XXX: find a better solution ? */ /* XXX: find a better solution ? */
rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.ul); rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.ul);
sym = external_global_sym(func, func_old_type, 0); sym = external_global_sym(func, &func_old_type, 0);
if (!sym->c) if (!sym->c)
put_extern_sym(sym, NULL, 0, 0); put_extern_sym(sym, NULL, 0, 0);
rel->r_info = ELF32_R_INFO(sym->c, ELF32_R_TYPE(rel->r_info)); rel->r_info = ELF32_R_INFO(sym->c, ELF32_R_TYPE(rel->r_info));

1126
tcc.c

File diff suppressed because it is too large Load Diff