aboutsummaryrefslogtreecommitdiff
path: root/lib/IR/NaClAtomicIntrinsics.cpp
blob: 02fe295fad11cfae5aca5c050b04cc7e20ce7ffa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//=== llvm/IR/NaClAtomicIntrinsics.cpp - NaCl Atomic Intrinsics -*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file describes atomic intrinsic functions that are specific to NaCl.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/NaClAtomicIntrinsics.h"
#include "llvm/IR/Type.h"

namespace llvm {

namespace NaCl {

AtomicIntrinsics::AtomicIntrinsics(LLVMContext &C) {
  Type *IT[NumAtomicIntrinsicOverloadTypes] = { Type::getInt8Ty(C),
                                                Type::getInt16Ty(C),
                                                Type::getInt32Ty(C),
                                                Type::getInt64Ty(C) };
  size_t CurIntrin = 0;

  // Initialize each of the atomic intrinsics and their overloads. They
  // have up to 5 parameters, the following macro will take care of
  // overloading.
#define INIT(P0, P1, P2, P3, P4, INTRIN)                                       \
  do {                                                                         \
    for (size_t CurType = 0; CurType != NumAtomicIntrinsicOverloadTypes;       \
         ++CurType) {                                                          \
      size_t Param = 0;                                                        \
      I[CurIntrin][CurType].OverloadedType = IT[CurType];                      \
      I[CurIntrin][CurType].ID = Intrinsic::nacl_atomic_##INTRIN;              \
      I[CurIntrin][CurType].Overloaded =                                       \
          P0 == Int || P0 == Ptr || P1 == Int || P1 == Ptr || P2 == Int ||     \
          P2 == Ptr || P3 == Int || P3 == Ptr || P4 == Int || P4 == Ptr;       \
      I[CurIntrin][CurType].NumParams =                                        \
          (P0 != NoP) + (P1 != NoP) + (P2 != NoP) + (P3 != NoP) + (P4 != NoP); \
      I[CurIntrin][CurType].ParamType[Param++] = P0;                           \
      I[CurIntrin][CurType].ParamType[Param++] = P1;                           \
      I[CurIntrin][CurType].ParamType[Param++] = P2;                           \
      I[CurIntrin][CurType].ParamType[Param++] = P3;                           \
      I[CurIntrin][CurType].ParamType[Param++] = P4;                           \
    }                                                                          \
    ++CurIntrin;                                                               \
  } while (0)

  INIT(Ptr, Mem, NoP, NoP, NoP, load);
  INIT(Ptr, Int, Mem, NoP, NoP, store);
  INIT(RMW, Ptr, Int, Mem, NoP, rmw);
  INIT(Ptr, Int, Int, Mem, Mem, cmpxchg);
  INIT(Mem, NoP, NoP, NoP, NoP, fence);
  INIT(NoP, NoP, NoP, NoP, NoP, fence_all);
}

AtomicIntrinsics::View AtomicIntrinsics::allIntrinsicsAndOverloads() const {
  return View(&I[0][0], NumAtomicIntrinsics * NumAtomicIntrinsicOverloadTypes);
}

AtomicIntrinsics::View AtomicIntrinsics::overloadsFor(Intrinsic::ID ID) const {
  // Overloads are stored consecutively.
  View R = allIntrinsicsAndOverloads();
  for (const AtomicIntrinsic *AI = R.begin(), *E = R.end(); AI != E; ++AI)
    if (AI->ID == ID)
      return View(AI, NumAtomicIntrinsicOverloadTypes);
  llvm_unreachable("unhandled atomic intrinsic");
}

const AtomicIntrinsics::AtomicIntrinsic *
AtomicIntrinsics::find(Intrinsic::ID ID, Type *OverloadedType) const {
  View R = allIntrinsicsAndOverloads();
  for (const AtomicIntrinsic *AI = R.begin(), *E = R.end(); AI != E; ++AI)
    if (AI->ID == ID && AI->OverloadedType == OverloadedType)
      return AI;
  llvm_unreachable("unhandled atomic intrinsic");
}

} // End NaCl namespace

} // End llvm namespace