/****************************************************************************
* libs/libc/machine/tricore/arch_atomic.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/atomic.h>
#include <IfxCpu_Intrinsics.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define ARCH_ATOMIC_STORE_4(func) \
\
void func(volatile void *ptr, int32_t value, int memorder) \
{ \
__swap((void *)ptr, value); \
}
#define ARCH_ATOMIC_LOAD_4(func) \
\
int32_t func(const volatile void *ptr, int memorder) \
{ \
return __ld32((void *)ptr); \
}
#define ARCH_ATOMIC_EXCHANGE_4(func) \
\
int32_t func(volatile void *ptr, int32_t value, int memorder) \
{ \
return __swap((void *)ptr, value); \
}
#define ARCH_ATOMIC_COMPARE_EXCHANGE_4(func) \
\
bool func(volatile void *ptr, volatile void *expect, int32_t desired, \
bool weak, int success, int failure) \
{ \
int32_t old; \
\
old = __cmpAndSwap(ptr, desired, *(int32_t *)expect); \
if (old == *(int32_t *)expect) \
{ \
return true; \
} \
\
*(int32_t *)expect = old; \
\
return false; \
}
#define ARCH_ATOMIC_FLAGS_TEST_AND_SET_4(func) \
\
int32_t func(volatile void *ptr, int memorder) \
{ \
return __swap((void *)ptr, 1); \
}
#define ARCH_ATOMIC_FETCH_ADD_4(func) \
\
int32_t func(volatile void *ptr, int32_t value, int memorder) \
\
{ \
int32_t old_val; \
\
do \
{ \
old_val = atomic_load_4(ptr, memorder); \
} \
while (__cmpAndSwap(ptr, old_val + value, old_val) != old_val); \
\
return old_val; \
}
#define ARCH_ATOMIC_FETCH_SUB_4(func) \
\
int32_t func(volatile void *ptr, int32_t value, int memorder) \
{ \
int32_t old_val; \
\
do \
{ \
old_val = atomic_load_4(ptr, memorder); \
} \
while (__cmpAndSwap(ptr, old_val - value, old_val) != old_val); \
\
return old_val; \
}
#define ARCH_ATOMIC_FETCH_AND_4(func) \
\
int32_t func(volatile void *ptr, int32_t value, int memorder) \
{ \
int32_t old_val; \
\
do \
{ \
old_val = atomic_load_4(ptr, memorder); \
} \
while (__cmpAndSwap(ptr, old_val & value, old_val) != old_val); \
\
return old_val; \
}
#define ARCH_ATOMIC_FETCH_OR_4(func) \
\
int32_t func(volatile void *ptr, int32_t value, int memorder) \
{ \
int32_t old_val; \
\
do \
{ \
old_val = atomic_load_4(ptr, memorder); \
} \
while (__cmpAndSwap(ptr, old_val | value, old_val) != old_val); \
\
return old_val; \
}
#define ARCH_ATOMIC_FETCH_XOR_4(func) \
\
int32_t func(volatile void *ptr, int32_t value, int memorder) \
{ \
int32_t old_val; \
\
do \
{ \
old_val = atomic_load_4(ptr, memorder); \
} \
while (__cmpAndSwap(ptr, old_val ^ value, old_val) != old_val); \
\
return old_val; \
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: atomic_store_4
****************************************************************************/
ARCH_ATOMIC_STORE_4(__atomic_store_4)
ARCH_ATOMIC_STORE_4(atomic_store_4)
/****************************************************************************
* Name: atomic_load_4
****************************************************************************/
ARCH_ATOMIC_LOAD_4(__atomic_load_4)
ARCH_ATOMIC_LOAD_4(atomic_load_4)
/****************************************************************************
* Name: atomic_exchange_4
****************************************************************************/
ARCH_ATOMIC_EXCHANGE_4(__atomic_exchange_4)
ARCH_ATOMIC_EXCHANGE_4(atomic_exchange_4)
/****************************************************************************
* Name: atomic_compare_exchange_4
****************************************************************************/
ARCH_ATOMIC_COMPARE_EXCHANGE_4(__atomic_compare_exchange_4)
ARCH_ATOMIC_COMPARE_EXCHANGE_4(atomic_compare_exchange_4)
/****************************************************************************
* Name: atomic_flag_test_and_set_4
****************************************************************************/
ARCH_ATOMIC_FLAGS_TEST_AND_SET_4(__atomic_flags_test_and_set_4)
ARCH_ATOMIC_FLAGS_TEST_AND_SET_4(atomic_flags_test_and_set_4)
/****************************************************************************
* Name: atomic_fetch_add_4
****************************************************************************/
ARCH_ATOMIC_FETCH_ADD_4(__atomic_fetch_add_4)
ARCH_ATOMIC_FETCH_ADD_4(atomic_fetch_add_4)
/****************************************************************************
* Name: atomic_fetch_sub_4
****************************************************************************/
ARCH_ATOMIC_FETCH_SUB_4(__atomic_fetch_sub_4)
ARCH_ATOMIC_FETCH_SUB_4(atomic_fetch_sub_4)
/****************************************************************************
* Name: atomic_fetch_and_4
****************************************************************************/
ARCH_ATOMIC_FETCH_AND_4(__atomic_fetch_and_4)
ARCH_ATOMIC_FETCH_AND_4(atomic_fetch_and_4)
/****************************************************************************
* Name: atomic_fetch_or_4
****************************************************************************/
ARCH_ATOMIC_FETCH_OR_4(__atomic_fetch_or_4)
ARCH_ATOMIC_FETCH_OR_4(atomic_fetch_or_4)
/****************************************************************************
* Name: atomic_fetch_xor_4
****************************************************************************/
ARCH_ATOMIC_FETCH_XOR_4(__atomic_fetch_xor_4)
ARCH_ATOMIC_FETCH_XOR_4(atomic_fetch_xor_4)