Home | History | Annotate | Download | only in src
      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 
     24 RelocOffsetT 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 
     34 GlobalString 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 
     47 size_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     if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(ConstValue)) {
     61       if (!Asm.fixupIsPCRel(kind()) && getFlags().getUseNonsfi() &&
     62           CR->getName().toString() != GlobalOffsetTable) {
     63         Str << "@GOTOFF";
     64       }
     65     }
     66   }
     67 
     68   assert(Asm.load<RelocOffsetT>(position()) == 0);
     69 
     70   RelocOffsetT Offset = offset();
     71   if (Offset != 0) {
     72     if (Offset > 0) {
     73       Str << " + " << Offset;
     74     } else {
     75       assert(Offset != std::numeric_limits<RelocOffsetT>::lowest());
     76       Str << " - " << -Offset;
     77     }
     78   }
     79 
     80   // We need to emit the '- .' for PCRel fixups. Even if the relocation kind()
     81   // is not PCRel, we emit the '- .' for the _GLOBAL_OFFSET_TABLE_.
     82   // TODO(jpp): create fixups wrt the GOT with the right fixup kind.
     83   if (Asm.fixupIsPCRel(kind()) || Symbol == GlobalOffsetTable)
     84     Str << " - .";
     85   Str << "\n";
     86   return FixupSize;
     87 }
     88 
     89 void AssemblerFixup::emitOffset(Assembler *Asm) const {
     90   Asm->store(position(), offset());
     91 }
     92 
     93 size_t AssemblerTextFixup::emit(GlobalContext *Ctx, const Assembler &) const {
     94   Ctx->getStrEmit() << Message << "\n";
     95   return NumBytes;
     96 }
     97 
     98 } // end of namespace Ice
     99