opensolaris_atomic.S revision 185029
1168482Spjd/* 2168482Spjd * CDDL HEADER START 3168482Spjd * 4168482Spjd * The contents of this file are subject to the terms of the 5185029Spjd * Common Development and Distribution License (the "License"). 6185029Spjd * You may not use this file except in compliance with the License. 7168482Spjd * 8168482Spjd * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9168482Spjd * or http://www.opensolaris.org/os/licensing. 10168482Spjd * See the License for the specific language governing permissions 11168482Spjd * and limitations under the License. 12168482Spjd * 13168482Spjd * When distributing Covered Code, include this CDDL HEADER in each 14168482Spjd * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15168482Spjd * If applicable, add the following below this CDDL HEADER, with the 16168482Spjd * fields enclosed by brackets "[]" replaced with your own identifying 17168482Spjd * information: Portions Copyright [yyyy] [name of copyright owner] 18168482Spjd * 19168482Spjd * CDDL HEADER END 20168482Spjd */ 21185029Spjd 22168482Spjd/* 23185029Spjd * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24168482Spjd * Use is subject to license terms. 25168482Spjd */ 26168482Spjd 27185029Spjd .file "atomic.s" 28168482Spjd 29168482Spjd#define _ASM 30168482Spjd#include <sys/asm_linkage.h> 31168482Spjd 32185029Spjd /* 33185029Spjd * NOTE: If atomic_dec_64 and atomic_dec_64_nv are ever 34185029Spjd * separated, it is important to edit the libc i386 platform 35185029Spjd * specific mapfile and remove the NODYNSORT attribute 36185029Spjd * from atomic_dec_64_nv. 37185029Spjd */ 38185029Spjd ENTRY(atomic_dec_64) 39185029Spjd ALTENTRY(atomic_dec_64_nv) 40185029Spjd pushl %edi 41185029Spjd pushl %ebx 42185029Spjd movl 12(%esp), %edi // %edi = target address 43185029Spjd movl (%edi), %eax 44185029Spjd movl 4(%edi), %edx // %edx:%eax = old value 45185029Spjd1: 46185029Spjd xorl %ebx, %ebx 47185029Spjd xorl %ecx, %ecx 48185029Spjd not %ecx 49185029Spjd not %ebx // %ecx:%ebx = -1 50185029Spjd addl %eax, %ebx 51185029Spjd adcl %edx, %ecx // add in the carry from inc 52185029Spjd lock 53185029Spjd cmpxchg8b (%edi) // try to stick it in 54185029Spjd jne 1b 55185029Spjd movl %ebx, %eax 56185029Spjd movl %ecx, %edx // return new value 57185029Spjd popl %ebx 58185029Spjd popl %edi 59185029Spjd ret 60185029Spjd SET_SIZE(atomic_dec_64_nv) 61185029Spjd SET_SIZE(atomic_dec_64) 62185029Spjd 63185029Spjd /* 64185029Spjd * NOTE: If atomic_add_64 and atomic_add_64_nv are ever 65185029Spjd * separated, it is important to edit the libc i386 platform 66185029Spjd * specific mapfile and remove the NODYNSORT attribute 67185029Spjd * from atomic_add_64_nv. 68185029Spjd */ 69168482Spjd ENTRY(atomic_add_64) 70168482Spjd ALTENTRY(atomic_add_64_nv) 71168482Spjd pushl %edi 72168482Spjd pushl %ebx 73168675Spjd movl 12(%esp), %edi // %edi = target address 74168482Spjd movl (%edi), %eax 75168675Spjd movl 4(%edi), %edx // %edx:%eax = old value 76168482Spjd1: 77168482Spjd movl 16(%esp), %ebx 78168675Spjd movl 20(%esp), %ecx // %ecx:%ebx = delta 79168482Spjd addl %eax, %ebx 80168675Spjd adcl %edx, %ecx // %ecx:%ebx = new value 81168482Spjd lock 82168675Spjd cmpxchg8b (%edi) // try to stick it in 83168482Spjd jne 1b 84168482Spjd movl %ebx, %eax 85168675Spjd movl %ecx, %edx // return new value 86168482Spjd popl %ebx 87168482Spjd popl %edi 88168482Spjd ret 89168482Spjd SET_SIZE(atomic_add_64_nv) 90168482Spjd SET_SIZE(atomic_add_64) 91168482Spjd 92168482Spjd ENTRY(atomic_or_8_nv) 93168675Spjd movl 4(%esp), %edx // %edx = target address 94168675Spjd movb (%edx), %al // %al = old value 95168482Spjd1: 96168675Spjd movl 8(%esp), %ecx // %ecx = delta 97168675Spjd orb %al, %cl // %cl = new value 98168482Spjd lock 99168675Spjd cmpxchgb %cl, (%edx) // try to stick it in 100168482Spjd jne 1b 101168675Spjd movzbl %cl, %eax // return new value 102168482Spjd ret 103168482Spjd SET_SIZE(atomic_or_8_nv) 104168482Spjd 105170431Spjd ENTRY(atomic_cas_ptr) 106168482Spjd movl 4(%esp), %edx 107168482Spjd movl 8(%esp), %eax 108168482Spjd movl 12(%esp), %ecx 109168482Spjd lock 110168482Spjd cmpxchgl %ecx, (%edx) 111168482Spjd ret 112168482Spjd SET_SIZE(atomic_cas_ptr) 113168482Spjd 114168482Spjd ENTRY(atomic_cas_64) 115168482Spjd pushl %ebx 116168482Spjd pushl %esi 117168482Spjd movl 12(%esp), %esi 118168482Spjd movl 16(%esp), %eax 119168482Spjd movl 20(%esp), %edx 120168482Spjd movl 24(%esp), %ebx 121168482Spjd movl 28(%esp), %ecx 122168482Spjd lock 123168482Spjd cmpxchg8b (%esi) 124168482Spjd popl %esi 125168482Spjd popl %ebx 126168482Spjd ret 127168482Spjd SET_SIZE(atomic_cas_64) 128168482Spjd 129170431Spjd ENTRY(membar_producer) 130168482Spjd lock 131168482Spjd xorl $0, (%esp) 132168482Spjd ret 133168482Spjd SET_SIZE(membar_producer) 134