[LispM-Hackers] Needed infrastructure

Dave Richards dave@synergy.org
Sun, 3 Mar 2002 12:19:09 -0800


Now that we have a firm grip on the first function, there is some needed
infrastructure:

	1. We need a set of routines to handle "addressing modes",
	2. We need an MMU interface,
	3. We need some CPU registers

(1) The macroinstructions, e.g. SET-NIL needs to be able to call a "set
argument" routine.  The argument is a function of the addressing mode.  The
addressing mode is instruction format-dependent.  So I could see something
like:

	Word MAIN-OP::getArgument()
	MAIN-OP::setArgument(INSN, Word)

The assumption is that MAIN-OP from which SET-NIL inherits provides two
routines for getting and setting arguments based on the instruction encoding
which MAIN-OP understands.

These two routines are going to need helper routines.

                  15          9 8   6 5         0
                 +-------------+-----+-----------+
                 |  op-code    |base |  offset   |
                 +-------------+-----+-----------+

                 base register: 0 = FEF
                                1 = FEF+64
                                2 = FEF+128
                                3 = higher lexical context
                                4 = SELF mapping table
                                5 = local variables
                                6 = arguments
                                7 = PDL-POP [offset not used]
For example:

	MAIN-OP::getArgument()
	{
		switch ((opcode >> 6) & 3)
		{
		case 0:
			return CPU::getFef(opcode & 077);
		case 1:
			return CPU::getFef((opcode & 077) + 64);
		case 2:
			return CPU::getFef((opcode & 077) + 128);
		case 3:
			return CPU::getLexicalVariable(opcode & 077);
				.
				.
				.
		}
	}

and a similar function for setting arguments.

I don't know which class CPU is in e3 right now.  Whicever it is, it has
access to the CPU registers and can issue memory loads and stores.

This infrastructure would make it possible to implement SET-NIL:

	MAIN-OP::SET-NIL
	{
		setArgument(NIL);
	}

Now, the $64k question then becomes, how do we fill out all of those
routines?  A good number of them I don't know yet, but some are obvious:

	1. FEF|o

	FEF is a register in the CPU.  In fact, we know its initial value because
that's the function we're looking at now.  So, when we load the band we
initialize the FEF register to the function.  So getFef is really just:

	getFef(Offset)
	{
		return readWord(MMU::VTOP(FEF + Offset))
	}

That's 3 of the 7 cases (1 is illegal and should throw an exception).
Lexical environments are usually not hard but I don't know how they are
encoded yet.  Locals are just as easy.  When we build a stack frame during
the call, we initialize the local pointer.  Thus, local argument processing
is really the same as FEF except we use the local pointer not the FEF
pointer.  The same is true for arguments.  So really, lexical vars and self
are the only two that aren't just CPU reister + offset.  The PDL is just x =
PDL[PP--]; and PDL[++PP] = x; (which appropriate wrap around checking.

These routines will make it possible to implement SET-NIL.  The CALL- INSN
which follows is going to be a bear.  A lot of complexity exists around
calls.

	Dave