Ejemplo n.º 1
0
/*-----------------------------------------------------------------*/
void
redoStackOffsets (void)
{
  symbol *sym;
  int sPtr = 0;
  int xsPtr = -1;

  /* after register allocation is complete we know
     which variables will need to be assigned space
     on the stack. We will eliminate those variables
     which do not have the allocReq flag thus reducing
     the stack space */
  for (sym = setFirstItem (istack->syms); sym; sym = setNextItem (istack->syms))
    {
      int size = getSize (sym->type);
      /* nothing to do with parameters so continue */
      if ((sym->_isparm && !IS_REGPARM (sym->etype)))
        continue;

      if (BTREE_STACK)
        {
          /* Remove them all, and let btree_alloc() below put them back in more efficiently. */
          currFunc->stack -= size;
          SPEC_STAK (currFunc->etype) -= size;
      
          if(IS_AGGREGATE (sym->type) || sym->allocreq)
            btree_add_symbol (sym);
        }
       /* Do it the old way - compared to the btree approach we waste space when allocating
          variables that had their address taken, unions and aggregates. */
       else
        {
          /* if allocation not required then subtract
             size from overall stack size & continue */
          if (!IS_AGGREGATE (sym->type) && !sym->allocreq)
            {
              currFunc->stack -= size;
              SPEC_STAK (currFunc->etype) -= size;
              continue;
            }

          if (port->stack.direction > 0)
            {
              SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
              sPtr += size;
            }
          else
            {
              sPtr -= size;
              SPEC_STAK (sym->etype) = sym->stack = sPtr;
            }
        }
    }

  if (BTREE_STACK && elementsInSet (istack->syms))
    {
      btree_alloc ();
      btree_clear ();
    }

  /* do the same for the external stack */

  if (!xstack)
    return;

  for (sym = setFirstItem (xstack->syms); sym; sym = setNextItem (xstack->syms))
    {
      int size = getSize (sym->type);
      /* nothing to do with parameters so continue */
      if ((sym->_isparm && !IS_REGPARM (sym->etype)))
        continue;

      if (IS_AGGREGATE (sym->type))
        {
          SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
          xsPtr += size;
          continue;
        }

      /* if allocation not required then subtract
         size from overall stack size & continue */
      if (!sym->allocreq)
        {
          currFunc->xstack -= size;
          SPEC_STAK (currFunc->etype) -= size;
          continue;
        }

      SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
      xsPtr += size;
    }
}
Ejemplo n.º 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;
}
Ejemplo n.º 3
0
/*-----------------------------------------------------------------*/
static void
pic14emitOverlay (struct dbuf_s * aBuf)
{
        set *ovrset;

        /*  if (!elementsInSet (ovrSetSets))*/

        /* the hack below, fixes translates for devices which
        * only have udata_shr memory */
        dbuf_printf (aBuf, "%s\t%s\n",
                (elementsInSet(ovrSetSets)?"":";"),
                port->mem.overlay_name);

        /* for each of the sets in the overlay segment do */
        for (ovrset = setFirstItem (ovrSetSets); ovrset;
        ovrset = setNextItem (ovrSetSets))
        {

                symbol *sym;

                if (elementsInSet (ovrset))
                {
                /* this dummy area is used to fool the assembler
                otherwise the assembler will append each of these
                declarations into one chunk and will not overlay
                        sad but true */

                        /* I don't think this applies to us. We are using gpasm.  CRF */

                        dbuf_printf (aBuf, ";\t.area _DUMMY\n");
                        /* output the area informtion */
                        dbuf_printf (aBuf, ";\t.area\t%s\n", port->mem.overlay_name);   /* MOF */
                }

                for (sym = setFirstItem (ovrset); sym;
                sym = setNextItem (ovrset))
                {

                        /* if extern then do nothing */
                        if (IS_EXTERN (sym->etype))
                                continue;

                                /* if allocation required check is needed
                                then check if the symbol really requires
                        allocation only for local variables */
                        if (!IS_AGGREGATE (sym->type) &&
                                !(sym->_isparm && !IS_REGPARM (sym->etype))
                                && !sym->allocreq && sym->level)
                                continue;

                                /* if global variable & not static or extern
                        and addPublics allowed then add it to the public set */
                        if ((sym->_isparm && !IS_REGPARM (sym->etype))
                                && !IS_STATIC (sym->etype))
                                addSetHead (&publics, sym);

                                /* if extern then do nothing or is a function
                        then do nothing */
                        if (IS_FUNC (sym->type))
                                continue;

                        /* print extra debug info if required */
                        if (options.debug || sym->level == 0)
                        {
                                if (!sym->level)
                                {               /* global */
                                        if (IS_STATIC (sym->etype))
                                                dbuf_printf (aBuf, "F%s_", moduleName); /* scope is file */
                                        else
                                                dbuf_printf (aBuf, "G_");       /* scope is global */
                                }
                                else
                                        /* symbol is local */
                                        dbuf_printf (aBuf, "L%s_",
                                        (sym->localof ? sym->localof->name : "-null-"));
                                dbuf_printf (aBuf, "%s_%d_%d", sym->name, sym->level, sym->block);
                        }

                        /* if is has an absolute address then generate
                        an equate for this no need to allocate space */
                        if (SPEC_ABSA (sym->etype))
                        {

                                if (options.debug || sym->level == 0)
                                        dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));

                                dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
                                        sym->rname,
                                        SPEC_ADDR (sym->etype));
                        }
                        else
                        {
                                if (options.debug || sym->level == 0)
                                        dbuf_printf (aBuf, "==.\n");

                                /* allocate space */
                                dbuf_printf (aBuf, "%s:\n", sym->rname);
                                dbuf_printf (aBuf, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
                        }

                }
        }
}
Ejemplo n.º 4
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);
}
Ejemplo n.º 5
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);
}
Ejemplo n.º 6
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;

}
Ejemplo n.º 7
0
/*-----------------------------------------------------------------*/
void
redoStackOffsets (void)
{
  symbol *sym;
  int sPtr = 0;
  int xsPtr = -1;

  /* after register allocation is complete we know
     which variables will need to be assigned space
     on the stack. We will eliminate those variables
     which do not have the allocReq flag thus reducing
     the stack space */
  for (sym = setFirstItem (istack->syms); sym; sym = setNextItem (istack->syms))
    {
      int size = getSize (sym->type);
      /* nothing to do with parameters so continue */
      if ((sym->_isparm && !IS_REGPARM (sym->etype)))
        continue;

      if (IS_AGGREGATE (sym->type))
        {
          if (port->stack.direction > 0)
            {
              SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
              sPtr += size;
            }
          else
            {
              sPtr -= size;
              SPEC_STAK (sym->etype) = sym->stack = sPtr;
            }
          continue;
        }

      /* if allocation not required then subtract
         size from overall stack size & continue */
      if (!sym->allocreq)
        {
          currFunc->stack -= size;
          SPEC_STAK (currFunc->etype) -= size;
          continue;
        }

      if (port->stack.direction > 0)
        {
          SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
          sPtr += size;
        }
      else
        {
          sPtr -= size;
          SPEC_STAK (sym->etype) = sym->stack = sPtr;
        }
    }

  /* do the same for the external stack */

  for (sym = setFirstItem (xstack->syms); sym; sym = setNextItem (xstack->syms))
    {
      int size = getSize (sym->type);
      /* nothing to do with parameters so continue */
      if ((sym->_isparm && !IS_REGPARM (sym->etype)))
        continue;

      if (IS_AGGREGATE (sym->type))
        {
          SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
          xsPtr += size;
          continue;
        }

      /* if allocation not required then subtract
         size from overall stack size & continue */
      if (!sym->allocreq)
        {
          currFunc->xstack -= size;
          SPEC_STAK (currFunc->etype) -= size;
          continue;
        }

      SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
      xsPtr += size;
    }
}