Well, I guess I settled on that last addressing mode. It's two more modes, which pretty much just copy the existing immediate-memory-location and something-from-the-stack addressing modes.
Again, my terminology might be way off, but I'm going to call it indirect-whatever mode.
Syntax in the assember for it is **address, or *$stack_offset.
Here's what it's doing in code for the "fetch" part. (Excuse the crappy temporary error handling for now.)
inline LilyVM::Word LilyVM::fetchParameterByType(LilyVM::ParamType type)
case PARAM_NULL: return 0;
case PARAM_IMMEDIATE: return fetchInstruction();
case PARAM_ADDRESS: return fetchRaw(fetchInstruction());
case PARAM_STACK: return fetchRaw(stackPointer + fetchInstruction());
case PARAM_INDIRECT_ADDRESS: return fetchRaw(fetchRaw(fetchInstruction()));
case PARAM_INDIRECT_STACK: return fetchRaw(fetchRaw(stackPointer + fetchInstruction()));
// TODO: Throw error (bad instruction).
cout << "Bad addressing mode for read: " << type << endl;
And here's a little example snippet of assembly demonstrating it.
mov 123 **someAddress
mov 123 *$somestackOffset
The ability to add in-line, immediate data was also added in the last couple of revisions. There are assembly directives to have the next few Words be some explicit values, or to fill the next 'n' Words with some specific value.
I think the incomplete VM code might almost be not-embarrassing enough to toss up GitHub soon.
Next up: Profiling and comparisons against Lua and native code. Then taking out some of the modulo crap and trying it again.