Пример #1
0
/*
 * Emit the section preamble, absolute location (if any) and
 * symbol name(s) for intialized data.
 */
static int
emitIvalLabel(struct dbuf_s *oBuf, symbol *sym)
{
    char *segname;
    static int in_code = 0;
    static int sectionNr = 0;

    if (sym) {
        // code or data space?
        if (IS_CODE(getSpec(sym->type))) {
            segname = "code";
            in_code = 1;
        } else {
            segname = "idata";
            in_code  = 0;
        }
        dbuf_printf(oBuf, "\nID_%s_%d\t%s", moduleName, sectionNr++, segname);
        if (SPEC_ABSA(getSpec(sym->type))) {
            // specify address for absolute symbols
            dbuf_printf(oBuf, "\t0x%04X", SPEC_ADDR(getSpec(sym->type)));
        } // if
        dbuf_printf(oBuf, "\n%s\n", sym->rname);

        addSet(&emitted, sym->rname);
    }
    return (in_code);
}
Пример #2
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;
}
Пример #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;
}
Пример #4
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);
                        }

                }
        }
}
Пример #5
0
static void
pic14_constructAbsMap (struct dbuf_s *oBuf, struct dbuf_s *gloBuf)
{
  memmap *maps[] = { data, sfr, NULL };
  int i;
  hTab *ht = NULL;
  symbol *sym;
  set *aliases;
  int addr, min=-1, max=-1;
  int size;

  for (i=0; maps[i] != NULL; i++)
  {
    for (sym = (symbol *)setFirstItem (maps[i]->syms);
        sym; sym = setNextItem (maps[i]->syms))
    {
      if (IS_DEFINED_HERE(sym) && SPEC_ABSA(sym->etype))
      {
        addr = SPEC_ADDR(sym->etype);

        /* handle CONFIG words here */
        if (IS_CONFIG_ADDRESS( addr ))
        {
          //fprintf( stderr, "%s: assignment to CONFIG@0x%x found\n", __FUNCTION__, addr );
          //fprintf( stderr, "ival: %p (0x%x)\n", sym->ival, (int)list2int( sym->ival ) );
          if (sym->ival) {
            pic14_assignConfigWordValue( addr, (int)list2int( sym->ival ) );
          } else {
            fprintf( stderr, "ERROR: Symbol %s, which is covering a __CONFIG word must be initialized!\n", sym->name );
          }
          continue;
        }

        if (max == -1 || addr > max) max = addr;
        if (min == -1 || addr < min) min = addr;
        //fprintf (stderr, "%s: sym %s @ 0x%x\n", __FUNCTION__, sym->name, addr);
        aliases = hTabItemWithKey (ht, addr);
        if (aliases) {
          /* May not use addSetHead, as we cannot update the
           * list's head in the hastable `ht'. */
          addSet (&aliases, sym);
#if 0
          fprintf( stderr, "%s: now %d aliases for %s @ 0x%x\n",
              __FUNCTION__, elementsInSet(aliases), sym->name, addr);
#endif
        } else {
          addSet (&aliases, sym);
          hTabAddItem (&ht, addr, aliases);
        } // if
      } // if
    } // for sym
  } // for i

  /* now emit definitions for all absolute symbols */
  dbuf_printf (oBuf, "%s", iComments2);
  dbuf_printf (oBuf, "; absolute symbol definitions\n");
  dbuf_printf (oBuf, "%s", iComments2);
  for (addr=min; addr <= max; addr++)
  {
    size = 1;
    aliases = hTabItemWithKey (ht, addr);
    if (aliases && elementsInSet(aliases)) {
      /* Make sure there is no initialized value at this location! */
      for (sym = setFirstItem(aliases); sym; sym = setNextItem(aliases)) {
          if (sym->ival) break;
      } // for
      if (sym) continue;

      dbuf_printf (oBuf, "UD_abs_%s_%x\tudata_ovr\t0x%04x\n",
          moduleName, addr, addr);
      for (sym = setFirstItem (aliases); sym;
          sym = setNextItem (aliases))
      {
        if (getSize(sym->type) > size) {
          size = getSize(sym->type);
        }

        /* initialized values are handled somewhere else */
        if (sym->ival) continue;

        /* emit STATUS as well as _STATUS, required for SFRs only */
        //dbuf_printf (oBuf, "%s\tres\t0\n", sym->name);
        dbuf_printf (oBuf, "%s\n", sym->rname);

        if (IS_GLOBAL(sym) && !IS_STATIC(sym->etype)) {
            //emitIfNew(gloBuf, &emitted, "\tglobal\t%s\n", sym->name);
            emitIfNew(gloBuf, &emitted, "\tglobal\t%s\n", sym->rname);
        } // if
      } // for
      dbuf_printf (oBuf, "\tres\t%d\n", size);
    } // if
  } // for i
}
Пример #6
0
/*
 * Emit a set of symbols.
 * type - 0: have symbol tell whether it is local, extern or global
 *        1: assume all symbols in set to be global
 *        2: assume all symbols in set to be extern
 */
static void
emitSymbolSet(set *s, int type)
{
    symbol *sym;
    initList *list;
    unsigned sectionNr = 0;

    for (sym = setFirstItem(s); sym; sym = setNextItem(s)) {
#if 0
        fprintf (stdout, ";    name %s, rname %s, level %d, block %d, key %d, local %d, ival %p, static %d, cdef %d, used %d\n",
                sym->name, sym->rname, sym->level, sym->block, sym->key, sym->islocal, sym->ival, IS_STATIC(sym->etype), sym->cdef, sym->used);
#endif

        if (sym->etype && SPEC_ABSA(sym->etype)
                && IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))
                && sym->ival)
        {
            // handle config words
            pic14_assignConfigWordValue(SPEC_ADDR(sym->etype),
                    (int)list2int(sym->ival));
            pic14_stringInSet(sym->rname, &emitted, 1);
            continue;
        }

        if (sym->isstrlit) {
            // special case: string literals
            emitInitVal(ivalBuf, sym, sym->type, NULL);
            continue;
        }

        if (type != 0 || sym->cdef
                || (!IS_STATIC(sym->etype)
                    && IS_GLOBAL(sym)))
        {
            // bail out for ___fsadd and friends
            if (sym->cdef && !sym->used) continue;

            /* export or import non-static globals */
            if (!pic14_stringInSet(sym->rname, &emitted, 0)) {

                if (type == 2 || IS_EXTERN(sym->etype) || sym->cdef)
                {
                    /* do not add to emitted set, it might occur again! */
                    //if (!sym->used) continue;
                    // declare symbol
                    emitIfNew (extBuf, &emitted, "\textern\t%s\n", sym->rname);
                } else {
                    // declare symbol
                    emitIfNew (gloBuf, &emitted, "\tglobal\t%s\n", sym->rname);
                    if (!sym->ival && !IS_FUNC(sym->type)) {
                        // also define symbol
                        if (IS_ABSOLUTE(sym->etype)) {
                            // absolute location?
                            //dbuf_printf (gloDefBuf, "UD_%s_%u\tudata\t0x%04X\n", moduleName, sectionNr++, SPEC_ADDR(sym->etype));
                            // deferred to pic14_constructAbsMap
                        } else {
                            dbuf_printf (gloDefBuf, "UD_%s_%u\tudata\n", moduleName, sectionNr++);
                            dbuf_printf (gloDefBuf, "%s\tres\t%d\n\n", sym->rname, getSize(sym->type));
                        }
                    } // if
                } // if
                pic14_stringInSet(sym->rname, &emitted, 1);
            } // if
        } // if
        list = sym->ival;
        //if (list) showInitList(list, 0);
        if (list) {
            resolveIvalSym( list, sym->type );
            emitInitVal(ivalBuf, sym, sym->type, sym->ival);
            dbuf_printf (ivalBuf, "\n");
        }
    } // for sym
}