Shop OBEX P1 Docs P2 Docs Learn Events
SHL won't do 32 bits — Parallax Forums

SHL won't do 32 bits

Red_DogRed_Dog Posts: 7
edited 2014-07-03 16:32 in Propeller 1
I'm trying to write a shift routine to shift two 32 bit registers to perform a 64 bit shift.
When the shift count is <= 32 I'm doing the following:

Mov temp, #32
Sub temp, count
Mov high_temp, high_long
Shl high_temp, temp
Shr low_long, count
Add low_long, high_temp
Shr high_long, count

The problem I'm having is when temp is 32, shl doesn't shift at all.
If I make temp #31, it works, but not #32. If make
Temp t#33, it shifts it as if temp is #1.

The manual doesn't say anything about limitations for the number of
Bits that can be shifted, although it wouldn't make sense to shift it
More than 32.

What am I missing?

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2014-07-01 20:13
    Shift src arguments uses only the lower 5 bits, so they have a range of 0..31. If you try to shift by 32 bits, it's the same as zero bits. You'll just have to make an exception in your program for that case.

    -Phil
  • Mark_TMark_T Posts: 1,981
    edited 2014-07-03 04:30
    Fortunately the exception case is very simple to handle, you move low to high long and zero the low one...

    A thought: code the shift using rotates, since a 32 bit and a 0 bit rotate are the same thing anyway.
  • JonnyMacJonnyMac Posts: 9,105
    edited 2014-07-03 12:32
    I'm sure that PASM gurus (Marko, Phil, Beau, et al) will show me better ways to do this -- I took a whack as an exercise over lunch.
    shifter                 cmp     shiftbits, #64          wc, wz
                  if_ae     mov     lolong, #0
                  if_ae     mov     hilong, #0
                  if_ae     jmp     #shifter_ret
    
                            cmp     shiftbits, #32          wc, wz
                  if_e      mov     hilong, lolong
                  if_e      mov     lolong, #0
                  if_e      jmp     #shifter_ret
    
                  if_a      sub     shiftbits, #32
                  if_a      shl     hilong, shiftbits
                  if_a      mov     lolong, #0
                  if_a      jmp     #shifter_ret
    
    :loop                   shl     lolong, #1              wc
                            rcl     hilong, #1
                            djnz    shiftbits, #:loop
    
    shifter_ret             ret
    
  • Mark_TMark_T Posts: 1,981
    edited 2014-07-03 13:28
    bit-by-bit shifting is slow, something like:
    shifter                 cmp     shiftbits, #64          wc, wz
                  if_b      jmp     #:less64
    
                            mov     lolong, #0
                            mov     hilong, #0
                            jmp     #shifter_ret
    
    :less64                 rol     lolong, shiftbits
                            neg     mask, #1
                            shl     mask, shiftbits
                            cmp     shiftbits, #32         wc,wz
                  if_b      jmp     #:less32
    
                            mov     hilong, lolong
                            and     hilong, mask
                            mov     lolong, #0
                            jmp     #shifter_ret
    
    :less32                 shl     hilong, shiftbits
                            xor     hilong, lolong
                            and     lolong, mask
                            xor     hilong, lolong
    shifter_ret            ret
    
    
  • Mark_TMark_T Posts: 1,981
    edited 2014-07-03 13:39
    Or even
    shifter                 cmpsub  shiftbits, #32  wc
                  if_c      mov     hilong, lolong
                  if_c      mov     lolong, #0
                  if_c      jmp     #shifter
                            rol     lolong, shiftbits 
                            neg     mask, #1
                            shl     mask, shiftbits
                            shl     hilong, shiftbits
                            xor     hilong, lolong
                            and     lolong, mask
                            xor     hilong, lolong
    shifter_ret             ret
    
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2014-07-03 13:57
    I think this will do it (untested):
    shl64         mov       hilong,lowlong
                  shl       lolong,shftamt
                  cmp       shftamt,#32 wc
            if_nc mov       lolong,#0
                  cmp       shftamt,#64 wc
                  neg       shftamt,shftamt wz
                  shr       hilong,shftamt
       if_z_or_nc mov       hilong,#0
    shl64_ret     ret
    


    -Phil
  • Mark_TMark_T Posts: 1,981
    edited 2014-07-03 15:59
    Not a great start for a shift on a 64 bit value:
    shl64         mov       hilong,lowlong
    
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2014-07-03 16:32
    Oh Smile; for some reason I thought the initial value was 32 bits. Nevermind.

    -Phil
Sign In or Register to comment.