File:  [Research Unix] / researchv9 / jtools / src / pi / asm.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:21:59 2018 UTC (8 years, 1 month ago) by root
Branches: belllabs, MAIN
CVS tags: researchv9-SUN3_old, researchv9-SUN3, HEAD
researchv9-SUN3(old)

#include "asm.pri"
#include "core.pub"
#include "format.pub"
#include "parse.h"
#include "expr.pub"
#include "frame.pub"
#include "process.pub"
#include "symtab.pub"
#include "symbol.h"
#include "bpts.pub"
SRCFILE("asm.c")

char *Instr::arg(int)			{ return "<arg>";	}
char *Instr::mnemonic()			{ return sf("0x%X?", opcode&0xFF); }
int Instr::argtype(int)			{ return 0;		}
int Instr::nargs()			{ return 0;		}
char *Asm::literaldelimiter()		{ return "<literal>"; }
Instr *Asm::newInstr(long)		{ return 0; }

Asm::Asm(Core *c)
{
	trace( "%d.Asm(%d)", this, c );		VOK;
	core = c;
	fmt = F_SYMBOLIC|F_HEX;
}

void Asm::userclose()
{
	trace( "%d.userclose()", this );	VOK;
	delete pad;
	pad = 0;
	Instr *instrsetsib;
	for( ; instrset; instrset = instrsetsib ){
		instrsetsib = instrset->sib;		// new malloc
		delete instrset;
	}
}

void Asm::banner()
{
	trace( "%d.banner()", this );	VOK;
	if( pad ){
		pad->banner("Assembler: %s", core->procpath());
		pad->name("Asm %s", basename(core->procpath()));
	}
}

void Asm::open(long a)
{
	trace("%d.open(%d)", this, a);	VOK;
	if( !pad ){
		Menu m;
		pad = new Pad( (PadRcv*) this );
		banner();
		m.last( "display pc",     (Action)&Asm::displaypc	 );
		if( core->online() ){
			m.first( "run",		  (Action)&Asm::go		 );
			m.last( "step  1 instr ", (Action)&Asm::instrstep,  1 );
			m.last( "step  4 instrs", (Action)&Asm::instrstep,  4 );
			m.last( "step 16 instrs", (Action)&Asm::instrstep, 16 );
			m.last( "step 64 instrs", (Action)&Asm::instrstep, 64 );
			m.last( "step over call", (Action)&Asm::stepover	 );
		}
		pad->menu(m);
	}
	pad->makecurrent();
	if( a ) newInstr(a);
}

void Asm::go()
{
	trace( "%d.go()", this ); VOK;
	core->process()->go();
}

void Asm::displaypc()
{
	trace("%d.displaypc()", this);	VOK;
	open(core->pc());
}

char *Asm::help()
{
	trace( "%d.help()", this );
	return ".=<expr> {display instruction at address}";
}

char *Asm::kbd(char *s)
{
	Parse y(G_DOTEQ_CONEX,0);
	Expr *e;
	Bls error;

	trace( "%d.kbd(%s)", this, s );		OK("kbd");
	if( !(e = (Expr*)y.parse(s)) )
		return sf("%s: %s", y.error, s);
	e->evaltext(core->process()->globals, error);
	if( e->evalerr )
		return sf("%s: %s", s, error.text);
	newInstr(e->val.lng);
	return 0;
}

char *Instr::literal(long f)			/* is Format right? */
{
	static char t[128];

	trace( "%d.literal(0x%X) 0x%X %g", this, f, m.lng, m.flt ); OK("literal");
	sprintf( t, "%s%s", _asm->literaldelimiter(),
			Format(f&~F_SYMBOLIC).f(m.lng,m.dbl) );
	return t;
}

char *Instr::symbolic(char *prefix)		/* is Format right? */
{
	static char t[128];

	trace( "%d.symbolic(%s) 0x%X", this, prefix, m.lng ); OK("symbolic");
	strcpy(t, prefix);
	strcat(t, Format(fmt, _asm->core->symtab()).f(m.lng));
	return t;
}

Var *Instr::local(UDisc d, long a)		/* VAX */
{
	Func *f;
	Block *b;

	trace("%d.local(0x%X,%d)", this, d, a); OK(0);
	if( !(f = (Func*)_asm->core->symtab()->loctosym(U_FUNC, addr)) ) return 0;
	if( !(b = f->blk(addr)) ) return 0;
	BlkVars bv(b);
	Var *v;
	while( v = bv.gen() )
		if( v->disc() == d && v->range.lo == a )
			break;
	return v;
}

Var *Instr::field(Var *v, long a)
{
	trace( "%d.field(%d,%d)", this, v, a ); OK(0);
	if( !v->type.isptr() ) return 0;
	DType *d = v->type.decref();
	if( !d->isstrun() ) return 0;
	TypMems tm(d->utype());
	while( v = tm.gen() )
		if( v->range.lo == a ) break;
	return v;
}

char *Instr::regarg(char *lay, long f)		/* is Format right? */
{
	static char t[128];
	char *o, *r;
	Var *v;

	trace("%d.regarg(%s,0x%X) %d 0x%X", this, lay, f, reg, m.lng); OK("regarg");
	r = _asm->core->regname(reg);
	o = Format(f&~F_SYMBOLIC).f(m.lng);
	if( f&F_SYMBOLIC ){
		if( reg == _asm->core->REG_AP() ){
			if( v = local(U_ARG, m.lng) )
				o = v->text();
		} else if( reg == _asm->core->REG_FP() ){
			if( v = local(U_AUT, m.lng) )
				o = v->text();
		} else {
			if( v = local(U_REG, reg) ){
				r = sf("%s=%s", v->text(), r);
				if( v = field(v, m.lng) )
					o = v->text();
			}
		}
	}
	sprintf(t, lay, o, r);
	return t;
}

void Instr::dobpt(int setorclr)
{
	trace( "%d.dobpt(%d)", this, setorclr ); VOK;
	Stmt *stmt = new Stmt(0,0,0);
	stmt->range.lo = addr;
	stmt->process = _asm->core->process();
	stmt->dobpt(setorclr);
}

Instr::Instr(Asm *a, long l)
{
	trace( "%d.Instr(%d,%d)", this, a, l );	VOK;
	if( !l ) return;
	addr = l;
	_asm = a;
	sib = _asm->instrset;
	_asm->instrset = this;
	_asm->banner();					/* why here? */
	fmt = _asm->fmt;
	bpt = _asm->core->process()->bpts()->isasmbpt(addr);
}

void Instr::display()
{
	int	i;
	Bls	t;

	trace( "%d.display()", this );	VOK;
	if( !addr ) return;
	t.af("%s%s", bpt?">>>":"", Format(fmt,_asm->core->symtab()).f(addr));
	opcode = _asm->core->peekcode(addr)->chr;
	next = addr+1;
	char *mnem = mnemonic();
	if( mnem ){
		t.af(": %s ", mnem);
		int n = nargs();
		for( i = 0; i < n; ++i )
			t.af("%s%s", i?",":"", arg(i));
	}
	_asm->pad->insert(addr, SELECTLINE, (PadRcv*)this, carte(), "%s", t.text);
}

void Instr::showsrc()
{
	trace( "%d.showsrc()", this );	ok();
	Stmt *stmt = (Stmt*) _asm->core->symtab()->loctosym(U_STMT, addr);
	if( stmt ) stmt->select();
}

long AF[] = { F_OCTAL, F_SIGNED, F_HEX, F_SYMBOLIC, 0 };

Index Instr::carte()
{
	Menu m, f;

	trace( "%d.carte()", this );	ok();
	if( _asm->core->online() ){
		if( bpt )
			m.last( "clr bpt", (Action)&Instr::dobpt, 0 );
		else
			m.last( "set bpt", (Action)&Instr::dobpt, 1 );
	}
	if( _asm->core->symtab()->loctosym(U_STMT, addr) )
		m.last( "src text", (Action)&Instr::showsrc, 0 );
	m.last( "open frame",	(Action)&Instr::openframe );
	m.last( "next  1",	(Action)&Instr::succ,		1 );
	m.last( "next  5",	(Action)&Instr::succ,		5 );
	m.last( "next 10",	(Action)&Instr::succ,		10 );
	for( int i = 0; AF[i]; ++i ){
		long b = AF[i];
		if( fmt&b ) b |= F_TURNOFF;
		f.last(FmtName(b), (Action)&Instr::reformat, b);
	}
	m.last(f.index("format"));
	m.last( "refresh",	(Action)&Instr::succ,		-1 );
	m.last( "raw mem",	(Action)&Instr::memory,	0 );
	return m.index();
}

void Instr::openframe()
{
	trace( "%d.openframe()", this ); VOK;
	_asm->core->process()->openframe(addr);
}

void Instr::reformat(int f)
{
	trace( "%d.reformat(0x%X) 0x%X", this, f, fmt ); VOK;
	if( f&F_TURNOFF)
		fmt &= ~f;
	else
		fmt |= f;
	if( !fmt ) fmt = F_HEX;
	_asm->fmt = fmt;
	_asm->newInstr(addr);
}

void Instr::succ(int n)		/* think about it! */
{
	trace( "%d.succ(%d)", this, n );	VOK;
	_asm->fmt = fmt;
	if( n>0 ) _asm->newInstr(next)->succ(n-1);
	else if( n<0 ) _asm->newInstr(addr);
}

void Instr::memory()
{
	trace( "%d.memory()" ); VOK;
	_asm->core->process()->openmemory(addr);
}

void Asm::instrstep(long i)
{
	trace( "%d.instrstep(%d)", this, i );	VOK;
	core->process()->instrstep(i);
}

void Asm::stepover()
{
	trace( "%d.stepover()", this );	VOK;
	core->process()->
		stepover( core->pc(), newInstr(core->pc())->next );
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.