184c3e9923108122045d689f1d2412359ad5208ebDuane Sand/* 284c3e9923108122045d689f1d2412359ad5208ebDuane Sand * Copyright (C) 2010 The Android Open Source Project 384c3e9923108122045d689f1d2412359ad5208ebDuane Sand * 484c3e9923108122045d689f1d2412359ad5208ebDuane Sand * Licensed under the Apache License, Version 2.0 (the "License"); 584c3e9923108122045d689f1d2412359ad5208ebDuane Sand * you may not use this file except in compliance with the License. 684c3e9923108122045d689f1d2412359ad5208ebDuane Sand * You may obtain a copy of the License at 784c3e9923108122045d689f1d2412359ad5208ebDuane Sand * 884c3e9923108122045d689f1d2412359ad5208ebDuane Sand * http://www.apache.org/licenses/LICENSE-2.0 984c3e9923108122045d689f1d2412359ad5208ebDuane Sand * 1084c3e9923108122045d689f1d2412359ad5208ebDuane Sand * Unless required by applicable law or agreed to in writing, software 1184c3e9923108122045d689f1d2412359ad5208ebDuane Sand * distributed under the License is distributed on an "AS IS" BASIS, 1284c3e9923108122045d689f1d2412359ad5208ebDuane Sand * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1384c3e9923108122045d689f1d2412359ad5208ebDuane Sand * See the License for the specific language governing permissions and 1484c3e9923108122045d689f1d2412359ad5208ebDuane Sand * limitations under the License. 1584c3e9923108122045d689f1d2412359ad5208ebDuane Sand */ 1684c3e9923108122045d689f1d2412359ad5208ebDuane Sand 1784c3e9923108122045d689f1d2412359ad5208ebDuane Sand#ifndef ANDROID_CUTILS_ATOMIC_MIPS64_H 1884c3e9923108122045d689f1d2412359ad5208ebDuane Sand#define ANDROID_CUTILS_ATOMIC_MIPS64_H 1984c3e9923108122045d689f1d2412359ad5208ebDuane Sand 2084c3e9923108122045d689f1d2412359ad5208ebDuane Sand#include <stdint.h> 2184c3e9923108122045d689f1d2412359ad5208ebDuane Sand 2284c3e9923108122045d689f1d2412359ad5208ebDuane Sand#ifndef ANDROID_ATOMIC_INLINE 2384c3e9923108122045d689f1d2412359ad5208ebDuane Sand#define ANDROID_ATOMIC_INLINE inline __attribute__((always_inline)) 2484c3e9923108122045d689f1d2412359ad5208ebDuane Sand#endif 2584c3e9923108122045d689f1d2412359ad5208ebDuane Sand 2684c3e9923108122045d689f1d2412359ad5208ebDuane Sandextern ANDROID_ATOMIC_INLINE void android_compiler_barrier(void) 2784c3e9923108122045d689f1d2412359ad5208ebDuane Sand{ 2884c3e9923108122045d689f1d2412359ad5208ebDuane Sand __asm__ __volatile__ ("" : : : "memory"); 2984c3e9923108122045d689f1d2412359ad5208ebDuane Sand} 3084c3e9923108122045d689f1d2412359ad5208ebDuane Sand 3184c3e9923108122045d689f1d2412359ad5208ebDuane Sandextern ANDROID_ATOMIC_INLINE void android_memory_barrier(void) 3284c3e9923108122045d689f1d2412359ad5208ebDuane Sand{ 3384c3e9923108122045d689f1d2412359ad5208ebDuane Sand __asm__ __volatile__ ("sync" : : : "memory"); 3484c3e9923108122045d689f1d2412359ad5208ebDuane Sand} 3584c3e9923108122045d689f1d2412359ad5208ebDuane Sand 3684c3e9923108122045d689f1d2412359ad5208ebDuane Sandextern ANDROID_ATOMIC_INLINE 3784c3e9923108122045d689f1d2412359ad5208ebDuane Sandint32_t android_atomic_acquire_load(volatile const int32_t *ptr) 3884c3e9923108122045d689f1d2412359ad5208ebDuane Sand{ 3984c3e9923108122045d689f1d2412359ad5208ebDuane Sand int32_t value = *ptr; 4084c3e9923108122045d689f1d2412359ad5208ebDuane Sand android_memory_barrier(); 4184c3e9923108122045d689f1d2412359ad5208ebDuane Sand return value; 4284c3e9923108122045d689f1d2412359ad5208ebDuane Sand} 4384c3e9923108122045d689f1d2412359ad5208ebDuane Sand 4484c3e9923108122045d689f1d2412359ad5208ebDuane Sandextern ANDROID_ATOMIC_INLINE 4584c3e9923108122045d689f1d2412359ad5208ebDuane Sandint32_t android_atomic_release_load(volatile const int32_t *ptr) 4684c3e9923108122045d689f1d2412359ad5208ebDuane Sand{ 4784c3e9923108122045d689f1d2412359ad5208ebDuane Sand android_memory_barrier(); 4884c3e9923108122045d689f1d2412359ad5208ebDuane Sand return *ptr; 4984c3e9923108122045d689f1d2412359ad5208ebDuane Sand} 5084c3e9923108122045d689f1d2412359ad5208ebDuane Sand 5184c3e9923108122045d689f1d2412359ad5208ebDuane Sandextern ANDROID_ATOMIC_INLINE 5284c3e9923108122045d689f1d2412359ad5208ebDuane Sandvoid android_atomic_acquire_store(int32_t value, volatile int32_t *ptr) 5384c3e9923108122045d689f1d2412359ad5208ebDuane Sand{ 5484c3e9923108122045d689f1d2412359ad5208ebDuane Sand *ptr = value; 5584c3e9923108122045d689f1d2412359ad5208ebDuane Sand android_memory_barrier(); 5684c3e9923108122045d689f1d2412359ad5208ebDuane Sand} 5784c3e9923108122045d689f1d2412359ad5208ebDuane Sand 5884c3e9923108122045d689f1d2412359ad5208ebDuane Sandextern ANDROID_ATOMIC_INLINE 5984c3e9923108122045d689f1d2412359ad5208ebDuane Sandvoid android_atomic_release_store(int32_t value, volatile int32_t *ptr) 6084c3e9923108122045d689f1d2412359ad5208ebDuane Sand{ 6184c3e9923108122045d689f1d2412359ad5208ebDuane Sand android_memory_barrier(); 6284c3e9923108122045d689f1d2412359ad5208ebDuane Sand *ptr = value; 6384c3e9923108122045d689f1d2412359ad5208ebDuane Sand} 6484c3e9923108122045d689f1d2412359ad5208ebDuane Sand 6584c3e9923108122045d689f1d2412359ad5208ebDuane Sandextern ANDROID_ATOMIC_INLINE 6684c3e9923108122045d689f1d2412359ad5208ebDuane Sandint android_atomic_cas(int32_t old_value, int32_t new_value, volatile int32_t *ptr) 6784c3e9923108122045d689f1d2412359ad5208ebDuane Sand{ 6884c3e9923108122045d689f1d2412359ad5208ebDuane Sand int32_t prev, status; 6984c3e9923108122045d689f1d2412359ad5208ebDuane Sand do { 7084c3e9923108122045d689f1d2412359ad5208ebDuane Sand __asm__ __volatile__ ( 7184c3e9923108122045d689f1d2412359ad5208ebDuane Sand " ll %[prev], (%[ptr])\n" 7284c3e9923108122045d689f1d2412359ad5208ebDuane Sand " li %[status], 1\n" 7384c3e9923108122045d689f1d2412359ad5208ebDuane Sand " bne %[prev], %[old], 9f\n" 7484c3e9923108122045d689f1d2412359ad5208ebDuane Sand " move %[status], %[new_value]\n" 7584c3e9923108122045d689f1d2412359ad5208ebDuane Sand " sc %[status], (%[ptr])\n" 7684c3e9923108122045d689f1d2412359ad5208ebDuane Sand "9:\n" 7784c3e9923108122045d689f1d2412359ad5208ebDuane Sand : [prev] "=&r" (prev), [status] "=&r" (status) 7884c3e9923108122045d689f1d2412359ad5208ebDuane Sand : [ptr] "r" (ptr), [old] "r" (old_value), [new_value] "r" (new_value) 7984c3e9923108122045d689f1d2412359ad5208ebDuane Sand ); 8084c3e9923108122045d689f1d2412359ad5208ebDuane Sand } while (__builtin_expect(status == 0, 0)); 8184c3e9923108122045d689f1d2412359ad5208ebDuane Sand return prev != old_value; 8284c3e9923108122045d689f1d2412359ad5208ebDuane Sand} 8384c3e9923108122045d689f1d2412359ad5208ebDuane Sand 8484c3e9923108122045d689f1d2412359ad5208ebDuane Sandextern ANDROID_ATOMIC_INLINE 8584c3e9923108122045d689f1d2412359ad5208ebDuane Sandint android_atomic_acquire_cas(int32_t old_value, 8684c3e9923108122045d689f1d2412359ad5208ebDuane Sand int32_t new_value, 8784c3e9923108122045d689f1d2412359ad5208ebDuane Sand volatile int32_t *ptr) 8884c3e9923108122045d689f1d2412359ad5208ebDuane Sand{ 8984c3e9923108122045d689f1d2412359ad5208ebDuane Sand int status = android_atomic_cas(old_value, new_value, ptr); 9084c3e9923108122045d689f1d2412359ad5208ebDuane Sand android_memory_barrier(); 9184c3e9923108122045d689f1d2412359ad5208ebDuane Sand return status; 9284c3e9923108122045d689f1d2412359ad5208ebDuane Sand} 9384c3e9923108122045d689f1d2412359ad5208ebDuane Sand 9484c3e9923108122045d689f1d2412359ad5208ebDuane Sandextern ANDROID_ATOMIC_INLINE 9584c3e9923108122045d689f1d2412359ad5208ebDuane Sandint android_atomic_release_cas(int32_t old_value, 9684c3e9923108122045d689f1d2412359ad5208ebDuane Sand int32_t new_value, 9784c3e9923108122045d689f1d2412359ad5208ebDuane Sand volatile int32_t *ptr) 9884c3e9923108122045d689f1d2412359ad5208ebDuane Sand{ 9984c3e9923108122045d689f1d2412359ad5208ebDuane Sand android_memory_barrier(); 10084c3e9923108122045d689f1d2412359ad5208ebDuane Sand return android_atomic_cas(old_value, new_value, ptr); 10184c3e9923108122045d689f1d2412359ad5208ebDuane Sand} 10284c3e9923108122045d689f1d2412359ad5208ebDuane Sand 10384c3e9923108122045d689f1d2412359ad5208ebDuane Sandextern ANDROID_ATOMIC_INLINE 10484c3e9923108122045d689f1d2412359ad5208ebDuane Sandint32_t android_atomic_add(int32_t increment, volatile int32_t *ptr) 10584c3e9923108122045d689f1d2412359ad5208ebDuane Sand{ 10684c3e9923108122045d689f1d2412359ad5208ebDuane Sand int32_t prev, status; 10784c3e9923108122045d689f1d2412359ad5208ebDuane Sand android_memory_barrier(); 10884c3e9923108122045d689f1d2412359ad5208ebDuane Sand do { 10984c3e9923108122045d689f1d2412359ad5208ebDuane Sand __asm__ __volatile__ ( 11084c3e9923108122045d689f1d2412359ad5208ebDuane Sand " ll %[prev], (%[ptr])\n" 11184c3e9923108122045d689f1d2412359ad5208ebDuane Sand " addu %[status], %[prev], %[inc]\n" 11284c3e9923108122045d689f1d2412359ad5208ebDuane Sand " sc %[status], (%[ptr])\n" 11384c3e9923108122045d689f1d2412359ad5208ebDuane Sand : [status] "=&r" (status), [prev] "=&r" (prev) 11484c3e9923108122045d689f1d2412359ad5208ebDuane Sand : [ptr] "r" (ptr), [inc] "Ir" (increment) 11584c3e9923108122045d689f1d2412359ad5208ebDuane Sand ); 11684c3e9923108122045d689f1d2412359ad5208ebDuane Sand } while (__builtin_expect(status == 0, 0)); 11784c3e9923108122045d689f1d2412359ad5208ebDuane Sand return prev; 11884c3e9923108122045d689f1d2412359ad5208ebDuane Sand} 11984c3e9923108122045d689f1d2412359ad5208ebDuane Sand 12084c3e9923108122045d689f1d2412359ad5208ebDuane Sandextern ANDROID_ATOMIC_INLINE int32_t 12184c3e9923108122045d689f1d2412359ad5208ebDuane Sandandroid_atomic_inc(volatile int32_t *addr) 12284c3e9923108122045d689f1d2412359ad5208ebDuane Sand{ 12384c3e9923108122045d689f1d2412359ad5208ebDuane Sand return android_atomic_add(1, addr); 12484c3e9923108122045d689f1d2412359ad5208ebDuane Sand} 12584c3e9923108122045d689f1d2412359ad5208ebDuane Sand 12684c3e9923108122045d689f1d2412359ad5208ebDuane Sandextern ANDROID_ATOMIC_INLINE int32_t 12784c3e9923108122045d689f1d2412359ad5208ebDuane Sandandroid_atomic_dec(volatile int32_t *addr) 12884c3e9923108122045d689f1d2412359ad5208ebDuane Sand{ 12984c3e9923108122045d689f1d2412359ad5208ebDuane Sand return android_atomic_add(-1, addr); 13084c3e9923108122045d689f1d2412359ad5208ebDuane Sand} 13184c3e9923108122045d689f1d2412359ad5208ebDuane Sand 13284c3e9923108122045d689f1d2412359ad5208ebDuane Sandextern ANDROID_ATOMIC_INLINE int32_t 13384c3e9923108122045d689f1d2412359ad5208ebDuane Sandandroid_atomic_and(int32_t value, volatile int32_t *ptr) 13484c3e9923108122045d689f1d2412359ad5208ebDuane Sand{ 13584c3e9923108122045d689f1d2412359ad5208ebDuane Sand int32_t prev, status; 13684c3e9923108122045d689f1d2412359ad5208ebDuane Sand android_memory_barrier(); 13784c3e9923108122045d689f1d2412359ad5208ebDuane Sand do { 13884c3e9923108122045d689f1d2412359ad5208ebDuane Sand __asm__ __volatile__ ( 13984c3e9923108122045d689f1d2412359ad5208ebDuane Sand " ll %[prev], (%[ptr])\n" 14084c3e9923108122045d689f1d2412359ad5208ebDuane Sand " and %[status], %[prev], %[value]\n" 14184c3e9923108122045d689f1d2412359ad5208ebDuane Sand " sc %[status], (%[ptr])\n" 14284c3e9923108122045d689f1d2412359ad5208ebDuane Sand : [prev] "=&r" (prev), [status] "=&r" (status) 14384c3e9923108122045d689f1d2412359ad5208ebDuane Sand : [ptr] "r" (ptr), [value] "Ir" (value) 14484c3e9923108122045d689f1d2412359ad5208ebDuane Sand ); 14584c3e9923108122045d689f1d2412359ad5208ebDuane Sand } while (__builtin_expect(status == 0, 0)); 14684c3e9923108122045d689f1d2412359ad5208ebDuane Sand return prev; 14784c3e9923108122045d689f1d2412359ad5208ebDuane Sand} 14884c3e9923108122045d689f1d2412359ad5208ebDuane Sand 14984c3e9923108122045d689f1d2412359ad5208ebDuane Sandextern ANDROID_ATOMIC_INLINE int32_t 15084c3e9923108122045d689f1d2412359ad5208ebDuane Sandandroid_atomic_or(int32_t value, volatile int32_t *ptr) 15184c3e9923108122045d689f1d2412359ad5208ebDuane Sand{ 15284c3e9923108122045d689f1d2412359ad5208ebDuane Sand int32_t prev, status; 15384c3e9923108122045d689f1d2412359ad5208ebDuane Sand android_memory_barrier(); 15484c3e9923108122045d689f1d2412359ad5208ebDuane Sand do { 15584c3e9923108122045d689f1d2412359ad5208ebDuane Sand __asm__ __volatile__ ( 15684c3e9923108122045d689f1d2412359ad5208ebDuane Sand " ll %[prev], (%[ptr])\n" 15784c3e9923108122045d689f1d2412359ad5208ebDuane Sand " or %[status], %[prev], %[value]\n" 15884c3e9923108122045d689f1d2412359ad5208ebDuane Sand " sc %[status], (%[ptr])\n" 15984c3e9923108122045d689f1d2412359ad5208ebDuane Sand : [prev] "=&r" (prev), [status] "=&r" (status) 16084c3e9923108122045d689f1d2412359ad5208ebDuane Sand : [ptr] "r" (ptr), [value] "Ir" (value) 16184c3e9923108122045d689f1d2412359ad5208ebDuane Sand ); 16284c3e9923108122045d689f1d2412359ad5208ebDuane Sand } while (__builtin_expect(status == 0, 0)); 16384c3e9923108122045d689f1d2412359ad5208ebDuane Sand return prev; 16484c3e9923108122045d689f1d2412359ad5208ebDuane Sand} 16584c3e9923108122045d689f1d2412359ad5208ebDuane Sand 16684c3e9923108122045d689f1d2412359ad5208ebDuane Sand#endif /* ANDROID_CUTILS_ATOMIC_MIPS_H */ 167