295 lines
6.8 KiB
C++
295 lines
6.8 KiB
C++
/*
|
|
* 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");
|
|
}
|
|
}
|