| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/intrinsifier.h" | 8 #include "vm/intrinsifier.h" |
| 9 | 9 |
| 10 #include "vm/assembler.h" | 10 #include "vm/assembler.h" |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 RBX, | 303 RBX, |
| 304 TIMES_2, | 304 TIMES_2, |
| 305 Uint32Array::data_offset())); | 305 Uint32Array::data_offset())); |
| 306 __ SmiTag(RAX); | 306 __ SmiTag(RAX); |
| 307 __ ret(); | 307 __ ret(); |
| 308 __ Bind(&fall_through); | 308 __ Bind(&fall_through); |
| 309 return false; | 309 return false; |
| 310 } | 310 } |
| 311 | 311 |
| 312 | 312 |
| 313 // Tests if two top most arguments are smis, jumps to label not_smi if not. |
| 314 // Topmost argument is in RAX. |
| 315 static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) { |
| 316 __ movq(RAX, Address(RSP, + 1 * kWordSize)); |
| 317 __ movq(RCX, Address(RSP, + 2 * kWordSize)); |
| 318 __ orq(RCX, RAX); |
| 319 __ testq(RCX, Immediate(kSmiTagMask)); |
| 320 __ j(NOT_ZERO, not_smi, Assembler::kNearJump); |
| 321 } |
| 322 |
| 323 |
| 313 bool Intrinsifier::Integer_addFromInteger(Assembler* assembler) { | 324 bool Intrinsifier::Integer_addFromInteger(Assembler* assembler) { |
| 314 return false; | 325 return false; |
| 315 } | 326 } |
| 316 | 327 |
| 317 | 328 |
| 318 bool Intrinsifier::Integer_add(Assembler* assembler) { | 329 bool Intrinsifier::Integer_add(Assembler* assembler) { |
| 319 return false; | 330 return false; |
| 320 } | 331 } |
| 321 | 332 |
| 322 | 333 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 335 return false; | 346 return false; |
| 336 } | 347 } |
| 337 | 348 |
| 338 | 349 |
| 339 bool Intrinsifier::Integer_mul(Assembler* assembler) { | 350 bool Intrinsifier::Integer_mul(Assembler* assembler) { |
| 340 return false; | 351 return false; |
| 341 } | 352 } |
| 342 | 353 |
| 343 | 354 |
| 344 bool Intrinsifier::Integer_modulo(Assembler* assembler) { | 355 bool Intrinsifier::Integer_modulo(Assembler* assembler) { |
| 356 Label fall_through, return_zero, try_modulo; |
| 357 TestBothArgumentsSmis(assembler, &fall_through); |
| 358 // RAX: right argument (divisor) |
| 359 // Check if modulo by zero -> exception thrown in main function. |
| 360 __ cmpq(RAX, Immediate(0)); |
| 361 __ j(EQUAL, &fall_through, Assembler::kNearJump); |
| 362 __ movq(RCX, Address(RSP, + 2 * kWordSize)); // Left argument (dividend). |
| 363 __ cmpq(RCX, Immediate(0)); |
| 364 __ j(LESS, &fall_through, Assembler::kNearJump); |
| 365 __ cmpq(RCX, RAX); |
| 366 __ j(EQUAL, &return_zero, Assembler::kNearJump); |
| 367 __ j(GREATER, &try_modulo, Assembler::kNearJump); |
| 368 __ movq(RAX, RCX); // Return dividend as it is smaller than divisor. |
| 369 __ ret(); |
| 370 __ Bind(&return_zero); |
| 371 __ xorq(RAX, RAX); // Return zero. |
| 372 __ ret(); |
| 373 __ Bind(&try_modulo); |
| 374 // RAX: right (non-null divisor). |
| 375 __ movq(RCX, RAX); |
| 376 __ SmiUntag(RCX); |
| 377 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Left argument (dividend). |
| 378 __ SmiUntag(RAX); |
| 379 __ cqo(); |
| 380 __ idivq(RCX); |
| 381 __ movq(RAX, RDX); |
| 382 __ SmiTag(RAX); |
| 383 __ ret(); |
| 384 __ Bind(&fall_through); |
| 345 return false; | 385 return false; |
| 346 } | 386 } |
| 347 | 387 |
| 348 | 388 |
| 349 bool Intrinsifier::Integer_truncDivide(Assembler* assembler) { | 389 bool Intrinsifier::Integer_truncDivide(Assembler* assembler) { |
| 350 return false; | 390 return false; |
| 351 } | 391 } |
| 352 | 392 |
| 353 | 393 |
| 354 bool Intrinsifier::Integer_negate(Assembler* assembler) { | 394 bool Intrinsifier::Integer_negate(Assembler* assembler) { |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 | 609 |
| 570 bool Intrinsifier::String_isEmpty(Assembler* assembler) { | 610 bool Intrinsifier::String_isEmpty(Assembler* assembler) { |
| 571 return false; | 611 return false; |
| 572 } | 612 } |
| 573 | 613 |
| 574 #undef __ | 614 #undef __ |
| 575 | 615 |
| 576 } // namespace dart | 616 } // namespace dart |
| 577 | 617 |
| 578 #endif // defined TARGET_ARCH_X64 | 618 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |