1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ART_COMPILER_UTILS_LABEL_H_
18 #define ART_COMPILER_UTILS_LABEL_H_
19 
20 #include <android-base/logging.h>
21 #include <android-base/macros.h>
22 
23 namespace art {
24 
25 class Assembler;
26 class AssemblerBuffer;
27 class AssemblerFixup;
28 
29 namespace arm64 {
30 class Arm64Assembler;
31 }  // namespace arm64
32 namespace x86 {
33 class X86Assembler;
34 class NearLabel;
35 }  // namespace x86
36 namespace x86_64 {
37 class X86_64Assembler;
38 class NearLabel;
39 }  // namespace x86_64
40 
41 class ExternalLabel {
42  public:
ExternalLabel(const char * name_in,uintptr_t address_in)43   ExternalLabel(const char* name_in, uintptr_t address_in)
44       : name_(name_in), address_(address_in) {
45     DCHECK(name_in != nullptr);
46   }
47 
name()48   const char* name() const { return name_; }
address()49   uintptr_t address() const {
50     return address_;
51   }
52 
53  private:
54   const char* name_;
55   const uintptr_t address_;
56 };
57 
58 class Label {
59  public:
Label()60   Label() : position_(0) {}
61 
Label(Label && src)62   Label(Label&& src)
63       : position_(src.position_) {
64     // We must unlink/unbind the src label when moving; if not, calling the destructor on
65     // the src label would fail.
66     src.position_ = 0;
67   }
68 
~Label()69   ~Label() {
70     // Assert if label is being destroyed with unresolved branches pending.
71     CHECK(!IsLinked());
72   }
73 
74   // Returns the position for bound and linked labels. Cannot be used
75   // for unused labels.
Position()76   int Position() const {
77     CHECK(!IsUnused());
78     return IsBound() ? -position_ - sizeof(void*) : position_ - sizeof(void*);
79   }
80 
LinkPosition()81   int LinkPosition() const {
82     CHECK(IsLinked());
83     return position_ - sizeof(void*);
84   }
85 
IsBound()86   bool IsBound() const { return position_ < 0; }
IsUnused()87   bool IsUnused() const { return position_ == 0; }
IsLinked()88   bool IsLinked() const { return position_ > 0; }
89 
90  private:
91   int position_;
92 
Reinitialize()93   void Reinitialize() {
94     position_ = 0;
95   }
96 
BindTo(int position)97   void BindTo(int position) {
98     CHECK(!IsBound());
99     position_ = -position - sizeof(void*);
100     CHECK(IsBound());
101   }
102 
LinkTo(int position)103   void LinkTo(int position) {
104     CHECK(!IsBound());
105     position_ = position + sizeof(void*);
106     CHECK(IsLinked());
107   }
108 
109   friend class arm64::Arm64Assembler;
110   friend class x86::X86Assembler;
111   friend class x86::NearLabel;
112   friend class x86_64::X86_64Assembler;
113   friend class x86_64::NearLabel;
114 
115   DISALLOW_COPY_AND_ASSIGN(Label);
116 };
117 
118 }  // namespace art
119 
120 #endif  // ART_COMPILER_UTILS_LABEL_H_
121