Files
sigmaker-ida/idasdk76/module/tms320c54/tms320c54.hpp
2021-10-31 21:20:46 +02:00

244 lines
5.9 KiB
C++

/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-99 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* E-mail: ig@datarescue.com
*
*
*/
#ifndef _TMS320C54_HPP
#define _TMS320C54_HPP
#include "../idaidp.hpp"
#include <diskio.hpp>
#include "ins.hpp"
#include "../iohandler.hpp"
// #define TMS320C54_NO_NAME_NO_REF
//------------------------------------------------------------------
#ifdef _MSC_VER
#define ENUM8BIT : uint8
#else
#define ENUM8BIT
#endif
enum regnum_t ENUM8BIT
{
PC, // program counter
A, // accumulator
B, // accumulator
// flags
ASM, // 5-bit accumulator shift mode field in ST1
ARP, // auxiliary register pointer
TS, // shift value (bits 5-0 of T)
OVB,
OVA,
C,
TC,
CMPT,
FRCT,
C16,
SXM,
OVM,
INTM,
HM,
XF,
BRAF,
// CPU memory mapped registers
IMR,
IFR,
ST0,
ST1,
AL,
AH,
AG,
BL,
BH,
BG,
T, // temporary register
TRN, // transition register
AR0,
AR1,
AR2,
AR3,
AR4,
AR5,
AR6,
AR7,
SP, // stack pointer
BK,
BRC,
RSA,
REA,
PMST,
// segment registers
XPC, // program counter extension register
CPL, // compiler mode
DP, // data page pointer
rVcs, rVds, // virtual registers for code and data segments
rnone = 0xFF, // no register
};
//------------------------------------------------------------------
// specific condition codes
#define COND_A 0x0
#define COND_B 0x8
#define COND_GEQ 0x2
#define COND_LT 0x3
#define COND_NEQ 0x4
#define COND_EQ 0x5
#define COND_GT 0x6
#define COND_LEQ 0x7
#define COND4_AGEQ (COND_A | COND_GEQ)
#define COND4_ALT (COND_A | COND_LT)
#define COND4_ANEQ (COND_A | COND_NEQ)
#define COND4_AEQ (COND_A | COND_EQ)
#define COND4_AGT (COND_A | COND_GT)
#define COND4_ALEQ (COND_A | COND_LEQ)
#define COND4_BGEQ (COND_B | COND_GEQ)
#define COND4_BLT (COND_B | COND_LT)
#define COND4_BNEQ (COND_B | COND_NEQ)
#define COND4_BEQ (COND_B | COND_EQ)
#define COND4_BGT (COND_B | COND_GT)
#define COND4_BLEQ (COND_B | COND_LEQ)
#define COND8_FROM_COND4 0x40
#define COND8_UNC 0x00
#define COND8_NBIO 0x02
#define COND8_BIO 0x03
#define COND8_NC 0x08
#define COND8_C 0x0C
#define COND8_NTC 0x20
#define COND8_TC 0x30
#define COND8_AGEQ (COND8_FROM_COND4 | COND4_AGEQ)
#define COND8_ALT (COND8_FROM_COND4 | COND4_ALT)
#define COND8_ANEQ (COND8_FROM_COND4 | COND4_ANEQ)
#define COND8_AEQ (COND8_FROM_COND4 | COND4_AEQ)
#define COND8_AGT (COND8_FROM_COND4 | COND4_AGT)
#define COND8_ALEQ (COND8_FROM_COND4 | COND4_ALEQ)
#define COND8_ANOV 0x60
#define COND8_AOV 0x70
#define COND8_BGEQ (COND8_FROM_COND4 | COND4_BGEQ)
#define COND8_BLT (COND8_FROM_COND4 | COND4_BLT)
#define COND8_BNEQ (COND8_FROM_COND4 | COND4_BNEQ)
#define COND8_BEQ (COND8_FROM_COND4 | COND4_BEQ)
#define COND8_BGT (COND8_FROM_COND4 | COND4_BGT)
#define COND8_BLEQ (COND8_FROM_COND4 | COND4_BLEQ)
#define COND8_BNOV (COND_B | COND8_ANOV)
#define COND8_BOV (COND_B | COND8_AOV)
//------------------------------------------------------------------
// specific processor records
#define o_bit o_idpspec0
#define o_cond8 o_idpspec1
#define o_cond2 o_idpspec2
#define o_local o_idpspec3
#define o_mmr o_idpspec4
#define o_farmem o_idpspec5
#define Op4_type auxpref_u8[0]
#define Op4_value auxpref_u8[1]
#define IsParallel segpref
// != 0 => MOD = IndirectAddressingMOD-1
#define IndirectAddressingMOD specflag1
#define ABSOLUTE_INDIRECT_ADRESSING 0xF // special "indirect" adressing
// (in fact absolute adressing)
#define Signed specflag1
#define NoCardinal specflag2
#define IOimm specflag3
//------------------------------------------------------------------
// processor types
typedef uchar proctype_t;
const proctype_t TMS320C54 = 0;
#define TMS320C54_IO 0x0001 // use I/O definitions
#define TMS320C54_MMR 0x0002 // use memory mapped registers
//------------------------------------------------------------------
const char *const cfgname = "tms320c54.cfg";
struct tms320c54_iohandler_t : public iohandler_t
{
tms320c54_iohandler_t(netnode &nn) : iohandler_t(nn) {}
void get_cfg_filename(char *buf, size_t bufsize) override
{
qstrncpy(buf, cfgname, bufsize);
}
};
struct tms320c54_t : public procmod_t
{
netnode helper;
tms320c54_iohandler_t ioh = tms320c54_iohandler_t(helper);
ea_t dataseg;
ushort idpflags = TMS320C54_IO|TMS320C54_MMR;
proctype_t ptype = TMS320C54;
bool flow = false;
virtual ssize_t idaapi on_event(ssize_t msgid, va_list va) override;
const char *find_sym(ea_t address);
void apply_symbols(void);
const char *idaapi set_idp_options(
const char *keyword,
int value_type,
const void * value,
bool idb_loaded);
int ana(insn_t *insn);
int emu(const insn_t &insn);
void handle_operand(const insn_t &insn, const op_t &x, flags_t F, bool use);
ea_t calc_data_mem(const insn_t &insn, ea_t ea, bool is_mem) const;
bool create_func_frame(func_t *pfn) const;
regnum_t get_mapped_register(ea_t ea) const;
void assumes(outctx_t &ctx);
void print_segment_register(outctx_t &ctx, int reg, sel_t value);
void segstart(outctx_t &ctx, segment_t *seg) const;
void footer(outctx_t &ctx) const;
void gen_stkvar_def(outctx_t &ctx, const member_t *mptr, sval_t v) const;
void save_idpflags() { helper.altset(-1, idpflags); }
void save_dataseg() { helper.altset(0, dataseg); }
void load_from_idb();
};
extern int data_id;
#define PROCMOD_NODE_NAME "$ tms320c54"
#define PROCMOD_NAME tms320c54
ea_t calc_code_mem(const insn_t &insn, ea_t ea, bool is_near = true);
const char *get_cond8(char value);
//------------------------------------------------------------------
void idaapi header(outctx_t &ctx);
void idaapi segend(outctx_t &ctx, segment_t *seg);
void idaapi data(ea_t ea);
int idaapi tms_get_frame_retsize(const func_t *pfn);
int idaapi is_align_insn(ea_t ea);
bool is_basic_block_end(const insn_t &insn); // 0-no, 2-yes
#endif // _TMS320C54_HPP