329 lines
11 KiB
C++
329 lines
11 KiB
C++
/*
|
|
* 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
|
|
};
|