| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <limits.h> // For LONG_MIN, LONG_MAX. | 5 #include <limits.h> // For LONG_MIN, LONG_MAX. |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_ARM | 7 #if V8_TARGET_ARCH_ARM |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/base/division-by-constant.h" | 10 #include "src/base/division-by-constant.h" |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 mov_operand.instructions_required(this, mov_instr) * kInstrSize; | 82 mov_operand.instructions_required(this, mov_instr) * kInstrSize; |
| 83 } | 83 } |
| 84 | 84 |
| 85 | 85 |
| 86 int MacroAssembler::CallStubSize( | 86 int MacroAssembler::CallStubSize( |
| 87 CodeStub* stub, TypeFeedbackId ast_id, Condition cond) { | 87 CodeStub* stub, TypeFeedbackId ast_id, Condition cond) { |
| 88 return CallSize(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id, cond); | 88 return CallSize(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id, cond); |
| 89 } | 89 } |
| 90 | 90 |
| 91 | 91 |
| 92 int MacroAssembler::CallSizeNotPredictableCodeSize(Isolate* isolate, | |
| 93 Address target, | |
| 94 RelocInfo::Mode rmode, | |
| 95 Condition cond) { | |
| 96 Instr mov_instr = cond | MOV | LeaveCC; | |
| 97 Operand mov_operand = Operand(reinterpret_cast<intptr_t>(target), rmode); | |
| 98 return kInstrSize + | |
| 99 mov_operand.instructions_required(NULL, mov_instr) * kInstrSize; | |
| 100 } | |
| 101 | |
| 102 | |
| 103 void MacroAssembler::Call(Address target, | 92 void MacroAssembler::Call(Address target, |
| 104 RelocInfo::Mode rmode, | 93 RelocInfo::Mode rmode, |
| 105 Condition cond, | 94 Condition cond, |
| 106 TargetAddressStorageMode mode) { | 95 TargetAddressStorageMode mode) { |
| 107 // Block constant pool for the call instruction sequence. | 96 // Block constant pool for the call instruction sequence. |
| 108 BlockConstPoolScope block_const_pool(this); | 97 BlockConstPoolScope block_const_pool(this); |
| 109 Label start; | 98 Label start; |
| 110 bind(&start); | 99 bind(&start); |
| 111 | 100 |
| 112 bool old_predictable_code_size = predictable_code_size(); | 101 bool old_predictable_code_size = predictable_code_size(); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 DCHECK(RelocInfo::IsCodeTarget(rmode)); | 155 DCHECK(RelocInfo::IsCodeTarget(rmode)); |
| 167 if (rmode == RelocInfo::CODE_TARGET && !ast_id.IsNone()) { | 156 if (rmode == RelocInfo::CODE_TARGET && !ast_id.IsNone()) { |
| 168 SetRecordedAstId(ast_id); | 157 SetRecordedAstId(ast_id); |
| 169 rmode = RelocInfo::CODE_TARGET_WITH_ID; | 158 rmode = RelocInfo::CODE_TARGET_WITH_ID; |
| 170 } | 159 } |
| 171 // 'code' is always generated ARM code, never THUMB code | 160 // 'code' is always generated ARM code, never THUMB code |
| 172 AllowDeferredHandleDereference embedding_raw_address; | 161 AllowDeferredHandleDereference embedding_raw_address; |
| 173 Call(reinterpret_cast<Address>(code.location()), rmode, cond, mode); | 162 Call(reinterpret_cast<Address>(code.location()), rmode, cond, mode); |
| 174 } | 163 } |
| 175 | 164 |
| 165 void MacroAssembler::CallDeoptimizer(Address target) { |
| 166 BlockConstPoolScope block_const_pool(this); |
| 167 |
| 168 uintptr_t target_raw = reinterpret_cast<uintptr_t>(target); |
| 169 |
| 170 // We use blx, like a call, but it does not return here. The link register is |
| 171 // used by the deoptimizer to work out what called it. |
| 172 if (CpuFeatures::IsSupported(ARMv7)) { |
| 173 CpuFeatureScope scope(this, ARMv7); |
| 174 movw(ip, target_raw & 0xffff); |
| 175 movt(ip, (target_raw >> 16) & 0xffff); |
| 176 blx(ip); |
| 177 } else { |
| 178 // We need to load a literal, but we can't use the usual constant pool |
| 179 // because we call this from a patcher, and cannot afford the guard |
| 180 // instruction and other administrative overhead. |
| 181 ldr(ip, MemOperand(pc, (2 * kInstrSize) - kPcLoadDelta)); |
| 182 blx(ip); |
| 183 dd(target_raw); |
| 184 } |
| 185 } |
| 186 |
| 187 int MacroAssembler::CallDeoptimizerSize() { |
| 188 // ARMv7+: |
| 189 // movw ip, ... |
| 190 // movt ip, ... |
| 191 // blx ip @ This never returns. |
| 192 // |
| 193 // ARMv6: |
| 194 // ldr ip, =address |
| 195 // blx ip @ This never returns. |
| 196 // .word address |
| 197 return 3 * kInstrSize; |
| 198 } |
| 176 | 199 |
| 177 void MacroAssembler::Ret(Condition cond) { | 200 void MacroAssembler::Ret(Condition cond) { |
| 178 bx(lr, cond); | 201 bx(lr, cond); |
| 179 } | 202 } |
| 180 | 203 |
| 181 | 204 |
| 182 void MacroAssembler::Drop(int count, Condition cond) { | 205 void MacroAssembler::Drop(int count, Condition cond) { |
| 183 if (count > 0) { | 206 if (count > 0) { |
| 184 add(sp, sp, Operand(count * kPointerSize), LeaveCC, cond); | 207 add(sp, sp, Operand(count * kPointerSize), LeaveCC, cond); |
| 185 } | 208 } |
| (...skipping 3771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3957 DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 3980 DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
| 3958 } | 3981 } |
| 3959 | 3982 |
| 3960 | 3983 |
| 3961 CodePatcher::~CodePatcher() { | 3984 CodePatcher::~CodePatcher() { |
| 3962 // Indicate that code has changed. | 3985 // Indicate that code has changed. |
| 3963 if (flush_cache_ == FLUSH) { | 3986 if (flush_cache_ == FLUSH) { |
| 3964 Assembler::FlushICache(masm_.isolate(), address_, size_); | 3987 Assembler::FlushICache(masm_.isolate(), address_, size_); |
| 3965 } | 3988 } |
| 3966 | 3989 |
| 3990 // Check that we don't have any pending constant pools. |
| 3991 DCHECK(masm_.num_pending_32_bit_constants_ == 0); |
| 3992 DCHECK(masm_.num_pending_64_bit_constants_ == 0); |
| 3993 |
| 3967 // Check that the code was patched as expected. | 3994 // Check that the code was patched as expected. |
| 3968 DCHECK(masm_.pc_ == address_ + size_); | 3995 DCHECK(masm_.pc_ == address_ + size_); |
| 3969 DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 3996 DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
| 3970 } | 3997 } |
| 3971 | 3998 |
| 3972 | 3999 |
| 3973 void CodePatcher::Emit(Instr instr) { | 4000 void CodePatcher::Emit(Instr instr) { |
| 3974 masm()->emit(instr); | 4001 masm()->emit(instr); |
| 3975 } | 4002 } |
| 3976 | 4003 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 4006 } | 4033 } |
| 4007 } | 4034 } |
| 4008 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); | 4035 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); |
| 4009 add(result, result, Operand(dividend, LSR, 31)); | 4036 add(result, result, Operand(dividend, LSR, 31)); |
| 4010 } | 4037 } |
| 4011 | 4038 |
| 4012 } // namespace internal | 4039 } // namespace internal |
| 4013 } // namespace v8 | 4040 } // namespace v8 |
| 4014 | 4041 |
| 4015 #endif // V8_TARGET_ARCH_ARM | 4042 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |