134f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker/* 234f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker * cmpxchg.h -- forked from asm/atomic.h with this copyright: 334f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker * 434f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker * Copyright 2010 Tilera Corporation. All Rights Reserved. 534f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker * 634f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker * This program is free software; you can redistribute it and/or 734f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker * modify it under the terms of the GNU General Public License 834f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker * as published by the Free Software Foundation, version 2. 934f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker * 1034f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker * This program is distributed in the hope that it will be useful, but 1134f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker * WITHOUT ANY WARRANTY; without even the implied warranty of 1234f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 1334f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker * NON INFRINGEMENT. See the GNU General Public License for 1434f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker * more details. 1534f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker * 1634f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker */ 1734f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker 1834f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker#ifndef _ASM_TILE_CMPXCHG_H 1934f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker#define _ASM_TILE_CMPXCHG_H 2034f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker 2134f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker#ifndef __ASSEMBLY__ 2234f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker 236dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf#include <asm/barrier.h> 2434f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker 256dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf/* Nonexistent functions intended to cause compile errors. */ 266dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalfextern void __xchg_called_with_bad_pointer(void) 276dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf __compiletime_error("Bad argument size for xchg"); 286dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalfextern void __cmpxchg_called_with_bad_pointer(void) 296dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf __compiletime_error("Bad argument size for cmpxchg"); 306dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf 316dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf#ifndef __tilegx__ 326dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf 336dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf/* Note the _atomic_xxx() routines include a final mb(). */ 346dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalfint _atomic_xchg(int *ptr, int n); 356dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalfint _atomic_xchg_add(int *v, int i); 366dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalfint _atomic_xchg_add_unless(int *v, int a, int u); 376dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalfint _atomic_cmpxchg(int *ptr, int o, int n); 38b924a69067b00d3121debae5a738fb0bcbbbb03cChen Ganglong long _atomic64_xchg(long long *v, long long n); 39b924a69067b00d3121debae5a738fb0bcbbbb03cChen Ganglong long _atomic64_xchg_add(long long *v, long long i); 40b924a69067b00d3121debae5a738fb0bcbbbb03cChen Ganglong long _atomic64_xchg_add_unless(long long *v, long long a, long long u); 41b924a69067b00d3121debae5a738fb0bcbbbb03cChen Ganglong long _atomic64_cmpxchg(long long *v, long long o, long long n); 426dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf 436dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf#define xchg(ptr, n) \ 446dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf ({ \ 456dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf if (sizeof(*(ptr)) != 4) \ 466dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf __xchg_called_with_bad_pointer(); \ 476dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf smp_mb(); \ 486dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf (typeof(*(ptr)))_atomic_xchg((int *)(ptr), (int)(n)); \ 496dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf }) 506dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf 516dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf#define cmpxchg(ptr, o, n) \ 526dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf ({ \ 536dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf if (sizeof(*(ptr)) != 4) \ 546dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf __cmpxchg_called_with_bad_pointer(); \ 556dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf smp_mb(); \ 56b924a69067b00d3121debae5a738fb0bcbbbb03cChen Gang (typeof(*(ptr)))_atomic_cmpxchg((int *)ptr, (int)o, \ 57b924a69067b00d3121debae5a738fb0bcbbbb03cChen Gang (int)n); \ 586dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf }) 596dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf 606dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf#define xchg64(ptr, n) \ 616dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf ({ \ 626dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf if (sizeof(*(ptr)) != 8) \ 636dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf __xchg_called_with_bad_pointer(); \ 646dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf smp_mb(); \ 65b924a69067b00d3121debae5a738fb0bcbbbb03cChen Gang (typeof(*(ptr)))_atomic64_xchg((long long *)(ptr), \ 66b924a69067b00d3121debae5a738fb0bcbbbb03cChen Gang (long long)(n)); \ 676dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf }) 686dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf 696dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf#define cmpxchg64(ptr, o, n) \ 706dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf ({ \ 716dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf if (sizeof(*(ptr)) != 8) \ 726dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf __cmpxchg_called_with_bad_pointer(); \ 736dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf smp_mb(); \ 74b924a69067b00d3121debae5a738fb0bcbbbb03cChen Gang (typeof(*(ptr)))_atomic64_cmpxchg((long long *)ptr, \ 75b924a69067b00d3121debae5a738fb0bcbbbb03cChen Gang (long long)o, (long long)n); \ 766dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf }) 776dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf 786dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf#else 796dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf 806dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf#define xchg(ptr, n) \ 8134f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker ({ \ 8234f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker typeof(*(ptr)) __x; \ 836dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf smp_mb(); \ 8434f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker switch (sizeof(*(ptr))) { \ 8534f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker case 4: \ 866dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf __x = (typeof(__x))(unsigned long) \ 87b924a69067b00d3121debae5a738fb0bcbbbb03cChen Gang __insn_exch4((ptr), \ 88b924a69067b00d3121debae5a738fb0bcbbbb03cChen Gang (u32)(unsigned long)(n)); \ 8934f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker break; \ 9034f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker case 8: \ 91b924a69067b00d3121debae5a738fb0bcbbbb03cChen Gang __x = (typeof(__x)) \ 926dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf __insn_exch((ptr), (unsigned long)(n)); \ 9334f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker break; \ 9434f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker default: \ 9534f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker __xchg_called_with_bad_pointer(); \ 966dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf break; \ 9734f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker } \ 986dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf smp_mb(); \ 9934f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker __x; \ 10034f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker }) 10134f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker 10234f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker#define cmpxchg(ptr, o, n) \ 10334f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker ({ \ 10434f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker typeof(*(ptr)) __x; \ 1056dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf __insn_mtspr(SPR_CMPEXCH_VALUE, (unsigned long)(o)); \ 1066dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf smp_mb(); \ 10734f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker switch (sizeof(*(ptr))) { \ 10834f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker case 4: \ 1096dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf __x = (typeof(__x))(unsigned long) \ 110b924a69067b00d3121debae5a738fb0bcbbbb03cChen Gang __insn_cmpexch4((ptr), \ 111b924a69067b00d3121debae5a738fb0bcbbbb03cChen Gang (u32)(unsigned long)(n)); \ 11234f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker break; \ 11334f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker case 8: \ 114b924a69067b00d3121debae5a738fb0bcbbbb03cChen Gang __x = (typeof(__x))__insn_cmpexch((ptr), \ 115b924a69067b00d3121debae5a738fb0bcbbbb03cChen Gang (long long)(n)); \ 11634f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker break; \ 11734f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker default: \ 11834f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker __cmpxchg_called_with_bad_pointer(); \ 1196dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf break; \ 12034f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker } \ 1216dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf smp_mb(); \ 12234f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker __x; \ 12334f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker }) 12434f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker 1256dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf#define xchg64 xchg 1266dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf#define cmpxchg64 cmpxchg 12734f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker 1286dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf#endif 1296dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf 1306dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf#define tas(ptr) xchg((ptr), 1) 131cf3a13d790f9760c4bfcae802aaba80efb3519afChen Gang 13234f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker#endif /* __ASSEMBLY__ */ 13334f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker 13434f2c0ac111aaf090c7d2432dab532640870733aPaul Gortmaker#endif /* _ASM_TILE_CMPXCHG_H */ 135