1*03ce13f7SAndroid Build Coastguard Worker //===- subzero/src/IceIntrinsics.cpp - Functions related to intrinsics ----===// 2*03ce13f7SAndroid Build Coastguard Worker // 3*03ce13f7SAndroid Build Coastguard Worker // The Subzero Code Generator 4*03ce13f7SAndroid Build Coastguard Worker // 5*03ce13f7SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*03ce13f7SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*03ce13f7SAndroid Build Coastguard Worker // 8*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*03ce13f7SAndroid Build Coastguard Worker /// 10*03ce13f7SAndroid Build Coastguard Worker /// \file 11*03ce13f7SAndroid Build Coastguard Worker /// \brief Implements the Intrinsics utilities for matching and then dispatching 12*03ce13f7SAndroid Build Coastguard Worker /// by name. 13*03ce13f7SAndroid Build Coastguard Worker /// 14*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 15*03ce13f7SAndroid Build Coastguard Worker 16*03ce13f7SAndroid Build Coastguard Worker #include "IceIntrinsics.h" 17*03ce13f7SAndroid Build Coastguard Worker 18*03ce13f7SAndroid Build Coastguard Worker #include "IceCfg.h" 19*03ce13f7SAndroid Build Coastguard Worker #include "IceCfgNode.h" 20*03ce13f7SAndroid Build Coastguard Worker #include "IceInst.h" 21*03ce13f7SAndroid Build Coastguard Worker #include "IceLiveness.h" 22*03ce13f7SAndroid Build Coastguard Worker #include "IceOperand.h" 23*03ce13f7SAndroid Build Coastguard Worker #include "IceStringPool.h" 24*03ce13f7SAndroid Build Coastguard Worker 25*03ce13f7SAndroid Build Coastguard Worker #include <utility> 26*03ce13f7SAndroid Build Coastguard Worker 27*03ce13f7SAndroid Build Coastguard Worker namespace Ice { 28*03ce13f7SAndroid Build Coastguard Worker 29*03ce13f7SAndroid Build Coastguard Worker static_assert(sizeof(Intrinsics::IntrinsicInfo) == 4, 30*03ce13f7SAndroid Build Coastguard Worker "Unexpected sizeof(IntrinsicInfo)"); 31*03ce13f7SAndroid Build Coastguard Worker isMemoryOrderValid(IntrinsicID ID,uint64_t Order,uint64_t OrderOther)32*03ce13f7SAndroid Build Coastguard Workerbool Intrinsics::isMemoryOrderValid(IntrinsicID ID, uint64_t Order, 33*03ce13f7SAndroid Build Coastguard Worker uint64_t OrderOther) { 34*03ce13f7SAndroid Build Coastguard Worker // Reject orderings not allowed by C++11. 35*03ce13f7SAndroid Build Coastguard Worker switch (ID) { 36*03ce13f7SAndroid Build Coastguard Worker default: 37*03ce13f7SAndroid Build Coastguard Worker llvm_unreachable("isMemoryOrderValid: Unknown IntrinsicID"); 38*03ce13f7SAndroid Build Coastguard Worker return false; 39*03ce13f7SAndroid Build Coastguard Worker case AtomicFence: 40*03ce13f7SAndroid Build Coastguard Worker case AtomicFenceAll: 41*03ce13f7SAndroid Build Coastguard Worker case AtomicRMW: 42*03ce13f7SAndroid Build Coastguard Worker return true; 43*03ce13f7SAndroid Build Coastguard Worker case AtomicCmpxchg: 44*03ce13f7SAndroid Build Coastguard Worker // Reject orderings that are disallowed by C++11 as invalid combinations 45*03ce13f7SAndroid Build Coastguard Worker // for cmpxchg. 46*03ce13f7SAndroid Build Coastguard Worker switch (OrderOther) { 47*03ce13f7SAndroid Build Coastguard Worker case MemoryOrderRelaxed: 48*03ce13f7SAndroid Build Coastguard Worker case MemoryOrderConsume: 49*03ce13f7SAndroid Build Coastguard Worker case MemoryOrderAcquire: 50*03ce13f7SAndroid Build Coastguard Worker case MemoryOrderSequentiallyConsistent: 51*03ce13f7SAndroid Build Coastguard Worker if (OrderOther > Order) 52*03ce13f7SAndroid Build Coastguard Worker return false; 53*03ce13f7SAndroid Build Coastguard Worker if (Order == MemoryOrderRelease && OrderOther != MemoryOrderRelaxed) 54*03ce13f7SAndroid Build Coastguard Worker return false; 55*03ce13f7SAndroid Build Coastguard Worker return true; 56*03ce13f7SAndroid Build Coastguard Worker default: 57*03ce13f7SAndroid Build Coastguard Worker return false; 58*03ce13f7SAndroid Build Coastguard Worker } 59*03ce13f7SAndroid Build Coastguard Worker case AtomicLoad: 60*03ce13f7SAndroid Build Coastguard Worker switch (Order) { 61*03ce13f7SAndroid Build Coastguard Worker case MemoryOrderRelease: 62*03ce13f7SAndroid Build Coastguard Worker case MemoryOrderAcquireRelease: 63*03ce13f7SAndroid Build Coastguard Worker return false; 64*03ce13f7SAndroid Build Coastguard Worker default: 65*03ce13f7SAndroid Build Coastguard Worker return true; 66*03ce13f7SAndroid Build Coastguard Worker } 67*03ce13f7SAndroid Build Coastguard Worker case AtomicStore: 68*03ce13f7SAndroid Build Coastguard Worker switch (Order) { 69*03ce13f7SAndroid Build Coastguard Worker case MemoryOrderConsume: 70*03ce13f7SAndroid Build Coastguard Worker case MemoryOrderAcquire: 71*03ce13f7SAndroid Build Coastguard Worker case MemoryOrderAcquireRelease: 72*03ce13f7SAndroid Build Coastguard Worker return false; 73*03ce13f7SAndroid Build Coastguard Worker default: 74*03ce13f7SAndroid Build Coastguard Worker return true; 75*03ce13f7SAndroid Build Coastguard Worker } 76*03ce13f7SAndroid Build Coastguard Worker } 77*03ce13f7SAndroid Build Coastguard Worker } 78*03ce13f7SAndroid Build Coastguard Worker 79*03ce13f7SAndroid Build Coastguard Worker Intrinsics::ValidateIntrinsicValue validateIntrinsic(const InstIntrinsic * Intrinsic,SizeT & ArgIndex) const80*03ce13f7SAndroid Build Coastguard WorkerIntrinsics::FullIntrinsicInfo::validateIntrinsic(const InstIntrinsic *Intrinsic, 81*03ce13f7SAndroid Build Coastguard Worker SizeT &ArgIndex) const { 82*03ce13f7SAndroid Build Coastguard Worker assert(NumTypes >= 1); 83*03ce13f7SAndroid Build Coastguard Worker Variable *Result = Intrinsic->getDest(); 84*03ce13f7SAndroid Build Coastguard Worker if (Result == nullptr) { 85*03ce13f7SAndroid Build Coastguard Worker if (getReturnType() != IceType_void) 86*03ce13f7SAndroid Build Coastguard Worker return Intrinsics::BadReturnType; 87*03ce13f7SAndroid Build Coastguard Worker } else if (getReturnType() != Result->getType()) { 88*03ce13f7SAndroid Build Coastguard Worker return Intrinsics::BadReturnType; 89*03ce13f7SAndroid Build Coastguard Worker } 90*03ce13f7SAndroid Build Coastguard Worker if (Intrinsic->getNumArgs() != getNumArgs()) { 91*03ce13f7SAndroid Build Coastguard Worker return Intrinsics::WrongNumOfArgs; 92*03ce13f7SAndroid Build Coastguard Worker } 93*03ce13f7SAndroid Build Coastguard Worker for (size_t i = 1; i < NumTypes; ++i) { 94*03ce13f7SAndroid Build Coastguard Worker if (Intrinsic->getArg(i - 1)->getType() != Signature[i]) { 95*03ce13f7SAndroid Build Coastguard Worker ArgIndex = i - 1; 96*03ce13f7SAndroid Build Coastguard Worker return Intrinsics::WrongArgType; 97*03ce13f7SAndroid Build Coastguard Worker } 98*03ce13f7SAndroid Build Coastguard Worker } 99*03ce13f7SAndroid Build Coastguard Worker return Intrinsics::IsValidIntrinsic; 100*03ce13f7SAndroid Build Coastguard Worker } 101*03ce13f7SAndroid Build Coastguard Worker getArgType(SizeT Index) const102*03ce13f7SAndroid Build Coastguard WorkerType Intrinsics::FullIntrinsicInfo::getArgType(SizeT Index) const { 103*03ce13f7SAndroid Build Coastguard Worker assert(NumTypes > 1); 104*03ce13f7SAndroid Build Coastguard Worker assert(Index + 1 < NumTypes); 105*03ce13f7SAndroid Build Coastguard Worker return Signature[Index + 1]; 106*03ce13f7SAndroid Build Coastguard Worker } 107*03ce13f7SAndroid Build Coastguard Worker 108*03ce13f7SAndroid Build Coastguard Worker } // end of namespace Ice 109