| 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/simulator.h" | 9 #include "vm/simulator.h" |
| 10 #include "vm/runtime_entry.h" | 10 #include "vm/runtime_entry.h" |
| 11 #include "vm/stub_code.h" | 11 #include "vm/stub_code.h" |
| 12 | 12 |
| 13 // An extra check since we are assuming the existence of /proc/cpuinfo below. | 13 // An extra check since we are assuming the existence of /proc/cpuinfo below. |
| 14 #if !defined(USING_SIMULATOR) && !defined(__linux__) | 14 #if !defined(USING_SIMULATOR) && !defined(__linux__) |
| 15 #error ARM cross-compile only supported on Linux | 15 #error ARM cross-compile only supported on Linux |
| 16 #endif | 16 #endif |
| 17 | 17 |
| 18 namespace dart { | 18 namespace dart { |
| 19 | 19 |
| 20 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); | 20 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); |
| 21 | 21 DECLARE_FLAG(bool, inline_alloc); |
| 22 | 22 |
| 23 bool CPUFeatures::integer_division_supported_ = false; | 23 bool CPUFeatures::integer_division_supported_ = false; |
| 24 #if defined(DEBUG) | 24 #if defined(DEBUG) |
| 25 bool CPUFeatures::initialized_ = false; | 25 bool CPUFeatures::initialized_ = false; |
| 26 #endif | 26 #endif |
| 27 | 27 |
| 28 | 28 |
| 29 bool CPUFeatures::integer_division_supported() { | 29 bool CPUFeatures::integer_division_supported() { |
| 30 DEBUG_ASSERT(initialized_); | 30 DEBUG_ASSERT(initialized_); |
| 31 return integer_division_supported_; | 31 return integer_division_supported_; |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 EmitType01(cond, so.type(), MOV, 1, R0, rd, so); | 407 EmitType01(cond, so.type(), MOV, 1, R0, rd, so); |
| 408 } | 408 } |
| 409 | 409 |
| 410 | 410 |
| 411 void Assembler::bic(Register rd, Register rn, ShifterOperand so, | 411 void Assembler::bic(Register rd, Register rn, ShifterOperand so, |
| 412 Condition cond) { | 412 Condition cond) { |
| 413 EmitType01(cond, so.type(), BIC, 0, rn, rd, so); | 413 EmitType01(cond, so.type(), BIC, 0, rn, rd, so); |
| 414 } | 414 } |
| 415 | 415 |
| 416 | 416 |
| 417 void Assembler::bics(Register rd, Register rn, ShifterOperand so, |
| 418 Condition cond) { |
| 419 EmitType01(cond, so.type(), BIC, 1, rn, rd, so); |
| 420 } |
| 421 |
| 422 |
| 417 void Assembler::mvn(Register rd, ShifterOperand so, Condition cond) { | 423 void Assembler::mvn(Register rd, ShifterOperand so, Condition cond) { |
| 418 EmitType01(cond, so.type(), MVN, 0, R0, rd, so); | 424 EmitType01(cond, so.type(), MVN, 0, R0, rd, so); |
| 419 } | 425 } |
| 420 | 426 |
| 421 | 427 |
| 422 void Assembler::mvns(Register rd, ShifterOperand so, Condition cond) { | 428 void Assembler::mvns(Register rd, ShifterOperand so, Condition cond) { |
| 423 EmitType01(cond, so.type(), MVN, 1, R0, rd, so); | 429 EmitType01(cond, so.type(), MVN, 1, R0, rd, so); |
| 424 } | 430 } |
| 425 | 431 |
| 426 | 432 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 510 } | 516 } |
| 511 | 517 |
| 512 | 518 |
| 513 void Assembler::umull(Register rd_lo, Register rd_hi, | 519 void Assembler::umull(Register rd_lo, Register rd_hi, |
| 514 Register rn, Register rm, Condition cond) { | 520 Register rn, Register rm, Condition cond) { |
| 515 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. | 521 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. |
| 516 EmitMulOp(cond, B23, rd_lo, rd_hi, rn, rm); | 522 EmitMulOp(cond, B23, rd_lo, rd_hi, rn, rm); |
| 517 } | 523 } |
| 518 | 524 |
| 519 | 525 |
| 526 void Assembler::smlal(Register rd_lo, Register rd_hi, |
| 527 Register rn, Register rm, Condition cond) { |
| 528 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. |
| 529 EmitMulOp(cond, B23 | B22 | B21, rd_lo, rd_hi, rn, rm); |
| 530 } |
| 531 |
| 532 |
| 520 void Assembler::EmitDivOp(Condition cond, int32_t opcode, | 533 void Assembler::EmitDivOp(Condition cond, int32_t opcode, |
| 521 Register rd, Register rn, Register rm) { | 534 Register rd, Register rn, Register rm) { |
| 522 ASSERT(CPUFeatures::integer_division_supported()); | 535 ASSERT(CPUFeatures::integer_division_supported()); |
| 523 ASSERT(rd != kNoRegister); | 536 ASSERT(rd != kNoRegister); |
| 524 ASSERT(rn != kNoRegister); | 537 ASSERT(rn != kNoRegister); |
| 525 ASSERT(rm != kNoRegister); | 538 ASSERT(rm != kNoRegister); |
| 526 ASSERT(cond != kNoCondition); | 539 ASSERT(cond != kNoCondition); |
| 527 int32_t encoding = opcode | | 540 int32_t encoding = opcode | |
| 528 (static_cast<int32_t>(cond) << kConditionShift) | | 541 (static_cast<int32_t>(cond) << kConditionShift) | |
| 529 (static_cast<int32_t>(rn) << kDivRnShift) | | 542 (static_cast<int32_t>(rn) << kDivRnShift) | |
| (...skipping 1523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2053 regs |= (1 << PP); | 2066 regs |= (1 << PP); |
| 2054 } | 2067 } |
| 2055 LeaveFrame(regs); | 2068 LeaveFrame(regs); |
| 2056 // Adjust SP for null PC pushed in EnterStubFrame. | 2069 // Adjust SP for null PC pushed in EnterStubFrame. |
| 2057 AddImmediate(SP, kWordSize); | 2070 AddImmediate(SP, kWordSize); |
| 2058 } | 2071 } |
| 2059 | 2072 |
| 2060 | 2073 |
| 2061 void Assembler::TryAllocate(const Class& cls, | 2074 void Assembler::TryAllocate(const Class& cls, |
| 2062 Label* failure, | 2075 Label* failure, |
| 2063 bool near_jump, | |
| 2064 Register instance_reg) { | 2076 Register instance_reg) { |
| 2065 UNIMPLEMENTED(); | 2077 ASSERT(failure != NULL); |
| 2078 if (FLAG_inline_alloc) { |
| 2079 Heap* heap = Isolate::Current()->heap(); |
| 2080 const intptr_t instance_size = cls.instance_size(); |
| 2081 LoadImmediate(instance_reg, heap->TopAddress()); |
| 2082 ldr(instance_reg, Address(instance_reg, 0)); |
| 2083 AddImmediate(instance_reg, instance_size); |
| 2084 |
| 2085 // instance_reg: potential next object start. |
| 2086 LoadImmediate(TMP, heap->EndAddress()); |
| 2087 ldr(TMP, Address(TMP, 0)); |
| 2088 cmp(TMP, ShifterOperand(instance_reg)); |
| 2089 // fail if heap end unsigned less than or equal to instance_reg. |
| 2090 b(failure, LS); |
| 2091 |
| 2092 // Successfully allocated the object, now update top to point to |
| 2093 // next object start and store the class in the class field of object. |
| 2094 LoadImmediate(TMP, heap->TopAddress()); |
| 2095 str(instance_reg, Address(TMP, 0)); |
| 2096 |
| 2097 ASSERT(instance_size >= kHeapObjectTag); |
| 2098 AddImmediate(instance_reg, -instance_size + kHeapObjectTag); |
| 2099 |
| 2100 uword tags = 0; |
| 2101 tags = RawObject::SizeTag::update(instance_size, tags); |
| 2102 ASSERT(cls.id() != kIllegalCid); |
| 2103 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
| 2104 LoadImmediate(TMP, tags); |
| 2105 str(TMP, FieldAddress(instance_reg, Object::tags_offset())); |
| 2106 } else { |
| 2107 b(failure); |
| 2108 } |
| 2066 } | 2109 } |
| 2067 | 2110 |
| 2068 | 2111 |
| 2069 void Assembler::Stop(const char* message) { | 2112 void Assembler::Stop(const char* message) { |
| 2070 if (FLAG_print_stop_message) { | 2113 if (FLAG_print_stop_message) { |
| 2071 PushList((1 << R0) | (1 << IP) | (1 << LR)); // Preserve R0, IP, LR. | 2114 PushList((1 << R0) | (1 << IP) | (1 << LR)); // Preserve R0, IP, LR. |
| 2072 LoadImmediate(R0, reinterpret_cast<int32_t>(message)); | 2115 LoadImmediate(R0, reinterpret_cast<int32_t>(message)); |
| 2073 // PrintStopMessage() preserves all registers. | 2116 // PrintStopMessage() preserves all registers. |
| 2074 BranchLink(&StubCode::PrintStopMessageLabel()); // Passing message in R0. | 2117 BranchLink(&StubCode::PrintStopMessageLabel()); // Passing message in R0. |
| 2075 PopList((1 << R0) | (1 << IP) | (1 << LR)); // Restore R0, IP, LR. | 2118 PopList((1 << R0) | (1 << IP) | (1 << LR)); // Restore R0, IP, LR. |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2163 | 2206 |
| 2164 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 2207 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
| 2165 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); | 2208 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); |
| 2166 return fpu_reg_names[reg]; | 2209 return fpu_reg_names[reg]; |
| 2167 } | 2210 } |
| 2168 | 2211 |
| 2169 } // namespace dart | 2212 } // namespace dart |
| 2170 | 2213 |
| 2171 #endif // defined TARGET_ARCH_ARM | 2214 #endif // defined TARGET_ARCH_ARM |
| 2172 | 2215 |
| OLD | NEW |