| //===- 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 <utility> |
| |
| 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 |