What about bits 9-31 for literal values in PASM?
ags
Posts: 386
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.
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
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!)
<instruction> <dest>,#<0-512 value>
then the 23 MSB of the accumulator will be set to 0.
Thanks,
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.
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.
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.
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.
Hell no, that's what the experts are for:)
I've not seen the need to print the second one out. Good job all around on that effort. Recommended.
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.
What are you talking about ?...
The manual says that literals are zero-extended...
I'm sure someone else just answered this. Here's why I use a zero constant.
You can't have literal in a destination.
Duane
Jonathan
This is what I read and understood before asking the question:
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.