1 /* 2 * z_Windows_NT-586_util.cpp -- platform specific routines. 3 */ 4 5 6 //===----------------------------------------------------------------------===// 7 // 8 // The LLVM Compiler Infrastructure 9 // 10 // This file is dual licensed under the MIT and the University of Illinois Open 11 // Source Licenses. See LICENSE.txt for details. 12 // 13 //===----------------------------------------------------------------------===// 14 15 16 #include "kmp.h" 17 18 #if (KMP_ARCH_X86 || KMP_ARCH_X86_64) 19 /* Only 32-bit "add-exchange" instruction on IA-32 architecture causes us to 20 * use compare_and_store for these routines 21 */ 22 23 kmp_int8 24 __kmp_test_then_or8( volatile kmp_int8 *p, kmp_int8 d ) 25 { 26 kmp_int8 old_value, new_value; 27 28 old_value = TCR_1( *p ); 29 new_value = old_value | d; 30 31 while ( ! __kmp_compare_and_store8 ( p, old_value, new_value ) ) 32 { 33 KMP_CPU_PAUSE(); 34 old_value = TCR_1( *p ); 35 new_value = old_value | d; 36 } 37 return old_value; 38 } 39 40 kmp_int8 41 __kmp_test_then_and8( volatile kmp_int8 *p, kmp_int8 d ) 42 { 43 kmp_int8 old_value, new_value; 44 45 old_value = TCR_1( *p ); 46 new_value = old_value & d; 47 48 while ( ! __kmp_compare_and_store8 ( p, old_value, new_value ) ) 49 { 50 KMP_CPU_PAUSE(); 51 old_value = TCR_1( *p ); 52 new_value = old_value & d; 53 } 54 return old_value; 55 } 56 57 kmp_int32 58 __kmp_test_then_or32( volatile kmp_int32 *p, kmp_int32 d ) 59 { 60 kmp_int32 old_value, new_value; 61 62 old_value = TCR_4( *p ); 63 new_value = old_value | d; 64 65 while ( ! __kmp_compare_and_store32 ( p, old_value, new_value ) ) 66 { 67 KMP_CPU_PAUSE(); 68 old_value = TCR_4( *p ); 69 new_value = old_value | d; 70 } 71 return old_value; 72 } 73 74 kmp_int32 75 __kmp_test_then_and32( volatile kmp_int32 *p, kmp_int32 d ) 76 { 77 kmp_int32 old_value, new_value; 78 79 old_value = TCR_4( *p ); 80 new_value = old_value & d; 81 82 while ( ! __kmp_compare_and_store32 ( p, old_value, new_value ) ) 83 { 84 KMP_CPU_PAUSE(); 85 old_value = TCR_4( *p ); 86 new_value = old_value & d; 87 } 88 return old_value; 89 } 90 91 kmp_int8 92 __kmp_test_then_add8( volatile kmp_int8 *p, kmp_int8 d ) 93 { 94 kmp_int64 old_value, new_value; 95 96 old_value = TCR_1( *p ); 97 new_value = old_value + d; 98 while ( ! __kmp_compare_and_store8 ( p, old_value, new_value ) ) 99 { 100 KMP_CPU_PAUSE(); 101 old_value = TCR_1( *p ); 102 new_value = old_value + d; 103 } 104 return old_value; 105 } 106 107 #if KMP_ARCH_X86 108 kmp_int64 109 __kmp_test_then_add64( volatile kmp_int64 *p, kmp_int64 d ) 110 { 111 kmp_int64 old_value, new_value; 112 113 old_value = TCR_8( *p ); 114 new_value = old_value + d; 115 while ( ! __kmp_compare_and_store64 ( p, old_value, new_value ) ) 116 { 117 KMP_CPU_PAUSE(); 118 old_value = TCR_8( *p ); 119 new_value = old_value + d; 120 } 121 return old_value; 122 } 123 #endif /* KMP_ARCH_X86 */ 124 125 kmp_int64 126 __kmp_test_then_or64( volatile kmp_int64 *p, kmp_int64 d ) 127 { 128 kmp_int64 old_value, new_value; 129 130 old_value = TCR_8( *p ); 131 new_value = old_value | d; 132 while ( ! __kmp_compare_and_store64 ( p, old_value, new_value ) ) 133 { 134 KMP_CPU_PAUSE(); 135 old_value = TCR_8( *p ); 136 new_value = old_value | d; 137 } 138 139 return old_value; 140 } 141 142 kmp_int64 143 __kmp_test_then_and64( volatile kmp_int64 *p, kmp_int64 d ) 144 { 145 kmp_int64 old_value, new_value; 146 147 old_value = TCR_8( *p ); 148 new_value = old_value & d; 149 while ( ! __kmp_compare_and_store64 ( p, old_value, new_value ) ) 150 { 151 KMP_CPU_PAUSE(); 152 old_value = TCR_8( *p ); 153 new_value = old_value & d; 154 } 155 156 return old_value; 157 } 158 159 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */ 160 161 /* ------------------------------------------------------------------------ */ 162 /* ------------------------------------------------------------------------ */ 163 164