| OLD | NEW |
| 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/intrinsifier.h" | 8 #include "vm/intrinsifier.h" |
| 9 | 9 |
| 10 #include "vm/assembler.h" | 10 #include "vm/assembler.h" |
| (...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 | 514 |
| 515 void Intrinsifier::Integer_bitXor(Assembler* assembler) { | 515 void Intrinsifier::Integer_bitXor(Assembler* assembler) { |
| 516 Integer_bitXorFromInteger(assembler); | 516 Integer_bitXorFromInteger(assembler); |
| 517 } | 517 } |
| 518 | 518 |
| 519 | 519 |
| 520 void Intrinsifier::Integer_shl(Assembler* assembler) { | 520 void Intrinsifier::Integer_shl(Assembler* assembler) { |
| 521 ASSERT(kSmiTagShift == 1); | 521 ASSERT(kSmiTagShift == 1); |
| 522 ASSERT(kSmiTag == 0); | 522 ASSERT(kSmiTag == 0); |
| 523 Label fall_through; | 523 Label fall_through; |
| 524 __ Push(R6); | |
| 525 TestBothArgumentsSmis(assembler, &fall_through); | 524 TestBothArgumentsSmis(assembler, &fall_through); |
| 526 __ CompareImmediate(R0, Smi::RawValue(Smi::kBits)); | 525 __ CompareImmediate(R0, Smi::RawValue(Smi::kBits)); |
| 527 __ b(&fall_through, HI); | 526 __ b(&fall_through, HI); |
| 528 | 527 |
| 529 __ SmiUntag(R0); | 528 __ SmiUntag(R0); |
| 530 | 529 |
| 531 // Check for overflow by shifting left and shifting back arithmetically. | 530 // Check for overflow by shifting left and shifting back arithmetically. |
| 532 // If the result is different from the original, there was overflow. | 531 // If the result is different from the original, there was overflow. |
| 533 __ mov(IP, Operand(R1, LSL, R0)); | 532 __ mov(IP, Operand(R1, LSL, R0)); |
| 534 __ cmp(R1, Operand(IP, ASR, R0)); | 533 __ cmp(R1, Operand(IP, ASR, R0)); |
| 535 | 534 |
| 536 // No overflow, result in R0. | 535 // No overflow, result in R0. |
| 537 __ mov(R0, Operand(R1, LSL, R0), EQ); | 536 __ mov(R0, Operand(R1, LSL, R0), EQ); |
| 538 __ bx(LR, EQ); | 537 __ bx(LR, EQ); |
| 539 | 538 |
| 540 // Arguments are Smi but the shift produced an overflow to Mint. | 539 // Arguments are Smi but the shift produced an overflow to Mint. |
| 541 __ CompareImmediate(R1, 0); | 540 __ CompareImmediate(R1, 0); |
| 542 __ b(&fall_through, LT); | 541 __ b(&fall_through, LT); |
| 543 __ SmiUntag(R1); | 542 __ SmiUntag(R1); |
| 544 | 543 |
| 545 // Pull off high bits that will be shifted off of R1 by making a mask | 544 // Pull off high bits that will be shifted off of R1 by making a mask |
| 546 // ((1 << R0) - 1), shifting it to the left, masking R1, then shifting back. | 545 // ((1 << R0) - 1), shifting it to the left, masking R1, then shifting back. |
| 547 // high bits = (((1 << R0) - 1) << (32 - R0)) & R1) >> (32 - R0) | 546 // high bits = (((1 << R0) - 1) << (32 - R0)) & R1) >> (32 - R0) |
| 548 // lo bits = R1 << R0 | 547 // lo bits = R1 << R0 |
| 549 __ LoadImmediate(NOTFP, 1); | 548 __ LoadImmediate(NOTFP, 1); |
| 550 __ mov(NOTFP, Operand(NOTFP, LSL, R0)); // NOTFP <- 1 << R0 | 549 __ mov(NOTFP, Operand(NOTFP, LSL, R0)); // NOTFP <- 1 << R0 |
| 551 __ sub(NOTFP, NOTFP, Operand(1)); // NOTFP <- NOTFP - 1 | 550 __ sub(NOTFP, NOTFP, Operand(1)); // NOTFP <- NOTFP - 1 |
| 552 __ rsb(R6, R0, Operand(32)); // R6 <- 32 - R0 | 551 __ rsb(R3, R0, Operand(32)); // R3 <- 32 - R0 |
| 553 __ mov(NOTFP, Operand(NOTFP, LSL, R6)); // NOTFP <- NOTFP << R6 | 552 __ mov(NOTFP, Operand(NOTFP, LSL, R3)); // NOTFP <- NOTFP << R3 |
| 554 __ and_(NOTFP, R1, Operand(NOTFP)); // NOTFP <- NOTFP & R1 | 553 __ and_(NOTFP, R1, Operand(NOTFP)); // NOTFP <- NOTFP & R1 |
| 555 __ mov(NOTFP, Operand(NOTFP, LSR, R6)); // NOTFP <- NOTFP >> R6 | 554 __ mov(NOTFP, Operand(NOTFP, LSR, R3)); // NOTFP <- NOTFP >> R3 |
| 556 // Now NOTFP has the bits that fall off of R1 on a left shift. | 555 // Now NOTFP has the bits that fall off of R1 on a left shift. |
| 557 __ mov(R1, Operand(R1, LSL, R0)); // R1 gets the low bits. | 556 __ mov(R1, Operand(R1, LSL, R0)); // R1 gets the low bits. |
| 558 | 557 |
| 559 const Class& mint_class = Class::Handle( | 558 const Class& mint_class = Class::Handle( |
| 560 Isolate::Current()->object_store()->mint_class()); | 559 Isolate::Current()->object_store()->mint_class()); |
| 561 __ TryAllocate(mint_class, &fall_through, R0, R2); | 560 __ TryAllocate(mint_class, &fall_through, R0, R2); |
| 562 | 561 |
| 563 | 562 |
| 564 __ str(R1, FieldAddress(R0, Mint::value_offset())); | 563 __ str(R1, FieldAddress(R0, Mint::value_offset())); |
| 565 __ str(NOTFP, FieldAddress(R0, Mint::value_offset() + kWordSize)); | 564 __ str(NOTFP, FieldAddress(R0, Mint::value_offset() + kWordSize)); |
| 566 __ Pop(R6); | |
| 567 __ Ret(); | 565 __ Ret(); |
| 568 __ Bind(&fall_through); | 566 __ Bind(&fall_through); |
| 569 ASSERT(CODE_REG == R6); | |
| 570 __ Pop(R6); | |
| 571 } | 567 } |
| 572 | 568 |
| 573 | 569 |
| 574 static void Get64SmiOrMint(Assembler* assembler, | 570 static void Get64SmiOrMint(Assembler* assembler, |
| 575 Register res_hi, | 571 Register res_hi, |
| 576 Register res_lo, | 572 Register res_lo, |
| 577 Register reg, | 573 Register reg, |
| 578 Label* not_smi_or_mint) { | 574 Label* not_smi_or_mint) { |
| 579 Label not_smi, done; | 575 Label not_smi, done; |
| 580 __ tst(reg, Operand(kSmiTagMask)); | 576 __ tst(reg, Operand(kSmiTagMask)); |
| (...skipping 1551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2132 __ ldr(R0, Address(R0, TimelineStream::enabled_offset())); | 2128 __ ldr(R0, Address(R0, TimelineStream::enabled_offset())); |
| 2133 __ cmp(R0, Operand(0)); | 2129 __ cmp(R0, Operand(0)); |
| 2134 __ LoadObject(R0, Bool::True(), NE); | 2130 __ LoadObject(R0, Bool::True(), NE); |
| 2135 __ LoadObject(R0, Bool::False(), EQ); | 2131 __ LoadObject(R0, Bool::False(), EQ); |
| 2136 __ Ret(); | 2132 __ Ret(); |
| 2137 } | 2133 } |
| 2138 | 2134 |
| 2139 } // namespace dart | 2135 } // namespace dart |
| 2140 | 2136 |
| 2141 #endif // defined TARGET_ARCH_ARM | 2137 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |