update to ida 7.6, add builds

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

View File

@@ -0,0 +1,740 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-2001 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* E-mail: ig@datarescue.com
*
*
*/
#include "i960.hpp"
struct sparse_tabent_t
{
ushort code;
ushort itype;
char opnum;
};
//--------------------------------------------------------------------------
inline void opimm(op_t &x, uval_t value, char dtype)
{
x.type = o_imm;
x.dtype = dtype;
x.value = value;
}
//--------------------------------------------------------------------------
inline void opreg(op_t &x, int reg)
{
x.type = o_reg;
x.dtype = dt_dword;
x.reg = (uchar)reg;
}
//--------------------------------------------------------------------------
inline void opmem(op_t &x, uval_t addr, char dtype)
{
x.type = o_mem;
x.dtype = dtype;
x.addr = addr;
}
//--------------------------------------------------------------------------
inline void opdsp(op_t &x, int base, int idx, int scale, uval_t disp, char dtype)
{
x.type = o_displ;
x.dtype = dtype;
x.addr = disp;
x.reg = (uint16)base;
x.index = (uchar)idx;
x.scale = (uchar)scale;
}
//--------------------------------------------------------------------------
inline void opphr(op_t &x, int base, int idx, int scale, char dtype)
{
x.type = o_phrase;
x.dtype = dtype;
x.reg = (uint16)base;
x.index = (uchar)idx;
x.scale = (uchar)scale;
}
//--------------------------------------------------------------------------
inline void opnear(op_t &x, uval_t addr)
{
x.type = o_near;
x.dtype = dt_code;
x.addr = addr;
}
//--------------------------------------------------------------------------
bool i960_t::ctrl(insn_t &insn, uint32 code)
{
static const ushort itypes[] =
{
I960_null, /* 0x00 */
I960_null, /* 0x01 */
I960_null, /* 0x02 */
I960_null, /* 0x03 */
I960_null, /* 0x04 */
I960_null, /* 0x05 */
I960_null, /* 0x06 */
I960_null, /* 0x07 */
I960_b, /* 0x08 */
I960_call, /* 0x09 */
I960_ret, /* 0x0a */
I960_bal, /* 0x0b */
I960_null, /* 0x0c */
I960_null, /* 0x0d */
I960_null, /* 0x0e */
I960_null, /* 0x0f */
I960_bno, /* 0x10 */
I960_bg, /* 0x11 */
I960_be, /* 0x12 */
I960_bge, /* 0x13 */
I960_bl, /* 0x14 */
I960_bne, /* 0x15 */
I960_ble, /* 0x16 */
I960_bo, /* 0x17 */
I960_faultno, /* 0x18 */
I960_faultg, /* 0x19 */
I960_faulte, /* 0x1a */
I960_faultge, /* 0x1b */
I960_faultl, /* 0x1c */
I960_faultne, /* 0x1d */
I960_faultle, /* 0x1e */
I960_faulto, /* 0x1f */
};
int opcode = code >> 24;
if ( opcode >= qnumber(itypes) )
return false;
if ( is_strict() && (code & 1) != 0 )
return false;
insn.itype = itypes[opcode];
if ( opcode >= 0x10 ) // .t or .f are allowed
{
insn.auxpref |= (code & 2) ? aux_f : aux_t;
}
// has operand?
if ( Instructions[insn.itype].feature & CF_USE1 )
{
sval_t disp = code & 0xFFFFFC;
if ( disp & 0x800000 )
disp |= ~uval_t(0xFFFFFF); // sign extend
opnear(insn.Op1, insn.ip+disp);
}
return true;
}
//--------------------------------------------------------------------------
static bool cobr(insn_t &insn, uint32 code)
{
static const ushort itypes[] =
{
I960_testno, /* 0x20 */
I960_testg, /* 0x21 */
I960_teste, /* 0x22 */
I960_testge, /* 0x23 */
I960_testl, /* 0x24 */
I960_testne, /* 0x25 */
I960_testle, /* 0x26 */
I960_testo, /* 0x27 */
I960_null, /* 0x28 */
I960_null, /* 0x29 */
I960_null, /* 0x2a */
I960_null, /* 0x2b */
I960_null, /* 0x2c */
I960_null, /* 0x2d */
I960_null, /* 0x2e */
I960_null, /* 0x2f */
I960_bbc, /* 0x30 */
I960_cmpobg, /* 0x31 */
I960_cmpobe, /* 0x32 */
I960_cmpobge, /* 0x33 */
I960_cmpobl, /* 0x34 */
I960_cmpobne, /* 0x35 */
I960_cmpoble, /* 0x36 */
I960_bbs, /* 0x37 */
I960_cmpibno, /* 0x38 */
I960_cmpibg, /* 0x39 */
I960_cmpibe, /* 0x3a */
I960_cmpibge, /* 0x3b */
I960_cmpibl, /* 0x3c */
I960_cmpibne, /* 0x3d */
I960_cmpible, /* 0x3e */
I960_cmpibo, /* 0x3f */
};
uint32 opcode = (code >> 24) - 0x20;
if ( opcode >= qnumber(itypes) )
return false;
insn.itype = itypes[opcode];
insn.auxpref |= (code & 2) ? aux_f : aux_t;
int src1 = (code >> 19) & 0x1F;
int src2 = (code >> 14) & 0x1F;
// operand 1
if ( code & 0x2000 ) // M1
{
opimm(insn.Op1, src1, dt_byte);
if ( opcode < 8 )
return false; // test instructions can't have imm
}
else
{
opreg(insn.Op1, src1);
}
if ( Instructions[insn.itype].feature & (CF_USE2|CF_CHG2) )
{
// instruction has at least 3 operands
if ( code & 1 )
src2 += SF0; // S2
opreg(insn.Op2, src2);
sval_t disp = code & 0x1FFC;
if ( disp & 0x1000 )
disp |= ~uval_t(0x1FFF); // sign extend
opnear(insn.Op3, insn.ip+disp);
}
return true;
}
//--------------------------------------------------------------------------
bool i960_t::opmemory(insn_t &insn, op_t &x, uint32 code, char dtype)
{
int reg2 = (code >> 14) & 0x1F;
int mode = (code >> 10) & 0xF;
if ( mode & 4 ) /* MEMB FORMAT */
{
unsigned scale = (code >> 7) & 0x07;
if ( (scale > 4) )
return false;
bool badscale = ((code >> 5) & 0x03) != 0;
static const int scale_tab[] = { 1, 2, 4, 8, 16 };
scale = scale_tab[scale];
int reg3 = code & 0x1F;
uval_t disp;
switch ( mode )
{
case 4: /* (reg) */
opphr(x, reg2, -1, 1, dtype);
break;
case 5: /* displ+8(ip) */
x.offb = (uchar)insn.size;
disp = insn.get_next_dword();
opdsp(x, IP, -1, 1, disp, dtype);
// opmem(x, insn.ip+8+disp, dtype);
// insn.auxpref |= aux_ip;
break;
case 7: /* (reg)[index*scale] */
if ( is_strict() && badscale )
return false;
opphr(x, reg2, reg3, scale, dtype);
break;
case 12: /* displacement */
x.offb = (uchar)insn.size;
disp = insn.get_next_dword();
opmem(x, disp, dtype);
break;
case 13: /* displ(reg) */
x.offb = (uchar)insn.size;
disp = insn.get_next_dword();
opdsp(x, reg2, -1, 1, disp, dtype);
break;
case 14: /* displ[index*scale] */
if ( is_strict() && badscale )
return false;
x.offb = (uchar)insn.size;
disp = insn.get_next_dword();
opdsp(x, -1, reg3, scale, disp, dtype);
break;
case 15: /* displ(reg)[index*scale] */
if ( is_strict() && badscale )
return false;
x.offb = (uchar)insn.size;
disp = insn.get_next_dword();
opdsp(x, reg2, reg3, scale, disp, dtype);
break;
default:
return false;
}
}
else /* MEMA FORMAT */
{
int offset = code & 0xFFF;
if ( mode & 8 )
opdsp(x, reg2, -1, 1, offset, dtype);
else
opmem(x, offset, dtype);
}
if ( x.type == o_mem && dtype == dt_code )
x.type = o_near;
return true;
}
//--------------------------------------------------------------------------
bool i960_t::mem(insn_t &insn, uint32 code)
{
static const tabent_t itypes[] =
{
{ /* 0x80 */ I960_ldob, 2, dt_byte },
{ /* 0x81 */ I960_null, 0, 0 },
{ /* 0x82 */ I960_stob, -2, dt_byte },
{ /* 0x83 */ I960_null, 0, 0 },
{ /* 0x84 */ I960_bx, 1, dt_code },
{ /* 0x85 */ I960_balx, 2, dt_code },
{ /* 0x86 */ I960_callx, 1, dt_code },
{ /* 0x87 */ I960_null, 0, 0 },
{ /* 0x88 */ I960_ldos, 2, dt_word },
{ /* 0x89 */ I960_null, 0, 0 },
{ /* 0x8a */ I960_stos, -2, dt_word },
{ /* 0x8b */ I960_null, 0, 0 },
{ /* 0x8c */ I960_lda, 2, dt_byte },
{ /* 0x8d */ I960_null, 0, 0 },
{ /* 0x8e */ I960_null, 0, 0 },
{ /* 0x8f */ I960_null, 0, 0 },
{ /* 0x90 */ I960_ld, 2, dt_dword },
{ /* 0x91 */ I960_null, 0, 0 },
{ /* 0x92 */ I960_st, -2, dt_dword },
{ /* 0x93 */ I960_null, 0, 0 },
{ /* 0x94 */ I960_null, 0, 0 },
{ /* 0x95 */ I960_null, 0, 0 },
{ /* 0x96 */ I960_null, 0, 0 },
{ /* 0x97 */ I960_null, 0, 0 },
{ /* 0x98 */ I960_ldl, 2, dt_qword },
{ /* 0x99 */ I960_null, 0, 0 },
{ /* 0x9a */ I960_stl, -2, dt_qword },
{ /* 0x9b */ I960_null, 0, 0 },
{ /* 0x9c */ I960_null, 0, 0 },
{ /* 0x9d */ I960_null, 0, 0 },
{ /* 0x9e */ I960_null, 0, 0 },
{ /* 0x9f */ I960_null, 0, 0 },
{ /* 0xa0 */ I960_ldt, 2, dt_fword },
{ /* 0xa1 */ I960_null, 0, 0 },
{ /* 0xa2 */ I960_stt, -2, dt_fword },
{ /* 0xa3 */ I960_null, 0, 0 },
{ /* 0xa4 */ I960_null, 0, 0 },
{ /* 0xa5 */ I960_null, 0, 0 },
{ /* 0xa6 */ I960_null, 0, 0 },
{ /* 0xa7 */ I960_null, 0, 0 },
{ /* 0xa8 */ I960_null, 0, 0 },
{ /* 0xa9 */ I960_null, 0, 0 },
{ /* 0xaa */ I960_null, 0, 0 },
{ /* 0xab */ I960_null, 0, 0 },
{ /* 0xac */ I960_dcinva, 1, dt_byte },
{ /* 0xad */ I960_null, 0, 0 },
{ /* 0xae */ I960_null, 0, 0 },
{ /* 0xaf */ I960_null, 0, 0 },
{ /* 0xb0 */ I960_ldq, 2, dt_byte16 },
{ /* 0xb1 */ I960_null, 0, 0 },
{ /* 0xb2 */ I960_stq, -2, dt_byte16 },
{ /* 0xb3 */ I960_null, 0, 0 },
{ /* 0xb4 */ I960_null, 0, 0 },
{ /* 0xb5 */ I960_null, 0, 0 },
{ /* 0xb6 */ I960_null, 0, 0 },
{ /* 0xb7 */ I960_null, 0, 0 },
{ /* 0xb8 */ I960_null, 0, 0 },
{ /* 0xb9 */ I960_null, 0, 0 },
{ /* 0xba */ I960_null, 0, 0 },
{ /* 0xbb */ I960_null, 0, 0 },
{ /* 0xbc */ I960_null, 0, 0 },
{ /* 0xbd */ I960_null, 0, 0 },
{ /* 0xbe */ I960_null, 0, 0 },
{ /* 0xbf */ I960_null, 0, 0 },
{ /* 0xc0 */ I960_ldib, 2, dt_byte },
{ /* 0xc1 */ I960_null, 0, 0 },
{ /* 0xc2 */ I960_stib, -2, dt_byte },
{ /* 0xc3 */ I960_null, 0, 0 },
{ /* 0xc4 */ I960_null, 0, 0 },
{ /* 0xc5 */ I960_null, 0, 0 },
{ /* 0xc6 */ I960_null, 0, 0 },
{ /* 0xc7 */ I960_null, 0, 0 },
{ /* 0xc8 */ I960_ldis, 2, dt_word },
{ /* 0xc9 */ I960_null, 0, 0 },
{ /* 0xca */ I960_stis, -2, dt_word },
};
uint32 opcode = (code >> 24) - 0x80;
if ( opcode >= qnumber(itypes) )
return false;
insn.itype = itypes[opcode].itype;
int reg1 = (code >> 19) & 0x1F;
switch ( itypes[opcode].opnum )
{
case -2: /* STORE INSTRUCTION */
opreg(insn.Op1, reg1);
if ( !opmemory(insn, insn.Op2, code, itypes[opcode].dtype) )
return false;
break;
case 2: /* LOAD INSTRUCTION */
opreg(insn.Op2, reg1);
// no break
case 1: /* BX/CALLX INSTRUCTION */
if ( !opmemory(insn, insn.Op1, code, itypes[opcode].dtype) )
return false;
break;
}
if ( insn.itype == I960_lda && insn.Op1.type == o_mem )
opimm(insn.Op1, insn.Op1.addr, dt_dword);
return true;
}
//--------------------------------------------------------------------------
static void regop(op_t &x, bool mode, bool spec, int reg, bool fp)
{
if ( fp ) /* FLOATING POINT INSTRUCTION */
{
if ( mode ) /* FP operand */
{
switch ( reg )
{
case 0:
opreg(x, FP0);
break;
case 1:
opreg(x, FP1);
break;
case 2:
opreg(x, FP2);
break;
case 3:
opreg(x, FP3);
break;
/* case 16: "0f0.0"
break;
case 22: "0f1.0"
break;
default: "?"
break;*/
}
}
else
{ /* Non-FP register */
opreg(x, reg);
}
}
else
{ /* NOT FLOATING POINT */
if ( mode ) /* Literal */
{
opimm(x, reg, dt_dword);
}
else
{ /* Register */
if ( spec )
reg += SF0;
opreg(x, reg);
}
}
}
//--------------------------------------------------------------------------
// Register Instruction Destination Operand
static void dstop(op_t &x, bool mode, int reg, bool fp)
{
// 'dst' operand can't be a literal. On non-FP instructions, register
// mode is assumed and "m3" acts as if were "s3"; on FP-instructions,
// sf registers are not allowed so m3 acts normally.
if ( fp )
regop(x, mode, false, reg, fp);
else
regop(x, false, mode, reg, fp);
}
//--------------------------------------------------------------------------
bool i960_t::reg(insn_t &insn, uint32 code)
{
static const sparse_tabent_t reg_init[] =
{
{ 0x580, I960_notbit, 3 },
{ 0x581, I960_and, 3 },
{ 0x582, I960_andnot, 3 },
{ 0x583, I960_setbit, 3 },
{ 0x584, I960_notand, 3 },
{ 0x586, I960_xor, 3 },
{ 0x587, I960_or, 3 },
{ 0x588, I960_nor, 3 },
{ 0x589, I960_xnor, 3 },
{ 0x58a, I960_not, -2 },
{ 0x58b, I960_ornot, 3 },
{ 0x58c, I960_clrbit, 3 },
{ 0x58d, I960_notor, 3 },
{ 0x58e, I960_nand, 3 },
{ 0x58f, I960_alterbit, 3 },
{ 0x590, I960_addo, 3 },
{ 0x591, I960_addi, 3 },
{ 0x592, I960_subo, 3 },
{ 0x593, I960_subi, 3 },
{ 0x594, I960_cmpob, 2 },
{ 0x595, I960_cmpib, 2 },
{ 0x596, I960_cmpos, 2 },
{ 0x597, I960_cmpis, 2 },
{ 0x598, I960_shro, 3 },
{ 0x59a, I960_shrdi, 3 },
{ 0x59b, I960_shri, 3 },
{ 0x59c, I960_shlo, 3 },
{ 0x59d, I960_rotate, 3 },
{ 0x59e, I960_shli, 3 },
{ 0x5a0, I960_cmpo, 2 },
{ 0x5a1, I960_cmpi, 2 },
{ 0x5a2, I960_concmpo, 2 },
{ 0x5a3, I960_concmpi, 2 },
{ 0x5a4, I960_cmpinco, 3 },
{ 0x5a5, I960_cmpinci, 3 },
{ 0x5a6, I960_cmpdeco, 3 },
{ 0x5a7, I960_cmpdeci, 3 },
{ 0x5ac, I960_scanbyte, 2 },
{ 0x5ad, I960_bswap, -2 },
{ 0x5ae, I960_chkbit, 2 },
{ 0x5b0, I960_addc, 3 },
{ 0x5b2, I960_subc, 3 },
{ 0x5b4, I960_intdis, 0 },
{ 0x5b5, I960_inten, 0 },
{ 0x5cc, I960_mov, -2 },
{ 0x5d8, I960_eshro, 3 },
{ 0x5dc, I960_movl, -2 },
{ 0x5ec, I960_movt, -2 },
{ 0x5fc, I960_movq, -2 },
{ 0x600, I960_synmov, 2 },
{ 0x601, I960_synmovl, 2 },
{ 0x602, I960_synmovq, 2 },
{ 0x603, I960_cmpstr, 3 },
{ 0x604, I960_movqstr, 3 },
{ 0x605, I960_movstr, 3 },
{ 0x610, I960_atmod, 3 },
{ 0x612, I960_atadd, 3 },
{ 0x613, I960_inspacc, -2 },
{ 0x614, I960_ldphy, -2 },
{ 0x615, I960_synld, -2 },
{ 0x617, I960_fill, 3 },
{ 0x630, I960_sdma, 3 },
{ 0x631, I960_udma, 0 },
{ 0x640, I960_spanbit, -2 },
{ 0x641, I960_scanbit, -2 },
{ 0x642, I960_daddc, 3 },
{ 0x643, I960_dsubc, 3 },
{ 0x644, I960_dmovt, -2 },
{ 0x645, I960_modac, 3 },
{ 0x646, I960_condrec, -2 },
{ 0x650, I960_modify, 3 },
{ 0x651, I960_extract, 3 },
{ 0x654, I960_modtc, 3 },
{ 0x655, I960_modpc, 3 },
{ 0x656, I960_receive, -2 },
{ 0x658, I960_intctl, -2 },
{ 0x659, I960_sysctl, 3 },
{ 0x65b, I960_icctl, 3 },
{ 0x65c, I960_dcctl, 3 },
{ 0x65d, I960_halt, 1 },
{ 0x660, I960_calls, 1 },
{ 0x662, I960_send, 3 },
{ 0x663, I960_sendserv, 1 },
{ 0x664, I960_resumprcs, 1 },
{ 0x665, I960_schedprcs, 1 },
{ 0x666, I960_saveprcs, 0 },
{ 0x668, I960_condwait, 1 },
{ 0x669, I960_wait, 1 },
{ 0x66a, I960_signal, 1 },
{ 0x66b, I960_mark, 0 },
{ 0x66c, I960_fmark, 0 },
{ 0x66d, I960_flushreg, 0 },
{ 0x66f, I960_syncf, 0 },
{ 0x670, I960_emul, 3 },
{ 0x671, I960_ediv, 3 },
{ 0x673, I960_ldtime, -1 },
{ 0x674, I960_fcvtir, -2 },
{ 0x675, I960_fcvtilr, -2 },
{ 0x676, I960_fscalerl, 3 },
{ 0x677, I960_fscaler, 3 },
{ 0x680, I960_fatanr, 3 },
{ 0x681, I960_flogepr, 3 },
{ 0x682, I960_flogr, 3 },
{ 0x683, I960_fremr, 3 },
{ 0x684, I960_fcmpor, 2 },
{ 0x685, I960_fcmpr, 2 },
{ 0x688, I960_fsqrtr, -2 },
{ 0x689, I960_fexpr, -2 },
{ 0x68a, I960_flogbnr, -2 },
{ 0x68b, I960_froundr, -2 },
{ 0x68c, I960_fsinr, -2 },
{ 0x68d, I960_fcosr, -2 },
{ 0x68e, I960_ftanr, -2 },
{ 0x68f, I960_fclassr, 1 },
{ 0x690, I960_fatanrl, 3 },
{ 0x691, I960_flogeprl, 3 },
{ 0x692, I960_flogrl, 3 },
{ 0x693, I960_fremrl, 3 },
{ 0x694, I960_fcmporl, 2 },
{ 0x695, I960_fcmprl, 2 },
{ 0x698, I960_fsqrtrl, -2 },
{ 0x699, I960_fexprl, -2 },
{ 0x69a, I960_flogbnrl, -2 },
{ 0x69b, I960_froundrl, -2 },
{ 0x69c, I960_fsinrl, -2 },
{ 0x69d, I960_fcosrl, -2 },
{ 0x69e, I960_ftanrl, -2 },
{ 0x69f, I960_fclassrl, 1 },
{ 0x6c0, I960_fcvtri, -2 },
{ 0x6c1, I960_fcvtril, -2 },
{ 0x6c2, I960_fcvtzri, -2 },
{ 0x6c3, I960_fcvtzril, -2 },
{ 0x6c9, I960_fmovr, -2 },
{ 0x6d9, I960_fmovrl, -2 },
{ 0x6e1, I960_fmovre, -2 },
{ 0x6e2, I960_fcpysre, 3 },
{ 0x6e3, I960_fcpyrsre, 3 },
{ 0x701, I960_mulo, 3 },
{ 0x708, I960_remo, 3 },
{ 0x70b, I960_divo, 3 },
{ 0x741, I960_muli, 3 },
{ 0x748, I960_remi, 3 },
{ 0x749, I960_modi, 3 },
{ 0x74b, I960_divi, 3 },
{ 0x780, I960_addono, 3 },
{ 0x781, I960_addino, 3 },
{ 0x782, I960_subono, 3 },
{ 0x783, I960_subino, 3 },
{ 0x784, I960_selno, 3 },
{ 0x78b, I960_fdivr, 3 },
{ 0x78c, I960_fmulr, 3 },
{ 0x78d, I960_fsubr, 3 },
{ 0x78f, I960_faddr, 3 },
{ 0x790, I960_addog, 3 },
{ 0x791, I960_addig, 3 },
{ 0x792, I960_subog, 3 },
{ 0x793, I960_subig, 3 },
{ 0x794, I960_selg, 3 },
{ 0x79b, I960_fdivrl, 3 },
{ 0x79c, I960_fmulrl, 3 },
{ 0x79d, I960_fsubrl, 3 },
{ 0x79f, I960_faddrl, 3 },
{ 0x7a0, I960_addoe, 3 },
{ 0x7a1, I960_addie, 3 },
{ 0x7a2, I960_suboe, 3 },
{ 0x7a3, I960_subie, 3 },
{ 0x7a4, I960_sele, 3 },
{ 0x7b0, I960_addoge, 3 },
{ 0x7b1, I960_addige, 3 },
{ 0x7b2, I960_suboge, 3 },
{ 0x7b3, I960_subige, 3 },
{ 0x7b4, I960_selge, 3 },
{ 0x7c0, I960_addol, 3 },
{ 0x7c1, I960_addil, 3 },
{ 0x7c2, I960_subol, 3 },
{ 0x7c3, I960_subil, 3 },
{ 0x7c4, I960_sell, 3 },
{ 0x7d0, I960_addone, 3 },
{ 0x7d1, I960_addine, 3 },
{ 0x7d2, I960_subone, 3 },
{ 0x7d3, I960_subine, 3 },
{ 0x7d4, I960_selne, 3 },
{ 0x7e0, I960_addole, 3 },
{ 0x7e1, I960_addile, 3 },
{ 0x7e2, I960_subole, 3 },
{ 0x7e3, I960_subile, 3 },
{ 0x7e4, I960_selle, 3 },
{ 0x7f0, I960_addoo, 3 },
{ 0x7f1, I960_addio, 3 },
{ 0x7f2, I960_suboo, 3 },
{ 0x7f3, I960_subio, 3 },
{ 0x7f4, I960_selo, 3 },
};
if ( reg_tab == NULL )
{
reg_tab = reg_tab_buf;
for ( int i = 0; i < qnumber(reg_init); i++ )
{
int j = reg_init[i].code - REG_MIN;
QASSERT(10086, j >= 0 && j < qnumber(reg_tab_buf));
reg_tab[j].itype = reg_init[i].itype;
reg_tab[j].opnum = reg_init[i].opnum;
}
}
int opcode = ((code >> 20) & 0xff0) | ((code >> 7) & 0xf);
if ( opcode < REG_MIN || opcode > REG_MAX )
return false;
int i = opcode - REG_MIN;
insn.itype = reg_tab[i].itype;
bool fp = insn.itype >= I960_fp_first && insn.itype <= I960_fp_last;
bool s1 = ((code >> 5) & 1) != 0;
bool s2 = ((code >> 6) & 1) != 0;
bool m1 = ((code >> 11) & 1) != 0;
bool m2 = ((code >> 12) & 1) != 0;
bool m3 = ((code >> 13) & 1) != 0;
int src = code & 0x1f;
int src2 = (code >> 14) & 0x1f;
int dst = (code >> 19) & 0x1f;
switch ( reg_tab[i].opnum )
{
case 1:
regop(insn.Op1, m1, s1, src, fp);
break;
case -1:
dstop(insn.Op1, m3, dst, fp);
break;
case 2:
regop(insn.Op1, m1, s1, src, fp);
regop(insn.Op2, m2, s2, src2, fp);
break;
case -2:
regop(insn.Op1, m1, s1, src, fp);
dstop(insn.Op2, m3, dst, fp);
break;
case 3:
regop(insn.Op1, m1, s1, src, fp);
regop(insn.Op2, m2, s2, src2, fp);
dstop(insn.Op3, m3, dst, fp);
break;
}
return true;
}
//--------------------------------------------------------------------------
int i960_t::i960_ana(insn_t *_insn)
{
insn_t &insn = *_insn;
if ( insn.ip & 3 )
return 0; // alignment error
uint32 code = insn.get_next_dword();
switch ( code >> 28 )
{
case 0x0:
case 0x1:
if ( !ctrl(insn, code) )
return 0;
break;
case 0x2:
case 0x3:
if ( !cobr(insn, code) )
return 0;
break;
case 0x5:
case 0x6:
case 0x7:
if ( !reg(insn, code) )
return 0;
break;
case 0x8:
case 0x9:
case 0xA:
case 0xB:
case 0xC:
if ( !mem(insn, code) )
return 0;
break;
default:
return 0;
}
return insn.itype == I960_null ? 0 : insn.size;
}

View File

@@ -0,0 +1,128 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-2001 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* E-mail: ig@datarescue.com
*
*
*/
#include "i960.hpp"
//----------------------------------------------------------------------
ea_t calc_mem(const insn_t &insn, ea_t ea)
{
return to_ea(insn.cs, ea);
}
//----------------------------------------------------------------------
void i960_t::handle_operand(const insn_t &insn, const op_t &x, bool isload)
{
ea_t ea;
dref_t dref;
if ( is_forced_operand(insn.ea, x.n) )
return;
switch ( x.type )
{
case o_reg:
case o_phrase:
break;
case o_imm:
{
flags_t F = get_flags(insn.ea);
QASSERT(10105, isload);
set_immd(insn.ea);
if ( op_adds_xrefs(F, x.n) )
insn.add_off_drefs(x, dr_O, OOFS_IFSIGN|OOFW_IMM);
}
break;
case o_mem:
ea = calc_mem(insn, x.addr);
insn.create_op_data(ea, x);
dref = insn.itype == I960_lda ? dr_O : isload ? dr_R : dr_W;
insn.add_dref(ea, x.offb, dref);
break;
case o_near:
{
cref_t ftype = fl_JN;
ea = calc_mem(insn, x.addr);
if ( has_insn_feature(insn.itype, CF_CALL) )
{
// don't add call xref to next instruction
if ( ea == insn.ea + insn.size )
break;
flow = func_does_return(ea);
ftype = fl_CN;
}
insn.add_cref(ea, x.offb, ftype);
}
break;
case o_displ:
{
dref = insn.itype == I960_lda ? dr_O : isload ? dr_R : dr_W;
set_immd(insn.ea);
if ( x.reg == IP )
{
ea = insn.ea + 8 + x.addr;
insn.add_dref(ea, x.offb, dref);
}
else
{
flags_t F = get_flags(insn.ea);
if ( op_adds_xrefs(F, x.n) )
insn.add_off_drefs(x, dref, OOFS_IFSIGN|OOF_SIGNED|OOF_ADDR|OOFW_32);
}
}
break;
default:
INTERR(10364);
}
}
//----------------------------------------------------------------------
int i960_t::i960_emu(const insn_t &insn)
{
uint32 Feature = insn.get_canon_feature(ph);
flow = ((Feature & CF_STOP) == 0);
if ( Feature & CF_USE1 ) handle_operand(insn, insn.Op1, true);
if ( Feature & CF_USE2 ) handle_operand(insn, insn.Op2, true);
if ( Feature & CF_USE3 ) handle_operand(insn, insn.Op3, true);
if ( Feature & CF_CHG1 ) handle_operand(insn, insn.Op1, false);
if ( Feature & CF_CHG2 ) handle_operand(insn, insn.Op2, false);
if ( Feature & CF_CHG3 ) handle_operand(insn, insn.Op3, false);
//
// Determine if the next instruction should be executed
//
if ( segtype(insn.ea) == SEG_XTRN )
flow = false;
if ( flow )
add_cref(insn.ea,insn.ea+insn.size,fl_F);
//
// convert "lda imm, reg" to "lda mem, reg"
//
if ( insn.itype == I960_lda
&& insn.Op1.type == o_imm
&& !is_defarg(get_flags(insn.ea), 0)
&& is_mapped(insn.Op1.value) )
{
op_plain_offset(insn.ea, 0, 0);
}
return 1;
}
//----------------------------------------------------------------------
int idaapi is_align_insn(ea_t /*ea*/)
{
return false;
}

View File

@@ -0,0 +1,736 @@
;
; This file defines SFR names and bit names for Intel 960 processors.
;
; This file can be configured for different devices.
; At the beginning of the file there are definitions common for all devices
; Device-specific definitions are introduced by
;
; .devicename
;
; line. Also an optional directive
;
; .default=devicename
;
; designates the default device name.
;
;
.default IQ80960RM/RN
; Common hardware definitions
LED_1_ADDR 0xb0040000
PP_DATA_ADDR 0xb0080004
PP_STAT_ADDR 0xb0080000
SQUALL_BASE_ADDR 0xc0000000
;/*====================================================================*/
.IQ80960RM/RN
;/* define JX memory mapped register addresses */
;/* Common to Jx and Rx: */
DLMCON_ADDR 0xff008100
LMAR0_ADDR 0xff008108
LMMR0_ADDR 0xff00810c
LMAR1_ADDR 0xff008110
LMMR1_ADDR 0xff008114
IPB0_ADDR 0xff008400
IPB1_ADDR 0xff008404
DAB0_ADDR 0xff008420
DAB1_ADDR 0xff008424
BPCON_ADDR 0xff008440
IPND_ADDR 0xff008500
IMSK_ADDR 0xff008504
ICON_ADDR 0xff008510
IMAP0_ADDR 0xff008520
IMAP1_ADDR 0xff008524
IMAP2_ADDR 0xff008528
PMCON0_ADDR 0xff008600
PMCON2_ADDR 0xff008608
PMCON4_ADDR 0xff008610
PMCON6_ADDR 0xff008618
PMCON8_ADDR 0xff008620
PMCON10_ADDR 0xff008628
PMCON12_ADDR 0xff008630
PMCON14_ADDR 0xff008638
BCON_ADDR 0xff0086fc
PRCB_ADDR 0xff008700
ISP_ADDR 0xff008704
SSP_ADDR 0xff008708
DEVID_ADDR 0xff008710
TRR0_ADDR 0xff000300
TCR0_ADDR 0xff000304
TMR0_ADDR 0xff000308
TRR1_ADDR 0xff000310
TCR1_ADDR 0xff000314
TMR1_ADDR 0xff000318
;/* PCI-to-PCI Bridge Unit 0000 1000H through 0000 10FFH */
VIDR_ADDR 0x00001000
DIDR_ADDR 0x00001002
PCMDR_ADDR 0x00001004
PSR_ADDR 0x00001006
RIDR_ADDR 0x00001008
CCR_ADDR 0x00001009
CLSR_ADDR 0x0000100C
PLTR_ADDR 0x0000100D
HTR_ADDR 0x0000100E
;/* Reserved 0x0000100F through 0x00001017 */
PBNR_ADDR 0x00001018
SBNR_ADDR 0x00001019
SUBBNR_ADDR 0x0000101A
SLTR_ADDR 0x0000101B
IOBR_ADDR 0x0000101C
IOLR_ADDR 0x0000101D
SSR_ADDR 0x0000101E
MBR_ADDR 0x00001020
MLR_ADDR 0x00001022
PMBR_ADDR 0x00001024
PMLR_ADDR 0x00001026
;/* Reserved 0x00001028 through 0x00001033 */
BSVIR_ADDR 0x00001034
BSIR_ADDR 0x00001036
;/* Reserved 0x00001038 through 0x0000103D */
BCR_ADDR 0x0000103E
EBCR_ADDR 0x00001040
SISR_ADDR 0x00001042
PBISR_ADDR 0x00001044
SBISR_ADDR 0x00001048
SACR_ADDR 0x0000104C
PIRSR_ADDR 0x00001050
SIOBR_ADDR 0x00001054
SIOLR_ADDR 0x00001055
SCCR_ADDR 0x00001056 /* EAS inconsistent */
SMBR_ADDR 0x00001058
SMLR_ADDR 0x0000105A
SDER_ADDR 0x0000105C
QCR_ADDR 0x0000105E
CDTR_ADDR 0x00001060 /* EAS inconsistent */
;/* Reserved 0x00001064 through 0x000010FFH */
;/* Performance Monitoring Unit 0000 1100H through 0000 11FFH */
GMTR_ADDR 0x00001100
ESR_ADDR 0x00001104
EMISR_ADDR 0x00001108
;/* Reserved 0x0000110C */ /* EAS inconsistent */
GTSR_ADDR 0x00001110 /* EAS inconsistent */
PECR1_ADDR 0x00001114 /* EAS inconsistent */
PECR2_ADDR 0x00001118 /* EAS inconsistent */
PECR3_ADDR 0x0000111C /* EAS inconsistent */
PECR4_ADDR 0x00001120 /* EAS inconsistent */
PECR5_ADDR 0x00001124 /* EAS inconsistent */
PECR6_ADDR 0x00001128 /* EAS inconsistent */
PECR7_ADDR 0x0000112C /* EAS inconsistent */
PECR8_ADDR 0x00001130 /* EAS inconsistent */
PECR9_ADDR 0x00001134 /* EAS inconsistent */
PECR10_ADDR 0x00001138 /* EAS inconsistent */
PECR11_ADDR 0x0000113C /* EAS inconsistent */
PECR12_ADDR 0x00001140 /* EAS inconsistent */
PECR13_ADDR 0x00001144 /* EAS inconsistent */
PECR14_ADDR 0x00001148 /* EAS inconsistent */
;/* Reserved 0x0000104C through 0x000011FFH */ /* EAS inconsistent */
;/* Address Translation Unit 0000 1200H through 0000 12FFH */
ATUVID_ADDR 0x00001200
ATUDID_ADDR 0x00001202
PATUCMD_ADDR 0x00001204
PATUSR_ADDR 0x00001206
ATURID_ADDR 0x00001208
ATUCCR_ADDR 0x00001209
ATUCLSR_ADDR 0x0000120C
ATULT_ADDR 0x0000120D
ATUHTR_ADDR 0x0000120E
ATUBISTR_ADDR 0x0000120F
PIABAR_ADDR 0x00001210
;/* Reserved 0x00001214 through 0x0000122B */
ASVIR_ADDR 0x0000122C
ASIR_ADDR 0x0000122E
ERBAR_ADDR 0x00001230
;/* Reserved 0x00001234 */
;/* Reserved 0x00001238 */
ATUILR_ADDR 0x0000123C
ATUIPR_ADDR 0x0000123D
ATUMGNT_ADDR 0x0000123E
ATUMLAT_ADDR 0x0000123F
PIALR_ADDR 0x00001240
PIATVR_ADDR 0x00001244
SIABAR_ADDR 0x00001248
SIALR_ADDR 0x0000124C
SIATVR_ADDR 0x00001250
POMWVR_ADDR 0x00001254
;/* Reserved 0x00001258 */
POIOWVR_ADDR 0x0000125C
PODWVR_ADDR 0x00001260
POUDR_ADDR 0x00001264
SOMWVR_ADDR 0x00001268
SOIOWVR_ADDR 0x0000126C
;/* Reserved 0x00001270 */
ERLR_ADDR 0x00001274
ERTVR_ADDR 0x00001278
;/* Reserved 0x0000127C */
;/* Reserved 0x00001280 */
;/* Reserved 0x00001284 */
ATUCR_ADDR 0x00001288
;/* Reserved 0x0000128C */
PATUISR_ADDR 0x00001290
SATUISR_ADDR 0x00001294
SATUCMD_ADDR 0x00001298
SATUSR_ADDR 0x0000129A
SODWVR_ADDR 0x0000129C
SOUDR_ADDR 0x000012A0
POCCAR_ADDR 0x000012A4
SOCCAR_ADDR 0x000012A8
POCCDR_ADDR 0x000012AC
SOCCDR_ADDR 0x000012B0
PAQCR_ADDR 0x000012B4
SAQCR_ADDR 0x000012B8
PAIMR_ADDR 0x000012BC
SAIMR_ADDR 0x000012C0
;/* Reserved 0x000012C4 through 0x000012FF */
;/* Messaging Unit 0000 1300H through 0000 130FH */
IMR0_ADDR 0x00001310
IMR1_ADDR 0x00001314
OMR0_ADDR 0x00001318
OMR1_ADDR 0x0000131C
IDR_ADDR 0x00001320
IISR_ADDR 0x00001324
IIMR_ADDR 0x00001328
ODR_ADDR 0x0000132C
OISR_ADDR 0x00001330
OIMR_ADDR 0x00001334
;/* Reserved 0x00001338 through 0x0000134F */
MUCR_ADDR 0x00001350
QBAR_ADDR 0x00001354
;/* Reserved 0x00001358 */
;/* Reserved 0x0000135C */
IFHPR_ADDR 0x00001360
IFTPR_ADDR 0x00001364
IPHPR_ADDR 0x00001368
IPTPR_ADDR 0x0000136C
OFHPR_ADDR 0x00001370
OFTPR_ADDR 0x00001374
OPHPR_ADDR 0x00001378
OPTPR_ADDR 0x0000137C
IAR_ADDR 0x00001380
;/* Reserved 0x00001384 through 0x000013FF */
;/* DMA Controller 0000 1400H through 0000 14FFH */
CCR0_ADDR 0x00001400
CSR0_ADDR 0x00001404
;/* Reserved 0x00001408 */
DAR0_ADDR 0x0000140C
NDAR0_ADDR 0x00001410
PADR0_ADDR 0x00001414
PUADR0_ADDR 0x00001418
LADR0_ADDR 0x0000141C
BCR0_ADDR 0x00001420
DCR0_ADDR 0x00001424
;/* Reserved 0x00001428 through 0x0000143F */
CCR1_ADDR 0x00001440
CSR1_ADDR 0x00001444
;/* Reserved 0x00001448 */
DAR1_ADDR 0x0000144C
NDAR1_ADDR 0x00001450
PADR1_ADDR 0x00001454
PUADR1_ADDR 0x00001458
LADR1_ADDR 0x0000145C
BCR1_ADDR 0x00001460
DCR1_ADDR 0x00001464
;/* Reserved 0x00001468 through 0x0000147F */
CCR2_ADDR 0x00001480
CSR2_ADDR 0x00001484
;/* Reserved 0x00001488 */
DAR2_ADDR 0x0000148C
NDAR2_ADDR 0x00001490
PADR2_ADDR 0x00001494
PUADR2_ADDR 0x00001498
LADR2_ADDR 0x0000149C
BCR2_ADDR 0x000014A0
DCR2_ADDR 0x000014A4
;/* Reserved 0x000014A8 through 0x000014FF */
;/* Memory Controller 0000 1500H through 0000 15FFH */
SDIR_ADDR 0x00001500
SDCR_ADDR 0x00001504
SDBR_ADDR 0x00001508
SBR0_ADDR 0x0000150C
SBR1_ADDR 0x00001510
SDPR0_ADDR 0x00001514
SDPR1_ADDR 0x00001518
SDPR2_ADDR 0x0000151C
SDPR3_ADDR 0x00001520
SDPR4_ADDR 0x00001524
SDPR5_ADDR 0x00001528
SDPR6_ADDR 0x0000152C
SDPR7_ADDR 0x00001530
ECCR_ADDR 0x00001534
ELOG0_ADDR 0x00001538
ELOG1_ADDR 0x0000153C
ECAR0_ADDR 0x00001540
ECAR1_ADDR 0x00001544
ECTST_ADDR 0x00001548
FEBR0_ADDR 0x0000154C
FEBR1_ADDR 0x00001550
FBSR0_ADDR 0x00001554
FBSR1_ADDR 0x00001558
FWSR0_ADDR 0x0000155C
FWSR1_ADDR 0x00001560
MCISR_ADDR 0x00001564
RFR_ADDR 0x00001568
;/* Reserved 0x0000156C through 0x000015FF */
;/* Arbitration Control Unit 0000 1600H through 0000 167FH */
IACR_ADDR 0x00001600
MLTR_ADDR 0x00001604
MTTR_ADDR 0x00001608
;/* Reserved 0x0000160C through 0x0000163F */
;/* Bus Interface Control Unit 0000 1640H through 0000 167FH */
BIUCR_ADDR 0x00001640
BIUISR_ADDR 0x00001644
;/* Reserved 0x00001648 through 0x0000167F */
;/* I2C Bus Interface Unit 0000 1680H through 0000 16FFH */
ICR_ADDR 0x00001680
ISR_ADDR 0x00001684
ISAR_ADDR 0x00001688
IDBR_ADDR 0x0000168C
ICCR_ADDR 0x00001690
IBMR_ADDR 0x00001694
;/* Reserved 0x00001698 through 0x000016FF */
;/* PCI And Peripheral Interrupt Controller 0000 1700H through 0000 17FFH */
NISR_ADDR 0x00001700
X7ISR_ADDR 0x00001704
X6ISR_ADDR 0x00001708
PDIDR_ADDR 0x00001710 /* EAS inconsistent */
;/* Reserved 0x00001714 through 0x0000177F */
;/* Application Accelerator Unit 0000 1800H through 0000 18FFH */
ACR_ADDR 0x00001800
ASR_ADDR 0x00001804
ADAR_ADDR 0x00001808
ANDAR_ADDR 0x0000180C
SAR1_ADDR 0x00001810
SAR2_ADDR 0x00001814
SAR3_ADDR 0x00001818
SAR4_ADDR 0x0000181C
DAR_ADDR 0x00001820
ABCR_ADDR 0x00001824
ADCR_ADDR 0x00001828
SAR5_ADDR 0x0000182C
SAR6_ADDR 0x00001830
SAR7_ADDR 0x00001834
SAR8_ADDR 0x00001838
;/*====================================================================*/
.IQ80960RP
USER_LED_REG 0xe0040000
;/* define JX memory mapped register addresses */
;/* Common to Jx and RP: */
DLMCON_ADDR 0xff008100
LMAR0_ADDR 0xff008108
LMMR0_ADDR 0xff00810c
LMAR1_ADDR 0xff008110
LMMR1_ADDR 0xff008114
IPB0_ADDR 0xff008400
IPB1_ADDR 0xff008404
DAB0_ADDR 0xff008420
DAB1_ADDR 0xff008424
BPCON_ADDR 0xff008440
IPND_ADDR 0xff008500
IMSK_ADDR 0xff008504
ICON_ADDR 0xff008510
IMAP0_ADDR 0xff008520
IMAP1_ADDR 0xff008524
IMAP2_ADDR 0xff008528
PMCON0_ADDR 0xff008600
PMCON2_ADDR 0xff008608
PMCON4_ADDR 0xff008610
PMCON6_ADDR 0xff008618
PMCON8_ADDR 0xff008620
PMCON10_ADDR 0xff008628
PMCON12_ADDR 0xff008630
PMCON14_ADDR 0xff008638
BCON_ADDR 0xff0086fc
PRCB_ADDR 0xff008700
ISP_ADDR 0xff008704
SSP_ADDR 0xff008708
DEVID_ADDR 0xff008710
TRR0_ADDR 0xff000300
TCR0_ADDR 0xff000304
TMR0_ADDR 0xff000308
TRR1_ADDR 0xff000310
TCR1_ADDR 0xff000314
TMR1_ADDR 0xff000318
;/* PCI-to-PCI Bridge Unit 0000 1000H through 0000 10FFH */
VIDR_ADDR 0x00001000
DIDR_ADDR 0x00001002
PCMDR_ADDR 0x00001004
PSR_ADDR 0x00001006
RIDR_ADDR 0x00001008
CCR_ADDR 0x00001009
CLSR_ADDR 0x0000100C
PLTR_ADDR 0x0000100D
HTR_ADDR 0x0000100E
;/* Reserved 0x0000100F through 0x00001017 */
PBNR_ADDR 0x00001018
SBNR_ADDR 0x00001019
SubBNR_ADDR 0x0000101A
SLTR_ADDR 0x0000101B
IOBR_ADDR 0x0000101C
IOLR_ADDR 0x0000101D
SSR_ADDR 0x0000101E
MBR_ADDR 0x00001020
MLR_ADDR 0x00001022
PMBR_ADDR 0x00001024
PMLR_ADDR 0x00001026
;/* Reserved 0x00001028 through 0x00001033 */
BSVIR_ADDR 0x00001034
BSIR_ADDR 0x00001036
;/* Reserved 0x00001038 through 0x0000103D */
BCR_ADDR 0x0000103E
EBCR_ADDR 0x00001040
SISR_ADDR 0x00001042
PBISR_ADDR 0x00001044
SBISR_ADDR 0x00001048
SACR_ADDR 0x0000104C
PRSR_ADDR 0x00001050
;/* rmg 3/13/97....name changed from PRSR to PIRSR */
SIOBR_ADDR 0x00001054
SIOLR_ADDR 0x00001055
SMBR_ADDR 0x00001058
SMLR_ADDR 0x0000105A
SDER_ADDR 0x0000105C
;/* Reserved 0x0000105E through 0x000011FFH */
;/* Address Translation Unit 0000 1200H through 0000 12FFH */
ATUVID_ADDR 0x00001200
ATUDID_ADDR 0x00001202
PATUCMD_ADDR 0x00001204
PATUSR_ADDR 0x00001206
ATURID_ADDR 0x00001208
ATUCCR_ADDR 0x00001209
ATUCLSR_ADDR 0x0000120C
ATULT_ADDR 0x0000120D
ATUHTR_ADDR 0x0000120E
ATUBISTR_ADDR 0x0000120F
PIABAR_ADDR 0x00001210
;/* Reserved 0x00001214 */
;/* Reserved 0x00001218 */
;/* Reserved 0x0000121C */
;/* Reserved 0x00001220 */
;/* Reserved 0x00001224 */
;/* Reserved 0x00001228 */
ASVIR_ADDR 0x0000122C
ASIR_ADDR 0x0000122E
ERBAR_ADDR 0x00001230
;/* Reserved 0x00001234 */
;/* Reserved 0x00001238 */
ATUILR_ADDR 0x0000123C
ATUIPR_ADDR 0x0000123D
ATUMGNT_ADDR 0x0000123E
ATUMLAT_ADDR 0x0000123F
PIALR_ADDR 0x00001240
PIATVR_ADDR 0x00001244
SIABAR_ADDR 0x00001248
SIALR_ADDR 0x0000124C
SIATVR_ADDR 0x00001250
POMWVR_ADDR 0x00001254
;/* Reserved 0x00001258 */
POIOWVR_ADDR 0x0000125
PODWVR_ADDR 0x00001260
POUDR_ADDR 0x00001264
SOMWVR_ADDR 0x00001268
SOIOWVR_ADDR 0x0000126C
;/* Reserved 0x00001270 */
ERLR_ADDR 0x00001274
ERTVR_ADDR 0x00001278
;/* Reserved 0x0000127C */
;/* Reserved 0x00001280 */
;/* Reserved 0x00001284 */
ATUCR_ADDR 0x00001288
;/* Reserved 0x0000128C */
PATUISR_ADDR 0x00001290
SATUISR_ADDR 0x00001294
SATUCMD_ADDR 0x00001298
SATUSR_ADDR 0x0000129A
SODWVR_ADDR 0x0000129C
SOUDR_ADDR 0x000012A0
POCCAR_ADDR 0x000012A4
SOCCAR_ADDR 0x000012A8
POCCDR_ADDR 0x000012AC
SOCCDR_ADDR 0x000012B0
;/* Reserved 0x000012B4 through 0x000012FF */
;/* Messaging Unit 0000 1300H through 0000 13FFH */
ARSR_ADDR 0x00001300
;/* Reserved 0x00001304 */
AWR_ADDR 0x00001308
;/* Reserved 0x0000130C */
IMR0_ADDR 0x00001310
IMR1_ADDR 0x00001314
OMR0_ADDR 0x00001318
OMR1_ADDR 0x0000131C
IDR_ADDR 0x00001320
IISR_ADDR 0x00001324
IIMR_ADDR 0x00001328
ODR_ADDR 0x0000132C
OISR_ADDR 0x00001330
OIMR_ADDR 0x00001334
;/* Reserved 0x00001338 through 0x0000134F */
MUCR_ADDR 0x00001350
QBAR_ADDR 0x00001354
;/* Reserved 0x00001358 */
;/* Reserved 0x0000135C */
IFHPR_ADDR 0x00001360
IFTPR_ADDR 0x00001364
IPHPR_ADDR 0x00001368
IPTPR_ADDR 0x0000136C
OFHPR_ADDR 0x00001370
OFTPR_ADDR 0x00001374
OPHPR_ADDR 0x00001378
OPTPR_ADDR 0x0000137C
IAR_ADDR 0x00001380
;/* Reserved 0x00001384 through 0x000013FF */
;/* DMA Controller 0000 1400H through 0000 14FFH */
CCR0_ADDR 0x00001400
CSR0_ADDR 0x00001404
;/* Reserved 0x00001408 */
DAR0_ADDR 0x0000140C
NDAR0_ADDR 0x00001410
PADR0_ADDR 0x00001414
PUADR0_ADDR 0x00001418
LADR0_ADDR 0x0000141C
BCR0_ADDR 0x00001420
DCR0_ADDR 0x00001424
;/* Reserved 0x00001428 through 0x0000143F */
CCR1_ADDR 0x00001440
CSR1_ADDR 0x00001444
;/* Reserved 0x00001448 */
DAR1_ADDR 0x0000144C
NDAR1_ADDR 0x00001450
PADR1_ADDR 0x00001454
PUADR1_ADDR 0x00001458
LADR1_ADDR 0x0000145C
BCR1_ADDR 0x00001460
DCR1_ADDR 0x00001464
;/* Reserved 0x00001468 through 0x0000147F */
CCR2_ADDR 0x00001480
CSR2_ADDR 0x00001484
;/* Reserved 0x00001488 */
DAR2_ADDR 0x0000148C
NDAR2_ADDR 0x00001490
PADR2_ADDR 0x00001494
PUADR2_ADDR 0x00001498
LADR2_ADDR 0x0000149C
BCR2_ADDR 0x000014A0
DCR2_ADDR 0x000014A4
;/* Reserved 0x000014A8 through 0x000014FF */
;/* Memory Controller 0000 1500H through 0000 15FFH */
MBCR_ADDR 0x00001500
MBBAR0_ADDR 0x00001504
MBRWS0_ADDR 0x00001508
MBWWS0_ADDR 0x0000150C
MBBAR1_ADDR 0x00001510
MBRWS1_ADDR 0x00001514
MBWWS1_ADDR 0x00001518
DBCR_ADDR 0x0000151C
DBAR_ADDR 0x00001520
DRWS_ADDR 0x00001524
DWWS_ADDR 0x00001528
DRIR_ADDR 0x0000152C
DPER_ADDR 0x00001530
BMER_ADDR 0x00001534
MEAR_ADDR 0x00001538
LPISR_ADDR 0x0000153C
;/* Reserved 0x00001540 through 0x000015FF */
;/* Local Bus Arbitration Unit 0000 1600H through 0000 167FH */
LBACR_ADDR 0x00001600
LBALCR_ADDR 0x00001604
;/* Reserved 0x00001608 through 0x0000167F */
;/* I2C Bus Interface Unit 0000 1680H through 0000 16FFH */
ICR_ADDR 0x00001680
ISR_ADDR 0x00001684
ISAR_ADDR 0x00001688
IDBR_ADDR 0x0000168C
ICCR_ADDR 0x00001690
;/* Reserved 0x00001694 through 0x000016FF */
;/* PCI And Peripheral Interrupt Controller 0000 1700H through 0000 177FH */
NISR_ADDR 0x00001700
X7ISR_ADDR 0x00001704
X6ISR_ADDR 0x00001708
PDDIR_ADDR 0x00001710
;/* Reserved 0x00001714 through 0x0000177F */
;/* APIC Bus Interface Unit 0000 1780H through 0000 17FFH */
APICIDR_ADDR 0x00001780
APICARBID_ADDR 0x00001784
EVR_ADDR 0x00001788
IMR_ADDR 0x0000178C
APICCSR_ADDR 0x00001790
;/* Reserved 0x00001794 through 0x000017FF */
;;/*====================================================================*/
.i960CA/JX
LMAR0_ADDR 0xff008108
LMMR0_ADDR 0xff00810c
LMAR1_ADDR 0xff008110
LMMR1_ADDR 0xff008114
IPB0_ADDR 0xff008400
IPB1_ADDR 0xff008404
DAB0_ADDR 0xff008420
DAB1_ADDR 0xff008424
BPCON_ADDR 0xff008440
IPND_ADDR 0xff008500
IMSK_ADDR 0xff008504
ICON_ADDR 0xff008510
IMAP0_ADDR 0xff008520
IMAP1_ADDR 0xff008524
IMAP2_ADDR 0xff008528
PMCON0_ADDR 0xff008600
PMCON2_ADDR 0xff008608
PMCON4_ADDR 0xff008610
PMCON6_ADDR 0xff008618
PMCON8_ADDR 0xff008620
PMCON10_ADDR 0xff008628
PMCON12_ADDR 0xff008630
PMCON14_ADDR 0xff008638
BCON_ADDR 0xff0086fc
PRCB_ADDR 0xff008700
ISP_ADDR 0xff008704
SSP_ADDR 0xff008708
DEVID_ADDR 0xff008710
TRR0_ADDR 0xff000300
TCR0_ADDR 0xff000304
TMR0_ADDR 0xff000308
TRR1_ADDR 0xff000310
TCR1_ADDR 0xff000314
TMR1_ADDR 0xff000318
;/*====================================================================*/
.i960CA/HX
GCON_ADDR 0xff008000
DLMCON 0xff008100
LMAR0_ADDR 0xff008108
LMMR0_ADDR 0xff00810c
LMAR1_ADDR 0xff008110
LMMR1_ADDR 0xff008114
LMAR2_ADDR 0xff008118
LMMR2_ADDR 0xff00811c
LMAR3_ADDR 0xff008120
LMMR3_ADDR 0xff008124
LMAR4_ADDR 0xff008128
LMMR4_ADDR 0xff00812c
LMAR5_ADDR 0xff008130
LMMR5_ADDR 0xff008134
LMAR6_ADDR 0xff008138
LMMR6_ADDR 0xff00813c
LMAR7_ADDR 0xff008140
LMMR7_ADDR 0xff008144
LMAR8_ADDR 0xff008148
LMMR8_ADDR 0xff00814c
LMAR9_ADDR 0xff008150
LMMR9_ADDR 0xff008154
LMAR10_ADDR 0xff008158
LMMR10_ADDR 0xff00815c
LMAR11_ADDR 0xff008160
LMMR11_ADDR 0xff008164
LMAR12_ADDR 0xff008168
LMMR12_ADDR 0xff00816c
LMAR13_ADDR 0xff008170
LMMR13_ADDR 0xff008174
LMAR14_ADDR 0xff008178
LMMR14_ADDR 0xff00817c
LMAR15_ADDR 0xff008180
LMMR15_ADDR 0xff008184
IPB0_ADDR 0xff008400
IPB1_ADDR 0xff008404
IPB2_ADDR 0xff008408
IPB3_ADDR 0xff00840c
IPB4_ADDR 0xff008410
IPB5_ADDR 0xff008414
DAB0_ADDR 0xff008420
DAB1_ADDR 0xff008424
DAB2_ADDR 0xff008428
DAB3_ADDR 0xff00842c
DAB4_ADDR 0xff008430
DAB5_ADDR 0xff008434
BPCON_ADDR 0xff008440
XBPCON_ADDR 0xff008444
IPND_ADDR 0xff008500
IMSK_ADDR 0xff008504
ICON_ADDR 0xff008510
IMAP0_ADDR 0xff008520
IMAP1_ADDR 0xff008524
IMAP2_ADDR 0xff008528
PMCON0_ADDR 0xff008600
PMCON1_ADDR 0xff008604
PMCON2_ADDR 0xff008608
PMCON3_ADDR 0xff00860c
PMCON4_ADDR 0xff008610
PMCON5_ADDR 0xff008614
PMCON6_ADDR 0xff008618
PMCON7_ADDR 0xff00861c
PMCON8_ADDR 0xff008620
PMCON9_ADDR 0xff008624
PMCON10_ADDR 0xff008628
PMCON11_ADDR 0xff00862c
PMCON12_ADDR 0xff008630
PMCON13_ADDR 0xff008634
PMCON14_ADDR 0xff008638
PMCON15_ADDR 0xff00863c
BCON_ADDR 0xff0086fc
PRCB_ADDR 0xff008700
ISP_ADDR 0xff008704
SSP_ADDR 0xff008708
DEVID_ADDR 0xff008710
TRR0_ADDR 0xff000300
TCR0_ADDR 0xff000304
TMR0_ADDR 0xff000308
TRR1_ADDR 0xff000310
TCR1_ADDR 0xff000314
TMR1_ADDR 0xff000318
MPAR0_ADDR 0xff008010
MPAMR0_ADDR 0xff008014
MPAR1_ADDR 0xff008018
MPAMR1_ADDR 0xff00801c
MDUB0_ADDR 0xff008080
MDLB0_ADDR 0xff008084
MDUB1_ADDR 0xff008088
MDLB1_ADDR 0xff00808c
MDUB2_ADDR 0xff008090
MDLB2_ADDR 0xff008094
MDUB3_ADDR 0xff008098
MDLB3_ADDR 0xff00809c
MDUB4_ADDR 0xff0080a0
MDLB5_ADDR 0xff0080a4
MDUB5_ADDR 0xff0080a8
MDLB4_ADDR 0xff0080ac

View File

@@ -0,0 +1,127 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-2001 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* E-mail: ig@datarescue.com
*
*
*/
#ifndef _I960_HPP
#define _I960_HPP
#include "../idaidp.hpp"
#include <diskio.hpp>
#include "ins.hpp"
#include "../iohandler.hpp"
// Absolute offset (<4096) offset exp MEMA o_imm
// Absolute displacement disp exp MEMB o_imm
// Register Indirect abase (reg) o_phrase, index=-1, scale=1
// with offset abase+offset exp(reg) o_displ, index=-1,scale=1
// with displacement abase+disp exp(reg) o_displ, index=-1,scale=1
// with index abase+(index*scale) (reg)[reg*scale] o_phrase, index=index
// with index and displacement abase+(index*scale)+disp exp(reg)[reg*scale] o_displ
// Index with displacement (index*scale) + disp exp[reg*scale] o_displ, reg=index, index=-1
// IP with displacement IP+disp+8 exp(IP) o_near
#define index specflag1 // o_displ, o_phrase
#define scale specflag2 // o_displ, o_phrase
#define aux_t 0x0001 // .t suffix
#define aux_f 0x0002 // .f suffix
#define aux_ip 0x0004 // ip relative addressing
//------------------------------------------------------------------
enum regnum_t
{
LR0, LR1, LR2, LR3, LR4, LR5, LR6, LR7,
LR8, LR9, LR10, LR11, LR12, LR13, LR14, LR15,
GR0, GR1, GR2, GR3, GR4, GR5, GR6, GR7,
GR8, GR9, GR10, GR11, GR12, GR13, GR14, GR15,
SF0, SF31=SF0+31,
PC, AC, IP, TC,
FP0, FP1, FP2, FP3,
ds, cs,
MAXREG = cs,
PFP = LR0,
SP = LR1,
RIP = LR2,
FP = GR15,
IPND = SF0+0,
IMSK = SF0+1,
DMAC = SF0+2,
};
//------------------------------------------------------------------
ea_t calc_mem(const insn_t &insn, ea_t ea); // map virtual to physical ea
//------------------------------------------------------------------
void idaapi i960_header(outctx_t &ctx);
void idaapi i960_segend(outctx_t &ctx, segment_t *seg);
void idaapi i960_assumes(outctx_t &ctx); // function to produce assume directives
int idaapi is_align_insn(ea_t ea);
//------------------------------------------------------------------
struct tabent_t
{
ushort itype;
char opnum;
char dtype;
};
//------------------------------------------------------------------
struct i960_iohandler_t : public iohandler_t
{
struct i960_t &pm;
i960_iohandler_t(i960_t &_pm, netnode &nn) : iohandler_t(nn), pm(_pm) {}
};
struct i960_t : public procmod_t
{
netnode helper;
i960_iohandler_t ioh = i960_iohandler_t(*this, helper);
ushort idpflags;
#define IDP_STRICT 0x0001 // Strictly adhere to instruction encodings
inline bool is_strict(void) { return (idpflags & IDP_STRICT) != 0; }
void save_idpflags() { helper.altset(-1, idpflags); }
#define REG_MIN 0x580
#define REG_MAX 0x7f4
struct tabent_t reg_tab_buf[REG_MAX - REG_MIN + 1];
struct tabent_t *reg_tab = nullptr;
bool flow;
virtual ssize_t idaapi on_event(ssize_t msgid, va_list va) override;
void load_symbols(void);
const char *find_sym(ea_t address);
void choose_device();
const char *set_idp_options(
const char *keyword,
int value_type,
const void * value,
bool idb_loaded);
bool ctrl(insn_t &insn, uint32 code);
bool opmemory(insn_t &insn, op_t &x, uint32 code, char dtype);
bool mem(insn_t &insn, uint32 code);
int i960_ana(insn_t *_insn);
bool reg(insn_t &insn, uint32 code);
void handle_operand(const insn_t &insn, const op_t &x, bool isload);
int i960_emu(const insn_t &insn);
void i960_segstart(outctx_t &ctx, segment_t *Sarea) const;
void i960_footer(outctx_t &ctx) const;
void load_from_idb();
};
extern int data_id;
#define PROCMOD_NODE_NAME "$ i960"
#define PROCMOD_NAME i960
#endif // _I960_HPP

View File

@@ -0,0 +1,286 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-2001 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* E-mail: ig@datarescue.com
*
*
*/
#include "i960.hpp"
const instruc_t Instructions[] =
{
{ "", 0 }, // Unknown Operation
{ "addc", CF_USE1|CF_USE2|CF_CHG3 }, // Add ordinal with carry
{ "addi", CF_USE1|CF_USE2|CF_CHG3 }, // Add integer
{ "addo", CF_USE1|CF_USE2|CF_CHG3 }, // Add ordinal
{ "alterbit", CF_USE1|CF_USE2|CF_CHG3 }, // Alter bit
{ "and", CF_USE1|CF_USE2|CF_CHG3 }, // Src2 AND src1
{ "andnot", CF_USE1|CF_USE2|CF_CHG3 }, // Src2 AND (NOT src1)
{ "atadd", CF_USE1|CF_USE2|CF_CHG3 }, // Atomic add
{ "atmod", CF_USE1|CF_USE2|CF_USE3|CF_CHG3 }, // Atomic modify
{ "b", CF_USE1|CF_STOP }, // Branch
{ "bal", CF_USE1|CF_CALL }, // Branch and Link
{ "balx", CF_USE1|CF_CHG2|CF_CALL }, // Branch and Link Extended
{ "bbc", CF_USE1|CF_USE2|CF_USE3 }, // Check bit and branch if clear
{ "bbs", CF_USE1|CF_USE2|CF_USE3 }, // Check bit and branch if set
{ "bno", CF_USE1 }, // Branch if unordered/false
{ "bg", CF_USE1 }, // Branch if greater
{ "be", CF_USE1 }, // Branch if equal/true
{ "bge", CF_USE1 }, // Branch if greater or equal
{ "bl", CF_USE1 }, // Branch if less
{ "bne", CF_USE1 }, // Branch if not equal
{ "ble", CF_USE1 }, // Branch if less or equal
{ "bo", CF_USE1 }, // Branch if ordered
{ "bx", CF_USE1|CF_STOP }, // Branch Extended
{ "call", CF_USE1|CF_CALL }, // Call
{ "calls", CF_USE1|CF_CALL }, // Call system
{ "callx", CF_USE1|CF_CALL }, // Call extended
{ "chkbit", CF_USE1|CF_USE2 }, // Check bit
{ "clrbit", CF_USE1|CF_USE2|CF_CHG3 }, // Clear bit
{ "cmpdeci", CF_USE1|CF_USE2|CF_CHG3 }, // Compare and decrement integer
{ "cmpdeco", CF_USE1|CF_USE2|CF_CHG3 }, // Compare and decrement ordinal
{ "cmpi", CF_USE1|CF_USE2 }, // Compare integer
{ "cmpibno", CF_USE1|CF_USE2|CF_USE3 }, // Compare integer and branch if unordered
{ "cmpibg", CF_USE1|CF_USE2|CF_USE3 }, // Compare integer and branch if greater
{ "cmpibe", CF_USE1|CF_USE2|CF_USE3 }, // Compare integer and branch if equal
{ "cmpibge", CF_USE1|CF_USE2|CF_USE3 }, // Compare integer and branch if greater or equal
{ "cmpibl", CF_USE1|CF_USE2|CF_USE3 }, // Compare integer and branch if less
{ "cmpibne", CF_USE1|CF_USE2|CF_USE3 }, // Compare integer and branch if not equal
{ "cmpible", CF_USE1|CF_USE2|CF_USE3 }, // Compare integer and branch if less or equal
{ "cmpibo", CF_USE1|CF_USE2|CF_USE3 }, // Compare integer and branch if ordered
{ "cmpinci", CF_USE1|CF_USE2|CF_CHG3 }, // Compare and increment integer
{ "cmpinco", CF_USE1|CF_USE2|CF_CHG3 }, // Compare and increment ordinal
{ "cmpo", CF_USE1|CF_USE2 }, // Compare ordinal
{ "cmpobg", CF_USE1|CF_USE2|CF_USE3 }, // Compare ordinal and branch if greater
{ "cmpobe", CF_USE1|CF_USE2|CF_USE3 }, // Compare ordinal and branch if equal
{ "cmpobge", CF_USE1|CF_USE2|CF_USE3 }, // Compare ordinal and branch if greater or equal
{ "cmpobl", CF_USE1|CF_USE2|CF_USE3 }, // Compare ordinal and branch if less
{ "cmpobne", CF_USE1|CF_USE2|CF_USE3 }, // Compare ordinal and branch if not equal
{ "cmpoble", CF_USE1|CF_USE2|CF_USE3 }, // Compare ordinal and branch if less or equal
{ "concmpi", CF_USE1|CF_USE2 }, // Conditional compare integer
{ "concmpo", CF_USE1|CF_USE2 }, // Conditional compare ordinal
{ "divi", CF_USE1|CF_USE2|CF_CHG3 }, // Divide integer
{ "divo", CF_USE1|CF_USE2|CF_CHG3 }, // Divide ordinal
{ "ediv", CF_USE1|CF_USE2|CF_CHG3 }, // Extended divide
{ "emul", CF_USE1|CF_USE2|CF_CHG3 }, // Extended multiply
{ "eshro", CF_USE1|CF_USE2|CF_CHG3 }, // Extended shift right ordinal
{ "extract", CF_USE1|CF_USE2|CF_USE3|CF_CHG3 }, // Extract
{ "faultno", 0 }, // Fault if unordered
{ "faultg", 0 }, // Fault if greater
{ "faulte", 0 }, // Fault if equal
{ "faultge", 0 }, // Fault if greater or equal
{ "faultl", 0 }, // Fault if less
{ "faultne", 0 }, // Fault if not equal
{ "faultle", 0 }, // Fault if less or equal
{ "faulto", 0 }, // Fault if ordered
{ "flushreg", 0 }, // Flush cached local register sets to memory
{ "fmark", 0 }, // Force mark
{ "ld", CF_USE1|CF_CHG2 }, // Load word
{ "lda", CF_USE1|CF_CHG2 }, // Load address
{ "ldib", CF_USE1|CF_CHG2 }, // Load integer byte
{ "ldis", CF_USE1|CF_CHG2 }, // Load integer short
{ "ldl", CF_USE1|CF_CHG2 }, // Load long
{ "ldob", CF_USE1|CF_CHG2 }, // Load ordinal byte
{ "ldos", CF_USE1|CF_CHG2 }, // Load ordinal short
{ "ldq", CF_USE1|CF_CHG2 }, // Load quad
{ "ldt", CF_USE1|CF_CHG2 }, // Load triple
{ "mark", 0 }, // Mark
{ "modac", CF_USE1|CF_USE2|CF_CHG3 }, // Modify the AC register
{ "modi", CF_USE1|CF_USE2|CF_CHG3 }, // Modulo integer
{ "modify", CF_USE1|CF_USE2|CF_USE3|CF_CHG3 }, // Modify
{ "modpc", CF_USE1|CF_USE2|CF_USE3|CF_CHG3 }, // Modify the process controls register
{ "modtc", CF_USE1|CF_USE2|CF_CHG3 }, // Modify trace controls
{ "mov", CF_USE1|CF_CHG2 }, // Move word
{ "movl", CF_USE1|CF_CHG2 }, // Move long word
{ "movq", CF_USE1|CF_CHG2 }, // Move quad word
{ "movt", CF_USE1|CF_CHG2 }, // Move triple word
{ "muli", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply integer
{ "mulo", CF_USE1|CF_USE2|CF_CHG3 }, // Multiply ordinal
{ "nand", CF_USE1|CF_USE2|CF_CHG3 }, // NOT (src2 AND src1)
{ "nor", CF_USE1|CF_USE2|CF_CHG3 }, // NOT (src2 OR src1)
{ "not", CF_USE1|CF_CHG2 }, // NOT src1
{ "notand", CF_USE1|CF_USE2|CF_CHG3 }, // (NOT src2) AND src1
{ "notbit", CF_USE1|CF_USE2|CF_CHG3 }, // Not bit
{ "notor", CF_USE1|CF_USE2|CF_CHG3 }, // (NOT src2) or src1
{ "or", CF_USE1|CF_USE2|CF_CHG3 }, // Src2 OR src1
{ "ornot", CF_USE1|CF_USE2|CF_CHG3 }, // Src2 or (NOT src1)
{ "remi", CF_USE1|CF_USE2|CF_CHG3 }, // Remainder integer
{ "remo", CF_USE1|CF_USE2|CF_CHG3 }, // Remainder ordinal
{ "ret", CF_STOP }, // Return
{ "rotate", CF_USE1|CF_USE2|CF_CHG3 }, // Rotate left
{ "scanbit", CF_USE1|CF_CHG2 }, // Scan for bit
{ "scanbyte", CF_USE1|CF_USE2 }, // Scan byte equal
{ "setbit", CF_USE1|CF_USE2|CF_CHG3 }, // Set bit
{ "shli", CF_USE1|CF_USE2|CF_CHG3 }, // Shift left integer
{ "shlo", CF_USE1|CF_USE2|CF_CHG3 }, // Shift left ordinal
{ "shrdi", CF_USE1|CF_USE2|CF_CHG3 }, // Shift right dividing integer
{ "shri", CF_USE1|CF_USE2|CF_CHG3 }, // Shift right integer
{ "shro", CF_USE1|CF_USE2|CF_CHG3 }, // Shift right ordinal
{ "spanbit", CF_USE1|CF_CHG2 }, // Span over bit
{ "st", CF_USE1|CF_CHG2 }, // Store word
{ "stib", CF_USE1|CF_CHG2 }, // Store integer byte
{ "stis", CF_USE1|CF_CHG2 }, // Store integer short
{ "stl", CF_USE1|CF_CHG2 }, // Store long
{ "stob", CF_USE1|CF_CHG2 }, // Store ordinal byte
{ "stos", CF_USE1|CF_CHG2 }, // Store ordinal short
{ "stq", CF_USE1|CF_CHG2 }, // Store quad
{ "stt", CF_USE1|CF_CHG2 }, // Store triple
{ "subc", CF_USE1|CF_USE2|CF_CHG3 }, // Subtract ordinal with carry
{ "subi", CF_USE1|CF_USE2|CF_CHG3 }, // Subtract integer
{ "subo", CF_USE1|CF_USE2|CF_CHG3 }, // Subtract ordinal
{ "syncf", 0 }, // Synchronize faults
{ "testno", CF_CHG1 }, // Test for unordered
{ "testg", CF_CHG1 }, // Test for greater
{ "teste", CF_CHG1 }, // Test for equal
{ "testge", CF_CHG1 }, // Test for greater or equal
{ "testl", CF_CHG1 }, // Test for less
{ "testne", CF_CHG1 }, // Test for not equal
{ "testle", CF_CHG1 }, // Test for less or equal
{ "testo", CF_CHG1 }, // Test for ordered
{ "xnor", CF_USE1|CF_USE2|CF_CHG3 }, // Src2 XNOR src1
{ "xor", CF_USE1|CF_USE2|CF_CHG3 }, // Src2 XOR src1
// Cx instructions
{ "sdma", CF_USE1|CF_USE2|CF_USE3 }, // Set up a DMA controller channel
{ "sysctl", CF_USE1|CF_USE2|CF_USE3 }, // Perform system control function
{ "udma", 0 }, // Copy current DMA pointers to internal data RAM
// Unknown instructions
{ "dcinva", CF_USE1 },
{ "cmpob", CF_USE1|CF_USE2 },
{ "cmpib", CF_USE1|CF_USE2 },
{ "cmpos", CF_USE1|CF_USE2 },
{ "cmpis", CF_USE1|CF_USE2 },
{ "bswap", CF_USE1|CF_CHG2 },
{ "intdis", 0 },
{ "inten", 0 },
{ "synmov", CF_USE1|CF_USE2 },
{ "synmovl", CF_USE1|CF_USE2 },
{ "synmovq", CF_USE1|CF_USE2 },
{ "cmpstr", CF_USE1|CF_USE2|CF_CHG3 },
{ "movqstr", CF_USE1|CF_USE2|CF_CHG3 },
{ "movstr", CF_USE1|CF_USE2|CF_CHG3 },
{ "inspacc", CF_USE1|CF_CHG2 },
{ "ldphy", CF_USE1|CF_CHG2 },
{ "synld", CF_USE1|CF_CHG2 },
{ "fill", CF_USE1|CF_USE2|CF_CHG3 },
{ "daddc", CF_USE1|CF_USE2|CF_CHG3 },
{ "dsubc", CF_USE1|CF_USE2|CF_CHG3 },
{ "dmovt", CF_USE1|CF_CHG2 },
{ "condrec", CF_USE1|CF_CHG2 },
{ "receive", CF_USE1|CF_CHG2 },
{ "intctl", CF_USE1|CF_CHG2 },
{ "icctl", CF_USE1|CF_USE2|CF_CHG3 },
{ "dcctl", CF_USE1|CF_USE2|CF_CHG3 },
{ "halt", CF_USE1|CF_STOP },
{ "send", CF_USE1|CF_USE2|CF_CHG3 },
{ "sendserv", CF_USE1 },
{ "resumprcs", CF_USE1 },
{ "schedprcs", CF_USE1 },
{ "saveprcs", 0 },
{ "condwait", CF_USE1 },
{ "wait", CF_USE1 },
{ "signal", CF_USE1 },
{ "ldtime", CF_CHG1 },
{ "addono", CF_USE1|CF_USE2|CF_CHG3 },
{ "addino", CF_USE1|CF_USE2|CF_CHG3 },
{ "subono", CF_USE1|CF_USE2|CF_CHG3 },
{ "subino", CF_USE1|CF_USE2|CF_CHG3 },
{ "selno", CF_USE1|CF_USE2|CF_CHG3 },
{ "addog", CF_USE1|CF_USE2|CF_CHG3 },
{ "addig", CF_USE1|CF_USE2|CF_CHG3 },
{ "subog", CF_USE1|CF_USE2|CF_CHG3 },
{ "subig", CF_USE1|CF_USE2|CF_CHG3 },
{ "selg", CF_USE1|CF_USE2|CF_CHG3 },
{ "addoe", CF_USE1|CF_USE2|CF_CHG3 },
{ "addie", CF_USE1|CF_USE2|CF_CHG3 },
{ "suboe", CF_USE1|CF_USE2|CF_CHG3 },
{ "subie", CF_USE1|CF_USE2|CF_CHG3 },
{ "sele", CF_USE1|CF_USE2|CF_CHG3 },
{ "addoge", CF_USE1|CF_USE2|CF_CHG3 },
{ "addige", CF_USE1|CF_USE2|CF_CHG3 },
{ "suboge", CF_USE1|CF_USE2|CF_CHG3 },
{ "subige", CF_USE1|CF_USE2|CF_CHG3 },
{ "selge", CF_USE1|CF_USE2|CF_CHG3 },
{ "addol", CF_USE1|CF_USE2|CF_CHG3 },
{ "addil", CF_USE1|CF_USE2|CF_CHG3 },
{ "subol", CF_USE1|CF_USE2|CF_CHG3 },
{ "subil", CF_USE1|CF_USE2|CF_CHG3 },
{ "sell", CF_USE1|CF_USE2|CF_CHG3 },
{ "addone", CF_USE1|CF_USE2|CF_CHG3 },
{ "addine", CF_USE1|CF_USE2|CF_CHG3 },
{ "subone", CF_USE1|CF_USE2|CF_CHG3 },
{ "subine", CF_USE1|CF_USE2|CF_CHG3 },
{ "selne", CF_USE1|CF_USE2|CF_CHG3 },
{ "addole", CF_USE1|CF_USE2|CF_CHG3 },
{ "addile", CF_USE1|CF_USE2|CF_CHG3 },
{ "subole", CF_USE1|CF_USE2|CF_CHG3 },
{ "subile", CF_USE1|CF_USE2|CF_CHG3 },
{ "selle", CF_USE1|CF_USE2|CF_CHG3 },
{ "addoo", CF_USE1|CF_USE2|CF_CHG3 },
{ "addio", CF_USE1|CF_USE2|CF_CHG3 },
{ "suboo", CF_USE1|CF_USE2|CF_CHG3 },
{ "subio", CF_USE1|CF_USE2|CF_CHG3 },
{ "selo", CF_USE1|CF_USE2|CF_CHG3 },
// Floating point instructions
{ "addr", CF_USE1|CF_USE2|CF_CHG3 },
{ "addrl", CF_USE1|CF_USE2|CF_CHG3 },
{ "atanr", CF_USE1|CF_USE2|CF_CHG3 },
{ "atanrl", CF_USE1|CF_USE2|CF_CHG3 },
{ "classr", CF_USE1 },
{ "classrl", CF_USE1 },
{ "cmpor", CF_USE1|CF_USE2 },
{ "cmporl", CF_USE1|CF_USE2 },
{ "cmpr", CF_USE1|CF_USE2 },
{ "cmprl", CF_USE1|CF_USE2 },
{ "cosr", CF_USE1|CF_CHG2 },
{ "cosrl", CF_USE1|CF_CHG2 },
{ "cpyrsre", CF_USE1|CF_USE2|CF_CHG3 },
{ "cpysre", CF_USE1|CF_USE2|CF_CHG3 },
{ "cvtilr", CF_USE1|CF_CHG2 },
{ "cvtir", CF_USE1|CF_CHG2 },
{ "cvtri", CF_USE1|CF_CHG2 },
{ "cvtril", CF_USE1|CF_CHG2 },
{ "cvtzri", CF_USE1|CF_CHG2 },
{ "cvtzril", CF_USE1|CF_CHG2 },
{ "divr", CF_USE1|CF_USE2|CF_CHG3 },
{ "divrl", CF_USE1|CF_USE2|CF_CHG3 },
{ "expr", CF_USE1|CF_CHG2 },
{ "exprl", CF_USE1|CF_CHG2 },
{ "logbnr", CF_USE1|CF_CHG2 },
{ "logbnrl", CF_USE1|CF_CHG2 },
{ "logepr", CF_USE1|CF_USE2|CF_CHG3 },
{ "logeprl", CF_USE1|CF_USE2|CF_CHG3 },
{ "logr", CF_USE1|CF_USE2|CF_CHG3 },
{ "logrl", CF_USE1|CF_USE2|CF_CHG3 },
{ "movr", CF_USE1|CF_CHG2 },
{ "movre", CF_USE1|CF_CHG2 },
{ "movrl", CF_USE1|CF_CHG2 },
{ "mulr", CF_USE1|CF_USE2|CF_CHG3 },
{ "mulrl", CF_USE1|CF_USE2|CF_CHG3 },
{ "remr", CF_USE1|CF_USE2|CF_CHG3 },
{ "remrl", CF_USE1|CF_USE2|CF_CHG3 },
{ "roundr", CF_USE1|CF_CHG2 },
{ "roundrl", CF_USE1|CF_CHG2 },
{ "scaler", CF_USE1|CF_USE2|CF_CHG3 },
{ "scalerl", CF_USE1|CF_USE2|CF_CHG3 },
{ "sinr", CF_USE1|CF_CHG2 },
{ "sinrl", CF_USE1|CF_CHG2 },
{ "sqrtr", CF_USE1|CF_CHG2 },
{ "sqrtrl", CF_USE1|CF_CHG2 },
{ "subr", CF_USE1|CF_USE2|CF_CHG3 },
{ "subrl", CF_USE1|CF_USE2|CF_CHG3 },
{ "tanr", CF_USE1|CF_CHG2 },
{ "tanrl", CF_USE1|CF_CHG2 },
};
CASSERT(qnumber(Instructions) == I960_last);

View File

@@ -0,0 +1,288 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-2021 Hex-Rays
* ALL RIGHTS RESERVED.
*
*/
#ifndef __INSTRS_HPP
#define __INSTRS_HPP
extern const instruc_t Instructions[];
enum nameNum
{
I960_null = 0, // Unknown Operation
I960_addc, // Add ordinal with carry
I960_addi, // Add integer
I960_addo, // Add ordinal
I960_alterbit, // Alter bit
I960_and, // Src2 AND src1
I960_andnot, // Src2 AND (NOT src1)
I960_atadd, // Atomic add
I960_atmod, // Atomic modify
I960_b, // Branch
I960_bal, // Branch and Link
I960_balx, // Branch and Link Extended
I960_bbc, // Check bit and branch if clear
I960_bbs, // Check bit and branch if set
I960_bno, // Branch if unordered/false
I960_bg, // Branch if greater
I960_be, // Branch if equal/true
I960_bge, // Branch if greater or equal
I960_bl, // Branch if less
I960_bne, // Branch if not equal
I960_ble, // Branch if less or equal
I960_bo, // Branch if ordered
I960_bx, // Branch Extended
I960_call, // Call
I960_calls, // Call system
I960_callx, // Call extended
I960_chkbit, // Check bit
I960_clrbit, // Clear bit
I960_cmpdeci, // Compare and decrement integer
I960_cmpdeco, // Compare and decrement ordinal
I960_cmpi, // Compare integer
I960_cmpibno, // Compare integer and branch if unordered
I960_cmpibg, // Compare integer and branch if greater
I960_cmpibe, // Compare integer and branch if equal
I960_cmpibge, // Compare integer and branch if greater or equal
I960_cmpibl, // Compare integer and branch if less
I960_cmpibne, // Compare integer and branch if not equal
I960_cmpible, // Compare integer and branch if less or equal
I960_cmpibo, // Compare integer and branch if ordered
I960_cmpinci, // Compare and increment integer
I960_cmpinco, // Compare and increment ordinal
I960_cmpo, // Compare ordinal
I960_cmpobg, // Compare ordinal and branch if greater
I960_cmpobe, // Compare ordinal and branch if equal
I960_cmpobge, // Compare ordinal and branch if greater or equal
I960_cmpobl, // Compare ordinal and branch if less
I960_cmpobne, // Compare ordinal and branch if not equal
I960_cmpoble, // Compare ordinal and branch if less or equal
I960_concmpi, // Conditional compare integer
I960_concmpo, // Conditional compare ordinal
I960_divi, // Divide integer
I960_divo, // Divide ordinal
I960_ediv, // Extended divide
I960_emul, // Extended multiply
I960_eshro, // Extended shift right ordinal
I960_extract, // Extract
I960_faultno, // Fault if unordered
I960_faultg, // Fault if greater
I960_faulte, // Fault if equal
I960_faultge, // Fault if greater or equal
I960_faultl, // Fault if less
I960_faultne, // Fault if not equal
I960_faultle, // Fault if less or equal
I960_faulto, // Fault if ordered
I960_flushreg, // Flush cached local register sets to memory
I960_fmark, // Force mark
I960_ld, // Load word
I960_lda, // Load address
I960_ldib, // Load integer byte
I960_ldis, // Load integer short
I960_ldl, // Load long
I960_ldob, // Load ordinal byte
I960_ldos, // Load ordinal short
I960_ldq, // Load quad
I960_ldt, // Load triple
I960_mark, // Mark
I960_modac, // Modify the AC register
I960_modi, // Modulo integer
I960_modify, // Modify
I960_modpc, // Modify the process controls register
I960_modtc, // Modify trace controls
I960_mov, // Move word
I960_movl, // Move long word
I960_movq, // Move quad word
I960_movt, // Move triple word
I960_muli, // Multiply integer
I960_mulo, // Multiply ordinal
I960_nand, // NOT (src2 AND src1)
I960_nor, // NOT (src2 OR src1)
I960_not, // NOT src1
I960_notand, // (NOT src2) AND src1
I960_notbit, // Not bit
I960_notor, // (NOT src2) or src1
I960_or, // Src2 OR src1
I960_ornot, // Src2 or (NOT src1)
I960_remi, // Remainder integer
I960_remo, // Remainder ordinal
I960_ret, // Return
I960_rotate, // Rotate left
I960_scanbit, // Scan for bit
I960_scanbyte, // Scan byte equal
I960_setbit, // Set bit
I960_shli, // Shift left integer
I960_shlo, // Shift left ordinal
I960_shrdi, // Shift right dividing integer
I960_shri, // Shift right integer
I960_shro, // Shift right ordinal
I960_spanbit, // Span over bit
I960_st, // Store word
I960_stib, // Store integer byte
I960_stis, // Store integer short
I960_stl, // Store long
I960_stob, // Store ordinal byte
I960_stos, // Store ordinal short
I960_stq, // Store quad
I960_stt, // Store triple
I960_subc, // Subtract ordinal with carry
I960_subi, // Subtract integer
I960_subo, // Subtract ordinal
I960_syncf, // Synchronize faults
I960_testno, // Test for unordered
I960_testg, // Test for greater
I960_teste, // Test for equal
I960_testge, // Test for greater or equal
I960_testl, // Test for less
I960_testne, // Test for not equal
I960_testle, // Test for less or equal
I960_testo, // Test for ordered
I960_xnor, // Src2 XNOR src1
I960_xor, // Src2 XOR src1
// Cx instructions
I960_sdma, // Set up a DMA controller channel
I960_sysctl, // Perform system control function
I960_udma, // Copy current DMA pointers to internal data RAM
// Unknown instructions
I960_dcinva,
I960_cmpob,
I960_cmpib,
I960_cmpos,
I960_cmpis,
I960_bswap,
I960_intdis,
I960_inten,
I960_synmov,
I960_synmovl,
I960_synmovq,
I960_cmpstr,
I960_movqstr,
I960_movstr,
I960_inspacc,
I960_ldphy,
I960_synld,
I960_fill,
I960_daddc,
I960_dsubc,
I960_dmovt,
I960_condrec,
I960_receive,
I960_intctl,
I960_icctl,
I960_dcctl,
I960_halt,
I960_send,
I960_sendserv,
I960_resumprcs,
I960_schedprcs,
I960_saveprcs,
I960_condwait,
I960_wait,
I960_signal,
I960_ldtime,
I960_addono,
I960_addino,
I960_subono,
I960_subino,
I960_selno,
I960_addog,
I960_addig,
I960_subog,
I960_subig,
I960_selg,
I960_addoe,
I960_addie,
I960_suboe,
I960_subie,
I960_sele,
I960_addoge,
I960_addige,
I960_suboge,
I960_subige,
I960_selge,
I960_addol,
I960_addil,
I960_subol,
I960_subil,
I960_sell,
I960_addone,
I960_addine,
I960_subone,
I960_subine,
I960_selne,
I960_addole,
I960_addile,
I960_subole,
I960_subile,
I960_selle,
I960_addoo,
I960_addio,
I960_suboo,
I960_subio,
I960_selo,
// Floating point instructions
I960_faddr, I960_fp_first = I960_faddr,
I960_faddrl,
I960_fatanr,
I960_fatanrl,
I960_fclassr,
I960_fclassrl,
I960_fcmpor,
I960_fcmporl,
I960_fcmpr,
I960_fcmprl,
I960_fcosr,
I960_fcosrl,
I960_fcpyrsre,
I960_fcpysre,
I960_fcvtilr,
I960_fcvtir,
I960_fcvtri,
I960_fcvtril,
I960_fcvtzri,
I960_fcvtzril,
I960_fdivr,
I960_fdivrl,
I960_fexpr,
I960_fexprl,
I960_flogbnr,
I960_flogbnrl,
I960_flogepr,
I960_flogeprl,
I960_flogr,
I960_flogrl,
I960_fmovr,
I960_fmovre,
I960_fmovrl,
I960_fmulr,
I960_fmulrl,
I960_fremr,
I960_fremrl,
I960_froundr,
I960_froundrl,
I960_fscaler,
I960_fscalerl,
I960_fsinr,
I960_fsinrl,
I960_fsqrtr,
I960_fsqrtrl,
I960_fsubr,
I960_fsubrl,
I960_ftanr,
I960_ftanrl, I960_fp_last = I960_ftanrl,
I960_last,
};
#endif

View File

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

View File

@@ -0,0 +1,253 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-2001 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* E-mail: ig@datarescue.com
*
*
*/
#include "i960.hpp"
//----------------------------------------------------------------------
class out_i960_t : public outctx_t
{
out_i960_t(void) = delete; // not used
i960_t &pm() { return *static_cast<i960_t *>(procmod); }
public:
void outreg(int r);
bool outmem(const op_t &x, ea_t ea, bool printerr = true);
bool out_operand(const op_t &x);
void out_insn(void);
void out_proc_mnem(void);
};
CASSERT(sizeof(out_i960_t) == sizeof(outctx_t));
DECLARE_OUT_FUNCS(out_i960_t)
//----------------------------------------------------------------------
void out_i960_t::outreg(int r)
{
if ( r > MAXREG )
warning("%a: outreg: illegal reg %d", insn.ea, r);
else
out_register(ph.reg_names[r]);
}
//----------------------------------------------------------------------
bool out_i960_t::outmem(const op_t &x, ea_t ea, bool printerr)
{
if ( out_name_expr(x, ea, BADADDR) )
return true;
const char *p = pm().find_sym(x.addr);
if ( p == NULL || p[0] == '\0' )
{
if ( printerr )
{
out_tagon(COLOR_ERROR);
out_btoa(x.addr, 16);
out_tagoff(COLOR_ERROR);
remember_problem(PR_NONAME,insn.ea);
}
}
else
{
out_line(p, COLOR_IMPNAME);
return true;
}
return false;
}
//----------------------------------------------------------------------
bool out_i960_t::out_operand(const op_t &x)
{
switch ( x.type )
{
case o_void:
return 0;
case o_reg:
outreg(x.reg);
break;
case o_imm:
{
if ( insn.itype == I960_lda && (is_off(F, x.n) || !is_defarg(F, x.n)) )
{
op_t y = x;
y.addr = x.value;
if ( outmem(y, calc_mem(insn, y.addr), false) )
break;
}
out_value(x, OOFS_IFSIGN|OOFW_IMM);
}
break;
case o_displ:
{
if ( x.addr != 0
|| is_off(F, x.n)
|| is_stkvar(F, x.n)
|| is_enum(F, x.n)
|| is_stroff(F, x.n) )
{
out_value(x, OOFS_IFSIGN|OOF_SIGNED|OOF_ADDR|OOFW_32);
}
}
// no break
case o_phrase:
if ( uchar(x.reg) != uchar(-1) )
{
out_symbol('(');
outreg(x.reg);
out_symbol(')');
}
if ( uchar(x.index) != uchar(-1) )
{
out_symbol('[');
outreg(x.index);
if ( x.scale != 1 )
{
out_tagon(COLOR_SYMBOL);
out_char('*');
out_btoa(x.scale, 10);
out_tagoff(COLOR_SYMBOL);
}
out_symbol(']');
}
break;
case o_mem:
case o_near:
outmem(x, calc_mem(insn, x.addr));
break;
default:
INTERR(10365);
break;
}
return 1;
}
//----------------------------------------------------------------------
void out_i960_t::out_proc_mnem(void)
{
const char *postfix = NULL;
// if ( insn.auxpref & aux_t ) postfix = ".t";
if ( insn.auxpref & aux_f )
postfix = ".f";
out_mnem(8, postfix);
}
//----------------------------------------------------------------------
void out_i960_t::out_insn(void)
{
out_mnemonic();
out_one_operand(0);
if ( insn.Op2.type != o_void )
{
out_symbol(',');
out_char(' ');
out_one_operand(1);
}
if ( insn.Op3.type != o_void )
{
out_symbol(',');
out_char(' ');
out_one_operand(2);
}
out_immchar_cmts();
flush_outbuf();
}
//--------------------------------------------------------------------------
//lint -esym(1764, ctx) could be made const
//lint -esym(818, Sarea) could be made const
void i960_t::i960_segstart(outctx_t &ctx, segment_t *Sarea) const
{
const char *const predefined[] =
{
".text", // Text section
// ".rdata", // Read-only data section
".data", // Data sections
// ".lit8", // Data sections
// ".lit4", // Data sections
// ".sdata", // Small data section, addressed through register $gp
// ".sbss", // Small bss section, addressed through register $gp
// ".bss", // bss (block started by storage) section, which loads zero-initialized data
};
if ( is_spec_segm(Sarea->type) )
return;
qstring sname;
qstring sclas;
get_segm_name(&sname, Sarea);
get_segm_class(&sclas, Sarea);
if ( sname == ".bss" )
{
int align = 0;
switch ( Sarea->align )
{
case saAbs: align = 0; break;
case saRelByte: align = 0; break;
case saRelWord: align = 1; break;
case saRelPara: align = 4; break;
case saRelPage: align = 8; break;
case saRelDble: align = 2; break;
case saRel4K: align = 12; break;
case saGroup: align = 0; break;
case saRel32Bytes: align = 5; break;
case saRel64Bytes: align = 6; break;
case saRelQword: align = 3; break;
};
asize_t size = Sarea->type == SEG_NULL ? 0 : Sarea->size();
char buf[MAX_NUMBUF];
btoa(buf, sizeof(buf), size);
validate_name(&sname, VNT_IDENT);
ctx.gen_printf(DEFAULT_INDENT,
COLSTR("%s %s, %d", SCOLOR_ASMDIR),
sname.c_str(), buf, align);
}
else
{
if ( !print_predefined_segname(ctx, &sname, predefined, qnumber(predefined)) )
ctx.gen_printf(DEFAULT_INDENT,
COLSTR("%s", SCOLOR_ASMDIR) "" COLSTR("%s %s", SCOLOR_AUTOCMT),
sclas == "CODE" ? ".text" : ".data",
ash.cmnt,
sname.c_str());
}
}
//--------------------------------------------------------------------------
void idaapi i960_segend(outctx_t &, segment_t *)
{
}
//--------------------------------------------------------------------------
void idaapi i960_header(outctx_t &ctx)
{
ctx.gen_header(GH_PRINT_ALL_BUT_BYTESEX);
ctx.gen_empty_line();
}
//--------------------------------------------------------------------------
void i960_t::i960_footer(outctx_t &ctx) const
{
qstring nbuf = get_colored_name(inf_get_start_ea());
const char *name = nbuf.c_str();
const char *end = ash.end;
if ( end == NULL )
ctx.gen_printf(DEFAULT_INDENT, COLSTR("%s end %s",SCOLOR_AUTOCMT), ash.cmnt, name);
else
ctx.gen_printf(DEFAULT_INDENT,
COLSTR("%s",SCOLOR_ASMDIR) " " COLSTR("%s %s",SCOLOR_AUTOCMT),
ash.end, ash.cmnt, name);
}

View File

@@ -0,0 +1,440 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-2001 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* E-mail: ig@datarescue.com
*
*
*/
#include "i960.hpp"
#include <diskio.hpp>
#include <typeinf.hpp>
#include <ieee.h>
int data_id;
//--------------------------------------------------------------------------
static const char *const register_names[] =
{
"pfp", "sp", "rip", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
"g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
"g8", "g9", "g10", "g11", "g12", "g13", "g14", "fp",
"sf0", "sf1", "sf2", "sf3", "sf4", "sf5", "sf6", "sf7",
"sf8", "sf9", "sf10", "sf11", "sf12", "sf13", "sf14", "sf15",
"sf16", "sf17","sf18", "sf19", "sf20", "sf21", "sf22", "sf23",
"sf24", "sf25","sf26", "sf27", "sf28", "sf29", "sf30", "sf31",
"pc", "ac", "ip", "tc",
"fp0", "fp1", "fp2", "fp3",
"ds", "cs",
};
//--------------------------------------------------------------------------
static const bytes_t retcodes[] =
{
// { sizeof(retcode0), retcode0 },
{ 0, NULL }
};
//-----------------------------------------------------------------------
// GNU assembler
//-----------------------------------------------------------------------
static const asm_t gnuasm =
{
AS_ASCIIC|AS_ALIGN2|ASH_HEXF3|ASD_DECF0|ASB_BINF3|ASO_OCTF1|AS_COLON|AS_N2CHR|AS_NCMAS|AS_ONEDUP,
0,
"GNU assembler",
0,
NULL, // header lines
".org", // org
NULL, // end
"#", // comment string
'"', // string delimiter
'\'', // char delimiter
"\"'", // special symbols in char and string constants
".ascii", // ascii string directive
".byte", // byte directive
".short", // word directive
".long", // double words
".quad", // qwords
".octa", // oword (16 bytes)
".float", // float (4 bytes)
".double", // double (8 bytes)
".extended", // tbyte (10/12 bytes)
NULL, // packed decimal real
".fill #d, #s(1,2,4,8), #v", // arrays (#h,#d,#v,#s(...)
".space %s", // uninited arrays
"=", // equ
NULL, // 'seg' prefix (example: push seg seg001)
".", // current IP (instruction pointer)
NULL, // func_header
NULL, // func_footer
".global", // "public" name keyword
NULL, // "weak" name keyword
".extern", // "extrn" name keyword
// .extern directive requires an explicit object size
".comm", // "comm" (communal variable)
NULL, // get_type_name
".align", // "align" keyword
'(', ')', // lbrace, rbrace
"%", // mod
"&", // and
"|", // or
"^", // xor
"~", // not
"<<", // shl
">>", // shr
NULL, // sizeof
};
static const asm_t *const asms[] = { &gnuasm, NULL };
//--------------------------------------------------------------------------
static const char *const cfgname = "i960.cfg";
void i960_t::load_symbols(void)
{
ioh.ports.clear();
read_ioports(&ioh.ports, &ioh.device, cfgname);
}
const char *i960_t::find_sym(ea_t address)
{
const ioport_t *port = find_ioport(ioh.ports, address);
return port ? port->name.c_str() : NULL;
}
//--------------------------------------------------------------------------
void i960_t::choose_device()
{
if ( choose_ioport_device(&ioh.device, cfgname) )
{
ioh.set_device_name(ioh.device.c_str(), IORESP_NONE);
load_symbols();
}
}
//--------------------------------------------------------------------------
static int idaapi choose_device_cb(int, form_actions_t &fa)
{
i960_t &pm = *(i960_t *)fa.get_ud();
pm.choose_device();
return 0;
}
//--------------------------------------------------------------------------
const char *i960_t::set_idp_options(
const char *keyword,
int value_type,
const void * value,
bool idb_loaded)
{
static const char form[] =
"HELP\n"
"Intel 960 specific options\n"
"\n"
" Choose device name\n"
" Here you may select a specific Intel 960 device\n"
" IDA will use the definitions in the I960.CFG file for\n"
" the i/o port names\n"
"\n"
" Strictly adhere to instruction encodings\n"
" If this option is on, IDA will check that unused fields\n"
" of instructions are filled by zeroes. If they are not,\n"
" it will refuse to disassemble the instruction.\n"
"\n"
"ENDHELP\n"
"Intel 960 specific options\n"
"%*\n"
" <~C~hoose device name:B:0:::>\n"
"\n"
" <~S~trictly adhere to instruction encodings:C>>\n"
"\n"
"\n";
if ( keyword == NULL )
{
CASSERT(sizeof(idpflags) == sizeof(ushort));
ask_form(form, this, choose_device_cb, &idpflags);
OK:
if ( idb_loaded )
save_idpflags();
return IDPOPT_OK;
}
else
{
if ( value_type != IDPOPT_BIT )
return IDPOPT_BADTYPE;
if ( strcmp(keyword, "I960_STRICT") == 0 )
{
setflag(idpflags, IDP_STRICT, *(int*)value != 0);
goto OK;
}
}
return IDPOPT_BADKEY;
}
//--------------------------------------------------------------------------
void i960_t::load_from_idb()
{
// restore ptype
int n = ph.get_proc_index();
inf_set_be((n > 1));
idpflags = helper.altval(-1);
ioh.restore_device();
load_symbols();
}
//----------------------------------------------------------------------
// This old-style callback only returns the processor module object.
static ssize_t idaapi notify(void *, int msgid, va_list)
{
if ( msgid == processor_t::ev_get_procmod )
return size_t(SET_MODULE_DATA(i960_t));
return 0;
}
//--------------------------------------------------------------------------
ssize_t idaapi i960_t::on_event(ssize_t msgid, va_list va)
{
switch ( msgid )
{
case processor_t::ev_init:
helper.create(PROCMOD_NODE_NAME);
break;
case processor_t::ev_term:
ioh.ports.clear();
clr_module_data(data_id);
break;
case processor_t::ev_newfile: // new file loaded
choose_device();
save_idpflags();
break;
case processor_t::ev_oldfile: // old file loaded
ioh.upgrade_device_index();
// fall through
case processor_t::ev_ending_undo:
load_from_idb();
break;
case processor_t::ev_newprc:
{
int n = va_arg(va, int);
bool keep_cfg = va_argi(va, bool);
if ( !keep_cfg )
inf_set_be((n > 1));
}
break;
// +++ TYPE CALLBACKS
case processor_t::ev_decorate_name:
{
qstring *outbuf = va_arg(va, qstring *);
const char *name = va_arg(va, const char *);
bool mangle = va_argi(va, bool);
cm_t cc = va_argi(va, cm_t);
tinfo_t *type = va_arg(va, tinfo_t *);
return gen_decorate_name(outbuf, name, mangle, cc, type) ? 1 : 0;
}
case processor_t::ev_max_ptr_size:
return 4;
case processor_t::ev_calc_arglocs:
return -1;
case processor_t::ev_use_stkarg_type:
return 0;
case processor_t::ev_use_regarg_type:
return -1;
case processor_t::ev_get_cc_regs:
{
callregs_t *callregs = va_arg(va, callregs_t *);
cm_t cc = va_argi(va, cm_t);
if ( cc == CM_CC_FASTCALL || cc == CM_CC_THISCALL )
{
callregs->reset();
return 1;
}
}
break;
case processor_t::ev_calc_cdecl_purged_bytes:// calculate number of purged bytes after call
{
// ea_t ea = va_arg(va, ea_t);
return 0;
}
case processor_t::ev_get_stkarg_offset: // get offset from SP to the first stack argument
// args: none
// returns: the offset
return 0;
// --- TYPE CALLBACKS
case processor_t::ev_out_mnem:
{
outctx_t *ctx = va_arg(va, outctx_t *);
out_mnem(*ctx);
return 1;
}
case processor_t::ev_out_header:
{
outctx_t *ctx = va_arg(va, outctx_t *);
i960_header(*ctx);
return 1;
}
case processor_t::ev_out_footer:
{
outctx_t *ctx = va_arg(va, outctx_t *);
i960_footer(*ctx);
return 1;
}
case processor_t::ev_out_segstart:
{
outctx_t *ctx = va_arg(va, outctx_t *);
segment_t *seg = va_arg(va, segment_t *);
i960_segstart(*ctx, seg);
return 1;
}
case processor_t::ev_out_segend:
{
outctx_t *ctx = va_arg(va, outctx_t *);
segment_t *seg = va_arg(va, segment_t *);
i960_segend(*ctx, seg);
return 1;
}
case processor_t::ev_ana_insn:
{
insn_t *out = va_arg(va, insn_t *);
return i960_ana(out);
}
case processor_t::ev_emu_insn:
{
const insn_t *insn = va_arg(va, const insn_t *);
return i960_emu(*insn) ? 1 : -1;
}
case processor_t::ev_out_insn:
{
outctx_t *ctx = va_arg(va, outctx_t *);
out_insn(*ctx);
return 1;
}
case processor_t::ev_out_operand:
{
outctx_t *ctx = va_arg(va, outctx_t *);
const op_t *op = va_arg(va, const op_t *);
return out_opnd(*ctx, *op) ? 1 : -1;
}
case processor_t::ev_set_idp_options:
{
const char *keyword = va_arg(va, const char *);
int value_type = va_arg(va, int);
const char *value = va_arg(va, const char *);
const char **errmsg = va_arg(va, const char **);
bool idb_loaded = va_argi(va, bool);
const char *ret = set_idp_options(keyword, value_type, value, idb_loaded);
if ( ret == IDPOPT_OK )
return 1;
if ( errmsg != NULL )
*errmsg = ret;
return -1;
}
case processor_t::ev_is_align_insn:
{
ea_t ea = va_arg(va, ea_t);
return is_align_insn(ea);
}
default:
break;
}
return 0;
}
//-----------------------------------------------------------------------
#define FAMILY "Intel 960:"
static const char *const shnames[] =
{
"i960",
"i960l",
"i960b",
NULL
};
static const char *const lnames[] =
{
FAMILY"Intel 960 little endian (default)",
"Intel 960 little endian",
"Intel 960 big endian",
NULL
};
//-----------------------------------------------------------------------
// Processor Definition
//-----------------------------------------------------------------------
processor_t LPH =
{
IDP_INTERFACE_VERSION, // version
PLFM_I960, // id
// flag
PRN_HEX
| PR_RNAMESOK
| PR_SEGS
| PR_USE32
| PR_DEFSEG32
| PR_TYPEINFO,
// flag2
PR2_IDP_OPTS, // the module has processor-specific configuration options
8, // 8 bits in a byte for code segments
8, // 8 bits in a byte for other segments
shnames,
lnames,
asms,
notify,
register_names, // Register names
qnumber(register_names), // Number of registers
ds, // first
cs, // last
2, // size of a segment register
cs, ds,
NULL, // No known code start sequences
retcodes,
I960_null,
I960_last,
Instructions, // instruc
10, // int tbyte_size (0-doesn't exist)
{ 0, 7, 15, 19 }, // char real_width[4];
// number of symbols after decimal point
// 2byte float (0-does not exist)
// normal float
// normal double
// long double
I960_ret, // Icode of return instruction. It is ok to give any of possible return instructions
};