示例#1
0
文件: SDCCmem.c 项目: doniexun/kcc
/*-----------------------------------------------------------------*/
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;
    }
}
示例#2
0
文件: glue.c 项目: ruedagato/arqui
/*-----------------------------------------------------------------*/
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);
                        }

                }
        }
}
示例#3
0
/*-----------------------------------------------------------------*/
static void
regTypeNum (void)
{
  symbol *sym;
  int k;

  /* for each live range do */
  for (sym = hTabFirstItem (liveRanges, &k); sym; sym = hTabNextItem (liveRanges, &k))
    {
      /* if used zero times then no registers needed. Exception: Variables larger than 4 bytes - these might need a spill location when they are return values */
      if ((sym->liveTo - sym->liveFrom) == 0 && getSize (sym->type) <= 4)
        continue;

      D (D_ALLOC, ("regTypeNum: loop on sym %p\n", sym));

      /* if the live range is a temporary */
      if (sym->isitmp)
        {
          /* if the type is marked as a conditional */
          if (sym->regType == REG_CND)
            continue;

          /* if used in return only then we don't
             need registers */
          if (sym->ruonly || sym->accuse)
            {
              if (IS_AGGREGATE (sym->type) || sym->isptr)
                sym->type = aggrToPtr (sym->type, FALSE);
              continue;
            }

          /* if not then we require registers */
          D (D_ALLOC,
             ("regTypeNum: isagg %u nRegs %u type %p\n", IS_AGGREGATE (sym->type) || sym->isptr, sym->nRegs, sym->type));
          sym->nRegs =
            ((IS_AGGREGATE (sym->type)
              || sym->isptr) ? getSize (sym->type = aggrToPtr (sym->type, FALSE)) : getSize (sym->type));
          D (D_ALLOC, ("regTypeNum: setting nRegs of %s (%p) to %u\n", sym->name, sym, sym->nRegs));

          D (D_ALLOC, ("regTypeNum: setup to assign regs sym %p\n", sym));

          if (sym->nRegs > 8)
            {
              fprintf (stderr, "allocated more than 8 registers for type ");
              printTypeChain (sym->type, stderr);
              fprintf (stderr, "\n");
            }

          /* determine the type of register required */
          /* Always general purpose */
          sym->regType = REG_GPR;
        }
      else
        {
          /* for the first run we don't provide */
          /* registers for true symbols we will */
          /* see how things go                  */
          D (D_ALLOC, ("regTypeNum: #2 setting num of %p to 0\n", sym));
          sym->nRegs = 0;
        }
    }
}
示例#4
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;
    }
}
示例#5
0
文件: glue.c 项目: TronicLabs/sdcc
/*
 * Parse the type and its initializer and emit it (recursively).
 */
static void
emitInitVal(struct dbuf_s *oBuf, symbol *topsym, sym_link *my_type, initList *list)
{
    symbol *sym;
    int size, i;
    long lit;
    unsigned char *str;

    /* Handle designated initializers */
    if (list)
      list = reorderIlist (my_type, list);

    /* If this is a hole, substitute an appropriate initializer. */
    if (list && list->type == INIT_HOLE)
      {
        if (IS_AGGREGATE (my_type))
          {
            list = newiList(INIT_DEEP, NULL); /* init w/ {} */
          }
        else
          {
            ast *ast = newAst_VALUE (constVal("0"));
            ast = decorateType (ast, RESULT_TYPE_NONE);
            list = newiList(INIT_NODE, ast);
          }
      }

    size = getSize(my_type);

    if (IS_PTR(my_type)) {
        DEBUGprintf ("(pointer, %d byte) %p\n", size, list ? (void *)(long)list2int(list) : NULL);
        emitIvals(oBuf, topsym, list, 0, size);
        return;
    }

    if (IS_ARRAY(my_type) && topsym && topsym->isstrlit) {
        str = (unsigned char *)SPEC_CVAL(topsym->etype).v_char;
        emitIvalLabel(oBuf, topsym);
        do {
            dbuf_printf (oBuf, "\tretlw 0x%02x ; '%c'\n", str[0], (str[0] >= 0x20 && str[0] < 128) ? str[0] : '.');
        } while (*(str++));
        return;
    }

    if (IS_ARRAY(my_type) && list && list->type == INIT_NODE) {
        fprintf (stderr, "Unhandled initialized symbol: %s\n", topsym->name);
        assert ( !"Initialized char-arrays are not yet supported, assign at runtime instead." );
        return;
    }

    if (IS_ARRAY(my_type)) {
        DEBUGprintf ("(array, %d items, %d byte) below\n", DCL_ELEM(my_type), size);
        assert (!list || list->type == INIT_DEEP);
        if (list) list = list->init.deep;
        for (i = 0; i < DCL_ELEM(my_type); i++) {
            emitInitVal(oBuf, topsym, my_type->next, list);
            topsym = NULL;
            if (list) list = list->next;
        } // for i
        return;
    }

    if (IS_FLOAT(my_type)) {
        // float, 32 bit
        DEBUGprintf ("(float, %d byte) %lf\n", size, list ? list2int(list) : 0.0);
        emitIvals(oBuf, topsym, list, 0, size);
        return;
    }

    if (IS_CHAR(my_type) || IS_INT(my_type) || IS_LONG(my_type)) {
        // integral type, 8, 16, or 32 bit
        DEBUGprintf ("(integral, %d byte) 0x%lx/%ld\n", size, list ? (long)list2int(list) : 0, list ? (long)list2int(list) : 0);
        emitIvals(oBuf, topsym, list, 0, size);
        return;

    } else if (IS_STRUCT(my_type) && SPEC_STRUCT(my_type)->type == STRUCT) {
        // struct
        DEBUGprintf ("(struct, %d byte) handled below\n", size);
        assert (!list || (list->type == INIT_DEEP));

        // iterate over struct members and initList
        if (list) list = list->init.deep;
        sym = SPEC_STRUCT(my_type)->fields;
        while (sym) {
            long bitfield = 0;
            int len = 0;
            if (IS_BITFIELD(sym->type)) {
                while (sym && IS_BITFIELD(sym->type)) {
                    int bitoff = SPEC_BSTR(getSpec(sym->type)) + 8 * sym->offset;
                    assert (!list || ((list->type == INIT_NODE)
                                && IS_AST_LIT_VALUE(list->init.node)));
                    lit = (long) (list ? list2int(list) : 0);
                    DEBUGprintf ( "(bitfield member) %02lx (%d bit, starting at %d, bitfield %02lx)\n",
                            lit, SPEC_BLEN(getSpec(sym->type)),
                            bitoff, bitfield);
                    bitfield |= (lit & ((1ul << SPEC_BLEN(getSpec(sym->type))) - 1)) << bitoff;
                    len += SPEC_BLEN(getSpec(sym->type));

                    sym = sym->next;
                    if (list) list = list->next;
                } // while
                assert (len < sizeof (long) * 8); // did we overflow our initializer?!?
                len = (len + 7) & ~0x07; // round up to full bytes
                emitIvals(oBuf, topsym, NULL, bitfield, len / 8);
                topsym = NULL;
            } // if

            if (sym) {
                emitInitVal(oBuf, topsym, sym->type, list);
                topsym = NULL;
                sym = sym->next;
                if (list) list = list->next;
            } // if
        } // while
        if (list) {
            assert ( !"Excess initializers." );
        } // if
        return;

    } else if (IS_STRUCT(my_type) && SPEC_STRUCT(my_type)->type == UNION) {
        // union
        DEBUGprintf ("(union, %d byte) handled below\n", size);
        assert (list && list->type == INIT_DEEP);

        // iterate over union members and initList, try to map number and type of fields and initializers
        my_type = matchIvalToUnion(list, my_type, size);
        if (my_type) {
            emitInitVal(oBuf, topsym, my_type, list->init.deep);
            topsym = NULL;
            size -= getSize(my_type);
            if (size > 0) {
                // pad with (leading) zeros
                emitIvals(oBuf, NULL, NULL, 0, size);
            }
            return;
        } // if

        assert ( !"No UNION member matches the initializer structure.");
    } else if (IS_BITFIELD(my_type)) {
        assert ( !"bitfields should only occur in structs..." );

    } else {
        printf ("SPEC_NOUN: %d\n", SPEC_NOUN(my_type));
        assert( !"Unhandled initialized type.");
    }
}