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