LLVM: include/llvm/ExecutionEngine/JITLink/loongarch.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13#ifndef LLVM_EXECUTIONENGINE_JITLINK_LOONGARCH_H

14#define LLVM_EXECUTIONENGINE_JITLINK_LOONGARCH_H

15

22

23namespace llvm {

26

27

29

30

31

32

33

35

36

37

38

39

40

41

42

43

44

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

112

113

114

115

116

117

118

119

120

121

122

123

125

126

127

128

129

130

131

132

133

134

135

136

138

139

140

141

142

143

144

145

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

163

164

165

166

167

168

169

170

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

231

232

233

234

235

236

238

239

240

241

242

243

245

246

247

248

249

250

252

253

254

255

256

257

259

260

261

262

263

264

266

267

268

269

270

271

273

274

275

276

277

278

280

281

282

283

284

285

287

288

289

290

291

292

294

295

296

297

298

299

301

302

303

304

305

306

308

309

310

311

312

313

315

316

317

318

319

320

322};

323

324

325

327

328

330 return Hi == 63 ? Val >> Lo : (Val & ((((uint64_t)1 << (Hi + 1)) - 1))) >> Lo;

331}

332

333

336

337 char *BlockWorkingMem = B.getAlreadyMutableContent().data();

338 char *FixupPtr = BlockWorkingMem + E.getOffset();

339 uint64_t FixupAddress = (B.getAddress() + E.getOffset()).getValue();

340 uint64_t TargetAddress = E.getTarget().getAddress().getValue();

341 int64_t Addend = E.getAddend();

342

343 switch (E.getKind()) {

345 *(ulittle64_t *)FixupPtr = TargetAddress + Addend;

346 break;

349 if (Value > std::numeric_limits<uint32_t>::max())

351 *(ulittle32_t *)FixupPtr = Value;

352 break;

353 }

355 int64_t Value = TargetAddress - FixupAddress + Addend;

356

359

362

363 uint32_t RawInstr = *(little32_t *)FixupPtr;

366 *(little32_t *)FixupPtr = RawInstr | Imm15_0;

367 break;

368 }

370 int64_t Value = TargetAddress - FixupAddress + Addend;

371

374

377

378 uint32_t RawInstr = *(little32_t *)FixupPtr;

382 *(little32_t *)FixupPtr = RawInstr | Imm15_0 | Imm20_16;

383 break;

384 }

386 int64_t Value = TargetAddress - FixupAddress + Addend;

387

390

393

394 uint32_t RawInstr = *(little32_t *)FixupPtr;

398 *(little32_t *)FixupPtr = RawInstr | Imm15_0 | Imm25_16;

399 break;

400 }

402 int64_t Value = TargetAddress - FixupAddress + Addend;

403

406 *(little32_t *)FixupPtr = Value;

407 break;

408 }

410 int64_t Value = FixupAddress - TargetAddress + Addend;

413 *(little32_t *)FixupPtr = Value;

414 break;

415 }

417 *(little64_t *)FixupPtr = TargetAddress - FixupAddress + Addend;

418 break;

423 uint64_t PCPage = FixupAddress & ~static_cast<uint64_t>(0xfff);

424

425 int64_t PageDelta = TargetPage - PCPage;

428

429 uint32_t RawInstr = *(little32_t *)FixupPtr;

431 *(little32_t *)FixupPtr = RawInstr | Imm31_12;

432 break;

433 }

435 uint64_t TargetOffset = (TargetAddress + Addend) & 0xfff;

436

437 uint32_t RawInstr = *(ulittle32_t *)FixupPtr;

438 uint32_t Imm11_0 = TargetOffset << 10;

439 *(ulittle32_t *)FixupPtr = RawInstr | Imm11_0;

440 break;

441 }

443 int64_t Value = TargetAddress - FixupAddress + Addend;

444

447

450

451 uint32_t Pcaddu18i = *(little32_t *)FixupPtr;

453 *(little32_t *)FixupPtr = Pcaddu18i | Hi20;

454 uint32_t Jirl = *(little32_t *)(FixupPtr + 4);

456 *(little32_t *)(FixupPtr + 4) = Jirl | Lo16;

457 break;

458 }

460 int64_t Value = *(reinterpret_cast<const int8_t *>(FixupPtr));

461 Value += ((TargetAddress + Addend) & 0x3f);

462 *FixupPtr = (*FixupPtr & 0xc0) | (static_cast<int8_t>(Value) & 0x3f);

463 break;

464 }

467 TargetAddress + *(reinterpret_cast<const int8_t *>(FixupPtr)) + Addend;

468 *FixupPtr = static_cast<int8_t>(Value);

469 break;

470 }

474 *(little16_t *)FixupPtr = static_cast<int16_t>(Value);

475 break;

476 }

480 *(little32_t *)FixupPtr = static_cast<int32_t>(Value);

481 break;

482 }

486 *(little64_t *)FixupPtr = static_cast<int64_t>(Value);

487 break;

488 }

490 const uint32_t Maxcount = 1 + 64 / 7;

492 const char *Error = nullptr;

495

499 ": extra space for uleb128");

500

502 encodeULEB128((Orig + TargetAddress + Addend) & Mask,

503 (reinterpret_cast<uint8_t *>(FixupPtr)), Count);

504 break;

505 }

507 int64_t Value = *(reinterpret_cast<const int8_t *>(FixupPtr));

508 Value -= ((TargetAddress + Addend) & 0x3f);

509 *FixupPtr = (*FixupPtr & 0xc0) | (static_cast<int8_t>(Value) & 0x3f);

510 break;

511 }

514 *(reinterpret_cast<const int8_t *>(FixupPtr)) - TargetAddress - Addend;

515 *FixupPtr = static_cast<int8_t>(Value);

516 break;

517 }

521 *(little16_t *)FixupPtr = static_cast<int16_t>(Value);

522 break;

523 }

527 *(little32_t *)FixupPtr = static_cast<int32_t>(Value);

528 break;

529 }

533 *(little64_t *)FixupPtr = static_cast<int64_t>(Value);

534 break;

535 }

537 const uint32_t Maxcount = 1 + 64 / 7;

539 const char *Error = nullptr;

542

546 ": extra space for uleb128");

547

549 encodeULEB128((Orig - TargetAddress - Addend) & Mask,

550 (reinterpret_cast<uint8_t *>(FixupPtr)), Count);

551 break;

552 }

554

555 break;

556 default:

558 "In graph " + G.getName() + ", section " + B.getSection().getName() +

560 }

561

563}

564

565

569 G.getPointerSize()};

570}

571

572

573

574

575

576

577

578

583 auto StubContent =

585 return {reinterpret_cast<const char *>(StubContent), StubEntrySize};

586}

587

588

589

590

591

592

593

594

595

596

598 Symbol *InitialTarget = nullptr,

599 uint64_t InitialAddend = 0) {

602 if (InitialTarget)

604 *InitialTarget, InitialAddend);

605 return G.addAnonymousSymbol(B, 0, G.getPointerSize(), false, false);

606}

607

608

609

612 Symbol &PointerSymbol) {

613 Block &StubContentBlock = G.createContentBlock(

615 StubContentBlock.addEdge(Page20, 0, PointerSymbol, 0);

617 return G.addAnonymousSymbol(StubContentBlock, 0, StubEntrySize, true, false);

618}

619

620

622public:

624

626 Edge::Kind KindToSet = Edge::Invalid;

627 switch (E.getKind()) {

630 break;

633 break;

634 default:

635 return false;

636 }

637 assert(KindToSet != Edge::Invalid &&

638 "Fell through switch, but no new kind to set");

640 dbgs() << " Fixing " << G.getEdgeKindName(E.getKind()) << " edge at "

641 << B->getFixupAddress(E) << " (" << B->getAddress() << " + "

642 << formatv("{0:x}", E.getOffset()) << ")\n";

643 });

644 E.setKind(KindToSet);

646 return true;

647 }

648

652

653private:

655 if (!GOTSection)

658 return *GOTSection;

659 }

660

661 Section *GOTSection = nullptr;

662};

663

664

666public:

668

670

673 E.getTarget().isDefined()) {

675 dbgs() << " Fixing " << G.getEdgeKindName(E.getKind()) << " edge at "

676 << B->getFixupAddress(E) << " (" << B->getAddress() << " + "

677 << formatv("{0:x}", E.getOffset()) << ")\n";

678 });

680 return true;

681 }

682 return false;

683 }

684

689

690public:

697

700};

701

702}

703}

704}

705

706#endif

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

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

#define DEBUG_WITH_TYPE(TYPE,...)

DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

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

Target - Wrapper for Target specific information.

LLVM Value Representation.

An Addressable with content and edges.

void addEdge(Edge::Kind K, Edge::OffsetT Offset, Symbol &Target, Edge::AddendT Addend)

Add an edge to this block.

Represents fixups and constraints in the LinkGraph.

Represents an object file section.

A CRTP base for tables that are built on demand, e.g.

Symbol & getEntryForTarget(LinkGraph &G, Symbol &Target)

Global Offset Table Builder.

Definition loongarch.h:621

Symbol & createEntry(LinkGraph &G, Symbol &Target)

Definition loongarch.h:649

bool visitEdge(LinkGraph &G, Block *B, Edge &E)

Definition loongarch.h:625

static StringRef getSectionName()

Definition loongarch.h:623

static StringRef getSectionName()

Definition loongarch.h:669

PLTTableManager(GOTTableManager &GOT)

Definition loongarch.h:667

Section & getStubsSection(LinkGraph &G)

Definition loongarch.h:691

Symbol & createEntry(LinkGraph &G, Symbol &Target)

Definition loongarch.h:685

bool visitEdge(LinkGraph &G, Block *B, Edge &E)

Definition loongarch.h:671

Section * StubsSection

Definition loongarch.h:699

GOTTableManager & GOT

Definition loongarch.h:698

Represents an address in the executor process.

Definition loongarch.h:25

Symbol & createAnonymousPointerJumpStub(LinkGraph &G, Section &StubSection, Symbol &PointerSymbol)

Create a jump stub that jumps via the pointer at the given symbol and an anonymous symbol pointing to...

Definition loongarch.h:610

Symbol & createAnonymousPointer(LinkGraph &G, Section &PointerSection, Symbol *InitialTarget=nullptr, uint64_t InitialAddend=0)

Creates a new pointer block in the given section and returns an Anonymous symbol pointing to it.

Definition loongarch.h:597

ArrayRef< char > getStubBlockContent(LinkGraph &G)

Definition loongarch.h:582

LLVM_ABI const char * getEdgeKindName(Edge::Kind K)

Returns a string name for the given loongarch edge.

ArrayRef< char > getGOTEntryBlockContent(LinkGraph &G)

Definition loongarch.h:567

EdgeKind_loongarch

Represents loongarch fixups.

Definition loongarch.h:28

@ Branch16PCRel

A 16-bit PC-relative branch.

Definition loongarch.h:67

@ Add16

16 bits label addition

Definition loongarch.h:251

@ AddUleb128

ULEB128 bits label addition.

Definition loongarch.h:272

@ RequestGOTAndTransformToPage20

A GOT entry getter/constructor, transformed to Page20 pointing at the GOT entry for the original targ...

Definition loongarch.h:191

@ Sub16

16 bits label subtraction

Definition loongarch.h:293

@ NegDelta32

A 32-bit negative delta.

Definition loongarch.h:137

@ SubUleb128

ULEB128 bits label subtraction.

Definition loongarch.h:314

@ Sub8

8 bits label subtraction

Definition loongarch.h:286

@ PageOffset12

The 12-bit offset of the target within its page.

Definition loongarch.h:171

@ Sub32

32 bits label subtraction

Definition loongarch.h:300

@ Add64

64 bits label addition

Definition loongarch.h:265

@ Sub6

low 6 bits label subtraction

Definition loongarch.h:279

@ Add8

8 bits label addition

Definition loongarch.h:244

@ Delta32

A 32-bit delta.

Definition loongarch.h:124

@ Page20

The signed 20-bit delta from the fixup page to the page containing the target.

Definition loongarch.h:162

@ Pointer64

A plain 64-bit pointer value relocation.

Definition loongarch.h:34

@ Delta64

A 64-bit delta.

Definition loongarch.h:146

@ RequestGOTAndTransformToPageOffset12

A GOT entry getter/constructor, transformed to Pageoffset12 pointing at the GOT entry for the origina...

Definition loongarch.h:207

@ Call36PCRel

A 36-bit PC-relative call.

Definition loongarch.h:230

@ Add6

low 6 bits label addition

Definition loongarch.h:237

@ Branch21PCRel

A 21-bit PC-relative branch.

Definition loongarch.h:89

@ Branch26PCRel

A 26-bit PC-relative branch.

Definition loongarch.h:111

@ Add32

32 bits label addition

Definition loongarch.h:258

@ Pointer32

A plain 32-bit pointer value relocation.

Definition loongarch.h:45

@ AlignRelaxable

Alignment requirement used by linker relaxation.

Definition loongarch.h:321

@ Sub64

64 bits label subtraction

Definition loongarch.h:307

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

Apply fixup expression for edge to block content.

Definition loongarch.h:334

LLVM_ABI const uint8_t LA32StubContent[StubEntrySize]

LLVM_ABI const uint8_t LA64StubContent[StubEntrySize]

LLVM_ABI const char NullPointerContent[8]

loongarch null pointer content.

uint32_t extractBits(uint64_t Val, unsigned Hi, unsigned Lo)

Definition loongarch.h:329

constexpr size_t StubEntrySize

loongarch stub content.

Definition loongarch.h:579

LLVM_ABI Error makeTargetOutOfRangeError(const LinkGraph &G, const Block &B, const Edge &E)

Create an out of range error for the given edge in the given block.

LLVM_ABI Error makeAlignmentError(llvm::orc::ExecutorAddr Loc, uint64_t Value, int N, const Edge &E)

uint64_t read64le(const void *P)

uint16_t read16le(const void *P)

uint32_t read32le(const void *P)

This is an optimization pass for GlobalISel generic memory operations.

constexpr bool isInt(int64_t x)

Checks if an integer fits into the given bit width.

uint64_t decodeULEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)

Utility function to decode a ULEB128 value.

std::string utohexstr(uint64_t X, bool LowerCase=false, unsigned Width=0)

auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

FunctionAddr VTableAddr Count

Error make_error(ArgTs &&... Args)

Make a Error instance representing failure using the given error info type.

constexpr bool isShiftedInt(int64_t x)

Checks if a signed integer is an N bit number shifted left by S.

unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)

Utility function to encode a ULEB128 value to an output stream.

constexpr int64_t SignExtend64(uint64_t x)

Sign-extend the number in the bottom B bits of X to a 64-bit integer.