diff options
author | 2015-09-09 13:15:38 -0700 | |
---|---|---|
committer | 2015-09-17 14:41:52 -0700 | |
commit | 85b62f23fc6dfffe2ddd3ddfa74611666c9ff41d (patch) | |
tree | c916b01b1608558a7d8c9d100274c4c6b6706386 /compiler/utils | |
parent | 6766eae2d91e894b4ceab9f29cc983900e7bc0c7 (diff) |
ART: Refactor intrinsics slow-paths
Refactor slow paths so that there is a default implementation for
common cases (only arm64 with vixl is special). Write a generic
intrinsic slow-path that can be reused for the specific architectures.
Move helper functions into CodeGenerator so that they are accessible.
Change-Id: Ibd788dce432601c6a9f7e6f13eab31f28dcb8550
Diffstat (limited to 'compiler/utils')
-rw-r--r-- | compiler/utils/arm/assembler_arm.h | 6 | ||||
-rw-r--r-- | compiler/utils/arm64/assembler_arm64.h | 7 | ||||
-rw-r--r-- | compiler/utils/assembler.h | 104 | ||||
-rw-r--r-- | compiler/utils/label.h | 129 | ||||
-rw-r--r-- | compiler/utils/mips/assembler_mips.h | 7 | ||||
-rw-r--r-- | compiler/utils/mips64/assembler_mips64.h | 5 | ||||
-rw-r--r-- | compiler/utils/x86/assembler_x86.h | 5 | ||||
-rw-r--r-- | compiler/utils/x86_64/assembler_x86_64.h | 5 |
8 files changed, 163 insertions, 105 deletions
diff --git a/compiler/utils/arm/assembler_arm.h b/compiler/utils/arm/assembler_arm.h index a4d1837748..967b191d32 100644 --- a/compiler/utils/arm/assembler_arm.h +++ b/compiler/utils/arm/assembler_arm.h @@ -834,8 +834,6 @@ class ArmAssembler : public Assembler { static bool IsInstructionForExceptionHandling(uintptr_t pc); - virtual void Bind(Label* label) = 0; - virtual void CompareAndBranchIfZero(Register r, Label* label) = 0; virtual void CompareAndBranchIfNonZero(Register r, Label* label) = 0; @@ -985,6 +983,10 @@ class ArmAssembler : public Assembler { } } + void Jump(Label* label) OVERRIDE { + b(label); + } + protected: // Returns whether or not the given register is used for passing parameters. static int RegisterCompare(const Register* reg1, const Register* reg2) { diff --git a/compiler/utils/arm64/assembler_arm64.h b/compiler/utils/arm64/assembler_arm64.h index 8e85fe96ab..7b25b8f3f5 100644 --- a/compiler/utils/arm64/assembler_arm64.h +++ b/compiler/utils/arm64/assembler_arm64.h @@ -193,6 +193,13 @@ class Arm64Assembler FINAL : public Assembler { // Unpoison a heap reference contained in `reg` if heap poisoning is enabled. void MaybeUnpoisonHeapReference(vixl::Register reg); + void Bind(Label* label ATTRIBUTE_UNUSED) OVERRIDE { + UNIMPLEMENTED(FATAL) << "Do not use Bind for ARM64"; + } + void Jump(Label* label ATTRIBUTE_UNUSED) OVERRIDE { + UNIMPLEMENTED(FATAL) << "Do not use Jump for ARM64"; + } + private: static vixl::Register reg_x(int code) { CHECK(code < kNumberOfXRegisters) << code; diff --git a/compiler/utils/assembler.h b/compiler/utils/assembler.h index 64d76b881d..1088cb1bbd 100644 --- a/compiler/utils/assembler.h +++ b/compiler/utils/assembler.h @@ -23,6 +23,7 @@ #include "base/logging.h" #include "base/macros.h" #include "arm/constants_arm.h" +#include "label.h" #include "managed_register.h" #include "memory_region.h" #include "mips/constants_mips.h" @@ -35,106 +36,6 @@ namespace art { class Assembler; class AssemblerBuffer; -class AssemblerFixup; - -namespace arm { - class ArmAssembler; - class Arm32Assembler; - class Thumb2Assembler; -} -namespace arm64 { - class Arm64Assembler; -} -namespace mips { - class MipsAssembler; -} -namespace mips64 { - class Mips64Assembler; -} -namespace x86 { - class X86Assembler; - class NearLabel; -} -namespace x86_64 { - class X86_64Assembler; - class NearLabel; -} - -class ExternalLabel { - public: - ExternalLabel(const char* name_in, uintptr_t address_in) - : name_(name_in), address_(address_in) { - DCHECK(name_in != nullptr); - } - - const char* name() const { return name_; } - uintptr_t address() const { - return address_; - } - - private: - const char* name_; - const uintptr_t address_; -}; - -class Label { - public: - Label() : position_(0) {} - - ~Label() { - // Assert if label is being destroyed with unresolved branches pending. - CHECK(!IsLinked()); - } - - // Returns the position for bound and linked labels. Cannot be used - // for unused labels. - int Position() const { - CHECK(!IsUnused()); - return IsBound() ? -position_ - sizeof(void*) : position_ - sizeof(void*); - } - - int LinkPosition() const { - CHECK(IsLinked()); - return position_ - sizeof(void*); - } - - bool IsBound() const { return position_ < 0; } - bool IsUnused() const { return position_ == 0; } - bool IsLinked() const { return position_ > 0; } - - private: - int position_; - - void Reinitialize() { - position_ = 0; - } - - void BindTo(int position) { - CHECK(!IsBound()); - position_ = -position - sizeof(void*); - CHECK(IsBound()); - } - - void LinkTo(int position) { - CHECK(!IsBound()); - position_ = position + sizeof(void*); - CHECK(IsLinked()); - } - - friend class arm::ArmAssembler; - friend class arm::Arm32Assembler; - friend class arm::Thumb2Assembler; - friend class arm64::Arm64Assembler; - friend class mips::MipsAssembler; - friend class mips64::Mips64Assembler; - friend class x86::X86Assembler; - friend class x86::NearLabel; - friend class x86_64::X86_64Assembler; - friend class x86_64::NearLabel; - - DISALLOW_COPY_AND_ASSIGN(Label); -}; - // Assembler fixups are positions in generated code that require processing // after the code has been copied to executable memory. This includes building @@ -534,6 +435,9 @@ class Assembler { // and branch to a ExceptionSlowPath if it is. virtual void ExceptionPoll(ManagedRegister scratch, size_t stack_adjust) = 0; + virtual void Bind(Label* label) = 0; + virtual void Jump(Label* label) = 0; + virtual ~Assembler() {} /** diff --git a/compiler/utils/label.h b/compiler/utils/label.h new file mode 100644 index 0000000000..ff4a1a4333 --- /dev/null +++ b/compiler/utils/label.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_COMPILER_UTILS_LABEL_H_ +#define ART_COMPILER_UTILS_LABEL_H_ + +#include "base/logging.h" +#include "base/macros.h" + +namespace art { + +class Assembler; +class AssemblerBuffer; +class AssemblerFixup; + +namespace arm { + class ArmAssembler; + class Arm32Assembler; + class Thumb2Assembler; +} +namespace arm64 { + class Arm64Assembler; +} +namespace mips { + class MipsAssembler; +} +namespace mips64 { + class Mips64Assembler; +} +namespace x86 { + class X86Assembler; + class NearLabel; +} +namespace x86_64 { + class X86_64Assembler; + class NearLabel; +} + +class ExternalLabel { + public: + ExternalLabel(const char* name_in, uintptr_t address_in) + : name_(name_in), address_(address_in) { + DCHECK(name_in != nullptr); + } + + const char* name() const { return name_; } + uintptr_t address() const { + return address_; + } + + private: + const char* name_; + const uintptr_t address_; +}; + +class Label { + public: + Label() : position_(0) {} + + ~Label() { + // Assert if label is being destroyed with unresolved branches pending. + CHECK(!IsLinked()); + } + + // Returns the position for bound and linked labels. Cannot be used + // for unused labels. + int Position() const { + CHECK(!IsUnused()); + return IsBound() ? -position_ - sizeof(void*) : position_ - sizeof(void*); + } + + int LinkPosition() const { + CHECK(IsLinked()); + return position_ - sizeof(void*); + } + + bool IsBound() const { return position_ < 0; } + bool IsUnused() const { return position_ == 0; } + bool IsLinked() const { return position_ > 0; } + + private: + int position_; + + void Reinitialize() { + position_ = 0; + } + + void BindTo(int position) { + CHECK(!IsBound()); + position_ = -position - sizeof(void*); + CHECK(IsBound()); + } + + void LinkTo(int position) { + CHECK(!IsBound()); + position_ = position + sizeof(void*); + CHECK(IsLinked()); + } + + friend class arm::ArmAssembler; + friend class arm::Arm32Assembler; + friend class arm::Thumb2Assembler; + friend class arm64::Arm64Assembler; + friend class mips::MipsAssembler; + friend class mips64::Mips64Assembler; + friend class x86::X86Assembler; + friend class x86::NearLabel; + friend class x86_64::X86_64Assembler; + friend class x86_64::NearLabel; + + DISALLOW_COPY_AND_ASSIGN(Label); +}; + +} // namespace art + +#endif // ART_COMPILER_UTILS_LABEL_H_ diff --git a/compiler/utils/mips/assembler_mips.h b/compiler/utils/mips/assembler_mips.h index 6c8b162d62..378a59cb3e 100644 --- a/compiler/utils/mips/assembler_mips.h +++ b/compiler/utils/mips/assembler_mips.h @@ -150,6 +150,13 @@ class MipsAssembler FINAL : public Assembler { void EmitJump(Label* label, bool link); void Bind(Label* label, bool is_jump); + void Bind(Label* label) OVERRIDE { + Bind(label, false); + } + void Jump(Label* label) OVERRIDE { + EmitJump(label, false); + } + // // Overridden common assembler high-level functionality // diff --git a/compiler/utils/mips64/assembler_mips64.h b/compiler/utils/mips64/assembler_mips64.h index a120abb238..c170313728 100644 --- a/compiler/utils/mips64/assembler_mips64.h +++ b/compiler/utils/mips64/assembler_mips64.h @@ -240,7 +240,10 @@ class Mips64Assembler FINAL : public Assembler { void Addiu32(GpuRegister rt, GpuRegister rs, int32_t value, GpuRegister rtmp = AT); void Daddiu64(GpuRegister rt, GpuRegister rs, int64_t value, GpuRegister rtmp = AT); // MIPS64 - void Bind(Label* label); // R6 + void Bind(Label* label) OVERRIDE; // R6 + void Jump(Label* label) OVERRIDE { + B(label); + } void B(Label* label); // R6 void Jalr(Label* label, GpuRegister indirect_reg = RA); // R6 // TODO: implement common for R6 and non-R6 interface for conditional branches? diff --git a/compiler/utils/x86/assembler_x86.h b/compiler/utils/x86/assembler_x86.h index af786637a6..93ecdf52fe 100644 --- a/compiler/utils/x86/assembler_x86.h +++ b/compiler/utils/x86/assembler_x86.h @@ -600,7 +600,10 @@ class X86Assembler FINAL : public Assembler { // int PreferredLoopAlignment() { return 16; } void Align(int alignment, int offset); - void Bind(Label* label); + void Bind(Label* label) OVERRIDE; + void Jump(Label* label) OVERRIDE { + jmp(label); + } void Bind(NearLabel* label); // diff --git a/compiler/utils/x86_64/assembler_x86_64.h b/compiler/utils/x86_64/assembler_x86_64.h index c8875e87df..255f551675 100644 --- a/compiler/utils/x86_64/assembler_x86_64.h +++ b/compiler/utils/x86_64/assembler_x86_64.h @@ -680,7 +680,10 @@ class X86_64Assembler FINAL : public Assembler { // int PreferredLoopAlignment() { return 16; } void Align(int alignment, int offset); - void Bind(Label* label); + void Bind(Label* label) OVERRIDE; + void Jump(Label* label) OVERRIDE { + jmp(label); + } void Bind(NearLabel* label); // |