LLVM: lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

20

21using namespace llvm;

22

23

24

25

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 auto handleImmValue = [&](bool IsSigned, unsigned W) -> uint64_t {

51 if (!(IsSigned ? checkFixupInRange(minIntN(W), maxIntN(W))

52 : checkFixupInRange(0, maxUIntN(W))))

53 return 0;

55 };

56

57 switch (unsigned(Kind)) {

59 return handlePCRelFixupValue(12);

61 return handlePCRelFixupValue(16);

63 return handlePCRelFixupValue(24);

65 return handlePCRelFixupValue(32);

66

68 return 0;

69

71 return handleImmValue(true, 8);

73 return handleImmValue(true, 16);

75 Value = handleImmValue(true, 20);

76

77

80 return (DLo << 8) | DHi;

81 }

83 return handleImmValue(true, 32);

85 return handleImmValue(false, 1);

87 return handleImmValue(false, 2);

89 return handleImmValue(false, 3);

91 return handleImmValue(false, 4);

93 return handleImmValue(false, 8);

95 return handleImmValue(false, 12);

97 return handleImmValue(false, 16);

99 return handleImmValue(false, 32);

101 return handleImmValue(false, 48);

102 }

103

105}

106

107namespace {

108class SystemZMCAsmBackend : public MCAsmBackend {

109public:

110 SystemZMCAsmBackend() : MCAsmBackend(llvm::endianness::big) {}

111

112

113 std::optional getFixupKind(StringRef Name) const override;

114 MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override;

115 void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target,

116 uint8_t *Data, uint64_t Value, bool IsResolved) override;

117 bool writeNopData(raw_ostream &OS, uint64_t Count,

118 const MCSubtargetInfo *STI) const override;

119};

120}

121

122std::optional

123SystemZMCAsmBackend::getFixupKind(StringRef Name) const {

124 unsigned Type = llvm::StringSwitch(Name)

125#define ELF_RELOC(X, Y) .Case(#X, Y)

126#include "llvm/BinaryFormat/ELFRelocs/SystemZ.def"

127#undef ELF_RELOC

128 .Case("BFD_RELOC_NONE", ELF::R_390_NONE)

129 .Case("BFD_RELOC_8", ELF::R_390_8)

130 .Case("BFD_RELOC_16", ELF::R_390_16)

131 .Case("BFD_RELOC_32", ELF::R_390_32)

132 .Case("BFD_RELOC_64", ELF::R_390_64)

133 .Default(-1u);

134 if (Type != -1u)

136 return std::nullopt;

137}

138

139MCFixupKindInfo SystemZMCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {

140

141

143 return {};

144

147

149 "Invalid kind!");

151}

152

153void SystemZMCAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,

154 const MCValue &Target, uint8_t *Data,

155 uint64_t Value, bool IsResolved) {

156 if (Target.getSpecifier())

157 IsResolved = false;

158 maybeAddReloc(F, Fixup, Target, Value, IsResolved);

161 return;

162 unsigned BitSize = getFixupKindInfo(Kind).TargetSize;

163 unsigned Size = (BitSize + 7) / 8;

164

165 assert(Fixup.getOffset() + Size <= F.getSize() && "Invalid fixup offset!");

166

167

169 if (BitSize < 64)

170 Value &= ((uint64_t)1 << BitSize) - 1;

171 unsigned ShiftValue = (Size * 8) - 8;

172 for (unsigned I = 0; I != Size; ++I) {

173 Data[I] |= uint8_t(Value >> ShiftValue);

174 ShiftValue -= 8;

175 }

176}

177

178bool SystemZMCAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,

179 const MCSubtargetInfo *STI) const {

180 for (uint64_t I = 0; I != Count; ++I)

181 OS << '\x7';

182 return true;

183}

184

185namespace {

186class ELFSystemZAsmBackend : public SystemZMCAsmBackend {

187 uint8_t OSABI;

188

189public:

190 ELFSystemZAsmBackend(uint8_t OsABI) : SystemZMCAsmBackend(), OSABI(OsABI){};

191

192 std::unique_ptr

193 createObjectTargetWriter() const override {

195 }

196};

197

198class GOFFSystemZAsmBackend : public SystemZMCAsmBackend {

199public:

200 GOFFSystemZAsmBackend() : SystemZMCAsmBackend(){};

201

202 std::unique_ptr

203 createObjectTargetWriter() const override {

205 }

206};

207}

208

214 return new GOFFSystemZAsmBackend();

215 }

216

219 return new ELFSystemZAsmBackend(OSABI);

220}

unsigned const MachineRegisterInfo * MRI

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

PowerPC TLS Dynamic Call Fixup

This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...

static uint64_t extractBitsForFixup(MCFixupKind Kind, uint64_t Value, const MCFixup &Fixup, MCContext &Ctx)

Definition SystemZMCAsmBackend.cpp:26

Generic interface to target specific assembler backends.

virtual MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const

Get information on a fixup kind.

Context object for machine code objects.

Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...

MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...

Generic base class for all target subtargets.

const Triple & getTargetTriple() const

StringRef - Represent a constant reference to a string, i.e.

Target - Wrapper for Target specific information.

OSType getOS() const

Get the parsed operating system type of this triple.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

LLVM Value Representation.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

static const MCFixupKindInfo MCFixupKindInfos[SystemZ::NumTargetFixupKinds]

VE::Fixups getFixupKind(uint8_t S)

Error applyFixup(LinkGraph &G, Block &B, const Edge &E, const ArmConfig &ArmCfg)

Apply fixup expression for edge to block content.

bool isRelocation(MCFixupKind FixupKind)

Context & getContext() const

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

constexpr uint64_t maxUIntN(uint64_t N)

Gets the maximum value for a N-bit unsigned integer.

constexpr int64_t minIntN(int64_t N)

Gets the minimum value for a N-bit signed integer.

std::unique_ptr< MCObjectTargetWriter > createSystemZGOFFObjectWriter()

MCAsmBackend * createSystemZMCAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)

Definition SystemZMCAsmBackend.cpp:209

uint16_t MCFixupKind

Extensible enumeration to represent the type of a fixup.

FunctionAddr VTableAddr Count

@ FirstLiteralRelocationKind

FunctionAddr VTableAddr uintptr_t uintptr_t Data

constexpr int64_t maxIntN(int64_t N)

Gets the maximum value for a N-bit signed integer.

std::unique_ptr< MCObjectTargetWriter > createSystemZELFObjectWriter(uint8_t OSABI)