Files
2021-10-31 21:20:46 +02:00

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
};