SFUNC question

2456713

Comments

  • jmg wrote: »
    ersmith wrote: »
    jmg wrote: »
    The P2 already has BIT opcodes that can place C into any BIT of a register, so that opens up your X being a boolean VAR that consumes just ONE bit of valuable register space, instead of 32 bits in a LONG.
    Sure, if you're writing custom code in PASM. But C uses LONGS, not bits. Similarly for the Risc-V and ZPU interpreters I have to deal with the instruction sets as defined (which operate on 32 bits and which have instructions which produce 1/0 based on a test).
    OK, then perhaps a variant of the BIT instruction family, that clears non-destination bits ?
    Seems to use only 5 bits of the 9 bit S field, looks to be room to use MSB as Atomic/Alone choice ?

    But those upper four bits (D[8:5]) might be part of a multi-long bit address.
  • jmgjmg Posts: 9,829
    cgracey wrote: »
    jmg wrote: »
    OK, then perhaps a variant of the BIT instruction family, that clears non-destination bits ?
    Seems to use only 5 bits of the 9 bit S field, looks to be room to use MSB as Atomic/Alone choice ?
    But those upper four bits (D[8:5]) might be part of a multi-long bit address.
    Can you give some examples ?
    The opcode to me looks to have a D field that defines the register, and 5 bits of S define the BIT within that register.
    Are you saying this has more 'reach' than just 32b, allowing up to 512 bits to be indexed from a base ?
    (or across up to 16 Longs ?) If that's the case, some of the bits of D overlap, giving some redundancy ?


  • jmg wrote: »
    cgracey wrote: »
    jmg wrote: »
    OK, then perhaps a variant of the BIT instruction family, that clears non-destination bits ?
    Seems to use only 5 bits of the 9 bit S field, looks to be room to use MSB as Atomic/Alone choice ?
    But those upper four bits (D[8:5]) might be part of a multi-long bit address.
    Can you give some examples ?
    The opcode to me looks to have a D field that defines the register, and 5 bits of S define the BIT within that register.
    Are you saying this has more 'reach' than just 32b, allowing up to 512 bits to be indexed from a base ?
    (or across up to 16 Longs ?) If that's the case, some of the bits of D overlap, giving some redundancy ?


    When used with ALTB, those upper D bits used by the subsequent bit instruction are the register index.
  • ozpropdev wrote: »
    TonyB wrote: »
    Thinking about sprites led me somewhere unexpected. In the TI VDP sprite bit patterns can be up to 16 x 16 pixels at normal size or 32 x 32 magnified with bits doubled. Normal and magnified sprites can appear onscreen at the same time. A quick way of doubling would save time and code by allowing sprite patterns to be shifted out at the same rate, whether normal size or magnified.

    Applying this doubling idea to different data widths produces the family of operations on D shown below. Half the resulting bits in adjacent lines are identical so the logic should optimise quite well.

    Before:
    XXXXXXXX XXXXXXXX ABCDEFGH IJKLMNOP D[31:16] are don't care

    After:
    AABBCCDD EEFFGGHH IIJJKKLL MMNNOOPP Bit doubler BITDBL
    ABABCDCD EFEFGHGH IJIJKLKL MNMNOPOP Twit doubler TWTDBL
    ABCDABCD EFGHEFGH IJKLIJKL MNOPMNOP Nibble doubler NIBDBL
    ABCDEFGH ABCDEFGH IJKLMNOP IJKLMNOP Byte doubler BYTDBL
    ABCDEFGH IJKLMNOP ABCDEFGH IJKLMNOP Word doubler WRDDBL

    I didn't intend to suggest anything else new, these doublers just appeared out of the fog last night. They might be useful when data must be output at twice their usual rate, e.g. when mixing data streams with a single fixed clock.

    Unlike MASKNIB/MNIBS, I don't think they are vital but if considered worthwhile they could be added to the fairly similar SFUNCs without affecting other instructions. Bit doubling in particular is a horrible algorithm to do in software.

    Some of these can already be achieved using these instructions.
    'AABBCCDD EEFFGGHH IIJJKKLL MMNNOOPP Bit doubler BITDBL
    	rolword	dx,dx,#0
    	mergew	dx
    
    'ABCDEFGH ABCDEFGH IJKLMNOP IJKLMNOP Byte doubler BYTDBL
    	movbyts	dx,#%%1100
    
    'ABCDEFGH IJKLMNOP ABCDEFGH IJKLMNOP Word doubler WRDDBL
    	rolword	dx,dx,#0
    

    Thanks! Bit doubling was the most important to me and two instructions is very good. Forget the doublers.

  • ersmithersmith Posts: 2,069
    edited April 28 Vote Up0Vote Down
    Is there a (fast) way to read the C and Z registers? Obviously one can do a pair of muxes, for 4 cycles to read both flags. There are also some 4 cycle call instructions that push the flags. But I don't see any GETCZ instruction. There's a SETCZ, which is a bit odd because there was already:
        shr D, #1 wc,wz
    
    which could set both C and Z based on the low bits of D (assuming the upper bits of D are 0, of course).

    Could SETCZ be changed to save the original state of C and Z in D? That way if used without wc and wz it would act as a GETCZ (instead of now, where it seems to do a ror D, #2).

    I could see multiple uses for this (e.g. for interrupt routines, or interpreters, or just code that wants to save/restore the flags without touching the stack).

    Eric
  • I thought we had GETZC or GETZC at one point, but I don't see it now.
    Do not taunt Happy Fun Ball! @opengeekorg ---> Be Excellent To One Another SKYPE = acuity_doug
    Parallax colors simplified: http://forums.parallax.com/showthread.php?123709-Commented-Graphics_Demo.spin<br>
  • ozpropdevozpropdev Posts: 1,791
    edited April 28 Vote Up0Vote Down
    In P2-Hot we had the PUSHZC D & POPZC D instructions.
    You could use CALLD reg,#addr to save the flags into a register.

    @Chip
    A reminder that Pnut still has issues with CALLD that need fixing.
    Melbourne, Australia
  • There was a discussion about this a while back. If I recall correctly, it can be summarized as:

    * "SETCZ" is needed to set flags directly. This is especially true for setting it with an immediate value.
    * To read flags, use BITC and BITZ.
    * GETCZ would only be useful when you want to capture both C and Z. Otherwise, it is effectively a BITC or BITZ.
    * The most common reason for capturing both flags is to preserve them across CALLS. That capability is already baked into CALL.
    * As a result, GETCZ is unlikely to be used.

    Interestingly, if you want use bits other than D[1:0], you can sort of use BITC and BITNZ to set C and Z, since the flags are optionally set to the original bit at S[4:0]. The only catch, of course, is that D will also be altered.
  • Seairth wrote: »
    * "SETCZ" is needed to set flags directly. This is especially true for setting it with an immediate value.
    Except that as I pointed out above you can do:
      shr D, #1 wc, wz
    
    to set C and Z together, so to e.g. clear both C and Z you'd do:
      mov D, #%10
      shr D, #1 wc, wz
    
    That destroys D, but then so does the SETCZ instruction now. So the only advantage of SETCZ is that it's simpler and saves one instruction. Which is good! But the same argument applies for having a way to get C and Z.
    * GETCZ would only be useful when you want to capture both C and Z. Otherwise, it is effectively a BITC or BITZ.
    * The most common reason for capturing both flags is to preserve them across CALLS. That capability is already baked into CALL.
    * As a result, GETCZ is unlikely to be used.

    There are cases where you want a snippet of code that's using direct jumps (not calls) to save/restore the flags. I've certainly seen this in P1 code. I also think it would be pretty useful for emulating other processors which have flag registers, especially ones that combine both a signed and unsigned compare in one instruction. Here the emulator is already having to issue both CMP and CMPS, and forcing it to do 3 MUXs instead of a MUX and GETCZ is adding insult to injury :)

    It's not a huge deal, but I don't see any logical reason SETCZ shouldn't save the original state of the bits into D. Otherwise SETCZ without the wc and wz flags is completely redundant. If this is going to affect timing that's another story, but it seems like the original values are available right at the start of execution so it shouldn't be too much trouble to put them into D? There's already logic that will put C in there for RORC.

    (Just to be clear, I'm not suggesting a new opcode for GETCZ, just a new output value for SETCZ; instead of D = {D[1:0], D[31:2]} I'm suggesting D = { D[31:2], origC, origZ }. Or actually pretty much any permutation that gets the original C and Z bits into D somewhere, although putting them in a place where a later SETCZ can use them again seems logical.)

  • So, looking for a minimal change, what if SETCZ were as follows: Set flags according to D. C = D[1], Z = D[0]. If D is a register then D = {C, Z, D[31:2]}.

    This is exactly the same behavior as before, except the old C and Z are shifted in instead of D[1:0]. Of course, you'd need to shift it to set C and Z back to those values, but they would at least be captured...

    By the way, my recollection of the rotated C/Z bits in D was because you could then use this with a series of two-bit state values. you would SETCZ x WC,WZ, then use if_00, if_01, etc. to conditionally execute blocks of code or jumps. I think Chip even had some example code a while back that was doing exactly this. with all of the other changes made to the instruction set since then, it might be that this is OBE. In which case, it might must make more sens to change SETCZ as I think you have been suggesting: Set flags according to D. C = D[1], Z = D[0]. If D is a register then D[1:0] = { C, Z }.

    Possibly even better:

    SWAPCZ {#}D {wc, wz}

    Set flags according to D. If WC, C = D[1] and D[1] = C (if D is register). If WZ, Z = D[0] and D[0] = Z (if D is register).
  • Cluso99Cluso99 Posts: 12,518
    edited April 28 Vote Up0Vote Down
    Just an idea..

    SHLCZ {#}D {wc,wz}
    SHRCZ {#}D {wc,wz}

    This performs the save of both C and Z by shifting them in while preserving any previous saves.
    At the same time, you can also optionally set C and/or Z from the lost bits at the opposite end of D.
    So effectively you can save C and Z one end of D while setting C and Z from the other end.
    Alternately you can just save C and Z on either end of D while preserving a previous saved C and Z provided it is on the same end.

    Postedit: Best to keep CZ in the same orientation as CALL saves them.
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • jmgjmg Posts: 9,829
    Cluso99 wrote: »
    Just an idea..

    SHLCZ {#}D {wc,wz}
    SHRCZ {#}D {wc,wz}

    This performs the save of both C and Z by shifting them in while preserving any previous saves.
    At the same time, you can also optionally set C and/or Z from the lost bits at the opposite end of D.
    So effectively you can save C and Z one end of D while setting C and Z from the other end.
    Alternately you can just save C and Z on either end of D while preserving a previous saved C and Z provided it is on the same end.

    Postedit: Best to keep CZ in the same orientation as CALL saves them.

    Do you mean {wc,wz} determine what is inserted ?
    The count still applies here, so it would be #2 in order to load/move two bits ?

    I like the idea of using the {wc,wz} to qualify 'active bits', leverages off an underused part of the opcode.
    Those single opcodes could have assembler aliases for clarity.
  • {wc,wz} means (as per normal) what flags (c and/or z) will be set following the automatic save of both C & Z by shifting then into D.

    Yes, the shift will always be #2,so 2 bits will be shifted out, and those may be used to set C and/or Z.

    SHRCZ D WC,WZ
    result will be..
    CZ{D31:2} and C=D1, Z=D0
    if only WC was specified, then C=D1 but Z remains the same
    if only WZ was specified, then C remains the same and Z=D0
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • jmgjmg Posts: 9,829
    Cluso99 wrote: »
    {wc,wz} means (as per normal) what flags (c and/or z) will be set following the automatic save of both C & Z by shifting then into D.

    Yes, the shift will always be #2,so 2 bits will be shifted out, and those may be used to set C and/or Z.

    SHRCZ D WC,WZ
    result will be..
    CZ{D31:2} and C=D1, Z=D0
    if only WC was specified, then C=D1 but Z remains the same
    if only WZ was specified, then C remains the same and Z=D0

    I was thinking of a slight variant, where {wc,wz} means {rwc,rwz}

    SHRCZe D WC,WZ -> CZ{D31:2} and C=D1, Z=D0
    SHRCZe D WC -> C{D31:1} and C=D0
    SHRCZe D WZ -> Z{D31:1} and Z=D0
    SHRCZe D -> D0{D31:1} ?

    I thought there was already an opcode that shifted pairs {Z,C} ?
  • Is there any reason to not to use (ie always save) {wc,wz} on CALL D/CALLA D/CALLB D instructions?
    This would make it the same as CALL #A/CALLA #A/CALLB #A where C & A are always saved.

    Otherwise it is a source of errors because CALLx D must specify WC,WZ whereas CALLx #A automatically saves C & Z.

    Does _RET_ also restore C & Z or not restore C & Z ?
    The {wc,wz} applies to the instruction labelled with _RET_ so they are not available for the _RET_.
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • Cluso99 wrote: »
    Is there any reason to not to use (ie always save) {wc,wz} on CALL D/CALLA D/CALLB D instructions?
    Sometimes it's convenient for a subroutine to "return" a value by setting a flag. For example, if the subroutine calculates a number it might also set the Z flag to let the caller know whether the result is 0 or not.
  • You can do a "RET wz,wc" for that... Guess not with the _RET_ version though...
    Prop Info and Apps: http://www.rayslogic.com/
  • Cluso99 wrote: »
    Just an idea..

    SHLCZ {#}D {wc,wz}
    SHRCZ {#}D {wc,wz}

    This performs the save of both C and Z by shifting them in while preserving any previous saves.
    At the same time, you can also optionally set C and/or Z from the lost bits at the opposite end of D.
    So effectively you can save C and Z one end of D while setting C and Z from the other end.
    Alternately you can just save C and Z on either end of D while preserving a previous saved C and Z provided it is on the same end.

    Postedit: Best to keep CZ in the same orientation as CALL saves them.
    What you are describing there is the old P2Hot PUSHZC/POPZC instructions.
    http://forums.parallax.com/discussion/comment/1382218/#Comment_1382218
    Melbourne, Australia
  • ersmith wrote: »
    Cluso99 wrote: »
    Is there any reason to not to use (ie always save) {wc,wz} on CALL D/CALLA D/CALLB D instructions?
    Sometimes it's convenient for a subroutine to "return" a value by setting a flag. For example, if the subroutine calculates a number it might also set the Z flag to let the caller know whether the result is 0 or not.
    I am talking about CALLx D {wc, wz}, not the RETx instructions here. Why not just always save C & Z?
    First, that does not affect the RETx instructions!
    Second, CALLx #A always saves C & Z - there is no option to not save them!

    Currently, the user must use the WC & WZ options for CALLx D whereas not with CALLx #A. Hence these variants are inconsistent and likely will be a source of errors/bugs. Since there is no real reason (that I can see) not to just always save C &Z for both variants.

    As for _RET_, I was just pointing out there is no possible option for C & Z restore, so which way round is it, and is this the best way?
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • ozpropdev wrote: »
    Cluso99 wrote: »
    Just an idea..

    SHLCZ {#}D {wc,wz}
    SHRCZ {#}D {wc,wz}

    This performs the save of both C and Z by shifting them in while preserving any previous saves.
    At the same time, you can also optionally set C and/or Z from the lost bits at the opposite end of D.
    So effectively you can save C and Z one end of D while setting C and Z from the other end.
    Alternately you can just save C and Z on either end of D while preserving a previous saved C and Z provided it is on the same end.

    Postedit: Best to keep CZ in the same orientation as CALL saves them.
    What you are describing there is the old P2Hot PUSHZC/POPZC instructions.
    http://forums.parallax.com/discussion/comment/1382218/#Comment_1382218
    Oh yes. But PUSHCZ and POPCZ make no sense now because we have a stack and PUSH/POP instructions.

    I was suggesting these would be better than the current one SETCZ instruction, while describing actually what is being done.

    @jmg,
    I don't see any need to just save and shift 1bit C or Z. Save both, restore none/either/both.
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • I fixed up those math instructions which don't affect flags:
    EEEE 1001101 10I DDDDDDDDD SSSSSSSSS        SETD    D,S/#
    EEEE 1001101 11I DDDDDDDDD SSSSSSSSS        SETS    D,S/#
    EEEE 1001110 00I DDDDDDDDD SSSSSSSSS    *   DECOD   D,S/#
    EEEE 1001110 01I DDDDDDDDD SSSSSSSSS    *   BMASK   D,S/#
    EEEE 1001110 10I DDDDDDDDD SSSSSSSSS    *   ZEROX   D,S/#
    EEEE 1001110 11I DDDDDDDDD SSSSSSSSS    *   SIGNX   D,S/#
    EEEE 1001111 00I DDDDDDDDD SSSSSSSSS    *   MUXNITS D,S/#
    EEEE 1001111 01I DDDDDDDDD SSSSSSSSS    *   MUXNIBS D,S/#
    EEEE 1001111 10I DDDDDDDDD SSSSSSSSS        MOVBYTS D,S/#
    EEEE 1001111 11I DDDDDDDDD SSSSSSSSS        SFUNC   D,S/#
    

    REV is now part of SFUNC which I'll move out to the D-only instruction encodings. Also, XORO32 is part of SFUNC, which performs the high-quality PRNG iteration that Evanh did all the testing for.

    I renamed TRIML to ZEROX for 'zero-extend' and added the new SIGNX for 'sign-extend'.

    MUXNIBS overwrites each 4-bit field in D with data from the same field in S when the S field is non-0. This is like what was being called MASKNIB earlier, but there's also a 2-bit variant called MUXNITS.

    We'll get the C/Z thing worked out next. Also, we'll see about some boolean-helper instructions that Ersmith was asking for.
  • I've got those unary SFUNC operations moved over to the D-only instruction encodings.

    What was SFUNC is now empty. There are 6 free unary opcodes available in the new D-only area, as well. I would like to put in some boolean-helpers like Ersmith was asking for. These instructions can input C,Z,D[31:0] and output new C,Z,D[31:0]. Anything simple that can be done with those variables is implementable. Logical operations can be done on flags, D can be evaluated, and new C,Z,D[31:0] can be output. Any ideas?

    When this gets resolved, I'll do a new compile for the FPGA boards.

    Here's what's new:

    - Selectable MSB- or LSB-biased bytecodes under XBYTE via '_RET_ SETQ' data LSB
    - Signed and unsigned fast variable-length reads via RFVAR/RFVARS (1..4 bytes = 7/14/21/29 bits)
    - SIGNX instruction for sign-extension from bit 0..31
    - Masking and overwriting for 4- and 2-bit pixels via MUXNIBS/MUXNITS
    - Optimized 32-bit software PRNG iterator instruction (XORO32) modeled after Xoroshiro128+
    - New boolean helper instructions to be determined SOON

    These late changes have really sped up bytecode interpretation and allowed the interpreter to become very compact. The boolean instructions will help Ersmith's RiscV emulator and probably be targeted by C compilers.

    Here is the current instruction set. Note there are asterisks before the mnemonics that have changed recently:

  • JRetSapDoogJRetSapDoog Posts: 474
    edited April 29 Vote Up0Vote Down
    cgracey wrote: »
    A two-bit version could be useful for line or textual graphics, where there is a background color plus three foreground colors. We'd need to get rid of an instruction, though, in the vicinity.
    Sounds intriguing. Wish I fully understood it. Can anyone expand on this or what it would allow? Does one of the four bit patters choose to use the background color? Is that the same as specifying transparent? If so, the background color itself is brought in from elsewhere, I presume. Anyway, could such a provision for a "two-bit version" be used to underline or highlight text (on the fly)? Would it at all be useful for something resembling a mouse pointer (perhaps without inverse video)? How does this compare or contrast speed-wise, etc. with what standard techniques and sprites can provide? Again, it sounds interesting, but I don't really get it. I realize that this might be a moot post since the current instruction space doesn't accommodate it, but "we" won't likely contend to try to squeeze the instruction space to make room for it unless we know what this could make possible. Perhaps it could facilitate some useful on-the-fly stuff, but what? BTW, the phrase "line graphics" kind of reminds me of the FTDI's EVE chip series.

  • cgracey wrote: »
    What was SFUNC is now empty. There are 6 free unary opcodes available in the new D-only area, as well. I would like to put in some boolean-helpers like Ersmith was asking for. These instructions can input C,Z,D[31:0] and output new C,Z,D[31:0]. Anything simple that can be done with those variables is implementable. Logical operations can be done on flags, D can be evaluated, and new C,Z,D[31:0] can be output. Any ideas?
    The SIGNX instruction looks nice, thanks Chip!

    As far as booleans go, how about we go for simple:
      SETC   D  sets D to 0/1 based on the state of the C flag
      SETNC D
      SETZ  D  sets D to 0/1 based on the state of the Z flag
      SETNZ D
    
    That's enough to do all the C booleans in two instructions: CMP (or CMPS) followed by the appropriate SET. These are not really crucial (it's just saving an instruction) but it does make for more compact and faster code.

    I'd also like to vote for having SETCZ put the original C,Z into D at some place, wherever is most convenient, rather than only rotating D.

    Another way to get the SETC/SETZ effects (rather than adding new instructions) would be to make the "wc" bits in MUXC/MUXZ/etc. select what happens to the non-muxed bits: wc=0 means leave the bits alone, wc=1 means write zeros to them; then SETC D becomes MUXC D,#1 wc. I don't know if people use the parity feature of the MUX instructions much; if they do then this is obviously a non-starter.

    A bit field extract instruction might be nice too, but again it's a convenience rather than a necessity.

    Eric
  • Eric,

    The bit extractor is a tall order because it involves a 32-bit shifter, which is large. Also, it would be kind of nice to have the complement, too, where you could insert some number of S' LSBs at an offset into D. If we had some pre-settable register that contained the shift metrics, then it would be neat to have one instruction to extract the field from within S into D (LSB-justified) and another instruction to insert the field from S' LSBs into D. We'd need two 'D,S' slots for that (maybe SETFLD/GETFLD).

    So, your instructions are super easy to implement, of course, but what about SETLE and SETGT (less-than or equal, or greater-than), as well? Those would take all six slots, then.

    For SETCZ, how about if C/Z were stored in D[2:1] and the new C/Z were extracted from D[1:0]?

    I'd rather not use WC in the MUXxx instructions to change their behavior. The rules for WC and WZ are very consistent, still. I think, anyway.
  • Cluso99 wrote: »
    Just an idea..

    SHLCZ {#}D {wc,wz}
    SHRCZ {#}D {wc,wz}

    This performs the save of both C and Z by shifting them in while preserving any previous saves.
    At the same time, you can also optionally set C and/or Z from the lost bits at the opposite end of D.
    So effectively you can save C and Z one end of D while setting C and Z from the other end.
    Alternately you can just save C and Z on either end of D while preserving a previous saved C and Z provided it is on the same end.

    Postedit: Best to keep CZ in the same orientation as CALL saves them.

    Chip,
    Wouldn't this be better than the SETCZ that we have now, or what has been suggested?
    This achieves almost all suggestions in two instructions and retires one instruction.
    It's logical and consistent.
    Does it add much logic?

    Also did you read my comments about CALLx D {wc,wz} vs CALLx #A ?
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • jmgjmg Posts: 9,829
    edited April 29 Vote Up0Vote Down
    cgracey wrote: »
    REV is now part of SFUNC which I'll move out to the D-only instruction encodings. Also, XORO32 is part of SFUNC, which performs the high-quality PRNG iteration that Evanh did all the testing for.

    I renamed TRIML to ZEROX for 'zero-extend' and added the new SIGNX for 'sign-extend'.

    MUXNIBS overwrites each 4-bit field in D with data from the same field in S when the S field is non-0. This is like what was being called MASKNIB earlier, but there's also a 2-bit variant called MUXNITS.

    We'll get the C/Z thing worked out next. Also, we'll see about some boolean-helper instructions that Ersmith was asking for.

    This all sounds good.
    For Boolean helpers, I'd suggest first doing a table of all opcodes that can work on single bits. (or CZ pairs)
    Then we can see what is not covered.

    cgracey wrote: »
    I'd rather not use WC in the MUXxx instructions to change their behavior. The rules for WC and WZ are very consistent, still. I think, anyway.

    It makes sense to keep {wc,wz} consistent for arithmetic opcodes, but when you look at BIT opcodes like BITC, BITNC, which are C -> BIT opcodes, the {wc,wz} to me present a great means to extend the smarts of those boolean opcodes. (conventional WC makes little sense)

    One simple and obvious extension, is to use WZ as zero extend, which then adds the 'type conversion' opcodes of Boolean<->Long Eric asks for.

    Once you can SET/CLR individual boolean flags, the sensible next operation is Boolean AND.OR (CPL/XOR I think is already there)
    ( AND.OR may be there, but buried in another mnemonic.)
    That allows more valuable COG RAM to be saved with native boolean types.
    A quick google finds names like _Bool, bit, sbit commonly used in C on Microcontrollers.

    ersmith wrote: »
    Another way to get the SETC/SETZ effects (rather than adding new instructions) would be to make the "wc" bits in MUXC/MUXZ/etc. select what happens to the non-muxed bits: wc=0 means leave the bits alone, wc=1 means write zeros to them; then SETC D becomes MUXC D,#1 wc.

    I agree the wc,wz bits have less conventional meaning in BIT opcodes, so can be applied to Zero extend.
    I'd avoid the mnemonic form as you have written tho, instead just use the opcode bit locations, and maybe an E for extend.
    BITC does C -> AnyBit, so BITC with wz bit set, could zero extend. BITZ is used, and SETxx has been discarded before, as meaning SET TO ONE.
    Maybe BITCE for copy C to bit and extend. Not sure if the extend should apply in general case (rarer?), or only be valid for BIT #1 ?


    ersmith wrote: »
    I don't know if people use the parity feature of the MUX instructions much; if they do then this is obviously a non-starter.
    Other opcodes can extract parity already, which is more naturally a read-only operation. MUX is a RMW, so use of that for parity would be unusual.

  • IMHO the P2 have great potential to be used as the CPU for small PLCs, industrial controllers, industrial instrumentation or smart sensors/measurement systems, ...

    In this regards the following functions are used often times:
    BCD<->BIN(DEC,INT)
    GREY<->BIN(DEC,INT)

    Now the BCD is most used in communication with other instruments/sensors which most of the times happens over serial or other low rate protocols and thus can be handled in software.

    For the grey encoding the bin2grey is easier and involves two instructions
    grey=binary xor shl(binary,1)
    and can be also managed in software.
    But the opposite grey2bin, which is the most often times the case (because you are reading eg absolute encoders) requires more instructions (or loops) to decode.
    It will be nice to have some helper instructions that will enable to do a grey2bin in the same time that bin2grey could be done.

    The quadrature decoding (hoping edge based, 3ch: a, b, z) is already in the smart pins, isn't it?
    Propeller Object Exchange (last Publications / Updates) --- Oldbitcollector's guest map
    JustForMe
  • dMajo,

    Prop2-Hot actually had binary<-->grey and the the grey-->binary took two clock, as there was only time to resolves 16 series XOR's per clock. We also had a bin-->bcd instruction. There were even a few other such things.

    The smart pins do have quadrature encoding, but only use A,B. What's the Z pin for? Home position sensing?
  • jmgjmg Posts: 9,829
    dMajo wrote: »
    IMHO the P2 have great potential to be used as the CPU for small PLCs, industrial controllers, industrial instrumentation or smart sensors/measurement systems, ...

    Certainly.
    dMajo wrote: »
    In this regards the following functions are used often times:
    BCD<->BIN(DEC,INT)
    GREY<->BIN(DEC,INT)

    Now the BCD is most used in communication with other instruments/sensors which most of the times happens over serial or other low rate protocols and thus can be handled in software.
    existing DIV and DIV.MOD operations should make this conversion very fast, not that is needs to be, as you say.
    dMajo wrote: »
    For the grey encoding the bin2grey is easier and involves two instructions
    grey=binary xor shl(binary,1)
    and can be also managed in software.
    But the opposite grey2bin, which is the most often times the case (because you are reading eg absolute encoders) requires more instructions (or loops) to decode.
    It will be nice to have some helper instructions that will enable to do a grey2bin in the same time that bin2grey could be done.
    This is rare tho, and an additional challenge/problem here is there are more than one Grey Code...
    Single Track Grey codes can allow simpler sensors.
    This is probably most easily managed as a table lookup, rather than special niche opcodes.

    More useful focus will be general boolean opcodes, as those certainly CAN be used in PLCs, and speed code.
    dMajo wrote: »
    The quadrature decoding (hoping edge based, 3ch: a, b, z) is already in the smart pins, isn't it?
    Certainly Quad 2 pin is supported, but I think the Z channel needs software help, which could be via interrupt, or capture.
    Can't recall if capture is possible on a PinCell doing quad counting, but 'Z as capture' seems safest, as that is MHz capable.

Sign In or Register to comment.