forked from Mirrors/tinycc
fixed floating poing compare - use LVAL type - optimized bound checking
parent
30766d3cd1
commit
264dbcfed2
97
i386-gen.c
97
i386-gen.c
|
@ -207,16 +207,17 @@ void load(int r, SValue *sv)
|
||||||
} else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
|
} else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
|
||||||
o(0xdb); /* fldt */
|
o(0xdb); /* fldt */
|
||||||
r = 5;
|
r = 5;
|
||||||
} else if ((ft & VT_TYPE) == VT_BYTE)
|
} else if ((ft & VT_TYPE) == VT_BYTE) {
|
||||||
o(0xbe0f); /* movsbl */
|
o(0xbe0f); /* movsbl */
|
||||||
else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED))
|
} else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
|
||||||
o(0xb60f); /* movzbl */
|
o(0xb60f); /* movzbl */
|
||||||
else if ((ft & VT_TYPE) == VT_SHORT)
|
} else if ((ft & VT_TYPE) == VT_SHORT) {
|
||||||
o(0xbf0f); /* movswl */
|
o(0xbf0f); /* movswl */
|
||||||
else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED))
|
} else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) {
|
||||||
o(0xb70f); /* movzwl */
|
o(0xb70f); /* movzwl */
|
||||||
else
|
} else {
|
||||||
o(0x8b); /* movl */
|
o(0x8b); /* movl */
|
||||||
|
}
|
||||||
gen_modrm(r, fr, fc);
|
gen_modrm(r, fr, fc);
|
||||||
} else {
|
} else {
|
||||||
if (v == VT_CONST) {
|
if (v == VT_CONST) {
|
||||||
|
@ -303,7 +304,7 @@ 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(VT_INT, r, 0);
|
vset(vtop->t, r | VT_LVAL, 0);
|
||||||
vswap();
|
vswap();
|
||||||
vstore();
|
vstore();
|
||||||
c->args_size += size;
|
c->args_size += size;
|
||||||
|
@ -655,11 +656,22 @@ void gen_opf(int op)
|
||||||
gv(RC_FLOAT);
|
gv(RC_FLOAT);
|
||||||
vswap();
|
vswap();
|
||||||
}
|
}
|
||||||
|
swapped = 0;
|
||||||
|
/* swap the stack if needed so that t1 is the register and t2 is
|
||||||
|
the memory reference */
|
||||||
|
if (vtop[-1].r & VT_LVAL) {
|
||||||
|
vswap();
|
||||||
|
swapped = 1;
|
||||||
|
}
|
||||||
if (op >= TOK_ULT && op <= TOK_GT) {
|
if (op >= TOK_ULT && op <= TOK_GT) {
|
||||||
/* load on stack second operand */
|
/* load on stack second operand */
|
||||||
load(REG_ST0, vtop);
|
load(REG_ST0, vtop);
|
||||||
save_reg(REG_EAX); /* eax is used by FP comparison code */
|
save_reg(REG_EAX); /* eax is used by FP comparison code */
|
||||||
if (op == TOK_GE || op == TOK_GT)
|
if (op == TOK_GE || op == TOK_GT)
|
||||||
|
swapped = !swapped;
|
||||||
|
else if (op == TOK_EQ || op == TOK_NE)
|
||||||
|
swapped = 0;
|
||||||
|
if (swapped)
|
||||||
o(0xc9d9); /* fxch %st(1) */
|
o(0xc9d9); /* fxch %st(1) */
|
||||||
o(0xe9da); /* fucompp */
|
o(0xe9da); /* fucompp */
|
||||||
o(0xe0df); /* fnstsw %ax */
|
o(0xe0df); /* fnstsw %ax */
|
||||||
|
@ -681,13 +693,6 @@ void gen_opf(int op)
|
||||||
vtop->r = VT_CMP;
|
vtop->r = VT_CMP;
|
||||||
vtop->c.i = op;
|
vtop->c.i = op;
|
||||||
} else {
|
} else {
|
||||||
swapped = 0;
|
|
||||||
/* swap the stack if needed so that t1 is the register and t2 is
|
|
||||||
the memory reference */
|
|
||||||
if (vtop[-1].r & VT_LVAL) {
|
|
||||||
vswap();
|
|
||||||
swapped = 1;
|
|
||||||
}
|
|
||||||
/* 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->t & VT_BTYPE) == VT_LDOUBLE) {
|
||||||
load(REG_ST0, vtop);
|
load(REG_ST0, vtop);
|
||||||
|
@ -821,45 +826,57 @@ void gen_cvt_ftof(int t)
|
||||||
|
|
||||||
/* bound check support functions */
|
/* bound check support functions */
|
||||||
#ifdef CONFIG_TCC_BCHECK
|
#ifdef CONFIG_TCC_BCHECK
|
||||||
/* generate first part of bounded pointer addition */
|
|
||||||
void gen_bounded_ptr_add1(void)
|
/* generate a bounded pointer addition */
|
||||||
|
void gen_bounded_ptr_add(void)
|
||||||
{
|
{
|
||||||
|
int addr;
|
||||||
/* prepare fast i386 function call (args in eax and edx) */
|
/* prepare fast i386 function call (args in eax and edx) */
|
||||||
gv2(RC_EAX, RC_EDX);
|
gv2(RC_EAX, RC_EDX);
|
||||||
/* save all temporary registers */
|
/* save all temporary registers */
|
||||||
vtop--;
|
vtop -= 2;
|
||||||
vtop->r = VT_CONST;
|
save_regs(0);
|
||||||
save_regs(0);
|
/* do a fast function call */
|
||||||
|
addr = ind;
|
||||||
|
oad(0xe8, (int)__bound_ptr_add - ind - 5);
|
||||||
|
/* returned pointer is in eax */
|
||||||
|
vtop++;
|
||||||
|
vtop->r = REG_EAX | VT_BOUNDED;
|
||||||
|
vtop->c.ul = addr; /* address of bounding function call point */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if deref is true, then also test dereferencing */
|
/* patch pointer addition in vtop so that pointer dereferencing is
|
||||||
void gen_bounded_ptr_add2(int deref)
|
also tested */
|
||||||
|
void gen_bounded_ptr_deref(void)
|
||||||
{
|
{
|
||||||
void *func;
|
void *func;
|
||||||
int size, align;
|
int size, align, addr;
|
||||||
|
|
||||||
if (deref) {
|
size = 0;
|
||||||
|
/* XXX: put that code in generic part of tcc */
|
||||||
|
if (!is_float(vtop->t)) {
|
||||||
|
if (vtop->r & VT_LVAL_BYTE)
|
||||||
|
size = 1;
|
||||||
|
else if (vtop->r & VT_LVAL_SHORT)
|
||||||
|
size = 2;
|
||||||
|
}
|
||||||
|
if (!size)
|
||||||
size = type_size(vtop->t, &align);
|
size = type_size(vtop->t, &align);
|
||||||
switch(size) {
|
switch(size) {
|
||||||
case 1: func = __bound_ptr_indir1; break;
|
case 1: func = __bound_ptr_indir1; break;
|
||||||
case 2: func = __bound_ptr_indir2; break;
|
case 2: func = __bound_ptr_indir2; break;
|
||||||
case 4: func = __bound_ptr_indir4; break;
|
case 4: func = __bound_ptr_indir4; break;
|
||||||
case 8: func = __bound_ptr_indir8; break;
|
case 8: func = __bound_ptr_indir8; break;
|
||||||
case 12: func = __bound_ptr_indir12; break;
|
case 12: func = __bound_ptr_indir12; break;
|
||||||
case 16: func = __bound_ptr_indir16; break;
|
case 16: func = __bound_ptr_indir16; break;
|
||||||
default:
|
default:
|
||||||
error("unhandled size when derefencing bounded pointer");
|
error("unhandled size when derefencing bounded pointer");
|
||||||
func = NULL;
|
func = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
} else {
|
|
||||||
func = __bound_ptr_add;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* do a fast function call */
|
addr = vtop->c.ul;
|
||||||
oad(0xe8, (int)func - ind - 5);
|
*(int *)(addr + 1) = (int)func - addr - 5;
|
||||||
/* return pointer is there */
|
|
||||||
vtop->r = REG_EAX;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue