Files
m241Neelima/vxworks-6.9/target/h/arch/mips/vxAtomicArchLib.h
T
2026-07-30 11:19:44 +05:30

819 lines
20 KiB
C

/* vxAtomicArchLib.h - MIPS specific atomic library header */
/*
* Copyright (c) 2006-2010 Wind River Systems, Inc.
*
* The right to copy, distribute or otherwise make use of this software
* may be licensed only pursuant to the terms of an applicable Wind River
* license agreement.
*/
/*
modification history
--------------------
01k,22may10,gls added vxAtomic32XXX_inline definitions for GCC
01j,28apr10,pad Moved extern C statement after include statements.
01i,22mar10,dhy(slk) delete a unused variable
01h,09jun09,slk add gnu inline atomics
01g,15may09,gls made memory barriers available in user space
01f,28apr09,cww Add fixed size APIs
01e,15aug08,slk add additional atomic inline operators
01d,16jun08,zl use _WRS_BARRIER() for memory barrier implementations
01c,17jan08,gls renamed inline routines
01b,14dec07,wap Add inline versions of some vxAtomic functions
01a,21nov06,slk Created
*/
#ifndef __INCvxAtomicArchLibh
#define __INCvxAtomicArchLibh
#include <arch/mips/vxAtomicArchLibCommon.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _ASMLANGUAGE
#if defined (__DCC__)
#define vxCas_inline vxAtomicCas_inline
__asm volatile BOOL vxAtomicCas_inline (atomic_t * address,
atomicVal_t old_value,
atomicVal_t new_value)
{
% reg address; reg old_value; reg new_value; \
lab vxCas1_inline, vxCas2_inline
vxCas1_inline:
.set noreorder
ll t0, 0(address)
bne t0, old_value, vxCas2_inline
li v0, FALSE
move t1, new_value
sc t1, 0(address)
beqz t1, vxCas1_inline
li v0, FALSE
li v0, TRUE
.set reorder
vxCas2_inline:
}
__asm volatile BOOL vxAtomic32Cas_inline (atomic32_t * address,
atomic32Val_t old_value,
atomic32Val_t new_value)
{
% reg address; reg old_value; reg new_value; \
lab vxCas1_inline, vxCas2_inline
vxCas1_inline:
.set noreorder
ll t0, 0(address)
bne t0, old_value, vxCas2_inline
li v0, FALSE
move t1, new_value
sc t1, 0(address)
beqz t1, vxCas1_inline
li v0, FALSE
li v0, TRUE
.set reorder
vxCas2_inline:
}
__asm volatile atomicVal_t vxAtomicSet_inline (atomic_t * address,
atomicVal_t value)
{
% reg address; reg value; \
lab vxAtomicSet1_inline
.set noreorder
move t0, value
vxAtomicSet1_inline:
ll v0, 0(address)
sc t0, 0(address)
beqz t0, vxAtomicSet1_inline
move t0, value
.set reorder
}
__asm volatile atomic32Val_t vxAtomic32Set_inline (atomic32_t * address,
atomic32Val_t value)
{
% reg address; reg value; \
lab vxAtomicSet1_inline
.set noreorder
move t0, value
vxAtomicSet1_inline:
ll v0, 0(address)
sc t0, 0(address)
beqz t0, vxAtomicSet1_inline
move t0, value
.set reorder
}
__asm volatile atomicVal_t vxAtomicGet_inline (atomic_t * address)
{
% reg address;
lw v0, 0(address)
}
__asm volatile atomic32Val_t vxAtomic32Get_inline (atomic32_t * address)
{
% reg address;
lw v0, 0(address)
}
__asm volatile atomicVal_t vxAtomicAnd_inline (atomic_t * address,
atomicVal_t value)
{
% reg address; reg value; \
lab vxAtomicAnd1_inline
vxAtomicAnd1_inline:
.set noreorder
ll v0, 0(address)
and t0, value, v0
sc t0, 0(address)
beqz t0, vxAtomicAnd1_inline
nop
.set reorder
}
__asm volatile atomic32Val_t vxAtomic32And_inline (atomic32_t * address,
atomic32Val_t value)
{
% reg address; reg value; \
lab vxAtomicAnd1_inline
vxAtomicAnd1_inline:
.set noreorder
ll v0, 0(address)
and t0, value, v0
sc t0, 0(address)
beqz t0, vxAtomicAnd1_inline
nop
.set reorder
}
__asm volatile atomicVal_t vxAtomicOr_inline (atomic_t * address,
atomicVal_t value)
{
% reg address; reg value; \
lab vxAtomicOr1_inline
vxAtomicOr1_inline:
.set noreorder
ll v0, 0(address)
or t0, value, v0
sc t0, 0(address)
beqz t0, vxAtomicOr1_inline
nop
.set reorder
}
__asm volatile atomic32Val_t vxAtomic32Or_inline (atomic32_t * address,
atomic32Val_t value)
{
% reg address; reg value; \
lab vxAtomicOr1_inline
vxAtomicOr1_inline:
.set noreorder
ll v0, 0(address)
or t0, value, v0
sc t0, 0(address)
beqz t0, vxAtomicOr1_inline
nop
.set reorder
}
__asm volatile atomicVal_t vxAtomicXor_inline (atomic_t * address,
atomicVal_t value)
{
% reg address; reg value; \
lab vxAtomicXor1_inline
vxAtomicXor1_inline:
.set noreorder
ll v0, 0(address)
xor t0, value, v0
sc t0, 0(address)
beqz t0, vxAtomicXor1_inline
nop
.set reorder
}
__asm volatile atomic32Val_t vxAtomic32Xor_inline (atomic32_t * address,
atomic32Val_t value)
{
% reg address; reg value; \
lab vxAtomicXor1_inline
vxAtomicXor1_inline:
.set noreorder
ll v0, 0(address)
xor t0, value, v0
sc t0, 0(address)
beqz t0, vxAtomicXor1_inline
nop
.set reorder
}
__asm volatile atomicVal_t vxAtomicNand_inline (atomic_t * address,
atomicVal_t value)
{
% reg address; reg value; \
lab vxAtomicNand1_inline
vxAtomicNand1_inline:
.set noreorder
ll v0, 0(address)
and t0, value, v0
not t0
sc t0, 0(address)
beqz t0, vxAtomicNand1_inline
nop
.set reorder
}
__asm volatile atomic32Val_t vxAtomic32Nand_inline (atomic32_t * address,
atomic32Val_t value)
{
% reg address; reg value; \
lab vxAtomicNand1_inline
vxAtomicNand1_inline:
.set noreorder
ll v0, 0(address)
and t0, value, v0
not t0
sc t0, 0(address)
beqz t0, vxAtomicNand1_inline
nop
.set reorder
}
__asm volatile atomicVal_t vxAtomicDec_inline (atomic_t * address)
{
% reg address; \
lab vxAtomicDec1_inline
vxAtomicDec1_inline:
.set noreorder
ll v0, 0(address)
subu t0, v0, 1
sc t0, 0(address)
beqz t0, vxAtomicDec1_inline
nop
.set reorder
}
__asm volatile atomic32Val_t vxAtomic32Dec_inline (atomic32_t * address)
{
% reg address; \
lab vxAtomicDec1_inline
vxAtomicDec1_inline:
.set noreorder
ll v0, 0(address)
subu t0, v0, 1
sc t0, 0(address)
beqz t0, vxAtomicDec1_inline
nop
.set reorder
}
__asm volatile atomicVal_t vxAtomicInc_inline (atomic_t * address)
{
% reg address; \
lab vxAtomicInc1_inline
vxAtomicInc1_inline:
.set noreorder
ll v0, 0(address)
addu t0, v0, 1
sc t0, 0(address)
beqz t0, vxAtomicInc1_inline
nop
.set reorder
}
__asm volatile atomic32Val_t vxAtomic32Inc_inline (atomic32_t * address)
{
% reg address; \
lab vxAtomicInc1_inline
vxAtomicInc1_inline:
.set noreorder
ll v0, 0(address)
addu t0, v0, 1
sc t0, 0(address)
beqz t0, vxAtomicInc1_inline
nop
.set reorder
}
__asm volatile atomicVal_t vxAtomicClear_inline (atomic_t * address)
{
% reg address; \
lab vxAtomicClear1_inline
.set noreorder
move t0, zero
vxAtomicClear1_inline:
ll v0, 0(address)
sc t0, 0(address)
beqz t0, vxAtomicClear1_inline
move t0, zero
.set reorder
}
__asm volatile atomic32Val_t vxAtomic32Clear_inline (atomic32_t * address)
{
% reg address; \
lab vxAtomicClear1_inline
.set noreorder
move t0, zero
vxAtomicClear1_inline:
ll v0, 0(address)
sc t0, 0(address)
beqz t0, vxAtomicClear1_inline
move t0, zero
.set reorder
}
__asm volatile atomicVal_t vxAtomicAdd_inline (atomic_t * address,
atomicVal_t value)
{
% reg address; reg value; \
lab vxAtomicAdd1_inline
vxAtomicAdd1_inline:
.set noreorder
ll v0, 0(address)
addu t0, v0, value
sc t0, 0(address)
beqz t0, vxAtomicAdd1_inline
nop
.set reorder
}
__asm volatile atomic32Val_t vxAtomic32Add_inline (atomic32_t * address,
atomic32Val_t value)
{
% reg address; reg value; \
lab vxAtomicAdd1_inline
vxAtomicAdd1_inline:
.set noreorder
ll v0, 0(address)
addu t0, v0, value
sc t0, 0(address)
beqz t0, vxAtomicAdd1_inline
nop
.set reorder
}
__asm volatile atomicVal_t vxAtomicSub_inline (atomic_t * address,
atomicVal_t value)
{
% reg address; reg value; \
lab vxAtomicSub1_inline
vxAtomicSub1_inline:
.set noreorder
ll v0, 0(address)
subu t0, v0, value
sc t0, 0(address)
beqz t0, vxAtomicSub1_inline
nop
.set reorder
}
__asm volatile atomic32Val_t vxAtomic32Sub_inline (atomic32_t * address,
atomic32Val_t value)
{
% reg address; reg value; \
lab vxAtomicSub1_inline
vxAtomicSub1_inline:
.set noreorder
ll v0, 0(address)
subu t0, v0, value
sc t0, 0(address)
beqz t0, vxAtomicSub1_inline
nop
.set reorder
}
#elif defined (__GNUC__)
#define vxCas_inline vxAtomicCas_inline
static __inline__ BOOL vxAtomicCas_inline(atomic_t * address,
atomicVal_t old_value,
atomicVal_t new_value)
{
int rtn;
__asm__ (
".set noreorder \n"
"ll %0, %1 \n"
"bne %0, %2, 1f \n"
"move %0, $0 \n"
"move %0, %3 \n"
"sc %0, %1 \n"
"beqz %0, 1f \n"
"move %0, $0 \n"
"ori %0, 1 \n"
"1: \n"
".set reorder \n"
: "=&r" (rtn), "+m" (*address)
: "r" (old_value), "r" (new_value) : "memory");
return (rtn);
}
static __inline__ BOOL vxAtomic32Cas_inline(atomic_t * address,
atomicVal_t old_value,
atomicVal_t new_value)
{
int rtn;
__asm__ (
".set noreorder \n"
"ll %0, %1 \n"
"bne %0, %2, 1f \n"
"move %0, $0 \n"
"move %0, %3 \n"
"sc %0, %1 \n"
"beqz %0, 1f \n"
"move %0, $0 \n"
"ori %0, 1 \n"
"1: \n"
".set reorder \n"
: "=&r" (rtn), "+m" (*address)
: "r" (old_value), "r" (new_value) : "memory");
return (rtn);
}
static __inline__ atomicVal_t vxAtomicGet_inline(atomic_t * address)
{
int rtn;
__asm__ ("lw %0, %1" : "=r" (rtn) : "m" (*address) );
return (rtn);
}
static __inline__ atomicVal_t vxAtomic32Get_inline(atomic_t * address)
{
int rtn;
__asm__ ("lw %0, %1" : "=r" (rtn) : "m" (*address) );
return (rtn);
}
static __inline__ atomicVal_t vxAtomicSet_inline(atomic_t * address,
atomicVal_t value)
{
int rtn, tmp;
__asm__ (
".set noreorder \n"
"move %2, %3 \n"
"0: ll %0, %1 \n"
"sc %2, %1 \n"
"beqz %2, 0b \n"
"move %2, %3 \n"
".set reorder \n"
: "=&r" (rtn), "+m" (*address), "=r" (tmp)
: "r" (value) : "memory");
return (rtn);
}
static __inline__ atomicVal_t vxAtomic32Set_inline(atomic_t * address,
atomicVal_t value)
{
int rtn, tmp;
__asm__ (
".set noreorder \n"
"move %2, %3 \n"
"0: ll %0, %1 \n"
"sc %2, %1 \n"
"beqz %2, 0b \n"
"move %2, %3 \n"
".set reorder \n"
: "=&r" (rtn), "+m" (*address), "=r" (tmp)
: "r" (value) : "memory");
return (rtn);
}
static __inline__ atomicVal_t vxAtomicAnd_inline(atomic_t * address,
atomicVal_t value)
{
int rtn, tmp;
__asm__ (
".set noreorder \n"
"0: ll %0, %1 \n"
"and %2, %0, %3 \n"
"sc %2, %1 \n"
"beqz %2, 0b \n"
"nop \n"
".set reorder \n"
: "=&r" (rtn), "+m" (*address), "=r" (tmp)
: "r" (value) : "memory");
return (rtn);
}
static __inline__ atomicVal_t vxAtomic32And_inline(atomic_t * address,
atomicVal_t value)
{
int rtn, tmp;
__asm__ (
".set noreorder \n"
"0: ll %0, %1 \n"
"and %2, %0, %3 \n"
"sc %2, %1 \n"
"beqz %2, 0b \n"
"nop \n"
".set reorder \n"
: "=&r" (rtn), "+m" (*address), "=r" (tmp)
: "r" (value) : "memory");
return (rtn);
}
static __inline__ atomicVal_t vxAtomicNand_inline(atomic_t * address,
atomicVal_t value)
{
int rtn, tmp;
__asm__ (
".set noreorder \n"
"0: ll %0, %1 \n"
"and %2, %0, %3 \n"
"not %2 \n"
"sc %2, %1 \n"
"beqz %2, 0b \n"
"nop \n"
".set reorder \n"
: "=&r" (rtn), "+m" (*address), "=r" (tmp)
: "r" (value) : "memory");
return (rtn);
}
static __inline__ atomicVal_t vxAtomic32Nand_inline(atomic_t * address,
atomicVal_t value)
{
int rtn, tmp;
__asm__ (
".set noreorder \n"
"0: ll %0, %1 \n"
"and %2, %0, %3 \n"
"not %2 \n"
"sc %2, %1 \n"
"beqz %2, 0b \n"
"nop \n"
".set reorder \n"
: "=&r" (rtn), "+m" (*address), "=r" (tmp)
: "r" (value) : "memory");
return (rtn);
}
static __inline__ atomicVal_t vxAtomicOr_inline(atomic_t * address,
atomicVal_t value)
{
int rtn, tmp;
__asm__ (
".set noreorder \n"
"0: ll %0, %1 \n"
"or %2, %0, %3 \n"
"sc %2, %1 \n"
"beqz %2, 0b \n"
"nop \n"
".set reorder \n"
: "=&r" (rtn), "+m" (*address), "=r" (tmp)
: "r" (value) : "memory");
return (rtn);
}
static __inline__ atomicVal_t vxAtomic32Or_inline(atomic_t * address,
atomicVal_t value)
{
int rtn, tmp;
__asm__ (
".set noreorder \n"
"0: ll %0, %1 \n"
"or %2, %0, %3 \n"
"sc %2, %1 \n"
"beqz %2, 0b \n"
"nop \n"
".set reorder \n"
: "=&r" (rtn), "+m" (*address), "=r" (tmp)
: "r" (value) : "memory");
return (rtn);
}
static __inline__ atomicVal_t vxAtomicXor_inline(atomic_t * address,
atomicVal_t value)
{
int rtn, tmp;
__asm__ (
".set noreorder \n"
"0: ll %0, %1 \n"
"xor %2, %0, %3 \n"
"sc %2, %1 \n"
"beqz %2, 0b \n"
"nop \n"
".set reorder \n"
: "=&r" (rtn), "+m" (*address), "=r" (tmp)
: "r" (value) : "memory");
return (rtn);
}
static __inline__ atomicVal_t vxAtomic32Xor_inline(atomic_t * address,
atomicVal_t value)
{
int rtn, tmp;
__asm__ (
".set noreorder \n"
"0: ll %0, %1 \n"
"xor %2, %0, %3 \n"
"sc %2, %1 \n"
"beqz %2, 0b \n"
"nop \n"
".set reorder \n"
: "=&r" (rtn), "+m" (*address), "=r" (tmp)
: "r" (value) : "memory");
return (rtn);
}
static __inline__ atomicVal_t vxAtomicDec_inline(atomic_t * address)
{
int rtn, tmp;
__asm__ (
".set noreorder \n"
"0: ll %0, %1 \n"
"addiu %2, %0, -1 \n"
"sc %2, %1 \n"
"beqz %2, 0b \n"
"nop \n"
".set reorder \n"
: "=&r" (rtn), "+m" (*address), "=r" (tmp) : : "memory");
return (rtn);
}
static __inline__ atomicVal_t vxAtomic32Dec_inline(atomic_t * address)
{
int rtn, tmp;
__asm__ (
".set noreorder \n"
"0: ll %0, %1 \n"
"addiu %2, %0, -1 \n"
"sc %2, %1 \n"
"beqz %2, 0b \n"
"nop \n"
".set reorder \n"
: "=&r" (rtn), "+m" (*address), "=r" (tmp) : : "memory");
return (rtn);
}
static __inline__ atomicVal_t vxAtomicInc_inline(atomic_t * address)
{
int rtn, tmp;
__asm__ (
".set noreorder \n"
"0: ll %0, %1 \n"
"addiu %2, %0, 1 \n"
"sc %2, %1 \n"
"beqz %2, 0b \n"
"nop \n"
".set reorder \n"
: "=&r" (rtn), "+m" (*address), "=r" (tmp) : : "memory");
return (rtn);
}
static __inline__ atomicVal_t vxAtomic32Inc_inline(atomic_t * address)
{
int rtn, tmp;
__asm__ (
".set noreorder \n"
"0: ll %0, %1 \n"
"addiu %2, %0, 1 \n"
"sc %2, %1 \n"
"beqz %2, 0b \n"
"nop \n"
".set reorder \n"
: "=&r" (rtn), "+m" (*address), "=r" (tmp) : : "memory");
return (rtn);
}
static __inline__ atomicVal_t vxAtomicClear_inline(atomic_t * address)
{
int rtn, tmp;
__asm__ (
".set noreorder \n"
"move %2, $0 \n"
"0: ll %0, %1 \n"
"sc %2, %1 \n"
"beqz %2, 0b \n"
"move %2, $0 \n"
".set reorder \n"
: "=&r" (rtn), "+m" (*address), "=r" (tmp) : : "memory");
return (rtn);
}
static __inline__ atomicVal_t vxAtomic32Clear_inline(atomic_t * address)
{
int rtn, tmp;
__asm__ (
".set noreorder \n"
"move %2, $0 \n"
"0: ll %0, %1 \n"
"sc %2, %1 \n"
"beqz %2, 0b \n"
"move %2, $0 \n"
".set reorder \n"
: "=&r" (rtn), "+m" (*address), "=r" (tmp) : : "memory");
return (rtn);
}
static __inline__ atomicVal_t vxAtomicAdd_inline(atomic_t * address,
atomicVal_t value)
{
int rtn, tmp;
__asm__ (
".set noreorder \n"
"0: ll %0, %1 \n"
"addu %2, %0, %3 \n"
"sc %2, %1 \n"
"beqz %2, 0b \n"
"nop \n"
".set reorder \n"
: "=&r" (rtn), "+m" (*address), "=r" (tmp)
: "r" (value) : "memory");
return (rtn);
}
static __inline__ atomicVal_t vxAtomic32Add_inline(atomic_t * address,
atomicVal_t value)
{
int rtn, tmp;
__asm__ (
".set noreorder \n"
"0: ll %0, %1 \n"
"addu %2, %0, %3 \n"
"sc %2, %1 \n"
"beqz %2, 0b \n"
"nop \n"
".set reorder \n"
: "=&r" (rtn), "+m" (*address), "=r" (tmp)
: "r" (value) : "memory");
return (rtn);
}
static __inline__ atomicVal_t vxAtomicSub_inline(atomic_t * address,
atomicVal_t value)
{
int rtn, tmp;
__asm__ (
".set noreorder \n"
"0: ll %0, %1 \n"
"subu %2, %0, %3 \n"
"sc %2, %1 \n"
"beqz %2, 0b \n"
"nop \n"
".set reorder \n"
: "=&r" (rtn), "+m" (*address), "=r" (tmp)
: "r" (value) : "memory");
return (rtn);
}
static __inline__ atomicVal_t vxAtomic32Sub_inline(atomic_t * address,
atomicVal_t value)
{
int rtn, tmp;
__asm__ (
".set noreorder \n"
"0: ll %0, %1 \n"
"subu %2, %0, %3 \n"
"sc %2, %1 \n"
"beqz %2, 0b \n"
"nop \n"
".set reorder \n"
: "=&r" (rtn), "+m" (*address), "=r" (tmp)
: "r" (value) : "memory");
return (rtn);
}
#else
#define vxCas_inline vxAtomicCas
#define vxAtomicCas_inline vxAtomicCas
#define vxAtomic32Cas_inline vxAtomic32Cas
#define vxAtomicAdd_inline vxAtomicAdd
#define vxAtomic32Add_inline vxAtomic32Add
#define vxAtomicSub_inline vxAtomicSub
#define vxAtomic32Sub_inline vxAtomic32Sub
#define vxAtomicInc_inline vxAtomicInc
#define vxAtomic32Inc_inline vxAtomic32Inc
#define vxAtomicDec_inline vxAtomicDec
#define vxAtomic32Dec_inline vxAtomic32Dec
#define vxAtomicSet_inline vxAtomicSet
#define vxAtomic32Set_inline vxAtomic32Set
#define vxAtomicClear_inline vxAtomicClear
#define vxAtomic32Clear_inline vxAtomic32Clear
#define vxAtomicGet_inline vxAtomicGet
#define vxAtomic32Get_inline vxAtomic32Get
#define vxAtomicAnd_inline vxAtomicAnd
#define vxAtomic32And_inline vxAtomic32And
#define vxAtomicNand_inline vxAtomicNand
#define vxAtomic32Nand_inline vxAtomic32Nand
#define vxAtomicOr_inline vxAtomicOr
#define vxAtomic32Or_inline vxAtomic32Or
#define vxAtomicXor_inline vxAtomicXor
#define vxAtomic32Xor_inline vxAtomic32Xor
#endif /* _VX_TOOL_FAMILY */
#endif /* _ASMLANGUAGE */
#ifdef __cplusplus
}
#endif
#endif /* __INCvxAtomicArchLibh */