| OLD | NEW |
| 1 //===- subzero/src/IceIntrinsics.cpp - Functions related to intrinsics ----===// | 1 //===- subzero/src/IceIntrinsics.cpp - Functions related to intrinsics ----===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This file implements the Intrinsics utilities for matching and | 10 // This file implements the Intrinsics utilities for matching and |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 | 21 |
| 22 #include <utility> | 22 #include <utility> |
| 23 | 23 |
| 24 namespace Ice { | 24 namespace Ice { |
| 25 | 25 |
| 26 static_assert(sizeof(Intrinsics::IntrinsicInfo) == 4, | 26 static_assert(sizeof(Intrinsics::IntrinsicInfo) == 4, |
| 27 "Unexpected sizeof(IntrinsicInfo)"); | 27 "Unexpected sizeof(IntrinsicInfo)"); |
| 28 | 28 |
| 29 namespace { | 29 namespace { |
| 30 | 30 |
| 31 #define INTRIN(ID, SE, RT) { Intrinsics::ID, Intrinsics::SE, Intrinsics::RT } | 31 #define INTRIN(ID, SE, RT) \ |
| 32 { Intrinsics::ID, Intrinsics::SE, Intrinsics::RT } |
| 32 | 33 |
| 33 // Build list of intrinsics with their attributes and expected prototypes. | 34 // Build list of intrinsics with their attributes and expected prototypes. |
| 34 // List is sorted alphabetically. | 35 // List is sorted alphabetically. |
| 35 const struct IceIntrinsicsEntry_ { | 36 const struct IceIntrinsicsEntry_ { |
| 36 Intrinsics::FullIntrinsicInfo Info; | 37 Intrinsics::FullIntrinsicInfo Info; |
| 37 const char *IntrinsicName; | 38 const char *IntrinsicName; |
| 38 } IceIntrinsicsTable[] = { | 39 } IceIntrinsicsTable[] = { |
| 39 | 40 |
| 40 #define AtomicCmpxchgInit(Overload, NameSuffix) \ | 41 #define AtomicCmpxchgInit(Overload, NameSuffix) \ |
| 41 { \ | 42 { \ |
| 42 { \ | 43 { \ |
| 43 INTRIN(AtomicCmpxchg, SideEffects_T, ReturnsTwice_F), \ | 44 INTRIN(AtomicCmpxchg, SideEffects_T, ReturnsTwice_F), {Overload, \ |
| 44 { Overload, IceType_i32, Overload, Overload, IceType_i32, IceType_i32 }, \ | 45 IceType_i32, \ |
| 45 6 }, \ | 46 Overload, \ |
| 46 "nacl.atomic.cmpxchg." NameSuffix \ | 47 Overload, \ |
| 48 IceType_i32, \ |
| 49 IceType_i32}, \ |
| 50 6 \ |
| 51 } \ |
| 52 , "nacl.atomic.cmpxchg." NameSuffix \ |
| 47 } | 53 } |
| 48 AtomicCmpxchgInit(IceType_i8, "i8"), | 54 AtomicCmpxchgInit(IceType_i8, "i8"), |
| 49 AtomicCmpxchgInit(IceType_i16, "i16"), | 55 AtomicCmpxchgInit(IceType_i16, "i16"), |
| 50 AtomicCmpxchgInit(IceType_i32, "i32"), | 56 AtomicCmpxchgInit(IceType_i32, "i32"), |
| 51 AtomicCmpxchgInit(IceType_i64, "i64"), | 57 AtomicCmpxchgInit(IceType_i64, "i64"), |
| 52 #undef AtomicCmpxchgInit | 58 #undef AtomicCmpxchgInit |
| 53 | 59 |
| 54 { { INTRIN(AtomicFence, SideEffects_T, ReturnsTwice_F), | 60 {{INTRIN(AtomicFence, SideEffects_T, ReturnsTwice_F), |
| 55 { IceType_void, IceType_i32 }, 2 }, | 61 {IceType_void, IceType_i32}, |
| 56 "nacl.atomic.fence" }, | 62 2}, |
| 57 { { INTRIN(AtomicFenceAll, SideEffects_T, ReturnsTwice_F), | 63 "nacl.atomic.fence"}, |
| 58 { IceType_void }, 1 }, | 64 {{INTRIN(AtomicFenceAll, SideEffects_T, ReturnsTwice_F), |
| 59 "nacl.atomic.fence.all" }, | 65 {IceType_void}, |
| 60 { { INTRIN(AtomicIsLockFree, SideEffects_F, ReturnsTwice_F), | 66 1}, |
| 61 { IceType_i1, IceType_i32, IceType_i32 }, 3 }, | 67 "nacl.atomic.fence.all"}, |
| 62 "nacl.atomic.is.lock.free" }, | 68 {{INTRIN(AtomicIsLockFree, SideEffects_F, ReturnsTwice_F), |
| 69 {IceType_i1, IceType_i32, IceType_i32}, |
| 70 3}, |
| 71 "nacl.atomic.is.lock.free"}, |
| 63 | 72 |
| 64 #define AtomicLoadInit(Overload, NameSuffix) \ | 73 #define AtomicLoadInit(Overload, NameSuffix) \ |
| 65 { \ | 74 { \ |
| 66 { \ | 75 { \ |
| 67 INTRIN(AtomicLoad, SideEffects_T, ReturnsTwice_F), \ | 76 INTRIN(AtomicLoad, SideEffects_T, ReturnsTwice_F), \ |
| 68 { Overload, IceType_i32, IceType_i32 }, 3 }, \ | 77 {Overload, IceType_i32, IceType_i32}, 3 \ |
| 69 "nacl.atomic.load." NameSuffix \ | 78 } \ |
| 79 , "nacl.atomic.load." NameSuffix \ |
| 70 } | 80 } |
| 71 AtomicLoadInit(IceType_i8, "i8"), | 81 AtomicLoadInit(IceType_i8, "i8"), |
| 72 AtomicLoadInit(IceType_i16, "i16"), | 82 AtomicLoadInit(IceType_i16, "i16"), |
| 73 AtomicLoadInit(IceType_i32, "i32"), | 83 AtomicLoadInit(IceType_i32, "i32"), |
| 74 AtomicLoadInit(IceType_i64, "i64"), | 84 AtomicLoadInit(IceType_i64, "i64"), |
| 75 #undef AtomicLoadInit | 85 #undef AtomicLoadInit |
| 76 | 86 |
| 77 #define AtomicRMWInit(Overload, NameSuffix) \ | 87 #define AtomicRMWInit(Overload, NameSuffix) \ |
| 78 { \ | 88 { \ |
| 79 { \ | 89 { \ |
| 80 INTRIN(AtomicRMW, SideEffects_T, ReturnsTwice_F) \ | 90 INTRIN(AtomicRMW, SideEffects_T, ReturnsTwice_F) \ |
| 81 , { Overload, IceType_i32, IceType_i32, Overload, IceType_i32 }, 5 \ | 91 , {Overload, IceType_i32, IceType_i32, Overload, IceType_i32}, 5 \ |
| 82 } \ | 92 } \ |
| 83 , "nacl.atomic.rmw." NameSuffix \ | 93 , "nacl.atomic.rmw." NameSuffix \ |
| 84 } | 94 } |
| 85 AtomicRMWInit(IceType_i8, "i8"), | 95 AtomicRMWInit(IceType_i8, "i8"), |
| 86 AtomicRMWInit(IceType_i16, "i16"), | 96 AtomicRMWInit(IceType_i16, "i16"), |
| 87 AtomicRMWInit(IceType_i32, "i32"), | 97 AtomicRMWInit(IceType_i32, "i32"), |
| 88 AtomicRMWInit(IceType_i64, "i64"), | 98 AtomicRMWInit(IceType_i64, "i64"), |
| 89 #undef AtomicRMWInit | 99 #undef AtomicRMWInit |
| 90 | 100 |
| 91 #define AtomicStoreInit(Overload, NameSuffix) \ | 101 #define AtomicStoreInit(Overload, NameSuffix) \ |
| 92 { \ | 102 { \ |
| 93 { \ | 103 { \ |
| 94 INTRIN(AtomicStore, SideEffects_T, ReturnsTwice_F) \ | 104 INTRIN(AtomicStore, SideEffects_T, ReturnsTwice_F) \ |
| 95 , { IceType_void, Overload, IceType_i32, IceType_i32 }, 4 \ | 105 , {IceType_void, Overload, IceType_i32, IceType_i32}, 4 \ |
| 96 } \ | 106 } \ |
| 97 , "nacl.atomic.store." NameSuffix \ | 107 , "nacl.atomic.store." NameSuffix \ |
| 98 } | 108 } |
| 99 AtomicStoreInit(IceType_i8, "i8"), | 109 AtomicStoreInit(IceType_i8, "i8"), |
| 100 AtomicStoreInit(IceType_i16, "i16"), | 110 AtomicStoreInit(IceType_i16, "i16"), |
| 101 AtomicStoreInit(IceType_i32, "i32"), | 111 AtomicStoreInit(IceType_i32, "i32"), |
| 102 AtomicStoreInit(IceType_i64, "i64"), | 112 AtomicStoreInit(IceType_i64, "i64"), |
| 103 #undef AtomicStoreInit | 113 #undef AtomicStoreInit |
| 104 | 114 |
| 105 #define BswapInit(Overload, NameSuffix) \ | 115 #define BswapInit(Overload, NameSuffix) \ |
| 106 { \ | 116 { \ |
| 107 { \ | 117 { \ |
| 108 INTRIN(Bswap, SideEffects_F, ReturnsTwice_F) \ | 118 INTRIN(Bswap, SideEffects_F, ReturnsTwice_F) \ |
| 109 , { Overload, Overload }, 2 \ | 119 , {Overload, Overload}, 2 \ |
| 110 } \ | 120 } \ |
| 111 , "bswap." NameSuffix \ | 121 , "bswap." NameSuffix \ |
| 112 } | 122 } |
| 113 BswapInit(IceType_i16, "i16"), | 123 BswapInit(IceType_i16, "i16"), |
| 114 BswapInit(IceType_i32, "i32"), | 124 BswapInit(IceType_i32, "i32"), |
| 115 BswapInit(IceType_i64, "i64"), | 125 BswapInit(IceType_i64, "i64"), |
| 116 #undef BswapInit | 126 #undef BswapInit |
| 117 | 127 |
| 118 #define CtlzInit(Overload, NameSuffix) \ | 128 #define CtlzInit(Overload, NameSuffix) \ |
| 119 { \ | 129 { \ |
| 120 { \ | 130 { \ |
| 121 INTRIN(Ctlz, SideEffects_F, ReturnsTwice_F) \ | 131 INTRIN(Ctlz, SideEffects_F, ReturnsTwice_F) \ |
| 122 , { Overload, Overload, IceType_i1 }, 3 \ | 132 , {Overload, Overload, IceType_i1}, 3 \ |
| 123 } \ | 133 } \ |
| 124 , "ctlz." NameSuffix \ | 134 , "ctlz." NameSuffix \ |
| 125 } | 135 } |
| 126 CtlzInit(IceType_i32, "i32"), | 136 CtlzInit(IceType_i32, "i32"), |
| 127 CtlzInit(IceType_i64, "i64"), | 137 CtlzInit(IceType_i64, "i64"), |
| 128 #undef CtlzInit | 138 #undef CtlzInit |
| 129 | 139 |
| 130 #define CtpopInit(Overload, NameSuffix) \ | 140 #define CtpopInit(Overload, NameSuffix) \ |
| 131 { \ | 141 { \ |
| 132 { \ | 142 { \ |
| 133 INTRIN(Ctpop, SideEffects_F, ReturnsTwice_F) \ | 143 INTRIN(Ctpop, SideEffects_F, ReturnsTwice_F) \ |
| 134 , { Overload, Overload }, 2 \ | 144 , {Overload, Overload}, 2 \ |
| 135 } \ | 145 } \ |
| 136 , "ctpop." NameSuffix \ | 146 , "ctpop." NameSuffix \ |
| 137 } | 147 } |
| 138 CtpopInit(IceType_i32, "i32"), | 148 CtpopInit(IceType_i32, "i32"), |
| 139 CtpopInit(IceType_i64, "i64"), | 149 CtpopInit(IceType_i64, "i64"), |
| 140 #undef CtpopInit | 150 #undef CtpopInit |
| 141 | 151 |
| 142 #define CttzInit(Overload, NameSuffix) \ | 152 #define CttzInit(Overload, NameSuffix) \ |
| 143 { \ | 153 { \ |
| 144 { \ | 154 { \ |
| 145 INTRIN(Cttz, SideEffects_F, ReturnsTwice_F) \ | 155 INTRIN(Cttz, SideEffects_F, ReturnsTwice_F) \ |
| 146 , { Overload, Overload, IceType_i1 }, 3 \ | 156 , {Overload, Overload, IceType_i1}, 3 \ |
| 147 } \ | 157 } \ |
| 148 , "cttz." NameSuffix \ | 158 , "cttz." NameSuffix \ |
| 149 } | 159 } |
| 150 CttzInit(IceType_i32, "i32"), | 160 CttzInit(IceType_i32, "i32"), |
| 151 CttzInit(IceType_i64, "i64"), | 161 CttzInit(IceType_i64, "i64"), |
| 152 #undef CttzInit | 162 #undef CttzInit |
| 153 | 163 |
| 154 { { INTRIN(Longjmp, SideEffects_T, ReturnsTwice_F), | 164 {{INTRIN(Longjmp, SideEffects_T, ReturnsTwice_F), |
| 155 { IceType_void, IceType_i32, IceType_i32 }, 3 }, | 165 {IceType_void, IceType_i32, IceType_i32}, |
| 156 "nacl.longjmp" }, | 166 3}, |
| 157 { { INTRIN(Memcpy, SideEffects_T, ReturnsTwice_F), | 167 "nacl.longjmp"}, |
| 158 { IceType_void, IceType_i32, IceType_i32, IceType_i32, IceType_i32, | 168 {{INTRIN(Memcpy, SideEffects_T, ReturnsTwice_F), |
| 159 IceType_i1}, | 169 {IceType_void, IceType_i32, IceType_i32, IceType_i32, IceType_i32, |
| 160 6 }, | 170 IceType_i1}, |
| 161 "memcpy.p0i8.p0i8.i32" }, | 171 6}, |
| 162 { { INTRIN(Memmove, SideEffects_T, ReturnsTwice_F), | 172 "memcpy.p0i8.p0i8.i32"}, |
| 163 { IceType_void, IceType_i32, IceType_i32, IceType_i32, IceType_i32, | 173 {{INTRIN(Memmove, SideEffects_T, ReturnsTwice_F), |
| 164 IceType_i1 }, | 174 {IceType_void, IceType_i32, IceType_i32, IceType_i32, IceType_i32, |
| 165 6 }, | 175 IceType_i1}, |
| 166 "memmove.p0i8.p0i8.i32" }, | 176 6}, |
| 167 { { INTRIN(Memset, SideEffects_T, ReturnsTwice_F), | 177 "memmove.p0i8.p0i8.i32"}, |
| 168 { IceType_void, IceType_i32, IceType_i8, IceType_i32, IceType_i32, | 178 {{INTRIN(Memset, SideEffects_T, ReturnsTwice_F), |
| 169 IceType_i1 }, | 179 {IceType_void, IceType_i32, IceType_i8, IceType_i32, IceType_i32, |
| 170 6 }, | 180 IceType_i1}, |
| 171 "memset.p0i8.i32" }, | 181 6}, |
| 172 { { INTRIN(NaClReadTP, SideEffects_F, ReturnsTwice_F), | 182 "memset.p0i8.i32"}, |
| 173 { IceType_i32 }, 1 }, | 183 {{INTRIN(NaClReadTP, SideEffects_F, ReturnsTwice_F), {IceType_i32}, 1}, |
| 174 "nacl.read.tp" }, | 184 "nacl.read.tp"}, |
| 175 { { INTRIN(Setjmp, SideEffects_T, ReturnsTwice_T), | 185 {{INTRIN(Setjmp, SideEffects_T, ReturnsTwice_T), |
| 176 { IceType_i32, IceType_i32 }, 2 }, | 186 {IceType_i32, IceType_i32}, |
| 177 "nacl.setjmp" }, | 187 2}, |
| 188 "nacl.setjmp"}, |
| 178 | 189 |
| 179 #define SqrtInit(Overload, NameSuffix) \ | 190 #define SqrtInit(Overload, NameSuffix) \ |
| 180 { \ | 191 { \ |
| 181 { \ | 192 { INTRIN(Sqrt, SideEffects_F, ReturnsTwice_F), {Overload, Overload}, 2 } \ |
| 182 INTRIN(Sqrt, SideEffects_F, ReturnsTwice_F), \ | 193 , "sqrt." NameSuffix \ |
| 183 { Overload, Overload }, 2 }, \ | |
| 184 "sqrt." NameSuffix \ | |
| 185 } | 194 } |
| 186 SqrtInit(IceType_f32, "f32"), | 195 SqrtInit(IceType_f32, "f32"), |
| 187 SqrtInit(IceType_f64, "f64"), | 196 SqrtInit(IceType_f64, "f64"), |
| 188 #undef SqrtInit | 197 #undef SqrtInit |
| 189 | 198 |
| 190 { { INTRIN(Stacksave, SideEffects_T, ReturnsTwice_F), | 199 {{INTRIN(Stacksave, SideEffects_T, ReturnsTwice_F), {IceType_i32}, 1}, |
| 191 { IceType_i32 }, 1 }, | 200 "stacksave"}, |
| 192 "stacksave" }, | 201 {{INTRIN(Stackrestore, SideEffects_T, ReturnsTwice_F), |
| 193 { { INTRIN(Stackrestore, SideEffects_T, ReturnsTwice_F), | 202 {IceType_void, IceType_i32}, |
| 194 { IceType_void, IceType_i32 }, 2 }, | 203 2}, |
| 195 "stackrestore" }, | 204 "stackrestore"}, |
| 196 { { INTRIN(Trap, SideEffects_T, ReturnsTwice_F), | 205 {{INTRIN(Trap, SideEffects_T, ReturnsTwice_F), {IceType_void}, 1}, |
| 197 { IceType_void }, 1 }, | 206 "trap"}}; |
| 198 "trap" } | |
| 199 }; | |
| 200 const size_t IceIntrinsicsTableSize = llvm::array_lengthof(IceIntrinsicsTable); | 207 const size_t IceIntrinsicsTableSize = llvm::array_lengthof(IceIntrinsicsTable); |
| 201 | 208 |
| 202 #undef INTRIN | 209 #undef INTRIN |
| 203 | 210 |
| 204 } // end of anonymous namespace | 211 } // end of anonymous namespace |
| 205 | 212 |
| 206 Intrinsics::Intrinsics() { | 213 Intrinsics::Intrinsics() { |
| 207 for (size_t I = 0; I < IceIntrinsicsTableSize; ++I) { | 214 for (size_t I = 0; I < IceIntrinsicsTableSize; ++I) { |
| 208 const struct IceIntrinsicsEntry_ &Entry = IceIntrinsicsTable[I]; | 215 const struct IceIntrinsicsEntry_ &Entry = IceIntrinsicsTable[I]; |
| 209 assert(Entry.Info.NumTypes <= kMaxIntrinsicParameters); | 216 assert(Entry.Info.NumTypes <= kMaxIntrinsicParameters); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 return Intrinsics::IsValidCall; | 256 return Intrinsics::IsValidCall; |
| 250 } | 257 } |
| 251 | 258 |
| 252 Type Intrinsics::FullIntrinsicInfo::getArgType(SizeT Index) const { | 259 Type Intrinsics::FullIntrinsicInfo::getArgType(SizeT Index) const { |
| 253 assert(NumTypes > 1); | 260 assert(NumTypes > 1); |
| 254 assert(Index + 1 < NumTypes); | 261 assert(Index + 1 < NumTypes); |
| 255 return Signature[Index + 1]; | 262 return Signature[Index + 1]; |
| 256 } | 263 } |
| 257 | 264 |
| 258 } // end of namespace Ice | 265 } // end of namespace Ice |
| OLD | NEW |