mirror of
https://github.com/TinyCC/tinycc.git
synced 2025-11-16 12:34:45 +00:00
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:
72
x86_64-gen.c
72
x86_64-gen.c
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user