opensolaris_atomic.S revision 219089
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 .file "atomic.s" 28 29#define _ASM 30#include <sys/asm_linkage.h> 31 32 /* 33 * NOTE: If atomic_dec_64 and atomic_dec_64_nv are ever 34 * separated, it is important to edit the libc i386 platform 35 * specific mapfile and remove the NODYNSORT attribute 36 * from atomic_dec_64_nv. 37 */ 38 ENTRY(atomic_dec_64) 39 ALTENTRY(atomic_dec_64_nv) 40 pushl %edi 41 pushl %ebx 42 movl 12(%esp), %edi // %edi = target address 43 movl (%edi), %eax 44 movl 4(%edi), %edx // %edx:%eax = old value 451: 46 xorl %ebx, %ebx 47 xorl %ecx, %ecx 48 not %ecx 49 not %ebx // %ecx:%ebx = -1 50 addl %eax, %ebx 51 adcl %edx, %ecx // add in the carry from inc 52 lock 53 cmpxchg8b (%edi) // try to stick it in 54 jne 1b 55 movl %ebx, %eax 56 movl %ecx, %edx // return new value 57 popl %ebx 58 popl %edi 59 ret 60 SET_SIZE(atomic_dec_64_nv) 61 SET_SIZE(atomic_dec_64) 62 63 /* 64 * NOTE: If atomic_add_64 and atomic_add_64_nv are ever 65 * separated, it is important to edit the libc i386 platform 66 * specific mapfile and remove the NODYNSORT attribute 67 * from atomic_add_64_nv. 68 */ 69 ENTRY(atomic_add_64) 70 ALTENTRY(atomic_add_64_nv) 71 pushl %edi 72 pushl %ebx 73 movl 12(%esp), %edi // %edi = target address 74 movl (%edi), %eax 75 movl 4(%edi), %edx // %edx:%eax = old value 761: 77 movl 16(%esp), %ebx 78 movl 20(%esp), %ecx // %ecx:%ebx = delta 79 addl %eax, %ebx 80 adcl %edx, %ecx // %ecx:%ebx = new value 81 lock 82 cmpxchg8b (%edi) // try to stick it in 83 jne 1b 84 movl %ebx, %eax 85 movl %ecx, %edx // return new value 86 popl %ebx 87 popl %edi 88 ret 89 SET_SIZE(atomic_add_64_nv) 90 SET_SIZE(atomic_add_64) 91 92 ENTRY(atomic_or_8_nv) 93 movl 4(%esp), %edx // %edx = target address 94 movb (%edx), %al // %al = old value 951: 96 movl 8(%esp), %ecx // %ecx = delta 97 orb %al, %cl // %cl = new value 98 lock 99 cmpxchgb %cl, (%edx) // try to stick it in 100 jne 1b 101 movzbl %cl, %eax // return new value 102 ret 103 SET_SIZE(atomic_or_8_nv) 104 105 ENTRY(atomic_cas_32) 106 movl 4(%esp), %edx 107 movl 8(%esp), %eax 108 movl 12(%esp), %ecx 109 lock 110 cmpxchgl %ecx, (%edx) 111 ret 112 SET_SIZE(atomic_cas_32) 113 114 ENTRY(atomic_cas_64) 115 pushl %ebx 116 pushl %esi 117 movl 12(%esp), %esi 118 movl 16(%esp), %eax 119 movl 20(%esp), %edx 120 movl 24(%esp), %ebx 121 movl 28(%esp), %ecx 122 lock 123 cmpxchg8b (%esi) 124 popl %esi 125 popl %ebx 126 ret 127 SET_SIZE(atomic_cas_64) 128 129 ENTRY(membar_producer) 130 lock 131 xorl $0, (%esp) 132 ret 133 SET_SIZE(membar_producer) 134