• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)32 bool 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) const80 Intrinsics::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) const102 Type 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