Alien-TinyCCx
view release on metacpan or search on metacpan
src/arm-gen.c view on Meta::CPAN
r=gv(RC_FLOAT);
x|=vfpr(r);
r=regmask(r);
if(!fneg) {
int r2;
vswap();
r2=gv(RC_FLOAT);
x|=vfpr(r2)<<16;
r|=regmask(r2);
}
vtop->r=get_reg_ex(RC_FLOAT,r);
if(!fneg)
vtop--;
o(x|(vfpr(vtop->r)<<12));
}
#else
static uint32_t is_fconst()
{
long double f;
uint32_t r;
if((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
return 0;
if (vtop->type.t == VT_FLOAT)
f = vtop->c.f;
else if (vtop->type.t == VT_DOUBLE)
f = vtop->c.d;
else
f = vtop->c.ld;
if(!ieee_finite(f))
return 0;
r=0x8;
if(f<0.0) {
r=0x18;
f=-f;
}
if(f==0.0)
return r;
if(f==1.0)
return r|1;
if(f==2.0)
return r|2;
if(f==3.0)
return r|3;
if(f==4.0)
return r|4;
if(f==5.0)
return r|5;
if(f==0.5)
return r|6;
if(f==10.0)
return r|7;
return 0;
}
/* generate a floating point operation 'v = t1 op t2' instruction. The
two operands are guaranted to have the same floating point type */
void gen_opf(int op)
{
uint32_t x, r, r2, c1, c2;
//fputs("gen_opf\n",stderr);
vswap();
c1 = is_fconst();
vswap();
c2 = is_fconst();
x=0xEE000100;
#if LDOUBLE_SIZE == 8
if ((vtop->type.t & VT_BTYPE) != VT_FLOAT)
x|=0x80;
#else
if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
x|=0x80;
else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE)
x|=0x80000;
#endif
switch(op)
{
case '+':
if(!c2) {
vswap();
c2=c1;
}
vswap();
r=fpr(gv(RC_FLOAT));
vswap();
if(c2) {
if(c2>0xf)
x|=0x200000; // suf
r2=c2&0xf;
} else {
r2=fpr(gv(RC_FLOAT));
}
break;
case '-':
if(c2) {
if(c2<=0xf)
x|=0x200000; // suf
r2=c2&0xf;
vswap();
r=fpr(gv(RC_FLOAT));
vswap();
} else if(c1 && c1<=0xf) {
x|=0x300000; // rsf
r2=c1;
r=fpr(gv(RC_FLOAT));
vswap();
} else {
x|=0x200000; // suf
vswap();
r=fpr(gv(RC_FLOAT));
vswap();
r2=fpr(gv(RC_FLOAT));
}
break;
case '*':
if(!c2 || c2>0xf) {
vswap();
c2=c1;
}
vswap();
r=fpr(gv(RC_FLOAT));
( run in 0.589 second using v1.01-cache-2.11-cpan-13bb782fe5a )