Shop OBEX P1 Docs P2 Docs Learn Events
P2 Instructions TESTB & TESTBN - Page 3 — Parallax Forums

P2 Instructions TESTB & TESTBN

13

Comments

  • Cluso99Cluso99 Posts: 18,066
    I am not sure of a use for the instructions AND/OR/XOR of a [NOT]-BIT/PIN with the Z and/or C flag.
    Still seems wrong to me but I guess since I cannot see a use, I can accept it being the wrong way around. It will catch people who use it tho'.

    So now we have the MOV{C/Z}[N]{B/P} instructions...

    So far, the use I have found for them have been to set the Z flag based on the bit/pin value. Here, I would like the Z flag to be set as it normally would ie Z=set=ZERO. How to solve this is easy with the compiler :smile:
    I've just taken the MOVZxx instructions (from above) as the C is not at issue here.
    MOVZB   reg,bitindex  '  Bit --> Z    equiv    TESTNB  reg,bitindex WZ  ' Z if !Bit=0
    MOVZNB  reg,bitindex  ' !Bit --> Z    equiv    TESTB   reg,bitindex WZ  ' Z if  Bit=0
    
    MOVZP   pinindex      '  Pin --> Z    equiv    TESTNB  pinindex WZ      ' Z if !Pin=0
    MOVZNP  pinindex      ' !Pin --> Z    equiv    TESTB   pinindex WZ      ' Z if  Pin=0
    
    MOV  moves the bit/pin into the Z flag                         (ie Z=SET=1=zero-cond if bit/pin=1
    TEST sets the Z flag according to the test result of bit/pin=0 (ie Z=SET=1=zero-cond if bit/pin=0)
    
    So we have a pseudo code for testing the bit/pin which is equivalent to the inverse of moving the bit/pin.
  • Cluso99Cluso99 Posts: 18,066
    TonyB_ wrote: »
    CALLs that modify the flags write D[30] or S[30] to Z.
    RCZL writes D[30] to Z.
    RCZR writes D[0] to Z.

    Z does not always mean zero.

    I have just been looking thru the instruction set. There are more inconsistencies :(

    I expect that the following are not what would normally be expected either (not tested)...
    DRVZ {#}D {WCZ}
    DRVNZ {#}D {WCZ}
    My assumption would have been that if Z is set (ie means zero) that the pin would be set LOW. Is it set HIGH ???

    Same applies to these ???
    WRZ D
    WRNZ D

    And of course CALL and its variants are likely saving Z as "1" and not "0" as I would have previously expected. It's only a problem if you test these bits. It's fine for the RET instruction as a negative-negative will result in a positive.
  • evanhevanh Posts: 15,126
    The existing listed TESTxx instruction encodings have a hole in the CZ bit encodings of each one.

    Assuming Chip likes the idea of absorbing C/Z into the mnemonics, I'm guessing Chip will remove the existing TESTxx mnemonics and issue a new, more verbose set as per Roys/Peters examples. ie: It won't be aliases.

  • Cluso99Cluso99 Posts: 18,066
    evanh wrote: »
    The existing listed TESTxx instruction encodings have a hole in the CZ bit encodings of each one.

    Assuming Chip likes the idea of absorbing C/Z into the mnemonics, I'm guessing Chip will remove the existing TESTxx mnemonics and issue a new, more verbose set as per Roys/Peters examples. ie: It won't be aliases.

    The aliases will allow those (including myself) who want to test the bit/pin using the sensible and consistent settings of the Z flag.
  • Ahle2Ahle2 Posts: 1,178
    It's all good and well until we start writing some real assembly code as garryj did and then we will see where it can be confusing or awkward. Maybe I might have a problem but then I think I will anyway, the P2 is radically different even from the P1.

    Here is Roy's suggestion tidied up using mov instead of set.
    MOVZB   reg,bitindex     ' Z = Bit
    MOVZNB  reg,bitindex     ' Z = !Bit
    MOVCB   reg,bitindex     ' C = Bit
    MOVCNB  reg,bitindex     ' C = !Bit
    ANDZB   reg,bitindex     ' Z = Z & Bit
    ANDZNB  reg,bitindex     ' Z = Z & !Bit
    ANDCB   reg,bitindex     ' C = C & Bit
    ANDCNB  reg,bitindex     ' C = C & !Bit
    ORZB    reg,bitindex     ' Z = Z | Bit
    ORZNB   reg,bitindex     ' Z = Z | !Bit
    ORCB    reg,bitindex     ' C = C | Bit
    ORCNB   reg,bitindex     ' C = C | !Bit
    XORZB   reg,bitindex     ' Z = Z ^ Bit
    XORZNB  reg,bitindex     ' Z = Z ^ !Bit
    XORCB   reg,bitindex     ' C = C ^ Bit
    XORCNB  reg,bitindex     ' C = C ^ !Bit
    
    MOVZP   pinindex         ' Z = Pin
    MOVZNP  pinindex         ' Z = !Pin
    MOVCP   pinindex         ' C = Pin
    MOVCNP  pinindex         ' C = !Pin
    ANDZP   pinindex         ' Z = Z & Pin
    ANDZNP  pinindex         ' Z = Z & !Pin
    ANDCP   pinindex         ' C = C & Pin
    ANDCNP  pinindex         ' C = C & !Pin
    ORZP    pinindex         ' Z = Z | Pin
    ORZNP   pinindex         ' Z = Z | !Pin
    ORCP    pinindex         ' C = C | Pin
    ORCNP   pinindex         ' C = C | !Pin
    XORZP   pinindex         ' Z = Z ^ Pin
    XORZNP  pinindex         ' Z = Z ^ !Pin
    XORCP   pinindex         ' C = C ^ Pin
    XORCNP  pinindex         ' C = C ^ !Pin
    

    This makes perfectly sense and I think it is not confusing, even to a hardcore assembly programmer. Remember SEC and CLC instructions on the 6502? While there was no SEZ and CLZ, I think most assembly programmers are very familier with the concept of setting the status flags in other ways than by arithmetical results.
  • Cluso99 wrote: »
    I am not sure of a use for the instructions AND/OR/XOR of a [NOT]-BIT/PIN with the Z and/or C flag.
    Still seems wrong to me but I guess since I cannot see a use, I can accept it being the wrong way around. It will catch people who use it tho'.
    Here's an example of a CRC calc.
    	rep	#4,#8
    	shr	data,#1 wc
    	testb	crc16,#0 xorc
    	shr	crc16,#1
    if_c	xor	crc16,poly
    
  • Cluso99 wrote: »
    DRVZ {#}D {WCZ}
    DRVNZ {#}D {WCZ}
    My assumption would have been that if Z is set (ie means zero) that the pin would be set LOW. Is it set HIGH ???

    DRVZ will drive the pin high if the result was zero.(z=1)
  • cgraceycgracey Posts: 14,133
    Cluso99 wrote: »
    TonyB_ wrote: »
    CALLs that modify the flags write D[30] or S[30] to Z.
    RCZL writes D[30] to Z.
    RCZR writes D[0] to Z.

    Z does not always mean zero.

    I have just been looking thru the instruction set. There are more inconsistencies :(

    I expect that the following are not what would normally be expected either (not tested)...
    DRVZ {#}D {WCZ}
    DRVNZ {#}D {WCZ}
    My assumption would have been that if Z is set (ie means zero) that the pin would be set LOW. Is it set HIGH ???

    Same applies to these ???
    WRZ D
    WRNZ D

    And of course CALL and its variants are likely saving Z as "1" and not "0" as I would have previously expected. It's only a problem if you test these bits. It's fine for the RET instruction as a negative-negative will result in a positive.

    Maybe we should rename the Z flag into something that means "not zero", but in the positive, like "S" for "something", as opposed to nothing. Then, all this madness could go away.
  • Cluso99Cluso99 Posts: 18,066
    cgracey wrote: »
    Cluso99 wrote: »
    TonyB_ wrote: »
    CALLs that modify the flags write D[30] or S[30] to Z.
    RCZL writes D[30] to Z.
    RCZR writes D[0] to Z.

    Z does not always mean zero.

    I have just been looking thru the instruction set. There are more inconsistencies :(

    I expect that the following are not what would normally be expected either (not tested)...
    DRVZ {#}D {WCZ}
    DRVNZ {#}D {WCZ}
    My assumption would have been that if Z is set (ie means zero) that the pin would be set LOW. Is it set HIGH ???

    Same applies to these ???
    WRZ D
    WRNZ D

    And of course CALL and its variants are likely saving Z as "1" and not "0" as I would have previously expected. It's only a problem if you test these bits. It's fine for the RET instruction as a negative-negative will result in a positive.

    Maybe we should rename the Z flag into something that means "not zero", but in the positive, like "S" for "something", as opposed to nothing. Then, all this madness could go away.
    Z has always been at odds with C.
    Perhaps it could be called "N" for Non-zero. Of course we already use "N" to be NOT although in that context it might be ok.

    I really don't follow why we introduced the notion of shifting into Z rather than the standard way of Z being set in the result. RCZL/RCZR is the only place where the shifting notion has real meaning, and it could be covered here as being the same as Z is set if the shift result is Zero.

    Currently, it does not matter how you cut it, Z is not consistent. Sometimes it means Zero, sometimes it means Non-Zero.
  • evanhevanh Posts: 15,126
    And sometimes C means Carry, sometimes it doesn't. That's why there is so many ways of labelling the if_ conditions.

    There is only the two flags. The Prop doesn't have a whole register full of condition codes bits, so the Z and C get repurposed.

  • AribaAriba Posts: 2,682
    Cluso99 wrote: »
    ...
    Currently, it does not matter how you cut it, Z is not consistent. Sometimes it means Zero, sometimes it means Non-Zero.

    It's not sometimes, it's well defined:
    For ALU operations the Z flag indicates if the resulting value is zero, that is: all bits are zero, not just a single bit. ALU operations work 32bit wide and all bits count, that is totally different from single bit operations.

    For single bit operations it makes much more sense to use the true state of the bits for the universal C and Z flags. So they behave the same and are interchangeable.

    Why is this such a problem for you with the Z flag, but not with the C flag? C is even more inconsistent, and should be always cleared for logical operations, because there is no overflow, and therefore no carry to indicate. For sure this would make it unusable.

    Andy
  • I have the same question. The sorting Roy did makes a lot of sense!

    For what it's worth, didn't we add the flag ops in response to a discussion about saving variable space some time back? That's where all this came from. Rather than maintain an entire long, and read / write to it, use the flags for more complex state information.

    That also means we can ignore these instructions in most cases, just doing things in the usual way, does it not?

  • Chip,
    Please don't change the Z flag. That's impacting almost all of the instructions/modifiers for an issue with just a small number of them. It will have ramifications across the board, including making porting from P1 harder.
    Just rename the instructions, like I suggested and Peter revised.
  • Seconded. I would rather see the conflicting instructions removed before changing the Z flag.
  • cgraceycgracey Posts: 14,133
    edited 2018-12-10 19:36
    potatohead wrote: »
    Seconded. I would rather see the conflicting instructions removed before changing the Z flag.

    I don't want to change the Z flag, believe me. That is opening a big can of worms.

    We could rename those instructions, however. I would like to require WZ or WC after the operands, so that a quick look at the code will tell you a flag is being modified.

    Can someone make a list of the proposed instructions, substituting the letter F for the letter C or Z? That would cut the mnemonics in half and give need for WZ/WC.
  • TonyB_TonyB_ Posts: 2,108
    edited 2018-12-10 20:32
    No need for F in my view.
    MOVB	D,{#},S		WC/WZ
    MOVBN	D,{#},S		WC/WZ
    ANDB	D,{#},S		WC/WZ
    ANDBN	D,{#},S		WC/WZ
    ORB	D,{#},S		WC/WZ
    ORBN	D,{#},S		WC/WZ
    XORB	D,{#},S		WC/WZ
    XORBN	D,{#},S		WC/WZ
    
    MOVP	D,{#},S		WC/WZ
    MOVPN	D,{#},S		WC/WZ
    ANDP	D,{#},S		WC/WZ
    ANDPN	D,{#},S		WC/WZ
    ORP	D,{#},S		WC/WZ
    ORPN	D,{#},S		WC/WZ
    XORP	D,{#},S		WC/WZ
    XORPN	D,{#},S		WC/WZ
    

  • I really think it's better if you DO NOT put the WC/WZ on the end. That is part of the confusion. With WZ on there it should mean that the Z flag is set based on the result of the operation and not just part of the operation like it is in these instructions.

    Having the flag name in the instruction should be enough to know that it's going to manipulate the flag.

    If you insist on having something on the end to indicate it, then it should be a unique identifier that is not WZ/WC/WCZ. Perhaps WF? And keep the flag name in the instruction.
  • cgraceycgracey Posts: 14,133
    TonyB_ wrote: »
    No need for F in my view.
    MOVB	D,{#},S		WC/WZ
    MOVBN	D,{#},S		WC/WZ
    ANDB	D,{#},S		WC/WZ
    ANDBN	D,{#},S		WC/WZ
    ORB	D,{#},S		WC/WZ
    ORBN	D,{#},S		WC/WZ
    XORB	D,{#},S		WC/WZ
    XORBN	D,{#},S		WC/WZ
    
    MOVP	D,{#},S		WC/WZ
    MOVPN	D,{#},S		WC/WZ
    ANDP	D,{#},S		WC/WZ
    ANDPN	D,{#},S		WC/WZ
    ORP	D,{#},S		WC/WZ
    ORPN	D,{#},S		WC/WZ
    XORP	D,{#},S		WC/WZ
    XORPN	D,{#},S		WC/WZ
    

    I see MOVB and think a bit is being moved, but from where to where?

    Maybe this is better:
    GETB	D,{#},S		WC/WZ
    GETBN	D,{#},S		WC/WZ
    GETB	D,{#},S		ANDC/ANDZ
    GETBN	D,{#},S		ANDC/ANDZ
    GETB	D,{#},S		ORC/ORZ
    GETBN	D,{#},S		ORC/ORZ
    GETB	D,{#},S		XORC/XORZ
    GETBN	D,{#},S		XORC/XORZ
    
    GETP	D,{#},S		WC/WZ
    GETPN	D,{#},S		WC/WZ
    GETP	D,{#},S		ANDC/ANDZ
    GETPN	D,{#},S		ANDC/ANDZ
    GETP	D,{#},S		ORC/ORZ
    GETPN	D,{#},S		ORC/ORZ
    GETP	D,{#},S		XORC/XORZ
    GETPN	D,{#},S		XORC/XORZ
    


  • Roy ElthamRoy Eltham Posts: 2,996
    edited 2018-12-10 21:18
    Ugh, I give up, are you even reading my posts?

    MOVBZ <-- move B to Z
    MOVPZ <--- move P to Z

    Having the flag in the instruction name MAKES it more clear.
  • cgraceycgracey Posts: 14,133
    edited 2018-12-10 21:44
    Roy Eltham wrote: »
    Ugh, I give up, are you even reading my posts?

    MOVBZ <-- move B to Z
    MOVPZ <--- move P to Z

    Having the flag in the instruction name MAKES it more clear.

    Yes, I've been reading your posts.

    As I've said, I would like to keep some flag suffix, so that it's obvious a flag is being affected.

    I like MOVBZ/MOVPZ, except for their lack of flag suffix.

    I agree that TESTB(N)/TESTP(N) is a little confusing because of the TEST(N) precedent.

    These instructions are really 'getting' a bit and affecting a flag with it. I think GETB(N)/GETP(N) are most accurate and preserve the flag suffix.
  • Roy ElthamRoy Eltham Posts: 2,996
    edited 2018-12-10 21:47
    My recent post suggested a new suffix for these. Is that acceptable?
    As I said, the problem is that having WZ on the suffix implies that the Z flag will be set according to the result (as in set when the result is 0) and not what will actually happen with these instructions.
    That, to me, is the crux of the problem. So it needs to be something else that indicates it.

    Also, I don't like GET* at all.
  • cgraceycgracey Posts: 14,133
    Roy Eltham wrote: »
    My recent post suggested a new suffix for these. Is that acceptable?
    As I said, the problem is that having WZ on the suffix implies that the Z flag will be set according to the result (as in set when the result is 0) and not what will actually happen with these instructions.
    That, to me, is the crux of the problem. So it needs to be something else that indicates it.

    Also, I don't like GET* at all.

    If people insist on thinking "GETB reg,bit WZ" is going to make Z = !bit, I can't help that.

    "WF" as a suffix doesn't tell what flag is being affected.

    GET seems most accurate for what is going on.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2018-12-10 22:01
    'Too bad it couldn't have been an NZ flag. Then we wouldn't be having this discussion. :)

    (Just kidding, Chip. Please don't even think about changing it.)

    -Phil
  • AJLAJL Posts: 512
    edited 2018-12-10 22:03
    Roy Eltham wrote: »
    My recent post suggested a new suffix for these. Is that acceptable?
    As I said, the problem is that having WZ on the suffix implies that the Z flag will be set according to the result (as in set when the result is 0) and not what will actually happen with these instructions.
    That, to me, is the crux of the problem. So it needs to be something else that indicates it.

    Also, I don't like GET* at all.

    To me (and I think it's safe to say, Chip), all the WC and WZ suffices indicate is that the particular flag is affected (may change). I humbly submit that the "set according to the result (as in set when the result is 0)" is an inference, not an implication.

    To me, the crux of the problem is whether one can accept the idea of flag states being directly controlled, or being restricted to the ALU state output only. It seems obvious to me that we have some who can and some who can't (or won't), but only for the Z flag; Direct control of the C flag is accepted without question.
    I find this inconsistency quite puzzling.

  • I think as a compromise, that the instruction should have the flag name in it also.

    In your example: GETB reg,bit WZ ' Where is B being put? You seem to think the WZ explains that, but it doesn't. On every other ALU instruction WZ is not the destination, it's indicating that the Z flag will be written based on the result.

    GETBZ reg, bit WZ ' this is better, in my opinion, because it's more clear. It's not ideal, but since you insist on having the WZ, this compromise is acceptable.

    Also, I still think MOVBZ is more clear than GETBZ, but whatever, it's not as big a deal as the main issue.
  • AribaAriba Posts: 2,682
    I like the GETxx syntax.

    WZ and WC just mean that the corresponding flag gets written. What kind of operation is used to generate the C and Z flag depends on the instruction.
    GETB  D,#S  WZ     'Get Bit from D and write it into Z.
    GETP  D,#S  XORC   'Get Pin from Port and xor it with C.
    

    maybe GETNB instead of GETBN describes better what happens.
  • cgraceycgracey Posts: 14,133
    edited 2018-12-10 22:17
    Roy Eltham wrote: »
    I think as a compromise, that the instruction should have the flag name in it also.

    In your example: GETB reg,bit WZ ' Where is B being put? You seem to think the WZ explains that, but it doesn't. On every other ALU instruction WZ is not the destination, it's indicating that the Z flag will be written based on the result.

    GETBZ reg, bit WZ ' this is better, in my opinion, because it's more clear. It's not ideal, but since you insist on having the WZ, this compromise is acceptable.

    Also, I still think MOVBZ is more clear than GETBZ, but whatever, it's not as big a deal as the main issue.

    I kind of agree, but when it comes to the logical operations AND/OR/XOR, things get really hard to infer, since it seems most likely that the bit would be getting affected. That's why I like GET - it's very passive in regards to the bit.
  • cgraceycgracey Posts: 14,133
    'Too bad it couldn't have been an NZ flag. Then we wouldn't be having this discussion. :)

    (Just kidding, Chip. Please don't even think about changing it.)

    -Phil

    Our problem is that in English and math parlance, we don't have a word that means NOT ZERO, so we can only express the function as ZERO in the negative.
  • TubularTubular Posts: 4,620
    edited 2018-12-10 22:35
    Since ZIP can mean zero, how about a flag UNZIP ?

    I'm not yet persuaded we need to rake over things like this. Its not like P2 is a processor without quirks

    I'm not so worried about what gets decided here, as I am about the precedent it sets for revisiting so many decisions from past years. Those decisions made some kind of marginal sense at the time, but its hard to respool the surrounding context that led to those decisions
  • GET works for me.

    We already have
    GETWORD
    GETBYTE
    GETNIB

    so it makes sense to "carry" that form on with
    GETBIT
    GETPIN

    One trick I learned many years ago to avoid confusion is to read the documentation.
    I never assume that one MCU is going to behave the same as another.

Sign In or Register to comment.