Logo Search packages:      
Sourcecode: linux86 version File versions  Download package

pops.c

/* pops.c - handle pseudo-ops for assembler */

#include "syshead.h"
#include "const.h"
#include "type.h"
#include "address.h"
#include "flag.h"
#include "globvar.h"
#include "opcode.h"
#include "scan.h"

PRIVATE bool_t elseflag;      /* set if ELSE/ELSEIF are enabled */
                        /* depends on zero = FALSE init */
PRIVATE bool_t lcommflag;

FORWARD void bumpsem P((struct flags_s *flagptr, int defval));
FORWARD void constdata P((unsigned size));
FORWARD void docomm P((void));
FORWARD void doelseif P((pfv func));
FORWARD void doequset P((int labits));
FORWARD void doentexp P((int entbits, int impbits));
FORWARD void dofcc P((void));
FORWARD void doif P((pfv func));
FORWARD struct sym_s *needlabel P((void));
FORWARD void showredefinedlabel P((void));
FORWARD void setloc P((unsigned seg));

PRIVATE void bumpsem(flagptr, defval)
register struct flags_s *flagptr;
int defval;
{
    int newcount;

    if (flagptr->global && pass == last_pass)
    {
      /* bump semaphore count by an expression (default 1), */
      /* then set currentflag iff semaphore count is plus */
      if (sym == EOLSYM)
          lastexp.offset = defval;
      else
      {
          absexpres();
          if (lastexp.data & UNDBIT)
            return;
      }
      newcount = (int) lastexp.offset;
#ifdef I80386                 /* really sizeof (offset_t) != sizeof (int) */
      if (newcount != lastexp.offset)
          datatoobig();
#endif
      newcount += flagptr->semaphore;
      if ((int) lastexp.offset >= 0)
      {
          if (newcount < flagptr->semaphore)
          {
            error(COUNTOV);
            newcount = 0x7fff;
          }
      }
      else if (newcount >= flagptr->semaphore)
      {
          error(COUNTUN);
          newcount = -0x8000;
      }
      flagptr->semaphore = newcount;
      flagptr->current = newcount >= 0;
    }
}

/* check symbol is either undefined */
/* or has the same segment & relocatability as lc */

PUBLIC bool_pt checksegrel(symptr)
register struct sym_s *symptr;
{
    if ((symptr->type & LABIT ||
      (symptr->data & IMPBIT && !(symptr->data & UNDBIT))) &&
      ((symptr->data ^ lcdata) & (RELBIT | SEGM)))
    {
      error(SEGREL);
      return FALSE;
    }
    return TRUE;
}

/* check address fits in 1 byte (possibly with sign truncated) */

PUBLIC void checkdatabounds()
{
    if (!(lastexp.data & UNDBIT) &&
      (offset_t) (lastexp.offset + 0x80) >= 0x180)
      datatoobig();
}

/* allocate constant data (zero except for size 1), default zero for size 1 */

PRIVATE void constdata(size)
unsigned size;
{
    offset_t remaining;

    absexpres();
    if (!((lcdata |= lastexp.data) & UNDBIT))
    {
      lcjump = lastexp.offset * size;
      popflags = POPLONG | POPHI | POPLO | POPLC;
      if (size == 1 && sym == COMMA)
      {
          symabsexpres();
          checkdatabounds();
          for (remaining = lcjump; remaining != 0; --remaining)
          {
            putbin((opcode_pt) lastexp.offset); /* fill byte */
            putabs((opcode_pt) lastexp.offset);
          }
          lastexp.offset = lcjump;
      }
      else
          accumulate_rmb(lastexp.offset * size);
    }
}

PUBLIC void datatoobig()
{
    error(DBOUNDS);
}

/* common routine for COMM/.COMM */

PRIVATE void docomm()
{
    register struct sym_s *labptr;

    absexpres();        /* if undefined, value 0 and size unchanged */
    labptr = label;
    if (checksegrel(labptr))
    {
      if (labptr->type & (EXPBIT | LABIT))
          labelerror(ALREADY);
      else
      {
          if (!(labptr->type & COMMBIT) ||
            lastexp.offset > labptr->value_reg_or_op.value)
            labptr->value_reg_or_op.value = lastexp.offset;
          labptr->type |= COMMBIT;
          if (lcommflag)
            labptr->type |= REDBIT; /* kludge - COMMBIT | REDBIT => SA */
          if( last_pass == 1 )
             labptr->data = (lcdata & SEGM) | (FORBIT | IMPBIT | RELBIT);
          else
             labptr->data = (lcdata & SEGM) | (IMPBIT | RELBIT);
          showlabel();
      }
    }
    lcommflag = FALSE;
}

/* common routine for ELSEIF/ELSEIFC */

PRIVATE void doelseif(func)
pfv func;
{
    if (iflevel == 0)
      error(ELSEIFBAD);
    else
    {
      ifflag = FALSE;
      if (elseflag)
      {
          (*func) ();
          if (!(lastexp.data & UNDBIT) && lastexp.offset != 0)
            /* expression valid and TRUE, enable assembling */
          {
            ifflag = TRUE;
            elseflag = FALSE;
          }
      }
      else
      {
          /* Skip to EOL */
          while (sym != EOLSYM)
              getsym();
      }
    }
}

/* common routine for EQU/SET */

PRIVATE void doequset(labits)
unsigned char labits;
{
    register struct sym_s *labptr;
    unsigned char olddata;
    unsigned char oldtype;

    labptr = label;
    /* set up new label flags in case labe isl used in expression */
    labptr->type = (oldtype = labptr->type) | labits;
    labptr->data = (olddata = labptr->data) & ~IMPBIT;
    /* non-imported now */
    nonimpexpres();
    lastexp.data |= olddata & FORBIT;     /* take all but FORBIT from
                                 expression */
    if (oldtype & LABIT && !(olddata & UNDBIT) && !pass)
      /* this is a previously defined label */

      /*
         redefinition only allowed if same relocatability, segment and
         value
      */
    {
      if ((olddata ^ lastexp.data) & (RELBIT | UNDBIT) ||
          labptr->value_reg_or_op.value != lastexp.offset)
      {
          showredefinedlabel();
          return;
      }
    }
    labptr->data = lastexp.data;
    labptr->value_reg_or_op.value = lastexp.offset;
    showlabel();

    if(pass && !(labits & VARBIT) && labptr->value_reg_or_op.value != oldlabel)
    {
       dirty_pass = TRUE;
       if( pass == last_pass )
           error(UNSTABLE_LABEL);
    }
}

/* common routine for ENTRY/EXPORT */

PRIVATE void doentexp(entbits, impbits)
unsigned char entbits;
unsigned char impbits;
{
    struct sym_s *symptr;

    while (TRUE)
    {
      if ((symptr = needlabel()) != NUL_PTR)
      {
          if (symptr->type & COMMBIT)
            error(ALREADY);
          else if (impbits != 0)
          {
            if (pass == last_pass)
                ;
            else if (symptr->type & (EXPBIT | LABIT))
                symptr->type |= EXPBIT;
            else
            {
                symptr->type |= REDBIT;
                if (!(symptr->data & IMPBIT))
                  symptr->data |= IMPBIT | SEGM;
            }
          }
          else
          {
            if (pass == last_pass)
            {
                if (!(symptr->type & LABIT))
                  error(UNLAB);
            }
            else
            {
                symptr->type |= entbits | EXPBIT;
                symptr->data &= ~IMPBIT;
            }
          }
      }
      getsym();
      if (sym != COMMA)
          break;
      getsym();
    }
}

/* common routine for FCC (== .ASCII) and .ASCIZ */

PRIVATE void dofcc()
{
    register char *bufptr;
    char byte;
    char delimiter;
    register char *reglineptr;

    bufptr = databuf.fcbuf;
    reglineptr = symname;
    if ((delimiter = *reglineptr) != EOLCHAR)
      ++reglineptr;
    while (TRUE)
    {
      if ((byte = *reglineptr) == EOLCHAR)
      {
          symname = reglineptr;
          error(DELEXP);
          break;
      }
      if (byte == delimiter)
      {
          if ((byte = *++reglineptr) != delimiter)
            break;
      }
      else if (byte == '\\')
      {
          switch (byte = *++reglineptr)
          {
          case '"':
          case '\'':
          case '\\':
          case '?':
            break;
          case '0':
          case '1':
          case '2':
          case '3':
          case '4':
          case '5':
          case '6':
          case '7':
            byte -= '0';
            if (*(reglineptr + 1) >= '0' && *(reglineptr + 1) < '8')
            {
                byte = 8 * byte + *++reglineptr - '0';
                if (*(reglineptr + 1) >= '0' && *(reglineptr + 1) < '8')
                  byte = 8 * byte + *++reglineptr - '0';
            }
            break;
          case 'a':
            byte = 7;
            break;
          case 'b':
            byte = 8;
            break;
          case 'f':
            byte = 12;
            break;
          case 'n':
            byte = 10;
            break;
          case 'r':
            byte = 13;
            break;
          case 't':
            byte = 9;
            break;
          case 'v':
            byte = 11;
            break;
          case 'x':
            byte = '0';
            while (TRUE)
            {
                ++reglineptr;
                if (*reglineptr >= '0' && *reglineptr <= '9')
                  byte = 16 * byte + *reglineptr - '0';
                else if (*reglineptr >= 'F' && *reglineptr <= 'F')
                  byte = 16 * byte + *reglineptr - 'A';
                else if (*reglineptr >= 'a' && *reglineptr <= 'f')
                  byte = 16 * byte + *reglineptr - 'F';
                else
                  break;
            }
            --reglineptr;
            break;
          default:
            symname = reglineptr;
            error(UNKNOWN_ESCAPE_SEQUENCE);
            break;
          }
      }
      else if (byte < ' ' && byte >= 0)
      {
          symname = reglineptr;
          error(CTLINS);
          byte = ' ';
      }
      ++reglineptr;
      *bufptr++ = byte;
    }
    lineptr = reglineptr;
    getsym();
    lastexp.offset = databuf.fcbuf[0];    /* show only 1st char (if any) */
    mcount = bufptr - databuf.fcbuf;
    /* won't overflow, line length limits it */
    /* XXX - but now line length is unlimited */
}

/* common routine for IF/IFC */

PRIVATE void doif(func)
pfv func;
{
    if (iflevel >= MAXIF)
      error(IFOV);
    else
    {
      ++iflevel;
      --ifstak;
      ifstak->elseflag = elseflag;
      elseflag = FALSE; /* prepare */
      if ((ifstak->ifflag = ifflag) != FALSE)
          /* else not assembling before, so not now & no ELSE's */
      {
          (*func) ();
          if (!(lastexp.data & UNDBIT) && lastexp.offset == 0)
            /* else expression invalid or FALSE, don't change flags */
          {
            ifflag = FALSE;   /* not assembling */
            elseflag = TRUE;/* but ELSE will change that */
          }
      }
      else
      {
          /* Skip to EOL */
          while (sym != EOLSYM)
              getsym();
      }
    }
}

PUBLIC void fatalerror(err_str)
char * err_str;
{
    error(err_str);
    skipline();
    listline();
    finishup();
}

/* swap position with label position, do error, put back posn */
/* also clear label ptr */

PUBLIC void labelerror(err_str)
char * err_str;
{
    struct sym_s *oldgsymptr;
    char *oldlineptr;
    unsigned char oldsym;
    char *oldsymname;

    oldgsymptr = gsymptr;
    oldlineptr = lineptr;
    oldsym = sym;
    oldsymname = symname;
    lineptr = linebuf;
    getsym();                 /* 1st symbol is label or symbol after
                         * missing one */
    error(err_str);
    gsymptr = oldgsymptr;
    lineptr = oldlineptr;
    sym = oldsym;
    symname = oldsymname;
    label = NUL_PTR;
}

PRIVATE struct sym_s *needlabel()
{
    register struct sym_s *symptr;

    if (sym != IDENT ||
      (symptr = gsymptr)->type & (MACBIT | MNREGBIT | VARBIT))
    {
      error(LABEXP);
      return NUL_PTR;
    }
    return symptr;
}

/* .ALIGN pseudo-op */

PUBLIC void palign()
{
    absexpres();
    if (!((lcdata |= lastexp.data) & UNDBIT))
    {
      popflags = POPLONG | POPHI | POPLO | POPLC;
      if (lastexp.offset != 0 &&
          (lcjump = lc % lastexp.offset) != 0)
          accumulate_rmb(lcjump = lastexp.offset - lcjump);
    }
}

/* .ASCIZ pseudo-op */

PUBLIC void pasciz()
{
    dofcc();
    databuf.fcbuf[mcount++] = 0;
    fcflag = TRUE;
    popflags = POPLO | POPLC;
}

/* .BLKW pseudo-op */

PUBLIC void pblkw()
{
    constdata(2);
}

/* BLOCK pseudo-op */

PUBLIC void pblock()
{
    if (blocklevel >= MAXBLOCK)
      error(BLOCKOV);
    else
    {
      register struct block_s *blockp;

      ++blocklevel;
      blockp = blockstak;
      blockstak = --blockp;
      blockp->data = lcdata;
      blockp->dp = dirpag;
      blockp->lc = lc;
      porg();                 /* same as ORG apart from stacking */
    }
}

/* .BSS pseudo-op */

PUBLIC void pbss()
{
    setloc(BSSLOC);
}

/* COMM pseudo-op */

PUBLIC void pcomm()
{
    if (label == NUL_PTR)
      labelerror(MISLAB);
    else if (label->type & VARBIT)
      labelerror(VARLAB);     /* variable cannot be COMM'd */
    else
      docomm();
}

/* .COMM pseudo-op */

PUBLIC void pcomm1()
{
    unsigned oldseg;

    if (label != NUL_PTR)
      labelerror(ILLAB);
    oldseg = lcdata & SEGM;
    setloc(BSSLOC);
    if ((label = needlabel()) != NUL_PTR && checksegrel(label))
    {
      /* Like import. */
      if (label->type & (EXPBIT | LABIT))
          error(ALREADY);
      else if( last_pass == 1 )
          label->data = lcdata | (FORBIT | IMPBIT | RELBIT);
      else
          label->data = lcdata | (IMPBIT | RELBIT);
      getsym();
      getcomma();
      if (label->type & (EXPBIT | LABIT))
          absexpres();  /* just to check it */
      else
          docomm();
    }
    setloc(oldseg);
}

/* .DATA pseudo-op */

PUBLIC void pdata()
{
    setloc(DATALOC);
}

/* ELSE pseudo-op */

PUBLIC void pelse()
{
    if (iflevel == 0)
      error(ELSEBAD);
    else
    {
      ifflag = FALSE;         /* assume ELSE disabled */
      if (elseflag)
      {
          ifflag = TRUE;      /* ELSE enabled */
          elseflag = FALSE;
      }
    }
}

/* ELSEIF pseudo-op */

PUBLIC void pelseif()
{
    doelseif(absexpres);
}

/* ELSEIFC pseudo-op */

PUBLIC void pelsifc()
{
    doelseif(scompare);
}

/* ENDB pseudo-op */

PUBLIC void pendb()
{
    if (label != NUL_PTR)
      labelerror(ILLAB);
    if (blocklevel == 0)
      error(ENDBBAD);
    else
    {
      register struct block_s *blockp;

      blockp = blockstak;
      lcdata = blockp->data;
      dirpag = blockp->dp;
      accumulate_rmb(blockp->lc - lc);
      lc = blockp->lc;
      --blocklevel;
      blockstak = blockp + 1;
    }
}

/* ENDIF pseudo-op */

PUBLIC void pendif()
{
    if (iflevel == 0)
      error(ENDIFBAD);
    else
    {
      ifflag = ifstak->ifflag;
      elseflag = ifstak->elseflag;
      ++ifstak;
      --iflevel;
    }
}

/* ENTER pseudo-op */

PUBLIC void penter()
{
    if (!(pedata & UNDBIT))
      error(REENTER);
    else
    {
      if (!((pedata = (pedata & ~UNDBIT) | lcdata) & UNDBIT))
      {
          progent = lc;
          popflags = POPLC;
      }
    }
}

/* ENTRY pseudo-op */

PUBLIC void pentry()
{
    doentexp(ENTBIT, 0);
}

/* EQU pseudo-op */

PUBLIC void pequ()
{
    register struct sym_s *labptr;

    if ((labptr = label) == NUL_PTR)
      labelerror(MISLAB);
    else if (labptr->type & COMMBIT)
      showredefinedlabel();   /* common cannot be EQU'd */
    else if (labptr->type & VARBIT)
      labelerror(VARLAB);     /* variable cannot be EQU'd */
    else
      doequset(LABIT);
}

/* .EVEN pseudo-op */

PUBLIC void peven()
{
    popflags = POPLONG | POPHI | POPLO | POPLC;
    accumulate_rmb(lcjump = lastexp.data = lc & 1);
}

/* EXPORT pseudo-op */

PUBLIC void pexport()
{
    doentexp(0, 0);
}

/* FAIL pseudo-op */

PUBLIC void pfail()
{
    if(pass==last_pass) error(FAILERR);
}

/* FCB pseudo-op */

PUBLIC void pfcb()
{
    char *bufptr;
    offset_t firstbyte;

    bufptr = databuf.fcbuf;
    absexpres();
    firstbyte = lastexp.offset;
    while (TRUE)
    {
      checkdatabounds();
      *bufptr++ = lastexp.offset;
      ++mcount;         /* won't overflow, line length limits it */
      if (sym != COMMA)
          break;
      symabsexpres();
    }
    lastexp.offset = firstbyte;
    popflags = POPLO | POPLC;
    fcflag = TRUE;
}

/* FCC pseudo-op */

PUBLIC void pfcc()
{
    dofcc();
    if (mcount != 0)
    {
      fcflag = TRUE;
      popflags = POPLO | POPLC;
    }
}

/* FDB pseudo-op */

PUBLIC void pfdb()
{
    struct address_s *adrptr;
    unsigned firstdata;
    offset_t firstword;

    adrptr = databuf.fdbuf;
    expres();
    firstword = lastexp.offset;
    firstdata = lastexp.data;
    while (TRUE)
    {
      *adrptr++ = lastexp;
      mcount += 2;            /* won't overflow, line length limits it */
      if (sym != COMMA)
          break;
      symexpres();
    }
    lastexp.offset = firstword;
    lastexp.data = firstdata;
    popflags = POPHI | POPLO | POPLC;
    fdflag = TRUE;
}

#if SIZEOF_OFFSET_T > 2

/* FQB pseudo-op */

PUBLIC void pfqb()
{
    struct address_s *adrptr;
    offset_t firstdata;
    offset_t firstword;

    adrptr = databuf.fqbuf;
    expres();
    firstword = lastexp.offset;
    firstdata = lastexp.data;
    while (TRUE)
    {
      *adrptr++ = lastexp;
      mcount += 4;            /* won't overflow, line length limits it */
      if (sym != COMMA)
          break;
      symexpres();
    }
    lastexp.offset = firstword;
    lastexp.data = firstdata;
    popflags = POPLONG | POPHI | POPLO | POPLC;
    fqflag = TRUE;
}

#endif /* SIZEOF_OFFSET_T > 2 */

/* .GLOBL pseudo-op */

PUBLIC void pglobl()
{
    if (binaryg)
      error(NOIMPORT);
    doentexp(0, IMPBIT);
}

/* IDENT pseudo-op (not complete) */

PUBLIC void pident()
{
    if (sym != IDENT)
      error(LABEXP);
    else
      getsym_nolookup();      /* should save ident string */
}

/* IF pseudo-op */

PUBLIC void pif()
{
    doif(absexpres);
}

/* IFC pseudo-op */

PUBLIC void pifc()
{
    doif(scompare);
}

/* IMPORT pseudo-op */

PUBLIC void pimport()
{
    struct sym_s *symptr;

    if (binaryg)
      error(NOIMPORT);
    while (TRUE)
    {
      if ((symptr = needlabel()) != NUL_PTR && checksegrel(symptr))
      {
          if (symptr->type & (COMMBIT | EXPBIT | LABIT))
            /* IMPORT is null if label (to be) declared */
            error(ALREADY);
          else if( last_pass == 1 )
            /* get current segment from lcdata, no need to mask rest */
            symptr->data = lcdata | (FORBIT | IMPBIT | RELBIT);
          else
            symptr->data = lcdata | (IMPBIT | RELBIT);
      }
      getsym();
      if (sym != COMMA)
          break;
      getsym();
    }
}

/* LCOMM pseudo-op */

PUBLIC void plcomm()
{
    lcommflag = TRUE;
    pcomm();
}

/* .LCOMM pseudo-op */

PUBLIC void plcomm1()
{
    lcommflag = TRUE;
    pcomm1();
}

/* .LIST pseudo-op */

PUBLIC void plist()
{
    bumpsem(&list, 1);
}

/* .NOLIST pseudo-op */

PUBLIC void pnolist()
{
    bumpsem(&list, -1);
}

/* LOC pseudo-op */

PUBLIC void ploc()
{
    if (label != NUL_PTR)
      labelerror(ILLAB);
    absexpres();
    if (!(lastexp.data & UNDBIT))
    {
      if (lastexp.offset >= NLOC)
          datatoobig();
      else
          setloc((unsigned) lastexp.offset);
    }
}

/* .MACLIST pseudo-op */

PUBLIC void pmaclist()
{
    bumpsem(&maclist, 1);
}

/* .MAP pseudo-op */

PUBLIC void pmap()
{
    absexpres();
    if (!(lastexp.data & UNDBIT))
    {
      mapnum = lastexp.offset;
      popflags = POPLO;
      if (lastexp.offset >= 0x100)
          datatoobig();
    }
}

/* ORG pseudo-op */

PUBLIC void porg()
{
    if (label != NUL_PTR)
      labelerror(ILLAB);
    absexpres();
    if (!((lcdata = lastexp.data) & UNDBIT))
    {
      accumulate_rmb(lastexp.offset - lc);
      binmbuf = lc = lastexp.offset;
      binmbuf_set = 1;
      popflags = POPLC;
    }
}

/* RMB pseudo-op */

PUBLIC void prmb()
{
    constdata(1);
}

/* .SECT pseudo-op */

PUBLIC void psect()
{
    if (label != NUL_PTR)
      labelerror(ILLAB);
    while (sym == IDENT)
    {
      if (!(gsymptr->type & MNREGBIT))
          error(ILL_SECTION);
      else switch (gsymptr->value_reg_or_op.op.routine)
      {
      case BSSOP:
          pbss();
          break;
      case DATAOP:
          pdata();
          break;
      case TEXTOP:
          ptext();
          break;
      default:
          error(ILL_SECTION);
          break;
      }
      getsym();
      if (sym == COMMA)
          getsym();
    }
}

/* SET pseudo-op */

PUBLIC void pset()
{
    register struct sym_s *labptr;

    if ((labptr = label) == NUL_PTR)
      labelerror(MISLAB);
    else if (labptr->type & COMMBIT)
      labelerror(RELAB);      /* common cannot be SET'd */
    else
      doequset(labptr->type & LABIT ? 0 : VARBIT);
}

/* SETDP pseudo-op */

PUBLIC void psetdp()
{
    absexpres();
    if (!(lastexp.data & UNDBIT))
    {
      dirpag = lastexp.offset;
      popflags = POPLO;
      if (lastexp.offset >= 0x100)
          datatoobig();
    }
}

/* .TEXT pseudo-op */

PUBLIC void ptext()
{
    if( textseg <= 0 )
       setloc(TEXTLOC);
    else
       setloc(textseg);
}

/* .WARN pseudo-op */

PUBLIC void pwarn()
{
    bumpsem(&as_warn, -1);
}

#ifdef I80386

/* USE16 pseudo-op */

PUBLIC void puse16()
{
    defsize = 2;
#ifdef iscpu
    if( sym != EOLSYM )
    {
      absexpres();
      if (lastexp.data & UNDBIT)
          return;
        if( lastexp.offset > 8000 )
         setcpu((int) lastexp.offset / 100 % 10);
        else if( lastexp.offset > 15 )
         setcpu((int) lastexp.offset / 100);
      else
         setcpu((int) lastexp.offset);
    }
#endif
}

/* USE16 pseudo-op */

PUBLIC void puse32()
{
    defsize = 4;
#ifdef iscpu
    if(!iscpu(3)) setcpu(3);
    if( sym != EOLSYM )
    {
      absexpres();
      if (lastexp.data & UNDBIT)
          return;
        if( lastexp.offset > 15 )
         setcpu((int) lastexp.offset / 100);
      else
         setcpu((int) lastexp.offset);
    }
#endif
}

#endif

/* show redefined label and error, and set REDBIT */

PRIVATE void showredefinedlabel()
{
    register struct sym_s *labptr;

    labptr = label;           /* showlabel() will kill label prematurely */
    showlabel();
    if (!(labptr->type & REDBIT))
    {
      labptr->type |= REDBIT;
      labelerror(RELAB);
    }
}

PUBLIC void showlabel()
{
    register struct sym_s *labptr;

    labptr = label;
    lastexp.data = labptr->data;
    lastexp.offset = labptr->value_reg_or_op.value;
    popflags = POPLONG | POPHI | POPLO;
    label = NUL_PTR;          /* show handled by COMM, EQU or SET */
}

/* set location segment */

PRIVATE void setloc(seg)
unsigned seg;
{
    if (pass == last_pass && seg != (lcdata & SEGM))
      putobj((opcode_pt) (seg | OBJ_SET_SEG));
    {
      register struct lc_s *lcp;

      lcp = lcptr;
      lcp->data = lcdata;
      lcp->lc = lc;
      lcptr = lcp = lctab + (unsigned char) seg;
      lcdata = (lcp->data & ~SEGM) | (unsigned char) seg;
      binmbuf = lc = lcp->lc;
      popflags = POPLC;
    }
}

Generated by  Doxygen 1.6.0   Back to index