Index: runtime/vm/intermediate_language_arm64.cc |
=================================================================== |
--- runtime/vm/intermediate_language_arm64.cc (revision 36115) |
+++ runtime/vm/intermediate_language_arm64.cc (working copy) |
@@ -848,13 +848,17 @@ |
LocationSummary* LoadUntaggedInstr::MakeLocationSummary(bool opt) const { |
- UNIMPLEMENTED(); |
- return NULL; |
+ const intptr_t kNumInputs = 1; |
+ return LocationSummary::Make(kNumInputs, |
+ Location::RequiresRegister(), |
+ LocationSummary::kNoCall); |
} |
void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
- UNIMPLEMENTED(); |
+ Register object = locs()->in(0).reg(); |
+ Register result = locs()->out(0).reg(); |
+ __ LoadFieldFromOffset(result, object, offset(), PP); |
} |
@@ -1013,17 +1017,11 @@ |
element_address = Address(array, index.reg(), UXTX, Address::Unscaled); |
if ((representation() == kUnboxedDouble) || |
- (representation() == kUnboxedMint) || |
(representation() == kUnboxedFloat32x4) || |
(representation() == kUnboxedInt32x4) || |
(representation() == kUnboxedFloat64x2)) { |
const VRegister result = locs()->out(0).fpu_reg(); |
switch (class_id()) { |
- case kTypedDataInt32ArrayCid: |
- case kTypedDataUint32ArrayCid: |
- // TODO(zra): Add when we have simd. |
- UNIMPLEMENTED(); |
- break; |
case kTypedDataFloat32ArrayCid: |
// Load single precision float. |
__ fldrs(result, element_address); |
@@ -1035,8 +1033,7 @@ |
case kTypedDataFloat64x2ArrayCid: |
case kTypedDataInt32x4ArrayCid: |
case kTypedDataFloat32x4ArrayCid: |
- // TODO(zra): Add when we have simd. |
- UNIMPLEMENTED(); |
+ __ fldrq(result, element_address); |
break; |
} |
return; |
@@ -1099,10 +1096,9 @@ |
case kExternalTypedDataUint8ClampedArrayCid: |
case kTypedDataInt16ArrayCid: |
case kTypedDataUint16ArrayCid: |
- return kTagged; |
case kTypedDataInt32ArrayCid: |
case kTypedDataUint32ArrayCid: |
- return value()->IsSmiValue() ? kTagged : kUnboxedMint; |
+ return kTagged; |
case kTypedDataFloat32ArrayCid: |
case kTypedDataFloat64ArrayCid: |
return kUnboxedDouble; |
@@ -1147,14 +1143,7 @@ |
break; |
case kTypedDataInt32ArrayCid: |
case kTypedDataUint32ArrayCid: |
- // Mints are stored in Q registers. For smis, use a writable register |
- // because the value must be untagged before storing. |
- if (value()->IsSmiValue()) { |
- locs->set_in(2, Location::WritableRegister()); |
- } else { |
- // TODO(zra): Implement when we add simd loads and stores. |
- UNIMPLEMENTED(); |
- } |
+ locs->set_in(2, Location::WritableRegister()); |
break; |
case kTypedDataFloat32ArrayCid: |
case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants. |
@@ -1163,8 +1152,7 @@ |
case kTypedDataInt32x4ArrayCid: |
case kTypedDataFloat32x4ArrayCid: |
case kTypedDataFloat64x2ArrayCid: |
- // TODO(zra): Implement when we add simd loads and stores. |
- UNIMPLEMENTED(); |
+ locs->set_in(2, Location::RequiresFpuRegister()); |
break; |
default: |
UNREACHABLE(); |
@@ -1280,15 +1268,9 @@ |
} |
case kTypedDataInt32ArrayCid: |
case kTypedDataUint32ArrayCid: { |
- if (value()->IsSmiValue()) { |
- ASSERT(RequiredInputRepresentation(2) == kTagged); |
- const Register value = locs()->in(2).reg(); |
- __ SmiUntag(value); |
- __ str(value, element_address, kUnsignedWord); |
- } else { |
- // TODO(zra): Implement when we add simd loads and stores. |
- UNIMPLEMENTED(); |
- } |
+ const Register value = locs()->in(2).reg(); |
+ __ SmiUntag(value); |
+ __ str(value, element_address, kUnsignedWord); |
break; |
} |
case kTypedDataFloat32ArrayCid: { |
@@ -1306,8 +1288,9 @@ |
case kTypedDataFloat64x2ArrayCid: |
case kTypedDataInt32x4ArrayCid: |
case kTypedDataFloat32x4ArrayCid: { |
- // TODO(zra): Implement when we add simd loads and stores. |
- UNIMPLEMENTED(); |
+ const VRegister in2 = locs()->in(2).fpu_reg(); |
+ __ add(index.reg(), index.reg(), Operand(array)); |
+ __ StoreQToOffset(in2, index.reg(), 0, PP); |
break; |
} |
default: |
@@ -3460,13 +3443,87 @@ |
LocationSummary* MathMinMaxInstr::MakeLocationSummary(bool opt) const { |
- UNIMPLEMENTED(); |
- return NULL; |
+ if (result_cid() == kDoubleCid) { |
+ 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()); |
+ // Reuse the left register so that code can be made shorter. |
+ summary->set_out(0, Location::SameAsFirstInput()); |
+ return summary; |
+ } |
+ ASSERT(result_cid() == kSmiCid); |
+ const intptr_t kNumInputs = 2; |
+ const intptr_t kNumTemps = 0; |
+ LocationSummary* summary = |
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
+ summary->set_in(0, Location::RequiresRegister()); |
+ summary->set_in(1, Location::RequiresRegister()); |
+ // Reuse the left register so that code can be made shorter. |
+ summary->set_out(0, Location::SameAsFirstInput()); |
+ return summary; |
} |
void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
- UNIMPLEMENTED(); |
+ ASSERT((op_kind() == MethodRecognizer::kMathMin) || |
+ (op_kind() == MethodRecognizer::kMathMax)); |
+ const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin); |
+ if (result_cid() == kDoubleCid) { |
+ Label done, returns_nan, are_equal; |
+ const VRegister left = locs()->in(0).fpu_reg(); |
+ const VRegister right = locs()->in(1).fpu_reg(); |
+ const VRegister result = locs()->out(0).fpu_reg(); |
+ __ fcmpd(left, right); |
+ __ b(&returns_nan, VS); |
+ __ b(&are_equal, EQ); |
+ const Condition double_condition = |
+ is_min ? TokenKindToDoubleCondition(Token::kLTE) |
+ : TokenKindToDoubleCondition(Token::kGTE); |
+ ASSERT(left == result); |
+ __ b(&done, double_condition); |
+ __ fmovdd(result, right); |
+ __ b(&done); |
+ |
+ __ Bind(&returns_nan); |
+ __ LoadDImmediate(result, NAN, PP); |
+ __ b(&done); |
+ |
+ __ Bind(&are_equal); |
+ // Check for negative zero: -0.0 is equal 0.0 but min or max must return |
+ // -0.0 or 0.0 respectively. |
+ // Check for negative left value (get the sign bit): |
+ // - min -> left is negative ? left : right. |
+ // - max -> left is negative ? right : left |
+ // Check the sign bit. |
+ __ fmovrd(TMP, left); // Sign bit is in bit 63 of TMP. |
+ __ CompareImmediate(TMP, 0, PP); |
+ if (is_min) { |
+ ASSERT(left == result); |
+ __ b(&done, LT); |
+ __ fmovdd(result, right); |
+ } else { |
+ __ b(&done, GE); |
+ __ fmovdd(result, right); |
+ ASSERT(left == result); |
+ } |
+ __ Bind(&done); |
+ return; |
+ } |
+ |
+ ASSERT(result_cid() == kSmiCid); |
+ Register left = locs()->in(0).reg(); |
+ Register right = locs()->in(1).reg(); |
+ Register result = locs()->out(0).reg(); |
+ __ CompareRegisters(left, right); |
+ ASSERT(result == left); |
+ if (is_min) { |
+ __ csel(result, right, left, GT); |
+ } else { |
+ __ csel(result, right, left, LT); |
+ } |
} |