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,435 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-99 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* E-mail: ig@datarescue.com
*
*
*/
#include "tms320c54.hpp"
#include <segregs.hpp>
#include <frame.hpp>
//------------------------------------------------------------------------
ea_t calc_code_mem(const insn_t &insn, ea_t ea, bool is_near)
{
ea_t rv;
if ( is_near )
{
sel_t xpc = get_sreg(insn.ea, XPC);
if ( xpc == BADSEL )
xpc = 0;
rv = ((xpc & 0x7F) << 16) | (ea & 0xFFFF);
}
else
{
rv = to_ea(insn.cs, ea);
}
return use_mapping(rv);
}
//------------------------------------------------------------------------
ea_t tms320c54_t::calc_data_mem(const insn_t &insn, ea_t ea, bool is_mem) const
{
ea_t rv;
if ( is_mem )
{
sel_t dp = get_sreg(insn.ea, DP);
if ( dp == BADSEL )
return BADSEL;
rv = ((dp & 0x1FF) << 7) | (ea & 0x7F);
}
else
{
rv = ea;
}
rv += dataseg;
return use_mapping(rv);
}
//----------------------------------------------------------------------
regnum_t tms320c54_t::get_mapped_register(ea_t ea) const
{
if ( idpflags & TMS320C54_MMR )
{
switch ( ea-dataseg )
{
case 0x00: return IMR;
case 0x01: return IFR;
case 0x06: return ST0;
case 0x07: return ST1;
case 0x08: return AL;
case 0x09: return AH;
case 0x0A: return AG;
case 0x0B: return BL;
case 0x0C: return BH;
case 0x0D: return BG;
case 0x0E: return T;
case 0x0F: return TRN;
case 0x10: return AR0;
case 0x11: return AR1;
case 0x12: return AR2;
case 0x13: return AR3;
case 0x14: return AR4;
case 0x15: return AR5;
case 0x16: return AR6;
case 0x17: return AR7;
case 0x18: return SP;
case 0x19: return BK;
case 0x1A: return BRC;
case 0x1B: return RSA;
case 0x1C: return REA;
case 0x1D: return PMST;
case 0x1E: return XPC;
default: return rnone;
}
}
else
return rnone;
}
//----------------------------------------------------------------------
static void process_imm(const insn_t &insn, const op_t &x, flags_t F)
{
set_immd(insn.ea);
if ( is_defarg(F, x.n) )
return; // if already defined by user
switch ( insn.itype )
{
case TMS320C54_cmpm:
case TMS320C54_bitf:
case TMS320C54_andm:
case TMS320C54_orm:
case TMS320C54_xorm:
case TMS320C54_addm:
case TMS320C54_st:
case TMS320C54_stm:
case TMS320C54_rpt:
case TMS320C54_ld3:
case TMS320C54_mpy2:
case TMS320C54_rptz:
case TMS320C54_add3:
case TMS320C54_sub3:
case TMS320C54_and3:
case TMS320C54_or3:
case TMS320C54_xor3:
case TMS320C54_mac2:
op_num(insn.ea, x.n);
}
}
//----------------------------------------------------------------------
void tms320c54_t::handle_operand(const insn_t &insn, const op_t &x, flags_t F, bool use)
{
switch ( x.type )
{
case o_bit:
case o_reg:
case o_cond8:
case o_cond2:
return;
case o_near:
case o_far:
{
if ( insn.itype != TMS320C54_rptb && insn.itype != TMS320C54_rptbd )
{
cref_t ftype = fl_JN;
ea_t ea = calc_code_mem(insn, x.addr, x.type == o_near);
if ( has_insn_feature(insn.itype, CF_CALL) )
{
if ( !func_does_return(ea) )
flow = false;
ftype = fl_CN;
}
#ifndef TMS320C54_NO_NAME_NO_REF
if ( x.dtype == dt_byte )
insn.add_dref(ea, x.offb, dr_R);
else
insn.add_cref(ea, x.offb, ftype);
#endif
}
#ifndef TMS320C54_NO_NAME_NO_REF
else // evaluate RPTB[D] loops as dref
insn.add_dref(calc_code_mem(insn, x.addr), x.offb, dr_I);
#endif
}
break;
case o_imm:
QASSERT(10113, use);
process_imm(insn, x, F);
#ifndef TMS320C54_NO_NAME_NO_REF
if ( op_adds_xrefs(F, x.n) )
insn.add_off_drefs(x, dr_O, x.Signed ? OOF_SIGNED : 0);
#endif
break;
case o_mem:
case o_farmem:
case o_mmr:
{
ea_t ea = calc_data_mem(insn, x.addr, x.type == o_mem);
if ( ea != BADADDR )
{
#ifndef TMS320C54_NO_NAME_NO_REF
insn.add_dref(ea, x.offb, use ? dr_R : dr_W);
#endif
insn.create_op_data(ea, x);
}
}
break;
case o_local: // local variables
if ( may_create_stkvars()
&& (get_func(insn.ea) != NULL)
&& insn.create_stkvar(x, x.addr, STKVAR_VALID_SIZE) )
{
op_stkvar(insn.ea, x.n);
}
break;
case o_displ:
set_immd(insn.ea);
break;
default:
warning("interr: emu2 address:%a operand:%d type:%d", insn.ea, x.n, x.type);
}
}
//----------------------------------------------------------------------
// is the previous instruction a delayed jump ?
//
// The following array shows all delayed instructions (xxx[D])
// who are required to always stop.
//
// Z = 1 : delay instruction bit
//
// BRANCH INSTRUCTIONS
//
// TMS320C54_bd, // Branch Unconditionally 1111 00Z0 0111 0011 16-bit constant B[D] pmad
// TMS320C54_baccd, // Branch to Location Specified by Accumulator 1111 01ZS 1110 0010 BACC[D] src
// TMS320C54_fbd, // Far Branch Unconditionally 1111 10Z0 1 7bit constant=pmad(22-16) 16-bit constant=pmad(15-0) FB[D] extpmad
// TMS320C54_fbaccd, // Far Branch to Location Specified by Accumulator 1111 01ZS 1110 0110 FBACC[D] src
//
// RETURN INSTRUCTIONS
//
// TMS320C54_fretd, // Far Return 1111 01Z0 1110 0100 FRET[D]
// TMS320C54_freted, // Enable Interrupts and Far Return From Interrupt 1111 01Z0 1110 0101 FRETE[D]
// TMS320C54_retd, // Return 1111 11Z0 0000 0000 RET[D]
// TMS320C54_reted, // Enable Interrupts and Return From Interrupt 1111 01Z0 1110 1011 RETE[D]
// TMS320C54_retfd, // Enable Interrupts and Fast Return From Interrupt 1111 01Z0 1001 1011 RETF[D]
static bool delayed_stop(const insn_t &insn, flags_t F)
{
if ( !is_flow(F) )
return false;
if ( insn.size == 0 || insn.size > 2 )
return false;
int sub = 2 - insn.size; // backward offset to skip the previous 1-word instruction in the case of 2 consecutive 1-word instructions
// first, we analyze 1-word instructions
ea_t ea = insn.ea - sub - 1;
if ( is_code(get_flags(ea)) )
{
int code = get_wide_byte(ea); // get the instruction word
switch ( code )
{
case 0xF6E2: // TMS320C54_baccd, // Branch to Location Specified by Accumulator 1111 01ZS 1110 0010 BACC[D] src
case 0xF7E2:
case 0xF6E6: // TMS320C54_fbaccd, // Far Branch to Location Specified by Accumulator 1111 01ZS 1110 0110 FBACC[D] src
case 0xF7E6:
case 0xF6E4: // TMS320C54_fretd, // Far Return 1111 01Z0 1110 0100 FRET[D]
case 0xF6E5: // TMS320C54_freted, // Enable Interrupts and Far Return From Interrupt 1111 01Z0 1110 0101 FRETE[D]
case 0xFE00: // TMS320C54_retd, // Return 1111 11Z0 0000 0000 RET[D]
case 0xF6EB: // TMS320C54_reted, // Enable Interrupts and Return From Interrupt 1111 01Z0 1110 1011 RETE[D]
case 0xF69B: // TMS320C54_retfd, // Enable Interrupts and Fast Return From Interrupt 1111 01Z0 1001 1011 RETF[D]
return true;
}
}
// else, we analyze 2-word instructions
ea = insn.ea - sub - 2;
if ( is_code(get_flags(ea)) )
{
int code = get_wide_byte(ea); // get the first instruction word
if ( code == 0xF273 // TMS320C54_bd, // Branch Unconditionally 1111 00Z0 0111 0011 16-bit constant B[D] pmad
|| (code & 0xFF80) == 0xFA80 ) // TMS320C54_fbd, // Far Branch Unconditionally 1111 10Z0 1 7bit constant=pmad(22-16) 16-bit constant=pmad(15-0) FB[D] extpmad
{
return true;
}
}
return false;
}
//----------------------------------------------------------------------
bool is_basic_block_end(const insn_t &insn)
{
flags_t F = get_flags(insn.ea);
if ( delayed_stop(insn, F) )
return true;
return !is_flow(get_flags(insn.ea+insn.size));
}
//----------------------------------------------------------------------
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)
{
// trace SP changes
switch ( insn.itype )
{
case TMS320C54_fret:
case TMS320C54_fretd:
case TMS320C54_frete:
case TMS320C54_freted:
add_stkpnt(insn, 2);
break;
case TMS320C54_ret:
case TMS320C54_retd:
case TMS320C54_rete:
case TMS320C54_reted:
case TMS320C54_retf:
case TMS320C54_retfd:
add_stkpnt(insn, 1);
break;
case TMS320C54_frame:
add_stkpnt(insn, insn.Op1.value);
break;
case TMS320C54_popd:
case TMS320C54_popm:
add_stkpnt(insn, 1);
break;
case TMS320C54_pshd:
case TMS320C54_pshm:
add_stkpnt(insn, -1);
break;
}
}
//----------------------------------------------------------------------
int tms320c54_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_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);
// check for CPL changes
if ( (insn.itype == TMS320C54_rsbx1 || insn.itype == TMS320C54_ssbx1)
&& insn.Op1.type == o_reg && insn.Op1.reg == CPL )
{
int value = insn.itype == TMS320C54_rsbx1 ? 0 : 1;
split_sreg_range(get_item_end(insn.ea), CPL, value, SR_auto);
}
// check for DP changes
if ( insn.itype == TMS320C54_ld2
&& insn.Op1.type == o_imm
&& insn.Op1.dtype == dt_byte
&& insn.Op2.type == o_reg
&& insn.Op2.reg == DP )
{
split_sreg_range(get_item_end(insn.ea), DP, insn.Op1.value & 0x1FF, SR_auto);
}
// determine if the next instruction should be executed
if ( segtype(insn.ea) == SEG_XTRN )
flow = false;
if ( flow && delayed_stop(insn, F) )
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 tms320c54_t::create_func_frame(func_t *pfn) const
{
if ( pfn != NULL )
{
if ( pfn->frame == BADNODE )
{
insn_t insn;
int regsize = 0;
ea_t ea = pfn->start_ea;
while ( ea < pfn->end_ea ) // check for register pushs
{
if ( decode_insn(&insn, ea) < 1 )
break;
if ( insn.itype != TMS320C54_pshm )
break;
if ( insn.Op1.type != o_mem && insn.Op1.type != o_mmr )
break;
if ( get_mapped_register(insn.Op1.addr) == rnone )
break;
regsize++;
ea += insn.size;
}
int localsize = 0;
while ( ea < pfn->end_ea ) // check for frame creation
{
if ( insn.itype == TMS320C54_frame && insn.Op1.type == o_imm )
{
localsize = -(int)insn.Op1.value;
break;
}
ea += insn.size;
if ( decode_insn(&insn, ea) < 1 )
break;
}
add_frame(pfn, localsize+regsize, 0, 0);
}
}
return 0;
}
//----------------------------------------------------------------------
int idaapi tms_get_frame_retsize(const func_t * /*pfn*/)
{
return 1; // 1 'byte' for the return address
}
//----------------------------------------------------------------------
int idaapi is_align_insn(ea_t ea)
{
insn_t insn;
if ( decode_insn(&insn, ea) < 1 )
return 0;
switch ( insn.itype )
{
case TMS320C54_nop:
break;
default:
return 0;
}
return insn.size;
}

View File

@@ -0,0 +1,307 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-99 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* E-mail: ig@datarescue.com
*
*
*/
#include "tms320c54.hpp"
const instruc_t Instructions[] =
{
{ "", 0 }, // Unknown Operation
// ARITHMETIC OPERATIONS
// ADD INSTRUCTIONS
{ "add", CF_CHG1 }, // Add to Accumulator
{ "add", CF_USE1|CF_CHG2 }, // Add to Accumulator
{ "add", CF_USE1|CF_USE2|CF_CHG3 }, // Add to Accumulator
{ "addc", CF_USE1|CF_CHG2 }, // Add to Accumulator With Carry
{ "addm", CF_USE1|CF_CHG2 }, // Add Long-Immediate Value to Memory
{ "adds", CF_USE1|CF_CHG2 }, // Add to Accumulator With Sign-Extension Suppressed
// SUBTRACT INSTRUCTIONS
{ "sub", CF_CHG1 }, // Sub From Accumulator
{ "sub", CF_USE1|CF_CHG2 }, // Sub From Accumulator
{ "sub", CF_USE1|CF_USE2|CF_CHG3 }, // Sub From Accumulator
{ "subb", CF_USE1|CF_CHG2 }, // Sub From Accumulator With Borrow
{ "subc", CF_USE1|CF_CHG2 }, // Subtract Conditionally
{ "subs", CF_USE1|CF_CHG2 }, // Subtract From Accumulator With Sign Extension Suppressed
// MULTIPLY INSTRUCTIONS
{ "mpy", CF_USE1|CF_CHG2 }, // Multiply Without Rounding
{ "mpy", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Without Rounding
{ "mpyr", CF_USE1|CF_CHG2 }, // Multiply With Rounding
{ "mpya", CF_CHG1 }, // Multiply by Accumulator A
{ "mpyu", CF_USE1|CF_CHG2 }, // Multiply Unsigned
{ "squr", CF_USE1|CF_CHG2 }, // Square
// MULTIPLY-ACCUMULATE AND MULTIPLY-SUBTRACT INSTRUCTIONS
{ "mac", CF_USE1|CF_CHG2 }, // Multiply Accumulate Without Rounding
{ "mac", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Accumulate Without Rounding
{ "macr", CF_USE1|CF_CHG2 }, // Multiply Accumulate With Rounding
{ "macr", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Accumulate With Rounding
{ "maca", CF_CHG1 }, // Multiply by Accumulator A and Accumulate Without Rounding
{ "maca", CF_USE1|CF_CHG2 }, // Multiply by Accumulator A and Accumulate Without Rounding
{ "maca", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply by Accumulator A and Accumulate Without Rounding
{ "macar", CF_CHG1 }, // Multiply by Accumulator A and Accumulate With Rounding
{ "macar", CF_USE1|CF_CHG2 }, // Multiply by Accumulator A and Accumulate With Rounding
{ "macar", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply by Accumulator A and Accumulate With Rounding
{ "macd", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply by Program Memory and Accumulate With Delay
{ "macp", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply by Program Memory and Accumulate
{ "macsu", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Signed by Unsigned and Accumulate
{ "mas", CF_USE1|CF_CHG2 }, // Multiply and Subtract Without Rounding
{ "mas", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply and Subtract Without Rounding
{ "masr", CF_USE1|CF_CHG2 }, // Multiply and Subtract With Rounding
{ "masr", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply and Subtract With Rounding
// TMS320C54_mas,
{ "masa", CF_CHG1 }, // Multiply by Accumulator A and Subtract Without Rounding
{ "masa", CF_USE1|CF_CHG2 }, // Multiply by Accumulator A and Subtract Without Rounding
{ "masa", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply by Accumulator A and Subtract Without Rounding
{ "masar", CF_CHG1 }, // Multiply by Accumulator A and Subtract With Rounding
{ "masar", CF_USE1|CF_CHG2 }, // Multiply by Accumulator A and Subtract With Rounding
{ "masar", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply by Accumulator A and Subtract With Rounding
{ "squra", CF_USE1|CF_CHG2 }, // Square and Accumulate
{ "squrs", CF_USE1|CF_CHG2 }, // Square and Subtract
// DOUBLE INSTRUCTIONS
{ "dadd", CF_USE1|CF_CHG2 }, // Double-Precision/Dual 16-Bit Add to Accumulator
{ "dadd", CF_USE1|CF_USE2|CF_CHG3 }, // Double-Precision/Dual 16-Bit Add to Accumulator
{ "dadst", CF_USE1|CF_CHG2 }, // Double-Precision Load With T Add/Dual 16-Bit Load With T Add/Subtract
{ "drsub", CF_USE1|CF_CHG2 }, // Double-Precision/Dual 16-Bit Subtract From Long Word
{ "dsadt", CF_USE1|CF_CHG2 }, // Long-Word Load With T Add/Dual 16-Bit Load With T Subtract/Add
{ "dsub", CF_USE1|CF_CHG2 }, // Double-Precision/Dual 16-Bit Subtract From Accumulator
{ "dsubt", CF_USE1|CF_CHG2 }, // Long-Word Load With T Subtract/Dual 16-Bit Load With T Subtract
// APPLICATION-SPECIFIC INSTRUCTIONS
{ "abdst", CF_USE1|CF_USE2 }, // Absolute distance
{ "abs", CF_CHG1 }, // Absolute Value of Accumulator
{ "abs", CF_USE1|CF_CHG2 }, // Absolute Value of Accumulator
{ "cmpl", CF_CHG1 }, // Complement Accumulator
{ "cmpl", CF_USE1|CF_CHG2 }, // Complement Accumulator
{ "delay", CF_USE1 }, // Memory Delay
{ "exp", CF_USE1 }, // Accumulator Exponent
{ "firs", CF_USE1|CF_USE2 }, // Symmetrical Finite Impulse Response Filter
{ "lms", CF_USE1|CF_USE2 }, // Least Mean Square
{ "max", CF_CHG1 }, // Accumulator Maximum
{ "min", CF_CHG1 }, // Accumulator Minimum
{ "neg", CF_CHG1 }, // Negate Accumulator
{ "neg", CF_USE1|CF_CHG2 }, // Negate Accumulator
{ "norm", CF_CHG1 }, // Normalization
{ "norm", CF_USE1|CF_CHG2 }, // Normalization
{ "poly", CF_USE1 }, // Polynominal Evaluation
{ "rnd", CF_CHG1 }, // Round Accumulator
{ "rnd", CF_USE1|CF_CHG2 }, // Round Accumulator
{ "sat", CF_CHG1 }, // Saturate Accumulator
{ "sqdst", CF_USE1|CF_USE2 }, // Square Distance
// LOGICAL OPERATIONS
// AND INSTRUCTIONS
{ "and", CF_CHG1 }, // AND With Accumulator
{ "and", CF_USE1|CF_CHG2 }, // AND With Accumulator
{ "and", CF_USE1|CF_USE2|CF_CHG3 }, // AND With Accumulator
{ "andm", CF_USE1|CF_CHG2 }, // AND Memory With Long Immediate
// OR INSTRUCTIONS
{ "or", CF_CHG1 }, // OR With Accumulator
{ "or", CF_USE1|CF_CHG2 }, // OR With Accumulator
{ "or", CF_USE1|CF_USE2|CF_CHG3 }, // OR With Accumulator
{ "orm", CF_USE1|CF_CHG2 }, // OR Memory With Constant
// XOR INSTRUCTIONS
{ "xor", CF_CHG1 }, // Exclusive OR With Accumulator
{ "xor", CF_USE1|CF_CHG2 }, // Exclusive OR With Accumulator
{ "xor", CF_USE1|CF_USE2|CF_CHG3 }, // Exclusive OR With Accumulator
{ "xorm", CF_USE1|CF_CHG2 }, // Exclusive OR Memory With Constant
// SHIFT INSTRUCTIONS
{ "rol", CF_CHG1 }, // Rotate Accumulator
{ "roltc", CF_CHG1 }, // Rotate Accumulator Left Using TC
{ "ror", CF_CHG1 }, // Rotate Accumulator Right
{ "sfta", CF_CHG1|CF_USE2 }, // Shift Accumulator Arithmetically
{ "sfta", CF_USE1|CF_USE2|CF_CHG3 }, // Shift Accumulator Arithmetically
{ "sftc", CF_CHG1 }, // Shift Accumulator Conditionally
{ "sftl", CF_CHG1|CF_USE2 }, // Shift Accumulator Logically
{ "sftl", CF_USE1|CF_USE2|CF_CHG3 }, // Shift Accumulator Logically
// TEST INSTRUCTIONS
{ "bit", CF_USE1|CF_USE2 }, // Test Bit
{ "bitf", CF_USE1|CF_USE2 }, // Test Bit Field Specified by Immediate Value
{ "bitt", CF_USE1 }, // Test Bit Specified by T
{ "cmpm", CF_USE1|CF_USE2 }, // Compare Memory With Long Immediate
{ "cmpr", CF_USE1|CF_USE2 }, // Compare Auxiliary Register with AR0
// PROGRAM CONTROL OPERATIONS
// BRANCH INSTRUCTIONS
{ "b", CF_USE1|CF_STOP }, // Branch Unconditionally
{ "bd", CF_USE1 }, // Branch Unconditionally
{ "bacc", CF_USE1|CF_STOP }, // Branch to Location Specified by Accumulator
{ "baccd", CF_USE1 }, // Branch to Location Specified by Accumulator
{ "banz", CF_USE1|CF_USE2 }, // Branch on Auxiliary Register Not Zero
{ "banzd", CF_USE1|CF_USE2 }, // Branch on Auxiliary Register Not Zero
{ "bc", CF_USE1|CF_USE2 }, // Branch Conditionally
{ "bc", CF_USE1|CF_USE2|CF_USE3 }, // Branch Conditionally
{ "bcd", CF_USE1|CF_USE2 }, // Branch Conditionally
{ "bcd", CF_USE1|CF_USE2|CF_USE3 }, // Branch Conditionally
{ "fb", CF_USE1|CF_STOP }, // Far Branch Unconditionally
{ "fbd", CF_USE1 }, // Far Branch Unconditionally
{ "fbacc", CF_USE1 }, // Far Branch to Location Specified by Accumulator
{ "fbaccd", CF_USE1 }, // Far Branch to Location Specified by Accumulator
// CALL INSTRUCTIONS
{ "cala", CF_USE1|CF_CALL }, // Call Subroutine at Location Specified by Accumulator
{ "calad", CF_USE1|CF_CALL }, // Call Subroutine at Location Specified by Accumulator
{ "call", CF_USE1|CF_CALL }, // Call Unconditionally
{ "calld", CF_USE1|CF_CALL }, // Call Unconditionally
{ "cc", CF_USE1|CF_USE2|CF_CALL }, // Call Conditionally
{ "cc", CF_USE1|CF_USE2|CF_USE3|CF_CALL }, // Call Conditionally
{ "ccd", CF_USE1|CF_USE2|CF_CALL }, // Call Conditionally
{ "ccd", CF_USE1|CF_USE2|CF_USE3|CF_CALL }, // Call Conditionally
{ "fcala", CF_USE1|CF_CALL }, // Far Call Subroutine at Location Specified by Accumulator
{ "fcalad", CF_USE1|CF_CALL }, // Far Call Subroutine at Location Specified by Accumulator
{ "fcall", CF_USE1|CF_CALL }, // Far Call Unconditionally
{ "fcalld", CF_USE1|CF_CALL }, // Far Call Unconditionally
// INTERRUPT INSTRUCTIONS
{ "intr", CF_USE1|CF_CALL }, // Software Interrupt
{ "trap", CF_USE1|CF_CALL }, // Software Interrupt
// RETURN INSTRUCTIONS
{ "fret", CF_STOP }, // Far Return
{ "fretd", 0 }, // Far Return
{ "frete", CF_STOP }, // Enable Interrupts and Far Return From Interrupt
{ "freted", 0 }, // Enable Interrupts and Far Return From Interrupt
{ "rc", CF_USE1 }, // Return Conditionally
{ "rc", CF_USE1|CF_USE2 }, // Return Conditionally
{ "rc", CF_USE1|CF_USE2|CF_USE3 }, // Return Conditionally
{ "rcd", CF_USE1 }, // Return Conditionally
{ "rcd", CF_USE1|CF_USE2 }, // Return Conditionally
{ "rcd", CF_USE1|CF_USE2|CF_USE3 }, // Return Conditionally
{ "ret", CF_STOP }, // Return
{ "retd", 0 }, // Return
{ "rete", CF_STOP }, // Enable Interrupts and Far Return From Interrupt
{ "reted", 0 }, // Enable Interrupts and Far Return From Interrupt
{ "retf", CF_STOP }, // Enable Interrupts and Fast Return From Interrupt
{ "retfd", 0 }, // Enable Interrupts and Fast Return From Interrupt
// REPEAT INSTRUCTIONS
{ "rpt", CF_USE1 }, // Repeat Next Instruction
{ "rptb", CF_USE1 }, // Block Repeat
{ "rptbd", CF_USE1 }, // Block Repeat
{ "rptz", CF_CHG1|CF_USE2 }, // Repeat Next Instruction And Clear Accumulator
// STACK MANIPULATING INSTRUCTIONS
{ "frame", CF_USE1 }, // Stack Pointer Immediate Offset
{ "popd", CF_CHG1 }, // Pop Top of Stack to Data Memory
{ "popm", CF_CHG1 }, // Pop Top of Stack to Memory-Mapped Register
{ "pshd", CF_USE1 }, // Push Data-Memory Value Onto Stack
{ "pshm", CF_USE1 }, // Push Memory-Mapped Register Onto Stack
// MISCELLANEOUS PROGRAM-CONTROL INSTRUCTIONS
{ "idle", CF_USE1 }, // Idle Until Interrupt
{ "mar", CF_USE1 }, // Modify Auxiliary Register
{ "nop", 0 }, // No Operation
{ "reset", 0 }, // Software Reset
{ "rsbx", CF_CHG1 }, // Reset Status Register Bit
{ "rsbx", CF_USE1|CF_USE2 }, // Reset Status Register Bit
{ "ssbx", CF_CHG1 }, // Set Status Register Bit
{ "ssbx", CF_USE1|CF_USE2 }, // Set Status Register Bit
{ "xc", CF_USE1|CF_USE2 }, // Execute Conditionally
{ "xc", CF_USE1|CF_USE2|CF_USE3 }, // Execute Conditionally
// LOAD AND STORE OPERATIONS
// LOAD INSTRUCTIONS
{ "dld", CF_USE1|CF_CHG2 }, // Double-Precision/Dual 16-Bit Long-Word Load to Accumulator
{ "ld", CF_CHG1 }, // Load Accumulator With Shift
{ "ld", CF_USE1|CF_CHG2 }, // Load Accumulator With Shift
{ "ld", CF_USE1|CF_USE2|CF_CHG3 }, // Load Accumulator With Shift
{ "ldm", CF_USE1|CF_CHG2 }, // Load Memory-Mapped Register
{ "ldr", CF_USE1|CF_CHG2 }, // Load Memory Value in Accumulator High With Rounding
{ "ldu", CF_USE1|CF_CHG2 }, // Load Unsigned Memory Value
{ "ltd", CF_USE1 }, // Load T and insert Delay
// STORE INSTRUCTIONS
{ "dst", CF_USE1|CF_CHG2 }, // Store Accumulator in Long Word
{ "st", CF_USE1|CF_CHG2 }, // Store T, TRN, or Immediate Value into Memory
{ "sth", CF_USE1|CF_CHG2 }, // Store Accumulator High Into Memory
{ "sth", CF_USE1|CF_USE2|CF_CHG3 }, // Store Accumulator High Into Memory
{ "stl", CF_USE1|CF_CHG2 }, // Store Accumulator Low Into Memory
{ "stl", CF_USE1|CF_USE2|CF_CHG3 }, // Store Accumulator Low Into Memory
{ "stlm", CF_USE1|CF_CHG2 }, // Store Accumulator Low Into Memory-Mapped Register
{ "stm", CF_USE1|CF_CHG2 }, // Store Immediate Value Into Memory-Mapped Register
// CONDITIONAL STORE INSTRUCTIONS
{ "cmps", CF_USE1|CF_CHG2 }, // Compare, Select and Store Maximum
{ "saccd", CF_USE1|CF_CHG2|CF_USE3 }, // Store Accumulator Conditionally
{ "srccd", CF_CHG1|CF_USE2 }, // Store Block Repeat Counter Conditionally
{ "strcd", CF_CHG1|CF_USE2 }, // Store T Conditionally
// PARALLEL LOAD AND STORE INSTRUCTIONS
{ "st", CF_USE1|CF_CHG2|CF_CHG3 }, // Store Accumulator With Parallel Load // TMS320C54_st_ld
// PARALLEL LOAD AND MULTIPLY INSTRUCTIONS
{ "ld", CF_USE1|CF_CHG2|CF_CHG3 }, // Load Accumulator With Parallel Multiply Accumulate Without Rounding // TMS320C54_ld_mac
{ "ld", CF_USE1|CF_CHG2|CF_CHG3 }, // Load Accumulator With Parallel Multiply Accumulate With Rounding // TMS320C54_ld_macr
{ "ld", CF_USE1|CF_CHG2|CF_CHG3 }, // Load Accumulator With Parallel Multiply Subtract Without Rounding // TMS320C54_ld_mas
{ "ld", CF_USE1|CF_CHG2|CF_CHG3 }, // Load Accumulator With Parallel Multiply Subtract With Rounding // TMS320C54_ld_masr
// PARALLEL STORE AND ADD/SUBSTRACT INSTRUCTIONS
{ "st", CF_USE1|CF_CHG2|CF_CHG3 }, // Store Accumulator With Parallel Add // TMS320C54_st_add
{ "st", CF_USE1|CF_CHG2|CF_CHG3 }, // Store Accumulator With Parallel Subtract // TMS320C54_st_sub
// PARALLEL STORE AND MULTIPLY INSTRUCTIONS
{ "st", CF_USE1|CF_CHG2|CF_CHG3 }, // Store Accumulator With Parallel Multiply Accumulate Without Rounding // TMS320C54_st_mac
{ "st", CF_USE1|CF_CHG2|CF_CHG3 }, // Store Accumulator With Parallel Multiply Accumulate With Rounding // TMS320C54_st_macr
{ "st", CF_USE1|CF_CHG2|CF_CHG3 }, // Store Accumulator With Parallel Multiply Subtract Without Rounding // TMS320C54_st_mas
{ "st", CF_USE1|CF_CHG2|CF_CHG3 }, // Store Accumulator With Parallel Multiply Subtract With Rounding // TMS320C54_st_masr
{ "st", CF_USE1|CF_CHG2|CF_CHG3 }, // Store Accumulator With Parallel Multiply // TMS320C54_st_mpy
// MISCELLANEOUS LOAD-TYPE AND STORE-TYPE INSTRUCTIONS
{ "mvdd", CF_USE1|CF_CHG2 }, // Move Data From Data Memory to Data Memory With X,Y Addressing
{ "mvdk", CF_USE1|CF_CHG2 }, // Move Data From Data Memory to Data Memory With Destination Addressing
{ "mvdm", CF_USE1|CF_CHG2 }, // Move Data From Data Memory to Memory-Mapped Register
{ "mvdp", CF_USE1|CF_CHG2 }, // Move Data From Data Memory to Program Memory
{ "mvkd", CF_USE1|CF_CHG2 }, // Move Data From Data Memory to Data Memory With Source Addressing
{ "mvmd", CF_USE1|CF_CHG2 }, // Move Data From Memory-Mapped Register to Data Memory
{ "mvmm", CF_USE1|CF_CHG2 }, // Move Data From Memory-Mapped Register to Memory-Mapped Register
{ "mvpd", CF_USE1|CF_CHG2 }, // Move Data From Program Memory to Data Memory
{ "portr", CF_USE1|CF_USE2 }, // Read Data From Port
{ "portw", CF_USE1|CF_USE2 }, // Write Data to Port
{ "reada", CF_CHG1 }, // Read Program Memory Addressed by Accumulator A and Store in Data Memory
{ "writa", CF_USE1 }, // Write Data to Program Memory Addressed by Accumulator A
};
CASSERT(qnumber(Instructions) == TMS320C54_last);

View File

@@ -0,0 +1,311 @@
/*
* 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)
{
TMS320C54_null = 0, // Unknown Operation
// ARITHMETIC OPERATIONS
// ADD INSTRUCTIONS
TMS320C54_add1, // Add to Accumulator
TMS320C54_add2, // Add to Accumulator
TMS320C54_add3, // Add to Accumulator
TMS320C54_addc, // Add to Accumulator With Carry
TMS320C54_addm, // Add Long-Immediate Value to Memory
TMS320C54_adds, // Add to Accumulator With Sign-Extension Suppressed
// SUBTRACT INSTRUCTIONS
TMS320C54_sub1, // Sub From Accumulator
TMS320C54_sub2, // Sub From Accumulator
TMS320C54_sub3, // Sub From Accumulator
TMS320C54_subb, // Sub From Accumulator With Borrow
TMS320C54_subc, // Subtract Conditionally
TMS320C54_subs, // Subtract From Accumulator With Sign Extension Suppressed
// MULTIPLY INSTRUCTIONS
TMS320C54_mpy2, // Multiply Without Rounding
TMS320C54_mpy3, // Multiply Without Rounding
TMS320C54_mpyr2, // Multiply With Rounding
TMS320C54_mpya, // Multiply by Accumulator A
TMS320C54_mpyu, // Multiply Unsigned
TMS320C54_squr, // Square
// MULTIPLY-ACCUMULATE AND MULTIPLY-SUBTRACT INSTRUCTIONS
TMS320C54_mac2, // Multiply Accumulate Without Rounding
TMS320C54_mac3, // Multiply Accumulate Without Rounding
TMS320C54_macr2, // Multiply Accumulate With Rounding
TMS320C54_macr3, // Multiply Accumulate With Rounding
TMS320C54_maca1, // Multiply by Accumulator A and Accumulate Without Rounding
TMS320C54_maca2, // Multiply by Accumulator A and Accumulate Without Rounding
TMS320C54_maca3, // Multiply by Accumulator A and Accumulate Without Rounding
TMS320C54_macar1, // Multiply by Accumulator A and Accumulate With Rounding
TMS320C54_macar2, // Multiply by Accumulator A and Accumulate With Rounding
TMS320C54_macar3, // Multiply by Accumulator A and Accumulate With Rounding
TMS320C54_macd, // Multiply by Program Memory and Accumulate With Delay
TMS320C54_macp, // Multiply by Program Memory and Accumulate
TMS320C54_macsu, // Multiply Signed by Unsigned and Accumulate
TMS320C54_mas2, // Multiply and Subtract Without Rounding
TMS320C54_mas3, // Multiply and Subtract Without Rounding
TMS320C54_masr2, // Multiply and Subtract With Rounding
TMS320C54_masr3, // Multiply and Subtract With Rounding
// TMS320C54_mas,
TMS320C54_masa1, // Multiply by Accumulator A and Subtract Without Rounding
TMS320C54_masa2, // Multiply by Accumulator A and Subtract Without Rounding
TMS320C54_masa3, // Multiply by Accumulator A and Subtract Without Rounding
TMS320C54_masar1, // Multiply by Accumulator A and Subtract With Rounding
TMS320C54_masar2, // Multiply by Accumulator A and Subtract With Rounding
TMS320C54_masar3, // Multiply by Accumulator A and Subtract With Rounding
TMS320C54_squra, // Square and Accumulate
TMS320C54_squrs, // Square and Subtract
// DOUBLE INSTRUCTIONS
TMS320C54_dadd2, // Double-Precision/Dual 16-Bit Add to Accumulator
TMS320C54_dadd3, // Double-Precision/Dual 16-Bit Add to Accumulator
TMS320C54_dadst, // Double-Precision Load With T Add/Dual 16-Bit Load With T Add/Subtract
TMS320C54_drsub, // Double-Precision/Dual 16-Bit Subtract From Long Word
TMS320C54_dsadt, // Long-Word Load With T Add/Dual 16-Bit Load With T Subtract/Add
TMS320C54_dsub, // Double-Precision/Dual 16-Bit Subtract From Accumulator
TMS320C54_dsubt, // Long-Word Load With T Subtract/Dual 16-Bit Load With T Subtract
// APPLICATION-SPECIFIC INSTRUCTIONS
TMS320C54_abdst, // Absolute distance
TMS320C54_abs1, // Absolute Value of Accumulator
TMS320C54_abs2, // Absolute Value of Accumulator
TMS320C54_cmpl1, // Complement Accumulator
TMS320C54_cmpl2, // Complement Accumulator
TMS320C54_delay, // Memory Delay
TMS320C54_exp, // Accumulator Exponent
TMS320C54_firs, // Symmetrical Finite Impulse Response Filter
TMS320C54_lms, // Least Mean Square
TMS320C54_max, // Accumulator Maximum
TMS320C54_min, // Accumulator Minimum
TMS320C54_neg1, // Negate Accumulator
TMS320C54_neg2, // Negate Accumulator
TMS320C54_norm1, // Normalization
TMS320C54_norm2, // Normalization
TMS320C54_poly, // Polynominal Evaluation
TMS320C54_rnd1, // Round Accumulator
TMS320C54_rnd2, // Round Accumulator
TMS320C54_sat, // Saturate Accumulator
TMS320C54_sqdst, // Square Distance
// LOGICAL OPERATIONS
// AND INSTRUCTIONS
TMS320C54_and1, // AND With Accumulator
TMS320C54_and2, // AND With Accumulator
TMS320C54_and3, // AND With Accumulator
TMS320C54_andm, // AND Memory With Long Immediate
// OR INSTRUCTIONS
TMS320C54_or1, // OR With Accumulator
TMS320C54_or2, // OR With Accumulator
TMS320C54_or3, // OR With Accumulator
TMS320C54_orm, // OR Memory With Constant
// XOR INSTRUCTIONS
TMS320C54_xor1, // Exclusive OR With Accumulator
TMS320C54_xor2, // Exclusive OR With Accumulator
TMS320C54_xor3, // Exclusive OR With Accumulator
TMS320C54_xorm, // Exclusive OR Memory With Constant
// SHIFT INSTRUCTIONS
TMS320C54_rol, // Rotate Accumulator
TMS320C54_roltc, // Rotate Accumulator Left Using TC
TMS320C54_ror, // Rotate Accumulator Right
TMS320C54_sfta2, // Shift Accumulator Arithmetically
TMS320C54_sfta3, // Shift Accumulator Arithmetically
TMS320C54_sftc, // Shift Accumulator Conditionally
TMS320C54_sftl2, // Shift Accumulator Logically
TMS320C54_sftl3, // Shift Accumulator Logically
// TEST INSTRUCTIONS
TMS320C54_bit, // Test Bit
TMS320C54_bitf, // Test Bit Field Specified by Immediate Value
TMS320C54_bitt, // Test Bit Specified by T
TMS320C54_cmpm, // Compare Memory With Long Immediate
TMS320C54_cmpr, // Compare Auxiliary Register with AR0
// PROGRAM CONTROL OPERATIONS
// BRANCH INSTRUCTIONS
TMS320C54_b, // Branch Unconditionally
TMS320C54_bd, // Branch Unconditionally
TMS320C54_bacc, // Branch to Location Specified by Accumulator
TMS320C54_baccd, // Branch to Location Specified by Accumulator
TMS320C54_banz, // Branch on Auxiliary Register Not Zero
TMS320C54_banzd, // Branch on Auxiliary Register Not Zero
TMS320C54_bc2, // Branch Conditionally
TMS320C54_bc3, // Branch Conditionally
TMS320C54_bcd2, // Branch Conditionally
TMS320C54_bcd3, // Branch Conditionally
TMS320C54_fb, // Far Branch Unconditionally
TMS320C54_fbd, // Far Branch Unconditionally
TMS320C54_fbacc, // Far Branch to Location Specified by Accumulator
TMS320C54_fbaccd, // Far Branch to Location Specified by Accumulator
// CALL INSTRUCTIONS
TMS320C54_cala, // Call Subroutine at Location Specified by Accumulator
TMS320C54_calad, // Call Subroutine at Location Specified by Accumulator
TMS320C54_call, // Call Unconditionally
TMS320C54_calld, // Call Unconditionally
TMS320C54_cc2, // Call Conditionally
TMS320C54_cc3, // Call Conditionally
TMS320C54_ccd2, // Call Conditionally
TMS320C54_ccd3, // Call Conditionally
TMS320C54_fcala, // Far Call Subroutine at Location Specified by Accumulator
TMS320C54_fcalad, // Far Call Subroutine at Location Specified by Accumulator
TMS320C54_fcall, // Far Call Unconditionally
TMS320C54_fcalld, // Far Call Unconditionally
// INTERRUPT INSTRUCTIONS
TMS320C54_intr, // Software Interrupt
TMS320C54_trap, // Software Interrupt
// RETURN INSTRUCTIONS
TMS320C54_fret, // Far Return
TMS320C54_fretd, // Far Return
TMS320C54_frete, // Enable Interrupts and Far Return From Interrupt
TMS320C54_freted, // Enable Interrupts and Far Return From Interrupt
TMS320C54_rc1, // Return Conditionally
TMS320C54_rc2, // Return Conditionally
TMS320C54_rc3, // Return Conditionally
TMS320C54_rcd1, // Return Conditionally
TMS320C54_rcd2, // Return Conditionally
TMS320C54_rcd3, // Return Conditionally
TMS320C54_ret, // Return
TMS320C54_retd, // Return
TMS320C54_rete, // Enable Interrupts and Return From Interrupt
TMS320C54_reted, // Enable Interrupts and Return From Interrupt
TMS320C54_retf, // Enable Interrupts and Fast Return From Interrupt
TMS320C54_retfd, // Enable Interrupts and Fast Return From Interrupt
// REPEAT INSTRUCTIONS
TMS320C54_rpt, // Repeat Next Instruction
TMS320C54_rptb, // Block Repeat
TMS320C54_rptbd, // Block Repeat
TMS320C54_rptz, // Repeat Next Instruction And Clear Accumulator
// STACK MANIPULATING INSTRUCTIONS
TMS320C54_frame, // Stack Pointer Immediate Offset
TMS320C54_popd, // Pop Top of Stack to Data Memory
TMS320C54_popm, // Pop Top of Stack to Memory-Mapped Register
TMS320C54_pshd, // Push Data-Memory Value Onto Stack
TMS320C54_pshm, // Push Memory-Mapped Register Onto Stack
// MISCELLANEOUS PROGRAM-CONTROL INSTRUCTIONS
TMS320C54_idle, // Idle Until Interrupt
TMS320C54_mar, // Modify Auxiliary Register
TMS320C54_nop, // No Operation
TMS320C54_reset, // Software Reset
TMS320C54_rsbx1, // Reset Status Register Bit
TMS320C54_rsbx2, // Reset Status Register Bit
TMS320C54_ssbx1, // Set Status Register Bit
TMS320C54_ssbx2, // Set Status Register Bit
TMS320C54_xc2, // Execute Conditionally
TMS320C54_xc3, // Execute Conditionally
// LOAD AND STORE OPERATIONS
// LOAD INSTRUCTIONS
TMS320C54_dld, // Double-Precision/Dual 16-Bit Long-Word Load to Accumulator
TMS320C54_ld1, // Load Accumulator With Shift
TMS320C54_ld2, // Load Accumulator With Shift
TMS320C54_ld3, // Load Accumulator With Shift
TMS320C54_ldm, // Load Memory-Mapped Register
TMS320C54_ldr, // Load Memory Value in Accumulator High With Rounding
TMS320C54_ldu, // Load Unsigned Memory Value
TMS320C54_ltd, // Load T and insert Delay
// STORE INSTRUCTIONS
TMS320C54_dst, // Store Accumulator in Long Word
TMS320C54_st, // Store T, TRN, or Immediate Value into Memory
TMS320C54_sth2, // Store Accumulator High Into Memory
TMS320C54_sth3, // Store Accumulator High Into Memory
TMS320C54_stl2, // Store Accumulator Low Into Memory
TMS320C54_stl3, // Store Accumulator Low Into Memory
TMS320C54_stlm, // Store Accumulator Low Into Memory-Mapped Register
TMS320C54_stm, // Store Immediate Value Into Memory-Mapped Register
// CONDITIONAL STORE INSTRUCTIONS
TMS320C54_cmps, // Compare, Select and Store Maximum
TMS320C54_saccd, // Store Accumulator Conditionally
TMS320C54_srccd, // Store Block Repeat Counter Conditionally
TMS320C54_strcd, // Store T Conditionally
// PARALLEL LOAD AND STORE INSTRUCTIONS
TMS320C54_st_ld, // Store Accumulator With Parallel Load
// PARALLEL LOAD AND MULTIPLY INSTRUCTIONS
TMS320C54_ld_mac, // Load Accumulator With Parallel Multiply Accumulate Without Rounding
TMS320C54_ld_macr, // Load Accumulator With Parallel Multiply Accumulate With Rounding
TMS320C54_ld_mas, // Load Accumulator With Parallel Multiply Subtract Without Rounding
TMS320C54_ld_masr, // Load Accumulator With Parallel Multiply Subtract With Rounding
// PARALLEL STORE AND ADD/SUBSTRACT INSTRUCTIONS
TMS320C54_st_add, // Store Accumulator With Parallel Add
TMS320C54_st_sub, // Store Accumulator With Parallel Subtract
// PARALLEL STORE AND MULTIPLY INSTRUCTIONS
TMS320C54_st_mac, // Store Accumulator With Parallel Multiply Accumulate Without Rounding
TMS320C54_st_macr, // Store Accumulator With Parallel Multiply Accumulate With Rounding
TMS320C54_st_mas, // Store Accumulator With Parallel Multiply Subtract Without Rounding
TMS320C54_st_masr, // Store Accumulator With Parallel Multiply Subtract With Rounding
TMS320C54_st_mpy, // Store Accumulator With Parallel Multiply
// MISCELLANEOUS LOAD-TYPE AND STORE-TYPE INSTRUCTIONS
TMS320C54_mvdd, // Move Data From Data Memory to Data Memory With X,Y Addressing
TMS320C54_mvdk, // Move Data From Data Memory to Data Memory With Destination Addressing
TMS320C54_mvdm, // Move Data From Data Memory to Memory-Mapped Register
TMS320C54_mvdp, // Move Data From Data Memory to Program Memory
TMS320C54_mvkd, // Move Data From Data Memory to Data Memory With Source Addressing
TMS320C54_mvmd, // Move Data From Memory-Mapped Register to Data Memory
TMS320C54_mvmm, // Move Data From Memory-Mapped Register to Memory-Mapped Register
TMS320C54_mvpd, // Move Data From Program Memory to Data Memory
TMS320C54_portr, // Read Data From Port
TMS320C54_portw, // Write Data to Port
TMS320C54_reada, // Read Program Memory Addressed by Accumulator A and Store in Data Memory
TMS320C54_writa, // Write Data to Program Memory Addressed by Accumulator A
TMS320C54_last
};
#endif

View File

@@ -0,0 +1,60 @@
PROC=tms32054
CONFIGS=tms320c54.cfg
include ../module.mak
# MAKEDEP dependency list ------------------
$(F)OBJS$(O) :
$(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 tms320c54.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 tms320c54.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 tms320c54.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 \
tms320c54.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 notify_codes.hpp reg.cpp \
tms320c54.hpp

View File

@@ -0,0 +1,33 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-2021 Hex-Rays
* ALL RIGHTS RESERVED.
*
*/
#ifndef __TMS320C54_NOTIFY_CODES_HPP
#define __TMS320C54_NOTIFY_CODES_HPP
#include <idp.hpp>
//----------------------------------------------------------------------
// The following events are supported by the TMS320C54 module in the ph.notify() function
namespace tms320c54_module_t
{
enum event_codes_t
{
ev_set_dataseg = processor_t::ev_loader + 2,
};
inline processor_t::event_t idp_ev(event_codes_t ev)
{
return processor_t::event_t(ev);
}
inline void set_dataseg(ea_t ea)
{
processor_t::notify(idp_ev(ev_set_dataseg), ea);
}
}
#endif // __TMS320C54_NOTIFY_CODES_HPP

View File

@@ -0,0 +1,467 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-99 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* E-mail: ig@datarescue.com
*
*
*/
#include "tms320c54.hpp"
#include <frame.hpp>
#include <segregs.hpp>
#include <struct.hpp>
// 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_tms320c54_t : public outctx_t
{
out_tms320c54_t(void) = delete; // not used
tms320c54_t &pm() { return *static_cast<tms320c54_t *>(procmod); }
public:
bool out_operand(const op_t &x);
void out_insn(void);
void out_address(ea_t ea, const op_t &x, bool mapping, bool at);
void out_cond8(char value);
};
CASSERT(sizeof(out_tms320c54_t) == sizeof(outctx_t));
DECLARE_OUT_FUNCS_WITHOUT_OUTMNEM(out_tms320c54_t)
//----------------------------------------------------------------------
void out_tms320c54_t::out_address(ea_t ea, const op_t &x, bool mapping, bool at)
{
regnum_t reg = pm().get_mapped_register(ea);
if ( mapping && reg != rnone )
{
out_register(ph.reg_names[reg]);
}
else
{
#ifndef TMS320C54_NO_NAME_NO_REF
qstring qbuf;
// since tms320c54 uses memory mapping, we turn off verification
// of name expression values (4th arg of get_name_expr is BADADDR)
if ( get_name_expr(&qbuf, insn.ea+x.offb, x.n, ea, BADADDR) > 0 )
{
if ( at )
out_symbol('@');
out_line(qbuf.begin());
}
else
#endif
{
out_tagon(COLOR_ERROR);
out_value(x, OOF_ADDR|OOFW_32);
out_tagoff(COLOR_ERROR);
remember_problem(PR_NONAME, insn.ea);
}
}
}
//----------------------------------------------------------------------
const char *get_cond8(char value)
{
switch ( value )
{
case COND8_UNC: return "unc";
case COND8_NBIO: return "nbio";
case COND8_BIO: return "bio";
case COND8_NC: return "nc";
case COND8_C: return "c";
case COND8_NTC: return "ntc";
case COND8_TC: return "tc";
case COND8_AGEQ: return "ageq";
case COND8_ALT: return "alt";
case COND8_ANEQ: return "aneq";
case COND8_AEQ: return "aeq";
case COND8_AGT: return "agt";
case COND8_ALEQ: return "aleq";
case COND8_ANOV: return "anov";
case COND8_AOV: return "aov";
case COND8_BGEQ: return "bgeq";
case COND8_BLT: return "blt";
case COND8_BNEQ: return "bneq";
case COND8_BEQ: return "beq";
case COND8_BGT: return "bgt";
case COND8_BLEQ: return "bleq";
case COND8_BNOV: return "bnov";
case COND8_BOV: return "bov";
default: return NULL;
}
}
//----------------------------------------------------------------------
void out_tms320c54_t::out_cond8(char value)
{
const char *cond = get_cond8(value);
QASSERT(256, cond != NULL);
out_line(cond, COLOR_REG);
}
//----------------------------------------------------------------------
bool out_tms320c54_t::out_operand(const op_t &x)
{
ea_t ea;
switch ( x.type )
{
case o_void:
return 0;
case o_reg:
out_register(ph.reg_names[x.reg]);
break;
case o_near:
case o_far:
ea = calc_code_mem(insn, x.addr, x.type == o_near);
out_address(ea, x, false, false);
break;
case o_imm:
{
const char *name = NULL;
if ( pm().idpflags & TMS320C54_IO && x.IOimm )
name = pm().find_sym(x.value);
if ( !x.NoCardinal )
out_symbol('#');
if ( name != NULL && name[0] != '\0' )
{
out_line(name, COLOR_IMPNAME);
}
else
{
if ( !x.Signed )
out_value(x, OOFW_IMM);
else
out_value(x, OOFS_IFSIGN|OOF_SIGNED|OOF_NUMBER|OOFW_IMM);
}
break;
}
case o_local:
out_value(x, OOF_ADDR|OOFW_32);
break;
case o_mmr:
case o_mem:
case o_farmem:
if ( x.IndirectAddressingMOD == ABSOLUTE_INDIRECT_ADRESSING )
{
out_symbol('*');
out_symbol('(');
}
ea = pm().calc_data_mem(insn, x.addr, x.type == o_mem);
if ( ea != BADADDR )
{
// no '@' if absolute "indirect" adressing
bool at = x.IndirectAddressingMOD != ABSOLUTE_INDIRECT_ADRESSING;
out_address(ea, x, true, at);
}
else
{
out_value(x, OOF_ADDR|OOFW_32);
}
if ( x.IndirectAddressingMOD == ABSOLUTE_INDIRECT_ADRESSING )
out_symbol(')');
break;
case o_displ: // Indirect addressing mode
{
char buf[8];
const char *reg = ph.reg_names[x.reg];
switch ( x.IndirectAddressingMOD )
{
case 0:
qsnprintf(buf, sizeof(buf), "*%s",reg);
out_register(buf);
break;
case 1:
qsnprintf(buf, sizeof(buf), "*%s-",reg);
out_register(buf);
break;
case 2:
qsnprintf(buf, sizeof(buf), "*%s+",reg);
out_register(buf);
break;
case 3:
qsnprintf(buf, sizeof(buf), "*+%s",reg);
out_register(buf);
break;
case 4:
qsnprintf(buf, sizeof(buf), "*%s-0B",reg);
out_register(buf);
break;
case 5:
qsnprintf(buf, sizeof(buf), "*%s-0",reg);
out_register(buf);
break;
case 6:
qsnprintf(buf, sizeof(buf), "*%s+0",reg);
out_register(buf);
break;
case 7:
qsnprintf(buf, sizeof(buf), "*%s+0B",reg);
out_register(buf);
break;
case 8:
qsnprintf(buf, sizeof(buf), "*%s-%%",reg);
out_register(buf);
break;
case 9:
qsnprintf(buf, sizeof(buf), "*%s-0%%",reg);
out_register(buf);
break;
case 0xA:
qsnprintf(buf, sizeof(buf), "*%s+%%",reg);
out_register(buf);
break;
case 0xB:
qsnprintf(buf, sizeof(buf), "*%s+0%%",reg);
out_register(buf);
break;
case 0xC:
qsnprintf(buf, sizeof(buf), "*%s(",reg);
out_register(buf);
out_value(x, OOF_ADDR|OOF_SIGNED|OOFW_16);
out_symbol(')');
break;
case 0xD:
qsnprintf(buf, sizeof(buf), "*+%s(",reg);
out_register(buf);
out_value(x, OOF_ADDR|OOF_SIGNED|OOFW_16);
out_symbol(')');
break;
case 0xE:
qsnprintf(buf, sizeof(buf), "*+%s(",reg);
out_register(buf);
out_value(x, OOF_ADDR|OOF_SIGNED|OOFW_16);
out_symbol(')');
out_symbol('%');
break;
// this special adressing mode is now defined as o_farmem !
// case ABSOLUTE_INDIRECT_ADRESSING:
// out_symbol('*');
// out_symbol('(');
// out_value(x, OOF_ADDR|OOF_SIGNED|OOFW_16);
// out_symbol(')');
// break;
default:
error("interr: out: o_displ");
}
break;
}
case o_bit:
{
if ( !x.NoCardinal )
out_symbol('#');
char buf[20];
qsnprintf(buf, sizeof(buf), "%d", int(x.value));
out_line(buf, COLOR_REG);
break;
}
case o_cond8:
out_cond8((uchar)x.value);
break;
case o_cond2:
{
const char *cond = "";
switch ( x.value )
{
case 0: cond = "eq"; break;
case 1: cond = "lt"; break;
case 2: cond = "gt"; break;
case 3: cond = "neq"; break;
default: warning("interr: out 2-bit condition");
}
out_line(cond, COLOR_REG);
break;
}
default:
error("interr: out");
}
return 1;
}
//----------------------------------------------------------------------
void out_tms320c54_t::out_insn(void)
{
out_mnemonic();
out_one_operand(0);
if ( insn.Op2.type != o_void )
{
out_symbol(',');
out_char(' ');
out_one_operand(1);
if ( insn.IsParallel )
{ // new line for Parallel instructions
flush_outbuf();
out_line("|| ", COLOR_INSN);
const char *insn2 = NULL;
switch ( insn.itype )
{
case TMS320C54_ld_mac: insn2 = "mac "; break;
case TMS320C54_ld_macr: insn2 = "macr "; break;
case TMS320C54_ld_mas: insn2 = "mas "; break;
case TMS320C54_ld_masr: insn2 = "masr "; break;
case TMS320C54_st_add: insn2 = "add "; break;
case TMS320C54_st_sub: insn2 = "sub "; break;
case TMS320C54_st_ld: insn2 = "ld "; break;
case TMS320C54_st_mpy: insn2 = "mpy "; break;
case TMS320C54_st_mac: insn2 = "mac "; break;
case TMS320C54_st_macr: insn2 = "macr "; break;
case TMS320C54_st_mas: insn2 = "mas "; break;
case TMS320C54_st_masr: insn2 = "masr "; break;
default: warning("interr: out parallel instruction");
}
out_line(insn2, COLOR_INSN);
}
if ( insn.Op3.type != o_void )
{
if ( !insn.IsParallel )
{
out_symbol(',');
out_char(' ');
}
out_one_operand(2);
if ( insn.Op4_type != 0 )
{
out_symbol(',');
out_char(' ');
switch ( insn.Op4_type )
{
case o_reg:
out_register(ph.reg_names[insn.Op4_value]);
break;
case o_cond8:
out_cond8(insn.Op4_value);
break;
default:
break;
}
}
}
}
out_immchar_cmts();
flush_outbuf();
}
//--------------------------------------------------------------------------
void tms320c54_t::print_segment_register(outctx_t &ctx, int reg, sel_t value)
{
if ( reg == ph.reg_data_sreg )
return;
if ( value != BADADDR )
{
char buf[MAX_NUMBUF];
btoa(buf, sizeof(buf), value);
ctx.gen_cmt_line("assume %s = %s", ph.reg_names[reg], buf);
}
else
{
ctx.gen_cmt_line("drop %s", ph.reg_names[reg]);
}
}
//--------------------------------------------------------------------------
// function to produce assume directives
//lint -e{1764} ctx could be const
void tms320c54_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 tms320c54_t::segstart(outctx_t &ctx, segment_t *seg) const
{
if ( is_spec_segm(seg->type) )
return;
qstring sclas;
get_segm_class(&sclas, seg);
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));
if ( seg->orgbase != 0 )
{
char buf[MAX_NUMBUF];
btoa(buf, sizeof(buf), seg->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();
}
//--------------------------------------------------------------------------
void tms320c54_t::footer(outctx_t &ctx) const
{
ctx.gen_printf(DEFAULT_INDENT, COLSTR("%s",SCOLOR_ASMDIR), ash.end);
}
//--------------------------------------------------------------------------
void tms320c54_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,687 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-99 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* E-mail: ig@datarescue.com
*
*
*/
#include "tms320c54.hpp"
#include "notify_codes.hpp"
#include <diskio.hpp>
#include <segregs.hpp>
#include <ieee.h>
int data_id;
//--------------------------------------------------------------------------
static const char *const register_names[] =
{
"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
"cs","ds", // virtual registers for code and data segments
};
//--------------------------------------------------------------------------
static const uchar retcode_0[] = { 0xF4, 0xE4 }; // fret
static const uchar retcode_1[] = { 0xF6, 0xE4 }; // fretd
static const uchar retcode_2[] = { 0xF4, 0xE5 }; // frete
static const uchar retcode_3[] = { 0xF6, 0xE5 }; // freted
static const uchar retcode_4[] = { 0xFC }; // rc
static const uchar retcode_5[] = { 0xFE }; // rcd
static const uchar retcode_6[] = { 0xFC, 0x00 }; // ret
static const uchar retcode_7[] = { 0xFE, 0x00 }; // retd
static const uchar retcode_8[] = { 0xF4, 0xEA }; // rete
static const uchar retcode_9[] = { 0xF6, 0xEA }; // reted
static const uchar retcode_10[] = { 0xF4, 0x9A }; // retf
static const uchar retcode_11[] = { 0xF6, 0x9A }; // retfd
static const bytes_t retcodes[] =
{
{ sizeof(retcode_0), retcode_0 },
{ sizeof(retcode_1), retcode_1 },
{ sizeof(retcode_2), retcode_2 },
{ sizeof(retcode_3), retcode_3 },
{ sizeof(retcode_4), retcode_4 },
{ sizeof(retcode_5), retcode_5 },
{ sizeof(retcode_6), retcode_6 },
{ sizeof(retcode_7), retcode_7 },
{ sizeof(retcode_8), retcode_8 },
{ sizeof(retcode_9), retcode_9 },
{ sizeof(retcode_10), retcode_10 },
{ sizeof(retcode_11), retcode_11 },
{ 0, NULL }
};
//-----------------------------------------------------------------------
// TMS320C54 ASM
//-----------------------------------------------------------------------
static const asm_t fasm =
{
AS_N2CHR|ASH_HEXF0|ASD_DECF0|ASO_OCTF5|ASB_BINF0|AS_ONEDUP|AS_COLON,
0,
"ASM500",
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
".word", // byte directive
".long", // word directive
NULL, // 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 16*%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
};
//-----------------------------------------------------------------------
// GNU ASM
//-----------------------------------------------------------------------
static const asm_t gnuasm =
{
AS_N2CHR|ASH_HEXF3|ASD_DECF0|ASO_OCTF5|ASB_BINF0|AS_ONEDUP|AS_COLON|AS_ASCIIC,
0,
"GNU assembler",
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
".word", // byte directive
".long", // word directive
NULL, // 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(...)
".zero 2*%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
".weak", // "weak" name keyword
".extern", // "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
NULL, // cmnt2
NULL, // low8
NULL, // high8
NULL, // low16
NULL, // high16
"#include \"%s\"", // a_include_fmt
};
static const asm_t *const asms[] = { &fasm, &gnuasm, NULL };
//--------------------------------------------------------------------------
const char *tms320c54_t::find_sym(ea_t address)
{
const ioport_t *port = find_ioport(ioh.ports, address);
return port ? port->name.c_str() : NULL;
}
//----------------------------------------------------------------------
void tms320c54_t::apply_symbols(void)
{
insn_t dummy;
for ( int i=0; i < ioh.ports.size(); i++ )
{
ea_t ea = calc_data_mem(dummy, ioh.ports[i].address, false);
segment_t *s = getseg(ea);
if ( s == NULL || s->type != SEG_IMEM )
continue;
create_byte(ea, 1);
const char *name = ioh.ports[i].name.c_str();
if ( !set_name(ea, name, SN_NOCHECK|SN_NOWARN|SN_NODUMMY) )
set_cmt(ea, name, 0);
}
}
//--------------------------------------------------------------------------
inline void swap(unsigned char &c1, unsigned char &c2)
{
unsigned char tmp = c1;
c1 = c2;
c2 = tmp;
}
fpvalue_error_t idaapi tms_realcvt(void *m, fpvalue_t *e, ushort swt)
{
fpvalue_error_t ret;
switch ( swt )
{
case 1: // float to e
{
unsigned char p[4];
memcpy(p, m, 4);
swap(p[0], p[1]);
swap(p[2], p[3]);
ret = ieee_realcvt(p, e, swt);
break;
}
case 011: // float output //-V536 octal
{
ret = ieee_realcvt(m, e, swt);
unsigned char *p = (unsigned char*)m;
swap(p[0], p[1]);
swap(p[2], p[3]);
break;
}
default:
ret = ieee_realcvt(m, e, swt);
break;
}
return ret;
}
//--------------------------------------------------------------------------
static int idaapi choose_device(int, form_actions_t &fa)
{
tms320c54_t &pm = *(tms320c54_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 *tms320c54_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"
"TMS320C54 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"
" Device name\n"
"\n"
" Choose the exact device name for the processor.\n"
" If you don't see the name you want, you can add\n"
" a section about it to the tms320c54.cfg file\n"
"\n"
" Data segment address\n"
"\n"
" The data segment linear address.\n"
"\n"
"ENDHELP\n"
"TMS320C54 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"
" <~D~ata segment address:N::18::>\n"
"\n";
CASSERT(sizeof(idpflags) == sizeof(ushort));
CASSERT(sizeof(dataseg) == sizeof(ea_t));
ask_form(form, this, &idpflags, choose_device, &dataseg);
}
else
{
if ( strcmp(keyword, "TMS320C54_DSEG") == 0 )
{
if ( value_type != IDPOPT_NUM )
return IDPOPT_BADTYPE;
dataseg = *(uval_t *)value;
}
if ( value_type != IDPOPT_BIT )
return IDPOPT_BADTYPE;
if ( strcmp(keyword, "TMS320C54_IO") == 0 )
{
setflag(idpflags, TMS320C54_IO, *(int*)value != 0);
}
else if ( strcmp(keyword, "TMS320C54_MMR") == 0 )
{
setflag(idpflags, TMS320C54_MMR, *(int*)value != 0);
}
else
{
return IDPOPT_BADKEY;
}
}
if ( idb_loaded )
{
save_idpflags();
save_dataseg();
}
return IDPOPT_OK;
}
//--------------------------------------------------------------------------
static const proctype_t ptypes[] =
{
TMS320C54
};
void tms320c54_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());
}
inf_set_wide_high_byte_first(false);
idpflags = (ushort)helper.altval(-1);
dataseg = helper.altval(0);
}
//----------------------------------------------------------------------
// 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(tms320c54_t));
return 0;
}
//--------------------------------------------------------------------------
ssize_t idaapi tms320c54_t::on_event(ssize_t msgid, va_list va)
{
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4063)
#endif
int code = 0;
switch ( msgid ) // Cast to avoid lint complaining.
{
case processor_t::ev_init:
helper.create(PROCMOD_NODE_NAME);
inf_set_be(true); // MSB first
inf_set_wide_high_byte_first(true);
dataseg = helper.altval(0);
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();
save_dataseg();
inf_set_wide_high_byte_first(false);
{
segment_t *s = get_first_seg();
if ( s != NULL )
apply_symbols();
while ( s != NULL )
{
qstring sclas;
get_segm_class(&sclas, s);
for ( int i = XPC; i <= rVds; i++ )
set_default_sreg_value(s, i, BADSEL);
if ( sclas == "CODE" )
set_default_sreg_value(s, XPC, s->start_ea >> 16);
s = get_next_seg(s->start_ea);
}
}
break;
case tms320c54_module_t::ev_set_dataseg:
dataseg = va_arg(va, ea_t);
save_dataseg();
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_newbinary:
inf_set_wide_high_byte_first(true);
break;
case processor_t::ev_endbinary:
inf_set_wide_high_byte_first(false);
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 TMS320C54:
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_is_basic_block_end:
{
const insn_t *insn = va_arg(va, const insn_t *);
return is_basic_block_end(*insn) ? 1 : -1;
}
case processor_t::ev_is_sane_insn:
{
const insn_t *insn = va_arg(va, const insn_t *);
int no_crefs = va_arg(va, int);
// add 0, a is not a sane instruction without crefs to it
code = no_crefs && get_wide_byte(insn->ea) == 0 ? -1 : 1;
}
break;
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_realcvt:
{
void *m = va_arg(va, void *);
fpvalue_t *e = va_arg(va, fpvalue_t *);
uint16 swt = va_argi(va, uint16);
fpvalue_error_t code1 = tms_realcvt(m, e, swt);
return code1 == REAL_ERROR_OK ? 1 : code1;
}
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_get_frame_retsize:
{
int *frsize = va_arg(va, int *);
const func_t *pfn = va_arg(va, const func_t *);
*frsize = tms_get_frame_retsize(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;
}
#ifdef _MSC_VER
#pragma warning(pop)
#endif
return code;
}
//-----------------------------------------------------------------------
#define FAMILY "TMS320C54x Series:"
static const char *const shnames[] =
{
"TMS32054",
NULL
};
static const char *const lnames[] =
{
FAMILY"Texas Instruments TMS320C54",
NULL
};
//-----------------------------------------------------------------------
// Processor Definition
//-----------------------------------------------------------------------
processor_t LPH =
{
IDP_INTERFACE_VERSION, // version
PLFM_TMS320C54, // id
// flag
PRN_HEX
| PR_SEGS
| PR_SGROTHER
| PR_ALIGN,
// flag2
PR2_MAPPINGS // use memory mapping
| PR2_REALCVT // the module has 'realcvt' event implementation
| PR2_IDP_OPTS, // the module has processor-specific configuration options
16, // 16 bits in a byte for code segments
16, // 16 bits in a byte for other segments
shnames,
lnames,
asms,
notify,
register_names, // Register names
qnumber(register_names), // Number of registers
XPC, // first
rVds, // last
1, // size of a segment register
rVcs, rVds,
NULL, // No known code start sequences
retcodes,
TMS320C54_null,
TMS320C54_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
TMS320C54_ret, // Icode of return instruction. It is ok to give any of possible return instructions
};

View File

@@ -0,0 +1,200 @@
;
; This file defines SFR names and bit names for TMS320C54 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 C541
OUTDAT 0x7
INDAT 0x60
TEST 0xFCFDFEFF
;-------------------------------
; Device specific definitions
.C542
; insert definitions here
.C543
; insert definitions here
.C544
; insert definitions here
.C545
; insert definitions here
.C546
; insert definitions here
.C548
; insert definitions here
.C549
; insert definitions here
.C5402
; insert definitions here
.C5410
; insert definitions here
.C5420
; insert definitions here
.CALYPSO
; entry _reset 0xff80 Reset vector
; RIF
RIF_DXR 0x0000
RIF_DRR 0x0001
RIF_SPCX 0x0002
RIF_SPCR 0x0003
; CYPHER
CYPHER_CNTL 0x2800
CYPHER_CNTL.START 0
CYPHER_CNTL.RESETSW 1
CYPHER_CNTL.MODE0 2
CYPHER_CNTL.MODE1 3
CYPHER_CNTL.CLK_EN 4
CYPHER_CNTL.CYPHER_ONLY 5
CYPHER_STATUS_IRQ 0x2801
CYPHER_STATUS_IRQ.LT_FIN 0
CYPHER_STATUS_WORK 0x2802
CYPHER_STATUS_WORK.WORKING 0
CYPHER_KC_1 0x2803
CYPHER_KC_2 0x2804
CYPHER_KC_3 0x2805
CYPHER_KC_4 0x2806
CYPHER_COUNT_1 0x2807
CYPHER_COUNT_2 0x2808
CYPHER_DECI_1 0x2809
CYPHER_DECI_2 0x280A
CYPHER_DECI_3 0x280B
CYPHER_DECI_4 0x280C
CYPHER_DECI_5 0x280D
CYPHER_DECI_6 0x280E
CYPHER_DECI_7 0x280F
CYPHER_DECI_8 0x2810
CYPHER_ENCI_1 0x2811
CYPHER_ENCI_2 0x2812
CYPHER_ENCI_3 0x2813
CYPHER_ENCI_4 0x2814
CYPHER_ENCI_5 0x2815
CYPHER_ENCI_6 0x2816
CYPHER_ENCI_7 0x2817
CYPHER_ENCI_8 0x2818
; MCSI
MCSI_CONTROL 0x0800
MCSI_MAIN-PARAMETERS 0x0801
MCSI_INTERRUPTS 0x0802
MCSI_CHANNEL-USED 0x0803
MCSI_OVER-CLK 0x0804
MCSI_CLK-FREQ 0x0805
MCSI_STATUS 0x0806
MCSI_TX0 0x0820
MCSI_TX1 0x0821
MCSI_TX2 0x0822
MCSI_TX3 0x0823
MCSI_TX4 0x0824
MCSI_TX5 0x0825
MCSI_TX6 0x0826
MCSI_TX7 0x0827
MCSI_TX8 0x0828
MCSI_TX9 0x0829
MCSI_TX10 0x082A
MCSI_TX11 0x082B
MCSI_TX12 0x082C
MCSI_TX13 0x082D
MCSI_TX14 0x082E
MCSI_TX15 0x082F
MCSI_RX0 0x0830
MCSI_RX1 0x0831
MCSI_RX2 0x0832
MCSI_RX3 0x0833
MCSI_RX4 0x0834
MCSI_RX5 0x0835
MCSI_RX6 0x0836
MCSI_RX7 0x0837
MCSI_RX8 0x0838
MCSI_RX9 0x0839
MCSI_RX10 0x083A
MCSI_RX11 0x083B
MCSI_RX12 0x083C
MCSI_RX13 0x083D
MCSI_RX14 0x083E
MCSI_RX15 0x083F
; RHEA
RHEA_TRANSFER_RATE 0xF800
RHEA_BRIDGE-CTRL 0xF801
RHEA_BRIDGE-CTRL.TIMEOUT_ENABLE 8
RHEA_BRIDGE-CTRL.NSUPV 9
; API
API_CONF 0xF900
API_CONF.RESERVED0 0
API_CONF.API_HOM 1
API_CONF.BRIDGE_CLK_EN 2
; Interrupts
INT_CNTRL 0xFA00
INT_CLEAR 0xFA01
; DMA
DMA_CONTROLLER_CONF 0xFC00
DMA_ALLOC_CONFIG 0xFC02
DMA1_RAD 0xFC10
DMA1_RDPTH 0xFC12
DMA1_AAD 0xFC14
DMA1_ALGTH 0xFC16
DMA1_CTRL 0xFC18
DMA1_CUR_OFFSET_API 0xFC1A
DMA2_RAD 0xFC20
DMA2_RDPTH 0xFC22
DMA2_AAD 0xFC24
DMA2_ALGTH 0xFC26
DMA2_CTRL 0xFC28
DMA2_CUR_OFFSET_API 0xFC2A
DMA3_RAD 0xFC30
DMA3_RDPTH 0xFC32
DMA3_AAD 0xFC34
DMA3_ALGTH 0xFC36
DMA3_CTRL 0xFC38
DMA3_CUR_OFFSET_API 0xFC3A
DMA4_RAD 0xFC40
DMA4_RDPTH 0xFC42
DMA4_AAD 0xFC44
DMA4_ALGTH 0xFC46
DMA4_CTRL 0xFC48
DMA4_CUR_OFFSET_API 0xFC4A

View File

@@ -0,0 +1,243 @@
/*
* 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