update to ida 7.6, add builds

This commit is contained in:
2021-10-31 21:20:46 +02:00
parent e0e0f2be99
commit b1809fe2d9
1408 changed files with 279193 additions and 302468 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,397 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-99 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* E-mail: ig@datarescue.com
*
*
*/
#include "tms320c55.hpp"
#include <segregs.hpp>
#include <frame.hpp>
//------------------------------------------------------------------------
ea_t calc_data_mem(const insn_t &insn, const op_t &op)
{
ea_t addr = op.addr;
sel_t dph = 0;
if ( op.tms_regH == DPH )
{
dph = get_sreg(to_ea(insn.cs, insn.ip), DPH);
if ( dph == BADSEL )
return BADSEL;
addr &= 0xFFFF;
}
sel_t dp = 0;
if ( op.tms_regP == DP )
{
dp = get_sreg(to_ea(insn.cs, insn.ip), DP);
if ( dp == BADSEL )
return BADSEL;
addr &= 0xFFFF;
}
return (((dph & 0x7F) << 16) | (dp + addr)) << 1;
}
//----------------------------------------------------------------------
ea_t calc_io_mem(const insn_t &insn, const op_t &op)
{
ea_t addr = op.addr;
sel_t pdp = 0;
if ( op.tms_regP == PDP )
{
pdp = get_sreg(to_ea(insn.cs, insn.ip), PDP);
if ( pdp == BADSEL )
return BADSEL;
addr &= 0x7F;
}
ea_t ea = ((pdp & 0x1FF) << 7) | addr;
return to_ea(insn.cs, ea);
}
//----------------------------------------------------------------------
int tms320c55_t::get_mapped_register(ea_t ea) const
{
ea = ea >> 1;
if ( idpflags & TMS320C55_MMR )
{
static const int registers[] =
{
IER0, IFR0, ST0_55, ST1_55, ST3_55, -1, ST0, ST1,
AC0L, AC0H, AC0G, AC1L, AC1H, AC1G, T3, TRN0,
AR0, AR1, AR2, AR3, AR4, AR5, AR6, AR7,
SP, BK03, BRC0, RSA0L, REA0L, PMST, XPC, -1,
T0, T1, T2, T3, AC2L, AC2H, AC2G, CDP,
AC3L, AC3H, AC3H, DPH, -1, -1, DP, PDP,
BK47, BKC, BSA01, BSA23, BSA45, BSA67, BSAC, -1,
TRN1, BRC1, BRS1, CSR, RSA0H, RSA0L, REA0H, REA0L,
RSA1H, RSA1L, REA1H, REA1L, RPTC, IER1, IFR1, DBIER0,
DBIER1, IVPD, IVPH, ST2_55, SSP, SP, SPH, CDPH
};
if ( ea <= 0x4F )
return registers[int(ea)];
}
return -1;
}
//----------------------------------------------------------------------
static void process_imm(const insn_t &insn, const op_t &x, flags_t F)
{
set_immd(insn.ea); // assign contextual menu for conversions
if ( is_defarg(F, x.n) )
return; // if already defined by user
switch ( insn.itype )
{
case TMS320C55_rptcc:
case TMS320C55_rpt:
case TMS320C55_aadd:
case TMS320C55_amov:
case TMS320C55_asub:
case TMS320C55_mov2:
case TMS320C55_and3:
case TMS320C55_or3:
case TMS320C55_xor2:
case TMS320C55_xor3:
case TMS320C55_mpyk2:
case TMS320C55_mpyk3:
case TMS320C55_mpykr2:
case TMS320C55_mpykr3:
case TMS320C55_mack3:
case TMS320C55_mack4:
case TMS320C55_mackr3:
case TMS320C55_mackr4:
case TMS320C55_bclr2:
case TMS320C55_bset2:
case TMS320C55_rptadd:
case TMS320C55_rptsub:
case TMS320C55_add2:
case TMS320C55_add3:
case TMS320C55_sub2:
case TMS320C55_sub3:
case TMS320C55_and2:
case TMS320C55_or2:
case TMS320C55_intr:
case TMS320C55_trap:
case TMS320C55_btst:
op_num(insn.ea, x.n);
}
}
//----------------------------------------------------------------------
void tms320c55_t::handle_operand(const insn_t &insn, const op_t &op, flags_t F, bool use)
{
switch ( op.type )
{
case o_cond:
case o_shift:
case o_io:
return;
case o_reg:
// analyze immediate values
if ( op.tms_modifier == TMS_MODIFIER_REG_OFFSET
|| op.tms_modifier == TMS_MODIFIER_P_REG_OFFSET
|| op.tms_modifier == TMS_MODIFIER_REG_SHORT_OFFSET )
{
set_immd(insn.ea);
}
// analyze local vars
if ( op.reg == SP && op.tms_modifier == TMS_MODIFIER_REG_OFFSET )
{
if ( may_create_stkvars()
&& get_func(insn.ea) != NULL
&& insn.create_stkvar(op, 2 * op.value, STKVAR_VALID_SIZE) )
{
op_stkvar(insn.ea, op.n);
}
}
// DP, DPH and PDP unknown changes
if ( !use )
{
if ( op.reg == DP || op.reg == DPH || op.reg == PDP )
split_sreg_range(get_item_end(insn.ea), op.reg, BADSEL, SR_auto);
}
break;
case o_relop: // analyze immediate value
if ( op.tms_relop_type == TMS_RELOP_IMM )
set_immd(insn.ea);
break;
case o_near:
{
if ( insn.itype != TMS320C55_rptb && insn.itype != TMS320C55_rptblocal )
{
cref_t ftype = fl_JN;
ea_t ea = calc_code_mem(insn, op.addr);
if ( has_insn_feature(insn.itype, CF_CALL) )
{
if ( !func_does_return(ea) )
flow = false;
ftype = fl_CN;
}
#ifndef TMS320C55_NO_NAME_NO_REF
insn.add_cref(ea, op.offb, ftype);
#endif
}
#ifndef TMS320C55_NO_NAME_NO_REF
else // evaluate RPTB loops as dref
insn.add_dref(calc_code_mem(insn, op.addr), op.offb, dr_I);
#endif
break;
}
case o_imm:
QASSERT(10114, use);
process_imm(insn, op, F);
#ifndef TMS320C55_NO_NAME_NO_REF
if ( op_adds_xrefs(F, op.n) )
insn.add_off_drefs(op, dr_O, op.tms_signed ? OOF_SIGNED : 0);
#endif
break;
case o_mem:
{
ea_t ea = calc_data_mem(insn, op);
if ( ea != BADADDR )
{
#ifndef TMS320C55_NO_NAME_NO_REF
insn.add_dref(ea, op.offb, use ? dr_R : dr_W);
#endif
insn.create_op_data(ea, op);
if ( !use )
{
int reg = get_mapped_register(ea);
if ( reg == DP || reg == DPH || reg == PDP )
split_sreg_range(get_item_end(insn.ea), reg, BADSEL, SR_auto);
}
}
}
break;
default:
warning("interr: emu2 address:%a operand:%d type:%d", insn.ea, op.n, op.type);
}
}
//----------------------------------------------------------------------
static bool add_stkpnt(const insn_t &insn, sval_t delta)
{
func_t *pfn = get_func(insn.ea);
if ( pfn == NULL )
return false;
return add_auto_stkpnt(pfn, insn.ea+insn.size, delta);
}
//----------------------------------------------------------------------
static void trace_sp(const insn_t &insn)
{
switch ( insn.itype )
{
case TMS320C55_pop1: // pop dst; pop dbl(ACx); pop Smem; pop dbl(Lmem)
add_stkpnt(insn, (insn.Op1.tms_operator1 & TMS_OPERATOR_DBL) ? 4:2);
break;
case TMS320C55_pop2: // pop dst1, dst2; pop dst, Smem
add_stkpnt(insn, 4);
break;
case TMS320C55_psh1: // psh dst; psh dbl(ACx); psh Smem; psh dbl(Lmem)
add_stkpnt(insn, (insn.Op1.tms_operator1 & TMS_OPERATOR_DBL) ? -4:-2);
break;
case TMS320C55_psh2: // psh src1, src2; psh src, Smem
add_stkpnt(insn, -4);
break;
case TMS320C55_popboth:
case TMS320C55_ret:
add_stkpnt(insn, 2);
break;
case TMS320C55_pshboth:
add_stkpnt(insn, -2);
break;
case TMS320C55_reti:
add_stkpnt(insn, 6);
break;
case TMS320C55_aadd:
if ( insn.Op2.type == o_reg && insn.Op2.reg == SP && insn.Op1.type == o_imm )
add_stkpnt(insn, 2 * insn.Op1.value);
break;
}
}
//----------------------------------------------------------------------
int tms320c55_t::emu(const insn_t &insn)
{
uint32 feature = insn.get_canon_feature(ph);
flow = (feature & CF_STOP) == 0;
flags_t F = get_flags(insn.ea);
if ( feature & CF_USE1 ) handle_operand(insn, insn.Op1, F, true);
if ( feature & CF_USE2 ) handle_operand(insn, insn.Op2, F, true);
if ( feature & CF_USE3 ) handle_operand(insn, insn.Op3, F, true);
if ( feature & CF_USE4 ) handle_operand(insn, insn.Op4, F, true);
if ( feature & CF_USE5 ) handle_operand(insn, insn.Op5, F, true);
if ( feature & CF_USE6 ) handle_operand(insn, insn.Op6, F, true);
if ( feature & CF_CHG1 ) handle_operand(insn, insn.Op1, F, false);
if ( feature & CF_CHG2 ) handle_operand(insn, insn.Op2, F, false);
if ( feature & CF_CHG3 ) handle_operand(insn, insn.Op3, F, false);
if ( feature & CF_CHG4 ) handle_operand(insn, insn.Op4, F, false);
if ( feature & CF_CHG5 ) handle_operand(insn, insn.Op5, F, false);
if ( feature & CF_CHG6 ) handle_operand(insn, insn.Op6, F, false);
// CPL and ARMS status flags changes
if ( (insn.itype == TMS320C55_bclr1 || insn.itype == TMS320C55_bset1)
&& insn.Op1.type == o_reg
&& (insn.Op1.reg == CPL || insn.Op1.reg == ARMS) )
{
int value = insn.itype == TMS320C55_bclr1 ? 0 : 1;
split_sreg_range(get_item_end(insn.ea), insn.Op1.reg, value, SR_auto);
}
// DP, DPH and PDP changes
if ( insn.itype == TMS320C55_mov2
&& insn.Op2.type == o_reg
&& insn.Op1.type == o_imm )
{
ea_t end = insn.ea + insn.size;
if ( insn.Op2.reg == DP )
split_sreg_range(end, DP, insn.Op1.value & 0xFFFF, SR_auto);
else if ( insn.Op2.reg == DPH )
split_sreg_range(end, DPH, insn.Op1.value & 0x7F, SR_auto);
else if ( insn.Op2.reg == PDP )
split_sreg_range(end, PDP, insn.Op1.value & 0x1FF, SR_auto);
}
// determine if the next instruction should be executed
if ( flow && segtype(insn.ea) == SEG_XTRN )
flow = false;
if ( flow )
add_cref(insn.ea, insn.ea+insn.size, fl_F);
if ( may_trace_sp() )
{
if ( !flow )
recalc_spd(insn.ea); // recalculate SP register for the next insn
else
trace_sp(insn);
}
return 1;
}
//----------------------------------------------------------------------
bool idaapi create_func_frame(func_t *pfn)
{
if ( pfn != NULL )
{
if ( pfn->frame == BADNODE )
{
insn_t insn;
ushort regsize = 0;
ea_t ea = pfn->start_ea;
while ( ea < pfn->end_ea ) // check for register pushs
{
decode_insn(&insn, ea);
ea += insn.size;
if ( insn.itype == TMS320C55_psh1 )
regsize += (insn.Op1.tms_operator1 & TMS_OPERATOR_DBL) ? 4 : 2;
else if ( insn.itype == TMS320C55_psh2 )
regsize += 4;
else if ( insn.itype == TMS320C55_pshboth )
regsize += 2;
else
break;
}
int localsize = 0;
while ( ea < pfn->end_ea ) // check for frame creation
{
if ( decode_insn(&insn, ea) < 1 )
break;
ea += insn.size;
if ( insn.itype == TMS320C55_aadd
&& insn.Op2.type == o_reg
&& insn.Op2.reg == SP
&& insn.Op1.type == o_imm )
{
localsize = int(2 * insn.Op1.value);
break;
}
}
add_frame(pfn, localsize, regsize, 0);
}
}
return 0;
}
//----------------------------------------------------------------------
int idaapi is_align_insn(ea_t ea)
{
insn_t insn;
if ( decode_insn(&insn, ea) < 1 )
return 0;
switch ( insn.itype )
{
case TMS320C55_nop:
case TMS320C55_nop_16:
break;
default:
return 0;
}
return insn.size;
}
//----------------------------------------------------------------------
bool idaapi can_have_type(const op_t &op)
{
switch ( op.type )
{
case o_io:
case o_reg:
case o_relop:
case o_imm:
return true;
}
return false;
}

View File

@@ -0,0 +1,362 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-99 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* E-mail: ig@datarescue.com
*
*
*/
#include "tms320c55.hpp"
const instruc_t Instructions[] =
{
{ "", 0 }, // Unknown Operation
// ARITHMETICAL OPERATIONS
{ "abdst", CF_CHG1|CF_CHG2|CF_CHG3|CF_CHG4 }, // Absolute Distance
{ "abs", CF_CHG1 }, // Absolute Value
{ "abs", CF_USE1|CF_CHG2 }, // Absolute Value
{ "add", CF_CHG1 }, // Addition
{ "add", CF_USE1|CF_CHG2 }, // Addition
{ "add", CF_USE1|CF_USE2|CF_CHG3 }, // Addition
{ "add", CF_USE1|CF_USE2|CF_USE3|CF_CHG4 }, // Addition
{ "addv", CF_CHG1 }, // Addition
{ "addv", CF_USE1|CF_CHG2 }, // Addition
{ "addrv", CF_CHG1 }, // Addition and Round
{ "addrv", CF_USE1|CF_CHG2 }, // Addition and Round
{ "maxdiff", CF_USE1|CF_USE2|CF_CHG3|CF_CHG4 }, // Compare and Select Maximum
{ "dmaxdiff", CF_USE1|CF_USE2|CF_CHG3|CF_CHG4|CF_CHG5 }, // Compare and Select 40-bit Maximum
{ "mindiff", CF_USE1|CF_USE2|CF_CHG3|CF_CHG4 }, // Compare and Select Minimum
{ "dmindiff", CF_USE1|CF_USE2|CF_CHG3|CF_CHG4|CF_CHG5 }, // Compare and Select 40-bit Minimum
{ "addsubcc", CF_USE1|CF_USE2|CF_USE3|CF_CHG4 }, // Conditional Add or Subtract
{ "addsubcc", CF_USE1|CF_USE2|CF_USE3|CF_USE4|CF_CHG5 }, // Conditional Add or Subtract
{ "addsub2cc", CF_USE1|CF_USE2|CF_USE3|CF_USE4|CF_USE5|CF_CHG6 }, // Conditional Add or Subtract
{ "sftcc", CF_CHG1|CF_CHG2 }, // Conditional Shift
{ "subc", CF_USE1|CF_CHG2 }, // Conditional Subtract
{ "subc", CF_USE1|CF_USE2|CF_CHG3 }, // Conditional Subtract
{ "addsub", CF_USE1|CF_USE2|CF_CHG3 }, // Paralleled Add - Subtract
{ "subadd", CF_USE1|CF_USE2|CF_CHG3 }, // Parallel Subtract - Add
// "add","sub"
{ "mpy\0mpy", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Two Parallel Multiply
{ "mpyr\0mpyr", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Two Parallel Multiply, and Round
{ "mpy40\0mpy40", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Two Parallel Multiply, on 40 bits
{ "mpyr40\0mpyr40", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Two Parallel Multiply, and Round on 40 bits
{ "mac\0mpy", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Parallel Multiply - Accumulate
{ "macr\0mpyr", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Parallel Multiply - Accumulate, and Round
{ "mac40\0mpy40", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Parallel Multiply - Accumulate, on 40 bits
{ "macr40\0mpyr40", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Parallel Multiply - Accumulate, and Round on 40 bits
{ "mas\0mpy", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Parallel Multiply - Subtract
{ "masr\0mpyr", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Parallel Multiply - Subtract, and Round
{ "mas40\0mpy40", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Parallel Multiply - Subtract, on 40 bits
{ "masr40\0mpyr40", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Parallel Multiply - Subtract, and Round on 40 bits
{ "amar\0mpy", CF_CHG1|CF_USE2|CF_USE3|CF_CHG4 }, // Parallel Modify Auxiliary Register - Multiply
{ "amar\0mpyr", CF_CHG1|CF_USE2|CF_USE3|CF_CHG4 }, // Parallel Modify Auxiliary Register - Multiply, and Round
{ "amar\0mpy40", CF_CHG1|CF_USE2|CF_USE3|CF_CHG4 }, // Parallel Modify Auxiliary Register - Multiply, on 40 bits
{ "amar\0mpyr40", CF_CHG1|CF_USE2|CF_USE3|CF_CHG4 }, // Parallel Modify Auxiliary Register - Multiply, and Round on 40 bits
{ "mac\0mac", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Two Parallel Multiply and Accumulate
{ "macr\0macr", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Two Parallel Multiply and Accumulate, and Round
{ "mac40\0mac40", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Two Parallel Multiply and Accumulate, on 40 bits
{ "macr40\0macr40", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Two Parallel Multiply and Accumulate, and Round on 40 bits
{ "mas\0mac", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Parallel Multiply and Subtract - Multiply and Accumulate
{ "masr\0macr", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Parallel Multiply and Subtract - Multiply and Accumulate, and Round
{ "mas40\0mac40", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Parallel Multiply and Subtract - Multiply and Accumulate, on 40 bits
{ "masr40\0macr40", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Parallel Multiply and Subtract - Multiply and Accumulate, and Round on 40 bits
{ "amar\0mac", CF_CHG1|CF_USE2|CF_USE3|CF_CHG4 }, // Parallel Modify Auxiliary Register - Multiply and Accumulate
{ "amar\0macr", CF_CHG1|CF_USE2|CF_USE3|CF_CHG4 }, // Parallel Modify Auxiliary Register - Multiply and Accumulate, and Round
{ "amar\0mac40", CF_CHG1|CF_USE2|CF_USE3|CF_CHG4 }, // Parallel Modify Auxiliary Register - Multiply and Accumulate, on 40 bits
{ "amar\0macr40", CF_CHG1|CF_USE2|CF_USE3|CF_CHG4 }, // Parallel Modify Auxiliary Register - Multiply and Accumulate, and Round on 40 bits
{ "mas\0mas", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Two Parallel Multiply and Subtract
{ "masr\0masr", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Two Parallel Multiply and Subtract, and Round
{ "mas40\0mas40", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Two Parallel Multiply and Subtract, on 40 bits
{ "masr40\0masr40", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Two Parallel Multiply and Subtract, and Round on 40 bits
{ "amar\0mas", CF_CHG1|CF_USE2|CF_USE3|CF_CHG4 }, // Parallel Modify Auxiliary Register - Multiply and Subtract
{ "amar\0masr", CF_CHG1|CF_USE2|CF_USE3|CF_CHG4 }, // Parallel Modify Auxiliary Register - Multiply and Subtract, and Round
{ "amar\0mas40", CF_CHG1|CF_USE2|CF_USE3|CF_CHG4 }, // Parallel Modify Auxiliary Register - Multiply and Subtract, on 40 bits
{ "amar\0masr40", CF_CHG1|CF_USE2|CF_USE3|CF_CHG4 }, // Parallel Modify Auxiliary Register - Multiply and Subtract, and Round on 40 bits
// "mac\0mac"
{ "mpy\0mac", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Parallel Multiply - Multiply and Accumulate
{ "mpyr\0macr", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Parallel Multiply - Multiply and Accumulate, and Round
{ "mpy40\0mac40", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Parallel Multiply - Multiply and Accumulate, on 40 bits
{ "mpyr40\0macr40", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_USE5|CF_CHG6 }, // Parallel Multiply - Multiply and Accumulate, and Round on 40 bits
// "mac\0mac"
// "mas\0mac"
// "amar\0mac"
{ "amar", CF_CHG1|CF_CHG2|CF_CHG3 }, // Three Parallel Modify Auxiliary Registers
{ "firsadd", CF_USE1|CF_USE2|CF_USE3|CF_CHG4|CF_CHG5 }, // Parallel Multiply and Accumulate - Add
{ "firssub", CF_USE1|CF_USE2|CF_USE3|CF_CHG4|CF_CHG5 }, // Parallel Multiply and Accumulate - Subtract
{ "mpym\0mov", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_CHG5 }, // Parallel Multiply - Store
{ "mpymr\0mov", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_CHG5 }, // Parallel Multiply - Store, and Round
{ "macm\0mov", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_CHG5 }, // Parallel Multiply and Accumulate - Store
{ "macmr\0mov", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_CHG5 }, // Parallel Multiply and Accumulate - Store, and Round
{ "masm\0mov", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_CHG5 }, // Parallel Multiply and Subtract - Store
{ "masmr\0mov", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_CHG5 }, // Parallel Multiply and Subtract - Store, and Round
{ "add\0mov", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_CHG5 }, // Parallel Add - Store
{ "sub\0mov", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_CHG5 }, // Parallel Subtract - Store
{ "mov\0mov", CF_USE1|CF_USE2|CF_USE3|CF_CHG4 }, // Parallel Load - Store
{ "mov\0aadd", CF_USE1|CF_CHG2|CF_USE3|CF_CHG4 }, // Parallel Load - aadd
{ "mov\0add", CF_USE1|CF_CHG2|CF_USE3|CF_USE4|CF_CHG5 }, // Parallel Load - aadd
{ "amar\0amar", CF_CHG1|CF_CHG2 },
{ "add\0asub", CF_USE1|CF_USE2|CF_CHG3|CF_USE4|CF_CHG5 }, // Parallel Add - asub
{ "btst\0mov", CF_USE1|CF_CHG2|CF_CHG3|CF_USE4|CF_CHG5 }, // Parallel Bit Test - Store
{ "mov\0asub", CF_USE1|CF_CHG2|CF_USE3|CF_CHG4 }, // Parallel Load - aadd
// "macm\0mov"
// "masm\0mov"
{ "lms", CF_USE1|CF_USE2|CF_CHG3|CF_CHG4 }, // Least Mean Square
{ "max", CF_CHG1 }, // Maximum Comparison
{ "max", CF_USE1|CF_CHG2 }, // Maximum Comparison
{ "min", CF_CHG1 }, // Minimum Comparison
{ "min", CF_USE1|CF_CHG2 }, // Minimum Comparison
{ "cmp", CF_USE1|CF_CHG2 }, // Memory Comparison
{ "cmpu", CF_USE1|CF_CHG2 }, // Unsigned memory Comparison
{ "aadd", CF_USE1|CF_CHG2 }, // Add Two Registers
{ "asub", CF_USE1|CF_CHG2 }, // Subtract Two Registers
{ "amov", CF_USE1|CF_CHG2 }, // Move From Register to Register
// "aadd"
// "asub"
// "amov"
{ "amar", CF_CHG1 }, // Auxiliary Register Modification
// { "aadd", CF_USE1|CF_CHG2 }, // Modify Data Stack Pointer
{ "sqr", CF_CHG1 }, // Square
{ "sqr", CF_CHG1|CF_USE2 }, // Square
{ "sqrr", CF_CHG1 }, // Square and Round
{ "sqrr", CF_CHG1|CF_USE2 }, // Square and Round
{ "mpy", CF_CHG1 }, // Multiply
{ "mpy", CF_CHG1|CF_CHG2 }, // Multiply
{ "mpy", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply
{ "mpyr", CF_CHG1 }, // Multiply and Round
{ "mpyr", CF_CHG1|CF_CHG2 }, // Multiply and Round
{ "mpyr", CF_CHG1|CF_USE2|CF_CHG3 }, // Multiply and Round
{ "mpyk", CF_USE1|CF_CHG2 }, // Multiply by Constant
{ "mpyk", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply by Constant
{ "mpykr", CF_USE1|CF_CHG2 }, // Multiply by Constant and Round
{ "mpykr", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply by Constant and Round
{ "mpym", CF_USE1|CF_CHG2 }, // Multiply Memory Value
{ "mpym", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Memory Values
{ "mpymr", CF_USE1|CF_CHG2 }, // Multiply Memory Value and Round
{ "mpymr", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Memory Values and Round
{ "mpym40", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Memory Values on 40 bits
{ "mpymr40", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Memory Values and Round on 40 bits
{ "mpymu", CF_USE1|CF_USE2|CF_CHG3 }, // Unsigned multiply Memory Values
{ "mpymru", CF_USE1|CF_USE2|CF_CHG3 }, // Unsigned multiply Memory Values and Round
{ "sqrm", CF_USE1|CF_CHG2 }, // Square Memory Value
{ "sqrmr", CF_USE1|CF_CHG2 }, // Square Memory Value, and Round
{ "mpymk", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Memory Value by Constant
{ "mpymkr", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Memory Value by Constant and Round
{ "sqa", CF_CHG1 }, // Square and Accumulate
{ "sqa", CF_CHG1|CF_USE2 }, // Square and Accumulate
{ "sqar", CF_CHG1 }, // Square, Accumulate and Round
{ "sqar", CF_CHG1|CF_USE2 }, // Square, Accumulate and Round
{ "mac", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply and Accumulate
{ "mac", CF_USE1|CF_USE2|CF_CHG3|CF_CHG4 }, // Multiply and Accumulate
{ "macr", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply, Accumulate and Round
{ "macr", CF_USE1|CF_USE2|CF_CHG3|CF_CHG4 }, // Multiply, Accumulate and Round
{ "mack", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply by Constant and Accumulate
{ "mack", CF_USE1|CF_USE2|CF_USE3|CF_CHG4 }, // Multiply by Constant and Accumulate
{ "mackr", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply by Constant, Round and Accumulate
{ "mackr", CF_USE1|CF_USE2|CF_USE3|CF_CHG4 }, // Multiply by Constant, Round and Accumulate
{ "macm", CF_USE1|CF_CHG2 }, // Multiply and Accumulate Memory Values
{ "macm", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply and Accumulate Memory Values
{ "macm", CF_USE1|CF_USE2|CF_USE3|CF_CHG4 }, // Multiply and Accumulate Memory Values
{ "macmr", CF_USE1|CF_CHG2 }, // Multiply and Accumulate Memory Values, and Round
{ "macmr", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply and Accumulate Memory Values, and Round
{ "macmr", CF_USE1|CF_USE2|CF_USE3|CF_CHG4 }, // Multiply and Accumulate Memory Values, and Round
{ "macm40", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply and Accumulate Memory Values, on 40 bits
{ "macm40", CF_USE1|CF_USE2|CF_USE3|CF_CHG4 }, // Multiply and Accumulate Memory Values, on 40 bits
{ "macmr40", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply and Accumulate Memory Values, and Round on 40 bits
{ "macmr40", CF_USE1|CF_USE2|CF_USE3|CF_CHG4 }, // Multiply and Accumulate Memory Values, and Round on 40 bits
{ "macmz", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply and Accumulate Memory Values
{ "macmrz", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply and Accumulate Memory Values, and Round
{ "sqam", CF_USE1|CF_CHG2 }, // Square and Accumulate Memory Value
{ "sqam", CF_USE1|CF_USE2|CF_CHG3 }, // Square and Accumulate Memory Values
{ "sqamr", CF_USE1|CF_CHG2 }, // Square and Accumulate Memory Value, and Round
{ "sqamr", CF_USE1|CF_USE2|CF_CHG3 }, // Square and Accumulate Memory Values, and Round
{ "macmk", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Memory Value by Constant and Accumulate
{ "macmk", CF_USE1|CF_USE2|CF_USE3|CF_CHG4 }, // Multiply Memory Value by Constant and Accumulate
{ "macmkr", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Memory Value by Constant - Accumulate, and Round
{ "macmkr", CF_USE1|CF_USE2|CF_USE3|CF_CHG4 }, // Multiply Memory Value by Constant - Accumulate, and Round
{ "sqs", CF_CHG1 }, // Square and Subtract
{ "sqs", CF_CHG1|CF_USE2 }, // Square and Subtract
{ "sqsr", CF_CHG1 }, // Square, Subtract and Round
{ "sqsr", CF_CHG1|CF_USE2 }, // Square, Subtract and Round
{ "mas", CF_USE1|CF_CHG2 }, // Multiply and Subtract
{ "mas", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply and Subtract
{ "masr", CF_USE1|CF_CHG2 }, // Multiply, Subtract and Round
{ "masr", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply, Subtract and Round
{ "masm", CF_USE1|CF_CHG2 }, // Multiply and Subtract Memory Value
{ "masm", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply and Subtract Memory Values
{ "masm", CF_USE1|CF_USE2|CF_USE3|CF_CHG4 }, // Multiply and Subtract Memory Values
{ "masmr", CF_USE1|CF_CHG2 }, // Multiply and Subtract Memory Value, and Round
{ "masmr", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply and Subtract Memory Values, and Round
{ "masmr", CF_USE1|CF_USE2|CF_USE3|CF_CHG4 }, // Multiply and Subtract Memory Values, and Round
{ "masm40", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply and Subtract Memory Values, on 40 bits
{ "masm40", CF_USE1|CF_USE2|CF_USE3|CF_CHG4 }, // Multiply and Subtract Memory Values, on 40 bits
{ "masmr40", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply and Subtract Memory Values, and Round on 40 bits
{ "masmr40", CF_USE1|CF_USE2|CF_USE3|CF_CHG4 }, // Multiply and Subtract Memory Values, and Round on 40 bits
{ "sqsm", CF_USE1|CF_CHG2 }, // Square and Subtract Memory Values
{ "sqsm", CF_USE1|CF_USE2|CF_CHG3 }, // Square and Subtract Memory Values
{ "sqsmr", CF_USE1|CF_CHG2 }, // Square and Subtract Memory Values, and Round
{ "sqsmr", CF_USE1|CF_USE2|CF_CHG3 }, // Square and Subtract Memory Values, and Round
{ "neg", CF_CHG1 }, // Negation
{ "neg", CF_CHG1|CF_USE2 }, // Negation
{ "mant\0nexp", CF_USE1|CF_CHG2|CF_USE3|CF_CHG4 }, // Exponent and Mantissa
{ "exp", CF_USE1|CF_CHG2 }, // Exponent
{ "cmpand", CF_USE1|CF_CHG2|CF_CHG3 }, // Compare and AND
{ "cmpandu", CF_USE1|CF_CHG2|CF_CHG3 }, // Unsigned compare and AND
{ "cmpor", CF_USE1|CF_CHG2|CF_CHG3 }, // Compare and OR
{ "cmporu", CF_USE1|CF_CHG2|CF_CHG3 }, // Unsigned compare and OR
{ "round", CF_CHG1 }, // Round
{ "round", CF_USE1|CF_CHG2 }, // Round
{ "sat", CF_CHG1 }, // Saturate
{ "sat", CF_USE1|CF_CHG2 }, // Saturate
{ "satr", CF_CHG1 }, // Saturate and Round
{ "satr", CF_USE1|CF_CHG2 }, // Saturate and Round
{ "sfts", CF_CHG1|CF_USE2 }, // Signed Shift
{ "sfts", CF_USE1|CF_USE2|CF_CHG3 }, // Signed Shift
{ "sftsc", CF_CHG1|CF_USE2 }, // Signed Shift with Carry
{ "sftsc", CF_USE1|CF_USE2|CF_CHG3 }, // Signed Shift with Carry
{ "sqdst", CF_USE1|CF_USE2|CF_CHG3|CF_CHG4 }, // Square distance
{ "sub", CF_USE1 }, // Subtract
{ "sub", CF_USE1|CF_CHG2 }, // Subtract
{ "sub", CF_USE1|CF_USE2|CF_CHG3 }, // Subtract
{ "sub", CF_USE1|CF_USE2|CF_USE3|CF_CHG4 }, // Subtract
// BIT MANIPULATION OPERATIONS
{ "band", CF_USE1|CF_USE2|CF_CHG3 }, // Bit Field Comparison
{ "bfxpa", CF_USE1|CF_USE2|CF_CHG3 }, // Bit Field Expand
{ "bfxtr", CF_USE1|CF_USE2|CF_CHG3 }, // Bit Field Extract
{ "btst", CF_USE1|CF_CHG2|CF_CHG3 }, // Bit Test
{ "bnot", CF_USE1|CF_CHG2 }, // Bit NOT
{ "bclr", CF_USE1|CF_CHG2 }, // Bit Clear
{ "bset", CF_USE1|CF_CHG2 }, // Bit Set
{ "btstset", CF_USE1|CF_CHG2|CF_CHG3 }, // Bit Test and Set
{ "btstclr", CF_USE1|CF_CHG2|CF_CHG3 }, // Bit Test and Clear
{ "btstnot", CF_USE1|CF_CHG2|CF_CHG3 }, // Bit Test and NOT
{ "btstp", CF_USE1|CF_USE2 }, // Bit Pair Test
{ "bclr", CF_CHG1 }, // Bit Clear
{ "bset", CF_CHG1 }, // Bit Set
// EXTENDED AUXILIARY REGISTER OPERATIONS
{ "amar", CF_USE1|CF_CHG2 }, // Load Effective Address to Extended Auxiliary Register
{ "popboth", CF_CHG1 }, // Pop Extended Auxiliary Register from Stack Pointers
{ "pshboth", CF_USE1 }, // Push Extended Auxiliary Register to Stack Pointers
// LOGICAL OPERATIONS
{ "bcnt", CF_USE1|CF_USE2|CF_CHG3|CF_CHG4 }, // Count Bit Field
{ "not", CF_CHG1 }, // NOT
{ "not", CF_USE1|CF_CHG2 }, // NOT
{ "and", CF_USE1 }, // AND
{ "and", CF_USE1|CF_CHG2 }, // AND
{ "and", CF_USE1|CF_USE2|CF_CHG3 }, // AND
{ "or", CF_USE1 }, // OR
{ "or", CF_USE1|CF_CHG2 }, // OR
{ "or", CF_USE1|CF_USE2|CF_CHG3 }, // OR
{ "xor", CF_USE1 }, // XOR
{ "xor", CF_USE1|CF_CHG2 }, // XOR
{ "xor", CF_USE1|CF_USE2|CF_CHG3 }, // XOR
{ "sftl", CF_USE1|CF_USE2 }, // Logical Shift
{ "sftl", CF_USE1|CF_USE2|CF_CHG3 }, // Logical Shift
{ "rol", CF_CHG1|CF_USE2|CF_USE3|CF_CHG4 }, // Rotate Left
{ "ror", CF_USE1|CF_USE2|CF_USE3|CF_CHG4 }, // Rotate Right
// MOVE OPERATIONS
{ "swap", CF_CHG1|CF_CHG2 }, // Swap Registers
{ "swapp", CF_CHG1|CF_CHG2 }, // Swap Pair Registers
{ "swap4", CF_CHG1|CF_CHG2 }, // Swap 4 Registers
{ "mov", CF_USE1|CF_CHG2 }, // Move Data
{ "mov", CF_USE1|CF_USE2|CF_CHG3 }, // Move 2 Data
{ "mov40", CF_USE1|CF_CHG2 }, // Move Data on 40 bits
{ "delay", CF_USE1 }, // Memory Delay
{ "pop", CF_CHG1 }, // Pop Top of Stack
{ "pop", CF_CHG1|CF_CHG2 }, // Pop Top of Stack
{ "psh", CF_USE1 }, // Pop Top of Stack
{ "psh", CF_USE1|CF_USE2 }, // Pop Top of Stack
// PROGRAM CONTROL OPERATIONS
{ "bcc", CF_USE1|CF_USE2 }, // Branch Conditionally
{ "bccu", CF_USE1|CF_USE2 }, // Branch Conditionally
{ "b", CF_USE1|CF_STOP }, // Branch Unconditionally
{ "callcc", CF_USE1|CF_USE2|CF_CALL }, // Call Conditionally
{ "call", CF_USE1|CF_CALL }, // Call Unconditionally
{ "xcc", CF_USE1 }, // Execute Conditionally
{ "xccpart", CF_USE1 }, // Execute Conditionally
{ "idle", 0 }, // Idle
{ "nop", 0 }, // No Operation
{ "nop_16", 0 }, // No Operation
{ "rptblocal", CF_USE1 }, // Repeat Block of Instructions Unconditionally
{ "rptb", CF_USE1 }, // Repeat Block of Instructions Unconditionally
{ "rptcc", CF_USE1|CF_USE2 }, // Repeat Single Instruction Conditionally
{ "rpt", CF_USE1 }, // Repeat Single Instruction Unconditionally
{ "rptadd", CF_USE1|CF_USE2 }, // Repeat Single Instruction Unconditionally and Add to Register
{ "rptsub", CF_USE1|CF_USE2 }, // Repeat Single Instruction Unconditionally and Subtract to Register
{ "retcc", CF_USE1 }, // Return Conditionally
{ "ret", CF_STOP }, // Return Unconditionally
{ "reti", CF_STOP }, // Return from Interrupt
{ "intr", CF_USE1 }, // Software Interrupt
{ "reset", 0 }, // Software Reset
{ "trap", CF_USE1 }, // Software Trap
};
CASSERT(qnumber(Instructions) == TMS320C55_last);

View File

@@ -0,0 +1,350 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-2021 Hex-Rays
* ALL RIGHTS RESERVED.
*
*/
#ifndef __INSTRS_HPP
#define __INSTRS_HPP
extern const instruc_t Instructions[];
enum nameNum ENUM_SIZE(uint16)
{
TMS320C55_null = 0, // Unknown Operation
// ARITHMETICAL OPERATIONS
TMS320C55_abdst, // Absolute Distance
TMS320C55_abs1, // Absolute Value
TMS320C55_abs2, // Absolute Value
TMS320C55_add1, // Addition
TMS320C55_add2, // Addition
TMS320C55_add3, // Addition
TMS320C55_add4, // Addition
TMS320C55_addv1, // Addition
TMS320C55_addv2, // Addition
TMS320C55_addrv1, // Addition and Round
TMS320C55_addrv2, // Addition and Round
TMS320C55_maxdiff, // Compare and Select Maximum
TMS320C55_dmaxdiff, // Compare and Select 40-bit Maximum
TMS320C55_mindiff, // Compare and Select Minimum
TMS320C55_dmindiff, // Compare and Select 40-bit Minimum
TMS320C55_addsubcc4, // Conditional Add or Subtract
TMS320C55_addsubcc5, // Conditional Add or Subtract
TMS320C55_addsub2cc, // Conditional Add or Subtract
TMS320C55_sftcc, // Conditional Shift
TMS320C55_subc2, // Conditional Subtract
TMS320C55_subc3, // Conditional Subtract
TMS320C55_addsub, // Paralleled Add - Subtract
TMS320C55_subadd, // Parallel Subtract - Add
TMS320C55_mpy_mpy, // Two Parallel Multiply
TMS320C55_mpy_mpyr, // Two Parallel Multiply, and Round
TMS320C55_mpy_mpy40, // Two Parallel Multiply, on 40 bits
TMS320C55_mpy_mpyr40, // Two Parallel Multiply, and Round on 40 bits
TMS320C55_mac_mpy, // Parallel Multiply - Accumulate
TMS320C55_macr_mpyr, // Parallel Multiply - Accumulate, and Round
TMS320C55_mac40_mpy40, // Parallel Multiply - Accumulate, on 40 bits
TMS320C55_macr40_mpyr40, // Parallel Multiply - Accumulate, and Round on 40 bits
TMS320C55_mas_mpy, // Parallel Multiply - Subtract
TMS320C55_masr_mpyr, // Parallel Multiply - Subtract, and Round
TMS320C55_mas40_mpy40, // Parallel Multiply - Subtract, on 40 bits
TMS320C55_masr40_mpyr40, // Parallel Multiply - Subtract, and Round on 40 bits
TMS320C55_amar_mpy, // Parallel Modify Auxiliary Register - Multiply
TMS320C55_amar_mpyr, // Parallel Modify Auxiliary Register - Multiply, and Round
TMS320C55_amar_mpy40, // Parallel Modify Auxiliary Register - Multiply, on 40 bits
TMS320C55_amar_mpyr40, // Parallel Modify Auxiliary Register - Multiply, and Round on 40 bits
TMS320C55_mac_mac, // Two Parallel Multiply and Accumulate
TMS320C55_macr_macr, // Two Parallel Multiply and Accumulate, and Round
TMS320C55_mac40_mac40, // Two Parallel Multiply and Accumulate, on 40 bits
TMS320C55_macr40_macr40, // Two Parallel Multiply and Accumulate, and Round on 40 bits
TMS320C55_mas_mac, // Parallel Multiply and Subtract - Multiply and Accumulate
TMS320C55_masr_macr, // Parallel Multiply and Subtract - Multiply and Accumulate, and Round
TMS320C55_mas40_mac40, // Parallel Multiply and Subtract - Multiply and Accumulate, on 40 bits
TMS320C55_masr40_macr40, // Parallel Multiply and Subtract - Multiply and Accumulate, and Round on 40 bits
TMS320C55_amar_mac, // Parallel Modify Auxiliary Register - Multiply and Accumulate
TMS320C55_amar_macr, // Parallel Modify Auxiliary Register - Multiply and Accumulate, and Round
TMS320C55_amar_mac40, // Parallel Modify Auxiliary Register - Multiply and Accumulate, on 40 bits
TMS320C55_amar_macr40, // Parallel Modify Auxiliary Register - Multiply and Accumulate, and Round on 40 bits
TMS320C55_mas_mas, // Two Parallel Multiply and Subtract
TMS320C55_masr_masr, // Two Parallel Multiply and Subtract, and Round
TMS320C55_mas40_mas40, // Two Parallel Multiply and Subtract, on 40 bits
TMS320C55_masr40_masr40, // Two Parallel Multiply and Subtract, and Round on 40 bits
TMS320C55_amar_mas, // Parallel Modify Auxiliary Register - Multiply and Subtract
TMS320C55_amar_masr, // Parallel Modify Auxiliary Register - Multiply and Subtract, and Round
TMS320C55_amar_mas40, // Parallel Modify Auxiliary Register - Multiply and Subtract, on 40 bits
TMS320C55_amar_masr40, // Parallel Modify Auxiliary Register - Multiply and Subtract, and Round on 40 bits
TMS320C55_mpy_mac, // Parallel Multiply - Multiply and Accumulate
TMS320C55_mpyr_macr, // Parallel Multiply - Multiply and Accumulate, and Round
TMS320C55_mpy40_mac40, // Parallel Multiply - Multiply and Accumulate, on 40 bits
TMS320C55_mpyr40_macr40, // Parallel Multiply - Multiply and Accumulate, and Round on 40 bits
TMS320C55_amar3, // Three Parallel Modify Auxiliary Registers
TMS320C55_firsadd, // Parallel Multiply and Accumulate - Add
TMS320C55_firssub, // Parallel Multiply and Accumulate - Subtract
TMS320C55_mpym_mov, // Parallel Multiply - Store
TMS320C55_mpymr_mov, // Parallel Multiply - Store, and Round
TMS320C55_macm_mov, // Parallel Multiply and Accumulate - Store
TMS320C55_macmr_mov, // Parallel Multiply and Accumulate - Store, and Round
TMS320C55_masm_mov, // Parallel Multiply and Subtract - Store
TMS320C55_masmr_mov, // Parallel Multiply and Subtract - Store, and Round
TMS320C55_add_mov, // Parallel Add - Store
TMS320C55_sub_mov, // Parallel Subtract - Store
TMS320C55_mov_mov, // Parallel Load - Store
TMS320C55_mov_aadd, // Parallel Store - aadd
TMS320C55_mov_add, // Parallel Store - Add
TMS320C55_amar_amar, // Parallel Modify Auxiliary Register - Modify Auxiliary Register
TMS320C55_add_asub, // Parallel Add - asub
TMS320C55_btst_mov, // Parallel Bit Test - Store
TMS320C55_mov_asub, // Parallel Store - asub
TMS320C55_lms, // Least Mean Square
TMS320C55_max1, // Maximum Comparison
TMS320C55_max2, // Maximum Comparison
TMS320C55_min1, // Minimum Comparison
TMS320C55_min2, // Minimum Comparison
TMS320C55_cmp, // Memory Comparison
TMS320C55_cmpu, // Unsigned memory Comparison
TMS320C55_aadd, // Add Two Registers
TMS320C55_asub, // Subtract Two Registers
TMS320C55_amov, // Move From Register to Register
TMS320C55_amar1, // Auxiliary Register Modification
TMS320C55_sqr1, // Square
TMS320C55_sqr2, // Square
TMS320C55_sqrr1, // Square and Round
TMS320C55_sqrr2, // Square and Round
TMS320C55_mpy1, // Multiply
TMS320C55_mpy2, // Multiply
TMS320C55_mpy3, // Multiply
TMS320C55_mpyr1, // Multiply and Round
TMS320C55_mpyr2, // Multiply and Round
TMS320C55_mpyr3, // Multiply and Round
TMS320C55_mpyk2, // Multiply by Constant
TMS320C55_mpyk3, // Multiply by Constant
TMS320C55_mpykr2, // Multiply by Constant and Round
TMS320C55_mpykr3, // Multiply by Constant and Round
TMS320C55_mpym2, // Multiply Memory Value
TMS320C55_mpym3, // Multiply Memory Values
TMS320C55_mpymr2, // Multiply Memory Value and Round
TMS320C55_mpymr3, // Multiply Memory Values and Round
TMS320C55_mpym403, // Multiply Memory Values on 40 bits
TMS320C55_mpymr403, // Multiply Memory Values and Round on 40 bits
TMS320C55_mpymu3, // Unsigned multiply Memory Values
TMS320C55_mpymru3, // Unsigned multiply Memory Values and Round
TMS320C55_sqrm, // Square Memory Value
TMS320C55_sqrmr, // Square Memory Value, and Round
TMS320C55_mpymk, // Multiply Memory Value by Constant
TMS320C55_mpymkr, // Multiply Memory Value by Constant and Round
TMS320C55_sqa1, // Square and Accumulate
TMS320C55_sqa2, // Square and Accumulate
TMS320C55_sqar1, // Square, Accumulate and Round
TMS320C55_sqar2, // Square, Accumulate and Round
TMS320C55_mac3, // Multiply and Accumulate
TMS320C55_mac4, // Multiply and Accumulate
TMS320C55_macr3, // Multiply, Accumulate and Round
TMS320C55_macr4, // Multiply, Accumulate and Round
TMS320C55_mack3, // Multiply by Constant and Accumulate
TMS320C55_mack4, // Multiply by Constant and Accumulate
TMS320C55_mackr3, // Multiply by Constant, Round and Accumulate
TMS320C55_mackr4, // Multiply by Constant, Round and Accumulate
TMS320C55_macm2, // Multiply and Accumulate Memory Values
TMS320C55_macm3, // Multiply and Accumulate Memory Values
TMS320C55_macm4, // Multiply and Accumulate Memory Values
TMS320C55_macmr2, // Multiply and Accumulate Memory Values, and Round
TMS320C55_macmr3, // Multiply and Accumulate Memory Values, and Round
TMS320C55_macmr4, // Multiply and Accumulate Memory Values, and Round
TMS320C55_macm403, // Multiply and Accumulate Memory Values, on 40 bits
TMS320C55_macm404, // Multiply and Accumulate Memory Values, on 40 bits
TMS320C55_macmr403, // Multiply and Accumulate Memory Values, and Round on 40 bits
TMS320C55_macmr404, // Multiply and Accumulate Memory Values, and Round on 40 bits
TMS320C55_macmz, // Multiply and Accumulate Memory Values
TMS320C55_macmrz, // Multiply and Accumulate Memory Values, and Round
TMS320C55_sqam2, // Square and Accumulate Memory Value
TMS320C55_sqam3, // Square and Accumulate Memory Values
TMS320C55_sqamr2, // Square and Accumulate Memory Value, and Round
TMS320C55_sqamr3, // Square and Accumulate Memory Values, and Round
TMS320C55_macmk3, // Multiply Memory Value by Constant and Accumulate
TMS320C55_macmk4, // Multiply Memory Value by Constant and Accumulate
TMS320C55_macmkr3, // Multiply Memory Value by Constant - Accumulate, and Round
TMS320C55_macmkr4, // Multiply Memory Value by Constant - Accumulate, and Round
TMS320C55_sqs1, // Square and Subtract
TMS320C55_sqs2, // Square and Subtract
TMS320C55_sqsr1, // Square, Subtract and Round
TMS320C55_sqsr2, // Square, Subtract and Round
TMS320C55_mas2, // Multiply and Subtract
TMS320C55_mas3, // Multiply and Subtract
TMS320C55_masr2, // Multiply, Subtract and Round
TMS320C55_masr3, // Multiply, Subtract and Round
TMS320C55_masm2, // Multiply and Subtract Memory Value
TMS320C55_masm3, // Multiply and Subtract Memory Values
TMS320C55_masm4, // Multiply and Subtract Memory Values
TMS320C55_masmr2, // Multiply and Subtract Memory Values, and Round
TMS320C55_masmr3, // Multiply and Subtract Memory Values, and Round
TMS320C55_masmr4, // Multiply and Subtract Memory Values, and Round
TMS320C55_masm403, // Multiply and Subtract Memory Values, on 40 bits
TMS320C55_masm404, // Multiply and Subtract Memory Values, on 40 bits
TMS320C55_masmr403, // Multiply and Subtract Memory Values, and Round on 40 bits
TMS320C55_masmr404, // Multiply and Subtract Memory Values, and Round on 40 bits
TMS320C55_sqsm2, // Square and Subtract Memory Values
TMS320C55_sqsm3, // Square and Subtract Memory Values
TMS320C55_sqsmr2, // Square and Subtract Memory Values, and Round
TMS320C55_sqsmr3, // Square and Subtract Memory Values, and Round
TMS320C55_neg1, // Negation
TMS320C55_neg2, // Negation
TMS320C55_mant_nexp, // Exponent and Mantissa
TMS320C55_exp, // Exponent
TMS320C55_cmpand, // Compare and AND
TMS320C55_cmpandu, // Unsigned compare and AND
TMS320C55_cmpor, // Compare and OR
TMS320C55_cmporu, // Unsigned compare and OR
TMS320C55_round1, // Round
TMS320C55_round2, // Round
TMS320C55_sat1, // Saturate
TMS320C55_sat2, // Saturate
TMS320C55_satr1, // Saturate and Round
TMS320C55_satr2, // Saturate and Round
TMS320C55_sfts2, // Signed Shift
TMS320C55_sfts3, // Signed Shift
TMS320C55_sftsc2, // Signed Shift with Carry
TMS320C55_sftsc3, // Signed Shift with Carry
TMS320C55_sqdst, // Square distance
TMS320C55_sub1, // Subtract
TMS320C55_sub2, // Subtract
TMS320C55_sub3, // Subtract
TMS320C55_sub4, // Subtract
TMS320C55_band, // Bit Field Comparison
TMS320C55_bfxpa, // Bit Field Expand
TMS320C55_bfxtr, // Bit Field Extract
TMS320C55_btst, // Bit Test
TMS320C55_bnot, // Bit NOT
TMS320C55_bclr2, // Bit Clear
TMS320C55_bset2, // Bit Set
TMS320C55_btstset, // Bit Test and Set
TMS320C55_btstclr, // Bit Test and Clear
TMS320C55_btstnot, // Bit Test and NOT
TMS320C55_btstp, // Bit Pair Test
TMS320C55_bclr1, // Bit Clear
TMS320C55_bset1, // Bit Set
TMS320C55_amar2, // Load Effective Address to Extended Auxiliary Register
TMS320C55_popboth, // Pop Extended Auxiliary Register from Stack Pointers
TMS320C55_pshboth, // Push Extended Auxiliary Register to Stack Pointers
// LOGICAL OPERATIONS
TMS320C55_bcnt, // Count Bit Field
TMS320C55_not1, // NOT
TMS320C55_not2, // NOT
TMS320C55_and1, // AND
TMS320C55_and2, // AND
TMS320C55_and3, // AND
TMS320C55_or1, // OR
TMS320C55_or2, // OR
TMS320C55_or3, // OR
TMS320C55_xor1, // XOR
TMS320C55_xor2, // XOR
TMS320C55_xor3, // XOR
TMS320C55_sftl2, // Logical Shift
TMS320C55_sftl3, // Logical Shift
TMS320C55_rol, // Rotate Left
TMS320C55_ror, // Rotate Right
// MISCELLANEOUS OPERATIONS
// MOVE OPERATIONS
TMS320C55_swap, // Swap Registers
TMS320C55_swapp, // Swap Pair Registers
TMS320C55_swap4, // Swap 4 Registers
TMS320C55_mov2, // Move Data
TMS320C55_mov3, // Move 2 Data
TMS320C55_mov402, // Move Data on 40 bits
TMS320C55_delay, // Memory Delay
TMS320C55_pop1, // Pop Top of Stack1
TMS320C55_pop2, // Pop Top of Stack2
TMS320C55_psh1, // Pop Top of Stack3
TMS320C55_psh2, // Pop Top of Stack4
// PROGRAM CONTROL OPERATIONS
TMS320C55_bcc, // Branch Conditionally
TMS320C55_bccu, // Branch Conditionally
TMS320C55_b, // Branch Unconditionally
TMS320C55_callcc, // Call Conditionally
TMS320C55_call, // Call Unconditionally
TMS320C55_xcc, // Execute Conditionally
TMS320C55_xccpart, // Execute Conditionally
TMS320C55_idle, // Idle
TMS320C55_nop, // No Operation
TMS320C55_nop_16, // No Operation
TMS320C55_rptblocal, // Repeat Block of Instructions Unconditionally
TMS320C55_rptb, // Repeat Block of Instructions Unconditionally
TMS320C55_rptcc, // Repeat Single Instruction Conditionally
TMS320C55_rpt, // Repeat Single Instruction Unconditionally
TMS320C55_rptadd, // Repeat Single Instruction Unconditionally and Add to Register
TMS320C55_rptsub, // Repeat Single Instruction Unconditionally and Subtract to Register
TMS320C55_retcc, // Return Conditionally
TMS320C55_ret, // Return Unconditionally
TMS320C55_reti, // Return from Interrupt
TMS320C55_intr, // Software Interrupt
TMS320C55_reset, // Software Reset
TMS320C55_trap, // Software Trap
TMS320C55_last
};
#endif

View File

@@ -0,0 +1,58 @@
PROC=tms32055
CONFIGS=tms320c55.cfg
include ../module.mak
# MAKEDEP dependency list ------------------
$(F)ana$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
$(I)config.hpp $(I)diskio.hpp \
$(I)entry.hpp $(I)fpro.h $(I)funcs.hpp $(I)ida.hpp \
$(I)idp.hpp $(I)ieee.h $(I)kernwin.hpp $(I)lines.hpp \
$(I)llong.hpp $(I)loader.hpp \
$(I)nalt.hpp $(I)name.hpp \
$(I)netnode.hpp $(I)offset.hpp $(I)pro.h \
$(I)problems.hpp $(I)range.hpp $(I)segment.hpp \
$(I)segregs.hpp $(I)ua.hpp $(I)xref.hpp ../idaidp.hpp \
../iohandler.hpp ana.cpp ins.hpp tms320c55.hpp
$(F)emu$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
$(I)config.hpp $(I)diskio.hpp \
$(I)entry.hpp $(I)fpro.h $(I)frame.hpp $(I)funcs.hpp \
$(I)ida.hpp $(I)idp.hpp $(I)ieee.h $(I)kernwin.hpp \
$(I)lines.hpp $(I)llong.hpp $(I)loader.hpp \
$(I)nalt.hpp $(I)name.hpp \
$(I)netnode.hpp $(I)offset.hpp $(I)pro.h \
$(I)problems.hpp $(I)range.hpp $(I)segment.hpp \
$(I)segregs.hpp $(I)ua.hpp $(I)xref.hpp ../idaidp.hpp \
../iohandler.hpp emu.cpp ins.hpp tms320c55.hpp
$(F)ins$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
$(I)config.hpp $(I)diskio.hpp \
$(I)entry.hpp $(I)fpro.h $(I)funcs.hpp $(I)ida.hpp \
$(I)idp.hpp $(I)ieee.h $(I)kernwin.hpp $(I)lines.hpp \
$(I)llong.hpp $(I)loader.hpp \
$(I)nalt.hpp $(I)name.hpp \
$(I)netnode.hpp $(I)offset.hpp $(I)pro.h \
$(I)problems.hpp $(I)range.hpp $(I)segment.hpp \
$(I)ua.hpp $(I)xref.hpp ../idaidp.hpp ../iohandler.hpp \
ins.cpp ins.hpp tms320c55.hpp
$(F)out$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
$(I)config.hpp $(I)diskio.hpp \
$(I)entry.hpp $(I)fpro.h $(I)frame.hpp $(I)funcs.hpp \
$(I)ida.hpp $(I)idp.hpp $(I)ieee.h $(I)kernwin.hpp \
$(I)lines.hpp $(I)llong.hpp $(I)loader.hpp \
$(I)nalt.hpp $(I)name.hpp \
$(I)netnode.hpp $(I)offset.hpp $(I)pro.h \
$(I)problems.hpp $(I)range.hpp $(I)segment.hpp \
$(I)segregs.hpp $(I)struct.hpp $(I)ua.hpp $(I)xref.hpp \
../idaidp.hpp ../iohandler.hpp ins.hpp out.cpp \
tms320c55.hpp
$(F)reg$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
$(I)config.hpp $(I)diskio.hpp \
$(I)entry.hpp $(I)fpro.h $(I)funcs.hpp $(I)ida.hpp \
$(I)idp.hpp $(I)ieee.h $(I)kernwin.hpp $(I)lines.hpp \
$(I)llong.hpp $(I)loader.hpp \
$(I)nalt.hpp $(I)name.hpp \
$(I)netnode.hpp $(I)offset.hpp $(I)pro.h \
$(I)problems.hpp $(I)range.hpp $(I)segment.hpp \
$(I)segregs.hpp $(I)ua.hpp $(I)xref.hpp ../idaidp.hpp \
../iohandler.hpp ins.hpp reg.cpp tms320c55.hpp

View File

@@ -0,0 +1,754 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-99 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* E-mail: ig@datarescue.com
*
*
*/
#include "tms320c55.hpp"
#include <frame.hpp>
#include <segregs.hpp>
#include <struct.hpp>
//? problem with stack variables:
// SP+offsets point to a word, but stack variables works at the byte level
// => variables offsets aren't just
// simple wrapper class for syntactic sugar of member functions
// this class may have only simple member functions.
// virtual functions and data fields are forbidden, otherwise the class
// layout may change
class out_tms320c55_t : public outctx_t
{
out_tms320c55_t(void) = delete; // not used
public:
bool out_operand(const op_t &x);
void out_insn(void);
void out_proc_mnem(void);
void out_address(const op_t &op);
void out_shift(uval_t value);
void out_symbol_shift(const op_t &op, bool is_out = false);
void out_operators_begin(const op_t &op);
void out_operators_end(const op_t &op);
void out_reg(const op_t &op);
void out_cond(const op_t &x);
void out_relop(const op_t &op);
};
CASSERT(sizeof(out_tms320c55_t) == sizeof(outctx_t));
DECLARE_OUT_FUNCS(out_tms320c55_t)
//----------------------------------------------------------------------
void out_tms320c55_t::out_address(const op_t &op)
{
tms320c55_t &pm = *static_cast<tms320c55_t *>(procmod);
ea_t ea = BADADDR;
if ( op.type == o_near )
ea = calc_code_mem(insn, op.addr);
else if ( op.type == o_mem )
ea = calc_data_mem(insn, op);
else if ( op.type == o_io )
ea = calc_io_mem(insn, op);
int reg = -1;
if ( op.type == o_mem )
reg = pm.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.reg_names[reg]);
}
else
{
#ifndef TMS320C55_NO_NAME_NO_REF
if ( !out_name_expr(op, ea, ea) )
#endif
{
out_tagon(COLOR_ERROR);
out_btoa(op.addr, 16);
out_tagoff(COLOR_ERROR);
remember_problem(PR_NONAME, insn.ea);
}
}
}
else // IO address
{
if ( ea != BADADDR )
{
const char *name = NULL;
if ( pm.idpflags & TMS320C55_IO )
name = pm.find_sym(ea);
if ( name != NULL && name[0] != '\0' )
out_line(name, COLOR_IMPNAME);
else
out_btoa(ea, 16);
}
else
{
out_tagon(COLOR_ERROR);
out_btoa(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");
}
}
//--------------------------------------------------------------------------
void out_tms320c55_t::out_shift(uval_t value)
{
out_symbol('#');
char buf[8];
qsnprintf(buf, sizeof(buf), "%d", (int)value);
out_line(buf, COLOR_DNUM);
}
//--------------------------------------------------------------------------
// output shift symbol (if out = true, output outside of brackets)
void out_tms320c55_t::out_symbol_shift(const op_t &op, bool is_out)
{
if ( op.tms_shift != TMS_OP_SHIFT_NULL )
{
if ( ((op.tms_shift & TMS_OP_SHIFT_OUT) != 0) == is_out ) // check if the shift must be print inside or outside the brackets
{
switch ( op.tms_shift & TMS_OP_SHIFT_TYPE )
{
case TMS_OP_SHIFTL_IMM:
out_line(" << ",COLOR_SYMBOL);
out_shift(op.tms_shift_value);
break;
case TMS_OP_SHIFTL_REG:
out_line(" << ",COLOR_SYMBOL);
out_register(ph.reg_names[op.tms_shift_value]);
break;
case TMS_OP_SHIFTR_IMM:
out_line(" >> ",COLOR_SYMBOL);
out_shift(op.tms_shift_value);
break;
case TMS_OP_EQ:
out_line(" == ",COLOR_SYMBOL);
out_shift(op.tms_shift_value);
break;
case TMS_OP_NEQ:
out_line(" != ",COLOR_SYMBOL);
out_shift(op.tms_shift_value);
break;
default:
error("interr: out: out_symbol_shift");
}
}
}
}
//--------------------------------------------------------------------------
void out_tms320c55_t::out_operators_begin(const op_t &op)
{
static const char *const strings[TMS_OPERATORS_SIZE] =
{
"T3=", "!", "uns(", "dbl(",
"rnd(", "pair(", "lo(", "hi(",
"low_byte(", "high_byte(", "saturate(", "dual(",
"port("
};
short operators = (op.tms_operator2 << 8) | (op.tms_operator1 &0xFF);
for ( int i = 0; i < TMS_OPERATORS_SIZE; i++ )
if ( operators & (1<<i) )
out_line(strings[i], COLOR_SYMBOL);
}
//--------------------------------------------------------------------------
void out_tms320c55_t::out_operators_end(const op_t &op)
{
short operators = (op.tms_operator2 << 8) | (op.tms_operator1 &0xFF);
int brackets = 0;
for ( int i = 0; i < TMS_OPERATORS_SIZE; i++ )
if ( operators & (1<<i) )
brackets++;
if ( operators & TMS_OPERATOR_T3 )
brackets--;
if ( operators & TMS_OPERATOR_NOT )
brackets--;
for ( int i = 0; i < brackets; i++ )
out_line(")", COLOR_SYMBOL);
}
//--------------------------------------------------------------------------
void out_tms320c55_t::out_reg(const op_t &op)
{
const char *reg = ph.reg_names[op.reg];
switch ( op.tms_modifier )
{
case TMS_MODIFIER_NULL:
out_register(reg);
break;
case TMS_MODIFIER_REG:
out_symbol('*');
out_register(reg);
break;
case TMS_MODIFIER_REG_P:
out_symbol('*');
out_register(reg);
out_symbol('+');
break;
case TMS_MODIFIER_REG_M:
out_symbol('*');
out_register(reg);
out_symbol('-');
break;
case TMS_MODIFIER_REG_P_T0:
out_line("*(", COLOR_SYMBOL);
out_register(reg);
out_symbol('+');
out_register(ph.reg_names[T0]);
out_symbol(')');
break;
case TMS_MODIFIER_REG_P_T1:
out_line("*(", COLOR_SYMBOL);
out_register(reg);
out_symbol('+');
out_register(ph.reg_names[T1]);
out_symbol(')');
break;
case TMS_MODIFIER_REG_M_T0:
out_line("*(", COLOR_SYMBOL);
out_register(reg);
out_symbol('-');
out_register(ph.reg_names[T0]);
out_symbol(')');
break;
case TMS_MODIFIER_REG_M_T1:
out_line("*(", COLOR_SYMBOL);
out_register(reg);
out_symbol('-');
out_register(ph.reg_names[T1]);
out_symbol(')');
break;
case TMS_MODIFIER_REG_T0:
out_symbol('*');
out_register(reg);
out_symbol('(');
out_register(ph.reg_names[T0]);
out_symbol(')');
break;
case TMS_MODIFIER_REG_OFFSET:
case TMS_MODIFIER_P_REG_OFFSET:
out_symbol('*');
if ( op.tms_modifier == TMS_MODIFIER_P_REG_OFFSET )
out_symbol('+');
out_register(reg);
out_line("(#", COLOR_SYMBOL);
out_value(op, OOFS_IFSIGN|OOF_SIGNED|OOF_NUMBER|OOFW_IMM);
out_symbol(')');
break;
case TMS_MODIFIER_REG_SHORT_OFFSET:
out_symbol('*');
out_register(reg);
out_line("(short(#", COLOR_SYMBOL);
out_value(op, OOFS_IFSIGN|OOF_SIGNED|OOF_NUMBER|OOFW_IMM);
out_line("))", COLOR_SYMBOL);
break;
case TMS_MODIFIER_REG_T1:
out_symbol('*');
out_register(reg);
out_symbol('(');
out_register(ph.reg_names[T1]);
out_symbol(')');
break;
case TMS_MODIFIER_P_REG:
out_symbol('+');
out_register(reg);
break;
case TMS_MODIFIER_M_REG:
out_symbol('-');
out_register(reg);
break;
case TMS_MODIFIER_REG_P_T0B:
out_line("*(", COLOR_SYMBOL);
out_register(reg);
out_symbol('+');
out_register("T0B");
out_symbol(')');
break;
case TMS_MODIFIER_REG_M_T0B:
out_line("*(", COLOR_SYMBOL);
out_register(reg);
out_symbol('-');
out_register("T0B");
out_symbol(')');
break;
default:
error("interr: out: o_reg: modifier");
}
}
//--------------------------------------------------------------------------
void out_tms320c55_t::out_cond(const op_t &x)
{
const char *reg = ph.reg_names[x.reg];
switch ( x.value )
{
case 0x00:
out_register(reg);
out_line(" == #", COLOR_SYMBOL);
out_long(0, 10);
break;
case 0x10:
out_register(reg);
out_line(" != #", COLOR_SYMBOL);
out_long(0, 10);
break;
case 0x20:
out_register(reg);
out_line(" < #", COLOR_SYMBOL);
out_long(0, 10);
break;
case 0x30:
out_register(reg);
out_line(" <= #", COLOR_SYMBOL);
out_long(0, 10);
break;
case 0x40:
out_register(reg);
out_line(" > #", COLOR_SYMBOL);
out_long(0, 10);
break;
case 0x50:
out_register(reg);
out_line(" >= #", COLOR_SYMBOL);
out_long(0, 10);
break;
case 0x60:
out_line("overflow(", COLOR_SYMBOL);
out_register(reg);
out_symbol(')');
break;
case 0x64:
out_register(ph.reg_names[TC1]);
break;
case 0x65:
out_register(ph.reg_names[TC2]);
break;
case 0x66:
out_register(ph.reg_names[CARRY]);
break;
case 0x68:
out_register(ph.reg_names[TC1]);
out_line(" & ", COLOR_SYMBOL);
out_register(ph.reg_names[TC2]);
break;
case 0x69:
out_register(ph.reg_names[TC1]);
out_line(" & !", COLOR_SYMBOL);
out_register(ph.reg_names[TC2]);
break;
case 0x6A:
out_symbol('!');
out_register(ph.reg_names[TC1]);
out_line(" & ", COLOR_SYMBOL);
out_register(ph.reg_names[TC2]);
break;
case 0x6B:
out_symbol('!');
out_register(ph.reg_names[TC1]);
out_line(" & !", COLOR_SYMBOL);
out_register(ph.reg_names[TC2]);
break;
case 0x70:
out_line("!overflow(", COLOR_SYMBOL);
out_register(reg);
out_symbol(')');
break;
case 0x74:
out_symbol('!');
out_register(ph.reg_names[TC1]);
break;
case 0x75:
out_symbol('!');
out_register(ph.reg_names[TC2]);
break;
case 0x76:
out_symbol('!');
out_register(ph.reg_names[CARRY]);
break;
case 0x78:
out_register(ph.reg_names[TC1]);
out_line(" | ", COLOR_SYMBOL);
out_register(ph.reg_names[TC2]);
break;
case 0x79:
out_register(ph.reg_names[TC1]);
out_line(" | !", COLOR_SYMBOL);
out_register(ph.reg_names[TC2]);
break;
case 0x7A:
out_symbol('!');
out_register(ph.reg_names[TC1]);
out_line(" | ", COLOR_SYMBOL);
out_register(ph.reg_names[TC2]);
break;
case 0x7B:
out_symbol('!');
out_register(ph.reg_names[TC1]);
out_line(" | !", COLOR_SYMBOL);
out_register(ph.reg_names[TC2]);
break;
case 0x7C:
out_register(ph.reg_names[TC1]);
out_line(" ^ ", COLOR_SYMBOL);
out_register(ph.reg_names[TC2]);
break;
case 0x7D:
out_register(ph.reg_names[TC1]);
out_line(" ^ !", COLOR_SYMBOL);
out_register(ph.reg_names[TC2]);
break;
case 0x7E:
out_symbol('!');
out_register(ph.reg_names[TC1]);
out_line(" ^ ", COLOR_SYMBOL);
out_register(ph.reg_names[TC2]);
break;
case 0x7F:
out_symbol('!');
out_register(ph.reg_names[TC1]);
out_line(" ^ !", COLOR_SYMBOL);
out_register(ph.reg_names[TC2]);
break;
default:
error("interr: out: o_cond");
}
}
//--------------------------------------------------------------------------
void out_tms320c55_t::out_relop(const op_t &op)
{
out_register(ph.reg_names[op.reg]);
const char *relop = NULL;
switch ( op.tms_relop )
{
case 0:
relop = " == ";
break;
case 1:
relop = " < ";
break;
case 2:
relop = " >= ";
break;
case 3:
relop = " != ";
break;
default:
error("interr: out: o_relop");
}
out_line(relop, COLOR_SYMBOL);
switch ( op.tms_relop_type )
{
case TMS_RELOP_REG:
out_register(ph.reg_names[int(op.value)]);
break;
case TMS_RELOP_IMM:
out_symbol('#');
out_value(op, OOFS_IFSIGN|OOF_SIGNED|OOF_NUMBER|OOFW_IMM);
break;
}
}
//----------------------------------------------------------------------
bool out_tms320c55_t::out_operand(const op_t &op)
{
switch ( op.type )
{
case o_void:
return 0;
case o_reg:
out_operators_begin(op);
out_reg(op);
out_symbol_shift(op, false);
out_operators_end(op);
out_symbol_shift(op, true);
break;
case o_relop:
out_relop(op);
break;
case o_shift:
out_shift(op.value);
break;
case o_imm:
if ( op.tms_prefix == 0 )
out_symbol('#');
else
out_symbol(op.tms_prefix);
if ( op.tms_signed )
out_value(op, OOFS_IFSIGN|OOF_SIGNED|OOFW_IMM);
else
out_value(op, OOFW_IMM);
out_symbol_shift(op);
break;
case o_near:
out_address(op);
break;
case o_mem:
case o_io:
out_operators_begin(op);
out_address(op);
out_symbol_shift(op, false);
out_operators_end(op);
out_symbol_shift(op, true);
break;
case o_cond:
out_cond(op);
break;
default:
error("interr: out");
}
return 1;
}
//----------------------------------------------------------------------
void out_tms320c55_t::out_proc_mnem(void)
{
if ( (insn.SpecialModes & TMS_MODE_USER_PARALLEL) == 0 )
{
if ( (insn.SpecialModes & (TMS_MODE_LR|TMS_MODE_CR)) != 0 )
{
out_line(insn.get_canon_mnem(ph), COLOR_INSN);
out_line((insn.SpecialModes & TMS_MODE_LR) ? ".lr ":".cr ", COLOR_INSN);
}
else
{
out_mnem();
}
}
else
{ // user-defined parallelism
out_line("|| ", COLOR_INSN);
out_line(insn.get_canon_mnem(ph), COLOR_INSN);
out_line(" ", COLOR_INSN);
}
}
//----------------------------------------------------------------------
void out_tms320c55_t::out_insn(void)
{
out_mnemonic();
for ( int op = 0; op < UA_MAXOP; op++ )
{
if ( insn.ops[op].type == o_void )
break;
if ( op != 0 ) // not the first operand
{
if ( insn.Parallel != TMS_PARALLEL_BIT && op == insn.Parallel ) // multi-line instruction
{
flush_outbuf();
// print the second instruction line
if ( insn.SpecialModes & TMS_MODE_SIMULATE_USER_PARALLEL )
out_line("|| ", COLOR_INSN);
else
out_line(":: ", COLOR_INSN);
const char *insn2 = insn.get_canon_mnem(ph);
if ( insn2 == NULL )
insn2 = "?";
insn2 += strlen(insn2);
insn2++;
out_line(insn2, COLOR_INSN);
}
else
out_symbol(',');
out_char(' ');
}
// print the operand
out_one_operand(op);
}
// print immediate values
out_immchar_cmts();
flush_outbuf();
}
//--------------------------------------------------------------------------
void tms320c55_t::print_segment_register(outctx_t &ctx, int reg, sel_t value)
{
if ( reg == ph.reg_data_sreg )
return;
char buf[MAX_NUMBUF];
btoa(buf, sizeof(buf), value);
switch ( reg )
{
case ARMS:
if ( value == BADSEL )
break;
ctx.gen_printf(DEFAULT_INDENT,COLSTR(".arms_%s",SCOLOR_ASMDIR), value ? "on":"off");
return;
case CPL:
if ( value == BADSEL )
break;
ctx.gen_printf(DEFAULT_INDENT,COLSTR(".cpl_%s",SCOLOR_ASMDIR), value ? "on":"off");
return;
case DP:
if ( value == BADSEL )
break;
ctx.gen_printf(DEFAULT_INDENT,COLSTR(".dp %s",SCOLOR_ASMDIR), buf);
return;
}
ctx.gen_cmt_line("assume %s = %s", ph.reg_names[reg], buf);
}
//--------------------------------------------------------------------------
// function to produce assume directives
//lint -e{1764} ctx could be const
void tms320c55_t::assumes(outctx_t &ctx)
{
ea_t ea = ctx.insn_ea;
segment_t *seg = getseg(ea);
if ( (inf_get_outflags() & OFLG_GEN_ASSUME) == 0 || seg == NULL )
return;
bool seg_started = (ea == seg->start_ea);
for ( int i = ph.reg_first_sreg; i <= ph.reg_last_sreg; ++i )
{
if ( i == ph.reg_code_sreg )
continue;
sreg_range_t sra;
if ( !get_sreg_range(&sra, ea, i) )
continue;
if ( seg_started || sra.start_ea == ea )
{
sel_t now = get_sreg(ea, i);
sreg_range_t prev;
bool prev_exists = get_sreg_range(&prev, ea-1, i);
if ( seg_started || (prev_exists && get_sreg(prev.start_ea, i) != now) )
print_segment_register(ctx, i, now);
}
}
}
//--------------------------------------------------------------------------
//lint -e{818} seg could be const
void tms320c55_t::segstart(outctx_t &ctx, segment_t *seg) const
{
ea_t ea = seg->start_ea;
segment_t *Srange = getseg(ea);
if ( is_spec_segm(Srange->type) )
return;
qstring sclas;
get_segm_class(&sclas, Srange);
if ( sclas == "CODE" )
ctx.gen_printf(DEFAULT_INDENT, COLSTR(".text", SCOLOR_ASMDIR));
else if ( sclas == "DATA" )
ctx.gen_printf(DEFAULT_INDENT, COLSTR(".data", SCOLOR_ASMDIR));
// gen_printf(DEFAULT_INDENT, COLSTR(".sect %s", SCOLOR_ASMDIR), sname);
if ( Srange->orgbase != 0 )
{
char buf[MAX_NUMBUF];
btoa(buf, sizeof(buf), Srange->orgbase);
ctx.gen_printf(DEFAULT_INDENT, COLSTR("%s %s", SCOLOR_ASMDIR), ash.origin, buf);
}
}
//--------------------------------------------------------------------------
void idaapi segend(outctx_t &, segment_t *)
{
}
//--------------------------------------------------------------------------
void idaapi header(outctx_t &ctx)
{
ctx.gen_header(GH_PRINT_ALL | GH_BYTESEX_HAS_HIGHBYTE);
ctx.gen_empty_line();
ctx.gen_printf(0,COLSTR("MY_BYTE .macro BYTE",SCOLOR_ASMDIR));
ctx.gen_printf(0,COLSTR(" .emsg \"ERROR - Impossible to generate 8bit bytes on this processor. Please convert them to 16bit words.\"",SCOLOR_ASMDIR));
ctx.gen_printf(0,COLSTR(" .endm",SCOLOR_ASMDIR));
ctx.gen_empty_line();
}
//--------------------------------------------------------------------------
void tms320c55_t::footer(outctx_t &ctx) const
{
ctx.gen_printf(DEFAULT_INDENT, COLSTR("%s",SCOLOR_ASMDIR), ash.end);
}
//--------------------------------------------------------------------------
void tms320c55_t::gen_stkvar_def(outctx_t &ctx, const member_t *mptr, sval_t v) const
{
char sign = ' ';
if ( v < 0 )
{
sign = '-';
v = -v;
}
qstring name = get_member_name(mptr->id);
char vstr[MAX_NUMBUF];
btoa(vstr, sizeof(vstr), v);
ctx.out_printf(COLSTR(" %s ",SCOLOR_KEYWORD)
COLSTR("%c%s",SCOLOR_DNUM)
COLSTR(",",SCOLOR_SYMBOL) " "
COLSTR("%s",SCOLOR_LOCNAME),
ash.a_equ,
sign,
vstr,
name.c_str());
}

View File

@@ -0,0 +1,592 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-99 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* E-mail: ig@datarescue.com
*
*
*/
#include <ctype.h>
#include "tms320c55.hpp"
#include <diskio.hpp>
#include <segregs.hpp>
#include <ieee.h>
int data_id;
//--------------------------------------------------------------------------
static const char *const register_names[] =
{
"AC0", // Accumulator
"AC1", // Accumulator
"AC2", // Accumulator
"AC3", // Accumulator
"T0", // Temporary register
"T1", // Temporary register
"T2", // Temporary register
"T3", // Temporary register
"AR0", // Auxiliary register
"AR1", // Auxiliary register
"AR2", // Auxiliary register
"AR3", // Auxiliary register
"AR4", // Auxiliary register
"AR5", // Auxiliary register
"AR6", // Auxiliary register
"AR7", // Auxiliary register
"AC0L", // Accumulator
"AC0H", // Accumulator
"AC0G", // Accumulator
"AC1L", // Accumulator
"AC1H", // Accumulator
"AC1G", // Accumulator
"AC2L", // Accumulator
"AC2H", // Accumulator
"AC2G", // Accumulator
"AC3L", // Accumulator
"AC3H", // Accumulator
"AC3G", // Accumulator
"BK03", // Circular buffer size register
"BK47", // Circular buffer size register
"BKC", // Circular buffer size register
"BRC0", // Block-repeat counter
"BRC1", // Block-repeat counter
"BRS1", // BRC1 save register
"BSA01", // Circulat buffer start address register
"BSA23", // Circulat buffer start address register
"BSA45", // Circulat buffer start address register
"BSA67", // Circulat buffer start address register
"BSAC", // Circulat buffer start address register
"CDP", // Coefficient data pointer (low part of XCDP)
"CDPH", // High part of XCDP
"CFCT", // Control-flow contect register
"CSR", // Computed single-repeat register
"DBIER0", // Debug interrupt enable register
"DBIER1", // Debug interrupt enable register
// DP Data page register (low part of XDP)
// DPH High part of XDP
"IER0", // Interrupt enable register
"IER1", // Interrupt enable register
"IFR0", // Interrupt flag register
"IFR1", // Interrupt flag register
"IVPD",
"IVPH",
"PC", // Program counter
// PDP Peripheral data page register
"PMST",
"REA0", // Block-repeat end address register
"REA0L", // Block-repeat end address register
"REA0H", // Block-repeat end address register
"REA1", // Block-repeat end address register
"REA1L", // Block-repeat end address register
"REA1H", // Block-repeat end address register
"RETA", // Return address register
"RPTC", // Single-repeat counter
"RSA0", // Block-repeat start address register
"RSA0L", // Block-repeat start address register
"RSA0H", // Block-repeat start address register
"RSA1", // Block-repeat start address register
"RSA1L", // Block-repeat start address register
"RSA1H", // Block-repeat start address register
"SP", // Data stack pointer
"SPH", // High part of XSP and XSSP
"SSP", // System stack pointer
"ST0", // Status register
"ST1", // Status register
"ST0_55", // Status register
"ST1_55", // Status register
"ST2_55", // Status register
"ST3_55", // Status register
"TRN0", // Transition register
"TRN1", // Transition register
"XAR0", // Extended auxiliary register
"XAR1", // Extended auxiliary register
"XAR2", // Extended auxiliary register
"XAR3", // Extended auxiliary register
"XAR4", // Extended auxiliary register
"XAR5", // Extended auxiliary register
"XAR6", // Extended auxiliary register
"XAR7", // Extended auxiliary register
"XCDP", // Extended coefficient data pointer
"XDP", // Extended data page register
"XPC", // Extended program counter
"XSP", // Extended data stack pointer
"XSSP", // Extended system stack pointer
"MDP", // Main Data page pointer (direct memory access / indirect from CDP)
"MDP05", // Main Data page pointer (indirect AR[0-5])
"MDP67", // Main Data page pointer (indirect AR[6-7])
// flags
"ACOV2",
"ACOV3",
"TC1",
"TC2",
"CARRY",
"ACOV0",
"ACOV1",
"BRAF",
"XF",
"HM",
"INTM",
"M40",
"SATD",
"SXMD",
"C16",
"FRCT",
"C54CM",
"DBGM",
"EALLOW",
"RDM",
"CDPLC",
"AR7LC",
"AR6LC",
"AR5LC",
"AR4LC",
"AR3LC",
"AR2LC",
"AR1LC",
"AR0LC",
"CAFRZ",
"CAEN",
"CACLR",
"HINT",
"CBERR",
"MPNMC",
"SATA",
"CLKOFF",
"SMUL",
"SST",
"BORROW",
// segment registers
"ARMS", // AR indirect operands available
"CPL", // Compiler mode
"DP", // Data page pointer
"DPH", // Data page
"PDP", // Peripheral data page register
"cs","ds" // virtual registers for code and data segments
};
//--------------------------------------------------------------------------
static const uchar retcode_0[] = { 0x48, 0x04 }; // ret
static const uchar retcode_1[] = { 0x48, 0x05 }; // reti
static const bytes_t retcodes[] =
{
{ sizeof(retcode_0), retcode_0 },
{ sizeof(retcode_1), retcode_1 },
{ 0, NULL }
};
//-----------------------------------------------------------------------
// TMS320C55 ASM
//-----------------------------------------------------------------------
static const asm_t masm55 =
{
AS_COLON|AS_N2CHR|ASH_HEXF0|ASD_DECF0|ASO_OCTF5|ASB_BINF0|AS_ONEDUP,
0,
"MASM55",
0,
NULL, // header lines
NULL, // org
".end", // end
";", // comment string
'"', // string delimiter
'\'', // char delimiter
"'\"", // special symbols in char and string constants
".pstring", // ascii string directive
"MY_BYTE", // byte directive
".word", // word directive
".long", // double words
NULL, // qwords
NULL, // oword (16 bytes)
".float", // float (4 bytes)
NULL, // double (8 bytes)
NULL, // tbyte (10/12 bytes)
NULL, // packed decimal real
NULL, // arrays (#h,#d,#v,#s(...)
".space 8*%s",// uninited arrays
".asg", // equ
NULL, // 'seg' prefix (example: push seg seg001)
"$", // current IP (instruction pointer)
NULL, // func_header
NULL, // func_footer
".global", // "public" name keyword
NULL, // "weak" name keyword
".ref", // "extrn" name keyword
NULL, // "comm" (communal variable)
NULL, // get_type_name
".align", // "align" keyword
'(', ')', // lbrace, rbrace
"%", // mod
"&", // and
"|", // or
"^", // xor
"~", // not
"<<", // shl
">>", // shr
NULL, // sizeof
AS2_STRINV // invert string byte order
};
static const asm_t *const asms[] = { &masm55, NULL };
//--------------------------------------------------------------------------
const char *tms320c55_t::find_sym(ea_t address)
{
const ioport_t *port = find_ioport(ioh.ports, address);
return port ? port->name.c_str() : NULL;
}
//--------------------------------------------------------------------------
static int idaapi choose_device(int, form_actions_t &fa)
{
tms320c55_t &pm = *(tms320c55_t *)fa.get_ud();
if ( choose_ioport_device(&pm.ioh.device, cfgname) )
pm.ioh.set_device_name(pm.ioh.device.c_str(), IORESP_ALL);
return 0;
}
//--------------------------------------------------------------------------
const char *tms320c55_t::set_idp_options(
const char *keyword,
int value_type,
const void *value,
bool idb_loaded)
{
if ( keyword == NULL )
{
static const char form[] =
"HELP\n"
"TMS320C55 specific options\n"
"\n"
" Use I/O definitions \n"
"\n"
" If this option is on, IDA will use I/O definitions\n"
" from the configuration file into a macro instruction.\n"
"\n"
" Detect memory mapped registers \n"
"\n"
" If this option is on, IDA will replace addresses\n"
" by an equivalent memory mapped register.\n"
"\n"
"ENDHELP\n"
"TMS320C55 specific options\n"
"%*\n"
" <Use ~I~/O definitions:C>\n"
" <Detect memory mapped ~r~egisters:C>>\n"
"\n"
" <~C~hoose device name:B:0::>\n"
"\n"
"\n";
CASSERT(sizeof(idpflags) == sizeof(ushort));
ask_form(form, this, &idpflags, choose_device);
}
else
{
if ( value_type != IDPOPT_BIT )
return IDPOPT_BADTYPE;
if ( strcmp(keyword, "TMS320C55_IO") == 0 )
{
setflag(idpflags, TMS320C55_IO, *(int*)value != 0);
}
else if ( strcmp(keyword, "TMS320C55_MMR") == 0 )
{
setflag(idpflags, TMS320C55_MMR, *(int*)value != 0);
}
else
{
return IDPOPT_BADKEY;
}
}
if ( idb_loaded )
save_idpflags();
return IDPOPT_OK;
}
//--------------------------------------------------------------------------
static const proctype_t ptypes[] =
{
TMS320C55
};
//--------------------------------------------------------------------------
void tms320c55_t::load_from_idb()
{
ptype = ptypes[ph.get_proc_index()];
ioh.restore_device();
if ( ioh.device.empty() )
{
read_ioports(&ioh.ports, &ioh.device, cfgname);
helper.supset(-1, ioh.device.c_str());
}
idpflags = (ushort)helper.altval(-1);
}
//----------------------------------------------------------------------
// This old-style callback only returns the processor module object.
static ssize_t idaapi notify(void *, int msgid, va_list)
{
if ( msgid == processor_t::ev_get_procmod )
return size_t(SET_MODULE_DATA(tms320c55_t));
return 0;
}
//--------------------------------------------------------------------------
ssize_t idaapi tms320c55_t::on_event(ssize_t msgid, va_list va)
{
int code = 0;
switch ( msgid )
{
case processor_t::ev_init:
helper.create(PROCMOD_NODE_NAME);
inf_set_be(true); // MSB first
break;
case processor_t::ev_term:
ioh.ports.clear();
clr_module_data(data_id);
break;
case processor_t::ev_newfile: // new file loaded
{
read_ioports(&ioh.ports, &ioh.device, cfgname);
helper.supset(-1, ioh.device.c_str());
save_idpflags();
{
set_default_sreg_value(NULL, ARMS, 0);
set_default_sreg_value(NULL, CPL, 1);
for ( int i = DP; i <= rVds; i++ )
set_default_sreg_value(NULL, i, 0);
}
static const char *const informations =
"AUTOHIDE REGISTRY\n"
"Default values of flags and registers:\n"
"\n"
"ARMS bit = 0 (DSP mode operands).\n"
"CPL bit = 1 (SP direct addressing mode).\n"
"DP register = 0 (Data Page register)\n"
"DPH register = 0 (High part of EXTENDED Data Page Register)\n"
"PDP register = 0 (Peripheral Data Page register)\n"
"\n"
"You can change the register values by pressing Alt-G\n"
"(Edit, Segments, Change segment register value)\n";
info(informations);
break;
}
case processor_t::ev_oldfile: // old file loaded
ioh.upgrade_device_index();
// fall through
case processor_t::ev_ending_undo:
load_from_idb();
break;
case processor_t::ev_newprc: // new processor type
{
ptype = ptypes[va_arg(va, int)];
// bool keep_cfg = va_argi(va, bool);
switch ( ptype )
{
case TMS320C55:
break;
default:
error("interr: setprc");
}
}
break;
case processor_t::ev_newasm: // new assembler type
break;
case processor_t::ev_creating_segm: // new segment
break;
case processor_t::ev_get_stkvar_scale_factor:
return 2;
case processor_t::ev_out_mnem:
{
outctx_t *ctx = va_arg(va, outctx_t *);
out_mnem(*ctx);
return 1;
}
case processor_t::ev_out_header:
{
outctx_t *ctx = va_arg(va, outctx_t *);
header(*ctx);
return 1;
}
case processor_t::ev_out_footer:
{
outctx_t *ctx = va_arg(va, outctx_t *);
footer(*ctx);
return 1;
}
case processor_t::ev_out_segstart:
{
outctx_t *ctx = va_arg(va, outctx_t *);
segment_t *seg = va_arg(va, segment_t *);
segstart(*ctx, seg);
return 1;
}
case processor_t::ev_out_segend:
{
outctx_t *ctx = va_arg(va, outctx_t *);
segment_t *seg = va_arg(va, segment_t *);
segend(*ctx, seg);
return 1;
}
case processor_t::ev_out_assumes:
{
outctx_t *ctx = va_arg(va, outctx_t *);
assumes(*ctx);
return 1;
}
case processor_t::ev_ana_insn:
{
insn_t *out = va_arg(va, insn_t *);
return ana(out);
}
case processor_t::ev_emu_insn:
{
const insn_t *insn = va_arg(va, const insn_t *);
return emu(*insn) ? 1 : -1;
}
case processor_t::ev_out_insn:
{
outctx_t *ctx = va_arg(va, outctx_t *);
out_insn(*ctx);
return 1;
}
case processor_t::ev_out_operand:
{
outctx_t *ctx = va_arg(va, outctx_t *);
const op_t *op = va_arg(va, const op_t *);
return out_opnd(*ctx, *op) ? 1 : -1;
}
case processor_t::ev_can_have_type:
{
const op_t *op = va_arg(va, const op_t *);
return can_have_type(*op) ? 1 : -1;
}
case processor_t::ev_create_func_frame:
{
func_t *pfn = va_arg(va, func_t *);
create_func_frame(pfn);
return 1;
}
case processor_t::ev_gen_stkvar_def:
{
outctx_t *ctx = va_arg(va, outctx_t *);
const member_t *mptr = va_arg(va, const member_t *);
sval_t v = va_arg(va, sval_t);
gen_stkvar_def(*ctx, mptr, v);
return 1;
}
case processor_t::ev_set_idp_options:
{
const char *keyword = va_arg(va, const char *);
int value_type = va_arg(va, int);
const char *value = va_arg(va, const char *);
const char **errmsg = va_arg(va, const char **);
bool idb_loaded = va_argi(va, bool);
const char *ret = set_idp_options(keyword, value_type, value, idb_loaded);
if ( ret == IDPOPT_OK )
return 1;
if ( errmsg != NULL )
*errmsg = ret;
return -1;
}
case processor_t::ev_is_align_insn:
{
ea_t ea = va_arg(va, ea_t);
return is_align_insn(ea);
}
default:
break;
}
return code;
}
//-----------------------------------------------------------------------
#define FAMILY "TMS320C55x Series:"
static const char *const shnames[] =
{ "TMS32055",
NULL
};
static const char *const lnames[] =
{
FAMILY"Texas Instruments TMS320C55",
NULL
};
//-----------------------------------------------------------------------
// Processor Definition
//-----------------------------------------------------------------------
processor_t LPH =
{
IDP_INTERFACE_VERSION, // version
PLFM_TMS320C55, // id
// flag
PRN_HEX
| PR_SEGS
| PR_SGROTHER
| PR_SCALE_STKVARS,
// flag2
PR2_IDP_OPTS, // the module has processor-specific configuration options
8, // 8 bits in a byte for code segments
8, // 8 bits in a byte for other segments
shnames,
lnames,
asms,
notify,
register_names, // Register names
qnumber(register_names), // Number of registers
ARMS, // first
rVds, // last
1, // size of a segment register
rVcs, rVds,
NULL, // No known code start sequences
retcodes,
TMS320C55_null,
TMS320C55_last,
Instructions, // instruc
0, // int tbyte_size; -- doesn't exist
{ 0,7,15,19 }, // char real_width[4];
// number of symbols after decimal point
// 2byte float (0-does not exist)
// normal float
// normal double
// long double
TMS320C55_ret, // Icode of return instruction. It is ok to give any of possible return instructions
};

View File

@@ -0,0 +1,26 @@
;
; This file defines SFR names and bit names for TMS320C55 processors.
;
; This file can be configured for different devices.
; At the beginning of the file there are definitions common for all devices
; Device-specific definitions are introduced by
;
; .devicename
;
; line. Also an optional directive
;
; .default=devicename
;
; designates the default device name.
;
.default TMS320C55
SAMPLE 0x1
;-------------------------------
; Device specific definitions
.TMS320C55
; insert definitions here

View File

@@ -0,0 +1,423 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-99 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* E-mail: ig@datarescue.com
*
*
*/
#ifndef _TMS320C55_HPP
#define _TMS320C55_HPP
#include "../idaidp.hpp"
#include <diskio.hpp>
#include "ins.hpp"
#include "../iohandler.hpp"
// #define TMS320C55_NO_NAME_NO_REF
//------------------------------------------------------------------
enum regnum_t ENUM_SIZE(uint16)
{
AC0, // Accumulator
AC1, // Accumulator
AC2, // Accumulator
AC3, // Accumulator
T0, // Temporary register
T1, // Temporary register
T2, // Temporary register
T3, // Temporary register
AR0, // Auxiliary register
AR1, // Auxiliary register
AR2, // Auxiliary register
AR3, // Auxiliary register
AR4, // Auxiliary register
AR5, // Auxiliary register
AR6, // Auxiliary register
AR7, // Auxiliary register
AC0L, // Accumulator
AC0H, // Accumulator
AC0G, // Accumulator
AC1L, // Accumulator
AC1H, // Accumulator
AC1G, // Accumulator
AC2L, // Accumulator
AC2H, // Accumulator
AC2G, // Accumulator
AC3L, // Accumulator
AC3H, // Accumulator
AC3G, // Accumulator
BK03, // Circular buffer size register
BK47, // Circular buffer size register
BKC, // Circular buffer size register
BRC0, // Block-repeat counter
BRC1, // Block-repeat counter
BRS1, // BRC1 save register
BSA01, // Circulat buffer start address register
BSA23, // Circulat buffer start address register
BSA45, // Circulat buffer start address register
BSA67, // Circulat buffer start address register
BSAC, // Circulat buffer start address register
CDP, // Coefficient data pointer (low part of XCDP)
CDPH, // High part of XCDP
CFCT, // Control-flow contect register
CSR, // Computed single-repeat register
DBIER0, // Debug interrupt enable register
DBIER1, // Debug interrupt enable register
// DP Data page register (low part of XDP)
// DPH High part of XDP
IER0, // Interrupt enable register
IER1, // Interrupt enable register
IFR0, // Interrupt flag register
IFR1, // Interrupt flag register
IVPD,
IVPH,
PC, // Program counter
// PDP Peripheral data page register
PMST,
REA0, // Block-repeat end address register
REA0L, // Block-repeat end address register
REA0H, // Block-repeat end address register
REA1, // Block-repeat end address register
REA1L, // Block-repeat end address register
REA1H, // Block-repeat end address register
RETA, // Return address register
RPTC, // Single-repeat counter
RSA0, // Block-repeat start address register
RSA0L, // Block-repeat start address register
RSA0H, // Block-repeat start address register
RSA1, // Block-repeat start address register
RSA1L, // Block-repeat start address register
RSA1H, // Block-repeat start address register
SP, // Data stack pointer
SPH, // High part of XSP and XSSP
SSP, // System stack pointer
ST0, // Status register
ST1, // Status register
ST0_55, // Status register
ST1_55, // Status register
ST2_55, // Status register
ST3_55, // Status register
TRN0, // Transition register
TRN1, // Transition register
XAR0, // Extended auxiliary register
XAR1, // Extended auxiliary register
XAR2, // Extended auxiliary register
XAR3, // Extended auxiliary register
XAR4, // Extended auxiliary register
XAR5, // Extended auxiliary register
XAR6, // Extended auxiliary register
XAR7, // Extended auxiliary register
XCDP, // Extended coefficient data pointer
XDP, // Extended data page register
XPC, // Extended program counter
XSP, // Extended data stack pointer
XSSP, // Extended system stack pointer
// these seem to be an old way of what is now DPH/CDPH/AR0H..AR7H
// i.e. supply bits 22:16 of the address for specific situations)
MDP, // Main Data page pointer (direct memory access / indirect from CDP)
MDP05, // Main Data page pointer (indirect AR[0-5])
MDP67, // Main Data page pointer (indirect AR[6-7])
// flags
ACOV2,
ACOV3,
TC1,
TC2,
CARRY,
ACOV0,
ACOV1,
BRAF,
XF,
HM,
INTM,
M40,
SATD,
SXMD,
C16,
FRCT,
C54CM,
DBGM,
EALLOW,
RDM,
CDPLC,
AR7LC,
AR6LC,
AR5LC,
AR4LC,
AR3LC,
AR2LC,
AR1LC,
AR0LC,
CAFRZ,
CAEN,
CACLR,
HINT,
CBERR,
MPNMC,
SATA,
CLKOFF,
SMUL,
SST,
BORROW,
// segment registers
ARMS, // AR indirect operands available
CPL, // Compiler mode
DP, // Data page pointer
DPH, // Data page
PDP, // Peripheral data page register
rVcs, rVds, // virtual registers for code and data segments
};
//------------------------------------------------------------------
// 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)
//------------------------------------------------------------------
#define Parallel segpref // number of operands for the first line of a parallel instruction
#define TMS_PARALLEL_BIT -1
#define SpecialModes auxpref_u8[0]
#define TMS_MODE_USER_PARALLEL 0x1 // user parallel bit (E) is set
#define TMS_MODE_LR 0x2 // LR postfix
#define TMS_MODE_CR 0x4 // CR postfix
#define TMS_MODE_SIMULATE_USER_PARALLEL 0x8 // the instruction simulate two instructions linked by a user parallelism
#define OpMem auxpref_u8[1]
// complex operands
// for o_reg, o_imm, o_mem
#define tms_shift specval_shorts.low // operand << value
#define TMS_OP_SHIFT_NULL 0 // no shift
#define TMS_OP_SHIFT_TYPE 0x7FFF
#define TMS_OP_SHIFTL_IMM 1 // operand << #...
#define TMS_OP_SHIFTL_REG 2 // operand << reg
#define TMS_OP_SHIFTR_IMM 3 // operand >> #...
#define TMS_OP_EQ 4 // operand == #...
#define TMS_OP_NEQ 5 // operand != #...
#define TMS_OP_SHIFT_OUT 0x8000 // functions(...) << ... (default = functions(... << ...))
#define tms_shift_value specval_shorts.high
// for o_reg, o_mem
#define tms_modifier specflag2
#define TMS_MODIFIER_NULL 0
// o_reg
#define TMS_MODIFIER_REG 1 // *reg
#define TMS_MODIFIER_REG_P 2 // *reg+
#define TMS_MODIFIER_REG_M 3 // *reg-
#define TMS_MODIFIER_REG_P_T0 4 // *(reg+T0)
#define TMS_MODIFIER_REG_P_T1 5 // *(reg+T1)
#define TMS_MODIFIER_REG_M_T0 6 // *(reg-T0)
#define TMS_MODIFIER_REG_M_T1 7 // *(reg-T1)
#define TMS_MODIFIER_REG_T0 8 // *reg(T0)
#define TMS_MODIFIER_REG_OFFSET 9 // *reg(#value)
#define TMS_MODIFIER_P_REG_OFFSET 10 // *+reg(#value)
#define TMS_MODIFIER_REG_SHORT_OFFSET 11 // *reg(short(#value))
#define TMS_MODIFIER_REG_T1 12 // *reg(T1)
#define TMS_MODIFIER_P_REG 13 // *+reg
#define TMS_MODIFIER_M_REG 14 // *-reg
#define TMS_MODIFIER_REG_P_T0B 15 // *(reg+T0B)
#define TMS_MODIFIER_REG_M_T0B 16 // *(reg-T0B)
// o_mem, o_io
#define TMS_MODIFIER_DMA 1 // @addr
#define TMS_MODIFIER_ABS16 2 // *abs16(#addr)
#define TMS_MODIFIER_PTR 3 // *(#addr)
#define TMS_MODIFIER_MMAP 4 // mmap()
#define TMS_MODIFIER_PORT 5 // port(#addr)
#define TMS_MODIFIER_PORT_AT 6 // port(@addr)
// for o_reg, o_mem, o_io
#define tms_operator1 specflag3 // operators sorted by priority order
#define tms_operator2 specflag4
#define TMS_OPERATORS_SIZE 13
#define TMS_OPERATOR_NULL 0x0000
#define TMS_OPERATOR_T3 0x0001 // T3=xxx
#define TMS_OPERATOR_NOT 0x0002 // !xxx
#define TMS_OPERATOR_UNS 0x0004 // uns(xxx)
#define TMS_OPERATOR_DBL 0x0008 // dbl(xxx)
#define TMS_OPERATOR_RND 0x0010 // rnd(xxx)
#define TMS_OPERATOR_PAIR 0x0020 // pair(xxx)
#define TMS_OPERATOR_LO 0x0040 // lo(xxx)
#define TMS_OPERATOR_HI 0x0080 // hi(xxx)
#define TMS_OPERATOR_LB 0x0100 // low_byte(xxx)
#define TMS_OPERATOR_HB 0x0200 // high_byte(xxx)
#define TMS_OPERATOR_SAT 0x0400 // saturate(xxx)
#define TMS_OPERATOR_DUAL 0x0800 // dual(xxx)
#define TMS_OPERATOR_PORT 0x1000 // port(xxx)
// for o_imm
#define tms_signed specflag1
#define tms_prefix specflag2
// for o_mem (real address = tms_reg_h : tms_reg_p + addr)
#define tms_regH value_shorts.low
#define tms_regP value_shorts.high
#define o_cond o_idpspec0
#define o_shift o_idpspec1
#define o_relop o_idpspec2
#define tms_relop specflag1 // relational operator
#define tms_relop_type specflag2 // o_reg, o_imm
#define TMS_RELOP_REG 1 // operand << #...
#define TMS_RELOP_IMM 2 // operand << reg
// value will contain register or immediate
#define o_io o_idpspec3
//------------------------------------------------------------------
// processor types
typedef uchar proctype_t;
const proctype_t TMS320C55 = 0;
//------------------------------------------------------------------
#define TAG_SDUAL '2' // helper.altval(ea, '2') == length of the first part of sdual instruction
#define TMS320C55_IO 0x0001 // use I/O definitions
#define TMS320C55_MMR 0x0002 // use memory mapped registers
//------------------------------------------------------------------
const char *const cfgname = "tms320c55.cfg";
struct tms320c55_iohandler_t : public iohandler_t
{
struct tms320c55_t &pm;
qstring errbuf;
tms320c55_iohandler_t(tms320c55_t &_pm, netnode &nn) : iohandler_t(nn), pm(_pm) {}
void get_cfg_filename(char *buf, size_t bufsize) override
{
qstrncpy(buf, cfgname, bufsize);
}
};
struct mask_t;
class bytes_c;
struct tms320c55_t : public procmod_t
{
netnode helper;
tms320c55_iohandler_t ioh = tms320c55_iohandler_t(*this, helper);
ushort idpflags = TMS320C55_IO|TMS320C55_MMR;
proctype_t ptype = TMS320C55; // contains processor type
bool flow = false;
char optional_op = -1; // ana: index of an optional operand
ssize_t idaapi on_event(ssize_t msgid, va_list va) override;
const char *find_sym(ea_t address);
const char *idaapi set_idp_options(
const char *keyword,
int value_type,
const void * value,
bool idb_loaded);
int ana(insn_t *insn);
void process_masks(
insn_t &insn,
const mask_t *masks,
ushort itype_null,
bytes_c &bytes,
char lbytesize = 8);
bool process_masks_operand(
insn_t &insn,
const mask_t *mask,
int64 code,
int64 op_mask_n,
unsigned *p_opnum,
bool bTest);
int emu(const insn_t &insn);
void handle_operand(const insn_t &insn, const op_t &op, flags_t F, bool use);
int 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 load_from_idb();
};
extern int data_id;
#define PROCMOD_NODE_NAME "$ tms320c54"
#define PROCMOD_NAME tms320c55
const char *find_sym(ea_t address);
//------------------------------------------------------------------
void idaapi header(outctx_t &ctx);
void idaapi segend(outctx_t &ctx, segment_t *seg);
void idaapi data(outctx_t &ctx);
bool idaapi create_func_frame(func_t *pfn);
int idaapi is_align_insn(ea_t ea);
bool idaapi can_have_type(const op_t &op);
ea_t calc_io_mem(const insn_t &insn, const op_t &op);
ea_t calc_data_mem(const insn_t &insn, const op_t &op);
inline ea_t calc_code_mem(const insn_t &insn, ea_t ea)
{
return to_ea(insn.cs, ea);
}
#endif // _TMS320C55_HPP