As freak said, It's by design not a bug. It's the PB arithmtic shift. That's often a problem!
You have to mask out the the upper Bits after the shift.
But here is a full solution for the BSWAP
Code: Select all
Procedure.q BSWAP64(value.q)
CompilerIf #PB_Compiler_Backend = #PB_Backend_Asm
CompilerIf #PB_Compiler_32Bit
!lea ecx, [p.v_value] ; load effective address of value (:= @value)
!mov edx, dword [ecx]
!mov eax, dword [ecx +4]
!bswap edx
!bswap eax
ProcedureReturn ; 64Bit Return use EAX and EDX Register
CompilerElse
!mov rax, qword [p.v_value]
!bswap rax
ProcedureReturn
CompilerEndIf
CompilerElse ; C-Backend
!return __builtin_bswap64(v_value);
CompilerEndIf
EndProcedure
Structure pSwap ; Pointer Structure for swapping
a.a[0] ; unsigned Byte-Value
u.u[0] ; unsigned WORD-Value
EndStructure
Procedure.q BSWAP64_PB(value.q)
Protected *Swap.pSwap
*Swap = @value
Swap *Swap\a[0], *Swap\a[7]
Swap *Swap\a[1], *Swap\a[6]
Swap *Swap\a[2], *Swap\a[5]
Swap *Swap\a[3], *Swap\a[4]
ProcedureReturn value
EndProcedure
Test = $8877665544332211
Debug Hex(Test, #PB_Quad)
Debug Hex(BSWAP64(Test), #PB_Quad)
Debug Hex(BSWAP64_PB(Test), #PB_Quad)
If you need more Bit-Functions! I solved nearly all that Bit-Stuff for industrial use:
https://github.com/Maagic7/PureBasicFra ... ule_Bit.pb
And here the Macro verison for an universal BSWAP. But there is a problem in C-Backend, because C-Backend needs all
variables in LoCase.
Code: Select all
;{ TODO: Solve the LoCase var problem in C-Backend
;}
; ===========================================================================
CompilerIf #PB_Compiler_Backend = #PB_Backend_C
; there is a problem in C-Backend. In C-Backend we have to
; call BSwapVar always with variable name in lower case
; if we define L.l and call BSwapVar(L) we get an error
; if we call BSwapVar(l) it works!
; it looks like the compiler LoCase all variables but in a Macro not!
CompilerWarning "Use of Macro BSwapVar(var) in C-Backend: Attention! Pass all variable names in LoCase : BSwapVar(myvar)! BSwapVar(MyVar) produce an Error!"
Macro BSwapVar(var)
CompilerSelect SizeOf(var)
CompilerCase 2
!v_#var = __builtin_bswap16(v_#var);
CompilerCase 4
!v_#var = __builtin_bswap32(v_#var);
CompilerCase 8
!v_#var = __builtin_bswap64(v_#var);
CompilerEndSelect
EndMacro
CompilerElse ; ASM-Backend
; We use the EnableASM command only to load and save the variable
; because if we pass directly the 'MOV EAX, var' we have to add v_ for standard code
; or p.v_ for variables in a procedure. With the PB buildin ASM it is done by PB.
Macro BSwapVar(var)
EnableASM
CompilerSelect SizeOf(var)
CompilerCase 2
!XOR EAX, EAX
MOV AX, var
!XCHG AL, AH
MOV var, AX
CompilerCase 4
MOV EAX, var
!BSWAP EAX
MOV var, EAX
CompilerCase 8 ; Quad
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
MOV RAX, var
!BSWAP RAX
MOV var, RAX
CompilerElse ; ASM x32
LEA ECX, var ; load effective address of var : ECX= @var
!MOV EDX, DWORD [ECX]
!MOV EAX, DWORD [ECX +4]
!BSWAP EDX
!BSWAP EAX
!MOV DWORD [ECX], EAX
!MOV DWORD [ECX +4], EDX
CompilerEndIf
CompilerEndSelect
DisableASM
EndMacro
CompilerEndIf