forked from TCShenanigans/symphony_stdlib
add basic bit operations
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
mov r1, 0
|
||||
qcall clz
|
||||
add zr, zr, zr
|
||||
mov r1, 0x1
|
||||
qcall clz
|
||||
add zr, zr, zr
|
||||
add r1, zr, 0xAAAA
|
||||
lsl r1, r1, 6
|
||||
qcall popc
|
||||
|
||||
pub rotate_left:
|
||||
; (r1 >> r2) | (r1 << (32 - r2))
|
||||
sub r3, zr, r2
|
||||
add r3, r3, 32
|
||||
lsr r3, r1, r3
|
||||
lsl r1, r1, r2
|
||||
or r1, r1, r3
|
||||
|
||||
jmp r13
|
||||
|
||||
pub rotate_right:
|
||||
; (r1 << r2) | (r1 >> (32 - r2))
|
||||
sub r3, zr, r2
|
||||
add r3, r3, 32
|
||||
lsl r3, r1, r3
|
||||
lsr r1, r1, r2
|
||||
or r1, r1, r3
|
||||
|
||||
jmp r13
|
||||
|
||||
pub clz:
|
||||
; special case
|
||||
mov r4, 0
|
||||
; since we start the loop by shifting r2 load twice the value we need
|
||||
mov r2, 32
|
||||
mov r3, r1
|
||||
; divide and conquer algorithm
|
||||
clz_loop:
|
||||
; next finer step
|
||||
lsr r2, r2, 1
|
||||
; abort if there is no finer step
|
||||
cmp r2, 0
|
||||
je clz_end
|
||||
; see if there are still some 1 bits left with this additional shift
|
||||
lsr r3, r3, r2
|
||||
add r4, r4, r2
|
||||
cmp r3, 0
|
||||
jne clz_loop
|
||||
; undo shift if it resulted in zero
|
||||
sub r4, r4, r2
|
||||
lsr r3, r1, r4
|
||||
jmp clz_loop
|
||||
clz_end:
|
||||
; we calculated the position of the last 1 from the least significant side
|
||||
; inverse is what we want (position of last 0 from most significant side)
|
||||
mov r1, 31
|
||||
sub r1, r1, r4
|
||||
jmp r13
|
||||
|
||||
pub popc:
|
||||
mov r2, 0x0101 ; load mask of 0x01010101
|
||||
lsl r2, r2, 16
|
||||
or r2, r2, 0x0101
|
||||
|
||||
mov r3, 8 ; bits in byte
|
||||
mov r4, 0 ; pop count of each byte
|
||||
popc_loop:
|
||||
and r5, r1, r2 ; extract least significant bit of byte
|
||||
add r4, r4, r5
|
||||
|
||||
lsr r1, r1, 1 ; cycle through bits
|
||||
sub r3, r3, 1
|
||||
cmp r3, 0
|
||||
jg popc_loop
|
||||
|
||||
; sum up bytes
|
||||
lsr r2, r4, 8
|
||||
add r4, r4, r2
|
||||
lsr r2, r4, 16
|
||||
add r4, r4, r2
|
||||
and r1, r4, 0xFF ; mask out end result in lowest byte
|
||||
jmp r13
|
||||
Reference in New Issue
Block a user