summaryrefslogtreecommitdiff
path: root/include/llvm/Target/TargetAsmBackend.h
blob: 7a1689d0873655e2f7bd0a2dc7ab7ff9577dddd4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//===-- llvm/Target/TargetAsmBackend.h - Target Asm Backend -----*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_TARGET_TARGETASMBACKEND_H
#define LLVM_TARGET_TARGETASMBACKEND_H

#include "llvm/System/DataTypes.h"

namespace llvm {
class MCDataFragment;
class MCFixup;
class MCInst;
class MCInstFragment;
class MCObjectWriter;
class MCSection;
template<typename T>
class SmallVectorImpl;
class Target;
class raw_ostream;

/// TargetAsmBackend - Generic interface to target specific assembler backends.
class TargetAsmBackend {
  TargetAsmBackend(const TargetAsmBackend &);   // DO NOT IMPLEMENT
  void operator=(const TargetAsmBackend &);  // DO NOT IMPLEMENT
protected: // Can only create subclasses.
  TargetAsmBackend(const Target &);

  /// TheTarget - The Target that this machine was created for.
  const Target &TheTarget;

  unsigned HasAbsolutizedSet : 1;
  unsigned HasReliableSymbolDifference : 1;
  unsigned HasScatteredSymbols : 1;

public:
  virtual ~TargetAsmBackend();

  const Target &getTarget() const { return TheTarget; }

  /// createObjectWriter - Create a new MCObjectWriter instance for use by the
  /// assembler backend to emit the final object file.
  virtual MCObjectWriter *createObjectWriter(raw_ostream &OS) const = 0;

  /// hasAbsolutizedSet - Check whether this target "absolutizes"
  /// assignments. That is, given code like:
  ///   a:
  ///   ...
  ///   b:
  ///   tmp = a - b
  ///       .long tmp
  /// will the value of 'tmp' be a relocatable expression, or the assembly time
  /// value of L0 - L1. This distinction is only relevant for platforms that
  /// support scattered symbols, since in the absence of scattered symbols (a -
  /// b) cannot change after assembly.
  bool hasAbsolutizedSet() const { return HasAbsolutizedSet; }

  /// hasReliableSymbolDifference - Check whether this target implements
  /// accurate relocations for differences between symbols. If not, differences
  /// between symbols will always be relocatable expressions and any references
  /// to temporary symbols will be assumed to be in the same atom, unless they
  /// reside in a different section.
  ///
  /// This should always be true (since it results in fewer relocations with no
  /// loss of functionality), but is currently supported as a way to maintain
  /// exact object compatibility with Darwin 'as' (on non-x86_64). It should
  /// eventually should be eliminated. See also \see hasAbsolutizedSet.
  bool hasReliableSymbolDifference() const {
    return HasReliableSymbolDifference;
  }

  /// hasScatteredSymbols - Check whether this target supports scattered
  /// symbols. If so, the assembler should assume that atoms can be scattered by
  /// the linker. In particular, this means that the offsets between symbols
  /// which are in distinct atoms is not known at link time, and the assembler
  /// must generate fixups and relocations appropriately.
  ///
  /// Note that the assembler currently does not reason about atoms, instead it
  /// assumes all temporary symbols reside in the "current atom".
  bool hasScatteredSymbols() const { return HasScatteredSymbols; }

  /// doesSectionRequireSymbols - Check whether the given section requires that
  /// all symbols (even temporaries) have symbol table entries.
  virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
    return false;
  }

  /// isSectionAtomizable - Check whether the given section can be split into
  /// atoms.
  ///
  /// \see MCAssembler::isSymbolLinkerVisible().
  virtual bool isSectionAtomizable(const MCSection &Section) const {
    return true;
  }

  /// isVirtualSection - Check whether the given section is "virtual", that is
  /// has no actual object file contents.
  virtual bool isVirtualSection(const MCSection &Section) const = 0;

  /// ApplyFixup - Apply the \arg Value for given \arg Fixup into the provided
  /// data fragment, at the offset specified by the fixup and following the
  /// fixup kind as appropriate.
  virtual void ApplyFixup(const MCFixup &Fixup, MCDataFragment &Fragment,
                          uint64_t Value) const = 0;

  /// MayNeedRelaxation - Check whether the given instruction may need
  /// relaxation.
  ///
  /// \arg Inst - The instruction to test.
  virtual bool MayNeedRelaxation(const MCInst &Inst) const = 0;

  /// RelaxInstruction - Relax the instruction in the given fragment to the next
  /// wider instruction.
  virtual void RelaxInstruction(const MCInstFragment *IF,
                                MCInst &Res) const = 0;

  /// WriteNopData - Write an (optimal) nop sequence of Count bytes to the given
  /// output. If the target cannot generate such a sequence, it should return an
  /// error.
  ///
  /// \return - True on success.
  virtual bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const = 0;
};

} // End llvm namespace

#endif