LLVM  15.0.0git
SystemZMCAsmBackend.cpp
Go to the documentation of this file.
1 //===-- SystemZMCAsmBackend.cpp - SystemZ assembler backend ---------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
11 #include "llvm/ADT/StringSwitch.h"
12 #include "llvm/MC/MCAsmBackend.h"
13 #include "llvm/MC/MCAssembler.h"
14 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCInst.h"
18 #include "llvm/MC/MCObjectWriter.h"
20 
21 using namespace llvm;
22 
23 // Value is a fully-resolved relocation value: Symbol + Addend [- Pivot].
24 // Return the bits that should be installed in a relocation field for
25 // fixup kind Kind.
27  const MCFixup &Fixup, MCContext &Ctx) {
29  return Value;
30 
31  auto checkFixupInRange = [&](int64_t Min, int64_t Max) -> bool {
32  int64_t SVal = int64_t(Value);
33  if (SVal < Min || SVal > Max) {
34  Ctx.reportError(Fixup.getLoc(), "operand out of range (" + Twine(SVal) +
35  " not between " + Twine(Min) +
36  " and " + Twine(Max) + ")");
37  return false;
38  }
39  return true;
40  };
41 
42  auto handlePCRelFixupValue = [&](unsigned W) -> uint64_t {
43  if (Value % 2 != 0)
44  Ctx.reportError(Fixup.getLoc(), "Non-even PC relative offset.");
45  if (!checkFixupInRange(minIntN(W) * 2, maxIntN(W) * 2))
46  return 0;
47  return (int64_t)Value / 2;
48  };
49 
50  switch (unsigned(Kind)) {
52  return handlePCRelFixupValue(12);
54  return handlePCRelFixupValue(16);
56  return handlePCRelFixupValue(24);
58  return handlePCRelFixupValue(32);
59 
60  case SystemZ::FK_390_12:
61  if (!checkFixupInRange(0, maxUIntN(12)))
62  return 0;
63  return Value;
64 
65  case SystemZ::FK_390_20: {
66  if (!checkFixupInRange(minIntN(20), maxIntN(20)))
67  return 0;
68  // The high byte of a 20 bit displacement value comes first.
69  uint64_t DLo = Value & 0xfff;
70  uint64_t DHi = (Value >> 12) & 0xff;
71  return (DLo << 8) | DHi;
72  }
73 
75  return 0;
76  }
77 
78  llvm_unreachable("Unknown fixup kind!");
79 }
80 
81 namespace {
82 class SystemZMCAsmBackend : public MCAsmBackend {
83  uint8_t OSABI;
84 public:
85  SystemZMCAsmBackend(uint8_t osABI)
86  : MCAsmBackend(support::big), OSABI(osABI) {}
87 
88  // Override MCAsmBackend
89  unsigned getNumFixupKinds() const override {
91  }
92  Optional<MCFixupKind> getFixupKind(StringRef Name) const override;
93  const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
94  bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
95  const MCValue &Target) override;
96  void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
98  uint64_t Value, bool IsResolved,
99  const MCSubtargetInfo *STI) const override;
100  bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
101  const MCRelaxableFragment *Fragment,
102  const MCAsmLayout &Layout) const override {
103  return false;
104  }
105  bool writeNopData(raw_ostream &OS, uint64_t Count,
106  const MCSubtargetInfo *STI) const override;
107  std::unique_ptr<MCObjectTargetWriter>
108  createObjectTargetWriter() const override {
109  return createSystemZObjectWriter(OSABI);
110  }
111 };
112 } // end anonymous namespace
113 
114 Optional<MCFixupKind> SystemZMCAsmBackend::getFixupKind(StringRef Name) const {
116 #define ELF_RELOC(X, Y) .Case(#X, Y)
117 #include "llvm/BinaryFormat/ELFRelocs/SystemZ.def"
118 #undef ELF_RELOC
119  .Case("BFD_RELOC_NONE", ELF::R_390_NONE)
120  .Case("BFD_RELOC_8", ELF::R_390_8)
121  .Case("BFD_RELOC_16", ELF::R_390_16)
122  .Case("BFD_RELOC_32", ELF::R_390_32)
123  .Case("BFD_RELOC_64", ELF::R_390_64)
124  .Default(-1u);
125  if (Type != -1u)
126  return static_cast<MCFixupKind>(FirstLiteralRelocationKind + Type);
127  return None;
128 }
129 
130 const MCFixupKindInfo &
131 SystemZMCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
132  const static MCFixupKindInfo Infos[SystemZ::NumTargetFixupKinds] = {
133  { "FK_390_PC12DBL", 4, 12, MCFixupKindInfo::FKF_IsPCRel },
134  { "FK_390_PC16DBL", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
135  { "FK_390_PC24DBL", 0, 24, MCFixupKindInfo::FKF_IsPCRel },
136  { "FK_390_PC32DBL", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
137  { "FK_390_TLS_CALL", 0, 0, 0 },
138  { "FK_390_12", 4, 12, 0 },
139  { "FK_390_20", 4, 20, 0 }
140  };
141 
142  // Fixup kinds from .reloc directive are like R_390_NONE. They
143  // do not require any extra processing.
146 
149 
150  assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
151  "Invalid kind!");
152  return Infos[Kind - FirstTargetFixupKind];
153 }
154 
155 bool SystemZMCAsmBackend::shouldForceRelocation(const MCAssembler &,
156  const MCFixup &Fixup,
157  const MCValue &) {
158  return Fixup.getKind() >= FirstLiteralRelocationKind;
159 }
160 
162  const MCFixup &Fixup,
163  const MCValue &Target,
165  bool IsResolved,
166  const MCSubtargetInfo *STI) const {
167  MCFixupKind Kind = Fixup.getKind();
169  return;
170  unsigned Offset = Fixup.getOffset();
171  unsigned BitSize = getFixupKindInfo(Kind).TargetSize;
172  unsigned Size = (BitSize + 7) / 8;
173 
174  assert(Offset + Size <= Data.size() && "Invalid fixup offset!");
175 
176  // Big-endian insertion of Size bytes.
177  Value = extractBitsForFixup(Kind, Value, Fixup, Asm.getContext());
178  if (BitSize < 64)
179  Value &= ((uint64_t)1 << BitSize) - 1;
180  unsigned ShiftValue = (Size * 8) - 8;
181  for (unsigned I = 0; I != Size; ++I) {
182  Data[Offset + I] |= uint8_t(Value >> ShiftValue);
183  ShiftValue -= 8;
184  }
185 }
186 
187 bool SystemZMCAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
188  const MCSubtargetInfo *STI) const {
189  for (uint64_t I = 0; I != Count; ++I)
190  OS << '\x7';
191  return true;
192 }
193 
195  const MCSubtargetInfo &STI,
196  const MCRegisterInfo &MRI,
197  const MCTargetOptions &Options) {
198  uint8_t OSABI =
200  return new SystemZMCAsmBackend(OSABI);
201 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:76
llvm::StringSwitch::Case
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::MCRelaxableFragment
A relaxable fragment holds on to its MCInst, since it may need to be relaxed during the assembler lay...
Definition: MCFragment.h:270
llvm::MCAsmBackend::getFixupKindInfo
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
Definition: MCAsmBackend.cpp:78
llvm::SystemZ::FK_390_20
@ FK_390_20
Definition: SystemZMCFixups.h:24
llvm::MCContext
Context object for machine code objects.
Definition: MCContext.h:74
llvm::StringSwitch::Default
LLVM_NODISCARD R Default(T Value)
Definition: StringSwitch.h:183
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:140
llvm::SystemZ::FK_390_PC16DBL
@ FK_390_PC16DBL
Definition: SystemZMCFixups.h:19
llvm::RISCVFenceField::W
@ W
Definition: RISCVBaseInfo.h:241
llvm::FirstTargetFixupKind
@ FirstTargetFixupKind
Definition: MCFixup.h:45
MCAssembler.h
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::maxIntN
int64_t maxIntN(int64_t N)
Gets the maximum value for a N-bit signed integer.
Definition: MathExtras.h:446
llvm::Optional
Definition: APInt.h:33
MCFixupKindInfo.h
SystemZMCTargetDesc.h
llvm::SystemZ::FK_390_PC12DBL
@ FK_390_PC12DBL
Definition: SystemZMCFixups.h:18
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::FirstLiteralRelocationKind
@ FirstLiteralRelocationKind
The range [FirstLiteralRelocationKind, MaxTargetFixupKind) is used for relocations coming from ....
Definition: MCFixup.h:50
llvm::MCAsmBackend
Generic interface to target specific assembler backends.
Definition: MCAsmBackend.h:42
MCAsmBackend.h
llvm::MutableArrayRef< char >
llvm::SystemZ::FK_390_PC24DBL
@ FK_390_PC24DBL
Definition: SystemZMCFixups.h:20
llvm::MCSubtargetInfo::getTargetTriple
const Triple & getTargetTriple() const
Definition: MCSubtargetInfo.h:108
MCContext.h
llvm::SystemZ::FK_390_TLS_CALL
@ FK_390_TLS_CALL
Definition: SystemZMCFixups.h:22
MCInst.h
MCSubtargetInfo.h
Options
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
Definition: PassBuilderBindings.cpp:48
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:54
llvm::SystemZ::FK_390_12
@ FK_390_12
Definition: SystemZMCFixups.h:23
llvm::None
const NoneType None
Definition: None.h:24
llvm::lltok::Kind
Kind
Definition: LLToken.h:18
llvm::MCAssembler
Definition: MCAssembler.h:73
llvm::minIntN
int64_t minIntN(int64_t N)
Gets the minimum value for a N-bit signed integer.
Definition: MathExtras.h:439
llvm::AMDGPU::Hwreg::Offset
Offset
Definition: SIDefines.h:394
uint64_t
llvm::Triple::getOS
OSType getOS() const
Get the parsed operating system type of this triple.
Definition: Triple.h:346
MCELFObjectWriter.h
llvm::MCFixupKindInfo::FKF_IsPCRel
@ FKF_IsPCRel
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...
Definition: MCFixupKindInfo.h:19
I
#define I(x, y, z)
Definition: MD5.cpp:58
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MCFixupKindInfo
Target independent information on a fixup kind.
Definition: MCFixupKindInfo.h:15
llvm::MCContext::reportError
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:1002
llvm::MCTargetOptions
Definition: MCTargetOptions.h:36
llvm::createSystemZObjectWriter
std::unique_ptr< MCObjectTargetWriter > createSystemZObjectWriter(uint8_t OSABI)
Definition: SystemZMCObjectWriter.cpp:168
llvm::SystemZ::FK_390_PC32DBL
@ FK_390_PC32DBL
Definition: SystemZMCFixups.h:21
llvm::FK_NONE
@ FK_NONE
A no-op fixup.
Definition: MCFixup.h:22
llvm::MCELFObjectTargetWriter::getOSABI
uint8_t getOSABI() const
Definition: MCELFObjectWriter.h:101
Fixup
PowerPC TLS Dynamic Call Fixup
Definition: PPCTLSDynamicCall.cpp:233
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::MCRegisterInfo
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Definition: MCRegisterInfo.h:135
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
extractBitsForFixup
static uint64_t extractBitsForFixup(MCFixupKind Kind, uint64_t Value, const MCFixup &Fixup, MCContext &Ctx)
Definition: SystemZMCAsmBackend.cpp:26
MCObjectWriter.h
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
SystemZMCFixups.h
llvm::MCAsmLayout
Encapsulates the layout of an assembly file at a particular point in time.
Definition: MCAsmLayout.h:28
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
StringSwitch.h
llvm::SystemZ::NumTargetFixupKinds
@ NumTargetFixupKinds
Definition: SystemZMCFixups.h:28
llvm::MCFixupKind
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:21
llvm::createSystemZMCAsmBackend
MCAsmBackend * createSystemZMCAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
Definition: SystemZMCAsmBackend.cpp:194
support
Reimplement select in terms of SEL *We would really like to support but we need to prove that the add doesn t need to overflow between the two bit chunks *Implement pre post increment support(e.g. PR935) *Implement smarter const ant generation for binops with large immediates. A few ARMv6T2 ops should be pattern matched
Definition: README.txt:10
llvm::StringSwitch
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
llvm::HexStyle::Asm
@ Asm
0ffh
Definition: MCInstPrinter.h:34
llvm::MCValue
This represents an "assembler immediate".
Definition: MCValue.h:36
llvm::maxUIntN
uint64_t maxUIntN(uint64_t N)
Gets the maximum value for a N-bit unsigned integer.
Definition: MathExtras.h:428
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:76
llvm::MCFixup
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:71
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::support::big
@ big
Definition: Endian.h:27