How to use setq in the right way?
Patrick1ab
Posts: 136
in Propeller 2
Hello everyone!
It has been quite a while since I last posted here in this forum.
Back then I was using the P1, now I got a P2 Eval Board for Christmas and I am trying to port programs and drivers from Spin1 / PASM to Spin2 / PASM2.
While doing this, I came across something, which don't really understand.
This code does not work correctly, as the "setq" instruction seems to be applied only to the "rdlong", but not to the "wrlong":
This code seems to work, but looks a little odd:
Is there a chance to do this in a more elegant way?
Why does the first mentioned code fail? Is the setq only valid for the very next instruction?
Wishing you all the best for 2021!
Patrick
It has been quite a while since I last posted here in this forum.
Back then I was using the P1, now I got a P2 Eval Board for Christmas and I am trying to port programs and drivers from Spin1 / PASM to Spin2 / PASM2.
While doing this, I came across something, which don't really understand.
This code does not work correctly, as the "setq" instruction seems to be applied only to the "rdlong", but not to the "wrlong":
hub_cog_transfer rdlong buf_ptr,bufAdr cmp transfermode, #1 wz setq #128-1 ' setq to 128 longs to transfer if_nz rdlong speed_buf,buf_ptr if_z wrlong speed_buf,buf_ptr hub_cog_transfer_ret ret
This code seems to work, but looks a little odd:
hub_cog_transfer rdlong buf_ptr,bufAdr cmp transfermode, #1 wz if_z setq #128-1 ' setq to 128 longs to transfer if_z wrlong speed_buf,buf_ptr if_nz setq #128-1 ' setq to 128 longs to transfer if_nz rdlong speed_buf,buf_ptr hub_cog_transfer_ret ret
Is there a chance to do this in a more elegant way?
Why does the first mentioned code fail? Is the setq only valid for the very next instruction?
Wishing you all the best for 2021!
Patrick
Comments
That way, there would be not any "cancelled", nor decision-based-skipped instructions, in between SETQ and the RDLONG/WRLONG relying on Q's value, since the instruction pipeline would not be disturbed in any way.
It would look like the following:
Just in time: Happy New Year to you all!
An aside: The hidden Q register set by SETQ can be accessed independent of SETQ as well. MUXQ can read Q at any time. XORO32, RDLUT and GETXACC all write to Q. Some cordic ops and COGINIT clear Q by default. CRCNIB uses Q as a work register so needs IRQ shielded to prevent corruption.
or
I tested both proposed variants and they work just as expected.
There is still a lot for me to learn and discover regarding the P2 programming, but I must admit, that the P2 is a very powerful chip.
To give you an example:
The above code replaces all this of the orginal P1 "mb_rawb_spi" code by Jonathan "lonesock" Dummer, which for the P1 was already an incrediby fast solution for the hub <-> cog transfer.
There's Occam's Razor, shaving again!
I'm kind of anticipating (crystal ball lits on...): someday, somewhere, someone will be asking for just a few MORE instructions to be ADDED to any given snippet, in order to justify starting another COG... :LOL:
If there is a fixed difference between [bufAdr] and [buf_ptr], then the time between RDLONG and RDLONG/WRLONG can be determined and one or both of SKIPF and SETQ might be effectively "zero-cycle" instructions.
I don't like to see a RET if _RET_ will do. Sometimes, however, adding a RET can save code overall: