Index: runtime/vm/intermediate_language_arm.cc |
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc |
index 9cda2792a1256fc6e816b3caba69a122866df1f7..499244f5543875935b8a9a1778f420b7c89ac6a1 100644 |
--- a/runtime/vm/intermediate_language_arm.cc |
+++ b/runtime/vm/intermediate_language_arm.cc |
@@ -3310,6 +3310,54 @@ void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
} |
+LocationSummary* BinaryFloat64x2OpInstr::MakeLocationSummary(bool opt) const { |
+ const intptr_t kNumInputs = 2; |
+ const intptr_t kNumTemps = 0; |
+ LocationSummary* summary = |
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
+ summary->set_in(0, Location::RequiresFpuRegister()); |
+ summary->set_in(1, Location::RequiresFpuRegister()); |
+ summary->set_out(Location::RequiresFpuRegister()); |
+ return summary; |
+} |
+ |
+ |
+void BinaryFloat64x2OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
+ QRegister left = locs()->in(0).fpu_reg(); |
+ QRegister right = locs()->in(1).fpu_reg(); |
+ QRegister result = locs()->out().fpu_reg(); |
+ |
+ DRegister left0 = EvenDRegisterOf(left); |
+ DRegister left1 = OddDRegisterOf(left); |
+ |
+ DRegister right0 = EvenDRegisterOf(right); |
+ DRegister right1 = OddDRegisterOf(right); |
+ |
+ DRegister result0 = EvenDRegisterOf(result); |
+ DRegister result1 = OddDRegisterOf(result); |
+ |
+ switch (op_kind()) { |
+ case Token::kADD: |
+ __ vaddd(result0, left0, right0); |
+ __ vaddd(result1, left1, right1); |
+ break; |
+ case Token::kSUB: |
+ __ vsubd(result0, left0, right0); |
+ __ vsubd(result1, left1, right1); |
+ break; |
+ case Token::kMUL: |
+ __ vmuld(result0, left0, right0); |
+ __ vmuld(result1, left1, right1); |
+ break; |
+ case Token::kDIV: |
+ __ vdivd(result0, left0, right0); |
+ __ vdivd(result1, left1, right1); |
+ break; |
+ default: UNREACHABLE(); |
+ } |
+} |
+ |
+ |
LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary(bool opt) const { |
const intptr_t kNumInputs = 1; |
const intptr_t kNumTemps = 0; |
@@ -3813,6 +3861,171 @@ void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
} |
+LocationSummary* Simd64x2ShuffleInstr::MakeLocationSummary(bool opt) const { |
+ const intptr_t kNumInputs = 1; |
+ const intptr_t kNumTemps = 0; |
+ LocationSummary* summary = |
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
+ summary->set_in(0, Location::RequiresFpuRegister()); |
+ summary->set_out(Location::RequiresFpuRegister()); |
+ return summary; |
+} |
+ |
+ |
+void Simd64x2ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
+ QRegister value = locs()->in(0).fpu_reg(); |
+ |
+ DRegister dvalue0 = EvenDRegisterOf(value); |
+ DRegister dvalue1 = OddDRegisterOf(value); |
+ |
+ QRegister result = locs()->out().fpu_reg(); |
+ |
+ DRegister dresult0 = EvenDRegisterOf(result); |
+ |
+ switch (op_kind()) { |
+ case MethodRecognizer::kFloat64x2GetX: |
+ __ vmovd(dresult0, dvalue0); |
+ break; |
+ case MethodRecognizer::kFloat64x2GetY: |
+ __ vmovd(dresult0, dvalue1); |
+ break; |
+ default: UNREACHABLE(); |
+ } |
+} |
+ |
+ |
+LocationSummary* Float64x2ZeroInstr::MakeLocationSummary(bool opt) const { |
+ const intptr_t kNumInputs = 0; |
+ const intptr_t kNumTemps = 0; |
+ LocationSummary* summary = |
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
+ summary->set_out(Location::RequiresFpuRegister()); |
+ return summary; |
+} |
+ |
+ |
+void Float64x2ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
+ QRegister q = locs()->out().fpu_reg(); |
+ __ veorq(q, q, q); |
+} |
+ |
+ |
+LocationSummary* Float64x2SplatInstr::MakeLocationSummary(bool opt) const { |
+ const intptr_t kNumInputs = 1; |
+ const intptr_t kNumTemps = 0; |
+ LocationSummary* summary = |
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
+ summary->set_in(0, Location::RequiresFpuRegister()); |
+ summary->set_out(Location::RequiresFpuRegister()); |
+ return summary; |
+} |
+ |
+ |
+void Float64x2SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
+ QRegister value = locs()->in(0).fpu_reg(); |
+ |
+ DRegister dvalue = EvenDRegisterOf(value); |
+ |
+ QRegister result = locs()->out().fpu_reg(); |
+ |
+ DRegister dresult0 = EvenDRegisterOf(result); |
+ DRegister dresult1 = OddDRegisterOf(result); |
+ |
+ // Splat across all lanes. |
+ __ vmovd(dresult0, dvalue); |
+ __ vmovd(dresult1, dvalue); |
+} |
+ |
+ |
+LocationSummary* Float64x2ConstructorInstr::MakeLocationSummary( |
+ bool opt) const { |
+ const intptr_t kNumInputs = 2; |
+ const intptr_t kNumTemps = 0; |
+ LocationSummary* summary = |
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
+ summary->set_in(0, Location::RequiresFpuRegister()); |
+ summary->set_in(1, Location::RequiresFpuRegister()); |
+ summary->set_out(Location::RequiresFpuRegister()); |
+ return summary; |
+} |
+ |
+ |
+void Float64x2ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
+ QRegister q0 = locs()->in(0).fpu_reg(); |
+ QRegister q1 = locs()->in(1).fpu_reg(); |
+ QRegister r = locs()->out().fpu_reg(); |
+ |
+ DRegister d0 = EvenDRegisterOf(q0); |
+ DRegister d1 = EvenDRegisterOf(q1); |
+ |
+ DRegister dr0 = EvenDRegisterOf(r); |
+ DRegister dr1 = OddDRegisterOf(r); |
+ |
+ __ vmovd(dr0, d0); |
+ __ vmovd(dr1, d1); |
+} |
+ |
+ |
+LocationSummary* Float64x2ToFloat32x4Instr::MakeLocationSummary( |
+ bool opt) const { |
+ const intptr_t kNumInputs = 1; |
+ const intptr_t kNumTemps = 0; |
+ LocationSummary* summary = |
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
+ summary->set_in(0, Location::RequiresFpuRegister()); |
+ // Low (< 7) Q registers are needed for the vcvtsd instruction. |
+ summary->set_out(Location::FpuRegisterLocation(Q6)); |
+ return summary; |
+} |
+ |
+ |
+void Float64x2ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
+ QRegister q = locs()->in(0).fpu_reg(); |
+ QRegister r = locs()->out().fpu_reg(); |
+ |
+ DRegister dq0 = EvenDRegisterOf(q); |
+ DRegister dq1 = OddDRegisterOf(q); |
+ |
+ DRegister dr0 = EvenDRegisterOf(r); |
+ |
+ // Zero register. |
+ __ veorq(r, r, r); |
+ // Set X lane. |
+ __ vcvtsd(EvenSRegisterOf(dr0), dq0); |
+ // Set Y lane. |
+ __ vcvtsd(OddSRegisterOf(dr0), dq1); |
+} |
+ |
+ |
+LocationSummary* Float32x4ToFloat64x2Instr::MakeLocationSummary( |
+ bool opt) const { |
+ const intptr_t kNumInputs = 1; |
+ const intptr_t kNumTemps = 0; |
+ LocationSummary* summary = |
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
+ summary->set_in(0, Location::RequiresFpuRegister()); |
+ // Low (< 7) Q registers are needed for the vcvtsd instruction. |
+ summary->set_out(Location::FpuRegisterLocation(Q6)); |
+ return summary; |
+} |
+ |
+ |
+void Float32x4ToFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
+ QRegister q = locs()->in(0).fpu_reg(); |
+ QRegister r = locs()->out().fpu_reg(); |
+ |
+ DRegister dq0 = EvenDRegisterOf(q); |
+ |
+ DRegister dr0 = EvenDRegisterOf(r); |
+ DRegister dr1 = OddDRegisterOf(r); |
+ |
+ // Set X. |
+ __ vcvtds(dr0, EvenSRegisterOf(dq0)); |
+ // Set Y. |
+ __ vcvtds(dr1, OddSRegisterOf(dq0)); |
+} |
+ |
+ |
LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary( |
bool opt) const { |
const intptr_t kNumInputs = 4; |