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