Пример #1
0
/*-----------------------------------------------------------------*/
void
allocIntoSeg (symbol *sym)
{
  memmap *segment;

  if (SPEC_ADDRSPACE (sym->etype))
    {
      namedspacemap *nm;
      for (nm = namedspacemaps; nm; nm = nm->next)
        if (!strcmp (nm->name, SPEC_ADDRSPACE (sym->etype)->name))
          break;

      if (!nm)
        {
          nm = Safe_alloc (sizeof (namedspacemap));
          nm->name = Safe_alloc (strlen(SPEC_ADDRSPACE (sym->etype)->name) + 1);
          strcpy (nm->name, SPEC_ADDRSPACE (sym->etype)->name);
          nm->is_const = (SPEC_ADDRSPACE (sym->etype)->type && SPEC_CONST (SPEC_ADDRSPACE (sym->etype)->type));
          nm->map = nm->is_const ?
            allocMap (0, 1, 0, 0, 0, 1, options.code_loc, SPEC_ADDRSPACE (sym->etype)->name, 'C', CPOINTER) :
            allocMap (0, 0, 0, 1, 0, 0, options.data_loc, SPEC_ADDRSPACE (sym->etype)->name, 'E', POINTER);
          nm->next = namedspacemaps;
          namedspacemaps = nm;
        }

      addSet (&nm->map->syms, sym);

      return;
    }
  segment = SPEC_OCLS (sym->etype);
  addSet (&segment->syms, sym);
  if (segment == pdata)
    sym->iaccess = 1;
}
Пример #2
0
/*-----------------------------------------------------------------*/
hTab *
newHashTable (int size)
{
  hTab *htab;

  htab = Safe_alloc ( sizeof (hTab));

  if (!(htab->table = Safe_alloc ((size + 1) * sizeof (hashtItem *))))
    {
      fprintf (stderr, "out of virtual memory %s %d\n",
	       __FILE__, (size + 1) * (int) sizeof (hashtItem *));
      exit (1);
    }
  htab->minKey = htab->size = size;
  return htab;
}
Пример #3
0
/*-----------------------------------------------------------------*/
static void
add_line_node (const char *line)
{
  lineNode *pl;

  pl = Safe_alloc (sizeof (lineNode));

#if 1
  memcpy (pl, (lineElem_t *) & genLine.lineElement, sizeof (lineElem_t));
#else
  pl->ic = genLine.lineElement.ic;
  pl->isInline = genLine.lineElement.isInline;
  pl->isComment = genLine.lineElement.isComment;
  pl->isDebug = genLine.lineElement.isDebug;
  pl->isLabel = genLine.lineElement.isLabel;
  pl->visited = genLine.lineElement.visited;
  pl->aln = genLine.lineElement.aln;
#endif

  pl->line = Safe_strdup (line);

  if (genLine.lineCurr)
    {
      pl->next = NULL;
      genLine.lineCurr->next = pl;
      pl->prev = genLine.lineCurr;
      genLine.lineCurr = pl;
    }
  else
    {
      pl->prev = pl->next = NULL;
      genLine.lineCurr = genLine.lineHead = pl;
    }
}
Пример #4
0
/*-----------------------------------------------------------------*/
eBBlock *
neweBBlock ()
{
  eBBlock *ebb;

  ebb = Safe_alloc (sizeof (eBBlock));
  return ebb;
}
Пример #5
0
/*-----------------------------------------------------------------*/
lineNode *
newLineNode (const char *line)
{
  lineNode *pl;

  pl = Safe_alloc (sizeof (lineNode));
  pl->line = Safe_strdup (line);
  pl->ic = NULL;
  return pl;
}
Пример #6
0
static asmLineNode *
newAsmLineNode (void)
{
    asmLineNode *aln;

    aln = Safe_alloc ( sizeof (asmLineNode));
    aln->size = 0;

    return aln;
}
Пример #7
0
char *Safe_strdup(const char *sz)
{
  char *pret;
  assert(sz);

  pret = Safe_alloc(strlen(sz) +1);
  strcpy(pret, sz);

  return pret;
}
Пример #8
0
/*-----------------------------------------------------------------*/
edge *
newEdge (eBBlock * from, eBBlock * to)
{
  edge *ep;

  ep = Safe_alloc (sizeof (edge));

  ep->from = from;
  ep->to = to;
  return ep;
}
Пример #9
0
static asmLineNode *
newAsmLineNode (void)
{
  asmLineNode *aln;

  aln = Safe_alloc ( sizeof (asmLineNode));
  aln->size = 0;
  aln->regsRead = NULL;
  aln->regsWritten = NULL;

  return aln;
}
Пример #10
0
/*-----------------------------------------------------------------*/
static hashtItem *
_newHashtItem (int key, void *pkey, void *item)
{
  hashtItem *htip;

  htip = Safe_alloc ( sizeof (hashtItem));

  htip->key = key;
  htip->pkey = pkey;
  htip->item = item;
  htip->next = NULL;
  return htip;
}
Пример #11
0
int
my_system (const char *cmd)
{
  int argsStart, e, i = 0;
  char *cmdLine = NULL;

  argsStart = strstr (cmd, " ") - cmd;

  // try to find the command in predefined path's
  while (ExePathList[i])
    {
      cmdLine = (char *) Safe_alloc (strlen (ExePathList[i]) + strlen (cmd) + 10);
      strcpy (cmdLine, ExePathList[i]);	// the path

      strcat (cmdLine, DIR_SEPARATOR_STRING);
      strncat (cmdLine, cmd, argsStart);	// the command

#if NATIVE_WIN32
      strcat (cmdLine, ".exe");
#endif

      if (access (cmdLine, X_OK) == 0)
	{
	  // the arguments
	  strcat (cmdLine, cmd + argsStart);
	  break;
	}
      Safe_free (cmdLine);
      cmdLine = NULL;
      i++;
    }

  if (verboseExec)
    {
      printf ("+ %s\n", cmdLine ? cmdLine : cmd);
    }

  if (cmdLine)
    {
      // command found in predefined path
      e = system (cmdLine);
      Safe_free (cmdLine);
    }
  else
    {
      // trust on $PATH
      e = system (cmd);
    }
  return e;
}
Пример #12
0
/*-----------------------------------------------------------------*/
void 
computeControlFlow (ebbIndex * ebbi)
{
  eBBlock ** ebbs = ebbi->bbOrder;
  int dfCount = ebbi->count;
  int i;

  /* initialise some things */

  for (i = 0; i < ebbi->count; i++)
    {
      setToNull ((void *) &ebbs[i]->predList);
      setToNull ((void *) &ebbs[i]->domVect);
      setToNull ((void *) &ebbs[i]->succList);
      setToNull ((void *) &ebbs[i]->succVect);
      ebbs[i]->visited = 0;
      ebbs[i]->dfnum = 0;
    }

  setToNull ((void *) &graphEdges);
  /* this will put in the  */
  /* successor information for each blk */
  eBBSuccessors (ebbi);

  /* compute the depth first ordering */
  computeDFOrdering (ebbi->bbOrder[0], &dfCount);

  /* mark blocks with no paths to them */
  markNoPath (ebbi);

  /* with the depth first info in place */
  /* add the predecessors for the blocks */
  eBBPredecessors (ebbi);

  /* compute the dominance graph */
  computeDominance (ebbi);

  /* sort it by dfnumber */
  if (!ebbi->dfOrder)
    ebbi->dfOrder = Safe_alloc ((ebbi->count+1) * sizeof (eBBlock *));
  for (i = 0; i < (ebbi->count+1); i++)
    {
      ebbi->dfOrder[i] = ebbi->bbOrder[i];
    }
      
  qsort (ebbi->dfOrder, ebbi->count, sizeof (eBBlock *), dfNumCompare);

}
Пример #13
0
/*-----------------------------------------------------------------*/
memmap *
allocMap (char rspace,          /* sfr space                   */
          char farmap,          /* far or near segment         */
          char paged,           /* can this segment be paged   */
          char direct,          /* directly addressable        */
          char bitaddr,         /* bit addressable space       */
          char codemap,         /* this is code space          */
          unsigned sloc,        /* starting location           */
          const char *name,     /* 8 character name            */
          char dbName,          /* debug name                  */
          int ptrType           /* pointer type for this space */
)
{
  memmap *map;

  if (!name)
    return NULL;

  if (!(map = Safe_alloc (sizeof (memmap))))
    {
      werror (E_OUT_OF_MEM, __FILE__, sizeof (memmap));
      exit (1);
    }

  memset (map, ZERO, sizeof (memmap));
  map->regsp = rspace;
  map->fmap = farmap;
  map->paged = paged;
  map->direct = direct;
  map->bitsp = bitaddr;
  map->codesp = codemap;
  map->sloc = sloc;
  map->sname = name;
  map->dbName = dbName;
  map->ptrType = ptrType;
  map->syms = NULL;

  dbuf_init(&map->oBuf, 4096);

  return map;
}
Пример #14
0
static void
_setValues(void)
{
  const char *s;

  if (options.nostdlib == FALSE)
    {
      const char *s;
      char path[PATH_MAX];
      struct dbuf_s dbuf;

      dbuf_init(&dbuf, PATH_MAX);

      for (s = setFirstItem(libDirsSet); s != NULL; s = setNextItem(libDirsSet))
        {
          buildCmdLine2(path, sizeof path, "-k\"%s" DIR_SEPARATOR_STRING "{port}\" ", s);
          dbuf_append_str(&dbuf, path);
        }
      buildCmdLine2(path, sizeof path, "-l\"{port}.lib\"", s);
      dbuf_append_str(&dbuf, path);

      setMainValue ("z80libspec", dbuf_c_str(&dbuf));
      dbuf_destroy(&dbuf);

      for (s = setFirstItem(libDirsSet); s != NULL; s = setNextItem(libDirsSet))
        {
          struct stat stat_buf;

          buildCmdLine2(path, sizeof path, "%s" DIR_SEPARATOR_STRING "{port}" DIR_SEPARATOR_STRING "crt0{objext}", s);
          if (stat(path, &stat_buf) == 0)
            break;
        }

      if (s == NULL)
        setMainValue ("z80crt0", "\"crt0{objext}\"");
      else
        {
          char *buf;
          size_t len = strlen(path) + 3;

          buf = Safe_alloc(len);
          SNPRINTF(buf, len, "\"%s\"", path);
          setMainValue("z80crt0", buf);
          Safe_free(buf);
        }
    }
  else
    {
      setMainValue ("z80libspec", "");
      setMainValue ("z80crt0", "");
    }

  setMainValue ("z80extralibfiles", (s = joinStrSet(libFilesSet)));
  Safe_free((void *)s);
  setMainValue ("z80extralibpaths", (s = joinStrSet(libPathsSet)));
  Safe_free((void *)s);

  if (IS_GB)
    {
      setMainValue ("z80outputtypeflag", "-Z");
      setMainValue ("z80outext", ".gb");
    }
  else
    {
      setMainValue ("z80outputtypeflag", "-i");
      setMainValue ("z80outext", ".ihx");
    }

  setMainValue ("stdobjdstfilename" , "{dstfilename}{objext}");
  setMainValue ("stdlinkdstfilename", "{dstfilename}{z80outext}");

  setMainValue ("z80extraobj", (s = joinStrSet(relFilesSet)));
  Safe_free((void *)s);

  sprintf (buffer, "-b_CODE=0x%04X -b_DATA=0x%04X", options.code_loc, options.data_loc);
  setMainValue ("z80bases", buffer);
}
Пример #15
0
/*-----------------------------------------------------------------*/
ebbIndex *
iCodeBreakDown (iCode * ic)
{
  eBBlock **ebbs = NULL;
  iCode *loop = ic;
  ebbIndex *ebbi;

  ebbi = Safe_alloc (sizeof (ebbIndex));
  ebbi->count = 0;
  ebbi->dfOrder = NULL; /* no depth first order information yet */

  /* allocate for the first entry */

  ebbs = Safe_alloc (sizeof (eBBlock *));
  ebbi->bbOrder = ebbs;

  while (loop)
    {

      /* convert 2 block */
      eBBlock *ebb = iCode2eBBlock (loop);
      loop = ebb->ech->next;

      ebb->ech->next = NULL;    /* mark the end of this chain */
      if (loop)
        loop->prev = NULL;
      ebb->bbnum = ebbi->count; /* save this block number     */
      /* put it in the array */
      ebbs[(ebbi->count)++] = ebb;

      /* allocate for the next one. Remember to clear the new */
      /*  pointer at the end, that was created by realloc. */

      ebbs = Safe_realloc (ebbs, (ebbi->count + 1) * sizeof (eBBlock *));
      ebbi->bbOrder = ebbs;

      ebbs[ebbi->count] = 0;

      /* if this one ends in a goto or a conditional */
      /* branch then check if the block it is going  */
      /* to already exists, if yes then this could   */
      /* be a loop, add a preheader to the block it  */
      /* goes to  if it does not already have one    */
      if (ebbs[(ebbi->count) - 1]->ech &&
          (ebbs[(ebbi->count) - 1]->ech->op == GOTO ||
           ebbs[(ebbi->count) - 1]->ech->op == IFX))
        {

          symbol *label;
          eBBlock *destBlock;

          if (ebbs[(ebbi->count) - 1]->ech->op == GOTO)
            label = IC_LABEL (ebbs[(ebbi->count) - 1]->ech);
          else if (!(label = IC_TRUE (ebbs[(ebbi->count) - 1]->ech)))
            label = IC_FALSE (ebbs[(ebbi->count) - 1]->ech);

          if ((destBlock = eBBWithEntryLabel (ebbi, label)) &&
              destBlock->preHeader == NULL &&
              otherPathsPresent (ebbs, destBlock))
            {

              symbol *preHeaderLabel  = newiTempLoopHeaderLabel (1);
              int i, j;
              eBBlock *pBlock;

              /* go thru all block replacing the entryLabel with new label */
              /* till we reach the block , then we insert a new ebblock    */
              for (i = 0; i < (ebbi->count); i++)
                {
                  if (ebbs[i] == destBlock)
                    break;
                  replaceLabel (ebbs[i], label, preHeaderLabel);
                }

              (ebbi->count)++;

              /* if we have stopped at the block , allocate for an extra one */

              ebbs = Safe_realloc (ebbs, (ebbi->count + 1) * sizeof (eBBlock *));
              ebbi->bbOrder = ebbs;

              ebbs[ebbi->count] = 0;

              /* then move the block down one count */
              pBlock = ebbs[j = i];
              for (i += 1; i < (ebbi->count); i++)
                {
                  eBBlock *xBlock;

                  xBlock = ebbs[i];
                  ebbs[i] = pBlock;
                  ebbs[i]->bbnum = i;
                  pBlock = xBlock;
                }

              destBlock->preHeader = ebbs[j] = neweBBlock ();
              ebbs[j]->bbnum = j;
              ebbs[j]->entryLabel = preHeaderLabel;
              ebbs[j]->sch = ebbs[j]->ech = newiCodeLabelGoto (LABEL, preHeaderLabel);
              ebbs[j]->sch->filename = destBlock->sch->filename;
              ebbs[j]->sch->lineno = destBlock->sch->lineno;
            }
        }
    }

  /* mark the end */
  ebbs[ebbi->count] = NULL;

  return ebbi;
}
Пример #16
0
/*-----------------------------------------------------------------*/
static bool
removeDeadPopPush (const char *pReg, lineNode *currPl, lineNode *head)
{
  lineNode *pushPl, *pl;

  /* A pop/push pair can be removed, if these criteria are met
     (ar0 is just an example here, ar0...ar7 are possible):

     pop ar0

      ; area 1

      ; There must not be in area 1:
      ;    - read or write access of ar0
      ;    - "acall", "lcall", "pop", "ret", "reti" or "jmp @a+dptr" opcodes
      ;    - "push" opcode, which doesn't push ar0 
      ;    - inline assembly
      ;    - a jump in or out of area 1 (see checkLabelRef())

      ; area 1 must be terminated by a:
     push ar0

      ; area 2

      ; There must not be:
      ;    - read access of ar0
      ;    - "jmp @a+dptr" opcode
      ;    - inline assembly
      ;    - a jump in or out of area 2 (see checkLabelRef())

      ; An "acall", "lcall" (not callee save), "ret" (not PCALL with
      ; callee save), "reti" or write access of r0 terminate
      ; the search, and the "pop/push ar0" can safely be removed.
  */

  /* area 1 */
  pushPl = currPl->next;
  if (!doPushScan (&pushPl, pReg))
    return FALSE;

  if (!checkLabelRef())
    return FALSE;

  /* area 2 */
  pl = pushPl->next;
  if (!doTermScan (&pl, pReg))
    return FALSE;
  if (!checkLabelRef())
    return FALSE;

  /* Success! */
  if (options.noPeepComments)
    {
      /* remove pushPl from list */
      pushPl->prev->next = pushPl->next;
      pushPl->next->prev = pushPl->prev;
    }
  else
    {
      /* replace 'push ar0' by comment */
      #define STR ";\tPeephole\tpush %s removed"
      int size = sizeof(STR) + 2;

      pushPl->line = Safe_alloc (size);
      SNPRINTF (pushPl->line, size, STR, pReg);
      pushPl->isComment = TRUE;
    }

  /* 'pop ar0' will be removed by peephole framework after returning TRUE */
  return TRUE;
}
Пример #17
0
static char *
parseIvalAst (ast *node, int *inCodeSpace) {
#define LEN 4096
    char *buffer = NULL;
    char *left, *right;

    if (IS_AST_VALUE(node)) {
        value *val = AST_VALUE(node);
        symbol *sym = IS_AST_SYM_VALUE(node) ? AST_SYMBOL(node) : NULL;
        if (inCodeSpace && val->type
                && (IS_FUNC(val->type) || IS_CODE(getSpec(val->type))))
        {
            *inCodeSpace = 1;
        }
        if (inCodeSpace && sym
                && (IS_FUNC(sym->type)
                    || IS_CODE(getSpec(sym->type))))
        {
            *inCodeSpace = 1;
        }

        DEBUGprintf ("%s: AST_VALUE\n", __FUNCTION__);
        if (IS_AST_LIT_VALUE(node)) {
            buffer = Safe_alloc(LEN);
            SNPRINTF(buffer, LEN, "0x%lx", AST_ULONG_VALUE (node));
        } else if (IS_AST_SYM_VALUE(node)) {
            assert ( AST_SYMBOL(node) );
            /*
            printf ("sym %s: ", AST_SYMBOL(node)->rname);
            printTypeChain(AST_SYMBOL(node)->type, stdout);
            printTypeChain(AST_SYMBOL(node)->etype, stdout);
            printf ("\n---sym %s: done\n", AST_SYMBOL(node)->rname);
            */
            buffer = Safe_strdup(AST_SYMBOL(node)->rname);
        } else {
            assert ( !"Invalid values type for initializers in AST." );
        }
    } else if (IS_AST_OP(node)) {
        DEBUGprintf ("%s: AST_OP\n", __FUNCTION__);
        switch (node->opval.op) {
        case CAST:
            assert (node->right);
            buffer = parseIvalAst(node->right, inCodeSpace);
            DEBUGprintf ("%s: %s\n", __FUNCTION__, buffer);
            break;
        case '&':
            assert ( node->left && !node->right );
            buffer = parseIvalAst(node->left, inCodeSpace);
            DEBUGprintf ("%s: %s\n", __FUNCTION__, buffer);
            break;
        case '+':
            assert (node->left && node->right );
            left = parseIvalAst(node->left, inCodeSpace);
            right = parseIvalAst(node->right, inCodeSpace);
            buffer = Safe_alloc(LEN);
            SNPRINTF(buffer, LEN, "(%s + %s)", left, right);
            DEBUGprintf ("%s: %s\n", __FUNCTION__, buffer);
            Safe_free(left);
            Safe_free(right);
            break;
        case '[':
            assert ( node->left && node->right );
            assert ( IS_AST_VALUE(node->left) && AST_VALUE(node->left)->sym );
            right = parseIvalAst(node->right, inCodeSpace);
            buffer = Safe_alloc(LEN);
            SNPRINTF(buffer, LEN, "(%s + %u * %s)",
                    AST_VALUE(node->left)->sym->rname, getSize(AST_VALUE(node->left)->type), right);
            Safe_free(right);
            DEBUGprintf ("%s: %s\n", __FUNCTION__, &buffer[0]);
            break;
        default:
            assert ( !"Unhandled operation in initializer." );
            break;
        }
    } else {
        assert ( !"Invalid construct in initializer." );
    }

    return (buffer);
}