Shop OBEX P1 Docs P2 Docs Learn Events
Will the P2 have any one-step shift-and-mask instructions? — Parallax Forums

Will the P2 have any one-step shift-and-mask instructions?

jac_goudsmitjac_goudsmit Posts: 418
edited 2013-10-10 07:47 in Propeller 2
In many Propeller 1 projects, including my own, I'm seeing that a few adjacent pins are used together for some special function, and that some code needs to be used to shift and mask the important pins from the input, or to the output.

It would be nice if there would be some simple instructions that would do both the shifting and the masking at the same time. On the P1 you would have to do:

'Output value "value" masked with "mask" on bits "shift" and up
mov x, value ' get raw value
and x, #mask ' which bits are needed
shl x, #shift ' how far to shift
xor x, OUTA ' determine bits to change
xor OUTA, x ' change only those bits

'Input value "value" from bits "shift" and up, mask with "mask"
mov x, INA ' get the bits
shr x, #shift ' shift in place
and x, #mask ' discard unwanted bits

Any chance that those can be replaced by single instructions on the P2 that do the shifting and the masking (or at least just the shifting) all at once? Call it SHOUT and SHIN or something, to shift a value by a certain number of bits and dump it to an output, or read it from an input and shift it before writing it to memory.

===Jac

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2013-10-09 19:34
    Shifting and masking would require three arguments: the target register, the shift amount, and the mask. The Prop architecture (and instruction word length) is limited to two: a source and destination.

    -Phil
  • cgraceycgracey Posts: 14,151
    edited 2013-10-09 20:10
    Shifting and masking would require three arguments: the target register, the shift amount, and the mask. The Prop architecture (and instruction word length) is limited to two: a source and destination.

    -Phil

    To get random nibble/byte/word moves, I've used big blocks of instructions with ZCR cleared to %000. They are forced to write. Here's an example instruction space that can be repurposed:

    %01XXXX_000_I_CCCC_DDDDDDDDD_SSSSSSSS

    This space gives D and S with 4 bits of extra argument. I currently have this space used as a byte-to-byte remapper, where the first two X's determine byte within D and the next two X's determine byte within S.

    For fully-variable shift and mask, more is needed.
  • Cluso99Cluso99 Posts: 18,069
    edited 2013-10-09 22:58
    Chip said...
    To get random nibble/byte/word moves, I've used big blocks of instructions with ZCR cleared to %000. They are forced to write. Here's an example instruction space that can be repurposed:

    %01XXXX_000_I_CCCC_DDDDDDDDD_SSSSSSSS

    This space gives D and S with 4 bits of extra argument. I currently have this space used as a byte-to-byte remapper, where the first two X's determine byte within D and the next two X's determine byte within S.

    For fully-variable shift and mask, more is needed.
    A MASK & SHIFT instruction would be really nice for this example...
      MOV   DATA,INA
      AND   DATA, MASK
      SHR/SHL/ROR/ROL  DATA, #n
    
       SETZC   DATA  WZ, WC
    
    This could be done with the above instruction as follows...

    %01XXXX_000_n_nnnn_DDDDDDDDD_SSSSSSSSS

    where nnnnn = ROR #n (we don't require ROL since ROR X,#n == ROL X,#(32-n) )

    The instruction would become
    MASKROR DEST,SRCE,#n
    MASKROL DEST,SRCE,#n (the compiler would substitute MASKROR DEST,SRCE,#(32-n)
    We don't need a SHR/SHL because the MASK will overcome this.

    What would really be nice is that the instruction then sets (like SETZC)
    Z = bit 1
    C = bit 0
    BTW To me this is the wrong way around. I'd prefer Z=bit0, C=bit1

    This way we can completely decode the 2 lower bits into 4 cases.

    It's use is in reading a pair of pins, as in the example above, where you need to know which of 4 states the pair of pins is at.
  • jac_goudsmitjac_goudsmit Posts: 418
    edited 2013-10-10 07:47
    Shifting and masking would require three arguments: the target register, the shift amount, and the mask. The Prop architecture (and instruction word length) is limited to two: a source and destination.

    I realized that. Of course in most cases the mask is a series of adjacent bits starting at the shift value, (e.g. 8 bits starting at bit 22) so it would be easy to design an instruction that divides one of the operand fields into a 5-bit shift operand and a 4-bit number-of-bits-to-mask operand so it will be limited to 15 bits at a time (or 16 if a 0-value of number-of-bits-to-mask can be made to mean 16).

    But I imagine it would take a lot of extra gates to decode the instruction if it had a shift and mask value. Also the ALU would have to do two operations during one instruction and I don't know if it's designed for that.

    But just shifting in and out of place (without masking) while reading input or writing output would be a great feature. In many cases, no masking is necessary for setting outgoing bits because you'll already have the value stored with insignificant bits set to 0. For incoming data you won't have to do any post-masking if the data is near the top of a port (e.g. if I want to get bits n..31).

    The need of an operation such as a shift-and-mask came up because I realized that the Propeller doesn't have split registers (like the x86 has EAX, AX, AH and AL which are all parts of the same register). The closest you can get with the P1 is MOVD and MOVI but they are write-only (there is no instruction to get the destination or instruction field of another register without shifting or masking), they aren't complete (no instruction to write the last 5 bits) and they are inflexible (they only work on the three fields within an instruction, not on any number of bits at any place).

    ===Jac
Sign In or Register to comment.