So before anybody says "Are you nuts?" let me explain what happened in chronological order.
- I wrote a cross-compiler to create a TI-99 Forth kernel to see if I could make it faster.
- That succeeded somewhat giving about 8% improvement over conventional methods. No biggy. ( now it's all hard work to make it into something practical)
- I made the mistake of reading the multi year posts by "Insomonia" here about porting GCC to TI-99 and saw the resulting code output.
- I don't want to say that I'm very competitive but... it was much faster code than threaded Forth. Dam!
- After seeing the C compiler output I thought hey!... I could make my cross-compiler do something like that. The C compiler is making asm code and creating a return stack for sub-routines and local variables.
I started down the road of making a sub-routine threaded Forth system and realized I didn't have to go to all that trouble.
Many years ago the inventor of Forth, Chuck Moore, abandoned threaded code which essentially is; make a program that is lists of addresses, read the list of addresses and jump to each address to run the code. So threaded code has some overhead.
Chuck began working in something he called "machine Forth" which is so simple it's crazy.
The theory is why make a fancy compiler when all it's doing is putting some numbers in memory.
Chuck took his Forth Assembler and made Forth words that simply put the correct code into memory something like macros. Many times a Forth word translates to just 1 machine instruction so why jump to it or call it like a sub-routine? When Machine Forth reads a word, it just puts the correct code into the next available memory location and waits for the next word.
If it's big pile of code for that word, call it like a sub-routine. If it's small just put it in memory as is.
Forth '+' removes 2 numbers from the stack, adds them together and puts the answer back on the stack. If we keep the top of the stack in a register for convenience here is the Assembler code to do '+':
So when I type '+' in my program it puts one 16 bit integer (the machine code) into memory. That's ALL it knows how to do.
And many Forth words are that simple. Others are 2 or 3 instructions.
So I expanded my Forth Assembler to do just that and in general things run between
2 times to up to 7 times FASTER than CAMEL99 Forth in my early testing.
Machine Forth lets you decide if you want to insert the code inline for speed or call it to save some space. You are essentially using little assembler routines but it looks like Forth program text.
One other thing that ticked me off was that GCC was able to allocate free registers in the CPU as variables. That's is ideal for making faster code. DAM!
So I have created a new variable called a LOCAL, which is just a register that is automatically allocated for you. You have 6 of them and you create them like this:
LOCAL X LOCAL Y LOCAL Z
( code goes here... )
Locals only work in the current sub-routine and are freed up after your sub-routine completes.
I might even add an "infix" evaluator so you don't have to use reverse Polish notation but that's vapour-ware at the moment.
It's still a big work in progress but I think I have jumped through the looking glass...
Where's that damned cat?
Edited by TheBF, Fri Mar 10, 2017 10:22 AM.