LLVM: lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

26

27using namespace llvm;

28

29#define DEBUG_TYPE "csky-mccode-emitter"

30

31STATISTIC(MCNumEmitted, "Number of MC instructions emitted");

32

35 bool PCRel = false;

36 switch (Kind) {

45 PCRel = true;

46 }

48}

49

50namespace {

52 MCContext &Ctx;

53 const MCInstrInfo &MII;

54

55public:

56 CSKYMCCodeEmitter(MCContext &Ctx, const MCInstrInfo &MII)

57 : Ctx(Ctx), MII(MII) {}

58

59 ~CSKYMCCodeEmitter() {}

60

61 void encodeInstruction(const MCInst &Inst, SmallVectorImpl &CB,

62 SmallVectorImpl &Fixups,

63 const MCSubtargetInfo &STI) const override;

64

65

66 uint64_t getBinaryCodeForInstr(const MCInst &MI,

67 SmallVectorImpl &Fixups,

68 const MCSubtargetInfo &STI) const;

69

70

71 unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,

72 SmallVectorImpl &Fixups,

73 const MCSubtargetInfo &STI) const;

74

75 template

76 unsigned getImmOpValue(const MCInst &MI, unsigned Idx,

77 SmallVectorImpl &Fixups,

78 const MCSubtargetInfo &STI) const {

79 const MCOperand &MO = MI.getOperand(Idx);

81 return (MO.getImm() >> shift);

82

84

87 return 0;

88 }

89

90 unsigned getRegSeqImmOpValue(const MCInst &MI, unsigned Idx,

91 SmallVectorImpl &Fixups,

92 const MCSubtargetInfo &STI) const;

93

94 unsigned getRegisterSeqOpValue(const MCInst &MI, unsigned Op,

95 SmallVectorImpl &Fixups,

96 const MCSubtargetInfo &STI) const;

97

98 unsigned getOImmOpValue(const MCInst &MI, unsigned Idx,

99 SmallVectorImpl &Fixups,

100 const MCSubtargetInfo &STI) const;

101

102 unsigned getImmOpValueIDLY(const MCInst &MI, unsigned Idx,

103 SmallVectorImpl &Fixups,

104 const MCSubtargetInfo &STI) const;

105

106 unsigned getImmJMPIX(const MCInst &MI, unsigned Idx,

107 SmallVectorImpl &Fixups,

108 const MCSubtargetInfo &STI) const;

109

110 unsigned getImmOpValueMSBSize(const MCInst &MI, unsigned Idx,

111 SmallVectorImpl &Fixups,

112 const MCSubtargetInfo &STI) const;

113

114 unsigned getImmShiftOpValue(const MCInst &MI, unsigned Idx,

115 SmallVectorImpl &Fixups,

116 const MCSubtargetInfo &STI) const {

117 const MCOperand &MO = MI.getOperand(Idx);

118 assert(MO.isImm() && "Unexpected MO type.");

119 return 1 << MO.getImm();

120 }

121

122 MCFixupKind getTargetFixup(const MCExpr *Expr) const;

123

124 template <llvm::CSKY::Fixups FIXUP>

125 unsigned getBranchSymbolOpValue(const MCInst &MI, unsigned Idx,

126 SmallVectorImpl &Fixups,

127 const MCSubtargetInfo &STI) const {

128 const MCOperand &MO = MI.getOperand(Idx);

129

131 return MO.getImm() >> 1;

132

133 assert(MO.isExpr() && "Unexpected MO type.");

134

138

140 return 0;

141 }

142

143 template <llvm::CSKY::Fixups FIXUP>

144 unsigned getConstpoolSymbolOpValue(const MCInst &MI, unsigned Idx,

145 SmallVectorImpl &Fixups,

146 const MCSubtargetInfo &STI) const {

147 const MCOperand &MO = MI.getOperand(Idx);

148 assert(MO.isExpr() && "Unexpected MO type.");

149

153

155 return 0;

156 }

157

158 template <llvm::CSKY::Fixups FIXUP>

159 unsigned getDataSymbolOpValue(const MCInst &MI, unsigned Idx,

160 SmallVectorImpl &Fixups,

161 const MCSubtargetInfo &STI) const {

162 const MCOperand &MO = MI.getOperand(Idx);

163 assert(MO.isExpr() && "Unexpected MO type.");

164

168

170 return 0;

171 }

172

173 unsigned getCallSymbolOpValue(const MCInst &MI, unsigned Idx,

174 SmallVectorImpl &Fixups,

175 const MCSubtargetInfo &STI) const {

176 const MCOperand &MO = MI.getOperand(Idx);

177 assert(MO.isExpr() && "Unexpected MO type.");

178

182

184 return 0;

185 }

186

187 unsigned getBareSymbolOpValue(const MCInst &MI, unsigned Idx,

188 SmallVectorImpl &Fixups,

189 const MCSubtargetInfo &STI) const {

190 const MCOperand &MO = MI.getOperand(Idx);

191 assert(MO.isExpr() && "Unexpected MO type.");

192

196

198 return 0;

199 }

200

201 void expandJBTF(const MCInst &MI, SmallVectorImpl &CB,

202 SmallVectorImpl &Fixups,

203 const MCSubtargetInfo &STI) const;

204 void expandNEG(const MCInst &MI, SmallVectorImpl &CB,

205 SmallVectorImpl &Fixups,

206 const MCSubtargetInfo &STI) const;

207 void expandRSUBI(const MCInst &MI, SmallVectorImpl &CB,

208 SmallVectorImpl &Fixups,

209 const MCSubtargetInfo &STI) const;

210};

211}

212

213unsigned CSKYMCCodeEmitter::getOImmOpValue(const MCInst &MI, unsigned Idx,

216 const MCOperand &MO = MI.getOperand(Idx);

217 assert(MO.isImm() && "Unexpected MO type.");

218 return MO.getImm() - 1;

219}

220

221unsigned

222CSKYMCCodeEmitter::getImmOpValueIDLY(const MCInst &MI, unsigned Idx,

223 SmallVectorImpl &Fixups,

224 const MCSubtargetInfo &STI) const {

225 const MCOperand &MO = MI.getOperand(Idx);

226 assert(MO.isImm() && "Unexpected MO type.");

227

229 return V - 1;

230}

231

232unsigned

233CSKYMCCodeEmitter::getImmOpValueMSBSize(const MCInst &MI, unsigned Idx,

234 SmallVectorImpl &Fixups,

235 const MCSubtargetInfo &STI) const {

236 const MCOperand &MSB = MI.getOperand(Idx);

237 const MCOperand &LSB = MI.getOperand(Idx + 1);

239

241}

242

250

251void CSKYMCCodeEmitter::expandJBTF(const MCInst &MI, SmallVectorImpl &CB,

252 SmallVectorImpl &Fixups,

253 const MCSubtargetInfo &STI) const {

254

255 MCInst TmpInst;

256

258

259 TmpInst =

260 MCInstBuilder(MI.getOpcode() == CSKY::JBT_E ? CSKY::BF16 : CSKY::BT16)

262 .addImm(6);

263 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);

265

267 TmpInst = MCInstBuilder(CSKY::BR32)

269 .addOperand(MI.getOperand(2));

270 else

271 TmpInst = MCInstBuilder(CSKY::JMPI32).addOperand(MI.getOperand(2));

272 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);

275}

276

277void CSKYMCCodeEmitter::expandNEG(const MCInst &MI, SmallVectorImpl &CB,

278 SmallVectorImpl &Fixups,

279 const MCSubtargetInfo &STI) const {

280

281 MCInst TmpInst;

283 unsigned Size = MI.getOpcode() == CSKY::NEG32 ? 4 : 2;

284

285 TmpInst = MCInstBuilder(Size == 4 ? CSKY::NOT32 : CSKY::NOT16)

287 .addOperand(MI.getOperand(1));

288 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);

290

291 TmpInst = MCInstBuilder(Size == 4 ? CSKY::ADDI32 : CSKY::ADDI16)

293 .addOperand(MI.getOperand(0))

294 .addImm(1);

295 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);

297}

298

299void CSKYMCCodeEmitter::expandRSUBI(const MCInst &MI, SmallVectorImpl &CB,

300 SmallVectorImpl &Fixups,

301 const MCSubtargetInfo &STI) const {

302

303 MCInst TmpInst;

305 unsigned Size = MI.getOpcode() == CSKY::RSUBI32 ? 4 : 2;

306

307 TmpInst = MCInstBuilder(Size == 4 ? CSKY::NOT32 : CSKY::NOT16)

309 .addOperand(MI.getOperand(1));

310 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);

312

313 TmpInst = MCInstBuilder(Size == 4 ? CSKY::ADDI32 : CSKY::ADDI16)

315 .addOperand(MI.getOperand(0))

316 .addImm(MI.getOperand(2).getImm() + 1);

317 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);

319}

320

321void CSKYMCCodeEmitter::encodeInstruction(const MCInst &MI,

322 SmallVectorImpl &CB,

323 SmallVectorImpl &Fixups,

324 const MCSubtargetInfo &STI) const {

325 const MCInstrDesc &Desc = MII.get(MI.getOpcode());

326 unsigned Size = Desc.getSize();

327

328 MCInst TmpInst;

329

330 switch (MI.getOpcode()) {

331 default:

332 TmpInst = MI;

333 break;

334 case CSKY::JBT_E:

335 case CSKY::JBF_E:

336 expandJBTF(MI, CB, Fixups, STI);

337 MCNumEmitted += 2;

338 return;

339 case CSKY::NEG32:

340 case CSKY::NEG16:

341 expandNEG(MI, CB, Fixups, STI);

342 MCNumEmitted += 2;

343 return;

344 case CSKY::RSUBI32:

345 case CSKY::RSUBI16:

346 expandRSUBI(MI, CB, Fixups, STI);

347 MCNumEmitted += 2;

348 return;

349 case CSKY::JBSR32:

350 TmpInst = MCInstBuilder(CSKY::BSR32).addOperand(MI.getOperand(0));

351 break;

352 case CSKY::JBR16:

353 TmpInst = MCInstBuilder(CSKY::BR16).addOperand(MI.getOperand(0));

354 break;

355 case CSKY::JBR32:

356 TmpInst = MCInstBuilder(CSKY::BR32).addOperand(MI.getOperand(0));

357 break;

358 case CSKY::JBT16:

359 TmpInst = MCInstBuilder(CSKY::BT16)

361 .addOperand(MI.getOperand(1));

362 break;

363 case CSKY::JBT32:

364 TmpInst = MCInstBuilder(CSKY::BT32)

366 .addOperand(MI.getOperand(1));

367 break;

368 case CSKY::JBF16:

369 TmpInst = MCInstBuilder(CSKY::BF16)

371 .addOperand(MI.getOperand(1));

372 break;

373 case CSKY::JBF32:

374 TmpInst = MCInstBuilder(CSKY::BF32)

376 .addOperand(MI.getOperand(1));

377 break;

378 case CSKY::LRW32_Gen:

379 TmpInst = MCInstBuilder(CSKY::LRW32)

381 .addOperand(MI.getOperand(2));

382 break;

383 case CSKY::LRW16_Gen:

384 TmpInst = MCInstBuilder(CSKY::LRW16)

386 .addOperand(MI.getOperand(2));

387 break;

388 case CSKY::CMPLEI32:

389 TmpInst = MCInstBuilder(CSKY::CMPLTI32)

391 .addOperand(MI.getOperand(1))

392 .addImm(MI.getOperand(2).getImm() + 1);

393 break;

394 case CSKY::CMPLEI16:

395 TmpInst = MCInstBuilder(CSKY::CMPLTI16)

397 .addOperand(MI.getOperand(1))

398 .addImm(MI.getOperand(2).getImm() + 1);

399 break;

400 case CSKY::ROTRI32:

401 TmpInst = MCInstBuilder(CSKY::ROTLI32)

403 .addOperand(MI.getOperand(1))

404 .addImm(32 - MI.getOperand(2).getImm());

405 break;

406 case CSKY::BGENI:

407 auto V = 1 << MI.getOperand(1).getImm();

408 TmpInst =

409 MCInstBuilder(CSKY::MOVI32).addOperand(MI.getOperand(0)).addImm(V);

410 break;

411 }

412

413 ++MCNumEmitted;

414 writeData(getBinaryCodeForInstr(TmpInst, Fixups, STI), Size, CB);

415}

416

417unsigned

418CSKYMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,

419 SmallVectorImpl &Fixups,

420 const MCSubtargetInfo &STI) const {

423

425 return static_cast<unsigned>(MO.getImm());

426

428 return 0;

429}

430

431unsigned

432CSKYMCCodeEmitter::getRegSeqImmOpValue(const MCInst &MI, unsigned Idx,

433 SmallVectorImpl &Fixups,

434 const MCSubtargetInfo &STI) const {

435 assert(MI.getOperand(Idx).isReg() && "Unexpected MO type.");

436 assert(MI.getOperand(Idx + 1).isImm() && "Unexpected MO type.");

437

438 unsigned Ry = MI.getOperand(Idx).getReg();

439 unsigned Rz = MI.getOperand(Idx + 1).getImm();

440

443

445}

446

447unsigned

448CSKYMCCodeEmitter::getRegisterSeqOpValue(const MCInst &MI, unsigned Op,

449 SmallVectorImpl &Fixups,

450 const MCSubtargetInfo &STI) const {

451 unsigned Reg1 =

453 unsigned Reg2 =

455

456 unsigned Binary = ((Reg1 & 0x1f) << 5) | (Reg2 - Reg1);

457

459}

460

461unsigned CSKYMCCodeEmitter::getImmJMPIX(const MCInst &MI, unsigned Idx,

462 SmallVectorImpl &Fixups,

463 const MCSubtargetInfo &STI) const {

464 switch (MI.getOperand(Idx).getImm()) {

465 default:

467 case 16:

468 return 0;

469 case 24:

470 return 1;

471 case 32:

472 return 2;

473 case 40:

474 return 3;

475 }

476}

477

478MCFixupKind CSKYMCCodeEmitter::getTargetFixup(const MCExpr *Expr) const {

480 switch (CSKYExpr->getSpecifier()) {

481 default:

501 }

502}

503

506 return new CSKYMCCodeEmitter(Ctx, MCII);

507}

508

509#include "CSKYGenMCCodeEmitter.inc"

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

static void writeData(uint32_t Bin, unsigned Size, SmallVectorImpl< char > &CB)

Definition CSKYMCCodeEmitter.cpp:243

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

MCCodeEmitter - Generic instruction encoding interface.

Context object for machine code objects.

const MCRegisterInfo * getRegisterInfo() const

Base class for the full range of assembler expressions which are needed for parsing.

@ Specifier

Expression with a relocation specifier.

static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, bool PCRel=false)

Consider bit fields if we need more flags.

Instances of this class represent a single low-level machine instruction.

void addOperand(const MCOperand Op)

Interface to description of machine instruction set.

const MCInstrDesc & get(unsigned Opcode) const

Return the machine instruction descriptor that corresponds to the specified instruction opcode.

MCRegister getReg() const

Returns the register number.

const MCExpr * getExpr() const

uint16_t getEncodingValue(MCRegister Reg) const

Returns the encoding for Reg.

Generic base class for all target subtargets.

bool hasFeature(unsigned Feature) const

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

LLVM Value Representation.

#define llvm_unreachable(msg)

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

@ fixup_csky_pcrel_imm10_scale2

@ fixup_csky_pcrel_uimm7_scale4

@ fixup_csky_pcrel_imm16_scale2

@ fixup_csky_pcrel_imm18_scale2

@ fixup_csky_pcrel_uimm16_scale4

@ fixup_csky_plt_imm18_scale4

@ fixup_csky_pcrel_imm26_scale2

@ fixup_csky_got_imm18_scale4

@ fixup_csky_pcrel_uimm8_scale4

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.

uint16_t MCFixupKind

Extensible enumeration to represent the type of a fixup.

static void addFixup(SmallVectorImpl< MCFixup > &Fixups, uint32_t Offset, const MCExpr *Value, uint16_t Kind)

MCCodeEmitter * createCSKYMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)

Definition CSKYMCCodeEmitter.cpp:504

DWARFExpression::Operation Op

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.