Shop OBEX P1 Docs P2 Docs Learn Events
Hardware bug: AUGS + ALTS doesn't clear internal AUGS flag — Parallax Forums

Hardware bug: AUGS + ALTS doesn't clear internal AUGS flag

Just something to be aware of. And perhaps fix in whatever the next rev is @cgracey

CON _CLKFREQ = 10_000_000
DAT
        org
        mov pb,#someval
        alts pb,##1024
        mov sometmp,0-0
        nop
        nop
        mov pa,#0
        sub pb,#someval
        debug(uhex_long(pa),uhex_long(pb))
        jmp #$

someval long $DEADBEEF
sometmp res 1

Results in pa = $0000_0400 and pb = $0000_0002. The value for PB is as expected (ALTx autoincrement), but PA should obviously be zero, but isn't because it gets the high bits from the AUGS that is supposed to apply to ALTS only.

Comments

  • TonyB_TonyB_ Posts: 2,105
    edited 2022-01-02 11:05

    AUGS + ALTS seems to make no sense.
    What is final value of someval sometmp?

  • @TonyB_ said:
    AUGS + ALTS seems to make no sense.

    It makes total sense: for AUGS, S is the base pointer and autoincrement amount. With an unaugmented immediate, the autoincrement field is always zero.

    What is final value of someval sometmp?

    sometmp is set to someval (so $DEADBEEF), but that's not interesting.

  • You are using the address of someval not the value DEADBEEF when you move into pb, and subtract later. This might be $A if the debug instruction takes one long. Doesn't affect the result for PB, but is a little confusing.

    Still it doesn't really explain the PA result unless ALTS leaves the AUGS flag alone or something weird like that.

  • @rogloh said:
    Still it doesn't really explain the PA result unless ALTS leaves the AUGS flag alone or something weird like that.

    That that exact weird thing happens is the point of the post. AUGS is applying to both the ALTS and whatever immediate op comes after (the move into pa, in this case)

  • evanhevanh Posts: 15,126

    Cool! I hadn't tested that one before.

    The ALTS behaviour is known correct. ALTx instructions are excluded from AUGmenting. What I didn't know is that an unused AUGx state can stay primed until there is a use for it. In this case the first instruction that can consume the AUGS value is the mov pa,#0. It's surprising that the mov sometmp,0-0 doesn't consume the AUGS state/value but I guess it must require immediate addressing to be consumed.

    If that's all true (I don't have a Prop2 with me to test with.) then this can be used in some neat ways me thinks.

  • TonyB_TonyB_ Posts: 2,105
    edited 2022-01-02 11:15

    What is interesting here is how long AUGS "stays alive", until there is an instruction with immediate S that can be AUGmented.

  • It needs to be documented at least.

  • evanhevanh Posts: 15,126
    edited 2022-01-02 00:44

    Hehe, it does have a one-liner in the spreadsheet where it does explicitly say next 9-bit #S ...

    Queue #%nn_nnn_nnnnnnnnn_nnnnnnnnn to be used as upper 23 bits for next #S occurrence, so that the next 9-bit #S will be augmented to 32 bits.

  • evanhevanh Posts: 15,126

    Oh, that's another IRQ staller too. Like using REP as a code protect, an AUGx prevents branching to ISR until consumed.

  • @evanh said:
    Cool! I hadn't tested that one before.

    The ALTS behaviour is known correct. ALTx instructions are excluded from AUGmenting. What I didn't know is that an unused AUGx state can stay primed until there is a use for it. In this case the first instruction that can consume the AUGS value is the mov pa,#0. It's surprising that the mov sometmp,0-0 doesn't consume the AUGS state/value but I guess it must require immediate addressing to be consumed.

    The funny is that the ALTS is being augmented (otherwise pb would end up as zero), but it doesn't actually consume the AUGS.

  • Also, I assumed that AUGx stick around until used was common knowledge.

  • evanhevanh Posts: 15,126

    Hmm, I see. So the following will be PA = $0000_0400 and PB = 0, I presume?

    DAT
            org
            mov pb,#someval
            alts pb,#0
            mov sometmp,0-0
            augs #2
            nop
            nop
            mov pa,#0
            sub pb,#someval
            debug(uhex_long(pa),uhex_long(pb))
            jmp #$
    
    someval long $DEADBEEF
    sometmp res 1
    
  • evanhevanh Posts: 15,126

    @Wuerfel_21 said:
    Also, I assumed that AUGx stick around until used was common knowledge.

    I had thought only ALTx instructions postponed AUGx instructions. But clearly they're more flexible.

  • @evanh said:
    Hmm, I see. So the following will be PA = $0000_0400 and PB = 0, I presume?

    DAT
            org
            mov pb,#someval
            alts pb,#0
            mov sometmp,0-0
            augs #2
            nop
            nop
            mov pa,#0
            sub pb,#someval
            debug(uhex_long(pa),uhex_long(pb))
            jmp #$
    
    someval long $DEADBEEF
    sometmp res 1
    

    You have the right idea, but the assembler syntax is a bit weird in that you have to do AUGS #2<<9
    Then it will indeed have your predicted result.

  • TonyB_TonyB_ Posts: 2,105
    edited 2022-01-02 01:23

    @Wuerfel_21 said:
    The funny is that the ALTS is being augmented (otherwise pb would end up as zero), but it doesn't actually consume the AUGS.

    More accurate to say that ALTS D is incremented (or decremented), rather than ALTS is augmented.

  • @TonyB_ said:

    @Wuerfel_21 said:
    The funny is that the ALTS is being augmented (otherwise pb would end up as zero), but it doesn't actually consume the AUGS.

    More accurate to say that ALTS D is incremented (or decremented), rather than ALTS is augmented.

    How so? The higher bits of S being added to D is a normal thing, you just can't do it with a short immediate. I've always used that feature in tight loops where I hoisted the S value into a register, so that's why I never noticed the issue with AUGS before.

  • evanhevanh Posts: 15,126

    Funnily, I can't find documentation saying that AUGx instructions are ignored by ALTx instructions.

  • Wuerfel_21Wuerfel_21 Posts: 4,371
    edited 2022-01-02 01:41

    @evanh said:
    Funnily, I can't find documentation saying that AUGx instructions are ignored by ALTx instructions.

    Because they don't. It's more like "AUGx ignores ALTx, but not the other way round", I guess

  • evanhevanh Posts: 15,126
    edited 2022-01-02 01:53

    Chip did talk about it long time ago. I wasn't following too closely though so may have miss-understood intent.

  • TonyB_TonyB_ Posts: 2,105
    edited 2022-01-02 11:17

    @Wuerfel_21 said:

    @TonyB_ said:

    @Wuerfel_21 said:
    The funny is that the ALTS is being augmented (otherwise pb would end up as zero), but it doesn't actually consume the AUGS.

    More accurate to say that ALTS D is incremented (or decremented), rather than ALTS is augmented.

    How so? The higher bits of S being added to D is a normal thing, you just can't do it with a short immediate. I've always used that feature in tight loops where I hoisted the S value into a register, so that's why I never noticed the issue with AUGS before.

    I understand the point you are making, namely that you don't want AUGS to take effect in some later instruction, but ALTS D,S is the same code size and two cycles faster than ALTS D,##S and avoids the AUGS + ALTS issue.

  • evanhevanh Posts: 15,126

    The question is less what Ada expected in the example, but more around what did Chip intend originally, and is it doing so. Then secondly, what can be done with the new knowledge of how it actually works - which appears to be different to everyone's expectations.

  • @cgracey Could this perhaps be added to the "Known Bugs" bit of the silicon doc?

    Just scrolled by that again and thought this should probably be there.

  • cgraceycgracey Posts: 14,133

    @Wuerfel_21 said:
    @cgracey Could this perhaps be added to the "Known Bugs" bit of the silicon doc?

    Just scrolled by that again and thought this should probably be there.

    Yes, I'm glad you discovered this. I will look at the Verilog source code tomorrow to figure out why this is happening.

    By the way, this...

    debug(uhex_long(pa),uhex_long(pb))

    ...could be shortened to this...

    debug(uhex_long(pa,pb))

  • @cgracey said:
    By the way, this...

    debug(uhex_long(pa),uhex_long(pb))

    ...could be shortened to this...

    debug(uhex_long(pa,pb))

    I realized this, too. Didn't work in flexspin's debug implementation until then (though it was actually Eric who fixed it)

  • cgraceycgracey Posts: 14,133

    Indeed, AUGS is intentionally not consumed by ALTx instructions, but I forgot to inhibit the AUGS value from augmenting an ALTx #S.

    I'll make a note of this in the Google P2 Silicon doc.

    I also made a note in the Verilog code to fix this in any future silicon version, so that ALTx #S does not use the AUGS value. The fact that it does use the AUGS value undermines ALTx #S operation.

Sign In or Register to comment.