Пример #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;
}
Пример #2
0
/*-----------------------------------------------------------------*/
void
allocParms (value * val)
{
  value *lval;
  int pNum = 1;

  for (lval = val; lval; lval = lval->next, pNum++)
    {
      /* check the declaration */
      checkDecl (lval->sym, 0);

      /* if this a register parm then allocate
         it as a local variable by adding it
         to the first block we see in the body */
      if (IS_REGPARM (lval->etype))
        continue;

      /* mark it as my parameter */
      lval->sym->ismyparm = 1;
      lval->sym->localof = currFunc;

      /* if automatic variables r 2b stacked */
      if (options.stackAuto || IFFUNC_ISREENT (currFunc->type))
        {
          if (lval->sym)
            lval->sym->onStack = 1;

          /* choose which stack 2 use   */
          /*  use xternal stack */
          if (options.useXstack)
            {
              /* PENDING: stack direction support */
              SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack;
              SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
                xstackPtr - getSize (lval->type);
              xstackPtr -= getSize (lval->type);
            }
          else
            {                   /* use internal stack   */
              SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack;
              if (port->stack.direction > 0)
                {
                  SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
                    stackPtr - (FUNC_REGBANK (currFunc->type) ? port->stack.bank_overhead : 0) -
                    getSize (lval->type) -
                    (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0);
                  stackPtr -= getSize (lval->type);
                }
              else
                {
                  /* This looks like the wrong order but it turns out OK... */
                  /* PENDING: isr, bank overhead, ... */
                  SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
                    stackPtr +
                    ((IFFUNC_ISBANKEDCALL (currFunc->type) && !SPEC_STAT(getSpec(currFunc->etype)))? port->stack.banked_overhead : 0) +
                    (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0) +
                    0;
                  stackPtr += getSize (lval->type);
                }
            }
          allocIntoSeg (lval->sym);
        }
      else
        { /* allocate them in the automatic space */
          /* generate a unique name  */
          SNPRINTF (lval->sym->rname, sizeof(lval->sym->rname),
                    "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum);
          strncpyz (lval->name, lval->sym->rname, sizeof(lval->name));

          /* if declared in specific storage */
          if (allocDefault (lval->sym))
            {
              SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype);
              continue;
            }

          /* otherwise depending on the memory model */
          SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
              port->mem.default_local_map;
          if (options.model == MODEL_SMALL)
            {
              /* note here that we put it into the overlay segment
                 first, we will remove it from the overlay segment
                 after the overlay determination has been done */
              if (!options.noOverlay)
                {
                  SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
                    overlay;
                }
            }
          else if (options.model == MODEL_MEDIUM)
            {
              SPEC_SCLS (lval->etype) = S_PDATA;
            }
          else
            {
              SPEC_SCLS (lval->etype) = S_XDATA;
            }
          allocIntoSeg (lval->sym);
        }
    }
  return;
}