//---------------------------------------------------------------------- static void TouchArg( op_t &x, int isload ) { switch( x.type ) { case o_imm: doImmd(cmd.ea); if ( op_adds_xrefs(uFlag, x.n) ) ua_add_off_drefs2(x, dr_O, OOF_SIGNED); break; case o_indexed: // addr[value] doImmd(cmd.ea); if ( x.value == 0 && !isDefArg(uFlag, x.n) ) set_offset(cmd.ea, x.n, toEA(cmd.cs, 0)); if ( op_adds_xrefs(uFlag, x.n) ) // xref to addr { uval_t saved = x.value; x.value = x.addr; ua_add_off_drefs2(x, saved ? dr_O : isload ? dr_R : dr_W, OOF_SIGNED|OOF_ADDR); x.value = saved; } if ( x.value != 0 ) // xref to value { // no references to ZERO_REG ea_t ea = toEA(cmd.cs, x.value); ua_add_dref(x.offb, ea, isload ? dr_R : dr_W ); ua_dodata2(x.offb, ea, x.dtyp); } break; case o_indirect: case o_indirect_inc: case o_mem: { ea_t dea = toEA( cmd.cs, x.addr ); ua_dodata2(x.offb, dea, x.dtyp); if( !isload ) doVar(dea); ua_add_dref( x.offb, dea, isload ? dr_R : dr_W ); if ( !isload && (x.addr == 0x14 || x.addr == 0x15) ) { sel_t wsrval = BADSEL; if ( cmd.Op2.type == o_imm ) wsrval = sel_t(cmd.Op2.value); split_srarea(cmd.ea, x.addr == 0x14 ? WSR : WSR1, wsrval, SR_auto); } } break; case o_near: ea_t ea = toEA( cmd.cs, x.addr ); int iscall = InstrIsSet( cmd.itype, CF_CALL ); ua_add_cref( x.offb, ea, iscall ? fl_CN : fl_JN ); if ( flow && iscall ) flow = func_does_return(ea); } }
//---------------------------------------------------------------------- static void process_operand(op_t &x,int isAlt,int isload) { switch ( x.type ) { case o_reg: break; default: // interr("emu"); break; case o_imm: process_immediate_number(x.n); if ( op_adds_xrefs(uFlag, x.n) ) ua_add_off_drefs2(x, dr_O, OOFS_IFSIGN); break; case o_phrase: if ( !isAlt && op_adds_xrefs(uFlag, x.n) ) { ea_t ea = ua_add_off_drefs2(x, isload ? dr_R : dr_W, OOF_ADDR); if ( ea != BADADDR ) { ua_dodata2(x.offb, ea, x.dtyp); if ( !isload ) doVar(ea); } } break; case o_mem: { ea_t ea = calc_mem(x); ua_add_dref(x.offb, ea, isload ? dr_R : dr_W); ua_dodata2(x.offb, ea, x.dtyp); if ( !isload ) doVar(ea); if ( x.amode & amode_l ) { ea = ymem + x.addr; ua_add_dref(x.offb, ea, isload ? dr_R : dr_W); ua_dodata2(x.offb, ea, x.dtyp); } } break; case o_near: add_near_ref(x, calc_mem(x)); break; } }
//---------------------------------------------------------------------- static void TouchArg(op_t &x, int isload) { switch ( x.type ) { case o_displ: case o_imm: if ( op_adds_xrefs(uFlag, x.n) ) { int outf = x.type != o_imm ? OOF_ADDR : 0; ua_add_off_drefs2(x, dr_O, outf|OOF_SIGNED); } break; case o_mem: case o_ind_mem: case o_reg: case o_ind_reg: { ea_t dea; if ( x.type == o_mem || x.type == o_ind_mem ) { dea = map_addr(x.addr, x.n, true); } else { if ( x.reg >= rRR0 ) dea = map_addr(x.reg - rRR0, x.n, true); else dea = map_addr(x.reg - rR0, x.n, true); } ua_dodata2(x.offb, dea, x.dtyp); if ( !isload ) doVar(dea); ua_add_dref(x.offb, dea, isload ? dr_R : dr_W); if ( !has_user_name(get_flags_novalue(dea)) && dea > intmem) { char buf[10]; int num = dea - intmem; if ( num < 0x100 ) { qsnprintf(buf, sizeof(buf), "R%d", num); } else if ( num < 0x1000 ) { qsnprintf(buf, sizeof(buf), "ERF_%X_%d", num >> 8, num & 0xFF); } else { int reg_no = ((num >> 4) & 0xF0) + (num & 0xF); int subbank_no = ((num >> 4) & 0xF) + 1; qsnprintf(buf, sizeof(buf), "R%d_%X", reg_no, subbank_no); } set_name(dea, buf, SN_NOWARN); }
//---------------------------------------------------------------------- static bool TouchArg(op_t &x,int isload) { dref_t xreftype; uchar outf; switch ( x.type ) { case o_phrase: // 2 registers case o_reg: break; case o_imm: if ( !isload ) goto badTouch; xreftype = dr_O; outf = OOF_SIGNED; goto makeImm; case o_displ: xreftype = isload ? dr_R : dr_W; outf = OOF_SIGNED|OOF_ADDR; makeImm: doImmdValue(); if ( op_adds_xrefs(uFlag, x.n) ) ua_add_off_drefs2(x, xreftype, outf); break; case o_mem: ua_dodata2(x.offb, x.addr, x.dtyp); if ( !isload ) doVar(x.addr); ua_add_dref(x.offb,x.addr,isload ? dr_R : dr_W); break; case o_near: { int iscall = InstrIsSet(cmd.itype,CF_CALL); ua_add_cref(x.offb,x.addr,iscall ? fl_CN : fl_JN); if ( iscall && !func_does_return(x.addr) ) return false; } break; default: badTouch: warning("%a: %s,%d: bad optype %d", cmd.ea, cmd.get_canon_mnem(), x.n, x.type); break; } return true; }
//---------------------------------------------------------------------- static void TouchArg(op_t &x,int isload) { switch ( x.type ) { case o_regpair: case o_reg: case o_phrase: case o_spmask: case o_stgcyc: break; case o_imm: if ( !isload ) goto badTouch; /* no break */ case o_displ: doImmdValue(x.n); if ( op_adds_xrefs(uFlag, x.n) ) { int outf = x.type != o_imm ? OOF_ADDR : 0; if ( x.dtyp == dt_word ) outf |= OOF_SIGNED; ua_add_off_drefs2(x, dr_O, outf); } break; case o_near: { ea_t ea = toEA(cmd.cs,x.addr); ea_t ref = find_first_insn_in_packet(ea); ua_add_cref(x.offb, ref, fl_JN); } break; default: badTouch: warning("%a: %s,%d: bad optype %d", cmd.ea, cmd.get_canon_mnem(), x.n, x.type); break; } }
//---------------------------------------------------------------------- static void process_operand(op_t &x,int isAlt,int isload) { switch ( x.type ) { case o_reg: case o_reglist: return; case o_imm: QASSERT(10090, isload); process_immediate_number(x.n); if ( op_adds_xrefs(uFlag, x.n) ) ua_add_off_drefs2(x, dr_O, calc_opimm_flags()); break; case o_phrase: 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, calc_opdispl_flags()); if ( ea != BADADDR ) { ua_dodata2(x.offb, ea, x.dtyp); if ( !isload ) doVar(ea); } } // create stack variables if required if ( x.type == o_displ && 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: case o_far: { cref_t ftype = x.type == o_near ? fl_JN : fl_JF; ea_t ea = calc_mem(x); if ( InstrIsSet(cmd.itype, CF_CALL) ) { if ( !func_does_return(ea) ) flow = false; ftype = x.type == o_near ? fl_CN : fl_CF; } ua_add_cref(x.offb, ea, ftype); } break; case o_mem: { ea_t ea = calc_mem(x); ua_add_dref(x.offb, ea, isload ? dr_R : dr_W); ua_dodata2(x.offb, ea, x.dtyp); if ( !isload ) doVar(ea); } break; default: INTERR(10091); } }
//------------------------------------------------------------------------ static void TouchArg(op_t &x,int isAlt,int isload) { ea_t jmpa; switch ( x.type ) { case o_near: // Jcc/ [jmp/call 37/67] case o_mem: // 37/67/77 case o_far: jmpa = toEA(x.type == o_far ? x.segval : codeSeg(x.addr16,x.n), x.addr16); if ( x.phrase == 0) { ua_add_cref(x.offb,jmpa,fl_JN ); break; } //Jcc extxref: if ( (x.phrase & 070) == 070 ) goto xrefset; if ( cmd.itype == pdp_jmp) ua_add_cref(x.offb,jmpa,fl_JF ); else if ( cmd.itype == pdp_jsr || cmd.itype == pdp_call ) { ua_add_cref(x.offb,jmpa,fl_CF); if ( !func_does_return(jmpa) ) flow = false; } else { xrefset: ua_dodata2(x.offb, jmpa, x.dtyp); ua_add_dref(x.offb, jmpa, isload ? dr_R : dr_W); } break; case o_displ: // 6x/7x (!67/!77) doImmdValue(); if ( !isload && x.phrase == (060 + rR0) && x.addr16 <= 1 ) loadR0data(&x, x.addr16); if ( !isAlt && isOff(emuFlg,x.n ) && (jmpa = get_offbase(cmd.ea, x.n)) != BADADDR) { jmpa += x.addr16; goto extxref; } break; case o_imm: // 27 if ( !x.ill_imm ) { doImmdValue(); if ( op_adds_xrefs(uFlag, x.n) ) ua_add_off_drefs2(x, dr_O, OOF_SIGNED); } break; case o_number: // EMT/TRAP/MARK/SPL if ( cmd.itype == pdp_emt && get_cmt(cmd.ea, false, NULL, 0) <= 0 ) { if ( x.value >= 0374 && x.value <= 0375 ) { cmd.Op2.value = (x.value == 0375) ? emuR0data.b[1] : (emuR0 >> 8); cmd.Op2.type = o_imm; } char buf[MAXSTR]; if ( get_predef_insn_cmt(cmd, buf, sizeof(buf)) > 0 ) set_cmt(cmd.ea, buf, false); cmd.Op2.type = o_void; } break; case o_reg: // 0 if ( x.reg == rR0 ) { if ( cmd.Op2.type == o_void ) { // one operand cmd if ( cmd.itype != pdp_clr ) { goto undefall; } else { if ( cmd.bytecmd ) emuR0 &= 0xFF00; else emuR0 = 0; goto undefdata; } } if ( &x == &cmd.Op2 ) { if ( cmd.itype != pdp_mov ) { if ( cmd.bytecmd ) { emuR0 |= 0xFF; goto undefdata; } else goto undefall; } if ( cmd.bytecmd ) goto undefall; if ( cmd.Op1.type == o_imm ) { if ( (emuR0 = (ushort)cmd.Op1.value) & 1 ) goto undefdata; emuR0data.w = get_word(toEA(cmd.cs, emuR0)); } else { undefall: emuR0 = 0xFFFF; undefdata: emuR0data.w = 0xFFFF; } } } break; case o_phrase: // 1x/2x/3x/4x/5x (!27/!37) if ( (x.phrase & 7) == rR0 ) { if ( !isload && x.phrase == (010 + rR0)) loadR0data(&x, 0 ); else if ( cmd.Op2.type == o_void || &x == &cmd.Op2 ) goto undefall; } case o_fpreg: // FPP break; default: warning("%" FMT_EA "o (%s): bad optype %d", cmd.ip, cmd.get_canon_mnem(), x.type); break; }
//---------------------------------------------------------------------- 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); } }
// Emulate an operand. static void handle_operand(op_t &op, bool write) { switch ( op.type ) { // Code address case o_near: { cref_t mode; ea_t ea = toEA(cmd.cs, op.addr); // call or jump ? if ( cmd.itype == st9_call || cmd.itype == st9_calls ) { if ( !func_does_return(ea) ) flow = false; mode = fl_CN; } else { mode = fl_JN; } ua_add_cref(op.offb, ea, mode); } break; // Memory address case o_mem: { enum dref_t mode; mode = write ? dr_W: dr_R; ua_add_dref(op.offb, toEA(cmd.cs, op.addr), mode); ua_dodata2(op.offb, op.addr, op.dtyp); } break; // Immediate value case o_imm: doImmd(cmd.ea); // create a comment if this immediate is represented in the .cfg file { const ioport_t * port = find_sym(op.value); if ( port != NULL && !has_cmt(uFlag) ) { set_cmt(cmd.ea, port->cmt, false); } } // if the value was converted to an offset, then create a data xref: if ( op_adds_xrefs(uFlag, op.n) ) ua_add_off_drefs2(op, dr_O, 0); break; // Displacement case o_displ: doImmd(cmd.ea); if ( op_adds_xrefs(uFlag, op.n) ) { ea_t ea = ua_add_off_drefs2(op, dr_O, OOF_ADDR); ua_dodata2(op.offb, ea, op.dtyp); } // create stack variables if required if ( may_create_stkvars() && !isDefArg(uFlag, op.n) ) { func_t *pfn = get_func(cmd.ea); if ( pfn != NULL && pfn->flags & FUNC_FRAME ) { if ( ua_stkvar2(op, op.addr, STKVAR_VALID_SIZE) ) { op_stkvar(cmd.ea, op.n); if ( cmd.Op2.type == o_reg ) { regvar_t *r = find_regvar(pfn, cmd.ea, ph.regNames[cmd.Op2.reg]); if ( r != NULL ) { struc_t *s = get_frame(pfn); member_t *m = get_stkvar(op, op.addr, NULL); if ( s != NULL && m != NULL ) { char b[20]; qsnprintf(b, sizeof b, "%scopy", r->user); set_member_name(s, m->soff, b); } } } } } } break; // Register - Phrase - Void: do nothing case o_reg: case o_phrase: case o_void: break; default: INTERR(10076); } }
// emulate operand static void handle_operand(op_t &op, bool loading) { switch ( op.type ) { // Address case o_near: // branch label - create code reference (call or jump // according to the instruction) { ea_t ea = toEA(cmd.cs, op.addr); cref_t ftype = fl_JN; if ( cmd.itype == m32r_bl ) { if ( !func_does_return(ea) ) flow = false; ftype = fl_CN; } ua_add_cref(op.offb, ea, ftype); } break; // Immediate case o_imm: if ( !loading ) { interr1("handle_operand(): o_imm with CF_CHG"); } handle_imm(); // if the value was converted to an offset, then create a data xref: if ( op_adds_xrefs(uFlag, op.n) ) ua_add_off_drefs2(op, dr_O, OOFW_IMM|OOF_SIGNED); // create a comment if this immediate is represented in the .cfg file { const ioport_t * port = find_sym(op.value); if ( port != NULL && !has_cmt(uFlag) ) set_cmt(cmd.ea, port->cmt, false); } break; // Displ case o_displ: handle_imm(); // if the value was converted to an offset, then create a data xref: if ( op_adds_xrefs(uFlag, op.n) ) ua_add_off_drefs2(op, loading ? dr_R : dr_W, OOF_SIGNED|OOF_ADDR|OOFW_32); // create stack variables if required if ( may_create_stkvars() && !isDefArg(uFlag, op.n) ) { func_t *pfn = get_func(cmd.ea); if ( pfn != NULL && (op.reg == rFP || op.reg == rSP) && pfn->flags & FUNC_FRAME ) { if ( ua_stkvar2(op, op.addr, STKVAR_VALID_SIZE) ) { op_stkvar(cmd.ea, op.n); } } } break; case o_phrase: /* create stack variables if required */ if ( op.specflag1 == fRI && may_create_stkvars() && !isDefArg(uFlag, op.n) ) { func_t *pfn = get_func(cmd.ea); if ( pfn != NULL && (op.reg == rFP || op.reg == rSP) && pfn->flags & FUNC_FRAME ) { if ( ua_stkvar2(op, 0, STKVAR_VALID_SIZE) ) { op_stkvar(cmd.ea, op.n); } } } break; // Phrase - register - void : do nothing case o_reg: case o_void: break; // Others types should never be called default: interr2("handle_operand(): unknown type %d", op.type); break; } }