• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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() const24 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 
symbol() const34 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 
emit(GlobalContext * Ctx,const Assembler & Asm) const47 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 
emitOffset(Assembler * Asm) const89 void AssemblerFixup::emitOffset(Assembler *Asm) const {
90   Asm->store(position(), offset());
91 }
92 
emit(GlobalContext * Ctx,const Assembler &) const93 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