[LispM-Hackers] First Function

Dave Richards dave@synergy.org
Fri, 1 Mar 2002 22:28:28 -0800


Disassembling the first function, we can learn quite a bit (I did anyway, I
realize I'm just catching up).

 pc=0000   SET_NIL PDL|#o77             0 (a)
 pc=0001 c CALL_1_DEST_INDS FEF|#o5     0
 pc=0002   PUSH FEF|#o4                 1
 pc=0003 b BR_NOT_NIL_ELSE_POP disp=#o1 1/0 (b) (c)
 pc=0004   PUSH FEF|#o3                 1
 pc=0005 c CALL_1_DEST_INDS FEF|#o6     0
 pc=0006   PUSH FEF|#o7                 1
 pc=0007 m miscop=#o237                 1 (d)
 pc=0010 b BR_NIL disp=#o2              0
 pc=0011 c CALL_0_DEST_INDS FEF|#o10    0
 pc=0012 b BR_ALWAYS_NIL disp=#o773     0 (e)
 pc=0013   PUSH FEF|#o4                 1
 pc=0014 b BR_NOT_NIL_ELSE_POP disp=#o1 1/0
 pc=0015   PUSH FEF|#o3                 1
 pc=0016 c CALL_1_DEST_INDS FEF|#o11    0
 pc=0017 b BR_ALWAYS_NIL disp=#o766     0 (f)

(a) INSN 0 is a problem.  SET-NIL (this is not a disassembler bug, I
double-checked it against SSDN2) assigns NIL to the desination.  Why can
this INSN assign to the PDL that far back?  The PDL shouldn't even be
defined that far back.  I can only hope we don't really understand this INSN
yet.  Oh, we can also infer based on INSN 1 that INSN 0 should produce a
value (which SET-NIL doesn't), since INSN 1 is a CALL-1.  *think*

(b) Stack usage for branches appear to have the following rules:
	(1) BR-ALWAYS doesn't touch the stack.
	(2) BR-<COND> pops the value from the stack.
	(3) BR-<COND>-ELSE-POP pops the value from the stack, only if the condition
is false.

(c) As confirmed by Sect 11, displacement 0 refers to the next instruction.
Displacements in branches (both positive and negative) should use the next
instruction as the base.  This arithmetic must take both the word off but
the halfword index into account when doing the arithmetic.  It may make more
sense to turn the location count into a halfword counter.  This would allow
branch displacement arithmetic to work correctly as well as allowing
readMacroInstruction to take one (instead of two) location values.  I wonder
how Explorer stored this?  Somewhere along the line during call/return
processing, the location counter must get stored in the stack frame, it's be
nice to be able to see one of those frames to see how it got stored.

(d) The disassembler didn't have this guy, but SSDN2 says it's FBOUNDP,
which makes sense because FEP|7 holds a symbol.

(e) I think BR_ALWAYS_NIL is a bug in the disassembler.  Always and NIL
should be mutually exclusive.  I have not gone and looked at it yet.

(f) Afrter disp= we should add a friend like (0x0000) showing which INSN is
the actual target of the branch.  It would make it a bit easier to read.

(g) EVCPs (based on Sect 11) are invisible pointers.  This means that
something in memobj probably needs to do something like:

	for (;;)
	{
		word = readWord(address);
		if (!isEVCP(word))
			break;
		address = word;
	}

	return word;

It looks to me like the very first thing that happens in this function is
some hefty function calling.  And function calling is pretty involved (sect
11), so that's probably the place to start.

Is there any place where the registers of the processor are defined?  I
don't mean the micro-registers, I mean the macro ones.  We know that
registers must exist for the stack pointer, location counter, current
function.  There must also be some environment registers, etc.  Has anyone
seen a list of these?  I have not checked the stack groups section yet,
they're probably in there.

	Fun stuff!

	Dave