Alien-TinyCC
view release on metacpan or search on metacpan
src/arm-gen.c view on Meta::CPAN
#ifdef TCC_ARM_EABI
vtop--, nb_args--;
#endif
args_size = keep = 0;
for(i = 0;i < nb_args; i++) {
vrotb(keep+1);
if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
size = type_size(&vtop->type, &align);
/* align to stack align size */
size = (size + 3) & -4;
/* allocate the necessary size on stack */
gadd_sp(-size);
/* generate structure store */
r = get_reg(RC_INT);
o(0xE1A0000D|(intr(r)<<12));
vset(&vtop->type, r | VT_LVAL, 0);
vswap();
vstore();
vtop--;
args_size += size;
} else if (is_float(vtop->type.t)) {
#ifdef TCC_ARM_HARDFLOAT
if (!variadic && --vfp_argno<16 && vfp_plan[vfp_argno]!=-1) {
plan2[keep++]=vfp_plan[vfp_argno];
continue;
}
#endif
#ifdef TCC_ARM_VFP
r=vfpr(gv(RC_FLOAT))<<12;
size=4;
if ((vtop->type.t & VT_BTYPE) != VT_FLOAT)
{
size=8;
r|=0x101; /* fstms -> fstmd */
}
o(0xED2D0A01+r);
#else
r=fpr(gv(RC_FLOAT))<<12;
if ((vtop->type.t & VT_BTYPE) == VT_FLOAT)
size = 4;
else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
size = 8;
else
size = LDOUBLE_SIZE;
if (size == 12)
r|=0x400000;
else if(size == 8)
r|=0x8000;
o(0xED2D0100|r|(size>>2));
#endif
vtop--;
args_size += size;
} else {
int s;
/* simple type (currently always same size) */
/* XXX: implicit cast ? */
size=4;
if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
lexpand_nr();
s=-1;
if(--argno<4 && plan[argno][1]!=-1)
s=plan[argno][1];
argno++;
size = 8;
if(s==-1) {
r = gv(RC_INT);
o(0xE52D0004|(intr(r)<<12)); /* str r,[sp,#-4]! */
vtop--;
} else {
size=0;
plan2[keep]=s;
keep++;
vswap();
}
}
s=-1;
if(--argno<4 && plan[argno][0]!=-1)
s=plan[argno][0];
#ifdef TCC_ARM_EABI
if(vtop->type.t == VT_VOID) {
if(s == -1)
o(0xE24DD004); /* sub sp,sp,#4 */
vtop--;
} else
#endif
if(s == -1) {
r = gv(RC_INT);
o(0xE52D0004|(intr(r)<<12)); /* str r,[sp,#-4]! */
vtop--;
} else {
size=0;
plan2[keep]=s;
keep++;
}
args_size += size;
}
}
for(i = 0; i < keep; i++) {
vrotb(keep);
gv(regmask(plan2[i]));
#ifdef TCC_ARM_HARDFLOAT
/* arg is in s(2d+1): plan2[i]<plan2[i+1] => alignment occured (ex f,d,f) */
if (i < keep - 1 && is_float(vtop->type.t) && (plan2[i] <= plan2[i + 1])) {
o(0xEEF00A40|(vfpr(plan2[i])<<12)|vfpr(plan2[i]));
}
#endif
}
save_regs(keep); /* save used temporary registers */
keep++;
if(ncrn) {
int nb_regs=0;
if (ncrn>4)
ncrn=4;
todo&=((1<<ncrn)-1);
if(todo) {
int i;
o(0xE8BD0000|todo);
for(i=0;i<4;i++)
if(todo&(1<<i)) {
( run in 0.934 second using v1.01-cache-2.11-cpan-5b529ec07f3 )