brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.0 KiB · 37759fe Raw
193 lines · cpp
1/*2 * z_Windows_NT-586_util.cpp -- platform specific routines.3 */4 5//===----------------------------------------------------------------------===//6//7// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.8// See https://llvm.org/LICENSE.txt for license information.9// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception10//11//===----------------------------------------------------------------------===//12 13#include "kmp.h"14 15#if (KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_ARCH_AARCH64 || KMP_ARCH_ARM)16/* Only 32-bit "add-exchange" instruction on IA-32 architecture causes us to17   use compare_and_store for these routines */18 19kmp_int8 __kmp_test_then_or8(volatile kmp_int8 *p, kmp_int8 d) {20  kmp_int8 old_value, new_value;21 22  old_value = TCR_1(*p);23  new_value = old_value | d;24 25  while (!KMP_COMPARE_AND_STORE_REL8(p, old_value, new_value)) {26    KMP_CPU_PAUSE();27    old_value = TCR_1(*p);28    new_value = old_value | d;29  }30  return old_value;31}32 33kmp_int8 __kmp_test_then_and8(volatile kmp_int8 *p, kmp_int8 d) {34  kmp_int8 old_value, new_value;35 36  old_value = TCR_1(*p);37  new_value = old_value & d;38 39  while (!KMP_COMPARE_AND_STORE_REL8(p, old_value, new_value)) {40    KMP_CPU_PAUSE();41    old_value = TCR_1(*p);42    new_value = old_value & d;43  }44  return old_value;45}46 47kmp_uint32 __kmp_test_then_or32(volatile kmp_uint32 *p, kmp_uint32 d) {48  kmp_uint32 old_value, new_value;49 50  old_value = TCR_4(*p);51  new_value = old_value | d;52 53  while (!KMP_COMPARE_AND_STORE_REL32((volatile kmp_int32 *)p, old_value,54                                      new_value)) {55    KMP_CPU_PAUSE();56    old_value = TCR_4(*p);57    new_value = old_value | d;58  }59  return old_value;60}61 62kmp_uint32 __kmp_test_then_and32(volatile kmp_uint32 *p, kmp_uint32 d) {63  kmp_uint32 old_value, new_value;64 65  old_value = TCR_4(*p);66  new_value = old_value & d;67 68  while (!KMP_COMPARE_AND_STORE_REL32((volatile kmp_int32 *)p, old_value,69                                      new_value)) {70    KMP_CPU_PAUSE();71    old_value = TCR_4(*p);72    new_value = old_value & d;73  }74  return old_value;75}76 77#if KMP_ARCH_X86 || KMP_ARCH_X86_6478kmp_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_X8692kmp_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#endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */106 107kmp_uint64 __kmp_test_then_or64(volatile kmp_uint64 *p, kmp_uint64 d) {108  kmp_uint64 old_value, new_value;109 110  old_value = TCR_8(*p);111  new_value = old_value | d;112  while (!KMP_COMPARE_AND_STORE_REL64((volatile kmp_int64 *)p, old_value,113                                      new_value)) {114    KMP_CPU_PAUSE();115    old_value = TCR_8(*p);116    new_value = old_value | d;117  }118 119  return old_value;120}121 122kmp_uint64 __kmp_test_then_and64(volatile kmp_uint64 *p, kmp_uint64 d) {123  kmp_uint64 old_value, new_value;124 125  old_value = TCR_8(*p);126  new_value = old_value & d;127  while (!KMP_COMPARE_AND_STORE_REL64((volatile kmp_int64 *)p, old_value,128                                      new_value)) {129    KMP_CPU_PAUSE();130    old_value = TCR_8(*p);131    new_value = old_value & d;132  }133 134  return old_value;135}136 137#if KMP_ARCH_AARCH64 && KMP_COMPILER_MSVC138// For !KMP_COMPILER_MSVC, this function is provided in assembly form139// by z_Linux_asm.S.140int __kmp_invoke_microtask(microtask_t pkfn, int gtid, int tid, int argc,141                           void *p_argv[]142#if OMPT_SUPPORT143                           ,144                           void **exit_frame_ptr145#endif146) {147#if OMPT_SUPPORT148  *exit_frame_ptr = OMPT_GET_FRAME_ADDRESS(0);149#endif150 151  switch (argc) {152  case 0:153    (*pkfn)(&gtid, &tid);154    break;155  case 1:156    (*pkfn)(&gtid, &tid, p_argv[0]);157    break;158  case 2:159    (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1]);160    break;161  case 3:162    (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2]);163    break;164  case 4:165    (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3]);166    break;167  case 5:168    (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4]);169    break;170  default: {171    // p_argv[6] and onwards must be passed on the stack since 8 registers are172    // already used.173    size_t len = (argc - 6) * sizeof(void *);174    void *argbuf = alloca(len);175    memcpy(argbuf, &p_argv[6], len);176  }177    [[fallthrough]];178  case 6:179    (*pkfn)(&gtid, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4],180            p_argv[5]);181    break;182  }183 184#if OMPT_SUPPORT185  *exit_frame_ptr = 0;186#endif187 188  return 1;189}190#endif191 192#endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_ARCH_AARCH64 || KMP_ARCH_ARM */193