fxlibc/src/threads/atomic.S

89 lines
2.5 KiB
ArmAsm

.text
.global ___thread_atomic_start
.global ___thread_atomic_stop
.type ___thread_atomic_start, @function
.type ___thread_atomic_stop, @function
.align 2
// Save the current SR register and set the SR.BIT bit up (start atomic operations)
// @note: return the saved SR register (if has been saved), 0xffffffff otherwise.
___thread_atomic_start:
! Check if the calculator is currently
! into an atomic operation and update
! atomic counter.
mov.l atomic_counter, r1 ! r1 = atomic counter address
mov.l @r1, r2 ! r2 = atomic counter data
tst r2, r2 ! if atomic counter == 0...
add #1, r2 ! update atomic counter data
mov.l r2, @r1 ! update atomic counter.
bf.s atomic_start_exit ! ...if not, jump <atomic_start_exit>
mov #-1, r0 ! (db) return 0xffffffff
! Block interrupt if needed.
stc sr, r1 ! get SR register.
mov r1, r0 ! save current SR register.
mov.l bl_mask, r2 ! get SR.BL mask.
or r2, r1 ! set SR.BL = 1 and SR.IMASK = 0b1111.
ldc r1, sr ! update SR register.
! Save "old" SR register.
mov.l sr_save, r1 ! r1 = sr_save address
mov.l r0, @r1 ! save "old" SR register data.
atomic_start_exit:
rts ! exit.
nop ! (db) nop.
// Restore the saved SR register
// @note: return the restored SR register or -1 otherwise.
___thread_atomic_stop:
! Check if the calculator is currently
! into an atomic operation and update
! atomic counter if pssible.
mov.l atomic_counter, r1 ! r1 = atomic counter address
mov.l @r1, r0 ! r0 = atomic counter data
tst r0, r0 ! if atomic counter == 0...
bt atomic_end_error ! ...if yes, jump at <atomic_end_error>
cmp/eq #1, r0 ! if atomic counter == 1...
add #-1, r0 ! update atomic counter data
mov.l r0, @r1 ! update atomic counter
bf atomic_end_error ! ...if not, jump at <atomic_end_error>
! Restore saved SR register data.
mov.l sr_save, r1 ! get sr_save address
mov.l @r1, r0 ! r0 = "old" SR register data
ldc r0, sr ! restore SR register.
bra atomic_end_exit ! return the resotred SR register.
nop ! (db) nop
atomic_end_error:
mov #-1, r0 ! return 0xffffffff
atomic_end_exit:
rts ! exit.
nop ! (db) nop.
.align 4
bl_mask: .long 0x100000f0
sr_save: .long ___thread_atomic_sr_save
atomic_counter: .long ___thread_atomic_counter
##---
## Global part.
##---
.data
.global ___thread_atomic_sr_save
.global ___thread_atomic_counter
.type ___thread_atomic_sr_save, @object
.type ___thread_atomic_counter, @object
.align 4
___thread_atomic_sr_save: .long 0x00000000
___thread_atomic_counter: .long 0x00000000