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