I am no longer able to attach anything to my posts. I tried the other thread, but it doesn't work there either. I am being shut out - it appears.
Since JRoarke continues to attempt to sell me his code - he will attempt to tempt me with his code again. I am convinced he is an informant for the Securities & Exchange Commission.
I have asked 3 times for JRoarke to stay away from me. However, this discussion appears to be an attempt at entrapment by either the SEC or DOD.
I am no longer able to attach anything to my posts. I tried the other thread, but it doesn't work there either. I am being shut out - it appears.
Since JRoarke continues to attempt to sell me his code - he will attempt to tempt me with his code again. I am convinced he is an informant for the Securities & Exchange Commission.
I have asked 3 times for JRoarke to stay away from me. However, this discussion appears to be an attempt at entrapment by either the SEC or DOD.
@jonabel1971 This is an engineering and programming forum. Keep the conspiracy theories to yourself - you risk alienating everyone who has (very generously!) held your hands through the P2 learning process.
SQRT Square root of unsigned x
^^, XOR xor Logical XOR (x <> 0 XOR y <> 0, returns 0 or -1)
Could you please edit those lines to read
SQRT ^^ Square root of unsigned x
XOR xor Logical XOR (x <> 0 XOR y <> 0, returns 0 or -1)
Sorry I'm late to this, Ray. I updated the SQRT line as you suggested, but left ^^/XOR as-is after looking at the interpreter source and running a bit of test code on both versions of the operator.
pub get_ms() : ms | lo, hi
'' Return milliseconds after reset (32 bits).
'' -- system counter is fixed; cannot be changed by user
org
getct hi wc ' get cnt (now)
getct lo
stalli ' stall interrupts to protect cordic operation
setq hi ' divide cnt by ticks/ms
qdiv lo, ##MS_001
getqx ms
allowi ' allow interrupts
end
pub get_ms() : ms | lo, hi
'' Return milliseconds after reset (32 bits).
'' -- system counter is fixed; cannot be changed by user
org
rep #5,#1 ' executes once; protects code block from being interrupted
getct hi wc ' get cnt (now)
getct lo
' stalli ' stall interrupts to protect cordic operation
setq hi ' divide cnt by ticks/ms
qdiv lo, ##MS_001
getqx ms
' allowi ' allow interrupts
end
About replacing the pair of instructions STALLI/ALLOWI by a straight-pass REP, in some situations.
All three instructions have their proper uses; it's only in the sense of resorting to stalli, followed by some code, then allowi, as a "shield", to protect timing-sensitive or uninterruptible code pieces.
In such situations, and wherever rep can be used, one could avoid resorting to the "leading/trailling twins", and save an instruction, at least.
Sure, they (twins) are badly useful, in cases such:
' uninterruptible code
allowi
' none, or any interruptible code
stalli
' uninterruptible code
in order to craft a definite "window", for interrupts to chime in, within otherwise uninterruptible code.
What I like about this apart from saving an instruction, is that it leaves the interrupt state as it was before. ie. if interrupts are stalled they remain stalled, and if enabled before they should remain enabled after the REP completes. Of course you can't branch out but for tight inline code this method should be very useful. Could be a good way to protect CORDIC use in the main line code and other things that may require setq to be preserved.
What I like about this apart from saving an instruction, is that it leaves the interrupt state as it was before. ie. if interrupts are stalled they remain stalled, and if enabled before they should remain enabled after the REP completes.
Yes, for code with no branching and no skipping, REP is simpler and better than STALLI/ALLOWI. Three longs could be saved in the current Spin2 interpreter.
STALLI could be enhanced with {WC/WZ/WCZ} where C/Z = 'interrupt enable flag' (1 if interrupts were allowed before this instruction, else 0) for cases when REP could not be used.
One little tweak.
REP should be #6 not #5 to allow for a AUGS needed by the QDIV instruction.
rep #6,#1 ' executes once; protects code block from being interrupted
getct hi wc ' get cnt (now)
getct lo
' stalli ' stall interrupts to protect cordic operation
setq hi ' divide cnt by ticks/ms
qdiv lo, ##MS_001
getqx ms
' allowi
MS_001 should really be a register, so back to #5!
rep #5,#1 ' executes once; protects code block from being interrupted
getct hi wc ' get cnt (now)
getct lo
' stalli ' stall interrupts to protect cordic operation
setq hi ' divide cnt by ticks/ms
qdiv lo, MS_001
getqx ms
' allowi
Would someone like to add this to the Trick and Traps Reference thread, with a link to this discussion please.
The link to the first post of this discussion can be found by copying the posts' link which is obtained by right-clicking the posts' date next to the avartar.
Cluso,
You know you could've posted in here to remind everyone.
Regarding ALTx instructions in SKIPF blocks, they don't get any special treatment. If they are prefixing a cancelled instruction then they are effectively prefixing a NOP. Which ain't gonna do squat.
@evanh said:
Cluso,
You know you could've posted in here to remind everyone.
Yes. Didn't think
Regarding ALTx instructions in SKIPF blocks, they don't get any special treatment. If they are prefixing a cancelled instruction then they are effectively prefixing a NOP. Which ain't gonna do squat.
Yes, probably just skipped like an ordinary instruction.
Would have to be careful of AUGx as they are often automatically inserted which could play havoc with counting the instructions. IIRC I've identified this in the python program I wrote to make the skip bit patterns.
The other thing I was pointing out is that if the skip is greater than 7 instructions, a delay is inserted in the pipeline (must be 2 clocks). Just need to be aware of this if counting instructions for timing purposes.
If we can get a full set of details here I can post over my reference post.
AUGx is similar story, but they're not as rigid as an ALTx in that the alternate AUG and an ALTx can be stacked after and they'll all combine. I'd guess a NOP will consume all though. Which means a cancelled instruction will also release all AUGx and ALTx stacked prefixing.
I disagree with 3. A skip does indeed perform a 2 clock stall or a NOP equivalent, but it definitely does not consume (ie you need to waste) a skip bit.
Not sure what you mean about the rep+skipf? I am unsure about any rep implications.
A skip pattern with remaking bits can be overwritten or retired by performing a new skip.
@Cluso99 said:
I disagree with 3. A skip does indeed perform a 2 clock stall or a NOP equivalent, but it definitely does not consume (ie you need to waste) a skip bit.
Not sure what you mean about the rep+skipf? I am unsure about any rep implications.
A skip pattern with remaking bits can be overwritten or retired by performing a new skip.
A hidden NOP converts a 1 bit into a 0 bit, so it does consume a bit in that sense. The really important point is that you must increment the number of repeated instructions in REP for every hidden NOP in the REP block. This has been tested.
I disagree with the terminology of hidden NOP. What is happening is that an instruction is cancelled, instead of being skipped. The skip pattern is unchanged, but 2 cycles are required and the rep count increments, unlike for skipped instructions.
So I’d represent it as:
@TonyB_ said:
SKIPF traps/tips:
First instruction after SKIPF cannot be skipped and is cancelled if skip bit is 1.
Every 8th consecutive skipped instruction is cancelled instead of being skipped.
Unlike a skipped instruction, a cancelled instruction requires repeat instruction count to be incremented for REP+SKIPF.
Remaining skip bits are still active after a jump. If any of these are 1 then EXECF can be used to jump out of a skip pattern safely.
A hidden two-long instruction created by AUGx is a potent trap that can be avoided by using a register to hold a > 9-bit value, saving two cycles.
A CALL is treated as a single instruction, the importance of which cannot be overestimated. Skipping is suspended inside the subroutine.
@AJL said:
I disagree with the terminology of hidden NOP. What is happening is that an instruction is cancelled, instead of being skipped. The skip pattern is unchanged, but 2 cycles are required and the rep count increments, unlike for skipped instructions.
So I’d represent it as:
@TonyB_ said:
SKIPF traps/tips:
First instruction after SKIPF cannot be skipped and is cancelled if skip bit is 1.
Every 8th consecutive skipped instruction is cancelled instead of being skipped.
Unlike a skipped instruction, a cancelled instruction requires repeat instruction count to be incremented for REP+SKIPF.
Remaining skip bits are still active after a jump. If any of these are 1 then EXECF can be used to jump out of a skip pattern safely.
A hidden two-long instruction created by AUGx is a potent trap that can be avoided by using a register to hold a > 9-bit value, saving two cycles.
A CALL is treated as a single instruction, the importance of which cannot be overestimated. Skipping is suspended inside the subroutine.
It's all coming back. Yes, the 8th skipped instruction is executed as a nop, hence the 2 clocks.
First detail I'll add is the use case posted is for RDFAST with streamer writing to pins. NCO rate was sysclock/16.
EDIT: Well, having now tried to replicate the hypotheses in pure pasm - it don't crash for me ... it's not even skipping an instruction ... might be time to look more carefully at what Flexspin's Fcache is doing ...
Comments
Since JRoarke continues to attempt to sell me his code - he will attempt to tempt me with his code again. I am convinced he is an informant for the Securities & Exchange Commission.
I have asked 3 times for JRoarke to stay away from me. However, this discussion appears to be an attempt at entrapment by either the SEC or DOD.
There is no problem with someone wanting to sell the code they wrote. They do not have to give it away for free just because we are on a forum.
JRoake has been on this forum for many year longer the you and has been a good contributor to this forum.
You would have to provide a great amount of information in regards to SEC or DOD running this forum.
pnut rejects the ^^ as invalid. Thankfully it does this otherwise I would have had a bug that would be hard to find!
@Chip,
I presume that ^^ is not really meant to be equivalent to XOR? Otherwise that's a big gotcha for P1 conversion where ^^ was SQRT.
@JonnyMac
I note in the reference thread your post here (presuming Chip confirms ^^ is currently invalid, otherwise just one line needs changing)
https://forums.parallax.com/discussion/comment/1490793/#Comment_1490793
has these lines Could you please edit those lines to read Thanks Jon,
Ray
@Chip
BTW this line in your spin2 doc has this error needs ()
@jonabel1971 This is an engineering and programming forum. Keep the conspiracy theories to yourself - you risk alienating everyone who has (very generously!) held your hands through the P2 learning process.
"A Man Named Parallax"
What made me realise this is my P1 code used ^^ and pnut34y rejected it as an error.
https://forums.parallax.com/discussion/comment/1507102/#Comment_1507102
... up to...
https://forums.parallax.com/discussion/comment/1507133/#Comment_1507133
About replacing the pair of instructions STALLI/ALLOWI by a straight-pass REP, in some situations.
All three instructions have their proper uses; it's only in the sense of resorting to stalli, followed by some code, then allowi, as a "shield", to protect timing-sensitive or uninterruptible code pieces.
In such situations, and wherever rep can be used, one could avoid resorting to the "leading/trailling twins", and save an instruction, at least.
Sure, they (twins) are badly useful, in cases such:
in order to craft a definite "window", for interrupts to chime in, within otherwise uninterruptible code.
Just a bit "thrilling", but exciting.
Yes, for code with no branching and no skipping, REP is simpler and better than STALLI/ALLOWI. Three longs could be saved in the current Spin2 interpreter.
STALLI could be enhanced with {WC/WZ/WCZ} where C/Z = 'interrupt enable flag' (1 if interrupts were allowed before this instruction, else 0) for cases when REP could not be used.
REP should be #6 not #5 to allow for a AUGS needed by the QDIV instruction.
The link to the first post of this discussion can be found by copying the posts' link which is obtained by right-clicking the posts' date next to the avartar.
Cluso,
You know you could've posted in here to remind everyone.
Regarding ALTx instructions in SKIPF blocks, they don't get any special treatment. If they are prefixing a cancelled instruction then they are effectively prefixing a NOP. Which ain't gonna do squat.
Yes. Didn't think
Yes, probably just skipped like an ordinary instruction.
Would have to be careful of AUGx as they are often automatically inserted which could play havoc with counting the instructions. IIRC I've identified this in the python program I wrote to make the skip bit patterns.
The other thing I was pointing out is that if the skip is greater than 7 instructions, a delay is inserted in the pipeline (must be 2 clocks). Just need to be aware of this if counting instructions for timing purposes.
If we can get a full set of details here I can post over my reference post.
AUGx is similar story, but they're not as rigid as an ALTx in that the alternate AUG and an ALTx can be stacked after and they'll all combine. I'd guess a NOP will consume all though. Which means a cancelled instruction will also release all AUGx and ALTx stacked prefixing.
SKIPF traps/tips:
First instruction after SKIPF cannot be skipped and is replaced by a NOP if skip bit is 1.
The maximum skip jump is 7 and every 8th consecutive instruction with skip bit 1 is replaced by a NOP.
A hidden NOP consumes a skip bit and requires repeat instruction count to be incremented for REP+SKIPF.
Remaining skip bits are still active after a jump. If any of these are 1 then EXECF can be used to jump out of a skip pattern safely.
A hidden two-long instruction created by AUGx is a potent trap that can be avoided by using a register to hold a > 9-bit value, saving two cycles.
A CALL is treated as a single instruction, the importance of which cannot be overestimated. Skipping is suspended inside the subroutine.
I've had bugs caused by 1-4, but I bend over backwards to avoid ## in skip patterns.
I disagree with 3. A skip does indeed perform a 2 clock stall or a NOP equivalent, but it definitely does not consume (ie you need to waste) a skip bit.
Not sure what you mean about the rep+skipf? I am unsure about any rep implications.
A skip pattern with remaking bits can be overwritten or retired by performing a new skip.
A hidden NOP converts a 1 bit into a 0 bit, so it does consume a bit in that sense. The really important point is that you must increment the number of repeated instructions in REP for every hidden NOP in the REP block. This has been tested.
I disagree with the terminology of hidden NOP. What is happening is that an instruction is cancelled, instead of being skipped. The skip pattern is unchanged, but 2 cycles are required and the rep count increments, unlike for skipped instructions.
So I’d represent it as:
It's all coming back. Yes, the 8th skipped instruction is executed as a nop, hence the 2 clocks.
I'll likely be rewriting my latest gotcha - https://forums.parallax.com/discussion/comment/1539747/#Comment_1539747
Comments and questions can be added here in this topic.
First detail I'll add is the use case posted is for RDFAST with streamer writing to pins. NCO rate was sysclock/16.
EDIT: Well, having now tried to replicate the hypotheses in pure pasm - it don't crash for me ... it's not even skipping an instruction ... might be time to look more carefully at what Flexspin's Fcache is doing ...