blob: 68e393aaddf74fbbf650fb87a9b66c2400406eac [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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.
4
5#ifndef V8_COMPILER_MACHINE_OPERATOR_H_
6#define V8_COMPILER_MACHINE_OPERATOR_H_
7
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008#include "src/base/flags.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009#include "src/machine-type.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010
11namespace v8 {
12namespace internal {
13namespace compiler {
14
15// Forward declarations.
Emily Bernierd0a1eb72015-03-24 16:35:39 -040016struct MachineOperatorGlobalCache;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000017class Operator;
18
19
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000020// For operators that are not supported on all platforms.
21class OptionalOperator final {
22 public:
23 explicit OptionalOperator(const Operator* op) : op_(op) {}
24
25 bool IsSupported() const { return op_ != nullptr; }
26 const Operator* op() const {
27 DCHECK_NOT_NULL(op_);
28 return op_;
29 }
30
31 private:
32 const Operator* const op_;
33};
34
35
36// Supported float64 to int32 truncation modes.
37enum class TruncationMode : uint8_t {
38 kJavaScript, // ES6 section 7.1.5
39 kRoundToZero // Round towards zero. Implementation defined for NaN and ovf.
40};
41
42V8_INLINE size_t hash_value(TruncationMode mode) {
43 return static_cast<uint8_t>(mode);
44}
45
46std::ostream& operator<<(std::ostream&, TruncationMode);
47
48TruncationMode TruncationModeOf(Operator const*);
49
50
Ben Murdochb8a8cc12014-11-26 15:28:44 +000051// Supported write barrier modes.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000052enum WriteBarrierKind {
53 kNoWriteBarrier,
54 kMapWriteBarrier,
55 kPointerWriteBarrier,
56 kFullWriteBarrier
57};
Ben Murdochb8a8cc12014-11-26 15:28:44 +000058
Emily Bernierd0a1eb72015-03-24 16:35:39 -040059std::ostream& operator<<(std::ostream& os, WriteBarrierKind);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000060
61
Emily Bernierd0a1eb72015-03-24 16:35:39 -040062// A Load needs a MachineType.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000063typedef MachineType LoadRepresentation;
64
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000065LoadRepresentation LoadRepresentationOf(Operator const*);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000066
Emily Bernierd0a1eb72015-03-24 16:35:39 -040067// A Store needs a MachineType and a WriteBarrierKind in order to emit the
68// correct write barrier.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000069class StoreRepresentation final {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000070 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000071 StoreRepresentation(MachineRepresentation representation,
Ben Murdochb8a8cc12014-11-26 15:28:44 +000072 WriteBarrierKind write_barrier_kind)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000073 : representation_(representation),
74 write_barrier_kind_(write_barrier_kind) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +000075
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000076 MachineRepresentation representation() const { return representation_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000077 WriteBarrierKind write_barrier_kind() const { return write_barrier_kind_; }
78
79 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000080 MachineRepresentation representation_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000081 WriteBarrierKind write_barrier_kind_;
82};
83
Emily Bernierd0a1eb72015-03-24 16:35:39 -040084bool operator==(StoreRepresentation, StoreRepresentation);
85bool operator!=(StoreRepresentation, StoreRepresentation);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000086
Emily Bernierd0a1eb72015-03-24 16:35:39 -040087size_t hash_value(StoreRepresentation);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000088
Emily Bernierd0a1eb72015-03-24 16:35:39 -040089std::ostream& operator<<(std::ostream&, StoreRepresentation);
90
91StoreRepresentation const& StoreRepresentationOf(Operator const*);
92
93
94// A CheckedLoad needs a MachineType.
95typedef MachineType CheckedLoadRepresentation;
96
97CheckedLoadRepresentation CheckedLoadRepresentationOf(Operator const*);
98
99
100// A CheckedStore needs a MachineType.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000101typedef MachineRepresentation CheckedStoreRepresentation;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400102
103CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const*);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000104
Ben Murdoch097c5b22016-05-18 11:27:45 +0100105MachineRepresentation StackSlotRepresentationOf(Operator const* op);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000106
107// Interface for building machine-level operators. These operators are
108// machine-level but machine-independent and thus define a language suitable
109// for generating code to run on architectures such as ia32, x64, arm, etc.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000110class MachineOperatorBuilder final : public ZoneObject {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000111 public:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400112 // Flags that specify which operations are available. This is useful
113 // for operations that are unsupported by some back-ends.
114 enum Flag {
115 kNoFlags = 0u,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000116 // Note that Float*Max behaves like `(b < a) ? a : b`, not like Math.max().
117 // Note that Float*Min behaves like `(a < b) ? a : b`, not like Math.min().
118 kFloat32Max = 1u << 0,
119 kFloat32Min = 1u << 1,
120 kFloat64Max = 1u << 2,
121 kFloat64Min = 1u << 3,
122 kFloat32RoundDown = 1u << 4,
123 kFloat64RoundDown = 1u << 5,
124 kFloat32RoundUp = 1u << 6,
125 kFloat64RoundUp = 1u << 7,
126 kFloat32RoundTruncate = 1u << 8,
127 kFloat64RoundTruncate = 1u << 9,
128 kFloat32RoundTiesEven = 1u << 10,
129 kFloat64RoundTiesEven = 1u << 11,
130 kFloat64RoundTiesAway = 1u << 12,
131 kInt32DivIsSafe = 1u << 13,
132 kUint32DivIsSafe = 1u << 14,
133 kWord32ShiftIsSafe = 1u << 15,
134 kWord32Ctz = 1u << 16,
135 kWord64Ctz = 1u << 17,
136 kWord32Popcnt = 1u << 18,
137 kWord64Popcnt = 1u << 19,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100138 kWord32ReverseBits = 1u << 20,
139 kWord64ReverseBits = 1u << 21,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000140 kAllOptionalOps = kFloat32Max | kFloat32Min | kFloat64Max | kFloat64Min |
141 kFloat32RoundDown | kFloat64RoundDown | kFloat32RoundUp |
142 kFloat64RoundUp | kFloat32RoundTruncate |
143 kFloat64RoundTruncate | kFloat64RoundTiesAway |
144 kFloat32RoundTiesEven | kFloat64RoundTiesEven |
Ben Murdoch097c5b22016-05-18 11:27:45 +0100145 kWord32Ctz | kWord64Ctz | kWord32Popcnt | kWord64Popcnt |
146 kWord32ReverseBits | kWord64ReverseBits
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400147 };
148 typedef base::Flags<Flag, unsigned> Flags;
149
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000150 explicit MachineOperatorBuilder(
151 Zone* zone,
152 MachineRepresentation word = MachineType::PointerRepresentation(),
153 Flags supportedOperators = kNoFlags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000154
155 const Operator* Word32And();
156 const Operator* Word32Or();
157 const Operator* Word32Xor();
158 const Operator* Word32Shl();
159 const Operator* Word32Shr();
160 const Operator* Word32Sar();
161 const Operator* Word32Ror();
162 const Operator* Word32Equal();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000163 const Operator* Word32Clz();
164 const OptionalOperator Word32Ctz();
165 const OptionalOperator Word32Popcnt();
166 const OptionalOperator Word64Popcnt();
Ben Murdochda12d292016-06-02 14:46:10 +0100167 const Operator* Word64PopcntPlaceholder();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100168 const OptionalOperator Word32ReverseBits();
169 const OptionalOperator Word64ReverseBits();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400170 bool Word32ShiftIsSafe() const { return flags_ & kWord32ShiftIsSafe; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000171
172 const Operator* Word64And();
173 const Operator* Word64Or();
174 const Operator* Word64Xor();
175 const Operator* Word64Shl();
176 const Operator* Word64Shr();
177 const Operator* Word64Sar();
178 const Operator* Word64Ror();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000179 const Operator* Word64Clz();
180 const OptionalOperator Word64Ctz();
Ben Murdochda12d292016-06-02 14:46:10 +0100181 const Operator* Word64CtzPlaceholder();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000182 const Operator* Word64Equal();
183
Ben Murdochda12d292016-06-02 14:46:10 +0100184 const Operator* Int32PairAdd();
185 const Operator* Int32PairSub();
186 const Operator* Int32PairMul();
187 const Operator* Word32PairShl();
188 const Operator* Word32PairShr();
189 const Operator* Word32PairSar();
190
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000191 const Operator* Int32Add();
192 const Operator* Int32AddWithOverflow();
193 const Operator* Int32Sub();
194 const Operator* Int32SubWithOverflow();
195 const Operator* Int32Mul();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400196 const Operator* Int32MulHigh();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000197 const Operator* Int32Div();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000198 const Operator* Int32Mod();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000199 const Operator* Int32LessThan();
200 const Operator* Int32LessThanOrEqual();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400201 const Operator* Uint32Div();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000202 const Operator* Uint32LessThan();
203 const Operator* Uint32LessThanOrEqual();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400204 const Operator* Uint32Mod();
205 const Operator* Uint32MulHigh();
206 bool Int32DivIsSafe() const { return flags_ & kInt32DivIsSafe; }
207 bool Uint32DivIsSafe() const { return flags_ & kUint32DivIsSafe; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000208
209 const Operator* Int64Add();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000210 const Operator* Int64AddWithOverflow();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000211 const Operator* Int64Sub();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000212 const Operator* Int64SubWithOverflow();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000213 const Operator* Int64Mul();
214 const Operator* Int64Div();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000215 const Operator* Int64Mod();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000216 const Operator* Int64LessThan();
217 const Operator* Int64LessThanOrEqual();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400218 const Operator* Uint64Div();
219 const Operator* Uint64LessThan();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000220 const Operator* Uint64LessThanOrEqual();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400221 const Operator* Uint64Mod();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000222
223 // These operators change the representation of numbers while preserving the
224 // value of the number. Narrowing operators assume the input is representable
225 // in the target type and are *not* defined for other inputs.
226 // Use narrowing change operators only when there is a static guarantee that
227 // the input value is representable in the target value.
228 const Operator* ChangeFloat32ToFloat64();
229 const Operator* ChangeFloat64ToInt32(); // narrowing
230 const Operator* ChangeFloat64ToUint32(); // narrowing
Ben Murdochda12d292016-06-02 14:46:10 +0100231 const Operator* TruncateFloat64ToUint32();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100232 const Operator* TruncateFloat32ToInt32();
233 const Operator* TruncateFloat32ToUint32();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000234 const Operator* TryTruncateFloat32ToInt64();
235 const Operator* TryTruncateFloat64ToInt64();
236 const Operator* TryTruncateFloat32ToUint64();
237 const Operator* TryTruncateFloat64ToUint64();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000238 const Operator* ChangeInt32ToFloat64();
239 const Operator* ChangeInt32ToInt64();
240 const Operator* ChangeUint32ToFloat64();
241 const Operator* ChangeUint32ToUint64();
242
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000243 // These operators truncate or round numbers, both changing the representation
244 // of the number and mapping multiple input values onto the same output value.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000245 const Operator* TruncateFloat64ToFloat32();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000246 const Operator* TruncateFloat64ToInt32(TruncationMode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000247 const Operator* TruncateInt64ToInt32();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100248 const Operator* RoundInt32ToFloat32();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000249 const Operator* RoundInt64ToFloat32();
250 const Operator* RoundInt64ToFloat64();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100251 const Operator* RoundUint32ToFloat32();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000252 const Operator* RoundUint64ToFloat32();
253 const Operator* RoundUint64ToFloat64();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000254
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000255 // These operators reinterpret the bits of a floating point number as an
256 // integer and vice versa.
257 const Operator* BitcastFloat32ToInt32();
258 const Operator* BitcastFloat64ToInt64();
259 const Operator* BitcastInt32ToFloat32();
260 const Operator* BitcastInt64ToFloat64();
261
262 // Floating point operators always operate with IEEE 754 round-to-nearest
263 // (single-precision).
264 const Operator* Float32Add();
265 const Operator* Float32Sub();
266 const Operator* Float32Mul();
267 const Operator* Float32Div();
268 const Operator* Float32Sqrt();
269
270 // Floating point operators always operate with IEEE 754 round-to-nearest
271 // (double-precision).
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000272 const Operator* Float64Add();
273 const Operator* Float64Sub();
274 const Operator* Float64Mul();
275 const Operator* Float64Div();
276 const Operator* Float64Mod();
277 const Operator* Float64Sqrt();
278
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000279 // Floating point comparisons complying to IEEE 754 (single-precision).
280 const Operator* Float32Equal();
281 const Operator* Float32LessThan();
282 const Operator* Float32LessThanOrEqual();
283
284 // Floating point comparisons complying to IEEE 754 (double-precision).
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000285 const Operator* Float64Equal();
286 const Operator* Float64LessThan();
287 const Operator* Float64LessThanOrEqual();
288
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000289 // Floating point min/max complying to IEEE 754 (single-precision).
290 const OptionalOperator Float32Max();
291 const OptionalOperator Float32Min();
292
293 // Floating point min/max complying to IEEE 754 (double-precision).
294 const OptionalOperator Float64Max();
295 const OptionalOperator Float64Min();
296
297 // Floating point abs complying to IEEE 754 (single-precision).
298 const Operator* Float32Abs();
299
300 // Floating point abs complying to IEEE 754 (double-precision).
301 const Operator* Float64Abs();
302
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400303 // Floating point rounding.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000304 const OptionalOperator Float32RoundDown();
305 const OptionalOperator Float64RoundDown();
306 const OptionalOperator Float32RoundUp();
307 const OptionalOperator Float64RoundUp();
308 const OptionalOperator Float32RoundTruncate();
309 const OptionalOperator Float64RoundTruncate();
310 const OptionalOperator Float64RoundTiesAway();
311 const OptionalOperator Float32RoundTiesEven();
312 const OptionalOperator Float64RoundTiesEven();
313
314 // Floating point bit representation.
315 const Operator* Float64ExtractLowWord32();
316 const Operator* Float64ExtractHighWord32();
317 const Operator* Float64InsertLowWord32();
318 const Operator* Float64InsertHighWord32();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400319
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000320 // load [base + index]
321 const Operator* Load(LoadRepresentation rep);
322
323 // store [base + index], value
324 const Operator* Store(StoreRepresentation rep);
325
Ben Murdoch097c5b22016-05-18 11:27:45 +0100326 const Operator* StackSlot(MachineRepresentation rep);
327
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400328 // Access to the machine stack.
329 const Operator* LoadStackPointer();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000330 const Operator* LoadFramePointer();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100331 const Operator* LoadParentFramePointer();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400332
333 // checked-load heap, index, length
334 const Operator* CheckedLoad(CheckedLoadRepresentation);
335 // checked-store heap, index, length, value
336 const Operator* CheckedStore(CheckedStoreRepresentation);
337
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000338 // Target machine word-size assumed by this builder.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000339 bool Is32() const { return word() == MachineRepresentation::kWord32; }
340 bool Is64() const { return word() == MachineRepresentation::kWord64; }
341 MachineRepresentation word() const { return word_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000342
343// Pseudo operators that translate to 32/64-bit operators depending on the
344// word-size of the target machine assumed by this builder.
345#define PSEUDO_OP_LIST(V) \
346 V(Word, And) \
347 V(Word, Or) \
348 V(Word, Xor) \
349 V(Word, Shl) \
350 V(Word, Shr) \
351 V(Word, Sar) \
352 V(Word, Ror) \
Ben Murdochda12d292016-06-02 14:46:10 +0100353 V(Word, Clz) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000354 V(Word, Equal) \
355 V(Int, Add) \
356 V(Int, Sub) \
357 V(Int, Mul) \
358 V(Int, Div) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000359 V(Int, Mod) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000360 V(Int, LessThan) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400361 V(Int, LessThanOrEqual) \
362 V(Uint, Div) \
363 V(Uint, LessThan) \
364 V(Uint, Mod)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000365#define PSEUDO_OP(Prefix, Suffix) \
366 const Operator* Prefix##Suffix() { \
367 return Is32() ? Prefix##32##Suffix() : Prefix##64##Suffix(); \
368 }
369 PSEUDO_OP_LIST(PSEUDO_OP)
370#undef PSEUDO_OP
371#undef PSEUDO_OP_LIST
372
373 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000374 MachineOperatorGlobalCache const& cache_;
375 MachineRepresentation const word_;
376 Flags const flags_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400377
378 DISALLOW_COPY_AND_ASSIGN(MachineOperatorBuilder);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000379};
380
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400381
382DEFINE_OPERATORS_FOR_FLAGS(MachineOperatorBuilder::Flags)
383
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000384} // namespace compiler
385} // namespace internal
386} // namespace v8
387
388#endif // V8_COMPILER_MACHINE_OPERATOR_H_