Example #1
0
/*-----------------------------------------------------------------*/
static S4O_RET
termScanAtFunc (const lineNode *pl, int rIdx)
{
  sym_link *ftype;
  bool banked_reg = (rIdx == R0_IDX) || (rIdx == R1_IDX) || (rIdx == R2_IDX);

  if (!isFunc (pl))
    return S4O_CONTINUE;
  // let's assume calls to literally given locations use the default
  // most notably :  (*(void (*)()) 0) ();  see bug 1749275
  if (IS_VALOP (IC_LEFT (pl->ic)))
    return (options.model == MODEL_HUGE) && banked_reg ? S4O_ABORT : options.all_callee_saves ? S4O_CONTINUE : S4O_TERM;
  ftype = OP_SYM_TYPE(IC_LEFT(pl->ic));
  if (IS_FUNCPTR (ftype))
    ftype = ftype->next;
  if (IFFUNC_ISBANKEDCALL(ftype) && banked_reg)
    return S4O_ABORT;
  if (FUNC_ARGS (ftype) && getSize (FUNC_ARGS (ftype)->type) > 4)
    return S4O_ABORT;
  if (FUNC_CALLEESAVES(ftype))
    return S4O_CONTINUE;
  if (FUNC_ISNAKED(ftype))
    return S4O_CONTINUE;
  return S4O_TERM;
}
Example #2
0
/*-----------------------------------------------------------------*/
static void 
convilong (iCode * ic, eBBlock * ebp, sym_link * type, int op)
{
  symbol *func = NULL;
  iCode *ip = ic->next;
  iCode *newic;
  int lineno = ic->lineno;
  int bwd;
  int su;
  int bytesPushed=0;

  remiCodeFromeBBlock (ebp, ic);

  /* depending on the type */
  for (bwd = 0; bwd < 3; bwd++)
    {
      for (su = 0; su < 2; su++)
	{
	  if (compareType (type, __multypes[bwd][su]) == 1)
	    {
	      if (op == '*')
		func = __muldiv[0][bwd][su];
	      else if (op == '/')
		func = __muldiv[1][bwd][su];
	      else if (op == '%')
		func = __muldiv[2][bwd][su];
              else if (op == RRC)
		func = __rlrr[1][bwd][su];
              else if (op == RLC)
		func = __rlrr[0][bwd][su];
              else if (op == RIGHT_OP)
		func = __rlrr[1][bwd][su];
              else if (op == LEFT_OP)
		func = __rlrr[0][bwd][su];
	      else
		assert (0);
	      goto found;
	    }
	}
    }
  assert (0);
found:
  /* if int & long support routines NOT compiled as reentrant */
  if (!options.intlong_rent)
    {
      /* first one */
      if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
	newic = newiCode (SEND, IC_LEFT (ic), NULL);
      else
	{
	  newic = newiCode ('=', NULL, IC_LEFT (ic));
	  IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
	}
      addiCodeToeBBlock (ebp, newic, ip);
      newic->lineno = lineno;

      /* second one */
      if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
	newic = newiCode (SEND, IC_RIGHT (ic), NULL);
      else
	{
	  newic = newiCode ('=', NULL, IC_RIGHT (ic));
	  IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next);
	}
      addiCodeToeBBlock (ebp, newic, ip);
      newic->lineno = lineno;

    }
  else
    {
      /* compiled as reentrant then push */
      /* push right */
      if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
        {
          newic = newiCode (SEND, IC_RIGHT (ic), NULL);
        }
      else
	{
	  newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
	  newic->parmPush = 1;

	  bytesPushed += getSize(operandType(IC_RIGHT(ic)));
	}
      addiCodeToeBBlock (ebp, newic, ip);
      newic->lineno = lineno;

      /* insert push left */
      if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
        {
          newic = newiCode (SEND, IC_LEFT (ic), NULL);
        }
      else
	{
	  newic = newiCode (IPUSH, IC_LEFT (ic), NULL);
	  newic->parmPush = 1;

	  bytesPushed += getSize(operandType(IC_LEFT(ic)));
	}
      addiCodeToeBBlock (ebp, newic, ip);
      newic->lineno = lineno;

    }

  /* for the result */
  newic = newiCode (CALL, operandFromSymbol (func), NULL);
  IC_RESULT (newic) = IC_RESULT (ic);
  newic->lineno = lineno;
  newic->parmBytes+=bytesPushed; // to clear the stack after the call
  addiCodeToeBBlock (ebp, newic, ip);
}
Example #3
0
/*-----------------------------------------------------------------*/
static void 
cnvToFcall (iCode * ic, eBBlock * ebp)
{
  iCode *ip;
  iCode *newic;
  operand *left;
  operand *right;
  symbol *func = NULL;
  int lineno = ic->lineno;
  int bytesPushed=0;

  ip = ic->next;		/* insertion point */
  /* remove it from the iCode */
  remiCodeFromeBBlock (ebp, ic);

  left = IC_LEFT (ic);
  right = IC_RIGHT (ic);

  switch (ic->op)
    {
    case '+':
      func = __fsadd;
      break;
    case '-':
      func = __fssub;
      break;
    case '/':
      func = __fsdiv;
      break;
    case '*':
      func = __fsmul;
      break;
    case EQ_OP:
      func = __fseq;
      break;
    case NE_OP:
      func = __fsneq;
      break;
    case '<':
      func = __fslt;
      break;
    case '>':
      func = __fsgt;
      break;
    case LE_OP:
      func = __fslteq;
      break;
    case GE_OP:
      func = __fsgteq;
      break;
    }

  /* if float support routines NOT compiled as reentrant */
  if (!options.float_rent)
    {

      /* first one */
      if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
	{
	  newic = newiCode (SEND, IC_LEFT (ic), NULL);
	}
      else
	{
	  newic = newiCode ('=', NULL, IC_LEFT (ic));
	  IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
	}

      addiCodeToeBBlock (ebp, newic, ip);
      newic->lineno = lineno;

      /* second one */
      if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
	{
	  newic = newiCode (SEND, IC_LEFT (ic), NULL);
	}
      else
	{
	  newic = newiCode ('=', NULL, IC_RIGHT (ic));
	  IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next);
	}
      addiCodeToeBBlock (ebp, newic, ip);
      newic->lineno = lineno;

    }
  else
    {

      /* push right */
      if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
	{
	  newic = newiCode (SEND, right, NULL);
	}
      else
	{
	  newic = newiCode (IPUSH, right, NULL);
	  newic->parmPush = 1;
	  bytesPushed+=4;
	}

      addiCodeToeBBlock (ebp, newic, ip);
      newic->lineno = lineno;

      /* insert push left */
      if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
	{
	  newic = newiCode (SEND, left, NULL);
	}
      else
	{
	  newic = newiCode (IPUSH, left, NULL);
	  newic->parmPush = 1;
	  bytesPushed+=4;
	}
      addiCodeToeBBlock (ebp, newic, ip);
      newic->lineno = lineno;
    }
  /* insert the call */
  newic = newiCode (CALL, operandFromSymbol (func), NULL);
  IC_RESULT (newic) = IC_RESULT (ic);
  newic->lineno = lineno;
  newic->parmBytes+=bytesPushed;
  addiCodeToeBBlock (ebp, newic, ip);
}
Example #4
0
/*-----------------------------------------------------------------*/
static void 
cnvFromFloatCast (iCode * ic, eBBlock * ebp)
{
  iCode *ip, *newic;
  symbol *func;
  sym_link *type = operandType (IC_LEFT (ic));
  int lineno = ic->lineno;
  int bwd, su;

  ip = ic->next;
  /* remove it from the iCode */
  remiCodeFromeBBlock (ebp, ic);

  /* depending on the type */
  for (bwd = 0; bwd < 3; bwd++)
    {
      for (su = 0; su < 2; su++)
	{
	  if (compareType (type, __multypes[bwd][su]) == 1)
	    {
	      func = __conv[1][bwd][su];
	      goto found;
	    }
	}
    }
  assert (0);
found:

  /* if float support routines NOT compiled as reentrant */
  if (!options.float_rent)
    {
      /* first one */
      if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
	newic = newiCode (SEND, IC_RIGHT (ic), NULL);
      else
	{
	  newic = newiCode ('=', NULL, IC_RIGHT (ic));
	  IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type));
	}
      addiCodeToeBBlock (ebp, newic, ip);
      newic->lineno = lineno;

    }
  else
    {

      /* push the left */
      if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
	newic = newiCode (SEND, IC_RIGHT (ic), NULL);
      else
	{
	  newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
	  newic->parmPush = 1;
	}
      addiCodeToeBBlock (ebp, newic, ip);
      newic->lineno = lineno;

    }

  /* make the call */
  newic = newiCode (CALL, operandFromSymbol (func), NULL);
  IC_RESULT (newic) = IC_RESULT (ic);
  addiCodeToeBBlock (ebp, newic, ip);
  newic->lineno = lineno;

}