Ejemplo n.º 1
0
//----------------------------------------------------------------------
static bool get_op_value(op_t &x, int *value)
{
  if ( x.type == o_imm )
  {
    *value = (int)x.value;
    return true;
  }
  bool ok = false;
  if ( x.type == o_reg )
  {
    int reg = x.reg;
    insn_t saved = cmd;
    if ( decode_prev_insn(cmd.ea) != BADADDR
      && is_mov(cmd.itype)
      && cmd.Op1.type == o_imm
      && cmd.Op2.type == o_reg
      && cmd.Op2.reg  == reg )
    {
      *value = (int)cmd.Op1.value;
      ok = true;
    }
    cmd = saved;
  }
  return ok;
}
Ejemplo n.º 2
0
//----------------------------------------------------------------------
//      These are the recognized jump table sizing patterns
//0100                cmp.b   #7, r0l
//0102                bls     loc_108:8
//0104                bra     def_200:8
//0106      loc_108:  ; jump table lookup
//0200      def_200:  ; default jump target
//      Or
//0100                cmp.b   #7, r0l
//0102                bls     loc_108:8
//0104                jmp     def_2000:16
//0108      loc_108:  ; jump table lookup
//2000      def_2000: ; default jump target
//      Or
//0100                mov.w   #7, r3
//0104                cmp.w   r3, r0
//0106                bls     loc_10C:8
//0108                bra     def_200:8
//010A      loc_10C:  ; jump table lookup
//0200      def_200:  ; default jump target
//      Or
//0100                mov.w   #7, r3
//0104                cmp.w   r3, r0
//0106                bls     loc_10C:8
//0108                jmp     def_2000:16
//010C      loc_10C:  ; jump table lookup
//2000      def_2000: ; default jump target
//      Or
//0100                cmp.b   #7, r0l
//0102                bhi     def_200:8
//0104                ; jump table lookup
//0200      def_200:  ; default jump target
//      Or
//0100                mov.w   #7, r3
//0104                cmp.w   r3, r0
//0106                bhi     def_200:8
//0108                ; jump table lookup
//0200      def_200:  ; default jump target
//----------------------------------------------------------------------
static bool find_table_size(ea_t *defea, int *size, int rlx, ea_t code_ip)
{
  *defea = BADADDR;
  *size  = INT_MAX;
  if ( decode_prev_insn(cmd.ea) == BADADDR ) return true;

  if ( cmd.itype == H8_bhi )                    // bhi default
  {
    *defea = cmd.Op1.addr;
  }
  else
  {
    if ( cmd.itype != H8_jmp                    // jmp default
      && cmd.itype != H8_bra ) return true;     // bra default
    *defea = cmd.Op1.addr;

    if ( decode_prev_insn(cmd.ea) == BADADDR
      || cmd.itype != H8_bls                    // bls code_ip
      || cmd.Op1.addr != code_ip ) return true;
  }

  if ( decode_prev_insn(cmd.ea) == BADADDR
    || cmd.itype    != H8_cmp                   // cmp.b #size, rlx
    || cmd.Op2.type != o_reg ) return true;
  if ( cmd.Op1.type == o_imm )
  {
    if ( (cmd.auxpref &  aux_byte) == 0
      || cmd.Op2.reg  != rlx ) return true;
  }
  else
  {
    if ( cmd.Op1.type != o_reg                  // cmp.w RX, rx
      || cmd.Op2.reg  != (rlx - 24) ) return true;
    int rx = cmd.Op1.reg;
    if ( decode_prev_insn(cmd.ea) == BADADDR
      || cmd.itype    != H8_mov                 // mov.w #size, RX
      || cmd.Op2.type != o_reg
      || cmd.Op2.reg  != rx
      || cmd.Op1.type != o_imm ) return true;
  }

  *size = int(cmd.Op1.value + 1);
  return true;
}
Ejemplo n.º 3
0
//----------------------------------------------------------------------
//      This is jump table pattern #2
//      (*1* may be omitted...IE, this logic is located above jump table sizing instructions)
//0100    *1*          sub.b   r0h, r0h
//0102                 add.w   r0, r0
//0104                 mov.w   @(jpt_108:16,r0), r0
//0108                 jmp     @r0
//----------------------------------------------------------------------
static bool is_jump_pattern2(ea_t *base, ea_t *table, ea_t *defea, int *size, int *elsize)
{
  int reg = cmd.Op1.phrase;
  if ( decode_prev_insn(cmd.ea) == BADADDR
    || cmd.itype != H8_mov                      // mov.w   @(table:16,r0), r0
    || (cmd.auxpref & aux_word) == 0
    || cmd.Op1.type != o_displ
    || cmd.Op2.reg  != reg    ) return false;
  *table  = cmd.Op1.addr;
  int rx  = cmd.Op1.reg;
  *base   = 0;
  ea_t bea = toEA(cmd.cs, 0);
  set_offset(cmd.ea, 0, bea);

  if ( decode_prev_insn(cmd.ea) == BADADDR
    || cmd.itype != H8_add                      // add.w r0, r0
    || (cmd.auxpref & aux_word) == 0
    || cmd.Op1.type != o_reg
    || cmd.Op1.reg  != rx
    || cmd.Op2.reg  != rx     ) return false;
  int rhx = rx + 16;
  int rlx = rhx + 8;

  ea_t oldea = cmd.ea;
  ea_t oldip = cmd.ip;
  if ( decode_prev_insn(cmd.ea) == BADADDR
    || (cmd.itype != H8_sub && cmd.itype != H8_xor) // sub.b rhx, rhx
    || (cmd.auxpref & aux_byte) == 0
    || cmd.Op1.type != o_reg
    || cmd.Op2.type != o_reg
    || cmd.Op1.reg  != rhx
    || cmd.Op2.reg  != rhx    ) // return false;
  {
    cmd.ea = oldea; // forgive this...
    cmd.ip = oldip;
  }

  // the jump table is found, try to determine its size
  *elsize = 2;
  return find_table_size(defea, size, rlx, cmd.ip);
}
Ejemplo n.º 4
0
Archivo: emu.cpp Proyecto: nealey/vera
// Emulate an instruction.
int idaapi emu(void) {
    bool flow = !is_stop() || (cmd.auxpref & INSN_DELAY_SHOT);
    if ( flow )
    {
      insn_t cmd_backup = cmd;
      if ( decode_prev_insn(cmd.ea) != BADADDR ) {
          flow = !(is_stop() && (cmd.auxpref & INSN_DELAY_SHOT));
      }
      cmd = cmd_backup;
    }

    if ( cmd.Op1.type != o_void)            handle_operand(cmd.Op1 );
    if ( cmd.Op2.type != o_void)            handle_operand(cmd.Op2 );
    if ( cmd.Op3.type != o_void)            handle_operand(cmd.Op3 );
    if ( cmd.Op4.type != o_void)            handle_operand(cmd.Op4 );

    if ( flow )
        ua_add_cref(0, cmd.ea + cmd.size, fl_F);

    return 1;
}
Ejemplo n.º 5
0
//----------------------------------------------------------------------
//      This is jump table pattern #1
//0100                sub.b   r0h, r0h
//0102                mov.b   @(jpt_10a:16,r0), r0l
//0106                add.b   #loc_10C & 0xFF, r0l
//0108                addx    #loc_10C >> 8, r0h
//010A                jmp     @r0
//010C      loc_10C:  ; base address of jump table
//      Or
//0100                mov.b   @(jpt_10a:16,r0), r0l
//0104                sub.b   r0h, r0h
//0106                add.b   #loc_10C & 0xFF, r0l
//0108                addx    #loc_10C >> 8, r0h
//010A                jmp     @r0
//010C      loc_10C:  ; base address of jump table
//----------------------------------------------------------------------
static bool is_jump_pattern1(ea_t *base, ea_t *table, ea_t *defea, int *size, int *elsize)
{
  int reg = cmd.Op1.phrase;
  int rh  = reg + 16;
  int rl  = rh  + 8;
  if ( decode_prev_insn(cmd.ea) == BADADDR
    || cmd.itype != H8_addx                     // addx #baseh, rh
    || cmd.Op1.type != o_imm
    || cmd.Op2.reg  != rh     ) return false;
  int baseh = (int)cmd.Op1.value;       // msb of base
  ea_t eah = cmd.ea;

  if ( decode_prev_insn(cmd.ea) == BADADDR
    || cmd.itype != H8_add                      // add.b #basel, rl
    || (cmd.auxpref & aux_byte) == 0
    || cmd.Op1.type != o_imm
    || cmd.Op2.reg  != rl     ) return false;
  int basel = (int)cmd.Op1.value;       // lsb of base
  ea_t eal = cmd.ea;

  int rx, rhx, rlx;
  ea_t obase;
  if ( decode_prev_insn(cmd.ea) == BADADDR )
    return false;
  else
  {
    if ( cmd.itype == H8_mov )                     // mov.b @(table:16,rx), rl
    {
      if ( (cmd.auxpref & aux_byte) == 0
        || cmd.Op1.type != o_displ
        || cmd.Op2.reg  != rl     ) return false;

      *table  = cmd.Op1.addr;
      rx  = cmd.Op1.reg;
      rhx = rx + 16;
      rlx = rhx + 8;
      obase = toEA(cmd.cs, 0);
      set_offset(cmd.ea, 0, obase);

      if ( decode_prev_insn(cmd.ea) == BADADDR
        || (cmd.itype != H8_sub && cmd.itype != H8_xor) // sub.b rhx, rhx
        || (cmd.auxpref & aux_byte) == 0
        || cmd.Op1.type != o_reg
        || cmd.Op2.type != o_reg
        || cmd.Op1.reg  != rhx
        || cmd.Op2.reg  != rhx    ) return false;
    }
    else if ( cmd.itype == H8_sub || cmd.itype == H8_xor )  // sub.b rhx, rhx
    {
      if ( (cmd.auxpref & aux_byte) == 0
        || cmd.Op1.type != o_reg
        || cmd.Op2.type != o_reg
        || cmd.Op1.reg  != cmd.Op2.reg ) return false;

      rhx = cmd.Op1.reg;
      rlx = rhx + 8;
      rx = rhx - 16;

      if ( decode_prev_insn(cmd.ea) == BADADDR
        || (cmd.itype != H8_mov)                     // mov.b @(table:16,rx), rl
        || (cmd.auxpref & aux_byte) == 0
        || cmd.Op1.type != o_displ
        || cmd.Op2.reg  != rl
        || cmd.Op1.reg != rx ) return false;

      *table  = cmd.Op1.addr;
      obase = toEA(cmd.cs, 0);
      set_offset(cmd.ea, 0, obase);
    }
    else
      return false;
  }

  *base  = (baseh<<8) | basel;
  ea_t bea = toEA(cmd.cs, *base);
  op_offset(eah, 0, REF_HIGH8, bea, obase);
  op_offset(eal, 0, REF_LOW8,  bea, obase);

  // the jump table is found, try to determine its size
  *elsize = 1;
  return find_table_size(defea, size, rlx, cmd.ip);
}
int idaapi emu()
{
    char szLabel[MAXSTR];
    insn_t saved;
    segment_t* pSegment;
    ea_t ea, length, offset;
    flags_t flags;
    uint32 dwFeature, i;

    dwFeature = cmd.get_canon_feature();
    fFlow = !(dwFeature & CF_STOP);

    if (dwFeature & CF_USE1) op_emu(cmd.Op1, 1);
    if (dwFeature & CF_USE2) op_emu(cmd.Op2, 1);

    if (dwFeature & CF_CHG1) op_emu(cmd.Op1, 0);
    if (dwFeature & CF_CHG2) op_emu(cmd.Op2, 0);

    saved = cmd;
    switch (cmd.itype)
    {
    case M8B_MOV:
        if (!cmd.Op1.is_reg(rPSP))
            break;
    case M8B_SWAP:
        if (cmd.itype == M8B_SWAP && !cmd.Op2.is_reg(rDSP))
            break;

        for (i = 0; i < 5; ++i)
        {
            ea = decode_prev_insn(cmd.ea);
            if (ea == BADADDR) break;
            if (cmd.itype == M8B_MOV && cmd.Op1.is_reg(rA) && cmd.Op2.type == o_imm)
            {
                ea = toRAM(cmd.Op2.value);
                if (ea != BADADDR)
                {
                    qsnprintf(szLabel, sizeof(szLabel), "%s_%0.2X", cmd.itype == M8B_MOV ? "psp" : "dsp", cmd.Op2.value);
                    ua_add_dref(cmd.Op2.offb, ea, dr_O);
                    set_name(ea, szLabel, SN_NOWARN);
                }
                break;
            }
        }
        break;
    case M8B_JACC:
        pSegment = getseg(cmd.ea);
        if (!pSegment) break;
        length = pSegment->endEA - cmd.ea;
        if (length > 256) length = 256;
        for (offset = 2; offset < length; offset += 2)
        {
            ea = toROM(saved.Op1.addr + offset);
            if (ea == BADADDR) break;
            flags = getFlags(ea);
            if (!hasValue(flags) || (has_any_name(flags) || hasRef(flags)) || !create_insn(ea)) break;
            switch (cmd.itype)
            {
            case M8B_JMP:
            case M8B_RET:
            case M8B_RETI:
            case M8B_IPRET:
                add_cref(saved.ea, ea, fl_JN);
                break;
            default:
                offset = length;
            }
        }
        break;
    case M8B_IORD:
    case M8B_IOWR:
    case M8B_IOWX:
        for (i = 0; i < 5; ++i)
        {
            ea = (saved.itype == M8B_IORD) ? decode_insn(cmd.ea + cmd.size) : decode_prev_insn(cmd.ea);
            if (ea == BADADDR) break;
            if (cmd.Op1.is_reg(rA) && cmd.Op2.type == o_imm)
            {
                qsnprintf(szLabel, sizeof(szLabel), "[A=%0.2Xh] ", cmd.Op2.value);
                if (get_portbits_sym(szLabel + qstrlen(szLabel), saved.Op1.addr, cmd.Op2.value))
                    set_cmt(saved.ea, szLabel, false);
                break;
            }
        }
    }
    cmd = saved;

    if ((cmd.ea & 0xFF) == 0xFF)
    {
        switch (cmd.itype)
        {
        case M8B_RET:
        case M8B_RETI:
        case M8B_XPAGE:
            break;
        default:
            QueueMark(Q_noValid, cmd.ea);
        }
    }

    if (fFlow) ua_add_cref(0, cmd.ea + cmd.size, fl_F);

    return 1;
}
Ejemplo n.º 7
0
Archivo: emu.cpp Proyecto: nealey/vera
//----------------------------------------------------------------------
int emu(void)
{
  if ( segtype(cmd.ea) == SEG_XTRN ) return 1;

  //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);

//      Determine if the next instruction should be executed
  flow = (InstrIsSet(cmd.itype, CF_STOP) != true);



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

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


  // check for DP changes
  if ( cmd.itype == OAK_Dsp_lpg )
                splitSRarea1(get_item_end(cmd.ea), PAGE, cmd.Op1.value & 0xFF, SR_auto);
  if ( ( cmd.itype == OAK_Dsp_mov ) && (cmd.Op1.type == o_imm) && (cmd.Op2.type == o_reg) && (cmd.Op2.reg == ST1) )
                splitSRarea1(get_item_end(cmd.ea), PAGE, cmd.Op1.value & 0xFF, SR_auto);


  //Delayed Return

  insn_t saved = cmd;
  cycles = cmd.cmd_cycles;
  delayed = false;

  if ( decode_prev_insn(cmd.ea) != BADADDR )
  {
          if  ( (cmd.itype == OAK_Dsp_retd) || (cmd.itype == OAK_Dsp_retid) )
                  delayed = true;
          else
                  cycles += cmd.cmd_cycles;

          if (!delayed)
                if ( decode_prev_insn(cmd.ea) != BADADDR )
                        if ( (cmd.itype == OAK_Dsp_retd) || (cmd.itype == OAK_Dsp_retid) )
                                delayed = true;
  }

  if (delayed && (cycles > 1) )
          flow = 0;

  cmd = saved;

  //mov #imm, pc

  if ( ( cmd.itype == OAK_Dsp_mov ) && (cmd.Op2.type == o_reg) && (cmd.Op2.reg == PC) )
     flow = 0;

  if ( flow ) ua_add_cref(0,cmd.ea+cmd.size,fl_F);

  if ( may_trace_sp() )
  {
    if ( !flow )
      recalc_spd(cmd.ea);     // recalculate SP register for the next insn
    else
      trace_sp();
  }

  return 1;
}
Ejemplo n.º 8
0
//----------------------------------------------------------------------
bool jump_pattern_t::follow_tree(ea_t ea, int n)
{
  if ( n == 0 )
    return true;
  int rsaved[sizeof(r)];
  bool ssaved[sizeof(spoiled)];
  memcpy(rsaved, r, sizeof(r));
  memcpy(ssaved, spoiled, sizeof(spoiled));
  bool success = false;
  if ( n < 0 )
  {
    success = true;
    n = -n;
  }
  jmsg("follow_tree(%a, %d)\n", ea, n);
  if ( !skip[n] )
  {
    if ( eas[n] == BADADDR )
    {
      cmd.ea = ea;
      bool found_insn = false;
      while ( true )
      {
        if ( cmd.ea < minea )
          break;
        farref = false;
        ea_t prev = BADADDR;
        if ( allow_noflows || isFlow(get_flags_novalue(cmd.ea)) )
          prev = decode_prev_insn(cmd.ea);
        if ( prev == BADADDR )
        {
          if ( !allow_farrefs )
            break;
          ea_t cur_addr = cmd.ea;
          if ( decode_preceding_insn(cmd.ea, &farref) == BADADDR )
            break;
          
          // skip branches which are used to glue blocks together
          if ( farref && is_branch_to(cur_addr) )
            continue;
        }

        if ( handle_mov() )
          continue;
        if ( (this->*check[n])() )
        {
          found_insn = true;
          break;
        }
        if ( failed )
          return false;
        jmsg("%a: can't be %d.", cmd.ea, n);
        jmsg(" rA=%d%s rB=%d%s rC=%d%s rD=%d%s rE=%d%s\n",
                        r[1], spoiled[1] ? "*" : "",
                        r[2], spoiled[2] ? "*" : "",
                        r[3], spoiled[3] ? "*" : "",
                        r[4], spoiled[4] ? "*" : "",
                        r[5], spoiled[5] ? "*" : "");
        check_spoiled();
      }
      if ( !found_insn )
      {
        memcpy(r, rsaved, sizeof(r));
        if ( success )
          goto SUCC;
        return false;
      }
      eas[n] = cmd.ea;
    }
    if ( eas[n] >= ea )
    {
      jmsg("%a: depends on %a\n", ea, eas[n]);
      return success;
    }
    ea = eas[n];
    jmsg("%a: found %d\n", cmd.ea, n);
  }
SUCC:
  if ( depends[n][0] && !follow_tree(ea, depends[n][0]) )
    return success;
  if ( depends[n][1] && !follow_tree(ea, depends[n][1]) )
    return success;
  jmsg("follow_tree(%d) - ok\n", n);
  memcpy(spoiled, ssaved, sizeof(spoiled));
  return true;
}
Ejemplo n.º 9
0
Archivo: emu.cpp Proyecto: 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;
}
Ejemplo n.º 10
0
Archivo: emu.cpp Proyecto: nealey/vera
//----------------------------------------------------------------------
static void process_operand(op_t &x,int ,int isload)
{
    if ( cmd.Op2.type == o_reg && cmd.Op2.reg == F || cmd.itype == PIC_swapf ) isload = 0;
    switch ( x.type )
    {
    case o_reg:
        return;
    case o_imm:
        if ( !isload ) error("interr: emu");
        process_immediate_number(x.n);
        if ( isOff(uFlag, x.n) )
            ua_add_off_drefs2(x, dr_O, calc_outf(x));
        break;
    case o_near:
    {
        cref_t ftype = fl_JN;
        ea_t ea = calc_code_mem(x.addr);
        if ( InstrIsSet(cmd.itype, CF_CALL) )
        {
            if ( !func_does_return(ea) )
                flow = false;
            ftype = fl_CN;
        }
        ua_add_cref(x.offb, ea, ftype);
    }
    break;
    case o_mem:
    {
        ea_t ea = calc_data_mem(x.addr);
        destroy_if_unnamed_array(ea);
        ua_add_dref(x.offb, ea, isload ? dr_R : dr_W);
        ua_dodata2(x.offb, ea, x.dtyp);
        if ( !isload )
            doVar(ea);
        if ( may_create_stkvars())
        {
            if ( x.addr == PIC16_INDF2 )
            {
                func_t *pfn = get_func(cmd.ea);
                if ( pfn != NULL && (pfn->flags & FUNC_FRAME) != 0 )
                {
                    ua_stkvar2(cmd.Op1, 0, STKVAR_VALID_SIZE);
                }
            }
            else if ( x.addr == PIC16_PLUSW2 )
            {
                insn_t saved = cmd;
                if ( decode_prev_insn(cmd.ea) != BADADDR && cmd.itype == PIC_movlw )
                {
                    func_t *pfn = get_func(cmd.ea);
                    if ( pfn != NULL && (pfn->flags & FUNC_FRAME) != 0 )
                    {
                        if ( ua_stkvar2(cmd.Op1, cmd.Op1.value, STKVAR_VALID_SIZE) )
                            op_stkvar(cmd.ea, cmd.Op1.n);
                    }
                }
                cmd = saved;
            }
        }




    }
    break;
    default:
        warning("interr: emu2 %a", cmd.ea);
    }
}