Shop OBEX P1 Docs P2 Docs Learn Events
SHL, SHR, ROL, ROR, SAR instructions — Parallax Forums

SHL, SHR, ROL, ROR, SAR instructions

HarleyHarley Posts: 997
edited 2007-10-06 00:14 in Propeller 1
For some reason these instructions seem a bit strange. Like, I imagined them sort of like a shift register. And the 'wc' result would be effected by the last shift. Spent a few hours before realizing why no other bit (other than lsb or msb) affected the result.

What is the purpose of being able to shift more than 1 place yet 'wc' is only influenced by 'original' bit 0 (or 31 for left shift/rotates)? Seems limited.

Sure seems like it would make more sense to effect 'wc' with the last bit shifted out. So now need to do 'and register,#n' where n = the desired bit position or mask bit. (Is there a better way?) (A potential Trap??) yeah.gif

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko

Comments

  • RaymanRayman Posts: 14,162
    edited 2007-10-05 01:56
    I didn't appreciate that until you just mentioned it!· This does seem to be unlike the other machines I know...
  • deSilvadeSilva Posts: 2,967
    edited 2007-10-05 02:48
    Other "machines you know" can probably only shift one place.. So this question does not apply to them. For shifting "one place" the Propeller's shift/rot instructions behave eactly as you expect.

    Wider shifts are a hardly to be expected plus in such a machine as the Propeller. Shifting more places is generally a quite different application from algorithms shifting just one place.

    Best do NOT use the flags when shifting more than one place. Shifting N places is NOT N times shifting one place!!
  • Mike GreenMike Green Posts: 23,101
    edited 2007-10-05 03:01
    For those interested, what the Propeller has for shifting is called a "barrel shifter" because it's like an old fashioned wooden barrel that rotates. This is a device that shifts any number of bits in a single operation. As such, the notion of the last bit shifted is not real, so the current definition of the C flag is as reasonable as any other.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-10-05 03:46
    You can get a "last-bit-out" carry, with only a one-instruction penalty, by shifting by n-1, then by one.

    I've often wondered about the design considerations that led to the "first-bit-out" choice. I have to assume it wasn't an arbitrary decision; and, given (perhaps wrongly) that both could be implemented with equal difficulty, I have to believe that "first-bit-out" was judged the more useful. It would be interesting to get inside Chip's mind on this one. I hope he kept a journal. Perhaps some day he will write a book akin to Tracy Kidder's The Soul of a New Machine, a highly entertaining read!

    -Phil
  • deSilvadeSilva Posts: 2,967
    edited 2007-10-05 03:59
    Phil Pilgrim (PhiPi) said...
    You can get a "last-bit-out" carry, with only a one-instruction penalty, by shifting by n-1, then by one.
    You can see an example in deSilvas Tutorial "ex08A" (p. 22) smile.gif
    said...
    Perhaps some day he will write a book akin to Tracy Kidder's The Soul of a New Machine, a highly entertaining read!
    Tracy Kidd was/is a journalist with good but limited understanding of the technical aspect.. Most he was interested in the "human factor"!

    But may be Chip will hire deSilva to do this job smile.gif
  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-10-05 04:05
    There is also the consideration that by having a fixed bit determinent for the carry flag the silicon complexity is greatly reduced, instead of having to tap all 32 bits only the LSB and MSB need to be tapped. And as others have pointed out, the other behavior can be replicated easily.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.

    Post Edited (Paul Baker (Parallax)) : 10/5/2007 4:11:22 AM GMT
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-10-05 04:41
    The complexity is something I wondered about. If the carry flag were treated as an extension of the register being shifted, either left or right, would it not simply add one more bit to the result? But even that may have wedged out something more important on the die. I guess you have to draw the line somewhere.

    -Phil
  • potatoheadpotatohead Posts: 10,260
    edited 2007-10-05 05:09
    IMHO, this behavior made perfect sense to me. There is no real return on the complexity as the handling of the flags would only address some use cases. There are enough different use cases to make said address only impact a fraction of the overall processing burden. Better to just let the users deal with it, and provide other functionality that will address a significant fraction of use cases, that lie within it's scope.

    The ability to barrel shift more than makes up for the occasional instruction required to test the result. Non issue.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Propeller Wiki: Share the coolness!
  • BradCBradC Posts: 2,601
    edited 2007-10-05 05:31
    The barrel shifiting has allowed me to shave an instruction out of a *very* tight loop and as a consequence pack another feature in.. Lovely

    When you only have 512 words to play with.. (yeah yeah, I know it's 496) every cycle/instruction counts!

    It's very well explained in Phil Pilgrims Tricks and Traps document (I have that page stuck to the wall next to my monitor).

    Extremely useful stuff.
  • RaymanRayman Posts: 14,162
    edited 2007-10-05 11:24
    deSilva was right... The Epson MCU I've worked with lately only shifts one place at a time. But, one fundamental difference is that the plain "rotate right" and "rotate left" instructions rotate "through the carry". (I think that's the same for 80x86, but I'd have to check.) So, an n-1 shift then 1 shift wouldn't replicate the behavior...
  • HarleyHarley Posts: 997
    edited 2007-10-05 15:01
    to All,

    Rereading all the replies, I wanted to use SHL variable,#n wc,nr. Not to disturb any bit positioning, just to check if a bit was 1 or 0.

    Am now using AND variable,#m where 'm' is a mask bit for the desired position. Not quite as clean, but works. Probably several others could be used. SHR wasn't optimized, IMHO.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Harley Shanko

    Post Edited (Harley) : 10/5/2007 3:20:54 PM GMT
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-10-05 15:27
    Harley,

    ANDing is the usual and accepted way to do what you want. For readability, you can create your mask "on the fly", viz:

    ····and variable, #1 << bitposition nr,wz

    Incidentally, this is equivalent to

    ····test variable, #1 << bitposition wz

    which is just an and with the nr preset.

    -Phil

    Post Edited (Phil Pilgrim (PhiPi)) : 10/5/2007 3:35:15 PM GMT
  • HarleyHarley Posts: 997
    edited 2007-10-05 16:09
    Thanks Phil,

    I thought I read somewhere along in time that assembler instructions couldn't be as complex as Spin. Are you impling that one could also write

    ····test variable, (#1 << bitposition1 AND #1 << bitposition2) wz ' ???

    Does the manual define how complex 'value 2' could be for 'test' and other instructions? I don't recall ever seeing such a limitation for assembly.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Harley Shanko
  • deSilvadeSilva Posts: 2,967
    edited 2007-10-05 16:20
    You can use operations with constants with arbitrary complexity everywhere Note that assambly labels are nothing but constants.


    However what you have been writing is pure nonsens, as # is an operation code modifier and has nothing to do in the places where you put it. Under certain circumstances
     TEST variable, # (1 << bitposition1 | 1 << bitposition2) WZ
    


    will work.(I presume you wanted to say OR ratherthan AND ...) The circumstances are: The constant expression has to yield a value <512 smile.gif

    You can even say
    TEST variable, # (|< bitposition1 | |< bitposition2) WZ
    
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-10-05 16:22
    Harley,

    You don't want to AND your mask positions: your mask will end up being zero. Here's the correct way, using a bitwise OR:

    ····test variable, #(1 << bitposition1) | (1 << bitposition2) wz

    -Phil

    Addendum: In recognition of deSilva's admonition, "bitposition" must always be less than 9. This means you can't "reach" the upper bit positions using an immediate mask but, rather, must preload the mask into a memory location and use that instead.

    Post Edited (Phil Pilgrim (PhiPi)) : 10/5/2007 4:29:35 PM GMT
  • deSilvadeSilva Posts: 2,967
    edited 2007-10-05 16:29
    Rayman said...
    deSilva was right... ... an n-1 shift then 1 shift wouldn't replicate the behavior...

    No, it wouldn't. That is why I was after this fact: "A #N shift is not an N times #1 shift"
    The INTEL-style "rotate through carry" are beasts of very special kind. They can be best described as "rotate nine", i.e. The carry should be considered as the nineth bit, then imagine a rotate, that decouple the nineth bit again..
  • HarleyHarley Posts: 997
    edited 2007-10-05 16:42
    Thanks deSilva and Phil (again),

    This clarifies things very well. I just didn't write precisely what I intended (meant first mask bit 'and' second mask bit, or the first OR'd with second).

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Harley Shanko
  • IAN STROMEIAN STROME Posts: 49
    edited 2007-10-06 00:14
    Yep Rayman you suspect correctly,
    80x86 rotate left and right through carry,with RCL,RCR mnemonics
    as do 68K with ROL,ROR with optional ROXL,ROXR using extend flag X.
    Not sure about 80x86 ROL ROR ( only got an old 386 H/W manual ),but
    would suspect carry holds state of last shift,otherwise there's no point
    having the instruction.
    Certainly true for 68K,and I suspect for nearly all other processors!!

    Best Regards to All
    Ian

    :- We are here on earth to do good for others; What the others are here
    for I have no idea.
Sign In or Register to comment.