//===- subzero/src/IceIntrinsics.cpp - Functions related to intrinsics ----===// // // The Subzero Code Generator // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// /// /// \file /// \brief Implements the Intrinsics utilities for matching and then dispatching /// by name. /// //===----------------------------------------------------------------------===// #include "IceIntrinsics.h" #include "IceCfg.h" #include "IceCfgNode.h" #include "IceInst.h" #include "IceLiveness.h" #include "IceOperand.h" #include "IceStringPool.h" #include namespace Ice { static_assert(sizeof(Intrinsics::IntrinsicInfo) == 4, "Unexpected sizeof(IntrinsicInfo)"); bool Intrinsics::isMemoryOrderValid(IntrinsicID ID, uint64_t Order, uint64_t OrderOther) { // Reject orderings not allowed by C++11. switch (ID) { default: llvm_unreachable("isMemoryOrderValid: Unknown IntrinsicID"); return false; case AtomicFence: case AtomicFenceAll: case AtomicRMW: return true; case AtomicCmpxchg: // Reject orderings that are disallowed by C++11 as invalid combinations // for cmpxchg. switch (OrderOther) { case MemoryOrderRelaxed: case MemoryOrderConsume: case MemoryOrderAcquire: case MemoryOrderSequentiallyConsistent: if (OrderOther > Order) return false; if (Order == MemoryOrderRelease && OrderOther != MemoryOrderRelaxed) return false; return true; default: return false; } case AtomicLoad: switch (Order) { case MemoryOrderRelease: case MemoryOrderAcquireRelease: return false; default: return true; } case AtomicStore: switch (Order) { case MemoryOrderConsume: case MemoryOrderAcquire: case MemoryOrderAcquireRelease: return false; default: return true; } } } Intrinsics::ValidateIntrinsicValue Intrinsics::FullIntrinsicInfo::validateIntrinsic(const InstIntrinsic *Intrinsic, SizeT &ArgIndex) const { assert(NumTypes >= 1); Variable *Result = Intrinsic->getDest(); if (Result == nullptr) { if (getReturnType() != IceType_void) return Intrinsics::BadReturnType; } else if (getReturnType() != Result->getType()) { return Intrinsics::BadReturnType; } if (Intrinsic->getNumArgs() != getNumArgs()) { return Intrinsics::WrongNumOfArgs; } for (size_t i = 1; i < NumTypes; ++i) { if (Intrinsic->getArg(i - 1)->getType() != Signature[i]) { ArgIndex = i - 1; return Intrinsics::WrongArgType; } } return Intrinsics::IsValidIntrinsic; } Type Intrinsics::FullIntrinsicInfo::getArgType(SizeT Index) const { assert(NumTypes > 1); assert(Index + 1 < NumTypes); return Signature[Index + 1]; } } // end of namespace Ice