66 STATIC_ASSERT(8 == sizeof(D)); 67 68 D rv; 69 __asm__ volatile( 70 "1: \n\t" 71 " ldx [%2], %%o2\n\t" 72 " add %1, %%o2, %%o3\n\t" 73 " casx [%2], %%o2, %%o3\n\t" 74 " cmp %%o2, %%o3\n\t" 75 " bne %%xcc, 1b\n\t" 76 " nop\n\t" 77 " add %1, %%o2, %0\n\t" 78 : "=r" (rv) 79 : "r" (add_value), "r" (dest) 80 : "memory", "o2", "o3"); 81 return rv; 82 } 83 84 template<> 85 template<typename T> 86 inline T Atomic::PlatformXchg<4>::operator()(T exchange_value, 87 T volatile* dest, 88 atomic_memory_order order) const { 89 STATIC_ASSERT(4 == sizeof(T)); 90 T rv = exchange_value; 91 __asm__ volatile( 92 " swap [%2],%1\n\t" 93 : "=r" (rv) 94 : "0" (exchange_value) /* we use same register as for return value */, "r" (dest) 95 : "memory"); 96 return rv; 97 } 98 99 template<> 100 template<typename T> 101 inline T Atomic::PlatformXchg<8>::operator()(T exchange_value, 102 T volatile* dest, 103 atomic_memory_order order) const { 104 STATIC_ASSERT(8 == sizeof(T)); 105 T rv = exchange_value; 106 __asm__ volatile( 107 "1:\n\t" 108 " mov %1, %%o3\n\t" 109 " ldx [%2], %%o2\n\t" 110 " casx [%2], %%o2, %%o3\n\t" 111 " cmp %%o2, %%o3\n\t" 112 " bne %%xcc, 1b\n\t" 113 " nop\n\t" 114 " mov %%o2, %0\n\t" 115 : "=r" (rv) 116 : "r" (exchange_value), "r" (dest) 117 : "memory", "o2", "o3"); 118 return rv; 119 } 120 121 // No direct support for cmpxchg of bytes; emulate using int. 122 template<> | 66 STATIC_ASSERT(8 == sizeof(D)); 67 68 D rv; 69 __asm__ volatile( 70 "1: \n\t" 71 " ldx [%2], %%o2\n\t" 72 " add %1, %%o2, %%o3\n\t" 73 " casx [%2], %%o2, %%o3\n\t" 74 " cmp %%o2, %%o3\n\t" 75 " bne %%xcc, 1b\n\t" 76 " nop\n\t" 77 " add %1, %%o2, %0\n\t" 78 : "=r" (rv) 79 : "r" (add_value), "r" (dest) 80 : "memory", "o2", "o3"); 81 return rv; 82 } 83 84 template<> 85 template<typename T> 86 inline T Atomic::PlatformXchg<4>::operator()(T volatile* dest, 87 T exchange_value, 88 atomic_memory_order order) const { 89 STATIC_ASSERT(4 == sizeof(T)); 90 T rv = exchange_value; 91 __asm__ volatile( 92 " swap [%2],%1\n\t" 93 : "=r" (rv) 94 : "0" (exchange_value) /* we use same register as for return value */, "r" (dest) 95 : "memory"); 96 return rv; 97 } 98 99 template<> 100 template<typename T> 101 inline T Atomic::PlatformXchg<8>::operator()(T volatile* dest, 102 T exchange_value, 103 atomic_memory_order order) const { 104 STATIC_ASSERT(8 == sizeof(T)); 105 T rv = exchange_value; 106 __asm__ volatile( 107 "1:\n\t" 108 " mov %1, %%o3\n\t" 109 " ldx [%2], %%o2\n\t" 110 " casx [%2], %%o2, %%o3\n\t" 111 " cmp %%o2, %%o3\n\t" 112 " bne %%xcc, 1b\n\t" 113 " nop\n\t" 114 " mov %%o2, %0\n\t" 115 : "=r" (rv) 116 : "r" (exchange_value), "r" (dest) 117 : "memory", "o2", "o3"); 118 return rv; 119 } 120 121 // No direct support for cmpxchg of bytes; emulate using int. 122 template<> |