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

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

Issue 886173003: VM: Align implementations of assembler constant pools. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: fixed ARM debug assert Created 5 years, 10 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
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" // NOLINT 5 #include "vm/globals.h" // NOLINT
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/longjump.h" 10 #include "vm/longjump.h"
(...skipping 1569 matching lines...) Expand 10 before | Expand all | Expand 10 after
1580 if (object.IsSmi()) { 1580 if (object.IsSmi()) {
1581 LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw()), cond); 1581 LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw()), cond);
1582 } else if (object.InVMHeap() || !allow_constant_pool()) { 1582 } else if (object.InVMHeap() || !allow_constant_pool()) {
1583 // Make sure that class CallPattern is able to decode this load immediate. 1583 // Make sure that class CallPattern is able to decode this load immediate.
1584 const int32_t object_raw = reinterpret_cast<int32_t>(object.raw()); 1584 const int32_t object_raw = reinterpret_cast<int32_t>(object.raw());
1585 LoadImmediate(rd, object_raw, cond); 1585 LoadImmediate(rd, object_raw, cond);
1586 } else { 1586 } else {
1587 // Make sure that class CallPattern is able to decode this load from the 1587 // Make sure that class CallPattern is able to decode this load from the
1588 // object pool. 1588 // object pool.
1589 const int32_t offset = 1589 const int32_t offset =
1590 Array::data_offset() + 4*AddObject(object) - kHeapObjectTag; 1590 Array::element_offset(object_pool_.FindObject(object, kNotPatchable));
1591 LoadWordFromPoolOffset(rd, offset, cond); 1591 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, cond);
1592 } 1592 }
1593 } 1593 }
1594 1594
1595 1595
1596 void Assembler::PushObject(const Object& object) { 1596 void Assembler::PushObject(const Object& object) {
1597 LoadObject(IP, object); 1597 LoadObject(IP, object);
1598 Push(IP); 1598 Push(IP);
1599 } 1599 }
1600 1600
1601 1601
(...skipping 1064 matching lines...) Expand 10 before | Expand all | Expand 10 after
2666 blx(LR); // Use blx instruction so that the return branch prediction works. 2666 blx(LR); // Use blx instruction so that the return branch prediction works.
2667 } 2667 }
2668 2668
2669 2669
2670 void Assembler::BranchLinkPatchable(const ExternalLabel* label) { 2670 void Assembler::BranchLinkPatchable(const ExternalLabel* label) {
2671 // Make sure that class CallPattern is able to patch the label referred 2671 // Make sure that class CallPattern is able to patch the label referred
2672 // to by this code sequence. 2672 // to by this code sequence.
2673 // For added code robustness, use 'blx lr' in a patchable sequence and 2673 // For added code robustness, use 'blx lr' in a patchable sequence and
2674 // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors). 2674 // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors).
2675 const int32_t offset = 2675 const int32_t offset =
2676 Array::data_offset() + 4*AddExternalLabel(label) - kHeapObjectTag; 2676 Array::element_offset(object_pool_.FindExternalLabel(label, kPatchable));
2677 LoadWordFromPoolOffset(LR, offset); 2677 LoadWordFromPoolOffset(LR, offset - kHeapObjectTag);
2678 blx(LR); // Use blx instruction so that the return branch prediction works. 2678 blx(LR); // Use blx instruction so that the return branch prediction works.
2679 } 2679 }
2680 2680
2681 2681
2682 void Assembler::BranchLinkOffset(Register base, int32_t offset) { 2682 void Assembler::BranchLinkOffset(Register base, int32_t offset) {
2683 ASSERT(base != PC); 2683 ASSERT(base != PC);
2684 ASSERT(base != IP); 2684 ASSERT(base != IP);
2685 LoadFromOffset(kWord, IP, base, offset); 2685 LoadFromOffset(kWord, IP, base, offset);
2686 blx(IP); // Use blx instruction so that the return branch prediction works. 2686 blx(IP); // Use blx instruction so that the return branch prediction works.
2687 } 2687 }
(...skipping 15 matching lines...) Expand all
2703 } else { 2703 } else {
2704 ASSERT(version == ARMv7); 2704 ASSERT(version == ARMv7);
2705 const uint16_t value_low = Utils::Low16Bits(value); 2705 const uint16_t value_low = Utils::Low16Bits(value);
2706 const uint16_t value_high = Utils::High16Bits(value); 2706 const uint16_t value_high = Utils::High16Bits(value);
2707 movw(rd, value_low, cond); 2707 movw(rd, value_low, cond);
2708 movt(rd, value_high, cond); 2708 movt(rd, value_high, cond);
2709 } 2709 }
2710 } 2710 }
2711 2711
2712 2712
2713 void Assembler::LoadDecodableImmediate(
2714 Register rd, int32_t value, Condition cond) {
2715 const ARMVersion version = TargetCPUFeatures::arm_version();
2716 if ((version == ARMv5TE) || (version == ARMv6)) {
2717 LoadPatchableImmediate(rd, value, cond);
2718 } else {
2719 ASSERT(version == ARMv7);
2720 movw(rd, Utils::Low16Bits(value), cond);
2721 const uint16_t value_high = Utils::High16Bits(value);
2722 if (value_high != 0) {
2723 movt(rd, value_high, cond);
2724 }
2725 }
2726 }
2727
2728
2729 void Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) { 2713 void Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) {
2730 Operand o; 2714 Operand o;
2731 if (Operand::CanHold(value, &o)) { 2715 if (Operand::CanHold(value, &o)) {
2732 mov(rd, o, cond); 2716 mov(rd, o, cond);
2733 } else if (Operand::CanHold(~value, &o)) { 2717 } else if (Operand::CanHold(~value, &o)) {
2734 mvn(rd, o, cond); 2718 mvn(rd, o, cond);
2735 } else { 2719 } else {
2736 LoadDecodableImmediate(rd, value, cond); 2720 LoadPatchableImmediate(rd, value, cond);
zra 2015/02/09 15:30:30 What is the reason for this change? Does this imme
Florian Schneider 2015/02/09 15:49:41 No, I missed the case for <16 bit values. I'll und
2737 } 2721 }
2738 } 2722 }
2739 2723
2740 2724
2741 void Assembler::LoadSImmediate(SRegister sd, float value, Condition cond) { 2725 void Assembler::LoadSImmediate(SRegister sd, float value, Condition cond) {
2742 if (!vmovs(sd, value, cond)) { 2726 if (!vmovs(sd, value, cond)) {
2743 const DRegister dd = static_cast<DRegister>(sd >> 1); 2727 const DRegister dd = static_cast<DRegister>(sd >> 1);
2744 const int index = sd & 1; 2728 const int index = sd & 1;
2745 LoadImmediate(IP, bit_cast<int32_t, float>(value), cond); 2729 LoadImmediate(IP, bit_cast<int32_t, float>(value), cond);
2746 vmovdr(dd, index, IP, cond); 2730 vmovdr(dd, index, IP, cond);
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
3012 sub(rd, rn, o, cond); 2996 sub(rd, rn, o, cond);
3013 } else { 2997 } else {
3014 ASSERT(rn != IP); 2998 ASSERT(rn != IP);
3015 if (Operand::CanHold(~value, &o)) { 2999 if (Operand::CanHold(~value, &o)) {
3016 mvn(IP, o, cond); 3000 mvn(IP, o, cond);
3017 add(rd, rn, Operand(IP), cond); 3001 add(rd, rn, Operand(IP), cond);
3018 } else if (Operand::CanHold(~(-value), &o)) { 3002 } else if (Operand::CanHold(~(-value), &o)) {
3019 mvn(IP, o, cond); 3003 mvn(IP, o, cond);
3020 sub(rd, rn, Operand(IP), cond); 3004 sub(rd, rn, Operand(IP), cond);
3021 } else { 3005 } else {
3022 LoadDecodableImmediate(IP, value, cond); 3006 LoadPatchableImmediate(IP, value, cond);
3023 add(rd, rn, Operand(IP), cond); 3007 add(rd, rn, Operand(IP), cond);
3024 } 3008 }
3025 } 3009 }
3026 } 3010 }
3027 3011
3028 3012
3029 void Assembler::AddImmediateSetFlags(Register rd, Register rn, int32_t value, 3013 void Assembler::AddImmediateSetFlags(Register rd, Register rn, int32_t value,
3030 Condition cond) { 3014 Condition cond) {
3031 Operand o; 3015 Operand o;
3032 if (Operand::CanHold(value, &o)) { 3016 if (Operand::CanHold(value, &o)) {
3033 // Handles value == kMinInt32. 3017 // Handles value == kMinInt32.
3034 adds(rd, rn, o, cond); 3018 adds(rd, rn, o, cond);
3035 } else if (Operand::CanHold(-value, &o)) { 3019 } else if (Operand::CanHold(-value, &o)) {
3036 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. 3020 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection.
3037 subs(rd, rn, o, cond); 3021 subs(rd, rn, o, cond);
3038 } else { 3022 } else {
3039 ASSERT(rn != IP); 3023 ASSERT(rn != IP);
3040 if (Operand::CanHold(~value, &o)) { 3024 if (Operand::CanHold(~value, &o)) {
3041 mvn(IP, o, cond); 3025 mvn(IP, o, cond);
3042 adds(rd, rn, Operand(IP), cond); 3026 adds(rd, rn, Operand(IP), cond);
3043 } else if (Operand::CanHold(~(-value), &o)) { 3027 } else if (Operand::CanHold(~(-value), &o)) {
3044 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. 3028 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection.
3045 mvn(IP, o, cond); 3029 mvn(IP, o, cond);
3046 subs(rd, rn, Operand(IP), cond); 3030 subs(rd, rn, Operand(IP), cond);
3047 } else { 3031 } else {
3048 LoadDecodableImmediate(IP, value, cond); 3032 LoadPatchableImmediate(IP, value, cond);
3049 adds(rd, rn, Operand(IP), cond); 3033 adds(rd, rn, Operand(IP), cond);
3050 } 3034 }
3051 } 3035 }
3052 } 3036 }
3053 3037
3054 3038
3055 void Assembler::SubImmediateSetFlags(Register rd, Register rn, int32_t value, 3039 void Assembler::SubImmediateSetFlags(Register rd, Register rn, int32_t value,
3056 Condition cond) { 3040 Condition cond) {
3057 Operand o; 3041 Operand o;
3058 if (Operand::CanHold(value, &o)) { 3042 if (Operand::CanHold(value, &o)) {
3059 // Handles value == kMinInt32. 3043 // Handles value == kMinInt32.
3060 subs(rd, rn, o, cond); 3044 subs(rd, rn, o, cond);
3061 } else if (Operand::CanHold(-value, &o)) { 3045 } else if (Operand::CanHold(-value, &o)) {
3062 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. 3046 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection.
3063 adds(rd, rn, o, cond); 3047 adds(rd, rn, o, cond);
3064 } else { 3048 } else {
3065 ASSERT(rn != IP); 3049 ASSERT(rn != IP);
3066 if (Operand::CanHold(~value, &o)) { 3050 if (Operand::CanHold(~value, &o)) {
3067 mvn(IP, o, cond); 3051 mvn(IP, o, cond);
3068 subs(rd, rn, Operand(IP), cond); 3052 subs(rd, rn, Operand(IP), cond);
3069 } else if (Operand::CanHold(~(-value), &o)) { 3053 } else if (Operand::CanHold(~(-value), &o)) {
3070 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. 3054 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection.
3071 mvn(IP, o, cond); 3055 mvn(IP, o, cond);
3072 adds(rd, rn, Operand(IP), cond); 3056 adds(rd, rn, Operand(IP), cond);
3073 } else { 3057 } else {
3074 LoadDecodableImmediate(IP, value, cond); 3058 LoadPatchableImmediate(IP, value, cond);
3075 subs(rd, rn, Operand(IP), cond); 3059 subs(rd, rn, Operand(IP), cond);
3076 } 3060 }
3077 } 3061 }
3078 } 3062 }
3079 3063
3080 3064
3081 void Assembler::AndImmediate(Register rd, Register rs, int32_t imm, 3065 void Assembler::AndImmediate(Register rd, Register rs, int32_t imm,
3082 Condition cond) { 3066 Condition cond) {
3083 Operand o; 3067 Operand o;
3084 if (Operand::CanHold(imm, &o)) { 3068 if (Operand::CanHold(imm, &o)) {
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
3536 // 'unstop' and continue execution in the simulator or jump to the next 3520 // 'unstop' and continue execution in the simulator or jump to the next
3537 // instruction in gdb. 3521 // instruction in gdb.
3538 Label stop; 3522 Label stop;
3539 b(&stop); 3523 b(&stop);
3540 Emit(reinterpret_cast<int32_t>(message)); 3524 Emit(reinterpret_cast<int32_t>(message));
3541 Bind(&stop); 3525 Bind(&stop);
3542 svc(kStopMessageSvcCode); 3526 svc(kStopMessageSvcCode);
3543 } 3527 }
3544 3528
3545 3529
3546 int32_t Assembler::AddObject(const Object& obj) {
3547 ASSERT(obj.IsNotTemporaryScopedHandle());
3548 ASSERT(obj.IsOld());
3549 if (object_pool_.IsNull()) {
3550 // The object pool cannot be used in the vm isolate.
3551 ASSERT(Isolate::Current() != Dart::vm_isolate());
3552 object_pool_ = GrowableObjectArray::New(Heap::kOld);
3553 }
3554
3555 intptr_t index = object_pool_index_table_.Lookup(&obj);
3556 if (index != ObjIndexPair::kNoIndex) {
3557 return index;
3558 }
3559
3560 object_pool_.Add(obj, Heap::kOld);
3561 object_pool_index_table_.Insert(
3562 ObjIndexPair(&obj, object_pool_.Length() - 1));
3563 return object_pool_.Length() - 1;
3564 }
3565
3566
3567 int32_t Assembler::AddExternalLabel(const ExternalLabel* label) {
3568 if (object_pool_.IsNull()) {
3569 // The object pool cannot be used in the vm isolate.
3570 ASSERT(Isolate::Current() != Dart::vm_isolate());
3571 object_pool_ = GrowableObjectArray::New(Heap::kOld);
3572 }
3573 const word address = label->address();
3574 ASSERT(Utils::IsAligned(address, 4));
3575 // The address is stored in the object array as a RawSmi.
3576 const Smi& smi = Smi::Handle(Smi::New(address >> kSmiTagShift));
3577 // Do not reuse an existing entry, since each reference may be patched
3578 // independently.
3579 object_pool_.Add(smi, Heap::kOld);
3580 return object_pool_.Length() - 1;
3581 }
3582
3583
3584 Address Assembler::ElementAddressForIntIndex(bool is_load, 3530 Address Assembler::ElementAddressForIntIndex(bool is_load,
3585 bool is_external, 3531 bool is_external,
3586 intptr_t cid, 3532 intptr_t cid,
3587 intptr_t index_scale, 3533 intptr_t index_scale,
3588 Register array, 3534 Register array,
3589 intptr_t index, 3535 intptr_t index,
3590 Register temp) { 3536 Register temp) {
3591 const int64_t offset_base = 3537 const int64_t offset_base =
3592 (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag)); 3538 (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
3593 const int64_t offset = offset_base + 3539 const int64_t offset = offset_base +
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
3669 3615
3670 3616
3671 const char* Assembler::FpuRegisterName(FpuRegister reg) { 3617 const char* Assembler::FpuRegisterName(FpuRegister reg) {
3672 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); 3618 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters));
3673 return fpu_reg_names[reg]; 3619 return fpu_reg_names[reg];
3674 } 3620 }
3675 3621
3676 } // namespace dart 3622 } // namespace dart
3677 3623
3678 #endif // defined TARGET_ARCH_ARM 3624 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698