Index: src/compiler/simd-lowering.cc |
diff --git a/src/compiler/simd-lowering.cc b/src/compiler/simd-lowering.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..851139937d59ac2e181a892580f390b6c06d83f0 |
--- /dev/null |
+++ b/src/compiler/simd-lowering.cc |
@@ -0,0 +1,149 @@ |
+// Copyright 2016 the V8 project authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "src/compiler/simd-lowering.h" |
+ |
+#include "src/assembler.h" |
+#include "src/compiler/js-graph.h" |
+#include "src/compiler/linkage.h" |
+#include "src/compiler/machine-operator.h" |
+#include "src/compiler/operator-properties.h" |
+#include "src/compiler/simplified-operator.h" |
+ |
+namespace v8 { |
+namespace internal { |
+namespace compiler { |
+ |
+SimdLowering::~SimdLowering() {} |
+ |
+Reduction SimdLowering::Reduce(Node* node) { |
+ // For now lower everything to runtime calls. |
+ switch (node->opcode()) { |
+ case IrOpcode::kCreateInt32x4: { |
+ Conversion signature[] = {kOpaque, kInt32, kInt32, kInt32, kInt32}; |
+ return ChangeToRuntimeCall(node, Runtime::kCreateInt32x4, signature); |
+ } |
+ case IrOpcode::kCreateInt16x8: { |
+ Conversion signature[] = { |
titzer
2016/05/19 09:58:38
You can use "static const" here to make the C++ co
gdeepti
2016/07/01 22:24:47
Done.
|
+ kOpaque, kInt32, kInt32, kInt32, kInt32, |
+ kInt32, kInt32, kInt32, kInt32, |
+ }; |
+ return ChangeToRuntimeCall(node, Runtime::kCreateInt16x8, signature); |
+ } |
+ case IrOpcode::kCreateInt8x16: { |
+ Conversion signature[] = { |
+ kOpaque, kInt32, kInt32, kInt32, kInt32, kInt32, |
+ kInt32, kInt32, kInt32, kInt32, kInt32, kInt32, |
+ kInt32, kInt32, kInt32, kInt32, kInt32, |
+ }; |
+ return ChangeToRuntimeCall(node, Runtime::kCreateInt8x16, signature); |
+ } |
+ case IrOpcode::kCreateFloat32x4: { |
+ Conversion signature[] = {kOpaque, kFloat32, kFloat32, kFloat32, |
+ kFloat32}; |
+ return ChangeToRuntimeCall(node, Runtime::kCreateFloat32x4, signature); |
+ } |
+ case IrOpcode::kInt8x16ExtractLane: |
+ case IrOpcode::kInt16x8ExtractLane: |
+ case IrOpcode::kInt32x4ExtractLane: { |
+ Conversion signature[] = {kInt32, kOpaque, kInt32}; |
+ return ChangeToRuntimeCall(node, Runtime::kInt32x4ExtractLane, signature); |
+ } |
+ case IrOpcode::kFloat32x4ExtractLane: { |
+ Conversion signature[] = {kFloat32, kOpaque, kInt32}; |
+ return ChangeToRuntimeCall(node, Runtime::kFloat32x4ExtractLane, |
+ signature); |
+ } |
+ default: { break; } |
+ } |
+ // TODO(gdeepti): Implement and test. |
+ // Assume the others are all just simd in and out. |
+ switch (node->opcode()) { |
+#define F(Opcode) \ |
+ case IrOpcode::k##Opcode: { \ |
+ Conversion signature[17] = { \ |
+ kNone, kNone, kNone, kNone, kNone, kNone, kNone, kNone, kNone, \ |
+ kNone, kNone, kNone, kNone, kNone, kNone, kNone, kNone, \ |
bbudge
2016/05/19 09:53:13
I'm not sure what the compiler does with this repe
gdeepti
2016/07/01 22:24:48
Done.
|
+ }; \ |
+ return ChangeToRuntimeCall(node, Runtime::k##Opcode, signature); \ |
+ } |
+ MACHINE_SIMD_RETURN_SIMD_OP_LIST(F) |
+ MACHINE_SIMD_RETURN_BOOL_OP_LIST(F) |
+#undef F |
+ default: { return NoChange(); } |
+ } |
+ UNREACHABLE(); |
+ return NoChange(); |
+} |
+ |
+Reduction SimdLowering::ChangeToRuntimeCall(Node* node, Runtime::FunctionId f, |
+ Conversion* signature) { |
+ SimplifiedOperatorBuilder simplified(jsgraph()->zone()); |
+ const Runtime::Function* fun = Runtime::FunctionForId(f); |
+ CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor( |
+ jsgraph()->zone(), f, fun->nargs, Operator::kNoProperties, |
+ CallDescriptor::kNoFlags); |
+ Node* inputs[16 + 6]; |
bbudge
2016/05/19 09:53:13
Need some constants defined for these magic number
gdeepti
2016/07/01 22:24:47
Done.
|
+ DCHECK_LE(fun->nargs + 6, static_cast<int>(arraysize(inputs))); |
+ // Either there are control + effect or not. |
+ DCHECK(node->InputCount() == fun->nargs || |
+ node->InputCount() == fun->nargs + 2); |
+ int index = 0; |
+ inputs[index++] = jsgraph()->CEntryStubConstant(fun->result_size); |
+ for (int i = 0; i < fun->nargs; ++i) { |
+ Node* arg = node->InputAt(i); |
+ switch (signature[i + 1]) { |
+ case kInt32: |
+ arg = builder_->BuildChangeInt32ToTagged(arg); |
+ break; |
+ case kFloat32: |
+ arg = jsgraph()->graph()->NewNode( |
+ jsgraph()->machine()->ChangeFloat32ToFloat64(), arg); |
+ arg = builder_->BuildChangeFloat64ToTagged(arg); |
+ break; |
+ case kFloat64: |
+ arg = builder_->BuildChangeFloat64ToTagged(arg); |
+ break; |
+ default: |
+ break; |
+ } |
+ inputs[index++] = arg; |
+ } |
+ inputs[index++] = |
+ jsgraph()->ExternalConstant(ExternalReference(f, jsgraph()->isolate())); |
+ inputs[index++] = jsgraph()->Int32Constant(fun->nargs); |
+ inputs[index++] = jsgraph()->Constant(context_); |
+ // Loads and stores have control and effect, others do not and use |
+ // the start node instead. |
+ if (node->InputCount() == fun->nargs + 2) { |
+ inputs[index++] = node->InputAt(fun->nargs + 1); // effect |
+ inputs[index++] = node->InputAt(fun->nargs + 2); // control |
+ } else { |
+ inputs[index++] = jsgraph()->graph()->start(); // effect |
+ inputs[index++] = jsgraph()->graph()->start(); // control |
+ } |
+ Node* ret = jsgraph()->graph()->NewNode(jsgraph()->common()->Call(desc), |
+ index, inputs); |
+ switch (signature[0]) { |
bbudge
2016/05/19 09:53:14
Maybe this would benefit with a well named local,
gdeepti
2016/07/01 22:24:47
Done.
|
+ case kInt32: |
+ ret = builder_->BuildChangeTaggedToInt32(ret); |
+ break; |
+ case kFloat32: |
+ NodeProperties::SetType(ret, Type::Number()); |
+ ret = builder_->BuildChangeTaggedToFloat64(ret); |
+ ret = jsgraph()->graph()->NewNode( |
+ jsgraph()->machine()->TruncateInt64ToInt32(), ret); |
+ break; |
+ case kFloat64: |
+ ret = builder_->BuildChangeTaggedToFloat64(ret); |
+ break; |
+ default: |
+ break; |
+ } |
+ return Replace(ret); |
+} |
+ |
+} // namespace compiler |
+} // namespace internal |
+} // namespace v8 |