112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Copyright 2010 the V8 project authors. All rights reserved. 212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Redistribution and use in source and binary forms, with or without 312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// modification, are permitted provided that the following conditions are 412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// met: 512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// 612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// * Redistributions of source code must retain the above copyright 712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// notice, this list of conditions and the following disclaimer. 812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// * Redistributions in binary form must reproduce the above 912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// copyright notice, this list of conditions and the following 1012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// disclaimer in the documentation and/or other materials provided 1112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// with the distribution. 1212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// * Neither the name of Google Inc. nor the names of its 1312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// contributors may be used to endorse or promote products derived 1412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// from this software without specific prior written permission. 1512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// 1612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 2812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// This file is an internal atomic implementation, use atomicops.h instead. 2912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 3012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#ifndef V8_BASE_ATOMICOPS_INTERNALS_MIPS_GCC_H_ 3112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#define V8_BASE_ATOMICOPS_INTERNALS_MIPS_GCC_H_ 3212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 3312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgnamespace v8 { 3412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgnamespace base { 3512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 3612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Atomically execute: 3712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// result = *ptr; 3812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// if (*ptr == old_value) 3912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// *ptr = new_value; 4012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// return result; 4112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// 4212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value". 4312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Always return the old value of "*ptr" 4412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// 4512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// This routine implies no memory barriers. 4612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, 4712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic32 old_value, 4812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic32 new_value) { 4912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic32 prev, tmp; 5012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org __asm__ __volatile__(".set push\n" 5112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org ".set noreorder\n" 5212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "1:\n" 5312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "ll %0, %5\n" // prev = *ptr 5412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "bne %0, %3, 2f\n" // if (prev != old_value) goto 2 5512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "move %2, %4\n" // tmp = new_value 5612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "sc %2, %1\n" // *ptr = tmp (with atomic check) 5712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "beqz %2, 1b\n" // start again on atomic error 5812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "nop\n" // delay slot nop 5912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "2:\n" 6012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org ".set pop\n" 6112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org : "=&r" (prev), "=m" (*ptr), "=&r" (tmp) 6212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org : "Ir" (old_value), "r" (new_value), "m" (*ptr) 6312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org : "memory"); 6412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return prev; 6512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 6612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 6712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Atomically store new_value into *ptr, returning the previous value held in 6812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// *ptr. This routine implies no memory barriers. 6912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, 7012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic32 new_value) { 7112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic32 temp, old; 7212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org __asm__ __volatile__(".set push\n" 7312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org ".set noreorder\n" 7412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "1:\n" 7512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "ll %1, %2\n" // old = *ptr 7612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "move %0, %3\n" // temp = new_value 7712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "sc %0, %2\n" // *ptr = temp (with atomic check) 7812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "beqz %0, 1b\n" // start again on atomic error 7912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "nop\n" // delay slot nop 8012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org ".set pop\n" 8112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org : "=&r" (temp), "=&r" (old), "=m" (*ptr) 8212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org : "r" (new_value), "m" (*ptr) 8312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org : "memory"); 8412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 8512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return old; 8612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 8712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 8812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Atomically increment *ptr by "increment". Returns the new value of 8912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// *ptr with the increment applied. This routine implies no memory barriers. 9012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, 9112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic32 increment) { 9212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic32 temp, temp2; 9312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 9412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org __asm__ __volatile__(".set push\n" 9512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org ".set noreorder\n" 9612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "1:\n" 9712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "ll %0, %2\n" // temp = *ptr 9812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "addu %1, %0, %3\n" // temp2 = temp + increment 9912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "sc %1, %2\n" // *ptr = temp2 (with atomic check) 10012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "beqz %1, 1b\n" // start again on atomic error 10112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "addu %1, %0, %3\n" // temp2 = temp + increment 10212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org ".set pop\n" 10312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org : "=&r" (temp), "=&r" (temp2), "=m" (*ptr) 10412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org : "Ir" (increment), "m" (*ptr) 10512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org : "memory"); 10612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // temp2 now holds the final value. 10712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return temp2; 10812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 10912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 11012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, 11112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic32 increment) { 11212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org MemoryBarrier(); 11312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic32 res = NoBarrier_AtomicIncrement(ptr, increment); 11412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org MemoryBarrier(); 11512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return res; 11612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 11712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 11812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// "Acquire" operations 11912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// ensure that no later memory access can be reordered ahead of the operation. 12012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// "Release" operations ensure that no previous memory access can be reordered 12112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// after the operation. "Barrier" operations have both "Acquire" and "Release" 12212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// semantics. A MemoryBarrier() has "Barrier" semantics, but does no memory 12312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// access. 12412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, 12512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic32 old_value, 12612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic32 new_value) { 12712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value); 12812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org MemoryBarrier(); 12912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return res; 13012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 13112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 13212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, 13312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic32 old_value, 13412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic32 new_value) { 13512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org MemoryBarrier(); 13612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return NoBarrier_CompareAndSwap(ptr, old_value, new_value); 13712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 13812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 13912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline void NoBarrier_Store(volatile Atomic8* ptr, Atomic8 value) { 14012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org *ptr = value; 14112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 14212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 14312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { 14412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org *ptr = value; 14512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 14612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 14712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline void MemoryBarrier() { 14812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org __asm__ __volatile__("sync" : : : "memory"); 14912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 15012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 15112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { 15212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org *ptr = value; 15312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org MemoryBarrier(); 15412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 15512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 15612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { 15712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org MemoryBarrier(); 15812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org *ptr = value; 15912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 16012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 16112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline Atomic8 NoBarrier_Load(volatile const Atomic8* ptr) { 16212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return *ptr; 16312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 16412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 16512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { 16612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return *ptr; 16712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 16812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 16912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { 17012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic32 value = *ptr; 17112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org MemoryBarrier(); 17212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return value; 17312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 17412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 17512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline Atomic32 Release_Load(volatile const Atomic32* ptr) { 17612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org MemoryBarrier(); 17712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return *ptr; 17812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 17912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 18012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 18112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// 64-bit versions of the atomic ops. 18212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 18312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, 18412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic64 old_value, 18512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic64 new_value) { 18612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic64 prev, tmp; 18712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org __asm__ __volatile__(".set push\n" 18812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org ".set noreorder\n" 18912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "1:\n" 19012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "lld %0, %5\n" // prev = *ptr 19112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "bne %0, %3, 2f\n" // if (prev != old_value) goto 2 19212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "move %2, %4\n" // tmp = new_value 19312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "scd %2, %1\n" // *ptr = tmp (with atomic check) 19412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "beqz %2, 1b\n" // start again on atomic error 19512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "nop\n" // delay slot nop 19612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "2:\n" 19712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org ".set pop\n" 19812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org : "=&r" (prev), "=m" (*ptr), "=&r" (tmp) 19912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org : "Ir" (old_value), "r" (new_value), "m" (*ptr) 20012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org : "memory"); 20112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return prev; 20212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 20312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 20412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Atomically store new_value into *ptr, returning the previous value held in 20512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// *ptr. This routine implies no memory barriers. 20612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, 20712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic64 new_value) { 20812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic64 temp, old; 20912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org __asm__ __volatile__(".set push\n" 21012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org ".set noreorder\n" 21112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "1:\n" 21212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "lld %1, %2\n" // old = *ptr 21312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "move %0, %3\n" // temp = new_value 21412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "scd %0, %2\n" // *ptr = temp (with atomic check) 21512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "beqz %0, 1b\n" // start again on atomic error 21612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "nop\n" // delay slot nop 21712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org ".set pop\n" 21812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org : "=&r" (temp), "=&r" (old), "=m" (*ptr) 21912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org : "r" (new_value), "m" (*ptr) 22012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org : "memory"); 22112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 22212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return old; 22312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 22412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 22512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Atomically increment *ptr by "increment". Returns the new value of 22612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// *ptr with the increment applied. This routine implies no memory barriers. 22712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, 22812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic64 increment) { 22912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic64 temp, temp2; 23012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 23112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org __asm__ __volatile__(".set push\n" 23212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org ".set noreorder\n" 23312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "1:\n" 23412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "lld %0, %2\n" // temp = *ptr 23512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "daddu %1, %0, %3\n" // temp2 = temp + increment 23612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "scd %1, %2\n" // *ptr = temp2 (with atomic check) 23712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "beqz %1, 1b\n" // start again on atomic error 23812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org "daddu %1, %0, %3\n" // temp2 = temp + increment 23912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org ".set pop\n" 24012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org : "=&r" (temp), "=&r" (temp2), "=m" (*ptr) 24112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org : "Ir" (increment), "m" (*ptr) 24212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org : "memory"); 24312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org // temp2 now holds the final value. 24412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return temp2; 24512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 24612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 24712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, 24812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic64 increment) { 24912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org MemoryBarrier(); 25012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic64 res = NoBarrier_AtomicIncrement(ptr, increment); 25112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org MemoryBarrier(); 25212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return res; 25312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 25412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 25512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// "Acquire" operations 25612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// ensure that no later memory access can be reordered ahead of the operation. 25712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// "Release" operations ensure that no previous memory access can be reordered 25812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// after the operation. "Barrier" operations have both "Acquire" and "Release" 25912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// semantics. A MemoryBarrier() has "Barrier" semantics, but does no memory 26012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// access. 26112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, 26212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic64 old_value, 26312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic64 new_value) { 26412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic64 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value); 26512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org MemoryBarrier(); 26612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return res; 26712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 26812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 26912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, 27012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic64 old_value, 27112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic64 new_value) { 27212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org MemoryBarrier(); 27312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return NoBarrier_CompareAndSwap(ptr, old_value, new_value); 27412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 27512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 27612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { 27712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org *ptr = value; 27812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 27912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 28012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) { 28112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org *ptr = value; 28212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org MemoryBarrier(); 28312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 28412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 28512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { 28612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org MemoryBarrier(); 28712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org *ptr = value; 28812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 28912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 29012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { 29112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return *ptr; 29212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 29312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 29412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { 29512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org Atomic64 value = *ptr; 29612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org MemoryBarrier(); 29712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return value; 29812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 29912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 30012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orginline Atomic64 Release_Load(volatile const Atomic64* ptr) { 30112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org MemoryBarrier(); 30212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org return *ptr; 30312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} 30412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 30512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} } // namespace v8::base 30612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org 30712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#endif // V8_BASE_ATOMICOPS_INTERNALS_MIPS_GCC_H_ 308