#ifndef _DSP56K_HPP #define _DSP56K_HPP #include "../idaidp.hpp" #include "ins.hpp" #include #include "../iohandler.hpp" #define PROCMOD_NAME dsp56k #define PROCMOD_NODE_NAME "$ " QSTRINGIZE(PROCMOD_NAME) //------------------------------------------------------------------ // DSP56K instruction may have many operands. We keep them separately // in the following structure. struct addargs_t { ea_t ea; int nargs; op_t args[4][2]; addargs_t() : ea(BADADDR), nargs(0) { memset(args, 0, sizeof(args)); } }; //------------------------------------------------------------------ struct dsp56k_iohandler_t : public iohandler_t { struct dsp56k_t ± dsp56k_iohandler_t(dsp56k_t &_pm, netnode &nn) : iohandler_t(nn), pm(_pm) {} virtual const char *iocallback(const ioports_t &iop, const char *line) override; }; struct dsp56k_t : public procmod_t { netnode helper; dsp56k_iohandler_t ioh = dsp56k_iohandler_t(*this, helper); ea_t xmem = BADADDR; ea_t ymem = BADADDR; op_t *op = nullptr; // current operand addargs_t aa; int xmemsize = 0x10000; int ymemsize = 0x10000; int procnum = -1; // 0 - dsp56k, 1 - dsp561xx, 2 - dsp563xx, 3 - dsp566xx bool flow = false; inline bool is561xx(void) const { return procnum == 1; } inline bool is563xx(void) const { return procnum == 2; } inline bool is566xx(void) const { return procnum == 3; } virtual ssize_t idaapi on_event(ssize_t msgid, va_list va) override; const ioport_t *find_port(ea_t address); void create_xmem_ymem(void); void select_device(const char *dname, int resp_info); const char *set_idp_options( const char *keyword, int /*value_type*/, const void * /*value*/, bool /*idb_loaded*/); ea_t calc_mem(const insn_t &insn, const op_t &x) const; ea_t AdditionalSegment(asize_t size, int offset, const char *name) const; void handle_operand( const insn_t &insn, const op_t &x, flags_t F, bool is_forced, bool isload); int emu(const insn_t &insn); void header(outctx_t &ctx); void set_cpu(int procno); bool D_EE(insn_t &insn, int value); bool D_DDDDD(insn_t &insn, int value); bool D_ff(const insn_t &insn, int value, int reg_bank); bool D_df(insn_t &insn, int value, int reg_bank); bool S_xi(insn_t &, int value); bool D_ximm(insn_t &insn, int /*value*/); bool S_ximm(insn_t &insn, int value); bool S_sssss(insn_t &, int value); bool S_ssss(insn_t &, int value); bool D_xih(insn_t &, int value); bool S_xih(insn_t &insn, int value); bool SD_d(insn_t &insn, int value); bool SS_JJJd(insn_t &insn, int value); bool SD_JJJd(insn_t &insn, int value); bool SD_Jd(insn_t &insn, int value); bool D_d(insn_t &insn, int value); bool S_S(insn_t &insn, int value); bool SD_JJd(insn_t &insn, int value); bool D_dddd(insn_t &insn, int value); bool D_ddddd(insn_t &insn, int value); bool S_ddddd(insn_t &insn, int value); bool D_LLL(insn_t &insn, int value); bool D_sss(insn_t &insn, int value); bool S_sss(insn_t &insn, int value); bool D_qqq(insn_t &insn, int value); bool S_qqq(insn_t &insn, int value); bool S_qq(insn_t &insn, int value); bool S_QQ(insn_t &insn, int value); bool S_gggd(insn_t &insn, int value); bool D_MMRRR(insn_t &, int value); bool S_MMRRR(insn_t &insn, int value); bool D_MMRRR_XY(insn_t &, int value); bool D_pppppp(insn_t &, int value); bool S_pppppp(insn_t &insn, int value); bool D_qqqqqq(insn_t &, int value); bool S_qqqqqq(insn_t &insn, int value); bool D_qXqqqqq(insn_t &insn, int value); bool D_DDDDDD(insn_t &insn, int value); bool S_DDDDDD(insn_t &insn, int value); bool D_DDDD(insn_t &insn, int value); bool D_RRR(insn_t &insn, int value); bool S_RRR(insn_t &insn, int value); void make_o_mem(insn_t &insn); bool D_mMMMRRR(insn_t &insn, int value); bool S_mMMMRRR(insn_t &insn, int value); bool D_aaaaaa(insn_t &insn, int value); bool S_aaaaaa(insn_t &insn, int value); bool D_MMMRRR(insn_t &insn, int value); bool S_MMMRRR(insn_t &insn, int value); bool P_type(insn_t &, int); bool AAE(insn_t &insn, int); bool D_PC_dispL(insn_t &insn, int value); bool S_PC_dispL(insn_t &insn, int value); bool D_PC_dispS(insn_t &insn, int value); bool D_PC_RRR(insn_t &, int value); bool D_RRR_dispL(insn_t &insn, int value); bool D_RRR_dispS(insn_t &, int value); bool S_RR_dispS(insn_t &, int value); bool AA(insn_t &, int value); bool D_F(insn_t &insn, int value); bool S_F(insn_t &insn, int value); bool CCCC(insn_t &insn, int value); bool s(insn_t &insn, int value); bool ss(insn_t &insn, int value); bool SD_IIII(insn_t &insn, int value); bool D_zRR(insn_t &, int value); bool D_mRR(insn_t &, int value); bool D_RRm(insn_t &insn, int value); bool D_RR11m(insn_t &insn, int value); bool D_MMRR(insn_t &, int value); bool S_MMRR(insn_t &insn, int value); bool D_RR0MM(insn_t &insn, int value); bool D_qRR(insn_t &, int value); bool D_HHH(insn_t &, int value); bool D_HH(insn_t &, int value); bool SD_mWRRHHH(insn_t &insn, int value); bool S_FJJJ(insn_t &insn, int value); bool S_QQQ(insn_t &, int value); bool S_QQ2(insn_t &, int value); bool S_QQQQ(insn_t &, int value); bool S_Fh0h(insn_t &insn, int value); bool S_uFuuu_add(insn_t &insn, int value); bool S_uFuuu_sub(insn_t &insn, int value); bool D_RR(insn_t &insn, int value); bool D_NN(insn_t &insn, int value); bool DB_RR(insn_t &, int value); bool D_PC_RR(insn_t &, int value); bool DX_RR(insn_t &insn, int value); bool S_RR(insn_t &insn, int value); bool m_A_B(insn_t &, int /*value*/); bool IF(insn_t &, int /*value*/); bool IFU(insn_t &, int /*value*/); bool S_i(insn_t &insn, int value); bool SD_TT(insn_t &insn, int value); bool S_BBBiiiiiiii(insn_t &, int value); bool D_Pppppp(insn_t &insn, int value); bool D_ppppp(insn_t &insn, int value); bool D_aaaaa(insn_t &insn, int value); bool S_DDDDD(insn_t &insn, int value); bool D_xi(insn_t &, int value); bool D_xi16(insn_t &, int value); bool D_xi_adr_16(insn_t &insn, int value); bool D_DD(insn_t &insn, int value); bool S_DD(insn_t &insn, int value); bool D_Z(insn_t &, int value); bool D_t(insn_t &insn, int value); bool SD_F00J(insn_t &insn, int value); bool D_PC_eeeeee(insn_t &insn, int value); bool D_PC_aaaaaaaa(insn_t &insn, int value); bool D_BBBBBBBB(insn_t &, int value); bool is_valid_insn(ushort proc); bool disassemble_parallel_move(insn_t &insn, int i, int value); bool decode_XY_R_mem(insn_t &insn, int value); bool recognize_parallel_move_class1(insn_t &insn, int value); bool recognize_parallel_move_class1_3(insn_t &insn, int value); bool recognize_parallel_move_class2(insn_t &insn, int value); bool recognize_parallel_move_class3(insn_t &insn, int value); bool is_parallel_move(insn_t &insn, int value); bool use_table( insn_t &insn, const struct opcode_t *table, uint32 code, int entry, int start, int end); int ana_61(insn_t &insn); int ana_6x(insn_t &insn); int ana(insn_t *_insn); bool X_type(insn_t &, int); bool Y_type(insn_t &, int); bool mem_type(insn_t &, int value); bool space(insn_t &insn, int); bool sign(insn_t &, int value); int is_sane_insn(const insn_t &insn, int /*nocrefs*/) const; void fill_additional_args(const insn_t &insn) const; void switch_to_additional_args(insn_t &); inline void opreg(insn_t &, int reg); void reset_ops(insn_t &insn); void add_near_ref(const insn_t &insn, const op_t &x, ea_t ea); void segstart(outctx_t &ctx, segment_t *seg) const; void segend(outctx_t &ctx, segment_t *seg) const; void footer(outctx_t &ctx) const; void load_from_idb(); }; extern int data_id; //------------------------------------------------------------------ #define aux_cc 0x000F // condition code #define aux_su 0x0003 // sign/unsing code #define phtype specflag1 // o_phrase: phrase type // 0 (Rn)-n // 1 (Rn)+Nn // 2 (Rn)- // 3 (Rn)+ // 4 (Rn) // 5 (Rn+Nn) // 7 -(Rn) // 8 $+Rn // 9 (a1) // 10 (b1) #define amode specflag2 // addressing mode #define amode_ioshort 0x01 // << #define amode_short 0x02 // < #define amode_long 0x04 // > #define amode_neg 0x08 // - #define amode_x 0x10 // X: #define amode_y 0x20 // Y: #define amode_p 0x40 // P: #define amode_l 0x80 // L: #define imode specflag3 // IF mode #define imode_if 0x01 // IFcc #define imode_ifu 0x02 // IFUcc #define o_iftype o_idpspec0 // IF type #define o_vsltype o_idpspec1 // VSL 2-nd operand type //------------------------------------------------------------------ #define UAS_GNU 0x0001 // GNU assembler //------------------------------------------------------------------ enum RegNo ENUM_SIZE(uint16) { // data arithmetic logic unit X, X0, X1, Y, Y0, Y1, // accumulator registers A, A0, A1, A2, B, B0, B1, B2, AB, // a1:b1 BA, // b1:a1 A10, // a1:a0 B10, // b1:b0 // address generation unit (AGU) R0, R1, R2, R3, R4, R5, R6, R7, // pointers N0, N1, N2, N3, N4, N5, N6, N7, // offsets M0, M1, M2, M3, M4, M5, M6, M7, // modifiers // Program Control Unit PC, // Program Counter (16 Bits) MR, // Mode Register (8 Bits) CCR, // Condition Code Register (8 Bits) SR, // Status Register (MR:CCR, 16 Bits) OMR, // Operating Mode Register (8 Bits) LA, // Hardware Loop Address Register (16 Bits) LC, // Hardware Loop Counter (16 Bits) SP, // System Stack Pointer (6 Bits) SS, // System Stack RAM (15X32 Bits) SSH, // Upper 16 Bits of the Contents of the Current Top of Stack SSL, // Lower 16 Bits of the Contents of the Current Top of Stack SZ, // Stack Size register SC, // Stack Counter register EP, // Extension Pointer register VBA, // Vector Base Address Register vCS, vDS, // virtual registers for code and data segments }; //------------------------------------------------------------------ // condition codes enum cc_t { cc_CC, // carry clear (higher or same) C=0 cc_GE, // greater than or equal N xor V=0 cc_NE, // not equal Z=0 cc_PL, // plus N=0 cc_NN, // not normalized Z+(^U&^E)=0 cc_EC, // extension clear E=0 cc_LC, // limit clear L=0 cc_GT, // greater than Z+(N xor V)=0 cc_CS, // carry set (lower) C=1 cc_LT, // less than N xor V=1 cc_EQ, // equal Z=1 cc_MI, // minus N=1 cc_NR, // normalized Z+(^U&^E)=1 cc_ES, // extension set E=1 cc_LS, // limit set L=1 cc_LE, // less than or equal Z+(N xor V)=1 }; //------------------------------------------------------------------ enum PMoveClass { cl_0 = 0, // No Parallel move cl_1, // X Memory Data Move (common) cl_1_3, // X Memory Data Move with short displacement cl_2, // Dual X Memory Data Read cl_3, // X Memory Data Write and Register Data Move }; //------------------------------------------------------------------ // signed/unsigned codes enum su_t { s_SS, // signed * signed s_SU, // signed * unsigned s_UU, // unsigned * unsigned }; // Make sure that the 'aa' structure is up to date. void fill_additional_args(const insn_t &insn); //------------------------------------------------------------------ void interr(const insn_t *insn, const char *module); int idaapi ana(insn_t *insn); int idaapi emu(const insn_t &insn); int idaapi is_align_insn(ea_t ea); int idaapi is_sp_based(const insn_t &insn, const op_t &x); #endif // _DSP56K_HPP