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
diff --git a/compiler/utils/label.h b/compiler/utils/label.h
new file mode 100644
index 0000000..ff4a1a4
--- /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_