1897 lines
114 KiB
C++
1897 lines
114 KiB
C++
/*
|
|
* Interactive disassembler (IDA).
|
|
* Copyright (c) 1990-99 by Ilfak Guilfanov.
|
|
* ALL RIGHTS RESERVED.
|
|
* E-mail: ig@datarescue.com
|
|
*
|
|
* Texas Instruments's TMS5320C55
|
|
*
|
|
*/
|
|
|
|
//lint -e704 shift right of signed quantity
|
|
//lint -e1764 could be declared const
|
|
|
|
#include "tms320c55.hpp"
|
|
#include <segregs.hpp>
|
|
|
|
#define MAX_BYTE_USER_PARALLELIZED 0x5F
|
|
#define BYTE_MMAP 0x98
|
|
#define BYTE_PORT1 0x99
|
|
#define BYTE_PORT2 0x9A
|
|
#define BYTE_LR 0x9C
|
|
#define BYTE_CR 0x9D
|
|
|
|
//--------------------------------------------------------------------------
|
|
// class to store a bytes cache
|
|
#define BYTES_SIZE 32 // maximum cache size (maximum number of bytes)
|
|
class bytes_c
|
|
{
|
|
public:
|
|
bytes_c(insn_t &_insn) : insn(_insn), size(0), i(0)
|
|
{
|
|
memset(bytes, 0, sizeof(bytes));
|
|
}
|
|
private:
|
|
insn_t &insn;
|
|
int bytes[BYTES_SIZE];
|
|
int size;
|
|
int i;
|
|
public:
|
|
void reset(void) { i = 0; }
|
|
int get_next(void);
|
|
int get(int j) const { return bytes[j]; }
|
|
void set_cache(bytevec_t &bytes);
|
|
};
|
|
|
|
//--------------------------------------------------------------------------
|
|
// get the next byte
|
|
int bytes_c::get_next(void)
|
|
{
|
|
if ( i == size )
|
|
{
|
|
// if ( size >= CACHE_SIZE ) return NULL;
|
|
// load a new byte into the cache
|
|
bytes[size] = get_byte(insn.ea+size);
|
|
size++;
|
|
}
|
|
return bytes[i++];
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// set cache contents
|
|
void bytes_c::set_cache(bytevec_t &_bytes)
|
|
{
|
|
int n = _bytes.size();
|
|
n = qmin(n, qnumber(bytes)); //lint !e666 expression with side effects
|
|
for ( size_t j=0; j < n; j++ )
|
|
bytes[j] = _bytes[j];
|
|
size = n;
|
|
reset();
|
|
}
|
|
|
|
#define OP_MASK_N 15 // maximum nomber of op_mask_t for an instruction
|
|
|
|
struct mask_t;
|
|
|
|
// function to generate an operand
|
|
typedef void (*func_op_mask_t)(const mask_t *, int64 offset, op_t *op, insn_t &insn, char &optional_op);
|
|
|
|
typedef struct
|
|
{
|
|
func_op_mask_t func; // function to set operand
|
|
int64 mask; // mask of operand
|
|
} op_mask_t;
|
|
|
|
struct mask_t
|
|
{
|
|
int64 code; // full opcode of instruction
|
|
int64 mask; // full mask of instruction
|
|
char size; // number of bytes for instruction
|
|
ushort itype; //lint !e958 padding is required to align members
|
|
op_mask_t op_mask[OP_MASK_N]; //lint !e958 padding is required to align members
|
|
// function and mask to set operands
|
|
};
|
|
|
|
//--------------------------------------------------------------------------
|
|
// verify if a given byte match a byte (0 <= n <= mask_t.size-1) from a code and mask
|
|
static bool byte_match_code_mask(const mask_t *mask, int64 byte, char n, char lbytesize = 8)
|
|
{
|
|
// compute nshift and nmask
|
|
int nshift = (mask->size - 1 - n) * lbytesize;
|
|
int64 nmask = 0;
|
|
for ( int i = 0; i < lbytesize; i++ )
|
|
nmask = (nmask << 1) | 1;
|
|
|
|
// shift code and mask to get current byte
|
|
int64 mask_code = (mask->code >> nshift) & nmask;
|
|
int64 mask_mask = (mask->mask >> nshift) & nmask;
|
|
byte &= nmask;
|
|
|
|
return (mask_code & mask_mask) == (byte & mask_mask);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
#define OP_BITS 30 // bits effectively reserved for masks (other bits are reserved for special operators)
|
|
#define OP_MASK (~(int64(0xFFFFFFFF) << OP_BITS)) // effective mask
|
|
#define OP_MASK_5 (~(make_ulonglong(0x3FFFFFF, 0) << (OP_BITS+8))) // effective mask
|
|
#define OP_MASK_6 (~(make_ulonglong(0x3FFFF, 0) << (OP_BITS+16))) // effective mask
|
|
#define OP_OP_NULL 0
|
|
#define OP_OP_IMM 1
|
|
#define OP_IMM(imm) ((OP_OP_IMM << OP_BITS)|(imm)) // return offset = imm
|
|
#define OP_TRUE OP_IMM(1) // return offset = 1
|
|
#define OP_OP_NOT 2
|
|
#define OP_NOT(mask) ((OP_OP_NOT << OP_BITS)|(mask)) // return (~offset) & 1
|
|
// return a masked operand or the result of a special operation
|
|
#define OP_IMM_5(imm) (make_longlong(0x00000000, 0x40)|(imm)) // return offset = imm
|
|
#define OP_IMM_6(imm) (make_longlong(0x00000000, 0x4000)|(imm)) // return offset = imm
|
|
#define OP_TRUE_5 OP_IMM_5(1) // return offset = 1
|
|
#define OP_TRUE_6 OP_IMM_6(1) // return offset = 1
|
|
|
|
static int64 get_masked_operand(int64 code, int64 mask)
|
|
{
|
|
if ( mask == 0 )
|
|
return 0;
|
|
bool no = false;
|
|
// special operations
|
|
switch ( mask >> OP_BITS )
|
|
{
|
|
case OP_OP_NULL:
|
|
break;
|
|
case OP_OP_IMM:
|
|
return mask & OP_MASK;
|
|
case OP_OP_NOT:
|
|
no = true;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
code &= (mask & OP_MASK);
|
|
while ( (mask & 1) == 0 )
|
|
{
|
|
code = code >> 1;
|
|
mask = mask >> 1;
|
|
}
|
|
if ( no )
|
|
code = (~code) & 1;
|
|
return code;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
static int get_signed(int byte, int mask)
|
|
{
|
|
int bits = mask >> 1;
|
|
int sign = bits + 1;
|
|
if ( byte & sign ) // offset < 0
|
|
byte = ( byte & bits ) - sign;
|
|
else // offset >= 0
|
|
byte = byte & mask;
|
|
return byte;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
inline int get_signed64(int64 byte, int mask)
|
|
{
|
|
return get_signed((int)byte, mask);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
inline int get_unsigned(int byte, int mask)
|
|
{
|
|
byte = byte & mask;
|
|
return byte;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
static int64 get_masked_operand_5(int64 code, int64 mask)
|
|
{
|
|
if ( mask == 0 )
|
|
return 0;
|
|
bool no = false;
|
|
// special operations
|
|
int Switch=mask >> (OP_BITS+8);
|
|
switch ( Switch )
|
|
{
|
|
case OP_OP_NULL: break;
|
|
case OP_OP_IMM:
|
|
return mask & OP_MASK_5;
|
|
case OP_OP_NOT:
|
|
no = true;
|
|
break;
|
|
default:
|
|
INTERR(10262);
|
|
}
|
|
code &= (mask & OP_MASK_5);
|
|
while ( (mask & 1) == 0 )
|
|
{
|
|
code = code >> 1;
|
|
mask = mask >> 1;
|
|
}
|
|
if ( no )
|
|
code = (~code) & 1;
|
|
return code;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
static int64 get_masked_operand_6(int64 code, int64 mask, bool /*bTest*/)
|
|
{
|
|
if ( mask == 0 )
|
|
return 0;
|
|
bool no = false;
|
|
// special operations
|
|
int Switch = mask >> (OP_BITS+16);
|
|
switch ( Switch )
|
|
{
|
|
case OP_OP_NULL: break;
|
|
case OP_OP_IMM:
|
|
return mask & OP_MASK_6;
|
|
case OP_OP_NOT:
|
|
no = true;
|
|
break;
|
|
default:
|
|
INTERR(10263);
|
|
}
|
|
code &= mask & OP_MASK_6;
|
|
while ( (mask & 1) == 0 )
|
|
{
|
|
code = code >> 1;
|
|
mask = mask >> 1;
|
|
}
|
|
if ( no )
|
|
code = (~code) & 1;
|
|
return code;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// process mask->op_mask[op_mask_n] on insn.ops[op_n] (if op.n not modified) and eventually modify op_n
|
|
bool tms320c55_t::process_masks_operand(
|
|
insn_t &insn,
|
|
const mask_t *mask,
|
|
int64 code,
|
|
int64 op_mask_n,
|
|
unsigned *p_opnum,
|
|
bool bTest)
|
|
{
|
|
// initialize an operand to work on
|
|
op_t work;
|
|
unsigned opnum = *p_opnum;
|
|
if ( opnum < UA_MAXOP )
|
|
work = insn.ops[opnum];
|
|
else
|
|
work = insn.ops[UA_MAXOP-1];
|
|
|
|
const op_mask_t *op_mask = &mask->op_mask[int(op_mask_n)];
|
|
if ( op_mask->func == NULL )
|
|
return false;
|
|
|
|
int64 opv = mask->size == 5 ? get_masked_operand_5(code, op_mask->mask)
|
|
: mask->size == 6 ? get_masked_operand_6(code, op_mask->mask, bTest)
|
|
: get_masked_operand(code, op_mask->mask);
|
|
op_mask->func(mask, opv, &work, insn, optional_op);
|
|
|
|
if ( work.type != o_void ) // if the operand was modified
|
|
{
|
|
if ( work.n == opnum ) // the function worked on the current operand
|
|
{
|
|
if ( opnum >= UA_MAXOP )
|
|
return false; // error if not enough operands in insn
|
|
insn.ops[opnum] = work; // save the new operand
|
|
*p_opnum = ++opnum; // go to the next operand
|
|
}
|
|
else // the function modified the previous operand
|
|
{
|
|
if ( work.n >= UA_MAXOP )
|
|
return false;
|
|
insn.ops[work.n] = work; // save the new precedent operand (modified)
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// get number of bytes for a given instruction opcode (left-aligned in dword)
|
|
static int get_insn_size(const mask_t *masks, uint32 opcode)
|
|
{
|
|
const mask_t *p = masks;
|
|
while ( p->mask != 0 )
|
|
{
|
|
if ( p->size <= 4 && (p->mask & (opcode>>(8*(4-p->size)))) == p->code )
|
|
return p->size;
|
|
p++;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// analyze code by processing all necessary masks
|
|
void tms320c55_t::process_masks(
|
|
insn_t &insn,
|
|
const mask_t *masks,
|
|
ushort itype_null,
|
|
bytes_c &bytes,
|
|
char lbytesize)
|
|
{
|
|
insn.itype = itype_null;
|
|
insn.size = 1;
|
|
|
|
const mask_t *p = masks;
|
|
while ( p->mask != 0 )
|
|
{
|
|
bytes.reset();
|
|
ushort nbytes = 0;
|
|
while ( nbytes < p->size
|
|
&& byte_match_code_mask(p, bytes.get_next(), (uchar &)nbytes, lbytesize) )
|
|
{
|
|
nbytes++;
|
|
}
|
|
if ( nbytes == p->size ) // if bytes matches all bytes from code and mask
|
|
{
|
|
int i;
|
|
insn.itype = p->itype;
|
|
insn.size = nbytes;
|
|
// compute full code
|
|
int64 code = 0;
|
|
for ( i = 0; i < nbytes; i++ )
|
|
code = (code << lbytesize) | bytes.get(i);
|
|
// process operands
|
|
unsigned opnum = 0;
|
|
for ( i = 0; i < OP_MASK_N; i++ )
|
|
{
|
|
bool bTest = p->size == 6 && i == 2;
|
|
if ( !process_masks_operand(insn, p, code, i, &opnum, bTest) )
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
p++;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// permit a mask_func_n to work on the last operand
|
|
static bool get_last_op(op_t *op, const insn_t &insn)
|
|
{
|
|
int n;
|
|
for ( n = 0; n < 6; n++ ) // find the first o_void operand
|
|
if ( insn.ops[n].type == o_void )
|
|
break;
|
|
|
|
if ( n == 0 )
|
|
return false; // no precedent operand
|
|
*op = insn.ops[n-1]; // copy the precedent operand to the current position
|
|
return true;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// format instruction name
|
|
static void get_name_chars(
|
|
char *buf,
|
|
size_t bufsize,
|
|
bool incl_chars,
|
|
const char *name,
|
|
const char *chars)
|
|
{
|
|
char *bufend = qstpncpy(buf, name, bufsize);
|
|
if ( incl_chars )
|
|
qstrncpy(bufend, chars, bufsize - (bufend-buf));
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// instructions
|
|
|
|
// find instruction insn+"chars" with same operands:
|
|
// parallel indicate an instructions on 2 lines
|
|
// name1_chars indicate if we must have "chars" added to the first line
|
|
// name2_chars indicate if we must have "chars" added to the second line
|
|
// instructions in instruc_t Instructions[] must be sorted as follow:
|
|
// insn1 - insn2 - ... - insn"chars"1 - insn"chars"2 - ...
|
|
static bool find_insn_suffix(
|
|
insn_t &insn,
|
|
const char *chars,
|
|
ushort itype_last,
|
|
bool parallel,
|
|
bool name1_chars,
|
|
bool name2_chars)
|
|
{
|
|
const char *insn_name1 = Instructions[insn.itype].name;
|
|
char insn_name1_chars[MAXSTR];
|
|
get_name_chars(insn_name1_chars, sizeof(insn_name1_chars), name1_chars, insn_name1, chars);
|
|
|
|
const char *insn_name2 = NULL;
|
|
char insn_name2_chars[MAXSTR];
|
|
insn_name2_chars[0] = '\0';
|
|
if ( parallel )
|
|
{
|
|
insn_name2 = strchr(insn_name1, 0)+1;
|
|
get_name_chars(insn_name2_chars, sizeof(insn_name2_chars), name2_chars, insn_name2, chars);
|
|
}
|
|
|
|
ushort i = insn.itype + 1;
|
|
// jump over same instruction names (but eventually different number of params)
|
|
while ( streq(Instructions[i].name, insn_name1)
|
|
&& (!parallel || streq(strchr(Instructions[i].name, 0)+1, insn_name2)) ) //-V575 potential null pointer
|
|
{
|
|
if ( ++i == itype_last )
|
|
return false;
|
|
}
|
|
|
|
// loop until current instruction names are the same as what we are searching for (name or name+chars)
|
|
while ( !streq(Instructions[i].name, insn_name1_chars)
|
|
|| (parallel && !streq(strchr(Instructions[i].name, 0)+1, insn_name2_chars)) )
|
|
{
|
|
if ( ++i == itype_last )
|
|
return false;
|
|
}
|
|
|
|
// loop until current instruction has same params
|
|
uint32 insn_feature = Instructions[insn.itype].feature;
|
|
while ( Instructions[i].feature != insn_feature )
|
|
{
|
|
if ( ++i == itype_last )
|
|
return false;
|
|
}
|
|
|
|
insn.itype = i;
|
|
return true;
|
|
}
|
|
|
|
#define insn_chars(NAME, CHARS, PARALLEL, NAME1_CHARS, NAME2_CHARS) \
|
|
static void NAME(const mask_t *, int64 offset, op_t *, insn_t &insn, char &) \
|
|
{ \
|
|
if ( (offset & 1) != 0 ) \
|
|
{ \
|
|
bool ok = find_insn_suffix(insn, CHARS, TMS320C55_last, PARALLEL,\
|
|
NAME1_CHARS, NAME2_CHARS); \
|
|
if ( !ok ) \
|
|
error("interr: ana: adjust_insn_suffix"); \
|
|
} \
|
|
}
|
|
|
|
insn_chars(insn_1_R_2_R, "r", true, true, true) // insn_1_R_2_R %
|
|
insn_chars(insn_1_40_2_40, "40", true, true, true) // insn_1_40_2_40 g
|
|
insn_chars(insn_1_2_R, "r", true, false, true) // insn_1_2_R %
|
|
insn_chars(insn_1_2_40, "40", true, false, true) // insn_1_2_40 g
|
|
insn_chars(insn_1_R, "r", false, true, false) // insn_1_R %
|
|
insn_chars(insn_1_40, "40", false, true, false) // insn_1_40 g
|
|
insn_chars(insn_1_R_2, "r", true, true, false) // insn_1_R_2 %
|
|
insn_chars(insn_1_U, "u", false, true, false) // insn_1_U u
|
|
insn_chars(insn_1_P, "p", false, true, false) // insn_1_P swap()
|
|
insn_chars(insn_1_4, "4", false, true, false) // insn_1_4 swap()
|
|
|
|
// set user parellel
|
|
static void insn_UP(const mask_t *, int64, op_t *, insn_t &insn, char &)
|
|
{
|
|
insn.SpecialModes |= TMS_MODE_USER_PARALLEL;
|
|
}
|
|
|
|
// built-in parallelism
|
|
static void blt_prll(const mask_t *, int64, op_t *, insn_t &insn, char &)
|
|
{ // count the number of actual operands
|
|
insn.Parallel = 0;
|
|
for ( int i = 0; i < UA_MAXOP; i++ )
|
|
{
|
|
if ( insn.ops[i].type == o_void )
|
|
break;
|
|
insn.Parallel++;
|
|
}
|
|
}
|
|
|
|
// simulated user parallelism
|
|
// static void usr_prll(const mask_t *mask, int64 offset, op_t *op)
|
|
// {
|
|
// if ( offset & 1 )
|
|
// {
|
|
// blt_prll(mask, offset, op);
|
|
// insn.SpecialModes |= TMS_MODE_SIMULATE_USER_PARALLEL;
|
|
// }
|
|
// }
|
|
// ? actually not used, but will probably be used for non-documented opcodes
|
|
// need also to add new instructions "ins1\nins2" in ins.hpp & ins.cpp
|
|
|
|
// immediates
|
|
|
|
#define op_imm(NAME, DTYP) \
|
|
static void op_##NAME(const mask_t *, int64 offset, op_t *op, insn_t &, char &) \
|
|
{ \
|
|
op->type = o_imm; \
|
|
op->value = (uval_t)offset; \
|
|
op->dtype = dt_##DTYP; \
|
|
}
|
|
|
|
op_imm(k8, byte) // op_k8
|
|
op_imm(k16, word) // op_k16
|
|
#define op_k4 op_k8
|
|
#define op_k5 op_k8
|
|
#define op_k7 op_k8
|
|
#define op_k9 op_k16
|
|
#define op_k12 op_k16
|
|
|
|
//--------------------------------------------------------------------------
|
|
static void op_min_k4(const mask_t *, int64 offset, op_t *op, insn_t &, char &)
|
|
{
|
|
op->type = o_imm;
|
|
op->value = (uval_t)-offset;
|
|
op->dtype = dt_byte;
|
|
op->tms_signed = true;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
static void op_K8(const mask_t *, int64 offset, op_t *op, insn_t &, char &)
|
|
{
|
|
op->type = o_imm;
|
|
op->value = get_signed64(offset, 0xFF);
|
|
op->dtype = dt_byte;
|
|
op->tms_signed = true;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
static void op_K16(const mask_t *, int64 offset, op_t *op, insn_t &, char &)
|
|
{
|
|
op->type = o_imm;
|
|
op->value = get_signed64(offset, 0xFFFF);
|
|
op->dtype = dt_word;
|
|
op->tms_signed = true;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
/*
|
|
static void op_K23(const mask_t *, int64 offset, op_t *op, insn_t &, char &)
|
|
{
|
|
op->type = o_imm;
|
|
op->value = get_unsigned(offset, 0x7FFFFF);
|
|
op->dtype = dt_3byte;
|
|
}
|
|
*/
|
|
|
|
//--------------------------------------------------------------------------
|
|
static void op_1(const mask_t *, int64, op_t *op, insn_t &, char &)
|
|
{
|
|
op->type = o_imm;
|
|
op->value = 1;
|
|
op->dtype = dt_byte;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
static void op_min_1(const mask_t *, int64, op_t *op, insn_t &, char &)
|
|
{
|
|
op->type = o_imm;
|
|
op->value = uval_t(-1);
|
|
op->dtype = dt_byte;
|
|
op->tms_signed = true;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// registers
|
|
|
|
static void op_src(const mask_t *, int64 offset, op_t *op, insn_t &, char &optional_op) // FSSS, FDDD
|
|
{
|
|
op->type = o_reg;
|
|
op->dtype = dt_word;
|
|
op->reg = AC0 + uint16(offset);
|
|
optional_op = op->n;
|
|
}
|
|
|
|
#define op_dst op_src
|
|
#define op_ACw op_src
|
|
#define op_ACx op_src
|
|
#define op_ACy op_src
|
|
#define op_ACz op_src
|
|
#define op_TAx op_src // ARx or Tx
|
|
#define op_TAy op_src // ARy or Ty
|
|
|
|
// optional operand
|
|
static void opt_src(const mask_t *mask, int64 offset, op_t *op, insn_t &insn, char &optional_op) // FSSS, FDDD
|
|
{
|
|
if ( optional_op != -1
|
|
&& insn.ops[uchar(optional_op)].type == o_reg
|
|
&& insn.ops[uchar(optional_op)].reg == AC0 + offset )
|
|
{
|
|
return; // no operand if same than the source
|
|
}
|
|
// add the operand
|
|
op_src(mask, offset, op, insn, optional_op);
|
|
optional_op = -1;
|
|
insn.itype++;
|
|
}
|
|
|
|
#define opt_dst opt_src
|
|
#define opt_ACy opt_src
|
|
|
|
|
|
#define op_reg(NAME, REG) \
|
|
static void op_##NAME(const mask_t *, int64 offset, op_t *op, insn_t &, char &)\
|
|
{ \
|
|
op->type = o_reg; \
|
|
op->dtype = dt_word; \
|
|
op->reg = REG + uint16(offset); \
|
|
}
|
|
|
|
op_reg(Tx, T0) // op_Tx
|
|
op_reg(TCx, TC1) // op_TCx
|
|
op_reg(TRNx, TRN0) // op_TRNx
|
|
#define op_TCy op_TCx
|
|
op_reg(ARx, AR0) // op_ARx
|
|
op_reg(DPH, DPH) // op_DPH
|
|
op_reg(PDP, PDP) // op_PDP
|
|
op_reg(BK03, BK03) // op_BK03
|
|
op_reg(BK47, BK47) // op_BK47
|
|
op_reg(BKC, BKC) // op_BKC
|
|
op_reg(CSR, CSR) // op_CSR
|
|
op_reg(BRC0, BRC0) // op_BRC0
|
|
op_reg(BRC1, BRC1) // op_BRC1
|
|
op_reg(SP, SP) // op_SP
|
|
op_reg(SSP, SSP) // op_SSP
|
|
op_reg(CDP, CDP) // op_CDP
|
|
op_reg(RPTC, RPTC) // op_RPTC
|
|
op_reg(STx_55, ST0_55) // op_STx_55
|
|
op_reg(DP, DP) // op_DP
|
|
op_reg(BSA01, BSA01) // op_BSA01
|
|
op_reg(BSA23, BSA23) // op_BSA23
|
|
op_reg(BSA45, BSA45) // op_BSA45
|
|
op_reg(BSA67, BSA67) // op_BSA67
|
|
op_reg(BSAC, BSAC) // op_BSAC
|
|
op_reg(TRN0, TRN0) // op_TRN0
|
|
op_reg(TRN1, TRN1) // op_TRN1
|
|
op_reg(TC1, TC1) // op_TC1
|
|
op_reg(TC2, TC2) // op_TC2
|
|
op_reg(CARRY, CARRY) // op_CARRY
|
|
op_reg(BORROW, BORROW) // op_BORROW
|
|
op_reg(RETA, RETA) // op_RETA
|
|
op_reg(MDP05, MDP05) // op_MDP05
|
|
op_reg(MDP67, MDP67) // op_MDP67
|
|
|
|
//--------------------------------------------------------------------------
|
|
static void op_xsrc(const mask_t *, int64 offset, op_t *op, insn_t &, char &) // XSSS, XDDD
|
|
{ // AC0 AC1 AC2 AC3 XSP XSSP XDP XCDP XAR0 -> XAR7
|
|
static const ushort regs[] =
|
|
{
|
|
AC0, AC1, AC2, AC3, XSP, XSSP, XDP, XCDP,
|
|
XAR0, XAR1, XAR2, XAR3, XAR4, XAR5, XAR6, XAR7
|
|
};
|
|
op->type = o_reg;
|
|
op->dtype = dt_dword;
|
|
op->reg = regs[int(offset)];
|
|
}
|
|
#define op_xdst op_xsrc
|
|
|
|
//--------------------------------------------------------------------------
|
|
static void op_Xmem(const mask_t *mask, int64 offset, op_t *op, insn_t &insn, char &optional_op) // XXXMMM, YYYMMM
|
|
{
|
|
op_ARx(mask, offset >> 3, op, insn, optional_op);
|
|
op->tms_modifier = TMS_MODIFIER_REG + (offset & 0x7);
|
|
}
|
|
#define op_Ymem op_Xmem
|
|
|
|
//--------------------------------------------------------------------------
|
|
static void op_Cmem(const mask_t *mask, int64 offset, op_t *op, insn_t &insn, char &optional_op) // mm
|
|
{
|
|
op_CDP(mask, 0, op, insn, optional_op);
|
|
op->tms_modifier = TMS_MODIFIER_REG + (offset & 0x3);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
static void op_mem(
|
|
const mask_t *mask,
|
|
int64 offset,
|
|
op_t *op,
|
|
op_dtype_t dtype,
|
|
insn_t &insn,
|
|
char optional_op,
|
|
bool ARn_mod = false) // AAAAAAAI
|
|
{
|
|
insn.OpMem = 1 + op->n;
|
|
if ( !(offset & 1) ) // @dma
|
|
{ // direct memory address
|
|
sel_t cpl = get_sreg(insn.ea, CPL);
|
|
if ( cpl == BADSEL )
|
|
cpl = 0;
|
|
if ( !cpl )
|
|
{ // use DP
|
|
op->type = o_mem;
|
|
op->tms_regH = DPH;
|
|
op->tms_regP = DP;
|
|
op->addr = ea_t(offset >> 1);
|
|
op->tms_modifier = TMS_MODIFIER_DMA;
|
|
}
|
|
else
|
|
{ // use SP
|
|
op->type = o_reg;
|
|
op->reg = SP;
|
|
op->value = ea_t(offset >> 1);
|
|
op->tms_modifier = TMS_MODIFIER_REG_OFFSET;
|
|
}
|
|
}
|
|
else
|
|
{ // indirect memory access
|
|
if ( (offset & 0x1F) == 0x11 ) // xxx1 0001
|
|
{
|
|
int bits = int(offset >> 5);
|
|
switch ( bits )
|
|
{
|
|
case 0: // *ABS16(#k16)
|
|
op->type = o_mem;
|
|
op->tms_regH = DPH;
|
|
op->addr = (get_byte(insn.ea+insn.size) << 8)
|
|
| get_byte(insn.ea+insn.size+1);
|
|
op->tms_modifier = TMS_MODIFIER_ABS16;
|
|
insn.size += 2;
|
|
break;
|
|
case 1: // *(#k23)
|
|
op->type = o_mem;
|
|
op->addr = (get_byte(insn.ea+insn.size) << 16)
|
|
| (get_byte(insn.ea+insn.size+1) << 8)
|
|
| get_byte(insn.ea+insn.size+2);
|
|
op->tms_modifier = TMS_MODIFIER_PTR;
|
|
insn.size += 3;
|
|
break;
|
|
case 2: // port(#k16)
|
|
op->type = o_io;
|
|
op->addr = (get_byte(insn.ea+insn.size) << 8)
|
|
| get_byte(insn.ea+insn.size+1);
|
|
op->tms_modifier = TMS_MODIFIER_PORT;
|
|
insn.size += 2;
|
|
break;
|
|
case 3: // *CDP
|
|
case 4: // *CDP+
|
|
case 5: // *CDP-
|
|
op_CDP(mask, 0, op, insn, optional_op);
|
|
op->tms_modifier= TMS_MODIFIER_REG + uchar(bits)-3;
|
|
break;
|
|
case 6: // *CDP(#K16)
|
|
case 7: // *+CDP(#K16)
|
|
op_CDP(mask, 0, op, insn, optional_op);
|
|
op->value = get_signed((get_byte(insn.ea+insn.size) << 8)
|
|
| get_byte(insn.ea+insn.size+1), 0xFFFF);
|
|
op->tms_modifier = TMS_MODIFIER_REG_OFFSET + uchar(bits)-6;
|
|
insn.size += 2;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
op_ARx(mask, offset >> 5, op, insn, optional_op);
|
|
int bits = (offset >> 1) & 0xF;
|
|
if ( (offset & 0x11) == 0x01 ) // xxx0 xxx1
|
|
{
|
|
switch ( bits )
|
|
{
|
|
case 0: // *ARn
|
|
case 1: // *ARn+
|
|
case 2: // *ARn-
|
|
op->tms_modifier= TMS_MODIFIER_REG + uchar(bits);
|
|
break;
|
|
case 3: // *(ARn+T0)
|
|
op->tms_modifier= TMS_MODIFIER_REG_P_T0;
|
|
break;
|
|
case 4: // *(ARn-T0)
|
|
op->tms_modifier= TMS_MODIFIER_REG_M_T0;
|
|
break;
|
|
case 5: // *ARn(T0)
|
|
op->tms_modifier= TMS_MODIFIER_REG_T0;
|
|
break;
|
|
case 6: // *ARn(#K16)
|
|
case 7: // *+ARn(#K16)
|
|
op->value = get_signed((get_byte(insn.ea+insn.size) << 8)
|
|
| get_byte(insn.ea+insn.size+1), 0xFFFF);
|
|
op->tms_modifier = TMS_MODIFIER_REG_OFFSET + uchar(bits)-6;
|
|
insn.size += 2;
|
|
break;
|
|
}
|
|
}
|
|
else // xxx1 xxx1
|
|
{
|
|
int lbits = (offset >> 1) & 0x7;
|
|
sel_t arms = get_sreg(insn.ea, ARMS);
|
|
if ( arms == BADSEL )
|
|
arms = 0;
|
|
if ( ARn_mod || !arms )
|
|
{
|
|
switch ( lbits )
|
|
{
|
|
case 1: // *(ARn+T1)
|
|
op->tms_modifier= TMS_MODIFIER_REG_P_T1;
|
|
break;
|
|
case 2: // *(ARn-T1)
|
|
op->tms_modifier= TMS_MODIFIER_REG_M_T1;
|
|
break;
|
|
case 3: // *ARn(T1)
|
|
case 4: // *+ARn
|
|
case 5: // *-ARn
|
|
case 6: // *(ARn+T0B)
|
|
case 7: // *(ARn-T0B)
|
|
op->tms_modifier= TMS_MODIFIER_REG_T1 + uchar(lbits)-3;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{ // *ARn(short(#value))
|
|
op->value = lbits;
|
|
op->tms_modifier = TMS_MODIFIER_REG_SHORT_OFFSET;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
op->dtype = dtype;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
static void op_Smem(const mask_t *mask, int64 offset, op_t *op, insn_t &insn, char &optional_op) // AAAAAAAI //-V669 'optional_op' argument is a non-constant reference
|
|
{
|
|
op_mem(mask, offset, op, dt_word, insn, optional_op);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
static void op_Lmem(const mask_t *mask, int64 offset, op_t *op, insn_t &insn, char &optional_op) // AAAAAAAI //-V669 'optional_op' argument is a non-constant reference
|
|
{
|
|
op_mem(mask, offset, op, dt_dword, insn, optional_op);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
static void op_ARn_mod(const mask_t *mask, int64 offset, op_t *op, insn_t &insn, char &optional_op) // AAAAAAAI //-V669 'optional_op' argument is a non-constant reference
|
|
{
|
|
op_mem(mask, offset, op, dt_word, insn, optional_op, true);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// @dma = bit number
|
|
static void op_Baddr(const mask_t *mask, int64 offset, op_t *op, insn_t &insn, char &optional_op) // AAAAAAAI //-V669 'optional_op' argument is a non-constant reference
|
|
{
|
|
if ( !(offset & 1) ) // @dma
|
|
{
|
|
op->type = o_imm;
|
|
op->value = ea_t(offset >> 1);
|
|
op->dtype = dt_byte;
|
|
op->tms_prefix = '@';
|
|
op->tms_signed = false;
|
|
}
|
|
else
|
|
{
|
|
op_mem(mask, offset, op, dt_byte, insn, optional_op);
|
|
}
|
|
}
|
|
|
|
//lint -emacro(572,fn_operator) excessive shift value
|
|
#define fn_operator(NAME, OPERATOR) \
|
|
static void fn_##NAME(const mask_t *, int64 offset, op_t *op, insn_t &insn, char &) \
|
|
{ \
|
|
if ( offset & 1 ) \
|
|
{ \
|
|
get_last_op(op, insn); \
|
|
op->tms_operator1 |= TMS_OPERATOR_##OPERATOR & 0xFF; \
|
|
/*lint -e572 Excessive shift value*/ \
|
|
op->tms_operator2 |= (TMS_OPERATOR_##OPERATOR >> 8); \
|
|
} \
|
|
}
|
|
|
|
fn_operator(not, NOT) // fn_not
|
|
fn_operator(T3, T3) // fn_T3 U
|
|
fn_operator(uns, UNS) // fn_uns u
|
|
fn_operator(rnd, RND) // fn_rnd %
|
|
fn_operator(hb, HB) // fn_hb
|
|
fn_operator(lb, LB) // fn_lb
|
|
fn_operator(hi, HI) // fn_hi
|
|
fn_operator(lo, LO) // fn_lo
|
|
fn_operator(sat, SAT) // fn_sat = fn_uns
|
|
fn_operator(dbl, DBL) // fn_dbl
|
|
fn_operator(pair, PAIR) // fn_pair
|
|
fn_operator(dual, DUAL) // fn_dual
|
|
|
|
//--------------------------------------------------------------------------
|
|
static void op_BitIn(const mask_t *, int64 offset, op_t *op, insn_t &, char &)
|
|
{
|
|
op->type = o_reg;
|
|
op->dtype = dt_byte;
|
|
op->reg = (offset & 1) ? TC2 : CARRY;
|
|
}
|
|
#define op_BitOut op_BitIn
|
|
|
|
//--------------------------------------------------------------------------
|
|
static void op_swap(const mask_t *mask, int64 offset, op_t *op, insn_t &insn, char &optional_op)
|
|
{
|
|
insn.Op1.type = o_reg;
|
|
insn.Op1.dtype = dt_word;
|
|
insn.Op2.type = o_reg;
|
|
insn.Op2.dtype = dt_word;
|
|
switch ( offset )
|
|
{
|
|
case 0x00: insn.Op1.reg = AC0; insn.Op2.reg = AC2; break;
|
|
case 0x01: insn.Op1.reg = AC1; insn.Op2.reg = AC3; break;
|
|
case 0x04: insn.Op1.reg = T0; insn.Op2.reg = T2; break;
|
|
case 0x05: insn.Op1.reg = T1; insn.Op2.reg = T3; break;
|
|
case 0x08: insn.Op1.reg = AR0; insn.Op2.reg = AR2; break;
|
|
case 0x09: insn.Op1.reg = AR1; insn.Op2.reg = AR3; break;
|
|
case 0x0C: insn.Op1.reg = AR4; insn.Op2.reg = T0; break;
|
|
case 0x0D: insn.Op1.reg = AR5; insn.Op2.reg = T1; break;
|
|
case 0x0E: insn.Op1.reg = AR6; insn.Op2.reg = T2; break;
|
|
case 0x0F: insn.Op1.reg = AR7; insn.Op2.reg = T3; break;
|
|
case 0x10: insn_1_P(mask, 1, op, insn, optional_op); insn.Op1.reg = AC0; insn.Op2.reg = AC2; break;
|
|
case 0x14: insn_1_P(mask, 1, op, insn, optional_op); insn.Op1.reg = T0; insn.Op2.reg = T2; break;
|
|
case 0x18: insn_1_P(mask, 1, op, insn, optional_op); insn.Op1.reg = AR0; insn.Op2.reg = AR2; break;
|
|
case 0x1C: insn_1_P(mask, 1, op, insn, optional_op); insn.Op1.reg = AR4; insn.Op2.reg = T0; break;
|
|
case 0x1E: insn_1_P(mask, 1, op, insn, optional_op); insn.Op1.reg = AR6; insn.Op2.reg = T2; break;
|
|
case 0x2C: insn_1_4(mask, 1, op, insn, optional_op); insn.Op1.reg = AR4; insn.Op2.reg = T0; break;
|
|
case 0x38: insn.Op1.reg = AR0; insn.Op2.reg = AR1; break;
|
|
default: insn.itype = TMS320C55_null;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// get address for the branch offset base
|
|
// in case of parallel execution, this is the end of the second, parallel instruction
|
|
static ea_t get_next_ip(insn_t &insn)
|
|
{
|
|
ea_t next = insn.ip + insn.size;
|
|
if ( insn.size <= 3 )
|
|
{
|
|
uchar nextbyte = get_byte(insn.ea + insn.size);
|
|
if ( nextbyte <= MAX_BYTE_USER_PARALLELIZED && (nextbyte & 1) )
|
|
{
|
|
// next instruction is executed in parallel, so take it into account
|
|
insn_t tmp;
|
|
next += decode_insn(&tmp, insn.ea + insn.size);
|
|
}
|
|
}
|
|
return next;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// code addresses
|
|
|
|
static void op_l4(const mask_t *, int64 offset, op_t *op, insn_t &insn, char &) // llll
|
|
{
|
|
op->type = o_near;
|
|
op->addr = (get_next_ip(insn) + offset) & 0xFFFFFF;
|
|
op->dtype = dt_code;
|
|
}
|
|
|
|
static void op_L7(const mask_t *, int64 offset, op_t *op, insn_t &insn, char &) // LLLLLLL
|
|
{
|
|
op->type = o_near;
|
|
op->addr = (get_next_ip(insn) + get_signed64(offset, 0x7F)) & 0xFFFFFF;
|
|
op->dtype = dt_code;
|
|
}
|
|
|
|
static void op_L8(const mask_t *, int64 offset, op_t *op, insn_t &insn, char &) // LLLLLLLL
|
|
{
|
|
op->type = o_near;
|
|
op->addr = (get_next_ip(insn) + get_signed64(offset, 0xFF)) & 0xFFFFFF;
|
|
op->dtype = dt_code;
|
|
}
|
|
|
|
static void op_L16(const mask_t *, int64 offset, op_t *op, insn_t &insn, char &) // LLLLLLLL LLLLLLLL
|
|
{
|
|
op->type = o_near;
|
|
op->addr = (get_next_ip(insn) + get_signed64(offset, 0xFFFF)) & 0xFFFFFF;
|
|
op->dtype = dt_code;
|
|
}
|
|
|
|
static void op_pmad(const mask_t *, int64 offset, op_t *op, insn_t &insn, char &)
|
|
{
|
|
op->type = o_near;
|
|
op->addr = (get_next_ip(insn) + offset) & 0xFFFFFF;
|
|
op->dtype = dt_code;
|
|
}
|
|
|
|
static void op_P24(const mask_t *, int64, op_t *op, insn_t &insn, char &) // get_byte included
|
|
{
|
|
op->type = o_near;
|
|
op->addr = (get_byte(insn.ea+insn.size+0) << 16)
|
|
| (get_byte(insn.ea+insn.size+1) << 8)
|
|
| get_byte(insn.ea+insn.size+2);
|
|
op->dtype = dt_code;
|
|
insn.size += 3;
|
|
}
|
|
|
|
// data addresses
|
|
|
|
static void op_D16(const mask_t *, int64 offset, op_t *op, insn_t &, char &)
|
|
{
|
|
op->type = o_mem;
|
|
op->addr = ea_t(offset);
|
|
op->dtype = dt_word;
|
|
}
|
|
|
|
// various
|
|
|
|
static void op_SHIFTW(const mask_t *, int64 offset, op_t *op, insn_t &, char &)
|
|
{
|
|
op->type = o_shift;
|
|
op->value = (signed short)get_signed64(offset, 0x3F);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// shift left
|
|
static void shl_SHIFTW(const mask_t *, int64 offset, op_t *op, insn_t &insn, char &)
|
|
{
|
|
get_last_op(op, insn);
|
|
op->tms_shift = TMS_OP_SHIFTL_IMM;
|
|
op->tms_shift_value = (signed short)get_signed64(offset, 0x3F);
|
|
if ( short(op->tms_shift_value) < 0 )
|
|
{
|
|
op->tms_shift = TMS_OP_SHIFTR_IMM;
|
|
op->tms_shift_value = -op->tms_shift_value; //lint !e2501 negation of value of unsigned type
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// shift left out of brackets
|
|
static void slo_SHIFTW(const mask_t *mask, int64 offset, op_t *op, insn_t &insn, char &optional_op)
|
|
{
|
|
shl_SHIFTW(mask, offset, op, insn, optional_op);
|
|
op->tms_shift |= TMS_OP_SHIFT_OUT;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// shift right
|
|
static void shl_SHFT(const mask_t *, int64 offset, op_t *op, insn_t &insn, char &)
|
|
{
|
|
get_last_op(op, insn);
|
|
op->tms_shift = TMS_OP_SHIFTL_IMM;
|
|
op->tms_shift_value = (uint16)offset;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
static void shl_Tx(const mask_t *, int64 offset, op_t *op, insn_t &insn, char &)
|
|
{
|
|
get_last_op(op, insn);
|
|
op->tms_shift = TMS_OP_SHIFTL_REG;
|
|
op->tms_shift_value = T0 + uint16(offset);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
static void shl_T2(const mask_t *, int64, op_t *op, insn_t &insn, char &)
|
|
{
|
|
get_last_op(op, insn);
|
|
op->tms_shift = TMS_OP_SHIFTL_REG;
|
|
op->tms_shift_value = T2;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
static void shl_16(const mask_t *, int64, op_t *op, insn_t &insn, char &)
|
|
{
|
|
get_last_op(op, insn);
|
|
op->tms_shift = TMS_OP_SHIFTL_IMM;
|
|
op->tms_shift_value = 16;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
static void shr(const mask_t *, int64 imm, op_t *op, insn_t &insn, char &)
|
|
{
|
|
get_last_op(op, insn);
|
|
op->tms_shift = TMS_OP_SHIFTR_IMM;
|
|
op->tms_shift_value = uint16(imm);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
static void eq_K16(const mask_t *, int64 offset, op_t *op, insn_t &insn, char &)
|
|
{
|
|
get_last_op(op, insn);
|
|
op->tms_shift = TMS_OP_EQ;
|
|
op->tms_shift_value = (uint16)get_signed64(offset, 0xFFFF);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
static void neq_0(const mask_t *, int64, op_t *op, insn_t &insn, char &)
|
|
{
|
|
get_last_op(op, insn);
|
|
op->tms_shift = TMS_OP_NEQ;
|
|
op->tms_shift_value = 0;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
static void RELOP(const mask_t *, int64 offset, op_t *op, insn_t &insn, char &) // cc
|
|
{
|
|
get_last_op(op, insn);
|
|
op->type = o_relop;
|
|
op->tms_relop = offset & 0x3;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
static void RELOP_dst(const mask_t *mask, int64 offset, op_t *op, insn_t &insn, char &optional_op)
|
|
{
|
|
get_last_op(op, insn);
|
|
op->tms_relop_type = TMS_RELOP_REG;
|
|
ushort sav = op->reg;
|
|
op_src(mask, offset, op, insn, optional_op);
|
|
op->type = o_relop;
|
|
op->value = op->reg;
|
|
op->reg = sav;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
static void RELOP_K8(const mask_t *, int64 offset, op_t *op, insn_t &insn, char &)
|
|
{
|
|
get_last_op(op, insn);
|
|
op->tms_relop_type = TMS_RELOP_IMM;
|
|
op->value = (signed short)get_signed64(offset, 0xFF);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
static void op_cond(const mask_t *mask, int64 offset, op_t *op, insn_t &insn, char &optional_op) // CCC CCCC
|
|
{
|
|
op->reg = 0;
|
|
if ( (offset>>4) <= 0x5 ) // <= 101 xxxx
|
|
{ // src <comparison operator> 0
|
|
op_src(mask, offset & 0xF, op, insn, optional_op);
|
|
op->type = o_cond;
|
|
op->value = offset & 0x70;
|
|
}
|
|
else if ( (offset>>2) == 0x18 ) // == 110 00xx
|
|
{ // overflow(ACx)
|
|
op_src(mask, offset & 0x3, op, insn, optional_op);
|
|
op->type = o_cond;
|
|
op->value = offset & 0x7C;
|
|
}
|
|
else if ( (offset>>2) == 0x19 ) // == 110 01xx
|
|
{ // TC1, TC2, CARRY, reserved
|
|
if ( offset == 0x67 ) // 110 0111
|
|
insn.itype = TMS320C55_null; // reserved
|
|
else
|
|
{
|
|
op->type = o_cond;
|
|
op->value = (uval_t)offset;
|
|
}
|
|
}
|
|
else if ( (offset>>2) == 0x1A ) // == 110 10xx
|
|
{ // TC1 & TC2, TC1 & !TC2, !TC1 & TC2, !TC1 & !TC2
|
|
op->type = o_cond;
|
|
op->value = (uval_t)offset;
|
|
}
|
|
else if ( (offset>>2) == 0x1B ) // == 110 11xx
|
|
{
|
|
insn.itype = TMS320C55_null; // reserved
|
|
}
|
|
else if ( (offset>>2) == 0x1C ) // == 111 00xx
|
|
{ // !overflow(ACx)
|
|
op_src(mask, offset & 0x3, op, insn, optional_op);
|
|
op->type = o_cond;
|
|
op->value = offset & 0x7C;
|
|
}
|
|
else
|
|
{
|
|
if ( offset == 0x77 ) // 111 0111
|
|
insn.itype = TMS320C55_null; // reserved
|
|
else
|
|
{
|
|
op->type = o_cond;
|
|
op->value = (uval_t)offset;
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
//lint -e648 overflow in computing constant for operator '<<': signed shift result (0x80000000) sets the sign bit of the shift expression's type ('int') and becomes negative expanded from macro 'OP_NOT'
|
|
static const mask_t masks[] =
|
|
{
|
|
// 0000000E XDDDX000 error manual
|
|
{ 0x000000, 0xFE0000, 3, TMS320C55_rptcc, {{ op_k8, 0x0000FF }, { op_cond, 0x007F00 }}},
|
|
{ 0x020000, 0xFE0000, 3, TMS320C55_retcc, {{ op_cond, 0x007F00 }}},
|
|
{ 0x040000, 0xFE0000, 3, TMS320C55_bcc, {{ op_L8, 0x0000FF }, { op_cond, 0x007F00 }}},
|
|
{ 0x060000, 0xFE0000, 3, TMS320C55_b, {{ op_L16, 0x00FFFF }}},
|
|
{ 0x080000, 0xFE0000, 3, TMS320C55_call, {{ op_L16, 0x00FFFF }}},
|
|
// 0000101E GGGGGGGG Glllllll error manual
|
|
{ 0x0C0000, 0xFE0000, 3, TMS320C55_rpt, {{ op_k16, 0x00FFFF }}},
|
|
{ 0x0E0000, 0xFE0000, 3, TMS320C55_rptb, {{ op_pmad, 0x00FFFF }}},
|
|
{ 0x100000, 0xFE0F00, 3, TMS320C55_and1, {{ op_ACx, 0x003000 }, { shl_SHIFTW, 0x00003F }, { opt_ACy, 0x00C000 }}},
|
|
{ 0x100100, 0xFE0F00, 3, TMS320C55_or1, {{ op_ACx, 0x003000 }, { shl_SHIFTW, 0x00003F }, { opt_ACy, 0x00C000 }}},
|
|
{ 0x100200, 0xFE0F00, 3, TMS320C55_xor1, {{ op_ACx, 0x003000 }, { shl_SHIFTW, 0x00003F }, { opt_ACy, 0x00C000 }}},
|
|
{ 0x100300, 0xFE0F00, 3, TMS320C55_add2, {{ op_ACx, 0x003000 }, { shl_SHIFTW, 0x00003F }, { op_ACy, 0x00C000 }}},
|
|
{ 0x100400, 0xFE0F00, 3, TMS320C55_sub2, {{ op_ACx, 0x003000 }, { shl_SHIFTW, 0x00003F }, { op_ACy, 0x00C000 }}},
|
|
{ 0x100500, 0xFE0F00, 3, TMS320C55_sfts2, {{ op_ACx, 0x003000 }, { op_SHIFTW, 0x00003F }, { opt_ACy, 0x00C000 }}},
|
|
{ 0x100600, 0xFE0F00, 3, TMS320C55_sftsc2, {{ op_ACx, 0x003000 }, { op_SHIFTW, 0x00003F }, { opt_ACy, 0x00C000 }}}, // SFTA
|
|
{ 0x100700, 0xFE0F00, 3, TMS320C55_sftl2, {{ op_ACx, 0x003000 }, { op_SHIFTW, 0x00003F }, { opt_ACy, 0x00C000 }}},
|
|
{ 0x100800, 0xFE0F00, 3, TMS320C55_exp, {{ op_ACx, 0x003000 }, { op_Tx, 0x000030 }}},
|
|
{ 0x100900, 0xFE0F00, 3, TMS320C55_mant_nexp, {{ op_ACx, 0x003000 }, { op_ACy, 0x00C000 }, { blt_prll, 0 }, { op_ACx, 0x003000 }, { op_Tx, 0x000030 }}},
|
|
{ 0x100A00, 0xFE0F00, 3, TMS320C55_bcnt, {{ op_ACx, 0x003000 }, { op_ACy, 0x0000C0 }, { op_TCx, 0x000001 }, { op_Tx, 0x000030 }}},
|
|
{ 0x100C00, 0xFE0F00, 3, TMS320C55_maxdiff, {{ op_ACx, 0x003000 }, { op_ACy, 0x0000C0 }, { op_ACz, 0x00C000 }, { op_ACw, 0x000030 }}},
|
|
{ 0x100D00, 0xFE0F00, 3, TMS320C55_dmaxdiff, {{ op_ACx, 0x003000 }, { op_ACy, 0x0000C0 }, { op_ACz, 0x00C000 }, { op_ACw, 0x000030 }, { op_TRNx, 0x000001 }}},
|
|
{ 0x100E00, 0xFE0F00, 3, TMS320C55_mindiff, {{ op_ACx, 0x003000 }, { op_ACy, 0x0000C0 }, { op_ACz, 0x00C000 }, { op_ACw, 0x000030 }}},
|
|
{ 0x100F00, 0xFE0F00, 3, TMS320C55_dmindiff, {{ op_ACx, 0x003000 }, { op_ACy, 0x0000C0 }, { op_ACz, 0x00C000 }, { op_ACw, 0x000030 }, { op_TRNx, 0x000001 }}},
|
|
{ 0x120000, 0xFE0300, 3, TMS320C55_cmp, {{ insn_1_U, 0x000004 }, { op_src, 0x00F000 }, { RELOP, 0x000C00 }, { RELOP_dst, 0x0000F0 }, { op_TCx, 0x000001 }}},
|
|
{ 0x120100, 0xFE0308, 3, TMS320C55_cmpand, {{ insn_1_U, 0x000004 }, { op_src, 0x00F000 }, { RELOP, 0x000C00 }, { RELOP_dst, 0x0000F0 }, { op_TCy, 0x000002 }, { op_TCx, 0x000001 }}},
|
|
{ 0x120108, 0xFE0308, 3, TMS320C55_cmpand, {{ insn_1_U, 0x000004 }, { op_src, 0x00F000 }, { RELOP, 0x000C00 }, { RELOP_dst, 0x0000F0 }, { op_TCy, 0x000002 }, { fn_not, OP_TRUE }, { op_TCx, 0x000001 }}},
|
|
{ 0x120200, 0xFE0308, 3, TMS320C55_cmpor, {{ insn_1_U, OP_NOT(0x000004) }, { op_src, 0x00F000 }, { RELOP, 0x000C00 }, { RELOP_dst, 0x0000F0 }, { op_TCy, 0x000002 }, { op_TCx, 0x000001 }}},
|
|
{ 0x120208, 0xFE0308, 3, TMS320C55_cmpor, {{ insn_1_U, OP_NOT(0x000004) }, { op_src, 0x00F000 }, { RELOP, 0x000C00 }, { RELOP_dst, 0x0000F0 }, { op_TCy, 0x000002 }, { fn_not, OP_TRUE }, { op_TCx, 0x000001 }}},
|
|
{ 0x120300, 0xFE0308, 3, TMS320C55_rol, {{ op_BitOut, 0x000001 }, { op_src, 0x00F000 }, { op_BitIn, 0x000002 }, { op_dst, 0x0000F0 }}},
|
|
{ 0x120308, 0xFE0308, 3, TMS320C55_ror, {{ op_BitIn, 0x000002 }, { op_src, 0x00F000 }, { op_BitOut, 0x000001 }, { op_dst, 0x0000F0 }}},
|
|
{ 0x140000, 0xFE000F, 3, TMS320C55_aadd, {{ op_TAx, 0x00F000 }, { op_TAy, 0x0000F0 }}},
|
|
{ 0x140001, 0xFE000F, 3, TMS320C55_amov, {{ op_TAx, 0x00F000 }, { op_TAy, 0x0000F0 }}},
|
|
{ 0x140002, 0xFE000F, 3, TMS320C55_asub, {{ op_TAx, 0x00F000 }, { op_TAy, 0x0000F0 }}},
|
|
{ 0x140004, 0xFE000F, 3, TMS320C55_aadd, {{ op_k8, 0x00FF00 }, { op_TAx, 0x0000F0 }}},
|
|
{ 0x140005, 0xFE000F, 3, TMS320C55_amov, {{ op_k8, 0x00FF00 }, { op_TAx, 0x0000F0 }}},
|
|
{ 0x140006, 0xFE000F, 3, TMS320C55_asub, {{ op_k8, 0x00FF00 }, { op_TAx, 0x0000F0 }}},
|
|
{ 0x140008, 0xFE000F, 3, TMS320C55_aadd, {{ op_TAx, 0x00F000 }, { op_TAy, 0x0000F0 }}},
|
|
{ 0x140009, 0xFE000F, 3, TMS320C55_amov, {{ op_TAx, 0x00F000 }, { op_TAy, 0x0000F0 }}},
|
|
{ 0x14000A, 0xFE000F, 3, TMS320C55_asub, {{ op_TAx, 0x00F000 }, { op_TAy, 0x0000F0 }}},
|
|
{ 0x14000C, 0xFE000F, 3, TMS320C55_aadd, {{ op_k8, 0x00FF00 }, { op_TAx, 0x0000F0 }}},
|
|
{ 0x14000D, 0xFE000F, 3, TMS320C55_amov, {{ op_k8, 0x00FF00 }, { op_TAx, 0x0000F0 }}},
|
|
{ 0x14000E, 0xFE000F, 3, TMS320C55_asub, {{ op_k8, 0x00FF00 }, { op_TAx, 0x0000F0 }}},
|
|
{ 0x160000, 0xFE000F, 3, TMS320C55_mov2, {{ op_k7, 0x0007F0 }, { op_DPH, 0 }}},
|
|
{ 0x160001, 0xFE000F, 3, TMS320C55_mov2, {{ op_k7, 0x0007F0 }, { op_MDP05, 0 }}},
|
|
{ 0x160002, 0xFE000F, 3, TMS320C55_mov2, {{ op_k7, 0x0007F0 }, { op_MDP67, 0 }}},
|
|
{ 0x160003, 0xFE000F, 3, TMS320C55_mov2, {{ op_k9, 0x001FF0 }, { op_PDP, 0 }}},
|
|
{ 0x160004, 0xFE000F, 3, TMS320C55_mov2, {{ op_k12, 0x00FFF0 }, { op_BK03, 0 }}},
|
|
{ 0x160005, 0xFE000F, 3, TMS320C55_mov2, {{ op_k12, 0x00FFF0 }, { op_BK47, 0 }}},
|
|
{ 0x160006, 0xFE000F, 3, TMS320C55_mov2, {{ op_k12, 0x00FFF0 }, { op_BKC, 0 }}},
|
|
{ 0x160008, 0xFE000F, 3, TMS320C55_mov2, {{ op_k12, 0x00FFF0 }, { op_CSR, 0 }}},
|
|
{ 0x160009, 0xFE000F, 3, TMS320C55_mov2, {{ op_k12, 0x00FFF0 }, { op_BRC0, 0 }}},
|
|
{ 0x16000A, 0xFE000F, 3, TMS320C55_mov2, {{ op_k12, 0x00FFF0 }, { op_BRC1, 0 }}},
|
|
// 0001011E xxxxxxxk kkkk11xx error manual
|
|
{ 0x180000, 0xFE0000, 3, TMS320C55_and3, {{ op_k8, 0x00FF00 }, { op_src, 0x00000F }, { op_dst, 0x0000F0 }}},
|
|
{ 0x1A0000, 0xFE0000, 3, TMS320C55_or3, {{ op_k8, 0x00FF00 }, { op_src, 0x00000F }, { op_dst, 0x0000F0 }}},
|
|
{ 0x1C0000, 0xFE0000, 3, TMS320C55_xor3, {{ op_k8, 0x00FF00 }, { op_src, 0x00000F }, { op_dst, 0x0000F0 }}},
|
|
{ 0x1E0000, 0xFE0002, 3, TMS320C55_mpyk2, {{ insn_1_R, 0x000001 }, { op_K8, 0x00FF00 }, { op_ACx, 0x0000C0 }, { opt_ACy, 0x000030 }}},
|
|
{ 0x1E0002, 0xFE0002, 3, TMS320C55_mack3, {{ insn_1_R, 0x000001 }, { op_Tx, 0x00000C }, { op_K8, 0x00FF00 }, { op_ACx, 0x0000C0 }, { opt_ACy, 0x000030 }}},
|
|
{ 0x20, 0xFE, 1, TMS320C55_nop },
|
|
{ 0x2200, 0xFE00, 2, TMS320C55_mov2, {{ op_src, 0x00F0 }, { op_dst, 0x000F }}},
|
|
{ 0x2400, 0xFE00, 2, TMS320C55_add1, {{ op_src, 0x00F0 }, { opt_dst, 0x000F }}},
|
|
{ 0x2600, 0xFE00, 2, TMS320C55_sub1, {{ op_src, 0x00F0 }, { opt_dst, 0x000F }}},
|
|
{ 0x2800, 0xFE00, 2, TMS320C55_and2, {{ op_src, 0x00F0 }, { op_dst, 0x000F }}},
|
|
{ 0x2A00, 0xFE00, 2, TMS320C55_or2, {{ op_src, 0x00F0 }, { op_dst, 0x000F }}},
|
|
{ 0x2C00, 0xFE00, 2, TMS320C55_xor2, {{ op_src, 0x00F0 }, { op_dst, 0x000F }}},
|
|
{ 0x2E00, 0xFE00, 2, TMS320C55_max1, {{ op_src, 0x00F0 }, { op_dst, 0x000F }}},
|
|
{ 0x3000, 0xFE00, 2, TMS320C55_min1, {{ op_src, 0x00F0 }, { op_dst, 0x000F }}},
|
|
{ 0x3200, 0xFE00, 2, TMS320C55_abs1, {{ op_src, 0x00F0 }, { opt_dst, 0x000F }}},
|
|
{ 0x3400, 0xFE00, 2, TMS320C55_neg1, {{ op_src, 0x00F0 }, { opt_dst, 0x000F }}},
|
|
{ 0x3600, 0xFE00, 2, TMS320C55_not1, {{ op_src, 0x00F0 }, { opt_dst, 0x000F }}},
|
|
{ 0x3800, 0xFE00, 2, TMS320C55_psh2, {{ op_src, 0x00F0 }, { op_dst, 0x000F }}},
|
|
{ 0x3A00, 0xFE00, 2, TMS320C55_pop2, {{ op_src, 0x00F0 }, { op_dst, 0x000F }}},
|
|
{ 0x3C00, 0xFE00, 2, TMS320C55_mov2, {{ op_k4, 0x00F0 }, { op_dst, 0x000F }}},
|
|
{ 0x3E00, 0xFE00, 2, TMS320C55_mov2, {{ op_min_k4, 0x00F0 }, { op_dst, 0x000F }}},
|
|
{ 0x4000, 0xFE00, 2, TMS320C55_add2, {{ op_k4, 0x00F0 }, { op_dst, 0x000F }}},
|
|
{ 0x4200, 0xFE00, 2, TMS320C55_sub2, {{ op_k4, 0x00F0 }, { op_dst, 0x000F }}},
|
|
{ 0x4400, 0xFEC0, 2, TMS320C55_mov2, {{ op_ACx, 0x0030 }, { fn_hi, OP_TRUE }, { op_TAx, 0x000F }}},
|
|
{ 0x4440, 0xFED0, 2, TMS320C55_sfts2, {{ op_dst, 0x000F }, { op_min_1, 0 }}},
|
|
{ 0x4450, 0xFED0, 2, TMS320C55_sfts2, {{ op_dst, 0x000F }, { op_1, 0 }}},
|
|
{ 0x4480, 0xFEF0, 2, TMS320C55_mov2, {{ op_SP, 0 }, { op_TAx, 0x000F }}},
|
|
{ 0x4490, 0xFEF0, 2, TMS320C55_mov2, {{ op_SSP, 0 }, { op_TAx, 0x000F }}},
|
|
{ 0x44A0, 0xFEF0, 2, TMS320C55_mov2, {{ op_CDP, 0 }, { op_TAx, 0x000F }}},
|
|
{ 0x44C0, 0xFEF0, 2, TMS320C55_mov2, {{ op_BRC0, 0 }, { op_TAx, 0x000F }}},
|
|
{ 0x44D0, 0xFEF0, 2, TMS320C55_mov2, {{ op_BRC1, 0 }, { op_TAx, 0x000F }}},
|
|
{ 0x44E0, 0xFEF0, 2, TMS320C55_mov2, {{ op_RPTC, 0 }, { op_TAx, 0x000F }}},
|
|
{ 0x4600, 0xFE09, 2, TMS320C55_bclr2, {{ op_k4, 0x00F0 }, { op_STx_55, 0x0006 }}},
|
|
{ 0x4601, 0xFE09, 2, TMS320C55_bset2, {{ op_k4, 0x00F0 }, { op_STx_55, 0x0006 }}},
|
|
// 0100011E xxxx1000 error manual
|
|
// 0100011E xxxx1001 error manual
|
|
// 0100011E xxxx1010 error manual
|
|
// 0100011E xxxx1100 error manual
|
|
{ 0x4800, 0xFE07, 2, TMS320C55_rpt, {{ op_CSR, 0 }}},
|
|
{ 0x4801, 0xFE07, 2, TMS320C55_rptadd, {{ op_CSR, 0 }, { op_TAx, 0x00F0 }}},
|
|
{ 0x4802, 0xFE07, 2, TMS320C55_rptadd, {{ op_CSR, 0 }, { op_k4, 0x00F0 }}},
|
|
{ 0x4803, 0xFE07, 2, TMS320C55_rptsub, {{ op_CSR, 0 }, { op_k4, 0x00F0 }}},
|
|
{ 0x4804, 0xFE07, 2, TMS320C55_ret },
|
|
{ 0x4805, 0xFE07, 2, TMS320C55_reti },
|
|
{ 0x4A00, 0xFE80, 2, TMS320C55_b, {{ op_L7, 0x007F }}},
|
|
{ 0x4A80, 0xFE80, 2, TMS320C55_rptblocal, {{ op_pmad, 0x007F }}},
|
|
{ 0x4C00, 0xFE00, 2, TMS320C55_rpt, {{ op_k8, 0x00FF }}},
|
|
{ 0x4E00, 0xFE00, 2, TMS320C55_aadd, {{ op_K8, 0x00FF }, { op_SP, 0 }}},
|
|
{ 0x5000, 0xFE07, 2, TMS320C55_sftl2, {{ op_dst, 0x00F0 }, { op_1, 0 }}},
|
|
{ 0x5001, 0xFE07, 2, TMS320C55_sftl2, {{ op_dst, 0x00F0 }, { op_min_1, 0 }}},
|
|
{ 0x5002, 0xFE07, 2, TMS320C55_pop1, {{ op_dst, 0x00F0 }}},
|
|
{ 0x5003, 0xFE07, 2, TMS320C55_pop1, {{ op_ACx, 0x0030 }, { fn_dbl, OP_TRUE }}},
|
|
{ 0x5004, 0xFE07, 2, TMS320C55_popboth, {{ op_xsrc, 0x00F0 }}}, // not in documentation
|
|
{ 0x5005, 0xFE07, 2, TMS320C55_pshboth, {{ op_xsrc, 0x00F0 }}}, // not in documentation
|
|
{ 0x5006, 0xFE07, 2, TMS320C55_psh1, {{ op_dst, 0x00F0 }}},
|
|
{ 0x5007, 0xFE07, 2, TMS320C55_psh1, {{ op_ACx, 0x0030 }, { fn_dbl, OP_TRUE }}},
|
|
{ 0x5200, 0xFE0C, 2, TMS320C55_mov2, {{ op_TAx, 0x00F0 }, { op_ACx, 0x0003 }, { fn_hi, OP_TRUE }}},
|
|
{ 0x5208, 0xFE0F, 2, TMS320C55_mov2, {{ op_TAx, 0x00F0 }, { op_SP, 0 }}},
|
|
{ 0x5209, 0xFE0F, 2, TMS320C55_mov2, {{ op_TAx, 0x00F0 }, { op_SSP, 0 }}},
|
|
{ 0x520A, 0xFE0F, 2, TMS320C55_mov2, {{ op_TAx, 0x00F0 }, { op_CDP, 0 }}},
|
|
{ 0x520C, 0xFE0F, 2, TMS320C55_mov2, {{ op_TAx, 0x00F0 }, { op_CSR, 0 }}},
|
|
{ 0x520D, 0xFE0F, 2, TMS320C55_mov2, {{ op_TAx, 0x00F0 }, { op_BRC1, 0 }}},
|
|
{ 0x520E, 0xFE0F, 2, TMS320C55_mov2, {{ op_TAx, 0x00F0 }, { op_BRC0, 0 }}},
|
|
{ 0x5400, 0xFE0F, 2, TMS320C55_addv1, {{ op_ACx, 0x0030 }, { opt_ACy, 0x00C0 }}},
|
|
{ 0x5401, 0xFE0F, 2, TMS320C55_addrv1, {{ op_ACx, 0x0030 }, { opt_ACy, 0x00C0 }}},
|
|
{ 0x5402, 0xFE0E, 2, TMS320C55_sqa1, {{ insn_1_R, 0x0001 }, { op_ACx, 0x0030 }, { opt_ACy, 0x00C0 }}},
|
|
{ 0x5404, 0xFE0E, 2, TMS320C55_sqs1, {{ insn_1_R, 0x0001 }, { op_ACx, 0x0030 }, { opt_ACy, 0x00C0 }}},
|
|
{ 0x5406, 0xFE0E, 2, TMS320C55_mpy1, {{ insn_1_R, 0x0001 }, { op_ACx, 0x0030 }, { opt_ACy, 0x00C0 }}},
|
|
{ 0x5408, 0xFE0E, 2, TMS320C55_sqr1, {{ insn_1_R, 0x0001 }, { op_ACx, 0x0030 }, { opt_ACy, 0x00C0 }}},
|
|
{ 0x540A, 0xFE0E, 2, TMS320C55_round1, {{ op_ACx, 0x0030 }, { opt_ACy, 0x00C0 }}}, // error manual: unused bits
|
|
{ 0x540C, 0xFE0E, 2, TMS320C55_sat1, {{ insn_1_R, 0x0001 }, { op_ACx, 0x0030 }, { opt_ACy, 0x00C0 }}},
|
|
{ 0x5600, 0xFE02, 2, TMS320C55_mac3, {{ insn_1_R, 0x0001 }, { op_ACx, 0x0030 }, { op_Tx, 0x000C }, { opt_ACy, 0x00C0 }, { op_ACy, 0x00C0 }}},
|
|
{ 0x5602, 0xFE02, 2, TMS320C55_mas2, {{ insn_1_R, 0x0001 }, { op_Tx, 0x000C }, { op_ACx, 0x0030 }, { opt_ACy, 0x00C0 }}},
|
|
{ 0x5800, 0xFE02, 2, TMS320C55_mpy2, {{ insn_1_R, 0x0001 }, { op_Tx, 0x000C }, { op_ACx, 0x0030 }, { opt_ACy, 0x00C0 }}},
|
|
{ 0x5802, 0xFE02, 2, TMS320C55_mac4, {{ insn_1_R, 0x0001 }, { op_ACy, 0x00C0 }, { op_Tx, 0x000C }, { op_ACx, 0x0030 }, { op_ACy, 0x00C0 }}},
|
|
{ 0x5A00, 0xFE03, 2, TMS320C55_add2, {{ op_ACx, 0x0030 }, { shl_Tx, 0x000C }, { op_ACy, 0x00C0 }}},
|
|
{ 0x5A01, 0xFE03, 2, TMS320C55_sub2, {{ op_ACx, 0x0030 }, { shl_Tx, 0x000C }, { op_ACy, 0x00C0 }}},
|
|
{ 0x5A02, 0xFE02, 2, TMS320C55_sftcc, {{ op_ACx, 0x00C0 }, { op_TCx, 0x0001 }}},
|
|
{ 0x5C00, 0xFE03, 2, TMS320C55_sftl2, {{ op_ACx, 0x0030 }, { op_Tx, 0x000C }, { opt_ACy, 0x00C0 }}},
|
|
{ 0x5C01, 0xFE03, 2, TMS320C55_sfts2, {{ op_ACx, 0x0030 }, { op_Tx, 0x000C }, { opt_ACy, 0x00C0 }}},
|
|
{ 0x5C02, 0xFE03, 2, TMS320C55_sftsc2, {{ op_ACx, 0x0030 }, { op_Tx, 0x000C }, { opt_ACy, 0x00C0 }}},
|
|
{ 0x5E00, 0xFEC0, 2, TMS320C55_swap, {{ op_swap, 0x003F }}},
|
|
{ 0x5E80, 0xFEC0, 2, TMS320C55_nop_16 },
|
|
{ 0x6000, 0xF800, 2, TMS320C55_bcc, {{ op_l4, 0x0780 }, { op_cond, 0x007F }}},
|
|
{ 0x6800, 0xFF00, 2, TMS320C55_bcc, {{ op_P24, 0 }, { op_cond, 0x007F }}}, // compiler bug
|
|
{ 0x6900, 0xFF00, 2, TMS320C55_callcc, {{ op_P24, 0 }, { op_cond, 0x007F }}},
|
|
{ 0x6A, 0xFF, 1, TMS320C55_b, {{ op_P24, 0 }}},
|
|
{ 0x6C, 0xFF, 1, TMS320C55_call, {{ op_P24, 0 }}},
|
|
{ 0x6D000000, 0xFF000000, 4, TMS320C55_bcc, {{ op_L16, 0x0000FFFF }, { op_cond, 0x007F0000 }}},
|
|
{ 0x6E000000, 0xFF000000, 4, TMS320C55_callcc, {{ op_L16, 0x0000FFFF }, { op_cond, 0x007F0000 }}},
|
|
{ 0x6F000000, 0xFF000000, 4, TMS320C55_bcc, {{ insn_1_U, 0x00010000 }, { op_L8, 0x000000FF }, { op_src, 0x00F00000 }, { RELOP, 0x000C0000 }, { RELOP_K8, 0x0000FF00 }}},
|
|
{ 0x70000000, 0xFF000000, 4, TMS320C55_add2, {{ op_K16, 0x00FFFF00 }, { shl_SHFT, 0x0000000F }, { op_ACx, 0x000000C0 }, { opt_ACy, 0x00000030 }}},
|
|
{ 0x71000000, 0xFF000000, 4, TMS320C55_sub2, {{ op_K16, 0x00FFFF00 }, { shl_SHFT, 0x0000000F }, { op_ACx, 0x000000C0 }, { opt_ACy, 0x00000030 }}},
|
|
{ 0x72000000, 0xFF000000, 4, TMS320C55_and2, {{ op_k16, 0x00FFFF00 }, { shl_SHFT, 0x0000000F }, { op_ACx, 0x000000C0 }, { opt_ACy, 0x00000030 }}},
|
|
{ 0x73000000, 0xFF000000, 4, TMS320C55_or2, {{ op_k16, 0x00FFFF00 }, { shl_SHFT, 0x0000000F }, { op_ACx, 0x000000C0 }, { opt_ACy, 0x00000030 }}},
|
|
{ 0x74000000, 0xFF000000, 4, TMS320C55_xor2, {{ op_k16, 0x00FFFF00 }, { shl_SHFT, 0x0000000F }, { op_ACx, 0x000000C0 }, { opt_ACy, 0x00000030 }}},
|
|
{ 0x75000000, 0xFF000000, 4, TMS320C55_mov2, {{ op_K16, 0x00FFFF00 }, { shl_SHFT, 0x0000000F }, { op_ACx, 0x00000030 }}},
|
|
{ 0x76000000, 0xFF00000C, 4, TMS320C55_bfxtr, {{ op_k16, 0x00FFFF00 }, { op_ACx, 0x00000003 }, { op_dst, 0x000000F0 }}},
|
|
{ 0x76000004, 0xFF00000C, 4, TMS320C55_bfxpa, {{ op_k16, 0x00FFFF00 }, { op_ACx, 0x00000003 }, { op_dst, 0x000000F0 }}},
|
|
{ 0x76000008, 0xFF00000C, 4, TMS320C55_mov2, {{ op_K16, 0x00FFFF00 }, { op_dst, 0x000000F0 }}},
|
|
{ 0x77000000, 0xFF000000, 4, TMS320C55_amov, {{ op_D16, 0x00FFFF00 }, { op_TAx, 0x000000F0 }}},
|
|
{ 0x78000000, 0xFF00001E, 4, TMS320C55_mov2, {{ op_k16, 0x00FFFF00 }, { op_DP, 0 }}},
|
|
{ 0x78000002, 0xFF00001E, 4, TMS320C55_mov2, {{ op_k16, 0x00FFFF00 }, { op_SSP, 0 }}},
|
|
{ 0x78000004, 0xFF00001E, 4, TMS320C55_mov2, {{ op_k16, 0x00FFFF00 }, { op_CDP, 0 }}},
|
|
{ 0x78000006, 0xFF00001E, 4, TMS320C55_mov2, {{ op_k16, 0x00FFFF00 }, { op_BSA01, 0 }}},
|
|
{ 0x78000008, 0xFF00001E, 4, TMS320C55_mov2, {{ op_k16, 0x00FFFF00 }, { op_BSA23, 0 }}},
|
|
{ 0x7800000A, 0xFF00001E, 4, TMS320C55_mov2, {{ op_k16, 0x00FFFF00 }, { op_BSA45, 0 }}},
|
|
{ 0x7800000C, 0xFF00001E, 4, TMS320C55_mov2, {{ op_k16, 0x00FFFF00 }, { op_BSA67, 0 }}},
|
|
{ 0x7800000E, 0xFF00001E, 4, TMS320C55_mov2, {{ op_k16, 0x00FFFF00 }, { op_BSAC, 0 }}},
|
|
{ 0x78000010, 0xFF00001E, 4, TMS320C55_mov2, {{ op_k16, 0x00FFFF00 }, { op_SP, 0 }}},
|
|
{ 0x79000000, 0xFF000002, 4, TMS320C55_mpyk2, {{ insn_1_R, 0x00000001 }, { op_K16, 0x00FFFF00 }, { op_ACx, 0x000000C0 }, { opt_ACy, 0x00000030 }}},
|
|
{ 0x79000002, 0xFF000002, 4, TMS320C55_mack3, {{ insn_1_R, 0x00000001 }, { op_Tx, 0x0000000C }, { op_K16, 0x00FFFF00 }, { op_ACx, 0x000000C0 }, { opt_ACy, 0x00000030 }}},
|
|
{ 0x7A000000, 0xFF00000E, 4, TMS320C55_add2, {{ op_K16, 0x00FFFF00 }, { shl_16, 0, }, { op_ACx, 0x000000C0 }, { opt_ACy, 0x00000030 }}},
|
|
{ 0x7A000002, 0xFF00000E, 4, TMS320C55_sub2, {{ op_K16, 0x00FFFF00 }, { shl_16, 0, }, { op_ACx, 0x000000C0 }, { opt_ACy, 0x00000030 }}},
|
|
{ 0x7A000004, 0xFF00000E, 4, TMS320C55_and2, {{ op_k16, 0x00FFFF00 }, { shl_16, 0, }, { op_ACx, 0x000000C0 }, { opt_ACy, 0x00000030 }}},
|
|
{ 0x7A000006, 0xFF00000E, 4, TMS320C55_or2, {{ op_k16, 0x00FFFF00 }, { shl_16, 0, }, { op_ACx, 0x000000C0 }, { opt_ACy, 0x00000030 }}},
|
|
{ 0x7A000008, 0xFF00000E, 4, TMS320C55_xor2, {{ op_k16, 0x00FFFF00 }, { shl_16, 0, }, { op_ACx, 0x000000C0 }, { opt_ACy, 0x00000030 }}},
|
|
{ 0x7A00000A, 0xFF00000E, 4, TMS320C55_mov2, {{ op_K16, 0x00FFFF00 }, { shl_16, 0, }, { op_ACx, 0x00000030 }}},
|
|
{ 0x7A00000C, 0xFF00000E, 4, TMS320C55_idle },
|
|
{ 0x7B000000, 0xFF000000, 4, TMS320C55_add2, {{ op_K16, 0x00FFFF00 }, { op_src, 0x0000000F }, { opt_dst, 0x000000F0 }}},
|
|
{ 0x7C000000, 0xFF000000, 4, TMS320C55_sub2, {{ op_K16, 0x00FFFF00 }, { op_src, 0x0000000F }, { opt_dst, 0x000000F0 }}},
|
|
{ 0x7D000000, 0xFF000000, 4, TMS320C55_and2, {{ op_k16, 0x00FFFF00 }, { op_src, 0x0000000F }, { op_dst, 0x000000F0 }}},
|
|
{ 0x7E000000, 0xFF000000, 4, TMS320C55_or2, {{ op_k16, 0x00FFFF00 }, { op_src, 0x0000000F }, { op_dst, 0x000000F0 }}},
|
|
{ 0x7F000000, 0xFF000000, 4, TMS320C55_xor2, {{ op_k16, 0x00FFFF00 }, { op_src, 0x0000000F }, { op_dst, 0x000000F0 }}},
|
|
{ 0x800000, 0xFF000C, 3, TMS320C55_mov2, {{ op_Xmem, 0x00FC00 }, { fn_dbl, OP_TRUE, }, { op_Ymem, 0x0003F0 }, { fn_dbl, OP_TRUE }}},
|
|
{ 0x800004, 0xFF000C, 3, TMS320C55_mov2, {{ op_Xmem, 0x00FC00 }, { op_Ymem, 0x0003F0 }}},
|
|
{ 0x800008, 0xFF000C, 3, TMS320C55_mov3, {{ op_ACx, 0x000003 }, { op_Xmem, 0x00FC00, }, { op_Ymem, 0x0003F0 }}},
|
|
{ 0x810000, 0xFF000C, 3, TMS320C55_add3, {{ op_Xmem, 0x00FC00 }, { op_Ymem, 0x0003F0, }, { op_ACx, 0x000003 }}},
|
|
{ 0x810004, 0xFF000C, 3, TMS320C55_sub3, {{ op_Xmem, 0x00FC00 }, { op_Ymem, 0x0003F0, }, { op_ACx, 0x000003 }}},
|
|
{ 0x810008, 0xFF000C, 3, TMS320C55_mov3, {{ op_Xmem, 0x00FC00 }, { op_Ymem, 0x0003F0, }, { op_ACx, 0x000003 }}},
|
|
{ 0x82000000, 0xFF000C00, 4, TMS320C55_mpy_mpy, {{ insn_1_R_2_R, 0x00000001 }, { insn_1_40_2_40, 0x00000002 }, { op_Xmem, 0x00FC0000 }, { fn_uns, 0x00000080 }, { op_Cmem, 0x00000300 }, { fn_uns, 0x00000040 }, { op_ACx, 0x00000030 }, { blt_prll, 0 }, { op_Ymem, 0x0003F000 }, { fn_uns, 0x00000080 }, { op_Cmem, 0x00000300 }, { fn_uns, 0x00000040 }, { op_ACy, 0x0000000C }}},
|
|
{ 0x82000400, 0xFF000C00, 4, TMS320C55_mac_mpy, {{ insn_1_R_2_R, 0x00000001 }, { insn_1_40_2_40, 0x00000002 }, { op_Xmem, 0x00FC0000 }, { fn_uns, 0x00000080 }, { op_Cmem, 0x00000300 }, { fn_uns, 0x00000040 }, { op_ACx, 0x00000030 }, { blt_prll, 0 }, { op_Ymem, 0x0003F000 }, { fn_uns, 0x00000080 }, { op_Cmem, 0x00000300 }, { fn_uns, 0x00000040 }, { op_ACy, 0x0000000C }}},
|
|
{ 0x82000800, 0xFF000C00, 4, TMS320C55_mas_mpy, {{ insn_1_R_2_R, 0x00000001 }, { insn_1_40_2_40, 0x00000002 }, { op_Xmem, 0x00FC0000 }, { fn_uns, 0x00000080 }, { op_Cmem, 0x00000300 }, { fn_uns, 0x00000040 }, { op_ACx, 0x00000030 }, { blt_prll, 0 }, { op_Ymem, 0x0003F000 }, { fn_uns, 0x00000080 }, { op_Cmem, 0x00000300 }, { fn_uns, 0x00000040 }, { op_ACy, 0x0000000C }}},
|
|
{ 0x82000C00, 0xFF000C00, 4, TMS320C55_amar_mpy, {{ insn_1_2_R, 0x00000001 }, { insn_1_2_40, 0x00000002 }, { op_Xmem, 0x00FC0000 }, { blt_prll, 0, }, { op_Ymem, 0x0003F000 }, { fn_uns, 0x00000080 }, { op_Cmem, 0x00000300 }, { fn_uns, 0x00000040 }, { op_ACx, 0x0000000C }}},
|
|
{ 0x83000000, 0xFF000C00, 4, TMS320C55_mac_mac, {{ insn_1_R_2_R, 0x00000001 }, { insn_1_40_2_40, 0x00000002 }, { op_Xmem, 0x00FC0000 }, { fn_uns, 0x00000080 }, { op_Cmem, 0x00000300 }, { fn_uns, 0x00000040 }, { op_ACx, 0x00000030 }, { blt_prll, 0 }, { op_Ymem, 0x0003F000 }, { fn_uns, 0x00000080 }, { op_Cmem, 0x00000300 }, { fn_uns, 0x00000040 }, { op_ACy, 0x0000000C }}},
|
|
{ 0x83000400, 0xFF000C00, 4, TMS320C55_mas_mac, {{ insn_1_R_2_R, 0x00000001 }, { insn_1_40_2_40, 0x00000002 }, { op_Xmem, 0x00FC0000 }, { fn_uns, 0x00000080 }, { op_Cmem, 0x00000300 }, { fn_uns, 0x00000040 }, { op_ACx, 0x00000030 }, { blt_prll, 0 }, { op_Ymem, 0x0003F000 }, { fn_uns, 0x00000080 }, { op_Cmem, 0x00000300 }, { fn_uns, 0x00000040 }, { op_ACy, 0x0000000C }}},
|
|
{ 0x83000800, 0xFF000C00, 4, TMS320C55_mac_mac, {{ insn_1_R_2_R, 0x00000001 }, { insn_1_40_2_40, 0x00000002 }, { op_Xmem, 0x00FC0000 }, { fn_uns, 0x00000080 }, { op_Cmem, 0x00000300 }, { fn_uns, 0x00000040 }, { op_ACx, 0x00000030 }, { shr, OP_IMM(16) }, { blt_prll, 0 }, { op_Ymem, 0x0003F000 }, { fn_uns, 0x00000080 }, { op_Cmem, 0x00000300 }, { fn_uns, 0x00000040 }, { op_ACy, 0x0000000C }}},
|
|
{ 0x83000C00, 0xFF000C00, 4, TMS320C55_amar_mac, {{ insn_1_2_R, 0x00000001 }, { insn_1_2_40, 0x00000002 }, { op_Xmem, 0x00FC0000 }, { blt_prll, 0, }, { op_Ymem, 0x0003F000 }, { fn_uns, 0x00000080 }, { op_Cmem, 0x00000300 }, { fn_uns, 0x00000040 }, { op_ACx, 0x0000000C }}},
|
|
{ 0x84000000, 0xFF000C00, 4, TMS320C55_mas_mac, {{ insn_1_R_2_R, 0x00000001 }, { insn_1_40_2_40, 0x00000002 }, { op_Xmem, 0x00FC0000 }, { fn_uns, 0x00000080 }, { op_Cmem, 0x00000300 }, { fn_uns, 0x00000040 }, { op_ACx, 0x00000030 }, { blt_prll, 0 }, { op_Ymem, 0x0003F000 }, { fn_uns, 0x00000080 }, { op_Cmem, 0x00000300 }, { fn_uns, 0x00000040 }, { op_ACy, 0x0000000C }, { shr, OP_IMM(16) }}},
|
|
{ 0x84000400, 0xFF000C00, 4, TMS320C55_amar_mac, {{ insn_1_2_R, 0x00000001 }, { insn_1_2_40, 0x00000002 }, { op_Xmem, 0x00FC0000 }, { blt_prll, 0, }, { op_Ymem, 0x0003F000 }, { fn_uns, 0x00000080 }, { op_Cmem, 0x00000300 }, { fn_uns, 0x00000040 }, { op_ACx, 0x0000000C }, { shr, OP_IMM(16) }}},
|
|
{ 0x84000800, 0xFF000C00, 4, TMS320C55_mpy_mac, {{ insn_1_R_2_R, 0x00000001 }, { insn_1_40_2_40, 0x00000002 }, { op_Xmem, 0x00FC0000 }, { fn_uns, 0x00000080 }, { op_Cmem, 0x00000300 }, { fn_uns, 0x00000040 }, { op_ACx, 0x00000030 }, { blt_prll, 0 }, { op_Ymem, 0x0003F000 }, { fn_uns, 0x00000080 }, { op_Cmem, 0x00000300 }, { fn_uns, 0x00000040 }, { op_ACy, 0x0000000C }, { shr, OP_IMM(16) }}},
|
|
{ 0x84000C00, 0xFF000C00, 4, TMS320C55_mac_mac, {{ insn_1_R_2_R, 0x00000001 }, { insn_1_40_2_40, 0x00000002 }, { op_Xmem, 0x00FC0000 }, { fn_uns, 0x00000080 }, { op_Cmem, 0x00000300 }, { fn_uns, 0x00000040 }, { op_ACx, 0x00000030 }, { shr, OP_IMM(16) }, { blt_prll, 0 }, { op_Ymem, 0x0003F000 }, { fn_uns, 0x00000080 }, { op_Cmem, 0x00000300 }, { fn_uns, 0x00000040 }, { op_ACy, 0x0000000C }, { shr, OP_IMM(16) }}},
|
|
{ 0x85000000, 0xFF000C00, 4, TMS320C55_amar_mas, {{ insn_1_2_R, 0x00000001 }, { insn_1_2_40, 0x00000002 }, { op_Xmem, 0x00FC0000 }, { blt_prll, 0, }, { op_Ymem, 0x0003F000 }, { fn_uns, 0x00000080 }, { op_Cmem, 0x00000300 }, { fn_uns, 0x00000040 }, { op_ACx, 0x0000000C }}},
|
|
{ 0x85000400, 0xFF000C00, 4, TMS320C55_mas_mas, {{ insn_1_R_2_R, 0x00000001 }, { insn_1_40_2_40, 0x00000002 }, { op_Xmem, 0x00FC0000 }, { fn_uns, 0x00000080 }, { op_Cmem, 0x00000300 }, { fn_uns, 0x00000040 }, { op_ACx, 0x00000030 }, { blt_prll, 0 }, { op_Ymem, 0x0003F000 }, { fn_uns, 0x00000080 }, { op_Cmem, 0x00000300 }, { fn_uns, 0x00000040 }, { op_ACy, 0x0000000C }}},
|
|
{ 0x85000800, 0xFF000C00, 4, TMS320C55_amar3, {{ op_Xmem, 0x00FC0000 }, { op_Ymem, 0x0003F000 }, { op_Cmem, 0x00000300 }}},
|
|
{ 0x85000C00, 0xFF000C10, 4, TMS320C55_firsadd, {{ op_Xmem, 0x00FC0000 }, { op_Ymem, 0x0003F000 }, { op_Cmem, 0x00000300 }, { op_ACx, 0x000000C0 }, { op_ACy, 0x0000000C }}}, // error manual: unused bits: DDx0DDU% p552
|
|
{ 0x85000C10, 0xFF000C10, 4, TMS320C55_firssub, {{ op_Xmem, 0x00FC0000 }, { op_Ymem, 0x0003F000 }, { op_Cmem, 0x00000300 }, { op_ACx, 0x000000C0 }, { op_ACy, 0x0000000C }}}, // error manual: unused bits: DDx0DDU% p552
|
|
{ 0x86000000, 0xFF0000E0, 4, TMS320C55_mpym3, {{ insn_1_R, 0x00000001 }, { insn_1_40, 0x00000010 }, { op_Xmem, 0x00FC0000 }, { fn_uns, 0x00000008 }, { fn_T3, 0x00000002 }, { op_Ymem, 0x0003F000 }, { fn_uns, 0x00000004 }, { op_ACx, 0x00000300 }}},
|
|
{ 0x86000020, 0xFF0000E0, 4, TMS320C55_macm3, {{ insn_1_R, 0x00000001 }, { insn_1_40, 0x00000010 }, { op_Xmem, 0x00FC0000 }, { fn_uns, 0x00000008 }, { fn_T3, 0x00000002 }, { op_Ymem, 0x0003F000 }, { fn_uns, 0x00000004 }, { op_ACx, 0x00000C00 }, { opt_ACy, 0x00000300 }}},
|
|
{ 0x86000040, 0xFF0000E0, 4, TMS320C55_macm3, {{ insn_1_R, 0x00000001 }, { insn_1_40, 0x00000010 }, { op_Xmem, 0x00FC0000 }, { fn_uns, 0x00000008 }, { fn_T3, 0x00000002 }, { op_Ymem, 0x0003F000 }, { fn_uns, 0x00000004 }, { op_ACx, 0x00000C00 }, { shr, OP_IMM(16) }, { opt_ACy, 0x00000300 }}},
|
|
{ 0x86000060, 0xFF0000E0, 4, TMS320C55_masm3, {{ insn_1_R, 0x00000001 }, { insn_1_40, 0x00000010 }, { op_Xmem, 0x00FC0000 }, { fn_uns, 0x00000008 }, { fn_T3, 0x00000002 }, { op_Ymem, 0x0003F000 }, { fn_uns, 0x00000004 }, { op_ACx, 0x00000C00 }, { opt_ACy, 0x00000300 }}},
|
|
{ 0x86000080, 0xFF0000E0, 4, TMS320C55_masm_mov, {{ insn_1_R_2, 0x00000001 }, { op_Xmem, 0x00FC0000 }, { fn_T3, 0x00000002 }, { op_Tx, 0x0000000C }, { op_ACx, 0x00000C00 }, { blt_prll, 0, }, { op_Ymem, 0x0003F000 }, { shl_16, 0 }, { op_ACy, 0x00000300 }}},
|
|
{ 0x860000A0, 0xFF0000E0, 4, TMS320C55_macm_mov, {{ insn_1_R_2, 0x00000001 }, { op_Xmem, 0x00FC0000 }, { fn_T3, 0x00000002 }, { op_Tx, 0x0000000C }, { op_ACx, 0x00000C00 }, { blt_prll, 0, }, { op_Ymem, 0x0003F000 }, { shl_16, 0 }, { op_ACy, 0x00000300 }}},
|
|
{ 0x860000C0, 0xFF0000E0, 4, TMS320C55_lms, {{ op_Xmem, 0x00FC0000 }, { op_Ymem, 0x0003F000 }, { op_ACx, 0x00000C00 }, { op_ACy, 0x00000300 }}},
|
|
{ 0x860000E0, 0xFF0000F0, 4, TMS320C55_sqdst, {{ op_Xmem, 0x00FC0000 }, { op_Ymem, 0x0003F000 }, { op_ACx, 0x00000C00 }, { op_ACy, 0x00000300 }}},
|
|
{ 0x860000F0, 0xFF0000F0, 4, TMS320C55_abdst, {{ op_Xmem, 0x00FC0000 }, { op_Ymem, 0x0003F000 }, { op_ACx, 0x00000C00 }, { op_ACy, 0x00000300 }}},
|
|
{ 0x87000000, 0xFF0000E0, 4, TMS320C55_mpym_mov, {{ insn_1_R_2, 0x00000001 }, { op_Xmem, 0x00FC0000 }, { fn_T3, 0x00000002 }, { op_Tx, 0x0000000C }, { op_ACy, 0x00000300 }, { blt_prll, 0, }, { op_ACx, 0x00000C00 }, { fn_hi, OP_TRUE }, { shl_T2, 0 }, { op_Ymem, 0x0003F000 }}},
|
|
{ 0x87000020, 0xFF0000E0, 4, TMS320C55_macm_mov, {{ insn_1_R_2, 0x00000001 }, { op_Xmem, 0x00FC0000 }, { fn_T3, 0x00000002 }, { op_Tx, 0x0000000C }, { op_ACy, 0x00000300 }, { blt_prll, 0, }, { op_ACx, 0x00000C00 }, { fn_hi, OP_TRUE }, { shl_T2, 0 }, { op_Ymem, 0x0003F000 }}},
|
|
{ 0x87000040, 0xFF0000E0, 4, TMS320C55_masm_mov, {{ insn_1_R_2, 0x00000001 }, { op_Xmem, 0x00FC0000 }, { fn_T3, 0x00000002 }, { op_Tx, 0x0000000C }, { op_ACy, 0x00000300 }, { blt_prll, 0, }, { op_ACx, 0x00000C00 }, { fn_hi, OP_TRUE }, { shl_T2, 0 }, { op_Ymem, 0x0003F000 }}},
|
|
{ 0x87000080, 0xFF0000E0, 4, TMS320C55_add_mov, {{ op_Xmem, 0x00FC0000 }, { shl_16, 0, }, { op_ACx, 0x00000C00 }, { op_ACy, 0x00000300 }, { blt_prll, 0, }, { op_ACy, 0x00000300 }, { fn_hi, OP_TRUE, }, { shl_T2, 0 }, { op_Ymem, 0x0003F000 }}},
|
|
{ 0x870000A0, 0xFF0000E0, 4, TMS320C55_sub_mov, {{ op_Xmem, 0x00FC0000 }, { shl_16, 0, }, { op_ACx, 0x00000C00 }, { op_ACy, 0x00000300 }, { blt_prll, 0, }, { op_ACy, 0x00000300 }, { fn_hi, OP_TRUE, }, { shl_T2, 0 }, { op_Ymem, 0x0003F000 }}},
|
|
{ 0x870000C0, 0xFF0000E0, 4, TMS320C55_mov_mov, {{ op_Xmem, 0x00FC0000 }, { shl_16, 0, }, { op_ACy, 0x00000300 }, { blt_prll, 0, }, { op_ACx, 0x00000C00 }, { fn_hi, OP_TRUE }, { shl_T2, 0, }, { op_Ymem, 0x0003F000 }}},
|
|
{ 0x8A0000A0, 0xFF0000F0, 4, TMS320C55_mov_mov, {{ op_Xmem, 0x00FC0000 }, { op_dst, 0x00000F00 }, { blt_prll, 0, }, { op_Ymem, 0x0003F000 }, { op_dst, 0x0000000F }}},
|
|
{ make_longlong(0x00001000, 0x008A), make_longlong(0x0000F700, 0x00FF), 5, TMS320C55_mov_aadd, {{ op_Smem, 0xFF000000 }, { op_dst, 0x000F0000 }, { blt_prll, 0 }, { op_src, 0x00000000F0 }, { op_dst, 0x0000F00000 }}},
|
|
{ make_longlong(0x0000D600, 0x008A), make_longlong(0x0000FF00, 0x00FF), 5, TMS320C55_mov_add, {{ op_Xmem, 0xFC000000 }, { op_dst, 0x000F0000 }, { blt_prll, 0 }, { op_Ymem, 0x0003F00000 }, { op_dst, 0x00000000F0 }, { op_src, 0x000000000F }}},
|
|
{ make_longlong(0x0000E708, 0x008A), make_longlong(0x0000FF0C, 0x00FF), 5, TMS320C55_mov_mov, {{ op_Xmem, 0xFC000000 }, { op_dst, 0x000F0000 }, { blt_prll, 0 }, { op_ACx, 0x00000000C0 }, { shl_Tx, 0x0000000030 }, { fn_hi, OP_TRUE_5 }, { fn_rnd, 0x0000000001 }, { op_Ymem, 0x0003F00000 }}},
|
|
{ 0x8B0004B4, 0xFF000FFF, 4, TMS320C55_amar_amar, {{ op_Xmem, 0x00FC0000 }, { blt_prll, 0, }, { op_Ymem, 0x0003F000 }}},
|
|
{ make_longlong(0x00001400, 0x008C), make_longlong(0x0000F700, 0x00FF), 5, TMS320C55_mov_aadd, {{ op_src, 0x000F0000 }, { op_Smem, 0xFF000000 }, { blt_prll, 0 }, { op_k8, 0x00000000FF }, { op_dst, 0x0000F00000 }}},
|
|
{ make_longlong(0x000CB000, 0x008D), make_longlong(0x000FFC03, 0x00FF), 5, TMS320C55_btst_mov, {{ op_k4, 0x000000F0 }, { op_Xmem, 0xFC000000 }, { op_TCx, 0x00000001 }, { blt_prll, 0 }, { op_Ymem, 0x0003F00000 }, { shl_16, 0 }, { op_ACx, 0x00000300 }}},
|
|
{ make_longlong(0x061A0000, 0x8D00), make_longlong(0x0FF70000, 0xFF00), 6, TMS320C55_add_asub, {{ op_Smem, make_longlong(0x00000000, 0x00FF) }, { op_dst, make_longlong(0x0000F000, 0x0000) }, { op_src, 0x000000000F00 }, { blt_prll, 0 }, { op_src, 0x0000000000F0 }, { op_dst, 0x0000F0000000 }}},
|
|
{ make_longlong(0x0B100500, 0x8E00), make_longlong(0x0FF70F00, 0xFF00), 6, TMS320C55_mov_aadd, {{ op_xdst, make_longlong(0x0000F000, 0x0000) }, { op_Lmem, make_longlong(0x00000000, 0x00FF) }, { fn_dbl, OP_TRUE_6 }, { blt_prll, 0 }, { op_src, 0x0000000000F0 }, { op_dst, 0x0000F0000000 }}},
|
|
{ make_longlong(0x0B160500, 0x8E00), make_longlong(0x0FF70F00, 0xFF00), 6, TMS320C55_mov_asub, {{ op_xdst, make_longlong(0x0000F000, 0x0000) }, { op_Lmem, make_longlong(0x00000000, 0x00FF) }, { fn_dbl, OP_TRUE_6 }, { blt_prll, 0 }, { op_k8, 0x0000000000FF }, { op_dst, 0x0000F0000000 }}},
|
|
{ make_longlong(0x0D100800, 0x8E00), make_longlong(0x0FF70F00, 0xFF00), 6, TMS320C55_mov_aadd, {{ op_Lmem, make_longlong(0x00000000, 0x00FF) }, { fn_dbl, OP_TRUE_6 }, { op_ACx, 0x000000003000 }, { blt_prll, 0 }, { op_src, 0x0000000000F0 }, { op_dst, 0x0000F0000000 }}},
|
|
{ make_longlong(0x0B140500, 0x8E00), make_longlong(0x0FF70F00, 0xFF00), 6, TMS320C55_mov_aadd, {{ op_xdst, make_longlong(0x0000F000, 0x0000) }, { op_Lmem, make_longlong(0x00000000, 0x00FF) }, { fn_dbl, OP_TRUE_6 }, { blt_prll, 0 }, { op_k8, 0x0000000000FF }, { op_dst, 0x0000F0000000 }}},
|
|
{ make_longlong(0x0B140800, 0x8E00), make_longlong(0x0FF70F00, 0xFF00), 6, TMS320C55_mov_aadd, {{ op_ACx, make_longlong(0x00003000, 0x0000) }, { op_Lmem, make_longlong(0x00000000, 0x00FF) }, { fn_dbl, OP_TRUE_6 }, { blt_prll, 0 }, { op_k8, 0x0000000000FF }, { op_dst, 0x0000F0000000 }}},
|
|
{ make_longlong(0x0B100800, 0x8E00), make_longlong(0x0FF70F00, 0xFF00), 6, TMS320C55_mov_aadd, {{ op_ACx, make_longlong(0x00003000, 0x0000) }, { op_Lmem, make_longlong(0x00000000, 0x00FF) }, { fn_dbl, OP_TRUE_6 }, { blt_prll, 0 }, { op_src, 0x0000000000F0 }, { op_dst, 0x0000F0000000 }}},
|
|
{ make_longlong(0x06140000, 0x8E00), make_longlong(0x0FF70000, 0xFF00), 6, TMS320C55_mov_aadd, {{ op_k8, make_longlong(0x0000FF00, 0x0000) }, { op_Lmem, make_longlong(0x00000000, 0x00FF) }, { blt_prll, 0 }, { op_k8, 0x0000000000FF }, { op_dst, 0x0000F0000000 }}},
|
|
{ make_longlong(0x0DEB080D, 0x8E00), make_longlong(0x0FFF0F0F, 0xFF00), 6, TMS320C55_mov_mov, {{ op_Xmem, make_longlong(0x00000000, 0x00FC) }, { fn_dbl, OP_TRUE_6 }, { op_ACx, 0x000000003000 }, { blt_prll, 0 }, { op_ACx, 0x000000000030 }, { shr, OP_IMM_6(1) }, { op_Ymem, make_longlong(0xF0000000, 0x0003) }, { fn_dual, OP_TRUE_6 }}},
|
|
{ make_longlong(0x0EEB040D, 0x8E00), make_longlong(0x0FFF0F0F, 0xFF00), 6, TMS320C55_sub_mov, {{ op_Xmem, make_longlong(0x00000000, 0x00FC) }, { fn_dual, OP_TRUE_6 }, { op_ACx, 0x00000000C000 }, { op_ACy, 0x000000003000 }, { blt_prll, 0 }, { op_ACx, 0x000000000030 }, { shr, OP_IMM_6(1 ) }, { op_Ymem, make_longlong(0xF0000000, 0x03) }, { fn_dual, OP_TRUE_6 }}},
|
|
{ make_longlong(0x0EEB000D, 0x8E00), make_longlong(0x0FFF0F0F, 0xFF00), 6, TMS320C55_add_mov, {{ op_Xmem, make_longlong(0x00000000, 0x00FC) }, { fn_dual, OP_TRUE_6 }, { op_ACx, 0x00000000C000 }, { op_ACy, 0x000000003000 }, { blt_prll, 0 }, { op_ACx, 0x000000000030 }, { shr, OP_IMM_6(1 ) }, { op_Ymem, make_longlong(0xF0000000, 0x03) }, { fn_dual, OP_TRUE_6 }}},
|
|
{ make_longlong(0x0EEB0408, 0x8E00), make_longlong(0x0FFF0F0F, 0xFF00), 6, TMS320C55_sub_mov, {{ op_Xmem, make_longlong(0x00000000, 0x00FC) }, { fn_dual, OP_TRUE_6 }, { op_ACx, 0x00000000C000 }, { op_ACy, 0x000000003000 }, { blt_prll, 0 }, { op_ACx, 0x000000000030 }, { op_Ymem, make_longlong(0xF0000000, 0x0003) }, { fn_dbl, OP_TRUE_6 }}},
|
|
{ make_longlong(0x0EEB0008, 0x8E00), make_longlong(0x0FFF0F0F, 0xFF00), 6, TMS320C55_add_mov, {{ op_Xmem, make_longlong(0x00000000, 0x00FC) }, { fn_dual, OP_TRUE_6 }, { op_ACx, 0x00000000C000 }, { op_ACy, 0x000000003000 }, { blt_prll, 0 }, { op_ACx, 0x000000000030 }, { op_Ymem, make_longlong(0xF0000000, 0x0003) }, { fn_dbl, OP_TRUE_6 }}},
|
|
|
|
// 10001xxx error manual
|
|
{ 0x9000, 0xFF00, 2, TMS320C55_mov2, {{op_xsrc, 0x00F0 }, {op_xdst, 0x000F}}},
|
|
{ 0x9100, 0xFF00, 2, TMS320C55_b, {{ op_ACx, 0x0003 }}},
|
|
{ 0x9200, 0xFF00, 2, TMS320C55_call, {{ op_ACx, 0x0003 }}},
|
|
{ 0x9400, 0xFF00, 2, TMS320C55_reset },
|
|
{ 0x9500, 0xFF80, 2, TMS320C55_intr, {{ op_k5, 0x001F }}},
|
|
{ 0x9580, 0xFF80, 2, TMS320C55_trap, {{ op_k5, 0x001F }}},
|
|
{ 0x9600, 0xFF80, 2, TMS320C55_xcc, {{ op_cond, 0x007F }}},
|
|
{ 0x9680, 0xFF80, 2, TMS320C55_xccpart, {{ op_cond, 0x007F }}},
|
|
// 10010111 error manual
|
|
// mmap()
|
|
// port()
|
|
// <instruction>.LR
|
|
// <instruction>.CR
|
|
{ 0x9E00, 0xFF80, 2, TMS320C55_xcc, {{ op_cond, 0x007F }, { insn_UP, 0 }}},
|
|
{ 0x9E80, 0xFF80, 2, TMS320C55_xccpart, {{ op_cond, 0x007F }}},
|
|
{ 0x9F00, 0xFF80, 2, TMS320C55_xcc, {{ op_cond, 0x007F }}},
|
|
{ 0x9F80, 0xFF80, 2, TMS320C55_xccpart, {{ op_cond, 0x007F }}},
|
|
{ 0xA000, 0xF000, 2, TMS320C55_mov2, {{ op_Smem, 0x00FF }, { op_dst, 0x0F00 }}},
|
|
{ 0xB000, 0xFC00, 2, TMS320C55_mov2, {{ op_Smem, 0x00FF }, { shl_16, 0 }, { op_ACx, 0x0300 }}},
|
|
{ 0xB400, 0xFF00, 2, TMS320C55_amar1, {{ op_Smem, 0x00FF }}},
|
|
{ 0xB500, 0xFF00, 2, TMS320C55_psh1, {{ op_Smem, 0x00FF }}},
|
|
{ 0xB600, 0xFF00, 2, TMS320C55_delay, {{ op_Smem, 0x00FF }}},
|
|
{ 0xB700, 0xFF00, 2, TMS320C55_psh1, {{ op_Lmem, 0x00FF }, { fn_dbl, OP_TRUE }}},
|
|
{ 0xB800, 0xFF00, 2, TMS320C55_pop1, {{ op_Lmem, 0x00FF }, { fn_dbl, OP_TRUE }}},
|
|
{ 0xBB00, 0xFF00, 2, TMS320C55_pop1, {{ op_Smem, 0x00FF }}},
|
|
{ 0xBC00, 0xFC00, 2, TMS320C55_mov2, {{ op_ACx, 0x0300 }, { fn_hi, OP_TRUE }, { op_Smem, 0x00FF }}},
|
|
{ 0xC000, 0xF000, 2, TMS320C55_mov2, {{ op_src, 0x0F00 }, { op_Smem, 0x00FF }}},
|
|
{ 0xD00000, 0xFF0040, 3, TMS320C55_macmz, {{ op_Smem, 0x00FF00 }, { fn_T3, 0x000080 }, { op_Cmem, 0x000003 }, { op_ACx, 0x000030 }}},
|
|
{ 0xD00040, 0xFF0040, 3, TMS320C55_macmrz, {{ op_Smem, 0x00FF00 }, { fn_T3, 0x000080 }, { op_Cmem, 0x000003 }, { op_ACx, 0x000030 }}},
|
|
{ 0xD10000, 0xFF000C, 3, TMS320C55_mpym3, {{ insn_1_R, 0x000040 }, { op_Smem, 0x00FF00 }, { fn_T3, 0x000080 }, { op_Cmem, 0x000003 }, { op_ACx, 0x000030 }}},
|
|
{ 0xD10004, 0xFF000C, 3, TMS320C55_macm3, {{ insn_1_R, 0x000040 }, { op_Smem, 0x00FF00 }, { fn_T3, 0x000080 }, { op_Cmem, 0x000003 }, { op_ACx, 0x000030 }}},
|
|
{ 0xD10008, 0xFF000C, 3, TMS320C55_masm3, {{ insn_1_R, 0x000040 }, { op_Smem, 0x00FF00 }, { fn_T3, 0x000080 }, { op_Cmem, 0x000003 }, { op_ACx, 0x000030 }}},
|
|
{ 0xD20000, 0xFF000C, 3, TMS320C55_macm2, {{ insn_1_R, 0x000040 }, { op_Smem, 0x00FF00 }, { fn_T3, 0x000080 }, { op_ACx, 0x000003 }, { opt_ACy, 0x000030 }}},
|
|
{ 0xD20004, 0xFF000C, 3, TMS320C55_masm2, {{ insn_1_R, 0x000040 }, { op_Smem, 0x00FF00 }, { fn_T3, 0x000080 }, { op_ACx, 0x000003 }, { opt_ACy, 0x000030 }}},
|
|
{ 0xD20008, 0xFF000C, 3, TMS320C55_sqam2, {{ insn_1_R, 0x000040 }, { op_Smem, 0x00FF00 }, { fn_T3, 0x000080 }, { op_ACx, 0x000003 }, { opt_ACy, 0x000030 }}},
|
|
{ 0xD2000C, 0xFF000C, 3, TMS320C55_sqsm2, {{ insn_1_R, 0x000040 }, { op_Smem, 0x00FF00 }, { fn_T3, 0x000080 }, { op_ACx, 0x000003 }, { opt_ACy, 0x000030 }}},
|
|
{ 0xD30000, 0xFF000C, 3, TMS320C55_mpym2, {{ insn_1_R, 0x000040 }, { op_Smem, 0x00FF00 }, { fn_T3, 0x000080 }, { op_ACx, 0x000003 }, { opt_ACy, 0x000030 }}},
|
|
{ 0xD30008, 0xFF000C, 3, TMS320C55_sqrm, {{ insn_1_R, 0x000040 }, { op_Smem, 0x00FF00 }, { fn_T3, 0x000080 }, { op_ACx, 0x000030 }}},
|
|
{ 0xD30004, 0xFF0004, 3, TMS320C55_mpym3, {{ insn_1_R, 0x000040 }, { insn_1_U, 0x000008 }, { op_Smem, 0x00FF00 }, { fn_T3, 0x000080 }, { op_Tx, 0x000003 }, { op_ACx, 0x000030 }}},
|
|
{ 0xD40000, 0xFF0000, 3, TMS320C55_macm3, {{ insn_1_R, 0x000040 }, { op_Smem, 0x00FF00 }, { fn_T3, 0x000080 }, { op_Tx, 0x00000C }, { op_ACx, 0x000003 }, { opt_ACy, 0x000030 }}},
|
|
{ 0xD50000, 0xFF0000, 3, TMS320C55_masm3, {{ insn_1_R, 0x000040 }, { op_Smem, 0x00FF00 }, { fn_T3, 0x000080 }, { op_Tx, 0x00000C }, { op_ACx, 0x000003 }, { opt_ACy, 0x000030 }}},
|
|
{ 0xD60000, 0xFF0000, 3, TMS320C55_add2, {{ op_Smem, 0x00FF00 }, { op_src, 0x00000F }, { opt_dst, 0x0000F0 }}},
|
|
{ 0xD70000, 0xFF0000, 3, TMS320C55_sub2, {{ op_Smem, 0x00FF00 }, { op_src, 0x00000F }, { opt_dst, 0x0000F0 }}},
|
|
{ 0xD80000, 0xFF0000, 3, TMS320C55_sub3, {{ op_src, 0x00000F }, { op_Smem, 0x00FF00 }, { op_dst, 0x0000F0 }}},
|
|
{ 0xD90000, 0xFF0000, 3, TMS320C55_and3, {{ op_Smem, 0x00FF00 }, { op_src, 0x00000F }, { op_dst, 0x0000F0 }}},
|
|
{ 0xDA0000, 0xFF0000, 3, TMS320C55_or3, {{ op_Smem, 0x00FF00 }, { op_src, 0x00000F }, { op_dst, 0x0000F0 }}},
|
|
{ 0xDB0000, 0xFF0000, 3, TMS320C55_xor3, {{ op_Smem, 0x00FF00 }, { op_src, 0x00000F }, { op_dst, 0x0000F0 }}},
|
|
{ 0xDC0000, 0xFF0002, 3, TMS320C55_btst, {{ op_k4, 0x0000F0 }, { op_Smem, 0x00FF00 }, { op_TCx, 0x000001 }}},
|
|
{ 0xDC0002, 0xFF00F3, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { op_DP, 0 }}},
|
|
{ 0xDC0012, 0xFF00F3, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { op_CDP, 0 }}},
|
|
{ 0xDC0022, 0xFF00F3, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { op_BSA01, 0 }}},
|
|
{ 0xDC0032, 0xFF00F3, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { op_BSA23, 0 }}},
|
|
{ 0xDC0042, 0xFF00F3, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { op_BSA45, 0 }}},
|
|
{ 0xDC0052, 0xFF00F3, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { op_BSA67, 0 }}},
|
|
{ 0xDC0062, 0xFF00F3, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { op_BSAC, 0 }}},
|
|
{ 0xDC0072, 0xFF00F3, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { op_SP, 0 }}},
|
|
{ 0xDC0082, 0xFF00F3, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { op_SSP, 0 }}},
|
|
{ 0xDC0092, 0xFF00F3, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { op_BK03, 0 }}},
|
|
{ 0xDC00A2, 0xFF00F3, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { op_BK47, 0 }}},
|
|
{ 0xDC00B2, 0xFF00F3, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { op_BKC, 0 }}},
|
|
{ 0xDC00C2, 0xFF00F3, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { op_DPH, 0 }}},
|
|
{ 0xDC00D2, 0xFF00F3, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { op_MDP05, 0 }}},
|
|
{ 0xDC00E2, 0xFF00F3, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { op_MDP67, 0 }}},
|
|
{ 0xDC00F2, 0xFF00F3, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { op_PDP, 0 }}},
|
|
{ 0xDC0003, 0xFF0073, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { op_CSR, 0 }}},
|
|
{ 0xDC0013, 0xFF0073, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { op_BRC0, 0 }}},
|
|
{ 0xDC0023, 0xFF0073, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { op_BRC1, 0 }}},
|
|
{ 0xDC0033, 0xFF0073, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { op_TRN0, 0 }}},
|
|
{ 0xDC0043, 0xFF0073, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { op_TRN1, 0 }}},
|
|
{ 0xDD0000, 0xFF0003, 3, TMS320C55_add2, {{ op_Smem, 0x00FF00 }, { shl_Tx, 0x00000C }, { op_ACx, 0x0000C0 }, { opt_ACy, 0x000030 }}},
|
|
{ 0xDD0001, 0xFF0003, 3, TMS320C55_sub2, {{ op_Smem, 0x00FF00 }, { shl_Tx, 0x00000C }, { op_ACx, 0x0000C0 }, { opt_ACy, 0x000030 }}},
|
|
{ 0xDD0002, 0xFF0003, 3, TMS320C55_addsub2cc, {{ op_Smem, 0x00FF00 }, { op_ACx, 0x0000C0 }, { op_Tx, 0x00000C }, { op_TC1, 0, }, { op_TC2, 0, }, { op_ACy, 0x000030 }}},
|
|
{ 0xDD0003, 0xFF0003, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { shl_Tx, 0x00000C }, { fn_rnd, 0x000040 }, { op_ACx, 0x000030 }}},
|
|
{ 0xDE0000, 0xFF000F, 3, TMS320C55_addsubcc4, {{ op_Smem, 0x00FF00 }, { op_ACx, 0x0000C0 }, { op_TC1, 0 }, { op_ACy, 0x000030 }}},
|
|
{ 0xDE0001, 0xFF000F, 3, TMS320C55_addsubcc4, {{ op_Smem, 0x00FF00 }, { op_ACx, 0x0000C0 }, { op_TC2, 0 }, { op_ACy, 0x000030 }}},
|
|
{ 0xDE0002, 0xFF000F, 3, TMS320C55_addsubcc4, {{ op_Smem, 0x00FF00 }, { op_ACx, 0x0000C0 }, { op_TC1, 0 }, { op_TC2, 0, }, { op_ACy, 0x000030 }}},
|
|
{ 0xDE0003, 0xFF000F, 3, TMS320C55_subc2, {{ op_Smem, 0x00FF00 }, { op_ACx, 0x0000C0 }, { opt_ACy, 0x000030 }}},
|
|
{ 0xDE0004, 0xFF000F, 3, TMS320C55_add2, {{ op_Smem, 0x00FF00 }, { shl_16, 0 }, { op_ACx, 0x0000C0 }, { opt_ACy, 0x000030 }}},
|
|
{ 0xDE0005, 0xFF000F, 3, TMS320C55_sub2, {{ op_Smem, 0x00FF00 }, { shl_16, 0 }, { op_ACx, 0x0000C0 }, { opt_ACy, 0x000030 }}},
|
|
{ 0xDE0006, 0xFF000F, 3, TMS320C55_sub3, {{ op_ACx, 0x0000C0 }, { op_Smem, 0x00FF00 }, { shl_16, 0 }, { op_ACy, 0x000030 }}},
|
|
{ 0xDE0008, 0xFF000F, 3, TMS320C55_addsub, {{ op_Tx, 0x0000C0 }, { op_Smem, 0x00FF00 }, { op_ACx, 0x000030 }}},
|
|
{ 0xDE0009, 0xFF000F, 3, TMS320C55_subadd, {{ op_Tx, 0x0000C0 }, { op_Smem, 0x00FF00 }, { op_ACx, 0x000030 }}},
|
|
{ 0xDF0000, 0xFF000E, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { fn_hb, OP_TRUE }, { fn_uns, OP_NOT(0x000001) }, { op_dst, 0x0000F0 }}},
|
|
{ 0xDF0002, 0xFF000E, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { fn_lb, OP_TRUE }, { fn_uns, OP_NOT(0x000001) }, { op_dst, 0x0000F0 }}},
|
|
{ 0xDF0004, 0xFF000E, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { fn_uns, 0x000001 }, { op_ACx, 0x000030 }}},
|
|
{ 0xDF0008, 0xFF000E, 3, TMS320C55_add3, {{ op_Smem, 0x00FF00 }, { fn_uns, 0x000001 }, { op_CARRY, 0 }, { op_ACx, 0x0000C0 }, { opt_ACy, 0x000030 }}},
|
|
{ 0xDF000A, 0xFF000E, 3, TMS320C55_sub3, {{ op_Smem, 0x00FF00 }, { fn_uns, 0x000001 }, { op_BORROW, 0 }, { op_ACx, 0x0000C0 }, { opt_ACy, 0x000030 }}},
|
|
{ 0xDF000C, 0xFF000E, 3, TMS320C55_add2, {{ op_Smem, 0x00FF00 }, { fn_uns, 0x000001 }, { op_ACx, 0x0000C0 }, { opt_ACy, 0x000030 }}},
|
|
{ 0xDF000E, 0xFF000E, 3, TMS320C55_sub2, {{ op_Smem, 0x00FF00 }, { fn_uns, 0x000001 }, { op_ACx, 0x0000C0 }, { opt_ACy, 0x000030 }}},
|
|
{ 0xE00000, 0xFF0000, 3, TMS320C55_btst, {{ op_src, 0x0000F0 }, { op_Smem, 0x00FF00 }, { op_TCx, 0x000001 }}},
|
|
{ 0xE10000, 0xFF0000, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { fn_lb, OP_TRUE }, { slo_SHIFTW, 0x00003F }, { op_ACx, 0x0000C0 }}},
|
|
{ 0xE20000, 0xFF0000, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { fn_hb, OP_TRUE }, { slo_SHIFTW, 0x00003F }, { op_ACx, 0x0000C0 }}},
|
|
{ 0xE30000, 0xFF000E, 3, TMS320C55_btstset, {{ op_k4, 0x0000F0 }, { op_Smem, 0x00FF00 }, { op_TC1 }}},
|
|
{ 0xE30002, 0xFF000E, 3, TMS320C55_btstset, {{ op_k4, 0x0000F0 }, { op_Smem, 0x00FF00 }, { op_TC2 }}},
|
|
{ 0xE30004, 0xFF000E, 3, TMS320C55_btstclr, {{ op_k4, 0x0000F0 }, { op_Smem, 0x00FF00 }, { op_TC1 }}},
|
|
{ 0xE30006, 0xFF000E, 3, TMS320C55_btstclr, {{ op_k4, 0x0000F0 }, { op_Smem, 0x00FF00 }, { op_TC2 }}},
|
|
{ 0xE30008, 0xFF000E, 3, TMS320C55_btstnot, {{ op_k4, 0x0000F0 }, { op_Smem, 0x00FF00 }, { op_TC1 }}},
|
|
{ 0xE3000A, 0xFF000E, 3, TMS320C55_btstnot, {{ op_k4, 0x0000F0 }, { op_Smem, 0x00FF00 }, { op_TC2 }}},
|
|
{ 0xE3000C, 0xFF000F, 3, TMS320C55_bset2, {{ op_src, 0x0000F0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE3000D, 0xFF000F, 3, TMS320C55_bclr2, {{ op_src, 0x0000F0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE3000E, 0xFF000E, 3, TMS320C55_bnot, {{ op_src, 0x0000F0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE40000, 0xFF0004, 3, TMS320C55_psh2, {{ op_src, 0x0000F0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE40004, 0xFF0004, 3, TMS320C55_pop2, {{ op_dst, 0x0000F0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE50004, 0xFF000D, 3, TMS320C55_mov2, {{ op_src, 0x0000F0 }, { op_Smem, 0x00FF00 }, { fn_hb, OP_TRUE }}},
|
|
{ 0xE50005, 0xFF000D, 3, TMS320C55_mov2, {{ op_src, 0x0000F0 }, { op_Smem, 0x00FF00 }, { fn_lb, OP_TRUE }}},
|
|
{ 0xE50008, 0xFF00FC, 3, TMS320C55_mov2, {{ op_DP, 0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE50018, 0xFF00FC, 3, TMS320C55_mov2, {{ op_CDP, 0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE50028, 0xFF00FC, 3, TMS320C55_mov2, {{ op_BSA01, 0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE50038, 0xFF00FC, 3, TMS320C55_mov2, {{ op_BSA23, 0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE50048, 0xFF00FC, 3, TMS320C55_mov2, {{ op_BSA45, 0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE50058, 0xFF00FC, 3, TMS320C55_mov2, {{ op_BSA67, 0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE50068, 0xFF00FC, 3, TMS320C55_mov2, {{ op_BSAC, 0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE50078, 0xFF00FC, 3, TMS320C55_mov2, {{ op_SP, 0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE50088, 0xFF00FC, 3, TMS320C55_mov2, {{ op_SSP, 0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE50098, 0xFF00FC, 3, TMS320C55_mov2, {{ op_BK03, 0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE500A8, 0xFF00FC, 3, TMS320C55_mov2, {{ op_BK47, 0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE500B8, 0xFF00FC, 3, TMS320C55_mov2, {{ op_BKC, 0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE500C8, 0xFF00FC, 3, TMS320C55_mov2, {{ op_DPH, 0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE500D8, 0xFF00FC, 3, TMS320C55_mov2, {{ op_MDP05, 0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE500E8, 0xFF00FC, 3, TMS320C55_mov2, {{ op_MDP67, 0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE500F8, 0xFF00FC, 3, TMS320C55_mov2, {{ op_PDP, 0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE5000C, 0xFF007C, 3, TMS320C55_mov2, {{ op_CSR, 0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE5001C, 0xFF007C, 3, TMS320C55_mov2, {{ op_BRC0, 0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE5002C, 0xFF007C, 3, TMS320C55_mov2, {{ op_BRC1, 0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE5003C, 0xFF007C, 3, TMS320C55_mov2, {{ op_TRN0, 0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE5004C, 0xFF007C, 3, TMS320C55_mov2, {{ op_TRN1, 0 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE60000, 0xFF0000, 3, TMS320C55_mov2, {{ op_K8, 0x0000FF }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE70000, 0xFF000C, 3, TMS320C55_mov2, {{ op_ACx, 0x0000C0 }, { shl_Tx, 0x000030 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE70008, 0xFF000C, 3, TMS320C55_mov2, {{ op_ACx, 0x0000C0 }, { shl_Tx, 0x000030 }, { fn_hi, OP_TRUE, }, { fn_rnd, 0x000001 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE7000C, 0xFF000C, 3, TMS320C55_mov2, {{ op_ACx, 0x0000C0 }, { shl_Tx, 0x000030 }, { fn_sat, OP_TRUE, }, { fn_hi, OP_TRUE }, { fn_rnd, 0x000001 }, { fn_uns, 0x000002 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE80000, 0xFF0004, 3, TMS320C55_mov2, {{ op_ACx, 0x0000C0 }, { fn_hi, OP_TRUE }, { fn_rnd, 0x000001 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE80004, 0xFF0004, 3, TMS320C55_mov2, {{ op_ACx, 0x0000C0 }, { fn_sat, OP_TRUE }, { fn_hi, OP_TRUE }, { fn_rnd, 0x000001 }, { fn_uns, 0x000002 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xE90000, 0xFF0000, 3, TMS320C55_mov2, {{ op_ACx, 0x0000C0 }, { shl_SHIFTW, 0x00003F }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xEA0000, 0xFF0000, 3, TMS320C55_mov2, {{ op_ACx, 0x0000C0 }, { shl_SHIFTW, 0x00003F }, { fn_hi, OP_TRUE }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xEB0004, 0xFF000D, 3, TMS320C55_mov2, {{ op_RETA, 0 }, { op_Lmem, 0x00FF00 }, { fn_dbl, OP_TRUE }}},
|
|
{ 0xEB0005, 0xFF000D, 3, TMS320C55_mov2, {{ op_xsrc, 0x0000F0 }, { op_Lmem, 0x00FF00 }, { fn_dbl, OP_TRUE }}}, // not in documentation
|
|
{ 0xEB0008, 0xFF000D, 3, TMS320C55_mov2, {{ op_ACx, 0x000030 }, { op_Lmem, 0x00FF00 }, { fn_dbl, OP_TRUE }}},
|
|
{ 0xEB0009, 0xFF000D, 3, TMS320C55_mov2, {{ op_ACx, 0x000030 }, { fn_sat, OP_TRUE }, { fn_uns, 0x000002 }, { op_Lmem, 0x00FF00 }, { fn_dbl, OP_TRUE }}},
|
|
{ 0xEB000C, 0xFF000F, 3, TMS320C55_mov2, {{ op_TAx, 0x0000F0 }, { fn_pair, OP_TRUE }, { op_Lmem, 0x00FF00 }, { fn_dbl, OP_TRUE }}},
|
|
{ 0xEB000D, 0xFF000F, 3, TMS320C55_mov2, {{ op_ACx, 0x0000F0 }, { shr, OP_IMM(1) }, { op_Lmem, 0x00FF00 }, { fn_dual, OP_TRUE }}},
|
|
{ 0xEB000E, 0xFF000F, 3, TMS320C55_mov2, {{ op_ACx, 0x0000F0 }, { fn_hi, OP_TRUE }, { fn_pair, OP_TRUE }, { op_Lmem, 0x00FF00 }, { fn_dbl, OP_TRUE }}},
|
|
{ 0xEB000F, 0xFF000F, 3, TMS320C55_mov2, {{ op_ACx, 0x0000F0 }, { fn_lo, OP_TRUE }, { fn_pair, OP_TRUE }, { op_Lmem, 0x00FF00 }, { fn_dbl, OP_TRUE }}},
|
|
{ 0xEC0000, 0xFF000E, 3, TMS320C55_bset2, {{ op_Baddr, 0x00FF00 }, { op_src, 0x0000F0 }}},
|
|
{ 0xEC0002, 0xFF000E, 3, TMS320C55_bclr2, {{ op_Baddr, 0x00FF00 }, { op_src, 0x0000F0 }}},
|
|
{ 0xEC0004, 0xFF000E, 3, TMS320C55_btstp, {{ op_Baddr, 0x00FF00 }, { op_src, 0x0000F0 }}},
|
|
{ 0xEC0006, 0xFF000E, 3, TMS320C55_bnot, {{ op_Baddr, 0x00FF00 }, { op_src, 0x0000F0 }}},
|
|
{ 0xEC0008, 0xFF000E, 3, TMS320C55_btst, {{ op_Baddr, 0x00FF00 }, { op_src, 0x0000F0 }, { op_TCx, 0x000001 }}},
|
|
{ 0xEC000E, 0xFF000F, 3, TMS320C55_amar2, {{ op_Smem, 0x00FF00 }, { op_xdst, 0x0000F0 }}},
|
|
{ 0xED0000, 0xFF000E, 3, TMS320C55_add2, {{ op_Lmem, 0x00FF00 }, { fn_dbl, OP_TRUE }, { op_ACx, 0x0000C0 }, { opt_ACy, 0x000030 }}},
|
|
{ 0xED0002, 0xFF000E, 3, TMS320C55_sub2, {{ op_Lmem, 0x00FF00 }, { fn_dbl, OP_TRUE }, { op_ACx, 0x0000C0 }, { opt_ACy, 0x000030 }}},
|
|
{ 0xED0004, 0xFF000E, 3, TMS320C55_sub3, {{ op_ACx, 0x0000C0 }, { op_Lmem, 0x00FF00 }, { fn_dbl, OP_TRUE }, { op_ACy, 0x000030 }}},
|
|
{ 0xED0006, 0xFF000E, 3, TMS320C55_mov2, {{ op_Lmem, 0x00FF00 }, { fn_dbl, OP_TRUE }, { op_RETA, 0 }}},
|
|
{ 0xED0008, 0xFF000E, 3, TMS320C55_mov2, {{ insn_1_40, 0x000001 }, { op_Lmem, 0x00FF00 }, { fn_dbl, OP_TRUE }, { op_ACx, 0x000030 }}},
|
|
{ 0xED000A, 0xFF000E, 3, TMS320C55_mov2, {{ op_Lmem, 0x00FF00 }, { fn_dbl, OP_TRUE }, { op_ACx, 0x000030 }, { fn_hi, OP_TRUE, }, { fn_pair, OP_TRUE }}},
|
|
{ 0xED000C, 0xFF000E, 3, TMS320C55_mov2, {{ op_Lmem, 0x00FF00 }, { fn_dbl, OP_TRUE }, { op_ACx, 0x000030 }, { fn_lo, OP_TRUE, }, { fn_pair, OP_TRUE }}},
|
|
{ 0xED000E, 0xFF000F, 3, TMS320C55_mov2, {{ op_Lmem, 0x00FF00 }, { fn_dbl, OP_TRUE }, { op_TAx, 0x0000F0 }, { fn_pair, OP_TRUE }}},
|
|
{ 0xED000F, 0xFF000F, 3, TMS320C55_mov2, {{ op_Lmem, 0x00FF00 }, { fn_dbl, OP_TRUE }, { op_xdst, 0x0000F0 }}},
|
|
{ 0xEE0000, 0xFF000E, 3, TMS320C55_add2, {{ op_Lmem, 0x00FF00 }, { fn_dual, OP_TRUE }, { op_ACx, 0x0000C0 }, { opt_ACy, 0x000030 }}},
|
|
{ 0xEE0002, 0xFF000E, 3, TMS320C55_sub2, {{ op_Lmem, 0x00FF00 }, { fn_dual, OP_TRUE }, { op_ACx, 0x0000C0 }, { opt_ACy, 0x000030 }}},
|
|
{ 0xEE0004, 0xFF000E, 3, TMS320C55_sub3, {{ op_Lmem, 0x00FF00 }, { fn_dual, OP_TRUE }, { op_ACx, 0x0000C0 }, { op_ACy, 0x000030 }}},
|
|
{ 0xEE0006, 0xFF000E, 3, TMS320C55_sub3, {{ op_Lmem, 0x00FF00 }, { fn_dual, OP_TRUE }, { op_Tx, 0x0000C0 }, { op_ACx, 0x000030 }}},
|
|
{ 0xEE0008, 0xFF000E, 3, TMS320C55_add3, {{ op_Lmem, 0x00FF00 }, { fn_dual, OP_TRUE }, { op_Tx, 0x0000C0 }, { op_ACx, 0x000030 }}},
|
|
{ 0xEE000A, 0xFF000E, 3, TMS320C55_sub3, {{ op_Tx, 0x0000C0 }, { op_Lmem, 0x00FF00 }, { fn_dual, OP_TRUE }, { op_ACx, 0x000030 }}},
|
|
{ 0xEE000C, 0xFF000E, 3, TMS320C55_addsub, {{ op_Tx, 0x0000C0 }, { op_Lmem, 0x00FF00 }, { fn_dual, OP_TRUE }, { op_ACx, 0x000030 }}},
|
|
{ 0xEE000E, 0xFF000E, 3, TMS320C55_subadd, {{ op_Tx, 0x0000C0 }, { op_Lmem, 0x00FF00 }, { fn_dual, OP_TRUE }, { op_ACx, 0x000030 }}},
|
|
{ 0xEF0000, 0xFF000C, 3, TMS320C55_mov2, {{ op_Cmem, 0x000003 }, { op_Smem, 0x00FF00 }}},
|
|
{ 0xEF0004, 0xFF000C, 3, TMS320C55_mov2, {{ op_Smem, 0x00FF00 }, { op_Cmem, 0x000003 }}},
|
|
{ 0xEF0008, 0xFF000C, 3, TMS320C55_mov2, {{ op_Cmem, 0x000003 }, { op_Lmem, 0x00FF00 }, { fn_dbl, OP_TRUE }}},
|
|
{ 0xEF000C, 0xFF000C, 3, TMS320C55_mov2, {{ op_Lmem, 0x00FF00 }, { fn_dbl, OP_TRUE }, { op_Cmem, 0x000003 }}},
|
|
{ 0xF0000000, 0xFF000000, 4, TMS320C55_cmp, {{ op_Smem, 0x00FF0000 }, { eq_K16, 0x0000FFFF }, { op_TC1, 0 }}},
|
|
{ 0xF1000000, 0xFF000000, 4, TMS320C55_cmp, {{ op_Smem, 0x00FF0000 }, { eq_K16, 0x0000FFFF }, { op_TC2, 0 }}},
|
|
{ 0xF2000000, 0xFF000000, 4, TMS320C55_band, {{ op_Smem, 0x00FF0000 }, { op_k16, 0x0000FFFF }, { op_TC1, 0 }}},
|
|
{ 0xF3000000, 0xFF000000, 4, TMS320C55_band, {{ op_Smem, 0x00FF0000 }, { op_k16, 0x0000FFFF }, { op_TC2, 0 }}},
|
|
{ 0xF4000000, 0xFF000000, 4, TMS320C55_and2, {{ op_k16, 0x0000FFFF }, { op_Smem, 0x00FF0000 }}},
|
|
{ 0xF5000000, 0xFF000000, 4, TMS320C55_or2, {{ op_k16, 0x0000FFFF }, { op_Smem, 0x00FF0000 }}},
|
|
{ 0xF6000000, 0xFF000000, 4, TMS320C55_xor2, {{ op_k16, 0x0000FFFF }, { op_Smem, 0x00FF0000 }}},
|
|
{ 0xF7000000, 0xFF000000, 4, TMS320C55_add2, {{ op_K16, 0x0000FFFF }, { op_Smem, 0x00FF0000 }}},
|
|
{ 0xF8000000, 0xFF000004, 4, TMS320C55_mpymk, {{ insn_1_R, 0x00000001 }, { op_Smem, 0x00FF0000 }, { fn_T3, 0x00000002 }, { op_K8, 0x0000FF00 }, { op_ACx, 0x00000030 }}},
|
|
{ 0xF8000004, 0xFF000004, 4, TMS320C55_macmk3, {{ insn_1_R, 0x00000001 }, { op_Smem, 0x00FF0000 }, { fn_T3, 0x00000002 }, { op_K8, 0x0000FF00 }, { op_ACx, 0x000000C0 }, { opt_ACy, 0x00000030 }}},
|
|
{ 0xF9000000, 0xFF00000C, 4, TMS320C55_add2, {{ op_Smem, 0x00FF0000 }, { fn_uns, 0x00008000 }, { slo_SHIFTW, 0x00003F00 }, { op_ACx, 0x000000C0 }, { opt_ACy, 0x00000030 }}},
|
|
{ 0xF9000004, 0xFF00000C, 4, TMS320C55_sub2, {{ op_Smem, 0x00FF0000 }, { fn_uns, 0x00008000 }, { slo_SHIFTW, 0x00003F00 }, { op_ACx, 0x000000C0 }, { opt_ACy, 0x00000030 }}},
|
|
{ 0xF9000008, 0xFF00000C, 4, TMS320C55_mov2, {{ op_Smem, 0x00FF0000 }, { fn_uns, 0x00008000 }, { slo_SHIFTW, 0x00003F00 }, { op_ACx, 0x00000030 }}},
|
|
{ 0xFA000000, 0xFF000004, 4, TMS320C55_mov2, {{ op_ACx, 0x000000C0 }, { shl_SHIFTW, 0x00003F00 }, { fn_hi, OP_TRUE }, { fn_rnd, 0x00000001 }, { op_Smem, 0x00FF0000 }}},
|
|
{ 0xFA000004, 0xFF000004, 4, TMS320C55_mov2, {{ op_ACx, 0x000000C0 }, { shl_SHIFTW, 0x00003F00 }, { fn_sat, OP_TRUE }, { fn_hi, OP_TRUE }, { fn_rnd, 0x00000001 }, { fn_uns, 0x00008000 }, { op_Smem, 0x00FF0000 }}},
|
|
{ 0xFB000000, 0xFF000000, 4, TMS320C55_mov2, {{ op_K16, 0x0000FFFF }, { op_Smem, 0x00FF0000 }}},
|
|
{ 0xFC000000, 0xFF000000, 4, TMS320C55_bcc, {{ op_L16, 0x0000FFFF }, { op_ARn_mod, 0x00FF0000 }, { neq_0, OP_TRUE }}},
|
|
{ 0, 0, 0, TMS320C55_null }
|
|
};
|
|
|
|
//--------------------------------------------------------------------------
|
|
// unpack an "sdual" instruction operand ( 6->8 bits )
|
|
static uchar unpack_opsdual(uchar packed)
|
|
{
|
|
static const uchar lowpart[8] = { 0, 1, 2, 3, 9, 4, 10, 5 };
|
|
return ((lowpart[packed&7] | ((packed<<1) & 0x70)) << 1) | 1;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// unpack an "sdual" instruction
|
|
// these are probably instructions from C55x+ processor
|
|
static bool unpack_sdual(ea_t ea, bytevec_t *insn1, bytevec_t *insn2)
|
|
{
|
|
// sdual instruction packs two parallel instructions
|
|
uint32 word = 0;
|
|
for ( int i=0; i < 4; i++ )
|
|
word = (word << 8) | get_byte(ea + i);
|
|
uchar opc1 = ((word >> 20) & 0xF0) | ((word >> 8) & 0x0F);
|
|
uchar opc2 = (word & 0xFF);
|
|
if ( opc2 & 0x80 )
|
|
{
|
|
// 3 | 2 | 1 |
|
|
// 1098 7654|321098 76|5432 1098|76543210
|
|
// | | |
|
|
// 1000 1011|100010 10|1001 1100|11000001
|
|
// o1h | opd1 opd2 o1l| opc2
|
|
//
|
|
// opcode1 = o1h:o1l
|
|
// opcode2 = opc2
|
|
// opd1 and opd2 are packed operand parts
|
|
|
|
uchar ops1 = (word >> 18) & 0x3F;
|
|
uchar ops2 = (word >> 12) & 0x3F;
|
|
int insn1_len = get_insn_size(masks, opc1<<24);
|
|
if ( insn1_len < 2 )
|
|
return false;
|
|
int insn2_len = get_insn_size(masks, opc2<<24);
|
|
if ( insn2_len < 2 )
|
|
{
|
|
// try to add extra bytes (skip operand byte)
|
|
uint32 w2 = (opc2<<24) | (get_byte(ea + insn1_len+2) << 8);
|
|
insn2_len = get_insn_size(masks, w2);
|
|
if ( insn2_len < 2 )
|
|
{
|
|
w2 |= get_byte(ea + insn1_len+3);
|
|
insn2_len = get_insn_size(masks, w2);
|
|
}
|
|
}
|
|
if ( insn2_len < 2 )
|
|
return false;
|
|
if ( insn1 )
|
|
{
|
|
insn1->clear();
|
|
// add real opcode and operands
|
|
insn1->push_back(opc1);
|
|
insn1->push_back(unpack_opsdual(ops1));
|
|
// add extra bytes
|
|
for ( int i=4; i < insn1_len+2; i++ )
|
|
insn1->push_back(get_byte(ea + i));
|
|
}
|
|
if ( insn2 )
|
|
{
|
|
insn2->clear();
|
|
insn2->push_back(opc2);
|
|
insn2->push_back(unpack_opsdual(ops2));
|
|
for ( int i=insn1_len+2; i < (insn1_len+insn2_len); i++ )
|
|
insn2->push_back(get_byte(ea + i));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// unpacked insn1 can be 2, 3, or 4 bytes
|
|
// insn2 is always 3 bytes
|
|
//
|
|
// source bytes: ab cd ef gh ij kl mn op
|
|
// case 2+3:
|
|
// insn1 = bf cd
|
|
// insn2 = g4 ij eh
|
|
// case 3+3:
|
|
// insn1 = bf cd ij
|
|
// insn2 = g4 kl eh
|
|
// case 4+3:
|
|
// insn1 = bf cd ij kl
|
|
// insn2 = g4 mn eh
|
|
uint32 w1 = (opc1<<24) | (word & 0x00FF0000); // bfcd0000
|
|
uint32 w2 = (((word&0xF0)|4)<<24) | (word&0xF000) | ((word&0x0F)<<8); // g400eh00
|
|
int insn1_len = get_insn_size(masks, w1);
|
|
if ( insn1_len == 0 )
|
|
{
|
|
// try to add one byte
|
|
w1 |= (get_byte(ea + 4) << 8);
|
|
insn1_len = get_insn_size(masks, w1);
|
|
if ( insn1_len == 0 || insn1_len < 3 )
|
|
{
|
|
w1 |= get_byte(ea + 5);
|
|
insn1_len = get_insn_size(masks, w1);
|
|
if ( insn1_len != 4 )
|
|
return false;
|
|
}
|
|
}
|
|
int insn2_len = get_insn_size(masks, w2);
|
|
if ( insn1_len < 2 || insn2_len != 3 )
|
|
return false;
|
|
if ( insn1 )
|
|
{
|
|
insn1->clear();
|
|
insn1->push_back((w1>>24)&0xFF);
|
|
insn1->push_back((w1>>16)&0xFF);
|
|
// add extra bytes
|
|
for ( int i=4; i < insn1_len + 2; i++ )
|
|
insn1->push_back(get_byte(ea + i));
|
|
}
|
|
if ( insn2 )
|
|
{
|
|
insn2->clear();
|
|
insn2->push_back((w2>>24)&0xFF);
|
|
insn2->push_back(get_byte(ea + insn1_len + 2));
|
|
insn2->push_back((w2>>8)&0xFF);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
void ana_status_bits(insn_t &insn)
|
|
{
|
|
if ( (insn.itype == TMS320C55_bclr2 || insn.itype == TMS320C55_bset2)
|
|
&& insn.Op2.type == o_reg
|
|
&& insn.Op1.type == o_imm )
|
|
{
|
|
int reg = -1;
|
|
switch ( insn.Op2.reg )
|
|
{
|
|
case ST0_55:
|
|
{
|
|
static const int regs[] =
|
|
{
|
|
-1, -1, -1, -1, -1, -1, -1, -1,
|
|
-1, ACOV1, ACOV0, CARRY, TC2, TC1, ACOV3, ACOV2
|
|
};
|
|
reg = regs[int(insn.Op1.value)];
|
|
break;
|
|
}
|
|
case ST1_55:
|
|
{
|
|
static const int regs[] =
|
|
{
|
|
-1, -1, -1, -1, -1, C54CM, FRCT, C16,
|
|
SXMD, SATD, M40, INTM, HM, XF, CPL, BRAF
|
|
};
|
|
reg = regs[int(insn.Op1.value)];
|
|
break;
|
|
}
|
|
case ST2_55:
|
|
{
|
|
static const int regs[] =
|
|
{
|
|
AR0LC, AR1LC, AR2LC, AR3LC, AR4LC, AR5LC, AR6LC, AR7LC,
|
|
CDPLC, -1, RDM, EALLOW, DBGM, -1, -1, ARMS
|
|
};
|
|
reg = regs[int(insn.Op1.value)];
|
|
break;
|
|
}
|
|
case ST3_55:
|
|
{
|
|
static const int regs[] =
|
|
{
|
|
SST, SMUL, CLKOFF, -1, -1, SATA, MPNMC, CBERR,
|
|
-1, -1, -1, -1, HINT, CACLR, CAEN, CAFRZ
|
|
};
|
|
reg = regs[int(insn.Op1.value)];
|
|
break;
|
|
}
|
|
}
|
|
if ( reg != -1 )
|
|
{
|
|
insn.itype = (insn.itype == TMS320C55_bclr2) ? TMS320C55_bclr1 : TMS320C55_bset1;
|
|
insn.Op1.type = o_reg;
|
|
insn.Op1.reg = uint16(reg);
|
|
insn.Op2.type = o_void;
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
int tms320c55_t::ana(insn_t *_insn)
|
|
{
|
|
insn_t &insn = *_insn;
|
|
optional_op = -1;
|
|
bytes_c bytes(insn);
|
|
uchar firstbyte = bytes.get_next();
|
|
|
|
int sdual_len = helper.altval_ea(insn.ea, TAG_SDUAL);
|
|
if ( sdual_len != 0 )
|
|
{
|
|
// this is a second part of sdual instruction
|
|
bytevec_t insn_bytes;
|
|
if ( !unpack_sdual(insn.ea - sdual_len, NULL, &insn_bytes) )
|
|
return 0;
|
|
bytes.set_cache(insn_bytes);
|
|
process_masks(insn, masks, TMS320C55_null, bytes, 8); // analyze opcode
|
|
if ( insn.itype == TMS320C55_null || insn.size != insn_bytes.size() )
|
|
return 0;
|
|
ana_status_bits(insn);
|
|
insn.SpecialModes |= TMS_MODE_USER_PARALLEL;
|
|
return insn.size;
|
|
}
|
|
else
|
|
{
|
|
// a normal instruction ?
|
|
process_masks(insn, masks, TMS320C55_null, bytes, 8); // analyze opcode
|
|
if ( insn.size != 0 && insn.itype != TMS320C55_null )
|
|
{
|
|
helper.altdel_ea(insn.ea + insn.size, TAG_SDUAL);
|
|
}
|
|
else if ( (firstbyte & 0xF8) == 0x88 )
|
|
{
|
|
// "sdual" instruction; unpack it
|
|
bytevec_t insn_bytes;
|
|
if ( !unpack_sdual(insn.ea, &insn_bytes, NULL) )
|
|
return 0;
|
|
bytes.set_cache(insn_bytes);
|
|
process_masks(insn, masks, TMS320C55_null, bytes, 8); // analyze opcode
|
|
if ( insn.itype != TMS320C55_null && insn.size == insn_bytes.size() )
|
|
{
|
|
ana_status_bits(insn);
|
|
// remember that next address is the second part
|
|
helper.altset_ea(insn.ea + insn.size, insn.size, TAG_SDUAL);
|
|
return insn.size;
|
|
}
|
|
}
|
|
}
|
|
|
|
// analyze special bits access
|
|
ana_status_bits(insn);
|
|
|
|
// analyze user-parallelized instructions
|
|
if ( firstbyte <= MAX_BYTE_USER_PARALLELIZED && (firstbyte & 1) ) // instruction has E bit set
|
|
insn.SpecialModes |= TMS_MODE_USER_PARALLEL;
|
|
|
|
// analyze postfixes
|
|
uchar nextbyte = get_byte(insn.ea+insn.size); // is_mapped() not necessary here
|
|
switch ( nextbyte )
|
|
{
|
|
case BYTE_MMAP: // mmap()
|
|
if ( insn.OpMem != 0 )
|
|
{
|
|
int n = insn.OpMem - 1;
|
|
if ( insn.ops[n].type == o_mem
|
|
&& insn.ops[n].tms_regH == DPH
|
|
&& insn.ops[n].tms_regP == DP
|
|
&& insn.ops[n].tms_modifier == TMS_MODIFIER_DMA )
|
|
{ // @dma using DP
|
|
insn.ops[n].tms_regH = 0;
|
|
insn.ops[n].tms_regP = 0;
|
|
insn.ops[n].tms_modifier = TMS_MODIFIER_MMAP;
|
|
insn.size++;
|
|
}
|
|
else if ( insn.ops[n].type == o_reg
|
|
&& insn.ops[n].reg == SP
|
|
&& insn.ops[n].tms_modifier == TMS_MODIFIER_REG_OFFSET )
|
|
{ // @dma using SP
|
|
insn.ops[n].addr = insn.ops[n].value;
|
|
insn.ops[n].type = o_mem;
|
|
insn.ops[n].tms_regH = 0;
|
|
insn.ops[n].tms_regP = 0;
|
|
insn.ops[n].tms_modifier = TMS_MODIFIER_MMAP;
|
|
insn.size++;
|
|
}
|
|
}
|
|
break;
|
|
case BYTE_PORT1:
|
|
case BYTE_PORT2: // port()
|
|
if ( insn.OpMem != 0 )
|
|
{
|
|
int n = insn.OpMem - 1;
|
|
switch ( insn.ops[n].type )
|
|
{
|
|
case o_mem:
|
|
insn.ops[n].type = o_io;
|
|
insn.ops[n].tms_regH = 0;
|
|
insn.ops[n].tms_regP = PDP;
|
|
insn.ops[n].addr = insn.ops[n].addr >> 1;
|
|
insn.ops[n].tms_modifier = TMS_MODIFIER_PORT_AT;
|
|
insn.size++;
|
|
break;
|
|
case o_reg:
|
|
insn.ops[n].tms_operator1 |= TMS_OPERATOR_PORT & 0xFF;
|
|
insn.ops[n].tms_operator2 |= (TMS_OPERATOR_PORT >> 8);
|
|
insn.size++;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case BYTE_LR:
|
|
case BYTE_CR: // .lr & .cr
|
|
insn.SpecialModes |= nextbyte == BYTE_LR ? TMS_MODE_LR : TMS_MODE_CR;
|
|
insn.size++;
|
|
break;
|
|
}
|
|
if ( insn.itype == TMS320C55_null )
|
|
return 0;
|
|
return insn.size;
|
|
}
|