Blame


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