!	TXINFO -- print Tcode program information
!	Copyright (C) 1998 Nils M Holm

const	BUFSIZE	=	1025;

var	Buffer[BUFSIZE], Cp, Ep;
var	Ttop, Dtop, Ctop;
var	Id, Fv;
var	Stkmax;


const	ICLAB=129, IDLAB=130, IDECL=131, IDATA=132, ICREF=133,
	IDREF=134, ISTR=135, IPSTR=136, IINIT=137, IHDR=010,
	IEND=011,

	INEG=012, ILNOT=013, IBNOT=014, IPOP=015, ICLEAN=144,
	INOP=017,

	IINDB=018, IIND=019, IDREFB=020, IDEREF=021, IINCG=150,
	IINCL=151,

	IMUL=024, IDIV=025, IMOD=026, IADD=027, ISUB=028, IBAND=029,
	IBOR=030, IBXOR=031,

	IBSHL=032, IBSHR=033, IEQU=034, INEQU=035, ILESS=036,
	IGRTR=037, ILTEQ=038, IGTEQ=039,

	ILDG=168, ILDGV=169, ILDL=170, ILDLV=171, ILDLAB=172,

	INUM=173, ISAVG=174, ISAVL=175, ISTORE=048, ISTORB=049,

	ISTACK=178, ICALL=179, ICALR=52, IEXEC=181, IBRF=182,
	IBRT=183, INBRF=184, INBRT=185, IJUMP=186, IUNEXT=187,
	IDNEXT=188, IHALT=061,

	IPUB=190, IEXT=191,

	IUMUL=64, IUDIV=65, IULESS=66, IUGRTR=67, IULTEQ=68,
	IUGTEQ=69,

	IDUP = 70, ISWAP = 71,

	ILINE = 200, IGSYM = 201, ILSYM = 202,

	IENDOFSET=75;


init() do
	Ep := 1;
	Cp := 1;
	Dtop := 0;
	Ctop := 0;
	Ttop := 0;
	Id := -1;
	Fv := 0;
	Stkmax := 0;
end


rdch() do
	if (Cp >= Ep) do
		Ep := reads(Buffer, BUFSIZE-1);
		Cp := 0;
		if (\Ep) return %1;
	end
	Cp := Cp+1;
	Ttop := Ttop+1;
	return Buffer[Cp-1];
end


next() do
	var	op, o2, arg, i, j, ch;
	var	base;

	base := Ttop;
	op := rdch();
	if (op = %1) return 0;
	o2 := op & ~128;
	if (o2 < 1 \/ o2 >= IENDOFSET) do
		writes("TXINFO: invalid opcode: ");
		writes(ntoa(op, 0));
		newline();
		halt;
	end
	if (op & 128) do
		arg := rdch();
		arg := rdch() << 8 | arg;
	end
	if (op & 128) do
		if (arg > 32767) arg := arg-(16384<<2);	! 32-bit hack!
	end
	if (op = IINIT) Id := arg;
	if (op = ISTACK /\ arg > Stkmax) Stkmax := arg;
	ie (op = IINCL \/ op = IINCG \/ op = IINIT /\ arg > 1) do
		arg := rdch();
		arg := rdch() << 8 | arg;
		if (op = IINIT) Fv := arg;
	end
	else if (op = ISTR \/ op = IPSTR \/ op = IPUB \/ op = IEXT \/
		op = IGSYM \/ op = ILSYM
	) do
		for (i=0, arg) rdch();
		if (op = IGSYM \/ op = ILSYM) do
			arg := rdch();
			arg := rdch() << 8 | arg;
			if (arg > 32767) arg := arg-(16384<<2);	! 32-bit hack!
		end
	end
	ie (	op = ICLAB \/ op = IDLAB \/ op = IINIT \/ op = IPUB \/
		op = ILINE \/ op = IGSYM \/ op = ILSYM
	)
		;
	else ie (op = IDECL)
		Dtop := Dtop + (arg<<1);
	else ie (op = IDATA \/ op = IDREF)
		Dtop := Dtop+2;
	else ie (op = ISTR)
		Dtop := Dtop+(arg<<1)+2;
	else ie (op = IPSTR)
		Dtop := Dtop + (arg+2 & ~1);
	else
		Ctop := Ctop + (Ttop-base);
end


do
	init();
	while (Ep) next();
	if (Id = -1) do
		writes("TXINFO: not a Tcode program or unsupported version");
		newline();
		halt;
	end
	writes("Tcode version = "); writes(ntoa(Id,7)); newline();
	if (Id > 1) do
		writes("Feature vector = "); writes(ntoa(Fv,6)); newline();
	end
	Stkmax := Stkmax+512;
	writes("load image size = "); writes(ntoa(Ttop,5)); newline();
	writes("code length = "); writes(ntoa(Ctop,9)); newline();
	writes("data length = "); writes(ntoa(Dtop,9)); newline();
	writes("stack length >= "); writes(ntoa(Stkmax<<1,7)); newline();
	writes("total size >= "); writes(ntoa((Stkmax<<1)+Dtop+Ctop,9));
		newline();
end

