Chromium Code Reviews| Index: runtime/vm/intrinsifier.cc |
| diff --git a/runtime/vm/intrinsifier.cc b/runtime/vm/intrinsifier.cc |
| index 5e24dd35739cf3ef92ae6be446fe713656cb9c05..48498e10012f614d5f7712193614787b78fd9b43 100644 |
| --- a/runtime/vm/intrinsifier.cc |
| +++ b/runtime/vm/intrinsifier.cc |
| @@ -501,6 +501,128 @@ bool Intrinsifier::Build_Float64ArrayGetIndexed(FlowGraph* flow_graph) { |
| } |
| +static bool BuildBinaryFloat32x4Op(FlowGraph* flow_graph, Token::Kind kind) { |
| + if (!FlowGraphCompiler::SupportsUnboxedSimd128()) return false; |
| + |
| + GraphEntryInstr* graph_entry = flow_graph->graph_entry(); |
| + TargetEntryInstr* normal_entry = graph_entry->normal_entry(); |
| + BlockBuilder builder(flow_graph, normal_entry); |
| + |
| + Definition* right = builder.AddParameter(1); |
| + Definition* left = builder.AddParameter(2); |
| + |
| + const ICData& value_check = ICData::ZoneHandle(ICData::New( |
| + flow_graph->function(), |
| + String::Handle(flow_graph->function().name()), |
| + Object::empty_array(), // Dummy args. descr. |
| + Isolate::kNoDeoptId, |
| + 1)); |
| + value_check.AddReceiverCheck(kFloat32x4Cid, flow_graph->function()); |
| + // Check argument. Receiver (left) is known to be a Float32x4. |
| + builder.AddInstruction( |
| + new CheckClassInstr(new Value(right), |
| + Isolate::kNoDeoptId, |
| + value_check, |
| + builder.TokenPos())); |
| + Definition* left_simd = builder.AddDefinition( |
| + UnboxInstr::Create(kUnboxedFloat32x4, |
| + new Value(left), |
|
Cutch
2015/09/22 15:48:05
What about creating a helper:
Definition* Unbox(R
Florian Schneider
2015/09/22 16:13:38
Done.
|
| + Isolate::kNoDeoptId)); |
| + // Manually adjust reaching type because there is no type propagation |
| + // when building intrinsics. |
| + left_simd->AsUnbox()->value()->SetReachingType( |
| + ZoneCompileType::Wrap(CompileType::FromCid(kFloat32x4Cid))); |
| + |
| + Definition* right_simd = builder.AddDefinition( |
| + UnboxInstr::Create(kUnboxedFloat32x4, |
| + new Value(right), |
| + Isolate::kNoDeoptId)); |
| + // Manually adjust reaching type because there is no type propagation |
| + // when building intrinsics. |
| + right_simd->AsUnbox()->value()->SetReachingType( |
| + ZoneCompileType::Wrap(CompileType::FromCid(kFloat32x4Cid))); |
| + Definition* unboxed_result = builder.AddDefinition( |
| + new BinaryFloat32x4OpInstr(kind, |
| + new Value(left_simd), |
| + new Value(right_simd), |
| + Isolate::kNoDeoptId)); |
| + Definition* result = builder.AddDefinition( |
| + BoxInstr::Create(kUnboxedFloat32x4, new Value(unboxed_result))); |
| + builder.AddIntrinsicReturn(new Value(result)); |
| + return true; |
| +} |
| + |
| + |
| +bool Intrinsifier::Build_Float32x4Mul(FlowGraph* flow_graph) { |
| + return BuildBinaryFloat32x4Op(flow_graph, Token::kMUL); |
| +} |
| + |
| + |
| +bool Intrinsifier::Build_Float32x4Sub(FlowGraph* flow_graph) { |
| + return BuildBinaryFloat32x4Op(flow_graph, Token::kSUB); |
| +} |
| + |
| + |
| +bool Intrinsifier::Build_Float32x4Add(FlowGraph* flow_graph) { |
| + return BuildBinaryFloat32x4Op(flow_graph, Token::kADD); |
| +} |
| + |
| + |
| +static bool BuildFloat32x4Shuffle(FlowGraph* flow_graph, |
| + MethodRecognizer::Kind kind) { |
| + if (!FlowGraphCompiler::SupportsUnboxedSimd128()) return false; |
| + GraphEntryInstr* graph_entry = flow_graph->graph_entry(); |
| + TargetEntryInstr* normal_entry = graph_entry->normal_entry(); |
| + BlockBuilder builder(flow_graph, normal_entry); |
| + |
| + Definition* receiver = builder.AddParameter(1); |
| + |
| + Definition* unboxed_receiver = builder.AddDefinition( |
| + UnboxInstr::Create(kUnboxedFloat32x4, |
| + new Value(receiver), |
| + Isolate::kNoDeoptId)); |
| + // Manually adjust reaching type because there is no type propagation |
| + // when building intrinsics. |
| + unboxed_receiver->AsUnbox()->value()->SetReachingType( |
| + ZoneCompileType::Wrap(CompileType::FromCid(kFloat32x4Cid))); |
|
Cutch
2015/09/22 15:48:05
Use helper here too
Florian Schneider
2015/09/22 16:13:38
Done.
|
| + |
| + Definition* unboxed_result = builder.AddDefinition( |
| + new Simd32x4ShuffleInstr(kind, |
| + new Value(unboxed_receiver), |
| + 0, |
| + Isolate::kNoDeoptId)); |
| + |
| + Definition* result = builder.AddDefinition( |
| + BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result))); |
| + builder.AddIntrinsicReturn(new Value(result)); |
| + return true; |
| +} |
| + |
| + |
| +bool Intrinsifier::Build_Float32x4ShuffleX(FlowGraph* flow_graph) { |
| + return BuildFloat32x4Shuffle(flow_graph, |
| + MethodRecognizer::kFloat32x4ShuffleX); |
| +} |
| + |
| + |
| +bool Intrinsifier::Build_Float32x4ShuffleY(FlowGraph* flow_graph) { |
| + return BuildFloat32x4Shuffle(flow_graph, |
| + MethodRecognizer::kFloat32x4ShuffleY); |
| +} |
| + |
| + |
| +bool Intrinsifier::Build_Float32x4ShuffleZ(FlowGraph* flow_graph) { |
| + return BuildFloat32x4Shuffle(flow_graph, |
| + MethodRecognizer::kFloat32x4ShuffleZ); |
| +} |
| + |
| + |
| +bool Intrinsifier::Build_Float32x4ShuffleW(FlowGraph* flow_graph) { |
| + return BuildFloat32x4Shuffle(flow_graph, |
| + MethodRecognizer::kFloat32x4ShuffleW); |
| +} |
| + |
| + |
| static bool BuildLoadField(FlowGraph* flow_graph, intptr_t offset) { |
| GraphEntryInstr* graph_entry = flow_graph->graph_entry(); |
| TargetEntryInstr* normal_entry = graph_entry->normal_entry(); |