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