blob: 191625a7c18c0a7851503c407e3480a1c96b81e5 [file] [log] [blame]
Jan Voung8acded02014-09-22 18:02:25 -07001//===- subzero/src/IceFixups.h - Assembler fixup kinds ----------*- C++ -*-===//
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 Declares generic fixup types.
Andrew Scull9612d322015-07-06 14:53:25 -070012///
Jan Voung8acded02014-09-22 18:02:25 -070013//===----------------------------------------------------------------------===//
14
15#ifndef SUBZERO_SRC_ICEFIXUPS_H
16#define SUBZERO_SRC_ICEFIXUPS_H
17
Karl Schimpfd4699942016-04-02 09:55:31 -070018#include "IceClFlags.h"
Jan Voungec270732015-01-12 17:00:22 -080019#include "IceDefs.h"
Jim Stichnoth467ffe52016-03-29 15:01:06 -070020#include "IceStringPool.h"
Jan Voung8acded02014-09-22 18:02:25 -070021
22namespace Ice {
23
Andrew Scull9612d322015-07-06 14:53:25 -070024/// Each target and container format has a different namespace of relocations.
25/// This holds the specific target+container format's relocation number.
Andrew Scull8072bae2015-09-14 16:01:26 -070026using FixupKind = uint32_t;
Jan Voung8acded02014-09-22 18:02:25 -070027
Jim Stichnoth3e324002016-03-08 16:18:40 -080028struct ELFSym;
29
Andrew Scull9612d322015-07-06 14:53:25 -070030/// Assembler fixups are positions in generated code/data that hold relocation
31/// information that needs to be processed before finalizing the code/data.
John Portod1bd1d32016-01-26 11:44:01 -080032class AssemblerFixup {
Jim Stichnothc6ead202015-02-24 09:30:30 -080033 AssemblerFixup &operator=(const AssemblerFixup &) = delete;
34
Jan Voungec270732015-01-12 17:00:22 -080035public:
Jim Stichnotheafb56c2015-06-22 10:35:22 -070036 AssemblerFixup() = default;
Jim Stichnothc6ead202015-02-24 09:30:30 -080037 AssemblerFixup(const AssemblerFixup &) = default;
Sean Kleinfc707ff2016-02-29 16:44:07 -080038 virtual ~AssemblerFixup() = default;
Jim Stichnoth3e324002016-03-08 16:18:40 -080039 intptr_t position() const { return position_; }
40 void set_position(intptr_t Position) { position_ = Position; }
Jan Voungec270732015-01-12 17:00:22 -080041
42 FixupKind kind() const { return kind_; }
43 void set_kind(FixupKind Kind) { kind_ = Kind; }
44
45 RelocOffsetT offset() const;
Jim Stichnoth467ffe52016-03-29 15:01:06 -070046 GlobalString symbol() const;
Jan Voungf644a4b2015-03-19 11:57:52 -070047
48 static const Constant *NullSymbol;
Jim Stichnoth3e324002016-03-08 16:18:40 -080049 bool isNullSymbol() const { return ConstValue == NullSymbol; }
Jan Voungf644a4b2015-03-19 11:57:52 -070050
David Sehraa0b1a12015-10-27 16:55:40 -070051 static constexpr AssemblerFixup *NoFixup = nullptr;
52
Jim Stichnoth3e324002016-03-08 16:18:40 -080053 bool valueIsSymbol() const { return ValueIsSymbol; }
54 void set_value(const Constant *Value) {
55 ValueIsSymbol = false;
56 ConstValue = Value;
57 }
58 void set_value(const ELFSym *Value) {
59 ValueIsSymbol = true;
60 SymbolValue = Value;
61 }
62 const ELFSym *getSymbolValue() const {
63 assert(ValueIsSymbol);
64 return SymbolValue;
65 }
Jan Voungec270732015-01-12 17:00:22 -080066
John Portod1bd1d32016-01-26 11:44:01 -080067 void set_addend(RelocOffsetT Addend) { addend_ = Addend; }
John Porto6e8d3fa2016-02-04 10:35:20 -080068 RelocOffsetT get_addend() const { return addend_; }
John Portod1bd1d32016-01-26 11:44:01 -080069
Karl Schimpf2fee2a22015-10-22 08:19:26 -070070 /// Emits fixup, then returns the number of bytes to skip.
Karl Schimpfe4289e22015-10-27 15:16:27 -070071 virtual size_t emit(GlobalContext *Ctx, const Assembler &Asm) const;
Jan Voungec270732015-01-12 17:00:22 -080072
John Porto6e8d3fa2016-02-04 10:35:20 -080073 /// Emits offset() (little endian) in position_. If your fixup requires
74 /// something smarter, you must create your own fixup type.
75 virtual void emitOffset(Assembler *Asm) const;
76
Jan Voungec270732015-01-12 17:00:22 -080077private:
Jim Stichnotheafb56c2015-06-22 10:35:22 -070078 intptr_t position_ = 0;
79 FixupKind kind_ = 0;
John Portod1bd1d32016-01-26 11:44:01 -080080 // An offset addend to the fixup offset (as returned by offset()), in case the
81 // assembler needs to adjust it.
82 RelocOffsetT addend_ = 0;
Jim Stichnoth3e324002016-03-08 16:18:40 -080083
84 // Tagged union that holds either a Constant or ELFSym pointer, depending on
85 // the ValueIsSymbol tag.
86 bool ValueIsSymbol = false;
87 union {
88 const Constant *ConstValue;
89 const ELFSym *SymbolValue;
90 };
Jan Voung8acded02014-09-22 18:02:25 -070091};
92
Karl Schimpf2fee2a22015-10-22 08:19:26 -070093/// Extends a fixup to be textual. That is, it emits text instead of a sequence
94/// of bytes. This class is used as a fallback for unimplemented emitIAS
95/// methods, allowing them to generate compilable assembly code.
96class AssemblerTextFixup : public AssemblerFixup {
97 AssemblerTextFixup() = delete;
98 AssemblerTextFixup(const AssemblerTextFixup &) = delete;
99 AssemblerTextFixup &operator=(const AssemblerTextFixup &) = delete;
100
101public:
102 AssemblerTextFixup(const std::string &Message, size_t NumBytes)
103 : AssemblerFixup(), Message(Message), NumBytes(NumBytes) {}
104 ~AssemblerTextFixup() = default;
Karl Schimpfe4289e22015-10-27 15:16:27 -0700105 size_t emit(GlobalContext *Ctx, const Assembler &Asm) const override;
Karl Schimpf2fee2a22015-10-22 08:19:26 -0700106
107private:
108 const std::string Message;
109 const size_t NumBytes;
110};
111
Andrew Scull8072bae2015-09-14 16:01:26 -0700112using FixupList = std::vector<AssemblerFixup>;
113using FixupRefList = std::vector<AssemblerFixup *>;
Jan Voungec270732015-01-12 17:00:22 -0800114
Jan Voung8acded02014-09-22 18:02:25 -0700115} // end of namespace Ice
116
117#endif // SUBZERO_SRC_ICEFIXUPS_H