示例#1
0
void
setline(int line, int fileno)
{
    if ((sc_debug & (sSYMBOLIC | sCHKBOUNDS)) != 0)
    {
        stgwrite("line ");
        outval(line, FALSE);
        stgwrite(" ");
        outval(fileno, FALSE);
        stgwrite("\t; ");
        outval(code_idx, TRUE);
        code_idx += opcodes(1) + opargs(2);
    }				/* if */
}
示例#2
0
文件: sc4.c 项目: Oukache/pawn
/* Convert "distance of addresses" to "number of cells" in between.
 * Or convert a number of packed characters to the number of cells (with
 * truncation).
 * The ALT register is be used as scratch.
 */
SC_FUNC void addr2cell(void)
{
  stgwrite("\tconst.alt ");
  if (pc_cellsize==2) {
    outval(1,TRUE,TRUE);
  } else if (pc_cellsize==4) {
    outval(2,TRUE,TRUE);
  } else {
    assert(pc_cellsize==8);
    outval(3,TRUE,TRUE);
  } /* if */
  stgwrite("\tshr\n");
  code_idx+=opcodes(2)+opargs(1);
}
示例#3
0
文件: sc4.c 项目: Oukache/pawn
SC_FUNC void setheap_pri(void)
{
  if (!staging && pc_optimize>=sOPTIMIZE_FULL) {
    stgwrite("\theap.p ");
    outval(pc_cellsize,FALSE,TRUE);
    code_idx+=opcodes(3);       /* the other 2 opcodes follow below */
  } else {
    stgwrite("\theap ");        /* ALT = HEA++ */
    outval(pc_cellsize,TRUE,TRUE);
    code_idx+=opcodes(3)+opargs(1); /* the other 2 opcodes follow below */
  } /* if */
  stgwrite("\tstor.i\n");       /* store PRI (default value) at address ALT */
  stgwrite("\txchg\n");         /* move ALT to PRI: PRI contains the address */
}
示例#4
0
文件: sc4.c 项目: Oukache/pawn
/*
 *  Inclrement/decrement stack pointer. Note that this routine does
 *  nothing if the delta is zero.
 */
SC_FUNC void modstk(int delta)
{
  if (delta) {
    cell crit=((cell)1<<pc_cellsize*4);
    if (!staging && pc_optimize>=sOPTIMIZE_FULL && delta>=-crit && delta<crit) {
      stgwrite("\tstack.p ");
      outval(delta,FALSE,TRUE);
      code_idx+=opcodes(1);
    } else {
      stgwrite("\tstack ");
      outval(delta,TRUE,TRUE);
      code_idx+=opcodes(1)+opargs(1);
    } /* if */
  } /* if */
}
示例#5
0
文件: sc4.c 项目: glockwork/dfu
SC_FUNC void setheap(cell value)
{
  stgwrite("\tconst.pri ");     /* load default value in PRI */
  outval(value,TRUE,TRUE);
  code_idx+=opcodes(1)+opargs(1);
  setheap_pri();
}
示例#6
0
SC_FUNC void setheap_save(cell value)
{
  assert(value);
  stgwrite("\ttracker.push.c ");
  outval(value, TRUE);
  code_idx+=opcodes(1)+opargs(1);
}
示例#7
0
/* set the stack to a hard offset from the frame */
SC_FUNC void setstk(cell value)
{
  stgwrite("\tstackadjust ");
  assert(value<=0);             /* STK should always become <= FRM */
  outval(value, TRUE);        /* add (negative) offset */
  code_idx+=opcodes(1)+opargs(1);
}
示例#8
0
文件: sc4.c 项目: glockwork/dfu
SC_FUNC void oa_eq(cell size)
{
  stgwrite("\tcmps ");
  outval(size,TRUE,TRUE);
  stgwrite("\tnot\n");  /* CMPS results in zero if both arrays match, change it to 1 */
  code_idx+=opcodes(2)+opargs(1);
}
示例#9
0
文件: sc4.c 项目: glockwork/dfu
/*  writetrailer
 *  Not much left of this once important function.
 *
 *  Global references: pc_stksize       (referred to only)
 *                     sc_dataalign     (referred to only)
 *                     code_idx         (altered)
 *                     glb_declared     (altered)
 */
SC_FUNC void writetrailer(void)
{
  assert(sc_dataalign % opcodes(1) == 0);   /* alignment must be a multiple of
                                             * the opcode size */
  assert(sc_dataalign!=0);

  /* pad code to align data segment */
  if ((code_idx % sc_dataalign)!=0) {
    begcseg();
    while ((code_idx % sc_dataalign)!=0)
      nooperation();
  } /* if */

  /* pad data segment to align the stack and the heap */
  assert(litidx==0);            /* literal queue should have been emptied */
  assert(sc_dataalign % sizeof(cell) == 0);
  if (((glb_declared*sizeof(cell)) % sc_dataalign)!=0) {
    begdseg();
    defstorage();
    while (((glb_declared*sizeof(cell)) % sc_dataalign)!=0) {
      stgwrite("0 ");
      glb_declared++;
    } /* while */
  } /* if */

  stgwrite("\nSTKSIZE ");       /* write stack size (align stack top) */
  outval(pc_stksize - (pc_stksize % sc_dataalign),TRUE,TRUE);
}
示例#10
0
文件: sc4.c 项目: glockwork/dfu
SC_FUNC void setline(int chkbounds)
{
  if (sc_asmfile) {
    stgwrite("\t; line ");
    outval(fline,TRUE,TRUE);
  } /* if */
  if ((sc_debug & sSYMBOLIC)!=0 || chkbounds && (sc_debug & sCHKBOUNDS)!=0) {
    /* generate a "break" (start statement) opcode rather than a "line" opcode
     * because earlier versions of Small/Pawn have an incompatible version of the
     * line opcode
     */
    stgwrite("\tbreak\t; ");
    outval(code_idx,TRUE,TRUE);
    code_idx+=opcodes(1);
  } /* if */
}
示例#11
0
文件: sc4.c 项目: Oukache/pawn
/* Store a cell into a fixed address in memory */
SC_FUNC void storereg(cell address,regid reg)
{
  assert(reg==sPRI);
  stgwrite("\tstor ");
  outval(address,TRUE,TRUE);
  code_idx+=opcodes(1)+opargs(1);
}
示例#12
0
文件: sc4.c 项目: glockwork/dfu
/* Source must be in PRI, destination address in ALT. The "size"
 * parameter is in bytes, not cells.
 */
SC_FUNC void memcopy(cell size)
{
  stgwrite("\tmovs ");
  outval(size,TRUE,TRUE);

  code_idx+=opcodes(1)+opargs(1);
}
示例#13
0
/* Align PRI (which should hold a character index) to an address.
 * The first character in a "pack" occupies the highest bits of
 * the cell. This is at the lower memory address on Big Endian
 * computers and on the higher address on Little Endian computers.
 * The ALIGN.pri/alt instructions must solve this machine dependence;
 * that is, on Big Endian computers, ALIGN.pri/alt shuold do nothing
 * and on Little Endian computers they should toggle the address.
 *
 * NOTE: For Source Pawn, this is fliped.  It will do nothing on Little-Endian.
 */
SC_FUNC void charalign(void)
{
#if 0	/* TEMPORARILY DISABLED BECAUSE WE DON'T USE BIG ENDIAN */
  stgwrite("\talign.pri ");
  outval(sCHARBITS/8,TRUE);
  code_idx+=opcodes(1)+opargs(1);
#endif
}
示例#14
0
文件: sc4.c 项目: jte/pawn
/*
 *  Add a constant to the primary register.
 */
SC_FUNC void addconst(cell value)
{
  if (value!=0) {
    stgwrite("\tadd.c ");
    outval(value,TRUE);
    code_idx+=opcodes(1)+opargs(1);
  } /* if */
}
示例#15
0
文件: sc4.c 项目: Oukache/pawn
SC_FUNC void oa_ne(cell size)
{
  stgwrite("\tcmps ");
  outval(size,TRUE,TRUE); /* this leaves PRI == 0 when the arrays are equal */
  stgwrite("\tnot\n");    /* PRI == 1 if equal, 0 if different */
  stgwrite("\tnot\n");    /* PRI == 0 if equal, 1 = different */
  code_idx+=opcodes(3)+opargs(1);
}
示例#16
0
文件: sc4.c 项目: jte/pawn
SC_FUNC void setheap_pri(void)
{
  stgwrite("\theap ");          /* ALT = HEA++ */
  outval(sizeof(cell), TRUE);
  stgwrite("\tstor.i\n");       /* store PRI (default value) at address ALT */
  stgwrite("\tmove.pri\n");     /* move ALT to PRI: PRI contains the address */
  code_idx+=opcodes(3)+opargs(1);
}
示例#17
0
/*
 *  Inclrement/decrement stack pointer. Note that this routine does
 *  nothing if the delta is zero.
 */
void modstk(int delta)
{
  if (delta) {
    stgwrite("\tstack ");
    outval(delta, TRUE);
    code_idx+=opcodes(1)+opargs(1);
  } /* if */
}
示例#18
0
文件: sc4.c 项目: jte/pawn
SC_FUNC void modheap(int delta)
{
  if (delta) {
    stgwrite("\theap ");
    outval(delta, TRUE);
    code_idx+=opcodes(1)+opargs(1);
  } /* if */
}
示例#19
0
文件: sc4.c 项目: glockwork/dfu
SC_FUNC void oa_ne(cell size)
{
  stgwrite("\tcmps ");
  outval(size,TRUE,TRUE);
  stgwrite("\teq.c.pri 0\n");
  stgwrite("\tnot\n");
  code_idx+=opcodes(3)+opargs(2);
}
示例#20
0
文件: sc4.c 项目: glockwork/dfu
SC_FUNC void ffbounds(cell size)
{
  if ((sc_debug & sCHKBOUNDS)!=0) {
    stgwrite("\tbounds ");
    outval(size,TRUE,TRUE);
    code_idx+=opcodes(1)+opargs(1);
  } /* if */
}
示例#21
0
文件: sc4.c 项目: Oukache/pawn
/*  increment symbol
 */
SC_FUNC void inc(value *lval)
{
  symbol *sym;

  sym=lval->sym;
  if (lval->ident==iARRAYCELL) {
    /* indirect increment, address already in PRI */
    stgwrite("\tinc.i\n");
    code_idx+=opcodes(1);
  } else if (lval->ident==iARRAYCHAR) {
    /* indirect increment of single character, address already in PRI */
    stgwrite("\tpush.alt\n");
    stgwrite("\txchg\n");         /* ALT = address */
    stgwrite("\tlodb.i ");        /* read from ALT into PRI */
    outval(sCHARBITS/8,TRUE,TRUE);/* read one or two bytes */
    stgwrite("\tinc.pri\n");
    stgwrite("\tstrb.i ");        /* write PRI to ALT */
    outval(sCHARBITS/8,TRUE,TRUE);/* write one or two bytes */
    stgwrite("\txchg\n");         /* PRI = address (restored PRI) */
    stgwrite("\tpop.alt\n");
    code_idx+=opcodes(7)+opargs(2);
  } else if (lval->ident==iREFERENCE) {
    /* indirect increment, but address not yet in PRI */
    assert(sym!=NULL);
    stgwrite("\tpush.pri\n");
    assert(sym->vclass==sLOCAL);  /* global references don't exist in Pawn */
    stgwrite("\tload.s.pri ");
    outval(sym->addr,TRUE,TRUE);
    stgwrite("\tinc.i\n");
    stgwrite("\tpop.pri\n");
    code_idx+=opcodes(4)+opargs(1);
  } else {
    /* local or global variable */
    assert(sym!=NULL);
    stgwrite("\tpush.pri\n");
    if (sym->vclass==sLOCAL)
      stgwrite("\taddr.pri ");
    else
      stgwrite("\tconst.pri ");
    outval(sym->addr,TRUE,TRUE);
    stgwrite("\tinc.i\n");
    stgwrite("\tpop.pri\n");
    code_idx+=opcodes(4)+opargs(1);
  } /* if */
}
示例#22
0
文件: sc4.c 项目: glockwork/dfu
/*
 *  Inclrement/decrement stack pointer. Note that this routine does
 *  nothing if the delta is zero.
 */
SC_FUNC void modstk(int delta)
{
  if (delta) {
#if !defined AMX_NO_PACKED_OPC
    if (!staging && pc_optimize>sOPTIMIZE_NOMACRO && delta>=-(1<<sizeof(cell)*4) && delta<(1<<sizeof(cell)*4)) {
      stgwrite("\tstack.p ");
      outval(delta,FALSE,TRUE);
      code_idx+=opcodes(1);
    } else {
#endif
      stgwrite("\tstack ");
      outval(delta,TRUE,TRUE);
      code_idx+=opcodes(1)+opargs(1);
#if !defined AMX_NO_PACKED_OPC
    } /* if */
#endif
  } /* if */
}
示例#23
0
文件: sc4.c 项目: glockwork/dfu
SC_FUNC void ffcase(cell value,int label,int newtable,int icase)
{
  if (newtable) {
    if (icase)
      stgwrite("\ticasetbl\n");
    else
      stgwrite("\tcasetbl\n");
    code_idx+=opcodes(1);
  } /* if */
  if (icase)
    stgwrite("\ticase ");
  else
    stgwrite("\tcase ");
  outval(value,TRUE,FALSE);
  stgwrite(" ");
  outval(label,TRUE,TRUE);
  code_idx+=opcodes(0)+opargs(2);
}
示例#24
0
文件: sc4.c 项目: glockwork/dfu
/* Switch statements
 * The "switch" statement generates a "case" table using the "CASE" opcode.
 * The case table contains a list of records, each record holds a comparison
 * value and a label to branch to on a match. The very first record is an
 * exception: it holds the size of the table (excluding the first record) and
 * the label to branch to when none of the values in the case table match.
 * The case table is sorted on the comparison value. This allows more advanced
 * abstract machines to sift the case table with a binary search.
 * The iswitch statement uses an icase table. The parameter of an iswitch is
 * still a (relative) code address.
 */
SC_FUNC void ffswitch(int label,int iswitch)
{
  if (iswitch)
    stgwrite("\tiswitch ");
  else
    stgwrite("\tswitch ");
  outval(label,TRUE,TRUE);      /* the label is the address of the case table */
  code_idx+=opcodes(1)+opargs(1);
}
示例#25
0
static void addr_reg(int val, regid reg)
{
  if (reg == sPRI)
    stgwrite("\taddr.pri ");
  else
    stgwrite("\taddr.alt ");
  outval(val, TRUE);
  code_idx += opcodes(1) + opargs(1);
}
示例#26
0
// Load the number of arguments into PRI. Frame layout:
//   base + 0*sizeof(cell) == previous "base"
//   base + 1*sizeof(cell) == function return address
//   base + 2*sizeof(cell) == number of arguments
//   base + 3*sizeof(cell) == first argument of the function
static void load_argcount(regid reg)
{
  if (reg == sPRI)
    stgwrite("\tload.s.pri ");
  else
    stgwrite("\tload.s.alt ");
  outval(2 * sizeof(cell), TRUE);
  code_idx += opcodes(1) + opargs(1);
}
示例#27
0
文件: sc4.c 项目: glockwork/dfu
SC_FUNC void setheap_pri(void)
{
#if !defined AMX_NO_PACKED_OPC
  if (!staging && pc_optimize>sOPTIMIZE_NOMACRO) {
    stgwrite("\theap.p ");
    outval(sizeof(cell),FALSE,TRUE);
    code_idx+=opcodes(3);       /* the other 2 opcodes follow below */
  } else {
#endif
    stgwrite("\theap ");        /* ALT = HEA++ */
    outval(sizeof(cell),TRUE,TRUE);
    code_idx+=opcodes(3)+opargs(1); /* the other 2 opcodes follow below */
#if !defined AMX_NO_PACKED_OPC
  } /* if */
#endif
  stgwrite("\tstor.i\n");       /* store PRI (default value) at address ALT */
  stgwrite("\tmove.pri\n");     /* move ALT to PRI: PRI contains the address */
}
示例#28
0
文件: sc4.c 项目: glockwork/dfu
/* Store a cell into a fixed address in memory */
SC_FUNC void storereg(cell address,regid reg)
{
  assert(reg==sPRI || reg==sALT);
  if (reg==sPRI)
    stgwrite("\tstor.pri ");
  else
    stgwrite("\tstor.alt ");
  outval(address,TRUE,TRUE);
  code_idx+=opcodes(1)+opargs(1);
}
示例#29
0
/*
 * Generate an array
 */
SC_FUNC void genarray(int dims, int _autozero)
{
  if (_autozero) {
    stgwrite("\tgenarray.z ");
  } else {
    stgwrite("\tgenarray ");
  }
  outval(dims, TRUE);
  code_idx+=opcodes(1)+opargs(1);
}
示例#30
0
文件: sc4.c 项目: jte/pawn
/*
 *  Call specified function
 */
SC_FUNC void ffcall(symbol *sym,const char *label,int numargs)
{
  char symname[2*sNAMEMAX+16];

  assert(sym!=NULL);
  assert(sym->ident==iFUNCTN);
  if (sc_asmfile)
    funcdisplayname(symname,sym->name);
  if ((sym->usage & uNATIVE)!=0) {
    /* reserve a SYSREQ id if called for the first time */
    assert(label==NULL);
    if (sc_status==statWRITE && (sym->usage & uREAD)==0 && sym->addr>=0)
      sym->addr=ntv_funcid++;
    stgwrite("\tsysreq.c ");
    outval(sym->addr,FALSE);
    if (sc_asmfile) {
      stgwrite("\t; ");
      stgwrite(symname);
    } /* if */
    stgwrite("\n"); /* write on a separate line, to mark a sequence point for the peephole optimizer */
    stgwrite("\tstack ");
    outval((numargs+1)*sizeof(cell), TRUE);
    code_idx+=opcodes(2)+opargs(2);
  } else {
    /* normal function */
    stgwrite("\tcall ");
    if (label!=NULL) {
      stgwrite("l.");
      stgwrite(label);
    } else {
      stgwrite(".");
      stgwrite(sym->name);
    } /* if */
    if (sc_asmfile
        && (label!=NULL || !isalpha(sym->name[0]) && sym->name[0]!='_'  && sym->name[0]!=sc_ctrlchar))
    {
      stgwrite("\t; ");
      stgwrite(symname);
    } /* if */
    stgwrite("\n");
    code_idx+=opcodes(1)+opargs(1);
  } /* if */
}