Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf09c55d2f | ||
|
|
295ff03c93 | ||
|
|
64117db274 |
@@ -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
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
; ===== INTRODUCTION =====
|
||||||
|
; This is supposed to provide some standard library functionality for stock symphony.
|
||||||
|
; In particular its supposed to work with an unmodified ISA, that means some choices are not
|
||||||
|
; optimal (RA being stored in flags for example)
|
||||||
|
|
||||||
|
; ===== ABI =====
|
||||||
|
|
||||||
|
; ----- CALLING CONVENTION -----
|
||||||
|
; n.a. zr
|
||||||
|
; preserved: sp, r8 - r12
|
||||||
|
; scratch: flags, r1 - r7
|
||||||
|
; arguments: r1 - r7 (r1 = 1st argument, r6 = 6th arg/stack args, r7 = 7th arg/stack res)
|
||||||
|
; result: r1, r2 (r1 = low word, r2 = high word)
|
||||||
|
; return address: r13
|
||||||
|
|
||||||
|
; ----- STACK -----
|
||||||
|
; grows downwards from top of memory
|
||||||
|
; arguments are passed in reverse order with the stack so:
|
||||||
|
; lowest address = 1st stack arg
|
||||||
|
; highest address = last stack arg
|
||||||
|
|
||||||
|
; ----- HEAP -----
|
||||||
|
; i am not sure if there will ever be heap functionality, but to future proof:
|
||||||
|
; this library will use the label "heap_start" with the constant "heap_size"
|
||||||
|
; to determine properties of the heap
|
||||||
|
; you **have** to define those if you want this to compile
|
||||||
|
|
||||||
|
; ===== TYPES =====
|
||||||
|
|
||||||
|
pub include bit
|
||||||
Reference in New Issue
Block a user