Using ALTI for stacks
Seairth
Posts: 2,474
I'm was thinking about how to use ALTI effectively for stack manipulation (as was suggested in the "New Spin" thread). This is what I came up with (untested):
If you wanted to avoid the call overhead, the de-normalized code would be:
As noted, I don't think spacer instructions are needed, as you are not altering an instruction in the pipeline.
Does this look like what others were thinking? I'm, not crazy about the need for two ALTI instructions in the POP, but that doesn't seem too bad overall. Simple PUSH/POP instructions would certainly be nicer, though.
Edit: I just realized that the RDLUT probably requires SETR, not SETD. Code is updated to reflect that.
Edit: Removed unnecessary instructions from inlined version
loop SETD sp, #in_val CALL #push SETR sp, #out_val CALL #pop JMP #loop push ALTI sp, #%100_111 'substitute sp[17:9] into D, substitute sp[8:0] into S, then increment sp[8:0] WRLUT 0-0, 0-0 RET pop ALTI sp, #%010 'increment sp[8:0] ALTI sp, #%100_000_100 'substitute sp[17:9] into D, substitute sp[8:0] into S RDLUT 0-0, 0-0 RET sp LONG 0 in_val RES 1 out_val RES 1
If you wanted to avoid the call overhead, the de-normalized code would be:
loop ALTI sp, #%111 'substitute sp[17:9] into D, substitute sp[8:0] into S, then increment sp[8:0] WRLUT in_val, 0-0 ALTI sp, #%010 'increment sp[8:0] ALTI sp, #%100 'substitute sp[27:19] into R, substitute sp[8:0] into S RDLUT out_val, 0-0 JMP #loop RET sp LONG 0 in_val RES 1 out_val RES 1
As noted, I don't think spacer instructions are needed, as you are not altering an instruction in the pipeline.
Does this look like what others were thinking? I'm, not crazy about the need for two ALTI instructions in the POP, but that doesn't seem too bad overall. Simple PUSH/POP instructions would certainly be nicer, though.
Edit: I just realized that the RDLUT probably requires SETR, not SETD. Code is updated to reflect that.
Edit: Removed unnecessary instructions from inlined version
Comments
It seems to me (totally unsubstantiated, mind you) that this will not perform much better than a hub stack using inlined PUSHx/POPx. Of course, you could also inline the push/pop operations in the above code to avoid the CALL/RET overhead, but at a cost of readability.
Question to Chip: what happens if you mix ALTI and AUG? For instance, in the above code, what if I wanted to push a large immediate value? Is this allowed?
Oh well! I kinda figured, but was hopeful. That's bound to bite someone in the future, though. The assembler should probably flag it as an error.
The ALTxx instructions modify the next instruction, no matter what it is. The AUGS/AUGD instructions, however, will work around the ALTxx instructions. So, you'd do one or both AUGx instruction(s), then the ALTxx instruction, then the final instruction. That should work okay.
All those ALTxx instructions are only useful for indirect addressing of cog registers.
That's good to know. This would also imply that you can't use AUGx to modify ALTx, which seems reasonable.
That's correct.
That does point out a minor issue with doing hub stacks with PTRx: they are not bounded. Of course, if you exceed your stack size, all bets are off anyhow. It's probably a toss-up whether it's worse to corrupt the bottom of your stack or non-stack memory.
Yes it is. Didn't even consider that one.
In any case, stacks aren't really an issue. We've got reasonable ways to do them.
Nice!