1/*- 2 * Copyright (c) 1998 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * from: src/sys/alpha/include/atomic.h,v 1.21.2.3 2005/10/06 18:12:05 jhb 27 * $FreeBSD: stable/11/sys/mips/include/atomic.h 327195 2017-12-26 10:07:17Z kib $ 28 */ 29 30#ifndef _MACHINE_ATOMIC_H_ 31#define _MACHINE_ATOMIC_H_ 32 33#ifndef _SYS_CDEFS_H_ 34#error this file needs sys/cdefs.h as a prerequisite 35#endif 36 37#include <sys/atomic_common.h> 38 39/* 40 * Note: All the 64-bit atomic operations are only atomic when running 41 * in 64-bit mode. It is assumed that code compiled for n32 and n64 42 * fits into this definition and no further safeties are needed. 43 * 44 * It is also assumed that the add, subtract and other arithmetic is 45 * done on numbers not pointers. The special rules for n32 pointers 46 * do not have atomic operations defined for them, but generally shouldn't 47 * need atomic operations. 48 */ 49#ifndef __MIPS_PLATFORM_SYNC_NOPS 50#define __MIPS_PLATFORM_SYNC_NOPS "" 51#endif 52 53static __inline void 54mips_sync(void) 55{ 56 __asm __volatile (".set noreorder\n" 57 "\tsync\n" 58 __MIPS_PLATFORM_SYNC_NOPS 59 ".set reorder\n" 60 : : : "memory"); 61} 62 63#define mb() mips_sync() 64#define wmb() mips_sync() 65#define rmb() mips_sync() 66 67/* 68 * Various simple arithmetic on memory which is atomic in the presence 69 * of interrupts and SMP safe. 70 */ 71 72void atomic_set_8(__volatile uint8_t *, uint8_t); 73void atomic_clear_8(__volatile uint8_t *, uint8_t); 74void atomic_add_8(__volatile uint8_t *, uint8_t); 75void atomic_subtract_8(__volatile uint8_t *, uint8_t); 76 77void atomic_set_16(__volatile uint16_t *, uint16_t); 78void atomic_clear_16(__volatile uint16_t *, uint16_t); 79void atomic_add_16(__volatile uint16_t *, uint16_t); 80void atomic_subtract_16(__volatile uint16_t *, uint16_t); 81 82static __inline void 83atomic_set_32(__volatile uint32_t *p, uint32_t v) 84{ 85 uint32_t temp; 86 87 __asm __volatile ( 88 "1:\tll %0, %3\n\t" /* load old value */ 89 "or %0, %2, %0\n\t" /* calculate new value */ 90 "sc %0, %1\n\t" /* attempt to store */ 91 "beqz %0, 1b\n\t" /* spin if failed */ 92 : "=&r" (temp), "=m" (*p) 93 : "r" (v), "m" (*p) 94 : "memory"); 95 96} 97 98static __inline void 99atomic_clear_32(__volatile uint32_t *p, uint32_t v) 100{ 101 uint32_t temp; 102 v = ~v; 103 104 __asm __volatile ( 105 "1:\tll %0, %3\n\t" /* load old value */ 106 "and %0, %2, %0\n\t" /* calculate new value */ 107 "sc %0, %1\n\t" /* attempt to store */ 108 "beqz %0, 1b\n\t" /* spin if failed */ 109 : "=&r" (temp), "=m" (*p) 110 : "r" (v), "m" (*p) 111 : "memory"); 112} 113 114static __inline void 115atomic_add_32(__volatile uint32_t *p, uint32_t v) 116{ 117 uint32_t temp; 118 119 __asm __volatile ( 120 "1:\tll %0, %3\n\t" /* load old value */ 121 "addu %0, %2, %0\n\t" /* calculate new value */ 122 "sc %0, %1\n\t" /* attempt to store */ 123 "beqz %0, 1b\n\t" /* spin if failed */ 124 : "=&r" (temp), "=m" (*p) 125 : "r" (v), "m" (*p) 126 : "memory"); 127} 128 129static __inline void 130atomic_subtract_32(__volatile uint32_t *p, uint32_t v) 131{ 132 uint32_t temp; 133 134 __asm __volatile ( 135 "1:\tll %0, %3\n\t" /* load old value */ 136 "subu %0, %2\n\t" /* calculate new value */ 137 "sc %0, %1\n\t" /* attempt to store */ 138 "beqz %0, 1b\n\t" /* spin if failed */ 139 : "=&r" (temp), "=m" (*p) 140 : "r" (v), "m" (*p) 141 : "memory"); 142} 143 144static __inline uint32_t 145atomic_readandclear_32(__volatile uint32_t *addr) 146{ 147 uint32_t result,temp; 148 149 __asm __volatile ( 150 "1:\tll %0,%3\n\t" /* load current value, asserting lock */ 151 "li %1,0\n\t" /* value to store */ 152 "sc %1,%2\n\t" /* attempt to store */ 153 "beqz %1, 1b\n\t" /* if the store failed, spin */ 154 : "=&r"(result), "=&r"(temp), "=m" (*addr) 155 : "m" (*addr) 156 : "memory"); 157 158 return result; 159} 160 161static __inline uint32_t 162atomic_readandset_32(__volatile uint32_t *addr, uint32_t value) 163{ 164 uint32_t result,temp; 165 166 __asm __volatile ( 167 "1:\tll %0,%3\n\t" /* load current value, asserting lock */ 168 "or %1,$0,%4\n\t" 169 "sc %1,%2\n\t" /* attempt to store */ 170 "beqz %1, 1b\n\t" /* if the store failed, spin */ 171 : "=&r"(result), "=&r"(temp), "=m" (*addr) 172 : "m" (*addr), "r" (value) 173 : "memory"); 174 175 return result; 176} 177 178#if defined(__mips_n64) || defined(__mips_n32) 179static __inline void 180atomic_set_64(__volatile uint64_t *p, uint64_t v) 181{ 182 uint64_t temp; 183 184 __asm __volatile ( 185 "1:\n\t" 186 "lld %0, %3\n\t" /* load old value */ 187 "or %0, %2, %0\n\t" /* calculate new value */ 188 "scd %0, %1\n\t" /* attempt to store */ 189 "beqz %0, 1b\n\t" /* spin if failed */ 190 : "=&r" (temp), "=m" (*p) 191 : "r" (v), "m" (*p) 192 : "memory"); 193 194} 195 196static __inline void 197atomic_clear_64(__volatile uint64_t *p, uint64_t v) 198{ 199 uint64_t temp; 200 v = ~v; 201 202 __asm __volatile ( 203 "1:\n\t" 204 "lld %0, %3\n\t" /* load old value */ 205 "and %0, %2, %0\n\t" /* calculate new value */ 206 "scd %0, %1\n\t" /* attempt to store */ 207 "beqz %0, 1b\n\t" /* spin if failed */ 208 : "=&r" (temp), "=m" (*p) 209 : "r" (v), "m" (*p) 210 : "memory"); 211} 212 213static __inline void 214atomic_add_64(__volatile uint64_t *p, uint64_t v) 215{ 216 uint64_t temp; 217 218 __asm __volatile ( 219 "1:\n\t" 220 "lld %0, %3\n\t" /* load old value */ 221 "daddu %0, %2, %0\n\t" /* calculate new value */ 222 "scd %0, %1\n\t" /* attempt to store */ 223 "beqz %0, 1b\n\t" /* spin if failed */ 224 : "=&r" (temp), "=m" (*p) 225 : "r" (v), "m" (*p) 226 : "memory"); 227} 228 229static __inline void 230atomic_subtract_64(__volatile uint64_t *p, uint64_t v) 231{ 232 uint64_t temp; 233 234 __asm __volatile ( 235 "1:\n\t" 236 "lld %0, %3\n\t" /* load old value */ 237 "dsubu %0, %2\n\t" /* calculate new value */ 238 "scd %0, %1\n\t" /* attempt to store */ 239 "beqz %0, 1b\n\t" /* spin if failed */ 240 : "=&r" (temp), "=m" (*p) 241 : "r" (v), "m" (*p) 242 : "memory"); 243} 244 245static __inline uint64_t 246atomic_readandclear_64(__volatile uint64_t *addr) 247{ 248 uint64_t result,temp; 249 250 __asm __volatile ( 251 "1:\n\t" 252 "lld %0, %3\n\t" /* load old value */ 253 "li %1, 0\n\t" /* value to store */ 254 "scd %1, %2\n\t" /* attempt to store */ 255 "beqz %1, 1b\n\t" /* if the store failed, spin */ 256 : "=&r"(result), "=&r"(temp), "=m" (*addr) 257 : "m" (*addr) 258 : "memory"); 259 260 return result; 261} 262 263static __inline uint64_t 264atomic_readandset_64(__volatile uint64_t *addr, uint64_t value) 265{ 266 uint64_t result,temp; 267 268 __asm __volatile ( 269 "1:\n\t" 270 "lld %0,%3\n\t" /* Load old value*/ 271 "or %1,$0,%4\n\t" 272 "scd %1,%2\n\t" /* attempt to store */ 273 "beqz %1, 1b\n\t" /* if the store failed, spin */ 274 : "=&r"(result), "=&r"(temp), "=m" (*addr) 275 : "m" (*addr), "r" (value) 276 : "memory"); 277 278 return result; 279} 280#endif 281 282#define ATOMIC_ACQ_REL(NAME, WIDTH) \ 283static __inline void \ 284atomic_##NAME##_acq_##WIDTH(__volatile uint##WIDTH##_t *p, uint##WIDTH##_t v)\ 285{ \ 286 atomic_##NAME##_##WIDTH(p, v); \ 287 mips_sync(); \ 288} \ 289 \ 290static __inline void \ 291atomic_##NAME##_rel_##WIDTH(__volatile uint##WIDTH##_t *p, uint##WIDTH##_t v)\ 292{ \ 293 mips_sync(); \ 294 atomic_##NAME##_##WIDTH(p, v); \ 295} 296 297/* Variants of simple arithmetic with memory barriers. */ 298ATOMIC_ACQ_REL(set, 8) 299ATOMIC_ACQ_REL(clear, 8) 300ATOMIC_ACQ_REL(add, 8) 301ATOMIC_ACQ_REL(subtract, 8) 302ATOMIC_ACQ_REL(set, 16) 303ATOMIC_ACQ_REL(clear, 16) 304ATOMIC_ACQ_REL(add, 16) 305ATOMIC_ACQ_REL(subtract, 16) 306ATOMIC_ACQ_REL(set, 32) 307ATOMIC_ACQ_REL(clear, 32) 308ATOMIC_ACQ_REL(add, 32) 309ATOMIC_ACQ_REL(subtract, 32) 310#if defined(__mips_n64) || defined(__mips_n32) 311ATOMIC_ACQ_REL(set, 64) 312ATOMIC_ACQ_REL(clear, 64) 313ATOMIC_ACQ_REL(add, 64) 314ATOMIC_ACQ_REL(subtract, 64) 315#endif 316 317#undef ATOMIC_ACQ_REL 318 319/* 320 * We assume that a = b will do atomic loads and stores. 321 */ 322#define ATOMIC_STORE_LOAD(WIDTH) \ 323static __inline uint##WIDTH##_t \ 324atomic_load_acq_##WIDTH(__volatile uint##WIDTH##_t *p) \ 325{ \ 326 uint##WIDTH##_t v; \ 327 \ 328 v = *p; \ 329 mips_sync(); \ 330 return (v); \ 331} \ 332 \ 333static __inline void \ 334atomic_store_rel_##WIDTH(__volatile uint##WIDTH##_t *p, uint##WIDTH##_t v)\ 335{ \ 336 mips_sync(); \ 337 *p = v; \ 338} 339 340ATOMIC_STORE_LOAD(32) 341ATOMIC_STORE_LOAD(64) 342#undef ATOMIC_STORE_LOAD 343 344/* 345 * Atomically compare the value stored at *p with cmpval and if the 346 * two values are equal, update the value of *p with newval. Returns 347 * zero if the compare failed, nonzero otherwise. 348 */ 349static __inline uint32_t 350atomic_cmpset_32(__volatile uint32_t *p, uint32_t cmpval, uint32_t newval) 351{ 352 uint32_t ret; 353 354 __asm __volatile ( 355 "1:\tll %0, %4\n\t" /* load old value */ 356 "bne %0, %2, 2f\n\t" /* compare */ 357 "move %0, %3\n\t" /* value to store */ 358 "sc %0, %1\n\t" /* attempt to store */ 359 "beqz %0, 1b\n\t" /* if it failed, spin */ 360 "j 3f\n\t" 361 "2:\n\t" 362 "li %0, 0\n\t" 363 "3:\n" 364 : "=&r" (ret), "=m" (*p) 365 : "r" (cmpval), "r" (newval), "m" (*p) 366 : "memory"); 367 368 return ret; 369} 370 371/* 372 * Atomically compare the value stored at *p with cmpval and if the 373 * two values are equal, update the value of *p with newval. Returns 374 * zero if the compare failed, nonzero otherwise. 375 */ 376static __inline uint32_t 377atomic_cmpset_acq_32(__volatile uint32_t *p, uint32_t cmpval, uint32_t newval) 378{ 379 int retval; 380 381 retval = atomic_cmpset_32(p, cmpval, newval); 382 mips_sync(); 383 return (retval); 384} 385 386static __inline uint32_t 387atomic_cmpset_rel_32(__volatile uint32_t *p, uint32_t cmpval, uint32_t newval) 388{ 389 mips_sync(); 390 return (atomic_cmpset_32(p, cmpval, newval)); 391} 392 393static __inline uint32_t 394atomic_fcmpset_32(__volatile uint32_t *p, uint32_t *cmpval, uint32_t newval) 395{ 396 uint32_t ret; 397 398 __asm __volatile ( 399 "1:\n\t" 400 "ll %0, %1\n\t" /* load old value */ 401 "bne %0, %4, 2f\n\t" /* compare */ 402 "move %0, %3\n\t" /* value to store */ 403 "sc %0, %1\n\t" /* attempt to store */ 404 "beqz %0, 1b\n\t" /* if it failed, spin */ 405 "j 3f\n\t" 406 "2:\n\t" 407 "sw %0, %2\n\t" /* save old value */ 408 "li %0, 0\n\t" 409 "3:\n" 410 : "=&r" (ret), "+m" (*p), "=m" (*cmpval) 411 : "r" (newval), "r" (*cmpval) 412 : "memory"); 413 return ret; 414} 415 416static __inline uint32_t 417atomic_fcmpset_acq_32(__volatile uint32_t *p, uint32_t *cmpval, uint32_t newval) 418{ 419 int retval; 420 421 retval = atomic_fcmpset_32(p, cmpval, newval); 422 mips_sync(); 423 return (retval); 424} 425 426static __inline uint32_t 427atomic_fcmpset_rel_32(__volatile uint32_t *p, uint32_t *cmpval, uint32_t newval) 428{ 429 mips_sync(); 430 return (atomic_fcmpset_32(p, cmpval, newval)); 431} 432 433/* 434 * Atomically add the value of v to the integer pointed to by p and return 435 * the previous value of *p. 436 */ 437static __inline uint32_t 438atomic_fetchadd_32(__volatile uint32_t *p, uint32_t v) 439{ 440 uint32_t value, temp; 441 442 __asm __volatile ( 443 "1:\tll %0, %1\n\t" /* load old value */ 444 "addu %2, %3, %0\n\t" /* calculate new value */ 445 "sc %2, %1\n\t" /* attempt to store */ 446 "beqz %2, 1b\n\t" /* spin if failed */ 447 : "=&r" (value), "=m" (*p), "=&r" (temp) 448 : "r" (v), "m" (*p)); 449 return (value); 450} 451 452#if defined(__mips_n64) || defined(__mips_n32) 453/* 454 * Atomically compare the value stored at *p with cmpval and if the 455 * two values are equal, update the value of *p with newval. Returns 456 * zero if the compare failed, nonzero otherwise. 457 */ 458static __inline uint64_t 459atomic_cmpset_64(__volatile uint64_t *p, uint64_t cmpval, uint64_t newval) 460{ 461 uint64_t ret; 462 463 __asm __volatile ( 464 "1:\n\t" 465 "lld %0, %4\n\t" /* load old value */ 466 "bne %0, %2, 2f\n\t" /* compare */ 467 "move %0, %3\n\t" /* value to store */ 468 "scd %0, %1\n\t" /* attempt to store */ 469 "beqz %0, 1b\n\t" /* if it failed, spin */ 470 "j 3f\n\t" 471 "2:\n\t" 472 "li %0, 0\n\t" 473 "3:\n" 474 : "=&r" (ret), "=m" (*p) 475 : "r" (cmpval), "r" (newval), "m" (*p) 476 : "memory"); 477 478 return ret; 479} 480 481/* 482 * Atomically compare the value stored at *p with cmpval and if the 483 * two values are equal, update the value of *p with newval. Returns 484 * zero if the compare failed, nonzero otherwise. 485 */ 486static __inline uint64_t 487atomic_cmpset_acq_64(__volatile uint64_t *p, uint64_t cmpval, uint64_t newval) 488{ 489 int retval; 490 491 retval = atomic_cmpset_64(p, cmpval, newval); 492 mips_sync(); 493 return (retval); 494} 495 496static __inline uint64_t 497atomic_cmpset_rel_64(__volatile uint64_t *p, uint64_t cmpval, uint64_t newval) 498{ 499 mips_sync(); 500 return (atomic_cmpset_64(p, cmpval, newval)); 501} 502 503static __inline uint32_t 504atomic_fcmpset_64(__volatile uint64_t *p, uint64_t *cmpval, uint64_t newval) 505{ 506 uint32_t ret; 507 508 __asm __volatile ( 509 "1:\n\t" 510 "lld %0, %1\n\t" /* load old value */ 511 "bne %0, %4, 2f\n\t" /* compare */ 512 "move %0, %3\n\t" /* value to store */ 513 "scd %0, %1\n\t" /* attempt to store */ 514 "beqz %0, 1b\n\t" /* if it failed, spin */ 515 "j 3f\n\t" 516 "2:\n\t" 517 "sd %0, %2\n\t" /* save old value */ 518 "li %0, 0\n\t" 519 "3:\n" 520 : "=&r" (ret), "+m" (*p), "=m" (*cmpval) 521 : "r" (newval), "r" (*cmpval) 522 : "memory"); 523 524 return ret; 525} 526 527static __inline uint64_t 528atomic_fcmpset_acq_64(__volatile uint64_t *p, uint64_t *cmpval, uint64_t newval) 529{ 530 int retval; 531 532 retval = atomic_fcmpset_64(p, cmpval, newval); 533 mips_sync(); 534 return (retval); 535} 536 537static __inline uint64_t 538atomic_fcmpset_rel_64(__volatile uint64_t *p, uint64_t *cmpval, uint64_t newval) 539{ 540 mips_sync(); 541 return (atomic_fcmpset_64(p, cmpval, newval)); 542} 543 544/* 545 * Atomically add the value of v to the integer pointed to by p and return 546 * the previous value of *p. 547 */ 548static __inline uint64_t 549atomic_fetchadd_64(__volatile uint64_t *p, uint64_t v) 550{ 551 uint64_t value, temp; 552 553 __asm __volatile ( 554 "1:\n\t" 555 "lld %0, %1\n\t" /* load old value */ 556 "daddu %2, %3, %0\n\t" /* calculate new value */ 557 "scd %2, %1\n\t" /* attempt to store */ 558 "beqz %2, 1b\n\t" /* spin if failed */ 559 : "=&r" (value), "=m" (*p), "=&r" (temp) 560 : "r" (v), "m" (*p)); 561 return (value); 562} 563#endif 564 565static __inline void 566atomic_thread_fence_acq(void) 567{ 568 569 mips_sync(); 570} 571 572static __inline void 573atomic_thread_fence_rel(void) 574{ 575 576 mips_sync(); 577} 578 579static __inline void 580atomic_thread_fence_acq_rel(void) 581{ 582 583 mips_sync(); 584} 585 586static __inline void 587atomic_thread_fence_seq_cst(void) 588{ 589 590 mips_sync(); 591} 592 593/* Operations on chars. */ 594#define atomic_set_char atomic_set_8 595#define atomic_set_acq_char atomic_set_acq_8 596#define atomic_set_rel_char atomic_set_rel_8 597#define atomic_clear_char atomic_clear_8 598#define atomic_clear_acq_char atomic_clear_acq_8 599#define atomic_clear_rel_char atomic_clear_rel_8 600#define atomic_add_char atomic_add_8 601#define atomic_add_acq_char atomic_add_acq_8 602#define atomic_add_rel_char atomic_add_rel_8 603#define atomic_subtract_char atomic_subtract_8 604#define atomic_subtract_acq_char atomic_subtract_acq_8 605#define atomic_subtract_rel_char atomic_subtract_rel_8 606 607/* Operations on shorts. */ 608#define atomic_set_short atomic_set_16 609#define atomic_set_acq_short atomic_set_acq_16 610#define atomic_set_rel_short atomic_set_rel_16 611#define atomic_clear_short atomic_clear_16 612#define atomic_clear_acq_short atomic_clear_acq_16 613#define atomic_clear_rel_short atomic_clear_rel_16 614#define atomic_add_short atomic_add_16 615#define atomic_add_acq_short atomic_add_acq_16 616#define atomic_add_rel_short atomic_add_rel_16 617#define atomic_subtract_short atomic_subtract_16 618#define atomic_subtract_acq_short atomic_subtract_acq_16 619#define atomic_subtract_rel_short atomic_subtract_rel_16 620 621/* Operations on ints. */ 622#define atomic_set_int atomic_set_32 623#define atomic_set_acq_int atomic_set_acq_32 624#define atomic_set_rel_int atomic_set_rel_32 625#define atomic_clear_int atomic_clear_32 626#define atomic_clear_acq_int atomic_clear_acq_32 627#define atomic_clear_rel_int atomic_clear_rel_32 628#define atomic_add_int atomic_add_32 629#define atomic_add_acq_int atomic_add_acq_32 630#define atomic_add_rel_int atomic_add_rel_32 631#define atomic_subtract_int atomic_subtract_32 632#define atomic_subtract_acq_int atomic_subtract_acq_32 633#define atomic_subtract_rel_int atomic_subtract_rel_32 634#define atomic_cmpset_int atomic_cmpset_32 635#define atomic_cmpset_acq_int atomic_cmpset_acq_32 636#define atomic_cmpset_rel_int atomic_cmpset_rel_32 637#define atomic_fcmpset_int atomic_fcmpset_32 638#define atomic_fcmpset_acq_int atomic_fcmpset_acq_32 639#define atomic_fcmpset_rel_int atomic_fcmpset_rel_32 640#define atomic_load_acq_int atomic_load_acq_32 641#define atomic_store_rel_int atomic_store_rel_32 642#define atomic_readandclear_int atomic_readandclear_32 643#define atomic_readandset_int atomic_readandset_32 644#define atomic_fetchadd_int atomic_fetchadd_32 645 646/* 647 * I think the following is right, even for n32. For n32 the pointers 648 * are still 32-bits, so we need to operate on them as 32-bit quantities, 649 * even though they are sign extended in operation. For longs, there's 650 * no question because they are always 32-bits. 651 */ 652#ifdef __mips_n64 653/* Operations on longs. */ 654#define atomic_set_long atomic_set_64 655#define atomic_set_acq_long atomic_set_acq_64 656#define atomic_set_rel_long atomic_set_rel_64 657#define atomic_clear_long atomic_clear_64 658#define atomic_clear_acq_long atomic_clear_acq_64 659#define atomic_clear_rel_long atomic_clear_rel_64 660#define atomic_add_long atomic_add_64 661#define atomic_add_acq_long atomic_add_acq_64 662#define atomic_add_rel_long atomic_add_rel_64 663#define atomic_subtract_long atomic_subtract_64 664#define atomic_subtract_acq_long atomic_subtract_acq_64 665#define atomic_subtract_rel_long atomic_subtract_rel_64 666#define atomic_cmpset_long atomic_cmpset_64 667#define atomic_cmpset_acq_long atomic_cmpset_acq_64 668#define atomic_cmpset_rel_long atomic_cmpset_rel_64 669#define atomic_fcmpset_long atomic_fcmpset_64 670#define atomic_fcmpset_acq_long atomic_fcmpset_acq_64 671#define atomic_fcmpset_rel_long atomic_fcmpset_rel_64 672#define atomic_load_acq_long atomic_load_acq_64 673#define atomic_store_rel_long atomic_store_rel_64 674#define atomic_fetchadd_long atomic_fetchadd_64 675#define atomic_readandclear_long atomic_readandclear_64 676 677#else /* !__mips_n64 */ 678 679/* Operations on longs. */ 680#define atomic_set_long(p, v) \ 681 atomic_set_32((volatile u_int *)(p), (u_int)(v)) 682#define atomic_set_acq_long(p, v) \ 683 atomic_set_acq_32((volatile u_int *)(p), (u_int)(v)) 684#define atomic_set_rel_long(p, v) \ 685 atomic_set_rel_32((volatile u_int *)(p), (u_int)(v)) 686#define atomic_clear_long(p, v) \ 687 atomic_clear_32((volatile u_int *)(p), (u_int)(v)) 688#define atomic_clear_acq_long(p, v) \ 689 atomic_clear_acq_32((volatile u_int *)(p), (u_int)(v)) 690#define atomic_clear_rel_long(p, v) \ 691 atomic_clear_rel_32((volatile u_int *)(p), (u_int)(v)) 692#define atomic_add_long(p, v) \ 693 atomic_add_32((volatile u_int *)(p), (u_int)(v)) 694#define atomic_add_acq_long(p, v) \ 695 atomic_add_32((volatile u_int *)(p), (u_int)(v)) 696#define atomic_add_rel_long(p, v) \ 697 atomic_add_32((volatile u_int *)(p), (u_int)(v)) 698#define atomic_subtract_long(p, v) \ 699 atomic_subtract_32((volatile u_int *)(p), (u_int)(v)) 700#define atomic_subtract_acq_long(p, v) \ 701 atomic_subtract_acq_32((volatile u_int *)(p), (u_int)(v)) 702#define atomic_subtract_rel_long(p, v) \ 703 atomic_subtract_rel_32((volatile u_int *)(p), (u_int)(v)) 704#define atomic_cmpset_long(p, cmpval, newval) \ 705 atomic_cmpset_32((volatile u_int *)(p), (u_int)(cmpval), \ 706 (u_int)(newval)) 707#define atomic_cmpset_acq_long(p, cmpval, newval) \ 708 atomic_cmpset_acq_32((volatile u_int *)(p), (u_int)(cmpval), \ 709 (u_int)(newval)) 710#define atomic_cmpset_rel_long(p, cmpval, newval) \ 711 atomic_cmpset_rel_32((volatile u_int *)(p), (u_int)(cmpval), \ 712 (u_int)(newval)) 713#define atomic_fcmpset_long(p, cmpval, newval) \ 714 atomic_fcmpset_32((volatile u_int *)(p), (u_int *)(cmpval), \ 715 (u_int)(newval)) 716#define atomic_fcmpset_acq_long(p, cmpval, newval) \ 717 atomic_fcmpset_acq_32((volatile u_int *)(p), (u_int *)(cmpval), \ 718 (u_int)(newval)) 719#define atomic_fcmpset_rel_long(p, cmpval, newval) \ 720 atomic_fcmpset_rel_32((volatile u_int *)(p), (u_int *)(cmpval), \ 721 (u_int)(newval)) 722#define atomic_load_acq_long(p) \ 723 (u_long)atomic_load_acq_32((volatile u_int *)(p)) 724#define atomic_store_rel_long(p, v) \ 725 atomic_store_rel_32((volatile u_int *)(p), (u_int)(v)) 726#define atomic_fetchadd_long(p, v) \ 727 atomic_fetchadd_32((volatile u_int *)(p), (u_int)(v)) 728#define atomic_readandclear_long(p) \ 729 atomic_readandclear_32((volatile u_int *)(p)) 730 731#endif /* __mips_n64 */ 732 733/* Operations on pointers. */ 734#define atomic_set_ptr atomic_set_long 735#define atomic_set_acq_ptr atomic_set_acq_long 736#define atomic_set_rel_ptr atomic_set_rel_long 737#define atomic_clear_ptr atomic_clear_long 738#define atomic_clear_acq_ptr atomic_clear_acq_long 739#define atomic_clear_rel_ptr atomic_clear_rel_long 740#define atomic_add_ptr atomic_add_long 741#define atomic_add_acq_ptr atomic_add_acq_long 742#define atomic_add_rel_ptr atomic_add_rel_long 743#define atomic_subtract_ptr atomic_subtract_long 744#define atomic_subtract_acq_ptr atomic_subtract_acq_long 745#define atomic_subtract_rel_ptr atomic_subtract_rel_long 746#define atomic_cmpset_ptr atomic_cmpset_long 747#define atomic_cmpset_acq_ptr atomic_cmpset_acq_long 748#define atomic_cmpset_rel_ptr atomic_cmpset_rel_long 749#define atomic_fcmpset_ptr atomic_fcmpset_long 750#define atomic_fcmpset_acq_ptr atomic_fcmpset_acq_long 751#define atomic_fcmpset_rel_ptr atomic_fcmpset_rel_long 752#define atomic_load_acq_ptr atomic_load_acq_long 753#define atomic_store_rel_ptr atomic_store_rel_long 754#define atomic_readandclear_ptr atomic_readandclear_long 755 756#endif /* ! _MACHINE_ATOMIC_H_ */ 757