BSwap64/32/16

Share your advanced PureBasic knowledge/code with the community.
User avatar
mk-soft
Always Here
Always Here
Posts: 6202
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: BSwap64/32/16

Post by mk-soft »

There are not builtin ...

Code: Select all

Procedure.a bswap8(value.a)
  CompilerIf #PB_Compiler_Backend = #PB_Backend_C
    !return (v_value << 4 | v_value >> 4);
  CompilerElse
    !mov al, byte [p.v_value]  
    !rol al, 4
    ProcedureReturn
  CompilerEndIf  
EndProcedure

a = $9E
b = bswap8(a)
Debug Hex(b, #PB_Byte)
C-Code declare

Code: Select all

// Procedure.a bswap8(value.a)
static unsigned char f_bswap8(unsigned char v_value) {
...
}

But actually there is something like bswap8. It should be NippleSwap.
Where do you need something like that :?:
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
Lunasole
Addict
Addict
Posts: 1091
Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:

Re: BSwap64/32/16

Post by Lunasole »

mk-soft wrote: Sun Apr 16, 2023 6:03 pm But actually there is something like bswap8. It should be NibbleSwap.
Why it doesn't works like this?
I also tried that when doing others bswaps, wondered why failed and wonder if same works in C (not tried too).

Code: Select all

Procedure.b t(v_value.b)
	ProcedureReturn (v_value >> 4 | v_value << 4)
EndProcedure

Define e.b = %10001000
Debug Bin(e, #PB_Byte)
Debug Bin(t(e), #PB_Byte)
Debug Bin(t(t(e)), #PB_Byte)
; =
; 10001000
; 11111000
; 11111111
Where do you need something like that :?:
Ha, there are some ideas even for this extremely funny, but probably will not use soon.
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
User avatar
idle
Always Here
Always Here
Posts: 5835
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: BSwap64/32/16

Post by idle »

It fails as input is signed.

Byte swap is a stage in swar parallel bitreverse see here
https://graphics.stanford.edu/~seander/bithacks.html
User avatar
Lunasole
Addict
Addict
Posts: 1091
Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:

Re: BSwap64/32/16

Post by Lunasole »

idle wrote: Sun Apr 16, 2023 9:08 pm It fails as input is signed.

Byte swap is a stage in swar parallel bitreverse see here
https://graphics.stanford.edu/~seander/bithacks.html
I though he may explain his code, but well :|
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
User avatar
mk-soft
Always Here
Always Here
Posts: 6202
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: BSwap64/32/16

Post by mk-soft »

The type byte is signed (-128 .. 127)
You must take type ascii (0 ..255)

However, I prefer the type unsigned char for C-backend as in my example, because PB internally converts everything back to quad before shifting bits.

Code: Select all

Procedure.a t(v_value.a)
	ProcedureReturn (v_value >> 4 | v_value << 4)
EndProcedure

Define e.b = %10001001
Debug Bin(e, #PB_Byte)
Debug Bin(t(e), #PB_Byte)
Debug Bin(t(t(e)), #PB_Byte)
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
Lunasole
Addict
Addict
Posts: 1091
Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:

Re: BSwap64/32/16

Post by Lunasole »

mk-soft wrote: Sun Apr 16, 2023 10:07 pm However, I prefer the type unsigned char for C-backend as in my example, because PB internally converts everything back to quad before shifting bits.
No any theoretically possible fix for that with 1-byte? Like this I tried with masking:

Code: Select all

Procedure.b t(v_value.b)
	ProcedureReturn %00001111&v_value<<4|v_value&%11110000>>4
EndProcedure
It's far of course to dig to anything behind that, unless I really need it, but curious to ask if you know that all already so good.
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
User avatar
idle
Always Here
Always Here
Posts: 5835
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: BSwap64/32/16

Post by idle »

Do you understand it looking at the assembly?

Code: Select all

Procedure t(v_value.b)
  ProcedureReturn ((v_value & $FF) >> 4 | (v_value & $FF) << 4) 
  ;MOVSX  r15,byte [rsp+PS0+0]       
  ;And    r15,255
  ;SAR    r15,4
  ;MOVSX  r14,byte [rsp+PS0+0]
  ;And    r14,255
  ;SAL    r14,4
  ;Or     r15,r14
  ;MOV    rax,r15
  ;ProcedureReturn
   
EndProcedure

a.b = $F1
a = t(a)
Debug Hex(a,#PB_Byte) 

This thread should be moved to general discussions I think.
User avatar
Lunasole
Addict
Addict
Posts: 1091
Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:

Re: BSwap64/32/16

Post by Lunasole »

idle wrote: Mon Apr 17, 2023 4:38 am Do you understand it looking at the assembly?
Yes, at least see key ops, even though I don't want to go to ASM now and didn't looked at that <<4 also. Just curious as I said, asked without doing anything myself until really will need that, as soon at there are talks around that.
This thread should be moved to general discussions I think.
For me as it works and produces correct and predictable results (16-32-64), it's still good and usable variant, maybe even more goes to "tricks".
The other about 8 more a discussion.
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
User avatar
mk-soft
Always Here
Always Here
Posts: 6202
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: BSwap64/32/16

Post by mk-soft »

You're making it too complicated for yourself.

In Purebasic, all comparison, shift and math of byte, word, longs, integers, quads are processed signed.
With the introduction of Unicode, the vartype var.a (ascii) was added as an unsigned byte and the vartype var.u (unicode) as an unsigned word.
I hope you know how negative integers are represented and what happens when bits are shifted to avoid losing the sign.
Only with the use of the correct vartype it also works optimised.
There are already many examples from us ...
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
Lunasole
Addict
Addict
Posts: 1091
Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:

Re: BSwap64/32/16

Post by Lunasole »

mk-soft wrote: Mon Apr 17, 2023 1:12 pm You're making it too complicated for yourself.

In Purebasic, all comparison, shift and math of byte, word, longs, integers, quads are processed signed.
With the introduction of Unicode, the vartype var.a (ascii) was added as an unsigned byte and the vartype var.u (unicode) as an unsigned word.
I hope you know how negative integers are represented and what happens when bits are shifted to avoid losing the sign.
Only with the use of the correct vartype it also works optimised.
There are already many examples from us ...
Well I'd send you a silent "like" for your replies if this forum had them, but it doesn't so there is textural.

> I hope you know how negative integers are represented and what happens when bits are shifted to avoid losing the sign.
Remembering that single bit.
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
User avatar
RichAlgeni
Addict
Addict
Posts: 935
Joined: Wed Sep 22, 2010 1:50 am
Location: Bradenton, FL

Re: BSwap64/32/16

Post by RichAlgeni »

infratec wrote: Thu Apr 13, 2023 9:27 am The main problem is, that PB does not have unsigned long and quad.
I would so love unsigned integers.
User avatar
idle
Always Here
Always Here
Posts: 5835
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: BSwap64/32/16

Post by idle »

RichAlgeni wrote: Tue Apr 18, 2023 4:58 pm
infratec wrote: Thu Apr 13, 2023 9:27 am The main problem is, that PB does not have unsigned long and quad.
I would so love unsigned integers.
Yes and add type alias as int32 or uint32 it's clear for everyone with no ambiguity.

c backend abuse variable a is treated as unsigned!

Code: Select all

CompilerIf #PB_Compiler_Backend = #PB_Backend_C 
!unsigned long long v_a =0;  

Macro BSWAP64(v) 
  v = ((v >> 8) & $00FF00FF00FF00FF) | ((v & $00FF00FF00FF00FF) << 8) ;flip adjacent bytes 
  v = ((v >> 16) & $0000ffff0000ffff) | ((v & $0000ffff0000ffff) << 16) ; flip words 
  v = (v >> 32) | (v << 32) ;flip dwords 
EndMacro 

Macro BSWAP32(v) 
  v = ((v >> 8) & $00FF00FF) | ((v & $00FF00FF) << 8) ;flip adjacent bytes 
  v = (v >> 16) | v << 16                             ;flip words 
  v & $FFFFFFFF
EndMacro 

Macro BSWAP16(v) 
  v = ((v >> 8) & $00FF) | ((v & $00FF) << 8) ;flip adjacent bytes 
  v & $FFFF   
EndMacro   


Global a.q   ;a is unsigned 
Global b.q   ; b is signed 

a = $FEDCBA9876543210
b = a 
bswap64(a)
bswap64(b) 
Debug Hex(a) 
Debug Hex(b) 
a = $FEDCBA98 
bswap32(a) 
Debug Hex(a) 
a = $FEDC 
bswap16(a)
Debug Hex(a)

CompilerEndIf  

User avatar
Lunasole
Addict
Addict
Posts: 1091
Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:

Re: BSwap64/32/16

Post by Lunasole »

RichAlgeni wrote: Tue Apr 18, 2023 4:58 pm
infratec wrote: Thu Apr 13, 2023 9:27 am The main problem is, that PB does not have unsigned long and quad.
I would so love unsigned integers.
Nice.
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
User avatar
Lunasole
Addict
Addict
Posts: 1091
Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:

Re: BSwap64/32/16

Post by Lunasole »

idle wrote: Tue Apr 18, 2023 9:28 pm
RichAlgeni wrote: Tue Apr 18, 2023 4:58 pm
infratec wrote: Thu Apr 13, 2023 9:27 am The main problem is, that PB does not have unsigned long and quad.
I would so love unsigned integers.
Yes and add type alias as int32 or uint32 it's clear for everyone with no ambiguity.

c backend abuse variable a is treated as unsigned!

[/code]
Too.
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
Post Reply