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 mips {
33 class MipsAssembler;
34 class MipsLabel;
35 }  // namespace mips
36 namespace mips64 {
37 class Mips64Assembler;
38 class Mips64Label;
39 }  // namespace mips64
40 namespace x86 {
41 class X86Assembler;
42 class NearLabel;
43 }  // namespace x86
44 namespace x86_64 {
45 class X86_64Assembler;
46 class NearLabel;
47 }  // namespace x86_64
48 
49 class ExternalLabel {
50  public:
ExternalLabel(const char * name_in,uintptr_t address_in)51   ExternalLabel(const char* name_in, uintptr_t address_in)
52       : name_(name_in), address_(address_in) {
53     DCHECK(name_in != nullptr);
54   }
55 
name()56   const char* name() const { return name_; }
address()57   uintptr_t address() const {
58     return address_;
59   }
60 
61  private:
62   const char* name_;
63   const uintptr_t address_;
64 };
65 
66 class Label {
67  public:
Label()68   Label() : position_(0) {}
69 
Label(Label && src)70   Label(Label&& src)
71       : position_(src.position_) {
72     // We must unlink/unbind the src label when moving; if not, calling the destructor on
73     // the src label would fail.
74     src.position_ = 0;
75   }
76 
~Label()77   ~Label() {
78     // Assert if label is being destroyed with unresolved branches pending.
79     CHECK(!IsLinked());
80   }
81 
82   // Returns the position for bound and linked labels. Cannot be used
83   // for unused labels.
Position()84   int Position() const {
85     CHECK(!IsUnused());
86     return IsBound() ? -position_ - sizeof(void*) : position_ - sizeof(void*);
87   }
88 
LinkPosition()89   int LinkPosition() const {
90     CHECK(IsLinked());
91     return position_ - sizeof(void*);
92   }
93 
IsBound()94   bool IsBound() const { return position_ < 0; }
IsUnused()95   bool IsUnused() const { return position_ == 0; }
IsLinked()96   bool IsLinked() const { return position_ > 0; }
97 
98  private:
99   int position_;
100 
Reinitialize()101   void Reinitialize() {
102     position_ = 0;
103   }
104 
BindTo(int position)105   void BindTo(int position) {
106     CHECK(!IsBound());
107     position_ = -position - sizeof(void*);
108     CHECK(IsBound());
109   }
110 
LinkTo(int position)111   void LinkTo(int position) {
112     CHECK(!IsBound());
113     position_ = position + sizeof(void*);
114     CHECK(IsLinked());
115   }
116 
117   friend class arm64::Arm64Assembler;
118   friend class mips::MipsAssembler;
119   friend class mips::MipsLabel;
120   friend class mips64::Mips64Assembler;
121   friend class mips64::Mips64Label;
122   friend class x86::X86Assembler;
123   friend class x86::NearLabel;
124   friend class x86_64::X86_64Assembler;
125   friend class x86_64::NearLabel;
126 
127   DISALLOW_COPY_AND_ASSIGN(Label);
128 };
129 
130 }  // namespace art
131 
132 #endif  // ART_COMPILER_UTILS_LABEL_H_
133