I think I see that you use %0000 to clear C or Z and %1111 to set.
Do you need to use WCZ to set these?
I think you do, but don't see why. The other modX don't need anything special to work, right?
Also, is "cccc" and "zzzz" actually defined anywhere?
I think it's the same format as "instruction prefix".
But, this isn't so clear when applied here...
I think I see that you use %0000 to clear C or Z and %1111 to set.
Do you need to use WCZ to set these?
I think you do, but don't see why. The other modX don't need anything special to work, right?
Also, is "cccc" and "zzzz" actually defined anywhere?
I think it's the same format as "instruction prefix".
But, this isn't so clear when applied here...
I think I see that you use %0000 to clear C or Z and %1111 to set.
Do you need to use WCZ to set these?
I think you do, but don't see why. The other modX don't need anything special to work, right?
To expand on what TonyB_ wrote:
WCZ affects both flags, while WC and WZ only affect the respective flag; Without either, it effectively becomes a NOP.
Edit: MODC and MODZ are simply aliases for MODCZ that make it clear that you only intend to affect one flag.
We've been through that before. Cluso doesn't want the Z flag to be viewed as a plain store bit in any situation.
Yes, I saw that. It doesn't mean that his world view is entirely right, nor that it should be entirely ignored.
The fact that the Z flag can be operated on, set, and cleared directly is at odds with its function as a zero result flag.
Cluso99 wants (or needs) to continue to read Z as Zero state, and NZ as Non-Zero state, rather than Z as set state, and NZ as clear state (Not-Z) of the Z flag. Ok, fine by me, I think both views can be accommodated, even if you don't get all parties to agree.
The phrasing I selected was intended to be inclusive of both its operation and implementation (as a general purpose flag), and the interpretation of the meaning of the flag supported by its name.
The problem is that it varies depending on which instructions you are using.
I always view the Z flag as Z=result is zero and NZ is result is non-zero. That is the majority case!!!
Unfortunately a few instructions (like testB and MODZ) copy the bit into the Z flag rather than indicating the result is Zero or Non-Zero. So the Z flag is now reversed to the common usage.
I am living with it, but where the result is not what some expect, it needs a warning.
There is lots of small details that are not clear about many things. When I use the regular CMP instruction I always add the comment "C = borrow of (D - S)" because I can't be sure if it D or S that is above, below, greater, less or whatever.
The non-numeric uses of Z and C is one of the easier ones to follow.
The problem is that it varies depending on which instructions you are using.
I always view the Z flag as Z=result is zero and NZ is result is non-zero. That is the majority case!!!
Unfortunately a few instructions (like testB and MODZ) copy the bit into the Z flag rather than indicating the result is Zero or Non-Zero. So the Z flag is now reversed to the common usage.
I am living with it, but where the result is not what some expect, it needs a warning.
Personally I disagree with your view of the reversal of meaning, as the flag represents (among other things) the zero output of the ALU, but copying the bit into the flag doesn't involve an ALU operation, AFAICT. However, I'm not inflexible enough to stand my ground and insist that your view is wrong.
I agree regarding the need for a warning, but equally the warning needs to be clear to as many as possible.
The flag is labelled Z, and the states of the flag being referred to are Z and NZ, which everyone seems to follow and agree is correct, and therefore is the language I used for the reworded warning.
The issue appears to only relate to bit-wise operations, where copying the state of the bit to the flag disagrees with Cluso99's view of what should happen.
Many of us believe that when dealing with individual bits, the state should transfer unchanged, rather than performing a decision on whether the bit is Zero or Non-Zero.
Question for @Cluso99 : Do you believe the instructions that store and restore the state of the flags should invert the Z flag in both actions, or store and restore the flag state unchanged?
Looks like the difference is whether or not it is a regular ALU or move type of operation...
Things like testb and modcz are different and maybe can be expected to behave differently...
I'm not sure I like the name "testb" though as it does imply to me that it would behave like Cluso thinks....
Don't know what I'd call it instead though... Maybe "movbf" for move a bit to a flag...
Or, maybe "movbcz" is better...
and x,#1 wz
if_z 'the result was zero
testb x,#1 wz
if_nz 'the bit was zero
Is this consistent???
Yes, in my view it can be totally consistent:
and x,#1 wz
if_z 'the result was zero
testb x,#1 wz
if_nz 'the bit was clear
^^^^^
In each case the flag is set. I'm going to assume that neither of us will convince the other, but as I see it, the test is not whether the bit was 1 or 0, but instead whether it was set or clear; a small but significant difference. Note that TESTB and AND are different instructions performing significantly different operations. Don't confuse TEST with TESTB.
And in Chip's P1 Spin Interpreter he sets the bottom 2 bits of the byte code into the flags thus...
test op,#%01 wz 'get flags
test op,#%10 wc '(note varop requires c=1)
if_nc_and_z 'bits=00
if_nc_and_nz 'bits=01
if_c_and_z 'bits=10
if_c_and_nz 'bits=11
The flags are operating the same way, but the Z flag state had to be stored inverted because of the limitation set by the TEST instruction.
P2 code is not always the same as P1 code, however in the case of TEST it is.
From the P1 manual:
TEST is similar to AND except it doesn’t write a result to Value1; it performs a bitwise AND of the values in Value1 and Value2 and optionally stores the zero-result and parity of the result in the Z and C flags.
If the WZ effect is specified, the Z flag is set (1) if Value1 AND Value2 equals zero. If the WC effect is specified, the C flag is set (1) if the result contains an odd number of high (1) bits.
From the P2 Instruction spreadsheet:
Test D with S. C = parity of (D & S). Z = ((D & S) == 0).
To get Z set with TEST it is necessary to have all of the tested bits clear.
Addit: Also note that C is not set directly here, but is a parity result.
TESTB however is a new P2 instruction detailed as
Test bit S[4:0] of D, write to C/Z. C/Z = D[S[4:0]].
That is a single bit of D is copied into C or Z unchanged. This is a powerful new capability, but TEST has been left unchanged. If you prefer that approach use it!
Yes, that matches the P2 instruction document, plus there are also
IF_00 'same as IF_NC_AND_NZ which has the same meaning on P1
IF_01 'same as IF_NC_AND_Z which has the same meaning on P1
IF_10 'same as IF_C_AND_NZ which has the same meaning on P1
IF_11 'same as IF_C_AND_Z which has the same meaning on P1
But my point is that the storing and restoring of the flags gives no distortion of the state at any point in the process. If you check bits 1 and 0 in the LUT address targeted by XBYTE you will see the flags to be loaded in their correct state not with Z inverted to account for the TEST instruction limitations.
The Z flag has always meant ZERO. This goes way back to mainframe days when microprocessors were not even thought of.
It does not matter how you view the flag as whether its set or cleared. You just test it with an IF_Z , IF_NZ, or BNZ, JNZ, etc
Equality was an extension that when subtracted the result is considered zero, hence equal.
As far as I am concerned, TESTB and TEST should give the same results. It is just wrong when it doesn't.
Moving bits into flags is new for the P2, and it is inconsistent. It should have been a test like it always has been.
FWIW I know it will not be changed, but it is most definitely wrong.
The Z flag has always meant ZERO. This goes way back to mainframe days when microprocessors were not even thought of.
It does not matter how you view the flag as whether its set or cleared. You just test it with an IF_Z , IF_NZ, or BNZ, JNZ, etc
Equality was an extension that when subtracted the result is considered zero, hence equal.
As far as I am concerned, TESTB and TEST should give the same results. It is just wrong when it doesn't.
Moving bits into flags is new for the P2, and it is inconsistent. It should have been a test like it always has been.
FWIW I know it will not be changed, but it is most definitely wrong.
FWIW, I also have experience that extends beyond microprocessors, having worked on mainframes that didn't even have a Z flag, but instead had distinct Compare Designators, for Equal/Unequal, Greater than or Equal/Less Than, and Outside of Limits/Within Limits. On that processor checking a register contained zero was performed by a comparison with a register hardwired to return 0. There are many ways to achieve the same outcomes, and to declare one as wrong because it varies from your experience, no matter how extensive your experience may be, is somewhat limiting for meaningful discussion.
That said, the Z flag continues to mean ZERO; that hasn't changed. Direct control of the flag is what is new. Making programmers remember to store one of the flags inverted seems like unnecessary effort.
If TEST and TESTB gave the same the results, then one of them would be superfluous.
On the P1, TEST was an alias for AND with the NR effect specified. If you wanted to TEST a single bit in the range 10 to 31 you had to use a register to store the mask. TESTB allows copying any single bit to a flag with only an immediate for the designator (no mask necessary).
P1 and P2 not having Sign or Overflow flags feels odd, and AND/TEST putting the parity result into C has always seemed like an unusual choice to me, but because, unlike most other processors, you can choose whether the flags are affected or not it is actually a clever idea.
Part of what allows the Propeller chips to exist is that Chip takes a different approach to the usual.
Maybe one of the assemblers for the P2 can allow aliasing of instructions, so that you can choose a name that let's you rationalise the behaviour of these instructions. ;-)
The issue is that TEST and TESTB give opposite results. TEST can test multiple bits.
In the current ES chip TESTB can only test a single bit.
However, Chip has implemented a bit range for the new silicon. Whether that is in the TESTB instruction I don’t know. If it is, the who knows what the instruction will do.
BTW the mainframes did have flags. They were internal and implicit. A branch less, equal, greater were all testing these implicit flags. If you examined the circuitry you would find flipflops representing those flags. Some had a zero or equal, and maybe a less than so combined they would do less and equal. It just depended on the actual implementation. Sometimes the less than might be a negative flag.
Round and round we go ... TEST and TESTB are not related:
- TESTB is a bit op that, quite relevantly, equally uses C and Z. The most commonly used form is a plain bit move but I see it can also perform all four of the common logic ops with either of the specified flags. So the flags are what D is normally, and D is S and S is an extra control.
- TEST is a somewhat stray binary longword logic op. It is functionally AND NR, but there is no counterparts for the other logic ops.
Maybe that needs emphasised - The C and Z instruction encoding, for TESTB, means use C flag or Z flag as both ALU input and result - replacing the position D normally holds. The two flags are a convenient and accessible working space for the job of doing single-bit logic ops. And moves.
The issue is that TEST and TESTB give opposite results. TEST can test multiple bits.
In the current ES chip TESTB can only test a single bit.
However, Chip has implemented a bit range for the new silicon. Whether that is in the TESTB instruction I don’t know. If it is, the who knows what the instruction will do.
BTW the mainframes did have flags. They were internal and implicit. A branch less, equal, greater were all testing these implicit flags. If you examined the circuitry you would find flipflops representing those flags. Some had a zero or equal, and maybe a less than so combined they would do less and equal. It just depended on the actual implementation. Sometimes the less than might be a negative flag.
If you had read my response carefully you would have seen that the particular mainframe I was talking about called them Compare Designators (explicit, not implicit) and none of them represented Zero, the closest was the Equal/Unequal CD.
My point was that not every processor has a Zero flag, and that there are always many ways to achieve the same result.
The name is what seems to be the problem here. If, instead of it being called TESTB, it were called LDFLAGS would you still be concerned about the direct load nature of the operation?
Comments
I think I see that you use %0000 to clear C or Z and %1111 to set.
Do you need to use WCZ to set these?
I think you do, but don't see why. The other modX don't need anything special to work, right?
Also, is "cccc" and "zzzz" actually defined anywhere?
I think it's the same format as "instruction prefix".
But, this isn't so clear when applied here...
Is there any way to skip one clock?
Question: How does timing of waitse# track with INA?
Are they both 2 clocks behind?
Usage:
MODCZ cccc,zzzz WCZ
MODC cccc WC
MODZ zzzz WZ
To expand on what TonyB_ wrote:
WCZ affects both flags, while WC and WZ only affect the respective flag; Without either, it effectively becomes a NOP.
Edit: MODC and MODZ are simply aliases for MODCZ that make it clear that you only intend to affect one flag.
It's in "instructions.txt" within the zip file.
Those routes already exist for conveying results of other hub instructions, so there's no extra routes to cogs, only some hub logic.
Be careful, MODZ _SET WZ sets to Z,
whereas _CLR sets to NZ
I just tested this and it works correctly, setting or clearing the flag, and not toggling it.
I didn't mean it wasn't working, just that sometimes it seems back the front. Z is always a problem
Given the convention of a set flag being '1' state and a clear flag being '0' state, it is clearer to restate what you wrote as
"Be careful, MODZ _SET WZ sets the flag to indicate Z,
whereas _CLR clears the flag to indicate NZ"
with italics showing inserted text and bold showing changed text.
Yes, I saw that. It doesn't mean that his world view is entirely right, nor that it should be entirely ignored.
The fact that the Z flag can be operated on, set, and cleared directly is at odds with its function as a zero result flag.
Cluso99 wants (or needs) to continue to read Z as Zero state, and NZ as Non-Zero state, rather than Z as set state, and NZ as clear state (Not-Z) of the Z flag. Ok, fine by me, I think both views can be accommodated, even if you don't get all parties to agree.
The phrasing I selected was intended to be inclusive of both its operation and implementation (as a general purpose flag), and the interpretation of the meaning of the flag supported by its name.
I always view the Z flag as Z=result is zero and NZ is result is non-zero. That is the majority case!!!
Unfortunately a few instructions (like testB and MODZ) copy the bit into the Z flag rather than indicating the result is Zero or Non-Zero. So the Z flag is now reversed to the common usage.
I am living with it, but where the result is not what some expect, it needs a warning.
The non-numeric uses of Z and C is one of the easier ones to follow.
Personally I disagree with your view of the reversal of meaning, as the flag represents (among other things) the zero output of the ALU, but copying the bit into the flag doesn't involve an ALU operation, AFAICT. However, I'm not inflexible enough to stand my ground and insist that your view is wrong.
I agree regarding the need for a warning, but equally the warning needs to be clear to as many as possible.
The flag is labelled Z, and the states of the flag being referred to are Z and NZ, which everyone seems to follow and agree is correct, and therefore is the language I used for the reworded warning.
The issue appears to only relate to bit-wise operations, where copying the state of the bit to the flag disagrees with Cluso99's view of what should happen.
Many of us believe that when dealing with individual bits, the state should transfer unchanged, rather than performing a decision on whether the bit is Zero or Non-Zero.
Question for @Cluso99 : Do you believe the instructions that store and restore the state of the flags should invert the Z flag in both actions, or store and restore the flag state unchanged?
Here is the ambiguity in a nutshell...
Is this consistent???
And in Chip's P1 Spin Interpreter he sets the bottom 2 bits of the byte code into the flags thus... In P2 we can use XBYTE which can write the LUT EXEC bits 1 and 0 to C and Z
While I have not tested this, I expect that the Z will be reversed as
Things like testb and modcz are different and maybe can be expected to behave differently...
I'm not sure I like the name "testb" though as it does imply to me that it would behave like Cluso thinks....
Don't know what I'd call it instead though... Maybe "movbf" for move a bit to a flag...
Or, maybe "movbcz" is better...
Yes, in my view it can be totally consistent: In each case the flag is set. I'm going to assume that neither of us will convince the other, but as I see it, the test is not whether the bit was 1 or 0, but instead whether it was set or clear; a small but significant difference. Note that TESTB and AND are different instructions performing significantly different operations. Don't confuse TEST with TESTB.
The flags are operating the same way, but the Z flag state had to be stored inverted because of the limitation set by the TEST instruction.
P2 code is not always the same as P1 code, however in the case of TEST it is.
From the P1 manual: From the P2 Instruction spreadsheet: To get Z set with TEST it is necessary to have all of the tested bits clear.
Addit: Also note that C is not set directly here, but is a parity result.
TESTB however is a new P2 instruction detailed as That is a single bit of D is copied into C or Z unchanged. This is a powerful new capability, but TEST has been left unchanged. If you prefer that approach use it!
Yes, that matches the P2 instruction document, plus there are also
But my point is that the storing and restoring of the flags gives no distortion of the state at any point in the process. If you check bits 1 and 0 in the LUT address targeted by XBYTE you will see the flags to be loaded in their correct state not with Z inverted to account for the TEST instruction limitations.
Regards,
Anthony.
It does not matter how you view the flag as whether its set or cleared. You just test it with an IF_Z , IF_NZ, or BNZ, JNZ, etc
Equality was an extension that when subtracted the result is considered zero, hence equal.
As far as I am concerned, TESTB and TEST should give the same results. It is just wrong when it doesn't.
Moving bits into flags is new for the P2, and it is inconsistent. It should have been a test like it always has been.
FWIW I know it will not be changed, but it is most definitely wrong.
So what will TESTB do with multiple bits and the Z flag???
FWIW, I also have experience that extends beyond microprocessors, having worked on mainframes that didn't even have a Z flag, but instead had distinct Compare Designators, for Equal/Unequal, Greater than or Equal/Less Than, and Outside of Limits/Within Limits. On that processor checking a register contained zero was performed by a comparison with a register hardwired to return 0. There are many ways to achieve the same outcomes, and to declare one as wrong because it varies from your experience, no matter how extensive your experience may be, is somewhat limiting for meaningful discussion.
That said, the Z flag continues to mean ZERO; that hasn't changed.
Direct control of the flag is what is new. Making programmers remember to store one of the flags inverted seems like unnecessary effort.
If TEST and TESTB gave the same the results, then one of them would be superfluous.
On the P1, TEST was an alias for AND with the NR effect specified. If you wanted to TEST a single bit in the range 10 to 31 you had to use a register to store the mask. TESTB allows copying any single bit to a flag with only an immediate for the designator (no mask necessary).
P1 and P2 not having Sign or Overflow flags feels odd, and AND/TEST putting the parity result into C has always seemed like an unusual choice to me, but because, unlike most other processors, you can choose whether the flags are affected or not it is actually a clever idea.
Part of what allows the Propeller chips to exist is that Chip takes a different approach to the usual.
Maybe one of the assemblers for the P2 can allow aliasing of instructions, so that you can choose a name that let's you rationalise the behaviour of these instructions. ;-)
In the current ES chip TESTB can only test a single bit.
However, Chip has implemented a bit range for the new silicon. Whether that is in the TESTB instruction I don’t know. If it is, the who knows what the instruction will do.
BTW the mainframes did have flags. They were internal and implicit. A branch less, equal, greater were all testing these implicit flags. If you examined the circuitry you would find flipflops representing those flags. Some had a zero or equal, and maybe a less than so combined they would do less and equal. It just depended on the actual implementation. Sometimes the less than might be a negative flag.
- TESTB is a bit op that, quite relevantly, equally uses C and Z. The most commonly used form is a plain bit move but I see it can also perform all four of the common logic ops with either of the specified flags. So the flags are what D is normally, and D is S and S is an extra control.
- TEST is a somewhat stray binary longword logic op. It is functionally AND NR, but there is no counterparts for the other logic ops.
If you had read my response carefully you would have seen that the particular mainframe I was talking about called them Compare Designators (explicit, not implicit) and none of them represented Zero, the closest was the Equal/Unequal CD.
My point was that not every processor has a Zero flag, and that there are always many ways to achieve the same result.
The name is what seems to be the problem here. If, instead of it being called TESTB, it were called LDFLAGS would you still be concerned about the direct load nature of the operation?