| 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" // 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 1507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1518 | 1518 |
| 1519 | 1519 |
| 1520 void Assembler::Drop(intptr_t stack_elements) { | 1520 void Assembler::Drop(intptr_t stack_elements) { |
| 1521 ASSERT(stack_elements >= 0); | 1521 ASSERT(stack_elements >= 0); |
| 1522 if (stack_elements > 0) { | 1522 if (stack_elements > 0) { |
| 1523 AddImmediate(SP, SP, stack_elements * kWordSize); | 1523 AddImmediate(SP, SP, stack_elements * kWordSize); |
| 1524 } | 1524 } |
| 1525 } | 1525 } |
| 1526 | 1526 |
| 1527 | 1527 |
| 1528 intptr_t Assembler::FindImmediate(int32_t imm) { |
| 1529 return object_pool_wrapper_.FindImmediate(imm); |
| 1530 } |
| 1531 |
| 1532 |
| 1528 // Uses a code sequence that can easily be decoded. | 1533 // Uses a code sequence that can easily be decoded. |
| 1529 void Assembler::LoadWordFromPoolOffset(Register rd, | 1534 void Assembler::LoadWordFromPoolOffset(Register rd, |
| 1530 int32_t offset, | 1535 int32_t offset, |
| 1531 Condition cond) { | 1536 Condition cond) { |
| 1532 ASSERT(constant_pool_allowed()); | 1537 ASSERT(constant_pool_allowed()); |
| 1533 ASSERT(rd != PP); | 1538 ASSERT(rd != PP); |
| 1534 int32_t offset_mask = 0; | 1539 int32_t offset_mask = 0; |
| 1535 if (Address::CanHoldLoadOffset(kWord, offset, &offset_mask)) { | 1540 if (Address::CanHoldLoadOffset(kWord, offset, &offset_mask)) { |
| 1536 ldr(rd, Address(PP, offset), cond); | 1541 ldr(rd, Address(PP, offset), cond); |
| 1537 } else { | 1542 } else { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1548 ldr(rd, Address(rd, offset_lo), cond); | 1553 ldr(rd, Address(rd, offset_lo), cond); |
| 1549 } | 1554 } |
| 1550 } | 1555 } |
| 1551 | 1556 |
| 1552 | 1557 |
| 1553 void Assembler::LoadPoolPointer() { | 1558 void Assembler::LoadPoolPointer() { |
| 1554 const intptr_t object_pool_pc_dist = | 1559 const intptr_t object_pool_pc_dist = |
| 1555 Instructions::HeaderSize() - Instructions::object_pool_offset() + | 1560 Instructions::HeaderSize() - Instructions::object_pool_offset() + |
| 1556 CodeSize() + Instr::kPCReadOffset; | 1561 CodeSize() + Instr::kPCReadOffset; |
| 1557 LoadFromOffset(kWord, PP, PC, -object_pool_pc_dist); | 1562 LoadFromOffset(kWord, PP, PC, -object_pool_pc_dist); |
| 1563 set_constant_pool_allowed(true); |
| 1558 } | 1564 } |
| 1559 | 1565 |
| 1560 | 1566 |
| 1561 void Assembler::LoadIsolate(Register rd) { | 1567 void Assembler::LoadIsolate(Register rd) { |
| 1562 ldr(rd, Address(THR, Thread::isolate_offset())); | 1568 ldr(rd, Address(THR, Thread::isolate_offset())); |
| 1563 } | 1569 } |
| 1564 | 1570 |
| 1565 | 1571 |
| 1566 void Assembler::LoadObjectHelper(Register rd, | 1572 void Assembler::LoadObjectHelper(Register rd, |
| 1567 const Object& object, | 1573 const Object& object, |
| (...skipping 1171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2739 movw(rd, value_low, cond); | 2745 movw(rd, value_low, cond); |
| 2740 movt(rd, value_high, cond); | 2746 movt(rd, value_high, cond); |
| 2741 } | 2747 } |
| 2742 } | 2748 } |
| 2743 | 2749 |
| 2744 | 2750 |
| 2745 void Assembler::LoadDecodableImmediate( | 2751 void Assembler::LoadDecodableImmediate( |
| 2746 Register rd, int32_t value, Condition cond) { | 2752 Register rd, int32_t value, Condition cond) { |
| 2747 const ARMVersion version = TargetCPUFeatures::arm_version(); | 2753 const ARMVersion version = TargetCPUFeatures::arm_version(); |
| 2748 if ((version == ARMv5TE) || (version == ARMv6)) { | 2754 if ((version == ARMv5TE) || (version == ARMv6)) { |
| 2749 LoadPatchableImmediate(rd, value, cond); | 2755 if (constant_pool_allowed()) { |
| 2756 const int32_t offset = Array::element_offset(FindImmediate(value)); |
| 2757 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag); |
| 2758 } else { |
| 2759 LoadPatchableImmediate(rd, value, cond); |
| 2760 } |
| 2750 } else { | 2761 } else { |
| 2751 ASSERT(version == ARMv7); | 2762 ASSERT(version == ARMv7); |
| 2752 movw(rd, Utils::Low16Bits(value), cond); | 2763 movw(rd, Utils::Low16Bits(value), cond); |
| 2753 const uint16_t value_high = Utils::High16Bits(value); | 2764 const uint16_t value_high = Utils::High16Bits(value); |
| 2754 if (value_high != 0) { | 2765 if (value_high != 0) { |
| 2755 movt(rd, value_high, cond); | 2766 movt(rd, value_high, cond); |
| 2756 } | 2767 } |
| 2757 } | 2768 } |
| 2758 } | 2769 } |
| 2759 | 2770 |
| (...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3266 } | 3277 } |
| 3267 | 3278 |
| 3268 | 3279 |
| 3269 void Assembler::CallRuntime(const RuntimeEntry& entry, | 3280 void Assembler::CallRuntime(const RuntimeEntry& entry, |
| 3270 intptr_t argument_count) { | 3281 intptr_t argument_count) { |
| 3271 entry.Call(this, argument_count); | 3282 entry.Call(this, argument_count); |
| 3272 } | 3283 } |
| 3273 | 3284 |
| 3274 | 3285 |
| 3275 void Assembler::EnterDartFrame(intptr_t frame_size) { | 3286 void Assembler::EnterDartFrame(intptr_t frame_size) { |
| 3287 ASSERT(!constant_pool_allowed()); |
| 3276 const intptr_t offset = CodeSize(); | 3288 const intptr_t offset = CodeSize(); |
| 3277 | 3289 |
| 3278 // Save PC in frame for fast identification of corresponding code. | 3290 // Save PC in frame for fast identification of corresponding code. |
| 3279 // Note that callee-saved registers can be added to the register list. | 3291 // Note that callee-saved registers can be added to the register list. |
| 3280 EnterFrame((1 << PP) | (1 << FP) | (1 << LR) | (1 << PC), 0); | 3292 EnterFrame((1 << PP) | (1 << FP) | (1 << LR) | (1 << PC), 0); |
| 3281 | 3293 |
| 3282 if (offset != 0) { | 3294 if (offset != 0) { |
| 3283 // Adjust saved PC for any intrinsic code that could have been generated | 3295 // Adjust saved PC for any intrinsic code that could have been generated |
| 3284 // before a frame is created. Use PP as temp register. | 3296 // before a frame is created. Use PP as temp register. |
| 3285 ldr(PP, Address(FP, 2 * kWordSize)); | 3297 ldr(PP, Address(FP, 2 * kWordSize)); |
| 3286 AddImmediate(PP, PP, -offset); | 3298 AddImmediate(PP, PP, -offset); |
| 3287 str(PP, Address(FP, 2 * kWordSize)); | 3299 str(PP, Address(FP, 2 * kWordSize)); |
| 3288 } | 3300 } |
| 3289 | 3301 |
| 3290 // Setup pool pointer for this dart function. | 3302 // Setup pool pointer for this dart function. |
| 3291 LoadPoolPointer(); | 3303 LoadPoolPointer(); |
| 3292 | 3304 |
| 3293 // Reserve space for locals. | 3305 // Reserve space for locals. |
| 3294 AddImmediate(SP, -frame_size); | 3306 AddImmediate(SP, -frame_size); |
| 3295 } | 3307 } |
| 3296 | 3308 |
| 3297 | 3309 |
| 3298 // On entry to a function compiled for OSR, the caller's frame pointer, the | 3310 // On entry to a function compiled for OSR, the caller's frame pointer, the |
| 3299 // stack locals, and any copied parameters are already in place. The frame | 3311 // stack locals, and any copied parameters are already in place. The frame |
| 3300 // pointer is already set up. The PC marker is not correct for the | 3312 // pointer is already set up. The PC marker is not correct for the |
| 3301 // optimized function and there may be extra space for spill slots to | 3313 // optimized function and there may be extra space for spill slots to |
| 3302 // allocate. We must also set up the pool pointer for the function. | 3314 // allocate. We must also set up the pool pointer for the function. |
| 3303 void Assembler::EnterOsrFrame(intptr_t extra_size) { | 3315 void Assembler::EnterOsrFrame(intptr_t extra_size) { |
| 3316 ASSERT(!constant_pool_allowed()); |
| 3304 // mov(IP, Operand(PC)) loads PC + Instr::kPCReadOffset (8). This may be | 3317 // mov(IP, Operand(PC)) loads PC + Instr::kPCReadOffset (8). This may be |
| 3305 // different from EntryPointToPcMarkerOffset(). | 3318 // different from EntryPointToPcMarkerOffset(). |
| 3306 const intptr_t offset = | 3319 const intptr_t offset = |
| 3307 CodeSize() + Instr::kPCReadOffset - EntryPointToPcMarkerOffset(); | 3320 CodeSize() + Instr::kPCReadOffset - EntryPointToPcMarkerOffset(); |
| 3308 | 3321 |
| 3309 Comment("EnterOsrFrame"); | 3322 Comment("EnterOsrFrame"); |
| 3310 mov(IP, Operand(PC)); | 3323 mov(IP, Operand(PC)); |
| 3311 | 3324 |
| 3312 AddImmediate(IP, -offset); | 3325 AddImmediate(IP, -offset); |
| 3313 str(IP, Address(FP, kPcMarkerSlotFromFp * kWordSize)); | 3326 str(IP, Address(FP, kPcMarkerSlotFromFp * kWordSize)); |
| 3314 | 3327 |
| 3315 // Setup pool pointer for this dart function. | 3328 // Setup pool pointer for this dart function. |
| 3316 LoadPoolPointer(); | 3329 LoadPoolPointer(); |
| 3317 | 3330 |
| 3318 AddImmediate(SP, -extra_size); | 3331 AddImmediate(SP, -extra_size); |
| 3319 } | 3332 } |
| 3320 | 3333 |
| 3321 | 3334 |
| 3322 void Assembler::LeaveDartFrame() { | 3335 void Assembler::LeaveDartFrame() { |
| 3336 // LeaveDartFrame is called from stubs (pp disallowed) and from Dart code (pp |
| 3337 // allowed), so there is no point in checking the current value of |
| 3338 // constant_pool_allowed(). |
| 3339 set_constant_pool_allowed(false); |
| 3323 LeaveFrame((1 << PP) | (1 << FP) | (1 << LR)); | 3340 LeaveFrame((1 << PP) | (1 << FP) | (1 << LR)); |
| 3324 // Adjust SP for PC pushed in EnterDartFrame. | 3341 // Adjust SP for PC pushed in EnterDartFrame. |
| 3325 AddImmediate(SP, kWordSize); | 3342 AddImmediate(SP, kWordSize); |
| 3326 } | 3343 } |
| 3327 | 3344 |
| 3328 | 3345 |
| 3329 void Assembler::EnterStubFrame() { | 3346 void Assembler::EnterStubFrame() { |
| 3347 set_constant_pool_allowed(false); |
| 3330 // Push 0 as saved PC for stub frames. | 3348 // Push 0 as saved PC for stub frames. |
| 3331 mov(IP, Operand(LR)); | 3349 mov(IP, Operand(LR)); |
| 3332 mov(LR, Operand(0)); | 3350 mov(LR, Operand(0)); |
| 3333 RegList regs = (1 << PP) | (1 << FP) | (1 << IP) | (1 << LR); | 3351 RegList regs = (1 << PP) | (1 << FP) | (1 << IP) | (1 << LR); |
| 3334 EnterFrame(regs, 0); | 3352 EnterFrame(regs, 0); |
| 3335 // Setup pool pointer for this stub. | 3353 // Setup pool pointer for this stub. |
| 3336 LoadPoolPointer(); | 3354 LoadPoolPointer(); |
| 3337 } | 3355 } |
| 3338 | 3356 |
| 3339 | 3357 |
| 3340 void Assembler::LeaveStubFrame() { | 3358 void Assembler::LeaveStubFrame() { |
| 3341 LeaveFrame((1 << PP) | (1 << FP) | (1 << LR)); | 3359 LeaveFrame((1 << PP) | (1 << FP) | (1 << LR)); |
| 3360 set_constant_pool_allowed(false); |
| 3342 // Adjust SP for null PC pushed in EnterStubFrame. | 3361 // Adjust SP for null PC pushed in EnterStubFrame. |
| 3343 AddImmediate(SP, kWordSize); | 3362 AddImmediate(SP, kWordSize); |
| 3344 } | 3363 } |
| 3345 | 3364 |
| 3346 | 3365 |
| 3347 void Assembler::LoadAllocationStatsAddress(Register dest, | 3366 void Assembler::LoadAllocationStatsAddress(Register dest, |
| 3348 intptr_t cid, | 3367 intptr_t cid, |
| 3349 bool inline_isolate) { | 3368 bool inline_isolate) { |
| 3350 ASSERT(dest != kNoRegister); | 3369 ASSERT(dest != kNoRegister); |
| 3351 ASSERT(dest != TMP); | 3370 ASSERT(dest != TMP); |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3633 | 3652 |
| 3634 | 3653 |
| 3635 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 3654 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
| 3636 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); | 3655 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); |
| 3637 return fpu_reg_names[reg]; | 3656 return fpu_reg_names[reg]; |
| 3638 } | 3657 } |
| 3639 | 3658 |
| 3640 } // namespace dart | 3659 } // namespace dart |
| 3641 | 3660 |
| 3642 #endif // defined TARGET_ARCH_ARM | 3661 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |