Chromium Code Reviews| 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 |