Alien-TinyCC
view release on metacpan or search on metacpan
src/tccgen.c view on Meta::CPAN
#endif
/* generic ftoi for unsigned long long case */
static void gen_cvt_ftoi1(int t)
{
int st;
if (t == (VT_LLONG | VT_UNSIGNED)) {
/* not handled natively */
st = vtop->type.t & VT_BTYPE;
if (st == VT_FLOAT)
vpush_global_sym(&func_old_type, TOK___fixunssfdi);
#if LDOUBLE_SIZE != 8
else if (st == VT_LDOUBLE)
vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
#endif
else
vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
vrott(2);
gfunc_call(1);
vpushi(0);
vtop->r = REG_IRET;
vtop->r2 = REG_LRET;
} else {
gen_cvt_ftoi(t);
}
}
/* force char or short cast */
static void force_charshort_cast(int t)
{
int bits, dbt;
dbt = t & VT_BTYPE;
/* XXX: add optimization if lvalue : just change type and offset */
if (dbt == VT_BYTE)
bits = 8;
else
bits = 16;
if (t & VT_UNSIGNED) {
vpushi((1 << bits) - 1);
gen_op('&');
} else {
bits = 32 - bits;
vpushi(bits);
gen_op(TOK_SHL);
/* result must be signed or the SAR is converted to an SHL
This was not the case when "t" was a signed short
and the last value on the stack was an unsigned int */
vtop->type.t &= ~VT_UNSIGNED;
vpushi(bits);
gen_op(TOK_SAR);
}
}
/* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
static void gen_cast(CType *type)
{
int sbt, dbt, sf, df, c, p;
/* special delayed cast for char/short */
/* XXX: in some cases (multiple cascaded casts), it may still
be incorrect */
if (vtop->r & VT_MUSTCAST) {
vtop->r &= ~VT_MUSTCAST;
force_charshort_cast(vtop->type.t);
}
/* bitfields first get cast to ints */
if (vtop->type.t & VT_BITFIELD) {
gv(RC_INT);
}
dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
if (sbt != dbt) {
sf = is_float(sbt);
df = is_float(dbt);
c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
if (c) {
/* constant case: we can do it now */
/* XXX: in ISOC, cannot do it if error in convert */
if (sbt == VT_FLOAT)
vtop->c.ld = vtop->c.f;
else if (sbt == VT_DOUBLE)
vtop->c.ld = vtop->c.d;
if (df) {
if ((sbt & VT_BTYPE) == VT_LLONG) {
if (sbt & VT_UNSIGNED)
vtop->c.ld = vtop->c.ull;
else
vtop->c.ld = vtop->c.ll;
} else if(!sf) {
if (sbt & VT_UNSIGNED)
vtop->c.ld = vtop->c.ui;
else
vtop->c.ld = vtop->c.i;
}
if (dbt == VT_FLOAT)
vtop->c.f = (float)vtop->c.ld;
else if (dbt == VT_DOUBLE)
vtop->c.d = (double)vtop->c.ld;
} else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
vtop->c.ull = (unsigned long long)vtop->c.ld;
} else if (sf && dbt == VT_BOOL) {
vtop->c.i = (vtop->c.ld != 0);
} else {
if(sf)
vtop->c.ll = (long long)vtop->c.ld;
else if (sbt == (VT_LLONG|VT_UNSIGNED))
vtop->c.ll = vtop->c.ull;
else if (sbt & VT_UNSIGNED)
vtop->c.ll = vtop->c.ui;
#ifdef TCC_TARGET_X86_64
else if (sbt == VT_PTR)
;
#endif
else if (sbt != VT_LLONG)
( run in 1.224 second using v1.01-cache-2.11-cpan-787462296c9 )