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 kmp_int8 __kmp_test_then_or8(volatile kmp_int8 *p, kmp_int8 d) { 23 kmp_int8 old_value, new_value; 24 25 old_value = TCR_1(*p); 26 new_value = old_value | d; 27 28 while (!__kmp_compare_and_store8(p, old_value, new_value)) { 29 KMP_CPU_PAUSE(); 30 old_value = TCR_1(*p); 31 new_value = old_value | d; 32 } 33 return old_value; 34 } 35 36 kmp_int8 __kmp_test_then_and8(volatile kmp_int8 *p, kmp_int8 d) { 37 kmp_int8 old_value, new_value; 38 39 old_value = TCR_1(*p); 40 new_value = old_value & d; 41 42 while (!__kmp_compare_and_store8(p, old_value, new_value)) { 43 KMP_CPU_PAUSE(); 44 old_value = TCR_1(*p); 45 new_value = old_value & d; 46 } 47 return old_value; 48 } 49 50 kmp_uint32 __kmp_test_then_or32(volatile kmp_uint32 *p, kmp_uint32 d) { 51 kmp_uint32 old_value, new_value; 52 53 old_value = TCR_4(*p); 54 new_value = old_value | d; 55 56 while (!__kmp_compare_and_store32((volatile kmp_int32 *)p, old_value, 57 new_value)) { 58 KMP_CPU_PAUSE(); 59 old_value = TCR_4(*p); 60 new_value = old_value | d; 61 } 62 return old_value; 63 } 64 65 kmp_uint32 __kmp_test_then_and32(volatile kmp_uint32 *p, kmp_uint32 d) { 66 kmp_uint32 old_value, new_value; 67 68 old_value = TCR_4(*p); 69 new_value = old_value & d; 70 71 while (!__kmp_compare_and_store32((volatile kmp_int32 *)p, old_value, 72 new_value)) { 73 KMP_CPU_PAUSE(); 74 old_value = TCR_4(*p); 75 new_value = old_value & d; 76 } 77 return old_value; 78 } 79 80 kmp_int8 __kmp_test_then_add8(volatile kmp_int8 *p, kmp_int8 d) { 81 kmp_int64 old_value, new_value; 82 83 old_value = TCR_1(*p); 84 new_value = old_value + d; 85 while (!__kmp_compare_and_store8(p, old_value, new_value)) { 86 KMP_CPU_PAUSE(); 87 old_value = TCR_1(*p); 88 new_value = old_value + d; 89 } 90 return old_value; 91 } 92 93 #if KMP_ARCH_X86 94 kmp_int64 __kmp_test_then_add64(volatile kmp_int64 *p, kmp_int64 d) { 95 kmp_int64 old_value, new_value; 96 97 old_value = TCR_8(*p); 98 new_value = old_value + d; 99 while (!__kmp_compare_and_store64(p, old_value, new_value)) { 100 KMP_CPU_PAUSE(); 101 old_value = TCR_8(*p); 102 new_value = old_value + d; 103 } 104 return old_value; 105 } 106 #endif /* KMP_ARCH_X86 */ 107 108 kmp_uint64 __kmp_test_then_or64(volatile kmp_uint64 *p, kmp_uint64 d) { 109 kmp_uint64 old_value, new_value; 110 111 old_value = TCR_8(*p); 112 new_value = old_value | d; 113 while (!__kmp_compare_and_store64((volatile kmp_int64 *)p, old_value, 114 new_value)) { 115 KMP_CPU_PAUSE(); 116 old_value = TCR_8(*p); 117 new_value = old_value | d; 118 } 119 120 return old_value; 121 } 122 123 kmp_uint64 __kmp_test_then_and64(volatile kmp_uint64 *p, kmp_uint64 d) { 124 kmp_uint64 old_value, new_value; 125 126 old_value = TCR_8(*p); 127 new_value = old_value & d; 128 while (!__kmp_compare_and_store64((volatile kmp_int64 *)p, old_value, 129 new_value)) { 130 KMP_CPU_PAUSE(); 131 old_value = TCR_8(*p); 132 new_value = old_value & d; 133 } 134 135 return old_value; 136 } 137 138 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */ 139