How about a JMPLNK instruction?
Peter Jakacki
Posts: 10,193
in Propeller 2
This is the inner address interpreter loop in Tachyon:
Looking at it I was thinking that the jmp was a real waste of time and if CALL could push a specified address rather than the PC it would mean I could have a tighter loop. So essentially we could have a CALL instruction that I can simulate like this:
So with a JMPLNK instruction it would be coded like this:
I'm just asking this because I think that it might be quite easy to implement.
doNEXT rdword X,PTRA++ 'read word code instruction address call X ' could call cog or hub code jmp #doNEXT
Looking at it I was thinking that the jmp was a real waste of time and if CALL could push a specified address rather than the PC it would mean I could have a tighter loop. So essentially we could have a CALL instruction that I can simulate like this:
doNEXT rdword X,PTRA++ 'read word code instruction address push #doNext jmp X ' could call cog or hub code
So with a JMPLNK instruction it would be coded like this:
doNEXT rdword X,PTRA++ 'read word code instruction address jmplnk X,#doNext ' call cog or hub code but use doNext as the return address
I'm just asking this because I think that it might be quite easy to implement.
Comments
Why not the JMPREL opcode ?
I bet it's most convenient to have things end in RET, so that they can call each other, too, before returning.
Interesting idea. This wouldn't be too hard to make, but we've only got the opcode space for register-based JMPs, not any more immediate-address JMPs.
Is there a "next level" we could even take this to, so that it does even more?
Of course
- but the JMPREL is in there, and there is not yet a JMPLNK...
Now jmg says "why not the jmprel opcode?" but I don't really know what jmprel does although I keep inviting "everybody" to contribute to the documentation, even if it is describing one little instruction. My eyes keep getting blurry just formatting the stuff.
As for jmplnk or whatever it was just a suggestion and if we can make it happen then great but otherwise I wouldn't worry too much although I will keep looking into it.
https://forums.parallax.com/discussion/comment/1347205#Comment_1347205
It's very handy for jumping forward into a table of JMP instructions.
Here is without JMPREL in cog exec:
Here is without JMPREL in hub exec:
Here is with JMPREL:
Reading up on the JMP instruction, I hadn't considered a jump table like that being capable of full range addressing but surprisingly it is.
Err, none of these help him because he is not using any table lookup. The Forth program instructions are the routine pointers. Just like a CPU instruction set.
and have each of your routines do a "jmp #doNEXT" instead of "ret"?
On the other hand, if you need an indirect return address, maybe you could use CALLD like:
Then, to return, you would call "calld adrb, adrb wc, wz" instead of "ret". Note that you could take advantage of the interrupt instruction/register aliases. So, you could do:
Then, in your routines elsewhere, call "reti1" instead of "ret".
I made TF2 sub-routine threaded so everything ends up returning to whatever called it, not always the doNext loop which also means I can just as easily call a print routine from assembly code etc. The implementation is definitely not sluggish but while we are still at this pre-nascent stage I thought that a jmplnk would be fairly easy to implement although as Chip pointed out, there aren't any parking spaces left for that kind of instruction
This one looks effective. Peter, I presume you were expecting a single level stack only?
EDIT: Ah, Smile. The return address needs to be doNEXT, not two instructions later. Doh! Maybe that iret1 thingy then ...?
Enjoy!
Mike
No. If you jump out of a REP, the rep gets terminated.
I got rid of this terminate-REP-on-branch behavior because it was slowing things down and was only there because it was needed on Prop2-hot. Don't put branches in REP blocks, anymore, or chaos will ensue!
Cool! So, if you jump while in a REP, the PC will still get reset to the instruction after the REP after however many instructions the REP was told to REP for? Sounds fun!
Is even an equal-length-internal-branch out too ?
ie is REP counting opcodes, before forcing reload of PC ?
so no calls to subroutines inside of a REP loop?
Mike
First of all, read what Chip said. Jumps don't terminate REP anymore, but REP doesn't account for them, either. If you jumped somewhere or called something, the PC would get reset half way through your subroutine, which would be bad.
I'm guessing that you theoretically could call a subroutine as long as it still took the same number of instructions, but those cases would be very rare and hard to implement properly in software.
Balancing software paths is not uncommon, but it would be useful to know how REP works, and just what is possible/forbidden inside REP.
Ideally, the tools should track that & warn.
IIRC, HUB/LUT R/W access is legal inside REP, so REP likely tracks PC++ ?
reading alone does not mean understanding also. The way you describe it, there might be a way to write really confusing code.
So to understand this right, REP (in opposite to say DJNZ) does provide a seamless loop of them instructions and the 'jump' from last to first instruction does not take any clock cycles and just sets the PC back?
So basically what I do on the P1 when I 'unroll' a loop?
Interesting.
Mike
Yes, REP shines most on the smallest loops, and allows you to avoid 'unroll' a loop, saving code space.