1*03ce13f7SAndroid Build Coastguard Worker //===- subzero/src/IceFixups.cpp - Implementation of Assembler Fixups -----===// 2*03ce13f7SAndroid Build Coastguard Worker // 3*03ce13f7SAndroid Build Coastguard Worker // The Subzero Code Generator 4*03ce13f7SAndroid Build Coastguard Worker // 5*03ce13f7SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*03ce13f7SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*03ce13f7SAndroid Build Coastguard Worker // 8*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*03ce13f7SAndroid Build Coastguard Worker /// 10*03ce13f7SAndroid Build Coastguard Worker /// \file 11*03ce13f7SAndroid Build Coastguard Worker /// \brief Implements the AssemblerFixup class, a very basic target-independent 12*03ce13f7SAndroid Build Coastguard Worker /// representation of a fixup or relocation. 13*03ce13f7SAndroid Build Coastguard Worker /// 14*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 15*03ce13f7SAndroid Build Coastguard Worker 16*03ce13f7SAndroid Build Coastguard Worker #include "IceFixups.h" 17*03ce13f7SAndroid Build Coastguard Worker 18*03ce13f7SAndroid Build Coastguard Worker #include "IceOperand.h" 19*03ce13f7SAndroid Build Coastguard Worker 20*03ce13f7SAndroid Build Coastguard Worker namespace Ice { 21*03ce13f7SAndroid Build Coastguard Worker 22*03ce13f7SAndroid Build Coastguard Worker const Constant *AssemblerFixup::NullSymbol = nullptr; 23*03ce13f7SAndroid Build Coastguard Worker offset() const24*03ce13f7SAndroid Build Coastguard WorkerRelocOffsetT AssemblerFixup::offset() const { 25*03ce13f7SAndroid Build Coastguard Worker if (isNullSymbol()) 26*03ce13f7SAndroid Build Coastguard Worker return addend_; 27*03ce13f7SAndroid Build Coastguard Worker if (!ValueIsSymbol) { 28*03ce13f7SAndroid Build Coastguard Worker if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(ConstValue)) 29*03ce13f7SAndroid Build Coastguard Worker return CR->getOffset() + addend_; 30*03ce13f7SAndroid Build Coastguard Worker } 31*03ce13f7SAndroid Build Coastguard Worker return addend_; 32*03ce13f7SAndroid Build Coastguard Worker } 33*03ce13f7SAndroid Build Coastguard Worker symbol() const34*03ce13f7SAndroid Build Coastguard WorkerGlobalString AssemblerFixup::symbol() const { 35*03ce13f7SAndroid Build Coastguard Worker assert(!isNullSymbol()); 36*03ce13f7SAndroid Build Coastguard Worker assert(!ValueIsSymbol); 37*03ce13f7SAndroid Build Coastguard Worker const Constant *C = ConstValue; 38*03ce13f7SAndroid Build Coastguard Worker if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(C)) { 39*03ce13f7SAndroid Build Coastguard Worker return CR->getName(); 40*03ce13f7SAndroid Build Coastguard Worker } 41*03ce13f7SAndroid Build Coastguard Worker // NOTE: currently only float/doubles are put into constant pools. In the 42*03ce13f7SAndroid Build Coastguard Worker // future we may put integers as well. 43*03ce13f7SAndroid Build Coastguard Worker assert(llvm::isa<ConstantFloat>(C) || llvm::isa<ConstantDouble>(C)); 44*03ce13f7SAndroid Build Coastguard Worker return C->getLabelName(); 45*03ce13f7SAndroid Build Coastguard Worker } 46*03ce13f7SAndroid Build Coastguard Worker emit(GlobalContext * Ctx,const Assembler & Asm) const47*03ce13f7SAndroid Build Coastguard Workersize_t AssemblerFixup::emit(GlobalContext *Ctx, const Assembler &Asm) const { 48*03ce13f7SAndroid Build Coastguard Worker static constexpr const size_t FixupSize = 4; 49*03ce13f7SAndroid Build Coastguard Worker if (!BuildDefs::dump()) 50*03ce13f7SAndroid Build Coastguard Worker return FixupSize; 51*03ce13f7SAndroid Build Coastguard Worker Ostream &Str = Ctx->getStrEmit(); 52*03ce13f7SAndroid Build Coastguard Worker Str << "\t.long "; 53*03ce13f7SAndroid Build Coastguard Worker std::string Symbol; 54*03ce13f7SAndroid Build Coastguard Worker if (isNullSymbol()) { 55*03ce13f7SAndroid Build Coastguard Worker Str << "__Sz_AbsoluteZero"; 56*03ce13f7SAndroid Build Coastguard Worker } else { 57*03ce13f7SAndroid Build Coastguard Worker Symbol = symbol().toString(); 58*03ce13f7SAndroid Build Coastguard Worker Str << Symbol; 59*03ce13f7SAndroid Build Coastguard Worker assert(!ValueIsSymbol); 60*03ce13f7SAndroid Build Coastguard Worker } 61*03ce13f7SAndroid Build Coastguard Worker 62*03ce13f7SAndroid Build Coastguard Worker assert(Asm.load<RelocOffsetT>(position()) == 0); 63*03ce13f7SAndroid Build Coastguard Worker 64*03ce13f7SAndroid Build Coastguard Worker RelocOffsetT Offset = offset(); 65*03ce13f7SAndroid Build Coastguard Worker if (Offset != 0) { 66*03ce13f7SAndroid Build Coastguard Worker if (Offset > 0) { 67*03ce13f7SAndroid Build Coastguard Worker Str << " + " << Offset; 68*03ce13f7SAndroid Build Coastguard Worker } else { 69*03ce13f7SAndroid Build Coastguard Worker assert(Offset != std::numeric_limits<RelocOffsetT>::lowest()); 70*03ce13f7SAndroid Build Coastguard Worker Str << " - " << -Offset; 71*03ce13f7SAndroid Build Coastguard Worker } 72*03ce13f7SAndroid Build Coastguard Worker } 73*03ce13f7SAndroid Build Coastguard Worker 74*03ce13f7SAndroid Build Coastguard Worker // We need to emit the '- .' for PCRel fixups. Even if the relocation kind() 75*03ce13f7SAndroid Build Coastguard Worker // is not PCRel, we emit the '- .' for the _GLOBAL_OFFSET_TABLE_. 76*03ce13f7SAndroid Build Coastguard Worker // TODO(jpp): create fixups wrt the GOT with the right fixup kind. 77*03ce13f7SAndroid Build Coastguard Worker if (Asm.fixupIsPCRel(kind()) || Symbol == GlobalOffsetTable) 78*03ce13f7SAndroid Build Coastguard Worker Str << " - ."; 79*03ce13f7SAndroid Build Coastguard Worker Str << "\n"; 80*03ce13f7SAndroid Build Coastguard Worker return FixupSize; 81*03ce13f7SAndroid Build Coastguard Worker } 82*03ce13f7SAndroid Build Coastguard Worker emitOffset(Assembler * Asm) const83*03ce13f7SAndroid Build Coastguard Workervoid AssemblerFixup::emitOffset(Assembler *Asm) const { 84*03ce13f7SAndroid Build Coastguard Worker Asm->store(position(), offset()); 85*03ce13f7SAndroid Build Coastguard Worker } 86*03ce13f7SAndroid Build Coastguard Worker emit(GlobalContext * Ctx,const Assembler &) const87*03ce13f7SAndroid Build Coastguard Workersize_t AssemblerTextFixup::emit(GlobalContext *Ctx, const Assembler &) const { 88*03ce13f7SAndroid Build Coastguard Worker Ctx->getStrEmit() << Message << "\n"; 89*03ce13f7SAndroid Build Coastguard Worker return NumBytes; 90*03ce13f7SAndroid Build Coastguard Worker } 91*03ce13f7SAndroid Build Coastguard Worker 92*03ce13f7SAndroid Build Coastguard Worker } // end of namespace Ice 93