Morten Aune Lyrstad wrote:[color=blue]
>
> You seem to have some knowledge about this.[/color]
Actually I like compiler construction and built various
virtual CPU's for them. It's all about practice.
[color=blue]
> What do you think about this
> as a translated 'for' loop? My virtual machine can handle this now. It
> should be the equivalent of
>
> for (int i = 0; i < 10; i++)
> {
> }
>
> -------------------- SAGA code --------------------
> push [addr0] ;\
> push 10 ;} Store 10 into the first variable
> store ;/
> push [addr1] ;\
> push 0 ;} Store 0 into the second variable
> store ;/
> loopStart:
> push [addr1] ;} Load the second variable
> load ;/
> push [addr0] ;} Load the first variable
> load ;}
> lessi ; Compare integer. Is A less than B?
> jmpzero endLabel ; No, exit loop
> push [addr1] ; Push address of second variable
> push [addr1] ;} Load the second variable
> load ;/
> push 1 ;} Add 1 to the value
> addi ;/
> store ; Store into the second variable
> jmp loopStart ; Start loop over
> endLabel:
> end ; End function
> ------------------ SAGA code end ------------------
>
> I really appreciate your help.
>[/color]
Hmm. In the source code, 10 is a compile time constant not a variable.
So I would have expected something like this.
push [addr1] ;\
push 0 ;} Store 0 into the second variable
store ;/
loopStart:
push [addr1] ;} Load the second variable
load ;/
push 10 ;} Load the constant
lessi ; Compare integer. Is A less than B?
jmpzero endLabel ; No, exit loop
push [addr1] ; Push address of second variable
push [addr1] ;} Load the second variable
load ;/
push 1 ;} Add 1 to the value
addi ;/
store ; Store into the second variable
jmp loopStart ; Start loop over
endLabel:
end ; End function
Other then that: looks good.
Now we are back to your original question: 'What instructions should
a virtual CPU have'. Looking at your code, you will easily see a need
for an additional instruction: inci (increment integer). The sequence
push 1
addi
can easily be replaced by
inci ; increment top of stack elemnt
Other improvements: You often will see the sequence
push [some_addr]
load
which can easily be replaced with
load_from [some_addr]
and so on, and so on.
This is what I ment earlier: By looking at the generated assembly
one can often see possible improvements and adjust the instruction
set to include them. But beware: If you see such patterns, make
sure that they are frequent enough that it really pays to introduce
a new instruction. Eg. I once created a language which included
elements for doing 3D-graphics programming. In the instruction set
I had instructions for creating points, lines, edges, faces, lights,
and so on. I thought a while about also including a special instruction
for calculating the phythagorean distance ( sqrt(x*x+y*y+z*z) ) of 2
points. But I noticed that it was far to infrequently used to keep
it.
--
Karl Heinz Buchegger
kbuchegg@gascad.at