Shop OBEX P1 Docs P2 Docs Learn Events
What about bits 9-31 for literal values in PASM? — Parallax Forums

What about bits 9-31 for literal values in PASM?

agsags Posts: 386
edited 2011-08-01 10:22 in Propeller 1
There is an answer that seems obvious to me, but I want to check before I get used to doing something that is ultimately a bad habit that may cause problems.

When using a literal operand in PASM, the value must be less than 512 (because only 9 bits (of the full 32 bit sized PASM instruction) are available to represent either the immediate value or the cog register address). What happens to bits 9-31 (of the ALU register)? Are they set to zero? Are they left undisturbed in the previous set/reset state from the previous operation?

I've seen many code examples where the DAT block defines:

zero long $0
max long $FFFFFFFF

The first seems unnecessary if I can just use a literal value #$0 to clear all 32 bits. The second clearly could not be replaced using a literal operand value.

Thanks.

Comments

  • AleAle Posts: 2,363
    edited 2011-07-31 09:40
    You have to use a constant...
    mov  variable, pointer_to_constant
    
    pointer_to_constant
      long $BABE_FACE
    

    you need a extra long as you see :)

    When you load the lower 9 bits using mov, #constant the upper bits are cleared (this is not the case for movs, movd, movi, consult the manual!)
  • agsags Posts: 386
    edited 2011-07-31 13:06
    OK - so the answer is that the Propeller hardware implementation guarantees that if I load only the 9 LSB of the accumulator with an immediate value using

    <instruction> <dest>,#<0-512 value>

    then the 23 MSB of the accumulator will be set to 0.

    Thanks,
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-07-31 13:25
    Not quite. That's only true of mov. If you use movi, movd, or movs, only the targeted field of <dest> is affected; the rest of the destination register remains as it was.

    BTW, there is no accumulator in the Propeller, so I assume you were referring to <dest>. And finally, the limits for an immediate operand are 0 - 511, not 0 - 512.

    -Phil
  • Mark_TMark_T Posts: 1,981
    edited 2011-07-31 15:18
    Remember you can use neg if you want small negative immediate values...
  • kuronekokuroneko Posts: 3,623
    edited 2011-07-31 16:58
    ags wrote: »
    zero long $0
    max long $FFFFFFFF

    The first seems unnecessary if I can just use a literal value #$0 to clear all 32 bits.
    The general problem is not src slot usage but writing such a value to hub.
  • agsags Posts: 386
    edited 2011-07-31 20:22
    Not quite. That's only true of mov. If you use movi, movd, or movs, only the targeted field of <dest> is affected; the rest of the destination register remains as it was.

    BTW, there is no accumulator in the Propeller, so I assume you were referring to <dest>. And finally, the limits for an immediate operand are 0 - 511, not 0 - 512.

    -Phil

    I was very sloppy, boo on me. Yes, 9 bits, 0-511 range. Yes, I was referring to the destination register - but I presumed that there was some accumulator in which the actual operation (add, sub...) occurred and then the result was transferred to the destination register. What I'm trying to get at is whether the 9-bit immediate value only affected those 9 bits of the operation or if the other 23 bits were cleared. In other words, does the immediate value become the full value of the 32 bit long register?

    Yes, I am excluding the movs, movd and movi instructions. They only affect the bits as documented for each instruction.

    It is good to see the thoroughness with which questions are answered. It is very helpful, thanks.
  • agsags Posts: 386
    edited 2011-07-31 20:27
    kuroneko wrote: »
    The general problem is not src slot usage but writing such a value to hub.

    Sorry to be dense on this, but I don't understand what you are describing. Are you saying that since

    wrlong <dest>,<src>

    really has <dest> as the source, but since it can't use an immediate value, a register address needs to be provided (the register containing the $0, or other 0-511 ranged value to be written to hub) to have that value written to hub? I hadn't thought of that, but that may explain why I see all the "zero" labeled cog registers containing $0 values in the code I've found. [I'm just figuring this out on the fly as I type.]

    Thanks for the reply.
  • agsags Posts: 386
    edited 2011-07-31 20:29
    Mark_T wrote: »
    Remember you can use neg if you want small negative immediate values...

    Wow! Yet another idea that I hadn't thought of. I didn't see when that instruction would actually be of use. This is a good example. Thanks for the reply.
  • kuronekokuroneko Posts: 3,623
    edited 2011-07-31 20:31
    ags wrote: »
    Are you saying that since

    wrlong <dest>,<src>

    really has <dest> as the source, but since it can't use an immediate value, a register address needs to be provided ...
    Yes. wrxxxx is odd in that the meaning of the operands is reversed. This can be attributed to the fact that the only difference (apart from effect) to rdxxxx is the use of the result bit in its encoding (e.g. rdbyte nr == wrbyte, check the datasheet for the binary pattern). Meaning it's using the same mechanism underneath.

    As for writing 0 back to hub use wrxxxx par, addr or any other unused SPR if you're uncomfortable with shadow[par]. For -1 I guess that comes down to style. I rather stick with non-zero and use e.g. wrlong $, addr ($ referring to the current PASM register address so it's basically sending the instruction code for the wrlong down to hub RAM).

    That said, wrlong & Co can use immediate values (in the src slot), e.g. to fetch clkfreq I use rdlong cnt, #0.
  • AleAle Posts: 2,363
    edited 2011-08-01 03:41
    small comment... does anyone read the manual ?... the newest version is quite good....
  • Heater.Heater. Posts: 21,230
    edited 2011-08-01 03:59
    Read?
    Hell no, that's what the experts are for:)
  • potatoheadpotatohead Posts: 10,261
    edited 2011-08-01 06:11
    I refer to it regularly. It's a really nice revision, handy. Very useful as a PDF, which was the core trouble with the first edition. Navigation took too long. I printed one out! Was much faster.

    I've not seen the need to print the second one out. Good job all around on that effort. Recommended.
  • agsags Posts: 386
    edited 2011-08-01 06:12
    Ale wrote: »
    small comment... does anyone read the manual ?... the newest version is quite good....

    Hmm. Not sure how someone could formulate such a question without having first RTFM. The question was attempting to reconcile what isn't explicitly said in the manual (Propeller Manual v1.1, p241 "Literals must fit in 9 bits") and the practice noticed in many code examples (storing $0 in a cog register, even though that value could be loaded with a literal #$0).

    I guess the experts can always decline to answer a question that seems beneath them, or clearly stated in a manual.

    @kuroneko: thank you for the answer that did reconcile the documented behavior and the common practice I've seen (wrlong dest,src)
    @Mark_T: thank you for pointing out the use of "neg". I've seen it documented but didn't put together this use, which could be helpful.
  • AleAle Posts: 2,363
    edited 2011-08-01 06:57
    @ags: please READ and understand what is written in post #2.
    ags wrote:
    Hmm. Not sure how someone could formulate such a question without having first RTFM

    What are you talking about ?...

    The manual says that literals are zero-extended...
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-08-01 08:03
    ags wrote: »
    The question was attempting to reconcile what isn't explicitly said in the manual (Propeller Manual v1.1, p241 "Literals must fit in 9 bits") and the practice noticed in many code examples (storing $0 in a cog register, even though that value could be loaded with a literal #$0).

    I'm sure someone else just answered this. Here's why I use a zero constant.
    preloop                 wrbyte  zeroC, commandPtr             
    loop                    rdbyte  previousCmd, commandPtr            
    
    zeroC                   long    0                       ''constants
    

    You can't have literal in a destination.

    Duane
  • lonesocklonesock Posts: 917
    edited 2011-08-01 09:21
    The special purpose registers are cleared to 0 for you (excepting PAR, of course), so there are many registers you can use for 0 without defining one of your own. DIRB is my favorite 0, though it needs a little documentation to be clear, but saves a long. [8^)

    Jonathan
  • agsags Posts: 386
    edited 2011-08-01 10:22
    Ale wrote: »
    @ags: Please read and understand what is written in post #2.
    ...
    The manual says that literals are zero-extended...

    This is what I read and understood before asking the question:
    literals must fit in 9 bits
    [FONT=times new roman,times new roman][FONT=times new roman,times new roman]the source operand is only 9 bits wide; it can hold a value from 0 to 511 ($000 to $1ff). Keep this in mind when specifying literal values. If a value is too big to fit in 9 bits, it must be stored in a register and accessed via the register's address. For example: [/FONT]
    [/FONT][FONT=parallax,parallax][FONT=parallax,parallax]add x, bigvalue 'add bigvalue to x [/FONT][/FONT]
    [FONT=parallax,parallax][FONT=parallax,parallax]x long 50 [/FONT][/FONT]
    [FONT=parallax,parallax][FONT=parallax,parallax]bigvalue long 1024 [/FONT][/FONT]
    [FONT=arial,arial][FONT=arial,arial]propeller manual v1.1 [/FONT][/FONT][FONT=times new roman,times new roman][FONT=times new roman,times new roman]· [/FONT][/FONT][FONT=arial,arial][FONT=arial,arial]page 241 [/FONT][/FONT]

    If you'd like to contribute to my knowledge you are welcome to point me to the section that states the the upper bits are cleared when using a literal value. I didn't see it. That doesn't guarantee it's not there, I may have missed it or forgotten it. I do not attempt to keep the entire document in my head, I refer to it constantly to try to answer my questions before asking others.

    @Duane Degn: Yes, that is the explanation I found useful in understanding why anyone would store $0 in a register - because immediate values cannot be used for dest operands, and the wrxxxxx instruction is a good example of why that would be desired. Thanks.
    @lonesock: Nice trick, thanks.
Sign In or Register to comment.