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