99 lines
2.8 KiB
C++
99 lines
2.8 KiB
C++
|
|
//===- 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
|