//===-- go-llvm-builtins.cpp - BuiltinTable implementation ----------------===//
//
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
//===----------------------------------------------------------------------===//
//
// Methods for BuiltinTable and related classes
//
//===----------------------------------------------------------------------===//

#include "go-llvm.h"
#include "go-llvm-builtins.h"
#include "go-llvm-bfunction.h"
#include "go-llvm-typemanager.h"

BuiltinEntry::~BuiltinEntry()
{
  if (flavor() == IntrinsicBuiltin)
    delete bfunction_;
}

void BuiltinEntry::setBfunction(Bfunction *bfunc)
{
  assert(! bfunction_);
  bfunction_ = bfunc;
}

//........................................................................

BuiltinTable::BuiltinTable(TypeManager *tman, bool addLongDouble)
    : tman_(tman), addLongDouble_(addLongDouble)
{
}

void BuiltinTable::registerIntrinsicBuiltin(const char *name,
                                            const char *libname,
                                            llvm::Intrinsic::ID intrinsicId,
                                            const BuiltinEntryTypeVec &overloadTypes)
{
  assert(lookup(name) == nullptr);
  assert(libname == nullptr || lookup(libname) == nullptr);
  unsigned idx = entries_.size();
  entries_.push_back(BuiltinEntry(intrinsicId, name,
                                  libname ? libname : "",
                                  overloadTypes));
  tab_[std::string(name)] = idx;
  if (libname)
    tab_[std::string(libname)] = idx;
}

void BuiltinTable::registerLibCallBuiltin(const char *libname,
                                          const char *name,
                                          llvm::LibFunc libfunc,
                                          const BuiltinEntryTypeVec &paramTypes)
{
  assert(lookup(name) == nullptr);
  assert(libname == nullptr || lookup(libname) == nullptr);
  unsigned idx = entries_.size();
  entries_.push_back(BuiltinEntry(libfunc, name,
                                  libname ? libname : "",
                                  paramTypes));
  tab_[std::string(name)] = idx;
  if (libname)
    tab_[std::string(libname)] = idx;
}

void BuiltinTable::registerExprBuiltin(const char *name,
                                       const char *libname,
                                       const BuiltinEntryTypeVec &paramTypes,
                                       BuiltinExprMaker exprMaker)
{
  assert(lookup(name) == nullptr);
  assert(libname == nullptr || lookup(libname) == nullptr);
  unsigned idx = entries_.size();
  entries_.push_back(BuiltinEntry(name,
                                  libname ? libname : "",
                                  paramTypes,
                                  exprMaker));
  tab_[std::string(name)] = idx;
  if (libname)
    tab_[std::string(libname)] = idx;
}

BuiltinEntry *BuiltinTable::lookup(const std::string &name)
{
  auto it = tab_.find(name);
  if (it == tab_.end())
    return nullptr;
  unsigned idx = it->second;
  assert(idx < entries_.size());
  return &entries_[idx];
}

void BuiltinTable::defineAllBuiltins() {
  defineSyncFetchAndAddBuiltins();
  defineIntrinsicBuiltins();
  defineTrigBuiltins();
  defineExprBuiltins();
}

void BuiltinTable::defineIntrinsicBuiltins() {
  Btype *boolType = tman_->boolType();
  Btype *ptrType = tman_->pointerType(boolType);
  Btype *uint16Type = tman_->integerType(true, 16);
  Btype *uint32Type = tman_->integerType(true, 32);
  Btype *int32Type = tman_->integerType(false, 32);
  unsigned bitsInPtr = tman_->datalayout()->getPointerSizeInBits();
  Btype *uintPtrType = tman_->integerType(true, bitsInPtr);
  Btype *sizeType = uintPtrType;
  Btype *uint64Type = tman_->integerType(true, 64);
  Btype *int64Type = tman_->integerType(false, 64);

  // A note on the types below:
  // - for intrinsic builtins, return type is implicitly defined
  //   by the intrinsic itself; param types can be overloaded
  // - for libcall builtins, return type appears as the first
  //   entry in the param type list

  defineIntrinsicBuiltin("__builtin_trap", nullptr, llvm::Intrinsic::trap,
                         nullptr);
  defineIntrinsicBuiltin("__builtin_return_address", nullptr,
                         llvm::Intrinsic::returnaddress, ptrType,
                         uint32Type, nullptr);
  defineIntrinsicBuiltin("__builtin_frame_address", nullptr,
                         llvm::Intrinsic::frameaddress, ptrType,
                         uint32Type, nullptr);
  defineIntrinsicBuiltin("__builtin_dwarf_cfa", nullptr,
                         llvm::Intrinsic::eh_dwarf_cfa, ptrType,
                         uint32Type, nullptr);

  defineIntrinsicBuiltin("__builtin_prefetch", nullptr, llvm::Intrinsic::prefetch,
                         ptrType, nullptr);

  defineIntrinsicBuiltin("__builtin_expect", nullptr, llvm::Intrinsic::expect,
                         int64Type, int64Type, nullptr);

  defineLibcallBuiltin("__builtin_memcmp", "memcmp",
                       llvm::LibFunc::LibFunc_memcmp,
                       int32Type, ptrType, ptrType,
                       sizeType, nullptr);

  defineIntrinsicBuiltin("__builtin_memcpy", "memcpy",
                         llvm::Intrinsic::memcpy,
                         ptrType, ptrType, sizeType, nullptr);

  defineIntrinsicBuiltin("__builtin_memmove", "memmove",
                         llvm::Intrinsic::memmove,
                         ptrType, ptrType, sizeType, nullptr);

  // go runtime refers to this intrinsic as "ctz", however the LLVM
  // equivalent is named "cttz".
  defineIntrinsicBuiltin("__builtin_ctz", "ctz", llvm::Intrinsic::cttz,
                         uint32Type, nullptr);

  // go runtime refers to this intrinsic as "ctzll", however the LLVM
  // equivalent is named "cttz".
  defineIntrinsicBuiltin("__builtin_ctzll", "ctzll", llvm::Intrinsic::cttz,
                         uint64Type, nullptr);

  // go runtime refers to this intrinsic as "clz", however the LLVM
  // equivalent is named "ctlz".
  defineIntrinsicBuiltin("__builtin_clz", "clz", llvm::Intrinsic::ctlz,
                         uint32Type, nullptr);

  // go runtime refers to this intrinsic as "clzll", however the LLVM
  // equivalent is named "ctlz".
  defineIntrinsicBuiltin("__builtin_clzll", "clzll", llvm::Intrinsic::ctlz,
                         uint64Type, nullptr);

  // go runtime refers to this intrinsic as "popcount", however the LLVM
  // equivalent is named "ctpop".
  defineIntrinsicBuiltin("__builtin_popcount", "popcount", llvm::Intrinsic::ctpop,
                         uint32Type, nullptr);

  // go runtime refers to this intrinsic as "popcountll", however the LLVM
  // equivalent is named "ctpop".
  defineIntrinsicBuiltin("__builtin_popcountll", "popcountll", llvm::Intrinsic::ctpop,
                         uint64Type, nullptr);

  // go runtime refers to this intrinsic as "bswap16", however the LLVM
  // equivalent is named just "bswap"
  defineIntrinsicBuiltin("__builtin_bswap16", "bswap16", llvm::Intrinsic::bswap,
                         uint16Type, nullptr);

  // go runtime refers to this intrinsic as "bswap32", however the LLVM
  // equivalent is named just "bswap"
  defineIntrinsicBuiltin("__builtin_bswap32", "bswap32", llvm::Intrinsic::bswap,
                         uint32Type, nullptr);

  // go runtime refers to this intrinsic as "bswap64", however the LLVM
  // equivalent is named just "bswap"
  defineIntrinsicBuiltin("__builtin_bswap64", "bswap64", llvm::Intrinsic::bswap,
                         uint64Type, nullptr);
}

namespace {

typedef enum {
  OneArg = 0,  // takes form "double foo(double)"
  TwoArgs = 1, // takes form "double bar(double, double)"
  TwoMixed = 2 // takes form "double bar(double, int)"
} mflav;

typedef struct {
  const char *name;
  mflav nargs;
  llvm::LibFunc lf;
} mathfuncdesc;
}

void BuiltinTable::defineTrigBuiltins() {
  Btype *doubleType = tman_->floatType(64);
  Btype *longDoubleType = tman_->floatType(128);
  Btype *int32Type = tman_->integerType(false, 32);

  BuiltinEntryTypeVec onearg_double(2);
  onearg_double[0] = doubleType;
  onearg_double[1] = doubleType;

  BuiltinEntryTypeVec onearg_long_double(2);
  onearg_long_double[0] = longDoubleType;
  onearg_long_double[1] = longDoubleType;

  BuiltinEntryTypeVec twoargs_double(3);
  twoargs_double[0] = doubleType;
  twoargs_double[1] = doubleType;
  twoargs_double[2] = doubleType;

  BuiltinEntryTypeVec twoargs_long_double(3);
  twoargs_long_double[0] = longDoubleType;
  twoargs_long_double[1] = longDoubleType;
  twoargs_long_double[2] = longDoubleType;

  BuiltinEntryTypeVec mixed_double(3);
  mixed_double[0] = doubleType;
  mixed_double[1] = doubleType;
  mixed_double[2] = int32Type;

  BuiltinEntryTypeVec mixed_long_double(3);
  mixed_long_double[0] = longDoubleType;
  mixed_long_double[1] = longDoubleType;
  mixed_long_double[2] = int32Type;

  std::vector<BuiltinEntryTypeVec *> signatures = {
      &onearg_double, &twoargs_double, &mixed_double};
  std::vector<BuiltinEntryTypeVec *> lsignatures = {
      &onearg_long_double, &twoargs_long_double, &mixed_long_double};

  static const mathfuncdesc funcs[] = {
      {"acos", OneArg, llvm::LibFunc::LibFunc_acos},
      {"asin", OneArg, llvm::LibFunc::LibFunc_asin},
      {"atan", OneArg, llvm::LibFunc::LibFunc_atan},
      {"atan2", TwoArgs, llvm::LibFunc::LibFunc_atan2},
      {"ceil", OneArg, llvm::LibFunc::LibFunc_ceil},
      {"cos", OneArg, llvm::LibFunc::LibFunc_cos},
      {"exp", OneArg, llvm::LibFunc::LibFunc_exp},
      {"expm1", OneArg, llvm::LibFunc::LibFunc_expm1},
      {"fabs", OneArg, llvm::LibFunc::LibFunc_fabs},
      {"floor", OneArg, llvm::LibFunc::LibFunc_floor},
      {"fmod", TwoArgs, llvm::LibFunc::LibFunc_fmod},
      {"log", OneArg, llvm::LibFunc::LibFunc_log},
      {"log1p", OneArg, llvm::LibFunc::LibFunc_log1p},
      {"log10", OneArg, llvm::LibFunc::LibFunc_log10},
      {"log2", OneArg, llvm::LibFunc::LibFunc_log2},
      {"sin", OneArg, llvm::LibFunc::LibFunc_sin},
      {"sqrt", OneArg, llvm::LibFunc::LibFunc_sqrt},
      {"tan", OneArg, llvm::LibFunc::LibFunc_tan},
      {"trunc", OneArg, llvm::LibFunc::LibFunc_trunc},
      {"ldexp", TwoMixed, llvm::LibFunc::LibFunc_trunc},
  };

  const unsigned nfuncs = sizeof(funcs) / sizeof(mathfuncdesc);
  for (unsigned idx = 0; idx < nfuncs; ++idx) {
    const mathfuncdesc &d = funcs[idx];
    char bbuf[128];
    char lbuf[128];

    sprintf(bbuf, "__builtin_%s", d.name);
    BuiltinEntryTypeVec *sig = signatures[d.nargs];
    defineLibcallBuiltin(bbuf, d.name, *sig, d.lf);
    if (addLongDouble_) {
      sprintf(lbuf, "%sl", d.name);
      sprintf(bbuf, "__builtin_%s", lbuf);
      BuiltinEntryTypeVec *lsig = lsignatures[d.nargs];
      defineLibcallBuiltin(bbuf, lbuf, *lsig, d.lf);
    }
  }
}

void BuiltinTable::defineSyncFetchAndAddBuiltins() {
  std::vector<unsigned> sizes = {1, 2, 4, 8};
  for (auto sz : sizes) {
    char nbuf[64];
    sprintf(nbuf, "__sync_fetch_and_add_%u", sz);
    Btype *it = tman_->integerType(true,  sz << 3);
    Btype *pit = tman_->pointerType(it);
    defineLibcallBuiltin(nullptr, nbuf,  // libname, name
                         BuiltinEntry::NotInTargetLib, // Libfunc ID
                         tman_->voidType(),  // result type
                         pit, it,        // param types
                         nullptr);
  }
}

void BuiltinTable::defineLibcallBuiltin(const char *libname,
                                        const char *name,
                                        unsigned libfunc, ...)
{
  va_list ap;
  BuiltinEntryTypeVec types(0);
  va_start(ap, libfunc);
  Btype *resultType = va_arg(ap, Btype *);
  types.push_back(resultType);
  Btype *parmType = va_arg(ap, Btype *);
  while (parmType) {
    types.push_back(parmType);
    parmType = va_arg(ap, Btype *);
  }
  llvm::LibFunc lf = static_cast<llvm::LibFunc>(libfunc);
  registerLibCallBuiltin(libname, name, lf, types);
}

void BuiltinTable::defineLibcallBuiltin(const char *libname,
                                        const char *name,
                                        BuiltinEntryTypeVec &types,
                                        unsigned libfunc)
{
  llvm::LibFunc lf = static_cast<llvm::LibFunc>(libfunc);
  registerLibCallBuiltin(libname, name, lf, types);
}

void BuiltinTable::defineIntrinsicBuiltin(const char *name,
                                          const char *libname,
                                          unsigned intrinsicID, ...) {
  va_list ap;
  BuiltinEntryTypeVec overloadTypes;
  va_start(ap, intrinsicID);
  Btype *oType = va_arg(ap, Btype *);
  while (oType) {
    overloadTypes.push_back(oType);
    oType = va_arg(ap, Btype *);
  }
  llvm::Intrinsic::ID iid = static_cast<llvm::Intrinsic::ID>(intrinsicID);
  registerIntrinsicBuiltin(name, libname, iid, overloadTypes);
}

static llvm::Value *builtinExtractReturnAddrMaker(llvm::SmallVectorImpl<llvm::Value*> &args,
                                                  BlockLIRBuilder *builder,
                                                  Llvm_backend *be)
{
  // __builtin_extract_return_addr(uintptr) uintptr
  // extracts the actual encoded address from the address as returned
  // by __builtin_return_address, for example, used on 31-bit S390 to
  // mask out the top bit.
  // On most architectures this is simply identity function.
  // TODO: this is identity function for now. When we get to the
  // architectures that this matters, do the real thing.
  assert(args.size() == 1);
  return args[0];
}

static llvm::Value *builtinUnreachableMaker(llvm::SmallVectorImpl<llvm::Value*> &args,
                                            BlockLIRBuilder *builder,
                                            Llvm_backend *be)
{
  llvm::UnreachableInst *unr = builder->CreateUnreachable();
  return unr;
}

static llvm::Value *builtinMemsetMaker(llvm::SmallVectorImpl<llvm::Value*> &args,
                                       BlockLIRBuilder *builder,
                                       Llvm_backend *be)
{
  // __builtin_memset takes int32 as its second argument, whereas
  // LLVM intrinsic memset takes an i8. We wrap the intrinsic in
  // an expression builtin, which does a cast first.
  assert(args.size() == 3);
  llvm::Value *cast = builder->CreateTrunc(args[1], be->llvmInt8Type());
  llvm::Function* fn =
      llvm::Intrinsic::getDeclaration(&be->module(),
                                      llvm::Intrinsic::memset,
                                      {args[0]->getType(), args[2]->getType()});
  // LLVM memset takes an extra isVolatile argument.
  return builder->CreateCall(fn, {args[0], cast, args[2], builder->getFalse()});
}

static llvm::AtomicOrdering llvmOrder(int o)
{
  switch (o) {
  case __ATOMIC_RELAXED:
    return llvm::AtomicOrdering::Monotonic;
  case __ATOMIC_CONSUME:
    return llvm::AtomicOrdering::Acquire; // LLVM does not define consume
  case __ATOMIC_ACQUIRE:
    return llvm::AtomicOrdering::Acquire;
  case __ATOMIC_RELEASE:
    return llvm::AtomicOrdering::Release;
  case __ATOMIC_ACQ_REL:
    return llvm::AtomicOrdering::AcquireRelease;
  case __ATOMIC_SEQ_CST:
    return llvm::AtomicOrdering::SequentiallyConsistent;
  }
  llvm_unreachable("unknown atomic order");
}

static llvm::Value *atomicLoadMaker(llvm::SmallVectorImpl<llvm::Value*> &args,
                                    BlockLIRBuilder *builder,
                                    Llvm_backend *be, int sz)
{
  assert(args.size() == 2);
  llvm::Type *t = sz == 8 ? be->llvmInt64Type() : be->llvmInt32Type();
  llvm::LoadInst *load = builder->CreateLoad(t, args[0]);
  // FIXME: we assume the FE always emits constant memory order.
  // in case it doesn't, conservatively use SequentiallyConsistent.
  llvm::AtomicOrdering o =
      llvm::isa<llvm::ConstantInt>(args[1]) ?
      llvmOrder(llvm::cast<llvm::ConstantInt>(args[1])->getZExtValue()) :
      llvm::AtomicOrdering::SequentiallyConsistent;
  load->setAtomic(o);
  load->setAlignment(llvm::Align(sz));
  return load;
}

static llvm::Value *atomicLoad4Maker(llvm::SmallVectorImpl<llvm::Value*> &args,
                                     BlockLIRBuilder *builder,
                                     Llvm_backend *be)
{
  return atomicLoadMaker(args, builder, be, 4);
}

static llvm::Value *atomicLoad8Maker(llvm::SmallVectorImpl<llvm::Value*> &args,
                                     BlockLIRBuilder *builder,
                                     Llvm_backend *be)
{
  return atomicLoadMaker(args, builder, be, 8);
}

static llvm::Value *atomicStoreMaker(llvm::SmallVectorImpl<llvm::Value*> &args,
                                     BlockLIRBuilder *builder,
                                     Llvm_backend *be, int sz)
{
  assert(args.size() == 3);
  llvm::StoreInst *store = builder->CreateStore(args[1], args[0]);
  // FIXME: see atomicLoadMaker.
  llvm::AtomicOrdering o =
      llvm::isa<llvm::ConstantInt>(args[2]) ?
      llvmOrder(llvm::cast<llvm::ConstantInt>(args[2])->getZExtValue()) :
      llvm::AtomicOrdering::SequentiallyConsistent;
  store->setAtomic(o);
  store->setAlignment(llvm::Align(sz));
  return store;
}

static llvm::Value *atomicStore4Maker(llvm::SmallVectorImpl<llvm::Value*> &args,
                                      BlockLIRBuilder *builder,
                                      Llvm_backend *be)
{
  return atomicStoreMaker(args, builder, be, 4);
}

static llvm::Value *atomicStore8Maker(llvm::SmallVectorImpl<llvm::Value*> &args,
                                      BlockLIRBuilder *builder,
                                      Llvm_backend *be)
{
  return atomicStoreMaker(args, builder, be, 8);
}

static llvm::Value *atomicRMWMaker(llvm::AtomicRMWInst::BinOp op,
                                   llvm::SmallVectorImpl<llvm::Value*> &args,
                                   BlockLIRBuilder *builder,
                                   Llvm_backend *be)
{
  assert(args.size() == 3);
  // FIXME: see atomicLoadMaker.
  llvm::AtomicOrdering o =
      llvm::isa<llvm::ConstantInt>(args[2]) ?
      llvmOrder(llvm::cast<llvm::ConstantInt>(args[2])->getZExtValue()) :
      llvm::AtomicOrdering::SequentiallyConsistent;
  return builder->CreateAtomicRMW(op, args[0], args[1], llvm::MaybeAlign(), o);
}

static llvm::Value *atomicXchgMaker(llvm::SmallVectorImpl<llvm::Value*> &args,
                                    BlockLIRBuilder *builder,
                                    Llvm_backend *be)
{
  return atomicRMWMaker(llvm::AtomicRMWInst::Xchg, args, builder, be);
}

static llvm::Value *atomicAddMaker(llvm::SmallVectorImpl<llvm::Value*> &args,
                                   BlockLIRBuilder *builder,
                                   Llvm_backend *be)
{
  // atomicrmw returns the old content. We need to do the add.
  llvm::Value* old = atomicRMWMaker(llvm::AtomicRMWInst::Add, args, builder, be);
  return builder->CreateAdd(old, args[1]);
}

static llvm::Value *atomicAndMaker(llvm::SmallVectorImpl<llvm::Value*> &args,
                                   BlockLIRBuilder *builder,
                                   Llvm_backend *be)
{
  // atomicrmw returns the old content. We need to do the and.
  llvm::Value* old = atomicRMWMaker(llvm::AtomicRMWInst::And, args, builder, be);
  return builder->CreateAnd(old, args[1]);
}

static llvm::Value *atomicOrMaker(llvm::SmallVectorImpl<llvm::Value*> &args,
                                  BlockLIRBuilder *builder,
                                  Llvm_backend *be)
{
  // atomicrmw returns the old content. We need to do the or.
  llvm::Value* old = atomicRMWMaker(llvm::AtomicRMWInst::Or, args, builder, be);
  return builder->CreateOr(old, args[1]);
}

static llvm::Value *atomicCasMaker(llvm::SmallVectorImpl<llvm::Value*> &args,
                                   BlockLIRBuilder *builder,
                                   Llvm_backend *be)
{
  assert(args.size() == 6);
  // GCC __atomic_compare_exchange_n takes a pointer to the old value.
  // We need to load it.
  llvm::Value *old = builder->CreateLoad(args[1]);
  // FIXME: see atomicLoadMaker, but default to SequentiallyConsistent
  // for success order, Monotonic (i.e. relaxed) for failed order,
  // and false for weak.
  llvm::AtomicOrdering o =
      llvm::isa<llvm::ConstantInt>(args[4]) ?
      llvmOrder(llvm::cast<llvm::ConstantInt>(args[4])->getZExtValue()) :
      llvm::AtomicOrdering::SequentiallyConsistent;
  llvm::AtomicOrdering o2 =
      llvm::isa<llvm::ConstantInt>(args[5]) ?
      llvmOrder(llvm::cast<llvm::ConstantInt>(args[5])->getZExtValue()) :
      llvm::AtomicOrdering::Monotonic;
  bool weak =
      llvm::isa<llvm::ConstantInt>(args[3]) &&
      !llvm::cast<llvm::ConstantInt>(args[3])->isZero();
  llvm::AtomicCmpXchgInst *cas =
      builder->CreateAtomicCmpXchg(args[0], old, args[2], llvm::MaybeAlign(), o, o2);
  cas->setWeak(weak);
  // LLVM cmpxchg instruction returns { valType, i1 }. Extract the second
  // value, and cast to Go bool type (i8).
  llvm::Value *ret = builder->CreateExtractValue(cas, {1});
  return builder->CreateZExt(ret, be->llvmInt8Type());
}

void BuiltinTable::defineExprBuiltins()
{
  Btype *boolType = tman_->boolType();
  Btype *int32Type = tman_->integerType(false, 32);
  Btype *uint8Type = tman_->integerType(true, 8);
  Btype *uint8PtrType = tman_->pointerType(uint8Type);
  Btype *uint32Type = tman_->integerType(true, 32);
  Btype *uint32PtrType = tman_->pointerType(uint32Type);
  Btype *uint64Type = tman_->integerType(true, 64);
  Btype *uint64PtrType = tman_->pointerType(uint64Type);
  unsigned bitsInPtr = tman_->datalayout()->getPointerSizeInBits();
  Btype *uintPtrType = tman_->integerType(true, bitsInPtr);

  {
    BuiltinEntryTypeVec typeVec = {uintPtrType, uintPtrType};
    registerExprBuiltin("__builtin_extract_return_addr", nullptr,
                        typeVec, builtinExtractReturnAddrMaker);
  }

  {
    BuiltinEntryTypeVec typeVec;
    registerExprBuiltin("__builtin_unreachable", nullptr,
                        typeVec, builtinUnreachableMaker);
  }

  {
    BuiltinEntryTypeVec typeVec = {nullptr, uint8Type, int32Type, uintPtrType};
    registerExprBuiltin("__builtin_memset", nullptr,
                        typeVec, builtinMemsetMaker);
  }

  {
    BuiltinEntryTypeVec typeVec = {uint32Type, uint32PtrType, int32Type};
    registerExprBuiltin("__atomic_load_4", nullptr,
                        typeVec, atomicLoad4Maker);
  }
  {
    BuiltinEntryTypeVec typeVec = {uint64Type, uint64PtrType, int32Type};
    registerExprBuiltin("__atomic_load_8", nullptr,
                        typeVec, atomicLoad8Maker);
  }

  {
    BuiltinEntryTypeVec typeVec = {nullptr, uint32PtrType, uint32Type, int32Type};
    registerExprBuiltin("__atomic_store_4", nullptr,
                        typeVec, atomicStore4Maker);
  }
  {
    BuiltinEntryTypeVec typeVec = {nullptr, uint64PtrType, uint64Type, int32Type};
    registerExprBuiltin("__atomic_store_8", nullptr,
                        typeVec, atomicStore8Maker);
  }

  {
    BuiltinEntryTypeVec typeVec = {uint32Type, uint32PtrType, uint32Type, int32Type};
    registerExprBuiltin("__atomic_exchange_4", nullptr,
                        typeVec, atomicXchgMaker);
    registerExprBuiltin("__atomic_add_fetch_4", nullptr,
                        typeVec, atomicAddMaker);
  }
  {
    BuiltinEntryTypeVec typeVec = {uint64Type, uint64PtrType, uint64Type, int32Type};
    registerExprBuiltin("__atomic_exchange_8", nullptr,
                        typeVec, atomicXchgMaker);
    registerExprBuiltin("__atomic_add_fetch_8", nullptr,
                        typeVec, atomicAddMaker);
  }

  {
    BuiltinEntryTypeVec typeVec = {uint8Type, uint8PtrType, uint8Type, int32Type};
    registerExprBuiltin("__atomic_and_fetch_1", nullptr,
                        typeVec, atomicAndMaker);
    registerExprBuiltin("__atomic_or_fetch_1", nullptr,
                        typeVec, atomicOrMaker);
  }

  {
    BuiltinEntryTypeVec typeVec = {boolType, uint32PtrType, uint32PtrType, uint32Type,
                                   boolType, int32Type, int32Type};
    registerExprBuiltin("__atomic_compare_exchange_4", nullptr,
                        typeVec, atomicCasMaker);
  }
  {
    BuiltinEntryTypeVec typeVec = {boolType, uint64PtrType, uint64PtrType, uint64Type,
                                   boolType, int32Type, int32Type};
    registerExprBuiltin("__atomic_compare_exchange_8", nullptr,
                        typeVec, atomicCasMaker);
  }
}
