
Update v1.02
- Added SignX(...) for Byte, Word, etc
Update v1.03
- Added 32bit Compiler version
Update v1.04
- optimize code, Thanks to Wilbert
Update v1.05
- Added Get, Set and ClrBit
Update v1.06
- Added x64
Code: Select all
;-TOP
; Kommentar : Bitshift and Rotation
; Author : mk-soft
; Second Author :
; Datei : Bitshift.pb
; Version : v1.06
; Erstellt : 09.06.2007
; Geändert : 25.06.2017
;
; Compilermode :
;
; ***************************************************************************************
; Bitshift left shift
Procedure SHL8(value.b, count.l = 1)
!xor eax, eax
!mov al, byte [p.v_value]
!mov ecx, dword [p.v_count]
!shl al, cl
ProcedureReturn
EndProcedure
; Bitshift right shift
Procedure SHR8(value.b, count.l = 1)
!xor eax, eax
!mov al, byte [p.v_value]
!mov ecx, dword [p.v_count]
!shr al, cl
ProcedureReturn
EndProcedure
; Bitshift left shift
Procedure SHL16(value.w, count.l = 1)
!xor eax, eax
!mov ax, word [p.v_value]
!mov ecx, dword [p.v_count]
!shl ax, cl
ProcedureReturn
EndProcedure
; Bitshift right shift
Procedure SHR16(value.w, count.l = 1)
!xor eax, eax
!mov ax, word [p.v_value]
!mov ecx, dword [p.v_count]
!shr ax, cl
ProcedureReturn
EndProcedure
; Bitshift left shift
Procedure SHL32(value.l, count.l = 1)
!mov eax, dword [p.v_value]
!mov ecx, dword [p.v_count]
!shl eax, cl
ProcedureReturn
EndProcedure
; Bitshift right shift
Procedure SHR32(value.l, count.l = 1)
!mov eax, dword [p.v_value]
!mov ecx, dword [p.v_count]
!shr eax, cl
ProcedureReturn
EndProcedure
; Bitshift left shift
Procedure.q SHL64(value.q, count.q = 1); Bitshift left shift
CompilerIf #PB_Compiler_Processor=#PB_Processor_x64
!mov rax, qword [p.v_value]
!mov rcx, qword [p.v_count]
!shl rax, cl
ProcedureReturn
CompilerElse
ProcedureReturn value<<count
CompilerEndIf
EndProcedure
; Bitshift right shift
Procedure.q SHR64(value.q, count.q = 1); Bitshift right shift
CompilerIf #PB_Compiler_Processor=#PB_Processor_x64
!mov rax, qword [p.v_value]
!mov rcx, qword [p.v_count]
!shr rax, cl
ProcedureReturn
CompilerElse
Protected v1.q
v1 = ~($FFFFFFFFFFFFFFFF << (64-count))
ProcedureReturn value>>count & v1
CompilerEndIf
EndProcedure
; Bitshift left rotation
Procedure ROL32(value.l, count.l = 1)
!mov eax, dword [p.v_value]
!mov ecx, dword [p.v_count]
!rol eax, cl
ProcedureReturn
EndProcedure
; Bitshift right rotation
Procedure ROR32(value.l, count.l = 1)
!mov eax, dword [p.v_value]
!mov ecx, dword [p.v_count]
!ror eax, cl
ProcedureReturn
EndProcedure
; Bitshift left rotation
Procedure.q ROL64(value.q, count.q = 1); Bitshift left rotation
CompilerIf #PB_Compiler_Processor=#PB_Processor_x64
!mov rax, qword [p.v_value]
!mov rcx, qword [p.v_count]
!rol rax, cl
ProcedureReturn
CompilerElse
Protected v1.q = shr64(value, 64-count)
ProcedureReturn (value<<count) | v1
CompilerEndIf
EndProcedure
; Bitshift right rotation
Procedure.q ROR64(value.q, count.q = 1); Bitshift right rotation
CompilerIf #PB_Compiler_Processor=#PB_Processor_x64
!mov rax, qword [p.v_value]
!mov rcx, qword [p.v_count]
!ror rax, cl
ProcedureReturn
CompilerElse
Protected v1.q = shr64(value, count)
ProcedureReturn v1 | value<<(64-count)
CompilerEndIf
EndProcedure
; Swap Bytes
Procedure.w BSWAP16(value.w)
!xor eax,eax
!mov ax, word [p.v_value]
!rol ax, 8
ProcedureReturn
EndProcedure
Procedure BSWAP32(value.l)
!mov eax, dword [p.v_value]
!bswap eax
ProcedureReturn
EndProcedure
Procedure.q BSWAP64(value.q)
CompilerIf #PB_Compiler_Processor=#PB_Processor_x64
!mov rax, qword [p.v_value]
!bswap rax
CompilerElse
!mov edx, dword [p.v_value]
!mov eax, dword [p.v_value + 4]
!bswap edx
!bswap eax
CompilerEndIf
ProcedureReturn
EndProcedure
; -------------------------------------------------------------------------------------
Macro SignB(Value)
(Bool(Value > 0) - Bool(Value >> 7))
EndMacro
Macro SignW(Value)
(Bool(Value > 0) - Bool(Value >> 15))
EndMacro
Macro SignL(Value)
(Bool(Value > 0) - Bool(Value >> 31))
EndMacro
Macro SignQ(Value)
(Bool(Value > 0) - Bool(Value >> 63))
EndMacro
; -------------------------------------------------------------------------------------
Procedure GetBit32(value, bit)
!mov eax, dword [p.v_value]
!mov ecx, dword [p.v_bit]
!bt eax, ecx
!rcl eax, 1
!and eax, 1
ProcedureReturn
EndProcedure
Procedure GetBit64(value.q, bit.q)
CompilerIf #PB_Compiler_Processor=#PB_Processor_x64
!mov rax, qword [p.v_value]
!mov rcx, qword [p.v_bit]
!bt rax, rcx
!rcl rax, 1
!and rax, 1
ProcedureReturn
CompilerElse
ProcedureReturn value>>bit & 1
CompilerEndIf
ProcedureReturn
EndProcedure
Procedure SetBit32(value, bit)
!mov eax, dword [p.v_value]
!mov ecx, dword [p.v_bit]
!bts eax, ecx
ProcedureReturn
EndProcedure
Procedure.q SetBit64(value.q, bit.q)
CompilerIf #PB_Compiler_Processor=#PB_Processor_x64
!mov rax, qword [p.v_value]
!mov rcx, qword [p.v_bit]
!bts rax, rcx
ProcedureReturn
CompilerElse
ProcedureReturn (1 << bit) | value
CompilerEndIf
ProcedureReturn
EndProcedure
Procedure ClrBit32(value, bit)
!mov eax, dword [p.v_value]
!mov ecx, dword [p.v_bit]
!btr eax, ecx
ProcedureReturn
EndProcedure
Procedure.q ClrBit64(value.q, bit.q)
CompilerIf #PB_Compiler_Processor=#PB_Processor_x64
!mov rax, qword [p.v_value]
!mov rcx, qword [p.v_bit]
!btr rax, rcx
ProcedureReturn
CompilerElse
ProcedureReturn ~(1 << bit) & value
CompilerEndIf
ProcedureReturn
EndProcedure
Procedure ToggleBit32(value, bit)
!xor eax, eax
!mov ecx, dword [p.v_bit]
!bts eax, ecx
!mov ecx, dword [p.v_value]
!xor eax, ecx
ProcedureReturn
EndProcedure
Procedure.q ToggleBit64(value.q, bit.q)
CompilerIf #PB_Compiler_Processor=#PB_Processor_x64
!xor rax, rax
!mov rcx, qword [p.v_bit]
!bts rax, rcx
!mov rcx, qword [p.v_value]
!xor rax, rcx
ProcedureReturn
CompilerElse
ProcedureReturn (1 << bit) ! value
CompilerEndIf
ProcedureReturn
EndProcedure
; ***************************************************************************************
CompilerIf #PB_Compiler_IsMainFile
x.q
;-Test
Debug "shr8(x,2)"
x = $80
Debug RSet(Bin(x),8,"0")
x = shr8(x,2)
Debug RSet(Bin(x),8,"0")
Debug "shl8(x,2)"
x = $02
Debug RSet(Bin(x),8,"0")
x = shl8(x,2)
Debug RSet(Bin(x),8,"0")
Debug "bswap16"
x = $0102
Debug RSet(Hex(x),8,"0")
x = bswap16(x)
Debug RSet(Hex(x),8,"0")
Debug "bswap32"
x = $01020304
Debug RSet(Hex(x),8,"0")
x = bswap32(x)
Debug RSet(Hex(x),8,"0")
Debug "bswap64"
x = $0102030405060708
Debug RSet(Hex(x),16,"0")
x = bswap64(x)
Debug RSet(Hex(x),16,"0")
Debug "shl32(x,4)"
x = %1001
Debug RSet(Bin(x), 32, "0")
x = shl32(x, 4)
Debug RSet(Bin(x), 32, "0")
Debug "shr32(x,4)"
x = %1001
Debug RSet(Bin(x), 32, "0")
x = shr32(x, 4)
Debug RSet(Bin(x), 32, "0")
Debug "rol32(x,29)"
x = %1001
Debug RSet(Bin(x), 32, "0")
x = rol32(x, 29)
Debug RSet(Bin(x), 32, "0")
Debug "ror32(x,5)"
x = %1001
Debug RSet(Bin(x), 32, "0")
x = ror32(x, 5)
Debug RSet(Bin(x), 32, "0")
Debug "shl64(x,4)"
x = %1001
Debug RSet(Bin(x), 64, "0")
x = shl64(x, 4)
Debug RSet(Bin(x), 64, "0")
Debug "shr64(x,4)"
x = %1001
Debug RSet(Bin(x), 64, "0")
x = shr64(x, 4)
Debug RSet(Bin(x), 64, "0")
Debug "rol64(x,29)"
x = %1001
Debug RSet(Bin(x), 64, "0")
x = rol64(x, 29)
Debug RSet(Bin(x), 64, "0")
Debug "ror64(x,5)"
x = %1001
Debug RSet(Bin(x), 64, "0")
x = ror64(x, 5)
Debug RSet(Bin(x), 64, "0")
Debug "shl64(-33,4)"
x = -33
Debug RSet(Bin(x), 64, "0")
x = shl64(x, 4)
Debug RSet(Bin(x), 64, "0")
Debug "shr64(-33,4)"
x = -33
Debug RSet(Bin(x), 64, "0")
x = shr64(x, 4)
Debug RSet(Bin(x), 64, "0")
Debug "rol64(-33,50)"
x = -33
Debug RSet(Bin(x), 64, "0")
x = rol64(x, 50)
Debug RSet(Bin(x), 64, "0")
Debug "ror64(-33,8)"
x = -33
Debug RSet(Bin(x), 64, "0")
x = ror64(x, 8)
Debug RSet(Bin(x), 64, "0")
Debug "SetBit"
a.q = 0
b.q = 15
c1.q = SetBit32(a, b)
c2.q = SetBit64(a, b)
c1.q = GetBit32(c1,b)
c2.q = GetBit64(c2,b)
Debug c1
Debug c2
Debug "ClrBit"
c1 = ClrBit32(a, b)
c2 = ClrBit64(a, b)
c1 = GetBit32(c1,b)
c2 = GetBit64(c2,b)
Debug c1
Debug c2
Debug "ToggleBit"
c1 = 1 << 63
c2 = ToggleBit64(c1, 1)
Debug Hex(c2)
CompilerEndIf