Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Unified Diff: runtime/vm/intermediate_language_arm64.cc

Issue 284843004: Adds Math Min/Max to arm64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/pkg.status ('k') | tests/lib/lib.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
+ }
}
« no previous file with comments | « pkg/pkg.status ('k') | tests/lib/lib.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698