//===- subzero/src/IceFixups.cpp - Implementation of Assembler Fixups -----===// // // The Subzero Code Generator // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// /// /// \file /// \brief Implements the AssemblerFixup class, a very basic target-independent /// representation of a fixup or relocation. /// //===----------------------------------------------------------------------===// #include "IceFixups.h" #include "IceOperand.h" namespace Ice { const Constant *AssemblerFixup::NullSymbol = nullptr; RelocOffsetT AssemblerFixup::offset() const { if (isNullSymbol()) return addend_; if (!ValueIsSymbol) { if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(ConstValue)) return CR->getOffset() + addend_; } return addend_; } GlobalString AssemblerFixup::symbol() const { assert(!isNullSymbol()); assert(!ValueIsSymbol); const Constant *C = ConstValue; if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(C)) { return CR->getName(); } // NOTE: currently only float/doubles are put into constant pools. In the // future we may put integers as well. assert(llvm::isa<ConstantFloat>(C) || llvm::isa<ConstantDouble>(C)); return C->getLabelName(); } size_t AssemblerFixup::emit(GlobalContext *Ctx, const Assembler &Asm) const { static constexpr const size_t FixupSize = 4; if (!BuildDefs::dump()) return FixupSize; Ostream &Str = Ctx->getStrEmit(); Str << "\t.long "; std::string Symbol; if (isNullSymbol()) { Str << "__Sz_AbsoluteZero"; } else { Symbol = symbol().toString(); Str << Symbol; assert(!ValueIsSymbol); if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(ConstValue)) { if (!Asm.fixupIsPCRel(kind()) && getFlags().getUseNonsfi() && CR->getName().toString() != GlobalOffsetTable) { Str << "@GOTOFF"; } } } assert(Asm.load<RelocOffsetT>(position()) == 0); RelocOffsetT Offset = offset(); if (Offset != 0) { if (Offset > 0) { Str << " + " << Offset; } else { assert(Offset != std::numeric_limits<RelocOffsetT>::lowest()); Str << " - " << -Offset; } } // We need to emit the '- .' for PCRel fixups. Even if the relocation kind() // is not PCRel, we emit the '- .' for the _GLOBAL_OFFSET_TABLE_. // TODO(jpp): create fixups wrt the GOT with the right fixup kind. if (Asm.fixupIsPCRel(kind()) || Symbol == GlobalOffsetTable) Str << " - ."; Str << "\n"; return FixupSize; } void AssemblerFixup::emitOffset(Assembler *Asm) const { Asm->store(position(), offset()); } size_t AssemblerTextFixup::emit(GlobalContext *Ctx, const Assembler &) const { Ctx->getStrEmit() << Message << "\n"; return NumBytes; } } // end of namespace Ice