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" | 5 #include "vm/globals.h" |
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 2165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2176 return offset == 0; | 2176 return offset == 0; |
2177 } | 2177 } |
2178 default: { | 2178 default: { |
2179 UNREACHABLE(); | 2179 UNREACHABLE(); |
2180 return false; | 2180 return false; |
2181 } | 2181 } |
2182 } | 2182 } |
2183 } | 2183 } |
2184 | 2184 |
2185 | 2185 |
| 2186 bool Address::CanHoldImmediateOffset( |
| 2187 bool is_load, intptr_t cid, int64_t offset) { |
| 2188 int32_t offset_mask = 0; |
| 2189 if (is_load) { |
| 2190 return CanHoldLoadOffset(OperandSizeFor(cid), offset, &offset_mask); |
| 2191 } else { |
| 2192 return CanHoldStoreOffset(OperandSizeFor(cid), offset, &offset_mask); |
| 2193 } |
| 2194 } |
| 2195 |
| 2196 |
2186 void Assembler::Push(Register rd, Condition cond) { | 2197 void Assembler::Push(Register rd, Condition cond) { |
2187 str(rd, Address(SP, -kWordSize, Address::PreIndex), cond); | 2198 str(rd, Address(SP, -kWordSize, Address::PreIndex), cond); |
2188 } | 2199 } |
2189 | 2200 |
2190 | 2201 |
2191 void Assembler::Pop(Register rd, Condition cond) { | 2202 void Assembler::Pop(Register rd, Condition cond) { |
2192 ldr(rd, Address(SP, kWordSize, Address::PostIndex), cond); | 2203 ldr(rd, Address(SP, kWordSize, Address::PostIndex), cond); |
2193 } | 2204 } |
2194 | 2205 |
2195 | 2206 |
(...skipping 1021 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3217 ASSERT(Utils::IsAligned(address, 4)); | 3228 ASSERT(Utils::IsAligned(address, 4)); |
3218 // The address is stored in the object array as a RawSmi. | 3229 // The address is stored in the object array as a RawSmi. |
3219 const Smi& smi = Smi::Handle(Smi::New(address >> kSmiTagShift)); | 3230 const Smi& smi = Smi::Handle(Smi::New(address >> kSmiTagShift)); |
3220 // Do not reuse an existing entry, since each reference may be patched | 3231 // Do not reuse an existing entry, since each reference may be patched |
3221 // independently. | 3232 // independently. |
3222 object_pool_.Add(smi, Heap::kOld); | 3233 object_pool_.Add(smi, Heap::kOld); |
3223 return object_pool_.Length() - 1; | 3234 return object_pool_.Length() - 1; |
3224 } | 3235 } |
3225 | 3236 |
3226 | 3237 |
| 3238 Address Assembler::ElementAddressForIntIndex(bool is_load, |
| 3239 bool is_external, |
| 3240 intptr_t cid, |
| 3241 intptr_t index_scale, |
| 3242 Register array, |
| 3243 intptr_t index, |
| 3244 Register temp) { |
| 3245 const int64_t offset_base = |
| 3246 (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag)); |
| 3247 const int64_t offset = offset_base + |
| 3248 static_cast<int64_t>(index) * index_scale; |
| 3249 ASSERT(Utils::IsInt(32, offset)); |
| 3250 |
| 3251 if (Address::CanHoldImmediateOffset(is_load, cid, offset)) { |
| 3252 return Address(array, static_cast<int32_t>(offset)); |
| 3253 } else { |
| 3254 ASSERT(Address::CanHoldImmediateOffset(is_load, cid, offset - offset_base)); |
| 3255 AddImmediate(temp, array, static_cast<int32_t>(offset_base)); |
| 3256 return Address(temp, static_cast<int32_t>(offset - offset_base)); |
| 3257 } |
| 3258 } |
| 3259 |
| 3260 |
| 3261 Address Assembler::ElementAddressForRegIndex(bool is_load, |
| 3262 bool is_external, |
| 3263 intptr_t cid, |
| 3264 intptr_t index_scale, |
| 3265 Register array, |
| 3266 Register index) { |
| 3267 // Note that index is expected smi-tagged, (i.e, LSL 1) for all arrays. |
| 3268 const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) - kSmiTagShift; |
| 3269 int32_t offset = |
| 3270 is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag); |
| 3271 const OperandSize size = Address::OperandSizeFor(cid); |
| 3272 ASSERT(array != IP); |
| 3273 ASSERT(index != IP); |
| 3274 const Register base = is_load ? IP : index; |
| 3275 if ((offset != 0) || |
| 3276 (size == kSWord) || (size == kDWord) || (size == kRegList)) { |
| 3277 if (shift < 0) { |
| 3278 ASSERT(shift == -1); |
| 3279 add(base, array, Operand(index, ASR, 1)); |
| 3280 } else { |
| 3281 add(base, array, Operand(index, LSL, shift)); |
| 3282 } |
| 3283 } else { |
| 3284 if (shift < 0) { |
| 3285 ASSERT(shift == -1); |
| 3286 return Address(array, index, ASR, 1); |
| 3287 } else { |
| 3288 return Address(array, index, LSL, shift); |
| 3289 } |
| 3290 } |
| 3291 int32_t offset_mask = 0; |
| 3292 if ((is_load && !Address::CanHoldLoadOffset(size, |
| 3293 offset, |
| 3294 &offset_mask)) || |
| 3295 (!is_load && !Address::CanHoldStoreOffset(size, |
| 3296 offset, |
| 3297 &offset_mask))) { |
| 3298 AddImmediate(base, offset & ~offset_mask); |
| 3299 offset = offset & offset_mask; |
| 3300 } |
| 3301 return Address(base, offset); |
| 3302 } |
| 3303 |
| 3304 |
3227 static const char* cpu_reg_names[kNumberOfCpuRegisters] = { | 3305 static const char* cpu_reg_names[kNumberOfCpuRegisters] = { |
3228 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", | 3306 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", |
3229 "r8", "ctx", "pp", "fp", "ip", "sp", "lr", "pc", | 3307 "r8", "ctx", "pp", "fp", "ip", "sp", "lr", "pc", |
3230 }; | 3308 }; |
3231 | 3309 |
3232 | 3310 |
3233 const char* Assembler::RegisterName(Register reg) { | 3311 const char* Assembler::RegisterName(Register reg) { |
3234 ASSERT((0 <= reg) && (reg < kNumberOfCpuRegisters)); | 3312 ASSERT((0 <= reg) && (reg < kNumberOfCpuRegisters)); |
3235 return cpu_reg_names[reg]; | 3313 return cpu_reg_names[reg]; |
3236 } | 3314 } |
3237 | 3315 |
3238 | 3316 |
3239 static const char* fpu_reg_names[kNumberOfFpuRegisters] = { | 3317 static const char* fpu_reg_names[kNumberOfFpuRegisters] = { |
3240 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", | 3318 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", |
3241 #if defined(VFPv3_D32) | 3319 #if defined(VFPv3_D32) |
3242 "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", | 3320 "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", |
3243 #endif | 3321 #endif |
3244 }; | 3322 }; |
3245 | 3323 |
3246 | 3324 |
3247 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 3325 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
3248 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); | 3326 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); |
3249 return fpu_reg_names[reg]; | 3327 return fpu_reg_names[reg]; |
3250 } | 3328 } |
3251 | 3329 |
3252 } // namespace dart | 3330 } // namespace dart |
3253 | 3331 |
3254 #endif // defined TARGET_ARCH_ARM | 3332 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |