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

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

Issue 1250323002: Load immediates via the constant pool on armv5te and armv6. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 5 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
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | runtime/vm/code_patcher_arm_test.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" // 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
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 ASSERT(Isolate::Current() != Dart::vm_isolate());
1530 const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(imm));
1531 return object_pool_wrapper_.FindObject(smi);
zra 2015/07/23 22:45:59 Why not use ObjectPoolWrapper::FindImmediate() ? I
regis 2015/07/23 23:07:31 Because I forked the code in May, when arm64 was s
1532 }
1533
1534
1528 // Uses a code sequence that can easily be decoded. 1535 // Uses a code sequence that can easily be decoded.
1529 void Assembler::LoadWordFromPoolOffset(Register rd, 1536 void Assembler::LoadWordFromPoolOffset(Register rd,
1530 int32_t offset, 1537 int32_t offset,
1531 Condition cond) { 1538 Condition cond) {
1532 ASSERT(constant_pool_allowed()); 1539 ASSERT(constant_pool_allowed());
1533 ASSERT(rd != PP); 1540 ASSERT(rd != PP);
1534 int32_t offset_mask = 0; 1541 int32_t offset_mask = 0;
1535 if (Address::CanHoldLoadOffset(kWord, offset, &offset_mask)) { 1542 if (Address::CanHoldLoadOffset(kWord, offset, &offset_mask)) {
1536 ldr(rd, Address(PP, offset), cond); 1543 ldr(rd, Address(PP, offset), cond);
1537 } else { 1544 } else {
(...skipping 10 matching lines...) Expand all
1548 ldr(rd, Address(rd, offset_lo), cond); 1555 ldr(rd, Address(rd, offset_lo), cond);
1549 } 1556 }
1550 } 1557 }
1551 1558
1552 1559
1553 void Assembler::LoadPoolPointer() { 1560 void Assembler::LoadPoolPointer() {
1554 const intptr_t object_pool_pc_dist = 1561 const intptr_t object_pool_pc_dist =
1555 Instructions::HeaderSize() - Instructions::object_pool_offset() + 1562 Instructions::HeaderSize() - Instructions::object_pool_offset() +
1556 CodeSize() + Instr::kPCReadOffset; 1563 CodeSize() + Instr::kPCReadOffset;
1557 LoadFromOffset(kWord, PP, PC, -object_pool_pc_dist); 1564 LoadFromOffset(kWord, PP, PC, -object_pool_pc_dist);
1565 set_constant_pool_allowed(true);
1558 } 1566 }
1559 1567
1560 1568
1561 void Assembler::LoadIsolate(Register rd) { 1569 void Assembler::LoadIsolate(Register rd) {
1562 ldr(rd, Address(THR, Thread::isolate_offset())); 1570 ldr(rd, Address(THR, Thread::isolate_offset()));
1563 } 1571 }
1564 1572
1565 1573
1566 void Assembler::LoadObjectHelper(Register rd, 1574 void Assembler::LoadObjectHelper(Register rd,
1567 const Object& object, 1575 const Object& object,
(...skipping 1171 matching lines...) Expand 10 before | Expand all | Expand 10 after
2739 movw(rd, value_low, cond); 2747 movw(rd, value_low, cond);
2740 movt(rd, value_high, cond); 2748 movt(rd, value_high, cond);
2741 } 2749 }
2742 } 2750 }
2743 2751
2744 2752
2745 void Assembler::LoadDecodableImmediate( 2753 void Assembler::LoadDecodableImmediate(
2746 Register rd, int32_t value, Condition cond) { 2754 Register rd, int32_t value, Condition cond) {
2747 const ARMVersion version = TargetCPUFeatures::arm_version(); 2755 const ARMVersion version = TargetCPUFeatures::arm_version();
2748 if ((version == ARMv5TE) || (version == ARMv6)) { 2756 if ((version == ARMv5TE) || (version == ARMv6)) {
2749 LoadPatchableImmediate(rd, value, cond); 2757 if (constant_pool_allowed() &&
zra 2015/07/23 22:45:59 Here: https://codereview.chromium.org//1249623004
regis 2015/07/23 23:07:31 Done.
2758 // We *could* put constants in the pool in a VM isolate, but it is
2759 // simpler to maintain the invariant that the object pool is not used
2760 // in the VM isolate.
2761 (Isolate::Current() != Dart::vm_isolate())) {
2762 // Save the bit that must be masked-off for the SmiTag.
2763 int32_t val_smi_tag = value & kSmiTagMask;
2764 value &= ~kSmiTagMask; // Mask off the tag bit.
2765 const int32_t offset = Array::element_offset(FindImmediate(value));
2766 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag);
2767 if (val_smi_tag != 0) {
2768 // Add back the tag bit.
2769 orr(rd, rd, Operand(val_smi_tag));
2770 }
2771 } else {
2772 LoadPatchableImmediate(rd, value, cond);
2773 }
2750 } else { 2774 } else {
2751 ASSERT(version == ARMv7); 2775 ASSERT(version == ARMv7);
2752 movw(rd, Utils::Low16Bits(value), cond); 2776 movw(rd, Utils::Low16Bits(value), cond);
2753 const uint16_t value_high = Utils::High16Bits(value); 2777 const uint16_t value_high = Utils::High16Bits(value);
2754 if (value_high != 0) { 2778 if (value_high != 0) {
2755 movt(rd, value_high, cond); 2779 movt(rd, value_high, cond);
2756 } 2780 }
2757 } 2781 }
2758 } 2782 }
2759 2783
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after
3266 } 3290 }
3267 3291
3268 3292
3269 void Assembler::CallRuntime(const RuntimeEntry& entry, 3293 void Assembler::CallRuntime(const RuntimeEntry& entry,
3270 intptr_t argument_count) { 3294 intptr_t argument_count) {
3271 entry.Call(this, argument_count); 3295 entry.Call(this, argument_count);
3272 } 3296 }
3273 3297
3274 3298
3275 void Assembler::EnterDartFrame(intptr_t frame_size) { 3299 void Assembler::EnterDartFrame(intptr_t frame_size) {
3300 ASSERT(!constant_pool_allowed());
3276 const intptr_t offset = CodeSize(); 3301 const intptr_t offset = CodeSize();
3277 3302
3278 // Save PC in frame for fast identification of corresponding code. 3303 // Save PC in frame for fast identification of corresponding code.
3279 // Note that callee-saved registers can be added to the register list. 3304 // Note that callee-saved registers can be added to the register list.
3280 EnterFrame((1 << PP) | (1 << FP) | (1 << LR) | (1 << PC), 0); 3305 EnterFrame((1 << PP) | (1 << FP) | (1 << LR) | (1 << PC), 0);
3281 3306
3282 if (offset != 0) { 3307 if (offset != 0) {
3283 // Adjust saved PC for any intrinsic code that could have been generated 3308 // Adjust saved PC for any intrinsic code that could have been generated
3284 // before a frame is created. Use PP as temp register. 3309 // before a frame is created. Use PP as temp register.
3285 ldr(PP, Address(FP, 2 * kWordSize)); 3310 ldr(PP, Address(FP, 2 * kWordSize));
3286 AddImmediate(PP, PP, -offset); 3311 AddImmediate(PP, PP, -offset);
3287 str(PP, Address(FP, 2 * kWordSize)); 3312 str(PP, Address(FP, 2 * kWordSize));
3288 } 3313 }
3289 3314
3290 // Setup pool pointer for this dart function. 3315 // Setup pool pointer for this dart function.
3291 LoadPoolPointer(); 3316 LoadPoolPointer();
3292 3317
3293 // Reserve space for locals. 3318 // Reserve space for locals.
3294 AddImmediate(SP, -frame_size); 3319 AddImmediate(SP, -frame_size);
3295 } 3320 }
3296 3321
3297 3322
3298 // On entry to a function compiled for OSR, the caller's frame pointer, the 3323 // 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 3324 // 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 3325 // 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 3326 // 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. 3327 // allocate. We must also set up the pool pointer for the function.
3303 void Assembler::EnterOsrFrame(intptr_t extra_size) { 3328 void Assembler::EnterOsrFrame(intptr_t extra_size) {
3329 ASSERT(!constant_pool_allowed());
3304 // mov(IP, Operand(PC)) loads PC + Instr::kPCReadOffset (8). This may be 3330 // mov(IP, Operand(PC)) loads PC + Instr::kPCReadOffset (8). This may be
3305 // different from EntryPointToPcMarkerOffset(). 3331 // different from EntryPointToPcMarkerOffset().
3306 const intptr_t offset = 3332 const intptr_t offset =
3307 CodeSize() + Instr::kPCReadOffset - EntryPointToPcMarkerOffset(); 3333 CodeSize() + Instr::kPCReadOffset - EntryPointToPcMarkerOffset();
3308 3334
3309 Comment("EnterOsrFrame"); 3335 Comment("EnterOsrFrame");
3310 mov(IP, Operand(PC)); 3336 mov(IP, Operand(PC));
3311 3337
3312 AddImmediate(IP, -offset); 3338 AddImmediate(IP, -offset);
3313 str(IP, Address(FP, kPcMarkerSlotFromFp * kWordSize)); 3339 str(IP, Address(FP, kPcMarkerSlotFromFp * kWordSize));
3314 3340
3315 // Setup pool pointer for this dart function. 3341 // Setup pool pointer for this dart function.
3316 LoadPoolPointer(); 3342 LoadPoolPointer();
3317 3343
3318 AddImmediate(SP, -extra_size); 3344 AddImmediate(SP, -extra_size);
3319 } 3345 }
3320 3346
3321 3347
3322 void Assembler::LeaveDartFrame() { 3348 void Assembler::LeaveDartFrame() {
3349 // LeaveDartFrame is called from stubs (pp disallowed) and from Dart code (pp
3350 // allowed), so there is no point in checking the current value of
3351 // constant_pool_allowed().
3352 set_constant_pool_allowed(false);
3323 LeaveFrame((1 << PP) | (1 << FP) | (1 << LR)); 3353 LeaveFrame((1 << PP) | (1 << FP) | (1 << LR));
3324 // Adjust SP for PC pushed in EnterDartFrame. 3354 // Adjust SP for PC pushed in EnterDartFrame.
3325 AddImmediate(SP, kWordSize); 3355 AddImmediate(SP, kWordSize);
3326 } 3356 }
3327 3357
3328 3358
3329 void Assembler::EnterStubFrame() { 3359 void Assembler::EnterStubFrame() {
3360 set_constant_pool_allowed(false);
3330 // Push 0 as saved PC for stub frames. 3361 // Push 0 as saved PC for stub frames.
3331 mov(IP, Operand(LR)); 3362 mov(IP, Operand(LR));
3332 mov(LR, Operand(0)); 3363 mov(LR, Operand(0));
3333 RegList regs = (1 << PP) | (1 << FP) | (1 << IP) | (1 << LR); 3364 RegList regs = (1 << PP) | (1 << FP) | (1 << IP) | (1 << LR);
3334 EnterFrame(regs, 0); 3365 EnterFrame(regs, 0);
3335 // Setup pool pointer for this stub. 3366 // Setup pool pointer for this stub.
3336 LoadPoolPointer(); 3367 LoadPoolPointer();
3337 } 3368 }
3338 3369
3339 3370
3340 void Assembler::LeaveStubFrame() { 3371 void Assembler::LeaveStubFrame() {
3341 LeaveFrame((1 << PP) | (1 << FP) | (1 << LR)); 3372 LeaveFrame((1 << PP) | (1 << FP) | (1 << LR));
3373 set_constant_pool_allowed(false);
3342 // Adjust SP for null PC pushed in EnterStubFrame. 3374 // Adjust SP for null PC pushed in EnterStubFrame.
3343 AddImmediate(SP, kWordSize); 3375 AddImmediate(SP, kWordSize);
3344 } 3376 }
3345 3377
3346 3378
3347 void Assembler::LoadAllocationStatsAddress(Register dest, 3379 void Assembler::LoadAllocationStatsAddress(Register dest,
3348 intptr_t cid, 3380 intptr_t cid,
3349 bool inline_isolate) { 3381 bool inline_isolate) {
3350 ASSERT(dest != kNoRegister); 3382 ASSERT(dest != kNoRegister);
3351 ASSERT(dest != TMP); 3383 ASSERT(dest != TMP);
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
3633 3665
3634 3666
3635 const char* Assembler::FpuRegisterName(FpuRegister reg) { 3667 const char* Assembler::FpuRegisterName(FpuRegister reg) {
3636 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); 3668 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters));
3637 return fpu_reg_names[reg]; 3669 return fpu_reg_names[reg];
3638 } 3670 }
3639 3671
3640 } // namespace dart 3672 } // namespace dart
3641 3673
3642 #endif // defined TARGET_ARCH_ARM 3674 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | runtime/vm/code_patcher_arm_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698