Exemple #1
0
/*-----------------------------------------------------------------*/
void
allocLocal (symbol * sym)
{
  /* generate an unique name */
  SNPRINTF (sym->rname, sizeof(sym->rname),
            "%s%s_%s_%d_%d",
            port->fun_prefix,
            currFunc->name, sym->name, sym->level, sym->block);

  sym->islocal = 1;
  sym->localof = currFunc;

  /* if this is a static variable */
  if (IS_STATIC (sym->etype))
    {
      allocGlobal (sym);
      sym->allocreq = 1;
      return;
    }

  /* if volatile then */
  if (IS_VOLATILE (sym->etype))
    sym->allocreq = 1;

  /* this is automatic           */

  /* if it's to be placed on the stack */
  if (options.stackAuto || reentrant)
    {
      sym->onStack = 1;
      if (options.useXstack)
        {
          /* PENDING: stack direction for xstack */
          SPEC_OCLS (sym->etype) = xstack;
          SPEC_STAK (sym->etype) = sym->stack = (xstackPtr + 1);
          xstackPtr += getSize (sym->type);
        }
      else
        {
          SPEC_OCLS (sym->etype) = istack;
          if (port->stack.direction > 0)
            {
              SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1);
              stackPtr += getSize (sym->type);
            }
          else
            {
              stackPtr -= getSize (sym->type);
              SPEC_STAK (sym->etype) = sym->stack = stackPtr;
            }
        }
      allocIntoSeg (sym);
      return;
    }

  /* else depending on the storage class specified */

  /* if this is a function then assign code space    */
  if (IS_FUNC (sym->type))
    {
      SPEC_OCLS (sym->etype) = code;
      return;
    }

  /* if this is a bit variable and no storage class */
  if (bit && IS_SPEC(sym->type) && SPEC_NOUN (sym->type) == V_BIT)
    {
      SPEC_SCLS (sym->type) = S_BIT;
      SPEC_OCLS (sym->type) = bit;
      allocIntoSeg (sym);
      return;
    }

  if ((SPEC_SCLS (sym->etype) == S_DATA) || (SPEC_SCLS (sym->etype) == S_REGISTER))
    {
      SPEC_OCLS (sym->etype) = (options.noOverlay ? data : overlay);
      allocIntoSeg (sym);
      return;
    }

  if (allocDefault (sym))
    {
      return;
    }

  /* again note that we have put it into the overlay segment
     will remove and put into the 'data' segment if required after
     overlay  analysis has been done */
  if (options.model == MODEL_SMALL)
    {
      SPEC_OCLS (sym->etype) =
        (options.noOverlay ? port->mem.default_local_map : overlay);
    }
  else
    {
      SPEC_OCLS (sym->etype) = port->mem.default_local_map;
    }
  allocIntoSeg (sym);
}
Exemple #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 +
                    (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;
}
Exemple #3
0
/*-----------------------------------------------------------------*/
bool
defaultOClass (symbol *sym)
{
  switch (SPEC_SCLS (sym->etype))
    {
    case S_SFR:
      SPEC_OCLS (sym->etype) = sfr;
      break;
    case S_SBIT:
      SPEC_OCLS (sym->etype) = sfrbit;
      break;
    case S_CODE:
      if (sym->_isparm)
        return FALSE;
      /* if code change to constant */
      if (sym->ival && SPEC_ABSA (sym->etype))
        {
          SPEC_OCLS(sym->etype) = c_abs;
        }
      else
        {
          SPEC_OCLS (sym->etype) = statsg;
        }
      break;
    case S_XDATA:
      /* absolute initialized global */
      if (sym->ival && SPEC_ABSA (sym->etype))
        {
          SPEC_OCLS(sym->etype) = x_abs;
        }
      /* or should we move this to the initialized data segment? */
      else if (port->genXINIT && sym->ival && (sym->level==0))
        {
          SPEC_OCLS(sym->etype) = xidata;
        }
      else
        {
          SPEC_OCLS (sym->etype) = xdata;
        }
      break;
    case S_DATA:
      /* Absolute initialized global */
      if (sym->ival && SPEC_ABSA (sym->etype))
        {
          SPEC_OCLS (sym->etype) = d_abs;
        }
      /* Other initialized global */
      else if (sym->ival && port->mem.initialized_name && sym->level == 0)
        {
          SPEC_OCLS (sym->etype) = initialized;
        }
      else
        {
          SPEC_OCLS (sym->etype) = data;
        }
      break;
    case S_IDATA:
      /* absolute initialized global */
      if (sym->ival && SPEC_ABSA (sym->etype))
        {
          SPEC_OCLS(sym->etype) = i_abs;
        }
      else
        {
          SPEC_OCLS (sym->etype) = idata;
        }
      sym->iaccess = 1;
      break;
    case S_PDATA:
      SPEC_OCLS (sym->etype) = pdata;
      sym->iaccess = 1;
      break;
    case S_BIT:
      SPEC_OCLS (sym->etype) = bit;
      break;
    case S_EEPROM:
      SPEC_OCLS (sym->etype) = eeprom;
      break;
    default:
      return FALSE;
    }
  return TRUE;
}
Exemple #4
0
/*-----------------------------------------------------------------*/
void
allocGlobal (symbol * sym)
{
  /* symbol name is internal name  */
  if (!sym->level)              /* local statics can come here */
    SNPRINTF (sym->rname, sizeof(sym->rname),
              "%s%s", port->fun_prefix, sym->name);

  /* add it to the operandKey reset */
  if (!isinSet (operKeyReset, sym))
    {
      addSet(&operKeyReset, sym);
    }

  /* if this is a literal e.g. enumerated type */
  /* put it in the data segment & do nothing   */
  if (IS_LITERAL (sym->etype))
    {
      SPEC_OCLS (sym->etype) = data;
      return;
    }

  /* if this is a function then assign code space    */
  if (IS_FUNC (sym->type))
    {
      SPEC_OCLS (sym->etype) = code;
      /* if this is an interrupt service routine
         then put it in the interrupt service array */
      if (FUNC_ISISR (sym->type) && !options.noiv &&
          (FUNC_INTNO (sym->type) != INTNO_UNSPEC))
        {
          if (interrupts[FUNC_INTNO (sym->type)])
            werror (E_INT_DEFINED,
                    FUNC_INTNO (sym->type),
                    interrupts[FUNC_INTNO (sym->type)]->name);
          else
            interrupts[FUNC_INTNO (sym->type)] = sym;

          /* automagically extend the maximum interrupts */
          if (FUNC_INTNO (sym->type) >= maxInterrupts)
            maxInterrupts = FUNC_INTNO (sym->type) + 1;
        }
      /* if it is not compiler defined */
      if (!sym->cdef)
        allocIntoSeg (sym);

      return;
    }

  /* if this is a bit variable and no storage class */
  if (bit && IS_SPEC(sym->type) && SPEC_NOUN (sym->type) == V_BIT)
    {
      SPEC_OCLS (sym->type) = bit;
      allocIntoSeg (sym);
      return;
    }

  if (sym->level)
    /* register storage class ignored changed to FIXED */
    if (SPEC_SCLS (sym->etype) == S_REGISTER)
      SPEC_SCLS (sym->etype) = S_FIXED;

  /* if it is fixed, then allocate depending on the */
  /* current memory model, same for automatics      */
  if (SPEC_SCLS (sym->etype) == S_FIXED ||
      SPEC_SCLS (sym->etype) == S_AUTO)
    {
      if (port->mem.default_globl_map != xdata)
        {
          if (sym->ival && SPEC_ABSA (sym->etype))
            {
              /* absolute initialized global */
              SPEC_OCLS (sym->etype) = x_abs;
            }
          else if (sym->ival && sym->level == 0 && port->mem.initialized_name)
            {
              SPEC_OCLS (sym->etype) = initialized;
            }
          else
            {
              /* set the output class */
              SPEC_OCLS (sym->etype) = port->mem.default_globl_map;
            }
          /* generate the symbol  */
          allocIntoSeg (sym);
          return;
        }
      else
        {
          SPEC_SCLS (sym->etype) = S_XDATA;
        }
    }

  allocDefault (sym);
  return;
}
Exemple #5
0
/*-----------------------------------------------------------------*/
static symbol *
createStackSpil (symbol * sym)
{
  symbol *sloc = NULL;
  struct dbuf_s dbuf;

  D (D_ALLOC, ("createStackSpil: for sym %p %s\n", sym, sym->name));

  /* first go try and find a free one that is already
     existing on the stack */
  if (applyToSet (_G.stackSpil, isFreeSTM8, &sloc, sym))
    {
      /* found a free one : just update & return */
      sym->usl.spillLoc = sloc;
      sym->stackSpil = 1;
      sloc->isFree = 0;
      addSetHead (&sloc->usl.itmpStack, sym);
      D (D_ALLOC, ("createStackSpil: found existing\n"));
      return sym;
    }

  /* could not then have to create one , this is the hard part
     we need to allocate this on the stack : this is really a
     hack!! but cannot think of anything better at this time */

  dbuf_init (&dbuf, 128);
  dbuf_printf (&dbuf, "sloc%d", _G.slocNum++);
  sloc = newiTemp (dbuf_c_str (&dbuf));
  dbuf_destroy (&dbuf);

  /* set the type to the spilling symbol */
  sloc->type = copyLinkChain (sym->type);
  sloc->etype = getSpec (sloc->type);
  SPEC_SCLS (sloc->etype) = S_AUTO;
  SPEC_EXTR (sloc->etype) = 0;
  SPEC_STAT (sloc->etype) = 0;
  SPEC_VOLATILE (sloc->etype) = 0;

  allocLocal (sloc);

  sloc->isref = 1;              /* to prevent compiler warning */

  wassertl (currFunc, "Local variable used outside of function.");

  /* if it is on the stack then update the stack */
  if (IN_STACK (sloc->etype))
    {
      if (currFunc)
        currFunc->stack += getSize (sloc->type);
      _G.stackExtend += getSize (sloc->type);
    }
  else
    {
      _G.dataExtend += getSize (sloc->type);
    }

  /* add it to the stackSpil set */
  addSetHead (&_G.stackSpil, sloc);
  sym->usl.spillLoc = sloc;
  sym->stackSpil = 1;

  /* add it to the set of itempStack set
     of the spill location */
  addSetHead (&sloc->usl.itmpStack, sym);

  D (D_ALLOC, ("createStackSpil: created new\n"));
  return sym;
}