platform_system_core/libcutils/atomic-android-armv6.S
2009-03-03 19:32:55 -08:00

169 lines
3.7 KiB
ArmAsm

/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.text
.align
.global android_atomic_write
.global android_atomic_inc
.global android_atomic_dec
.global android_atomic_add
.global android_atomic_and
.global android_atomic_or
.global android_atomic_swap
.global android_atomic_cmpxchg
/* FIXME: On SMP systems memory barriers may be needed */
#warning "this file is not safe with SMP systems"
/*
* ----------------------------------------------------------------------------
* android_atomic_write
* input: r0=value, r1=address
* output: void
*/
android_atomic_write:
1: ldrex r12, [r1]
strex r12, r0, [r1]
cmp r12, #0
bne 1b
bx lr
/*
* ----------------------------------------------------------------------------
* android_atomic_inc
* input: r0 = address
* output: r0 = old value
*/
android_atomic_inc:
mov r12, r0
1: ldrex r0, [r12]
add r2, r0, #1
strex r1, r2, [r12]
cmp r1, #0
bxeq lr
b 1b
/*
* ----------------------------------------------------------------------------
* android_atomic_dec
* input: r0=address
* output: r0 = old value
*/
android_atomic_dec:
mov r12, r0
1: ldrex r0, [r12]
sub r2, r0, #1
strex r1, r2, [r12]
cmp r1, #0
bxeq lr
b 1b
/*
* ----------------------------------------------------------------------------
* android_atomic_add
* input: r0=value, r1=address
* output: r0 = old value
*/
android_atomic_add:
mov r12, r0
1: ldrex r0, [r1]
add r2, r0, r12
strex r3, r2, [r1]
cmp r3, #0
bxeq lr
b 1b
/*
* ----------------------------------------------------------------------------
* android_atomic_and
* input: r0=value, r1=address
* output: r0 = old value
*/
android_atomic_and:
mov r12, r0
1: ldrex r0, [r1]
and r2, r0, r12
strex r3, r2, [r1]
cmp r3, #0
bxeq lr
b 1b
/*
* ----------------------------------------------------------------------------
* android_atomic_or
* input: r0=value, r1=address
* output: r0 = old value
*/
android_atomic_or:
mov r12, r0
1: ldrex r0, [r1]
orr r2, r0, r12
strex r3, r2, [r1]
cmp r3, #0
bxeq lr
b 1b
/*
* ----------------------------------------------------------------------------
* android_atomic_swap
* input: r0=value, r1=address
* output: r0 = old value
*/
android_atomic_swap:
swp r0, r0, [r1]
bx lr
/*
* ----------------------------------------------------------------------------
* android_atomic_cmpxchg
* input: r0=oldvalue, r1=newvalue, r2=address
* output: r0 = 0 (xchg done) or non-zero (xchg not done)
*/
android_atomic_cmpxchg:
mov r12, r1
ldrex r3, [r2]
eors r0, r0, r3
strexeq r0, r12, [r2]
bx lr
/*
* ----------------------------------------------------------------------------
* android_atomic_cmpxchg_64
* input: r0-r1=oldvalue, r2-r3=newvalue, arg4 (on stack)=address
* output: r0 = 0 (xchg done) or non-zero (xchg not done)
*/
/* TODO: NEED IMPLEMENTATION FOR THIS ARCHITECTURE */