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 )