update to ida 7.6, add builds
This commit is contained in:
1577
idasdk76/module/tms320c6/ana.cpp
Normal file
1577
idasdk76/module/tms320c6/ana.cpp
Normal file
File diff suppressed because it is too large
Load Diff
375
idasdk76/module/tms320c6/emu.cpp
Normal file
375
idasdk76/module/tms320c6/emu.cpp
Normal file
@@ -0,0 +1,375 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA).
|
||||
* Copyright (c) 1990-98 by Ilfak Guilfanov.
|
||||
* ALL RIGHTS RESERVED.
|
||||
* E-mail: ig@estar.msk.su
|
||||
* FIDO: 2:5020/209
|
||||
*
|
||||
*
|
||||
* TMS320C6xx - VLIW (very long instruction word) architecture
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tms6.hpp"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static void set_immd_bit(const insn_t &insn, int n, flags_t F)
|
||||
{
|
||||
set_immd(insn.ea);
|
||||
if ( is_defarg(F, n) )
|
||||
return;
|
||||
switch ( insn.itype )
|
||||
{
|
||||
case TMS6_mvk:
|
||||
if ( is_mvk_scst16_form(insn.ea) )
|
||||
{
|
||||
op_hex(insn.ea, n);
|
||||
break;
|
||||
}
|
||||
// fallthrough for scst5 form
|
||||
case TMS6_addk:
|
||||
case TMS6_and: // Rd = Op1 & Op2
|
||||
case TMS6_xor: // Rd = Op1 ^ Op2
|
||||
case TMS6_or: // Rd = Op2 | Op1
|
||||
case TMS6_cmpeq:
|
||||
case TMS6_cmpgt:
|
||||
case TMS6_cmplt:
|
||||
case TMS6_mpy:
|
||||
case TMS6_mpyi:
|
||||
case TMS6_mpyid:
|
||||
case TMS6_mpysu:
|
||||
case TMS6_sadd:
|
||||
case TMS6_ssub:
|
||||
case TMS6_sub:
|
||||
case TMS6_set: // Rd = Op1 & ~Op2
|
||||
case TMS6_clr: // Rd = Op1 & ~Op2
|
||||
case TMS6_ext: // Rd = Op1 & ~Op2
|
||||
case TMS6_extu: // Rd = Op1 & ~Op2
|
||||
op_dec(insn.ea, n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
static void handle_operand(const insn_t &insn, const op_t &x, flags_t F, bool isload)
|
||||
{
|
||||
switch ( x.type )
|
||||
{
|
||||
case o_regpair:
|
||||
case o_reg:
|
||||
case o_phrase:
|
||||
case o_spmask:
|
||||
case o_stgcyc:
|
||||
break;
|
||||
case o_imm:
|
||||
if ( !isload )
|
||||
goto badTouch;
|
||||
/* no break */
|
||||
case o_displ:
|
||||
set_immd_bit(insn, x.n, F);
|
||||
if ( op_adds_xrefs(F, x.n) )
|
||||
{
|
||||
int outf = x.type != o_imm ? OOF_ADDR : 0;
|
||||
if ( x.dtype == dt_word )
|
||||
outf |= OOF_SIGNED;
|
||||
insn.add_off_drefs(x, dr_O, outf);
|
||||
}
|
||||
break;
|
||||
case o_near:
|
||||
{
|
||||
ea_t ea = to_ea(insn.cs, x.addr);
|
||||
ea_t ref = find_first_insn_in_packet(ea);
|
||||
insn.add_cref(ref, x.offb, fl_JN);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
badTouch:
|
||||
INTERR(10380);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
ea_t find_first_insn_in_packet(ea_t ea)
|
||||
{
|
||||
if ( !is_spec_ea(ea) )
|
||||
{
|
||||
while ( (ea & 0x1F) != 0 )
|
||||
{
|
||||
ea_t ea2 = prev_not_tail(ea);
|
||||
if ( ea2 == BADADDR
|
||||
|| !is_code(get_flags(ea2))
|
||||
|| (get_dword(ea2) & BIT0) == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
ea = ea2;
|
||||
}
|
||||
}
|
||||
return ea;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool is_tms6_nop(uint32 code)
|
||||
{
|
||||
return (code & 0x21FFEL) == 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool is_tms6_bnop(uint32 code)
|
||||
{
|
||||
return (code & 0x00001FFC) == 0x00000120 // Branch Using a Displacement With NOP
|
||||
|| (code & 0x0F830FFE) == 0x00800362; // Branch Using a Register With NOP
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
static int get_delay(uint32 code)
|
||||
{
|
||||
if ( is_tms6_nop(code) ) // NOP
|
||||
return int((code >> 13) & 0xF) + 1;
|
||||
if ( is_tms6_bnop(code) ) // BNOP
|
||||
return int((code >> 13) & 0x7);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
struct call_info_t
|
||||
{
|
||||
ea_t mvk;
|
||||
ea_t mvkh;
|
||||
uint32 next;
|
||||
int reg;
|
||||
call_info_t(ea_t n) : mvk(BADADDR), mvkh(BADADDR), next(n), reg(rB3) {}
|
||||
bool call_is_present(void) const { return mvk != BADADDR && mvkh != BADADDR; }
|
||||
void test(ea_t ea, uint32 code);
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline ushort get_mvk_op(uint32 code) { return ushort(code >> 7); }
|
||||
|
||||
void call_info_t::test(ea_t ea, uint32 code)
|
||||
{
|
||||
if ( (code & 0xF000007CL) == 0x28 && mvk == BADADDR )
|
||||
{ // unconditional MVK.S
|
||||
int mvk_reg = int(code >> 23) & 0x1F;
|
||||
if ( code & BIT1 )
|
||||
mvk_reg += rB0;
|
||||
if ( (reg == -1 || reg == mvk_reg) && ushort(next) == get_mvk_op(code) )
|
||||
{
|
||||
reg = mvk_reg;
|
||||
mvk = ea;
|
||||
}
|
||||
}
|
||||
else if ( (code & 0xF000007CL) == 0x68 && mvkh == BADADDR )
|
||||
{ // unconditional MVKH.S
|
||||
int mvk_reg = int(code >> 23) & 0x1F;
|
||||
if ( code & BIT1 )
|
||||
mvk_reg += rB0;
|
||||
if ( (reg == -1 || reg == mvk_reg) && ushort(next>>16) == get_mvk_op(code) )
|
||||
{
|
||||
reg = mvk_reg;
|
||||
mvkh = ea;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
static int calc_packet_delay(ea_t ea, call_info_t *ci)
|
||||
{
|
||||
int delay = 1;
|
||||
while ( true )
|
||||
{
|
||||
uint32 code = get_dword(ea);
|
||||
int d2 = get_delay(code);
|
||||
if ( d2 > delay )
|
||||
delay = d2;
|
||||
ci->test(ea, code);
|
||||
if ( (code & BIT0) == 0 )
|
||||
break;
|
||||
ea += 4;
|
||||
if ( !is_code(get_flags(ea)) )
|
||||
break;
|
||||
}
|
||||
return delay;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
static ea_t find_prev_packet(ea_t ea)
|
||||
{
|
||||
ea_t res = BADADDR;
|
||||
while ( 1 )
|
||||
{
|
||||
ea_t ea2 = prev_not_tail(res != BADADDR ? res : ea);
|
||||
if ( ea2 == BADADDR )
|
||||
break;
|
||||
if ( !is_code(get_flags(ea2)) )
|
||||
break;
|
||||
res = ea2;
|
||||
if ( (get_dword(ea2) & BIT0) == 0 )
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
static ea_t get_branch_ea(ea_t ea)
|
||||
{
|
||||
while ( 1 )
|
||||
{
|
||||
uint32 code = get_dword(ea);
|
||||
if ( (code >> 28) == cAL )
|
||||
{
|
||||
switch ( (code >> 2) & 0x1F )
|
||||
{
|
||||
case 0x04: // bcond()
|
||||
return ea;
|
||||
case 0x08: // S unit
|
||||
case 0x18:
|
||||
{
|
||||
int opcode = int(code >> 6) & 0x3F;
|
||||
switch ( opcode )
|
||||
{
|
||||
case 0: // bdec/bpos
|
||||
case 3: // b irp
|
||||
case 4: // bnop
|
||||
case 13: // b
|
||||
return ea;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( (code & BIT0) == 0 )
|
||||
break;
|
||||
ea += 4;
|
||||
if ( !is_code(get_flags(ea)) )
|
||||
break;
|
||||
}
|
||||
return BADADDR;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
int tms6_t::emu(const insn_t &insn)
|
||||
{
|
||||
uint32 Feature = insn.get_canon_feature(ph);
|
||||
flow = ((Feature & CF_STOP) == 0);
|
||||
|
||||
if ( segtype(insn.ea) == SEG_XTRN )
|
||||
{
|
||||
flow = false;
|
||||
}
|
||||
else if ( (insn.cflags & aux_para) == 0 ) // the last instruction of packet
|
||||
{
|
||||
// From spru732j.pdf:
|
||||
// Although branch instructions take one execute phase, there are five
|
||||
// delay slots between the execution of the branch and execution of the
|
||||
// target code.
|
||||
|
||||
// We look backwards for five delay slots to check for an unconditionnal
|
||||
// branch instruction.
|
||||
|
||||
ea_t ea = find_first_insn_in_packet(insn.ea);
|
||||
int delay = 0;
|
||||
call_info_t ci(insn.ea+insn.size);
|
||||
while ( 1 )
|
||||
{
|
||||
// If there are any crefs to this address, we cannot guarantee that
|
||||
// the branch instruction really got executed.
|
||||
if ( has_xref(get_flags(ea)) )
|
||||
break;
|
||||
|
||||
// Increment delay count for this packet.
|
||||
delay += calc_packet_delay(ea, &ci);
|
||||
if ( delay > 5 )
|
||||
break;
|
||||
|
||||
// Unless we have a bnop instruction, seek to the previous packet.
|
||||
bool is_bnop = is_tms6_bnop(get_dword(ea));
|
||||
if ( !is_bnop )
|
||||
{
|
||||
ea = find_prev_packet(ea);
|
||||
if ( ea == BADADDR )
|
||||
break;
|
||||
ea = find_first_insn_in_packet(ea);
|
||||
}
|
||||
|
||||
ea_t brea;
|
||||
if ( delay == 5 && (brea=get_branch_ea(ea)) != BADADDR )
|
||||
{
|
||||
// We seeked to the previous packet and it was a bnop. The check
|
||||
// for delay == 5 is no longer correct, since we did not take into
|
||||
// account the delays of the bnop instruction itself.
|
||||
if ( is_tms6_bnop(get_dword(ea)) && !is_bnop )
|
||||
break;
|
||||
|
||||
insn_t brins;
|
||||
calc_packet_delay(ea, &ci); // just to test for MVK/MVKH
|
||||
bool iscall = ci.call_is_present();
|
||||
decode_insn(&brins, brea);
|
||||
tgtinfo_t tgt;
|
||||
if ( brins.Op1.type == o_near )
|
||||
{
|
||||
ea_t target = to_ea(brins.cs, brins.Op1.addr);
|
||||
if ( iscall )
|
||||
{
|
||||
target = find_first_insn_in_packet(target);
|
||||
brins.add_cref(target, brins.Op1.offb, fl_CN);
|
||||
if ( !func_does_return(target) )
|
||||
flow = false;
|
||||
}
|
||||
tgt.type = iscall ? tgtinfo_t::CALL : tgtinfo_t::BRANCH;
|
||||
tgt.target = target;
|
||||
}
|
||||
else
|
||||
{
|
||||
tgt.type = iscall ? tgtinfo_t::IND_CALL : tgtinfo_t::IND_BRANCH;
|
||||
}
|
||||
if ( !iscall )
|
||||
flow = false;
|
||||
tgt.save_to_idb(*this, insn.ea);
|
||||
if ( iscall )
|
||||
{
|
||||
if ( !is_off0(get_flags(ci.mvk)) )
|
||||
op_offset(ci.mvk, 0, REF_LOW16, ci.next, brins.cs, 0);
|
||||
if ( !is_off0(get_flags(ci.mvkh)) )
|
||||
op_offset(ci.mvkh, 0, REF_HIGH16, ci.next, brins.cs, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// We don't check past one bnop instruction.
|
||||
if ( is_bnop )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if ( flow )
|
||||
add_cref(insn.ea, insn.ea + insn.size, fl_F);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
int idaapi is_align_insn(ea_t ea)
|
||||
{
|
||||
insn_t insn;
|
||||
decode_insn(&insn, ea);
|
||||
switch ( insn.itype )
|
||||
{
|
||||
case TMS6_mv:
|
||||
if ( insn.Op1.reg == insn.Op2.reg )
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
case TMS6_nop:
|
||||
break;
|
||||
}
|
||||
return insn.size;
|
||||
}
|
||||
256
idasdk76/module/tms320c6/ins.cpp
Normal file
256
idasdk76/module/tms320c6/ins.cpp
Normal file
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA).
|
||||
* Copyright (c) 1990-98 by Ilfak Guilfanov.
|
||||
* ALL RIGHTS RESERVED.
|
||||
* E-mail: ig@estar.msk.su
|
||||
* FIDO: 2:5020/209
|
||||
*
|
||||
*
|
||||
* TMS320C6xx - VLIW (very long instruction word) architecture
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tms6.hpp"
|
||||
|
||||
const instruc_t Instructions[] =
|
||||
{
|
||||
|
||||
// Original TMS320C62x instructions
|
||||
|
||||
{ "", 0 }, // Unknown Operation
|
||||
{ "ABS", CF_USE1|CF_CHG2 }, // Absolute value
|
||||
{ "ADD", CF_USE1|CF_USE2|CF_CHG3 }, // Integer addition without saturation (signed)
|
||||
{ "ADDU", CF_USE1|CF_USE2|CF_CHG3 }, // Integer addition without saturation (unsigned)
|
||||
{ "ADDAB", CF_USE1|CF_USE2|CF_CHG3 }, // Integer addition using addressing mode (byte)
|
||||
{ "ADDAH", CF_USE1|CF_USE2|CF_CHG3 }, // Integer addition using addressing mode (halfword)
|
||||
{ "ADDAW", CF_USE1|CF_USE2|CF_CHG3 }, // Integer addition using addressing mode (word)
|
||||
{ "ADDK", CF_USE1|CF_CHG2 }, // Integer addition 16bit signed constant
|
||||
{ "ADD2", CF_USE1|CF_USE2|CF_CHG3 }, // Two 16bit Integer adds on register halves
|
||||
{ "AND", CF_USE1|CF_USE2|CF_CHG3 }, // Logical AND
|
||||
{ "B", CF_USE1 }, // Branch
|
||||
{ "CLR", CF_USE1|CF_USE2|CF_CHG3 }, // Clear a bit field
|
||||
{ "CMPEQ", CF_USE1|CF_USE2|CF_CHG3 }, // Compare for equality
|
||||
{ "CMPGT", CF_USE1|CF_USE2|CF_CHG3 }, // Compare for greater than (signed)
|
||||
{ "CMPGTU", CF_USE1|CF_USE2|CF_CHG3 }, // Compare for greater than (unsigned)
|
||||
{ "CMPLT", CF_USE1|CF_USE2|CF_CHG3 }, // Compare for less than (signed)
|
||||
{ "CMPLTU", CF_USE1|CF_USE2|CF_CHG3 }, // Compare for less than (unsigned)
|
||||
{ "EXT", CF_USE1|CF_USE2|CF_CHG3 }, // Extract and sign-extend a bit filed
|
||||
{ "EXTU", CF_USE1|CF_USE2|CF_CHG3 }, // Extract an unsigned bit field
|
||||
{ "IDLE", CF_STOP }, // Multicycle NOP with no termination until interrupt
|
||||
{ "LDB", CF_USE1|CF_CHG2 }, // Load from memory (signed 8bit)
|
||||
{ "LDBU", CF_USE1|CF_CHG2 }, // Load from memory (unsigned 8bit)
|
||||
{ "LDH", CF_USE1|CF_CHG2 }, // Load from memory (signed 16bit)
|
||||
{ "LDHU", CF_USE1|CF_CHG2 }, // Load from memory (unsigned 16bit)
|
||||
{ "LDW", CF_USE1|CF_CHG2 }, // Load from memory (32bit)
|
||||
{ "LMBD", CF_USE1|CF_USE2|CF_CHG3 }, // Leftmost bit detection
|
||||
{ "MPY", CF_USE1|CF_USE2|CF_CHG3 }, // Signed Integer Multiply (LSB16 x LSB16)
|
||||
{ "MPYU", CF_USE1|CF_USE2|CF_CHG3 }, // Unsigned Integer Multiply (LSB16 x LSB16)
|
||||
{ "MPYUS", CF_USE1|CF_USE2|CF_CHG3 }, // Integer Multiply Signed*Unsigned (LSB16 x LSB16)
|
||||
{ "MPYSU", CF_USE1|CF_USE2|CF_CHG3 }, // Integer Multiply Unsigned*Signed (LSB16 x LSB16)
|
||||
{ "MPYH", CF_USE1|CF_USE2|CF_CHG3 }, // Signed Integer Multiply (MSB16 x MSB16)
|
||||
{ "MPYHU", CF_USE1|CF_USE2|CF_CHG3 }, // Unsigned Integer Multiply (MSB16 x MSB16)
|
||||
{ "MPYHUS", CF_USE1|CF_USE2|CF_CHG3 }, // Integer Multiply Unsigned*Signed (MSB16 x MSB16)
|
||||
{ "MPYHSU", CF_USE1|CF_USE2|CF_CHG3 }, // Integer Multiply Signed*Unsigned (MSB16 x MSB16)
|
||||
{ "MPYHL", CF_USE1|CF_USE2|CF_CHG3 }, // Signed Integer Multiply (MSB16 x LSB16)
|
||||
{ "MPYHLU", CF_USE1|CF_USE2|CF_CHG3 }, // Unsigned Integer Multiply (MSB16 x LSB16)
|
||||
{ "MPYHULS", CF_USE1|CF_USE2|CF_CHG3 }, // Integer Multiply Signed*Unsigned (MSB16 x LSB16)
|
||||
{ "MPYHSLU", CF_USE1|CF_USE2|CF_CHG3 }, // Integer Multiply Unsigned*Signed (MSB16 x LSB16)
|
||||
{ "MPYLH", CF_USE1|CF_USE2|CF_CHG3 }, // Signed Integer Multiply (LSB16 x MB16)
|
||||
{ "MPYLHU", CF_USE1|CF_USE2|CF_CHG3 }, // Unsigned Integer Multiply (LSB16 x MSB16)
|
||||
{ "MPYLUHS", CF_USE1|CF_USE2|CF_CHG3 }, // Integer Multiply Signed*Unsigned (LSB16 x MSB16)
|
||||
{ "MPYLSHU", CF_USE1|CF_USE2|CF_CHG3 }, // Integer Multiply Unsigned*Signed (LSB16 x MSB16)
|
||||
{ "MV", CF_USE1|CF_CHG2 }, // Move from register to register
|
||||
{ "MVC", CF_USE1|CF_CHG2 }, // Move between the control file & register file
|
||||
{ "MVK", CF_USE1|CF_CHG2 }, // Move a 16bit signed constant into register
|
||||
{ "MVKH", CF_USE1|CF_CHG2 }, // Move a 16bit constant into the upper bits of a register
|
||||
{ "MVKLH", CF_USE1|CF_CHG2 }, // Move a 16bit constant into the upper bits of a register
|
||||
{ "NEG", CF_USE1|CF_CHG2 }, // Negate
|
||||
{ "NOP", CF_USE1 }, // No operation
|
||||
{ "NORM", CF_USE1|CF_CHG2 }, // Normalize
|
||||
{ "NOT", CF_USE1|CF_CHG2 }, // Bitwise NOT
|
||||
{ "OR", CF_USE1|CF_USE2|CF_CHG3 }, // Logical or
|
||||
{ "SADD", CF_USE1|CF_USE2|CF_CHG3 }, // Integer addition with saturation
|
||||
{ "SAT", CF_USE1|CF_CHG2 }, // Saturate 40bit value to 32bits
|
||||
{ "SET", CF_USE1|CF_USE2|CF_CHG3 }, // Set a bit field
|
||||
{ "SHL", CF_USE1|CF_USE2|CF_CHG3 }, // Arithmetic shift left
|
||||
{ "SHR", CF_USE1|CF_USE2|CF_CHG3 }, // Arithmetic shift right
|
||||
{ "SHRU", CF_USE1|CF_USE2|CF_CHG3 }, // Logical shift left
|
||||
{ "SMPY", CF_USE1|CF_USE2|CF_CHG3 }, // Integer multiply with left shift & saturation (LSB16*LSB16)
|
||||
{ "SMPYHL", CF_USE1|CF_USE2|CF_CHG3 }, // Integer multiply with left shift & saturation (MSB16*LSB16)
|
||||
{ "SMPYLH", CF_USE1|CF_USE2|CF_CHG3 }, // Integer multiply with left shift & saturation (LSB16*MSB16)
|
||||
{ "SMPYH", CF_USE1|CF_USE2|CF_CHG3 }, // Integer multiply with left shift & saturation (MSB16*MSB16)
|
||||
{ "SSHL", CF_USE1|CF_USE2|CF_CHG3 }, // Shift left with saturation
|
||||
{ "SSUB", CF_USE1|CF_USE2|CF_CHG3 }, // Integer substraction with saturation
|
||||
{ "STB", CF_USE1|CF_CHG2 }, // Store to memory (signed 8bit)
|
||||
{ "STBU", CF_USE1|CF_CHG2 }, // Store to memory (unsigned 8bit)
|
||||
{ "STH", CF_USE1|CF_CHG2 }, // Store to memory (signed 16bit)
|
||||
{ "STHU", CF_USE1|CF_CHG2 }, // Store to memory (unsigned 16bit)
|
||||
{ "STW", CF_USE1|CF_CHG2 }, // Store to memory (32bit)
|
||||
{ "SUB", CF_USE1|CF_USE2|CF_CHG3 }, // Integer substaraction without saturation (signed)
|
||||
{ "SUBU", CF_USE1|CF_USE2|CF_CHG3 }, // Integer substaraction without saturation (unsigned)
|
||||
{ "SUBAB", CF_USE1|CF_USE2|CF_CHG3 }, // Integer subtraction using addressing mode (byte)
|
||||
{ "SUBAH", CF_USE1|CF_USE2|CF_CHG3 }, // Integer subtraction using addressing mode (halfword)
|
||||
{ "SUBAW", CF_USE1|CF_USE2|CF_CHG3 }, // Integer subtraction using addressing mode (word)
|
||||
{ "SUBC", CF_USE1|CF_USE2|CF_CHG3 }, // Conditional subtract & shift (for division)
|
||||
{ "SUB2", CF_USE1|CF_USE2|CF_CHG3 }, // Two 16bit integer subtractions on register halves
|
||||
{ "XOR", CF_USE1|CF_USE2|CF_CHG3 }, // Exclusive OR
|
||||
{ "ZERO", CF_CHG1 }, // Zero a register
|
||||
|
||||
// New TMS320C674x instructions
|
||||
|
||||
{ "ABS2", CF_USE1|CF_CHG2 }, // Absolute Value With Saturation, Signed, Packed 16-bit
|
||||
{ "ABSDP", CF_USE1|CF_CHG2 }, // Absolute Value, Double-Precision Floating-Point
|
||||
{ "ABSSP", CF_USE1|CF_CHG2 }, // Absolute Value, Single-Precision Floating-Point
|
||||
{ "ADD4", CF_USE1|CF_USE2|CF_CHG3 }, // Add Without Saturation, Four 8-Bit Pairs for Four 8-Bit Results
|
||||
{ "ADDAD", CF_USE1|CF_USE2|CF_CHG3 }, // Add Using Doubleword Addressing Mode
|
||||
{ "ADDDP", CF_USE1|CF_USE2|CF_CHG3 }, // Add Two Double-Precision Floating-Point Values
|
||||
{ "ADDKPC", CF_USE1|CF_CHG2|CF_USE3 }, // Add Signed 7-bit Constant to Program Counter
|
||||
{ "ADDSP", CF_USE1|CF_USE2|CF_CHG3 }, // Add Two Single-Precision Floating-Point Values
|
||||
{ "ADDSUB", CF_USE1|CF_USE2|CF_CHG3 }, // Parallel ADD and SUB Operations On Common Inputs
|
||||
{ "ADDSUB2", CF_USE1|CF_USE2|CF_CHG3 }, // Parallel ADD2 and SUB2 Operations On Common Inputs
|
||||
{ "ANDN", CF_USE1|CF_USE2|CF_CHG3 }, // Bitwise AND Invert
|
||||
{ "AVG2", CF_USE1|CF_USE2|CF_CHG3 }, // Average, Signed, Packed 16-bit
|
||||
{ "AVGU4", CF_USE1|CF_USE2|CF_CHG3 }, // Average, Unsigned, Packed 16-bit
|
||||
{ "BDEC", CF_USE1|CF_CHG2 }, // Branch and Decrement
|
||||
{ "BITC4", CF_USE1|CF_CHG2 }, // Bit Count, Packed 8-bit
|
||||
{ "BITR", CF_USE1|CF_CHG2 }, // Bit Reverse
|
||||
{ "BNOP", CF_USE1|CF_USE2 }, // Branch With NOP
|
||||
{ "BPOS", CF_USE1|CF_CHG2 }, // Branch Positive
|
||||
{ "CALLP", CF_USE1|CF_CHG2 }, // Call Using a Displacement
|
||||
{ "CMPEQ2", CF_USE1|CF_USE2|CF_CHG3 }, // Compare for Equality, Packed 16-bit
|
||||
{ "CMPEQ4", CF_USE1|CF_USE2|CF_CHG3 }, // Compare for Equality, Packed 8-bit
|
||||
{ "CMPEQDP", CF_USE1|CF_USE2|CF_CHG3 }, // Compare for Equality, Double-Precision Floating-Point Values
|
||||
{ "CMPEQSP", CF_USE1|CF_USE2|CF_CHG3 }, // Compare for Equality, Single-Precision Floating-Point Values
|
||||
{ "CMPGT2", CF_USE1|CF_USE2|CF_CHG3 }, // Compare for Greater Than, Packed 16-bit
|
||||
{ "CMPGTDP", CF_USE1|CF_USE2|CF_CHG3 }, // Compare for Greater Than, Double-Precision Floating-Point Values
|
||||
{ "CMPGTSP", CF_USE1|CF_USE2|CF_CHG3 }, // Compare for Greater Than, Single-Precision Floating-Point Values
|
||||
{ "CMPGTU4", CF_USE1|CF_USE2|CF_CHG3 }, // Compare for Greater Than, Unsigned, Packed 8-bit
|
||||
{ "CMPLT2", CF_USE1|CF_USE2|CF_CHG3 }, // Compare for Less Than, Packed 16-bit
|
||||
{ "CMPLTDP", CF_USE1|CF_USE2|CF_CHG3 }, // Compare for Less Than, Double-Precision Floating-Point Values
|
||||
{ "CMPLTSP", CF_USE1|CF_USE2|CF_CHG3 }, // Compare for Less Than, Single-Precision Floating-Point Values
|
||||
{ "CMPLTU4", CF_USE1|CF_USE2|CF_CHG3 }, // Compare for Less Than, Unsigned, Packed 8-bit
|
||||
{ "CMPY", CF_USE1|CF_USE2|CF_CHG3 }, // Complex Multiply Two Pairs, Signed, Packed 16-bit
|
||||
{ "CMPYR", CF_USE1|CF_USE2|CF_CHG3 }, // Complex Multiply Two Pairs, Signed, Packed 16-bit With Rounding
|
||||
{ "CMPYR1", CF_USE1|CF_USE2|CF_CHG3 }, // Complex Multiply Two Pairs, Signed, Packed 16-bit With Rounding
|
||||
{ "DDOTP4", CF_USE1|CF_USE2|CF_CHG3 }, // Double Dot Product, Signed, Packed 16-Bit and Signed, Packed 8-Bit
|
||||
{ "DDOTPH2", CF_USE1|CF_USE2|CF_CHG3 }, // Double Dot Product, Two Pairs, Signed, Packed 16-Bit
|
||||
{ "DDOTPH2R", CF_USE1|CF_USE2|CF_CHG3 }, // Double Dot Product With Rounding, Two Pairs, Signed, Packed 16-Bit
|
||||
{ "DDOTPL2", CF_USE1|CF_USE2|CF_CHG3 }, // Double Dot Product, Two Pairs, Signed, Packed 16-Bit
|
||||
{ "DDOTPL2R", CF_USE1|CF_USE2|CF_CHG3 }, // Double Dot Product With Rounding, Two Pairs, Signed Packed 16-Bit
|
||||
{ "DEAL", CF_USE1|CF_CHG2 }, // Deinterleave and Pack
|
||||
{ "DINT", 0 }, // Disable Interrupts and Save Previous Enable State
|
||||
{ "DMV", CF_USE1|CF_USE2|CF_CHG3 }, // Move Two Independent Registers to Register Pair
|
||||
{ "DOTP2", CF_USE1|CF_USE2|CF_CHG3 }, // Dot Product, Signed, Packed 16-Bit
|
||||
{ "DOTPN2", CF_USE1|CF_USE2|CF_CHG3 }, // Dot Product With Negate, Signed, Packed 16-Bit
|
||||
{ "DOTPNRSU2", CF_USE1|CF_USE2|CF_CHG3 }, // Dot Product With Negate, Shift and Round, Signed by Unsigned, Packed 16-Bit
|
||||
{ "DOTPNRUS2", CF_USE1|CF_USE2|CF_CHG3 }, // Dot Product With Negate, Shift and Round, Unsigned by Signed, Packed 16-Bit
|
||||
{ "DOTPRSU2", CF_USE1|CF_USE2|CF_CHG3 }, // Dot Product With Shift and Round, Signed by Unsigned, Packed 16-Bit
|
||||
{ "DOTPRUS2", CF_USE1|CF_USE2|CF_CHG3 }, // Dot Product With Shift and Round, Unsigned by Signed, Packed 16-Bit
|
||||
{ "DOTPSU4", CF_USE1|CF_USE2|CF_CHG3 }, // Dot Product, Signed by Unsigned, Packed 8-Bit
|
||||
{ "DOTPU4", CF_USE1|CF_USE2|CF_CHG3 }, // Dot Product, Unsigned, Packed 8-Bit
|
||||
{ "DOTPUS4", CF_USE1|CF_USE2|CF_CHG3 }, // Dot Product, Unsigned by Signed, Packed 8-Bit
|
||||
{ "DPACK2", CF_USE1|CF_USE2|CF_CHG3 }, // Parallel PACK2 and PACKH2 Operations
|
||||
{ "DPACKX2", CF_USE1|CF_USE2|CF_CHG3 }, // Parallel PACKLH2 Operations
|
||||
{ "DPINT", CF_USE1|CF_CHG2 }, // Convert Double-Precision Floating-Point Value to Integer
|
||||
{ "DPSP", CF_USE1|CF_CHG2 }, // Convert Double-Precision Floating-Point Value to Single-Precision Floating-Point Value
|
||||
{ "DPTRUNC", CF_USE1|CF_CHG2 }, // Convert Double-Precision Floating-Point Value to Integer With Truncation
|
||||
{ "GMPY", CF_USE1|CF_USE2|CF_CHG3 }, // Galois Field Multiply
|
||||
{ "GMPY4", CF_USE1|CF_USE2|CF_CHG3 }, // Galois Field Multiply, Packed 8-Bit
|
||||
{ "INTDP", CF_USE1|CF_CHG2 }, // Convert Signed Integer to Double-Precision Floating-Point Value
|
||||
{ "INTDPU", CF_USE1|CF_CHG2 }, // Convert Unsigned Integer to Double-Precision Floating-Point Value
|
||||
{ "INTSP", CF_USE1|CF_CHG2 }, // Convert Signed Integer to Single-Precision Floating-Point Value
|
||||
{ "INTSPU", CF_USE1|CF_CHG2 }, // Convert Unsigned Integer to Single-Precision Floating-Point Value
|
||||
{ "LDDW", CF_USE1|CF_CHG2 }, // Load Doubleword From Memory With a 5-Bit Unsigned Constant Offset or Register Offset
|
||||
{ "LDNDW", CF_USE1|CF_CHG2 }, // Load Nonaligned Doubleword From Memory With Constant or Register Offset
|
||||
{ "LDNW", CF_USE1|CF_CHG2 }, // Load Nonaligned Word From Memory With Constant or Register Offset
|
||||
{ "MAX2", CF_USE1|CF_USE2|CF_CHG3 }, // Maximum, Signed, Packed 16-Bit
|
||||
{ "MAXU4", CF_USE1|CF_USE2|CF_CHG3 }, // Maximum, Unsigned, Packed 8-Bit
|
||||
{ "MIN2", CF_USE1|CF_USE2|CF_CHG3 }, // Minimum, Signed, Packed 16-Bit
|
||||
{ "MINU4", CF_USE1|CF_USE2|CF_CHG3 }, // Minimum, Unsigned, Packed 8-Bit
|
||||
{ "MPY2", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Signed by Signed, 16 LSB x 16 LSB and 16 MSB x 16 MSB
|
||||
{ "MPY2IR", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Two 16-Bit x 32-Bit, Shifted by 15 to Produce a Rounded 32-Bit Result
|
||||
{ "MPY32", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Signed 32-Bit x Signed 32-Bit Into 32-Bit Result
|
||||
{ "MPY32SU", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Signed 32-Bit x Unsigned 32-Bit Into Signed 64-Bit Result
|
||||
{ "MPY32U", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Unsigned 32-Bit x Unsigned 32-Bit Into Unsigned 64-Bit Result
|
||||
{ "MPY32US", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Unsigned 32-Bit x Signed 32-Bit Into Signed 64-Bit Result
|
||||
{ "MPYDP", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Two Double-Precision Floating-Point Values
|
||||
{ "MPYHI", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply 16 MSB x 32-Bit Into 64-Bit Result
|
||||
{ "MPYHIR", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply 16 MSB x 32-Bit, Shifted by 15 to Produce a Rounded 32-Bit Result
|
||||
{ "MPYI", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply 32-Bit x 32-Bit Into 32-Bit Result
|
||||
{ "MPYID", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply 32-Bit x 32-Bit Into 64-Bit Result
|
||||
{ "MPYIH", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply 32-Bit x 16-MSB Into 64-Bit Result
|
||||
{ "MPYIHR", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply 32-Bit x 16 MSB, Shifted by 15 to Produce a Rounded 32-Bit Result
|
||||
{ "MPYIL", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply 32-Bit x 16 LSB Into 64-Bit Result
|
||||
{ "MPYILR", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply 32-Bit x 16 LSB, Shifted by 15 to Produce a Rounded 32-Bit Result
|
||||
{ "MPYLI", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply 16 LSB x 32-Bit Into 64-Bit Result
|
||||
{ "MPYLIR", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply 16 LSB x 32-Bit, Shifted by 15 to Produce a Rounded 32-Bit Result
|
||||
{ "MPYSP", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Two Single-Precision Floating-Point Values
|
||||
{ "MPYSP2DP", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Two Single-Precision Floating-Point Values for Double-Precision Result
|
||||
{ "MPYSPDP", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Single-Precision Floating-Point Value x Double-Precision Floating-Point Value
|
||||
{ "MPYSU4", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Signed x Unsigned, Four 8-Bit Pairs for Four 8-Bit Results
|
||||
{ "MPYU4", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Unsigned x Unsigned, Four 8-Bit Pairs for Four 8-Bit Results
|
||||
{ "MPYUS4", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Unsigned x Signed, Four 8-Bit Pairs for Four 8-Bit Results
|
||||
{ "MVD", CF_USE1|CF_CHG2 }, // Move From Register to Register, Delayed
|
||||
{ "MVKL", CF_USE1|CF_CHG2 }, // Move Signed Constant Into Register and Sign Extend
|
||||
{ "PACK2", CF_USE1|CF_USE2|CF_CHG3 }, // Pack Two 16 LSBs Into Upper and Lower Register Halves
|
||||
{ "PACKH2", CF_USE1|CF_USE2|CF_CHG3 }, // Pack Two 16 MSBs Into Upper and Lower Register Halves
|
||||
{ "PACKH4", CF_USE1|CF_USE2|CF_CHG3 }, // Pack Four High Bytes Into Four 8-Bit Halfwords
|
||||
{ "PACKHL2", CF_USE1|CF_USE2|CF_CHG3 }, // Pack 16 MSB Into Upper and 16 LSB Into Lower Register Halves
|
||||
{ "PACKL4", CF_USE1|CF_USE2|CF_CHG3 }, // Pack Four Low Bytes Into Four 8-Bit Halfwords
|
||||
{ "PACKLH2", CF_USE1|CF_USE2|CF_CHG3 }, // Pack 16 LSB Into Upper and 16 MSB Into Lower Register Halves
|
||||
{ "RCPDP", CF_USE1|CF_CHG2 }, // Double-Precision Floating-Point Reciprocal Approximation
|
||||
{ "RCPSP", CF_USE1|CF_CHG2 }, // Single-Precision Floating-Point Reciprocal Approximation
|
||||
{ "RINT", 0 }, // Restore Previous Enable State
|
||||
{ "ROTL", CF_USE1|CF_USE2|CF_CHG3 }, // Rotate Left
|
||||
{ "RPACK2", CF_USE1|CF_USE2|CF_CHG3 }, // Shift With Saturation and Pack Two 16 MSBs Into Upper and Lower Register Halves
|
||||
{ "RSQRDP", CF_USE1|CF_CHG2 }, // Double-Precision Floating-Point Square-Root Reciprocal Approximation
|
||||
{ "RSQRSP", CF_USE1|CF_CHG2 }, // Single-Precision Floating-Point Square-Root Reciprocal Approximation
|
||||
{ "SADD2", CF_USE1|CF_USE2|CF_CHG3 }, // Add Two Signed 16-Bit Integers on Upper and Lower Register Halves With Saturation
|
||||
{ "SADDSU2", CF_USE1|CF_USE2|CF_CHG3 }, // Add Two Signed and Unsigned 16-Bit Integers on Register Halves With Saturation
|
||||
{ "SADDSUB", CF_USE1|CF_USE2|CF_CHG3 }, // Parallel SADD and SSUB Operations On Common Inputs
|
||||
{ "SADDSUB2", CF_USE1|CF_USE2|CF_CHG3 }, // Parallel SADD2 and SSUB2 Operations On Common Inputs
|
||||
{ "SADDU4", CF_USE1|CF_USE2|CF_CHG3 }, // Add With Saturation, Four Unsigned 8-Bit Pairs for Four 8-Bit Results
|
||||
{ "SADDUS2", CF_USE1|CF_USE2|CF_CHG3 }, // Add Two Unsigned and Signed 16-Bit Integers on Register Halves With Saturation
|
||||
{ "SHFL", CF_USE1|CF_CHG2 }, // Shuffle
|
||||
{ "SHFL3", CF_USE1|CF_USE2|CF_CHG3 }, // 3-Way Bit Interleave On Three 16-Bit Values Into a 48-Bit Result
|
||||
{ "SHLMB", CF_USE1|CF_USE2|CF_CHG3 }, // Shift Left and Merge Byte
|
||||
{ "SHR2", CF_USE1|CF_USE2|CF_CHG3 }, // Arithmetic Shift Right, Signed, Packed 16-Bit
|
||||
{ "SHRMB", CF_USE1|CF_USE2|CF_CHG3 }, // Shift Right and Merge Byte
|
||||
{ "SHRU2", CF_USE1|CF_USE2|CF_CHG3 }, // Arithmetic Shift Right, Unsigned, Packed 16-Bit
|
||||
{ "SMPY2", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Signed by Signed, 16 LSB x 16 LSB and 16 MSB x 16 MSB With Left Shift and Saturation
|
||||
{ "SMPY32", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply Signed 32-Bit x Signed 32-Bit Into 64-Bit Result With Left Shift and Saturation
|
||||
{ "SPACK2", CF_USE1|CF_USE2|CF_CHG3 }, // Saturate and Pack Two 16 LSBs Into Upper and Lower Register Halves
|
||||
{ "SPACKU4", CF_USE1|CF_USE2|CF_CHG3 }, // Saturate and Pack Four Signed 16-Bit Integers Into Four Unsigned 8-Bit Halfwords
|
||||
{ "SPDP", CF_USE1|CF_CHG2 }, // Convert Single-Precision Floating-Point Value to Double-Precision Floating-Point Value
|
||||
{ "SPINT", CF_USE1|CF_CHG2 }, // Convert Single-Precision Floating-Point Value to Integer
|
||||
{ "SPKERNEL", CF_USE1 }, // Software Pipelined Loop (SPLOOP) Buffer Operation Code Boundary
|
||||
{ "SPKERNELR", 0 }, // Software Pipelined Loop (SPLOOP) Buffer Operation Code Boundary
|
||||
{ "SPLOOP", CF_USE1 }, // Software Pipelined Loop (SPLOOP) Buffer Operation
|
||||
{ "SPLOOPD", CF_USE1 }, // Software Pipelined Loop (SPLOOP) Buffer Operation With Delayed Testing
|
||||
{ "SPLOOPW", CF_USE1 }, // Software Pipelined Loop (SPLOOP) Buffer Operation With Delayed Testing and No Epilog
|
||||
{ "SPMASK", CF_USE1 }, // Software Pipelined Loop (SPLOOP) Buffer Operation Load/Execution Control
|
||||
{ "SPMASKR", CF_USE1 }, // Software Pipelined Loop (SPLOOP) Buffer Operation Load/Execution Control
|
||||
{ "SPTRUNC", CF_USE1|CF_CHG2 }, // Convert Single-Precision Floating-Point Value to Integer With Truncation
|
||||
{ "SSHVL", CF_USE1|CF_USE2|CF_CHG3 }, // Variable Shift Left
|
||||
{ "SSHVR", CF_USE1|CF_USE2|CF_CHG3 }, // Variable Shift Right
|
||||
{ "SSUB2", CF_USE1|CF_USE2|CF_CHG3 }, // Subtract Two Signed 16-Bit Integers on Upper and Lower Register Halves With Saturation
|
||||
{ "STDW", CF_USE1|CF_CHG2 }, // Store Doubleword to Memory With a 5-Bit Unsigned Constant Offset or Register Offset
|
||||
{ "STNDW", CF_USE1|CF_CHG2 }, // Store Nonaligned Doubleword to Memory With a 5-Bit Unsigned Constant Offset or Register Offset
|
||||
{ "STNW", CF_USE1|CF_CHG2 }, // Store Nonaligned Word to Memory With a 5-Bit Unsigned Constant Offset or Register Offset
|
||||
{ "SUB4", CF_USE1|CF_USE2|CF_CHG3 }, // Subtract Without Saturation, Four 8-Bit Pairs for Four 8-Bit Results
|
||||
{ "SUBABS4", CF_USE1|CF_USE2|CF_CHG3 }, // Subtract With Absolute Value, Four 8-Bit Pairs for Four 8-Bit Results
|
||||
{ "SUBDP", CF_USE1|CF_USE2|CF_CHG3 }, // Subtract Two Double-Precision Floating-Point Values
|
||||
{ "SUBSP", CF_USE1|CF_USE2|CF_CHG3 }, // Subtract Two Single-Precision Floating-Point Values
|
||||
{ "SWAP2", CF_USE1|CF_CHG2 }, // Swap Bytes in Upper and Lower Register Halves
|
||||
{ "SWAP4", CF_USE1|CF_CHG2 }, // Swap Byte Pairs in Upper and Lower Register Halves
|
||||
{ "SWE", 0 }, // Software Exception
|
||||
{ "SWENR", 0 }, // Software Exception, No Return
|
||||
{ "UNPKHU4", CF_USE1|CF_CHG2 }, // Unpack 16 MSB Into Two Lower 8-Bit Halfwords of Upper and Lower Register Halves
|
||||
{ "UNPKLU4", CF_USE1|CF_CHG2 }, // Unpack 16 LSB Into Two Lower 8-Bit Halfwords of Upper and Lower Register Halves
|
||||
{ "XORMPY", CF_USE1|CF_USE2|CF_CHG3 }, // Galois Field Multiply With Zero Polynomial
|
||||
{ "XPND2", CF_USE1|CF_CHG2 }, // Expand Bits to Packed 16-Bit Masks
|
||||
{ "XPND4", CF_USE1|CF_CHG2 }, // Expand Bits to Packed 8-Bit Masks
|
||||
|
||||
};
|
||||
|
||||
CASSERT(qnumber(Instructions) == TMS6_last);
|
||||
257
idasdk76/module/tms320c6/ins.hpp
Normal file
257
idasdk76/module/tms320c6/ins.hpp
Normal file
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA).
|
||||
* Copyright (c) 1990-2021 Hex-Rays
|
||||
* ALL RIGHTS RESERVED.
|
||||
*
|
||||
* TMS320C6xx - VLIW (very long instruction word) architecture
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __INSTRS_HPP
|
||||
#define __INSTRS_HPP
|
||||
|
||||
extern const instruc_t Instructions[];
|
||||
|
||||
enum nameNum ENUM_SIZE(uint16)
|
||||
{
|
||||
// Original TMS320C62x instructions
|
||||
|
||||
TMS6_null = 0, // Unknown Operation
|
||||
TMS6_abs, // Absolute value
|
||||
TMS6_add, // Integer addition without saturation (signed)
|
||||
TMS6_addu, // Integer addition without saturation (unsigned)
|
||||
TMS6_addab, // Integer addition using addressing mode (byte)
|
||||
TMS6_addah, // Integer addition using addressing mode (halfword)
|
||||
TMS6_addaw, // Integer addition using addressing mode (word)
|
||||
TMS6_addk, // Integer addition 16bit signed constant
|
||||
TMS6_add2, // Two 16bit Integer adds on register halves
|
||||
TMS6_and, // Logical AND
|
||||
TMS6_b, // Branch
|
||||
TMS6_clr, // Clear a bit field
|
||||
TMS6_cmpeq, // Compare for equality
|
||||
TMS6_cmpgt, // Compare for greater than (signed)
|
||||
TMS6_cmpgtu, // Compare for greater than (unsigned)
|
||||
TMS6_cmplt, // Compare for less than (signed)
|
||||
TMS6_cmpltu, // Compare for less than (unsigned)
|
||||
TMS6_ext, // Extract and sign-extend a bit filed
|
||||
TMS6_extu, // Extract an unsigned bit field
|
||||
TMS6_idle, // Multicycle NOP with no termination until interrupt
|
||||
TMS6_ldb, // Load from memory (signed 8bit)
|
||||
TMS6_ldbu, // Load from memory (unsigned 8bit)
|
||||
TMS6_ldh, // Load from memory (signed 16bit)
|
||||
TMS6_ldhu, // Load from memory (unsigned 16bit)
|
||||
TMS6_ldw, // Load from memory (32bit)
|
||||
TMS6_lmbd, // Leftmost bit detection
|
||||
TMS6_mpy, // Signed Integer Multiply (LSB16 x LSB16)
|
||||
TMS6_mpyu, // Unsigned Integer Multiply (LSB16 x LSB16)
|
||||
TMS6_mpyus, // Integer Multiply Signed*Unsigned (LSB16 x LSB16)
|
||||
TMS6_mpysu, // Integer Multiply Unsigned*Signed (LSB16 x LSB16)
|
||||
TMS6_mpyh, // Signed Integer Multiply (MSB16 x MSB16)
|
||||
TMS6_mpyhu, // Unsigned Integer Multiply (MSB16 x MSB16)
|
||||
TMS6_mpyhus, // Integer Multiply Unsigned*Signed (MSB16 x MSB16)
|
||||
TMS6_mpyhsu, // Integer Multiply Signed*Unsigned (MSB16 x MSB16)
|
||||
TMS6_mpyhl, // Signed Integer Multiply (MSB16 x LSB16)
|
||||
TMS6_mpyhlu, // Unsigned Integer Multiply (MSB16 x LSB16)
|
||||
TMS6_mpyhuls, // Integer Multiply Signed*Unsigned (MSB16 x LSB16)
|
||||
TMS6_mpyhslu, // Integer Multiply Unsigned*Signed (MSB16 x LSB16)
|
||||
TMS6_mpylh, // Signed Integer Multiply (LSB16 x MB16)
|
||||
TMS6_mpylhu, // Unsigned Integer Multiply (LSB16 x MSB16)
|
||||
TMS6_mpyluhs, // Integer Multiply Signed*Unsigned (LSB16 x MSB16)
|
||||
TMS6_mpylshu, // Integer Multiply Unsigned*Signed (LSB16 x MSB16)
|
||||
TMS6_mv, // Move from register to register
|
||||
TMS6_mvc, // Move between the control file & register file
|
||||
TMS6_mvk, // Move a 16bit signed constant into register
|
||||
TMS6_mvkh, // Move a 16bit constant into the upper bits of a register
|
||||
TMS6_mvklh, // Move a 16bit constant into the upper bits of a register
|
||||
TMS6_neg, // Negate
|
||||
TMS6_nop, // No operation
|
||||
TMS6_norm, // Normalize
|
||||
TMS6_not, // Bitwise NOT
|
||||
TMS6_or, // Logical or
|
||||
TMS6_sadd, // Integer addition with saturation
|
||||
TMS6_sat, // Saturate 40bit value to 32bits
|
||||
TMS6_set, // Set a bit field
|
||||
TMS6_shl, // Arithmetic shift left
|
||||
TMS6_shr, // Arithmetic shift right
|
||||
TMS6_shru, // Logical shift left
|
||||
TMS6_smpy, // Integer multiply with left shift & saturation (LSB16*LSB16)
|
||||
TMS6_smpyhl, // Integer multiply with left shift & saturation (MSB16*LSB16)
|
||||
TMS6_smpylh, // Integer multiply with left shift & saturation (LSB16*MSB16)
|
||||
TMS6_smpyh, // Integer multiply with left shift & saturation (MSB16*MSB16)
|
||||
TMS6_sshl, // Shift left with saturation
|
||||
TMS6_ssub, // Integer substraction with saturation
|
||||
TMS6_stb, // Store to memory (signed 8bit)
|
||||
TMS6_stbu, // Store to memory (unsigned 8bit)
|
||||
TMS6_sth, // Store to memory (signed 16bit)
|
||||
TMS6_sthu, // Store to memory (unsigned 16bit)
|
||||
TMS6_stw, // Store to memory (32bit)
|
||||
TMS6_sub, // Integer substaraction without saturation (signed)
|
||||
TMS6_subu, // Integer substaraction without saturation (unsigned)
|
||||
TMS6_subab, // Integer subtraction using addressing mode (byte)
|
||||
TMS6_subah, // Integer subtraction using addressing mode (halfword)
|
||||
TMS6_subaw, // Integer subtraction using addressing mode (word)
|
||||
TMS6_subc, // Conditional subtract & shift (for division)
|
||||
TMS6_sub2, // Two 16bit integer subtractions on register halves
|
||||
TMS6_xor, // Exclusive OR
|
||||
TMS6_zero, // Zero a register
|
||||
|
||||
// New TMS320C674x instructions
|
||||
|
||||
TMS6_abs2, // Absolute Value With Saturation, Signed, Packed 16-bit
|
||||
TMS6_absdp, // Absolute Value, Double-Precision Floating-Point
|
||||
TMS6_abssp, // Absolute Value, Single-Precision Floating-Point
|
||||
TMS6_add4, // Add Without Saturation, Four 8-Bit Pairs for Four 8-Bit Results
|
||||
TMS6_addad, // Add Using Doubleword Addressing Mode
|
||||
TMS6_adddp, // Add Two Double-Precision Floating-Point Values
|
||||
TMS6_addkpc, // Add Signed 7-bit Constant to Program Counter
|
||||
TMS6_addsp, // Add Two Single-Precision Floating-Point Values
|
||||
TMS6_addsub, // Parallel ADD and SUB Operations On Common Inputs
|
||||
TMS6_addsub2, // Parallel ADD2 and SUB2 Operations On Common Inputs
|
||||
TMS6_andn, // Bitwise AND Invert
|
||||
TMS6_avg2, // Average, Signed, Packed 16-bit
|
||||
TMS6_avgu4, // Average, Unsigned, Packed 16-bit
|
||||
TMS6_bdec, // Branch and Decrement
|
||||
TMS6_bitc4, // Bit Count, Packed 8-bit
|
||||
TMS6_bitr, // Bit Reverse
|
||||
TMS6_bnop, // Branch With NOP
|
||||
TMS6_bpos, // Branch Positive
|
||||
TMS6_callp, // Call Using a Displacement
|
||||
TMS6_cmpeq2, // Compare for Equality, Packed 16-bit
|
||||
TMS6_cmpeq4, // Compare for Equality, Packed 8-bit
|
||||
TMS6_cmpeqdp, // Compare for Equality, Double-Precision Floating-Point Values
|
||||
TMS6_cmpeqsp, // Compare for Equality, Single-Precision Floating-Point Values
|
||||
TMS6_cmpgt2, // Compare for Greater Than, Packed 16-bit
|
||||
TMS6_cmpgtdp, // Compare for Greater Than, Double-Precision Floating-Point Values
|
||||
TMS6_cmpgtsp, // Compare for Greater Than, Single-Precision Floating-Point Values
|
||||
TMS6_cmpgtu4, // Compare for Greater Than, Unsigned, Packed 8-bit
|
||||
TMS6_cmplt2, // Compare for Less Than, Packed 16-bit
|
||||
TMS6_cmpltdp, // Compare for Less Than, Double-Precision Floating-Point Values
|
||||
TMS6_cmpltsp, // Compare for Less Than, Single-Precision Floating-Point Values
|
||||
TMS6_cmpltu4, // Compare for Less Than, Unsigned, Packed 8-bit
|
||||
TMS6_cmpy, // Complex Multiply Two Pairs, Signed, Packed 16-bit
|
||||
TMS6_cmpyr, // Complex Multiply Two Pairs, Signed, Packed 16-bit With Rounding
|
||||
TMS6_cmpyr1, // Complex Multiply Two Pairs, Signed, Packed 16-bit With Rounding
|
||||
TMS6_ddotp4, // Double Dot Product, Signed, Packed 16-Bit and Signed, Packed 8-Bit
|
||||
TMS6_ddotph2, // Double Dot Product, Two Pairs, Signed, Packed 16-Bit
|
||||
TMS6_ddotph2r, // Double Dot Product With Rounding, Two Pairs, Signed, Packed 16-Bit
|
||||
TMS6_ddotpl2, // Double Dot Product, Two Pairs, Signed, Packed 16-Bit
|
||||
TMS6_ddotpl2r, // Double Dot Product With Rounding, Two Pairs, Signed Packed 16-Bit
|
||||
TMS6_deal, // Deinterleave and Pack
|
||||
TMS6_dint, // Disable Interrupts and Save Previous Enable State
|
||||
TMS6_dmv, // Move Two Independent Registers to Register Pair
|
||||
TMS6_dotp2, // Dot Product, Signed, Packed 16-Bit
|
||||
TMS6_dotpn2, // Dot Product With Negate, Signed, Packed 16-Bit
|
||||
TMS6_dotpnrsu2, // Dot Product With Negate, Shift and Round, Signed by Unsigned, Packed 16-Bit
|
||||
TMS6_dotpnrus2, // Dot Product With Negate, Shift and Round, Unsigned by Signed, Packed 16-Bit
|
||||
TMS6_dotprsu2, // Dot Product With Shift and Round, Signed by Unsigned, Packed 16-Bit
|
||||
TMS6_dotprus2, // Dot Product With Shift and Round, Unsigned by Signed, Packed 16-Bit
|
||||
TMS6_dotpsu4, // Dot Product, Signed by Unsigned, Packed 8-Bit
|
||||
TMS6_dotpu4, // Dot Product, Unsigned, Packed 8-Bit
|
||||
TMS6_dotpus4, // Dot Product, Unsigned by Signed, Packed 8-Bit
|
||||
TMS6_dpack2, // Parallel PACK2 and PACKH2 Operations
|
||||
TMS6_dpackx2, // Parallel PACKLH2 Operations
|
||||
TMS6_dpint, // Convert Double-Precision Floating-Point Value to Integer
|
||||
TMS6_dpsp, // Convert Double-Precision Floating-Point Value to Single-Precision Floating-Point Value
|
||||
TMS6_dptrunc, // Convert Double-Precision Floating-Point Value to Integer With Truncation
|
||||
TMS6_gmpy, // Galois Field Multiply
|
||||
TMS6_gmpy4, // Galois Field Multiply, Packed 8-Bit
|
||||
TMS6_intdp, // Convert Signed Integer to Double-Precision Floating-Point Value
|
||||
TMS6_intdpu, // Convert Unsigned Integer to Double-Precision Floating-Point Value
|
||||
TMS6_intsp, // Convert Signed Integer to Single-Precision Floating-Point Value
|
||||
TMS6_intspu, // Convert Unsigned Integer to Single-Precision Floating-Point Value
|
||||
TMS6_lddw, // Load Doubleword From Memory With a 5-Bit Unsigned Constant Offset or Register Offset
|
||||
TMS6_ldndw, // Load Nonaligned Doubleword From Memory With Constant or Register Offset
|
||||
TMS6_ldnw, // Load Nonaligned Word From Memory With Constant or Register Offset
|
||||
TMS6_max2, // Maximum, Signed, Packed 16-Bit
|
||||
TMS6_maxu4, // Maximum, Unsigned, Packed 8-Bit
|
||||
TMS6_min2, // Minimum, Signed, Packed 16-Bit
|
||||
TMS6_minu4, // Minimum, Unsigned, Packed 8-Bit
|
||||
TMS6_mpy2, // Multiply Signed by Signed, 16 LSB x 16 LSB and 16 MSB x 16 MSB
|
||||
TMS6_mpy2ir, // Multiply Two 16-Bit x 32-Bit, Shifted by 15 to Produce a Rounded 32-Bit Result
|
||||
TMS6_mpy32, // Multiply Signed 32-Bit x Signed 32-Bit Into 32-Bit Result
|
||||
TMS6_mpy32su, // Multiply Signed 32-Bit x Unsigned 32-Bit Into Signed 64-Bit Result
|
||||
TMS6_mpy32u, // Multiply Unsigned 32-Bit x Unsigned 32-Bit Into Unsigned 64-Bit Result
|
||||
TMS6_mpy32us, // Multiply Unsigned 32-Bit x Signed 32-Bit Into Signed 64-Bit Result
|
||||
TMS6_mpydp, // Multiply Two Double-Precision Floating-Point Values
|
||||
TMS6_mpyhi, // Multiply 16 MSB x 32-Bit Into 64-Bit Result
|
||||
TMS6_mpyhir, // Multiply 16 MSB x 32-Bit, Shifted by 15 to Produce a Rounded 32-Bit Result
|
||||
TMS6_mpyi, // Multiply 32-Bit x 32-Bit Into 32-Bit Result
|
||||
TMS6_mpyid, // Multiply 32-Bit x 32-Bit Into 64-Bit Result
|
||||
TMS6_mpyih, // Multiply 32-Bit x 16-MSB Into 64-Bit Result
|
||||
TMS6_mpyihr, // Multiply 32-Bit x 16 MSB, Shifted by 15 to Produce a Rounded 32-Bit Result
|
||||
TMS6_mpyil, // Multiply 32-Bit x 16 LSB Into 64-Bit Result
|
||||
TMS6_mpyilr, // Multiply 32-Bit x 16 LSB, Shifted by 15 to Produce a Rounded 32-Bit Result
|
||||
TMS6_mpyli, // Multiply 16 LSB x 32-Bit Into 64-Bit Result
|
||||
TMS6_mpylir, // Multiply 16 LSB x 32-Bit, Shifted by 15 to Produce a Rounded 32-Bit Result
|
||||
TMS6_mpysp, // Multiply Two Single-Precision Floating-Point Values
|
||||
TMS6_mpysp2dp, // Multiply Two Single-Precision Floating-Point Values for Double-Precision Result
|
||||
TMS6_mpyspdp, // Multiply Single-Precision Floating-Point Value x Double-Precision Floating-Point Value
|
||||
TMS6_mpysu4, // Multiply Signed x Unsigned, Four 8-Bit Pairs for Four 8-Bit Results
|
||||
TMS6_mpyu4, // Multiply Unsigned x Unsigned, Four 8-Bit Pairs for Four 8-Bit Results
|
||||
TMS6_mpyus4, // Multiply Unsigned x Signed, Four 8-Bit Pairs for Four 8-Bit Results
|
||||
TMS6_mvd, // Move From Register to Register, Delayed
|
||||
TMS6_mvkl, // Move Signed Constant Into Register and Sign Extend
|
||||
TMS6_pack2, // Pack Two 16 LSBs Into Upper and Lower Register Halves
|
||||
TMS6_packh2, // Pack Two 16 MSBs Into Upper and Lower Register Halves
|
||||
TMS6_packh4, // Pack Four High Bytes Into Four 8-Bit Halfwords
|
||||
TMS6_packhl2, // Pack 16 MSB Into Upper and 16 LSB Into Lower Register Halves
|
||||
TMS6_packl4, // Pack Four Low Bytes Into Four 8-Bit Halfwords
|
||||
TMS6_packlh2, // Pack 16 LSB Into Upper and 16 MSB Into Lower Register Halves
|
||||
TMS6_rcpdp, // Double-Precision Floating-Point Reciprocal Approximation
|
||||
TMS6_rcpsp, // Single-Precision Floating-Point Reciprocal Approximation
|
||||
TMS6_rint, // Restore Previous Enable State
|
||||
TMS6_rotl, // Rotate Left
|
||||
TMS6_rpack2, // Shift With Saturation and Pack Two 16 MSBs Into Upper and Lower Register Halves
|
||||
TMS6_rsqrdp, // Double-Precision Floating-Point Square-Root Reciprocal Approximation
|
||||
TMS6_rsqrsp, // Single-Precision Floating-Point Square-Root Reciprocal Approximation
|
||||
TMS6_sadd2, // Add Two Signed 16-Bit Integers on Upper and Lower Register Halves With Saturation
|
||||
TMS6_saddsu2, // Add Two Signed and Unsigned 16-Bit Integers on Register Halves With Saturation
|
||||
TMS6_saddsub, // Parallel SADD and SSUB Operations On Common Inputs
|
||||
TMS6_saddsub2, // Parallel SADD2 and SSUB2 Operations On Common Inputs
|
||||
TMS6_saddu4, // Add With Saturation, Four Unsigned 8-Bit Pairs for Four 8-Bit Results
|
||||
TMS6_saddus2, // Add Two Unsigned and Signed 16-Bit Integers on Register Halves With Saturation
|
||||
TMS6_shfl, // Shuffle
|
||||
TMS6_shfl3, // 3-Way Bit Interleave On Three 16-Bit Values Into a 48-Bit Result
|
||||
TMS6_shlmb, // Shift Left and Merge Byte
|
||||
TMS6_shr2, // Arithmetic Shift Right, Signed, Packed 16-Bit
|
||||
TMS6_shrmb, // Shift Right and Merge Byte
|
||||
TMS6_shru2, // Arithmetic Shift Right, Unsigned, Packed 16-Bit
|
||||
TMS6_smpy2, // Multiply Signed by Signed, 16 LSB x 16 LSB and 16 MSB x 16 MSB With Left Shift and Saturation
|
||||
TMS6_smpy32, // Multiply Signed 32-Bit x Signed 32-Bit Into 64-Bit Result With Left Shift and Saturation
|
||||
TMS6_spack2, // Saturate and Pack Two 16 LSBs Into Upper and Lower Register Halves
|
||||
TMS6_spacku4, // Saturate and Pack Four Signed 16-Bit Integers Into Four Unsigned 8-Bit Halfwords
|
||||
TMS6_spdp, // Convert Single-Precision Floating-Point Value to Double-Precision Floating-Point Value
|
||||
TMS6_spint, // Convert Single-Precision Floating-Point Value to Integer
|
||||
TMS6_spkernel, // Software Pipelined Loop (SPLOOP) Buffer Operation Code Boundary
|
||||
TMS6_spkernelr, // Software Pipelined Loop (SPLOOP) Buffer Operation Code Boundary
|
||||
TMS6_sploop, // Software Pipelined Loop (SPLOOP) Buffer Operation
|
||||
TMS6_sploopd, // Software Pipelined Loop (SPLOOP) Buffer Operation With Delayed Testing
|
||||
TMS6_sploopw, // Software Pipelined Loop (SPLOOP) Buffer Operation With Delayed Testing and No Epilog
|
||||
TMS6_spmask, // Software Pipelined Loop (SPLOOP) Buffer Operation Load/Execution Control
|
||||
TMS6_spmaskr, // Software Pipelined Loop (SPLOOP) Buffer Operation Load/Execution Control
|
||||
TMS6_sptrunc, // Convert Single-Precision Floating-Point Value to Integer With Truncation
|
||||
TMS6_sshvl, // Variable Shift Left
|
||||
TMS6_sshvr, // Variable Shift Right
|
||||
TMS6_ssub2, // Subtract Two Signed 16-Bit Integers on Upper and Lower Register Halves With Saturation
|
||||
TMS6_stdw, // Store Doubleword to Memory With a 5-Bit Unsigned Constant Offset or Register Offset
|
||||
TMS6_stndw, // Store Nonaligned Doubleword to Memory With a 5-Bit Unsigned Constant Offset or Register Offset
|
||||
TMS6_stnw, // Store Nonaligned Word to Memory With a 5-Bit Unsigned Constant Offset or Register Offset
|
||||
TMS6_sub4, // Subtract Without Saturation, Four 8-Bit Pairs for Four 8-Bit Results
|
||||
TMS6_subabs4, // Subtract With Absolute Value, Four 8-Bit Pairs for Four 8-Bit Results
|
||||
TMS6_subdp, // Subtract Two Double-Precision Floating-Point Values
|
||||
TMS6_subsp, // Subtract Two Single-Precision Floating-Point Values
|
||||
TMS6_swap2, // Swap Bytes in Upper and Lower Register Halves
|
||||
TMS6_swap4, // Swap Byte Pairs in Upper and Lower Register Halves
|
||||
TMS6_swe, // Software Exception
|
||||
TMS6_swenr, // Software Exception, no Return
|
||||
TMS6_unpkhu4, // Unpack 16 MSB Into Two Lower 8-Bit Halfwords of Upper and Lower Register Halves
|
||||
TMS6_unpklu4, // Unpack 16 LSB Into Two Lower 8-Bit Halfwords of Upper and Lower Register Halves
|
||||
TMS6_xormpy, // Galois Field Multiply With Zero Polynomial
|
||||
TMS6_xpnd2, // Expand Bits to Packed 16-Bit Masks
|
||||
TMS6_xpnd4, // Expand Bits to Packed 8-Bit Masks
|
||||
|
||||
TMS6_last,
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
51
idasdk76/module/tms320c6/makefile
Normal file
51
idasdk76/module/tms320c6/makefile
Normal file
@@ -0,0 +1,51 @@
|
||||
PROC=tms320c6
|
||||
|
||||
|
||||
include ../module.mak
|
||||
|
||||
# MAKEDEP dependency list ------------------
|
||||
$(F)ana$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
|
||||
$(I)config.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 ana.cpp ins.hpp \
|
||||
tms6.hpp
|
||||
$(F)emu$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
|
||||
$(I)config.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 emu.cpp ins.hpp \
|
||||
tms6.hpp
|
||||
$(F)ins$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
|
||||
$(I)config.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 ins.cpp ins.hpp \
|
||||
tms6.hpp
|
||||
$(F)out$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
|
||||
$(I)config.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 ins.hpp out.cpp \
|
||||
tms6.hpp
|
||||
$(F)reg$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
|
||||
$(I)config.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 ins.hpp reg.cpp \
|
||||
tms6.hpp
|
||||
505
idasdk76/module/tms320c6/out.cpp
Normal file
505
idasdk76/module/tms320c6/out.cpp
Normal file
@@ -0,0 +1,505 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA).
|
||||
* Copyright (c) 1990-98 by Ilfak Guilfanov.
|
||||
* ALL RIGHTS RESERVED.
|
||||
* E-mail: ig@estar.msk.su
|
||||
* FIDO: 2:5020/209
|
||||
*
|
||||
*
|
||||
* TMS320C6xx - VLIW (very long instruction word) architecture
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tms6.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_tms320c6_t : public outctx_t
|
||||
{
|
||||
out_tms320c6_t(void) = delete; // not used
|
||||
public:
|
||||
bool out_operand(const op_t &x);
|
||||
void out_insn(void);
|
||||
void outreg(int r) { out_register(ph.reg_names[r]); }
|
||||
void out_pre_mode(int mode);
|
||||
void out_post_mode(int mode);
|
||||
void print_stg_cyc(ea_t ea, int stgcyc);
|
||||
bool tms6_out_name_expr(const op_t &x, uval_t opval);
|
||||
};
|
||||
CASSERT(sizeof(out_tms320c6_t) == sizeof(outctx_t));
|
||||
|
||||
DECLARE_OUT_FUNCS_WITHOUT_OUTMNEM(out_tms320c6_t)
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
static bool is_first_insn_in_exec_packet(ea_t ea)
|
||||
{
|
||||
// if ( (ea & 0x1F) == 0 )
|
||||
// return 1;
|
||||
ea = prev_not_tail(ea);
|
||||
return ea == BADADDR
|
||||
|| !is_code(get_flags(ea))
|
||||
|| (get_dword(ea) & BIT0) == 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
static bool prev_complex(const insn_t &insn)
|
||||
{
|
||||
ea_t ea = prev_not_tail(insn.ea);
|
||||
if ( ea == BADADDR || !is_code(get_flags(ea)) )
|
||||
return 0;
|
||||
return !is_first_insn_in_exec_packet(ea);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void out_tms320c6_t::out_pre_mode(int mode)
|
||||
{
|
||||
out_symbol('*');
|
||||
switch ( mode )
|
||||
{
|
||||
case 0x08: // 1000 *--R[cst]
|
||||
case 0x0C: // 1100 *--Rb[Ro]
|
||||
out_symbol('-');
|
||||
// fallthrough
|
||||
case 0x00: // 0000 *-R[cst]
|
||||
case 0x04: // 0100 *-Rb[Ro]
|
||||
out_symbol('-');
|
||||
break;
|
||||
case 0x09: // 1001 *++R[cst]
|
||||
case 0x0D: // 1101 *++Rb[Ro]
|
||||
out_symbol('+');
|
||||
out_symbol('+');
|
||||
break;
|
||||
case 0x01: // 0001 *+R[cst]
|
||||
case 0x05: // 0101 *+Rb[Ro]
|
||||
// out_symbol('+');
|
||||
break;
|
||||
case 0x0A: // 1010 *R--[cst]
|
||||
case 0x0B: // 1011 *R++[cst]
|
||||
case 0x0E: // 1110 *Rb--[Ro]
|
||||
case 0x0F: // 1111 *Rb++[Ro]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void out_tms320c6_t::out_post_mode(int mode)
|
||||
{
|
||||
switch ( mode )
|
||||
{
|
||||
case 0x08: // 1000 *--R[cst]
|
||||
case 0x0C: // 1100 *--Rb[Ro]
|
||||
case 0x00: // 0000 *-R[cst]
|
||||
case 0x04: // 0100 *-Rb[Ro]
|
||||
case 0x09: // 1001 *++R[cst]
|
||||
case 0x0D: // 1101 *++Rb[Ro]
|
||||
case 0x01: // 0001 *+R[cst]
|
||||
case 0x05: // 0101 *+Rb[Ro]
|
||||
break;
|
||||
case 0x0A: // 1010 *R--[cst]
|
||||
case 0x0E: // 1110 *Rb--[Ro]
|
||||
out_symbol('-');
|
||||
out_symbol('-');
|
||||
break;
|
||||
case 0x0B: // 1011 *R++[cst]
|
||||
case 0x0F: // 1111 *Rb++[Ro]
|
||||
out_symbol('+');
|
||||
out_symbol('+');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
struct ii_info_t
|
||||
{
|
||||
char ii;
|
||||
char cyc;
|
||||
};
|
||||
|
||||
static const ii_info_t ii_info[] =
|
||||
{
|
||||
{ 1, 0 },
|
||||
{ 2, 1 },
|
||||
{ 4, 2 },
|
||||
{ 8, 3 },
|
||||
{ 14, 4 },
|
||||
};
|
||||
|
||||
void out_tms320c6_t::print_stg_cyc(ea_t ea, int stgcyc)
|
||||
{
|
||||
int ii = 1;
|
||||
insn_t prev;
|
||||
for ( int i=0; i < 14 && decode_prev_insn(&prev, ea) != BADADDR; i++ )
|
||||
{
|
||||
if ( prev.itype == TMS6_sploop
|
||||
|| prev.itype == TMS6_sploopd
|
||||
|| prev.itype == TMS6_sploopw )
|
||||
{
|
||||
ii = prev.Op1.value;
|
||||
break;
|
||||
}
|
||||
ea = prev.ea;
|
||||
}
|
||||
for ( int i=0; i < qnumber(ii_info); i++ )
|
||||
{
|
||||
if ( ii_info[i].ii >= ii )
|
||||
{
|
||||
int cyc = ii_info[i].cyc;
|
||||
int stg = 0;
|
||||
int stgbits = 6 - cyc;
|
||||
int bit = 1 << cyc;
|
||||
for ( int j=0; j < stgbits; j++, bit<<=1 )
|
||||
{
|
||||
stg <<= 1;
|
||||
if ( stgcyc & bit )
|
||||
stg |= 1;
|
||||
}
|
||||
cyc = stgcyc & ((1<<cyc)-1);
|
||||
out_long(stg, 10);
|
||||
out_symbol(',');
|
||||
out_long(cyc, 10);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool out_tms320c6_t::tms6_out_name_expr(const op_t &x, uval_t opval)
|
||||
{
|
||||
ea_t ea = to_ea(insn.cs, opval);
|
||||
ea_t safe = find_first_insn_in_packet(ea);
|
||||
adiff_t delta = ea - safe;
|
||||
if ( !out_name_expr(x, safe, opval - delta) )
|
||||
return false;
|
||||
if ( delta > 0 )
|
||||
{
|
||||
out_symbol('+');
|
||||
out_long(delta, 16);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool out_tms320c6_t::out_operand(const op_t &x)
|
||||
{
|
||||
switch ( x.type )
|
||||
{
|
||||
case o_void:
|
||||
return 0;
|
||||
|
||||
case o_reg:
|
||||
outreg(x.reg);
|
||||
break;
|
||||
|
||||
case o_regpair:
|
||||
outreg(x.reg + 1);
|
||||
out_symbol(':');
|
||||
outreg(x.reg);
|
||||
break;
|
||||
|
||||
case o_imm:
|
||||
{
|
||||
uchar sign = insn.itype == TMS6_mvkh
|
||||
|| insn.itype == TMS6_mvklh
|
||||
|| (insn.itype == TMS6_mvk && is_mvk_scst16_form(insn.ea))
|
||||
? 0
|
||||
: OOF_SIGNED;
|
||||
out_value(x, OOFS_IFSIGN|OOFW_IMM|sign);
|
||||
break;
|
||||
}
|
||||
|
||||
case o_stgcyc:
|
||||
print_stg_cyc(insn.ea, x.value);
|
||||
break;
|
||||
|
||||
case o_near:
|
||||
if ( !tms6_out_name_expr(x, x.addr) )
|
||||
{
|
||||
out_tagon(COLOR_ERROR);
|
||||
out_btoa(x.addr, 16);
|
||||
out_tagoff(COLOR_ERROR);
|
||||
remember_problem(PR_NONAME, insn.ea);
|
||||
}
|
||||
break;
|
||||
|
||||
case o_phrase:
|
||||
out_pre_mode(x.mode);
|
||||
outreg(x.reg);
|
||||
out_post_mode(x.mode);
|
||||
out_symbol('[');
|
||||
outreg(x.secreg);
|
||||
out_symbol(']');
|
||||
break;
|
||||
|
||||
case o_displ:
|
||||
out_pre_mode(x.mode);
|
||||
outreg(x.reg);
|
||||
out_post_mode(x.mode);
|
||||
{
|
||||
if ( x.addr != 0 || is_off(F, x.n) )
|
||||
{
|
||||
if ( is_off(F, x.n) )
|
||||
{
|
||||
out_symbol('(');
|
||||
out_value(x, OOF_ADDR|OOFS_IFSIGN|OOFW_IMM|OOF_SIGNED|OOFW_32);
|
||||
out_symbol(')');
|
||||
}
|
||||
else
|
||||
{
|
||||
out_symbol('[');
|
||||
out_value(x, OOF_ADDR|OOFS_IFSIGN|OOFW_IMM|OOF_SIGNED|OOFW_32);
|
||||
out_symbol(']');
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case o_spmask:
|
||||
{
|
||||
static const char units[] = "LLSSDDMM";
|
||||
uchar mask = x.reg;
|
||||
bool need_comma = false;
|
||||
for ( int i=0; i < 8; i++, mask>>=1 )
|
||||
{
|
||||
if ( mask & 1 )
|
||||
{
|
||||
if ( need_comma )
|
||||
out_symbol(',');
|
||||
out_tagon(COLOR_KEYWORD);
|
||||
out_char(units[i]);
|
||||
out_char('1'+(i&1));
|
||||
out_tagoff(COLOR_KEYWORD);
|
||||
need_comma = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
warning("out: %a: bad optype %d", insn.ea, x.type);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void out_tms320c6_t::out_insn(void)
|
||||
{
|
||||
//
|
||||
// Parallel instructions
|
||||
//
|
||||
ea_t ea = insn.ea;
|
||||
if ( !is_first_insn_in_exec_packet(ea) )
|
||||
{
|
||||
out_symbol('|');
|
||||
out_symbol('|');
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !has_any_name(F)
|
||||
&& (prev_complex(insn) || insn.cflags & aux_para) )
|
||||
{
|
||||
gen_empty_line();
|
||||
}
|
||||
out_char(' ');
|
||||
out_char(' ');
|
||||
}
|
||||
|
||||
//
|
||||
// Condition code
|
||||
//
|
||||
static const char *const conds[] =
|
||||
{
|
||||
" ", " ", "[B0] ", "[!B0]",
|
||||
"[B1] ", "[!B1]", "[B2] ", "[!B2]",
|
||||
"[A1] ", "[!A1]", "[A2] ", "[!A2]",
|
||||
"[A0] ", "[!A0]", " ", " "
|
||||
};
|
||||
out_keyword(conds[insn.cond]);
|
||||
out_char(' ');
|
||||
|
||||
//
|
||||
// Instruction name
|
||||
//
|
||||
out_mnemonic();
|
||||
//
|
||||
// Functional unit
|
||||
//
|
||||
static const char *const units[] =
|
||||
{
|
||||
NULL,
|
||||
".L1", ".L2",
|
||||
".S1", ".S2",
|
||||
".M1", ".M2",
|
||||
".D1", ".D2",
|
||||
};
|
||||
if ( insn.funit != FU_NONE )
|
||||
out_keyword(units[uchar(insn.funit)]);
|
||||
else
|
||||
out_line(" ");
|
||||
if ( insn.cflags & aux_xp )
|
||||
out_keyword("X");
|
||||
else
|
||||
out_char(' ');
|
||||
out_line(" ");
|
||||
|
||||
//
|
||||
// Operands
|
||||
//
|
||||
if ( (insn.cflags & aux_src2) != 0 )
|
||||
{
|
||||
outreg(insn.Op1.src2);
|
||||
out_symbol(',');
|
||||
out_char(' ');
|
||||
}
|
||||
|
||||
if ( insn.Op1.shown() )
|
||||
out_one_operand(0);
|
||||
|
||||
if ( insn.Op2.type != o_void && insn.Op2.shown() )
|
||||
{
|
||||
out_symbol(',');
|
||||
out_char(' ');
|
||||
out_one_operand(1);
|
||||
}
|
||||
|
||||
|
||||
if ( insn.Op3.type != o_void && insn.Op3.shown() )
|
||||
{
|
||||
out_symbol(',');
|
||||
out_char(' ');
|
||||
out_one_operand(2);
|
||||
}
|
||||
|
||||
out_immchar_cmts();
|
||||
|
||||
int indent = inf_get_indent() - 8; // reserve space for conditions
|
||||
if ( indent <= 1 ) // too little space?
|
||||
indent = 2; // pass -2, which means one space
|
||||
// (-1 would mean 'use DEFAULT_INDENT')
|
||||
flush_outbuf(-indent); // negative value means 'print opcodes here'
|
||||
|
||||
if ( (insn.cflags & aux_para) == 0 )
|
||||
{
|
||||
tms6_t &pm = *static_cast<tms6_t *>(procmod);
|
||||
tgtinfo_t tgt;
|
||||
if ( tgt.restore_from_idb(pm, ea) )
|
||||
{
|
||||
qstring buf = tgt.get_type_name();
|
||||
if ( tgt.has_target() )
|
||||
{
|
||||
qstring name = get_colored_name(tgt.target);
|
||||
buf.append(" ");
|
||||
buf.append(name);
|
||||
}
|
||||
gen_printf(DEFAULT_INDENT,
|
||||
COLSTR("; %s OCCURS", SCOLOR_AUTOCMT),
|
||||
buf.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//lint -e{818} seg could be const
|
||||
void idaapi segstart(outctx_t &ctx, segment_t *seg)
|
||||
{
|
||||
if ( is_spec_segm(seg->type) )
|
||||
return;
|
||||
|
||||
qstring sname;
|
||||
get_segm_name(&sname, seg);
|
||||
|
||||
if ( sname == ".bss" )
|
||||
return;
|
||||
if ( sname == ".text" || sname == ".data" )
|
||||
{
|
||||
ctx.gen_printf(DEFAULT_INDENT, COLSTR("%s", SCOLOR_ASMDIR), sname.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
validate_name(&sname, VNT_IDENT);
|
||||
ctx.gen_printf(DEFAULT_INDENT, COLSTR(".sect \"%s\"", SCOLOR_ASMDIR), sname.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void idaapi segend(outctx_t &, segment_t *)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void idaapi header(outctx_t &ctx)
|
||||
{
|
||||
ctx.gen_header(GH_PRINT_ALL);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void tms6_t::footer(outctx_t &ctx) const
|
||||
{
|
||||
qstring nbuf = get_colored_name(inf_get_start_ea());
|
||||
const char *name = nbuf.c_str();
|
||||
const char *end = ash.end;
|
||||
if ( end == NULL )
|
||||
ctx.gen_printf(DEFAULT_INDENT, COLSTR("%s end %s", SCOLOR_AUTOCMT), ash.cmnt, name);
|
||||
else
|
||||
ctx.gen_printf(DEFAULT_INDENT, COLSTR("%s", SCOLOR_ASMDIR)
|
||||
" "
|
||||
COLSTR("%s %s", SCOLOR_AUTOCMT), ash.end, ash.cmnt, name);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void idaapi data(outctx_t &ctx, bool analyze_only)
|
||||
{
|
||||
ea_t ea = ctx.insn_ea;
|
||||
segment_t *s = getseg(ea);
|
||||
if ( s != NULL )
|
||||
{
|
||||
qstring sname;
|
||||
if ( get_segm_name(&sname, s) > 0 && sname == ".bss" )
|
||||
{
|
||||
qstring name;
|
||||
if ( get_colored_name(&name, ea) <= 0 )
|
||||
name.sprnt(COLSTR("bss_dummy_name_%a", SCOLOR_UNKNAME), ea);
|
||||
char num[MAX_NUMBUF];
|
||||
btoa(num, sizeof(num), get_item_size(ea), get_radix(ctx.F, 0));
|
||||
ctx.ctxflags |= CTXF_LABEL_OK;
|
||||
ctx.gen_printf(-1,
|
||||
COLSTR(".bss", SCOLOR_KEYWORD)
|
||||
" %s, "
|
||||
COLSTR("%s", SCOLOR_DNUM),
|
||||
name.begin(),
|
||||
num);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ctx.out_data(analyze_only);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//lint -e{1764} ctx could be const
|
||||
bool tms6_t::outspec(outctx_t &ctx, uchar stype) const
|
||||
{
|
||||
ea_t ea = ctx.insn_ea;
|
||||
qstring nbuf;
|
||||
if ( get_colored_name(&nbuf, ea) <= 0 )
|
||||
return false;
|
||||
const char *name = nbuf.begin();
|
||||
char buf[MAX_NUMBUF];
|
||||
switch ( stype )
|
||||
{
|
||||
case SEG_XTRN:
|
||||
return ctx.gen_printf(-1, COLSTR("%s %s", SCOLOR_ASMDIR), ash.a_extrn,name);
|
||||
case SEG_ABSSYM:
|
||||
// i don't know how to declare absolute symbols.
|
||||
// perhaps, like this?
|
||||
btoa(buf, sizeof(buf), get_dword(ea));
|
||||
return ctx.gen_printf(-1, COLSTR("%s = %s", SCOLOR_ASMDIR), name, buf);
|
||||
case SEG_COMM:
|
||||
btoa(buf, sizeof(buf), get_dword(ea));
|
||||
ctx.gen_printf(-1,
|
||||
COLSTR("%s \"%s\", %s", SCOLOR_ASMDIR),
|
||||
ash.a_comdef, name, buf);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
415
idasdk76/module/tms320c6/reg.cpp
Normal file
415
idasdk76/module/tms320c6/reg.cpp
Normal file
@@ -0,0 +1,415 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA).
|
||||
* Copyright (c) 1990-98 by Ilfak Guilfanov.
|
||||
* ALL RIGHTS RESERVED.
|
||||
* E-mail: ig@estar.msk.su
|
||||
* FIDO: 2:5020/209
|
||||
*
|
||||
*
|
||||
* TMS320C6xx - VLIW (very long instruction word) architecture
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tms6.hpp"
|
||||
int data_id;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// B14 - data page pointer
|
||||
// B15 - stack pointer
|
||||
static const char *const RegNames[] =
|
||||
{
|
||||
"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
|
||||
"A8", "A9", "A10", "A11", "A12", "A13", "A14", "A15",
|
||||
"A16", "A17", "A18", "A19", "A20", "A21", "A22", "A23",
|
||||
"A24", "A25", "A26", "A27", "A28", "A29", "A30", "A31",
|
||||
"B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7",
|
||||
"B8", "B9", "B10", "B11", "B12", "B13", "B14", "B15",
|
||||
"B16", "B17", "B18", "B19", "B20", "B21", "B22", "B23",
|
||||
"B24", "B25", "B26", "B27", "B28", "B29", "B30", "B31",
|
||||
"AMR",
|
||||
"CSR",
|
||||
"IFR",
|
||||
"ISR",
|
||||
"ICR",
|
||||
"IER",
|
||||
"ISTP",
|
||||
"IRP",
|
||||
"NRP",
|
||||
"ACR", // undocumented, info from Jeff Bailey <jeff_bailey@infinitek.com>
|
||||
"ADR", // undocumented, info from Jeff Bailey <jeff_bailey@infinitek.com>
|
||||
"PCE1",
|
||||
"FADCR",
|
||||
"FAUCR",
|
||||
"FMCR",
|
||||
"TSCL",
|
||||
"TSCH",
|
||||
"ILC",
|
||||
"RILC",
|
||||
"REP",
|
||||
"DNUM",
|
||||
"SSR",
|
||||
"GPLYA",
|
||||
"GPLYB",
|
||||
"GFPGFR",
|
||||
"TSR",
|
||||
"ITSR",
|
||||
"NTSR",
|
||||
"ECR",
|
||||
"EFR",
|
||||
"IERR",
|
||||
"CS", "DS"
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
ssize_t idaapi idb_listener_t::on_event(ssize_t code, va_list va)
|
||||
{
|
||||
switch ( code )
|
||||
{
|
||||
case idb_event::segm_moved: // A segment is moved
|
||||
// Fix processor dependent address sensitive information
|
||||
{
|
||||
ea_t from = va_arg(va, ea_t);
|
||||
ea_t to = va_arg(va, ea_t);
|
||||
asize_t size = va_arg(va, asize_t);
|
||||
bool changed_netmap = va_argi(va, bool);
|
||||
if ( !changed_netmap )
|
||||
{
|
||||
nodeidx_t ndx1 = ea2node(from);
|
||||
nodeidx_t ndx2 = ea2node(to);
|
||||
pm.helper.altshift(ndx1, ndx2, size);
|
||||
// like altadjust()
|
||||
for ( nodeidx_t ndx = pm.helper.supfirst();
|
||||
ndx != BADADDR;
|
||||
ndx = pm.helper.supnext(ndx) )
|
||||
{
|
||||
tgtinfo_t tgt;
|
||||
ea_t ea = node2ea(ndx);
|
||||
tgt.restore_from_idb(pm, ea);
|
||||
if ( tgt.has_target() )
|
||||
{
|
||||
tgt.target = correct_address(tgt.target, from, to, size);
|
||||
tgt.save_to_idb(pm, ea);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 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(tms6_t));
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
ssize_t idaapi tms6_t::on_event(ssize_t msgid, va_list va)
|
||||
{
|
||||
int code = 0;
|
||||
switch ( msgid )
|
||||
{
|
||||
case processor_t::ev_init:
|
||||
hook_event_listener(HT_IDB, &idb_listener, &LPH);
|
||||
helper.create(PROCMOD_NODE_NAME);
|
||||
break;
|
||||
|
||||
case processor_t::ev_term:
|
||||
unhook_event_listener(HT_IDB, &idb_listener);
|
||||
clr_module_data(data_id);
|
||||
break;
|
||||
|
||||
case processor_t::ev_oldfile:
|
||||
{
|
||||
netnode old_tnode("$ tms node");
|
||||
if ( old_tnode != BADNODE )
|
||||
{
|
||||
upgrade_tnode(old_tnode);
|
||||
old_tnode.kill();
|
||||
}
|
||||
}
|
||||
// no break
|
||||
case processor_t::ev_ending_undo:
|
||||
case processor_t::ev_newfile:
|
||||
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_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_out_data:
|
||||
{
|
||||
outctx_t *ctx = va_arg(va, outctx_t *);
|
||||
bool analyze_only = va_argi(va, bool);
|
||||
data(*ctx, analyze_only);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case processor_t::ev_out_special_item:
|
||||
{
|
||||
outctx_t *ctx = va_arg(va, outctx_t *);
|
||||
uchar seg_type = va_argi(va, uchar);
|
||||
outspec(*ctx, seg_type);
|
||||
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;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void tms6_t::upgrade_tnode(const netnode &old_tnode)
|
||||
{
|
||||
// copy branch/call info to HELPER
|
||||
for ( nodeidx_t ndx = old_tnode.altfirst();
|
||||
ndx != BADADDR;
|
||||
ndx = old_tnode.altnext(ndx) )
|
||||
{
|
||||
nodeidx_t ndx2 = old_tnode.altval(ndx);
|
||||
if ( ndx2 == 0 )
|
||||
continue;
|
||||
tgtinfo_t tgt;
|
||||
switch ( ndx2 )
|
||||
{
|
||||
case 1:
|
||||
tgt.type = tgtinfo_t::IND_BRANCH;
|
||||
break;
|
||||
case 2:
|
||||
tgt.type = tgtinfo_t::IND_CALL;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
ea_t target = node2ea(ndx2);
|
||||
tgt.type = (target & 1) != 0
|
||||
? tgtinfo_t::BRANCH
|
||||
: tgtinfo_t::CALL;
|
||||
tgt.target = target & ~1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
tgt.save_to_idb(*this, node2ea(ndx));
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
const char *tgtinfo_t::get_type_name() const
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case tgtinfo_t::CALL: return "CALL";
|
||||
case tgtinfo_t::BRANCH: return "BRANCH";
|
||||
case tgtinfo_t::IND_CALL: return "INDIRECT CALL";
|
||||
case tgtinfo_t::IND_BRANCH: return "INDIRECT BRANCH";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
#define TGTINFO_MAX_SIZE (1 + ea_packed_size)
|
||||
void tgtinfo_t::save_to_idb(tms6_t &pm, ea_t ea) const
|
||||
{
|
||||
uchar buf[TGTINFO_MAX_SIZE];
|
||||
uchar *ptr = buf;
|
||||
uchar *end = buf + sizeof(buf);
|
||||
ptr = pack_db(ptr, end, uchar(type));
|
||||
if ( has_target() )
|
||||
ptr = pack_ea(ptr, end, ea2node(target));
|
||||
pm.helper.supset_ea(ea, buf, ptr - buf);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
bool tgtinfo_t::restore_from_idb(const tms6_t &pm, ea_t ea)
|
||||
{
|
||||
uchar buf[TGTINFO_MAX_SIZE];
|
||||
ssize_t code = pm.helper.supval_ea(ea, buf, sizeof(buf));
|
||||
if ( code < 1 )
|
||||
return false;
|
||||
memory_deserializer_t mmdsr(buf, code);
|
||||
uchar t = mmdsr.unpack_db();
|
||||
if ( t > IND_BRANCH )
|
||||
return false;
|
||||
type = type_t(t);
|
||||
if ( has_target() )
|
||||
target = node2ea(mmdsr.unpack_ea());
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// TMS320C6x COFF Assembler
|
||||
//-----------------------------------------------------------------------
|
||||
static const asm_t dspasm =
|
||||
{
|
||||
AS_COLON | ASH_HEXF0 | ASD_DECF0 | ASB_BINF0 | ASO_OCTF5,
|
||||
0,
|
||||
"TMS320C6x COFF Assembler",
|
||||
0,
|
||||
NULL, // header lines
|
||||
NULL, // org
|
||||
".end",
|
||||
|
||||
";", // comment string
|
||||
'"', // string delimiter
|
||||
'\'', // char delimiter
|
||||
"\\\"'", // special symbols in char and string constants
|
||||
|
||||
".string", // ascii string directive
|
||||
".char", // byte directive
|
||||
".short", // word directive
|
||||
".long", // double words
|
||||
NULL, // no qwords
|
||||
NULL, // oword (16 bytes)
|
||||
NULL, // float (4 bytes)
|
||||
NULL, // double (8 bytes)
|
||||
NULL, // tbyte (10/12 bytes)
|
||||
NULL, // packed decimal real
|
||||
NULL, // arrays (#h,#d,#v,#s(...)
|
||||
".space %s", // uninited arrays
|
||||
".set", // equ
|
||||
NULL, // 'seg' prefix (example: push seg seg001)
|
||||
"$", // current IP (instruction pointer)
|
||||
NULL, // func_header
|
||||
NULL, // func_footer
|
||||
".def", // "public" name keyword
|
||||
NULL, // "weak" name keyword
|
||||
".ref", // "extrn" name keyword
|
||||
".usect", // "comm" (communal variable)
|
||||
NULL, // get_type_name
|
||||
".align", // "align" keyword
|
||||
'(', ')', // lbrace, rbrace
|
||||
NULL, // mod
|
||||
"&", // and
|
||||
"|", // or
|
||||
"^", // xor
|
||||
"!", // not
|
||||
"<<", // shl
|
||||
">>", // shr
|
||||
NULL, // sizeof
|
||||
};
|
||||
|
||||
|
||||
static const asm_t *const asms[] = { &dspasm, NULL };
|
||||
//-----------------------------------------------------------------------
|
||||
#define FAMILY "TMS320C6 series:"
|
||||
static const char *const shnames[] = { "TMS320C6", NULL };
|
||||
static const char *const lnames[] =
|
||||
{
|
||||
FAMILY"Texas Instruments TMS320C6xxx",
|
||||
NULL
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static const uchar retcode_1[] = { 0x62, 0x63, 0x0C, 0x00 };
|
||||
|
||||
static const bytes_t retcodes[] =
|
||||
{
|
||||
{ sizeof(retcode_1), retcode_1 },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Processor Definition
|
||||
//-----------------------------------------------------------------------
|
||||
processor_t LPH =
|
||||
{
|
||||
IDP_INTERFACE_VERSION, // version
|
||||
PLFM_TMSC6, // id
|
||||
// flag
|
||||
PR_USE32
|
||||
| PR_DEFSEG32
|
||||
| PR_DELAYED
|
||||
| PR_ALIGN_INSN, // allow align instructions
|
||||
// flag2
|
||||
0,
|
||||
8, // 8 bits in a byte for code segments
|
||||
8, // 8 bits in a byte for other segments
|
||||
|
||||
shnames,
|
||||
lnames,
|
||||
|
||||
asms,
|
||||
|
||||
notify,
|
||||
|
||||
RegNames, // Register names
|
||||
qnumber(RegNames), // Number of registers
|
||||
|
||||
rVcs, // first
|
||||
rVds, // last
|
||||
0, // size of a segment register
|
||||
rVcs, rVds,
|
||||
|
||||
NULL, // No known code start sequences
|
||||
retcodes,
|
||||
|
||||
TMS6_null,
|
||||
TMS6_last,
|
||||
Instructions, // instruc
|
||||
0, // int tbyte_size;
|
||||
{ 2, 4, 8, 12 }, // char real_width[4];
|
||||
TMS6_null, // Icode of return instruction. It is ok to give any of possible return instructions
|
||||
};
|
||||
225
idasdk76/module/tms320c6/tms6.hpp
Normal file
225
idasdk76/module/tms320c6/tms6.hpp
Normal file
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA).
|
||||
* Copyright (c) 1990-98 by Ilfak Guilfanov.
|
||||
* ALL RIGHTS RESERVED.
|
||||
* E-mail: ig@estar.msk.su
|
||||
* FIDO: 2:5020/209
|
||||
*
|
||||
*
|
||||
* TMS320C6xx - VLIW (very long instruction word) architecture
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _TMS6_HPP
|
||||
#define _TMS6_HPP
|
||||
|
||||
#include "../idaidp.hpp"
|
||||
#include "ins.hpp"
|
||||
|
||||
#define PROCMOD_NAME tms6
|
||||
#define PROCMOD_NODE_NAME "$ tms"
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
DECLARE_PROC_LISTENER(idb_listener_t, struct tms6_t);
|
||||
|
||||
struct tms6_t : public procmod_t
|
||||
{
|
||||
netnode helper; // supval(ea) -> branch/call info, see tgtinfo_t
|
||||
idb_listener_t idb_listener = idb_listener_t(*this);
|
||||
bool flow = false;
|
||||
|
||||
ssize_t idaapi on_event(ssize_t msgid, va_list va);
|
||||
int emu(const insn_t &insn);
|
||||
void footer(outctx_t &ctx) const;
|
||||
bool outspec(outctx_t &ctx, uchar stype) const;
|
||||
|
||||
void upgrade_tnode(const netnode &old_tnode);
|
||||
};
|
||||
extern int data_id;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
struct tgtinfo_t
|
||||
{
|
||||
enum type_t { CALL, BRANCH, IND_CALL, IND_BRANCH };
|
||||
type_t type;
|
||||
ea_t target;
|
||||
bool has_target() const { return type == CALL || type == BRANCH; }
|
||||
const char *get_type_name() const;
|
||||
void save_to_idb(tms6_t &pm, ea_t ea) const;
|
||||
bool restore_from_idb(const tms6_t &pm, ea_t ea);
|
||||
};
|
||||
|
||||
//---------------------------------
|
||||
// Functional units:
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define ENUM8BIT : uint8
|
||||
#else
|
||||
#define ENUM8BIT
|
||||
#endif
|
||||
enum funit_t ENUM8BIT
|
||||
{
|
||||
FU_NONE, // No unit (NOP, IDLE)
|
||||
FU_L1, FU_L2, // 32/40-bit arithmetic and compare operations
|
||||
// Leftmost 1 or 0 bit counting for 32 bits
|
||||
// Normalization count for 32 and 40 bits
|
||||
// 32-bit logical operations
|
||||
|
||||
FU_S1, FU_S2, // 32-bit arithmetic operations
|
||||
// 32/40-bit shifts and 32-bit bit-field operations
|
||||
// 32-bit logical operations
|
||||
// Branches
|
||||
// Constant generation
|
||||
// Register transfers to/from the control register file (.S2 only)
|
||||
|
||||
FU_M1, FU_M2, // 16 x 16 bit multiply operations
|
||||
|
||||
FU_D1, FU_D2, // 32-bit add, subtract, linear and circular address calculation
|
||||
// Loads and stores with a 5-bit constant offset
|
||||
// Loads and stores with 15-bit constant offset (.D2 only)
|
||||
};
|
||||
|
||||
//---------------------------------
|
||||
// Operand types:
|
||||
#define o_regpair o_idpspec0 // Register pair (A1:A0..B15:B14)
|
||||
// Register pair is denoted by its
|
||||
// even register in op.reg
|
||||
// (Odd register keeps MSB)
|
||||
|
||||
#define o_spmask o_idpspec1 // unit mask (reg)
|
||||
#define o_stgcyc o_idpspec2 // fstg/fcyc (value)
|
||||
|
||||
|
||||
// o_phrase: the second register is held in secreg (specflag1)
|
||||
#define secreg specflag1
|
||||
// o_phrase, o_displ: mode
|
||||
#define mode specflag2
|
||||
|
||||
#define src2 specflag2 // for field instructions
|
||||
|
||||
//------------------------------------------------------------------
|
||||
#define funit segpref // Functional unit for insn
|
||||
#define cond auxpref_u8[0] // The condition code of instruction
|
||||
#define cflags auxpref_u8[1] // Various bit definitions:
|
||||
# define aux_para 0x0001 // parallel execution with the next insn
|
||||
# define aux_src2 0x0002 // src2 register for immediate form of
|
||||
// field instructions is present at "Op1.src2"
|
||||
# define aux_xp 0x0004 // X path is used
|
||||
# define aux_pseudo 0x0008 // Pseudo instruction
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// condition codes:
|
||||
#define cAL 0x0 // unconditional
|
||||
#define cB0 0x2 // B0
|
||||
#define cnB0 0x3 // !B0
|
||||
#define cB1 0x4 // B1
|
||||
#define cnB1 0x5 // !B1
|
||||
#define cB2 0x6 // B2
|
||||
#define cnB2 0x7 // !B2
|
||||
#define cA1 0x8 // A1
|
||||
#define cnA1 0x9 // !A1
|
||||
#define cA2 0xA // A2
|
||||
#define cnA2 0xB // !A2
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Bit definitions. Just for convenience:
|
||||
#define BIT0 0x00000001L
|
||||
#define BIT1 0x00000002L
|
||||
#define BIT2 0x00000004L
|
||||
#define BIT3 0x00000008L
|
||||
#define BIT4 0x00000010L
|
||||
#define BIT5 0x00000020L
|
||||
#define BIT6 0x00000040L
|
||||
#define BIT7 0x00000080L
|
||||
#define BIT8 0x00000100L
|
||||
#define BIT9 0x00000200L
|
||||
#define BIT10 0x00000400L
|
||||
#define BIT11 0x00000800L
|
||||
#define BIT12 0x00001000L
|
||||
#define BIT13 0x00002000L
|
||||
#define BIT14 0x00004000L
|
||||
#define BIT15 0x00008000L
|
||||
#define BIT16 0x00010000L
|
||||
#define BIT17 0x00020000L
|
||||
#define BIT18 0x00040000L
|
||||
#define BIT19 0x00080000L
|
||||
#define BIT20 0x00100000L
|
||||
#define BIT21 0x00200000L
|
||||
#define BIT22 0x00400000L
|
||||
#define BIT23 0x00800000L
|
||||
#define BIT24 0x01000000L
|
||||
#define BIT25 0x02000000L
|
||||
#define BIT26 0x04000000L
|
||||
#define BIT27 0x08000000L
|
||||
#define BIT28 0x10000000L
|
||||
#define BIT29 0x20000000L
|
||||
#define BIT30 0x40000000L
|
||||
#define BIT31 0x80000000L
|
||||
|
||||
//------------------------------------------------------------------
|
||||
enum RegNo ENUM8BIT
|
||||
{
|
||||
rA0, rA1, rA2, rA3, rA4, rA5, rA6, rA7,
|
||||
rA8, rA9, rA10, rA11, rA12, rA13, rA14, rA15,
|
||||
rA16, rA17, rA18, rA19, rA20, rA21, rA22, rA23,
|
||||
rA24, rA25, rA26, rA27, rA28, rA29, rA30, rA31,
|
||||
rB0, rB1, rB2, rB3, rB4, rB5, rB6, rB7,
|
||||
rB8, rB9, rB10, rB11, rB12, rB13, rB14, rB15,
|
||||
rB16, rB17, rB18, rB19, rB20, rB21, rB22, rB23,
|
||||
rB24, rB25, rB26, rB27, rB28, rB29, rB30, rB31,
|
||||
rAMR,
|
||||
rCSR,
|
||||
rIFR,
|
||||
rISR,
|
||||
rICR,
|
||||
rIER,
|
||||
rISTP,
|
||||
rIRP,
|
||||
rNRP,
|
||||
rACR,
|
||||
rADR,
|
||||
rPCE1,
|
||||
rFADCR,
|
||||
rFAUCR,
|
||||
rFMCR,
|
||||
rTSCL,
|
||||
rTSCH,
|
||||
rILC,
|
||||
rRILC,
|
||||
rREP,
|
||||
rDNUM,
|
||||
rSSR,
|
||||
rGPLYA,
|
||||
rGPLYB,
|
||||
rGFPGFR,
|
||||
rTSR,
|
||||
rITSR,
|
||||
rNTSR,
|
||||
rECR,
|
||||
rEFR,
|
||||
rIERR,
|
||||
rVcs, rVds, // virtual registers for code and data segments
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// XXX this assumes the non-compact encoding
|
||||
inline bool is_mvk_scst16_form(ea_t ea)
|
||||
{
|
||||
return ((get_dword(ea) >> 2) & 0x1F) == 0xA;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
void idaapi header(outctx_t &ctx);
|
||||
|
||||
void idaapi segstart(outctx_t &ctx, segment_t *seg);
|
||||
void idaapi segend(outctx_t &ctx, segment_t *seg);
|
||||
|
||||
void idaapi data(outctx_t &ctx, bool analyze_only);
|
||||
|
||||
int idaapi ana(insn_t *insn);
|
||||
|
||||
int idaapi is_align_insn(ea_t ea);
|
||||
|
||||
ea_t find_first_insn_in_packet(ea_t ea);
|
||||
|
||||
#endif // _TMS6_HPP
|
||||
Reference in New Issue
Block a user