1 // Copyright 2013 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 #ifndef V8_COMPILER_MACHINE_OPERATOR_H_
6 #define V8_COMPILER_MACHINE_OPERATOR_H_
8 #include "src/base/flags.h"
9 #include "src/compiler/machine-type.h"
15 // Forward declarations.
16 struct MachineOperatorGlobalCache;
20 // Supported write barrier modes.
21 enum WriteBarrierKind { kNoWriteBarrier, kFullWriteBarrier };
23 std::ostream& operator<<(std::ostream& os, WriteBarrierKind);
26 // A Load needs a MachineType.
27 typedef MachineType LoadRepresentation;
30 // A Store needs a MachineType and a WriteBarrierKind in order to emit the
31 // correct write barrier.
32 class StoreRepresentation FINAL {
34 StoreRepresentation(MachineType machine_type,
35 WriteBarrierKind write_barrier_kind)
36 : machine_type_(machine_type), write_barrier_kind_(write_barrier_kind) {}
38 MachineType machine_type() const { return machine_type_; }
39 WriteBarrierKind write_barrier_kind() const { return write_barrier_kind_; }
42 MachineType machine_type_;
43 WriteBarrierKind write_barrier_kind_;
46 bool operator==(StoreRepresentation, StoreRepresentation);
47 bool operator!=(StoreRepresentation, StoreRepresentation);
49 size_t hash_value(StoreRepresentation);
51 std::ostream& operator<<(std::ostream&, StoreRepresentation);
53 StoreRepresentation const& StoreRepresentationOf(Operator const*);
56 // A CheckedLoad needs a MachineType.
57 typedef MachineType CheckedLoadRepresentation;
59 CheckedLoadRepresentation CheckedLoadRepresentationOf(Operator const*);
62 // A CheckedStore needs a MachineType.
63 typedef MachineType CheckedStoreRepresentation;
65 CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const*);
68 // Interface for building machine-level operators. These operators are
69 // machine-level but machine-independent and thus define a language suitable
70 // for generating code to run on architectures such as ia32, x64, arm, etc.
71 class MachineOperatorBuilder FINAL : public ZoneObject {
73 // Flags that specify which operations are available. This is useful
74 // for operations that are unsupported by some back-ends.
77 kFloat64Max = 1u << 0,
78 kFloat64Min = 1u << 1,
79 kFloat64RoundDown = 1u << 2,
80 kFloat64RoundTruncate = 1u << 3,
81 kFloat64RoundTiesAway = 1u << 4,
82 kInt32DivIsSafe = 1u << 5,
83 kUint32DivIsSafe = 1u << 6,
84 kWord32ShiftIsSafe = 1u << 7
86 typedef base::Flags<Flag, unsigned> Flags;
88 explicit MachineOperatorBuilder(Zone* zone, MachineType word = kMachPtr,
89 Flags supportedOperators = kNoFlags);
91 const Operator* Word32And();
92 const Operator* Word32Or();
93 const Operator* Word32Xor();
94 const Operator* Word32Shl();
95 const Operator* Word32Shr();
96 const Operator* Word32Sar();
97 const Operator* Word32Ror();
98 const Operator* Word32Equal();
99 const Operator* Word32Clz();
100 bool Word32ShiftIsSafe() const { return flags_ & kWord32ShiftIsSafe; }
102 const Operator* Word64And();
103 const Operator* Word64Or();
104 const Operator* Word64Xor();
105 const Operator* Word64Shl();
106 const Operator* Word64Shr();
107 const Operator* Word64Sar();
108 const Operator* Word64Ror();
109 const Operator* Word64Equal();
111 const Operator* Int32Add();
112 const Operator* Int32AddWithOverflow();
113 const Operator* Int32Sub();
114 const Operator* Int32SubWithOverflow();
115 const Operator* Int32Mul();
116 const Operator* Int32MulHigh();
117 const Operator* Int32Div();
118 const Operator* Int32Mod();
119 const Operator* Int32LessThan();
120 const Operator* Int32LessThanOrEqual();
121 const Operator* Uint32Div();
122 const Operator* Uint32LessThan();
123 const Operator* Uint32LessThanOrEqual();
124 const Operator* Uint32Mod();
125 const Operator* Uint32MulHigh();
126 bool Int32DivIsSafe() const { return flags_ & kInt32DivIsSafe; }
127 bool Uint32DivIsSafe() const { return flags_ & kUint32DivIsSafe; }
129 const Operator* Int64Add();
130 const Operator* Int64Sub();
131 const Operator* Int64Mul();
132 const Operator* Int64Div();
133 const Operator* Int64Mod();
134 const Operator* Int64LessThan();
135 const Operator* Int64LessThanOrEqual();
136 const Operator* Uint64Div();
137 const Operator* Uint64LessThan();
138 const Operator* Uint64Mod();
140 // These operators change the representation of numbers while preserving the
141 // value of the number. Narrowing operators assume the input is representable
142 // in the target type and are *not* defined for other inputs.
143 // Use narrowing change operators only when there is a static guarantee that
144 // the input value is representable in the target value.
145 const Operator* ChangeFloat32ToFloat64();
146 const Operator* ChangeFloat64ToInt32(); // narrowing
147 const Operator* ChangeFloat64ToUint32(); // narrowing
148 const Operator* ChangeInt32ToFloat64();
149 const Operator* ChangeInt32ToInt64();
150 const Operator* ChangeUint32ToFloat64();
151 const Operator* ChangeUint32ToUint64();
153 // These operators truncate numbers, both changing the representation of
154 // the number and mapping multiple input values onto the same output value.
155 const Operator* TruncateFloat64ToFloat32();
156 const Operator* TruncateFloat64ToInt32(); // JavaScript semantics.
157 const Operator* TruncateInt64ToInt32();
159 // Floating point operators always operate with IEEE 754 round-to-nearest.
160 const Operator* Float64Add();
161 const Operator* Float64Sub();
162 const Operator* Float64Mul();
163 const Operator* Float64Div();
164 const Operator* Float64Mod();
165 const Operator* Float64Sqrt();
167 // Floating point comparisons complying to IEEE 754.
168 const Operator* Float64Equal();
169 const Operator* Float64LessThan();
170 const Operator* Float64LessThanOrEqual();
172 // Floating point min/max complying to IEEE 754.
173 const Operator* Float64Max();
174 const Operator* Float64Min();
175 bool HasFloat64Max() { return flags_ & kFloat64Max; }
176 bool HasFloat64Min() { return flags_ & kFloat64Min; }
178 // Floating point rounding.
179 const Operator* Float64RoundDown();
180 const Operator* Float64RoundTruncate();
181 const Operator* Float64RoundTiesAway();
182 bool HasFloat64RoundDown() { return flags_ & kFloat64RoundDown; }
183 bool HasFloat64RoundTruncate() { return flags_ & kFloat64RoundTruncate; }
184 bool HasFloat64RoundTiesAway() { return flags_ & kFloat64RoundTiesAway; }
186 // Floating point bit representation.
187 const Operator* Float64ExtractLowWord32();
188 const Operator* Float64ExtractHighWord32();
189 const Operator* Float64InsertLowWord32();
190 const Operator* Float64InsertHighWord32();
192 // load [base + index]
193 const Operator* Load(LoadRepresentation rep);
195 // store [base + index], value
196 const Operator* Store(StoreRepresentation rep);
198 // Access to the machine stack.
199 const Operator* LoadStackPointer();
201 // checked-load heap, index, length
202 const Operator* CheckedLoad(CheckedLoadRepresentation);
203 // checked-store heap, index, length, value
204 const Operator* CheckedStore(CheckedStoreRepresentation);
206 // Target machine word-size assumed by this builder.
207 bool Is32() const { return word() == kRepWord32; }
208 bool Is64() const { return word() == kRepWord64; }
209 MachineType word() const { return word_; }
211 // Pseudo operators that translate to 32/64-bit operators depending on the
212 // word-size of the target machine assumed by this builder.
213 #define PSEUDO_OP_LIST(V) \
228 V(Int, LessThanOrEqual) \
232 #define PSEUDO_OP(Prefix, Suffix) \
233 const Operator* Prefix##Suffix() { \
234 return Is32() ? Prefix##32##Suffix() : Prefix##64##Suffix(); \
236 PSEUDO_OP_LIST(PSEUDO_OP)
238 #undef PSEUDO_OP_LIST
242 MachineOperatorGlobalCache const& cache_;
243 MachineType const word_;
246 DISALLOW_COPY_AND_ASSIGN(MachineOperatorBuilder);
250 DEFINE_OPERATORS_FOR_FLAGS(MachineOperatorBuilder::Flags)
252 } // namespace compiler
253 } // namespace internal
256 #endif // V8_COMPILER_MACHINE_OPERATOR_H_