revert "Save registers around attribute cleanup" (almost)

In fact, we don't need to save registers.  We need to
save the symbol if it is a SValue on vstack (the return
value in this case)

Replaces b6a16e3be4
This commit is contained in:
grischka
2025-05-24 23:53:37 +02:00
parent b6a16e3be4
commit 83de532563
9 changed files with 73 additions and 251 deletions

View File

@@ -655,50 +655,6 @@ static void gcall_or_jmp(int is_jmp)
}
}
ST_FUNC void save_return_reg(CType *func_type)
{
int freg = is_float(func_type->t & VT_BTYPE);
int ireg = !freg;
if ((func_type->t & VT_BTYPE) == VT_STRUCT)
ireg = freg = 1;
if (ireg)
o(0x5250); /* push %rax; %push %rdx */
if (freg) {
if ((func_type->t & VT_BTYPE) == VT_LDOUBLE ||
(func_type->t & VT_BTYPE) == VT_STRUCT) {
o(0x10ec8348); /* sub $16,%rsp */
o(0x243cdb); /* fstpt (%rsp) */
}
o(0x20ec8348); /* sub $32,%rsp */
o(0x290f); /* movaps %xmm0,0x10(%rsp) */
o(0x102444);
o(0x240c290f); /* movaps %xmm1,(%rsp) */
}
}
ST_FUNC void restore_return_reg(CType *func_type)
{
int freg = is_float(func_type->t & VT_BTYPE);
int ireg = !freg;
if ((func_type->t & VT_BTYPE) == VT_STRUCT)
ireg = freg = 1;
if (freg) {
o(0x280f); /* movaps 0x10(%rsp),%xmm0 */
o(0x102444);
o(0x240c280f); /* movaps (%rsp),%xmm1 */
o(0x20c48348); /* add $32,%rsp */
if ((func_type->t & VT_BTYPE) == VT_LDOUBLE ||
(func_type->t & VT_BTYPE) == VT_STRUCT) {
o(0x242cdb); /* fldt (%rsp) */
o(0x10c48348); /* add $16,%rsp */
}
}
if (ireg)
o(0x585a); /* pop %rdx; pop %rax */
}
#if defined(CONFIG_TCC_BCHECK)
static void gen_bounds_call(int v)
@@ -725,13 +681,12 @@ static void gen_bounds_prolog(void)
oad(0xb8, 0); /* call to function */
}
static void gen_bounds_epilog(Sym *func_sym)
static void gen_bounds_epilog(void)
{
addr_t saved_ind;
addr_t *bounds_ptr;
Sym *sym_data;
int offset_modified = func_bound_offset != lbounds_section->data_offset;
CType *func_type = &func_sym->type.ref->type;
if (!offset_modified && !func_bound_add_epilog)
return;
@@ -754,14 +709,20 @@ static void gen_bounds_epilog(Sym *func_sym)
}
/* generate bound check local freeing */
if (func_type->t != VT_VOID)
save_return_reg(func_type);
o(0x5250); /* save returned value, if any */
o(0x20ec8348); /* sub $32,%rsp */
o(0x290f); /* movaps %xmm0,0x10(%rsp) */
o(0x102444);
o(0x240c290f); /* movaps %xmm1,(%rsp) */
greloca(cur_text_section, sym_data, ind + 3, R_X86_64_PC32, -4);
o(0x0d8d48 + ((TREG_FASTCALL_1 == TREG_RDI) * 0x300000)); /* lea xxx(%rip), %rcx/rdi */
gen_le32 (0);
gen_bounds_call(TOK___bound_local_delete);
if (func_type->t != VT_VOID)
restore_return_reg(func_type);
o(0x280f); /* movaps 0x10(%rsp),%xmm0 */
o(0x102444);
o(0x240c280f); /* movaps (%rsp),%xmm1 */
o(0x20c48348); /* add $32,%rsp */
o(0x585a); /* restore returned value, if any */
}
#endif
@@ -1044,7 +1005,7 @@ void gfunc_prolog(Sym *func_sym)
}
/* generate function epilog */
void gfunc_epilog(Sym *func_sym)
void gfunc_epilog(void)
{
int v, start;
@@ -1054,9 +1015,8 @@ void gfunc_epilog(Sym *func_sym)
#ifdef CONFIG_TCC_BCHECK
if (tcc_state->do_bounds_check)
gen_bounds_epilog(func_sym);
gen_bounds_epilog();
#endif
func_sym = NULL;
o(0xc9); /* leave */
if (func_ret_sub == 0) {
@@ -1640,16 +1600,14 @@ void gfunc_prolog(Sym *func_sym)
}
/* generate function epilog */
void gfunc_epilog(Sym *func_sym)
void gfunc_epilog(void)
{
int v, saved_ind;
#ifdef CONFIG_TCC_BCHECK
if (tcc_state->do_bounds_check)
gen_bounds_epilog(func_sym);
gen_bounds_epilog();
#endif
func_sym = NULL;
o(0xc9); /* leave */
if (func_ret_sub == 0) {
o(0xc3); /* ret */