| Index: runtime/vm/intermediate_language_arm.cc
|
| ===================================================================
|
| --- runtime/vm/intermediate_language_arm.cc (revision 25189)
|
| +++ runtime/vm/intermediate_language_arm.cc (working copy)
|
| @@ -3071,13 +3071,47 @@
|
|
|
|
|
| LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary() const {
|
| - UNIMPLEMENTED();
|
| - return NULL;
|
| + 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 Float32x4ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| - UNIMPLEMENTED();
|
| + QRegister left = locs()->in(0).fpu_reg();
|
| + QRegister right = locs()->in(1).fpu_reg();
|
| + QRegister result = locs()->out().fpu_reg();
|
| +
|
| + switch (op_kind()) {
|
| + case MethodRecognizer::kFloat32x4Equal:
|
| + __ vceqqs(result, left, right);
|
| + break;
|
| + case MethodRecognizer::kFloat32x4NotEqual:
|
| + __ vceqqs(result, left, right);
|
| + // Invert the result.
|
| + __ veorq(QTMP, QTMP, QTMP); // QTMP <- 0.
|
| + __ vornq(result, QTMP, result); // result <- ~result.
|
| + break;
|
| + case MethodRecognizer::kFloat32x4GreaterThan:
|
| + __ vcgtqs(result, left, right);
|
| + break;
|
| + case MethodRecognizer::kFloat32x4GreaterThanOrEqual:
|
| + __ vcgeqs(result, left, right);
|
| + break;
|
| + case MethodRecognizer::kFloat32x4LessThan:
|
| + __ vcgtqs(result, right, left);
|
| + break;
|
| + case MethodRecognizer::kFloat32x4LessThanOrEqual:
|
| + __ vcgeqs(result, right, left);
|
| + break;
|
| +
|
| + default: UNREACHABLE();
|
| + }
|
| }
|
|
|
|
|
| @@ -3137,13 +3171,49 @@
|
|
|
|
|
| LocationSummary* Float32x4WithInstr::MakeLocationSummary() const {
|
| - UNIMPLEMENTED();
|
| - return NULL;
|
| + 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 Float32x4WithInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| - UNIMPLEMENTED();
|
| + QRegister replacement = locs()->in(0).fpu_reg();
|
| + QRegister value = locs()->in(1).fpu_reg();
|
| + QRegister result = locs()->out().fpu_reg();
|
| +
|
| + DRegister dresult0 = EvenDRegisterOf(result);
|
| + DRegister dresult1 = OddDRegisterOf(result);
|
| + SRegister sresult0 = EvenSRegisterOf(dresult0);
|
| + SRegister sresult1 = OddSRegisterOf(dresult0);
|
| + SRegister sresult2 = EvenSRegisterOf(dresult1);
|
| + SRegister sresult3 = OddSRegisterOf(dresult1);
|
| +
|
| + __ vcvtsd(STMP, EvenDRegisterOf(replacement));
|
| + if (result != value) {
|
| + __ vmovq(result, value);
|
| + }
|
| +
|
| + switch (op_kind()) {
|
| + case MethodRecognizer::kFloat32x4WithX:
|
| + __ vmovs(sresult0, STMP);
|
| + break;
|
| + case MethodRecognizer::kFloat32x4WithY:
|
| + __ vmovs(sresult1, STMP);
|
| + break;
|
| + case MethodRecognizer::kFloat32x4WithZ:
|
| + __ vmovs(sresult2, STMP);
|
| + break;
|
| + case MethodRecognizer::kFloat32x4WithW:
|
| + __ vmovs(sresult3, STMP);
|
| + break;
|
| + default: UNREACHABLE();
|
| + }
|
| }
|
|
|
|
|
| @@ -3170,15 +3240,49 @@
|
|
|
|
|
| LocationSummary* Uint32x4GetFlagInstr::MakeLocationSummary() const {
|
| - UNIMPLEMENTED();
|
| - return NULL;
|
| + 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::RequiresRegister());
|
| + return summary;
|
| }
|
|
|
|
|
| void Uint32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| - UNIMPLEMENTED();
|
| + QRegister value = locs()->in(0).fpu_reg();
|
| + Register result = locs()->out().reg();
|
| +
|
| + DRegister dvalue0 = EvenDRegisterOf(value);
|
| + DRegister dvalue1 = OddDRegisterOf(value);
|
| + SRegister svalue0 = EvenSRegisterOf(dvalue0);
|
| + SRegister svalue1 = OddSRegisterOf(dvalue0);
|
| + SRegister svalue2 = EvenSRegisterOf(dvalue1);
|
| + SRegister svalue3 = OddSRegisterOf(dvalue1);
|
| +
|
| + switch (op_kind()) {
|
| + case MethodRecognizer::kUint32x4GetFlagX:
|
| + __ vmovrs(result, svalue0);
|
| + break;
|
| + case MethodRecognizer::kUint32x4GetFlagY:
|
| + __ vmovrs(result, svalue1);
|
| + break;
|
| + case MethodRecognizer::kUint32x4GetFlagZ:
|
| + __ vmovrs(result, svalue2);
|
| + break;
|
| + case MethodRecognizer::kUint32x4GetFlagW:
|
| + __ vmovrs(result, svalue3);
|
| + break;
|
| + default: UNREACHABLE();
|
| + }
|
| +
|
| + __ tst(result, ShifterOperand(result));
|
| + __ LoadObject(result, Bool::True(), NE);
|
| + __ LoadObject(result, Bool::False(), EQ);
|
| }
|
|
|
| +
|
| LocationSummary* Uint32x4SelectInstr::MakeLocationSummary() const {
|
| UNIMPLEMENTED();
|
| return NULL;
|
|
|