Alien-TinyCCx
view release on metacpan or search on metacpan
src/i386-gen.c view on Meta::CPAN
a = 1;
break;
case '/':
a = 6;
if (swapped)
a++;
break;
}
ft = vtop->type.t;
fc = vtop->c.i;
if ((ft & VT_BTYPE) == VT_LDOUBLE) {
o(0xde); /* fxxxp %st, %st(1) */
o(0xc1 + (a << 3));
} else {
/* if saved lvalue, then we must reload it */
r = vtop->r;
if ((r & VT_VALMASK) == VT_LLOCAL) {
SValue v1;
r = get_reg(RC_INT);
v1.type.t = VT_INT;
v1.r = VT_LOCAL | VT_LVAL;
v1.c.i = fc;
load(r, &v1);
fc = 0;
}
if ((ft & VT_BTYPE) == VT_DOUBLE)
o(0xdc);
else
o(0xd8);
gen_modrm(a, r, vtop->sym, fc);
}
vtop--;
}
}
/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
and 'long long' cases. */
ST_FUNC void gen_cvt_itof(int t)
{
save_reg(TREG_ST0);
gv(RC_INT);
if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
/* signed long long to float/double/long double (unsigned case
is handled generically) */
o(0x50 + vtop->r2); /* push r2 */
o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
o(0x242cdf); /* fildll (%esp) */
o(0x08c483); /* add $8, %esp */
} else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
(VT_INT | VT_UNSIGNED)) {
/* unsigned int to float/double/long double */
o(0x6a); /* push $0 */
g(0x00);
o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
o(0x242cdf); /* fildll (%esp) */
o(0x08c483); /* add $8, %esp */
} else {
/* int to float/double/long double */
o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
o(0x2404db); /* fildl (%esp) */
o(0x04c483); /* add $4, %esp */
}
vtop->r = TREG_ST0;
}
/* convert fp to int 't' type */
ST_FUNC void gen_cvt_ftoi(int t)
{
#if 1
gv(RC_FLOAT);
save_reg(TREG_EAX);
save_reg(TREG_EDX);
gen_static_call(TOK___tcc_cvt_ftol);
vtop->r = TREG_EAX; /* mark reg as used */
if (t == VT_LLONG)
vtop->r2 = TREG_EDX;
#else
int bt = vtop->type.t & VT_BTYPE;
if (bt == VT_FLOAT)
vpush_global_sym(&func_old_type, TOK___fixsfdi);
else if (bt == VT_LDOUBLE)
vpush_global_sym(&func_old_type, TOK___fixxfdi);
else
vpush_global_sym(&func_old_type, TOK___fixdfdi);
vswap();
gfunc_call(1);
vpushi(0);
vtop->r = REG_IRET;
vtop->r2 = REG_LRET;
#endif
}
/* convert from one floating point type to another */
ST_FUNC void gen_cvt_ftof(int t)
{
/* all we have to do on i386 is to put the float in a register */
gv(RC_FLOAT);
}
/* computed goto support */
ST_FUNC void ggoto(void)
{
gcall_or_jmp(1);
vtop--;
}
/* bound check support functions */
#ifdef CONFIG_TCC_BCHECK
/* generate a bounded pointer addition */
ST_FUNC void gen_bounded_ptr_add(void)
{
/* prepare fast i386 function call (args in eax and edx) */
gv2(RC_EAX, RC_EDX);
/* save all temporary registers */
vtop -= 2;
save_regs(0);
/* do a fast function call */
gen_static_call(TOK___bound_ptr_add);
/* returned pointer is in eax */
( run in 1.556 second using v1.01-cache-2.11-cpan-39bf76dae61 )