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