beginer : switch/case in asm
henrib75
Posts: 9
in Propeller 1
Hello,
I return to the asm after more than 20 years without. It's a bit rough. I have just asked for some help here because I have not found my answer in the forum or on Google. I try to make a mini interpreter of a small bytecode that I defined. Even if the question is probably classic, I wonder how to make the equivalent of a switch / case in asm specifically to interpret the byte of each bytecode, one after the other. Basically each byte corresponds to a bit of code asm to execute. There are surely x ways to do, but I obviously seek the fastest:
1 / I excluded the cmp and call / jmp to the chain, far too long
2 / I imagined running by dichotomy to accelerate, but it still seems too slow
3 / can it be possible to make a table with the addresses of the bits of code, and use the byte of the bytecode to treat as index of this table?
4 / I imagine that one could use the byte, multiply it by a value (related to the size of each block of instructions) and make the jump according to the result. On the other hand it imposes that all the blocks make the same size, quite to lose space ...
Well, I imagine there are more intelligent methods, but I can not find? And Google did not really help me on this one ...
THANK YOU
Ps: I'm French, so excuse my English ...
I return to the asm after more than 20 years without. It's a bit rough. I have just asked for some help here because I have not found my answer in the forum or on Google. I try to make a mini interpreter of a small bytecode that I defined. Even if the question is probably classic, I wonder how to make the equivalent of a switch / case in asm specifically to interpret the byte of each bytecode, one after the other. Basically each byte corresponds to a bit of code asm to execute. There are surely x ways to do, but I obviously seek the fastest:
1 / I excluded the cmp and call / jmp to the chain, far too long
2 / I imagined running by dichotomy to accelerate, but it still seems too slow
3 / can it be possible to make a table with the addresses of the bits of code, and use the byte of the bytecode to treat as index of this table?
4 / I imagine that one could use the byte, multiply it by a value (related to the size of each block of instructions) and make the jump according to the result. On the other hand it imposes that all the blocks make the same size, quite to lose space ...
Well, I imagine there are more intelligent methods, but I can not find? And Google did not really help me on this one ...
THANK YOU
Ps: I'm French, so excuse my English ...
Comments
If your byte codes were all sequential, you could use a jump table as a sort of switch/case structure.
The example above is from my current project but there are lots of other examples including examples from code in the Propeller Tool's library.
If your byte codes aren't sequential, then I doubt this technique will be useful to you.
But if you have up to 256 rejumps that would waste valuable 256 cog longs.
Store a lookup table of 4 addresses in a one cog long. (can only jump to half of a cogs ram, unless you shift it up one bit and start all snippets with a nop in case it's in a odd address type thing)
Decode the lower two bits of bytecode to mask out the address so it can be shifted and moved to a single location for jump address.
self-modify a jmp #0-0 could also work but would need a instruction in between and maybe you could not come up with a useful one.
And if you have 256 bytecode options how do you fit all those 256 code snippets in cog ram?
So I guess you don't have that many bytecode headers?
I understood your proposals, I will think about them. It seems simple to me.
For information, I have about 50 opcodes (including a dozen optional) I will see if it is possible as I go, I just start ...
By cons I do not understand the "self-modify a jmp # 0-0 could also work"?
If you for example:
tst bytecode, #%11 wz wc
ifnz shr snippet, #9 ' you have to lookup z c status as this is probably not correct
ifc shr snippet, #9 ' shift it another 9bits
movd lablej, snippet
nop
labelj jmp #0-0
the jump can not be modified just before next instruction due to pipleline,
sure you put a nop in between, but if you can find a instruction you need anyway I would do that.
if you instead create a long to store address, a nop is not needed.
mov snippetaddrs, snippet
labelj jmp snippetaddrs
Seems that would work well, with the 50 opcodes, you would end up with a sparse bytecode map, and could auto-generate the bytecodes from a source or listing file, so as to track any code changes/fixes.
Yes it's simple and smart! On the other hand it imposes lengths of asm codes for each opcodes ... and especially it seems to me complicated to modify if I want to optimize or to add opcodes (after writing programs) ? But this is probably the fastest solution ...
I think now I have to write the asm code for each bytecode and depending on the result I can choose the right solution.
I will give you news in the coming weeks ...
Probably the best way to approach it. Once you have the asm code for executing the commands you know how much memory is left and a clearer idea of what approach works best.