opensolaris_atomic.S revision 168675
1168482Spjd/* 2168482Spjd * CDDL HEADER START 3168482Spjd * 4168482Spjd * The contents of this file are subject to the terms of the 5168482Spjd * Common Development and Distribution License, Version 1.0 only 6168482Spjd * (the "License"). You may not use this file except in compliance 7168482Spjd * with the License. 8168482Spjd * 9168482Spjd * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10168482Spjd * or http://www.opensolaris.org/os/licensing. 11168482Spjd * See the License for the specific language governing permissions 12168482Spjd * and limitations under the License. 13168482Spjd * 14168482Spjd * When distributing Covered Code, include this CDDL HEADER in each 15168482Spjd * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16168482Spjd * If applicable, add the following below this CDDL HEADER, with the 17168482Spjd * fields enclosed by brackets "[]" replaced with your own identifying 18168482Spjd * information: Portions Copyright [yyyy] [name of copyright owner] 19168482Spjd * 20168482Spjd * CDDL HEADER END 21168482Spjd */ 22168482Spjd/* 23168482Spjd * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24168482Spjd * Use is subject to license terms. 25168482Spjd */ 26168482Spjd 27168482Spjd .ident "%Z%%M% %I% %E% SMI" 28168482Spjd 29168482Spjd .file "%M%" 30168482Spjd 31168482Spjd#define _ASM 32168482Spjd#include <sys/asm_linkage.h> 33168482Spjd 34168482Spjd#if defined(_KERNEL) 35168482Spjd /* 36168482Spjd * Legacy kernel interfaces; they will go away (eventually). 37168482Spjd */ 38168482Spjd ANSI_PRAGMA_WEAK2(cas8,atomic_cas_8,function) 39168482Spjd ANSI_PRAGMA_WEAK2(cas32,atomic_cas_32,function) 40168482Spjd ANSI_PRAGMA_WEAK2(cas64,atomic_cas_64,function) 41168482Spjd ANSI_PRAGMA_WEAK2(caslong,atomic_cas_ulong,function) 42168482Spjd ANSI_PRAGMA_WEAK2(casptr,atomic_cas_ptr,function) 43168482Spjd ANSI_PRAGMA_WEAK2(atomic_and_long,atomic_and_ulong,function) 44168482Spjd ANSI_PRAGMA_WEAK2(atomic_or_long,atomic_or_ulong,function) 45168482Spjd#endif 46168482Spjd 47168482Spjd ENTRY(atomic_inc_8) 48168482Spjd ALTENTRY(atomic_inc_uchar) 49168482Spjd movl 4(%esp), %eax 50168482Spjd lock 51168482Spjd incb (%eax) 52168482Spjd ret 53168482Spjd SET_SIZE(atomic_inc_uchar) 54168482Spjd SET_SIZE(atomic_inc_8) 55168482Spjd 56168482Spjd ENTRY(atomic_inc_16) 57168482Spjd ALTENTRY(atomic_inc_ushort) 58168482Spjd movl 4(%esp), %eax 59168482Spjd lock 60168482Spjd incw (%eax) 61168482Spjd ret 62168482Spjd SET_SIZE(atomic_inc_ushort) 63168482Spjd SET_SIZE(atomic_inc_16) 64168482Spjd 65168482Spjd ENTRY(atomic_inc_32) 66168482Spjd ALTENTRY(atomic_inc_uint) 67168482Spjd ALTENTRY(atomic_inc_ulong) 68168482Spjd movl 4(%esp), %eax 69168482Spjd lock 70168482Spjd incl (%eax) 71168482Spjd ret 72168482Spjd SET_SIZE(atomic_inc_ulong) 73168482Spjd SET_SIZE(atomic_inc_uint) 74168482Spjd SET_SIZE(atomic_inc_32) 75168482Spjd 76168482Spjd ENTRY(atomic_inc_8_nv) 77168482Spjd ALTENTRY(atomic_inc_uchar_nv) 78168675Spjd movl 4(%esp), %edx // %edx = target address 79168675Spjd movb (%edx), %al // %al = old value 80168482Spjd1: 81168675Spjd leal 1(%eax), %ecx // %cl = new value 82168482Spjd lock 83168675Spjd cmpxchgb %cl, (%edx) // try to stick it in 84168482Spjd jne 1b 85168675Spjd movzbl %cl, %eax // return new value 86168482Spjd ret 87168482Spjd SET_SIZE(atomic_inc_uchar_nv) 88168482Spjd SET_SIZE(atomic_inc_8_nv) 89168482Spjd 90168482Spjd ENTRY(atomic_inc_16_nv) 91168482Spjd ALTENTRY(atomic_inc_ushort_nv) 92168675Spjd movl 4(%esp), %edx // %edx = target address 93168675Spjd movw (%edx), %ax // %ax = old value 94168482Spjd1: 95168675Spjd leal 1(%eax), %ecx // %cx = new value 96168482Spjd lock 97168675Spjd cmpxchgw %cx, (%edx) // try to stick it in 98168482Spjd jne 1b 99168675Spjd movzwl %cx, %eax // return new value 100168482Spjd ret 101168482Spjd SET_SIZE(atomic_inc_ushort_nv) 102168482Spjd SET_SIZE(atomic_inc_16_nv) 103168482Spjd 104168482Spjd ENTRY(atomic_inc_32_nv) 105168482Spjd ALTENTRY(atomic_inc_uint_nv) 106168482Spjd ALTENTRY(atomic_inc_ulong_nv) 107168675Spjd movl 4(%esp), %edx // %edx = target address 108168675Spjd movl (%edx), %eax // %eax = old value 109168482Spjd1: 110168675Spjd leal 1(%eax), %ecx // %ecx = new value 111168482Spjd lock 112168675Spjd cmpxchgl %ecx, (%edx) // try to stick it in 113168482Spjd jne 1b 114168675Spjd movl %ecx, %eax // return new value 115168482Spjd ret 116168482Spjd SET_SIZE(atomic_inc_ulong_nv) 117168482Spjd SET_SIZE(atomic_inc_uint_nv) 118168482Spjd SET_SIZE(atomic_inc_32_nv) 119168482Spjd 120168482Spjd ENTRY(atomic_inc_64) 121168482Spjd ALTENTRY(atomic_inc_64_nv) 122168482Spjd pushl %edi 123168482Spjd pushl %ebx 124168675Spjd movl 12(%esp), %edi // %edi = target address 125168482Spjd movl (%edi), %eax 126168675Spjd movl 4(%edi), %edx // %edx:%eax = old value 127168482Spjd1: 128168482Spjd xorl %ebx, %ebx 129168482Spjd xorl %ecx, %ecx 130168675Spjd incl %ebx // %ecx:%ebx = 1 131168482Spjd addl %eax, %ebx 132168675Spjd adcl %edx, %ecx // add in the carry from inc 133168482Spjd lock 134168675Spjd cmpxchg8b (%edi) // try to stick it in 135168482Spjd jne 1b 136168482Spjd movl %ebx, %eax 137168675Spjd movl %ecx, %edx // return new value 138168482Spjd popl %ebx 139168482Spjd popl %edi 140168482Spjd ret 141168482Spjd SET_SIZE(atomic_inc_64_nv) 142168482Spjd SET_SIZE(atomic_inc_64) 143168482Spjd 144168482Spjd ENTRY(atomic_dec_8) 145168482Spjd ALTENTRY(atomic_dec_uchar) 146168482Spjd movl 4(%esp), %eax 147168482Spjd lock 148168482Spjd decb (%eax) 149168482Spjd ret 150168482Spjd SET_SIZE(atomic_dec_uchar) 151168482Spjd SET_SIZE(atomic_dec_8) 152168482Spjd 153168482Spjd ENTRY(atomic_dec_16) 154168482Spjd ALTENTRY(atomic_dec_ushort) 155168482Spjd movl 4(%esp), %eax 156168482Spjd lock 157168482Spjd decw (%eax) 158168482Spjd ret 159168482Spjd SET_SIZE(atomic_dec_ushort) 160168482Spjd SET_SIZE(atomic_dec_16) 161168482Spjd 162168482Spjd ENTRY(atomic_dec_32) 163168482Spjd ALTENTRY(atomic_dec_uint) 164168482Spjd ALTENTRY(atomic_dec_ulong) 165168482Spjd movl 4(%esp), %eax 166168482Spjd lock 167168482Spjd decl (%eax) 168168482Spjd ret 169168482Spjd SET_SIZE(atomic_dec_ulong) 170168482Spjd SET_SIZE(atomic_dec_uint) 171168482Spjd SET_SIZE(atomic_dec_32) 172168482Spjd 173168482Spjd ENTRY(atomic_dec_8_nv) 174168482Spjd ALTENTRY(atomic_dec_uchar_nv) 175168675Spjd movl 4(%esp), %edx // %edx = target address 176168675Spjd movb (%edx), %al // %al = old value 177168482Spjd1: 178168675Spjd leal -1(%eax), %ecx // %cl = new value 179168482Spjd lock 180168675Spjd cmpxchgb %cl, (%edx) // try to stick it in 181168482Spjd jne 1b 182168675Spjd movzbl %cl, %eax // return new value 183168482Spjd ret 184168482Spjd SET_SIZE(atomic_dec_uchar_nv) 185168482Spjd SET_SIZE(atomic_dec_8_nv) 186168482Spjd 187168482Spjd ENTRY(atomic_dec_16_nv) 188168482Spjd ALTENTRY(atomic_dec_ushort_nv) 189168675Spjd movl 4(%esp), %edx // %edx = target address 190168675Spjd movw (%edx), %ax // %ax = old value 191168482Spjd1: 192168675Spjd leal -1(%eax), %ecx // %cx = new value 193168482Spjd lock 194168675Spjd cmpxchgw %cx, (%edx) // try to stick it in 195168482Spjd jne 1b 196168675Spjd movzwl %cx, %eax // return new value 197168482Spjd ret 198168482Spjd SET_SIZE(atomic_dec_ushort_nv) 199168482Spjd SET_SIZE(atomic_dec_16_nv) 200168482Spjd 201168482Spjd ENTRY(atomic_dec_32_nv) 202168482Spjd ALTENTRY(atomic_dec_uint_nv) 203168482Spjd ALTENTRY(atomic_dec_ulong_nv) 204168675Spjd movl 4(%esp), %edx // %edx = target address 205168675Spjd movl (%edx), %eax // %eax = old value 206168482Spjd1: 207168675Spjd leal -1(%eax), %ecx // %ecx = new value 208168482Spjd lock 209168675Spjd cmpxchgl %ecx, (%edx) // try to stick it in 210168482Spjd jne 1b 211168675Spjd movl %ecx, %eax // return new value 212168482Spjd ret 213168482Spjd SET_SIZE(atomic_dec_ulong_nv) 214168482Spjd SET_SIZE(atomic_dec_uint_nv) 215168482Spjd SET_SIZE(atomic_dec_32_nv) 216168482Spjd 217168482Spjd ENTRY(atomic_dec_64) 218168482Spjd ALTENTRY(atomic_dec_64_nv) 219168482Spjd pushl %edi 220168482Spjd pushl %ebx 221168675Spjd movl 12(%esp), %edi // %edi = target address 222168482Spjd movl (%edi), %eax 223168675Spjd movl 4(%edi), %edx // %edx:%eax = old value 224168482Spjd1: 225168482Spjd xorl %ebx, %ebx 226168482Spjd xorl %ecx, %ecx 227168482Spjd not %ecx 228168675Spjd not %ebx // %ecx:%ebx = -1 229168482Spjd addl %eax, %ebx 230168675Spjd adcl %edx, %ecx // add in the carry from inc 231168482Spjd lock 232168675Spjd cmpxchg8b (%edi) // try to stick it in 233168482Spjd jne 1b 234168482Spjd movl %ebx, %eax 235168675Spjd movl %ecx, %edx // return new value 236168482Spjd popl %ebx 237168482Spjd popl %edi 238168482Spjd ret 239168482Spjd SET_SIZE(atomic_dec_64_nv) 240168482Spjd SET_SIZE(atomic_dec_64) 241168482Spjd 242168482Spjd ENTRY(atomic_or_8) 243168482Spjd ALTENTRY(atomic_or_uchar) 244168482Spjd movl 4(%esp), %eax 245168482Spjd movb 8(%esp), %cl 246168482Spjd lock 247168482Spjd orb %cl, (%eax) 248168482Spjd ret 249168482Spjd SET_SIZE(atomic_or_uchar) 250168482Spjd SET_SIZE(atomic_or_8) 251168482Spjd 252168482Spjd ENTRY(atomic_or_16) 253168482Spjd ALTENTRY(atomic_or_ushort) 254168482Spjd movl 4(%esp), %eax 255168482Spjd movw 8(%esp), %cx 256168482Spjd lock 257168482Spjd orw %cx, (%eax) 258168482Spjd ret 259168482Spjd SET_SIZE(atomic_or_ushort) 260168482Spjd SET_SIZE(atomic_or_16) 261168482Spjd 262168482Spjd ENTRY(atomic_or_32) 263168482Spjd ALTENTRY(atomic_or_uint) 264168482Spjd ALTENTRY(atomic_or_ulong) 265168482Spjd movl 4(%esp), %eax 266168482Spjd movl 8(%esp), %ecx 267168482Spjd lock 268168482Spjd orl %ecx, (%eax) 269168482Spjd ret 270168482Spjd SET_SIZE(atomic_or_ulong) 271168482Spjd SET_SIZE(atomic_or_uint) 272168482Spjd SET_SIZE(atomic_or_32) 273168482Spjd 274168482Spjd ENTRY(atomic_and_8) 275168482Spjd ALTENTRY(atomic_and_uchar) 276168482Spjd movl 4(%esp), %eax 277168482Spjd movb 8(%esp), %cl 278168482Spjd lock 279168482Spjd andb %cl, (%eax) 280168482Spjd ret 281168482Spjd SET_SIZE(atomic_and_uchar) 282168482Spjd SET_SIZE(atomic_and_8) 283168482Spjd 284168482Spjd ENTRY(atomic_and_16) 285168482Spjd ALTENTRY(atomic_and_ushort) 286168482Spjd movl 4(%esp), %eax 287168482Spjd movw 8(%esp), %cx 288168482Spjd lock 289168482Spjd andw %cx, (%eax) 290168482Spjd ret 291168482Spjd SET_SIZE(atomic_and_ushort) 292168482Spjd SET_SIZE(atomic_and_16) 293168482Spjd 294168482Spjd ENTRY(atomic_and_32) 295168482Spjd ALTENTRY(atomic_and_uint) 296168482Spjd ALTENTRY(atomic_and_ulong) 297168482Spjd movl 4(%esp), %eax 298168482Spjd movl 8(%esp), %ecx 299168482Spjd lock 300168482Spjd andl %ecx, (%eax) 301168482Spjd ret 302168482Spjd SET_SIZE(atomic_and_ulong) 303168482Spjd SET_SIZE(atomic_and_uint) 304168482Spjd SET_SIZE(atomic_and_32) 305168482Spjd 306168482Spjd ENTRY(atomic_add_8_nv) 307168482Spjd ALTENTRY(atomic_add_char_nv) 308168675Spjd movl 4(%esp), %edx // %edx = target address 309168675Spjd movb (%edx), %al // %al = old value 310168482Spjd1: 311168675Spjd movl 8(%esp), %ecx // %ecx = delta 312168675Spjd addb %al, %cl // %cl = new value 313168482Spjd lock 314168675Spjd cmpxchgb %cl, (%edx) // try to stick it in 315168482Spjd jne 1b 316168675Spjd movzbl %cl, %eax // return new value 317168482Spjd ret 318168482Spjd SET_SIZE(atomic_add_char_nv) 319168482Spjd SET_SIZE(atomic_add_8_nv) 320168482Spjd 321168482Spjd ENTRY(atomic_add_16_nv) 322168482Spjd ALTENTRY(atomic_add_short_nv) 323168675Spjd movl 4(%esp), %edx // %edx = target address 324168675Spjd movw (%edx), %ax // %ax = old value 325168482Spjd1: 326168675Spjd movl 8(%esp), %ecx // %ecx = delta 327168675Spjd addw %ax, %cx // %cx = new value 328168482Spjd lock 329168675Spjd cmpxchgw %cx, (%edx) // try to stick it in 330168482Spjd jne 1b 331168675Spjd movzwl %cx, %eax // return new value 332168482Spjd ret 333168482Spjd SET_SIZE(atomic_add_short_nv) 334168482Spjd SET_SIZE(atomic_add_16_nv) 335168482Spjd 336168482Spjd ENTRY(atomic_add_32_nv) 337168482Spjd ALTENTRY(atomic_add_int_nv) 338168482Spjd ALTENTRY(atomic_add_ptr_nv) 339168482Spjd ALTENTRY(atomic_add_long_nv) 340168675Spjd movl 4(%esp), %edx // %edx = target address 341168675Spjd movl (%edx), %eax // %eax = old value 342168482Spjd1: 343168675Spjd movl 8(%esp), %ecx // %ecx = delta 344168675Spjd addl %eax, %ecx // %ecx = new value 345168482Spjd lock 346168675Spjd cmpxchgl %ecx, (%edx) // try to stick it in 347168482Spjd jne 1b 348168675Spjd movl %ecx, %eax // return new value 349168482Spjd ret 350168482Spjd SET_SIZE(atomic_add_long_nv) 351168482Spjd SET_SIZE(atomic_add_ptr_nv) 352168482Spjd SET_SIZE(atomic_add_int_nv) 353168482Spjd SET_SIZE(atomic_add_32_nv) 354168482Spjd 355168482Spjd ENTRY(atomic_add_64) 356168482Spjd ALTENTRY(atomic_add_64_nv) 357168482Spjd pushl %edi 358168482Spjd pushl %ebx 359168675Spjd movl 12(%esp), %edi // %edi = target address 360168482Spjd movl (%edi), %eax 361168675Spjd movl 4(%edi), %edx // %edx:%eax = old value 362168482Spjd1: 363168482Spjd movl 16(%esp), %ebx 364168675Spjd movl 20(%esp), %ecx // %ecx:%ebx = delta 365168482Spjd addl %eax, %ebx 366168675Spjd adcl %edx, %ecx // %ecx:%ebx = new value 367168482Spjd lock 368168675Spjd cmpxchg8b (%edi) // try to stick it in 369168482Spjd jne 1b 370168482Spjd movl %ebx, %eax 371168675Spjd movl %ecx, %edx // return new value 372168482Spjd popl %ebx 373168482Spjd popl %edi 374168482Spjd ret 375168482Spjd SET_SIZE(atomic_add_64_nv) 376168482Spjd SET_SIZE(atomic_add_64) 377168482Spjd 378168482Spjd ENTRY(atomic_or_8_nv) 379168482Spjd ALTENTRY(atomic_or_uchar_nv) 380168675Spjd movl 4(%esp), %edx // %edx = target address 381168675Spjd movb (%edx), %al // %al = old value 382168482Spjd1: 383168675Spjd movl 8(%esp), %ecx // %ecx = delta 384168675Spjd orb %al, %cl // %cl = new value 385168482Spjd lock 386168675Spjd cmpxchgb %cl, (%edx) // try to stick it in 387168482Spjd jne 1b 388168675Spjd movzbl %cl, %eax // return new value 389168482Spjd ret 390168482Spjd SET_SIZE(atomic_or_uchar_nv) 391168482Spjd SET_SIZE(atomic_or_8_nv) 392168482Spjd 393168482Spjd ENTRY(atomic_or_16_nv) 394168482Spjd ALTENTRY(atomic_or_ushort_nv) 395168675Spjd movl 4(%esp), %edx // %edx = target address 396168675Spjd movw (%edx), %ax // %ax = old value 397168482Spjd1: 398168675Spjd movl 8(%esp), %ecx // %ecx = delta 399168675Spjd orw %ax, %cx // %cx = new value 400168482Spjd lock 401168675Spjd cmpxchgw %cx, (%edx) // try to stick it in 402168482Spjd jne 1b 403168675Spjd movzwl %cx, %eax // return new value 404168482Spjd ret 405168482Spjd SET_SIZE(atomic_or_ushort_nv) 406168482Spjd SET_SIZE(atomic_or_16_nv) 407168482Spjd 408168482Spjd ENTRY(atomic_or_32_nv) 409168482Spjd ALTENTRY(atomic_or_uint_nv) 410168482Spjd ALTENTRY(atomic_or_ulong_nv) 411168675Spjd movl 4(%esp), %edx // %edx = target address 412168675Spjd movl (%edx), %eax // %eax = old value 413168482Spjd1: 414168675Spjd movl 8(%esp), %ecx // %ecx = delta 415168675Spjd orl %eax, %ecx // %ecx = new value 416168482Spjd lock 417168675Spjd cmpxchgl %ecx, (%edx) // try to stick it in 418168482Spjd jne 1b 419168675Spjd movl %ecx, %eax // return new value 420168482Spjd ret 421168482Spjd SET_SIZE(atomic_or_ulong_nv) 422168482Spjd SET_SIZE(atomic_or_uint_nv) 423168482Spjd SET_SIZE(atomic_or_32_nv) 424168482Spjd 425168482Spjd ENTRY(atomic_or_64) 426168482Spjd ALTENTRY(atomic_or_64_nv) 427168482Spjd pushl %edi 428168482Spjd pushl %ebx 429168675Spjd movl 12(%esp), %edi // %edi = target address 430168482Spjd movl (%edi), %eax 431168675Spjd movl 4(%edi), %edx // %edx:%eax = old value 432168482Spjd1: 433168482Spjd movl 16(%esp), %ebx 434168675Spjd movl 20(%esp), %ecx // %ecx:%ebx = delta 435168482Spjd orl %eax, %ebx 436168675Spjd orl %edx, %ecx // %ecx:%ebx = new value 437168482Spjd lock 438168675Spjd cmpxchg8b (%edi) // try to stick it in 439168482Spjd jne 1b 440168482Spjd movl %ebx, %eax 441168675Spjd movl %ecx, %edx // return new value 442168482Spjd popl %ebx 443168482Spjd popl %edi 444168482Spjd ret 445168482Spjd SET_SIZE(atomic_or_64_nv) 446168482Spjd SET_SIZE(atomic_or_64) 447168482Spjd 448168482Spjd ENTRY(atomic_and_8_nv) 449168482Spjd ALTENTRY(atomic_and_uchar_nv) 450168675Spjd movl 4(%esp), %edx // %edx = target address 451168675Spjd movb (%edx), %al // %al = old value 452168482Spjd1: 453168675Spjd movl 8(%esp), %ecx // %ecx = delta 454168675Spjd andb %al, %cl // %cl = new value 455168482Spjd lock 456168675Spjd cmpxchgb %cl, (%edx) // try to stick it in 457168482Spjd jne 1b 458168675Spjd movzbl %cl, %eax // return new value 459168482Spjd ret 460168482Spjd SET_SIZE(atomic_and_uchar_nv) 461168482Spjd SET_SIZE(atomic_and_8_nv) 462168482Spjd 463168482Spjd ENTRY(atomic_and_16_nv) 464168482Spjd ALTENTRY(atomic_and_ushort_nv) 465168675Spjd movl 4(%esp), %edx // %edx = target address 466168675Spjd movw (%edx), %ax // %ax = old value 467168482Spjd1: 468168675Spjd movl 8(%esp), %ecx // %ecx = delta 469168675Spjd andw %ax, %cx // %cx = new value 470168482Spjd lock 471168675Spjd cmpxchgw %cx, (%edx) // try to stick it in 472168482Spjd jne 1b 473168675Spjd movzwl %cx, %eax // return new value 474168482Spjd ret 475168482Spjd SET_SIZE(atomic_and_ushort_nv) 476168482Spjd SET_SIZE(atomic_and_16_nv) 477168482Spjd 478168482Spjd ENTRY(atomic_and_32_nv) 479168482Spjd ALTENTRY(atomic_and_uint_nv) 480168482Spjd ALTENTRY(atomic_and_ulong_nv) 481168675Spjd movl 4(%esp), %edx // %edx = target address 482168675Spjd movl (%edx), %eax // %eax = old value 483168482Spjd1: 484168675Spjd movl 8(%esp), %ecx // %ecx = delta 485168675Spjd andl %eax, %ecx // %ecx = new value 486168482Spjd lock 487168675Spjd cmpxchgl %ecx, (%edx) // try to stick it in 488168482Spjd jne 1b 489168675Spjd movl %ecx, %eax // return new value 490168482Spjd ret 491168482Spjd SET_SIZE(atomic_and_ulong_nv) 492168482Spjd SET_SIZE(atomic_and_uint_nv) 493168482Spjd SET_SIZE(atomic_and_32_nv) 494168482Spjd 495168482Spjd ENTRY(atomic_and_64) 496168482Spjd ALTENTRY(atomic_and_64_nv) 497168482Spjd pushl %edi 498168482Spjd pushl %ebx 499168675Spjd movl 12(%esp), %edi // %edi = target address 500168482Spjd movl (%edi), %eax 501168675Spjd movl 4(%edi), %edx // %edx:%eax = old value 502168482Spjd1: 503168482Spjd movl 16(%esp), %ebx 504168675Spjd movl 20(%esp), %ecx // %ecx:%ebx = delta 505168482Spjd andl %eax, %ebx 506168675Spjd andl %edx, %ecx // %ecx:%ebx = new value 507168482Spjd lock 508168675Spjd cmpxchg8b (%edi) // try to stick it in 509168482Spjd jne 1b 510168482Spjd movl %ebx, %eax 511168675Spjd movl %ecx, %edx // return new value 512168482Spjd popl %ebx 513168482Spjd popl %edi 514168482Spjd ret 515168482Spjd SET_SIZE(atomic_and_64_nv) 516168482Spjd SET_SIZE(atomic_and_64) 517168482Spjd 518168482Spjd ENTRY(atomic_cas_8) 519168482Spjd ALTENTRY(atomic_cas_uchar) 520168482Spjd movl 4(%esp), %edx 521168482Spjd movzbl 8(%esp), %eax 522168482Spjd movb 12(%esp), %cl 523168482Spjd lock 524168482Spjd cmpxchgb %cl, (%edx) 525168482Spjd ret 526168482Spjd SET_SIZE(atomic_cas_uchar) 527168482Spjd SET_SIZE(atomic_cas_8) 528168482Spjd 529168482Spjd ENTRY(atomic_cas_16) 530168482Spjd ALTENTRY(atomic_cas_ushort) 531168482Spjd movl 4(%esp), %edx 532168482Spjd movzwl 8(%esp), %eax 533168482Spjd movw 12(%esp), %cx 534168482Spjd lock 535168482Spjd cmpxchgw %cx, (%edx) 536168482Spjd ret 537168482Spjd SET_SIZE(atomic_cas_ushort) 538168482Spjd SET_SIZE(atomic_cas_16) 539168482Spjd 540168482Spjd ENTRY(atomic_cas_32) 541168482Spjd ALTENTRY(atomic_cas_uint) 542168482Spjd ALTENTRY(atomic_cas_ulong) 543168482Spjd ALTENTRY(atomic_cas_ptr) 544168482Spjd movl 4(%esp), %edx 545168482Spjd movl 8(%esp), %eax 546168482Spjd movl 12(%esp), %ecx 547168482Spjd lock 548168482Spjd cmpxchgl %ecx, (%edx) 549168482Spjd ret 550168482Spjd SET_SIZE(atomic_cas_ptr) 551168482Spjd SET_SIZE(atomic_cas_ulong) 552168482Spjd SET_SIZE(atomic_cas_uint) 553168482Spjd SET_SIZE(atomic_cas_32) 554168482Spjd 555168482Spjd ENTRY(atomic_cas_64) 556168482Spjd pushl %ebx 557168482Spjd pushl %esi 558168482Spjd movl 12(%esp), %esi 559168482Spjd movl 16(%esp), %eax 560168482Spjd movl 20(%esp), %edx 561168482Spjd movl 24(%esp), %ebx 562168482Spjd movl 28(%esp), %ecx 563168482Spjd lock 564168482Spjd cmpxchg8b (%esi) 565168482Spjd popl %esi 566168482Spjd popl %ebx 567168482Spjd ret 568168482Spjd SET_SIZE(atomic_cas_64) 569168482Spjd 570168482Spjd ENTRY(atomic_swap_8) 571168482Spjd ALTENTRY(atomic_swap_uchar) 572168482Spjd movl 4(%esp), %edx 573168482Spjd movzbl 8(%esp), %eax 574168482Spjd lock 575168482Spjd xchgb %al, (%edx) 576168482Spjd ret 577168482Spjd SET_SIZE(atomic_swap_uchar) 578168482Spjd SET_SIZE(atomic_swap_8) 579168482Spjd 580168482Spjd ENTRY(atomic_swap_16) 581168482Spjd ALTENTRY(atomic_swap_ushort) 582168482Spjd movl 4(%esp), %edx 583168482Spjd movzwl 8(%esp), %eax 584168482Spjd lock 585168482Spjd xchgw %ax, (%edx) 586168482Spjd ret 587168482Spjd SET_SIZE(atomic_swap_ushort) 588168482Spjd SET_SIZE(atomic_swap_16) 589168482Spjd 590168482Spjd ENTRY(atomic_swap_32) 591168482Spjd ALTENTRY(atomic_swap_uint) 592168482Spjd ALTENTRY(atomic_swap_ptr) 593168482Spjd ALTENTRY(atomic_swap_ulong) 594168482Spjd movl 4(%esp), %edx 595168482Spjd movl 8(%esp), %eax 596168482Spjd lock 597168482Spjd xchgl %eax, (%edx) 598168482Spjd ret 599168482Spjd SET_SIZE(atomic_swap_ulong) 600168482Spjd SET_SIZE(atomic_swap_ptr) 601168482Spjd SET_SIZE(atomic_swap_uint) 602168482Spjd SET_SIZE(atomic_swap_32) 603168482Spjd 604168482Spjd ENTRY(atomic_swap_64) 605168482Spjd pushl %esi 606168482Spjd pushl %ebx 607168482Spjd movl 12(%esp), %esi 608168482Spjd movl 16(%esp), %ebx 609168482Spjd movl 20(%esp), %ecx 610168482Spjd movl (%esi), %eax 611168675Spjd movl 4(%esi), %edx // %edx:%eax = old value 612168482Spjd1: 613168482Spjd lock 614168482Spjd cmpxchg8b (%esi) 615168482Spjd jne 1b 616168482Spjd popl %ebx 617168482Spjd popl %esi 618168482Spjd ret 619168482Spjd SET_SIZE(atomic_swap_64) 620168482Spjd 621168482Spjd ENTRY(atomic_set_long_excl) 622168675Spjd movl 4(%esp), %edx // %edx = target address 623168675Spjd movl 8(%esp), %ecx // %ecx = bit id 624168482Spjd xorl %eax, %eax 625168482Spjd lock 626168482Spjd btsl %ecx, (%edx) 627168482Spjd jnc 1f 628168675Spjd decl %eax // return -1 629168482Spjd1: 630168482Spjd ret 631168482Spjd SET_SIZE(atomic_set_long_excl) 632168482Spjd 633168482Spjd ENTRY(atomic_clear_long_excl) 634168675Spjd movl 4(%esp), %edx // %edx = target address 635168675Spjd movl 8(%esp), %ecx // %ecx = bit id 636168482Spjd xorl %eax, %eax 637168482Spjd lock 638168482Spjd btrl %ecx, (%edx) 639168482Spjd jc 1f 640168675Spjd decl %eax // return -1 641168482Spjd1: 642168482Spjd ret 643168482Spjd SET_SIZE(atomic_clear_long_excl) 644168482Spjd 645168482Spjd ENTRY(membar_enter) 646168482Spjd ALTENTRY(membar_exit) 647168482Spjd ALTENTRY(membar_producer) 648168482Spjd ALTENTRY(membar_consumer) 649168482Spjd lock 650168482Spjd xorl $0, (%esp) 651168482Spjd ret 652168482Spjd SET_SIZE(membar_consumer) 653168482Spjd SET_SIZE(membar_producer) 654168482Spjd SET_SIZE(membar_exit) 655168482Spjd SET_SIZE(membar_enter) 656