LLVM: lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

26using namespace llvm;

27

30 auto checkBrFixup = [&](unsigned Bits) {

31 int64_t SVal = int64_t(Value);

32 if ((Value & 3) != 0) {

33 Ctx.reportError(Fixup.getLoc(), "branch target not a multiple of four (" +

34 Twine(SVal) + ")");

35 return;

36 }

37

38

40 Ctx.reportError(Fixup.getLoc(), "branch target out of range (" +

41 Twine(SVal) + " not between " +

44 }

45 };

46

47 switch (Kind) {

48 default:

58 checkBrFixup(14);

59 return Value & 0xfffc;

63 checkBrFixup(24);

64 return Value & 0x3fffffc;

66 return Value & 0xffff;

69 return Value & 0xfffc;

72 return Value & 0xffffffff;

75 return Value & 0x3ffffffff;

76 }

77}

78

80 switch (Kind) {

81 default:

84 return 1;

89 return 2;

96 return 4;

102 return 8;

104 return 0;

105 }

106}

107

108namespace {

109

111protected:

112 Triple TT;

113public:

114 PPCAsmBackend(const Target &T, const Triple &TT)

115 : MCAsmBackend(TT.isLittleEndian() ? llvm::endianness::little

117 TT(TT) {}

118

119 MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override;

120

121 void applyFixup(const MCFragment &, const MCFixup &Fixup,

122 const MCValue &Target, uint8_t *Data, uint64_t Value,

123 bool IsResolved) override;

124

126

127

128 if (Target.getSpecifier())

129 return true;

131 switch ((unsigned)Kind) {

132 default:

133 return false;

137

138

139

140 if (const auto *A = Target.getAddSym()) {

142

143

144

145 unsigned Other = static_cast<const MCSymbolELF *>(A)->getOther() << 2;

147 return true;

149 auto *S = static_cast<const MCSymbolXCOFF *>(A);

150 return Target.isAbsolute() && S->isExternal() &&

152 }

153 }

154 return false;

155 }

156 }

157

158 bool writeNopData(raw_ostream &OS, uint64_t Count,

159 const MCSubtargetInfo *STI) const override {

160 uint64_t NumNops = Count / 4;

161 for (uint64_t i = 0; i != NumNops; ++i)

163

165

166 return true;

167 }

168};

169}

170

172

174

175 {"fixup_ppc_br24", 6, 24, 0},

176 {"fixup_ppc_br24_notoc", 6, 24, 0},

177 {"fixup_ppc_brcond14", 16, 14, 0},

178 {"fixup_ppc_br24abs", 6, 24, 0},

179 {"fixup_ppc_brcond14abs", 16, 14, 0},

180 {"fixup_ppc_half16", 0, 16, 0},

181 {"fixup_ppc_half16ds", 0, 14, 0},

182 {"fixup_ppc_pcrel32", 0, 32, 0},

183 {"fixup_ppc_imm32", 0, 32, 0},

184 {"fixup_ppc_pcrel34", 0, 34, 0},

185 {"fixup_ppc_imm34", 0, 34, 0},

186 {"fixup_ppc_nofixup", 0, 0, 0}};

188

189 {"fixup_ppc_br24", 2, 24, 0},

190 {"fixup_ppc_br24_notoc", 2, 24, 0},

191 {"fixup_ppc_brcond14", 2, 14, 0},

192 {"fixup_ppc_br24abs", 2, 24, 0},

193 {"fixup_ppc_brcond14abs", 2, 14, 0},

194 {"fixup_ppc_half16", 0, 16, 0},

195 {"fixup_ppc_half16ds", 2, 14, 0},

196 {"fixup_ppc_pcrel32", 0, 32, 0},

197 {"fixup_ppc_imm32", 0, 32, 0},

198 {"fixup_ppc_pcrel34", 0, 34, 0},

199 {"fixup_ppc_imm34", 0, 34, 0},

200 {"fixup_ppc_nofixup", 0, 0, 0}};

201

202

203

204

206 return {};

207

210

212 "Invalid kind!");

214 ? InfosLE

216}

217

218void PPCAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,

219 const MCValue &TargetVal, uint8_t *Data,

220 uint64_t Value, bool IsResolved) {

221

222

223 auto Target = TargetVal;

225 Target.setAddSym(nullptr);

227 IsResolved = false;

228 if (!IsResolved)

229 Asm->getWriter().recordRelocation(F, Fixup, Target, Value);

230

233 return;

236 return;

237

239

240

241

242

243 for (unsigned i = 0; i != NumBytes; ++i) {

245 Data[i] |= uint8_t((Value >> (Idx * 8)) & 0xff);

246 }

247}

248

249

250namespace {

251

252class ELFPPCAsmBackend : public PPCAsmBackend {

253public:

254 ELFPPCAsmBackend(const Target &T, const Triple &TT) : PPCAsmBackend(T, TT) {}

255

256 std::unique_ptr

257 createObjectTargetWriter() const override {

259 bool Is64 = TT.isPPC64();

261 }

262

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

264};

265

266class XCOFFPPCAsmBackend : public PPCAsmBackend {

267public:

268 XCOFFPPCAsmBackend(const Target &T, const Triple &TT)

269 : PPCAsmBackend(T, TT) {}

270

271 std::unique_ptr

272 createObjectTargetWriter() const override {

274 }

275};

276

277}

278

279std::optional

280ELFPPCAsmBackend::getFixupKind(StringRef Name) const {

281 if (TT.isOSBinFormatELF()) {

282 unsigned Type;

283 if (TT.isPPC64()) {

284 Type = llvm::StringSwitch(Name)

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

286#include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def"

287#undef ELF_RELOC

288 .Case("BFD_RELOC_NONE", ELF::R_PPC64_NONE)

289 .Case("BFD_RELOC_16", ELF::R_PPC64_ADDR16)

290 .Case("BFD_RELOC_32", ELF::R_PPC64_ADDR32)

291 .Case("BFD_RELOC_64", ELF::R_PPC64_ADDR64)

292 .Default(-1u);

293 } else {

294 Type = llvm::StringSwitch(Name)

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

296#include "llvm/BinaryFormat/ELFRelocs/PowerPC.def"

297#undef ELF_RELOC

298 .Case("BFD_RELOC_NONE", ELF::R_PPC_NONE)

299 .Case("BFD_RELOC_16", ELF::R_PPC_ADDR16)

300 .Case("BFD_RELOC_32", ELF::R_PPC_ADDR32)

301 .Default(-1u);

302 }

303 if (Type != -1u)

305 }

306 return std::nullopt;

307}

308

314 if (TT.isOSBinFormatXCOFF())

315 return new XCOFFPPCAsmBackend(T, TT);

316

317 return new ELFPPCAsmBackend(T, TT);

318}

unsigned const MachineRegisterInfo * MRI

static unsigned getFixupKindNumBytes(unsigned Kind)

The number of bytes the fixup may change.

static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target, uint64_t Value, MCContext &Ctx, const Triple &TheTriple, bool IsResolved)

static bool shouldForceRelocation(const MCFixup &Fixup)

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

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static uint64_t adjustFixupValue(MCContext &Ctx, const MCFixup &Fixup, unsigned Kind, uint64_t Value)

Definition PPCAsmBackend.cpp:28

static unsigned getFixupKindNumBytes(unsigned Kind)

Definition PPCAsmBackend.cpp:79

PowerPC TLS Dynamic Call Fixup

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

Target - Wrapper for Target specific information.

Triple - Helper class for working with autoconf configuration names.

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

LLVM Value Representation.

raw_ostream & write_zeros(unsigned NumZeros)

write_zeros - Insert 'NumZeros' nulls.

#define llvm_unreachable(msg)

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

@ fixup_ppc_brcond14abs

14-bit absolute relocation for conditional branches.

@ fixup_ppc_half16

A 16-bit fixup corresponding to lo16(_foo) or ha16(_foo) for instrs like 'li' or 'addis'.

@ fixup_ppc_brcond14

14-bit PC relative relocation for conditional branches.

@ fixup_ppc_half16dq

A 16-bit fixup corresponding to lo16(_foo) with implied 3 zero bits for instrs like 'lxv'.

@ fixup_ppc_half16ds

A 14-bit fixup corresponding to lo16(_foo) with implied 2 zero bits for instrs like 'std'.

@ fixup_ppc_nofixup

Not a true fixup, but ties a symbol to a call to __tls_get_addr for the TLS general and local dynamic...

@ fixup_ppc_br24abs

24-bit absolute relocation for direct branches like 'ba' and 'bla'.

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

void write(void *memory, value_type value, endianness endian)

Write a value to memory with a particular endianness.

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

constexpr int64_t minIntN(int64_t N)

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

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

Definition PPCAsmBackend.cpp:309

uint16_t MCFixupKind

Extensible enumeration to represent the type of a fixup.

std::unique_ptr< MCObjectTargetWriter > createPPCXCOFFObjectWriter(bool Is64Bit)

Construct a PPC XCOFF object writer.

FunctionAddr VTableAddr Count

@ FirstLiteralRelocationKind

@ FK_Data_8

A eight-byte fixup.

@ FK_Data_1

A one-byte fixup.

@ FK_Data_4

A four-byte fixup.

@ FK_Data_2

A two-byte fixup.

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 > createPPCELFObjectWriter(bool Is64Bit, uint8_t OSABI)

Construct an PPC ELF object writer.

constexpr bool isIntN(unsigned N, int64_t x)

Checks if an signed integer fits into the given (dynamic) bit width.

Target independent information on a fixup kind.