Shop OBEX P1 Docs P2 Docs Learn Events
phsx is a very special, special register (pitfalls in PASM) — Parallax Forums

phsx is a very special, special register (pitfalls in PASM)

agsags Posts: 386
edited 2013-08-07 15:05 in Propeller 1
Propeller datasheet v1.4.0 states that phx registers are special, even among the 16 already-special cog registers:
PHS can only be read through the sourceoperand (same as PAR, CNT, INA, and INB). Bewarethat doing a read-modify-write instruction on PHS, like"ADD PHSA, #1", will cause the last-written value to beused as the destination operand input, rather than thecurrent accumulation.

OK, I can understand the example using add. phsa is the destination operand, and the add instruction reads the destination value, modifies it, then writes the new value to the destination. Question is, I see the following used all over the place, and it works as expected:
shl phsa, #1
Why does this work? How is shl not a read-modify-write instruction? phsa is the destination operand. Its value is read, modified, and then written back to the destination. Is there some concise way of differentiating a read-modify-write from those that are not? What am I missing?

I suppose this is minutia, but perhaps helpful in some cases to know.

Comments

  • AribaAriba Posts: 2,690
    edited 2013-08-07 10:18
    shl phsa, #1
    
    ...reads the destination register (=shadow register) shifts it left by 1 and writes the result back to the shadow register and the PHSA register.
    Just like the ADD example. Normally the SHL PHSx,#1 is used for fast SPI and the byte to send is written to the PHSx (left aligned) before the SHL PHSx loop begins, this also writes the shadow register with the same value.

    Andy
  • Dave HeinDave Hein Posts: 6,347
    edited 2013-08-07 10:21
    In the assembly section of the Prop manual it says
    PHSA and PHSB are read/write pseudo-registers. In the SrcOperand they read the counter’s accumulator value. In the DestOperand they read the shadow register whose address PHSA or PHSB occupies, but modifications affect both the shadow and accumulator registers.
    The shadow register contains the last value that was written to PHSX by an instruction. It won't match the actual value of the PHSX counter later on if it is actively counting. However, if the PHSX counter is not counting it will match the value in the shadow register, and read-modify-write instructions will work correctly.
  • agsags Posts: 386
    edited 2013-08-07 10:59
    OK, so the topic really isn't about some arcane difference between add and shl (they are both read-modify-write operations). It's really about phsx being even "more special" than I thought. The key is:
    ...but modifications affect both the shadow and accumulator registers.
    So unlike other shadow registers (cnt for example), writing modifies both the shadow and "real" registers. With cnt used as a destination operand, only the shadow register is written. That's why this works:
    mov cnt, cnt
    add cnt, #100
    waitcnt cnt, #0
    
    Thanks for pointing me toward the real issue/misunderstanding I had.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2013-08-07 12:20
    ags wrote:
    So unlike other shadow registers (cnt for example), writing modifies both the shadow and "real" registers.
    But, as Dave points out, the "real register" is modified only if the counter is not running. When the counter is running, it "owns" the real phsx, preventing read/modifiy/writes from affecting it. [See post #8.]

    BTW, the "correct" way to advance or retard the phase of a running counter is to increment or decrement frqx, then set it back to its original value.

    -Phil
  • agsags Posts: 386
    edited 2013-08-07 12:38
    Phil, this is not what I read Dave's post to say (not that I'm the expert). From the cited documentation, the write will affect both the shadow and real (counter controlled) register. A new value will be written to phsx, running or not. It just is not likely to be the expected value, because with a read-modify-write operation, the read is of the shadow register; if the counter is running (modifying phsx on its own) then the real phsx value will not be the same as the shadow register value, so the value written won't be based on the current phsx value but the last write to the shadow register.
  • Dave HeinDave Hein Posts: 6,347
    edited 2013-08-07 12:42
    In another part of the Prop manual it says
    Keep in mind that writing to PHSA or PHSB directly overrides both the current accumulated value and any potential accumulation scheduled for the same moment the write is performed.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2013-08-07 13:22
    ags, you may be right. I've always avoided modifying the phsx register during counting, but perhaps for the wrong reason. In any event, the way to advance or retard the phase is as I stated in post #5.

    -Phil
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2013-08-07 13:51
    Aaaand ... it looks like everything old is new again:

    My own hread, too. D'oh! :)

    -Phil
  • jmgjmg Posts: 15,173
    edited 2013-08-07 14:42
    ags wrote: »
    It just is not likely to be the expected value, because with a read-modify-write operation, the read is of the shadow register; if the counter is running (modifying phsx on its own) then the real phsx value will not be the same as the shadow register value, so the value written won't be based on the current phsx value but the last write to the shadow register.

    Perhaps they should extend the read-modify-write, to say read(last-write)-modify-write-to-both ?
  • tonyp12tonyp12 Posts: 1,951
    edited 2013-08-07 15:05
    Forget to state it in writing, someone need make a flash video of what is really happening.
    The video will show both Dest and Source side of PHSx in real-time while a few lines of pasm code is running.
Sign In or Register to comment.