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

Side by Side Diff: runtime/vm/intermediate_language_arm.cc

Issue 207063002: Refactor to support multiple outputs in location summary (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 11 matching lines...) Expand all
22 namespace dart { 22 namespace dart {
23 23
24 DECLARE_FLAG(int, optimization_counter_threshold); 24 DECLARE_FLAG(int, optimization_counter_threshold);
25 DECLARE_FLAG(bool, propagate_ic_data); 25 DECLARE_FLAG(bool, propagate_ic_data);
26 DECLARE_FLAG(bool, use_osr); 26 DECLARE_FLAG(bool, use_osr);
27 27
28 // Generic summary for call instructions that have all arguments pushed 28 // Generic summary for call instructions that have all arguments pushed
29 // on the stack and return the result in a fixed register R0. 29 // on the stack and return the result in a fixed register R0.
30 LocationSummary* Instruction::MakeCallSummary() { 30 LocationSummary* Instruction::MakeCallSummary() {
31 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); 31 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall);
32 result->set_out(Location::RegisterLocation(R0)); 32 result->set_out(0, Location::RegisterLocation(R0));
33 return result; 33 return result;
34 } 34 }
35 35
36 36
37 LocationSummary* PushArgumentInstr::MakeLocationSummary(bool opt) const { 37 LocationSummary* PushArgumentInstr::MakeLocationSummary(bool opt) const {
38 const intptr_t kNumInputs = 1; 38 const intptr_t kNumInputs = 1;
39 const intptr_t kNumTemps= 0; 39 const intptr_t kNumTemps= 0;
40 LocationSummary* locs = 40 LocationSummary* locs =
41 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 41 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
42 locs->set_in(0, Location::AnyOrConstant(value())); 42 locs->set_in(0, Location::AnyOrConstant(value()));
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 } 122 }
123 123
124 124
125 LocationSummary* IfThenElseInstr::MakeLocationSummary(bool opt) const { 125 LocationSummary* IfThenElseInstr::MakeLocationSummary(bool opt) const {
126 comparison()->InitializeLocationSummary(opt); 126 comparison()->InitializeLocationSummary(opt);
127 return comparison()->locs(); 127 return comparison()->locs();
128 } 128 }
129 129
130 130
131 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 131 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
132 const Register result = locs()->out().reg(); 132 const Register result = locs()->out(0).reg();
133 133
134 Location left = locs()->in(0); 134 Location left = locs()->in(0);
135 Location right = locs()->in(1); 135 Location right = locs()->in(1);
136 ASSERT(!left.IsConstant() || !right.IsConstant()); 136 ASSERT(!left.IsConstant() || !right.IsConstant());
137 137
138 // Clear out register. 138 // Clear out register.
139 __ eor(result, result, ShifterOperand(result)); 139 __ eor(result, result, ShifterOperand(result));
140 140
141 // Emit comparison code. This must not overwrite the result register. 141 // Emit comparison code. This must not overwrite the result register.
142 BranchLabels labels = { NULL, NULL, NULL }; 142 BranchLabels labels = { NULL, NULL, NULL };
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 } 179 }
180 } 180 }
181 } 181 }
182 182
183 183
184 LocationSummary* ClosureCallInstr::MakeLocationSummary(bool opt) const { 184 LocationSummary* ClosureCallInstr::MakeLocationSummary(bool opt) const {
185 const intptr_t kNumInputs = 0; 185 const intptr_t kNumInputs = 0;
186 const intptr_t kNumTemps = 1; 186 const intptr_t kNumTemps = 1;
187 LocationSummary* result = 187 LocationSummary* result =
188 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 188 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
189 result->set_out(Location::RegisterLocation(R0)); 189 result->set_out(0, Location::RegisterLocation(R0));
190 result->set_temp(0, Location::RegisterLocation(R4)); // Arg. descriptor. 190 result->set_temp(0, Location::RegisterLocation(R4)); // Arg. descriptor.
191 return result; 191 return result;
192 } 192 }
193 193
194 194
195 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 195 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
196 // The arguments to the stub include the closure, as does the arguments 196 // The arguments to the stub include the closure, as does the arguments
197 // descriptor. 197 // descriptor.
198 Register temp_reg = locs()->temp(0).reg(); 198 Register temp_reg = locs()->temp(0).reg();
199 int argument_count = ArgumentCount(); 199 int argument_count = ArgumentCount();
(...skipping 12 matching lines...) Expand all
212 212
213 213
214 LocationSummary* LoadLocalInstr::MakeLocationSummary(bool opt) const { 214 LocationSummary* LoadLocalInstr::MakeLocationSummary(bool opt) const {
215 return LocationSummary::Make(0, 215 return LocationSummary::Make(0,
216 Location::RequiresRegister(), 216 Location::RequiresRegister(),
217 LocationSummary::kNoCall); 217 LocationSummary::kNoCall);
218 } 218 }
219 219
220 220
221 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 221 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
222 Register result = locs()->out().reg(); 222 Register result = locs()->out(0).reg();
223 __ LoadFromOffset(kWord, result, FP, local().index() * kWordSize); 223 __ LoadFromOffset(kWord, result, FP, local().index() * kWordSize);
224 } 224 }
225 225
226 226
227 LocationSummary* StoreLocalInstr::MakeLocationSummary(bool opt) const { 227 LocationSummary* StoreLocalInstr::MakeLocationSummary(bool opt) const {
228 return LocationSummary::Make(1, 228 return LocationSummary::Make(1,
229 Location::SameAsFirstInput(), 229 Location::SameAsFirstInput(),
230 LocationSummary::kNoCall); 230 LocationSummary::kNoCall);
231 } 231 }
232 232
233 233
234 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 234 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
235 Register value = locs()->in(0).reg(); 235 Register value = locs()->in(0).reg();
236 Register result = locs()->out().reg(); 236 Register result = locs()->out(0).reg();
237 ASSERT(result == value); // Assert that register assignment is correct. 237 ASSERT(result == value); // Assert that register assignment is correct.
238 __ str(value, Address(FP, local().index() * kWordSize)); 238 __ str(value, Address(FP, local().index() * kWordSize));
239 } 239 }
240 240
241 241
242 LocationSummary* ConstantInstr::MakeLocationSummary(bool opt) const { 242 LocationSummary* ConstantInstr::MakeLocationSummary(bool opt) const {
243 return LocationSummary::Make(0, 243 return LocationSummary::Make(0,
244 Location::RequiresRegister(), 244 Location::RequiresRegister(),
245 LocationSummary::kNoCall); 245 LocationSummary::kNoCall);
246 } 246 }
247 247
248 248
249 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 249 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
250 // The register allocator drops constant definitions that have no uses. 250 // The register allocator drops constant definitions that have no uses.
251 if (!locs()->out().IsInvalid()) { 251 if (!locs()->out(0).IsInvalid()) {
252 Register result = locs()->out().reg(); 252 Register result = locs()->out(0).reg();
253 __ LoadObject(result, value()); 253 __ LoadObject(result, value());
254 } 254 }
255 } 255 }
256 256
257 257
258 LocationSummary* AssertAssignableInstr::MakeLocationSummary(bool opt) const { 258 LocationSummary* AssertAssignableInstr::MakeLocationSummary(bool opt) const {
259 const intptr_t kNumInputs = 3; 259 const intptr_t kNumInputs = 3;
260 const intptr_t kNumTemps = 0; 260 const intptr_t kNumTemps = 0;
261 LocationSummary* summary = 261 LocationSummary* summary =
262 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 262 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
263 summary->set_in(0, Location::RegisterLocation(R0)); // Value. 263 summary->set_in(0, Location::RegisterLocation(R0)); // Value.
264 summary->set_in(1, Location::RegisterLocation(R2)); // Instantiator. 264 summary->set_in(1, Location::RegisterLocation(R2)); // Instantiator.
265 summary->set_in(2, Location::RegisterLocation(R1)); // Type arguments. 265 summary->set_in(2, Location::RegisterLocation(R1)); // Type arguments.
266 summary->set_out(Location::RegisterLocation(R0)); 266 summary->set_out(0, Location::RegisterLocation(R0));
267 return summary; 267 return summary;
268 } 268 }
269 269
270 270
271 LocationSummary* AssertBooleanInstr::MakeLocationSummary(bool opt) const { 271 LocationSummary* AssertBooleanInstr::MakeLocationSummary(bool opt) const {
272 const intptr_t kNumInputs = 1; 272 const intptr_t kNumInputs = 1;
273 const intptr_t kNumTemps = 0; 273 const intptr_t kNumTemps = 0;
274 LocationSummary* locs = 274 LocationSummary* locs =
275 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 275 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
276 locs->set_in(0, Location::RegisterLocation(R0)); 276 locs->set_in(0, Location::RegisterLocation(R0));
277 locs->set_out(Location::RegisterLocation(R0)); 277 locs->set_out(0, Location::RegisterLocation(R0));
278 return locs; 278 return locs;
279 } 279 }
280 280
281 281
282 static void EmitAssertBoolean(Register reg, 282 static void EmitAssertBoolean(Register reg,
283 intptr_t token_pos, 283 intptr_t token_pos,
284 intptr_t deopt_id, 284 intptr_t deopt_id,
285 LocationSummary* locs, 285 LocationSummary* locs,
286 FlowGraphCompiler* compiler) { 286 FlowGraphCompiler* compiler) {
287 // Check that the type of the value is allowed in conditional context. 287 // Check that the type of the value is allowed in conditional context.
(...skipping 12 matching lines...) Expand all
300 1, 300 1,
301 locs); 301 locs);
302 // We should never return here. 302 // We should never return here.
303 __ bkpt(0); 303 __ bkpt(0);
304 __ Bind(&done); 304 __ Bind(&done);
305 } 305 }
306 306
307 307
308 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 308 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
309 Register obj = locs()->in(0).reg(); 309 Register obj = locs()->in(0).reg();
310 Register result = locs()->out().reg(); 310 Register result = locs()->out(0).reg();
311 311
312 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler); 312 EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler);
313 ASSERT(obj == result); 313 ASSERT(obj == result);
314 } 314 }
315 315
316 316
317 static Condition TokenKindToSmiCondition(Token::Kind kind) { 317 static Condition TokenKindToSmiCondition(Token::Kind kind) {
318 switch (kind) { 318 switch (kind) {
319 case Token::kEQ: return EQ; 319 case Token::kEQ: return EQ;
320 case Token::kNE: return NE; 320 case Token::kNE: return NE;
(...skipping 10 matching lines...) Expand all
331 331
332 LocationSummary* EqualityCompareInstr::MakeLocationSummary(bool opt) const { 332 LocationSummary* EqualityCompareInstr::MakeLocationSummary(bool opt) const {
333 const intptr_t kNumInputs = 2; 333 const intptr_t kNumInputs = 2;
334 if (operation_cid() == kMintCid) { 334 if (operation_cid() == kMintCid) {
335 const intptr_t kNumTemps = 1; 335 const intptr_t kNumTemps = 1;
336 LocationSummary* locs = 336 LocationSummary* locs =
337 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 337 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
338 locs->set_in(0, Location::RequiresFpuRegister()); 338 locs->set_in(0, Location::RequiresFpuRegister());
339 locs->set_in(1, Location::RequiresFpuRegister()); 339 locs->set_in(1, Location::RequiresFpuRegister());
340 locs->set_temp(0, Location::RequiresRegister()); 340 locs->set_temp(0, Location::RequiresRegister());
341 locs->set_out(Location::RequiresRegister()); 341 locs->set_out(0, Location::RequiresRegister());
342 return locs; 342 return locs;
343 } 343 }
344 if (operation_cid() == kDoubleCid) { 344 if (operation_cid() == kDoubleCid) {
345 const intptr_t kNumTemps = 0; 345 const intptr_t kNumTemps = 0;
346 LocationSummary* locs = 346 LocationSummary* locs =
347 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 347 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
348 locs->set_in(0, Location::RequiresFpuRegister()); 348 locs->set_in(0, Location::RequiresFpuRegister());
349 locs->set_in(1, Location::RequiresFpuRegister()); 349 locs->set_in(1, Location::RequiresFpuRegister());
350 locs->set_out(Location::RequiresRegister()); 350 locs->set_out(0, Location::RequiresRegister());
351 return locs; 351 return locs;
352 } 352 }
353 if (operation_cid() == kSmiCid) { 353 if (operation_cid() == kSmiCid) {
354 const intptr_t kNumTemps = 0; 354 const intptr_t kNumTemps = 0;
355 LocationSummary* locs = 355 LocationSummary* locs =
356 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 356 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
357 locs->set_in(0, Location::RegisterOrConstant(left())); 357 locs->set_in(0, Location::RegisterOrConstant(left()));
358 // Only one input can be a constant operand. The case of two constant 358 // Only one input can be a constant operand. The case of two constant
359 // operands should be handled by constant propagation. 359 // operands should be handled by constant propagation.
360 locs->set_in(1, locs->in(0).IsConstant() 360 locs->set_in(1, locs->in(0).IsConstant()
361 ? Location::RequiresRegister() 361 ? Location::RequiresRegister()
362 : Location::RegisterOrConstant(right())); 362 : Location::RegisterOrConstant(right()));
363 locs->set_out(Location::RequiresRegister()); 363 locs->set_out(0, Location::RequiresRegister());
364 return locs; 364 return locs;
365 } 365 }
366 UNREACHABLE(); 366 UNREACHABLE();
367 return NULL; 367 return NULL;
368 } 368 }
369 369
370 370
371 static void LoadValueCid(FlowGraphCompiler* compiler, 371 static void LoadValueCid(FlowGraphCompiler* compiler,
372 Register value_cid_reg, 372 Register value_cid_reg,
373 Register value_reg, 373 Register value_reg,
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 } 486 }
487 487
488 488
489 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 489 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
490 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 490 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
491 491
492 // The ARM code does not use true- and false-labels here. 492 // The ARM code does not use true- and false-labels here.
493 BranchLabels labels = { NULL, NULL, NULL }; 493 BranchLabels labels = { NULL, NULL, NULL };
494 Condition true_condition = EmitComparisonCode(compiler, labels); 494 Condition true_condition = EmitComparisonCode(compiler, labels);
495 495
496 Register result = locs()->out().reg(); 496 Register result = locs()->out(0).reg();
497 if (operation_cid() == kSmiCid) { 497 if (operation_cid() == kSmiCid) {
498 __ LoadObject(result, Bool::True(), true_condition); 498 __ LoadObject(result, Bool::True(), true_condition);
499 __ LoadObject(result, Bool::False(), NegateCondition(true_condition)); 499 __ LoadObject(result, Bool::False(), NegateCondition(true_condition));
500 } else { 500 } else {
501 ASSERT(operation_cid() == kDoubleCid); 501 ASSERT(operation_cid() == kDoubleCid);
502 Label done; 502 Label done;
503 __ LoadObject(result, Bool::False()); 503 __ LoadObject(result, Bool::False());
504 if (true_condition != NE) { 504 if (true_condition != NE) {
505 __ b(&done, VS); // x == NaN -> false, x != NaN -> true. 505 __ b(&done, VS); // x == NaN -> false, x != NaN -> true.
506 } 506 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 const intptr_t kNumInputs = 2; 573 const intptr_t kNumInputs = 2;
574 const intptr_t kNumTemps = 0; 574 const intptr_t kNumTemps = 0;
575 if (operation_cid() == kMintCid) { 575 if (operation_cid() == kMintCid) {
576 const intptr_t kNumTemps = 2; 576 const intptr_t kNumTemps = 2;
577 LocationSummary* locs = 577 LocationSummary* locs =
578 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 578 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
579 locs->set_in(0, Location::RequiresFpuRegister()); 579 locs->set_in(0, Location::RequiresFpuRegister());
580 locs->set_in(1, Location::RequiresFpuRegister()); 580 locs->set_in(1, Location::RequiresFpuRegister());
581 locs->set_temp(0, Location::RequiresRegister()); 581 locs->set_temp(0, Location::RequiresRegister());
582 locs->set_temp(1, Location::RequiresRegister()); 582 locs->set_temp(1, Location::RequiresRegister());
583 locs->set_out(Location::RequiresRegister()); 583 locs->set_out(0, Location::RequiresRegister());
584 return locs; 584 return locs;
585 } 585 }
586 if (operation_cid() == kDoubleCid) { 586 if (operation_cid() == kDoubleCid) {
587 LocationSummary* summary = 587 LocationSummary* summary =
588 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 588 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
589 summary->set_in(0, Location::RequiresFpuRegister()); 589 summary->set_in(0, Location::RequiresFpuRegister());
590 summary->set_in(1, Location::RequiresFpuRegister()); 590 summary->set_in(1, Location::RequiresFpuRegister());
591 summary->set_out(Location::RequiresRegister()); 591 summary->set_out(0, Location::RequiresRegister());
592 return summary; 592 return summary;
593 } 593 }
594 ASSERT(operation_cid() == kSmiCid); 594 ASSERT(operation_cid() == kSmiCid);
595 LocationSummary* summary = 595 LocationSummary* summary =
596 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 596 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
597 summary->set_in(0, Location::RegisterOrConstant(left())); 597 summary->set_in(0, Location::RegisterOrConstant(left()));
598 // Only one input can be a constant operand. The case of two constant 598 // Only one input can be a constant operand. The case of two constant
599 // operands should be handled by constant propagation. 599 // operands should be handled by constant propagation.
600 summary->set_in(1, summary->in(0).IsConstant() 600 summary->set_in(1, summary->in(0).IsConstant()
601 ? Location::RequiresRegister() 601 ? Location::RequiresRegister()
602 : Location::RegisterOrConstant(right())); 602 : Location::RegisterOrConstant(right()));
603 summary->set_out(Location::RequiresRegister()); 603 summary->set_out(0, Location::RequiresRegister());
604 return summary; 604 return summary;
605 } 605 }
606 606
607 607
608 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 608 Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
609 BranchLabels labels) { 609 BranchLabels labels) {
610 if (operation_cid() == kSmiCid) { 610 if (operation_cid() == kSmiCid) {
611 return EmitSmiComparisonOp(compiler, locs(), kind()); 611 return EmitSmiComparisonOp(compiler, locs(), kind());
612 } else { 612 } else {
613 ASSERT(operation_cid() == kDoubleCid); 613 ASSERT(operation_cid() == kDoubleCid);
614 return EmitDoubleComparisonOp(compiler, locs(), kind()); 614 return EmitDoubleComparisonOp(compiler, locs(), kind());
615 } 615 }
616 } 616 }
617 617
618 618
619 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 619 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
620 // The ARM code does not use true- and false-labels here. 620 // The ARM code does not use true- and false-labels here.
621 BranchLabels labels = { NULL, NULL, NULL }; 621 BranchLabels labels = { NULL, NULL, NULL };
622 Condition true_condition = EmitComparisonCode(compiler, labels); 622 Condition true_condition = EmitComparisonCode(compiler, labels);
623 623
624 Register result = locs()->out().reg(); 624 Register result = locs()->out(0).reg();
625 if (operation_cid() == kSmiCid) { 625 if (operation_cid() == kSmiCid) {
626 __ LoadObject(result, Bool::True(), true_condition); 626 __ LoadObject(result, Bool::True(), true_condition);
627 __ LoadObject(result, Bool::False(), NegateCondition(true_condition)); 627 __ LoadObject(result, Bool::False(), NegateCondition(true_condition));
628 } else { 628 } else {
629 ASSERT(operation_cid() == kDoubleCid); 629 ASSERT(operation_cid() == kDoubleCid);
630 Label done; 630 Label done;
631 __ LoadObject(result, Bool::False()); 631 __ LoadObject(result, Bool::False());
632 if (true_condition != NE) { 632 if (true_condition != NE) {
633 __ b(&done, VS); // x == NaN -> false, x != NaN -> true. 633 __ b(&done, VS); // x == NaN -> false, x != NaN -> true.
634 } 634 }
(...skipping 18 matching lines...) Expand all
653 653
654 654
655 LocationSummary* NativeCallInstr::MakeLocationSummary(bool opt) const { 655 LocationSummary* NativeCallInstr::MakeLocationSummary(bool opt) const {
656 const intptr_t kNumInputs = 0; 656 const intptr_t kNumInputs = 0;
657 const intptr_t kNumTemps = 3; 657 const intptr_t kNumTemps = 3;
658 LocationSummary* locs = 658 LocationSummary* locs =
659 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 659 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
660 locs->set_temp(0, Location::RegisterLocation(R1)); 660 locs->set_temp(0, Location::RegisterLocation(R1));
661 locs->set_temp(1, Location::RegisterLocation(R2)); 661 locs->set_temp(1, Location::RegisterLocation(R2));
662 locs->set_temp(2, Location::RegisterLocation(R5)); 662 locs->set_temp(2, Location::RegisterLocation(R5));
663 locs->set_out(Location::RegisterLocation(R0)); 663 locs->set_out(0, Location::RegisterLocation(R0));
664 return locs; 664 return locs;
665 } 665 }
666 666
667 667
668 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 668 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
669 ASSERT(locs()->temp(0).reg() == R1); 669 ASSERT(locs()->temp(0).reg() == R1);
670 ASSERT(locs()->temp(1).reg() == R2); 670 ASSERT(locs()->temp(1).reg() == R2);
671 ASSERT(locs()->temp(2).reg() == R5); 671 ASSERT(locs()->temp(2).reg() == R5);
672 Register result = locs()->out().reg(); 672 Register result = locs()->out(0).reg();
673 673
674 // Push the result place holder initialized to NULL. 674 // Push the result place holder initialized to NULL.
675 __ PushObject(Object::ZoneHandle()); 675 __ PushObject(Object::ZoneHandle());
676 // Pass a pointer to the first argument in R2. 676 // Pass a pointer to the first argument in R2.
677 if (!function().HasOptionalParameters()) { 677 if (!function().HasOptionalParameters()) {
678 __ AddImmediate(R2, FP, (kParamEndSlotFromFp + 678 __ AddImmediate(R2, FP, (kParamEndSlotFromFp +
679 function().NumParameters()) * kWordSize); 679 function().NumParameters()) * kWordSize);
680 } else { 680 } else {
681 __ AddImmediate(R2, FP, kFirstLocalSlotFromFp * kWordSize); 681 __ AddImmediate(R2, FP, kFirstLocalSlotFromFp * kWordSize);
682 } 682 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 const intptr_t kNumInputs = 1; 717 const intptr_t kNumInputs = 1;
718 // TODO(fschneider): Allow immediate operands for the char code. 718 // TODO(fschneider): Allow immediate operands for the char code.
719 return LocationSummary::Make(kNumInputs, 719 return LocationSummary::Make(kNumInputs,
720 Location::RequiresRegister(), 720 Location::RequiresRegister(),
721 LocationSummary::kNoCall); 721 LocationSummary::kNoCall);
722 } 722 }
723 723
724 724
725 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 725 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
726 Register char_code = locs()->in(0).reg(); 726 Register char_code = locs()->in(0).reg();
727 Register result = locs()->out().reg(); 727 Register result = locs()->out(0).reg();
728 __ LoadImmediate(result, 728 __ LoadImmediate(result,
729 reinterpret_cast<uword>(Symbols::PredefinedAddress())); 729 reinterpret_cast<uword>(Symbols::PredefinedAddress()));
730 __ AddImmediate(result, Symbols::kNullCharCodeSymbolOffset * kWordSize); 730 __ AddImmediate(result, Symbols::kNullCharCodeSymbolOffset * kWordSize);
731 __ ldr(result, Address(result, char_code, LSL, 1)); // Char code is a smi. 731 __ ldr(result, Address(result, char_code, LSL, 1)); // Char code is a smi.
732 } 732 }
733 733
734 734
735 LocationSummary* StringToCharCodeInstr::MakeLocationSummary(bool opt) const { 735 LocationSummary* StringToCharCodeInstr::MakeLocationSummary(bool opt) const {
736 const intptr_t kNumInputs = 1; 736 const intptr_t kNumInputs = 1;
737 return LocationSummary::Make(kNumInputs, 737 return LocationSummary::Make(kNumInputs,
738 Location::RequiresRegister(), 738 Location::RequiresRegister(),
739 LocationSummary::kNoCall); 739 LocationSummary::kNoCall);
740 } 740 }
741 741
742 742
743 void StringToCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 743 void StringToCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
744 ASSERT(cid_ == kOneByteStringCid); 744 ASSERT(cid_ == kOneByteStringCid);
745 Register str = locs()->in(0).reg(); 745 Register str = locs()->in(0).reg();
746 Register result = locs()->out().reg(); 746 Register result = locs()->out(0).reg();
747 __ ldr(result, FieldAddress(str, String::length_offset())); 747 __ ldr(result, FieldAddress(str, String::length_offset()));
748 __ cmp(result, ShifterOperand(Smi::RawValue(1))); 748 __ cmp(result, ShifterOperand(Smi::RawValue(1)));
749 __ LoadImmediate(result, Smi::RawValue(-1), NE); 749 __ LoadImmediate(result, Smi::RawValue(-1), NE);
750 __ ldrb(result, FieldAddress(str, OneByteString::data_offset()), EQ); 750 __ ldrb(result, FieldAddress(str, OneByteString::data_offset()), EQ);
751 __ SmiTag(result); 751 __ SmiTag(result);
752 } 752 }
753 753
754 754
755 LocationSummary* StringInterpolateInstr::MakeLocationSummary(bool opt) const { 755 LocationSummary* StringInterpolateInstr::MakeLocationSummary(bool opt) const {
756 const intptr_t kNumInputs = 1; 756 const intptr_t kNumInputs = 1;
757 const intptr_t kNumTemps = 0; 757 const intptr_t kNumTemps = 0;
758 LocationSummary* summary = 758 LocationSummary* summary =
759 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 759 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
760 summary->set_in(0, Location::RegisterLocation(R0)); 760 summary->set_in(0, Location::RegisterLocation(R0));
761 summary->set_out(Location::RegisterLocation(R0)); 761 summary->set_out(0, Location::RegisterLocation(R0));
762 return summary; 762 return summary;
763 } 763 }
764 764
765 765
766 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 766 void StringInterpolateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
767 Register array = locs()->in(0).reg(); 767 Register array = locs()->in(0).reg();
768 __ Push(array); 768 __ Push(array);
769 const int kNumberOfArguments = 1; 769 const int kNumberOfArguments = 1;
770 const Array& kNoArgumentNames = Object::null_array(); 770 const Array& kNoArgumentNames = Object::null_array();
771 compiler->GenerateStaticCall(deopt_id(), 771 compiler->GenerateStaticCall(deopt_id(),
772 token_pos(), 772 token_pos(),
773 CallFunction(), 773 CallFunction(),
774 kNumberOfArguments, 774 kNumberOfArguments,
775 kNoArgumentNames, 775 kNoArgumentNames,
776 locs()); 776 locs());
777 ASSERT(locs()->out().reg() == R0); 777 ASSERT(locs()->out(0).reg() == R0);
778 } 778 }
779 779
780 780
781 LocationSummary* LoadUntaggedInstr::MakeLocationSummary(bool opt) const { 781 LocationSummary* LoadUntaggedInstr::MakeLocationSummary(bool opt) const {
782 const intptr_t kNumInputs = 1; 782 const intptr_t kNumInputs = 1;
783 return LocationSummary::Make(kNumInputs, 783 return LocationSummary::Make(kNumInputs,
784 Location::RequiresRegister(), 784 Location::RequiresRegister(),
785 LocationSummary::kNoCall); 785 LocationSummary::kNoCall);
786 } 786 }
787 787
788 788
789 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 789 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
790 Register object = locs()->in(0).reg(); 790 Register object = locs()->in(0).reg();
791 Register result = locs()->out().reg(); 791 Register result = locs()->out(0).reg();
792 __ LoadFromOffset(kWord, result, object, offset() - kHeapObjectTag); 792 __ LoadFromOffset(kWord, result, object, offset() - kHeapObjectTag);
793 } 793 }
794 794
795 795
796 LocationSummary* LoadClassIdInstr::MakeLocationSummary(bool opt) const { 796 LocationSummary* LoadClassIdInstr::MakeLocationSummary(bool opt) const {
797 const intptr_t kNumInputs = 1; 797 const intptr_t kNumInputs = 1;
798 return LocationSummary::Make(kNumInputs, 798 return LocationSummary::Make(kNumInputs,
799 Location::RequiresRegister(), 799 Location::RequiresRegister(),
800 LocationSummary::kNoCall); 800 LocationSummary::kNoCall);
801 } 801 }
802 802
803 803
804 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 804 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
805 Register object = locs()->in(0).reg(); 805 Register object = locs()->in(0).reg();
806 Register result = locs()->out().reg(); 806 Register result = locs()->out(0).reg();
807 Label load, done; 807 Label load, done;
808 __ tst(object, ShifterOperand(kSmiTagMask)); 808 __ tst(object, ShifterOperand(kSmiTagMask));
809 __ b(&load, NE); 809 __ b(&load, NE);
810 __ LoadImmediate(result, Smi::RawValue(kSmiCid)); 810 __ LoadImmediate(result, Smi::RawValue(kSmiCid));
811 __ b(&done); 811 __ b(&done);
812 __ Bind(&load); 812 __ Bind(&load);
813 __ LoadClassId(result, object); 813 __ LoadClassId(result, object);
814 __ SmiTag(result); 814 __ SmiTag(result);
815 __ Bind(&done); 815 __ Bind(&done);
816 } 816 }
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 // TODO(regis): Revisit and see if the index can be immediate. 904 // TODO(regis): Revisit and see if the index can be immediate.
905 locs->set_in(1, Location::WritableRegister()); 905 locs->set_in(1, Location::WritableRegister());
906 if ((representation() == kUnboxedDouble) || 906 if ((representation() == kUnboxedDouble) ||
907 (representation() == kUnboxedFloat32x4) || 907 (representation() == kUnboxedFloat32x4) ||
908 (representation() == kUnboxedInt32x4) || 908 (representation() == kUnboxedInt32x4) ||
909 (representation() == kUnboxedFloat64x2)) { 909 (representation() == kUnboxedFloat64x2)) {
910 if (class_id() == kTypedDataFloat32ArrayCid) { 910 if (class_id() == kTypedDataFloat32ArrayCid) {
911 // Need register <= Q7 for float operations. 911 // Need register <= Q7 for float operations.
912 // TODO(fschneider): Add a register policy to specify a subset of 912 // TODO(fschneider): Add a register policy to specify a subset of
913 // registers. 913 // registers.
914 locs->set_out(Location::FpuRegisterLocation(Q7)); 914 locs->set_out(0, Location::FpuRegisterLocation(Q7));
915 } else { 915 } else {
916 locs->set_out(Location::RequiresFpuRegister()); 916 locs->set_out(0, Location::RequiresFpuRegister());
917 } 917 }
918 } else { 918 } else {
919 locs->set_out(Location::RequiresRegister()); 919 locs->set_out(0, Location::RequiresRegister());
920 } 920 }
921 return locs; 921 return locs;
922 } 922 }
923 923
924 924
925 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 925 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
926 Register array = locs()->in(0).reg(); 926 Register array = locs()->in(0).reg();
927 Location index = locs()->in(1); 927 Location index = locs()->in(1);
928 928
929 Address element_address(kNoRegister, 0); 929 Address element_address(kNoRegister, 0);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
961 __ AddImmediate(index.reg(), 961 __ AddImmediate(index.reg(),
962 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); 962 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
963 } 963 }
964 element_address = Address(array, index.reg(), LSL, 0); 964 element_address = Address(array, index.reg(), LSL, 0);
965 965
966 if ((representation() == kUnboxedDouble) || 966 if ((representation() == kUnboxedDouble) ||
967 (representation() == kUnboxedMint) || 967 (representation() == kUnboxedMint) ||
968 (representation() == kUnboxedFloat32x4) || 968 (representation() == kUnboxedFloat32x4) ||
969 (representation() == kUnboxedInt32x4) || 969 (representation() == kUnboxedInt32x4) ||
970 (representation() == kUnboxedFloat64x2)) { 970 (representation() == kUnboxedFloat64x2)) {
971 QRegister result = locs()->out().fpu_reg(); 971 QRegister result = locs()->out(0).fpu_reg();
972 DRegister dresult0 = EvenDRegisterOf(result); 972 DRegister dresult0 = EvenDRegisterOf(result);
973 DRegister dresult1 = OddDRegisterOf(result); 973 DRegister dresult1 = OddDRegisterOf(result);
974 switch (class_id()) { 974 switch (class_id()) {
975 case kTypedDataInt32ArrayCid: 975 case kTypedDataInt32ArrayCid:
976 UNIMPLEMENTED(); 976 UNIMPLEMENTED();
977 break; 977 break;
978 case kTypedDataUint32ArrayCid: 978 case kTypedDataUint32ArrayCid:
979 UNIMPLEMENTED(); 979 UNIMPLEMENTED();
980 break; 980 break;
981 case kTypedDataFloat32ArrayCid: 981 case kTypedDataFloat32ArrayCid:
(...skipping 14 matching lines...) Expand all
996 case kTypedDataFloat32x4ArrayCid: 996 case kTypedDataFloat32x4ArrayCid:
997 __ add(index.reg(), index.reg(), ShifterOperand(array)); 997 __ add(index.reg(), index.reg(), ShifterOperand(array));
998 // TODO(zra): Maybe use vldmd here. 998 // TODO(zra): Maybe use vldmd here.
999 __ LoadDFromOffset(dresult0, index.reg(), 0); 999 __ LoadDFromOffset(dresult0, index.reg(), 0);
1000 __ LoadDFromOffset(dresult1, index.reg(), 2 * kWordSize); 1000 __ LoadDFromOffset(dresult1, index.reg(), 2 * kWordSize);
1001 break; 1001 break;
1002 } 1002 }
1003 return; 1003 return;
1004 } 1004 }
1005 1005
1006 Register result = locs()->out().reg(); 1006 Register result = locs()->out(0).reg();
1007 switch (class_id()) { 1007 switch (class_id()) {
1008 case kTypedDataInt8ArrayCid: 1008 case kTypedDataInt8ArrayCid:
1009 ASSERT(index_scale() == 1); 1009 ASSERT(index_scale() == 1);
1010 __ ldrsb(result, element_address); 1010 __ ldrsb(result, element_address);
1011 __ SmiTag(result); 1011 __ SmiTag(result);
1012 break; 1012 break;
1013 case kTypedDataUint8ArrayCid: 1013 case kTypedDataUint8ArrayCid:
1014 case kTypedDataUint8ClampedArrayCid: 1014 case kTypedDataUint8ClampedArrayCid:
1015 case kExternalTypedDataUint8ArrayCid: 1015 case kExternalTypedDataUint8ArrayCid:
1016 case kExternalTypedDataUint8ClampedArrayCid: 1016 case kExternalTypedDataUint8ClampedArrayCid:
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after
1608 1608
1609 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1609 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1610 __ Comment("StoreInstanceFieldSlowPath"); 1610 __ Comment("StoreInstanceFieldSlowPath");
1611 __ Bind(entry_label()); 1611 __ Bind(entry_label());
1612 1612
1613 const Code& stub = 1613 const Code& stub =
1614 Code::Handle(StubCode::GetAllocationStubForClass(cls_)); 1614 Code::Handle(StubCode::GetAllocationStubForClass(cls_));
1615 const ExternalLabel label(cls_.ToCString(), stub.EntryPoint()); 1615 const ExternalLabel label(cls_.ToCString(), stub.EntryPoint());
1616 1616
1617 LocationSummary* locs = instruction_->locs(); 1617 LocationSummary* locs = instruction_->locs();
1618 locs->live_registers()->Remove(locs->out()); 1618 locs->live_registers()->Remove(locs->out(0));
1619 1619
1620 compiler->SaveLiveRegisters(locs); 1620 compiler->SaveLiveRegisters(locs);
1621 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 1621 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
1622 &label, 1622 &label,
1623 PcDescriptors::kOther, 1623 PcDescriptors::kOther,
1624 locs); 1624 locs);
1625 __ MoveRegister(locs->temp(0).reg(), R0); 1625 __ MoveRegister(locs->temp(0).reg(), R0);
1626 compiler->RestoreLiveRegisters(locs); 1626 compiler->RestoreLiveRegisters(locs);
1627 1627
1628 __ b(exit_label()); 1628 __ b(exit_label());
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
1901 __ Bind(&skip_store); 1901 __ Bind(&skip_store);
1902 } 1902 }
1903 1903
1904 1904
1905 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary(bool opt) const { 1905 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary(bool opt) const {
1906 const intptr_t kNumInputs = 1; 1906 const intptr_t kNumInputs = 1;
1907 const intptr_t kNumTemps = 0; 1907 const intptr_t kNumTemps = 0;
1908 LocationSummary* summary = 1908 LocationSummary* summary =
1909 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1909 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1910 summary->set_in(0, Location::RequiresRegister()); 1910 summary->set_in(0, Location::RequiresRegister());
1911 summary->set_out(Location::RequiresRegister()); 1911 summary->set_out(0, Location::RequiresRegister());
1912 return summary; 1912 return summary;
1913 } 1913 }
1914 1914
1915 1915
1916 // When the parser is building an implicit static getter for optimization, 1916 // When the parser is building an implicit static getter for optimization,
1917 // it can generate a function body where deoptimization ids do not line up 1917 // it can generate a function body where deoptimization ids do not line up
1918 // with the unoptimized code. 1918 // with the unoptimized code.
1919 // 1919 //
1920 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize. 1920 // This is safe only so long as LoadStaticFieldInstr cannot deoptimize.
1921 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1921 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1922 Register field = locs()->in(0).reg(); 1922 Register field = locs()->in(0).reg();
1923 Register result = locs()->out().reg(); 1923 Register result = locs()->out(0).reg();
1924 __ LoadFromOffset(kWord, result, 1924 __ LoadFromOffset(kWord, result,
1925 field, Field::value_offset() - kHeapObjectTag); 1925 field, Field::value_offset() - kHeapObjectTag);
1926 } 1926 }
1927 1927
1928 1928
1929 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(bool opt) const { 1929 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(bool opt) const {
1930 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); 1930 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall);
1931 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() 1931 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister()
1932 : Location::RequiresRegister()); 1932 : Location::RequiresRegister());
1933 locs->set_temp(0, Location::RequiresRegister()); 1933 locs->set_temp(0, Location::RequiresRegister());
(...skipping 17 matching lines...) Expand all
1951 1951
1952 1952
1953 LocationSummary* InstanceOfInstr::MakeLocationSummary(bool opt) const { 1953 LocationSummary* InstanceOfInstr::MakeLocationSummary(bool opt) const {
1954 const intptr_t kNumInputs = 3; 1954 const intptr_t kNumInputs = 3;
1955 const intptr_t kNumTemps = 0; 1955 const intptr_t kNumTemps = 0;
1956 LocationSummary* summary = 1956 LocationSummary* summary =
1957 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1957 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1958 summary->set_in(0, Location::RegisterLocation(R0)); 1958 summary->set_in(0, Location::RegisterLocation(R0));
1959 summary->set_in(1, Location::RegisterLocation(R2)); 1959 summary->set_in(1, Location::RegisterLocation(R2));
1960 summary->set_in(2, Location::RegisterLocation(R1)); 1960 summary->set_in(2, Location::RegisterLocation(R1));
1961 summary->set_out(Location::RegisterLocation(R0)); 1961 summary->set_out(0, Location::RegisterLocation(R0));
1962 return summary; 1962 return summary;
1963 } 1963 }
1964 1964
1965 1965
1966 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1966 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1967 ASSERT(locs()->in(0).reg() == R0); // Value. 1967 ASSERT(locs()->in(0).reg() == R0); // Value.
1968 ASSERT(locs()->in(1).reg() == R2); // Instantiator. 1968 ASSERT(locs()->in(1).reg() == R2); // Instantiator.
1969 ASSERT(locs()->in(2).reg() == R1); // Instantiator type arguments. 1969 ASSERT(locs()->in(2).reg() == R1); // Instantiator type arguments.
1970 1970
1971 compiler->GenerateInstanceOf(token_pos(), 1971 compiler->GenerateInstanceOf(token_pos(),
1972 deopt_id(), 1972 deopt_id(),
1973 type(), 1973 type(),
1974 negate_result(), 1974 negate_result(),
1975 locs()); 1975 locs());
1976 ASSERT(locs()->out().reg() == R0); 1976 ASSERT(locs()->out(0).reg() == R0);
1977 } 1977 }
1978 1978
1979 1979
1980 LocationSummary* CreateArrayInstr::MakeLocationSummary(bool opt) const { 1980 LocationSummary* CreateArrayInstr::MakeLocationSummary(bool opt) const {
1981 const intptr_t kNumInputs = 2; 1981 const intptr_t kNumInputs = 2;
1982 const intptr_t kNumTemps = 0; 1982 const intptr_t kNumTemps = 0;
1983 LocationSummary* locs = 1983 LocationSummary* locs =
1984 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1984 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1985 locs->set_in(kElementTypePos, Location::RegisterLocation(R1)); 1985 locs->set_in(kElementTypePos, Location::RegisterLocation(R1));
1986 locs->set_in(kLengthPos, Location::RegisterLocation(R2)); 1986 locs->set_in(kLengthPos, Location::RegisterLocation(R2));
1987 locs->set_out(Location::RegisterLocation(R0)); 1987 locs->set_out(0, Location::RegisterLocation(R0));
1988 return locs; 1988 return locs;
1989 } 1989 }
1990 1990
1991 1991
1992 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1992 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1993 // Allocate the array. R2 = length, R1 = element type. 1993 // Allocate the array. R2 = length, R1 = element type.
1994 ASSERT(locs()->in(kElementTypePos).reg() == R1); 1994 ASSERT(locs()->in(kElementTypePos).reg() == R1);
1995 ASSERT(locs()->in(kLengthPos).reg() == R2); 1995 ASSERT(locs()->in(kLengthPos).reg() == R2);
1996 compiler->GenerateCall(token_pos(), 1996 compiler->GenerateCall(token_pos(),
1997 &StubCode::AllocateArrayLabel(), 1997 &StubCode::AllocateArrayLabel(),
1998 PcDescriptors::kOther, 1998 PcDescriptors::kOther,
1999 locs()); 1999 locs());
2000 ASSERT(locs()->out().reg() == R0); 2000 ASSERT(locs()->out(0).reg() == R0);
2001 } 2001 }
2002 2002
2003 2003
2004 class BoxDoubleSlowPath : public SlowPathCode { 2004 class BoxDoubleSlowPath : public SlowPathCode {
2005 public: 2005 public:
2006 explicit BoxDoubleSlowPath(Instruction* instruction) 2006 explicit BoxDoubleSlowPath(Instruction* instruction)
2007 : instruction_(instruction) { } 2007 : instruction_(instruction) { }
2008 2008
2009 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 2009 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
2010 __ Comment("BoxDoubleSlowPath"); 2010 __ Comment("BoxDoubleSlowPath");
2011 __ Bind(entry_label()); 2011 __ Bind(entry_label());
2012 const Class& double_class = compiler->double_class(); 2012 const Class& double_class = compiler->double_class();
2013 const Code& stub = 2013 const Code& stub =
2014 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 2014 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
2015 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 2015 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
2016 2016
2017 LocationSummary* locs = instruction_->locs(); 2017 LocationSummary* locs = instruction_->locs();
2018 locs->live_registers()->Remove(locs->out()); 2018 locs->live_registers()->Remove(locs->out(0));
2019 2019
2020 compiler->SaveLiveRegisters(locs); 2020 compiler->SaveLiveRegisters(locs);
2021 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 2021 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
2022 &label, 2022 &label,
2023 PcDescriptors::kOther, 2023 PcDescriptors::kOther,
2024 locs); 2024 locs);
2025 __ MoveRegister(locs->out().reg(), R0); 2025 __ MoveRegister(locs->out(0).reg(), R0);
2026 compiler->RestoreLiveRegisters(locs); 2026 compiler->RestoreLiveRegisters(locs);
2027 2027
2028 __ b(exit_label()); 2028 __ b(exit_label());
2029 } 2029 }
2030 2030
2031 private: 2031 private:
2032 Instruction* instruction_; 2032 Instruction* instruction_;
2033 }; 2033 };
2034 2034
2035 2035
2036 class BoxFloat32x4SlowPath : public SlowPathCode { 2036 class BoxFloat32x4SlowPath : public SlowPathCode {
2037 public: 2037 public:
2038 explicit BoxFloat32x4SlowPath(Instruction* instruction) 2038 explicit BoxFloat32x4SlowPath(Instruction* instruction)
2039 : instruction_(instruction) { } 2039 : instruction_(instruction) { }
2040 2040
2041 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 2041 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
2042 __ Comment("BoxFloat32x4SlowPath"); 2042 __ Comment("BoxFloat32x4SlowPath");
2043 __ Bind(entry_label()); 2043 __ Bind(entry_label());
2044 const Class& float32x4_class = compiler->float32x4_class(); 2044 const Class& float32x4_class = compiler->float32x4_class();
2045 const Code& stub = 2045 const Code& stub =
2046 Code::Handle(StubCode::GetAllocationStubForClass(float32x4_class)); 2046 Code::Handle(StubCode::GetAllocationStubForClass(float32x4_class));
2047 const ExternalLabel label(float32x4_class.ToCString(), stub.EntryPoint()); 2047 const ExternalLabel label(float32x4_class.ToCString(), stub.EntryPoint());
2048 2048
2049 LocationSummary* locs = instruction_->locs(); 2049 LocationSummary* locs = instruction_->locs();
2050 locs->live_registers()->Remove(locs->out()); 2050 locs->live_registers()->Remove(locs->out(0));
2051 2051
2052 compiler->SaveLiveRegisters(locs); 2052 compiler->SaveLiveRegisters(locs);
2053 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 2053 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
2054 &label, 2054 &label,
2055 PcDescriptors::kOther, 2055 PcDescriptors::kOther,
2056 locs); 2056 locs);
2057 __ mov(locs->out().reg(), ShifterOperand(R0)); 2057 __ mov(locs->out(0).reg(), ShifterOperand(R0));
2058 compiler->RestoreLiveRegisters(locs); 2058 compiler->RestoreLiveRegisters(locs);
2059 2059
2060 __ b(exit_label()); 2060 __ b(exit_label());
2061 } 2061 }
2062 2062
2063 private: 2063 private:
2064 Instruction* instruction_; 2064 Instruction* instruction_;
2065 }; 2065 };
2066 2066
2067 2067
2068 class BoxFloat64x2SlowPath : public SlowPathCode { 2068 class BoxFloat64x2SlowPath : public SlowPathCode {
2069 public: 2069 public:
2070 explicit BoxFloat64x2SlowPath(Instruction* instruction) 2070 explicit BoxFloat64x2SlowPath(Instruction* instruction)
2071 : instruction_(instruction) { } 2071 : instruction_(instruction) { }
2072 2072
2073 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 2073 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
2074 __ Comment("BoxFloat64x2SlowPath"); 2074 __ Comment("BoxFloat64x2SlowPath");
2075 __ Bind(entry_label()); 2075 __ Bind(entry_label());
2076 const Class& float64x2_class = compiler->float64x2_class(); 2076 const Class& float64x2_class = compiler->float64x2_class();
2077 const Code& stub = 2077 const Code& stub =
2078 Code::Handle(StubCode::GetAllocationStubForClass(float64x2_class)); 2078 Code::Handle(StubCode::GetAllocationStubForClass(float64x2_class));
2079 const ExternalLabel label(float64x2_class.ToCString(), stub.EntryPoint()); 2079 const ExternalLabel label(float64x2_class.ToCString(), stub.EntryPoint());
2080 2080
2081 LocationSummary* locs = instruction_->locs(); 2081 LocationSummary* locs = instruction_->locs();
2082 locs->live_registers()->Remove(locs->out()); 2082 locs->live_registers()->Remove(locs->out(0));
2083 2083
2084 compiler->SaveLiveRegisters(locs); 2084 compiler->SaveLiveRegisters(locs);
2085 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 2085 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
2086 &label, 2086 &label,
2087 PcDescriptors::kOther, 2087 PcDescriptors::kOther,
2088 locs); 2088 locs);
2089 __ mov(locs->out().reg(), ShifterOperand(R0)); 2089 __ mov(locs->out(0).reg(), ShifterOperand(R0));
2090 compiler->RestoreLiveRegisters(locs); 2090 compiler->RestoreLiveRegisters(locs);
2091 2091
2092 __ b(exit_label()); 2092 __ b(exit_label());
2093 } 2093 }
2094 2094
2095 private: 2095 private:
2096 Instruction* instruction_; 2096 Instruction* instruction_;
2097 }; 2097 };
2098 2098
2099 2099
2100 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const { 2100 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const {
2101 const intptr_t kNumInputs = 1; 2101 const intptr_t kNumInputs = 1;
2102 const intptr_t kNumTemps = 0; 2102 const intptr_t kNumTemps = 0;
2103 LocationSummary* locs = 2103 LocationSummary* locs =
2104 new LocationSummary( 2104 new LocationSummary(
2105 kNumInputs, kNumTemps, 2105 kNumInputs, kNumTemps,
2106 (opt && !IsPotentialUnboxedLoad()) 2106 (opt && !IsPotentialUnboxedLoad())
2107 ? LocationSummary::kNoCall 2107 ? LocationSummary::kNoCall
2108 : LocationSummary::kCallOnSlowPath); 2108 : LocationSummary::kCallOnSlowPath);
2109 2109
2110 locs->set_in(0, Location::RequiresRegister()); 2110 locs->set_in(0, Location::RequiresRegister());
2111 2111
2112 if (IsUnboxedLoad() && opt) { 2112 if (IsUnboxedLoad() && opt) {
2113 locs->AddTemp(Location::RequiresRegister()); 2113 locs->AddTemp(Location::RequiresRegister());
2114 } else if (IsPotentialUnboxedLoad()) { 2114 } else if (IsPotentialUnboxedLoad()) {
2115 locs->AddTemp(opt ? Location::RequiresFpuRegister() 2115 locs->AddTemp(opt ? Location::RequiresFpuRegister()
2116 : Location::FpuRegisterLocation(Q1)); 2116 : Location::FpuRegisterLocation(Q1));
2117 locs->AddTemp(Location::RequiresRegister()); 2117 locs->AddTemp(Location::RequiresRegister());
2118 } 2118 }
2119 locs->set_out(Location::RequiresRegister()); 2119 locs->set_out(0, Location::RequiresRegister());
2120 return locs; 2120 return locs;
2121 } 2121 }
2122 2122
2123 2123
2124 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2124 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2125 Register instance_reg = locs()->in(0).reg(); 2125 Register instance_reg = locs()->in(0).reg();
2126 if (IsUnboxedLoad() && compiler->is_optimizing()) { 2126 if (IsUnboxedLoad() && compiler->is_optimizing()) {
2127 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); 2127 DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg());
2128 DRegister result_odd = OddDRegisterOf(locs()->out().fpu_reg()); 2128 DRegister result_odd = OddDRegisterOf(locs()->out(0).fpu_reg());
2129 Register temp = locs()->temp(0).reg(); 2129 Register temp = locs()->temp(0).reg();
2130 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); 2130 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes()));
2131 intptr_t cid = field()->UnboxedFieldCid(); 2131 intptr_t cid = field()->UnboxedFieldCid();
2132 switch (cid) { 2132 switch (cid) {
2133 case kDoubleCid: 2133 case kDoubleCid:
2134 __ Comment("UnboxedDoubleLoadFieldInstr"); 2134 __ Comment("UnboxedDoubleLoadFieldInstr");
2135 __ LoadDFromOffset(result, temp, 2135 __ LoadDFromOffset(result, temp,
2136 Double::value_offset() - kHeapObjectTag); 2136 Double::value_offset() - kHeapObjectTag);
2137 break; 2137 break;
2138 case kFloat32x4Cid: 2138 case kFloat32x4Cid:
(...skipping 12 matching lines...) Expand all
2151 __ LoadDFromOffset(result_odd, temp, 2151 __ LoadDFromOffset(result_odd, temp,
2152 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag); 2152 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag);
2153 break; 2153 break;
2154 default: 2154 default:
2155 UNREACHABLE(); 2155 UNREACHABLE();
2156 } 2156 }
2157 return; 2157 return;
2158 } 2158 }
2159 2159
2160 Label done; 2160 Label done;
2161 Register result_reg = locs()->out().reg(); 2161 Register result_reg = locs()->out(0).reg();
2162 if (IsPotentialUnboxedLoad()) { 2162 if (IsPotentialUnboxedLoad()) {
2163 Register temp = locs()->temp(1).reg(); 2163 Register temp = locs()->temp(1).reg();
2164 DRegister value = EvenDRegisterOf(locs()->temp(0).fpu_reg()); 2164 DRegister value = EvenDRegisterOf(locs()->temp(0).fpu_reg());
2165 DRegister value_odd = OddDRegisterOf(locs()->temp(0).fpu_reg()); 2165 DRegister value_odd = OddDRegisterOf(locs()->temp(0).fpu_reg());
2166 2166
2167 Label load_pointer; 2167 Label load_pointer;
2168 Label load_double; 2168 Label load_double;
2169 Label load_float32x4; 2169 Label load_float32x4;
2170 Label load_float64x2; 2170 Label load_float64x2;
2171 2171
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
2269 __ Bind(&done); 2269 __ Bind(&done);
2270 } 2270 }
2271 2271
2272 2272
2273 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const { 2273 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const {
2274 const intptr_t kNumInputs = 1; 2274 const intptr_t kNumInputs = 1;
2275 const intptr_t kNumTemps = 0; 2275 const intptr_t kNumTemps = 0;
2276 LocationSummary* locs = 2276 LocationSummary* locs =
2277 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 2277 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
2278 locs->set_in(0, Location::RegisterLocation(R0)); 2278 locs->set_in(0, Location::RegisterLocation(R0));
2279 locs->set_out(Location::RegisterLocation(R0)); 2279 locs->set_out(0, Location::RegisterLocation(R0));
2280 return locs; 2280 return locs;
2281 } 2281 }
2282 2282
2283 2283
2284 void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2284 void InstantiateTypeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2285 Register instantiator_reg = locs()->in(0).reg(); 2285 Register instantiator_reg = locs()->in(0).reg();
2286 Register result_reg = locs()->out().reg(); 2286 Register result_reg = locs()->out(0).reg();
2287 2287
2288 // 'instantiator_reg' is the instantiator TypeArguments object (or null). 2288 // 'instantiator_reg' is the instantiator TypeArguments object (or null).
2289 // A runtime call to instantiate the type is required. 2289 // A runtime call to instantiate the type is required.
2290 __ PushObject(Object::ZoneHandle()); // Make room for the result. 2290 __ PushObject(Object::ZoneHandle()); // Make room for the result.
2291 __ PushObject(type()); 2291 __ PushObject(type());
2292 __ Push(instantiator_reg); // Push instantiator type arguments. 2292 __ Push(instantiator_reg); // Push instantiator type arguments.
2293 compiler->GenerateRuntimeCall(token_pos(), 2293 compiler->GenerateRuntimeCall(token_pos(),
2294 deopt_id(), 2294 deopt_id(),
2295 kInstantiateTypeRuntimeEntry, 2295 kInstantiateTypeRuntimeEntry,
2296 2, 2296 2,
2297 locs()); 2297 locs());
2298 __ Drop(2); // Drop instantiator and uninstantiated type. 2298 __ Drop(2); // Drop instantiator and uninstantiated type.
2299 __ Pop(result_reg); // Pop instantiated type. 2299 __ Pop(result_reg); // Pop instantiated type.
2300 ASSERT(instantiator_reg == result_reg); 2300 ASSERT(instantiator_reg == result_reg);
2301 } 2301 }
2302 2302
2303 2303
2304 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary( 2304 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary(
2305 bool opt) const { 2305 bool opt) const {
2306 const intptr_t kNumInputs = 1; 2306 const intptr_t kNumInputs = 1;
2307 const intptr_t kNumTemps = 0; 2307 const intptr_t kNumTemps = 0;
2308 LocationSummary* locs = 2308 LocationSummary* locs =
2309 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 2309 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
2310 locs->set_in(0, Location::RegisterLocation(R0)); 2310 locs->set_in(0, Location::RegisterLocation(R0));
2311 locs->set_out(Location::RegisterLocation(R0)); 2311 locs->set_out(0, Location::RegisterLocation(R0));
2312 return locs; 2312 return locs;
2313 } 2313 }
2314 2314
2315 2315
2316 void InstantiateTypeArgumentsInstr::EmitNativeCode( 2316 void InstantiateTypeArgumentsInstr::EmitNativeCode(
2317 FlowGraphCompiler* compiler) { 2317 FlowGraphCompiler* compiler) {
2318 Register instantiator_reg = locs()->in(0).reg(); 2318 Register instantiator_reg = locs()->in(0).reg();
2319 Register result_reg = locs()->out().reg(); 2319 Register result_reg = locs()->out(0).reg();
2320 ASSERT(instantiator_reg == R0); 2320 ASSERT(instantiator_reg == R0);
2321 ASSERT(instantiator_reg == result_reg); 2321 ASSERT(instantiator_reg == result_reg);
2322 2322
2323 // 'instantiator_reg' is the instantiator TypeArguments object (or null). 2323 // 'instantiator_reg' is the instantiator TypeArguments object (or null).
2324 ASSERT(!type_arguments().IsUninstantiatedIdentity() && 2324 ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
2325 !type_arguments().CanShareInstantiatorTypeArguments( 2325 !type_arguments().CanShareInstantiatorTypeArguments(
2326 instantiator_class())); 2326 instantiator_class()));
2327 // If the instantiator is null and if the type argument vector 2327 // If the instantiator is null and if the type argument vector
2328 // instantiated from null becomes a vector of dynamic, then use null as 2328 // instantiated from null becomes a vector of dynamic, then use null as
2329 // the type arguments. 2329 // the type arguments.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2369 __ Bind(&type_arguments_instantiated); 2369 __ Bind(&type_arguments_instantiated);
2370 } 2370 }
2371 2371
2372 2372
2373 LocationSummary* AllocateContextInstr::MakeLocationSummary(bool opt) const { 2373 LocationSummary* AllocateContextInstr::MakeLocationSummary(bool opt) const {
2374 const intptr_t kNumInputs = 0; 2374 const intptr_t kNumInputs = 0;
2375 const intptr_t kNumTemps = 1; 2375 const intptr_t kNumTemps = 1;
2376 LocationSummary* locs = 2376 LocationSummary* locs =
2377 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 2377 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
2378 locs->set_temp(0, Location::RegisterLocation(R1)); 2378 locs->set_temp(0, Location::RegisterLocation(R1));
2379 locs->set_out(Location::RegisterLocation(R0)); 2379 locs->set_out(0, Location::RegisterLocation(R0));
2380 return locs; 2380 return locs;
2381 } 2381 }
2382 2382
2383 2383
2384 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2384 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2385 ASSERT(locs()->temp(0).reg() == R1); 2385 ASSERT(locs()->temp(0).reg() == R1);
2386 ASSERT(locs()->out().reg() == R0); 2386 ASSERT(locs()->out(0).reg() == R0);
2387 2387
2388 __ LoadImmediate(R1, num_context_variables()); 2388 __ LoadImmediate(R1, num_context_variables());
2389 const ExternalLabel label("alloc_context", 2389 const ExternalLabel label("alloc_context",
2390 StubCode::AllocateContextEntryPoint()); 2390 StubCode::AllocateContextEntryPoint());
2391 compiler->GenerateCall(token_pos(), 2391 compiler->GenerateCall(token_pos(),
2392 &label, 2392 &label,
2393 PcDescriptors::kOther, 2393 PcDescriptors::kOther,
2394 locs()); 2394 locs());
2395 } 2395 }
2396 2396
2397 2397
2398 LocationSummary* CloneContextInstr::MakeLocationSummary(bool opt) const { 2398 LocationSummary* CloneContextInstr::MakeLocationSummary(bool opt) const {
2399 const intptr_t kNumInputs = 1; 2399 const intptr_t kNumInputs = 1;
2400 const intptr_t kNumTemps = 0; 2400 const intptr_t kNumTemps = 0;
2401 LocationSummary* locs = 2401 LocationSummary* locs =
2402 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 2402 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
2403 locs->set_in(0, Location::RegisterLocation(R0)); 2403 locs->set_in(0, Location::RegisterLocation(R0));
2404 locs->set_out(Location::RegisterLocation(R0)); 2404 locs->set_out(0, Location::RegisterLocation(R0));
2405 return locs; 2405 return locs;
2406 } 2406 }
2407 2407
2408 2408
2409 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2409 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2410 Register context_value = locs()->in(0).reg(); 2410 Register context_value = locs()->in(0).reg();
2411 Register result = locs()->out().reg(); 2411 Register result = locs()->out(0).reg();
2412 2412
2413 __ PushObject(Object::ZoneHandle()); // Make room for the result. 2413 __ PushObject(Object::ZoneHandle()); // Make room for the result.
2414 __ Push(context_value); 2414 __ Push(context_value);
2415 compiler->GenerateRuntimeCall(token_pos(), 2415 compiler->GenerateRuntimeCall(token_pos(),
2416 deopt_id(), 2416 deopt_id(),
2417 kCloneContextRuntimeEntry, 2417 kCloneContextRuntimeEntry,
2418 1, 2418 1,
2419 locs()); 2419 locs());
2420 __ Drop(1); // Remove argument. 2420 __ Drop(1); // Remove argument.
2421 __ Pop(result); // Get result (cloned context). 2421 __ Pop(result); // Get result (cloned context).
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
2529 } 2529 }
2530 __ Bind(slow_path->exit_label()); 2530 __ Bind(slow_path->exit_label());
2531 } 2531 }
2532 2532
2533 2533
2534 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, 2534 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler,
2535 BinarySmiOpInstr* shift_left) { 2535 BinarySmiOpInstr* shift_left) {
2536 const bool is_truncating = shift_left->is_truncating(); 2536 const bool is_truncating = shift_left->is_truncating();
2537 const LocationSummary& locs = *shift_left->locs(); 2537 const LocationSummary& locs = *shift_left->locs();
2538 Register left = locs.in(0).reg(); 2538 Register left = locs.in(0).reg();
2539 Register result = locs.out().reg(); 2539 Register result = locs.out(0).reg();
2540 Label* deopt = shift_left->CanDeoptimize() ? 2540 Label* deopt = shift_left->CanDeoptimize() ?
2541 compiler->AddDeoptStub(shift_left->deopt_id(), kDeoptBinarySmiOp) : NULL; 2541 compiler->AddDeoptStub(shift_left->deopt_id(), kDeoptBinarySmiOp) : NULL;
2542 if (locs.in(1).IsConstant()) { 2542 if (locs.in(1).IsConstant()) {
2543 const Object& constant = locs.in(1).constant(); 2543 const Object& constant = locs.in(1).constant();
2544 ASSERT(constant.IsSmi()); 2544 ASSERT(constant.IsSmi());
2545 // Immediate shift operation takes 5 bits for the count. 2545 // Immediate shift operation takes 5 bits for the count.
2546 const intptr_t kCountLimit = 0x1F; 2546 const intptr_t kCountLimit = 0x1F;
2547 const intptr_t value = Smi::Cast(constant).Value(); 2547 const intptr_t value = Smi::Cast(constant).Value();
2548 if (value == 0) { 2548 if (value == 0) {
2549 __ MoveRegister(result, left); 2549 __ MoveRegister(result, left);
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
2651 summary->set_in(0, Location::RequiresRegister()); 2651 summary->set_in(0, Location::RequiresRegister());
2652 if (RightIsPowerOfTwoConstant()) { 2652 if (RightIsPowerOfTwoConstant()) {
2653 ConstantInstr* right_constant = right()->definition()->AsConstant(); 2653 ConstantInstr* right_constant = right()->definition()->AsConstant();
2654 summary->set_in(1, Location::Constant(right_constant->value())); 2654 summary->set_in(1, Location::Constant(right_constant->value()));
2655 summary->AddTemp(Location::RequiresRegister()); 2655 summary->AddTemp(Location::RequiresRegister());
2656 } else { 2656 } else {
2657 summary->set_in(1, Location::RequiresRegister()); 2657 summary->set_in(1, Location::RequiresRegister());
2658 summary->AddTemp(Location::RequiresRegister()); 2658 summary->AddTemp(Location::RequiresRegister());
2659 summary->AddTemp(Location::RequiresFpuRegister()); 2659 summary->AddTemp(Location::RequiresFpuRegister());
2660 } 2660 }
2661 summary->set_out(Location::RequiresRegister()); 2661 summary->set_out(0, Location::RequiresRegister());
2662 return summary; 2662 return summary;
2663 } 2663 }
2664 if (op_kind() == Token::kMOD) { 2664 if (op_kind() == Token::kMOD) {
2665 summary->set_in(0, Location::RequiresRegister()); 2665 summary->set_in(0, Location::RequiresRegister());
2666 summary->set_in(1, Location::RequiresRegister()); 2666 summary->set_in(1, Location::RequiresRegister());
2667 summary->AddTemp(Location::RequiresRegister()); 2667 summary->AddTemp(Location::RequiresRegister());
2668 summary->AddTemp(Location::RequiresFpuRegister()); 2668 summary->AddTemp(Location::RequiresFpuRegister());
2669 summary->set_out(Location::RequiresRegister()); 2669 summary->set_out(0, Location::RequiresRegister());
2670 return summary; 2670 return summary;
2671 } 2671 }
2672 summary->set_in(0, Location::RequiresRegister()); 2672 summary->set_in(0, Location::RequiresRegister());
2673 summary->set_in(1, Location::RegisterOrSmiConstant(right())); 2673 summary->set_in(1, Location::RegisterOrSmiConstant(right()));
2674 if (((op_kind() == Token::kSHL) && !is_truncating()) || 2674 if (((op_kind() == Token::kSHL) && !is_truncating()) ||
2675 (op_kind() == Token::kSHR)) { 2675 (op_kind() == Token::kSHR)) {
2676 summary->AddTemp(Location::RequiresRegister()); 2676 summary->AddTemp(Location::RequiresRegister());
2677 } 2677 }
2678 // We make use of 3-operand instructions by not requiring result register 2678 // We make use of 3-operand instructions by not requiring result register
2679 // to be identical to first input register as on Intel. 2679 // to be identical to first input register as on Intel.
2680 summary->set_out(Location::RequiresRegister()); 2680 summary->set_out(0, Location::RequiresRegister());
2681 return summary; 2681 return summary;
2682 } 2682 }
2683 2683
2684 2684
2685 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2685 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2686 if (op_kind() == Token::kSHL) { 2686 if (op_kind() == Token::kSHL) {
2687 EmitSmiShiftLeft(compiler, this); 2687 EmitSmiShiftLeft(compiler, this);
2688 return; 2688 return;
2689 } 2689 }
2690 2690
2691 ASSERT(!is_truncating()); 2691 ASSERT(!is_truncating());
2692 Register left = locs()->in(0).reg(); 2692 Register left = locs()->in(0).reg();
2693 Register result = locs()->out().reg(); 2693 Register result = locs()->out(0).reg();
2694 Label* deopt = NULL; 2694 Label* deopt = NULL;
2695 if (CanDeoptimize()) { 2695 if (CanDeoptimize()) {
2696 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); 2696 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp);
2697 } 2697 }
2698 2698
2699 if (locs()->in(1).IsConstant()) { 2699 if (locs()->in(1).IsConstant()) {
2700 const Object& constant = locs()->in(1).constant(); 2700 const Object& constant = locs()->in(1).constant();
2701 ASSERT(constant.IsSmi()); 2701 ASSERT(constant.IsSmi());
2702 int32_t imm = reinterpret_cast<int32_t>(constant.raw()); 2702 int32_t imm = reinterpret_cast<int32_t>(constant.raw());
2703 switch (op_kind()) { 2703 switch (op_kind()) {
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
3007 3007
3008 LocationSummary* BoxDoubleInstr::MakeLocationSummary(bool opt) const { 3008 LocationSummary* BoxDoubleInstr::MakeLocationSummary(bool opt) const {
3009 const intptr_t kNumInputs = 1; 3009 const intptr_t kNumInputs = 1;
3010 const intptr_t kNumTemps = 1; 3010 const intptr_t kNumTemps = 1;
3011 LocationSummary* summary = 3011 LocationSummary* summary =
3012 new LocationSummary(kNumInputs, 3012 new LocationSummary(kNumInputs,
3013 kNumTemps, 3013 kNumTemps,
3014 LocationSummary::kCallOnSlowPath); 3014 LocationSummary::kCallOnSlowPath);
3015 summary->set_in(0, Location::RequiresFpuRegister()); 3015 summary->set_in(0, Location::RequiresFpuRegister());
3016 summary->set_temp(0, Location::RequiresRegister()); 3016 summary->set_temp(0, Location::RequiresRegister());
3017 summary->set_out(Location::RequiresRegister()); 3017 summary->set_out(0, Location::RequiresRegister());
3018 return summary; 3018 return summary;
3019 } 3019 }
3020 3020
3021 3021
3022 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3022 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3023 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); 3023 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this);
3024 compiler->AddSlowPathCode(slow_path); 3024 compiler->AddSlowPathCode(slow_path);
3025 3025
3026 const Register out_reg = locs()->out().reg(); 3026 const Register out_reg = locs()->out(0).reg();
3027 const DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); 3027 const DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg());
3028 3028
3029 __ TryAllocate(compiler->double_class(), 3029 __ TryAllocate(compiler->double_class(),
3030 slow_path->entry_label(), 3030 slow_path->entry_label(),
3031 out_reg, 3031 out_reg,
3032 locs()->temp(0).reg()); 3032 locs()->temp(0).reg());
3033 __ Bind(slow_path->exit_label()); 3033 __ Bind(slow_path->exit_label());
3034 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); 3034 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag);
3035 } 3035 }
3036 3036
3037 3037
3038 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(bool opt) const { 3038 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(bool opt) const {
3039 const intptr_t kNumInputs = 1; 3039 const intptr_t kNumInputs = 1;
3040 const intptr_t value_cid = value()->Type()->ToCid(); 3040 const intptr_t value_cid = value()->Type()->ToCid();
3041 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kDoubleCid)); 3041 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kDoubleCid));
3042 const bool needs_writable_input = (value_cid == kSmiCid); 3042 const bool needs_writable_input = (value_cid == kSmiCid);
3043 const intptr_t kNumTemps = needs_temp ? 1 : 0; 3043 const intptr_t kNumTemps = needs_temp ? 1 : 0;
3044 LocationSummary* summary = 3044 LocationSummary* summary =
3045 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3045 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3046 summary->set_in(0, needs_writable_input 3046 summary->set_in(0, needs_writable_input
3047 ? Location::WritableRegister() 3047 ? Location::WritableRegister()
3048 : Location::RequiresRegister()); 3048 : Location::RequiresRegister());
3049 if (needs_temp) summary->set_temp(0, Location::RequiresRegister()); 3049 if (needs_temp) summary->set_temp(0, Location::RequiresRegister());
3050 summary->set_out(Location::RequiresFpuRegister()); 3050 summary->set_out(0, Location::RequiresFpuRegister());
3051 return summary; 3051 return summary;
3052 } 3052 }
3053 3053
3054 3054
3055 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3055 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3056 const intptr_t value_cid = value()->Type()->ToCid(); 3056 const intptr_t value_cid = value()->Type()->ToCid();
3057 const Register value = locs()->in(0).reg(); 3057 const Register value = locs()->in(0).reg();
3058 const DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); 3058 const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg());
3059 3059
3060 if (value_cid == kDoubleCid) { 3060 if (value_cid == kDoubleCid) {
3061 __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag); 3061 __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag);
3062 } else if (value_cid == kSmiCid) { 3062 } else if (value_cid == kSmiCid) {
3063 __ SmiUntag(value); // Untag input before conversion. 3063 __ SmiUntag(value); // Untag input before conversion.
3064 __ vmovsr(STMP, value); 3064 __ vmovsr(STMP, value);
3065 __ vcvtdi(result, STMP); 3065 __ vcvtdi(result, STMP);
3066 } else { 3066 } else {
3067 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); 3067 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp);
3068 Register temp = locs()->temp(0).reg(); 3068 Register temp = locs()->temp(0).reg();
(...skipping 16 matching lines...) Expand all
3085 3085
3086 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(bool opt) const { 3086 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(bool opt) const {
3087 const intptr_t kNumInputs = 1; 3087 const intptr_t kNumInputs = 1;
3088 const intptr_t kNumTemps = 1; 3088 const intptr_t kNumTemps = 1;
3089 LocationSummary* summary = 3089 LocationSummary* summary =
3090 new LocationSummary(kNumInputs, 3090 new LocationSummary(kNumInputs,
3091 kNumTemps, 3091 kNumTemps,
3092 LocationSummary::kCallOnSlowPath); 3092 LocationSummary::kCallOnSlowPath);
3093 summary->set_in(0, Location::RequiresFpuRegister()); 3093 summary->set_in(0, Location::RequiresFpuRegister());
3094 summary->set_temp(0, Location::RequiresRegister()); 3094 summary->set_temp(0, Location::RequiresRegister());
3095 summary->set_out(Location::RequiresRegister()); 3095 summary->set_out(0, Location::RequiresRegister());
3096 return summary; 3096 return summary;
3097 } 3097 }
3098 3098
3099 3099
3100 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3100 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3101 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); 3101 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this);
3102 compiler->AddSlowPathCode(slow_path); 3102 compiler->AddSlowPathCode(slow_path);
3103 3103
3104 Register out_reg = locs()->out().reg(); 3104 Register out_reg = locs()->out(0).reg();
3105 QRegister value = locs()->in(0).fpu_reg(); 3105 QRegister value = locs()->in(0).fpu_reg();
3106 DRegister value_even = EvenDRegisterOf(value); 3106 DRegister value_even = EvenDRegisterOf(value);
3107 DRegister value_odd = OddDRegisterOf(value); 3107 DRegister value_odd = OddDRegisterOf(value);
3108 3108
3109 __ TryAllocate(compiler->float32x4_class(), 3109 __ TryAllocate(compiler->float32x4_class(),
3110 slow_path->entry_label(), 3110 slow_path->entry_label(),
3111 out_reg, 3111 out_reg,
3112 locs()->temp(0).reg()); 3112 locs()->temp(0).reg());
3113 __ Bind(slow_path->exit_label()); 3113 __ Bind(slow_path->exit_label());
3114 3114
3115 __ StoreDToOffset(value_even, out_reg, 3115 __ StoreDToOffset(value_even, out_reg,
3116 Float32x4::value_offset() - kHeapObjectTag); 3116 Float32x4::value_offset() - kHeapObjectTag);
3117 __ StoreDToOffset(value_odd, out_reg, 3117 __ StoreDToOffset(value_odd, out_reg,
3118 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); 3118 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag);
3119 } 3119 }
3120 3120
3121 3121
3122 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(bool opt) const { 3122 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(bool opt) const {
3123 const intptr_t value_cid = value()->Type()->ToCid(); 3123 const intptr_t value_cid = value()->Type()->ToCid();
3124 const intptr_t kNumInputs = 1; 3124 const intptr_t kNumInputs = 1;
3125 const intptr_t kNumTemps = value_cid == kFloat32x4Cid ? 0 : 1; 3125 const intptr_t kNumTemps = value_cid == kFloat32x4Cid ? 0 : 1;
3126 LocationSummary* summary = 3126 LocationSummary* summary =
3127 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3127 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3128 summary->set_in(0, Location::RequiresRegister()); 3128 summary->set_in(0, Location::RequiresRegister());
3129 if (kNumTemps > 0) { 3129 if (kNumTemps > 0) {
3130 ASSERT(kNumTemps == 1); 3130 ASSERT(kNumTemps == 1);
3131 summary->set_temp(0, Location::RequiresRegister()); 3131 summary->set_temp(0, Location::RequiresRegister());
3132 } 3132 }
3133 summary->set_out(Location::RequiresFpuRegister()); 3133 summary->set_out(0, Location::RequiresFpuRegister());
3134 return summary; 3134 return summary;
3135 } 3135 }
3136 3136
3137 3137
3138 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3138 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3139 const intptr_t value_cid = value()->Type()->ToCid(); 3139 const intptr_t value_cid = value()->Type()->ToCid();
3140 const Register value = locs()->in(0).reg(); 3140 const Register value = locs()->in(0).reg();
3141 const QRegister result = locs()->out().fpu_reg(); 3141 const QRegister result = locs()->out(0).fpu_reg();
3142 3142
3143 if (value_cid != kFloat32x4Cid) { 3143 if (value_cid != kFloat32x4Cid) {
3144 const Register temp = locs()->temp(0).reg(); 3144 const Register temp = locs()->temp(0).reg();
3145 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); 3145 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
3146 __ tst(value, ShifterOperand(kSmiTagMask)); 3146 __ tst(value, ShifterOperand(kSmiTagMask));
3147 __ b(deopt, EQ); 3147 __ b(deopt, EQ);
3148 __ CompareClassId(value, kFloat32x4Cid, temp); 3148 __ CompareClassId(value, kFloat32x4Cid, temp);
3149 __ b(deopt, NE); 3149 __ b(deopt, NE);
3150 } 3150 }
3151 3151
3152 const DRegister result_even = EvenDRegisterOf(result); 3152 const DRegister result_even = EvenDRegisterOf(result);
3153 const DRegister result_odd = OddDRegisterOf(result); 3153 const DRegister result_odd = OddDRegisterOf(result);
3154 // TODO(zra): Maybe use vldmd here. 3154 // TODO(zra): Maybe use vldmd here.
3155 __ LoadDFromOffset(result_even, value, 3155 __ LoadDFromOffset(result_even, value,
3156 Float32x4::value_offset() - kHeapObjectTag); 3156 Float32x4::value_offset() - kHeapObjectTag);
3157 __ LoadDFromOffset(result_odd, value, 3157 __ LoadDFromOffset(result_odd, value,
3158 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); 3158 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag);
3159 } 3159 }
3160 3160
3161 3161
3162 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const { 3162 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const {
3163 const intptr_t kNumInputs = 1; 3163 const intptr_t kNumInputs = 1;
3164 const intptr_t kNumTemps = 1; 3164 const intptr_t kNumTemps = 1;
3165 LocationSummary* summary = 3165 LocationSummary* summary =
3166 new LocationSummary(kNumInputs, 3166 new LocationSummary(kNumInputs,
3167 kNumTemps, 3167 kNumTemps,
3168 LocationSummary::kCallOnSlowPath); 3168 LocationSummary::kCallOnSlowPath);
3169 summary->set_in(0, Location::RequiresFpuRegister()); 3169 summary->set_in(0, Location::RequiresFpuRegister());
3170 summary->set_temp(0, Location::RequiresRegister()); 3170 summary->set_temp(0, Location::RequiresRegister());
3171 summary->set_out(Location::RequiresRegister()); 3171 summary->set_out(0, Location::RequiresRegister());
3172 return summary; 3172 return summary;
3173 } 3173 }
3174 3174
3175 3175
3176 void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3176 void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3177 BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); 3177 BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this);
3178 compiler->AddSlowPathCode(slow_path); 3178 compiler->AddSlowPathCode(slow_path);
3179 3179
3180 Register out_reg = locs()->out().reg(); 3180 Register out_reg = locs()->out(0).reg();
3181 QRegister value = locs()->in(0).fpu_reg(); 3181 QRegister value = locs()->in(0).fpu_reg();
3182 DRegister value_even = EvenDRegisterOf(value); 3182 DRegister value_even = EvenDRegisterOf(value);
3183 DRegister value_odd = OddDRegisterOf(value); 3183 DRegister value_odd = OddDRegisterOf(value);
3184 3184
3185 __ TryAllocate(compiler->float64x2_class(), 3185 __ TryAllocate(compiler->float64x2_class(),
3186 slow_path->entry_label(), 3186 slow_path->entry_label(),
3187 out_reg, 3187 out_reg,
3188 locs()->temp(0).reg()); 3188 locs()->temp(0).reg());
3189 __ Bind(slow_path->exit_label()); 3189 __ Bind(slow_path->exit_label());
3190 3190
3191 __ StoreDToOffset(value_even, out_reg, 3191 __ StoreDToOffset(value_even, out_reg,
3192 Float64x2::value_offset() - kHeapObjectTag); 3192 Float64x2::value_offset() - kHeapObjectTag);
3193 __ StoreDToOffset(value_odd, out_reg, 3193 __ StoreDToOffset(value_odd, out_reg,
3194 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag); 3194 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag);
3195 } 3195 }
3196 3196
3197 3197
3198 LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(bool opt) const { 3198 LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(bool opt) const {
3199 const intptr_t value_cid = value()->Type()->ToCid(); 3199 const intptr_t value_cid = value()->Type()->ToCid();
3200 const intptr_t kNumInputs = 1; 3200 const intptr_t kNumInputs = 1;
3201 const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1; 3201 const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1;
3202 LocationSummary* summary = 3202 LocationSummary* summary =
3203 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3203 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3204 summary->set_in(0, Location::RequiresRegister()); 3204 summary->set_in(0, Location::RequiresRegister());
3205 if (kNumTemps > 0) { 3205 if (kNumTemps > 0) {
3206 ASSERT(kNumTemps == 1); 3206 ASSERT(kNumTemps == 1);
3207 summary->set_temp(0, Location::RequiresRegister()); 3207 summary->set_temp(0, Location::RequiresRegister());
3208 } 3208 }
3209 summary->set_out(Location::RequiresFpuRegister()); 3209 summary->set_out(0, Location::RequiresFpuRegister());
3210 return summary; 3210 return summary;
3211 } 3211 }
3212 3212
3213 3213
3214 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3214 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3215 const intptr_t value_cid = value()->Type()->ToCid(); 3215 const intptr_t value_cid = value()->Type()->ToCid();
3216 const Register value = locs()->in(0).reg(); 3216 const Register value = locs()->in(0).reg();
3217 const QRegister result = locs()->out().fpu_reg(); 3217 const QRegister result = locs()->out(0).fpu_reg();
3218 3218
3219 if (value_cid != kFloat64x2Cid) { 3219 if (value_cid != kFloat64x2Cid) {
3220 const Register temp = locs()->temp(0).reg(); 3220 const Register temp = locs()->temp(0).reg();
3221 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); 3221 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
3222 __ tst(value, ShifterOperand(kSmiTagMask)); 3222 __ tst(value, ShifterOperand(kSmiTagMask));
3223 __ b(deopt, EQ); 3223 __ b(deopt, EQ);
3224 __ CompareClassId(value, kFloat64x2Cid, temp); 3224 __ CompareClassId(value, kFloat64x2Cid, temp);
3225 __ b(deopt, NE); 3225 __ b(deopt, NE);
3226 } 3226 }
3227 3227
3228 const DRegister result_even = EvenDRegisterOf(result); 3228 const DRegister result_even = EvenDRegisterOf(result);
3229 const DRegister result_odd = OddDRegisterOf(result); 3229 const DRegister result_odd = OddDRegisterOf(result);
3230 // TODO(zra): Maybe use vldmd here. 3230 // TODO(zra): Maybe use vldmd here.
3231 __ LoadDFromOffset(result_even, value, 3231 __ LoadDFromOffset(result_even, value,
3232 Float64x2::value_offset() - kHeapObjectTag); 3232 Float64x2::value_offset() - kHeapObjectTag);
3233 __ LoadDFromOffset(result_odd, value, 3233 __ LoadDFromOffset(result_odd, value,
3234 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag); 3234 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag);
3235 } 3235 }
3236 3236
3237 3237
3238 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const { 3238 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const {
3239 const intptr_t kNumInputs = 1; 3239 const intptr_t kNumInputs = 1;
3240 const intptr_t kNumTemps = 1; 3240 const intptr_t kNumTemps = 1;
3241 LocationSummary* summary = 3241 LocationSummary* summary =
3242 new LocationSummary(kNumInputs, 3242 new LocationSummary(kNumInputs,
3243 kNumTemps, 3243 kNumTemps,
3244 LocationSummary::kCallOnSlowPath); 3244 LocationSummary::kCallOnSlowPath);
3245 summary->set_in(0, Location::RequiresFpuRegister()); 3245 summary->set_in(0, Location::RequiresFpuRegister());
3246 summary->set_temp(0, Location::RequiresRegister()); 3246 summary->set_temp(0, Location::RequiresRegister());
3247 summary->set_out(Location::RequiresRegister()); 3247 summary->set_out(0, Location::RequiresRegister());
3248 return summary; 3248 return summary;
3249 } 3249 }
3250 3250
3251 3251
3252 class BoxInt32x4SlowPath : public SlowPathCode { 3252 class BoxInt32x4SlowPath : public SlowPathCode {
3253 public: 3253 public:
3254 explicit BoxInt32x4SlowPath(BoxInt32x4Instr* instruction) 3254 explicit BoxInt32x4SlowPath(BoxInt32x4Instr* instruction)
3255 : instruction_(instruction) { } 3255 : instruction_(instruction) { }
3256 3256
3257 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 3257 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
3258 __ Comment("BoxInt32x4SlowPath"); 3258 __ Comment("BoxInt32x4SlowPath");
3259 __ Bind(entry_label()); 3259 __ Bind(entry_label());
3260 const Class& int32x4_class = compiler->int32x4_class(); 3260 const Class& int32x4_class = compiler->int32x4_class();
3261 const Code& stub = 3261 const Code& stub =
3262 Code::Handle(StubCode::GetAllocationStubForClass(int32x4_class)); 3262 Code::Handle(StubCode::GetAllocationStubForClass(int32x4_class));
3263 const ExternalLabel label(int32x4_class.ToCString(), stub.EntryPoint()); 3263 const ExternalLabel label(int32x4_class.ToCString(), stub.EntryPoint());
3264 3264
3265 LocationSummary* locs = instruction_->locs(); 3265 LocationSummary* locs = instruction_->locs();
3266 locs->live_registers()->Remove(locs->out()); 3266 locs->live_registers()->Remove(locs->out(0));
3267 3267
3268 compiler->SaveLiveRegisters(locs); 3268 compiler->SaveLiveRegisters(locs);
3269 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 3269 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
3270 &label, 3270 &label,
3271 PcDescriptors::kOther, 3271 PcDescriptors::kOther,
3272 locs); 3272 locs);
3273 __ mov(locs->out().reg(), ShifterOperand(R0)); 3273 __ mov(locs->out(0).reg(), ShifterOperand(R0));
3274 compiler->RestoreLiveRegisters(locs); 3274 compiler->RestoreLiveRegisters(locs);
3275 3275
3276 __ b(exit_label()); 3276 __ b(exit_label());
3277 } 3277 }
3278 3278
3279 private: 3279 private:
3280 BoxInt32x4Instr* instruction_; 3280 BoxInt32x4Instr* instruction_;
3281 }; 3281 };
3282 3282
3283 3283
3284 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3284 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3285 BoxInt32x4SlowPath* slow_path = new BoxInt32x4SlowPath(this); 3285 BoxInt32x4SlowPath* slow_path = new BoxInt32x4SlowPath(this);
3286 compiler->AddSlowPathCode(slow_path); 3286 compiler->AddSlowPathCode(slow_path);
3287 3287
3288 Register out_reg = locs()->out().reg(); 3288 Register out_reg = locs()->out(0).reg();
3289 QRegister value = locs()->in(0).fpu_reg(); 3289 QRegister value = locs()->in(0).fpu_reg();
3290 DRegister value_even = EvenDRegisterOf(value); 3290 DRegister value_even = EvenDRegisterOf(value);
3291 DRegister value_odd = OddDRegisterOf(value); 3291 DRegister value_odd = OddDRegisterOf(value);
3292 3292
3293 __ TryAllocate(compiler->int32x4_class(), 3293 __ TryAllocate(compiler->int32x4_class(),
3294 slow_path->entry_label(), 3294 slow_path->entry_label(),
3295 out_reg, 3295 out_reg,
3296 locs()->temp(0).reg()); 3296 locs()->temp(0).reg());
3297 __ Bind(slow_path->exit_label()); 3297 __ Bind(slow_path->exit_label());
3298 __ StoreDToOffset(value_even, out_reg, 3298 __ StoreDToOffset(value_even, out_reg,
3299 Int32x4::value_offset() - kHeapObjectTag); 3299 Int32x4::value_offset() - kHeapObjectTag);
3300 __ StoreDToOffset(value_odd, out_reg, 3300 __ StoreDToOffset(value_odd, out_reg,
3301 Int32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); 3301 Int32x4::value_offset() + 2 * kWordSize - kHeapObjectTag);
3302 } 3302 }
3303 3303
3304 3304
3305 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(bool opt) const { 3305 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(bool opt) const {
3306 const intptr_t value_cid = value()->Type()->ToCid(); 3306 const intptr_t value_cid = value()->Type()->ToCid();
3307 const intptr_t kNumInputs = 1; 3307 const intptr_t kNumInputs = 1;
3308 const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1; 3308 const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1;
3309 LocationSummary* summary = 3309 LocationSummary* summary =
3310 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3310 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3311 summary->set_in(0, Location::RequiresRegister()); 3311 summary->set_in(0, Location::RequiresRegister());
3312 if (kNumTemps > 0) { 3312 if (kNumTemps > 0) {
3313 ASSERT(kNumTemps == 1); 3313 ASSERT(kNumTemps == 1);
3314 summary->set_temp(0, Location::RequiresRegister()); 3314 summary->set_temp(0, Location::RequiresRegister());
3315 } 3315 }
3316 summary->set_out(Location::RequiresFpuRegister()); 3316 summary->set_out(0, Location::RequiresFpuRegister());
3317 return summary; 3317 return summary;
3318 } 3318 }
3319 3319
3320 3320
3321 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3321 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3322 const intptr_t value_cid = value()->Type()->ToCid(); 3322 const intptr_t value_cid = value()->Type()->ToCid();
3323 const Register value = locs()->in(0).reg(); 3323 const Register value = locs()->in(0).reg();
3324 const QRegister result = locs()->out().fpu_reg(); 3324 const QRegister result = locs()->out(0).fpu_reg();
3325 3325
3326 if (value_cid != kInt32x4Cid) { 3326 if (value_cid != kInt32x4Cid) {
3327 const Register temp = locs()->temp(0).reg(); 3327 const Register temp = locs()->temp(0).reg();
3328 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); 3328 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass);
3329 __ tst(value, ShifterOperand(kSmiTagMask)); 3329 __ tst(value, ShifterOperand(kSmiTagMask));
3330 __ b(deopt, EQ); 3330 __ b(deopt, EQ);
3331 __ CompareClassId(value, kInt32x4Cid, temp); 3331 __ CompareClassId(value, kInt32x4Cid, temp);
3332 __ b(deopt, NE); 3332 __ b(deopt, NE);
3333 } 3333 }
3334 3334
3335 const DRegister result_even = EvenDRegisterOf(result); 3335 const DRegister result_even = EvenDRegisterOf(result);
3336 const DRegister result_odd = OddDRegisterOf(result); 3336 const DRegister result_odd = OddDRegisterOf(result);
3337 // TODO(zra): Maybe use vldmd here. 3337 // TODO(zra): Maybe use vldmd here.
3338 __ LoadDFromOffset(result_even, value, 3338 __ LoadDFromOffset(result_even, value,
3339 Int32x4::value_offset() - kHeapObjectTag); 3339 Int32x4::value_offset() - kHeapObjectTag);
3340 __ LoadDFromOffset(result_odd, value, 3340 __ LoadDFromOffset(result_odd, value,
3341 Int32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); 3341 Int32x4::value_offset() + 2 * kWordSize - kHeapObjectTag);
3342 } 3342 }
3343 3343
3344 3344
3345 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(bool opt) const { 3345 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(bool opt) const {
3346 const intptr_t kNumInputs = 2; 3346 const intptr_t kNumInputs = 2;
3347 const intptr_t kNumTemps = 0; 3347 const intptr_t kNumTemps = 0;
3348 LocationSummary* summary = 3348 LocationSummary* summary =
3349 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3349 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3350 summary->set_in(0, Location::RequiresFpuRegister()); 3350 summary->set_in(0, Location::RequiresFpuRegister());
3351 summary->set_in(1, Location::RequiresFpuRegister()); 3351 summary->set_in(1, Location::RequiresFpuRegister());
3352 summary->set_out(Location::RequiresFpuRegister()); 3352 summary->set_out(0, Location::RequiresFpuRegister());
3353 return summary; 3353 return summary;
3354 } 3354 }
3355 3355
3356 3356
3357 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3357 void BinaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3358 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg()); 3358 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg());
3359 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg()); 3359 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg());
3360 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); 3360 DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg());
3361 switch (op_kind()) { 3361 switch (op_kind()) {
3362 case Token::kADD: __ vaddd(result, left, right); break; 3362 case Token::kADD: __ vaddd(result, left, right); break;
3363 case Token::kSUB: __ vsubd(result, left, right); break; 3363 case Token::kSUB: __ vsubd(result, left, right); break;
3364 case Token::kMUL: __ vmuld(result, left, right); break; 3364 case Token::kMUL: __ vmuld(result, left, right); break;
3365 case Token::kDIV: __ vdivd(result, left, right); break; 3365 case Token::kDIV: __ vdivd(result, left, right); break;
3366 default: UNREACHABLE(); 3366 default: UNREACHABLE();
3367 } 3367 }
3368 } 3368 }
3369 3369
3370 3370
3371 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(bool opt) const { 3371 LocationSummary* BinaryFloat32x4OpInstr::MakeLocationSummary(bool opt) const {
3372 const intptr_t kNumInputs = 2; 3372 const intptr_t kNumInputs = 2;
3373 const intptr_t kNumTemps = 0; 3373 const intptr_t kNumTemps = 0;
3374 LocationSummary* summary = 3374 LocationSummary* summary =
3375 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3375 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3376 summary->set_in(0, Location::RequiresFpuRegister()); 3376 summary->set_in(0, Location::RequiresFpuRegister());
3377 summary->set_in(1, Location::RequiresFpuRegister()); 3377 summary->set_in(1, Location::RequiresFpuRegister());
3378 summary->set_out(Location::RequiresFpuRegister()); 3378 summary->set_out(0, Location::RequiresFpuRegister());
3379 return summary; 3379 return summary;
3380 } 3380 }
3381 3381
3382 3382
3383 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3383 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3384 QRegister left = locs()->in(0).fpu_reg(); 3384 QRegister left = locs()->in(0).fpu_reg();
3385 QRegister right = locs()->in(1).fpu_reg(); 3385 QRegister right = locs()->in(1).fpu_reg();
3386 QRegister result = locs()->out().fpu_reg(); 3386 QRegister result = locs()->out(0).fpu_reg();
3387 3387
3388 switch (op_kind()) { 3388 switch (op_kind()) {
3389 case Token::kADD: __ vaddqs(result, left, right); break; 3389 case Token::kADD: __ vaddqs(result, left, right); break;
3390 case Token::kSUB: __ vsubqs(result, left, right); break; 3390 case Token::kSUB: __ vsubqs(result, left, right); break;
3391 case Token::kMUL: __ vmulqs(result, left, right); break; 3391 case Token::kMUL: __ vmulqs(result, left, right); break;
3392 case Token::kDIV: __ Vdivqs(result, left, right); break; 3392 case Token::kDIV: __ Vdivqs(result, left, right); break;
3393 default: UNREACHABLE(); 3393 default: UNREACHABLE();
3394 } 3394 }
3395 } 3395 }
3396 3396
3397 3397
3398 LocationSummary* BinaryFloat64x2OpInstr::MakeLocationSummary(bool opt) const { 3398 LocationSummary* BinaryFloat64x2OpInstr::MakeLocationSummary(bool opt) const {
3399 const intptr_t kNumInputs = 2; 3399 const intptr_t kNumInputs = 2;
3400 const intptr_t kNumTemps = 0; 3400 const intptr_t kNumTemps = 0;
3401 LocationSummary* summary = 3401 LocationSummary* summary =
3402 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3402 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3403 summary->set_in(0, Location::RequiresFpuRegister()); 3403 summary->set_in(0, Location::RequiresFpuRegister());
3404 summary->set_in(1, Location::RequiresFpuRegister()); 3404 summary->set_in(1, Location::RequiresFpuRegister());
3405 summary->set_out(Location::RequiresFpuRegister()); 3405 summary->set_out(0, Location::RequiresFpuRegister());
3406 return summary; 3406 return summary;
3407 } 3407 }
3408 3408
3409 3409
3410 void BinaryFloat64x2OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3410 void BinaryFloat64x2OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3411 QRegister left = locs()->in(0).fpu_reg(); 3411 QRegister left = locs()->in(0).fpu_reg();
3412 QRegister right = locs()->in(1).fpu_reg(); 3412 QRegister right = locs()->in(1).fpu_reg();
3413 QRegister result = locs()->out().fpu_reg(); 3413 QRegister result = locs()->out(0).fpu_reg();
3414 3414
3415 DRegister left0 = EvenDRegisterOf(left); 3415 DRegister left0 = EvenDRegisterOf(left);
3416 DRegister left1 = OddDRegisterOf(left); 3416 DRegister left1 = OddDRegisterOf(left);
3417 3417
3418 DRegister right0 = EvenDRegisterOf(right); 3418 DRegister right0 = EvenDRegisterOf(right);
3419 DRegister right1 = OddDRegisterOf(right); 3419 DRegister right1 = OddDRegisterOf(right);
3420 3420
3421 DRegister result0 = EvenDRegisterOf(result); 3421 DRegister result0 = EvenDRegisterOf(result);
3422 DRegister result1 = OddDRegisterOf(result); 3422 DRegister result1 = OddDRegisterOf(result);
3423 3423
(...skipping 19 matching lines...) Expand all
3443 } 3443 }
3444 3444
3445 3445
3446 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary(bool opt) const { 3446 LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary(bool opt) const {
3447 const intptr_t kNumInputs = 1; 3447 const intptr_t kNumInputs = 1;
3448 const intptr_t kNumTemps = 0; 3448 const intptr_t kNumTemps = 0;
3449 LocationSummary* summary = 3449 LocationSummary* summary =
3450 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3450 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3451 // Low (< Q7) Q registers are needed for the vcvtds and vmovs instructions. 3451 // Low (< Q7) Q registers are needed for the vcvtds and vmovs instructions.
3452 summary->set_in(0, Location::FpuRegisterLocation(Q5)); 3452 summary->set_in(0, Location::FpuRegisterLocation(Q5));
3453 summary->set_out(Location::FpuRegisterLocation(Q6)); 3453 summary->set_out(0, Location::FpuRegisterLocation(Q6));
3454 return summary; 3454 return summary;
3455 } 3455 }
3456 3456
3457 3457
3458 void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3458 void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3459 QRegister value = locs()->in(0).fpu_reg(); 3459 QRegister value = locs()->in(0).fpu_reg();
3460 QRegister result = locs()->out().fpu_reg(); 3460 QRegister result = locs()->out(0).fpu_reg();
3461 DRegister dresult0 = EvenDRegisterOf(result); 3461 DRegister dresult0 = EvenDRegisterOf(result);
3462 DRegister dresult1 = OddDRegisterOf(result); 3462 DRegister dresult1 = OddDRegisterOf(result);
3463 SRegister sresult0 = EvenSRegisterOf(dresult0); 3463 SRegister sresult0 = EvenSRegisterOf(dresult0);
3464 SRegister sresult1 = OddSRegisterOf(dresult0); 3464 SRegister sresult1 = OddSRegisterOf(dresult0);
3465 SRegister sresult2 = EvenSRegisterOf(dresult1); 3465 SRegister sresult2 = EvenSRegisterOf(dresult1);
3466 SRegister sresult3 = OddSRegisterOf(dresult1); 3466 SRegister sresult3 = OddSRegisterOf(dresult1);
3467 3467
3468 DRegister dvalue0 = EvenDRegisterOf(value); 3468 DRegister dvalue0 = EvenDRegisterOf(value);
3469 DRegister dvalue1 = OddDRegisterOf(value); 3469 DRegister dvalue1 = OddDRegisterOf(value);
3470 3470
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
3524 3524
3525 3525
3526 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary(bool opt) const { 3526 LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary(bool opt) const {
3527 const intptr_t kNumInputs = 2; 3527 const intptr_t kNumInputs = 2;
3528 const intptr_t kNumTemps = 0; 3528 const intptr_t kNumTemps = 0;
3529 LocationSummary* summary = 3529 LocationSummary* summary =
3530 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3530 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3531 // Low (< Q7) Q registers are needed for the vcvtds and vmovs instructions. 3531 // Low (< Q7) Q registers are needed for the vcvtds and vmovs instructions.
3532 summary->set_in(0, Location::FpuRegisterLocation(Q4)); 3532 summary->set_in(0, Location::FpuRegisterLocation(Q4));
3533 summary->set_in(1, Location::FpuRegisterLocation(Q5)); 3533 summary->set_in(1, Location::FpuRegisterLocation(Q5));
3534 summary->set_out(Location::FpuRegisterLocation(Q6)); 3534 summary->set_out(0, Location::FpuRegisterLocation(Q6));
3535 return summary; 3535 return summary;
3536 } 3536 }
3537 3537
3538 3538
3539 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3539 void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3540 QRegister left = locs()->in(0).fpu_reg(); 3540 QRegister left = locs()->in(0).fpu_reg();
3541 QRegister right = locs()->in(1).fpu_reg(); 3541 QRegister right = locs()->in(1).fpu_reg();
3542 QRegister result = locs()->out().fpu_reg(); 3542 QRegister result = locs()->out(0).fpu_reg();
3543 3543
3544 DRegister dresult0 = EvenDRegisterOf(result); 3544 DRegister dresult0 = EvenDRegisterOf(result);
3545 DRegister dresult1 = OddDRegisterOf(result); 3545 DRegister dresult1 = OddDRegisterOf(result);
3546 SRegister sresult0 = EvenSRegisterOf(dresult0); 3546 SRegister sresult0 = EvenSRegisterOf(dresult0);
3547 SRegister sresult1 = OddSRegisterOf(dresult0); 3547 SRegister sresult1 = OddSRegisterOf(dresult0);
3548 SRegister sresult2 = EvenSRegisterOf(dresult1); 3548 SRegister sresult2 = EvenSRegisterOf(dresult1);
3549 SRegister sresult3 = OddSRegisterOf(dresult1); 3549 SRegister sresult3 = OddSRegisterOf(dresult1);
3550 3550
3551 DRegister dleft0 = EvenDRegisterOf(left); 3551 DRegister dleft0 = EvenDRegisterOf(left);
3552 DRegister dleft1 = OddDRegisterOf(left); 3552 DRegister dleft1 = OddDRegisterOf(left);
(...skipping 26 matching lines...) Expand all
3579 } 3579 }
3580 3580
3581 3581
3582 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary(bool opt) const { 3582 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary(bool opt) const {
3583 const intptr_t kNumInputs = 1; 3583 const intptr_t kNumInputs = 1;
3584 const intptr_t kNumTemps = 1; 3584 const intptr_t kNumTemps = 1;
3585 LocationSummary* summary = 3585 LocationSummary* summary =
3586 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3586 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3587 summary->set_in(0, Location::FpuRegisterLocation(Q5)); 3587 summary->set_in(0, Location::FpuRegisterLocation(Q5));
3588 summary->set_temp(0, Location::RequiresRegister()); 3588 summary->set_temp(0, Location::RequiresRegister());
3589 summary->set_out(Location::RequiresRegister()); 3589 summary->set_out(0, Location::RequiresRegister());
3590 return summary; 3590 return summary;
3591 } 3591 }
3592 3592
3593 3593
3594 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3594 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3595 QRegister value = locs()->in(0).fpu_reg(); 3595 QRegister value = locs()->in(0).fpu_reg();
3596 DRegister dvalue0 = EvenDRegisterOf(value); 3596 DRegister dvalue0 = EvenDRegisterOf(value);
3597 DRegister dvalue1 = OddDRegisterOf(value); 3597 DRegister dvalue1 = OddDRegisterOf(value);
3598 3598
3599 Register out = locs()->out().reg(); 3599 Register out = locs()->out(0).reg();
3600 Register temp = locs()->temp(0).reg(); 3600 Register temp = locs()->temp(0).reg();
3601 3601
3602 // X lane. 3602 // X lane.
3603 __ vmovrs(out, EvenSRegisterOf(dvalue0)); 3603 __ vmovrs(out, EvenSRegisterOf(dvalue0));
3604 __ Lsr(out, out, 31); 3604 __ Lsr(out, out, 31);
3605 // Y lane. 3605 // Y lane.
3606 __ vmovrs(temp, OddSRegisterOf(dvalue0)); 3606 __ vmovrs(temp, OddSRegisterOf(dvalue0));
3607 __ Lsr(temp, temp, 31); 3607 __ Lsr(temp, temp, 31);
3608 __ orr(out, out, ShifterOperand(temp, LSL, 1)); 3608 __ orr(out, out, ShifterOperand(temp, LSL, 1));
3609 // Z lane. 3609 // Z lane.
(...skipping 13 matching lines...) Expand all
3623 bool opt) const { 3623 bool opt) const {
3624 const intptr_t kNumInputs = 4; 3624 const intptr_t kNumInputs = 4;
3625 const intptr_t kNumTemps = 0; 3625 const intptr_t kNumTemps = 0;
3626 LocationSummary* summary = 3626 LocationSummary* summary =
3627 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3627 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3628 summary->set_in(0, Location::RequiresFpuRegister()); 3628 summary->set_in(0, Location::RequiresFpuRegister());
3629 summary->set_in(1, Location::RequiresFpuRegister()); 3629 summary->set_in(1, Location::RequiresFpuRegister());
3630 summary->set_in(2, Location::RequiresFpuRegister()); 3630 summary->set_in(2, Location::RequiresFpuRegister());
3631 summary->set_in(3, Location::RequiresFpuRegister()); 3631 summary->set_in(3, Location::RequiresFpuRegister());
3632 // Low (< 7) Q registers are needed for the vcvtsd instruction. 3632 // Low (< 7) Q registers are needed for the vcvtsd instruction.
3633 summary->set_out(Location::FpuRegisterLocation(Q6)); 3633 summary->set_out(0, Location::FpuRegisterLocation(Q6));
3634 return summary; 3634 return summary;
3635 } 3635 }
3636 3636
3637 3637
3638 void Float32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3638 void Float32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3639 QRegister q0 = locs()->in(0).fpu_reg(); 3639 QRegister q0 = locs()->in(0).fpu_reg();
3640 QRegister q1 = locs()->in(1).fpu_reg(); 3640 QRegister q1 = locs()->in(1).fpu_reg();
3641 QRegister q2 = locs()->in(2).fpu_reg(); 3641 QRegister q2 = locs()->in(2).fpu_reg();
3642 QRegister q3 = locs()->in(3).fpu_reg(); 3642 QRegister q3 = locs()->in(3).fpu_reg();
3643 QRegister r = locs()->out().fpu_reg(); 3643 QRegister r = locs()->out(0).fpu_reg();
3644 3644
3645 DRegister dr0 = EvenDRegisterOf(r); 3645 DRegister dr0 = EvenDRegisterOf(r);
3646 DRegister dr1 = OddDRegisterOf(r); 3646 DRegister dr1 = OddDRegisterOf(r);
3647 3647
3648 __ vcvtsd(EvenSRegisterOf(dr0), EvenDRegisterOf(q0)); 3648 __ vcvtsd(EvenSRegisterOf(dr0), EvenDRegisterOf(q0));
3649 __ vcvtsd(OddSRegisterOf(dr0), EvenDRegisterOf(q1)); 3649 __ vcvtsd(OddSRegisterOf(dr0), EvenDRegisterOf(q1));
3650 __ vcvtsd(EvenSRegisterOf(dr1), EvenDRegisterOf(q2)); 3650 __ vcvtsd(EvenSRegisterOf(dr1), EvenDRegisterOf(q2));
3651 __ vcvtsd(OddSRegisterOf(dr1), EvenDRegisterOf(q3)); 3651 __ vcvtsd(OddSRegisterOf(dr1), EvenDRegisterOf(q3));
3652 } 3652 }
3653 3653
3654 3654
3655 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary(bool opt) const { 3655 LocationSummary* Float32x4ZeroInstr::MakeLocationSummary(bool opt) const {
3656 const intptr_t kNumInputs = 0; 3656 const intptr_t kNumInputs = 0;
3657 const intptr_t kNumTemps = 0; 3657 const intptr_t kNumTemps = 0;
3658 LocationSummary* summary = 3658 LocationSummary* summary =
3659 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3659 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3660 summary->set_out(Location::RequiresFpuRegister()); 3660 summary->set_out(0, Location::RequiresFpuRegister());
3661 return summary; 3661 return summary;
3662 } 3662 }
3663 3663
3664 3664
3665 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3665 void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3666 QRegister q = locs()->out().fpu_reg(); 3666 QRegister q = locs()->out(0).fpu_reg();
3667 __ veorq(q, q, q); 3667 __ veorq(q, q, q);
3668 } 3668 }
3669 3669
3670 3670
3671 LocationSummary* Float32x4SplatInstr::MakeLocationSummary(bool opt) const { 3671 LocationSummary* Float32x4SplatInstr::MakeLocationSummary(bool opt) const {
3672 const intptr_t kNumInputs = 1; 3672 const intptr_t kNumInputs = 1;
3673 const intptr_t kNumTemps = 0; 3673 const intptr_t kNumTemps = 0;
3674 LocationSummary* summary = 3674 LocationSummary* summary =
3675 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3675 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3676 summary->set_in(0, Location::RequiresFpuRegister()); 3676 summary->set_in(0, Location::RequiresFpuRegister());
3677 summary->set_out(Location::RequiresFpuRegister()); 3677 summary->set_out(0, Location::RequiresFpuRegister());
3678 return summary; 3678 return summary;
3679 } 3679 }
3680 3680
3681 3681
3682 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3682 void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3683 QRegister value = locs()->in(0).fpu_reg(); 3683 QRegister value = locs()->in(0).fpu_reg();
3684 QRegister result = locs()->out().fpu_reg(); 3684 QRegister result = locs()->out(0).fpu_reg();
3685 3685
3686 DRegister dvalue0 = EvenDRegisterOf(value); 3686 DRegister dvalue0 = EvenDRegisterOf(value);
3687 3687
3688 // Convert to Float32. 3688 // Convert to Float32.
3689 __ vcvtsd(STMP, dvalue0); 3689 __ vcvtsd(STMP, dvalue0);
3690 3690
3691 // Splat across all lanes. 3691 // Splat across all lanes.
3692 __ vdup(kWord, result, DTMP, 0); 3692 __ vdup(kWord, result, DTMP, 0);
3693 } 3693 }
3694 3694
3695 3695
3696 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary(bool opt) const { 3696 LocationSummary* Float32x4ComparisonInstr::MakeLocationSummary(bool opt) const {
3697 const intptr_t kNumInputs = 2; 3697 const intptr_t kNumInputs = 2;
3698 const intptr_t kNumTemps = 0; 3698 const intptr_t kNumTemps = 0;
3699 LocationSummary* summary = 3699 LocationSummary* summary =
3700 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3700 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3701 summary->set_in(0, Location::RequiresFpuRegister()); 3701 summary->set_in(0, Location::RequiresFpuRegister());
3702 summary->set_in(1, Location::RequiresFpuRegister()); 3702 summary->set_in(1, Location::RequiresFpuRegister());
3703 summary->set_out(Location::RequiresFpuRegister()); 3703 summary->set_out(0, Location::RequiresFpuRegister());
3704 return summary; 3704 return summary;
3705 } 3705 }
3706 3706
3707 3707
3708 void Float32x4ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3708 void Float32x4ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3709 QRegister left = locs()->in(0).fpu_reg(); 3709 QRegister left = locs()->in(0).fpu_reg();
3710 QRegister right = locs()->in(1).fpu_reg(); 3710 QRegister right = locs()->in(1).fpu_reg();
3711 QRegister result = locs()->out().fpu_reg(); 3711 QRegister result = locs()->out(0).fpu_reg();
3712 3712
3713 switch (op_kind()) { 3713 switch (op_kind()) {
3714 case MethodRecognizer::kFloat32x4Equal: 3714 case MethodRecognizer::kFloat32x4Equal:
3715 __ vceqqs(result, left, right); 3715 __ vceqqs(result, left, right);
3716 break; 3716 break;
3717 case MethodRecognizer::kFloat32x4NotEqual: 3717 case MethodRecognizer::kFloat32x4NotEqual:
3718 __ vceqqs(result, left, right); 3718 __ vceqqs(result, left, right);
3719 // Invert the result. 3719 // Invert the result.
3720 __ veorq(QTMP, QTMP, QTMP); // QTMP <- 0. 3720 __ veorq(QTMP, QTMP, QTMP); // QTMP <- 0.
3721 __ vornq(result, QTMP, result); // result <- ~result. 3721 __ vornq(result, QTMP, result); // result <- ~result.
(...skipping 16 matching lines...) Expand all
3738 } 3738 }
3739 3739
3740 3740
3741 LocationSummary* Float32x4MinMaxInstr::MakeLocationSummary(bool opt) const { 3741 LocationSummary* Float32x4MinMaxInstr::MakeLocationSummary(bool opt) const {
3742 const intptr_t kNumInputs = 2; 3742 const intptr_t kNumInputs = 2;
3743 const intptr_t kNumTemps = 0; 3743 const intptr_t kNumTemps = 0;
3744 LocationSummary* summary = 3744 LocationSummary* summary =
3745 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3745 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3746 summary->set_in(0, Location::RequiresFpuRegister()); 3746 summary->set_in(0, Location::RequiresFpuRegister());
3747 summary->set_in(1, Location::RequiresFpuRegister()); 3747 summary->set_in(1, Location::RequiresFpuRegister());
3748 summary->set_out(Location::RequiresFpuRegister()); 3748 summary->set_out(0, Location::RequiresFpuRegister());
3749 return summary; 3749 return summary;
3750 } 3750 }
3751 3751
3752 3752
3753 void Float32x4MinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3753 void Float32x4MinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3754 QRegister left = locs()->in(0).fpu_reg(); 3754 QRegister left = locs()->in(0).fpu_reg();
3755 QRegister right = locs()->in(1).fpu_reg(); 3755 QRegister right = locs()->in(1).fpu_reg();
3756 QRegister result = locs()->out().fpu_reg(); 3756 QRegister result = locs()->out(0).fpu_reg();
3757 3757
3758 switch (op_kind()) { 3758 switch (op_kind()) {
3759 case MethodRecognizer::kFloat32x4Min: 3759 case MethodRecognizer::kFloat32x4Min:
3760 __ vminqs(result, left, right); 3760 __ vminqs(result, left, right);
3761 break; 3761 break;
3762 case MethodRecognizer::kFloat32x4Max: 3762 case MethodRecognizer::kFloat32x4Max:
3763 __ vmaxqs(result, left, right); 3763 __ vmaxqs(result, left, right);
3764 break; 3764 break;
3765 default: UNREACHABLE(); 3765 default: UNREACHABLE();
3766 } 3766 }
3767 } 3767 }
3768 3768
3769 3769
3770 LocationSummary* Float32x4SqrtInstr::MakeLocationSummary(bool opt) const { 3770 LocationSummary* Float32x4SqrtInstr::MakeLocationSummary(bool opt) const {
3771 const intptr_t kNumInputs = 1; 3771 const intptr_t kNumInputs = 1;
3772 const intptr_t kNumTemps = 1; 3772 const intptr_t kNumTemps = 1;
3773 LocationSummary* summary = 3773 LocationSummary* summary =
3774 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3774 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3775 summary->set_in(0, Location::RequiresFpuRegister()); 3775 summary->set_in(0, Location::RequiresFpuRegister());
3776 summary->set_out(Location::RequiresFpuRegister()); 3776 summary->set_out(0, Location::RequiresFpuRegister());
3777 summary->set_temp(0, Location::RequiresFpuRegister()); 3777 summary->set_temp(0, Location::RequiresFpuRegister());
3778 return summary; 3778 return summary;
3779 } 3779 }
3780 3780
3781 3781
3782 void Float32x4SqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3782 void Float32x4SqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3783 QRegister left = locs()->in(0).fpu_reg(); 3783 QRegister left = locs()->in(0).fpu_reg();
3784 QRegister result = locs()->out().fpu_reg(); 3784 QRegister result = locs()->out(0).fpu_reg();
3785 QRegister temp = locs()->temp(0).fpu_reg(); 3785 QRegister temp = locs()->temp(0).fpu_reg();
3786 3786
3787 switch (op_kind()) { 3787 switch (op_kind()) {
3788 case MethodRecognizer::kFloat32x4Sqrt: 3788 case MethodRecognizer::kFloat32x4Sqrt:
3789 __ Vsqrtqs(result, left, temp); 3789 __ Vsqrtqs(result, left, temp);
3790 break; 3790 break;
3791 case MethodRecognizer::kFloat32x4Reciprocal: 3791 case MethodRecognizer::kFloat32x4Reciprocal:
3792 __ Vreciprocalqs(result, left); 3792 __ Vreciprocalqs(result, left);
3793 break; 3793 break;
3794 case MethodRecognizer::kFloat32x4ReciprocalSqrt: 3794 case MethodRecognizer::kFloat32x4ReciprocalSqrt:
3795 __ VreciprocalSqrtqs(result, left); 3795 __ VreciprocalSqrtqs(result, left);
3796 break; 3796 break;
3797 default: UNREACHABLE(); 3797 default: UNREACHABLE();
3798 } 3798 }
3799 } 3799 }
3800 3800
3801 3801
3802 LocationSummary* Float32x4ScaleInstr::MakeLocationSummary(bool opt) const { 3802 LocationSummary* Float32x4ScaleInstr::MakeLocationSummary(bool opt) const {
3803 const intptr_t kNumInputs = 2; 3803 const intptr_t kNumInputs = 2;
3804 const intptr_t kNumTemps = 0; 3804 const intptr_t kNumTemps = 0;
3805 LocationSummary* summary = 3805 LocationSummary* summary =
3806 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3806 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3807 summary->set_in(0, Location::RequiresFpuRegister()); 3807 summary->set_in(0, Location::RequiresFpuRegister());
3808 summary->set_in(1, Location::RequiresFpuRegister()); 3808 summary->set_in(1, Location::RequiresFpuRegister());
3809 summary->set_out(Location::RequiresFpuRegister()); 3809 summary->set_out(0, Location::RequiresFpuRegister());
3810 return summary; 3810 return summary;
3811 } 3811 }
3812 3812
3813 3813
3814 void Float32x4ScaleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3814 void Float32x4ScaleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3815 QRegister left = locs()->in(0).fpu_reg(); 3815 QRegister left = locs()->in(0).fpu_reg();
3816 QRegister right = locs()->in(1).fpu_reg(); 3816 QRegister right = locs()->in(1).fpu_reg();
3817 QRegister result = locs()->out().fpu_reg(); 3817 QRegister result = locs()->out(0).fpu_reg();
3818 3818
3819 switch (op_kind()) { 3819 switch (op_kind()) {
3820 case MethodRecognizer::kFloat32x4Scale: 3820 case MethodRecognizer::kFloat32x4Scale:
3821 __ vcvtsd(STMP, EvenDRegisterOf(left)); 3821 __ vcvtsd(STMP, EvenDRegisterOf(left));
3822 __ vdup(kWord, result, DTMP, 0); 3822 __ vdup(kWord, result, DTMP, 0);
3823 __ vmulqs(result, result, right); 3823 __ vmulqs(result, result, right);
3824 break; 3824 break;
3825 default: UNREACHABLE(); 3825 default: UNREACHABLE();
3826 } 3826 }
3827 } 3827 }
3828 3828
3829 3829
3830 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary(bool opt) const { 3830 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary(bool opt) const {
3831 const intptr_t kNumInputs = 1; 3831 const intptr_t kNumInputs = 1;
3832 const intptr_t kNumTemps = 0; 3832 const intptr_t kNumTemps = 0;
3833 LocationSummary* summary = 3833 LocationSummary* summary =
3834 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3834 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3835 summary->set_in(0, Location::RequiresFpuRegister()); 3835 summary->set_in(0, Location::RequiresFpuRegister());
3836 summary->set_out(Location::RequiresFpuRegister()); 3836 summary->set_out(0, Location::RequiresFpuRegister());
3837 return summary; 3837 return summary;
3838 } 3838 }
3839 3839
3840 3840
3841 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3841 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3842 QRegister left = locs()->in(0).fpu_reg(); 3842 QRegister left = locs()->in(0).fpu_reg();
3843 QRegister result = locs()->out().fpu_reg(); 3843 QRegister result = locs()->out(0).fpu_reg();
3844 3844
3845 switch (op_kind()) { 3845 switch (op_kind()) {
3846 case MethodRecognizer::kFloat32x4Negate: 3846 case MethodRecognizer::kFloat32x4Negate:
3847 __ vnegqs(result, left); 3847 __ vnegqs(result, left);
3848 break; 3848 break;
3849 case MethodRecognizer::kFloat32x4Absolute: 3849 case MethodRecognizer::kFloat32x4Absolute:
3850 __ vabsqs(result, left); 3850 __ vabsqs(result, left);
3851 break; 3851 break;
3852 default: UNREACHABLE(); 3852 default: UNREACHABLE();
3853 } 3853 }
3854 } 3854 }
3855 3855
3856 3856
3857 LocationSummary* Float32x4ClampInstr::MakeLocationSummary(bool opt) const { 3857 LocationSummary* Float32x4ClampInstr::MakeLocationSummary(bool opt) const {
3858 const intptr_t kNumInputs = 3; 3858 const intptr_t kNumInputs = 3;
3859 const intptr_t kNumTemps = 0; 3859 const intptr_t kNumTemps = 0;
3860 LocationSummary* summary = 3860 LocationSummary* summary =
3861 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3861 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3862 summary->set_in(0, Location::RequiresFpuRegister()); 3862 summary->set_in(0, Location::RequiresFpuRegister());
3863 summary->set_in(1, Location::RequiresFpuRegister()); 3863 summary->set_in(1, Location::RequiresFpuRegister());
3864 summary->set_in(2, Location::RequiresFpuRegister()); 3864 summary->set_in(2, Location::RequiresFpuRegister());
3865 summary->set_out(Location::RequiresFpuRegister()); 3865 summary->set_out(0, Location::RequiresFpuRegister());
3866 return summary; 3866 return summary;
3867 } 3867 }
3868 3868
3869 3869
3870 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3870 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3871 QRegister left = locs()->in(0).fpu_reg(); 3871 QRegister left = locs()->in(0).fpu_reg();
3872 QRegister lower = locs()->in(1).fpu_reg(); 3872 QRegister lower = locs()->in(1).fpu_reg();
3873 QRegister upper = locs()->in(2).fpu_reg(); 3873 QRegister upper = locs()->in(2).fpu_reg();
3874 QRegister result = locs()->out().fpu_reg(); 3874 QRegister result = locs()->out(0).fpu_reg();
3875 __ vminqs(result, left, upper); 3875 __ vminqs(result, left, upper);
3876 __ vmaxqs(result, result, lower); 3876 __ vmaxqs(result, result, lower);
3877 } 3877 }
3878 3878
3879 3879
3880 LocationSummary* Float32x4WithInstr::MakeLocationSummary(bool opt) const { 3880 LocationSummary* Float32x4WithInstr::MakeLocationSummary(bool opt) const {
3881 const intptr_t kNumInputs = 2; 3881 const intptr_t kNumInputs = 2;
3882 const intptr_t kNumTemps = 0; 3882 const intptr_t kNumTemps = 0;
3883 LocationSummary* summary = 3883 LocationSummary* summary =
3884 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3884 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3885 summary->set_in(0, Location::RequiresFpuRegister()); 3885 summary->set_in(0, Location::RequiresFpuRegister());
3886 summary->set_in(1, Location::RequiresFpuRegister()); 3886 summary->set_in(1, Location::RequiresFpuRegister());
3887 // Low (< 7) Q registers are needed for the vmovs instruction. 3887 // Low (< 7) Q registers are needed for the vmovs instruction.
3888 summary->set_out(Location::FpuRegisterLocation(Q6)); 3888 summary->set_out(0, Location::FpuRegisterLocation(Q6));
3889 return summary; 3889 return summary;
3890 } 3890 }
3891 3891
3892 3892
3893 void Float32x4WithInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3893 void Float32x4WithInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3894 QRegister replacement = locs()->in(0).fpu_reg(); 3894 QRegister replacement = locs()->in(0).fpu_reg();
3895 QRegister value = locs()->in(1).fpu_reg(); 3895 QRegister value = locs()->in(1).fpu_reg();
3896 QRegister result = locs()->out().fpu_reg(); 3896 QRegister result = locs()->out(0).fpu_reg();
3897 3897
3898 DRegister dresult0 = EvenDRegisterOf(result); 3898 DRegister dresult0 = EvenDRegisterOf(result);
3899 DRegister dresult1 = OddDRegisterOf(result); 3899 DRegister dresult1 = OddDRegisterOf(result);
3900 SRegister sresult0 = EvenSRegisterOf(dresult0); 3900 SRegister sresult0 = EvenSRegisterOf(dresult0);
3901 SRegister sresult1 = OddSRegisterOf(dresult0); 3901 SRegister sresult1 = OddSRegisterOf(dresult0);
3902 SRegister sresult2 = EvenSRegisterOf(dresult1); 3902 SRegister sresult2 = EvenSRegisterOf(dresult1);
3903 SRegister sresult3 = OddSRegisterOf(dresult1); 3903 SRegister sresult3 = OddSRegisterOf(dresult1);
3904 3904
3905 __ vcvtsd(STMP, EvenDRegisterOf(replacement)); 3905 __ vcvtsd(STMP, EvenDRegisterOf(replacement));
3906 if (result != value) { 3906 if (result != value) {
(...skipping 17 matching lines...) Expand all
3924 } 3924 }
3925 } 3925 }
3926 3926
3927 3927
3928 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary(bool opt) const { 3928 LocationSummary* Float32x4ToInt32x4Instr::MakeLocationSummary(bool opt) const {
3929 const intptr_t kNumInputs = 1; 3929 const intptr_t kNumInputs = 1;
3930 const intptr_t kNumTemps = 0; 3930 const intptr_t kNumTemps = 0;
3931 LocationSummary* summary = 3931 LocationSummary* summary =
3932 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3932 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3933 summary->set_in(0, Location::RequiresFpuRegister()); 3933 summary->set_in(0, Location::RequiresFpuRegister());
3934 summary->set_out(Location::RequiresFpuRegister()); 3934 summary->set_out(0, Location::RequiresFpuRegister());
3935 return summary; 3935 return summary;
3936 } 3936 }
3937 3937
3938 3938
3939 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3939 void Float32x4ToInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3940 QRegister value = locs()->in(0).fpu_reg(); 3940 QRegister value = locs()->in(0).fpu_reg();
3941 QRegister result = locs()->out().fpu_reg(); 3941 QRegister result = locs()->out(0).fpu_reg();
3942 3942
3943 if (value != result) { 3943 if (value != result) {
3944 __ vmovq(result, value); 3944 __ vmovq(result, value);
3945 } 3945 }
3946 } 3946 }
3947 3947
3948 3948
3949 LocationSummary* Simd64x2ShuffleInstr::MakeLocationSummary(bool opt) const { 3949 LocationSummary* Simd64x2ShuffleInstr::MakeLocationSummary(bool opt) const {
3950 const intptr_t kNumInputs = 1; 3950 const intptr_t kNumInputs = 1;
3951 const intptr_t kNumTemps = 0; 3951 const intptr_t kNumTemps = 0;
3952 LocationSummary* summary = 3952 LocationSummary* summary =
3953 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3953 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3954 summary->set_in(0, Location::RequiresFpuRegister()); 3954 summary->set_in(0, Location::RequiresFpuRegister());
3955 summary->set_out(Location::RequiresFpuRegister()); 3955 summary->set_out(0, Location::RequiresFpuRegister());
3956 return summary; 3956 return summary;
3957 } 3957 }
3958 3958
3959 3959
3960 void Simd64x2ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3960 void Simd64x2ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3961 QRegister value = locs()->in(0).fpu_reg(); 3961 QRegister value = locs()->in(0).fpu_reg();
3962 3962
3963 DRegister dvalue0 = EvenDRegisterOf(value); 3963 DRegister dvalue0 = EvenDRegisterOf(value);
3964 DRegister dvalue1 = OddDRegisterOf(value); 3964 DRegister dvalue1 = OddDRegisterOf(value);
3965 3965
3966 QRegister result = locs()->out().fpu_reg(); 3966 QRegister result = locs()->out(0).fpu_reg();
3967 3967
3968 DRegister dresult0 = EvenDRegisterOf(result); 3968 DRegister dresult0 = EvenDRegisterOf(result);
3969 3969
3970 switch (op_kind()) { 3970 switch (op_kind()) {
3971 case MethodRecognizer::kFloat64x2GetX: 3971 case MethodRecognizer::kFloat64x2GetX:
3972 __ vmovd(dresult0, dvalue0); 3972 __ vmovd(dresult0, dvalue0);
3973 break; 3973 break;
3974 case MethodRecognizer::kFloat64x2GetY: 3974 case MethodRecognizer::kFloat64x2GetY:
3975 __ vmovd(dresult0, dvalue1); 3975 __ vmovd(dresult0, dvalue1);
3976 break; 3976 break;
3977 default: UNREACHABLE(); 3977 default: UNREACHABLE();
3978 } 3978 }
3979 } 3979 }
3980 3980
3981 3981
3982 LocationSummary* Float64x2ZeroInstr::MakeLocationSummary(bool opt) const { 3982 LocationSummary* Float64x2ZeroInstr::MakeLocationSummary(bool opt) const {
3983 const intptr_t kNumInputs = 0; 3983 const intptr_t kNumInputs = 0;
3984 const intptr_t kNumTemps = 0; 3984 const intptr_t kNumTemps = 0;
3985 LocationSummary* summary = 3985 LocationSummary* summary =
3986 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3986 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3987 summary->set_out(Location::RequiresFpuRegister()); 3987 summary->set_out(0, Location::RequiresFpuRegister());
3988 return summary; 3988 return summary;
3989 } 3989 }
3990 3990
3991 3991
3992 void Float64x2ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3992 void Float64x2ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3993 QRegister q = locs()->out().fpu_reg(); 3993 QRegister q = locs()->out(0).fpu_reg();
3994 __ veorq(q, q, q); 3994 __ veorq(q, q, q);
3995 } 3995 }
3996 3996
3997 3997
3998 LocationSummary* Float64x2SplatInstr::MakeLocationSummary(bool opt) const { 3998 LocationSummary* Float64x2SplatInstr::MakeLocationSummary(bool opt) const {
3999 const intptr_t kNumInputs = 1; 3999 const intptr_t kNumInputs = 1;
4000 const intptr_t kNumTemps = 0; 4000 const intptr_t kNumTemps = 0;
4001 LocationSummary* summary = 4001 LocationSummary* summary =
4002 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4002 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4003 summary->set_in(0, Location::RequiresFpuRegister()); 4003 summary->set_in(0, Location::RequiresFpuRegister());
4004 summary->set_out(Location::RequiresFpuRegister()); 4004 summary->set_out(0, Location::RequiresFpuRegister());
4005 return summary; 4005 return summary;
4006 } 4006 }
4007 4007
4008 4008
4009 void Float64x2SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4009 void Float64x2SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4010 QRegister value = locs()->in(0).fpu_reg(); 4010 QRegister value = locs()->in(0).fpu_reg();
4011 4011
4012 DRegister dvalue = EvenDRegisterOf(value); 4012 DRegister dvalue = EvenDRegisterOf(value);
4013 4013
4014 QRegister result = locs()->out().fpu_reg(); 4014 QRegister result = locs()->out(0).fpu_reg();
4015 4015
4016 DRegister dresult0 = EvenDRegisterOf(result); 4016 DRegister dresult0 = EvenDRegisterOf(result);
4017 DRegister dresult1 = OddDRegisterOf(result); 4017 DRegister dresult1 = OddDRegisterOf(result);
4018 4018
4019 // Splat across all lanes. 4019 // Splat across all lanes.
4020 __ vmovd(dresult0, dvalue); 4020 __ vmovd(dresult0, dvalue);
4021 __ vmovd(dresult1, dvalue); 4021 __ vmovd(dresult1, dvalue);
4022 } 4022 }
4023 4023
4024 4024
4025 LocationSummary* Float64x2ConstructorInstr::MakeLocationSummary( 4025 LocationSummary* Float64x2ConstructorInstr::MakeLocationSummary(
4026 bool opt) const { 4026 bool opt) const {
4027 const intptr_t kNumInputs = 2; 4027 const intptr_t kNumInputs = 2;
4028 const intptr_t kNumTemps = 0; 4028 const intptr_t kNumTemps = 0;
4029 LocationSummary* summary = 4029 LocationSummary* summary =
4030 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4030 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4031 summary->set_in(0, Location::RequiresFpuRegister()); 4031 summary->set_in(0, Location::RequiresFpuRegister());
4032 summary->set_in(1, Location::RequiresFpuRegister()); 4032 summary->set_in(1, Location::RequiresFpuRegister());
4033 summary->set_out(Location::RequiresFpuRegister()); 4033 summary->set_out(0, Location::RequiresFpuRegister());
4034 return summary; 4034 return summary;
4035 } 4035 }
4036 4036
4037 4037
4038 void Float64x2ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4038 void Float64x2ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4039 QRegister q0 = locs()->in(0).fpu_reg(); 4039 QRegister q0 = locs()->in(0).fpu_reg();
4040 QRegister q1 = locs()->in(1).fpu_reg(); 4040 QRegister q1 = locs()->in(1).fpu_reg();
4041 QRegister r = locs()->out().fpu_reg(); 4041 QRegister r = locs()->out(0).fpu_reg();
4042 4042
4043 DRegister d0 = EvenDRegisterOf(q0); 4043 DRegister d0 = EvenDRegisterOf(q0);
4044 DRegister d1 = EvenDRegisterOf(q1); 4044 DRegister d1 = EvenDRegisterOf(q1);
4045 4045
4046 DRegister dr0 = EvenDRegisterOf(r); 4046 DRegister dr0 = EvenDRegisterOf(r);
4047 DRegister dr1 = OddDRegisterOf(r); 4047 DRegister dr1 = OddDRegisterOf(r);
4048 4048
4049 __ vmovd(dr0, d0); 4049 __ vmovd(dr0, d0);
4050 __ vmovd(dr1, d1); 4050 __ vmovd(dr1, d1);
4051 } 4051 }
4052 4052
4053 4053
4054 LocationSummary* Float64x2ToFloat32x4Instr::MakeLocationSummary( 4054 LocationSummary* Float64x2ToFloat32x4Instr::MakeLocationSummary(
4055 bool opt) const { 4055 bool opt) const {
4056 const intptr_t kNumInputs = 1; 4056 const intptr_t kNumInputs = 1;
4057 const intptr_t kNumTemps = 0; 4057 const intptr_t kNumTemps = 0;
4058 LocationSummary* summary = 4058 LocationSummary* summary =
4059 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4059 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4060 summary->set_in(0, Location::RequiresFpuRegister()); 4060 summary->set_in(0, Location::RequiresFpuRegister());
4061 // Low (< 7) Q registers are needed for the vcvtsd instruction. 4061 // Low (< 7) Q registers are needed for the vcvtsd instruction.
4062 summary->set_out(Location::FpuRegisterLocation(Q6)); 4062 summary->set_out(0, Location::FpuRegisterLocation(Q6));
4063 return summary; 4063 return summary;
4064 } 4064 }
4065 4065
4066 4066
4067 void Float64x2ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 4067 void Float64x2ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
4068 QRegister q = locs()->in(0).fpu_reg(); 4068 QRegister q = locs()->in(0).fpu_reg();
4069 QRegister r = locs()->out().fpu_reg(); 4069 QRegister r = locs()->out(0).fpu_reg();
4070 4070
4071 DRegister dq0 = EvenDRegisterOf(q); 4071 DRegister dq0 = EvenDRegisterOf(q);
4072 DRegister dq1 = OddDRegisterOf(q); 4072 DRegister dq1 = OddDRegisterOf(q);
4073 4073
4074 DRegister dr0 = EvenDRegisterOf(r); 4074 DRegister dr0 = EvenDRegisterOf(r);
4075 4075
4076 // Zero register. 4076 // Zero register.
4077 __ veorq(r, r, r); 4077 __ veorq(r, r, r);
4078 // Set X lane. 4078 // Set X lane.
4079 __ vcvtsd(EvenSRegisterOf(dr0), dq0); 4079 __ vcvtsd(EvenSRegisterOf(dr0), dq0);
4080 // Set Y lane. 4080 // Set Y lane.
4081 __ vcvtsd(OddSRegisterOf(dr0), dq1); 4081 __ vcvtsd(OddSRegisterOf(dr0), dq1);
4082 } 4082 }
4083 4083
4084 4084
4085 LocationSummary* Float32x4ToFloat64x2Instr::MakeLocationSummary( 4085 LocationSummary* Float32x4ToFloat64x2Instr::MakeLocationSummary(
4086 bool opt) const { 4086 bool opt) const {
4087 const intptr_t kNumInputs = 1; 4087 const intptr_t kNumInputs = 1;
4088 const intptr_t kNumTemps = 0; 4088 const intptr_t kNumTemps = 0;
4089 LocationSummary* summary = 4089 LocationSummary* summary =
4090 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4090 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4091 summary->set_in(0, Location::RequiresFpuRegister()); 4091 summary->set_in(0, Location::RequiresFpuRegister());
4092 // Low (< 7) Q registers are needed for the vcvtsd instruction. 4092 // Low (< 7) Q registers are needed for the vcvtsd instruction.
4093 summary->set_out(Location::FpuRegisterLocation(Q6)); 4093 summary->set_out(0, Location::FpuRegisterLocation(Q6));
4094 return summary; 4094 return summary;
4095 } 4095 }
4096 4096
4097 4097
4098 void Float32x4ToFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 4098 void Float32x4ToFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
4099 QRegister q = locs()->in(0).fpu_reg(); 4099 QRegister q = locs()->in(0).fpu_reg();
4100 QRegister r = locs()->out().fpu_reg(); 4100 QRegister r = locs()->out(0).fpu_reg();
4101 4101
4102 DRegister dq0 = EvenDRegisterOf(q); 4102 DRegister dq0 = EvenDRegisterOf(q);
4103 4103
4104 DRegister dr0 = EvenDRegisterOf(r); 4104 DRegister dr0 = EvenDRegisterOf(r);
4105 DRegister dr1 = OddDRegisterOf(r); 4105 DRegister dr1 = OddDRegisterOf(r);
4106 4106
4107 // Set X. 4107 // Set X.
4108 __ vcvtds(dr0, EvenSRegisterOf(dq0)); 4108 __ vcvtds(dr0, EvenSRegisterOf(dq0));
4109 // Set Y. 4109 // Set Y.
4110 __ vcvtds(dr1, OddSRegisterOf(dq0)); 4110 __ vcvtds(dr1, OddSRegisterOf(dq0));
4111 } 4111 }
4112 4112
4113 4113
4114 LocationSummary* Float64x2ZeroArgInstr::MakeLocationSummary(bool opt) const { 4114 LocationSummary* Float64x2ZeroArgInstr::MakeLocationSummary(bool opt) const {
4115 const intptr_t kNumInputs = 1; 4115 const intptr_t kNumInputs = 1;
4116 const intptr_t kNumTemps = 0; 4116 const intptr_t kNumTemps = 0;
4117 LocationSummary* summary = 4117 LocationSummary* summary =
4118 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4118 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4119 4119
4120 if (representation() == kTagged) { 4120 if (representation() == kTagged) {
4121 ASSERT(op_kind() == MethodRecognizer::kFloat64x2GetSignMask); 4121 ASSERT(op_kind() == MethodRecognizer::kFloat64x2GetSignMask);
4122 // Grabbing the S components means we need a low (< 7) Q. 4122 // Grabbing the S components means we need a low (< 7) Q.
4123 summary->set_in(0, Location::FpuRegisterLocation(Q6)); 4123 summary->set_in(0, Location::FpuRegisterLocation(Q6));
4124 summary->set_out(Location::RequiresRegister()); 4124 summary->set_out(0, Location::RequiresRegister());
4125 summary->AddTemp(Location::RequiresRegister()); 4125 summary->AddTemp(Location::RequiresRegister());
4126 } else { 4126 } else {
4127 summary->set_in(0, Location::RequiresFpuRegister()); 4127 summary->set_in(0, Location::RequiresFpuRegister());
4128 summary->set_out(Location::RequiresFpuRegister()); 4128 summary->set_out(0, Location::RequiresFpuRegister());
4129 } 4129 }
4130 return summary; 4130 return summary;
4131 } 4131 }
4132 4132
4133 4133
4134 void Float64x2ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4134 void Float64x2ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4135 QRegister q = locs()->in(0).fpu_reg(); 4135 QRegister q = locs()->in(0).fpu_reg();
4136 4136
4137 if ((op_kind() == MethodRecognizer::kFloat64x2GetSignMask)) { 4137 if ((op_kind() == MethodRecognizer::kFloat64x2GetSignMask)) {
4138 DRegister dvalue0 = EvenDRegisterOf(q); 4138 DRegister dvalue0 = EvenDRegisterOf(q);
4139 DRegister dvalue1 = OddDRegisterOf(q); 4139 DRegister dvalue1 = OddDRegisterOf(q);
4140 4140
4141 Register out = locs()->out().reg(); 4141 Register out = locs()->out(0).reg();
4142 Register temp = locs()->temp(0).reg(); 4142 Register temp = locs()->temp(0).reg();
4143 4143
4144 // Upper 32-bits of X lane. 4144 // Upper 32-bits of X lane.
4145 __ vmovrs(out, OddSRegisterOf(dvalue0)); 4145 __ vmovrs(out, OddSRegisterOf(dvalue0));
4146 __ Lsr(out, out, 31); 4146 __ Lsr(out, out, 31);
4147 // Upper 32-bits of Y lane. 4147 // Upper 32-bits of Y lane.
4148 __ vmovrs(temp, OddSRegisterOf(dvalue1)); 4148 __ vmovrs(temp, OddSRegisterOf(dvalue1));
4149 __ Lsr(temp, temp, 31); 4149 __ Lsr(temp, temp, 31);
4150 __ orr(out, out, ShifterOperand(temp, LSL, 1)); 4150 __ orr(out, out, ShifterOperand(temp, LSL, 1));
4151 // Tag. 4151 // Tag.
4152 __ SmiTag(out); 4152 __ SmiTag(out);
4153 return; 4153 return;
4154 } 4154 }
4155 ASSERT(representation() == kUnboxedFloat64x2); 4155 ASSERT(representation() == kUnboxedFloat64x2);
4156 QRegister r = locs()->out().fpu_reg(); 4156 QRegister r = locs()->out(0).fpu_reg();
4157 4157
4158 DRegister dvalue0 = EvenDRegisterOf(q); 4158 DRegister dvalue0 = EvenDRegisterOf(q);
4159 DRegister dvalue1 = OddDRegisterOf(q); 4159 DRegister dvalue1 = OddDRegisterOf(q);
4160 DRegister dresult0 = EvenDRegisterOf(r); 4160 DRegister dresult0 = EvenDRegisterOf(r);
4161 DRegister dresult1 = OddDRegisterOf(r); 4161 DRegister dresult1 = OddDRegisterOf(r);
4162 4162
4163 switch (op_kind()) { 4163 switch (op_kind()) {
4164 case MethodRecognizer::kFloat64x2Negate: 4164 case MethodRecognizer::kFloat64x2Negate:
4165 __ vnegd(dresult0, dvalue0); 4165 __ vnegd(dresult0, dvalue0);
4166 __ vnegd(dresult1, dvalue1); 4166 __ vnegd(dresult1, dvalue1);
(...skipping 11 matching lines...) Expand all
4178 } 4178 }
4179 4179
4180 4180
4181 LocationSummary* Float64x2OneArgInstr::MakeLocationSummary(bool opt) const { 4181 LocationSummary* Float64x2OneArgInstr::MakeLocationSummary(bool opt) const {
4182 const intptr_t kNumInputs = 2; 4182 const intptr_t kNumInputs = 2;
4183 const intptr_t kNumTemps = 0; 4183 const intptr_t kNumTemps = 0;
4184 LocationSummary* summary = 4184 LocationSummary* summary =
4185 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4185 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4186 summary->set_in(0, Location::RequiresFpuRegister()); 4186 summary->set_in(0, Location::RequiresFpuRegister());
4187 summary->set_in(1, Location::RequiresFpuRegister()); 4187 summary->set_in(1, Location::RequiresFpuRegister());
4188 summary->set_out(Location::SameAsFirstInput()); 4188 summary->set_out(0, Location::SameAsFirstInput());
4189 return summary; 4189 return summary;
4190 } 4190 }
4191 4191
4192 4192
4193 void Float64x2OneArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4193 void Float64x2OneArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4194 QRegister left = locs()->in(0).fpu_reg(); 4194 QRegister left = locs()->in(0).fpu_reg();
4195 DRegister left0 = EvenDRegisterOf(left); 4195 DRegister left0 = EvenDRegisterOf(left);
4196 DRegister left1 = OddDRegisterOf(left); 4196 DRegister left1 = OddDRegisterOf(left);
4197 QRegister right = locs()->in(1).fpu_reg(); 4197 QRegister right = locs()->in(1).fpu_reg();
4198 DRegister right0 = EvenDRegisterOf(right); 4198 DRegister right0 = EvenDRegisterOf(right);
4199 DRegister right1 = OddDRegisterOf(right); 4199 DRegister right1 = OddDRegisterOf(right);
4200 QRegister out = locs()->out().fpu_reg(); 4200 QRegister out = locs()->out(0).fpu_reg();
4201 ASSERT(left == out); 4201 ASSERT(left == out);
4202 4202
4203 switch (op_kind()) { 4203 switch (op_kind()) {
4204 case MethodRecognizer::kFloat64x2Scale: 4204 case MethodRecognizer::kFloat64x2Scale:
4205 __ vmuld(left0, left0, right0); 4205 __ vmuld(left0, left0, right0);
4206 __ vmuld(left1, left1, right0); 4206 __ vmuld(left1, left1, right0);
4207 break; 4207 break;
4208 case MethodRecognizer::kFloat64x2WithX: 4208 case MethodRecognizer::kFloat64x2WithX:
4209 __ vmovd(left0, right0); 4209 __ vmovd(left0, right0);
4210 break; 4210 break;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
4255 const intptr_t kNumInputs = 4; 4255 const intptr_t kNumInputs = 4;
4256 const intptr_t kNumTemps = 1; 4256 const intptr_t kNumTemps = 1;
4257 LocationSummary* summary = 4257 LocationSummary* summary =
4258 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4258 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4259 summary->set_in(0, Location::RequiresRegister()); 4259 summary->set_in(0, Location::RequiresRegister());
4260 summary->set_in(1, Location::RequiresRegister()); 4260 summary->set_in(1, Location::RequiresRegister());
4261 summary->set_in(2, Location::RequiresRegister()); 4261 summary->set_in(2, Location::RequiresRegister());
4262 summary->set_in(3, Location::RequiresRegister()); 4262 summary->set_in(3, Location::RequiresRegister());
4263 summary->set_temp(0, Location::RequiresRegister()); 4263 summary->set_temp(0, Location::RequiresRegister());
4264 // Low (< 7) Q register needed for the vmovsr instruction. 4264 // Low (< 7) Q register needed for the vmovsr instruction.
4265 summary->set_out(Location::FpuRegisterLocation(Q6)); 4265 summary->set_out(0, Location::FpuRegisterLocation(Q6));
4266 return summary; 4266 return summary;
4267 } 4267 }
4268 4268
4269 4269
4270 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4270 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4271 Register v0 = locs()->in(0).reg(); 4271 Register v0 = locs()->in(0).reg();
4272 Register v1 = locs()->in(1).reg(); 4272 Register v1 = locs()->in(1).reg();
4273 Register v2 = locs()->in(2).reg(); 4273 Register v2 = locs()->in(2).reg();
4274 Register v3 = locs()->in(3).reg(); 4274 Register v3 = locs()->in(3).reg();
4275 Register temp = locs()->temp(0).reg(); 4275 Register temp = locs()->temp(0).reg();
4276 QRegister result = locs()->out().fpu_reg(); 4276 QRegister result = locs()->out(0).fpu_reg();
4277 DRegister dresult0 = EvenDRegisterOf(result); 4277 DRegister dresult0 = EvenDRegisterOf(result);
4278 DRegister dresult1 = OddDRegisterOf(result); 4278 DRegister dresult1 = OddDRegisterOf(result);
4279 SRegister sresult0 = EvenSRegisterOf(dresult0); 4279 SRegister sresult0 = EvenSRegisterOf(dresult0);
4280 SRegister sresult1 = OddSRegisterOf(dresult0); 4280 SRegister sresult1 = OddSRegisterOf(dresult0);
4281 SRegister sresult2 = EvenSRegisterOf(dresult1); 4281 SRegister sresult2 = EvenSRegisterOf(dresult1);
4282 SRegister sresult3 = OddSRegisterOf(dresult1); 4282 SRegister sresult3 = OddSRegisterOf(dresult1);
4283 4283
4284 __ veorq(result, result, result); 4284 __ veorq(result, result, result);
4285 __ LoadImmediate(temp, 0xffffffff); 4285 __ LoadImmediate(temp, 0xffffffff);
4286 4286
(...skipping 11 matching lines...) Expand all
4298 } 4298 }
4299 4299
4300 4300
4301 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary(bool opt) const { 4301 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary(bool opt) const {
4302 const intptr_t kNumInputs = 1; 4302 const intptr_t kNumInputs = 1;
4303 const intptr_t kNumTemps = 0; 4303 const intptr_t kNumTemps = 0;
4304 LocationSummary* summary = 4304 LocationSummary* summary =
4305 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4305 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4306 // Low (< 7) Q registers are needed for the vmovrs instruction. 4306 // Low (< 7) Q registers are needed for the vmovrs instruction.
4307 summary->set_in(0, Location::FpuRegisterLocation(Q6)); 4307 summary->set_in(0, Location::FpuRegisterLocation(Q6));
4308 summary->set_out(Location::RequiresRegister()); 4308 summary->set_out(0, Location::RequiresRegister());
4309 return summary; 4309 return summary;
4310 } 4310 }
4311 4311
4312 4312
4313 void Int32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4313 void Int32x4GetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4314 QRegister value = locs()->in(0).fpu_reg(); 4314 QRegister value = locs()->in(0).fpu_reg();
4315 Register result = locs()->out().reg(); 4315 Register result = locs()->out(0).reg();
4316 4316
4317 DRegister dvalue0 = EvenDRegisterOf(value); 4317 DRegister dvalue0 = EvenDRegisterOf(value);
4318 DRegister dvalue1 = OddDRegisterOf(value); 4318 DRegister dvalue1 = OddDRegisterOf(value);
4319 SRegister svalue0 = EvenSRegisterOf(dvalue0); 4319 SRegister svalue0 = EvenSRegisterOf(dvalue0);
4320 SRegister svalue1 = OddSRegisterOf(dvalue0); 4320 SRegister svalue1 = OddSRegisterOf(dvalue0);
4321 SRegister svalue2 = EvenSRegisterOf(dvalue1); 4321 SRegister svalue2 = EvenSRegisterOf(dvalue1);
4322 SRegister svalue3 = OddSRegisterOf(dvalue1); 4322 SRegister svalue3 = OddSRegisterOf(dvalue1);
4323 4323
4324 switch (op_kind()) { 4324 switch (op_kind()) {
4325 case MethodRecognizer::kInt32x4GetFlagX: 4325 case MethodRecognizer::kInt32x4GetFlagX:
(...skipping 19 matching lines...) Expand all
4345 4345
4346 LocationSummary* Int32x4SelectInstr::MakeLocationSummary(bool opt) const { 4346 LocationSummary* Int32x4SelectInstr::MakeLocationSummary(bool opt) const {
4347 const intptr_t kNumInputs = 3; 4347 const intptr_t kNumInputs = 3;
4348 const intptr_t kNumTemps = 1; 4348 const intptr_t kNumTemps = 1;
4349 LocationSummary* summary = 4349 LocationSummary* summary =
4350 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4350 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4351 summary->set_in(0, Location::RequiresFpuRegister()); 4351 summary->set_in(0, Location::RequiresFpuRegister());
4352 summary->set_in(1, Location::RequiresFpuRegister()); 4352 summary->set_in(1, Location::RequiresFpuRegister());
4353 summary->set_in(2, Location::RequiresFpuRegister()); 4353 summary->set_in(2, Location::RequiresFpuRegister());
4354 summary->set_temp(0, Location::RequiresFpuRegister()); 4354 summary->set_temp(0, Location::RequiresFpuRegister());
4355 summary->set_out(Location::RequiresFpuRegister()); 4355 summary->set_out(0, Location::RequiresFpuRegister());
4356 return summary; 4356 return summary;
4357 } 4357 }
4358 4358
4359 4359
4360 void Int32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4360 void Int32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4361 QRegister mask = locs()->in(0).fpu_reg(); 4361 QRegister mask = locs()->in(0).fpu_reg();
4362 QRegister trueValue = locs()->in(1).fpu_reg(); 4362 QRegister trueValue = locs()->in(1).fpu_reg();
4363 QRegister falseValue = locs()->in(2).fpu_reg(); 4363 QRegister falseValue = locs()->in(2).fpu_reg();
4364 QRegister out = locs()->out().fpu_reg(); 4364 QRegister out = locs()->out(0).fpu_reg();
4365 QRegister temp = locs()->temp(0).fpu_reg(); 4365 QRegister temp = locs()->temp(0).fpu_reg();
4366 4366
4367 // Copy mask. 4367 // Copy mask.
4368 __ vmovq(temp, mask); 4368 __ vmovq(temp, mask);
4369 // Invert it. 4369 // Invert it.
4370 __ veorq(QTMP, QTMP, QTMP); // QTMP <- 0. 4370 __ veorq(QTMP, QTMP, QTMP); // QTMP <- 0.
4371 __ vornq(temp, QTMP, temp); // temp <- ~temp. 4371 __ vornq(temp, QTMP, temp); // temp <- ~temp.
4372 // mask = mask & trueValue. 4372 // mask = mask & trueValue.
4373 __ vandq(mask, mask, trueValue); 4373 __ vandq(mask, mask, trueValue);
4374 // temp = temp & falseValue. 4374 // temp = temp & falseValue.
4375 __ vandq(temp, temp, falseValue); 4375 __ vandq(temp, temp, falseValue);
4376 // out = mask | temp. 4376 // out = mask | temp.
4377 __ vorrq(out, mask, temp); 4377 __ vorrq(out, mask, temp);
4378 } 4378 }
4379 4379
4380 4380
4381 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary(bool opt) const { 4381 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary(bool opt) const {
4382 const intptr_t kNumInputs = 2; 4382 const intptr_t kNumInputs = 2;
4383 const intptr_t kNumTemps = 0; 4383 const intptr_t kNumTemps = 0;
4384 LocationSummary* summary = 4384 LocationSummary* summary =
4385 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4385 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4386 summary->set_in(0, Location::RequiresFpuRegister()); 4386 summary->set_in(0, Location::RequiresFpuRegister());
4387 summary->set_in(1, Location::RequiresRegister()); 4387 summary->set_in(1, Location::RequiresRegister());
4388 // Low (< 7) Q register needed for the vmovsr instruction. 4388 // Low (< 7) Q register needed for the vmovsr instruction.
4389 summary->set_out(Location::FpuRegisterLocation(Q6)); 4389 summary->set_out(0, Location::FpuRegisterLocation(Q6));
4390 return summary; 4390 return summary;
4391 } 4391 }
4392 4392
4393 4393
4394 void Int32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4394 void Int32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4395 QRegister mask = locs()->in(0).fpu_reg(); 4395 QRegister mask = locs()->in(0).fpu_reg();
4396 Register flag = locs()->in(1).reg(); 4396 Register flag = locs()->in(1).reg();
4397 QRegister result = locs()->out().fpu_reg(); 4397 QRegister result = locs()->out(0).fpu_reg();
4398 4398
4399 DRegister dresult0 = EvenDRegisterOf(result); 4399 DRegister dresult0 = EvenDRegisterOf(result);
4400 DRegister dresult1 = OddDRegisterOf(result); 4400 DRegister dresult1 = OddDRegisterOf(result);
4401 SRegister sresult0 = EvenSRegisterOf(dresult0); 4401 SRegister sresult0 = EvenSRegisterOf(dresult0);
4402 SRegister sresult1 = OddSRegisterOf(dresult0); 4402 SRegister sresult1 = OddSRegisterOf(dresult0);
4403 SRegister sresult2 = EvenSRegisterOf(dresult1); 4403 SRegister sresult2 = EvenSRegisterOf(dresult1);
4404 SRegister sresult3 = OddSRegisterOf(dresult1); 4404 SRegister sresult3 = OddSRegisterOf(dresult1);
4405 4405
4406 if (result != mask) { 4406 if (result != mask) {
4407 __ vmovq(result, mask); 4407 __ vmovq(result, mask);
(...skipping 19 matching lines...) Expand all
4427 } 4427 }
4428 } 4428 }
4429 4429
4430 4430
4431 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary(bool opt) const { 4431 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary(bool opt) const {
4432 const intptr_t kNumInputs = 1; 4432 const intptr_t kNumInputs = 1;
4433 const intptr_t kNumTemps = 0; 4433 const intptr_t kNumTemps = 0;
4434 LocationSummary* summary = 4434 LocationSummary* summary =
4435 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4435 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4436 summary->set_in(0, Location::RequiresFpuRegister()); 4436 summary->set_in(0, Location::RequiresFpuRegister());
4437 summary->set_out(Location::RequiresFpuRegister()); 4437 summary->set_out(0, Location::RequiresFpuRegister());
4438 return summary; 4438 return summary;
4439 } 4439 }
4440 4440
4441 4441
4442 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 4442 void Int32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
4443 QRegister value = locs()->in(0).fpu_reg(); 4443 QRegister value = locs()->in(0).fpu_reg();
4444 QRegister result = locs()->out().fpu_reg(); 4444 QRegister result = locs()->out(0).fpu_reg();
4445 4445
4446 if (value != result) { 4446 if (value != result) {
4447 __ vmovq(result, value); 4447 __ vmovq(result, value);
4448 } 4448 }
4449 } 4449 }
4450 4450
4451 4451
4452 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary(bool opt) const { 4452 LocationSummary* BinaryInt32x4OpInstr::MakeLocationSummary(bool opt) const {
4453 const intptr_t kNumInputs = 2; 4453 const intptr_t kNumInputs = 2;
4454 const intptr_t kNumTemps = 0; 4454 const intptr_t kNumTemps = 0;
4455 LocationSummary* summary = 4455 LocationSummary* summary =
4456 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4456 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4457 summary->set_in(0, Location::RequiresFpuRegister()); 4457 summary->set_in(0, Location::RequiresFpuRegister());
4458 summary->set_in(1, Location::RequiresFpuRegister()); 4458 summary->set_in(1, Location::RequiresFpuRegister());
4459 summary->set_out(Location::RequiresFpuRegister()); 4459 summary->set_out(0, Location::RequiresFpuRegister());
4460 return summary; 4460 return summary;
4461 } 4461 }
4462 4462
4463 4463
4464 void BinaryInt32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4464 void BinaryInt32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4465 QRegister left = locs()->in(0).fpu_reg(); 4465 QRegister left = locs()->in(0).fpu_reg();
4466 QRegister right = locs()->in(1).fpu_reg(); 4466 QRegister right = locs()->in(1).fpu_reg();
4467 QRegister result = locs()->out().fpu_reg(); 4467 QRegister result = locs()->out(0).fpu_reg();
4468 switch (op_kind()) { 4468 switch (op_kind()) {
4469 case Token::kBIT_AND: { 4469 case Token::kBIT_AND: {
4470 __ vandq(result, left, right); 4470 __ vandq(result, left, right);
4471 break; 4471 break;
4472 } 4472 }
4473 case Token::kBIT_OR: { 4473 case Token::kBIT_OR: {
4474 __ vorrq(result, left, right); 4474 __ vorrq(result, left, right);
4475 break; 4475 break;
4476 } 4476 }
4477 case Token::kBIT_XOR: { 4477 case Token::kBIT_XOR: {
(...skipping 12 matching lines...) Expand all
4490 4490
4491 4491
4492 LocationSummary* MathUnaryInstr::MakeLocationSummary(bool opt) const { 4492 LocationSummary* MathUnaryInstr::MakeLocationSummary(bool opt) const {
4493 if ((kind() == MethodRecognizer::kMathSin) || 4493 if ((kind() == MethodRecognizer::kMathSin) ||
4494 (kind() == MethodRecognizer::kMathCos)) { 4494 (kind() == MethodRecognizer::kMathCos)) {
4495 const intptr_t kNumInputs = 1; 4495 const intptr_t kNumInputs = 1;
4496 const intptr_t kNumTemps = 0; 4496 const intptr_t kNumTemps = 0;
4497 LocationSummary* summary = 4497 LocationSummary* summary =
4498 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 4498 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
4499 summary->set_in(0, Location::FpuRegisterLocation(Q0)); 4499 summary->set_in(0, Location::FpuRegisterLocation(Q0));
4500 summary->set_out(Location::FpuRegisterLocation(Q0)); 4500 summary->set_out(0, Location::FpuRegisterLocation(Q0));
4501 #if !defined(ARM_FLOAT_ABI_HARD) 4501 #if !defined(ARM_FLOAT_ABI_HARD)
4502 summary->AddTemp(Location::RegisterLocation(R0)); 4502 summary->AddTemp(Location::RegisterLocation(R0));
4503 summary->AddTemp(Location::RegisterLocation(R1)); 4503 summary->AddTemp(Location::RegisterLocation(R1));
4504 summary->AddTemp(Location::RegisterLocation(R2)); 4504 summary->AddTemp(Location::RegisterLocation(R2));
4505 summary->AddTemp(Location::RegisterLocation(R3)); 4505 summary->AddTemp(Location::RegisterLocation(R3));
4506 #endif 4506 #endif
4507 return summary; 4507 return summary;
4508 } 4508 }
4509 // Sqrt. 4509 // Sqrt.
4510 const intptr_t kNumInputs = 1; 4510 const intptr_t kNumInputs = 1;
4511 const intptr_t kNumTemps = 0; 4511 const intptr_t kNumTemps = 0;
4512 LocationSummary* summary = 4512 LocationSummary* summary =
4513 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4513 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4514 summary->set_in(0, Location::RequiresFpuRegister()); 4514 summary->set_in(0, Location::RequiresFpuRegister());
4515 summary->set_out(Location::RequiresFpuRegister()); 4515 summary->set_out(0, Location::RequiresFpuRegister());
4516 return summary; 4516 return summary;
4517 } 4517 }
4518 4518
4519 4519
4520 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4520 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4521 if (kind() == MethodRecognizer::kMathSqrt) { 4521 if (kind() == MethodRecognizer::kMathSqrt) {
4522 DRegister val = EvenDRegisterOf(locs()->in(0).fpu_reg()); 4522 DRegister val = EvenDRegisterOf(locs()->in(0).fpu_reg());
4523 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); 4523 DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg());
4524 __ vsqrtd(result, val); 4524 __ vsqrtd(result, val);
4525 } else { 4525 } else {
4526 #if defined(ARM_FLOAT_ABI_HARD) 4526 #if defined(ARM_FLOAT_ABI_HARD)
4527 __ CallRuntime(TargetFunction(), InputCount()); 4527 __ CallRuntime(TargetFunction(), InputCount());
4528 #else 4528 #else
4529 // If we aren't doing "hardfp", then we have to move the double arguments 4529 // If we aren't doing "hardfp", then we have to move the double arguments
4530 // to the integer registers, and take the results from the integer 4530 // to the integer registers, and take the results from the integer
4531 // registers. 4531 // registers.
4532 __ vmovrrd(R0, R1, D0); 4532 __ vmovrrd(R0, R1, D0);
4533 __ vmovrrd(R2, R3, D1); 4533 __ vmovrrd(R2, R3, D1);
4534 __ CallRuntime(TargetFunction(), InputCount()); 4534 __ CallRuntime(TargetFunction(), InputCount());
4535 __ vmovdrr(D0, R0, R1); 4535 __ vmovdrr(D0, R0, R1);
4536 __ vmovdrr(D1, R2, R3); 4536 __ vmovdrr(D1, R2, R3);
4537 #endif 4537 #endif
4538 } 4538 }
4539 } 4539 }
4540 4540
4541 4541
4542 LocationSummary* MathMinMaxInstr::MakeLocationSummary(bool opt) const { 4542 LocationSummary* MathMinMaxInstr::MakeLocationSummary(bool opt) const {
4543 if (result_cid() == kDoubleCid) { 4543 if (result_cid() == kDoubleCid) {
4544 const intptr_t kNumInputs = 2; 4544 const intptr_t kNumInputs = 2;
4545 const intptr_t kNumTemps = 1; 4545 const intptr_t kNumTemps = 1;
4546 LocationSummary* summary = 4546 LocationSummary* summary =
4547 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4547 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4548 summary->set_in(0, Location::RequiresFpuRegister()); 4548 summary->set_in(0, Location::RequiresFpuRegister());
4549 summary->set_in(1, Location::RequiresFpuRegister()); 4549 summary->set_in(1, Location::RequiresFpuRegister());
4550 // Reuse the left register so that code can be made shorter. 4550 // Reuse the left register so that code can be made shorter.
4551 summary->set_out(Location::SameAsFirstInput()); 4551 summary->set_out(0, Location::SameAsFirstInput());
4552 summary->set_temp(0, Location::RequiresRegister()); 4552 summary->set_temp(0, Location::RequiresRegister());
4553 return summary; 4553 return summary;
4554 } 4554 }
4555 ASSERT(result_cid() == kSmiCid); 4555 ASSERT(result_cid() == kSmiCid);
4556 const intptr_t kNumInputs = 2; 4556 const intptr_t kNumInputs = 2;
4557 const intptr_t kNumTemps = 0; 4557 const intptr_t kNumTemps = 0;
4558 LocationSummary* summary = 4558 LocationSummary* summary =
4559 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4559 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4560 summary->set_in(0, Location::RequiresRegister()); 4560 summary->set_in(0, Location::RequiresRegister());
4561 summary->set_in(1, Location::RequiresRegister()); 4561 summary->set_in(1, Location::RequiresRegister());
4562 // Reuse the left register so that code can be made shorter. 4562 // Reuse the left register so that code can be made shorter.
4563 summary->set_out(Location::SameAsFirstInput()); 4563 summary->set_out(0, Location::SameAsFirstInput());
4564 return summary; 4564 return summary;
4565 } 4565 }
4566 4566
4567 4567
4568 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4568 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4569 ASSERT((op_kind() == MethodRecognizer::kMathMin) || 4569 ASSERT((op_kind() == MethodRecognizer::kMathMin) ||
4570 (op_kind() == MethodRecognizer::kMathMax)); 4570 (op_kind() == MethodRecognizer::kMathMax));
4571 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin); 4571 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin);
4572 if (result_cid() == kDoubleCid) { 4572 if (result_cid() == kDoubleCid) {
4573 Label done, returns_nan, are_equal; 4573 Label done, returns_nan, are_equal;
4574 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg()); 4574 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg());
4575 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg()); 4575 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg());
4576 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); 4576 DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg());
4577 Register temp = locs()->temp(0).reg(); 4577 Register temp = locs()->temp(0).reg();
4578 __ vcmpd(left, right); 4578 __ vcmpd(left, right);
4579 __ vmstat(); 4579 __ vmstat();
4580 __ b(&returns_nan, VS); 4580 __ b(&returns_nan, VS);
4581 __ b(&are_equal, EQ); 4581 __ b(&are_equal, EQ);
4582 const Condition neg_double_condition = 4582 const Condition neg_double_condition =
4583 is_min ? TokenKindToDoubleCondition(Token::kGTE) 4583 is_min ? TokenKindToDoubleCondition(Token::kGTE)
4584 : TokenKindToDoubleCondition(Token::kLTE); 4584 : TokenKindToDoubleCondition(Token::kLTE);
4585 ASSERT(left == result); 4585 ASSERT(left == result);
4586 __ vmovd(result, right, neg_double_condition); 4586 __ vmovd(result, right, neg_double_condition);
(...skipping 19 matching lines...) Expand all
4606 __ vmovd(result, right, LT); 4606 __ vmovd(result, right, LT);
4607 ASSERT(left == result); 4607 ASSERT(left == result);
4608 } 4608 }
4609 __ Bind(&done); 4609 __ Bind(&done);
4610 return; 4610 return;
4611 } 4611 }
4612 4612
4613 ASSERT(result_cid() == kSmiCid); 4613 ASSERT(result_cid() == kSmiCid);
4614 Register left = locs()->in(0).reg(); 4614 Register left = locs()->in(0).reg();
4615 Register right = locs()->in(1).reg(); 4615 Register right = locs()->in(1).reg();
4616 Register result = locs()->out().reg(); 4616 Register result = locs()->out(0).reg();
4617 __ cmp(left, ShifterOperand(right)); 4617 __ cmp(left, ShifterOperand(right));
4618 ASSERT(result == left); 4618 ASSERT(result == left);
4619 if (is_min) { 4619 if (is_min) {
4620 __ mov(result, ShifterOperand(right), GT); 4620 __ mov(result, ShifterOperand(right), GT);
4621 } else { 4621 } else {
4622 __ mov(result, ShifterOperand(right), LT); 4622 __ mov(result, ShifterOperand(right), LT);
4623 } 4623 }
4624 } 4624 }
4625 4625
4626 4626
4627 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(bool opt) const { 4627 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(bool opt) const {
4628 const intptr_t kNumInputs = 1; 4628 const intptr_t kNumInputs = 1;
4629 const intptr_t kNumTemps = 0; 4629 const intptr_t kNumTemps = 0;
4630 LocationSummary* summary = 4630 LocationSummary* summary =
4631 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4631 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4632 summary->set_in(0, Location::RequiresRegister()); 4632 summary->set_in(0, Location::RequiresRegister());
4633 // We make use of 3-operand instructions by not requiring result register 4633 // We make use of 3-operand instructions by not requiring result register
4634 // to be identical to first input register as on Intel. 4634 // to be identical to first input register as on Intel.
4635 summary->set_out(Location::RequiresRegister()); 4635 summary->set_out(0, Location::RequiresRegister());
4636 return summary; 4636 return summary;
4637 } 4637 }
4638 4638
4639 4639
4640 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4640 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4641 Register value = locs()->in(0).reg(); 4641 Register value = locs()->in(0).reg();
4642 Register result = locs()->out().reg(); 4642 Register result = locs()->out(0).reg();
4643 switch (op_kind()) { 4643 switch (op_kind()) {
4644 case Token::kNEGATE: { 4644 case Token::kNEGATE: {
4645 Label* deopt = compiler->AddDeoptStub(deopt_id(), 4645 Label* deopt = compiler->AddDeoptStub(deopt_id(),
4646 kDeoptUnaryOp); 4646 kDeoptUnaryOp);
4647 __ rsbs(result, value, ShifterOperand(0)); 4647 __ rsbs(result, value, ShifterOperand(0));
4648 __ b(deopt, VS); 4648 __ b(deopt, VS);
4649 break; 4649 break;
4650 } 4650 }
4651 case Token::kBIT_NOT: 4651 case Token::kBIT_NOT:
4652 __ mvn(result, ShifterOperand(value)); 4652 __ mvn(result, ShifterOperand(value));
4653 // Remove inverted smi-tag. 4653 // Remove inverted smi-tag.
4654 __ bic(result, result, ShifterOperand(kSmiTagMask)); 4654 __ bic(result, result, ShifterOperand(kSmiTagMask));
4655 break; 4655 break;
4656 default: 4656 default:
4657 UNREACHABLE(); 4657 UNREACHABLE();
4658 } 4658 }
4659 } 4659 }
4660 4660
4661 4661
4662 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(bool opt) const { 4662 LocationSummary* UnaryDoubleOpInstr::MakeLocationSummary(bool opt) const {
4663 const intptr_t kNumInputs = 1; 4663 const intptr_t kNumInputs = 1;
4664 const intptr_t kNumTemps = 0; 4664 const intptr_t kNumTemps = 0;
4665 LocationSummary* summary = 4665 LocationSummary* summary =
4666 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4666 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4667 summary->set_in(0, Location::RequiresFpuRegister()); 4667 summary->set_in(0, Location::RequiresFpuRegister());
4668 summary->set_out(Location::RequiresFpuRegister()); 4668 summary->set_out(0, Location::RequiresFpuRegister());
4669 return summary; 4669 return summary;
4670 } 4670 }
4671 4671
4672 4672
4673 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4673 void UnaryDoubleOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4674 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); 4674 DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg());
4675 DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); 4675 DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg());
4676 __ vnegd(result, value); 4676 __ vnegd(result, value);
4677 } 4677 }
4678 4678
4679 4679
4680 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(bool opt) const { 4680 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(bool opt) const {
4681 const intptr_t kNumInputs = 1; 4681 const intptr_t kNumInputs = 1;
4682 const intptr_t kNumTemps = 0; 4682 const intptr_t kNumTemps = 0;
4683 LocationSummary* result = 4683 LocationSummary* result =
4684 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4684 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4685 result->set_in(0, Location::WritableRegister()); 4685 result->set_in(0, Location::WritableRegister());
4686 result->set_out(Location::RequiresFpuRegister()); 4686 result->set_out(0, Location::RequiresFpuRegister());
4687 return result; 4687 return result;
4688 } 4688 }
4689 4689
4690 4690
4691 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4691 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4692 Register value = locs()->in(0).reg(); 4692 Register value = locs()->in(0).reg();
4693 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); 4693 DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg());
4694 __ SmiUntag(value); 4694 __ SmiUntag(value);
4695 __ vmovsr(STMP, value); 4695 __ vmovsr(STMP, value);
4696 __ vcvtdi(result, STMP); 4696 __ vcvtdi(result, STMP);
4697 } 4697 }
4698 4698
4699 4699
4700 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary(bool opt) const { 4700 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary(bool opt) const {
4701 const intptr_t kNumInputs = 1; 4701 const intptr_t kNumInputs = 1;
4702 const intptr_t kNumTemps = 0; 4702 const intptr_t kNumTemps = 0;
4703 LocationSummary* result = 4703 LocationSummary* result =
4704 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 4704 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
4705 result->set_in(0, Location::RegisterLocation(R1)); 4705 result->set_in(0, Location::RegisterLocation(R1));
4706 result->set_out(Location::RegisterLocation(R0)); 4706 result->set_out(0, Location::RegisterLocation(R0));
4707 return result; 4707 return result;
4708 } 4708 }
4709 4709
4710 4710
4711 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4711 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4712 Register result = locs()->out().reg(); 4712 Register result = locs()->out(0).reg();
4713 Register value_obj = locs()->in(0).reg(); 4713 Register value_obj = locs()->in(0).reg();
4714 ASSERT(result == R0); 4714 ASSERT(result == R0);
4715 ASSERT(result != value_obj); 4715 ASSERT(result != value_obj);
4716 __ LoadDFromOffset(DTMP, value_obj, Double::value_offset() - kHeapObjectTag); 4716 __ LoadDFromOffset(DTMP, value_obj, Double::value_offset() - kHeapObjectTag);
4717 4717
4718 Label do_call, done; 4718 Label do_call, done;
4719 // First check for NaN. Checking for minint after the conversion doesn't work 4719 // First check for NaN. Checking for minint after the conversion doesn't work
4720 // on ARM because vcvtid gives 0 for NaN. 4720 // on ARM because vcvtid gives 0 for NaN.
4721 __ vcmpd(DTMP, DTMP); 4721 __ vcmpd(DTMP, DTMP);
4722 __ vmstat(); 4722 __ vmstat();
(...skipping 25 matching lines...) Expand all
4748 __ Bind(&done); 4748 __ Bind(&done);
4749 } 4749 }
4750 4750
4751 4751
4752 LocationSummary* DoubleToSmiInstr::MakeLocationSummary(bool opt) const { 4752 LocationSummary* DoubleToSmiInstr::MakeLocationSummary(bool opt) const {
4753 const intptr_t kNumInputs = 1; 4753 const intptr_t kNumInputs = 1;
4754 const intptr_t kNumTemps = 0; 4754 const intptr_t kNumTemps = 0;
4755 LocationSummary* result = new LocationSummary( 4755 LocationSummary* result = new LocationSummary(
4756 kNumInputs, kNumTemps, LocationSummary::kNoCall); 4756 kNumInputs, kNumTemps, LocationSummary::kNoCall);
4757 result->set_in(0, Location::RequiresFpuRegister()); 4757 result->set_in(0, Location::RequiresFpuRegister());
4758 result->set_out(Location::RequiresRegister()); 4758 result->set_out(0, Location::RequiresRegister());
4759 return result; 4759 return result;
4760 } 4760 }
4761 4761
4762 4762
4763 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4763 void DoubleToSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4764 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi); 4764 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptDoubleToSmi);
4765 Register result = locs()->out().reg(); 4765 Register result = locs()->out(0).reg();
4766 DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); 4766 DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg());
4767 // First check for NaN. Checking for minint after the conversion doesn't work 4767 // First check for NaN. Checking for minint after the conversion doesn't work
4768 // on ARM because vcvtid gives 0 for NaN. 4768 // on ARM because vcvtid gives 0 for NaN.
4769 __ vcmpd(value, value); 4769 __ vcmpd(value, value);
4770 __ vmstat(); 4770 __ vmstat();
4771 __ b(deopt, VS); 4771 __ b(deopt, VS);
4772 4772
4773 __ vcvtid(STMP, value); 4773 __ vcvtid(STMP, value);
4774 __ vmovrs(result, STMP); 4774 __ vmovrs(result, STMP);
4775 // Check for overflow and that it fits into Smi. 4775 // Check for overflow and that it fits into Smi.
(...skipping 14 matching lines...) Expand all
4790 } 4790 }
4791 4791
4792 4792
4793 LocationSummary* DoubleToFloatInstr::MakeLocationSummary(bool opt) const { 4793 LocationSummary* DoubleToFloatInstr::MakeLocationSummary(bool opt) const {
4794 const intptr_t kNumInputs = 1; 4794 const intptr_t kNumInputs = 1;
4795 const intptr_t kNumTemps = 0; 4795 const intptr_t kNumTemps = 0;
4796 LocationSummary* result = 4796 LocationSummary* result =
4797 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4797 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4798 // Low (<= Q7) Q registers are needed for the conversion instructions. 4798 // Low (<= Q7) Q registers are needed for the conversion instructions.
4799 result->set_in(0, Location::RequiresFpuRegister()); 4799 result->set_in(0, Location::RequiresFpuRegister());
4800 result->set_out(Location::FpuRegisterLocation(Q7)); 4800 result->set_out(0, Location::FpuRegisterLocation(Q7));
4801 return result; 4801 return result;
4802 } 4802 }
4803 4803
4804 4804
4805 void DoubleToFloatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4805 void DoubleToFloatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4806 DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg()); 4806 DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg());
4807 SRegister result = EvenSRegisterOf(EvenDRegisterOf(locs()->out().fpu_reg())); 4807 SRegister result = EvenSRegisterOf(EvenDRegisterOf(locs()->out(0).fpu_reg()));
4808 __ vcvtsd(result, value); 4808 __ vcvtsd(result, value);
4809 } 4809 }
4810 4810
4811 4811
4812 LocationSummary* FloatToDoubleInstr::MakeLocationSummary(bool opt) const { 4812 LocationSummary* FloatToDoubleInstr::MakeLocationSummary(bool opt) const {
4813 const intptr_t kNumInputs = 1; 4813 const intptr_t kNumInputs = 1;
4814 const intptr_t kNumTemps = 0; 4814 const intptr_t kNumTemps = 0;
4815 LocationSummary* result = 4815 LocationSummary* result =
4816 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4816 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4817 // Low (<= Q7) Q registers are needed for the conversion instructions. 4817 // Low (<= Q7) Q registers are needed for the conversion instructions.
4818 result->set_in(0, Location::FpuRegisterLocation(Q7)); 4818 result->set_in(0, Location::FpuRegisterLocation(Q7));
4819 result->set_out(Location::RequiresFpuRegister()); 4819 result->set_out(0, Location::RequiresFpuRegister());
4820 return result; 4820 return result;
4821 } 4821 }
4822 4822
4823 4823
4824 void FloatToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4824 void FloatToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4825 SRegister value = EvenSRegisterOf(EvenDRegisterOf(locs()->in(0).fpu_reg())); 4825 SRegister value = EvenSRegisterOf(EvenDRegisterOf(locs()->in(0).fpu_reg()));
4826 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); 4826 DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg());
4827 __ vcvtds(result, value); 4827 __ vcvtds(result, value);
4828 } 4828 }
4829 4829
4830 4830
4831 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const { 4831 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const {
4832 ASSERT((InputCount() == 1) || (InputCount() == 2)); 4832 ASSERT((InputCount() == 1) || (InputCount() == 2));
4833 const intptr_t kNumTemps = 0; 4833 const intptr_t kNumTemps = 0;
4834 LocationSummary* result = 4834 LocationSummary* result =
4835 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); 4835 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall);
4836 result->set_in(0, Location::FpuRegisterLocation(Q0)); 4836 result->set_in(0, Location::FpuRegisterLocation(Q0));
4837 if (InputCount() == 2) { 4837 if (InputCount() == 2) {
4838 result->set_in(1, Location::FpuRegisterLocation(Q1)); 4838 result->set_in(1, Location::FpuRegisterLocation(Q1));
4839 } 4839 }
4840 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { 4840 if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
4841 result->AddTemp(Location::RegisterLocation(R2)); 4841 result->AddTemp(Location::RegisterLocation(R2));
4842 result->AddTemp(Location::FpuRegisterLocation(Q2)); 4842 result->AddTemp(Location::FpuRegisterLocation(Q2));
4843 } 4843 }
4844 #if !defined(ARM_FLOAT_ABI_HARD) 4844 #if !defined(ARM_FLOAT_ABI_HARD)
4845 result->AddTemp(Location::RegisterLocation(R0)); 4845 result->AddTemp(Location::RegisterLocation(R0));
4846 result->AddTemp(Location::RegisterLocation(R1)); 4846 result->AddTemp(Location::RegisterLocation(R1));
4847 // Check if R2 is already added. 4847 // Check if R2 is already added.
4848 if (recognized_kind() != MethodRecognizer::kMathDoublePow) { 4848 if (recognized_kind() != MethodRecognizer::kMathDoublePow) {
4849 result->AddTemp(Location::RegisterLocation(R2)); 4849 result->AddTemp(Location::RegisterLocation(R2));
4850 } 4850 }
4851 result->AddTemp(Location::RegisterLocation(R3)); 4851 result->AddTemp(Location::RegisterLocation(R3));
4852 #endif 4852 #endif
4853 result->set_out(Location::FpuRegisterLocation(Q0)); 4853 result->set_out(0, Location::FpuRegisterLocation(Q0));
4854 return result; 4854 return result;
4855 } 4855 }
4856 4856
4857 4857
4858 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4858 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4859 // For pow-function return NaN if exponent is NaN. 4859 // For pow-function return NaN if exponent is NaN.
4860 Label do_call, skip_call; 4860 Label do_call, skip_call;
4861 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { 4861 if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
4862 // Pseudo code: 4862 // Pseudo code:
4863 // if (exponent == 0.0) return 0.0; 4863 // if (exponent == 0.0) return 0.0;
4864 // if (base == 1.0) return 1.0; 4864 // if (base == 1.0) return 1.0;
4865 // if (base.isNaN || exponent.isNaN) { 4865 // if (base.isNaN || exponent.isNaN) {
4866 // return double.NAN; 4866 // return double.NAN;
4867 // } 4867 // }
4868 DRegister base = EvenDRegisterOf(locs()->in(0).fpu_reg()); 4868 DRegister base = EvenDRegisterOf(locs()->in(0).fpu_reg());
4869 DRegister exp = EvenDRegisterOf(locs()->in(1).fpu_reg()); 4869 DRegister exp = EvenDRegisterOf(locs()->in(1).fpu_reg());
4870 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); 4870 DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg());
4871 Register temp = locs()->temp(0).reg(); 4871 Register temp = locs()->temp(0).reg();
4872 DRegister saved_base = EvenDRegisterOf(locs()->temp(1).fpu_reg()); 4872 DRegister saved_base = EvenDRegisterOf(locs()->temp(1).fpu_reg());
4873 ASSERT((base == result) && (result != saved_base)); 4873 ASSERT((base == result) && (result != saved_base));
4874 Label check_base_is_one; 4874 Label check_base_is_one;
4875 // Check if exponent is 0.0 -> return 1.0; 4875 // Check if exponent is 0.0 -> return 1.0;
4876 __ vmovd(saved_base, base); 4876 __ vmovd(saved_base, base);
4877 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0))); 4877 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0)));
4878 __ LoadDFromOffset(DTMP, temp, Double::value_offset() - kHeapObjectTag); 4878 __ LoadDFromOffset(DTMP, temp, Double::value_offset() - kHeapObjectTag);
4879 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1))); 4879 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1)));
4880 __ LoadDFromOffset(result, temp, Double::value_offset() - kHeapObjectTag); 4880 __ LoadDFromOffset(result, temp, Double::value_offset() - kHeapObjectTag);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
4917 const intptr_t kNumInputs = 2; 4917 const intptr_t kNumInputs = 2;
4918 const intptr_t kNumTemps = 4; 4918 const intptr_t kNumTemps = 4;
4919 LocationSummary* summary = 4919 LocationSummary* summary =
4920 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4920 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4921 summary->set_in(0, Location::RequiresRegister()); 4921 summary->set_in(0, Location::RequiresRegister());
4922 summary->set_in(1, Location::RequiresRegister()); 4922 summary->set_in(1, Location::RequiresRegister());
4923 summary->set_temp(0, Location::RequiresRegister()); 4923 summary->set_temp(0, Location::RequiresRegister());
4924 summary->set_temp(1, Location::RequiresFpuRegister()); 4924 summary->set_temp(1, Location::RequiresFpuRegister());
4925 summary->set_temp(2, Location::RequiresRegister()); // result_div. 4925 summary->set_temp(2, Location::RequiresRegister()); // result_div.
4926 summary->set_temp(3, Location::RequiresRegister()); // result_mod. 4926 summary->set_temp(3, Location::RequiresRegister()); // result_mod.
4927 summary->set_out(Location::RequiresRegister()); 4927 summary->set_out(0, Location::RequiresRegister());
4928 return summary; 4928 return summary;
4929 } 4929 }
4930 UNIMPLEMENTED(); 4930 UNIMPLEMENTED();
4931 return NULL; 4931 return NULL;
4932 } 4932 }
4933 4933
4934 4934
4935 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4935 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4936 Label* deopt = NULL; 4936 Label* deopt = NULL;
4937 if (CanDeoptimize()) { 4937 if (CanDeoptimize()) {
4938 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); 4938 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp);
4939 } 4939 }
4940 if (kind() == MergedMathInstr::kTruncDivMod) { 4940 if (kind() == MergedMathInstr::kTruncDivMod) {
4941 Register left = locs()->in(0).reg(); 4941 Register left = locs()->in(0).reg();
4942 Register right = locs()->in(1).reg(); 4942 Register right = locs()->in(1).reg();
4943 Register result = locs()->out().reg(); 4943 Register result = locs()->out(0).reg();
4944 Range* right_range = InputAt(1)->definition()->range(); 4944 Range* right_range = InputAt(1)->definition()->range();
4945 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { 4945 if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
4946 // Handle divide by zero in runtime. 4946 // Handle divide by zero in runtime.
4947 __ cmp(right, ShifterOperand(0)); 4947 __ cmp(right, ShifterOperand(0));
4948 __ b(deopt, EQ); 4948 __ b(deopt, EQ);
4949 } 4949 }
4950 Register temp = locs()->temp(0).reg(); 4950 Register temp = locs()->temp(0).reg();
4951 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); 4951 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg());
4952 Register result_div = locs()->temp(2).reg(); 4952 Register result_div = locs()->temp(2).reg();
4953 Register result_mod = locs()->temp(3).reg(); 4953 Register result_mod = locs()->temp(3).reg();
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
5041 deopt, 5041 deopt,
5042 deopt_id(), 5042 deopt_id(),
5043 instance_call()->token_pos(), 5043 instance_call()->token_pos(),
5044 locs()); 5044 locs());
5045 } 5045 }
5046 5046
5047 5047
5048 LocationSummary* BranchInstr::MakeLocationSummary(bool opt) const { 5048 LocationSummary* BranchInstr::MakeLocationSummary(bool opt) const {
5049 comparison()->InitializeLocationSummary(opt); 5049 comparison()->InitializeLocationSummary(opt);
5050 // Branches don't produce a result. 5050 // Branches don't produce a result.
5051 comparison()->locs()->set_out(Location::NoLocation()); 5051 comparison()->locs()->set_out(0, Location::NoLocation());
5052 return comparison()->locs(); 5052 return comparison()->locs();
5053 } 5053 }
5054 5054
5055 5055
5056 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5056 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5057 comparison()->EmitBranchCode(compiler, this); 5057 comparison()->EmitBranchCode(compiler, this);
5058 } 5058 }
5059 5059
5060 5060
5061 LocationSummary* CheckClassInstr::MakeLocationSummary(bool opt) const { 5061 LocationSummary* CheckClassInstr::MakeLocationSummary(bool opt) const {
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
5325 5325
5326 5326
5327 LocationSummary* CurrentContextInstr::MakeLocationSummary(bool opt) const { 5327 LocationSummary* CurrentContextInstr::MakeLocationSummary(bool opt) const {
5328 return LocationSummary::Make(0, 5328 return LocationSummary::Make(0,
5329 Location::RequiresRegister(), 5329 Location::RequiresRegister(),
5330 LocationSummary::kNoCall); 5330 LocationSummary::kNoCall);
5331 } 5331 }
5332 5332
5333 5333
5334 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5334 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5335 __ mov(locs()->out().reg(), ShifterOperand(CTX)); 5335 __ mov(locs()->out(0).reg(), ShifterOperand(CTX));
5336 } 5336 }
5337 5337
5338 5338
5339 LocationSummary* StrictCompareInstr::MakeLocationSummary(bool opt) const { 5339 LocationSummary* StrictCompareInstr::MakeLocationSummary(bool opt) const {
5340 const intptr_t kNumInputs = 2; 5340 const intptr_t kNumInputs = 2;
5341 const intptr_t kNumTemps = 0; 5341 const intptr_t kNumTemps = 0;
5342 if (needs_number_check()) { 5342 if (needs_number_check()) {
5343 LocationSummary* locs = 5343 LocationSummary* locs =
5344 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 5344 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
5345 locs->set_in(0, Location::RegisterLocation(R0)); 5345 locs->set_in(0, Location::RegisterLocation(R0));
5346 locs->set_in(1, Location::RegisterLocation(R1)); 5346 locs->set_in(1, Location::RegisterLocation(R1));
5347 locs->set_out(Location::RegisterLocation(R0)); 5347 locs->set_out(0, Location::RegisterLocation(R0));
5348 return locs; 5348 return locs;
5349 } 5349 }
5350 LocationSummary* locs = 5350 LocationSummary* locs =
5351 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 5351 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
5352 locs->set_in(0, Location::RegisterOrConstant(left())); 5352 locs->set_in(0, Location::RegisterOrConstant(left()));
5353 // Only one of the inputs can be a constant. Choose register if the first one 5353 // Only one of the inputs can be a constant. Choose register if the first one
5354 // is a constant. 5354 // is a constant.
5355 locs->set_in(1, locs->in(0).IsConstant() 5355 locs->set_in(1, locs->in(0).IsConstant()
5356 ? Location::RequiresRegister() 5356 ? Location::RequiresRegister()
5357 : Location::RegisterOrConstant(right())); 5357 : Location::RegisterOrConstant(right()));
5358 locs->set_out(Location::RequiresRegister()); 5358 locs->set_out(0, Location::RequiresRegister());
5359 return locs; 5359 return locs;
5360 } 5360 }
5361 5361
5362 5362
5363 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 5363 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
5364 BranchLabels labels) { 5364 BranchLabels labels) {
5365 Location left = locs()->in(0); 5365 Location left = locs()->in(0);
5366 Location right = locs()->in(1); 5366 Location right = locs()->in(1);
5367 ASSERT(!left.IsConstant() || !right.IsConstant()); 5367 ASSERT(!left.IsConstant() || !right.IsConstant());
5368 if (left.IsConstant()) { 5368 if (left.IsConstant()) {
(...skipping 17 matching lines...) Expand all
5386 } 5386 }
5387 5387
5388 5388
5389 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5389 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5390 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 5390 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
5391 5391
5392 // The ARM code does not use true- and false-labels here. 5392 // The ARM code does not use true- and false-labels here.
5393 BranchLabels labels = { NULL, NULL, NULL }; 5393 BranchLabels labels = { NULL, NULL, NULL };
5394 Condition true_condition = EmitComparisonCode(compiler, labels); 5394 Condition true_condition = EmitComparisonCode(compiler, labels);
5395 5395
5396 Register result = locs()->out().reg(); 5396 Register result = locs()->out(0).reg();
5397 __ LoadObject(result, Bool::True(), true_condition); 5397 __ LoadObject(result, Bool::True(), true_condition);
5398 __ LoadObject(result, Bool::False(), NegateCondition(true_condition)); 5398 __ LoadObject(result, Bool::False(), NegateCondition(true_condition));
5399 } 5399 }
5400 5400
5401 5401
5402 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 5402 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
5403 BranchInstr* branch) { 5403 BranchInstr* branch) {
5404 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 5404 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
5405 5405
5406 BranchLabels labels = compiler->CreateBranchLabels(branch); 5406 BranchLabels labels = compiler->CreateBranchLabels(branch);
5407 Condition true_condition = EmitComparisonCode(compiler, labels); 5407 Condition true_condition = EmitComparisonCode(compiler, labels);
5408 EmitBranchOnCondition(compiler, true_condition, labels); 5408 EmitBranchOnCondition(compiler, true_condition, labels);
5409 } 5409 }
5410 5410
5411 5411
5412 LocationSummary* BooleanNegateInstr::MakeLocationSummary(bool opt) const { 5412 LocationSummary* BooleanNegateInstr::MakeLocationSummary(bool opt) const {
5413 return LocationSummary::Make(1, 5413 return LocationSummary::Make(1,
5414 Location::RequiresRegister(), 5414 Location::RequiresRegister(),
5415 LocationSummary::kNoCall); 5415 LocationSummary::kNoCall);
5416 } 5416 }
5417 5417
5418 5418
5419 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5419 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5420 Register value = locs()->in(0).reg(); 5420 Register value = locs()->in(0).reg();
5421 Register result = locs()->out().reg(); 5421 Register result = locs()->out(0).reg();
5422 5422
5423 __ LoadObject(result, Bool::True()); 5423 __ LoadObject(result, Bool::True());
5424 __ cmp(result, ShifterOperand(value)); 5424 __ cmp(result, ShifterOperand(value));
5425 __ LoadObject(result, Bool::False(), EQ); 5425 __ LoadObject(result, Bool::False(), EQ);
5426 } 5426 }
5427 5427
5428 5428
5429 LocationSummary* AllocateObjectInstr::MakeLocationSummary(bool opt) const { 5429 LocationSummary* AllocateObjectInstr::MakeLocationSummary(bool opt) const {
5430 return MakeCallSummary(); 5430 return MakeCallSummary();
5431 } 5431 }
5432 5432
5433 5433
5434 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5434 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5435 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls())); 5435 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls()));
5436 const ExternalLabel label(cls().ToCString(), stub.EntryPoint()); 5436 const ExternalLabel label(cls().ToCString(), stub.EntryPoint());
5437 compiler->GenerateCall(token_pos(), 5437 compiler->GenerateCall(token_pos(),
5438 &label, 5438 &label,
5439 PcDescriptors::kOther, 5439 PcDescriptors::kOther,
5440 locs()); 5440 locs());
5441 __ Drop(ArgumentCount()); // Discard arguments. 5441 __ Drop(ArgumentCount()); // Discard arguments.
5442 } 5442 }
5443 5443
5444 } // namespace dart 5444 } // namespace dart
5445 5445
5446 #endif // defined TARGET_ARCH_ARM 5446 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698