示例#1
0
static void initPTable(void)
{
  register int i;

  TRACE(stderr, "[intPTable]");

  /* Skip over leading pcodes.  NOTE:  assumes executable begins after
   * the first oLABEL pcode
   */

  do
    {
      insn_GetOpCode(myPoffHandle, &ptable[0]);
      insn_AddTmpOpCode(myPoffProgHandle, &ptable[0]);
    }
  while ((GETOP(&ptable[0]) != oLABEL) && (GETOP(&ptable[0]) != oEND));

  /* Fill the pcode window and setup pointers to working section */

  for (i = 0; i < WINDOW; i++)
    {
      insn_GetOpCode(myPoffHandle, &ptable[i]);
    }
  setupPointer();
}
示例#2
0
static void putPCodeFromTable(void)
{
  register int i;

  TRACE(stderr, "[putPCodeFromTable]");

  /* Transfer all buffered P-Codes (except NOPs) to the optimized file */
  do
    {
      if ((GETOP(&ptable[0]) != oNOP) && !(end_out))
	{
	  insn_AddTmpOpCode(myPoffProgHandle, &ptable[0]);
	  end_out = (GETOP(&ptable[0]) == oEND);
	}

      /* Move all P-Codes down one slot */

      for (i = 1; i < WINDOW; i++)
	{
	  ptable[i-1] = ptable[i];
	}

      /* Then fill the end slot with a new P-Code from the input file */

      insn_GetOpCode(myPoffHandle, &ptable[WINDOW-1]);

    } while (GETOP(&ptable[0]) == oNOP);
  setupPointer();
}
示例#3
0
static uint32_t regm_CheckSection1 (poffHandle_t hPoff, uint32_t dwOffset)
{
  OPTYPE op;

  /* Seek to the beginning of the section. */

  regm_ProgSeek(hPoff, dwOffset);

  /* Read the opcode at that position. */

  (void)insn_GetOpCode(hPoff, &op);

  /* Is it a oJMP instruction? This happens when there are nested
   * functions.  The entry point into the parent function is a jump
   * around the nested functions.
   */

  if (GETOP(&op) == oJMP)
    {
      /* Yes, then the block really begins at the target of the jump */

      return GETARG(&op);
    }
  else
    {
      /* No, then the block really begins right here */

      return dwOffset;
    }
}
示例#4
0
文件: pfopt.c 项目: hechan/NuttX
static void pass1(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle)
{
    OPTYPE op;
    uint32_t pc;
    int opsize;
    int fileno = 0;

    /* Build label / line number reference table
     *
     * CASE 1: LABEL
     *   Add label number + PC to table
     *   discard
     * CASE 2: LINE
     *   genereate a line number reference
     *   discard
     * ELSE:
     *   pass through with no additional action
     */

    pc = 0;
    do
    {
        opsize = insn_GetOpCode(poffHandle, &op);
        if (GETOP(&op) == oLABEL)
        {
            poffAddToDefinedLabelTable(GETARG(&op), pc);
        }
        else if (GETOP(&op) == oINCLUDE)
        {
            fileno = GETARG(&op);
        }
        else if (GETOP(&op) == oLINE)
        {
            poffAddLineNumber(poffHandle, GETARG(&op), fileno, pc);
        }
        else
        {
            insn_AddTmpOpCode(poffProgHandle, &op);
            pc += opsize;
        }
    }
    while (GETOP(&op) != oEND);

    /* Replace the original program data with the new program data */

    poffReplaceProgData(poffHandle, poffProgHandle);
}
示例#5
0
static void setupPointer(void)
{
  register int pindex;

  TRACE(stderr, "[setupPointer]");

  for (pindex = 0; pindex < WINDOW; pindex++)
    pptr[pindex] = (OPTYPE *) NULL;

  nops = 0; 
  for (pindex = 0; pindex < WINDOW; pindex++)
    {
      switch (GETOP(&ptable[pindex]))
	{
	  /* Terminate list when a break from sequential logic is
	   * encountered
	   */

	case oRET   :
	case oEND   :
	case oJMP   :
	case oLABEL :
	case oPCAL  :
	  return;

	  /* Terminate list when a condition break from sequential logic is
	   * encountered but include the conditional branch in the list
	   */

	case oJEQUZ :
	case oJNEQZ :
	case oJLTZ  :
	case oJGTEZ :
	case oJGTZ  :
	case oJLTEZ :
	  pptr[nops] = &ptable[pindex];
	  nops++;
	  return;

	  /* Skip over NOPs and comment class pcodes */

	case oNOP   :
	case oLINE  :
	  break;

	  /* Include all other pcodes in the optimization list and continue */

	default     :
	  pptr[nops] = &ptable[pindex];
	  nops++;
	}
    }
}
示例#6
0
文件: pfopt.c 项目: hechan/NuttX
static void pass3(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle)
{
    OPTYPE   op;
    uint32_t pc;
    uint32_t opsize;

    /* Read each opcode, generate relocation information and
     * replace label references with program section offsets.
     *
     * CASE 1: LAC
     *   generate RODATA relocation entry
     * CASE 2: PCAL instructions
     *   replace label with I-space offset, OR
     *   generate a PROGRAM relocation entry
     * CASE 3: J* instructions
     *   replace label with I-space offset
     * CASE 4: LDS*, STS*, and LAS* instructions
     *   generate a STACK relocation (if imported?)
     * ELSE:
     *   pass through with no additional action
     */

    pc = 0;
    do
    {
        opsize = insn_GetOpCode(poffHandle, &op);
        switch (GETOP(&op))
        {
        /* Load of an address in the rodata section */

        case oLAC:
            /* We are referencing something from the rodata section.
             * No special action need be taken.
             */
            break;

        /* Call to a procedure or function. */

        case oPCAL:
        {
            /* Check if this is a defined label, i.e., a call to
             * procedure or function in the same file.
             */

            int32_t value = poffGetPcForDefinedLabel(GETARG(&op));
            if (value >= 0)
            {
                /* Yes... replace the label reference with
                 * a text section offset.  No relocation record
                 * is needed in this case.  The only relocation
                 * may be performed is a subsequent program data
                 * section offset.
                 */

                PUTARG(&op, value);
            }
            else
            {
                /* Check if this is a undefined label.  This would
                 * occur for a call to a procedure or a function that
                 * is defined in some other unit file.
                 */

                value = poffGetSymIndexForUndefinedLabel(GETARG(&op));
                if (value >= 0)
                {
                    /* Use the value zero now */

                    PUTARG(&op, 0);

                    /* And generate a symbol-based relocation */

                    (void)poffAddRelocation(poffHandle, RLT_PCAL, value, pc);
                }
                else
                {
                    DEBUG(stdout, "Failed to find call label L%04x\n",
                          GETARG(&op));
                    fatal(ePOFFCONFUSION);
                }
            }
        }
        break;

        /* Jumps to "nearby" addresses */

        case oJMP:   /* Unconditional */
        case oJEQUZ: /* Unary comparisons with zero */
        case oJNEQZ:
        case oJLTZ:
        case oJGTEZ:
        case oJGTZ:
        case oJLTEZ:
        case oJEQU:  /* Binary comparisons */
        case oJNEQ:
        case oJLT:
        case oJGTE:
        case oJGT:
        case oJLTE:
        {
            /* Check if this is a defined label.  This must be the case
             * because there can be no jumps into a unit file.
             */

            int32_t value = poffGetPcForDefinedLabel(GETARG(&op));
            if (value >= 0)
            {
                /* Yes... replace the label reference with
                 * a text section offset.  No relocation record
                 * is needed in this case.  The only relocation
                 * may be performed is a subsequent program data
                 * sectioin offset.
                 */

                PUTARG(&op, value);
            }
            else
            {
                DEBUG(stdout, "Failed to find jump label L%04x\n",
                      GETARG(&op));
                fatal(ePOFFCONFUSION);
            }
        }
        break;

        /* References to stack via level offset */

        case oLAS:   /* Load stack address */
        case oLASX:
        case oLDS:   /* Load value */
        case oLDSH:
        case oLDSB:
        case oLDSM:
        case oSTS:   /* Store value */
        case oSTSH:
        case oSTSB:
        case oSTSM:
        case oLDSX:
        case oLDSXH: /* Load value indexed */
        case oLDSXB:
        case oLDSXM:
        case oSTSX:  /* Store value indexed */
        case oSTSXH:
        case oSTSXB:
        case oSTSXM:
        {
#warning REVISIT
        }
        break;

        /* Otherwise, it is not an interesting opcode */
        default:
            break;
        }

        /* Save the potentially modified opcode in the temporary
         * program data container.
         */

        insn_AddTmpOpCode(poffProgHandle, &op);
        pc += opsize;
    }
    while (GETOP(&op) != oEND);

    /* Replace the original program data with the new program data */

    poffReplaceProgData(poffHandle, poffProgHandle);
}
int unaryOptimize(void)
{
  register uint32_t temp;
  register int i;
  int nchanges = 0;

  TRACE(stderr, "[unaryOptimize]");

  /* At least two pcodes are need to perform unary optimizations */

  i = 0;
  while (i < nops-1)
    {
      /* Check for a constant value being pushed onto the stack */

      if (GETOP(pptr[i]) == oPUSH)
        {
          switch (GETOP(pptr[i+1]))
            {
              /* Delete unary operators on constants */
            case oNEG   :
              PUTARG(pptr[i], -GETARG(pptr[i]));
              deletePcode(i+1);
              nchanges++;
              break;

            case oABS   :
              if ((int32_t)GETARG(pptr[i]) < 0)
                PUTARG(pptr[i], -(int32_t)GETARG(pptr[i]));
              deletePcode(i+1);
              nchanges++;
              break;

            case oINC   :
              PUTARG(pptr[i], GETARG(pptr[i]) + 1);
              deletePcode(i+1);
              nchanges++;
              break;

            case oDEC   :
              PUTARG(pptr[i], GETARG(pptr[i]) - 1);
              deletePcode(i+1);
              nchanges++;
              break;

            case oNOT   :
              PUTARG(pptr[i], ~GETARG(pptr[i]));
              PUTARG(pptr[i], ~(GETARG(pptr[i])));
              deletePcode(i+1);
              nchanges++;
              break;

              /* Simplify binary operations on constants */

            case oADD :
              if (GETARG(pptr[i]) == 0)
                {
                  deletePcodePair(i, (i+1));
                  nchanges++;
                } /* end if */
              else if (GETARG(pptr[i]) == 1)
                {
                  PUTOP(pptr[i+1], oINC);
                  deletePcode(i);
                  nchanges++;
                } /* end else if */
              else if (GETARG(pptr[i]) == ARGONES)
                {
                  PUTOP(pptr[i+1], oDEC);
                  deletePcode(i);
                  nchanges++;
                } /* end else if */
              else i++;
              break;

            case oSUB :
              if (GETARG(pptr[i]) == 0)
                {
                  deletePcodePair(i, (i+1));
                  nchanges++;
                } /* end if */
              else if (GETARG(pptr[i]) == 1)
                {
                  PUTOP(pptr[i+1], oDEC);
                  deletePcode(i);
                  nchanges++;
                } /* end else if */
              else if (GETARG(pptr[i]) == ARGONES)
                {
                  PUTOP(pptr[i+1], oINC);
                  deletePcode(i);
                  nchanges++;
                } /* end else if */
              else i++;
              break;

            case oMUL :
            case oDIV :
              temp = 0;
              switch (GETARG(pptr[i]))
                {
                case 1 :
                  deletePcodePair(i, (i+1));
                  nchanges++;
                  break;
                case 16384 : temp++;
                case  8192 : temp++;
                case  4096 : temp++;
                case  2048 : temp++;
                case  1024 : temp++;
                case   512 : temp++;
                case   256 : temp++;
                case   128 : temp++;
                case    64 : temp++;
                case    32 : temp++;
                case    16 : temp++;
                case     8 : temp++;
                case     4 : temp++;
                case     2 : temp++;
                  PUTARG(pptr[i], temp);
                  if (GETOP(pptr[i+1]) == oMUL)
                    PUTOP(pptr[i+1], oSLL);
                  else
                    PUTOP(pptr[i+1], oSRA);
                  nchanges++;
                  i++;
                  break;

                default :
                  i++;
                  break;
                } /* end switch */
              break;

            case oSLL :
            case oSRL :
            case oSRA :
            case oOR  :
              if (GETARG(pptr[i]) == 0)
                {
                  deletePcodePair(i, (i+1));
                  nchanges++;
                } /* end if */
              else i++;
              break;

            case oAND :
              if (GETARG(pptr[i]) == ARGONES)
                {
                  deletePcodePair(i, (i+1));
                  nchanges++;
                } /* end if */
              else i++;
              break;

              /* Delete comparisons of constants to zero */

            case oEQUZ  :
              if (GETARG(pptr[i]) == 0)
                PUTARG(pptr[i], -1);
              else
                PUTARG(pptr[i], 0);
              deletePcode(i+1);
              nchanges++;
              break;

            case oNEQZ  :
              if (GETARG(pptr[i]) != 0)
                PUTARG(pptr[i], -1);
              else
                PUTARG(pptr[i], 0);
              deletePcode(i+1);
              nchanges++;
              break;

            case oLTZ   :
              if ((int32_t)GETARG(pptr[i]) < 0)
                PUTARG(pptr[i], -1);
              else
                PUTARG(pptr[i], 0);
              deletePcode(i+1);
              nchanges++;
              break;

            case oGTEZ  :
              if ((int32_t)GETARG(pptr[i]) >= 0)
                PUTARG(pptr[i], -1);
              else
                PUTARG(pptr[i], 0);
              deletePcode(i+1);
              nchanges++;
              break;

            case oGTZ   :
              if (GETARG(pptr[i]) > 0)
                PUTARG(pptr[i], -1);
              else
                PUTARG(pptr[i], 0);
              deletePcode(i+1);
              nchanges++;
              break;

            case oLTEZ :
              if (GETARG(pptr[i]) <= 0)
                PUTARG(pptr[i], -1);
              else
                PUTARG(pptr[i], 0);
              deletePcode(i+1);
              nchanges++;
              break;

              /*  Simplify comparisons with certain constants */

            case oEQU   :
              if (GETARG(pptr[i]) == 0)
                {
                  PUTOP(pptr[i+1],oEQUZ);
                  deletePcode(i);
                  nchanges++;
                } /* end if */
              else if (GETARG(pptr[i]) == 1)
                {
                  PUTOP(pptr[i], oDEC);
                  PUTARG(pptr[i], 0);
                  PUTOP(pptr[i+1], oEQUZ);
                  nchanges++;
                } /* end else if */
              else if ((int32_t)GETARG(pptr[i]) == -1)
                {
                  PUTOP(pptr[i], oINC);
                  PUTARG(pptr[i], 0);
                  PUTOP(pptr[i+1], oEQUZ);
                  nchanges++;
                } /* end else if */
              else i++;
              break;

            case oNEQ   :
              if (GETARG(pptr[i]) == 0)
                {
                  PUTOP(pptr[i+1], oNEQZ);
                  deletePcode(i);
                  nchanges++;
                } /* end if */
              else if (GETARG(pptr[i]) == 1)
                {
                  PUTOP(pptr[i], oDEC);
                  PUTARG(pptr[i], 0);
                  PUTOP(pptr[i+1], oNEQZ);
                  nchanges++;
                } /* end else if */
              else if ((int32_t)GETARG(pptr[i]) == -1)
                {
                  PUTOP(pptr[i], oINC);
                  PUTARG(pptr[i], 0);
                  PUTOP(pptr[i+1], oNEQZ);
                  nchanges++;
                } /* end else if */
              else i++;
              break;

            case oLT    :
              if (GETARG(pptr[i]) == 0)
                {
                  PUTOP(pptr[i+1], oLTZ);
                  deletePcode(i);
                  nchanges++;
                } /* end if */
              else if (GETARG(pptr[i]) == 1)
                {
                  PUTOP(pptr[i], oDEC);
                  PUTARG(pptr[i], 0);
                  PUTOP(pptr[i+1], oLTZ);
                  nchanges++;
                } /* end else if */
              else if ((int32_t)GETARG(pptr[i]) == -1)
                {
                  PUTOP(pptr[i], oINC);
                  PUTARG(pptr[i], 0);
                  PUTOP(pptr[i+1], oLTZ);
                  nchanges++;
                } /* end else if */
              else i++;
              break;

            case oGTE   :
              if (GETARG(pptr[i]) == 0)
                {
                  PUTOP(pptr[i+1], oGTEZ);
                  deletePcode(i);
                  nchanges++;
                } /* end if */
              else if (GETARG(pptr[i]) == 1)
                {
                  PUTOP(pptr[i], oDEC);
                  PUTARG(pptr[i], 0);
                  PUTOP(pptr[i+1], oGTEZ);
                  nchanges++;
                } /* end else if */
              else if ((int32_t)GETARG(pptr[i]) == -1)
                {
                  PUTOP(pptr[i], oINC);
                  PUTARG(pptr[i], 0);
                  PUTOP(pptr[i+1], oGTEZ);
                  nchanges++;
                } /* end else if */
              else i++;
              break;

            case oGT    :
              if (GETARG(pptr[i]) == 0)
                {
                  PUTOP(pptr[i+1], oGTZ);
                  deletePcode(i);
                  nchanges++;
                } /* end if */
              else if (GETARG(pptr[i]) == 1)
                {
                  PUTOP(pptr[i], oDEC);
                  PUTARG(pptr[i], 0);
                  PUTOP(pptr[i+1], oGTZ);
                  nchanges++;
                } /* end else if */
              else if ((int32_t)GETARG(pptr[i]) == -1)
                {
                  PUTOP(pptr[i], oINC);
                  PUTARG(pptr[i], 0);
                  PUTOP(pptr[i+1], oGTZ);
                  nchanges++;
                } /* end else if */
              else i++;
              break;

            case oLTE   :
              if (GETARG(pptr[i]) == 0)
                {
                  PUTOP(pptr[i+1], oLTEZ);
                  deletePcode(i);
                  nchanges++;
                } /* end if */
              else if (GETARG(pptr[i]) == 1)
                {
                  PUTOP(pptr[i], oDEC);
                  PUTARG(pptr[i], 0);
                  PUTOP(pptr[i+1], oLTEZ);
                  nchanges++;
                } /* end else if */
              else if ((int32_t)GETARG(pptr[i]) == -1)
                {
                  PUTOP(pptr[i], oINC);
                  PUTARG(pptr[i], 0);
                  PUTOP(pptr[i+1], oLTEZ);
                  nchanges++;
                } /* end else if */
              else i++;
              break;

              /* Simplify or delete condition branches on constants */

            case oJEQUZ :
              if (GETARG(pptr[i]) == 0)
                {
                  PUTOP(pptr[i+1], oJMP);
                  deletePcode(i);
                } /* end if */
              else
                deletePcodePair(i, (i+1));
              nchanges++;
              break;

            case oJNEQZ :
              if (GETARG(pptr[i]) != 0)
                {
                  PUTOP(pptr[i+1], oJMP);
                  deletePcode(i);
                } /* end if */
              else
                deletePcodePair(i, (i+1));
              nchanges++;
              break;

            case oJLTZ  :
              if ((int32_t)GETARG(pptr[i]) < 0)
                {
                  PUTOP(pptr[i+1], oJMP);
                  deletePcode(i);
                } /* end if */
              else
                deletePcodePair(i, (i+1));
              nchanges++;
              break;

            case oJGTEZ :
              if ((int32_t)GETARG(pptr[i]) >= 0)
                {
                  PUTOP(pptr[i+1], oJMP);
                  deletePcode(i);
                } /* end if */
              else
                deletePcodePair(i, (i+1));
              nchanges++;
              break;

            case oJGTZ  :
              if (GETARG(pptr[i]) > 0)
                {
                  PUTOP(pptr[i+1], oJMP);
                  deletePcode(i);
                } /* end if */
              else
                deletePcodePair(i, (i+1));
              nchanges++;
              break;

            case oJLTEZ :
              if (GETARG(pptr[i]) <= 0)
                {
                  PUTOP(pptr[i+1], oJMP);
                  deletePcode(i);
                } /* end if */
              else
                deletePcodePair(i, (i+1));
              nchanges++;
              break;

            default     :
              i++;
              break;
            } /* end switch */
        } /* end if */

          /* Delete multiple modifications of DSEG pointer */

      else if (GETOP(pptr[i]) == oINDS)
        {
          if (GETOP(pptr[i+1]) == oINDS)
            {
              PUTARG(pptr[i], GETARG(pptr[i] + GETARG(pptr[i+1])));
              deletePcode(i+1);
            } /* end if */
          else i++;
        } /* end else if */
      else i++;
    } /* end while */

  return (nchanges);

} /* end unaryOptimize */
int binaryOptimize(void)
{
  register int i;
  int nchanges = 0;

  TRACE(stderr, "[binaryOptimize]");

  /* At least two pcodes are needed to perform the following binary */
  /* operator optimizations */

  i = 0;
  while (i < nops-2)
    {
      if (GETOP(pptr[i]) == oPUSH)
        {
          if (GETOP(pptr[i+1]) == oPUSH)
            {
              switch (GETOP(pptr[i+2]))
                {
                case oADD :
                  PUTARG(pptr[i], GETARG(pptr[i]) + GETARG(pptr[i+1]));
                  deletePcodePair((i+1), (i+2));
                  nchanges++;
                  break;

                case oSUB :
                  PUTARG(pptr[i], GETARG(pptr[i]) - GETARG(pptr[i+1]));
                  deletePcodePair((i+1), (i+2));
                  nchanges++;
                  break;

                case oMUL :
                  PUTARG(pptr[i], GETARG(pptr[i]) * GETARG(pptr[i+1]));
                  deletePcodePair((i+1), (i+2));
                  nchanges++;
                  break;

                case oDIV :
                  PUTARG(pptr[i], GETARG(pptr[i]) / (int32_t)GETARG(pptr[i+1]));
                  deletePcodePair((i+1), (i+2));
                  nchanges++;
                  break;

                case oMOD :
                  PUTARG(pptr[i], GETARG(pptr[i]) % GETARG(pptr[i+1]));
                  deletePcodePair((i+1), (i+2));
                  nchanges++;
                  break;

                case oSLL :
                  PUTARG(pptr[i], GETARG(pptr[i]) << GETARG(pptr[i+1]));
                  deletePcodePair((i+1), (i+2));
                  nchanges++;
                  break;

                case oSRL :
                  PUTARG(pptr[i], GETARG(pptr[i]) >> GETARG(pptr[i+1]));
                  deletePcodePair((i+1), (i+2));
                  nchanges++;
                  break;

                case oSRA :
                  PUTARG(pptr[i], (int32_t)GETARG(pptr[i]) >> GETARG(pptr[i+1]));
                  deletePcodePair((i+1), (i+2));
                  nchanges++;
                  break;

                case oOR  :
                  PUTARG(pptr[i], GETARG(pptr[i]) | GETARG(pptr[i+1]));
                  deletePcodePair((i+1), (i+2));
                  nchanges++;
                  break;

                case oAND :
                  PUTARG(pptr[i], GETARG(pptr[i]) & GETARG(pptr[i+1]));
                  deletePcodePair((i+1), (i+2));
                  nchanges++;
                  break;

                case oEQU :
                  if (GETARG(pptr[i]) == GETARG(pptr[i+1]))
                    PUTARG(pptr[i], -1);
                  else
                    PUTARG(pptr[i], 0);
                  deletePcodePair((i+1), (i+2));
                  nchanges++;
                  break;

                case oNEQ :
                  if (GETARG(pptr[i]) != GETARG(pptr[i+1]))
                    PUTARG(pptr[i], -1);
                  else
                    PUTARG(pptr[i], 0);
                  deletePcodePair((i+1), (i+2));
                  nchanges++;
                  break;

                case oLT  :
                  if ((int32_t)GETARG(pptr[i]) < (int32_t)GETARG(pptr[i+1]))
                    PUTARG(pptr[i], -1);
                  else
                    PUTARG(pptr[i], 0);
                  deletePcodePair((i+1), (i+2));
                  nchanges++;
                  break;

                case oGTE :
                  if ((int32_t)GETARG(pptr[i]) >= (int32_t)GETARG(pptr[i+1]))
                    PUTARG(pptr[i], -1);
                  else
                    PUTARG(pptr[i], 0);
                  deletePcodePair((i+1), (i+2));
                  nchanges++;
                  break;

                case oGT  :
                  if ((int32_t)GETARG(pptr[i]) > (int32_t)GETARG(pptr[i+1]))
                    PUTARG(pptr[i], -1);
                  else
                    PUTARG(pptr[i], 0);
                  deletePcodePair((i+1), (i+2));
                  nchanges++;
                  break;

                case oLTE :
                  if ((int32_t)GETARG(pptr[i]) <= (int32_t)GETARG(pptr[i+1]))
                    PUTARG(pptr[i], -1);
                  else
                    PUTARG(pptr[i], 0);
                  deletePcodePair((i+1), (i+2));
                  nchanges++;
                  break;

                default   :
                  i++;
                  break;
                } /* end switch */
            } /* end if */

          /* A single (constant) pcode is sufficient to perform the */
          /* following binary operator optimizations */

          else if ((GETOP(pptr[i+1]) == oLDSH) || (GETOP(pptr[i+1]) == oLDSB) ||
                   (GETOP(pptr[i+1]) == oLAS)  || (GETOP(pptr[i+1]) == oLAC))
            {
              switch (GETOP(pptr[i+2]))
                {
                case oADD :
                  if (GETARG(pptr[i]) == 0)
                    {
                      deletePcodePair(i, (i+2));
                      nchanges++;
                    } /* end if */
                  else if (GETARG(pptr[i]) == 1)
                    {
                      PUTOP(pptr[i+2], oINC);
                      deletePcode(i);
                      nchanges++;
                    } /* end else if */
                  else if (GETARG(pptr[i]) == ARGONES)
                    {
                      PUTOP(pptr[i+2], oDEC);
                      deletePcode(i);
                      nchanges++;
                    } /* end else if */
                  else i++;
                  break;

                case oSUB :
                  if (GETARG(pptr[i]) == 0)
                    {
                      PUTOP(pptr[i], oNEG);
                      deletePcode(i);
                      nchanges++;
                    } /* end if */
                  else i++;
                  break;

                case oMUL :
                  {
                    int32_t stmp32 = 0;
                    switch (GETARG(pptr[i]))
                      {
                      case 1 :
                        deletePcodePair(i, (i+2));
                        nchanges++;
                        break;
                      case 16384 : stmp32++;
                      case  8192 : stmp32++;
                      case  4096 : stmp32++;
                      case  2048 : stmp32++;
                      case  1024 : stmp32++;
                      case   512 : stmp32++;
                      case   256 : stmp32++;
                      case   128 : stmp32++;
                      case    64 : stmp32++;
                      case    32 : stmp32++;
                      case    16 : stmp32++;
                      case     8 : stmp32++;
                      case     4 : stmp32++;
                      case     2 : stmp32++;
                        PUTOP(pptr[i],    GETOP(pptr[i+1]));
                        PUTARG(pptr[i],   GETARG(pptr[i+1]));
                        PUTOP(pptr[i+1],  oPUSH);
                        PUTARG(pptr[i+1], stmp32);
                        PUTOP(pptr[i+2],  oSLL);
                        nchanges++;
                        i++;
                        break;

                      default :
                        i++;
                        break;
                      }
                  }
                  break;

                case oOR  :
                  if (GETARG(pptr[i]) == 0)
                    {
                      deletePcodePair(i, (i+2));
                      nchanges++;
                    } /* end if */
                  else i++;
                  break;

                case oAND :
                  if (GETARG(pptr[i]) == ARGONES)
                    {
                      deletePcodePair(i, (i+2));
                      nchanges++;
                    } /* end if */
                  else i++;
                  break;

                case oEQU :
                  if (GETARG(pptr[i]) == 0)
                    {
                      PUTOP(pptr[i+2], oEQUZ);
                      deletePcode(i);
                      nchanges++;
                    } /* end if */
                  else i++;
                  break;

                case oNEQ :
                  if (GETARG(pptr[i]) == 0)
                    {
                      PUTOP(pptr[i+2], oNEQZ);
                      deletePcode(i);
                      nchanges++;
                    } /* end if */
                  else i++;
                  break;

                case oLT  :
                  if (GETARG(pptr[i]) == 0)
                    {
                      PUTOP(pptr[i+2], oGTEZ);
                      deletePcode(i);
                      nchanges++;
                    } /* end if */
                  else i++;
                  break;

                case oGTE :
                  if (GETARG(pptr[i]) == 0)
                    {
                      PUTOP(pptr[i+2], oLTZ);
                      deletePcode(i);
                      nchanges++;
                    } /* end if */
                  else i++;
                  break;

                case oGT  :
                  if (GETARG(pptr[i]) == 0)
                    {
                      PUTOP(pptr[i+2], oLTEZ);
                      deletePcode(i);
                      nchanges++;
                    } /* end if */
                  else i++;
                  break;

                case oLTE :
                  if (GETARG(pptr[i]) == 0)
                    {
                      PUTOP(pptr[i+2], oGTZ);
                      deletePcode(i);
                      nchanges++;
                    } /* end if */
                  else i++;
                  break;

                default   :
                  i++;
                  break;

                } /* end switch */
            } /* end else if */
          else i++;
        } /* end if */

      /* Misc improvements on binary operators */

      else if (GETOP(pptr[i]) == oNEG)
示例#9
0
uint32_t regm_ReadNodePCodes(struct procdata_s *pNode, poffHandle_t hPoff,
                           uint32_t dwStartOffset, uint32_t dwEndOffset,
                           uint8_t cTerminalOpcode)
{
  uint32_t dwOffset = dwStartOffset;
  long nAlloc = INITIAL_PCODE_ALLOC;
  long nPCodes;
  uint8_t bTerminatorFound;

  dbg("Reading Node: %08lx %08lx %02x\n",
      dwStartOffset, dwEndOffset, cTerminalOpcode);

  /* Allocate an inital buffer to hold the instructions */

  pNode->pPCode = (OPTYPE*)
    malloc(INITIAL_PCODE_ALLOC*sizeof(struct procinsn_s*));
  if (!pNode->pPCode)
    {
      fatal(eNOMEMORY);
    }

  /* Seek to the beginning of the data */

  regm_ProgSeek(hPoff, dwStartOffset);

  /* Read all of the instructions in the main program section */

  nPCodes = 0;
  bTerminatorFound = 0;
  do
    {
      /* Make sure that there is space for another pcode */

      if (nPCodes > nAlloc)
        {
          /* If not, then reallocate the array */

          nAlloc += PCODE_RELLALLOC;
          pNode->pPCode = (OPTYPE*)
            realloc(pNode->pPCode, nAlloc*sizeof(OPTYPE));
        }

      /* Ready the pcode ito the array */

      dwOffset += insn_GetOpCode(hPoff, &pNode->pPCode[nPCodes]);

      /* Check for a terminating pcode */

      if ((GETOP(&pNode->pPCode[nPCodes]) == cTerminalOpcode) ||
          (GETOP(&pNode->pPCode[nPCodes]) == oEND))
        {
          bTerminatorFound++;
        }

      /* Increment the count of pcodes read */

      nPCodes++;
    }
  while (!bTerminatorFound && (dwOffset < dwEndOffset));

  dbg("              %08lx %08lx %02x\n",
      dwStartOffset, dwOffset, GETOP(&pNode->pPCode[nPCodes-1]));

  /* Save the number of pcodes that we found */

  pNode->nPCodes = nPCodes;

  /* Check for the correct terminator */

  if (GETOP(&pNode->pPCode[nPCodes-1]) != cTerminalOpcode)
    {
      fatal(ePOFFCONFUSION);
    }

  /* Return any unused space in the allocation */

  pNode->pPCode = (OPTYPE*)
    realloc(pNode->pPCode, nPCodes*sizeof(OPTYPE));

  /* Return the actual end offset */

  return dwOffset;
}