xref: /aosp_15_r20/external/swiftshader/third_party/subzero/src/IceIntrinsics.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
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 Worker bool 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 Worker Intrinsics::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 Worker Type 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