blob: b7e8031bddf771f6552bacb37fbf67a8ab2b10f1 [file] [log] [blame]
Jan Voungec270732015-01-12 17:00:22 -08001//===- 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//===----------------------------------------------------------------------===//
Andrew Scull9612d322015-07-06 14:53:25 -07009///
10/// \file
Jim Stichnoth92a6e5b2015-12-02 16:52:44 -080011/// \brief Implements the AssemblerFixup class, a very basic target-independent
12/// representation of a fixup or relocation.
Andrew Scull9612d322015-07-06 14:53:25 -070013///
Jan Voungec270732015-01-12 17:00:22 -080014//===----------------------------------------------------------------------===//
15
16#include "IceFixups.h"
John Porto67f8de92015-06-25 10:14:17 -070017
Jan Voungec270732015-01-12 17:00:22 -080018#include "IceOperand.h"
19
20namespace Ice {
21
Jan Voungf644a4b2015-03-19 11:57:52 -070022const Constant *AssemblerFixup::NullSymbol = nullptr;
23
Jan Voungec270732015-01-12 17:00:22 -080024RelocOffsetT AssemblerFixup::offset() const {
Jan Voungf644a4b2015-03-19 11:57:52 -070025 if (isNullSymbol())
John Portod1bd1d32016-01-26 11:44:01 -080026 return addend_;
Jim Stichnoth3e324002016-03-08 16:18:40 -080027 if (!ValueIsSymbol) {
28 if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(ConstValue))
29 return CR->getOffset() + addend_;
30 }
John Portod1bd1d32016-01-26 11:44:01 -080031 return addend_;
Jan Voungec270732015-01-12 17:00:22 -080032}
33
Jim Stichnoth467ffe52016-03-29 15:01:06 -070034GlobalString AssemblerFixup::symbol() const {
Jim Stichnoth3e324002016-03-08 16:18:40 -080035 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));
Jim Stichnoth467ffe52016-03-29 15:01:06 -070044 return C->getLabelName();
Jan Voungec270732015-01-12 17:00:22 -080045}
46
Karl Schimpfe4289e22015-10-27 15:16:27 -070047size_t AssemblerFixup::emit(GlobalContext *Ctx, const Assembler &Asm) const {
Karl Schimpf2fee2a22015-10-22 08:19:26 -070048 static constexpr const size_t FixupSize = 4;
Jim Stichnoth20b71f52015-06-24 15:52:24 -070049 if (!BuildDefs::dump())
Karl Schimpf2fee2a22015-10-22 08:19:26 -070050 return FixupSize;
Jan Voungec270732015-01-12 17:00:22 -080051 Ostream &Str = Ctx->getStrEmit();
Karl Schimpf2fee2a22015-10-22 08:19:26 -070052 Str << "\t.long ";
Jim Stichnoth467ffe52016-03-29 15:01:06 -070053 std::string Symbol;
John Porto6e8d3fa2016-02-04 10:35:20 -080054 if (isNullSymbol()) {
Jim Stichnoth927f7cc2015-03-19 23:23:00 -070055 Str << "__Sz_AbsoluteZero";
John Porto6e8d3fa2016-02-04 10:35:20 -080056 } else {
Jim Stichnoth467ffe52016-03-29 15:01:06 -070057 Symbol = symbol().toString();
John Porto6e8d3fa2016-02-04 10:35:20 -080058 Str << Symbol;
Jim Stichnoth3e324002016-03-08 16:18:40 -080059 assert(!ValueIsSymbol);
60 if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(ConstValue)) {
Karl Schimpfd4699942016-04-02 09:55:31 -070061 if (!Asm.fixupIsPCRel(kind()) && getFlags().getUseNonsfi() &&
Jim Stichnoth467ffe52016-03-29 15:01:06 -070062 CR->getName().toString() != GlobalOffsetTable) {
Jim Stichnoth3e324002016-03-08 16:18:40 -080063 Str << "@GOTOFF";
64 }
65 }
John Porto6e8d3fa2016-02-04 10:35:20 -080066 }
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)
Karl Schimpf2fee2a22015-10-22 08:19:26 -070084 Str << " - .";
85 Str << "\n";
86 return FixupSize;
87}
88
John Porto6e8d3fa2016-02-04 10:35:20 -080089void AssemblerFixup::emitOffset(Assembler *Asm) const {
90 Asm->store(position(), offset());
91}
92
Karl Schimpfe4289e22015-10-27 15:16:27 -070093size_t AssemblerTextFixup::emit(GlobalContext *Ctx, const Assembler &) const {
Karl Schimpf2fee2a22015-10-22 08:19:26 -070094 Ctx->getStrEmit() << Message << "\n";
95 return NumBytes;
Jan Voungec270732015-01-12 17:00:22 -080096}
97
98} // end of namespace Ice