示例#1
0
//----------------------------------------------------------------------
static void process_operand(op_t &x,int isAlt,int isload)
{
  switch ( x.type )
  {
    case o_reg:
    case o_phrase:
    case o_reglist:
      return;
    case o_imm:
      QASSERT(10094, isload);
      process_immediate_number(x.n);
      if ( op_adds_xrefs(uFlag, x.n) )
        ua_add_off_drefs2(x, dr_O, OOFS_IFSIGN|OOFW_IMM);
      break;
    case o_displ:
      process_immediate_number(x.n);
      if ( isAlt )
        break;
      if ( op_adds_xrefs(uFlag, x.n) )
      {
        ea_t ea = ua_add_off_drefs2(x, isload ? dr_R : dr_W, get_displ_outf(x));
        if ( ea != BADADDR )
        {
          ua_dodata2(x.offb, ea, x.dtyp);
          if ( !isload )
            doVar(ea);
        }
      }
      // create stack variables if required
      if ( may_create_stkvars() && !isDefArg(uFlag, x.n) )
      {
        func_t *pfn = get_func(cmd.ea);
        if ( pfn != NULL
          && (issp(x.phrase)
              || isbp(x.phrase) && (pfn->flags & FUNC_FRAME) != 0) )
        {
          if ( ua_stkvar2(x, x.addr, STKVAR_VALID_SIZE) )
            op_stkvar(cmd.ea, x.n);
        }
      }
      break;
    case o_near:
      add_code_xref(x, calc_mem(x.addr));
      break;
    case o_mem:
    case o_memind:
      {
        ea_t ea = calc_mem(x.addr);
        if ( !isEnabled(ea) && find_sym(ea) ) break;    // address not here
        ua_add_dref(x.offb, ea, isload ? dr_R : dr_W);
        ua_dodata2(x.offb, ea, x.dtyp);
        if ( x.type == o_memind )
        {
          ssize_t size = get_dtyp_size(x.dtyp);
          flags_t F = getFlags(ea);
          if ( (isWord(F) || isDwrd(F))
            && (!isDefArg0(F) || isOff0(F)) )
          {
            ea_t target = calc_mem(size == 2
                                ? get_word(ea)
                                : (get_long(ea) & 0xFFFFFFL));
            if ( isEnabled(target) ) add_code_xref(x, target);
            if ( !isOff0(F) )
              set_offset(ea, 0, calc_mem(0));
          }
          break;
        }
        if ( !isload ) doVar(ea);
      }
      break;
    default:
      INTERR(10095);
  }
}
示例#2
0
文件: emu.cpp 项目: nealey/vera
//----------------------------------------------------------------------
int idaapi emu(void)
{
    uint32 Feature = cmd.get_canon_feature();
    int flag1 = is_forced_operand(cmd.ea, 0);
    int flag2 = is_forced_operand(cmd.ea, 1);
    int flag3 = is_forced_operand(cmd.ea, 2);

    flow = (Feature & CF_STOP) == 0;

    if ( Feature & CF_USE1 ) process_operand(cmd.Op1, flag1, 1);
    if ( Feature & CF_USE2 ) process_operand(cmd.Op2, flag2, 1);
    if ( Feature & CF_USE3 ) process_operand(cmd.Op3, flag3, 1);

    if ( Feature & CF_CHG1 ) process_operand(cmd.Op1, flag1, 0);
    if ( Feature & CF_CHG2 ) process_operand(cmd.Op2, flag2, 0);
    if ( Feature & CF_CHG3 ) process_operand(cmd.Op3, flag3, 0);

//
//      Check for:
//        - the register bank changes
//        - PCLATH changes
//        - PCL changes
//
    for ( int i=0; i < 3; i++ )
    {
        int reg = 0;
        switch ( i )
        {
        case 0:
            reg = BANK;
            if ( !is_bank() ) continue;
            break;
        case 1:
            reg = PCLATH;
            if ( !is_pclath() ) continue;
            break;
        case 2:
            reg = -1;
            if ( !is_pcl() ) continue;
            break;
        }
        sel_t v = (reg == -1) ? cmd.ip : getSR(cmd.ea, reg);
        if ( cmd.Op2.type == o_reg && cmd.Op2.reg == F )
        {
//      split(reg, v);
        }
        else
        {
            switch ( cmd.itype )
            {
            case PIC_bcf:
            case PIC_bcf3:
            case PIC_bsf:
            case PIC_bsf3:
                if ( ((ptype == PIC12) && (cmd.Op2.value == 5) )  // bank selector
                        || ((ptype == PIC14) && (
                                (reg == BANK && (cmd.Op2.value == 5 || cmd.Op2.value == 6))
                                || (reg == PCLATH && (cmd.Op2.value == 3 || cmd.Op2.value == 4))))
                        || ((ptype == PIC16) && (sval_t(cmd.Op2.value) >= 0 && cmd.Op2.value <= 3)))
                {
                    if ( v == BADSEL ) v = 0;
                    int shift = 0;
                    if ( ptype == PIC14 && reg == BANK ) shift = 5;
                    if ( cmd.itype == PIC_bcf ) v = v & ~(1 << (cmd.Op2.value-shift));
                    else v = v | (1 << (cmd.Op2.value-shift));
                    split(reg, v);
                }
                break;
            case PIC_clrf:
            case PIC_clrf2:
                split(reg, 0);
                break;
            case PIC_swapf:
            case PIC_swapf3:
                split(reg, ((v>>4) & 15) | ((v & 15) << 4));
                break;
            case PIC_movwf:
            case PIC_movwf2:
            case PIC_addlw:
            case PIC_andlw:
            case PIC_iorlw:
            case PIC_sublw:
            case PIC_xorlw:
            {
                insn_t saved = cmd;
                if ( decode_prev_insn(cmd.ea) != BADADDR
                        && ( cmd.itype == PIC_movlw ) )
                {
                    switch ( saved.itype )
                    {
                    case PIC_movwf:
                    case PIC_movwf2:
                        v = cmd.Op1.value;
                        break;
                    case PIC_addlw:
                        v += cmd.Op1.value;
                        break;
                    case PIC_andlw:
                        v &= cmd.Op1.value;
                        break;
                    case PIC_iorlw:
                        v |= cmd.Op1.value;
                        break;
                    case PIC_sublw:
                        v -= cmd.Op1.value;
                        break;
                    case PIC_xorlw:
                        v ^= cmd.Op1.value;
                        break;
                    }
                }
                else
                {
                    v = BADSEL;
                }
                cmd = saved;
            }
            split(reg, v);
            break;
            case PIC_movlw:
                split(reg, cmd.Op2.value);
                break;
            }
        }
    }

// Such as , IDA doesn't seem to convert the following:
// tris 6
// into
// tris PORTB ( or whatever )

    if ( cmd.itype == PIC_tris && !isDefArg0(uFlag) )
        set_offset(cmd.ea, 0, dataseg);

//   movlw value
// followed by a
//   movwf FSR
// should convert value into an offset , because FSR is used as a pointer to
// the INDF (indirect addressing file)

    if ( ptype == PIC12 || ptype == PIC14
            && cmd.itype == PIC_movwf
            && cmd.Op1.type == o_mem
            && (cmd.Op1.addr & 0x7F) == 0x4 )    // FSR
    {
        insn_t saved = cmd;
        if ( decode_prev_insn(cmd.ea) != BADADDR
                && cmd.itype == PIC_movlw )
        {
            set_offset(cmd.ea, 0, dataseg);
        }
        cmd = saved;
    }

// Also - it seems to make sense to me that a
//   movlw value
// followed by a
//   tris PORTn  (or movwf TRISn)
// should convert value into a binary , because the bits indicate whether a
// port is defined for input or output.

    if ( is_load_tris_reg() )
    {
        insn_t saved = cmd;
        if ( decode_prev_insn(cmd.ea) != BADADDR
                && cmd.itype == PIC_movlw )
        {
            op_bin(cmd.ea, 0);
        }
        cmd = saved;
    }

// Move litteral to BSR

    if ( cmd.itype == PIC_movlb1 ) split(BANK, cmd.Op1.value);

//
//      Determine if the next instruction should be executed
//
    if ( !flow ) flow = conditional_insn();
    if ( segtype(cmd.ea) == SEG_XTRN ) flow = 0;
    if ( flow ) ua_add_cref(0,cmd.ea+cmd.size,fl_F);

    return 1;
}