Page 1 of 1

lrotl (long rotate left) function

Posted: Sat Aug 03, 2013 3:37 am
by ozzie
I recently had a need to use lrotl (long rotate left) on unsigned longs, so I wrote this procedure:

Code: Select all

Procedure.l lrotl(pSource.l, pShift)
  ; long rotate left
  ; pShift is number of bits to rotate left
  Protected nTmp.l, nSource.l, nTarget.l
  Protected nBit0.l
  
  nSource = pSource
  If nSource < 0
    nBit0 = 1 << (pShift-1)
    nSource & $7FFFFFFF
  EndIf
  nTmp = nSource >> (32 - pShift)
  nTmp | nBit0
  nTarget = nSource << pShift
  nTarget | nTmp
  ProcedureReturn nTarget
EndProcedure
It's necessary to specifically handle negatives or the sign bit gets propagated down the long by >>.

Hope it's of use to someone.

Re: lrotl (long rotate left) function

Posted: Sun Aug 04, 2013 9:41 am
by ozzie
I've received a PM from "idle" that provides a more compact way of implementing rotate. Here it is, with macros for rotating 32-bit or 64-bit variables, and including examples slightly modified by myself:

Code: Select all

Macro RotLeft32(var,pp)   ;variables need to be uniquely named for all scopes  
  !if  defined  v_#var
    !ROL dword [v_#var],pp
  !else 
    !ROL dword [p.v_#var],pp
  !end If 
EndMacro 

Macro RotLeft64(var,pp) 
  !if defined v_#var
    !ROL qword [v_#var],pp
  !else 
    !ROL qword [p.v_#var],pp
  !end If    
EndMacro 

Procedure foo() 
  Protected pa.l 
  ; pa = 22345 
  pa = $ABCD1234
  Debug "$" + Hex(pa,#PB_Long) + ", %" + RSet(Bin(pa,#PB_Long),32,"0")
  RotLeft32(pa,24)
  Debug "$" + Hex(pa,#PB_Long) + ", %" + RSet(Bin(pa,#PB_Long),32,"0")
  
EndProcedure   

Global a.l 

; a = 12345 
a = $12345678
Debug "$" + Hex(a,#PB_Long) + ", %" + RSet(Bin(a,#PB_Long),32,"0")
RotLeft32(a,24)
Debug "$" + Hex(a,#PB_Long) + ", %" + RSet(Bin(a,#PB_Long),32,"0")

foo()