blob: 180355d294c0fdfe8211f3c0754fe0fe4e2fb89c [file] [log] [blame]
Ben Murdoch4a90d5f2016-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";
27 case TruncationKind::kFloat32:
28 return "truncate-to-float32";
29 case TruncationKind::kFloat64:
30 return "truncate-to-float64";
31 case TruncationKind::kAny:
32 return "no-truncation";
33 }
34 UNREACHABLE();
35 return nullptr;
36}
37
38
39// Partial order for truncations:
40//
41// kWord64 kAny
42// ^ ^
43// \ |
44// \ kFloat64 <--+
45// \ ^ ^ |
46// \ / | |
47// kWord32 kFloat32 kBool
48// ^ ^ ^
49// \ | /
50// \ | /
51// \ | /
52// \ | /
53// \ | /
54// kNone
55
56// static
57Truncation::TruncationKind Truncation::Generalize(TruncationKind rep1,
58 TruncationKind rep2) {
59 if (LessGeneral(rep1, rep2)) return rep2;
60 if (LessGeneral(rep2, rep1)) return rep1;
61 // Handle the generalization of float64-representable values.
62 if (LessGeneral(rep1, TruncationKind::kFloat64) &&
63 LessGeneral(rep2, TruncationKind::kFloat64)) {
64 return TruncationKind::kFloat64;
65 }
66 // All other combinations are illegal.
67 FATAL("Tried to combine incompatible truncations");
68 return TruncationKind::kNone;
69}
70
71
72// static
73bool Truncation::LessGeneral(TruncationKind rep1, TruncationKind rep2) {
74 switch (rep1) {
75 case TruncationKind::kNone:
76 return true;
77 case TruncationKind::kBool:
78 return rep2 == TruncationKind::kBool || rep2 == TruncationKind::kAny;
79 case TruncationKind::kWord32:
80 return rep2 == TruncationKind::kWord32 ||
81 rep2 == TruncationKind::kWord64 ||
82 rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny;
83 case TruncationKind::kWord64:
84 return rep2 == TruncationKind::kWord64;
85 case TruncationKind::kFloat32:
86 return rep2 == TruncationKind::kFloat32 ||
87 rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny;
88 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 Murdoch4a90d5f2016-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
108
109// Changes representation from {output_rep} to {use_rep}. The {truncation}
110// parameter is only used for sanity checking - if the changer cannot figure
111// out signedness for the word32->float64 conversion, then we check that the
112// uses truncate to word32 (so they do not care about signedness).
113Node* RepresentationChanger::GetRepresentationFor(
114 Node* node, MachineRepresentation output_rep, Type* output_type,
115 MachineRepresentation use_rep, Truncation truncation) {
116 if (output_rep == MachineRepresentation::kNone) {
117 // The output representation should be set.
118 return TypeError(node, output_rep, output_type, use_rep);
119 }
120 if (use_rep == output_rep) {
121 // Representations are the same. That's a no-op.
122 return node;
123 }
124 if (IsWord(use_rep) && IsWord(output_rep)) {
125 // Both are words less than or equal to 32-bits.
126 // Since loads of integers from memory implicitly sign or zero extend the
127 // value to the full machine word size and stores implicitly truncate,
128 // no representation change is necessary.
129 return node;
130 }
131 switch (use_rep) {
132 case MachineRepresentation::kTagged:
133 return GetTaggedRepresentationFor(node, output_rep, output_type);
134 case MachineRepresentation::kFloat32:
135 return GetFloat32RepresentationFor(node, output_rep, output_type,
136 truncation);
137 case MachineRepresentation::kFloat64:
138 return GetFloat64RepresentationFor(node, output_rep, output_type,
139 truncation);
140 case MachineRepresentation::kBit:
141 return GetBitRepresentationFor(node, output_rep, output_type);
142 case MachineRepresentation::kWord8:
143 case MachineRepresentation::kWord16:
144 case MachineRepresentation::kWord32:
Ben Murdochda12d292016-06-02 14:46:10 +0100145 return GetWord32RepresentationFor(node, output_rep, output_type,
146 truncation);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000147 case MachineRepresentation::kWord64:
148 return GetWord64RepresentationFor(node, output_rep, output_type);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100149 case MachineRepresentation::kSimd128: // Fall through.
150 // TODO(bbudge) Handle conversions between tagged and untagged.
151 break;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000152 case MachineRepresentation::kNone:
153 return node;
154 }
155 UNREACHABLE();
156 return nullptr;
157}
158
159
160Node* RepresentationChanger::GetTaggedRepresentationFor(
161 Node* node, MachineRepresentation output_rep, Type* output_type) {
162 // Eagerly fold representation changes for constants.
163 switch (node->opcode()) {
164 case IrOpcode::kNumberConstant:
165 case IrOpcode::kHeapConstant:
166 return node; // No change necessary.
167 case IrOpcode::kInt32Constant:
168 if (output_type->Is(Type::Signed32())) {
169 int32_t value = OpParameter<int32_t>(node);
170 return jsgraph()->Constant(value);
171 } else if (output_type->Is(Type::Unsigned32())) {
172 uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node));
173 return jsgraph()->Constant(static_cast<double>(value));
174 } else if (output_rep == MachineRepresentation::kBit) {
175 return OpParameter<int32_t>(node) == 0 ? jsgraph()->FalseConstant()
176 : jsgraph()->TrueConstant();
177 } else {
178 return TypeError(node, output_rep, output_type,
179 MachineRepresentation::kTagged);
180 }
181 case IrOpcode::kFloat64Constant:
182 return jsgraph()->Constant(OpParameter<double>(node));
183 case IrOpcode::kFloat32Constant:
184 return jsgraph()->Constant(OpParameter<float>(node));
185 default:
186 break;
187 }
188 // Select the correct X -> Tagged operator.
189 const Operator* op;
190 if (output_rep == MachineRepresentation::kBit) {
Ben Murdochc5610432016-08-08 18:44:38 +0100191 op = simplified()->ChangeBitToTagged();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000192 } else if (IsWord(output_rep)) {
Ben Murdochc5610432016-08-08 18:44:38 +0100193 if (output_type->Is(Type::Signed31())) {
194 op = simplified()->ChangeInt31ToTaggedSigned();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000195 } else if (output_type->Is(Type::Signed32())) {
196 op = simplified()->ChangeInt32ToTagged();
Ben Murdochc5610432016-08-08 18:44:38 +0100197 } else if (output_type->Is(Type::Unsigned32())) {
198 op = simplified()->ChangeUint32ToTagged();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000199 } else {
200 return TypeError(node, output_rep, output_type,
201 MachineRepresentation::kTagged);
202 }
203 } else if (output_rep ==
204 MachineRepresentation::kFloat32) { // float32 -> float64 -> tagged
205 node = InsertChangeFloat32ToFloat64(node);
Ben Murdochc5610432016-08-08 18:44:38 +0100206 // TODO(bmeurer): Pass -0 hint to ChangeFloat64ToTagged.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000207 op = simplified()->ChangeFloat64ToTagged();
208 } else if (output_rep == MachineRepresentation::kFloat64) {
Ben Murdochc5610432016-08-08 18:44:38 +0100209 if (output_type->Is(Type::Signed31())) { // float64 -> int32 -> tagged
210 node = InsertChangeFloat64ToInt32(node);
211 op = simplified()->ChangeInt31ToTaggedSigned();
212 } else if (output_type->Is(
213 Type::Signed32())) { // float64 -> int32 -> tagged
214 node = InsertChangeFloat64ToInt32(node);
215 op = simplified()->ChangeInt32ToTagged();
216 } else if (output_type->Is(
217 Type::Unsigned32())) { // float64 -> uint32 -> tagged
218 node = InsertChangeFloat64ToUint32(node);
219 op = simplified()->ChangeUint32ToTagged();
220 } else {
221 // TODO(bmeurer): Pass -0 hint to ChangeFloat64ToTagged.
222 op = simplified()->ChangeFloat64ToTagged();
223 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000224 } else {
225 return TypeError(node, output_rep, output_type,
226 MachineRepresentation::kTagged);
227 }
228 return jsgraph()->graph()->NewNode(op, node);
229}
230
231
232Node* RepresentationChanger::GetFloat32RepresentationFor(
233 Node* node, MachineRepresentation output_rep, Type* output_type,
234 Truncation truncation) {
235 // Eagerly fold representation changes for constants.
236 switch (node->opcode()) {
237 case IrOpcode::kFloat64Constant:
238 case IrOpcode::kNumberConstant:
239 return jsgraph()->Float32Constant(
240 DoubleToFloat32(OpParameter<double>(node)));
241 case IrOpcode::kInt32Constant:
242 if (output_type->Is(Type::Unsigned32())) {
243 uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node));
244 return jsgraph()->Float32Constant(static_cast<float>(value));
245 } else {
246 int32_t value = OpParameter<int32_t>(node);
247 return jsgraph()->Float32Constant(static_cast<float>(value));
248 }
249 case IrOpcode::kFloat32Constant:
250 return node; // No change necessary.
251 default:
252 break;
253 }
254 // Select the correct X -> Float32 operator.
Ben Murdochda12d292016-06-02 14:46:10 +0100255 const Operator* op = nullptr;
256 if (IsWord(output_rep)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000257 if (output_type->Is(Type::Signed32())) {
Ben Murdochda12d292016-06-02 14:46:10 +0100258 // int32 -> float64 -> float32
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000259 op = machine()->ChangeInt32ToFloat64();
Ben Murdochda12d292016-06-02 14:46:10 +0100260 node = jsgraph()->graph()->NewNode(op, node);
261 op = machine()->TruncateFloat64ToFloat32();
262 } else if (output_type->Is(Type::Unsigned32()) ||
263 truncation.TruncatesToWord32()) {
264 // Either the output is uint32 or the uses only care about the
265 // low 32 bits (so we can pick uint32 safely).
266
267 // uint32 -> float64 -> float32
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000268 op = machine()->ChangeUint32ToFloat64();
Ben Murdochda12d292016-06-02 14:46:10 +0100269 node = jsgraph()->graph()->NewNode(op, node);
270 op = machine()->TruncateFloat64ToFloat32();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000271 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000272 } else if (output_rep == MachineRepresentation::kTagged) {
Ben Murdochc5610432016-08-08 18:44:38 +0100273 if (output_type->Is(Type::NumberOrUndefined())) {
Ben Murdochda12d292016-06-02 14:46:10 +0100274 op = simplified()
275 ->ChangeTaggedToFloat64(); // tagged -> float64 -> float32
276 node = jsgraph()->graph()->NewNode(op, node);
277 op = machine()->TruncateFloat64ToFloat32();
278 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000279 } else if (output_rep == MachineRepresentation::kFloat64) {
280 op = machine()->TruncateFloat64ToFloat32();
Ben Murdochda12d292016-06-02 14:46:10 +0100281 }
282 if (op == nullptr) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000283 return TypeError(node, output_rep, output_type,
284 MachineRepresentation::kFloat32);
285 }
286 return jsgraph()->graph()->NewNode(op, node);
287}
288
289
290Node* RepresentationChanger::GetFloat64RepresentationFor(
291 Node* node, MachineRepresentation output_rep, Type* output_type,
292 Truncation truncation) {
293 // Eagerly fold representation changes for constants.
294 switch (node->opcode()) {
295 case IrOpcode::kNumberConstant:
296 return jsgraph()->Float64Constant(OpParameter<double>(node));
297 case IrOpcode::kInt32Constant:
298 if (output_type->Is(Type::Signed32())) {
299 int32_t value = OpParameter<int32_t>(node);
300 return jsgraph()->Float64Constant(value);
301 } else {
302 DCHECK(output_type->Is(Type::Unsigned32()));
303 uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node));
304 return jsgraph()->Float64Constant(static_cast<double>(value));
305 }
306 case IrOpcode::kFloat64Constant:
307 return node; // No change necessary.
308 case IrOpcode::kFloat32Constant:
309 return jsgraph()->Float64Constant(OpParameter<float>(node));
310 default:
311 break;
312 }
313 // Select the correct X -> Float64 operator.
Ben Murdochda12d292016-06-02 14:46:10 +0100314 const Operator* op = nullptr;
315 if (IsWord(output_rep)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000316 if (output_type->Is(Type::Signed32())) {
317 op = machine()->ChangeInt32ToFloat64();
Ben Murdochda12d292016-06-02 14:46:10 +0100318 } else if (output_type->Is(Type::Unsigned32()) ||
319 truncation.TruncatesToWord32()) {
320 // Either the output is uint32 or the uses only care about the
321 // low 32 bits (so we can pick uint32 safely).
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000322 op = machine()->ChangeUint32ToFloat64();
323 }
324 } else if (output_rep == MachineRepresentation::kTagged) {
Ben Murdochc5610432016-08-08 18:44:38 +0100325 if (output_type->Is(Type::Undefined())) {
326 return jsgraph()->Float64Constant(
327 std::numeric_limits<double>::quiet_NaN());
328 } else if (output_type->Is(Type::TaggedSigned())) {
329 node = InsertChangeTaggedSignedToInt32(node);
330 op = machine()->ChangeInt32ToFloat64();
331 } else if (output_type->Is(Type::NumberOrUndefined())) {
Ben Murdochda12d292016-06-02 14:46:10 +0100332 op = simplified()->ChangeTaggedToFloat64();
333 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000334 } else if (output_rep == MachineRepresentation::kFloat32) {
335 op = machine()->ChangeFloat32ToFloat64();
Ben Murdochda12d292016-06-02 14:46:10 +0100336 }
337 if (op == nullptr) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000338 return TypeError(node, output_rep, output_type,
339 MachineRepresentation::kFloat64);
340 }
341 return jsgraph()->graph()->NewNode(op, node);
342}
343
344
345Node* RepresentationChanger::MakeTruncatedInt32Constant(double value) {
346 return jsgraph()->Int32Constant(DoubleToInt32(value));
347}
348
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000349Node* RepresentationChanger::GetWord32RepresentationFor(
Ben Murdochda12d292016-06-02 14:46:10 +0100350 Node* node, MachineRepresentation output_rep, Type* output_type,
351 Truncation truncation) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000352 // Eagerly fold representation changes for constants.
353 switch (node->opcode()) {
354 case IrOpcode::kInt32Constant:
355 return node; // No change necessary.
356 case IrOpcode::kFloat32Constant:
357 return MakeTruncatedInt32Constant(OpParameter<float>(node));
358 case IrOpcode::kNumberConstant:
359 case IrOpcode::kFloat64Constant:
360 return MakeTruncatedInt32Constant(OpParameter<double>(node));
361 default:
362 break;
363 }
364 // Select the correct X -> Word32 operator.
Ben Murdochda12d292016-06-02 14:46:10 +0100365 const Operator* op = nullptr;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000366 if (output_rep == MachineRepresentation::kBit) {
367 return node; // Sloppy comparison -> word32
368 } else if (output_rep == MachineRepresentation::kFloat64) {
Ben Murdochda12d292016-06-02 14:46:10 +0100369 if (output_type->Is(Type::Unsigned32())) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000370 op = machine()->ChangeFloat64ToUint32();
Ben Murdochda12d292016-06-02 14:46:10 +0100371 } else if (output_type->Is(Type::Signed32())) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000372 op = machine()->ChangeFloat64ToInt32();
Ben Murdochda12d292016-06-02 14:46:10 +0100373 } else if (truncation.TruncatesToWord32()) {
Ben Murdochc5610432016-08-08 18:44:38 +0100374 op = machine()->TruncateFloat64ToWord32();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000375 }
376 } else if (output_rep == MachineRepresentation::kFloat32) {
377 node = InsertChangeFloat32ToFloat64(node); // float32 -> float64 -> int32
Ben Murdochda12d292016-06-02 14:46:10 +0100378 if (output_type->Is(Type::Unsigned32())) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000379 op = machine()->ChangeFloat64ToUint32();
Ben Murdochda12d292016-06-02 14:46:10 +0100380 } else if (output_type->Is(Type::Signed32())) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000381 op = machine()->ChangeFloat64ToInt32();
Ben Murdochda12d292016-06-02 14:46:10 +0100382 } else if (truncation.TruncatesToWord32()) {
Ben Murdochc5610432016-08-08 18:44:38 +0100383 op = machine()->TruncateFloat64ToWord32();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000384 }
385 } else if (output_rep == MachineRepresentation::kTagged) {
Ben Murdochc5610432016-08-08 18:44:38 +0100386 if (output_type->Is(Type::TaggedSigned())) {
387 op = simplified()->ChangeTaggedSignedToInt32();
388 } else if (output_type->Is(Type::Unsigned32())) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000389 op = simplified()->ChangeTaggedToUint32();
Ben Murdochda12d292016-06-02 14:46:10 +0100390 } else if (output_type->Is(Type::Signed32())) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000391 op = simplified()->ChangeTaggedToInt32();
Ben Murdochda12d292016-06-02 14:46:10 +0100392 } else if (truncation.TruncatesToWord32()) {
Ben Murdochc5610432016-08-08 18:44:38 +0100393 op = simplified()->TruncateTaggedToWord32();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000394 }
Ben Murdochda12d292016-06-02 14:46:10 +0100395 }
396 if (op == nullptr) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000397 return TypeError(node, output_rep, output_type,
398 MachineRepresentation::kWord32);
399 }
400 return jsgraph()->graph()->NewNode(op, node);
401}
402
403
404Node* RepresentationChanger::GetBitRepresentationFor(
405 Node* node, MachineRepresentation output_rep, Type* output_type) {
406 // Eagerly fold representation changes for constants.
407 switch (node->opcode()) {
408 case IrOpcode::kHeapConstant: {
409 Handle<HeapObject> value = OpParameter<Handle<HeapObject>>(node);
410 DCHECK(value.is_identical_to(factory()->true_value()) ||
411 value.is_identical_to(factory()->false_value()));
412 return jsgraph()->Int32Constant(
413 value.is_identical_to(factory()->true_value()) ? 1 : 0);
414 }
415 default:
416 break;
417 }
418 // Select the correct X -> Bit operator.
419 const Operator* op;
420 if (output_rep == MachineRepresentation::kTagged) {
Ben Murdochc5610432016-08-08 18:44:38 +0100421 op = simplified()->ChangeTaggedToBit();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000422 } else {
423 return TypeError(node, output_rep, output_type,
424 MachineRepresentation::kBit);
425 }
426 return jsgraph()->graph()->NewNode(op, node);
427}
428
429
430Node* RepresentationChanger::GetWord64RepresentationFor(
431 Node* node, MachineRepresentation output_rep, Type* output_type) {
432 if (output_rep == MachineRepresentation::kBit) {
433 return node; // Sloppy comparison -> word64
434 }
435 // Can't really convert Word64 to anything else. Purported to be internal.
436 return TypeError(node, output_rep, output_type,
437 MachineRepresentation::kWord64);
438}
439
440
441const Operator* RepresentationChanger::Int32OperatorFor(
442 IrOpcode::Value opcode) {
443 switch (opcode) {
444 case IrOpcode::kNumberAdd:
445 return machine()->Int32Add();
446 case IrOpcode::kNumberSubtract:
447 return machine()->Int32Sub();
448 case IrOpcode::kNumberMultiply:
449 return machine()->Int32Mul();
450 case IrOpcode::kNumberDivide:
451 return machine()->Int32Div();
452 case IrOpcode::kNumberModulus:
453 return machine()->Int32Mod();
454 case IrOpcode::kNumberBitwiseOr:
455 return machine()->Word32Or();
456 case IrOpcode::kNumberBitwiseXor:
457 return machine()->Word32Xor();
458 case IrOpcode::kNumberBitwiseAnd:
459 return machine()->Word32And();
460 case IrOpcode::kNumberEqual:
461 return machine()->Word32Equal();
462 case IrOpcode::kNumberLessThan:
463 return machine()->Int32LessThan();
464 case IrOpcode::kNumberLessThanOrEqual:
465 return machine()->Int32LessThanOrEqual();
466 default:
467 UNREACHABLE();
468 return nullptr;
469 }
470}
471
472
473const Operator* RepresentationChanger::Uint32OperatorFor(
474 IrOpcode::Value opcode) {
475 switch (opcode) {
476 case IrOpcode::kNumberAdd:
477 return machine()->Int32Add();
478 case IrOpcode::kNumberSubtract:
479 return machine()->Int32Sub();
480 case IrOpcode::kNumberMultiply:
481 return machine()->Int32Mul();
482 case IrOpcode::kNumberDivide:
483 return machine()->Uint32Div();
484 case IrOpcode::kNumberModulus:
485 return machine()->Uint32Mod();
486 case IrOpcode::kNumberEqual:
487 return machine()->Word32Equal();
488 case IrOpcode::kNumberLessThan:
489 return machine()->Uint32LessThan();
490 case IrOpcode::kNumberLessThanOrEqual:
491 return machine()->Uint32LessThanOrEqual();
Ben Murdochda12d292016-06-02 14:46:10 +0100492 case IrOpcode::kNumberClz32:
493 return machine()->Word32Clz();
494 case IrOpcode::kNumberImul:
495 return machine()->Int32Mul();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000496 default:
497 UNREACHABLE();
498 return nullptr;
499 }
500}
501
502
503const Operator* RepresentationChanger::Float64OperatorFor(
504 IrOpcode::Value opcode) {
505 switch (opcode) {
506 case IrOpcode::kNumberAdd:
507 return machine()->Float64Add();
508 case IrOpcode::kNumberSubtract:
509 return machine()->Float64Sub();
510 case IrOpcode::kNumberMultiply:
511 return machine()->Float64Mul();
512 case IrOpcode::kNumberDivide:
513 return machine()->Float64Div();
514 case IrOpcode::kNumberModulus:
515 return machine()->Float64Mod();
516 case IrOpcode::kNumberEqual:
517 return machine()->Float64Equal();
518 case IrOpcode::kNumberLessThan:
519 return machine()->Float64LessThan();
520 case IrOpcode::kNumberLessThanOrEqual:
521 return machine()->Float64LessThanOrEqual();
522 default:
523 UNREACHABLE();
524 return nullptr;
525 }
526}
527
528
529Node* RepresentationChanger::TypeError(Node* node,
530 MachineRepresentation output_rep,
531 Type* output_type,
532 MachineRepresentation use) {
533 type_error_ = true;
534 if (!testing_type_errors_) {
535 std::ostringstream out_str;
536 out_str << output_rep << " (";
537 output_type->PrintTo(out_str, Type::SEMANTIC_DIM);
538 out_str << ")";
539
540 std::ostringstream use_str;
541 use_str << use;
542
543 V8_Fatal(__FILE__, __LINE__,
544 "RepresentationChangerError: node #%d:%s of "
545 "%s cannot be changed to %s",
546 node->id(), node->op()->mnemonic(), out_str.str().c_str(),
547 use_str.str().c_str());
548 }
549 return node;
550}
551
552
553Node* RepresentationChanger::InsertChangeFloat32ToFloat64(Node* node) {
554 return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(), node);
555}
556
Ben Murdochc5610432016-08-08 18:44:38 +0100557Node* RepresentationChanger::InsertChangeFloat64ToUint32(Node* node) {
558 return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToUint32(), node);
559}
560
561Node* RepresentationChanger::InsertChangeFloat64ToInt32(Node* node) {
562 return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToInt32(), node);
563}
564
565Node* RepresentationChanger::InsertChangeTaggedSignedToInt32(Node* node) {
566 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(),
567 node);
568}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000569
570Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) {
571 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
572 node);
573}
574
575} // namespace compiler
576} // namespace internal
577} // namespace v8