update to ida 7.6, add builds
This commit is contained in:
253
idasdk76/module/i960/out.cpp
Normal file
253
idasdk76/module/i960/out.cpp
Normal 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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user