update
This commit is contained in:
567
idasdk75/module/i860/ana.cpp
Normal file
567
idasdk75/module/i860/ana.cpp
Normal file
@@ -0,0 +1,567 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA).
|
||||
* Version 3.05
|
||||
* Copyright (c) 1990-95 by Ilfak Guilfanov.
|
||||
* ALL RIGHTS RESERVED.
|
||||
* FIDO: 2:5020/209
|
||||
* E-mail: ig@estar.msk.su
|
||||
*
|
||||
*/
|
||||
|
||||
#include "i860.hpp"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void i860_t::op_s1ni(op_t &x)
|
||||
{
|
||||
x.reg = op_s1();
|
||||
x.type = o_reg;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void i860_t::op_s2(op_t &x)
|
||||
{
|
||||
x.reg = op_s2();
|
||||
x.type = o_reg;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void i860_t::op_fs1(op_t &x)
|
||||
{
|
||||
x.reg = op_s1() + R_f0;
|
||||
x.type = o_reg;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void i860_t::op_fs2(op_t &x)
|
||||
{
|
||||
x.reg = op_s2() + R_f0;
|
||||
x.type = o_reg;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void i860_t::op_s1s(op_t &x)
|
||||
{
|
||||
if ( code & bit26 ) // immediate src1
|
||||
{
|
||||
x.type = o_imm;
|
||||
x.value = short(code);
|
||||
}
|
||||
else
|
||||
{
|
||||
op_s1ni(x);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void i860_t::op_s1u(op_t &x)
|
||||
{
|
||||
if ( code & bit26 ) // immediate src1
|
||||
{
|
||||
x.type = o_imm;
|
||||
x.value = ushort(code);
|
||||
}
|
||||
else
|
||||
{
|
||||
op_s1ni(x);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void i860_t::op_s1s2(op_t &x)
|
||||
{
|
||||
x.reg = op_s2();
|
||||
if ( code & bit26 ) // immediate src1
|
||||
{
|
||||
x.type = o_displ;
|
||||
x.addr = short(code);
|
||||
if ( code & bit28 )
|
||||
x.addr &= ~1L;
|
||||
if ( x.reg == 0 )
|
||||
x.type = o_mem;
|
||||
}
|
||||
else
|
||||
{
|
||||
x.type = o_phrase;
|
||||
x.addr = op_s1();
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void i860_t::op_dest(op_t &x)
|
||||
{
|
||||
x.reg = op_ds();
|
||||
x.type = o_reg;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void i860_t::op_fdest(op_t &x)
|
||||
{
|
||||
x.reg = op_ds() + R_f0;
|
||||
x.type = o_reg;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
char i860_t::dsize_28_0(void) const
|
||||
{
|
||||
if ( code & bit28 )
|
||||
return (code & bit0) ? dt_dword : dt_word;
|
||||
return dt_byte;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
char i860_t::dsize_1_2(void) const
|
||||
{
|
||||
if ( code & bit1 )
|
||||
return dt_dword;
|
||||
return (code & bit2) ? dt_byte16 : dt_qword;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
char i860_t::dsize_10_9(void) const
|
||||
{
|
||||
if ( code & bit10 )
|
||||
return (code & bit9) ? dt_dword : dt_dword;
|
||||
return (code & bit9) ? dt_word : dt_byte;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void i860_t::op_stoff(op_t &x)
|
||||
{
|
||||
x.type = o_displ;
|
||||
x.reg = op_s2();
|
||||
x.addr = short((code & 0x7FF) + (op_ds() << 11)); // extend sign
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//lint -e{1764} Reference parameter '' could be declared const ref
|
||||
void i860_t::op_bteoff(insn_t &insn, op_t &x)
|
||||
{
|
||||
x.type = o_near;
|
||||
x.addr = insn.ea + insn.size
|
||||
+ (sval_t((code & 0x7FF)+(op_ds()<<11)) << 2); // extend sign
|
||||
x.dtype = dt_code;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//lint -e{1764} Reference parameter '' could be declared const ref
|
||||
void i860_t::op_lbroff(insn_t &insn, op_t &x) const
|
||||
{
|
||||
x.type = o_near;
|
||||
sval_t lbr = code & 0x3FFFFFFL;
|
||||
if ( code & bit25 )
|
||||
lbr |= ~uval_t(0x3FFFFFF); // extend sign
|
||||
x.addr = insn.ea + insn.size + (lbr << 2);
|
||||
x.dtype = dt_code;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void i860_t::op_ainc(op_t &x)
|
||||
{
|
||||
op_s1s2(x);
|
||||
if ( code & bit0 )
|
||||
x.reg = - x.reg; //lint !e2501 negation of value of unsigned type
|
||||
if ( x.type == o_displ || x.type == o_mem )
|
||||
{
|
||||
x.addr &= ~3L;
|
||||
if ( (code & bit1) == 0 )
|
||||
x.addr &= ~7L;
|
||||
}
|
||||
x.dtype = dsize_1_2();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
int i860_t::op_ctl(op_t &x)
|
||||
{
|
||||
op_s2(x);
|
||||
if ( x.reg > (is860XP() ? 11 : 5) )
|
||||
return 0;
|
||||
x.reg += R_fir;
|
||||
return 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
int i860_t::i860_ana(insn_t *_insn)
|
||||
{
|
||||
if ( _insn == NULL )
|
||||
return 0;
|
||||
insn_t &insn = *_insn;
|
||||
|
||||
if ( (insn.ea & 3) != 0 )
|
||||
return 0; // only four byte boundaries
|
||||
code = insn.get_next_dword();
|
||||
|
||||
insn.Op1.dtype = dt_dword;
|
||||
insn.Op2.dtype = dt_dword;
|
||||
insn.Op3.dtype = dt_dword;
|
||||
insn.itype = I860_null;
|
||||
|
||||
switch ( code>>26 )
|
||||
{
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
insn.itype = I860_ld;
|
||||
op_s1s2(insn.Op1);
|
||||
op_dest(insn.Op2);
|
||||
insn.Op1.dtype = dsize_28_0();
|
||||
insn.Op2.dtype = insn.Op1.dtype;
|
||||
break;
|
||||
case 0x03:
|
||||
case 0x07:
|
||||
insn.itype = I860_st;
|
||||
op_s1ni(insn.Op2);
|
||||
op_stoff(insn.Op1);
|
||||
insn.Op1.dtype = dsize_28_0();
|
||||
insn.Op2.dtype = insn.Op1.dtype;
|
||||
break;
|
||||
case 0x02:
|
||||
insn.itype = I860_ixfr;
|
||||
op_s1ni(insn.Op1);
|
||||
op_fdest(insn.Op2);
|
||||
break;
|
||||
case 0x08:
|
||||
case 0x09:
|
||||
insn.itype = I860_fld;
|
||||
op_ainc(insn.Op1);
|
||||
op_fdest(insn.Op2);
|
||||
insn.Op2.dtype = insn.Op1.dtype;
|
||||
break;
|
||||
case 0x0A:
|
||||
case 0x0B:
|
||||
insn.itype = I860_fst;
|
||||
op_fdest(insn.Op1);
|
||||
op_ainc(insn.Op2);
|
||||
insn.Op1.dtype = insn.Op2.dtype;
|
||||
break;
|
||||
case 0x0D:
|
||||
insn.itype = I860_flush;
|
||||
op_ainc(insn.Op1);
|
||||
break;
|
||||
case 0x0F:
|
||||
insn.itype = I860_pst_d;
|
||||
op_fdest(insn.Op1);
|
||||
op_ainc(insn.Op2);
|
||||
insn.Op1.dtype = insn.Op2.dtype;
|
||||
break;
|
||||
case 0x0C:
|
||||
if ( !op_ctl(insn.Op1) )
|
||||
break;
|
||||
op_dest(insn.Op2);
|
||||
insn.itype = I860_ld_c;
|
||||
break;
|
||||
case 0x0E:
|
||||
op_s1ni(insn.Op1);
|
||||
if ( !op_ctl(insn.Op2) )
|
||||
break;
|
||||
insn.itype = I860_st_c;
|
||||
break;
|
||||
case 0x10:
|
||||
insn.itype = I860_bri;
|
||||
op_s1ni(insn.Op1);
|
||||
break;
|
||||
case 0x11:
|
||||
insn.itype = I860_trap;
|
||||
op_s1ni(insn.Op1);
|
||||
op_s2(insn.Op2);
|
||||
op_dest(insn.Op3);
|
||||
break;
|
||||
case 0x12:
|
||||
FPunit(insn);
|
||||
break;
|
||||
case 0x13:
|
||||
COREunit(insn);
|
||||
break;
|
||||
case 0x14:
|
||||
case 0x16:
|
||||
case 0x15:
|
||||
case 0x17:
|
||||
insn.itype = (code & bit27) ? I860_bte : I860_btne;
|
||||
if ( code & bit26 ) // small immediate
|
||||
{
|
||||
insn.Op1.type = o_imm;
|
||||
insn.Op1.value = op_s1();
|
||||
}
|
||||
else
|
||||
{
|
||||
op_s1ni(insn.Op1);
|
||||
}
|
||||
op_s2(insn.Op2);
|
||||
op_bteoff(insn, insn.Op3);
|
||||
break;
|
||||
case 0x18:
|
||||
case 0x19:
|
||||
op_ainc(insn.Op1);
|
||||
op_fdest(insn.Op2);
|
||||
insn.Op2.dtype = insn.Op1.dtype;
|
||||
if ( !is860XP() && insn.Op2.dtype == dt_byte16 )
|
||||
break;
|
||||
insn.itype = I860_pfld;
|
||||
break;
|
||||
case 0x1A:
|
||||
insn.itype = I860_br;
|
||||
op_lbroff(insn, insn.Op1);
|
||||
break;
|
||||
case 0x1B:
|
||||
insn.itype = I860_call;
|
||||
op_lbroff(insn, insn.Op1);
|
||||
break;
|
||||
case 0x1C:
|
||||
case 0x1D:
|
||||
insn.itype = (code & bit26) ? I860_bc_t : I860_bc;
|
||||
op_lbroff(insn, insn.Op1);
|
||||
break;
|
||||
case 0x1E:
|
||||
case 0x1F:
|
||||
insn.itype = (code & bit26) ? I860_bnc_t : I860_bnc;
|
||||
op_lbroff(insn, insn.Op1);
|
||||
break;
|
||||
case 0x20: case 0x21: case 0x22: case 0x23:
|
||||
case 0x24: case 0x25: case 0x26: case 0x27:
|
||||
insn.itype = (code & bit27)
|
||||
? (code & bit28) ? I860_subs : I860_subu
|
||||
: (code & bit28) ? I860_adds : I860_addu;
|
||||
op_s1s(insn.Op1);
|
||||
op_s2(insn.Op2);
|
||||
op_dest(insn.Op3);
|
||||
break;
|
||||
case 0x28:
|
||||
case 0x29:
|
||||
case 0x2A:
|
||||
case 0x2B:
|
||||
insn.itype = (code & bit27) ? I860_shr : I860_shl;
|
||||
op_s1u(insn.Op1);
|
||||
op_s2(insn.Op2);
|
||||
op_dest(insn.Op3);
|
||||
break;
|
||||
case 0x2C:
|
||||
insn.itype = I860_shrd;
|
||||
op_s1ni(insn.Op1);
|
||||
op_s2(insn.Op2);
|
||||
op_dest(insn.Op3);
|
||||
break;
|
||||
case 0x2D:
|
||||
insn.itype = I860_bla;
|
||||
op_s1ni(insn.Op1);
|
||||
op_s2(insn.Op2);
|
||||
op_bteoff(insn, insn.Op3);
|
||||
break;
|
||||
case 0x2E:
|
||||
case 0x2F:
|
||||
insn.itype = I860_shra;
|
||||
op_s1u(insn.Op1);
|
||||
op_s2(insn.Op2);
|
||||
op_dest(insn.Op3);
|
||||
break;
|
||||
case 0x30: case 0x31: case 0x33:
|
||||
insn.itype = (code & bit27) ? I860_andh : I860_and;
|
||||
goto common;
|
||||
case 0x34: case 0x35: case 0x37:
|
||||
insn.itype = (code & bit27) ? I860_andnoth : I860_andnot;
|
||||
goto common;
|
||||
case 0x38: case 0x39: case 0x3B:
|
||||
insn.itype = (code & bit27) ? I860_orh : I860_or;
|
||||
goto common;
|
||||
case 0x3C: case 0x3D: case 0x3F:
|
||||
insn.itype = (code & bit27) ? I860_xorh : I860_xor;
|
||||
common:
|
||||
op_s1u(insn.Op1);
|
||||
op_s2(insn.Op2);
|
||||
op_dest(insn.Op3);
|
||||
break;
|
||||
}
|
||||
if ( insn.itype == I860_null )
|
||||
return 0;
|
||||
return 4;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void i860_t::COREunit(insn_t &insn)
|
||||
{
|
||||
if ( (code & 0x1E0) != 0 )
|
||||
return;
|
||||
switch ( code & 0x1F )
|
||||
{
|
||||
case 1:
|
||||
insn.itype = I860_lock;
|
||||
break;
|
||||
case 2:
|
||||
insn.itype = I860_calli;
|
||||
op_s1ni(insn.Op1);
|
||||
insn.Op1.dtype = dt_code;
|
||||
break;
|
||||
case 4:
|
||||
insn.itype = I860_introvr;
|
||||
break;
|
||||
case 7:
|
||||
insn.itype = I860_unlock;
|
||||
break;
|
||||
case 8:
|
||||
if ( !is860XP() )
|
||||
break;
|
||||
insn.itype = I860_ldio;
|
||||
common:
|
||||
op_s2(insn.Op1);
|
||||
op_dest(insn.Op2);
|
||||
insn.Op1.dtype = dsize_10_9();
|
||||
insn.Op2.dtype = insn.Op1.dtype;
|
||||
break;
|
||||
case 9:
|
||||
if ( !is860XP() )
|
||||
break;
|
||||
insn.itype = I860_stio;
|
||||
op_s1ni(insn.Op1);
|
||||
op_s2(insn.Op2);
|
||||
insn.Op1.dtype = dsize_10_9();
|
||||
insn.Op2.dtype = insn.Op1.dtype;
|
||||
break;
|
||||
case 0x0A:
|
||||
if ( !is860XP() )
|
||||
break;
|
||||
insn.itype = I860_ldint;
|
||||
goto common;
|
||||
case 0x0B:
|
||||
if ( !is860XP() )
|
||||
break;
|
||||
insn.itype = I860_scyc;
|
||||
op_s2(insn.Op1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void i860_t::FPunit(insn_t &insn)
|
||||
{
|
||||
switch ( code & 0x7F )
|
||||
{
|
||||
case 0x00: case 0x01: case 0x02: case 0x03:
|
||||
case 0x04: case 0x05: case 0x06: case 0x07:
|
||||
case 0x08: case 0x09: case 0x0A: case 0x0B:
|
||||
case 0x0C: case 0x0D: case 0x0E: case 0x0F:
|
||||
case 0x10: case 0x11: case 0x12: case 0x13:
|
||||
case 0x14: case 0x15: case 0x16: case 0x17:
|
||||
case 0x18: case 0x19: case 0x1A: case 0x1B:
|
||||
case 0x1C: case 0x1D: case 0x1E:
|
||||
{
|
||||
static const int Pintrs[] =
|
||||
{
|
||||
I860_r2p1, I860_r2pt, I860_r2ap1, I860_r2apt,
|
||||
I860_i2p1, I860_i2pt, I860_i2ap1, I860_i2apt,
|
||||
I860_rat1p2, I860_m12apm, I860_ra1p2, I860_m12ttpa,
|
||||
I860_iat1p2, I860_m12tpm, I860_ia1p2, I860_m12tpa,
|
||||
I860_r2s1, I860_r2st, I860_r2as1, I860_r2ast,
|
||||
I860_i2s1, I860_i2st, I860_i2as1, I860_i2ast,
|
||||
I860_rat1s2, I860_m12asm, I860_ra1s2, I860_m12ttsa,
|
||||
I860_iat1s2, I860_m12tsm, I860_ia1s2, I860_m12tsa
|
||||
};
|
||||
static const int Mintrs[] =
|
||||
{
|
||||
I860_mr2p1, I860_mr2pt, I860_mr2mp1,I860_mr2mpt,
|
||||
I860_mi2p1, I860_mi2pt, I860_mi2mp1,I860_mi2mpt,
|
||||
I860_mrmt1p2,I860_mm12mpm,I860_mrm1p2,I860_mm12ttpm,
|
||||
I860_mimt1p2,I860_mm12tpm,I860_mim1p2,I860_null,
|
||||
I860_mr2s1, I860_mr2st, I860_mr2ms1,I860_mr2mst,
|
||||
I860_mi2s1, I860_mi2st, I860_mi2ms1,I860_mi2mst,
|
||||
I860_mrmt1s2,I860_mm12msm,I860_mrm1s2,I860_mm12ttsm,
|
||||
I860_mimt1s2,I860_mm12tsm,I860_mim1s2,I860_null
|
||||
};
|
||||
if ( isDS() )
|
||||
break;
|
||||
insn.itype = uint16(((code & Pbit) ? Pintrs : Mintrs)[ int(code) & 0xF ]);
|
||||
}
|
||||
common3:
|
||||
op_fs1(insn.Op1);
|
||||
op_fs2(insn.Op2);
|
||||
op_dest(insn.Op3);
|
||||
common:
|
||||
if ( code & Dbit )
|
||||
insn.auxpref |= aux_dual;
|
||||
if ( code & Sbit )
|
||||
insn.auxpref |= aux_sdbl;
|
||||
if ( code & Rbit )
|
||||
insn.auxpref |= aux_rdbl;
|
||||
break;
|
||||
case 0x20:
|
||||
if ( isDS() )
|
||||
break;
|
||||
insn.itype = (code & Pbit) ? I860_pfmul : I860_fmul;
|
||||
goto common3;
|
||||
case 0x21:
|
||||
insn.itype = I860_fmlow_dd;
|
||||
goto common3;
|
||||
case 0x22:
|
||||
if ( isDS() )
|
||||
break;
|
||||
insn.itype = I860_frcp;
|
||||
common22:
|
||||
op_fs2(insn.Op1);
|
||||
op_dest(insn.Op2);
|
||||
goto common;
|
||||
case 0x23:
|
||||
if ( isDS() )
|
||||
break;
|
||||
insn.itype = I860_frsqr;
|
||||
goto common22;
|
||||
case 0x24:
|
||||
if ( (code & (Rbit|Sbit)) != (Rbit|Sbit) )
|
||||
break;
|
||||
insn.itype = I860_pfmul3_dd;
|
||||
goto common3;
|
||||
case 0x30:
|
||||
if ( isDS() )
|
||||
break;
|
||||
insn.itype = (code & Pbit) ? I860_pfadd : I860_fadd;
|
||||
goto common3;
|
||||
case 0x31:
|
||||
if ( isDS() )
|
||||
break;
|
||||
insn.itype = (code & Pbit) ? I860_pfsub : I860_fsub;
|
||||
goto common3;
|
||||
case 0x32:
|
||||
if ( !isSDDD() )
|
||||
break;
|
||||
insn.itype = (code & Pbit) ? I860_pfix : I860_fix;
|
||||
goto common21;
|
||||
case 0x33:
|
||||
insn.itype = (code & Pbit) ? I860_pfamov : I860_famov;
|
||||
goto common21;
|
||||
case 0x34:
|
||||
if ( isDS() )
|
||||
break;
|
||||
insn.itype = (code & Rbit) ? I860_pfle : I860_pfgt;
|
||||
goto common3;
|
||||
case 0x35:
|
||||
if ( isDS() )
|
||||
break;
|
||||
insn.itype = I860_pfeq;
|
||||
goto common3;
|
||||
case 0x3A:
|
||||
if ( !isSDDD() )
|
||||
break;
|
||||
insn.itype = (code & Pbit) ? I860_pftrunc : I860_ftrunc;
|
||||
goto common21;
|
||||
case 0x40:
|
||||
insn.itype = I860_fxfr;
|
||||
common21:
|
||||
op_fs1(insn.Op1);
|
||||
op_dest(insn.Op2);
|
||||
goto common;
|
||||
case 0x49:
|
||||
if ( !isSSDD() )
|
||||
break;
|
||||
insn.itype = (code & Pbit) ? I860_pfiadd : I860_fiadd;
|
||||
goto common3;
|
||||
case 0x4D:
|
||||
if ( !isSSDD() )
|
||||
break;
|
||||
insn.itype = (code & Pbit) ? I860_pfisub : I860_fisub;
|
||||
goto common3;
|
||||
case 0x57: insn.itype = (code & Pbit) ? I860_pfzchkl: I860_fzchkl;goto common3;
|
||||
case 0x5F: insn.itype = (code & Pbit) ? I860_pfzchks: I860_fzchks;goto common3;
|
||||
case 0x50: insn.itype = (code & Pbit) ? I860_pfaddp : I860_faddp; goto common3;
|
||||
case 0x51: insn.itype = (code & Pbit) ? I860_pfaddz : I860_faddz; goto common3;
|
||||
case 0x5A:
|
||||
insn.itype = (code & Pbit) ? I860_pform : I860_form;
|
||||
goto common21;
|
||||
}
|
||||
}
|
||||
165
idasdk75/module/i860/emu.cpp
Normal file
165
idasdk75/module/i860/emu.cpp
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA).
|
||||
* Version 3.05
|
||||
* Copyright (c) 1990-95 by Ilfak Guilfanov.
|
||||
* ALL RIGHTS RESERVED.
|
||||
* FIDO: 2:5020/209
|
||||
* E-mail: ig@estar.msk.su
|
||||
*
|
||||
*/
|
||||
|
||||
#include "i860.hpp"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static void set_immd_bit(const insn_t &insn)
|
||||
{
|
||||
set_immd(insn.ea);
|
||||
if ( is_defarg(get_flags(insn.ea), 1) )
|
||||
return;
|
||||
switch ( insn.itype )
|
||||
{
|
||||
case I860_and:
|
||||
case I860_andh:
|
||||
case I860_andnot:
|
||||
case I860_andnoth:
|
||||
case I860_xor:
|
||||
case I860_xorh:
|
||||
op_num(insn.ea, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool i860_t::handle_operand(const insn_t &insn, const op_t &x, bool isload) const
|
||||
{
|
||||
dref_t xreftype;
|
||||
uchar outf;
|
||||
switch ( x.type )
|
||||
{
|
||||
case o_phrase: // 2 registers
|
||||
case o_reg:
|
||||
break;
|
||||
case o_imm:
|
||||
if ( !isload )
|
||||
goto badTouch;
|
||||
xreftype = dr_O;
|
||||
outf = OOF_SIGNED;
|
||||
goto makeImm;
|
||||
case o_displ:
|
||||
xreftype = isload ? dr_R : dr_W;
|
||||
outf = OOF_SIGNED|OOF_ADDR;
|
||||
makeImm:
|
||||
set_immd_bit(insn);
|
||||
if ( op_adds_xrefs(get_flags(insn.ea), x.n) )
|
||||
insn.add_off_drefs(x, xreftype, outf);
|
||||
break;
|
||||
case o_mem:
|
||||
insn.create_op_data(x.addr, x);
|
||||
insn.add_dref(x.addr, x.offb, isload ? dr_R : dr_W);
|
||||
break;
|
||||
case o_near:
|
||||
{
|
||||
int iscall = has_insn_feature(insn.itype,CF_CALL);
|
||||
insn.add_cref(x.addr, x.offb, iscall ? fl_CN : fl_JN);
|
||||
if ( iscall && !func_does_return(x.addr) )
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
badTouch:
|
||||
warning("%a: %s,%d: bad optype %d", insn.ea, insn.get_canon_mnem(ph), x.n, x.type);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
static bool isDual(uint32 code)
|
||||
{
|
||||
return int(code>>26) == 0x12 && (code & Dbit) != 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//static int isDelayed(uint32 code) {
|
||||
// // bc.t bla bnc.t br bri call calli
|
||||
// int opcode = int(code >> 26);
|
||||
// switch ( opcode ) {
|
||||
// case 0x13:
|
||||
// return ((code & 0x1F) == 2); // calli
|
||||
// case 0x10: // bri
|
||||
// case 0x1A: // br
|
||||
// case 0x1B: // call
|
||||
// case 0x1D: // bc.t
|
||||
// case 0x1F: // bnc.t
|
||||
// case 0x2D: // bla
|
||||
// return 1;
|
||||
// }
|
||||
// return 0;
|
||||
//}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
static int isDelayedStop(uint32 code)
|
||||
{
|
||||
// br bri
|
||||
int opcode = int(code >> 26);
|
||||
switch ( opcode )
|
||||
{
|
||||
case 0x10: // bri
|
||||
case 0x1A: // br
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
static bool canFlow(const insn_t &insn)
|
||||
{
|
||||
if ( !is_flow(get_flags(insn.ea)) )
|
||||
return 1; // no previous instructions
|
||||
ea_t ea = insn.ea - 4;
|
||||
flags_t F = get_flags(ea);
|
||||
if ( is_flow(F) && is_code(F) )
|
||||
{
|
||||
if ( isDelayedStop(get_dword(ea)) ) // now or later
|
||||
{
|
||||
ea -= 4;
|
||||
if ( !is_code(get_flags(ea)) || !isDual(get_dword(ea)) )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
if ( is_flow(F) )
|
||||
{
|
||||
ea -= 4;
|
||||
return !is_code(get_flags(ea)) || !isDelayedStop(get_dword(ea));
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
int i860_t::i860_emu(const insn_t &insn) const
|
||||
{
|
||||
bool flow = true;
|
||||
|
||||
uint32 Feature = insn.get_canon_feature(ph);
|
||||
|
||||
if ( Feature & CF_USE1 && !handle_operand(insn, insn.Op1, true) )
|
||||
flow = false;
|
||||
if ( Feature & CF_USE2 && !handle_operand(insn, insn.Op2, true) )
|
||||
flow = false;
|
||||
if ( Feature & CF_USE3 && !handle_operand(insn, insn.Op3, true) )
|
||||
flow = false;
|
||||
if ( Feature & CF_JUMP )
|
||||
remember_problem(PR_JUMP, insn.ea);
|
||||
|
||||
if ( Feature & CF_CHG1 && !handle_operand(insn, insn.Op1, false) )
|
||||
flow = false;
|
||||
if ( Feature & CF_CHG2 && !handle_operand(insn, insn.Op2, false) )
|
||||
flow = false;
|
||||
if ( Feature & CF_CHG3 && !handle_operand(insn, insn.Op3, false) )
|
||||
flow = false;
|
||||
|
||||
if ( flow && canFlow(insn) )
|
||||
add_cref(insn.ea, insn.ea + insn.size, fl_F);
|
||||
return 1;
|
||||
}
|
||||
141
idasdk75/module/i860/i860.hpp
Normal file
141
idasdk75/module/i860/i860.hpp
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA).
|
||||
* Version 3.05
|
||||
* Copyright (c) 1990-95 by Ilfak Guilfanov.
|
||||
* ALL RIGHTS RESERVED.
|
||||
* FIDO: 2:5020/209
|
||||
* E-mail: ig@estar.msk.su
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __I860_HPP
|
||||
#define __I860_HPP
|
||||
|
||||
#include "../idaidp.hpp"
|
||||
#include "ins.hpp"
|
||||
|
||||
// Intel 860 insn.auxpref bits:
|
||||
#define aux_dual 0x1 // is dual
|
||||
#define aux_sdbl 0x2 // source double
|
||||
#define aux_rdbl 0x4 // result double
|
||||
|
||||
#define _PT_860XR 0x01 // Intel 860 XR
|
||||
#define _PT_860XP 0x02 // Intel 860 XP
|
||||
|
||||
#define PT_860XP _PT_860XP
|
||||
#define PT_860XR (PT_860XP | _PT_860XR)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
enum i860RegNo
|
||||
{
|
||||
R_r0, R_r1, R_r2, R_r3, R_r4, R_r5, R_r6, R_r7,
|
||||
R_r8, R_r9, R_r10, R_r11, R_r12, R_r13, R_r14, R_r15,
|
||||
R_r16, R_r17, R_r18, R_r19, R_r20, R_r21, R_r22, R_r23,
|
||||
R_r24, R_r25, R_r26, R_r27, R_r28, R_r29, R_r30, R_r31,
|
||||
|
||||
R_f0, R_f1, R_f2, R_f3, R_f4, R_f5, R_f6, R_f7,
|
||||
R_f8, R_f9, R_f10, R_f11, R_f12, R_f13, R_f14, R_f15,
|
||||
R_f16, R_f17, R_f18, R_f19, R_f20, R_f21, R_f22, R_f23,
|
||||
R_f24, R_f25, R_f26, R_f27, R_f28, R_f29, R_f30, R_f31,
|
||||
|
||||
R_fir,
|
||||
R_psr,
|
||||
R_dirbase,
|
||||
R_db,
|
||||
R_fsr,
|
||||
R_epsr,
|
||||
R_bear,
|
||||
R_ccr,
|
||||
R_p0,
|
||||
R_p1,
|
||||
R_p2,
|
||||
R_p3,
|
||||
R_vcs,R_vds // virtual segment registers
|
||||
};
|
||||
|
||||
#define bit0 (1L<<0)
|
||||
#define bit1 (1L<<1)
|
||||
#define bit2 (1L<<2)
|
||||
#define bit3 (1L<<3)
|
||||
#define bit4 (1L<<4)
|
||||
#define bit5 (1L<<5)
|
||||
#define bit6 (1L<<6)
|
||||
#define bit7 (1L<<7)
|
||||
#define bit8 (1L<<8)
|
||||
#define bit9 (1L<<9)
|
||||
#define bit10 (1L<<10)
|
||||
#define bit11 (1L<<11)
|
||||
#define bit12 (1L<<12)
|
||||
#define bit13 (1L<<13)
|
||||
#define bit14 (1L<<14)
|
||||
#define bit15 (1L<<15)
|
||||
#define bit16 (1L<<16)
|
||||
#define bit17 (1L<<17)
|
||||
#define bit18 (1L<<18)
|
||||
#define bit19 (1L<<19)
|
||||
#define bit20 (1L<<20)
|
||||
#define bit21 (1L<<21)
|
||||
#define bit22 (1L<<22)
|
||||
#define bit23 (1L<<23)
|
||||
#define bit24 (1L<<24)
|
||||
#define bit25 (1L<<25)
|
||||
#define bit26 (1L<<26)
|
||||
#define bit27 (1L<<27)
|
||||
#define bit28 (1L<<28)
|
||||
#define bit29 (1L<<29)
|
||||
#define bit30 (1L<<30)
|
||||
#define bit31 (1L<<31)
|
||||
|
||||
#define Rbit bit7 // Result is double precision
|
||||
#define Sbit bit8 // Source is double precision
|
||||
#define Dbit bit9 // Dual Instruction
|
||||
#define Pbit bit10 // Pipelining
|
||||
|
||||
void idaapi i860_header(outctx_t &ctx);
|
||||
int idaapi i860_ana(insn_t *_insn);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
struct i860_t : public procmod_t
|
||||
{
|
||||
int pflag = 0;
|
||||
inline int is860XP(void) { return (pflag & PT_860XP) != 0; }
|
||||
|
||||
uint32 code = 0;
|
||||
inline uint16 op_s1(void) { return int((code>>11)) & 31; }
|
||||
inline uint16 op_ds(void) { return int((code>>16)) & 31; }
|
||||
inline uint16 op_s2(void) { return int((code>>21)) & 31; }
|
||||
inline int isDS(void) { return (code & (Sbit|Rbit)) == Sbit; } // prec .ds
|
||||
inline int isSSDD(void) { return (code & Sbit) == (code & Rbit); } // prec .ss .dd
|
||||
inline int isSDDD(void) { return (code & Rbit) != 0; } // prec .sd .dd
|
||||
|
||||
virtual ssize_t idaapi on_event(ssize_t msgid, va_list va) override;
|
||||
|
||||
int op_ctl(op_t &x);
|
||||
void set_cpu(int procnum);
|
||||
void COREunit(insn_t &insn);
|
||||
int i860_ana(insn_t *_insn);
|
||||
void op_s1ni(op_t &x);
|
||||
void op_s2(op_t &x);
|
||||
void op_fs1(op_t &x);
|
||||
void op_fs2(op_t &x);
|
||||
void op_s1s(op_t &x);
|
||||
void op_s1u(op_t &x);
|
||||
void op_s1s2(op_t &x);
|
||||
void op_dest(op_t &x);
|
||||
void op_fdest(op_t &x);
|
||||
char dsize_28_0(void) const;
|
||||
char dsize_1_2(void) const;
|
||||
char dsize_10_9(void) const;
|
||||
void op_stoff(op_t &x);
|
||||
void op_bteoff(insn_t &insn, op_t &x);
|
||||
void op_lbroff(insn_t &insn, op_t &x) const;
|
||||
void op_ainc(op_t &x);
|
||||
void FPunit(insn_t &insn);
|
||||
|
||||
int i860_emu(const insn_t &insn) const;
|
||||
bool handle_operand(const insn_t &insn, const op_t &x, bool isload) const;
|
||||
void i860_segstart(outctx_t &ctx, segment_t *Sarea) const;
|
||||
void i860_footer(outctx_t &ctx) const;
|
||||
};
|
||||
#endif
|
||||
167
idasdk75/module/i860/ins.cpp
Normal file
167
idasdk75/module/i860/ins.cpp
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA).
|
||||
* Version 3.05
|
||||
* Copyright (c) 1990-95 by Ilfak Guilfanov.
|
||||
* ALL RIGHTS RESERVED.
|
||||
* FIDO: 2:5020/209
|
||||
* E-mail: ig@estar.msk.su
|
||||
*
|
||||
*/
|
||||
|
||||
#include "i860.hpp"
|
||||
|
||||
const instruc_t Instructions[] =
|
||||
{
|
||||
|
||||
{ "", 0 }, // Unknown Operation
|
||||
//
|
||||
// Intel 860 XP instructions
|
||||
//
|
||||
{ "adds", CF_USE1|CF_USE2|CF_CHG3 }, // Add Signed: o3 <- o1 + o2
|
||||
{ "addu", CF_USE1|CF_USE2|CF_CHG3 }, // Add Unsigned: o3 <- o1 + o2
|
||||
{ "and", CF_USE1|CF_USE2|CF_CHG3 }, // Logical AND: o3 <- o1 & o2
|
||||
{ "andh", CF_USE1|CF_USE2|CF_CHG3 }, // Logical AND High: o3 <- (o1<<16) & o2
|
||||
{ "andnot", CF_USE1|CF_USE2|CF_CHG3 }, // Logical AND NOT: o3 <- (!o1) & o2
|
||||
{ "andnoth", CF_USE1|CF_USE2|CF_CHG3 }, // Logical AND NOT High: o3 <- (!(o1<<16)) & o3
|
||||
{ "bc", CF_USE1 }, // Branch on CC
|
||||
{ "bc.t", CF_USE1 }, // Branch on CC,Taken:\nif CC then execute 1 more intruction\n jump to o1\nelse skip next instruction
|
||||
{ "bla", CF_USE1|CF_USE2|CF_CHG2|CF_USE3 }, // Branch on LCC and Add:\nLCC' <- boolean(o1+o2 < 0)\no2 += o1\nexecute 1 more instruction\nif LCC then\n LCC <- LCC'\n jump to o3\nelse LCC <- LCC'
|
||||
{ "bnc", CF_USE1 }, // Branch on NOT CC
|
||||
{ "bnc.t", CF_USE1 }, // Branch on NOT CC, Taken:\nif !CC then execute 1 more intruction\n jump to o1\nelse skip next instruction
|
||||
{ "br", CF_USE1 }, // Branch Direct Unconditionally:\nexec 1 more instruction, jump to o3
|
||||
{ "bri", CF_USE1|CF_JUMP }, // Branch Indirect Unconditionally
|
||||
{ "bte", CF_USE1|CF_USE2|CF_USE3 }, // Branch If Equal
|
||||
{ "btne", CF_USE1|CF_USE2|CF_USE3 }, // Branch If Not Equal
|
||||
{ "call", CF_USE1|CF_CALL }, // Call Subroutine
|
||||
{ "calli", CF_USE1|CF_JUMP|CF_CALL }, // Call Indirect Subroutine
|
||||
{ "fadd", CF_USE1|CF_USE2|CF_CHG3 }, // Floating-Point Add
|
||||
{ "faddp", CF_USE1|CF_USE2|CF_CHG3 }, // Add With Pixel Merge
|
||||
{ "faddz", CF_USE1|CF_USE2|CF_CHG3 }, // Add With Z Merge
|
||||
{ "famov", CF_USE1|CF_CHG2 }, // Floating-Point Adder Move
|
||||
{ "fiadd", CF_USE1|CF_USE2|CF_CHG3 }, // Long Integer Add
|
||||
{ "fisub", CF_USE1|CF_USE2|CF_CHG3 }, // Long Integer Subtract
|
||||
{ "fix", CF_USE1|CF_CHG2 }, // Floating-Point to Integer Conversion
|
||||
{ "fld", CF_USE1|CF_CHG2 }, // Floating-Point Load
|
||||
{ "flush", CF_USE1 }, // Cache Flush
|
||||
{ "fmlow.dd", CF_USE1|CF_USE2|CF_CHG3 }, // Floating-Point Multiply Low
|
||||
{ "fmul", CF_USE1|CF_USE2|CF_CHG3 }, // Floating-Point Multiply
|
||||
{ "form", CF_USE1|CF_CHG2 }, // Or with MERGE register: o2 <- o1 | MERGE; MERGE <- 0
|
||||
{ "frcp", CF_USE1|CF_CHG2 }, // Floating-Point Reciprocal: o2 <- 1 / o1
|
||||
{ "frsqr", CF_USE1|CF_CHG2 }, // Floating-Point Reciprocal Square Root: o2 <- 1 / sqrt(o1)
|
||||
{ "fst", CF_CHG1|CF_USE2 }, // Floating-Point Reciprocal Store
|
||||
{ "fsub", CF_USE1|CF_USE2|CF_CHG3 }, // Floating-Point Subtract
|
||||
{ "ftrunc", CF_USE1|CF_CHG2 }, // Floating-Point to Integer Conversion
|
||||
{ "fxfr", CF_USE1|CF_CHG2 }, // Transfer F-P to Integer Register
|
||||
{ "fzchkl", CF_USE1|CF_USE2|CF_CHG3 }, // 32-bit Z-Buffer Check
|
||||
{ "fzchks", CF_USE1|CF_USE2|CF_CHG3 }, // 16-bit Z-Buffer Check
|
||||
{ "introvr", 0 }, // Software Trap on Integer Overflow
|
||||
{ "ixfr", CF_USE1|CF_CHG2 }, // Transfer Integer to F-P Register
|
||||
{ "ld.c", CF_USE1|CF_CHG2 }, // Load from Control Register
|
||||
{ "ld", CF_USE1|CF_CHG2 }, // Load Integer
|
||||
{ "ldint", CF_USE1|CF_CHG2 }, // Load Interrupt Vector
|
||||
{ "ldio", CF_USE1|CF_CHG2 }, // Load I/O
|
||||
{ "lock", 0 }, // Begin Interlocked Sequence
|
||||
{ "or", CF_USE1|CF_USE2|CF_CHG3 }, // Logical OR
|
||||
{ "orh", CF_USE1|CF_USE2|CF_CHG3 }, // Logical OR High
|
||||
{ "pfadd", CF_USE1|CF_USE2|CF_CHG3 }, // Pipelined Floating-Point Add
|
||||
{ "pfaddp", CF_USE1|CF_USE2|CF_CHG3 }, // Pipelined Add with Pixel Merge
|
||||
{ "pfaddz", CF_USE1|CF_USE2|CF_CHG3 }, // Pipelined Add with Z Merge
|
||||
{ "pfamov", CF_USE1|CF_CHG2 }, // Pipelined Floating-Point Adder Move
|
||||
{ "pfeq", CF_USE1|CF_USE2|CF_CHG3 }, // Pipelined Floating Point Equal Compare
|
||||
{ "pfgt", CF_USE1|CF_USE2|CF_CHG3 }, // Pipelined Floating Point Greater-Than Compare
|
||||
{ "pfiadd", CF_USE1|CF_USE2|CF_CHG3 }, // Pipelined Long Integer Add
|
||||
{ "pfisub", CF_USE1|CF_USE2|CF_CHG3 }, // Pipelined Long Integer Subtract
|
||||
{ "pfix", CF_USE1|CF_CHG2 }, // Pipelined Floating-Point to Integer Conversion
|
||||
{ "pfld", CF_USE1|CF_CHG2 }, // Pipelined Floating-Point Load
|
||||
{ "pfle", CF_USE1|CF_USE2|CF_CHG3 }, // Pipelined Floating Point Less-Than or Equal Compare
|
||||
{ "pfmul", CF_USE1|CF_USE2|CF_CHG3 }, // Pipelined Floating-Point Multiply
|
||||
{ "pfmul3.dd", CF_USE1|CF_USE2|CF_CHG3 }, // Three-Stage Pipelined Floating-Point Multiply
|
||||
{ "pform", CF_USE1|CF_CHG2 }, // Pipelined Or with MERGE register
|
||||
{ "pfsub", CF_USE1|CF_USE2|CF_CHG3 }, // Pipelined Floating-Point Subtract
|
||||
{ "pftrunc", CF_USE1|CF_CHG2 }, // Pipelined Floating-Point to Integer Conversion
|
||||
{ "pfzchkl", CF_USE1|CF_USE2|CF_CHG3 }, // Pipelined 32-bit Z-Buffer Check
|
||||
{ "pfzchks", CF_USE1|CF_USE2|CF_CHG3 }, // Pipelined 16-bit Z-Buffer Check
|
||||
{ "pst.d", CF_CHG1|CF_USE2 }, // Pixel Store
|
||||
{ "scyc", CF_USE1 }, // Special Cycles
|
||||
{ "shl", CF_USE1|CF_USE2|CF_CHG3 }, // Shift Left
|
||||
{ "shr", CF_USE1|CF_USE2|CF_CHG3 }, // Shift Right
|
||||
{ "shra", CF_USE1|CF_USE2|CF_CHG3 }, // Shift Right Arithmetic
|
||||
{ "shrd", CF_USE1|CF_USE2|CF_CHG3 }, // Shift Right Double
|
||||
{ "st.c", CF_USE1|CF_CHG2 }, // Store to Control Register
|
||||
{ "st", CF_USE1|CF_CHG2 }, // Store Integer
|
||||
{ "stio", CF_USE1|CF_USE2 }, // Store I/O
|
||||
{ "subs", CF_USE1|CF_USE2|CF_CHG3 }, // Subtract Signed: o3 <- o1 - o2
|
||||
{ "subu", CF_USE1|CF_USE2|CF_CHG3 }, // Subtract Unsigned: o3 <- o1 - o2
|
||||
{ "trap", CF_USE1|CF_USE2|CF_CHG3 }, // Software Trap
|
||||
{ "unlock", 0 }, // End Interlocked Sequence
|
||||
{ "xor", CF_USE1|CF_USE2|CF_CHG3 }, // Logical Exclusive OR: o3 <- o1 ^ o2
|
||||
{ "xorh", CF_USE1|CF_USE2|CF_CHG3 }, // Logical Exclusive OR High: o3 <- (o1<<16) ^ o2
|
||||
//
|
||||
// iNTEL 860 XP Pipelined F-P instructions
|
||||
//
|
||||
{ "r2p1", CF_USE1|CF_USE2|CF_CHG3 }, // PFAM: M(KR,o2) A(o1, Mres) T:No K:No
|
||||
{ "r2pt", CF_USE1|CF_USE2|CF_CHG3 }, // PFAM: M(KR,o2) A(T, Mres) T:No K:Yes
|
||||
{ "r2ap1", CF_USE1|CF_USE2|CF_CHG3 }, // PFAM: M(KR,o2) A(o1, Ares) T:Yes K:No
|
||||
{ "r2apt", CF_USE1|CF_USE2|CF_CHG3 }, // PFAM: M(KR,o2) A(T, Ares) T:Yes K:Yes
|
||||
{ "i2p1", CF_USE1|CF_USE2|CF_CHG3 }, // PFAM: M(KI,o2) A(o1, Mres) T:No K:No
|
||||
{ "i2pt", CF_USE1|CF_USE2|CF_CHG3 }, // PFAM: M(KI,o2) A(T, Mres) T:No K:Yes
|
||||
{ "i2ap1", CF_USE1|CF_USE2|CF_CHG3 }, // PFAM: M(KI,o2) A(o1, Ares) T:Yes K:No
|
||||
{ "i2apt", CF_USE1|CF_USE2|CF_CHG3 }, // PFAM: M(KI,o2) A(T, Ares) T:Yes K:Yes
|
||||
{ "rat1p2", CF_USE1|CF_USE2|CF_CHG3 }, // PFAM: M(KR,Ares) A(o1, o2) T:Yes K:No
|
||||
{ "m12apm", CF_USE1|CF_USE2|CF_CHG3 }, // PFAM: M(o1,o2) A(Ares,Mres) T:No K:No
|
||||
{ "ra1p2", CF_USE1|CF_USE2|CF_CHG3 }, // PFAM: M(KR,Ares) A(o1, o2) T:No K:No
|
||||
{ "m12ttpa", CF_USE1|CF_USE2|CF_CHG3 }, // PFAM: M(o1,o2) A(T, Ares) T:Yes K:No
|
||||
{ "iat1p2", CF_USE1|CF_USE2|CF_CHG3 }, // PFAM: M(KI,Ares) A(o1, o2) T:Yes K:No
|
||||
{ "m12tpm", CF_USE1|CF_USE2|CF_CHG3 }, // PFAM: M(o1,o2) A(T, Mres) T:No K:No
|
||||
{ "ia1p2", CF_USE1|CF_USE2|CF_CHG3 }, // PFAM: M(KI,Ares) A(o1, o2) T:No K:No
|
||||
{ "m12tpa", CF_USE1|CF_USE2|CF_CHG3 }, // PFAM: M(o1,o2) A(T, Ares) T:No K:No
|
||||
{ "r2s1", CF_USE1|CF_USE2|CF_CHG3 }, // PFSM: M(KR,o2) A(o1, Mres) T:No K:No
|
||||
{ "r2st", CF_USE1|CF_USE2|CF_CHG3 }, // PFSM: M(KR,o2) A(T, Mres) T:No K:Yes
|
||||
{ "r2as1", CF_USE1|CF_USE2|CF_CHG3 }, // PFSM: M(KR,o2) A(o1, Ares) T:Yes K:No
|
||||
{ "r2ast", CF_USE1|CF_USE2|CF_CHG3 }, // PFSM: M(KR,o2) A(T, Ares) T:Yes K:Yes
|
||||
{ "i2s1", CF_USE1|CF_USE2|CF_CHG3 }, // PFSM: M(KI,o2) A(o1, Mres) T:No K:No
|
||||
{ "i2st", CF_USE1|CF_USE2|CF_CHG3 }, // PFSM: M(KI,o2) A(T, Mres) T:No K:Yes
|
||||
{ "i2as1", CF_USE1|CF_USE2|CF_CHG3 }, // PFSM: M(KI,o2) A(o1, Ares) T:Yes K:No
|
||||
{ "i2ast", CF_USE1|CF_USE2|CF_CHG3 }, // PFSM: M(KI,o2) A(T, Ares) T:Yes K:Yes
|
||||
{ "rat1s2", CF_USE1|CF_USE2|CF_CHG3 }, // PFSM: M(KR,Ares) A(o1, o2) T:Yes K:No
|
||||
{ "m12asm", CF_USE1|CF_USE2|CF_CHG3 }, // PFSM: M(o1,o2) A(Ares,Mres) T:No K:No
|
||||
{ "ra1s2", CF_USE1|CF_USE2|CF_CHG3 }, // PFSM: M(KR,Ares) A(o1, o2) T:No K:No
|
||||
{ "m12ttsa", CF_USE1|CF_USE2|CF_CHG3 }, // PFSM: M(o1,o2) A(T, Ares) T:Yes K:No
|
||||
{ "iat1s2", CF_USE1|CF_USE2|CF_CHG3 }, // PFSM: M(KI,Ares) A(o1, o2) T:Yes K:No
|
||||
{ "m12tsm", CF_USE1|CF_USE2|CF_CHG3 }, // PFSM: M(o1,o2) A(T, Mres) T:No K:No
|
||||
{ "ia1s2", CF_USE1|CF_USE2|CF_CHG3 }, // PFSM: M(KI,Ares) A(o1, o2) T:No K:No
|
||||
{ "m12tsa", CF_USE1|CF_USE2|CF_CHG3 }, // PFSM: M(o1,o2) A(T, Ares) T:No K:No
|
||||
{ "mr2p1", CF_USE1|CF_USE2|CF_CHG3 }, // PFMAM: M(KR,o2) A(o1, Mres) T:No K:No
|
||||
{ "mr2pt", CF_USE1|CF_USE2|CF_CHG3 }, // PFMAM: M(KR,o2) A(T, Mres) T:No K:Yes
|
||||
{ "mr2mp1", CF_USE1|CF_USE2|CF_CHG3 }, // PFMAM: M(KR,o2) A(o1, Mres) T:Yes K:No
|
||||
{ "mr2mpt", CF_USE1|CF_USE2|CF_CHG3 }, // PFMAM: M(KR,o2) A(T, Mres) T:Yes K:Yes
|
||||
{ "mi2p1", CF_USE1|CF_USE2|CF_CHG3 }, // PFMAM: M(KI,o2) A(o1, Mres) T:No K:No
|
||||
{ "mi2pt", CF_USE1|CF_USE2|CF_CHG3 }, // PFMAM: M(KI,o2) A(T, Mres) T:No K:Yes
|
||||
{ "mi2mp1", CF_USE1|CF_USE2|CF_CHG3 }, // PFMAM: M(KI,o2) A(o1, Mres) T:Yes K:No
|
||||
{ "mi2mpt", CF_USE1|CF_USE2|CF_CHG3 }, // PFMAM: M(KI,o2) A(T, Mres) T:Yes K:Yes
|
||||
{ "mrmt1p2", CF_USE1|CF_USE2|CF_CHG3 }, // PFMAM: M(KR,Mres) A(o1, o2) T:Yes K:No
|
||||
{ "mm12mpm", CF_USE1|CF_USE2|CF_CHG3 }, // PFMAM: M(o1,o2) A(Mres,Mres) T:No K:No
|
||||
{ "mrm1p2", CF_USE1|CF_USE2|CF_CHG3 }, // PFMAM: M(KR,Mres) A(o1, o2) T:No K:No
|
||||
{ "mm12ttpm", CF_USE1|CF_USE2|CF_CHG3 }, // PFMAM: M(o1,o2) A(T, Mres) T:Yes K:No
|
||||
{ "mimt1p2", CF_USE1|CF_USE2|CF_CHG3 }, // PFMAM: M(KI,Mres) A(o1, o2) T:Yes K:No
|
||||
{ "mm12tpm", CF_USE1|CF_USE2|CF_CHG3 }, // PFMAM: M(o1,o2) A(T, Mres) T:No K:No
|
||||
{ "mim1p2", CF_USE1|CF_USE2|CF_CHG3 }, // PFMAM: M(KI,Mres) A(o1, o2) T:No K:No
|
||||
{ "mr2s1", CF_USE1|CF_USE2|CF_CHG3 }, // PFMSM: M(KR,o2) A(o1, Mres) T:No K:No
|
||||
{ "mr2st", CF_USE1|CF_USE2|CF_CHG3 }, // PFMSM: M(KR,o2) A(T, Mres) T:No K:Yes
|
||||
{ "mr2ms1", CF_USE1|CF_USE2|CF_CHG3 }, // PFMSM: M(KR,o2) A(o1, Mres) T:Yes K:No
|
||||
{ "mr2mst", CF_USE1|CF_USE2|CF_CHG3 }, // PFMSM: M(KR,o2) A(T, Mres) T:Yes K:Yes
|
||||
{ "mi2s1", CF_USE1|CF_USE2|CF_CHG3 }, // PFMSM: M(KI,o2) A(o1, Mres) T:No K:No
|
||||
{ "mi2st", CF_USE1|CF_USE2|CF_CHG3 }, // PFMSM: M(KI,o2) A(T, Mres) T:No K:Yes
|
||||
{ "mi2ms1", CF_USE1|CF_USE2|CF_CHG3 }, // PFMSM: M(KI,o2) A(o1, Mres) T:Yes K:No
|
||||
{ "mi2mst", CF_USE1|CF_USE2|CF_CHG3 }, // PFMSM: M(KI,o2) A(T, Mres) T:Yes K:Yes
|
||||
{ "mrmt1s2", CF_USE1|CF_USE2|CF_CHG3 }, // PFMSM: M(KR,Mres) A(o1, o2) T:Yes K:No
|
||||
{ "mm12msm", CF_USE1|CF_USE2|CF_CHG3 }, // PFMSM: M(o1,o2) A(Mres,Mres) T:No K:No
|
||||
{ "mrm1s2", CF_USE1|CF_USE2|CF_CHG3 }, // PFMSM: M(KR,Mres) A(o1, o2) T:No K:No
|
||||
{ "mm12ttsm", CF_USE1|CF_USE2|CF_CHG3 }, // PFMSM: M(o1,o2) A(T, Mres) T:Yes K:No
|
||||
{ "mimt1s2", CF_USE1|CF_USE2|CF_CHG3 }, // PFMSM: M(KI,Mres) A(o1, o2) T:Yes K:No
|
||||
{ "mm12tsm", CF_USE1|CF_USE2|CF_CHG3 }, // PFMSM: M(o1,o2) A(T, Mres) T:No K:No
|
||||
{ "mim1s2", CF_USE1|CF_USE2|CF_CHG3 }, // PFMSM: M(KI,Mres) A(o1, o2) T:No K:No
|
||||
|
||||
};
|
||||
|
||||
CASSERT(qnumber(Instructions) == I860_last);
|
||||
171
idasdk75/module/i860/ins.hpp
Normal file
171
idasdk75/module/i860/ins.hpp
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA).
|
||||
* Copyright (c) 1990-2020 Hex-Rays
|
||||
* ALL RIGHTS RESERVED.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __INSTRS_HPP
|
||||
#define __INSTRS_HPP
|
||||
|
||||
extern const instruc_t Instructions[];
|
||||
|
||||
enum nameNum ENUM_SIZE(uint16)
|
||||
{
|
||||
|
||||
I860_null = 0, // Unknown Operation
|
||||
|
||||
//
|
||||
// Intel 860 XP instructions
|
||||
//
|
||||
|
||||
I860_adds,
|
||||
I860_addu,
|
||||
I860_and,
|
||||
I860_andh,
|
||||
I860_andnot,
|
||||
I860_andnoth,
|
||||
I860_bc,
|
||||
I860_bc_t,
|
||||
I860_bla,
|
||||
I860_bnc,
|
||||
I860_bnc_t,
|
||||
I860_br,
|
||||
I860_bri,
|
||||
I860_bte,
|
||||
I860_btne,
|
||||
I860_call,
|
||||
I860_calli,
|
||||
I860_fadd,
|
||||
I860_faddp,
|
||||
I860_faddz,
|
||||
I860_famov,
|
||||
I860_fiadd,
|
||||
I860_fisub,
|
||||
I860_fix,
|
||||
I860_fld,
|
||||
I860_flush,
|
||||
I860_fmlow_dd,
|
||||
I860_fmul,
|
||||
I860_form,
|
||||
I860_frcp,
|
||||
I860_frsqr,
|
||||
I860_fst,
|
||||
I860_fsub,
|
||||
I860_ftrunc,
|
||||
I860_fxfr,
|
||||
I860_fzchkl,
|
||||
I860_fzchks,
|
||||
I860_introvr,
|
||||
I860_ixfr,
|
||||
I860_ld_c,
|
||||
I860_ld,
|
||||
I860_ldint,
|
||||
I860_ldio,
|
||||
I860_lock,
|
||||
I860_or,
|
||||
I860_orh,
|
||||
I860_pfadd,
|
||||
I860_pfaddp,
|
||||
I860_pfaddz,
|
||||
I860_pfamov,
|
||||
I860_pfeq,
|
||||
I860_pfgt,
|
||||
I860_pfiadd,
|
||||
I860_pfisub,
|
||||
I860_pfix,
|
||||
I860_pfld,
|
||||
I860_pfle,
|
||||
I860_pfmul,
|
||||
I860_pfmul3_dd,
|
||||
I860_pform,
|
||||
I860_pfsub,
|
||||
I860_pftrunc,
|
||||
I860_pfzchkl,
|
||||
I860_pfzchks,
|
||||
I860_pst_d,
|
||||
I860_scyc,
|
||||
I860_shl,
|
||||
I860_shr,
|
||||
I860_shra,
|
||||
I860_shrd,
|
||||
I860_st_c,
|
||||
I860_st,
|
||||
I860_stio,
|
||||
I860_subs,
|
||||
I860_subu,
|
||||
I860_trap,
|
||||
I860_unlock,
|
||||
I860_xor,
|
||||
I860_xorh,
|
||||
//
|
||||
// iNTEL 860 XP Pipelined F-P instructions
|
||||
//
|
||||
I860_r2p1,
|
||||
I860_r2pt,
|
||||
I860_r2ap1,
|
||||
I860_r2apt,
|
||||
I860_i2p1,
|
||||
I860_i2pt,
|
||||
I860_i2ap1,
|
||||
I860_i2apt,
|
||||
I860_rat1p2,
|
||||
I860_m12apm,
|
||||
I860_ra1p2,
|
||||
I860_m12ttpa,
|
||||
I860_iat1p2,
|
||||
I860_m12tpm,
|
||||
I860_ia1p2,
|
||||
I860_m12tpa,
|
||||
I860_r2s1,
|
||||
I860_r2st,
|
||||
I860_r2as1,
|
||||
I860_r2ast,
|
||||
I860_i2s1,
|
||||
I860_i2st,
|
||||
I860_i2as1,
|
||||
I860_i2ast,
|
||||
I860_rat1s2,
|
||||
I860_m12asm,
|
||||
I860_ra1s2,
|
||||
I860_m12ttsa,
|
||||
I860_iat1s2,
|
||||
I860_m12tsm,
|
||||
I860_ia1s2,
|
||||
I860_m12tsa,
|
||||
I860_mr2p1,
|
||||
I860_mr2pt,
|
||||
I860_mr2mp1,
|
||||
I860_mr2mpt,
|
||||
I860_mi2p1,
|
||||
I860_mi2pt,
|
||||
I860_mi2mp1,
|
||||
I860_mi2mpt,
|
||||
I860_mrmt1p2,
|
||||
I860_mm12mpm,
|
||||
I860_mrm1p2,
|
||||
I860_mm12ttpm,
|
||||
I860_mimt1p2,
|
||||
I860_mm12tpm,
|
||||
I860_mim1p2,
|
||||
I860_mr2s1,
|
||||
I860_mr2st,
|
||||
I860_mr2ms1,
|
||||
I860_mr2mst,
|
||||
I860_mi2s1,
|
||||
I860_mi2st,
|
||||
I860_mi2ms1,
|
||||
I860_mi2mst,
|
||||
I860_mrmt1s2,
|
||||
I860_mm12msm,
|
||||
I860_mrm1s2,
|
||||
I860_mm12ttsm,
|
||||
I860_mimt1s2,
|
||||
I860_mm12tsm,
|
||||
I860_mim1s2,
|
||||
|
||||
I860_last,
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
40
idasdk75/module/i860/makefile
Normal file
40
idasdk75/module/i860/makefile
Normal file
@@ -0,0 +1,40 @@
|
||||
PROC=i860
|
||||
|
||||
include ../module.mak
|
||||
|
||||
# MAKEDEP dependency list ------------------
|
||||
$(F)ana$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
|
||||
$(I)config.hpp $(I)fpro.h $(I)funcs.hpp $(I)ida.hpp \
|
||||
$(I)idp.hpp $(I)kernwin.hpp $(I)lines.hpp $(I)llong.hpp \
|
||||
$(I)loader.hpp $(I)nalt.hpp $(I)name.hpp $(I)netnode.hpp \
|
||||
$(I)offset.hpp $(I)pro.h $(I)problems.hpp $(I)range.hpp \
|
||||
$(I)segment.hpp $(I)ua.hpp $(I)xref.hpp ../idaidp.hpp \
|
||||
ana.cpp i860.hpp ins.hpp
|
||||
$(F)emu$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
|
||||
$(I)config.hpp $(I)fpro.h $(I)funcs.hpp $(I)ida.hpp \
|
||||
$(I)idp.hpp $(I)kernwin.hpp $(I)lines.hpp $(I)llong.hpp \
|
||||
$(I)loader.hpp $(I)nalt.hpp $(I)name.hpp $(I)netnode.hpp \
|
||||
$(I)offset.hpp $(I)pro.h $(I)problems.hpp $(I)range.hpp \
|
||||
$(I)segment.hpp $(I)ua.hpp $(I)xref.hpp ../idaidp.hpp \
|
||||
emu.cpp i860.hpp ins.hpp
|
||||
$(F)ins$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
|
||||
$(I)config.hpp $(I)fpro.h $(I)funcs.hpp $(I)ida.hpp \
|
||||
$(I)idp.hpp $(I)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 \
|
||||
i860.hpp ins.cpp ins.hpp
|
||||
$(F)out$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
|
||||
$(I)config.hpp $(I)fpro.h $(I)funcs.hpp $(I)ida.hpp \
|
||||
$(I)idp.hpp $(I)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 \
|
||||
i860.hpp ins.hpp out.cpp
|
||||
$(F)reg$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
|
||||
$(I)config.hpp $(I)fpro.h $(I)funcs.hpp $(I)ida.hpp \
|
||||
$(I)idp.hpp $(I)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 \
|
||||
i860.hpp ins.hpp reg.cpp
|
||||
294
idasdk75/module/i860/out.cpp
Normal file
294
idasdk75/module/i860/out.cpp
Normal file
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA).
|
||||
* Copyright (c) 1990-95 by Ilfak Guilfanov.
|
||||
* ALL RIGHTS RESERVED.
|
||||
* FIDO: 2:5020/209
|
||||
* E-mail: ig@estar.msk.su
|
||||
*
|
||||
*/
|
||||
|
||||
#include "i860.hpp"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
class out_i860_t : public outctx_t
|
||||
{
|
||||
out_i860_t(void) = delete; // not used
|
||||
public:
|
||||
void OutReg(int rgnum) { out_register(ph.reg_names[rgnum]); }
|
||||
|
||||
bool out_operand(const op_t &x);
|
||||
void out_insn(void);
|
||||
};
|
||||
CASSERT(sizeof(out_i860_t) == sizeof(outctx_t));
|
||||
|
||||
DECLARE_OUT_FUNCS_WITHOUT_OUTMNEM(out_i860_t)
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool out_i860_t::out_operand(const op_t &x)
|
||||
{
|
||||
switch ( x.type )
|
||||
{
|
||||
case o_reg:
|
||||
OutReg(x.reg);
|
||||
break;
|
||||
case o_displ:
|
||||
out_value(x, OOF_ADDR|OOFW_32);
|
||||
goto common;
|
||||
case o_phrase:
|
||||
OutReg(int(x.addr));
|
||||
common:
|
||||
{
|
||||
int s2 = char(x.reg);
|
||||
if ( s2 != 0 )
|
||||
{
|
||||
out_symbol('(');
|
||||
OutReg(s2 < 0 ? -s2 : s2);
|
||||
out_symbol(')');
|
||||
if ( char(x.reg) < 0 )
|
||||
{
|
||||
out_symbol('+');
|
||||
out_symbol('+');
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case o_imm:
|
||||
out_value(x, OOF_SIGNED|OOFW_32);
|
||||
break;
|
||||
case o_mem:
|
||||
case o_near:
|
||||
if ( !out_name_expr(x, x.addr, x.addr) )
|
||||
{
|
||||
out_value(x, OOF_ADDR|OOF_NUMBER|OOFS_NOSIGN|OOFW_32);
|
||||
remember_problem(PR_NONAME, insn.ea);
|
||||
}
|
||||
break;
|
||||
case o_void:
|
||||
return 0;
|
||||
default:
|
||||
warning("out: %a: bad optype %d", insn.ea, x.type);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void out_i860_t::out_insn(void)
|
||||
{
|
||||
{
|
||||
out_tagon(COLOR_INSN);
|
||||
const char *cname = insn.get_canon_mnem(ph);
|
||||
int i = 16 - (inf_get_indent() & 7);
|
||||
if ( insn.auxpref & Dbit )
|
||||
{
|
||||
out_char('d');
|
||||
out_char('.');
|
||||
i -= 2;
|
||||
}
|
||||
while ( *cname != 0 )
|
||||
{
|
||||
out_char(*cname++);
|
||||
i--;
|
||||
}
|
||||
switch ( insn.itype )
|
||||
{
|
||||
case I860_fadd:
|
||||
case I860_pfadd:
|
||||
case I860_famov:
|
||||
case I860_pfamov:
|
||||
case I860_fiadd:
|
||||
case I860_pfiadd:
|
||||
case I860_fisub:
|
||||
case I860_pfisub:
|
||||
case I860_fix:
|
||||
case I860_pfix:
|
||||
case I860_fmul:
|
||||
case I860_pfmul:
|
||||
case I860_frcp:
|
||||
case I860_frsqr:
|
||||
case I860_fsub:
|
||||
case I860_pfsub:
|
||||
case I860_ftrunc:
|
||||
case I860_pftrunc:
|
||||
case I860_pfeq:
|
||||
case I860_pfgt:
|
||||
case I860_pfle:
|
||||
case I860_r2p1:
|
||||
case I860_r2pt:
|
||||
case I860_r2ap1:
|
||||
case I860_r2apt:
|
||||
case I860_i2p1:
|
||||
case I860_i2pt:
|
||||
case I860_i2ap1:
|
||||
case I860_i2apt:
|
||||
case I860_rat1p2:
|
||||
case I860_m12apm:
|
||||
case I860_ra1p2:
|
||||
case I860_m12ttpa:
|
||||
case I860_iat1p2:
|
||||
case I860_m12tpm:
|
||||
case I860_ia1p2:
|
||||
case I860_m12tpa:
|
||||
case I860_r2s1:
|
||||
case I860_r2st:
|
||||
case I860_r2as1:
|
||||
case I860_r2ast:
|
||||
case I860_i2s1:
|
||||
case I860_i2st:
|
||||
case I860_i2as1:
|
||||
case I860_i2ast:
|
||||
case I860_rat1s2:
|
||||
case I860_m12asm:
|
||||
case I860_ra1s2:
|
||||
case I860_m12ttsa:
|
||||
case I860_iat1s2:
|
||||
case I860_m12tsm:
|
||||
case I860_ia1s2:
|
||||
case I860_m12tsa:
|
||||
case I860_mr2p1:
|
||||
case I860_mr2pt:
|
||||
case I860_mr2mp1:
|
||||
case I860_mr2mpt:
|
||||
case I860_mi2p1:
|
||||
case I860_mi2pt:
|
||||
case I860_mi2mp1:
|
||||
case I860_mi2mpt:
|
||||
case I860_mrmt1p2:
|
||||
case I860_mm12mpm:
|
||||
case I860_mrm1p2:
|
||||
case I860_mm12ttpm:
|
||||
case I860_mimt1p2:
|
||||
case I860_mm12tpm:
|
||||
case I860_mim1p2:
|
||||
case I860_mr2s1:
|
||||
case I860_mr2st:
|
||||
case I860_mr2ms1:
|
||||
case I860_mr2mst:
|
||||
case I860_mi2s1:
|
||||
case I860_mi2st:
|
||||
case I860_mi2ms1:
|
||||
case I860_mi2mst:
|
||||
case I860_mrmt1s2:
|
||||
case I860_mm12msm:
|
||||
case I860_mrm1s2:
|
||||
case I860_mm12ttsm:
|
||||
case I860_mimt1s2:
|
||||
case I860_mm12tsm:
|
||||
case I860_mim1s2:
|
||||
out_char('.');
|
||||
out_char( (insn.auxpref & Sbit) ? 'd' : 's');
|
||||
out_char( (insn.auxpref & Rbit) ? 'd' : 's');
|
||||
i -= 3;
|
||||
break;
|
||||
case I860_fld:
|
||||
case I860_fst:
|
||||
case I860_ld:
|
||||
case I860_ldint:
|
||||
case I860_ldio:
|
||||
case I860_pfld:
|
||||
case I860_scyc:
|
||||
case I860_st:
|
||||
case I860_stio:
|
||||
out_char('.');
|
||||
switch ( insn.Op1.dtype )
|
||||
{
|
||||
case dt_byte: out_char('b'); break;
|
||||
case dt_word: out_char('s'); break;
|
||||
case dt_dword: out_char('l'); break;
|
||||
case dt_qword: out_char('d'); break;
|
||||
case dt_byte16: out_char('q'); break;
|
||||
}
|
||||
i -= 2;
|
||||
break;
|
||||
}
|
||||
out_tagoff(COLOR_INSN);
|
||||
do
|
||||
{
|
||||
out_char(' ');
|
||||
i--;
|
||||
} while ( i > 0 );
|
||||
}
|
||||
|
||||
bool comma = out_one_operand(0);
|
||||
|
||||
if ( comma && insn.Op2.shown() && insn.Op2.type != o_void )
|
||||
{
|
||||
out_symbol(',');
|
||||
out_char(' ');
|
||||
}
|
||||
|
||||
out_one_operand(1);
|
||||
|
||||
if ( comma && insn.Op3.shown() && insn.Op3.type != o_void )
|
||||
{
|
||||
out_symbol(',');
|
||||
out_char(' ');
|
||||
}
|
||||
|
||||
out_one_operand(2);
|
||||
|
||||
out_immchar_cmts();
|
||||
flush_outbuf();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void idaapi i860_header(outctx_t &ctx)
|
||||
{
|
||||
ctx.gen_header(GH_PRINT_PROC);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//lint -esym(1764, ctx) could be made const
|
||||
//lint -esym(818, Sarea) could be made const
|
||||
void i860_t::i860_segstart(outctx_t &ctx, segment_t *Sarea) const
|
||||
{
|
||||
qstring sname;
|
||||
get_segm_name(&sname, Sarea);
|
||||
ctx.gen_printf(DEFAULT_INDENT, COLSTR(".text %s %s",SCOLOR_ASMDIR), ash.cmnt, sname.c_str());
|
||||
|
||||
const char *p = ".byte";
|
||||
switch ( Sarea->align )
|
||||
{
|
||||
case saRelByte: p = ".byte"; break;
|
||||
case saRelWord: p = ".word"; break;
|
||||
case saRelPara: p = ".float"; break;
|
||||
}
|
||||
ctx.gen_printf(DEFAULT_INDENT, COLSTR(".align %s", SCOLOR_ASMDIR), p);
|
||||
|
||||
if ( (inf_get_outflags() & OFLG_GEN_ORG) != 0 )
|
||||
{
|
||||
ea_t org = ctx.insn_ea - get_segm_base(Sarea);
|
||||
if ( org != 0 )
|
||||
{
|
||||
char buf[MAX_NUMBUF];
|
||||
btoa(buf, sizeof(buf), org);
|
||||
ctx.gen_printf(DEFAULT_INDENT,
|
||||
COLSTR("%s%s %s",SCOLOR_AUTOCMT),
|
||||
ash.cmnt, ash.origin, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void i860_t::i860_footer(outctx_t &ctx) const
|
||||
{
|
||||
char buf[MAXSTR];
|
||||
if ( ash.end != NULL )
|
||||
{
|
||||
ctx.gen_empty_line();
|
||||
char *ptr = buf;
|
||||
char *end = buf + sizeof(buf);
|
||||
APPEND(ptr, end, ash.end);
|
||||
qstring name;
|
||||
if ( get_colored_name(&name, inf_get_start_ea()) > 0 )
|
||||
{
|
||||
APPCHAR(ptr, end, ' ');
|
||||
APPEND(ptr, end, name.begin());
|
||||
}
|
||||
ctx.flush_buf(buf, DEFAULT_INDENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx.gen_cmt_line("end of file");
|
||||
}
|
||||
}
|
||||
328
idasdk75/module/i860/reg.cpp
Normal file
328
idasdk75/module/i860/reg.cpp
Normal file
@@ -0,0 +1,328 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA).
|
||||
* Version 3.05
|
||||
* Copyright (c) 1990-95 by Ilfak Guilfanov.
|
||||
* ALL RIGHTS RESERVED.
|
||||
* FIDO: 2:5020/209
|
||||
* E-mail: ig@estar.msk.su
|
||||
*
|
||||
*/
|
||||
|
||||
#include "i860.hpp"
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static const char *const RegNames[] =
|
||||
{
|
||||
// r0 == 0 always
|
||||
// r3 - stack frame pointer
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
||||
"r8", "r9", "r10","r11","r12","r13","r14","r15",
|
||||
"r16","r17","r18","r19","r20","r21","r22","r23",
|
||||
"r24","r25","r26","r27","r28","r29","r30","r31",
|
||||
// f0,f1 == 0 always
|
||||
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
|
||||
"f8", "f9", "f10","f11","f12","f13","f14","f15",
|
||||
"f16","f17","f18","f19","f20","f21","f22","f23",
|
||||
"f24","f25","f26","f27","f28","f29","f30","f31",
|
||||
"fir", // Fault Instruction Register (read-only)
|
||||
"psr", // Processor Status Register Can Modify
|
||||
// 0 - BR Break Read only supervisor
|
||||
// 1 - BW Break Write only supervisor
|
||||
// 2 - CC Condition Code
|
||||
// 3 - LCC Loop Condition Code
|
||||
// 4 - IM Interrupt Mode only supervisor
|
||||
// ena/disa external intrs
|
||||
// on INT pin
|
||||
// 5 - PIM Previous Interrupt Mode only supervisor
|
||||
// 6 - U User Mode only supervisor
|
||||
// 1 - user mode
|
||||
// 0 - supervisor
|
||||
// 7 - PU Previous User Mode only supervisor
|
||||
// 8 - IT Instruction Trap only supervisor
|
||||
// 9 - IN Interrupt only supervisor
|
||||
// 10- IAT Instruction Access Trap only supervisor
|
||||
// 11- DAT Data Access Trap only supervisor
|
||||
// 12- FT Floating Point Trap only supervisor
|
||||
// 13- DS Delayed Switch only supervisor
|
||||
// 14- DIM Dual Instruction Mode only supervisor
|
||||
// 15- KNF Kill Next FP Instruction only supervisor
|
||||
// 16- Reserved
|
||||
// 17-21 SC Shift Count
|
||||
// 22-23 PS Pixel Size
|
||||
// 00 - 8
|
||||
// 01 - 16
|
||||
// 10 - 32
|
||||
// 11 - undefined
|
||||
// 24-31 PM Pixel Mask
|
||||
"dirbase", // Directory Base Register
|
||||
// 0 ATE Address Translation Enable
|
||||
// 1-3 DPS DRAM Page Size
|
||||
// ignore 12+DPS bits
|
||||
// 4 BL Bus Lock
|
||||
// 5 ITI Cache and TLB Invalidate
|
||||
// 6 LB Late Back-off Mode
|
||||
// 7 CS8 Code Size 8-bit
|
||||
// 8-9 RB Replacement Block
|
||||
// 10-11 RC Replacement Control
|
||||
// 12-31 DTB Directory Table Base
|
||||
"db", // Data Breakpoint Register
|
||||
"fsr", // Floating Point Status Register
|
||||
// 0 FZ Flush Zero
|
||||
// 1 TI Trap Inexact
|
||||
// 2-3 RM Rounding Mode
|
||||
// 0 - nearest or even
|
||||
// 1 - down
|
||||
// 2 - up
|
||||
// 3 - chop
|
||||
// 4 U Update Bit
|
||||
// 5 FTE Floating Point Trap Enable
|
||||
// 6 Reserved
|
||||
// 7 SI Sticky Inexact
|
||||
// 8 SE Source Exception
|
||||
// 9 MU Multiplier Underflow
|
||||
// 10 MO Multiplier Overflow
|
||||
// 11 MI Multiplier Inexact
|
||||
// 12 MA Multiplier Add-One
|
||||
// 13 AU Adder Underflow
|
||||
// 14 AO Adder Overflow
|
||||
// 15 AI Adder Inexact
|
||||
// 16 AA Adder Add-One
|
||||
// 17-21 RR Result Register
|
||||
// 22-24 AE Adder Exponent
|
||||
// 25-26 LRP Load Pipe Result Precision
|
||||
// 27 IRP Integer (Graphics) Pipe Result Precision
|
||||
// 28 MRP Multiplier Pipe Result Precision
|
||||
// 29 ARP Adder Pipe Result Precision
|
||||
// 30 Reserved
|
||||
// 31 Reserved
|
||||
"epsr", // Extended Processor Status Register
|
||||
// 0-7 Processor Type
|
||||
// = 2 for i860 XP
|
||||
// 8-12 Stepping Number
|
||||
// 13 IL InterLock
|
||||
// 14 WP Write Protect
|
||||
// 15 PEF Parity Error Flag
|
||||
// 16 BEF Bus Error Flag
|
||||
// 17 INT Interrupt
|
||||
// 18-21 DCS Data Cache Size = 2**(12+DCS)
|
||||
// 22 PBM Page-Table Bit Mode
|
||||
// 23 BE Big Endian
|
||||
// 0 - little endian
|
||||
// 1 - big endian
|
||||
// 24 OF Overflow Flag
|
||||
// 25 BS BEF or PEF In Supervisor Mode
|
||||
// 26 DI Trap On Delayed Instruction
|
||||
// 27 TAI Trap On AutoIncrement Instruction
|
||||
// 28 PT Trap On Pipeline Use
|
||||
// 29 PI Pipeline Instruction
|
||||
// 30 SO Strong Ordering
|
||||
// 31 Reserved
|
||||
"bear", // Bus Error Address Register (read-only)
|
||||
"ccr", // Concurrency Control Register
|
||||
// 0-1 Reserved
|
||||
// 2 Detached Only
|
||||
// 3 CCU on
|
||||
// 4-11 Reserved
|
||||
// 12 Zero
|
||||
// 13-31 CCUBASE
|
||||
"p0", // Privileged Register 0 (any purpose)
|
||||
"p1", // Privileged Register 1 (any purpose)
|
||||
"p2", // Privileged Register 2 (any purpose)
|
||||
"p3", // Privileged Register 3 (any purpose)
|
||||
"cs","ds"
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void i860_t::set_cpu(int procnum)
|
||||
{
|
||||
pflag = procnum ? _PT_860XP : _PT_860XR;
|
||||
}
|
||||
//----------------------------------------------------------------------
|
||||
// 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(new i860_t);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
ssize_t idaapi i860_t::on_event(ssize_t msgid, va_list va)
|
||||
{
|
||||
switch ( msgid )
|
||||
{
|
||||
case processor_t::ev_ending_undo:
|
||||
// restore ptype
|
||||
set_cpu(ph.get_proc_index());
|
||||
break;
|
||||
|
||||
case processor_t::ev_newprc:
|
||||
set_cpu(va_arg(va, int));
|
||||
// bool keep_cfg = va_argi(va, bool);
|
||||
break;
|
||||
|
||||
case processor_t::ev_out_header:
|
||||
{
|
||||
outctx_t *ctx = va_arg(va, outctx_t *);
|
||||
i860_header(*ctx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case processor_t::ev_out_footer:
|
||||
{
|
||||
outctx_t *ctx = va_arg(va, outctx_t *);
|
||||
i860_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 *);
|
||||
i860_segstart(*ctx, seg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case processor_t::ev_ana_insn:
|
||||
{
|
||||
insn_t *out = va_arg(va, insn_t *);
|
||||
return i860_ana(out);
|
||||
}
|
||||
|
||||
case processor_t::ev_emu_insn:
|
||||
{
|
||||
const insn_t *insn = va_arg(va, const insn_t *);
|
||||
return i860_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;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// aIntel860,
|
||||
// Generic for Intel 860
|
||||
//-----------------------------------------------------------------------
|
||||
static const asm_t i860 =
|
||||
{
|
||||
AS_COLON | ASH_HEXF3,
|
||||
0,
|
||||
"Generic for Intel 860",
|
||||
0,
|
||||
NULL,
|
||||
"org",
|
||||
NULL,
|
||||
|
||||
"//", // comment string
|
||||
'\"', // string delimiter
|
||||
'\'', // char delimiter
|
||||
"'\"", // special symbols in char and string constants
|
||||
|
||||
".byte", // ascii string directive
|
||||
".byte", // byte directive
|
||||
".word", // word directive
|
||||
".long", // double words
|
||||
NULL, // qwords
|
||||
NULL, // oword (16 bytes)
|
||||
NULL, // float (4 bytes)
|
||||
NULL, // double (8 bytes)
|
||||
NULL, // tbyte (10/12 bytes)
|
||||
NULL, // packed decimal real
|
||||
"[#d] #v", // arrays (#h,#d,#v,#s(...)
|
||||
".byte [%s]", // uninited arrays
|
||||
NULL, // equ
|
||||
NULL, // seg prefix
|
||||
NULL, // curip
|
||||
NULL, // func_header
|
||||
NULL, // func_footer
|
||||
NULL, // public
|
||||
NULL, // weak
|
||||
NULL, // extrn
|
||||
NULL, // comm
|
||||
NULL, // get_type_name
|
||||
NULL, // align
|
||||
'(', ')', // lbrace, rbrace
|
||||
NULL, // mod
|
||||
NULL, // and
|
||||
NULL, // or
|
||||
NULL, // xor
|
||||
NULL, // not
|
||||
NULL, // shl
|
||||
NULL, // shr
|
||||
NULL, // sizeof
|
||||
};
|
||||
|
||||
const asm_t *const i860asms[] = { &i860, NULL };
|
||||
//-----------------------------------------------------------------------
|
||||
#define FAMILY "Intel 860 processors:"
|
||||
|
||||
static const char *const shnames[] =
|
||||
{
|
||||
"860xr",
|
||||
"860xp",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *const lnames[] =
|
||||
{
|
||||
FAMILY"Intel 860 XR",
|
||||
"Intel 860 XP",
|
||||
NULL
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static const bytes_t retcodes[] =
|
||||
{
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Intel 860XP processor definition
|
||||
//-----------------------------------------------------------------------
|
||||
processor_t LPH =
|
||||
{
|
||||
IDP_INTERFACE_VERSION, // version
|
||||
PLFM_I860, // id
|
||||
// flag
|
||||
PR_USE32,
|
||||
// flag2
|
||||
0,
|
||||
8, // 8 bits in a byte for code segments
|
||||
8, // 8 bits in a byte for other segments
|
||||
|
||||
shnames,
|
||||
lnames,
|
||||
|
||||
i860asms,
|
||||
|
||||
notify,
|
||||
|
||||
RegNames, // Regsiter names
|
||||
R_vds+1, // Number of registers
|
||||
|
||||
R_vcs,R_vds,
|
||||
0, // size of a segment register
|
||||
R_vcs,R_vds,
|
||||
|
||||
NULL, // No known code start sequences
|
||||
retcodes,
|
||||
|
||||
0,I860_last,
|
||||
Instructions, // instruc
|
||||
};
|
||||
Reference in New Issue
Block a user