185b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe/* 285b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe * Copyright (C) 2011 The Android Open Source Project 385b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe * 485b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe * Licensed under the Apache License, Version 2.0 (the "License"); 585b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe * you may not use this file except in compliance with the License. 685b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe * You may obtain a copy of the License at 785b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe * 885b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe * http://www.apache.org/licenses/LICENSE-2.0 985b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe * 1085b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe * Unless required by applicable law or agreed to in writing, software 1185b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe * distributed under the License is distributed on an "AS IS" BASIS, 1285b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1385b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe * See the License for the specific language governing permissions and 1485b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe * limitations under the License. 1585b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe */ 1685b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe 1785b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe#ifndef ART_COMPILER_UTILS_LABEL_H_ 1885b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe#define ART_COMPILER_UTILS_LABEL_H_ 1985b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe 2085b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe#include "base/logging.h" 2185b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe#include "base/macros.h" 2285b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe 2385b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampenamespace art { 2485b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe 2585b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampeclass Assembler; 2685b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampeclass AssemblerBuffer; 2785b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampeclass AssemblerFixup; 2885b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe 2985b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampenamespace arm { 3085b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe class ArmAssembler; 3185b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe class Arm32Assembler; 3285b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe class Thumb2Assembler; 3385b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe} 3485b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampenamespace arm64 { 3585b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe class Arm64Assembler; 3685b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe} 3785b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampenamespace mips { 3885b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe class MipsAssembler; 3985b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe} 4085b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampenamespace mips64 { 4185b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe class Mips64Assembler; 4285b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe} 4385b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampenamespace x86 { 4485b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe class X86Assembler; 4585b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe class NearLabel; 4685b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe} 4785b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampenamespace x86_64 { 4885b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe class X86_64Assembler; 4985b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe class NearLabel; 5085b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe} 5185b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe 5285b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampeclass ExternalLabel { 5385b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe public: 5485b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe ExternalLabel(const char* name_in, uintptr_t address_in) 5585b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe : name_(name_in), address_(address_in) { 5685b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe DCHECK(name_in != nullptr); 5785b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe } 5885b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe 5985b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe const char* name() const { return name_; } 6085b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe uintptr_t address() const { 6185b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe return address_; 6285b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe } 6385b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe 6485b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe private: 6585b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe const char* name_; 6685b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe const uintptr_t address_; 6785b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe}; 6885b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe 6985b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampeclass Label { 7085b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe public: 7185b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe Label() : position_(0) {} 7285b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe 738c434dcc78d497e18590461700894d1c3e96013dGoran Jakovljevic Label(Label&& src) 748c434dcc78d497e18590461700894d1c3e96013dGoran Jakovljevic : position_(src.position_) { 758c434dcc78d497e18590461700894d1c3e96013dGoran Jakovljevic // We must unlink/unbind the src label when moving; if not, calling the destructor on 768c434dcc78d497e18590461700894d1c3e96013dGoran Jakovljevic // the src label would fail. 778c434dcc78d497e18590461700894d1c3e96013dGoran Jakovljevic src.position_ = 0; 788c434dcc78d497e18590461700894d1c3e96013dGoran Jakovljevic } 798c434dcc78d497e18590461700894d1c3e96013dGoran Jakovljevic 8085b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe ~Label() { 8185b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe // Assert if label is being destroyed with unresolved branches pending. 8285b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe CHECK(!IsLinked()); 8385b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe } 8485b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe 8585b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe // Returns the position for bound and linked labels. Cannot be used 8685b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe // for unused labels. 8785b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe int Position() const { 8885b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe CHECK(!IsUnused()); 8985b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe return IsBound() ? -position_ - sizeof(void*) : position_ - sizeof(void*); 9085b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe } 9185b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe 9285b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe int LinkPosition() const { 9385b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe CHECK(IsLinked()); 9485b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe return position_ - sizeof(void*); 9585b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe } 9685b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe 9785b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe bool IsBound() const { return position_ < 0; } 9885b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe bool IsUnused() const { return position_ == 0; } 9985b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe bool IsLinked() const { return position_ > 0; } 10085b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe 10185b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe private: 10285b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe int position_; 10385b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe 10485b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe void Reinitialize() { 10585b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe position_ = 0; 10685b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe } 10785b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe 10885b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe void BindTo(int position) { 10985b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe CHECK(!IsBound()); 11085b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe position_ = -position - sizeof(void*); 11185b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe CHECK(IsBound()); 11285b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe } 11385b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe 11485b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe void LinkTo(int position) { 11585b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe CHECK(!IsBound()); 11685b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe position_ = position + sizeof(void*); 11785b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe CHECK(IsLinked()); 11885b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe } 11985b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe 12085b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe friend class arm::ArmAssembler; 12185b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe friend class arm::Arm32Assembler; 12285b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe friend class arm::Thumb2Assembler; 12385b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe friend class arm64::Arm64Assembler; 12485b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe friend class mips::MipsAssembler; 12585b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe friend class mips64::Mips64Assembler; 12685b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe friend class x86::X86Assembler; 12785b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe friend class x86::NearLabel; 12885b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe friend class x86_64::X86_64Assembler; 12985b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe friend class x86_64::NearLabel; 13085b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe 13185b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe DISALLOW_COPY_AND_ASSIGN(Label); 13285b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe}; 13385b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe 13485b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe} // namespace art 13585b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe 13685b62f23fc6dfffe2ddd3ddfa74611666c9ff41dAndreas Gampe#endif // ART_COMPILER_UTILS_LABEL_H_ 137