blob: e3e5108ee398486a1cdd04b8750f6fde3d22e6e1 [file] [log] [blame]
Ben Murdoch014dc512016-03-22 12:00:34 +00001// Copyright 2015 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/representation-change.h"
6
7#include <sstream>
8
9#include "src/base/bits.h"
10#include "src/code-factory.h"
11#include "src/compiler/machine-operator.h"
12
13namespace v8 {
14namespace internal {
15namespace compiler {
16
17const char* Truncation::description() const {
18 switch (kind()) {
19 case TruncationKind::kNone:
20 return "no-value-use";
21 case TruncationKind::kBool:
22 return "truncate-to-bool";
23 case TruncationKind::kWord32:
24 return "truncate-to-word32";
25 case TruncationKind::kWord64:
26 return "truncate-to-word64";
Ben Murdoch014dc512016-03-22 12:00:34 +000027 case TruncationKind::kFloat64:
28 return "truncate-to-float64";
29 case TruncationKind::kAny:
30 return "no-truncation";
31 }
32 UNREACHABLE();
33 return nullptr;
34}
35
36
37// Partial order for truncations:
38//
39// kWord64 kAny
40// ^ ^
41// \ |
42// \ kFloat64 <--+
Ben Murdochc8c1d9e2017-03-08 14:04:23 +000043// \ ^ |
44// \ / |
45// kWord32 kBool
46// ^ ^
47// \ /
48// \ /
49// \ /
50// \ /
51// \ /
Ben Murdoch014dc512016-03-22 12:00:34 +000052// kNone
53
54// static
55Truncation::TruncationKind Truncation::Generalize(TruncationKind rep1,
56 TruncationKind rep2) {
57 if (LessGeneral(rep1, rep2)) return rep2;
58 if (LessGeneral(rep2, rep1)) return rep1;
59 // Handle the generalization of float64-representable values.
60 if (LessGeneral(rep1, TruncationKind::kFloat64) &&
61 LessGeneral(rep2, TruncationKind::kFloat64)) {
62 return TruncationKind::kFloat64;
63 }
Ben Murdochf91f0612016-11-29 16:50:11 +000064 // Handle the generalization of any-representable values.
65 if (LessGeneral(rep1, TruncationKind::kAny) &&
66 LessGeneral(rep2, TruncationKind::kAny)) {
67 return TruncationKind::kAny;
68 }
Ben Murdoch014dc512016-03-22 12:00:34 +000069 // All other combinations are illegal.
70 FATAL("Tried to combine incompatible truncations");
71 return TruncationKind::kNone;
72}
73
74
75// static
76bool Truncation::LessGeneral(TruncationKind rep1, TruncationKind rep2) {
77 switch (rep1) {
78 case TruncationKind::kNone:
79 return true;
80 case TruncationKind::kBool:
81 return rep2 == TruncationKind::kBool || rep2 == TruncationKind::kAny;
82 case TruncationKind::kWord32:
83 return rep2 == TruncationKind::kWord32 ||
84 rep2 == TruncationKind::kWord64 ||
85 rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny;
86 case TruncationKind::kWord64:
87 return rep2 == TruncationKind::kWord64;
Ben Murdoch014dc512016-03-22 12:00:34 +000088 case TruncationKind::kFloat64:
89 return rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny;
90 case TruncationKind::kAny:
91 return rep2 == TruncationKind::kAny;
92 }
93 UNREACHABLE();
94 return false;
95}
96
97
98namespace {
99
Ben Murdoch014dc512016-03-22 12:00:34 +0000100bool IsWord(MachineRepresentation rep) {
101 return rep == MachineRepresentation::kWord8 ||
102 rep == MachineRepresentation::kWord16 ||
103 rep == MachineRepresentation::kWord32;
104}
105
106} // namespace
107
Ben Murdoch014dc512016-03-22 12:00:34 +0000108// Changes representation from {output_rep} to {use_rep}. The {truncation}
109// parameter is only used for sanity checking - if the changer cannot figure
110// out signedness for the word32->float64 conversion, then we check that the
111// uses truncate to word32 (so they do not care about signedness).
112Node* RepresentationChanger::GetRepresentationFor(
113 Node* node, MachineRepresentation output_rep, Type* output_type,
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100114 Node* use_node, UseInfo use_info) {
Ben Murdochf91f0612016-11-29 16:50:11 +0000115 if (output_rep == MachineRepresentation::kNone &&
116 output_type->IsInhabited()) {
117 // The output representation should be set if the type is inhabited (i.e.,
118 // if the value is possible).
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100119 return TypeError(node, output_rep, output_type, use_info.representation());
Ben Murdoch014dc512016-03-22 12:00:34 +0000120 }
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100121
122 // Handle the no-op shortcuts when no checking is necessary.
123 if (use_info.type_check() == TypeCheckKind::kNone ||
124 output_rep != MachineRepresentation::kWord32) {
125 if (use_info.representation() == output_rep) {
126 // Representations are the same. That's a no-op.
127 return node;
128 }
129 if (IsWord(use_info.representation()) && IsWord(output_rep)) {
130 // Both are words less than or equal to 32-bits.
131 // Since loads of integers from memory implicitly sign or zero extend the
132 // value to the full machine word size and stores implicitly truncate,
133 // no representation change is necessary.
134 return node;
135 }
Ben Murdoch014dc512016-03-22 12:00:34 +0000136 }
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100137
138 switch (use_info.representation()) {
Ben Murdochf91f0612016-11-29 16:50:11 +0000139 case MachineRepresentation::kTaggedSigned:
Ben Murdochf3b273f2017-01-17 12:11:28 +0000140 DCHECK(use_info.type_check() == TypeCheckKind::kNone ||
141 use_info.type_check() == TypeCheckKind::kSignedSmall);
142 return GetTaggedSignedRepresentationFor(node, output_rep, output_type,
143 use_node, use_info);
Ben Murdochf91f0612016-11-29 16:50:11 +0000144 case MachineRepresentation::kTaggedPointer:
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000145 DCHECK(use_info.type_check() == TypeCheckKind::kNone ||
146 use_info.type_check() == TypeCheckKind::kHeapObject);
147 return GetTaggedPointerRepresentationFor(node, output_rep, output_type,
148 use_node, use_info);
Ben Murdoch014dc512016-03-22 12:00:34 +0000149 case MachineRepresentation::kTagged:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100150 DCHECK(use_info.type_check() == TypeCheckKind::kNone);
Ben Murdochf3b273f2017-01-17 12:11:28 +0000151 return GetTaggedRepresentationFor(node, output_rep, output_type,
152 use_info.truncation());
Ben Murdoch014dc512016-03-22 12:00:34 +0000153 case MachineRepresentation::kFloat32:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100154 DCHECK(use_info.type_check() == TypeCheckKind::kNone);
Ben Murdoch014dc512016-03-22 12:00:34 +0000155 return GetFloat32RepresentationFor(node, output_rep, output_type,
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100156 use_info.truncation());
Ben Murdoch014dc512016-03-22 12:00:34 +0000157 case MachineRepresentation::kFloat64:
158 return GetFloat64RepresentationFor(node, output_rep, output_type,
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100159 use_node, use_info);
Ben Murdoch014dc512016-03-22 12:00:34 +0000160 case MachineRepresentation::kBit:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100161 DCHECK(use_info.type_check() == TypeCheckKind::kNone);
Ben Murdoch014dc512016-03-22 12:00:34 +0000162 return GetBitRepresentationFor(node, output_rep, output_type);
163 case MachineRepresentation::kWord8:
164 case MachineRepresentation::kWord16:
165 case MachineRepresentation::kWord32:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100166 return GetWord32RepresentationFor(node, output_rep, output_type, use_node,
167 use_info);
Ben Murdoch014dc512016-03-22 12:00:34 +0000168 case MachineRepresentation::kWord64:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100169 DCHECK(use_info.type_check() == TypeCheckKind::kNone);
Ben Murdoch014dc512016-03-22 12:00:34 +0000170 return GetWord64RepresentationFor(node, output_rep, output_type);
Ben Murdoch109988c2016-05-18 11:27:45 +0100171 case MachineRepresentation::kSimd128: // Fall through.
172 // TODO(bbudge) Handle conversions between tagged and untagged.
173 break;
Ben Murdoch014dc512016-03-22 12:00:34 +0000174 case MachineRepresentation::kNone:
175 return node;
176 }
177 UNREACHABLE();
178 return nullptr;
179}
180
Ben Murdochf3b273f2017-01-17 12:11:28 +0000181Node* RepresentationChanger::GetTaggedSignedRepresentationFor(
182 Node* node, MachineRepresentation output_rep, Type* output_type,
183 Node* use_node, UseInfo use_info) {
184 // Eagerly fold representation changes for constants.
185 switch (node->opcode()) {
186 case IrOpcode::kNumberConstant:
187 if (output_type->Is(Type::SignedSmall())) {
188 return node;
189 }
190 break;
191 default:
192 break;
193 }
194 // Select the correct X -> Tagged operator.
195 const Operator* op;
196 if (output_type->Is(Type::None())) {
197 // This is an impossible value; it should not be used at runtime.
198 // We just provide a dummy value here.
199 return jsgraph()->Constant(0);
200 } else if (IsWord(output_rep)) {
201 if (output_type->Is(Type::Signed31())) {
202 op = simplified()->ChangeInt31ToTaggedSigned();
203 } else if (output_type->Is(Type::Signed32())) {
204 if (SmiValuesAre32Bits()) {
205 op = simplified()->ChangeInt32ToTagged();
206 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
207 op = simplified()->CheckedInt32ToTaggedSigned();
208 } else {
209 return TypeError(node, output_rep, output_type,
210 MachineRepresentation::kTaggedSigned);
211 }
212 } else if (output_type->Is(Type::Unsigned32()) &&
213 use_info.type_check() == TypeCheckKind::kSignedSmall) {
214 op = simplified()->CheckedUint32ToTaggedSigned();
215 } else {
216 return TypeError(node, output_rep, output_type,
217 MachineRepresentation::kTaggedSigned);
218 }
219 } else if (output_rep == MachineRepresentation::kFloat64) {
220 if (output_type->Is(Type::Signed31())) {
221 // float64 -> int32 -> tagged signed
222 node = InsertChangeFloat64ToInt32(node);
223 op = simplified()->ChangeInt31ToTaggedSigned();
224 } else if (output_type->Is(Type::Signed32())) {
225 // float64 -> int32 -> tagged signed
226 node = InsertChangeFloat64ToInt32(node);
227 if (SmiValuesAre32Bits()) {
228 op = simplified()->ChangeInt32ToTagged();
229 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
230 op = simplified()->CheckedInt32ToTaggedSigned();
231 } else {
232 return TypeError(node, output_rep, output_type,
233 MachineRepresentation::kTaggedSigned);
234 }
235 } else if (output_type->Is(Type::Unsigned32()) &&
236 use_info.type_check() == TypeCheckKind::kSignedSmall) {
237 // float64 -> uint32 -> tagged signed
238 node = InsertChangeFloat64ToUint32(node);
239 op = simplified()->CheckedUint32ToTaggedSigned();
240 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
241 op = simplified()->CheckedFloat64ToInt32(
242 output_type->Maybe(Type::MinusZero())
243 ? CheckForMinusZeroMode::kCheckForMinusZero
244 : CheckForMinusZeroMode::kDontCheckForMinusZero);
245 node = InsertConversion(node, op, use_node);
246 if (SmiValuesAre32Bits()) {
247 op = simplified()->ChangeInt32ToTagged();
248 } else {
249 op = simplified()->CheckedInt32ToTaggedSigned();
250 }
251 } else {
252 return TypeError(node, output_rep, output_type,
253 MachineRepresentation::kTaggedSigned);
254 }
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000255 } else if (output_rep == MachineRepresentation::kFloat32) {
256 if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
257 op = machine()->ChangeFloat32ToFloat64();
258 node = InsertConversion(node, op, use_node);
259 op = simplified()->CheckedFloat64ToInt32(
260 output_type->Maybe(Type::MinusZero())
261 ? CheckForMinusZeroMode::kCheckForMinusZero
262 : CheckForMinusZeroMode::kDontCheckForMinusZero);
263 node = InsertConversion(node, op, use_node);
264 if (SmiValuesAre32Bits()) {
265 op = simplified()->ChangeInt32ToTagged();
266 } else {
267 op = simplified()->CheckedInt32ToTaggedSigned();
268 }
269 } else {
270 return TypeError(node, output_rep, output_type,
271 MachineRepresentation::kTaggedSigned);
272 }
Ben Murdochf3b273f2017-01-17 12:11:28 +0000273 } else if (CanBeTaggedPointer(output_rep) &&
274 use_info.type_check() == TypeCheckKind::kSignedSmall) {
275 op = simplified()->CheckedTaggedToTaggedSigned();
276 } else if (output_rep == MachineRepresentation::kBit &&
277 use_info.type_check() == TypeCheckKind::kSignedSmall) {
278 // TODO(turbofan): Consider adding a Bailout operator that just deopts.
279 // Also use that for MachineRepresentation::kPointer case above.
280 node = InsertChangeBitToTagged(node);
281 op = simplified()->CheckedTaggedToTaggedSigned();
282 } else {
283 return TypeError(node, output_rep, output_type,
284 MachineRepresentation::kTaggedSigned);
285 }
286 return InsertConversion(node, op, use_node);
287}
288
289Node* RepresentationChanger::GetTaggedPointerRepresentationFor(
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000290 Node* node, MachineRepresentation output_rep, Type* output_type,
291 Node* use_node, UseInfo use_info) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000292 // Eagerly fold representation changes for constants.
293 switch (node->opcode()) {
Ben Murdochf3b273f2017-01-17 12:11:28 +0000294 case IrOpcode::kHeapConstant:
295 return node; // No change necessary.
296 case IrOpcode::kInt32Constant:
Ben Murdochf3b273f2017-01-17 12:11:28 +0000297 case IrOpcode::kFloat64Constant:
298 case IrOpcode::kFloat32Constant:
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000299 UNREACHABLE();
Ben Murdochf3b273f2017-01-17 12:11:28 +0000300 default:
301 break;
302 }
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000303 // Select the correct X -> TaggedPointer operator.
304 Operator const* op;
Ben Murdochf3b273f2017-01-17 12:11:28 +0000305 if (output_type->Is(Type::None())) {
306 // This is an impossible value; it should not be used at runtime.
307 // We just provide a dummy value here.
308 return jsgraph()->TheHoleConstant();
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000309 } else if (output_rep == MachineRepresentation::kBit) {
310 return node;
311 } else if (IsWord(output_rep)) {
312 if (output_type->Is(Type::Unsigned32())) {
313 // uint32 -> float64 -> tagged
314 node = InsertChangeUint32ToFloat64(node);
315 } else if (output_type->Is(Type::Signed32())) {
316 // int32 -> float64 -> tagged
317 node = InsertChangeInt32ToFloat64(node);
318 } else {
319 return TypeError(node, output_rep, output_type,
320 MachineRepresentation::kTaggedPointer);
321 }
322 op = simplified()->ChangeFloat64ToTaggedPointer();
323 } else if (output_rep == MachineRepresentation::kFloat32) {
324 // float32 -> float64 -> tagged
325 node = InsertChangeFloat32ToFloat64(node);
326 op = simplified()->ChangeFloat64ToTaggedPointer();
327 } else if (output_rep == MachineRepresentation::kFloat64) {
328 // float64 -> tagged
329 op = simplified()->ChangeFloat64ToTaggedPointer();
330 } else if (CanBeTaggedSigned(output_rep) &&
331 use_info.type_check() == TypeCheckKind::kHeapObject) {
332 if (!output_type->Maybe(Type::SignedSmall())) {
333 return node;
334 }
335 // TODO(turbofan): Consider adding a Bailout operator that just deopts
336 // for TaggedSigned output representation.
337 op = simplified()->CheckedTaggedToTaggedPointer();
338 } else {
339 return TypeError(node, output_rep, output_type,
340 MachineRepresentation::kTaggedPointer);
Ben Murdochf3b273f2017-01-17 12:11:28 +0000341 }
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000342 return InsertConversion(node, op, use_node);
Ben Murdochf3b273f2017-01-17 12:11:28 +0000343}
344
345Node* RepresentationChanger::GetTaggedRepresentationFor(
346 Node* node, MachineRepresentation output_rep, Type* output_type,
347 Truncation truncation) {
348 // Eagerly fold representation changes for constants.
349 switch (node->opcode()) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000350 case IrOpcode::kNumberConstant:
351 case IrOpcode::kHeapConstant:
352 return node; // No change necessary.
353 case IrOpcode::kInt32Constant:
Ben Murdoch014dc512016-03-22 12:00:34 +0000354 case IrOpcode::kFloat64Constant:
Ben Murdoch014dc512016-03-22 12:00:34 +0000355 case IrOpcode::kFloat32Constant:
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000356 UNREACHABLE();
357 break;
Ben Murdoch014dc512016-03-22 12:00:34 +0000358 default:
359 break;
360 }
Ben Murdochf3b273f2017-01-17 12:11:28 +0000361 if (output_rep == MachineRepresentation::kTaggedSigned ||
362 output_rep == MachineRepresentation::kTaggedPointer) {
363 // this is a no-op.
364 return node;
365 }
Ben Murdoch014dc512016-03-22 12:00:34 +0000366 // Select the correct X -> Tagged operator.
367 const Operator* op;
Ben Murdochf3b273f2017-01-17 12:11:28 +0000368 if (output_type->Is(Type::None())) {
369 // This is an impossible value; it should not be used at runtime.
370 // We just provide a dummy value here.
371 return jsgraph()->TheHoleConstant();
Ben Murdochf91f0612016-11-29 16:50:11 +0000372 } else if (output_rep == MachineRepresentation::kBit) {
373 if (output_type->Is(Type::Boolean())) {
374 op = simplified()->ChangeBitToTagged();
375 } else {
376 return TypeError(node, output_rep, output_type,
377 MachineRepresentation::kTagged);
378 }
Ben Murdoch014dc512016-03-22 12:00:34 +0000379 } else if (IsWord(output_rep)) {
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100380 if (output_type->Is(Type::Signed31())) {
381 op = simplified()->ChangeInt31ToTaggedSigned();
Ben Murdoch014dc512016-03-22 12:00:34 +0000382 } else if (output_type->Is(Type::Signed32())) {
383 op = simplified()->ChangeInt32ToTagged();
Ben Murdochf3b273f2017-01-17 12:11:28 +0000384 } else if (output_type->Is(Type::Unsigned32()) ||
385 truncation.IsUsedAsWord32()) {
386 // Either the output is uint32 or the uses only care about the
387 // low 32 bits (so we can pick uint32 safely).
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100388 op = simplified()->ChangeUint32ToTagged();
Ben Murdoch014dc512016-03-22 12:00:34 +0000389 } else {
390 return TypeError(node, output_rep, output_type,
391 MachineRepresentation::kTagged);
392 }
393 } else if (output_rep ==
394 MachineRepresentation::kFloat32) { // float32 -> float64 -> tagged
395 node = InsertChangeFloat32ToFloat64(node);
Ben Murdochf3b273f2017-01-17 12:11:28 +0000396 op = simplified()->ChangeFloat64ToTagged();
Ben Murdoch014dc512016-03-22 12:00:34 +0000397 } else if (output_rep == MachineRepresentation::kFloat64) {
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100398 if (output_type->Is(Type::Signed31())) { // float64 -> int32 -> tagged
399 node = InsertChangeFloat64ToInt32(node);
400 op = simplified()->ChangeInt31ToTaggedSigned();
401 } else if (output_type->Is(
402 Type::Signed32())) { // float64 -> int32 -> tagged
403 node = InsertChangeFloat64ToInt32(node);
404 op = simplified()->ChangeInt32ToTagged();
405 } else if (output_type->Is(
406 Type::Unsigned32())) { // float64 -> uint32 -> tagged
407 node = InsertChangeFloat64ToUint32(node);
408 op = simplified()->ChangeUint32ToTagged();
409 } else {
Ben Murdochf3b273f2017-01-17 12:11:28 +0000410 op = simplified()->ChangeFloat64ToTagged();
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100411 }
Ben Murdoch014dc512016-03-22 12:00:34 +0000412 } else {
413 return TypeError(node, output_rep, output_type,
414 MachineRepresentation::kTagged);
415 }
416 return jsgraph()->graph()->NewNode(op, node);
417}
418
419
420Node* RepresentationChanger::GetFloat32RepresentationFor(
421 Node* node, MachineRepresentation output_rep, Type* output_type,
422 Truncation truncation) {
423 // Eagerly fold representation changes for constants.
424 switch (node->opcode()) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000425 case IrOpcode::kNumberConstant:
426 return jsgraph()->Float32Constant(
427 DoubleToFloat32(OpParameter<double>(node)));
428 case IrOpcode::kInt32Constant:
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000429 case IrOpcode::kFloat64Constant:
Ben Murdoch014dc512016-03-22 12:00:34 +0000430 case IrOpcode::kFloat32Constant:
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000431 UNREACHABLE();
432 break;
Ben Murdoch014dc512016-03-22 12:00:34 +0000433 default:
434 break;
435 }
436 // Select the correct X -> Float32 operator.
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100437 const Operator* op = nullptr;
Ben Murdochf3b273f2017-01-17 12:11:28 +0000438 if (output_type->Is(Type::None())) {
439 // This is an impossible value; it should not be used at runtime.
440 // We just provide a dummy value here.
441 return jsgraph()->Float32Constant(0.0f);
Ben Murdochf91f0612016-11-29 16:50:11 +0000442 } else if (IsWord(output_rep)) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000443 if (output_type->Is(Type::Signed32())) {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100444 // int32 -> float64 -> float32
Ben Murdoch014dc512016-03-22 12:00:34 +0000445 op = machine()->ChangeInt32ToFloat64();
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100446 node = jsgraph()->graph()->NewNode(op, node);
447 op = machine()->TruncateFloat64ToFloat32();
448 } else if (output_type->Is(Type::Unsigned32()) ||
Ben Murdochf91f0612016-11-29 16:50:11 +0000449 truncation.IsUsedAsWord32()) {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100450 // Either the output is uint32 or the uses only care about the
451 // low 32 bits (so we can pick uint32 safely).
452
453 // uint32 -> float64 -> float32
Ben Murdoch014dc512016-03-22 12:00:34 +0000454 op = machine()->ChangeUint32ToFloat64();
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100455 node = jsgraph()->graph()->NewNode(op, node);
456 op = machine()->TruncateFloat64ToFloat32();
Ben Murdoch014dc512016-03-22 12:00:34 +0000457 }
Ben Murdochf3b273f2017-01-17 12:11:28 +0000458 } else if (output_rep == MachineRepresentation::kTagged ||
459 output_rep == MachineRepresentation::kTaggedPointer) {
Ben Murdochf91f0612016-11-29 16:50:11 +0000460 if (output_type->Is(Type::NumberOrOddball())) {
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100461 // tagged -> float64 -> float32
462 if (output_type->Is(Type::Number())) {
463 op = simplified()->ChangeTaggedToFloat64();
464 } else {
465 op = simplified()->TruncateTaggedToFloat64();
466 }
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100467 node = jsgraph()->graph()->NewNode(op, node);
468 op = machine()->TruncateFloat64ToFloat32();
469 }
Ben Murdoch014dc512016-03-22 12:00:34 +0000470 } else if (output_rep == MachineRepresentation::kFloat64) {
471 op = machine()->TruncateFloat64ToFloat32();
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100472 }
473 if (op == nullptr) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000474 return TypeError(node, output_rep, output_type,
475 MachineRepresentation::kFloat32);
476 }
477 return jsgraph()->graph()->NewNode(op, node);
478}
479
Ben Murdoch014dc512016-03-22 12:00:34 +0000480Node* RepresentationChanger::GetFloat64RepresentationFor(
481 Node* node, MachineRepresentation output_rep, Type* output_type,
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100482 Node* use_node, UseInfo use_info) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000483 // Eagerly fold representation changes for constants.
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100484 if ((use_info.type_check() == TypeCheckKind::kNone)) {
485 // TODO(jarin) Handle checked constant conversions.
486 switch (node->opcode()) {
487 case IrOpcode::kNumberConstant:
488 return jsgraph()->Float64Constant(OpParameter<double>(node));
489 case IrOpcode::kInt32Constant:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100490 case IrOpcode::kFloat64Constant:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100491 case IrOpcode::kFloat32Constant:
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000492 UNREACHABLE();
493 break;
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100494 default:
495 break;
496 }
Ben Murdoch014dc512016-03-22 12:00:34 +0000497 }
498 // Select the correct X -> Float64 operator.
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100499 const Operator* op = nullptr;
Ben Murdochf3b273f2017-01-17 12:11:28 +0000500 if (output_type->Is(Type::None())) {
501 // This is an impossible value; it should not be used at runtime.
502 // We just provide a dummy value here.
503 return jsgraph()->Float64Constant(0.0);
Ben Murdochf91f0612016-11-29 16:50:11 +0000504 } else if (IsWord(output_rep)) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000505 if (output_type->Is(Type::Signed32())) {
506 op = machine()->ChangeInt32ToFloat64();
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100507 } else if (output_type->Is(Type::Unsigned32()) ||
Ben Murdochf91f0612016-11-29 16:50:11 +0000508 use_info.truncation().IsUsedAsWord32()) {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100509 // Either the output is uint32 or the uses only care about the
510 // low 32 bits (so we can pick uint32 safely).
Ben Murdoch014dc512016-03-22 12:00:34 +0000511 op = machine()->ChangeUint32ToFloat64();
512 }
Ben Murdochf91f0612016-11-29 16:50:11 +0000513 } else if (output_rep == MachineRepresentation::kBit) {
514 op = machine()->ChangeUint32ToFloat64();
Ben Murdochf3b273f2017-01-17 12:11:28 +0000515 } else if (output_rep == MachineRepresentation::kTagged ||
516 output_rep == MachineRepresentation::kTaggedSigned ||
517 output_rep == MachineRepresentation::kTaggedPointer) {
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100518 if (output_type->Is(Type::Undefined())) {
519 return jsgraph()->Float64Constant(
520 std::numeric_limits<double>::quiet_NaN());
Ben Murdochf3b273f2017-01-17 12:11:28 +0000521
522 } else if (output_rep == MachineRepresentation::kTaggedSigned) {
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100523 node = InsertChangeTaggedSignedToInt32(node);
524 op = machine()->ChangeInt32ToFloat64();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100525 } else if (output_type->Is(Type::Number())) {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100526 op = simplified()->ChangeTaggedToFloat64();
Ben Murdochf91f0612016-11-29 16:50:11 +0000527 } else if (output_type->Is(Type::NumberOrOddball())) {
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100528 // TODO(jarin) Here we should check that truncation is Number.
529 op = simplified()->TruncateTaggedToFloat64();
Ben Murdochf91f0612016-11-29 16:50:11 +0000530 } else if (use_info.type_check() == TypeCheckKind::kNumber ||
531 (use_info.type_check() == TypeCheckKind::kNumberOrOddball &&
532 !output_type->Maybe(Type::BooleanOrNullOrNumber()))) {
533 op = simplified()->CheckedTaggedToFloat64(CheckTaggedInputMode::kNumber);
534 } else if (use_info.type_check() == TypeCheckKind::kNumberOrOddball) {
535 op = simplified()->CheckedTaggedToFloat64(
536 CheckTaggedInputMode::kNumberOrOddball);
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100537 }
Ben Murdoch014dc512016-03-22 12:00:34 +0000538 } else if (output_rep == MachineRepresentation::kFloat32) {
539 op = machine()->ChangeFloat32ToFloat64();
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100540 }
541 if (op == nullptr) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000542 return TypeError(node, output_rep, output_type,
543 MachineRepresentation::kFloat64);
544 }
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100545 return InsertConversion(node, op, use_node);
Ben Murdoch014dc512016-03-22 12:00:34 +0000546}
547
Ben Murdoch014dc512016-03-22 12:00:34 +0000548Node* RepresentationChanger::MakeTruncatedInt32Constant(double value) {
549 return jsgraph()->Int32Constant(DoubleToInt32(value));
550}
551
Ben Murdoch014dc512016-03-22 12:00:34 +0000552Node* RepresentationChanger::GetWord32RepresentationFor(
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100553 Node* node, MachineRepresentation output_rep, Type* output_type,
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100554 Node* use_node, UseInfo use_info) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000555 // Eagerly fold representation changes for constants.
556 switch (node->opcode()) {
557 case IrOpcode::kInt32Constant:
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000558 case IrOpcode::kFloat32Constant:
559 case IrOpcode::kFloat64Constant:
560 UNREACHABLE();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100561 break;
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000562 case IrOpcode::kNumberConstant: {
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100563 double const fv = OpParameter<double>(node);
564 if (use_info.type_check() == TypeCheckKind::kNone ||
Ben Murdochf91f0612016-11-29 16:50:11 +0000565 ((use_info.type_check() == TypeCheckKind::kSignedSmall ||
566 use_info.type_check() == TypeCheckKind::kSigned32) &&
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100567 IsInt32Double(fv))) {
568 return MakeTruncatedInt32Constant(fv);
569 }
570 break;
571 }
Ben Murdoch014dc512016-03-22 12:00:34 +0000572 default:
573 break;
574 }
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100575
Ben Murdoch014dc512016-03-22 12:00:34 +0000576 // Select the correct X -> Word32 operator.
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100577 const Operator* op = nullptr;
Ben Murdochf3b273f2017-01-17 12:11:28 +0000578 if (output_type->Is(Type::None())) {
579 // This is an impossible value; it should not be used at runtime.
580 // We just provide a dummy value here.
581 return jsgraph()->Int32Constant(0);
Ben Murdochf91f0612016-11-29 16:50:11 +0000582 } else if (output_rep == MachineRepresentation::kBit) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000583 return node; // Sloppy comparison -> word32
584 } else if (output_rep == MachineRepresentation::kFloat64) {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100585 if (output_type->Is(Type::Unsigned32())) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000586 op = machine()->ChangeFloat64ToUint32();
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100587 } else if (output_type->Is(Type::Signed32())) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000588 op = machine()->ChangeFloat64ToInt32();
Ben Murdochf91f0612016-11-29 16:50:11 +0000589 } else if (use_info.truncation().IsUsedAsWord32()) {
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100590 op = machine()->TruncateFloat64ToWord32();
Ben Murdochf91f0612016-11-29 16:50:11 +0000591 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall ||
592 use_info.type_check() == TypeCheckKind::kSigned32) {
593 op = simplified()->CheckedFloat64ToInt32(
594 output_type->Maybe(Type::MinusZero())
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000595 ? use_info.minus_zero_check()
Ben Murdochf91f0612016-11-29 16:50:11 +0000596 : CheckForMinusZeroMode::kDontCheckForMinusZero);
Ben Murdoch014dc512016-03-22 12:00:34 +0000597 }
598 } else if (output_rep == MachineRepresentation::kFloat32) {
599 node = InsertChangeFloat32ToFloat64(node); // float32 -> float64 -> int32
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100600 if (output_type->Is(Type::Unsigned32())) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000601 op = machine()->ChangeFloat64ToUint32();
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100602 } else if (output_type->Is(Type::Signed32())) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000603 op = machine()->ChangeFloat64ToInt32();
Ben Murdochf91f0612016-11-29 16:50:11 +0000604 } else if (use_info.truncation().IsUsedAsWord32()) {
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100605 op = machine()->TruncateFloat64ToWord32();
Ben Murdochf91f0612016-11-29 16:50:11 +0000606 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall ||
607 use_info.type_check() == TypeCheckKind::kSigned32) {
608 op = simplified()->CheckedFloat64ToInt32(
609 output_type->Maybe(Type::MinusZero())
610 ? CheckForMinusZeroMode::kCheckForMinusZero
611 : CheckForMinusZeroMode::kDontCheckForMinusZero);
Ben Murdoch014dc512016-03-22 12:00:34 +0000612 }
Ben Murdochf3b273f2017-01-17 12:11:28 +0000613 } else if (output_rep == MachineRepresentation::kTaggedSigned) {
614 if (output_type->Is(Type::Signed32())) {
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100615 op = simplified()->ChangeTaggedSignedToInt32();
Ben Murdochf3b273f2017-01-17 12:11:28 +0000616 } else if (use_info.truncation().IsUsedAsWord32()) {
617 if (use_info.type_check() != TypeCheckKind::kNone) {
618 op = simplified()->CheckedTruncateTaggedToWord32();
619 } else {
620 op = simplified()->TruncateTaggedToWord32();
621 }
622 }
623 } else if (output_rep == MachineRepresentation::kTagged ||
624 output_rep == MachineRepresentation::kTaggedPointer) {
625 if (output_type->Is(Type::Unsigned32())) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000626 op = simplified()->ChangeTaggedToUint32();
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100627 } else if (output_type->Is(Type::Signed32())) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000628 op = simplified()->ChangeTaggedToInt32();
Ben Murdochf91f0612016-11-29 16:50:11 +0000629 } else if (use_info.truncation().IsUsedAsWord32()) {
630 if (use_info.type_check() != TypeCheckKind::kNone) {
631 op = simplified()->CheckedTruncateTaggedToWord32();
632 } else {
633 op = simplified()->TruncateTaggedToWord32();
634 }
635 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
636 op = simplified()->CheckedTaggedSignedToInt32();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100637 } else if (use_info.type_check() == TypeCheckKind::kSigned32) {
Ben Murdochf91f0612016-11-29 16:50:11 +0000638 op = simplified()->CheckedTaggedToInt32(
639 output_type->Maybe(Type::MinusZero())
640 ? CheckForMinusZeroMode::kCheckForMinusZero
641 : CheckForMinusZeroMode::kDontCheckForMinusZero);
Ben Murdoch014dc512016-03-22 12:00:34 +0000642 }
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100643 } else if (output_rep == MachineRepresentation::kWord32) {
644 // Only the checked case should get here, the non-checked case is
645 // handled in GetRepresentationFor.
Ben Murdochf91f0612016-11-29 16:50:11 +0000646 if (use_info.type_check() == TypeCheckKind::kSignedSmall ||
647 use_info.type_check() == TypeCheckKind::kSigned32) {
648 if (output_type->Is(Type::Signed32())) {
649 return node;
650 } else if (output_type->Is(Type::Unsigned32())) {
651 op = simplified()->CheckedUint32ToInt32();
652 }
653 } else {
654 DCHECK_EQ(TypeCheckKind::kNumberOrOddball, use_info.type_check());
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100655 return node;
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100656 }
657 } else if (output_rep == MachineRepresentation::kWord8 ||
658 output_rep == MachineRepresentation::kWord16) {
659 DCHECK(use_info.representation() == MachineRepresentation::kWord32);
Ben Murdochf91f0612016-11-29 16:50:11 +0000660 DCHECK(use_info.type_check() == TypeCheckKind::kSignedSmall ||
661 use_info.type_check() == TypeCheckKind::kSigned32);
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100662 return node;
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100663 }
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100664
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100665 if (op == nullptr) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000666 return TypeError(node, output_rep, output_type,
667 MachineRepresentation::kWord32);
668 }
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100669 return InsertConversion(node, op, use_node);
670}
671
672Node* RepresentationChanger::InsertConversion(Node* node, const Operator* op,
673 Node* use_node) {
674 if (op->ControlInputCount() > 0) {
675 // If the operator can deoptimize (which means it has control
676 // input), we need to connect it to the effect and control chains.
677 Node* effect = NodeProperties::GetEffectInput(use_node);
678 Node* control = NodeProperties::GetControlInput(use_node);
679 Node* conversion = jsgraph()->graph()->NewNode(op, node, effect, control);
680 NodeProperties::ReplaceEffectInput(use_node, conversion);
681 return conversion;
682 }
Ben Murdoch014dc512016-03-22 12:00:34 +0000683 return jsgraph()->graph()->NewNode(op, node);
684}
685
686
687Node* RepresentationChanger::GetBitRepresentationFor(
688 Node* node, MachineRepresentation output_rep, Type* output_type) {
689 // Eagerly fold representation changes for constants.
690 switch (node->opcode()) {
691 case IrOpcode::kHeapConstant: {
692 Handle<HeapObject> value = OpParameter<Handle<HeapObject>>(node);
Ben Murdochf3b273f2017-01-17 12:11:28 +0000693 return jsgraph()->Int32Constant(value->BooleanValue() ? 1 : 0);
Ben Murdoch014dc512016-03-22 12:00:34 +0000694 }
695 default:
696 break;
697 }
698 // Select the correct X -> Bit operator.
699 const Operator* op;
Ben Murdochf3b273f2017-01-17 12:11:28 +0000700 if (output_type->Is(Type::None())) {
701 // This is an impossible value; it should not be used at runtime.
702 // We just provide a dummy value here.
703 return jsgraph()->Int32Constant(0);
704 } else if (output_rep == MachineRepresentation::kTagged ||
705 output_rep == MachineRepresentation::kTaggedPointer) {
706 if (output_type->Is(Type::BooleanOrNullOrUndefined())) {
707 // true is the only trueish Oddball.
708 op = simplified()->ChangeTaggedToBit();
709 } else {
710 op = simplified()->TruncateTaggedToBit();
711 }
712 } else if (output_rep == MachineRepresentation::kTaggedSigned) {
713 node = jsgraph()->graph()->NewNode(machine()->WordEqual(), node,
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000714 jsgraph()->IntPtrConstant(0));
Ben Murdochf3b273f2017-01-17 12:11:28 +0000715 return jsgraph()->graph()->NewNode(machine()->Word32Equal(), node,
716 jsgraph()->Int32Constant(0));
717 } else if (IsWord(output_rep)) {
718 node = jsgraph()->graph()->NewNode(machine()->Word32Equal(), node,
719 jsgraph()->Int32Constant(0));
720 return jsgraph()->graph()->NewNode(machine()->Word32Equal(), node,
721 jsgraph()->Int32Constant(0));
722 } else if (output_rep == MachineRepresentation::kFloat32) {
723 node = jsgraph()->graph()->NewNode(machine()->Float32Abs(), node);
724 return jsgraph()->graph()->NewNode(machine()->Float32LessThan(),
725 jsgraph()->Float32Constant(0.0), node);
726 } else if (output_rep == MachineRepresentation::kFloat64) {
727 node = jsgraph()->graph()->NewNode(machine()->Float64Abs(), node);
728 return jsgraph()->graph()->NewNode(machine()->Float64LessThan(),
729 jsgraph()->Float64Constant(0.0), node);
Ben Murdoch014dc512016-03-22 12:00:34 +0000730 } else {
731 return TypeError(node, output_rep, output_type,
732 MachineRepresentation::kBit);
733 }
734 return jsgraph()->graph()->NewNode(op, node);
735}
736
Ben Murdoch014dc512016-03-22 12:00:34 +0000737Node* RepresentationChanger::GetWord64RepresentationFor(
738 Node* node, MachineRepresentation output_rep, Type* output_type) {
Ben Murdochf3b273f2017-01-17 12:11:28 +0000739 if (output_type->Is(Type::None())) {
740 // This is an impossible value; it should not be used at runtime.
741 // We just provide a dummy value here.
742 return jsgraph()->Int64Constant(0);
Ben Murdochf91f0612016-11-29 16:50:11 +0000743 } else if (output_rep == MachineRepresentation::kBit) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000744 return node; // Sloppy comparison -> word64
745 }
746 // Can't really convert Word64 to anything else. Purported to be internal.
747 return TypeError(node, output_rep, output_type,
748 MachineRepresentation::kWord64);
749}
750
Ben Murdoch014dc512016-03-22 12:00:34 +0000751const Operator* RepresentationChanger::Int32OperatorFor(
752 IrOpcode::Value opcode) {
753 switch (opcode) {
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100754 case IrOpcode::kSpeculativeNumberAdd: // Fall through.
Ben Murdoch014dc512016-03-22 12:00:34 +0000755 case IrOpcode::kNumberAdd:
756 return machine()->Int32Add();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100757 case IrOpcode::kSpeculativeNumberSubtract: // Fall through.
Ben Murdoch014dc512016-03-22 12:00:34 +0000758 case IrOpcode::kNumberSubtract:
759 return machine()->Int32Sub();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100760 case IrOpcode::kSpeculativeNumberMultiply:
Ben Murdoch014dc512016-03-22 12:00:34 +0000761 case IrOpcode::kNumberMultiply:
762 return machine()->Int32Mul();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100763 case IrOpcode::kSpeculativeNumberDivide:
Ben Murdoch014dc512016-03-22 12:00:34 +0000764 case IrOpcode::kNumberDivide:
765 return machine()->Int32Div();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100766 case IrOpcode::kSpeculativeNumberModulus:
Ben Murdoch014dc512016-03-22 12:00:34 +0000767 case IrOpcode::kNumberModulus:
768 return machine()->Int32Mod();
Ben Murdochf91f0612016-11-29 16:50:11 +0000769 case IrOpcode::kSpeculativeNumberBitwiseOr: // Fall through.
Ben Murdoch014dc512016-03-22 12:00:34 +0000770 case IrOpcode::kNumberBitwiseOr:
771 return machine()->Word32Or();
Ben Murdochf91f0612016-11-29 16:50:11 +0000772 case IrOpcode::kSpeculativeNumberBitwiseXor: // Fall through.
Ben Murdoch014dc512016-03-22 12:00:34 +0000773 case IrOpcode::kNumberBitwiseXor:
774 return machine()->Word32Xor();
Ben Murdochf91f0612016-11-29 16:50:11 +0000775 case IrOpcode::kSpeculativeNumberBitwiseAnd: // Fall through.
Ben Murdoch014dc512016-03-22 12:00:34 +0000776 case IrOpcode::kNumberBitwiseAnd:
777 return machine()->Word32And();
778 case IrOpcode::kNumberEqual:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100779 case IrOpcode::kSpeculativeNumberEqual:
Ben Murdoch014dc512016-03-22 12:00:34 +0000780 return machine()->Word32Equal();
781 case IrOpcode::kNumberLessThan:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100782 case IrOpcode::kSpeculativeNumberLessThan:
Ben Murdoch014dc512016-03-22 12:00:34 +0000783 return machine()->Int32LessThan();
784 case IrOpcode::kNumberLessThanOrEqual:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100785 case IrOpcode::kSpeculativeNumberLessThanOrEqual:
Ben Murdoch014dc512016-03-22 12:00:34 +0000786 return machine()->Int32LessThanOrEqual();
787 default:
788 UNREACHABLE();
789 return nullptr;
790 }
791}
792
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100793const Operator* RepresentationChanger::Int32OverflowOperatorFor(
794 IrOpcode::Value opcode) {
795 switch (opcode) {
Ben Murdochf91f0612016-11-29 16:50:11 +0000796 case IrOpcode::kSpeculativeNumberAdd:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100797 return simplified()->CheckedInt32Add();
Ben Murdochf91f0612016-11-29 16:50:11 +0000798 case IrOpcode::kSpeculativeNumberSubtract:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100799 return simplified()->CheckedInt32Sub();
Ben Murdochf91f0612016-11-29 16:50:11 +0000800 case IrOpcode::kSpeculativeNumberDivide:
801 return simplified()->CheckedInt32Div();
802 case IrOpcode::kSpeculativeNumberModulus:
803 return simplified()->CheckedInt32Mod();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100804 default:
805 UNREACHABLE();
806 return nullptr;
807 }
808}
Ben Murdoch014dc512016-03-22 12:00:34 +0000809
810const Operator* RepresentationChanger::Uint32OperatorFor(
811 IrOpcode::Value opcode) {
812 switch (opcode) {
813 case IrOpcode::kNumberAdd:
814 return machine()->Int32Add();
815 case IrOpcode::kNumberSubtract:
816 return machine()->Int32Sub();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100817 case IrOpcode::kSpeculativeNumberMultiply:
Ben Murdoch014dc512016-03-22 12:00:34 +0000818 case IrOpcode::kNumberMultiply:
819 return machine()->Int32Mul();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100820 case IrOpcode::kSpeculativeNumberDivide:
Ben Murdoch014dc512016-03-22 12:00:34 +0000821 case IrOpcode::kNumberDivide:
822 return machine()->Uint32Div();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100823 case IrOpcode::kSpeculativeNumberModulus:
Ben Murdoch014dc512016-03-22 12:00:34 +0000824 case IrOpcode::kNumberModulus:
825 return machine()->Uint32Mod();
826 case IrOpcode::kNumberEqual:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100827 case IrOpcode::kSpeculativeNumberEqual:
Ben Murdoch014dc512016-03-22 12:00:34 +0000828 return machine()->Word32Equal();
829 case IrOpcode::kNumberLessThan:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100830 case IrOpcode::kSpeculativeNumberLessThan:
Ben Murdoch014dc512016-03-22 12:00:34 +0000831 return machine()->Uint32LessThan();
832 case IrOpcode::kNumberLessThanOrEqual:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100833 case IrOpcode::kSpeculativeNumberLessThanOrEqual:
Ben Murdoch014dc512016-03-22 12:00:34 +0000834 return machine()->Uint32LessThanOrEqual();
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100835 case IrOpcode::kNumberClz32:
836 return machine()->Word32Clz();
837 case IrOpcode::kNumberImul:
838 return machine()->Int32Mul();
Ben Murdoch014dc512016-03-22 12:00:34 +0000839 default:
840 UNREACHABLE();
841 return nullptr;
842 }
843}
844
Ben Murdochf91f0612016-11-29 16:50:11 +0000845const Operator* RepresentationChanger::Uint32OverflowOperatorFor(
846 IrOpcode::Value opcode) {
847 switch (opcode) {
848 case IrOpcode::kSpeculativeNumberDivide:
849 return simplified()->CheckedUint32Div();
850 case IrOpcode::kSpeculativeNumberModulus:
851 return simplified()->CheckedUint32Mod();
852 default:
853 UNREACHABLE();
854 return nullptr;
855 }
856}
Ben Murdoch014dc512016-03-22 12:00:34 +0000857
858const Operator* RepresentationChanger::Float64OperatorFor(
859 IrOpcode::Value opcode) {
860 switch (opcode) {
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100861 case IrOpcode::kSpeculativeNumberAdd:
Ben Murdoch014dc512016-03-22 12:00:34 +0000862 case IrOpcode::kNumberAdd:
863 return machine()->Float64Add();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100864 case IrOpcode::kSpeculativeNumberSubtract:
Ben Murdoch014dc512016-03-22 12:00:34 +0000865 case IrOpcode::kNumberSubtract:
866 return machine()->Float64Sub();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100867 case IrOpcode::kSpeculativeNumberMultiply:
Ben Murdoch014dc512016-03-22 12:00:34 +0000868 case IrOpcode::kNumberMultiply:
869 return machine()->Float64Mul();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100870 case IrOpcode::kSpeculativeNumberDivide:
Ben Murdoch014dc512016-03-22 12:00:34 +0000871 case IrOpcode::kNumberDivide:
872 return machine()->Float64Div();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100873 case IrOpcode::kSpeculativeNumberModulus:
Ben Murdoch014dc512016-03-22 12:00:34 +0000874 case IrOpcode::kNumberModulus:
875 return machine()->Float64Mod();
876 case IrOpcode::kNumberEqual:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100877 case IrOpcode::kSpeculativeNumberEqual:
Ben Murdoch014dc512016-03-22 12:00:34 +0000878 return machine()->Float64Equal();
879 case IrOpcode::kNumberLessThan:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100880 case IrOpcode::kSpeculativeNumberLessThan:
Ben Murdoch014dc512016-03-22 12:00:34 +0000881 return machine()->Float64LessThan();
882 case IrOpcode::kNumberLessThanOrEqual:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100883 case IrOpcode::kSpeculativeNumberLessThanOrEqual:
Ben Murdoch014dc512016-03-22 12:00:34 +0000884 return machine()->Float64LessThanOrEqual();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100885 case IrOpcode::kNumberAbs:
886 return machine()->Float64Abs();
Ben Murdochf91f0612016-11-29 16:50:11 +0000887 case IrOpcode::kNumberAcos:
888 return machine()->Float64Acos();
889 case IrOpcode::kNumberAcosh:
890 return machine()->Float64Acosh();
891 case IrOpcode::kNumberAsin:
892 return machine()->Float64Asin();
893 case IrOpcode::kNumberAsinh:
894 return machine()->Float64Asinh();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100895 case IrOpcode::kNumberAtan:
896 return machine()->Float64Atan();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100897 case IrOpcode::kNumberAtanh:
898 return machine()->Float64Atanh();
Ben Murdochf91f0612016-11-29 16:50:11 +0000899 case IrOpcode::kNumberAtan2:
900 return machine()->Float64Atan2();
901 case IrOpcode::kNumberCbrt:
902 return machine()->Float64Cbrt();
903 case IrOpcode::kNumberCeil:
904 return machine()->Float64RoundUp().placeholder();
905 case IrOpcode::kNumberCos:
906 return machine()->Float64Cos();
907 case IrOpcode::kNumberCosh:
908 return machine()->Float64Cosh();
909 case IrOpcode::kNumberExp:
910 return machine()->Float64Exp();
911 case IrOpcode::kNumberExpm1:
912 return machine()->Float64Expm1();
913 case IrOpcode::kNumberFloor:
914 return machine()->Float64RoundDown().placeholder();
915 case IrOpcode::kNumberFround:
916 return machine()->TruncateFloat64ToFloat32();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100917 case IrOpcode::kNumberLog:
918 return machine()->Float64Log();
919 case IrOpcode::kNumberLog1p:
920 return machine()->Float64Log1p();
921 case IrOpcode::kNumberLog2:
922 return machine()->Float64Log2();
923 case IrOpcode::kNumberLog10:
924 return machine()->Float64Log10();
Ben Murdochf91f0612016-11-29 16:50:11 +0000925 case IrOpcode::kNumberMax:
926 return machine()->Float64Max();
927 case IrOpcode::kNumberMin:
928 return machine()->Float64Min();
929 case IrOpcode::kNumberPow:
930 return machine()->Float64Pow();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100931 case IrOpcode::kNumberSin:
932 return machine()->Float64Sin();
Ben Murdochf91f0612016-11-29 16:50:11 +0000933 case IrOpcode::kNumberSinh:
934 return machine()->Float64Sinh();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100935 case IrOpcode::kNumberSqrt:
936 return machine()->Float64Sqrt();
Ben Murdochf91f0612016-11-29 16:50:11 +0000937 case IrOpcode::kNumberTan:
938 return machine()->Float64Tan();
939 case IrOpcode::kNumberTanh:
940 return machine()->Float64Tanh();
941 case IrOpcode::kNumberTrunc:
942 return machine()->Float64RoundTruncate().placeholder();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100943 case IrOpcode::kNumberSilenceNaN:
944 return machine()->Float64SilenceNaN();
Ben Murdoch014dc512016-03-22 12:00:34 +0000945 default:
946 UNREACHABLE();
947 return nullptr;
948 }
949}
950
951
952Node* RepresentationChanger::TypeError(Node* node,
953 MachineRepresentation output_rep,
954 Type* output_type,
955 MachineRepresentation use) {
956 type_error_ = true;
957 if (!testing_type_errors_) {
958 std::ostringstream out_str;
959 out_str << output_rep << " (";
Ben Murdochf3b273f2017-01-17 12:11:28 +0000960 output_type->PrintTo(out_str);
Ben Murdoch014dc512016-03-22 12:00:34 +0000961 out_str << ")";
962
963 std::ostringstream use_str;
964 use_str << use;
965
966 V8_Fatal(__FILE__, __LINE__,
967 "RepresentationChangerError: node #%d:%s of "
968 "%s cannot be changed to %s",
969 node->id(), node->op()->mnemonic(), out_str.str().c_str(),
970 use_str.str().c_str());
971 }
972 return node;
973}
974
Ben Murdochf3b273f2017-01-17 12:11:28 +0000975Node* RepresentationChanger::InsertChangeBitToTagged(Node* node) {
976 return jsgraph()->graph()->NewNode(simplified()->ChangeBitToTagged(), node);
977}
Ben Murdoch014dc512016-03-22 12:00:34 +0000978
979Node* RepresentationChanger::InsertChangeFloat32ToFloat64(Node* node) {
980 return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(), node);
981}
982
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100983Node* RepresentationChanger::InsertChangeFloat64ToUint32(Node* node) {
984 return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToUint32(), node);
985}
986
987Node* RepresentationChanger::InsertChangeFloat64ToInt32(Node* node) {
988 return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToInt32(), node);
989}
990
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000991Node* RepresentationChanger::InsertChangeInt32ToFloat64(Node* node) {
992 return jsgraph()->graph()->NewNode(machine()->ChangeInt32ToFloat64(), node);
993}
994
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100995Node* RepresentationChanger::InsertChangeTaggedSignedToInt32(Node* node) {
996 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(),
997 node);
998}
Ben Murdoch014dc512016-03-22 12:00:34 +0000999
1000Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) {
1001 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
1002 node);
1003}
1004
Ben Murdochc8c1d9e2017-03-08 14:04:23 +00001005Node* RepresentationChanger::InsertChangeUint32ToFloat64(Node* node) {
1006 return jsgraph()->graph()->NewNode(machine()->ChangeUint32ToFloat64(), node);
1007}
1008
Ben Murdoch014dc512016-03-22 12:00:34 +00001009} // namespace compiler
1010} // namespace internal
1011} // namespace v8