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_cas_64) 93 pushl %ebx 94 pushl %esi 95 movl 12(%esp), %esi 96 movl 16(%esp), %eax 97 movl 20(%esp), %edx 98 movl 24(%esp), %ebx 99 movl 28(%esp), %ecx 100 lock 101 cmpxchg8b (%esi) 102 popl %esi 103 popl %ebx 104 ret 105 SET_SIZE(atomic_cas_64) 106 107 ENTRY(atomic_swap_64) 108 pushl %esi 109 pushl %ebx 110 movl 12(%esp), %esi 111 movl 16(%esp), %ebx 112 movl 20(%esp), %ecx 113 movl (%esi), %eax 114 movl 4(%esi), %edx // %edx:%eax = old value 1151: 116 lock 117 cmpxchg8b (%esi) 118 jne 1b 119 popl %ebx 120 popl %esi 121 ret 122 SET_SIZE(atomic_swap_64) 123 124 ENTRY(atomic_load_64) 125 pushl %esi 126 movl 8(%esp), %esi 127 movl %ebx, %eax // make old and new values equal, so that 128 movl %ecx, %edx // destination is never changed 129 lock 130 cmpxchg8b (%esi) 131 popl %esi 132 ret 133 SET_SIZE(atomic_load_64) 134