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.
5 #include "src/compiler/machine-operator.h"
7 #include "src/base/lazy-instance.h"
8 #include "src/compiler/opcodes.h"
9 #include "src/compiler/operator.h"
15 std::ostream& operator<<(std::ostream& os, WriteBarrierKind kind) {
18 return os << "NoWriteBarrier";
19 case kFullWriteBarrier:
20 return os << "FullWriteBarrier";
27 bool operator==(StoreRepresentation lhs, StoreRepresentation rhs) {
28 return lhs.machine_type() == rhs.machine_type() &&
29 lhs.write_barrier_kind() == rhs.write_barrier_kind();
33 bool operator!=(StoreRepresentation lhs, StoreRepresentation rhs) {
38 size_t hash_value(StoreRepresentation rep) {
39 return base::hash_combine(rep.machine_type(), rep.write_barrier_kind());
43 std::ostream& operator<<(std::ostream& os, StoreRepresentation rep) {
44 return os << "(" << rep.machine_type() << " : " << rep.write_barrier_kind()
49 StoreRepresentation const& StoreRepresentationOf(Operator const* op) {
50 DCHECK_EQ(IrOpcode::kStore, op->opcode());
51 return OpParameter<StoreRepresentation>(op);
55 CheckedLoadRepresentation CheckedLoadRepresentationOf(Operator const* op) {
56 DCHECK_EQ(IrOpcode::kCheckedLoad, op->opcode());
57 return OpParameter<CheckedLoadRepresentation>(op);
61 CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const* op) {
62 DCHECK_EQ(IrOpcode::kCheckedStore, op->opcode());
63 return OpParameter<CheckedStoreRepresentation>(op);
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(Word32Clz, Operator::kNoProperties, 1, 0, 1) \
77 V(Word64And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
78 V(Word64Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
79 V(Word64Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
80 V(Word64Shl, Operator::kNoProperties, 2, 0, 1) \
81 V(Word64Shr, Operator::kNoProperties, 2, 0, 1) \
82 V(Word64Sar, Operator::kNoProperties, 2, 0, 1) \
83 V(Word64Ror, Operator::kNoProperties, 2, 0, 1) \
84 V(Word64Equal, Operator::kCommutative, 2, 0, 1) \
85 V(Int32Add, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
86 V(Int32AddWithOverflow, Operator::kAssociative | Operator::kCommutative, 2, \
88 V(Int32Sub, Operator::kNoProperties, 2, 0, 1) \
89 V(Int32SubWithOverflow, Operator::kNoProperties, 2, 0, 2) \
90 V(Int32Mul, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
91 V(Int32MulHigh, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
92 V(Int32Div, Operator::kNoProperties, 2, 1, 1) \
93 V(Int32Mod, Operator::kNoProperties, 2, 1, 1) \
94 V(Int32LessThan, Operator::kNoProperties, 2, 0, 1) \
95 V(Int32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \
96 V(Uint32Div, Operator::kNoProperties, 2, 1, 1) \
97 V(Uint32LessThan, Operator::kNoProperties, 2, 0, 1) \
98 V(Uint32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \
99 V(Uint32Mod, Operator::kNoProperties, 2, 1, 1) \
100 V(Uint32MulHigh, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
101 V(Int64Add, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
102 V(Int64Sub, Operator::kNoProperties, 2, 0, 1) \
103 V(Int64Mul, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
104 V(Int64Div, Operator::kNoProperties, 2, 0, 1) \
105 V(Int64Mod, Operator::kNoProperties, 2, 0, 1) \
106 V(Int64LessThan, Operator::kNoProperties, 2, 0, 1) \
107 V(Int64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \
108 V(Uint64Div, Operator::kNoProperties, 2, 0, 1) \
109 V(Uint64LessThan, Operator::kNoProperties, 2, 0, 1) \
110 V(Uint64Mod, Operator::kNoProperties, 2, 0, 1) \
111 V(ChangeFloat32ToFloat64, Operator::kNoProperties, 1, 0, 1) \
112 V(ChangeFloat64ToInt32, Operator::kNoProperties, 1, 0, 1) \
113 V(ChangeFloat64ToUint32, Operator::kNoProperties, 1, 0, 1) \
114 V(ChangeInt32ToFloat64, Operator::kNoProperties, 1, 0, 1) \
115 V(ChangeInt32ToInt64, Operator::kNoProperties, 1, 0, 1) \
116 V(ChangeUint32ToFloat64, Operator::kNoProperties, 1, 0, 1) \
117 V(ChangeUint32ToUint64, Operator::kNoProperties, 1, 0, 1) \
118 V(TruncateFloat64ToFloat32, Operator::kNoProperties, 1, 0, 1) \
119 V(TruncateFloat64ToInt32, Operator::kNoProperties, 1, 0, 1) \
120 V(TruncateInt64ToInt32, Operator::kNoProperties, 1, 0, 1) \
121 V(Float64Add, Operator::kCommutative, 2, 0, 1) \
122 V(Float64Sub, Operator::kNoProperties, 2, 0, 1) \
123 V(Float64Mul, Operator::kCommutative, 2, 0, 1) \
124 V(Float64Div, Operator::kNoProperties, 2, 0, 1) \
125 V(Float64Mod, Operator::kNoProperties, 2, 0, 1) \
126 V(Float64Sqrt, Operator::kNoProperties, 1, 0, 1) \
127 V(Float64RoundDown, 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(Float64ExtractLowWord32, Operator::kNoProperties, 1, 0, 1) \
134 V(Float64ExtractHighWord32, Operator::kNoProperties, 1, 0, 1) \
135 V(Float64InsertLowWord32, Operator::kNoProperties, 2, 0, 1) \
136 V(Float64InsertHighWord32, Operator::kNoProperties, 2, 0, 1) \
137 V(Float64Max, Operator::kNoProperties, 2, 0, 1) \
138 V(Float64Min, Operator::kNoProperties, 2, 0, 1) \
139 V(LoadStackPointer, Operator::kNoProperties, 0, 0, 1)
142 #define MACHINE_TYPE_LIST(V) \
164 struct MachineOperatorGlobalCache {
165 #define PURE(Name, properties, value_input_count, control_input_count, \
167 struct Name##Operator FINAL : public Operator { \
169 : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \
170 value_input_count, 0, control_input_count, output_count, 0, \
173 Name##Operator k##Name;
178 struct Load##Type##Operator FINAL : public Operator1<LoadRepresentation> { \
179 Load##Type##Operator() \
180 : Operator1<LoadRepresentation>( \
181 IrOpcode::kLoad, Operator::kNoThrow | Operator::kNoWrite, \
182 "Load", 2, 1, 1, 1, 1, 0, k##Type) {} \
184 struct CheckedLoad##Type##Operator FINAL \
185 : public Operator1<CheckedLoadRepresentation> { \
186 CheckedLoad##Type##Operator() \
187 : Operator1<CheckedLoadRepresentation>( \
188 IrOpcode::kCheckedLoad, Operator::kNoThrow | Operator::kNoWrite, \
189 "CheckedLoad", 3, 1, 1, 1, 1, 0, k##Type) {} \
191 Load##Type##Operator kLoad##Type; \
192 CheckedLoad##Type##Operator kCheckedLoad##Type;
193 MACHINE_TYPE_LIST(LOAD)
196 #define STORE(Type) \
197 struct Store##Type##Operator : public Operator1<StoreRepresentation> { \
198 explicit Store##Type##Operator(WriteBarrierKind write_barrier_kind) \
199 : Operator1<StoreRepresentation>( \
200 IrOpcode::kStore, Operator::kNoRead | Operator::kNoThrow, \
201 "Store", 3, 1, 1, 0, 1, 0, \
202 StoreRepresentation(k##Type, write_barrier_kind)) {} \
204 struct Store##Type##NoWriteBarrier##Operator FINAL \
205 : public Store##Type##Operator { \
206 Store##Type##NoWriteBarrier##Operator() \
207 : Store##Type##Operator(kNoWriteBarrier) {} \
209 struct Store##Type##FullWriteBarrier##Operator FINAL \
210 : public Store##Type##Operator { \
211 Store##Type##FullWriteBarrier##Operator() \
212 : Store##Type##Operator(kFullWriteBarrier) {} \
214 struct CheckedStore##Type##Operator FINAL \
215 : public Operator1<CheckedStoreRepresentation> { \
216 CheckedStore##Type##Operator() \
217 : Operator1<CheckedStoreRepresentation>( \
218 IrOpcode::kCheckedStore, Operator::kNoRead | Operator::kNoThrow, \
219 "CheckedStore", 4, 1, 1, 0, 1, 0, k##Type) {} \
221 Store##Type##NoWriteBarrier##Operator kStore##Type##NoWriteBarrier; \
222 Store##Type##FullWriteBarrier##Operator kStore##Type##FullWriteBarrier; \
223 CheckedStore##Type##Operator kCheckedStore##Type;
224 MACHINE_TYPE_LIST(STORE)
229 static base::LazyInstance<MachineOperatorGlobalCache>::type kCache =
230 LAZY_INSTANCE_INITIALIZER;
233 MachineOperatorBuilder::MachineOperatorBuilder(Zone* zone, MachineType word,
235 : zone_(zone), cache_(kCache.Get()), word_(word), flags_(flags) {
236 DCHECK(word == kRepWord32 || word == kRepWord64);
240 #define PURE(Name, properties, value_input_count, control_input_count, \
242 const Operator* MachineOperatorBuilder::Name() { return &cache_.k##Name; }
247 const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) {
251 return &cache_.kLoad##Type;
252 MACHINE_TYPE_LIST(LOAD)
258 return new (zone_) Operator1<LoadRepresentation>( // --
259 IrOpcode::kLoad, Operator::kNoThrow | Operator::kNoWrite, "Load", 2, 1, 1,
264 const Operator* MachineOperatorBuilder::Store(StoreRepresentation rep) {
265 switch (rep.machine_type()) {
266 #define STORE(Type) \
268 switch (rep.write_barrier_kind()) { \
269 case kNoWriteBarrier: \
270 return &cache_.k##Store##Type##NoWriteBarrier; \
271 case kFullWriteBarrier: \
272 return &cache_.k##Store##Type##FullWriteBarrier; \
275 MACHINE_TYPE_LIST(STORE)
282 return new (zone_) Operator1<StoreRepresentation>( // --
283 IrOpcode::kStore, Operator::kNoRead | Operator::kNoThrow, "Store", 3, 1,
288 const Operator* MachineOperatorBuilder::CheckedLoad(
289 CheckedLoadRepresentation rep) {
293 return &cache_.kCheckedLoad##Type;
294 MACHINE_TYPE_LIST(LOAD)
300 return new (zone_) Operator1<CheckedLoadRepresentation>(
301 IrOpcode::kCheckedLoad, Operator::kNoThrow | Operator::kNoWrite,
302 "CheckedLoad", 3, 1, 1, 1, 1, 0, rep);
306 const Operator* MachineOperatorBuilder::CheckedStore(
307 CheckedStoreRepresentation rep) {
309 #define STORE(Type) \
311 return &cache_.kCheckedStore##Type;
312 MACHINE_TYPE_LIST(STORE)
318 return new (zone_) Operator1<CheckedStoreRepresentation>(
319 IrOpcode::kCheckedStore, Operator::kNoRead | Operator::kNoThrow,
320 "CheckedStore", 4, 1, 1, 0, 1, 0, rep);
323 } // namespace compiler
324 } // namespace internal