2522a8e15dba03740ffe9a5e1cd72ff00666511f
[platform/upstream/nodejs.git] / deps / v8 / src / compiler / machine-operator.cc
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/compiler/machine-operator.h"
6
7 #include "src/base/lazy-instance.h"
8 #include "src/compiler/opcodes.h"
9 #include "src/compiler/operator.h"
10
11 namespace v8 {
12 namespace internal {
13 namespace compiler {
14
15 std::ostream& operator<<(std::ostream& os, WriteBarrierKind kind) {
16   switch (kind) {
17     case kNoWriteBarrier:
18       return os << "NoWriteBarrier";
19     case kFullWriteBarrier:
20       return os << "FullWriteBarrier";
21   }
22   UNREACHABLE();
23   return os;
24 }
25
26
27 bool operator==(StoreRepresentation lhs, StoreRepresentation rhs) {
28   return lhs.machine_type() == rhs.machine_type() &&
29          lhs.write_barrier_kind() == rhs.write_barrier_kind();
30 }
31
32
33 bool operator!=(StoreRepresentation lhs, StoreRepresentation rhs) {
34   return !(lhs == rhs);
35 }
36
37
38 size_t hash_value(StoreRepresentation rep) {
39   return base::hash_combine(rep.machine_type(), rep.write_barrier_kind());
40 }
41
42
43 std::ostream& operator<<(std::ostream& os, StoreRepresentation rep) {
44   return os << "(" << rep.machine_type() << " : " << rep.write_barrier_kind()
45             << ")";
46 }
47
48
49 StoreRepresentation const& StoreRepresentationOf(Operator const* op) {
50   DCHECK_EQ(IrOpcode::kStore, op->opcode());
51   return OpParameter<StoreRepresentation>(op);
52 }
53
54
55 CheckedLoadRepresentation CheckedLoadRepresentationOf(Operator const* op) {
56   DCHECK_EQ(IrOpcode::kCheckedLoad, op->opcode());
57   return OpParameter<CheckedLoadRepresentation>(op);
58 }
59
60
61 CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const* op) {
62   DCHECK_EQ(IrOpcode::kCheckedStore, op->opcode());
63   return OpParameter<CheckedStoreRepresentation>(op);
64 }
65
66
67 #define PURE_OP_LIST(V)                                                       \
68   V(Word32And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)      \
69   V(Word32Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)       \
70   V(Word32Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)      \
71   V(Word32Shl, Operator::kNoProperties, 2, 0, 1)                              \
72   V(Word32Shr, Operator::kNoProperties, 2, 0, 1)                              \
73   V(Word32Sar, Operator::kNoProperties, 2, 0, 1)                              \
74   V(Word32Ror, Operator::kNoProperties, 2, 0, 1)                              \
75   V(Word32Equal, Operator::kCommutative, 2, 0, 1)                             \
76   V(Word64And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)      \
77   V(Word64Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)       \
78   V(Word64Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)      \
79   V(Word64Shl, Operator::kNoProperties, 2, 0, 1)                              \
80   V(Word64Shr, Operator::kNoProperties, 2, 0, 1)                              \
81   V(Word64Sar, Operator::kNoProperties, 2, 0, 1)                              \
82   V(Word64Ror, Operator::kNoProperties, 2, 0, 1)                              \
83   V(Word64Equal, Operator::kCommutative, 2, 0, 1)                             \
84   V(Int32Add, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)       \
85   V(Int32AddWithOverflow, Operator::kAssociative | Operator::kCommutative, 2, \
86     0, 2)                                                                     \
87   V(Int32Sub, Operator::kNoProperties, 2, 0, 1)                               \
88   V(Int32SubWithOverflow, Operator::kNoProperties, 2, 0, 2)                   \
89   V(Int32Mul, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)       \
90   V(Int32MulHigh, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)   \
91   V(Int32Div, Operator::kNoProperties, 2, 1, 1)                               \
92   V(Int32Mod, Operator::kNoProperties, 2, 1, 1)                               \
93   V(Int32LessThan, Operator::kNoProperties, 2, 0, 1)                          \
94   V(Int32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                   \
95   V(Uint32Div, Operator::kNoProperties, 2, 1, 1)                              \
96   V(Uint32LessThan, Operator::kNoProperties, 2, 0, 1)                         \
97   V(Uint32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                  \
98   V(Uint32Mod, Operator::kNoProperties, 2, 1, 1)                              \
99   V(Uint32MulHigh, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)  \
100   V(Int64Add, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)       \
101   V(Int64Sub, Operator::kNoProperties, 2, 0, 1)                               \
102   V(Int64Mul, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)       \
103   V(Int64Div, Operator::kNoProperties, 2, 0, 1)                               \
104   V(Int64Mod, Operator::kNoProperties, 2, 0, 1)                               \
105   V(Int64LessThan, Operator::kNoProperties, 2, 0, 1)                          \
106   V(Int64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                   \
107   V(Uint64Div, Operator::kNoProperties, 2, 0, 1)                              \
108   V(Uint64LessThan, Operator::kNoProperties, 2, 0, 1)                         \
109   V(Uint64Mod, Operator::kNoProperties, 2, 0, 1)                              \
110   V(ChangeFloat32ToFloat64, Operator::kNoProperties, 1, 0, 1)                 \
111   V(ChangeFloat64ToInt32, Operator::kNoProperties, 1, 0, 1)                   \
112   V(ChangeFloat64ToUint32, Operator::kNoProperties, 1, 0, 1)                  \
113   V(ChangeInt32ToFloat64, Operator::kNoProperties, 1, 0, 1)                   \
114   V(ChangeInt32ToInt64, Operator::kNoProperties, 1, 0, 1)                     \
115   V(ChangeUint32ToFloat64, Operator::kNoProperties, 1, 0, 1)                  \
116   V(ChangeUint32ToUint64, Operator::kNoProperties, 1, 0, 1)                   \
117   V(TruncateFloat64ToFloat32, Operator::kNoProperties, 1, 0, 1)               \
118   V(TruncateFloat64ToInt32, Operator::kNoProperties, 1, 0, 1)                 \
119   V(TruncateInt64ToInt32, Operator::kNoProperties, 1, 0, 1)                   \
120   V(Float64Add, Operator::kCommutative, 2, 0, 1)                              \
121   V(Float64Sub, Operator::kNoProperties, 2, 0, 1)                             \
122   V(Float64Mul, Operator::kCommutative, 2, 0, 1)                              \
123   V(Float64Div, Operator::kNoProperties, 2, 0, 1)                             \
124   V(Float64Mod, Operator::kNoProperties, 2, 0, 1)                             \
125   V(Float64Sqrt, Operator::kNoProperties, 1, 0, 1)                            \
126   V(Float64Ceil, Operator::kNoProperties, 1, 0, 1)                            \
127   V(Float64Floor, Operator::kNoProperties, 1, 0, 1)                           \
128   V(Float64RoundTruncate, Operator::kNoProperties, 1, 0, 1)                   \
129   V(Float64RoundTiesAway, Operator::kNoProperties, 1, 0, 1)                   \
130   V(Float64Equal, Operator::kCommutative, 2, 0, 1)                            \
131   V(Float64LessThan, Operator::kNoProperties, 2, 0, 1)                        \
132   V(Float64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                 \
133   V(LoadStackPointer, Operator::kNoProperties, 0, 0, 1)
134
135
136 #define MACHINE_TYPE_LIST(V) \
137   V(MachFloat32)             \
138   V(MachFloat64)             \
139   V(MachInt8)                \
140   V(MachUint8)               \
141   V(MachInt16)               \
142   V(MachUint16)              \
143   V(MachInt32)               \
144   V(MachUint32)              \
145   V(MachInt64)               \
146   V(MachUint64)              \
147   V(MachAnyTagged)           \
148   V(RepBit)                  \
149   V(RepWord8)                \
150   V(RepWord16)               \
151   V(RepWord32)               \
152   V(RepWord64)               \
153   V(RepFloat32)              \
154   V(RepFloat64)              \
155   V(RepTagged)
156
157
158 struct MachineOperatorGlobalCache {
159 #define PURE(Name, properties, value_input_count, control_input_count,         \
160              output_count)                                                     \
161   struct Name##Operator FINAL : public Operator {                              \
162     Name##Operator()                                                           \
163         : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name,     \
164                    value_input_count, 0, control_input_count, output_count, 0, \
165                    0) {}                                                       \
166   };                                                                           \
167   Name##Operator k##Name;
168   PURE_OP_LIST(PURE)
169 #undef PURE
170
171 #define LOAD(Type)                                                             \
172   struct Load##Type##Operator FINAL : public Operator1<LoadRepresentation> {   \
173     Load##Type##Operator()                                                     \
174         : Operator1<LoadRepresentation>(                                       \
175               IrOpcode::kLoad, Operator::kNoThrow | Operator::kNoWrite,        \
176               "Load", 2, 1, 1, 1, 1, 0, k##Type) {}                            \
177   };                                                                           \
178   struct CheckedLoad##Type##Operator FINAL                                     \
179       : public Operator1<CheckedLoadRepresentation> {                          \
180     CheckedLoad##Type##Operator()                                              \
181         : Operator1<CheckedLoadRepresentation>(                                \
182               IrOpcode::kCheckedLoad, Operator::kNoThrow | Operator::kNoWrite, \
183               "CheckedLoad", 3, 1, 1, 1, 1, 0, k##Type) {}                     \
184   };                                                                           \
185   Load##Type##Operator kLoad##Type;                                            \
186   CheckedLoad##Type##Operator kCheckedLoad##Type;
187   MACHINE_TYPE_LIST(LOAD)
188 #undef LOAD
189
190 #define STORE(Type)                                                            \
191   struct Store##Type##Operator : public Operator1<StoreRepresentation> {       \
192     explicit Store##Type##Operator(WriteBarrierKind write_barrier_kind)        \
193         : Operator1<StoreRepresentation>(                                      \
194               IrOpcode::kStore, Operator::kNoRead | Operator::kNoThrow,        \
195               "Store", 3, 1, 1, 0, 1, 0,                                       \
196               StoreRepresentation(k##Type, write_barrier_kind)) {}             \
197   };                                                                           \
198   struct Store##Type##NoWriteBarrier##Operator FINAL                           \
199       : public Store##Type##Operator {                                         \
200     Store##Type##NoWriteBarrier##Operator()                                    \
201         : Store##Type##Operator(kNoWriteBarrier) {}                            \
202   };                                                                           \
203   struct Store##Type##FullWriteBarrier##Operator FINAL                         \
204       : public Store##Type##Operator {                                         \
205     Store##Type##FullWriteBarrier##Operator()                                  \
206         : Store##Type##Operator(kFullWriteBarrier) {}                          \
207   };                                                                           \
208   struct CheckedStore##Type##Operator FINAL                                    \
209       : public Operator1<CheckedStoreRepresentation> {                         \
210     CheckedStore##Type##Operator()                                             \
211         : Operator1<CheckedStoreRepresentation>(                               \
212               IrOpcode::kCheckedStore, Operator::kNoRead | Operator::kNoThrow, \
213               "CheckedStore", 4, 1, 1, 0, 1, 0, k##Type) {}                    \
214   };                                                                           \
215   Store##Type##NoWriteBarrier##Operator kStore##Type##NoWriteBarrier;          \
216   Store##Type##FullWriteBarrier##Operator kStore##Type##FullWriteBarrier;      \
217   CheckedStore##Type##Operator kCheckedStore##Type;
218   MACHINE_TYPE_LIST(STORE)
219 #undef STORE
220 };
221
222
223 static base::LazyInstance<MachineOperatorGlobalCache>::type kCache =
224     LAZY_INSTANCE_INITIALIZER;
225
226
227 MachineOperatorBuilder::MachineOperatorBuilder(Zone* zone, MachineType word,
228                                                Flags flags)
229     : zone_(zone), cache_(kCache.Get()), word_(word), flags_(flags) {
230   DCHECK(word == kRepWord32 || word == kRepWord64);
231 }
232
233
234 #define PURE(Name, properties, value_input_count, control_input_count, \
235              output_count)                                             \
236   const Operator* MachineOperatorBuilder::Name() { return &cache_.k##Name; }
237 PURE_OP_LIST(PURE)
238 #undef PURE
239
240
241 const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) {
242   switch (rep) {
243 #define LOAD(Type) \
244   case k##Type:    \
245     return &cache_.kLoad##Type;
246     MACHINE_TYPE_LIST(LOAD)
247 #undef LOAD
248     default:
249       break;
250   }
251   // Uncached.
252   return new (zone_) Operator1<LoadRepresentation>(  // --
253       IrOpcode::kLoad, Operator::kNoThrow | Operator::kNoWrite, "Load", 2, 1, 1,
254       1, 1, 0, rep);
255 }
256
257
258 const Operator* MachineOperatorBuilder::Store(StoreRepresentation rep) {
259   switch (rep.machine_type()) {
260 #define STORE(Type)                                      \
261   case k##Type:                                          \
262     switch (rep.write_barrier_kind()) {                  \
263       case kNoWriteBarrier:                              \
264         return &cache_.k##Store##Type##NoWriteBarrier;   \
265       case kFullWriteBarrier:                            \
266         return &cache_.k##Store##Type##FullWriteBarrier; \
267     }                                                    \
268     break;
269     MACHINE_TYPE_LIST(STORE)
270 #undef STORE
271
272     default:
273       break;
274   }
275   // Uncached.
276   return new (zone_) Operator1<StoreRepresentation>(  // --
277       IrOpcode::kStore, Operator::kNoRead | Operator::kNoThrow, "Store", 3, 1,
278       1, 0, 1, 0, rep);
279 }
280
281
282 const Operator* MachineOperatorBuilder::CheckedLoad(
283     CheckedLoadRepresentation rep) {
284   switch (rep) {
285 #define LOAD(Type) \
286   case k##Type:    \
287     return &cache_.kCheckedLoad##Type;
288     MACHINE_TYPE_LIST(LOAD)
289 #undef LOAD
290     default:
291       break;
292   }
293   // Uncached.
294   return new (zone_) Operator1<CheckedLoadRepresentation>(
295       IrOpcode::kCheckedLoad, Operator::kNoThrow | Operator::kNoWrite,
296       "CheckedLoad", 3, 1, 1, 1, 1, 0, rep);
297 }
298
299
300 const Operator* MachineOperatorBuilder::CheckedStore(
301     CheckedStoreRepresentation rep) {
302   switch (rep) {
303 #define STORE(Type) \
304   case k##Type:     \
305     return &cache_.kCheckedStore##Type;
306     MACHINE_TYPE_LIST(STORE)
307 #undef STORE
308     default:
309       break;
310   }
311   // Uncached.
312   return new (zone_) Operator1<CheckedStoreRepresentation>(
313       IrOpcode::kCheckedStore, Operator::kNoRead | Operator::kNoThrow,
314       "CheckedStore", 4, 1, 1, 0, 1, 0, rep);
315 }
316
317 }  // namespace compiler
318 }  // namespace internal
319 }  // namespace v8