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 // This is forked from Dart revision df52deea9f25690eb8b66c5995da92b70f7ac1fe | 5 // This is forked from Dart revision df52deea9f25690eb8b66c5995da92b70f7ac1fe |
6 // Please update the (git) revision if we merge changes from Dart. | 6 // Please update the (git) revision if we merge changes from Dart. |
7 // https://code.google.com/p/dart/wiki/GettingTheSource | 7 // https://code.google.com/p/dart/wiki/GettingTheSource |
8 | 8 |
9 #include "vm/globals.h" // NOLINT | 9 #include "vm/globals.h" // NOLINT |
10 #if defined(TARGET_ARCH_ARM) | 10 #if defined(TARGET_ARCH_ARM) |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | | 85 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | |
86 type << kTypeShift | | 86 type << kTypeShift | |
87 static_cast<int32_t>(opcode) << kOpcodeShift | | 87 static_cast<int32_t>(opcode) << kOpcodeShift | |
88 set_cc << kSShift | | 88 set_cc << kSShift | |
89 static_cast<int32_t>(rn) << kRnShift | | 89 static_cast<int32_t>(rn) << kRnShift | |
90 static_cast<int32_t>(rd) << kRdShift | | 90 static_cast<int32_t>(rd) << kRdShift | |
91 o.encoding(); | 91 o.encoding(); |
92 Emit(encoding); | 92 Emit(encoding); |
93 } | 93 } |
94 | 94 |
95 // Moved to ARM32::AssemblerARM32::emitType05. | 95 // Moved to ARM32::AssemblerARM32::emitType05() |
96 void Assembler::EmitType5(Condition cond, int32_t offset, bool link) { | 96 void Assembler::EmitType5(Condition cond, int32_t offset, bool link) { |
97 ASSERT(cond != kNoCondition); | 97 ASSERT(cond != kNoCondition); |
98 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | | 98 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | |
99 5 << kTypeShift | | 99 5 << kTypeShift | |
100 (link ? 1 : 0) << kLinkShift; | 100 (link ? 1 : 0) << kLinkShift; |
101 Emit(Assembler::EncodeBranchOffset(offset, encoding)); | 101 Emit(Assembler::EncodeBranchOffset(offset, encoding)); |
102 } | 102 } |
103 | 103 |
104 // Moved to ARM32::AssemblerARM32::emitMemOp() | 104 // Moved to ARM32::AssemblerARM32::emitMemOp() |
105 void Assembler::EmitMemOp(Condition cond, | 105 void Assembler::EmitMemOp(Condition cond, |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 EmitType01(cond, o.type(), MOV, 0, R0, rd, o); | 297 EmitType01(cond, o.type(), MOV, 0, R0, rd, o); |
298 } | 298 } |
299 #endif | 299 #endif |
300 | 300 |
301 void Assembler::movs(Register rd, Operand o, Condition cond) { | 301 void Assembler::movs(Register rd, Operand o, Condition cond) { |
302 EmitType01(cond, o.type(), MOV, 1, R0, rd, o); | 302 EmitType01(cond, o.type(), MOV, 1, R0, rd, o); |
303 } | 303 } |
304 | 304 |
305 | 305 |
306 #if 0 | 306 #if 0 |
307 // Moved to ARM32::AssemblerARM32::bic(); | 307 // Moved to ARM32::AssemblerARM32::bic() |
308 void Assembler::bic(Register rd, Register rn, Operand o, Condition cond) { | 308 void Assembler::bic(Register rd, Register rn, Operand o, Condition cond) { |
309 EmitType01(cond, o.type(), BIC, 0, rn, rd, o); | 309 EmitType01(cond, o.type(), BIC, 0, rn, rd, o); |
310 } | 310 } |
311 | 311 |
312 // Moved to ARM32::AssemblerARM32::bic(); | 312 // Moved to ARM32::AssemblerARM32::bic() |
313 void Assembler::bics(Register rd, Register rn, Operand o, Condition cond) { | 313 void Assembler::bics(Register rd, Register rn, Operand o, Condition cond) { |
314 EmitType01(cond, o.type(), BIC, 1, rn, rd, o); | 314 EmitType01(cond, o.type(), BIC, 1, rn, rd, o); |
315 } | 315 } |
316 #endif | |
317 | 316 |
| 317 // Moved to ARM32::AssemblerARM32::mvn() |
318 void Assembler::mvn(Register rd, Operand o, Condition cond) { | 318 void Assembler::mvn(Register rd, Operand o, Condition cond) { |
319 EmitType01(cond, o.type(), MVN, 0, R0, rd, o); | 319 EmitType01(cond, o.type(), MVN, 0, R0, rd, o); |
320 } | 320 } |
321 | 321 |
322 | 322 // Moved to ARM32::AssemblerARM32::mvn() |
323 void Assembler::mvns(Register rd, Operand o, Condition cond) { | 323 void Assembler::mvns(Register rd, Operand o, Condition cond) { |
324 EmitType01(cond, o.type(), MVN, 1, R0, rd, o); | 324 EmitType01(cond, o.type(), MVN, 1, R0, rd, o); |
325 } | 325 } |
326 | 326 #endif |
327 | 327 |
328 void Assembler::clz(Register rd, Register rm, Condition cond) { | 328 void Assembler::clz(Register rd, Register rm, Condition cond) { |
329 ASSERT(rd != kNoRegister); | 329 ASSERT(rd != kNoRegister); |
330 ASSERT(rm != kNoRegister); | 330 ASSERT(rm != kNoRegister); |
331 ASSERT(cond != kNoCondition); | 331 ASSERT(cond != kNoCondition); |
332 ASSERT(rd != PC); | 332 ASSERT(rd != PC); |
333 ASSERT(rm != PC); | 333 ASSERT(rm != PC); |
334 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | | 334 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | |
335 B24 | B22 | B21 | (0xf << 16) | | 335 B24 | B22 | B21 | (0xf << 16) | |
336 (static_cast<int32_t>(rd) << kRdShift) | | 336 (static_cast<int32_t>(rd) << kRdShift) | |
337 (0xf << 8) | B4 | static_cast<int32_t>(rm); | 337 (0xf << 8) | B4 | static_cast<int32_t>(rm); |
338 Emit(encoding); | 338 Emit(encoding); |
339 } | 339 } |
340 | 340 |
341 | 341 |
342 #if | 342 #if |
343 // Moved to ARM32::AssemblerARM32::movw | 343 // Moved to ARM32::AssemblerARM32::movw() |
344 void Assembler::movw(Register rd, uint16_t imm16, Condition cond) { | 344 void Assembler::movw(Register rd, uint16_t imm16, Condition cond) { |
345 ASSERT(cond != kNoCondition); | 345 ASSERT(cond != kNoCondition); |
346 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | | 346 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | |
347 B25 | B24 | ((imm16 >> 12) << 16) | | 347 B25 | B24 | ((imm16 >> 12) << 16) | |
348 static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff); | 348 static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff); |
349 Emit(encoding); | 349 Emit(encoding); |
350 } | 350 } |
351 | 351 |
352 | 352 |
353 // Moved to ARM32::AssemblerARM32::movt | 353 // Moved to ARM32::AssemblerARM32::movt() |
354 void Assembler::movt(Register rd, uint16_t imm16, Condition cond) { | 354 void Assembler::movt(Register rd, uint16_t imm16, Condition cond) { |
355 ASSERT(cond != kNoCondition); | 355 ASSERT(cond != kNoCondition); |
356 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | | 356 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | |
357 B25 | B24 | B22 | ((imm16 >> 12) << 16) | | 357 B25 | B24 | B22 | ((imm16 >> 12) << 16) | |
358 static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff); | 358 static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff); |
359 Emit(encoding); | 359 Emit(encoding); |
360 } | 360 } |
361 #endif | 361 #endif |
362 | 362 |
363 #if 0 | 363 #if 0 |
364 // Moved to ARM32::AssemblerARM32::emitMulOp | 364 // Moved to ARM32::AssemblerARM32::emitMulOp() |
365 void Assembler::EmitMulOp(Condition cond, int32_t opcode, | 365 void Assembler::EmitMulOp(Condition cond, int32_t opcode, |
366 Register rd, Register rn, | 366 Register rd, Register rn, |
367 Register rm, Register rs) { | 367 Register rm, Register rs) { |
368 ASSERT(rd != kNoRegister); | 368 ASSERT(rd != kNoRegister); |
369 ASSERT(rn != kNoRegister); | 369 ASSERT(rn != kNoRegister); |
370 ASSERT(rm != kNoRegister); | 370 ASSERT(rm != kNoRegister); |
371 ASSERT(rs != kNoRegister); | 371 ASSERT(rs != kNoRegister); |
372 ASSERT(cond != kNoCondition); | 372 ASSERT(cond != kNoCondition); |
373 int32_t encoding = opcode | | 373 int32_t encoding = opcode | |
374 (static_cast<int32_t>(cond) << kConditionShift) | | 374 (static_cast<int32_t>(cond) << kConditionShift) | |
375 (static_cast<int32_t>(rn) << kRnShift) | | 375 (static_cast<int32_t>(rn) << kRnShift) | |
376 (static_cast<int32_t>(rd) << kRdShift) | | 376 (static_cast<int32_t>(rd) << kRdShift) | |
377 (static_cast<int32_t>(rs) << kRsShift) | | 377 (static_cast<int32_t>(rs) << kRsShift) | |
378 B7 | B4 | | 378 B7 | B4 | |
379 (static_cast<int32_t>(rm) << kRmShift); | 379 (static_cast<int32_t>(rm) << kRmShift); |
380 Emit(encoding); | 380 Emit(encoding); |
381 } | 381 } |
382 | 382 |
383 // Moved to ARM32::AssemblerARM32::mul | 383 // Moved to ARM32::AssemblerARM32::mul() |
384 void Assembler::mul(Register rd, Register rn, Register rm, Condition cond) { | 384 void Assembler::mul(Register rd, Register rn, Register rm, Condition cond) { |
385 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. | 385 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. |
386 EmitMulOp(cond, 0, R0, rd, rn, rm); | 386 EmitMulOp(cond, 0, R0, rd, rn, rm); |
387 } | 387 } |
388 #endif | 388 #endif |
389 | 389 |
390 // Like mul, but sets condition flags. | 390 // Like mul, but sets condition flags. |
391 void Assembler::muls(Register rd, Register rn, Register rm, Condition cond) { | 391 void Assembler::muls(Register rd, Register rn, Register rm, Condition cond) { |
392 EmitMulOp(cond, B20, R0, rd, rn, rm); | 392 EmitMulOp(cond, B20, R0, rd, rn, rm); |
393 } | 393 } |
(...skipping 1703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2097 ASSERT(ICData::IsValidRangeFeedbackIndex(index)); | 2097 ASSERT(ICData::IsValidRangeFeedbackIndex(index)); |
2098 ComputeRange(scratch1, value, scratch2, miss); | 2098 ComputeRange(scratch1, value, scratch2, miss); |
2099 ldr(scratch2, FieldAddress(ic_data, ICData::state_bits_offset())); | 2099 ldr(scratch2, FieldAddress(ic_data, ICData::state_bits_offset())); |
2100 orr(scratch2, | 2100 orr(scratch2, |
2101 scratch2, | 2101 scratch2, |
2102 Operand(scratch1, LSL, ICData::RangeFeedbackShift(index))); | 2102 Operand(scratch1, LSL, ICData::RangeFeedbackShift(index))); |
2103 str(scratch2, FieldAddress(ic_data, ICData::state_bits_offset())); | 2103 str(scratch2, FieldAddress(ic_data, ICData::state_bits_offset())); |
2104 } | 2104 } |
2105 | 2105 |
2106 #if 0 | 2106 #if 0 |
2107 // Moved to ::canEncodeBranchoffset in IceAssemblerARM32.cpp. | 2107 // Moved to ::canEncodeBranchoffset() in IceAssemblerARM32.cpp. |
2108 static bool CanEncodeBranchOffset(int32_t offset) { | 2108 static bool CanEncodeBranchOffset(int32_t offset) { |
2109 ASSERT(Utils::IsAligned(offset, 4)); | 2109 ASSERT(Utils::IsAligned(offset, 4)); |
2110 // Note: This check doesn't take advantage of the fact that offset>>2 | 2110 // Note: This check doesn't take advantage of the fact that offset>>2 |
2111 // is stored (allowing two more bits in address space). | 2111 // is stored (allowing two more bits in address space). |
2112 return Utils::IsInt(Utils::CountOneBits(kBranchOffsetMask), offset); | 2112 return Utils::IsInt(Utils::CountOneBits(kBranchOffsetMask), offset); |
2113 } | 2113 } |
2114 | 2114 |
2115 // Moved to ARM32::AssemblerARM32::encodeBranchOffset. | 2115 // Moved to ARM32::AssemblerARM32::encodeBranchOffset() |
2116 int32_t Assembler::EncodeBranchOffset(int32_t offset, int32_t inst) { | 2116 int32_t Assembler::EncodeBranchOffset(int32_t offset, int32_t inst) { |
2117 // The offset is off by 8 due to the way the ARM CPUs read PC. | 2117 // The offset is off by 8 due to the way the ARM CPUs read PC. |
2118 offset -= Instr::kPCReadOffset; | 2118 offset -= Instr::kPCReadOffset; |
2119 | 2119 |
2120 if (!CanEncodeBranchOffset(offset)) { | 2120 if (!CanEncodeBranchOffset(offset)) { |
2121 ASSERT(!use_far_branches()); | 2121 ASSERT(!use_far_branches()); |
2122 Thread::Current()->long_jump_base()->Jump( | 2122 Thread::Current()->long_jump_base()->Jump( |
2123 1, Object::branch_offset_error()); | 2123 1, Object::branch_offset_error()); |
2124 } | 2124 } |
2125 | 2125 |
2126 // Properly preserve only the bits supported in the instruction. | 2126 // Properly preserve only the bits supported in the instruction. |
2127 offset >>= 2; | 2127 offset >>= 2; |
2128 offset &= kBranchOffsetMask; | 2128 offset &= kBranchOffsetMask; |
2129 return (inst & ~kBranchOffsetMask) | offset; | 2129 return (inst & ~kBranchOffsetMask) | offset; |
2130 } | 2130 } |
2131 | 2131 |
2132 // Moved to AssemberARM32::decodeBranchOffset. | 2132 // Moved to AssemberARM32::decodeBranchOffset() |
2133 int Assembler::DecodeBranchOffset(int32_t inst) { | 2133 int Assembler::DecodeBranchOffset(int32_t inst) { |
2134 // Sign-extend, left-shift by 2, then add 8. | 2134 // Sign-extend, left-shift by 2, then add 8. |
2135 return ((((inst & kBranchOffsetMask) << 8) >> 6) + Instr::kPCReadOffset); | 2135 return ((((inst & kBranchOffsetMask) << 8) >> 6) + Instr::kPCReadOffset); |
2136 } | 2136 } |
2137 #endif | 2137 #endif |
2138 | 2138 |
2139 static int32_t DecodeARMv7LoadImmediate(int32_t movt, int32_t movw) { | 2139 static int32_t DecodeARMv7LoadImmediate(int32_t movt, int32_t movw) { |
2140 int32_t offset = 0; | 2140 int32_t offset = 0; |
2141 offset |= (movt & 0xf0000) << 12; | 2141 offset |= (movt & 0xf0000) << 12; |
2142 offset |= (movt & 0xfff) << 16; | 2142 offset |= (movt & 0xfff) << 16; |
(...skipping 1550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3693 | 3693 |
3694 | 3694 |
3695 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 3695 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
3696 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); | 3696 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); |
3697 return fpu_reg_names[reg]; | 3697 return fpu_reg_names[reg]; |
3698 } | 3698 } |
3699 | 3699 |
3700 } // namespace dart | 3700 } // namespace dart |
3701 | 3701 |
3702 #endif // defined TARGET_ARCH_ARM | 3702 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |