Blob


1 #include "u.h"
2 #include "libc.h"
4 /*
5 * first argument (l) is in r3 at entry.
6 * r3 contains return value upon return.
7 */
8 int
9 _tas(int *x)
10 {
11 int v;
12 int tmp, tmp2, tmp3;
14 /*
15 * this __asm__ works with gcc on linux
16 */
17 __asm__("\n sync\n"
18 " li %1,0\n"
19 " mr %2,%4 /* &x->val */\n"
20 " lis %3,0xdead /* assemble constant 0xdeaddead */\n"
21 " ori %3,%3,0xdead /* \" */\n"
22 "tas1:\n"
23 " dcbf %2,%1 /* cache flush; \"fix for 603x bug\" */\n"
24 " lwarx %0,%2,%1 /* v = x->val with reservation */\n"
25 " cmp cr0,0,%0,%1 /* v == 0 */\n"
26 " bne tas0\n"
27 " stwcx. %3,%2,%1 /* if (x->val same) x->val = 0xdeaddead */\n"
28 " bne tas1\n"
29 "tas0:\n"
30 " sync\n"
31 " isync\n"
32 : "=r" (v), "=&r" (tmp), "=&r"(tmp2), "=&r"(tmp3)
33 : "r" (x)
34 : "cr0", "memory"
35 );
36 switch(v) {
37 case 0: return 0;
38 case 0xdeaddead: return 1;
39 default: fprint(2, "tas: corrupted 0x%lux\n", v);
40 }
41 return 0;
42 }