Home | History | Annotate | Download | only in utils
      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:
     53   ExternalLabel(const char* name_in, uintptr_t address_in)
     54       : name_(name_in), address_(address_in) {
     55     DCHECK(name_in != nullptr);
     56   }
     57 
     58   const char* name() const { return name_; }
     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:
     70   Label() : position_(0) {}
     71 
     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 
     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.
     86   int Position() const {
     87     CHECK(!IsUnused());
     88     return IsBound() ? -position_ - sizeof(void*) : position_ - sizeof(void*);
     89   }
     90 
     91   int LinkPosition() const {
     92     CHECK(IsLinked());
     93     return position_ - sizeof(void*);
     94   }
     95 
     96   bool IsBound() const { return position_ < 0; }
     97   bool IsUnused() const { return position_ == 0; }
     98   bool IsLinked() const { return position_ > 0; }
     99 
    100  private:
    101   int position_;
    102 
    103   void Reinitialize() {
    104     position_ = 0;
    105   }
    106 
    107   void BindTo(int position) {
    108     CHECK(!IsBound());
    109     position_ = -position - sizeof(void*);
    110     CHECK(IsBound());
    111   }
    112 
    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