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(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, \
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)
136 #define MACHINE_TYPE_LIST(V) \
158 struct MachineOperatorGlobalCache {
159 #define PURE(Name, properties, value_input_count, control_input_count, \
161 struct Name##Operator FINAL : public Operator { \
163 : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \
164 value_input_count, 0, control_input_count, output_count, 0, \
167 Name##Operator k##Name;
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) {} \
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) {} \
185 Load##Type##Operator kLoad##Type; \
186 CheckedLoad##Type##Operator kCheckedLoad##Type;
187 MACHINE_TYPE_LIST(LOAD)
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)) {} \
198 struct Store##Type##NoWriteBarrier##Operator FINAL \
199 : public Store##Type##Operator { \
200 Store##Type##NoWriteBarrier##Operator() \
201 : Store##Type##Operator(kNoWriteBarrier) {} \
203 struct Store##Type##FullWriteBarrier##Operator FINAL \
204 : public Store##Type##Operator { \
205 Store##Type##FullWriteBarrier##Operator() \
206 : Store##Type##Operator(kFullWriteBarrier) {} \
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) {} \
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)
223 static base::LazyInstance<MachineOperatorGlobalCache>::type kCache =
224 LAZY_INSTANCE_INITIALIZER;
227 MachineOperatorBuilder::MachineOperatorBuilder(Zone* zone, MachineType word,
229 : zone_(zone), cache_(kCache.Get()), word_(word), flags_(flags) {
230 DCHECK(word == kRepWord32 || word == kRepWord64);
234 #define PURE(Name, properties, value_input_count, control_input_count, \
236 const Operator* MachineOperatorBuilder::Name() { return &cache_.k##Name; }
241 const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) {
245 return &cache_.kLoad##Type;
246 MACHINE_TYPE_LIST(LOAD)
252 return new (zone_) Operator1<LoadRepresentation>( // --
253 IrOpcode::kLoad, Operator::kNoThrow | Operator::kNoWrite, "Load", 2, 1, 1,
258 const Operator* MachineOperatorBuilder::Store(StoreRepresentation rep) {
259 switch (rep.machine_type()) {
260 #define STORE(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; \
269 MACHINE_TYPE_LIST(STORE)
276 return new (zone_) Operator1<StoreRepresentation>( // --
277 IrOpcode::kStore, Operator::kNoRead | Operator::kNoThrow, "Store", 3, 1,
282 const Operator* MachineOperatorBuilder::CheckedLoad(
283 CheckedLoadRepresentation rep) {
287 return &cache_.kCheckedLoad##Type;
288 MACHINE_TYPE_LIST(LOAD)
294 return new (zone_) Operator1<CheckedLoadRepresentation>(
295 IrOpcode::kCheckedLoad, Operator::kNoThrow | Operator::kNoWrite,
296 "CheckedLoad", 3, 1, 1, 1, 1, 0, rep);
300 const Operator* MachineOperatorBuilder::CheckedStore(
301 CheckedStoreRepresentation rep) {
303 #define STORE(Type) \
305 return &cache_.kCheckedStore##Type;
306 MACHINE_TYPE_LIST(STORE)
312 return new (zone_) Operator1<CheckedStoreRepresentation>(
313 IrOpcode::kCheckedStore, Operator::kNoRead | Operator::kNoThrow,
314 "CheckedStore", 4, 1, 1, 0, 1, 0, rep);
317 } // namespace compiler
318 } // namespace internal