//---------------------------------------------------------------------- static void apply_symbols(void) { free_mappings(); if ( dataseg != BADADDR ) { for ( int i=0; i < numports; i++ ) { ea_t ea = calc_data_mem(ports[i].address); segment_t *s = getseg(ea); if ( s == NULL || s->type != SEG_IMEM ) continue; doByte(ea, 1); const char *name = ports[i].name; if ( !set_name(ea, name, SN_NOWARN) ) set_cmt(ea, name, 0); } ea_t ea = dataseg; segment_t *d = getseg(dataseg); if ( d != NULL ) { ea_t dataend = d->endEA; while ( 1 ) { ea = next_unknown(ea, dataend); if ( ea == BADADDR ) break; ea_t end = nextthat(ea, dataend, f_isHead, NULL); if ( end == BADADDR ) end = dataend; doByte(ea, end-ea); } create_mappings(); } } }
//---------------------------------------------------------------------- bool idaapi outop(op_t &x) { ea_t ea; if ( x.type == o_imm ) out_symbol('#'); char buf[MAXSTR]; switch ( x.type ) { case o_void: return 0; case o_imm: OutValue(x, OOFS_IFSIGN|OOFW_IMM); break; case o_reg: outreg(x.reg); break; case o_mem: // no break; case o_near: { ea = calc_mem(x); if ( ea == cmd.ea+cmd.size ) out_ip_rel(cmd.size); else if ( !out_name_expr(x, ea, x.addr) ) out_bad_address(x.addr); } break; case o_phrase: { qsnprintf(buf, sizeof(buf), "%%%c%" FMT_EA "x", 'a' + x.reg, x.value); ea = calc_data_mem(x, as + x.reg); if ( ( ea != BADADDR ) && ( ( x.reg != SR3 ) || ( x.value < 6 ) ) ) { out_line(buf, COLOR_AUTOCMT); out_symbol(' '); out_address(ea, x); } else out_line(buf, COLOR_REG); } break; default: interr("out"); break; } return 1; }
//---------------------------------------------------------------------- // tris PORTn (or movwf TRISn) static bool is_load_tris_reg(void) { ea_t addr; const char *key; switch ( cmd.itype ) { case PIC_tris: addr = cmd.Op1.value; key = "port"; break; case PIC_movwf: addr = cmd.Op1.addr; key = "tris"; break; default: return false; } char nbuf[MAXSTR]; char *name = get_name(BADADDR, calc_data_mem(addr), nbuf, sizeof(nbuf)); return name != NULL && strnicmp(name, key, 4) == 0; }
//---------------------------------------------------------------------- bool idaapi outop(op_t &x) { ea_t ea; switch ( x.type ) { case o_void: return 0; case o_reg: out_register(ph.regNames[x.reg]); break; case o_near: case o_far: out_address(calc_code_mem(x.addr, x.type == o_near), x, false, false); break; case o_imm: { const char *name = NULL; if ( idpflags & TMS320C54_IO && x.IOimm ) name = find_sym(x.value); if ( !x.NoCardinal ) out_symbol('#'); if ( name != NULL ) { out_line(name, COLOR_IMPNAME); } else { if ( !x.Signed ) OutValue(x, OOFW_IMM); else OutValue(x, OOFS_IFSIGN|OOF_SIGNED|OOF_NUMBER|OOFW_IMM); } break; } case o_local: OutValue(x, OOFW_IMM|OOF_ADDR); break; case o_mmr: case o_mem: case o_farmem: if ( x.IndirectAddressingMOD == ABSOLUTE_INDIRECT_ADRESSING ) { out_symbol('*'); out_symbol('('); } ea = calc_data_mem(x.addr, x.type == o_mem); if ( ea != BADADDR ) out_address(ea, x, true, x.IndirectAddressingMOD != ABSOLUTE_INDIRECT_ADRESSING); // no '@' if absolute "indirect" adressing else OutValue(x, OOFW_IMM|OOF_ADDR); if ( x.IndirectAddressingMOD == ABSOLUTE_INDIRECT_ADRESSING ) out_symbol(')'); break; case o_displ: // Indirect addressing mode { const char *reg = ph.regNames[x.reg]; char buf[8]; switch ( x.IndirectAddressingMOD ) { case 0: qsnprintf(buf, sizeof(buf), "*%s",reg); out_register(buf); break; case 1: qsnprintf(buf, sizeof(buf), "*%s-",reg); out_register(buf); break; case 2: qsnprintf(buf, sizeof(buf), "*%s+",reg); out_register(buf); break; case 3: qsnprintf(buf, sizeof(buf), "*+%s",reg); out_register(buf); break; case 4: qsnprintf(buf, sizeof(buf), "*%s-0B",reg); out_register(buf); break; case 5: qsnprintf(buf, sizeof(buf), "*%s-0",reg); out_register(buf); break; case 6: qsnprintf(buf, sizeof(buf), "*%s+0",reg); out_register(buf); break; case 7: qsnprintf(buf, sizeof(buf), "*%s+0B",reg); out_register(buf); break; case 8: qsnprintf(buf, sizeof(buf), "*%s-%%",reg); out_register(buf); break; case 9: qsnprintf(buf, sizeof(buf), "*%s-0%%",reg); out_register(buf); break; case 0xA: qsnprintf(buf, sizeof(buf), "*%s+%%",reg); out_register(buf); break; case 0xB: qsnprintf(buf, sizeof(buf), "*%s+0%%",reg); out_register(buf); break; case 0xC: qsnprintf(buf, sizeof(buf), "*%s(",reg); out_register(buf); OutValue(x, OOF_ADDR|OOF_SIGNED|OOFW_16); out_symbol(')'); break; case 0xD: qsnprintf(buf, sizeof(buf), "*+%s(",reg); out_register(buf); OutValue(x, OOF_ADDR|OOF_SIGNED|OOFW_16); out_symbol(')'); break; case 0xE: qsnprintf(buf, sizeof(buf), "*+%s(",reg); out_register(buf); OutValue(x, OOF_ADDR|OOF_SIGNED|OOFW_16); out_symbol(')'); out_symbol('%'); break; // this special adressing mode is now defined as o_farmem ! // case ABSOLUTE_INDIRECT_ADRESSING: // out_symbol('*'); // out_symbol('('); // OutValue(x, OOF_ADDR|OOF_SIGNED|OOFW_16); // out_symbol(')'); // break; default: error("interr: out: o_displ"); } break; } case o_bit: { if ( !x.NoCardinal ) out_symbol('#'); char buf[20]; qsnprintf(buf, sizeof(buf), "%d", int(x.value)); out_line(buf,COLOR_REG); break; } case o_cond8: out_cond8((uchar)x.value); break; case o_cond2: { const char *cond = ""; switch ( x.value ) { case 0: cond = "eq"; break; case 1: cond = "lt"; break; case 2: cond = "gt"; break; case 3: cond = "neq"; break; default: warning("interr: out 2-bit condition"); } out_line(cond, COLOR_REG); break; } default: error("interr: out"); break; } return 1; }
//---------------------------------------------------------------------- static void out_address(op_t &op) { ea_t ea; if (op.type == o_near) ea = calc_code_mem(op.addr); else if (op.type == o_mem) ea = calc_data_mem(op); else if (op.type == o_io) ea = calc_io_mem(op); int reg = -1; if (op.type == o_mem) reg = get_mapped_register(ea); // print begin of the modifier switch(op.tms_modifier) { case TMS_MODIFIER_NULL: break; case TMS_MODIFIER_DMA: if ((int)reg == -1) out_symbol('@'); break; case TMS_MODIFIER_ABS16: case TMS_MODIFIER_PTR: out_symbol('*'); if (op.tms_modifier == TMS_MODIFIER_ABS16) out_line("abs16", COLOR_SYMBOL); out_line("(#", COLOR_SYMBOL); break; case TMS_MODIFIER_MMAP: out_line("mmap(@", COLOR_SYMBOL); break; case TMS_MODIFIER_PORT: out_line("port(#", COLOR_SYMBOL); break; case TMS_MODIFIER_PORT_AT: out_line("port(@", COLOR_SYMBOL); break; default: error("interr: out: o_address: modifier_begin"); } if (op.type != o_io) { if (int(reg) != -1) // memory mapped register out_register(ph.regNames[reg]); else { #ifndef TMS320C55_NO_NAME_NO_REF if ( !out_name_expr(op, ea, ea) ) #endif { out_tagon(COLOR_ERROR); if (op.type != o_mem) OutLong(op.addr, 16); else OutLong(op.addr, 16); out_tagoff(COLOR_ERROR); QueueMark(Q_noName, cmd.ea); } } } else // IO address { if (ea != BADADDR) { const char *name = NULL; if (idpflags & TMS320C55_IO) name = find_sym(ea); if (name) out_line(name, COLOR_IMPNAME); else OutLong(ea, 16); } else { out_tagon(COLOR_ERROR); OutLong(op.addr, 16); out_tagoff(COLOR_ERROR); } } // print end of the modifier switch(op.tms_modifier) { case TMS_MODIFIER_NULL: case TMS_MODIFIER_DMA: break; case TMS_MODIFIER_ABS16: case TMS_MODIFIER_PTR: case TMS_MODIFIER_MMAP: case TMS_MODIFIER_PORT: case TMS_MODIFIER_PORT_AT: out_symbol(')'); break; default: error("interr: out: o_address: modifier_begin"); } }
//---------------------------------------------------------------------- static void process_operand(op_t &x, int use) { switch ( x.type ) { case o_reg: return; case o_near: { if (cmd.itype != TMS320C3X_RPTB ) { cref_t ftype = fl_JN; ea_t ea = calc_code_mem(x); if ( InstrIsSet(cmd.itype, CF_CALL) ) { if ( !func_does_return(ea) ) flow = false; ftype = fl_CN; } ua_add_cref(x.offb, ea, ftype); } else // evaluate RPTB loops as dref ua_add_dref(x.offb, calc_code_mem(x), dr_I); } break; case o_imm: if ( !use ) error("interr: emu"); process_imm(x); if ( isOff(uFlag, x.n) ) ua_add_off_drefs2(x, dr_O, 0); break; case o_mem: { ea_t ea = calc_data_mem(x); if (ea != BADADDR) { ua_add_dref(x.offb, ea, use ? dr_R : dr_W); ua_dodata2(x.offb, ea, x.dtyp); if ( !use ) doVar(ea); } } break; case o_phrase: break; case o_displ: doImmd(cmd.ea); break; default: if ( x.type == o_void ) { if ( cmd.itype == TMS320C3X_ABSF ) break; if ( cmd.itype == TMS320C3X_ABSI ) break; } warning("interr: emu2 address:%a operand:%d type:%d", cmd.ea, x.n, x.type); } }
//---------------------------------------------------------------------- static void process_operand(op_t &x, int use) { switch ( x.type ) { case o_bit: case o_reg: case o_cond8: case o_cond2: return; case o_near: case o_far: { if (cmd.itype != TMS320C54_rptb && cmd.itype != TMS320C54_rptbd) { cref_t ftype = fl_JN; ea_t ea = calc_code_mem(x.addr, x.type == o_near); if ( InstrIsSet(cmd.itype, CF_CALL) ) { if ( !func_does_return(ea) ) flow = false; ftype = fl_CN; } #ifndef TMS320C54_NO_NAME_NO_REF if ( x.dtyp == dt_byte ) ua_add_dref(x.offb, ea, dr_R); else ua_add_cref(x.offb, ea, ftype); #endif } #ifndef TMS320C54_NO_NAME_NO_REF else // evaluate RPTB[D] loops as dref ua_add_dref(x.offb, calc_code_mem(x.addr), dr_I); #endif } break; case o_imm: if ( !use ) error("interr: emu"); process_imm(x); #ifndef TMS320C54_NO_NAME_NO_REF if ( isOff(uFlag, x.n) ) ua_add_off_drefs2(x, dr_O, x.Signed ? OOF_SIGNED : 0); #endif break; case o_mem: case o_farmem: case o_mmr: { ea_t ea = calc_data_mem(x.addr, x.type == o_mem); if (ea != BADADDR) { #ifndef TMS320C54_NO_NAME_NO_REF ua_add_dref(x.offb, ea, use ? dr_R : dr_W); #endif ua_dodata2(x.offb, ea, x.dtyp); if ( !use ) doVar(ea); } } break; case o_local: // local variables if ( may_create_stkvars() && (get_func(cmd.ea) != NULL) && ua_stkvar2(x, x.addr, STKVAR_VALID_SIZE) ) { op_stkvar(cmd.ea, x.n); } break; case o_displ: doImmd(cmd.ea); break; default: warning("interr: emu2 address:%a operand:%d type:%d", cmd.ea, x.n, x.type); } }
//---------------------------------------------------------------------- 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); } }