LLVM: lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

25

26using namespace llvm;

27

28#define DEBUG_TYPE "mccodeemitter"

29

30namespace {

31class LoongArchMCCodeEmitter : public MCCodeEmitter {

32 LoongArchMCCodeEmitter(const LoongArchMCCodeEmitter &) = delete;

33 void operator=(const LoongArchMCCodeEmitter &) = delete;

36

37public:

39 : Ctx(ctx), MCII(MCII) {}

40

41 ~LoongArchMCCodeEmitter() override = default;

42

46

47 template

51

55

56

57

61

62

63

67

68

69

70

71

72 unsigned getImmOpValueSub1(const MCInst &MI, unsigned OpNo,

75

76

77

78

79

80

81 template

82 unsigned getImmOpValueAsr(const MCInst &MI, unsigned OpNo,

85 const MCOperand &MO = MI.getOperand(OpNo);

87 unsigned Res = MI.getOperand(OpNo).getImm();

88 assert((Res & ((1U << N) - 1U)) == 0 && "lowest N bits are non-zero");

89 return Res >> N;

90 }

91 return getExprOpValue(MI, MO, Fixups, STI);

92 }

93

97};

98}

99

102 bool PCRel = false;

103 switch (Kind) {

107 PCRel = true;

108 }

110}

111

112unsigned

113LoongArchMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,

116

119

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

122

123

125 return getExprOpValue(MI, MO, Fixups, STI);

126}

127

128unsigned

129LoongArchMCCodeEmitter::getImmOpValueSub1(const MCInst &MI, unsigned OpNo,

130 SmallVectorImpl &Fixups,

131 const MCSubtargetInfo &STI) const {

132 return MI.getOperand(OpNo).getImm() - 1;

133}

134

135unsigned

136LoongArchMCCodeEmitter::getExprOpValue(const MCInst &MI, const MCOperand &MO,

137 SmallVectorImpl &Fixups,

138 const MCSubtargetInfo &STI) const {

139 assert(MO.isExpr() && "getExprOpValue expects only expressions");

140 bool RelaxCandidate = false;

141 bool EnableRelax = STI.hasFeature(LoongArch::FeatureRelax);

142 const MCExpr *Expr = MO.getExpr();

152 case ELF::R_LARCH_TLS_LE_ADD_R:

153 llvm_unreachable("ELF::R_LARCH_TLS_LE_ADD_R should not represent an "

154 "instruction operand");

155 case ELF::R_LARCH_B16:

157 break;

158 case ELF::R_LARCH_B21:

160 break;

161 case ELF::R_LARCH_B26:

163 break;

164 case ELF::R_LARCH_MARK_LA:

165

166

170 [[fallthrough]];

171 case ELF::R_LARCH_ABS_HI20:

173 break;

174 case ELF::R_LARCH_ABS_LO12:

176 break;

177 case ELF::R_LARCH_ABS64_LO20:

179 break;

180 case ELF::R_LARCH_ABS64_HI12:

182 break;

183 case ELF::R_LARCH_CALL36:

184 case ELF::R_LARCH_TLS_LE_HI20_R:

185 case ELF::R_LARCH_TLS_LE_LO12_R:

186 RelaxCandidate = true;

187 break;

188 }

190 switch (MI.getOpcode()) {

191 default:

192 break;

193 case LoongArch::BEQ:

194 case LoongArch::BNE:

195 case LoongArch::BLT:

196 case LoongArch::BGE:

197 case LoongArch::BLTU:

198 case LoongArch::BGEU:

200 break;

201 case LoongArch::BEQZ:

202 case LoongArch::BNEZ:

203 case LoongArch::BCEQZ:

204 case LoongArch::BCNEZ:

206 break;

207 case LoongArch::B:

208 case LoongArch::BL:

210 break;

211 }

212 }

213

215 "Unhandled expression!");

216

218

219

220

221 if (EnableRelax && RelaxCandidate)

222 Fixups.back().setLinkerRelaxable();

223

224 return 0;

225}

226

227template

228void LoongArchMCCodeEmitter::expandToVectorLDI(

229 const MCInst &MI, SmallVectorImpl &CB,

230 SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const {

231 int64_t Imm = MI.getOperand(1).getImm() & 0x3FF;

232 switch (MI.getOpcode()) {

233 case LoongArch::PseudoVREPLI_B:

234 case LoongArch::PseudoXVREPLI_B:

235 break;

236 case LoongArch::PseudoVREPLI_H:

237 case LoongArch::PseudoXVREPLI_H:

238 Imm |= 0x400;

239 break;

240 case LoongArch::PseudoVREPLI_W:

241 case LoongArch::PseudoXVREPLI_W:

242 Imm |= 0x800;

243 break;

244 case LoongArch::PseudoVREPLI_D:

245 case LoongArch::PseudoXVREPLI_D:

246 Imm |= 0xC00;

247 break;

248 }

249 MCInst TmpInst = MCInstBuilder(Opc).addOperand(MI.getOperand(0)).addImm(Imm);

250 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);

252}

253

254void LoongArchMCCodeEmitter::expandAddTPRel(const MCInst &MI,

255 SmallVectorImpl &CB,

256 SmallVectorImpl &Fixups,

257 const MCSubtargetInfo &STI) const {

258 MCOperand Rd = MI.getOperand(0);

259 MCOperand Rj = MI.getOperand(1);

260 MCOperand Rk = MI.getOperand(2);

261 MCOperand Symbol = MI.getOperand(3);

263 "Expected expression as third input to TP-relative add");

264

267 "Expected %le_add_r relocation on TP-relative symbol");

268

269

270 addFixup(Fixups, 0, Expr, ELF::R_LARCH_TLS_LE_ADD_R);

271 if (STI.hasFeature(LoongArch::FeatureRelax))

272 Fixups.back().setLinkerRelaxable();

273

274

275 unsigned ADD = MI.getOpcode() == LoongArch::PseudoAddTPRel_D

276 ? LoongArch::ADD_D

277 : LoongArch::ADD_W;

278 MCInst TmpInst =

279 MCInstBuilder(ADD).addOperand(Rd).addOperand(Rj).addOperand(Rk);

280 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);

282}

283

284void LoongArchMCCodeEmitter::encodeInstruction(

285 const MCInst &MI, SmallVectorImpl &CB,

286 SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const {

287 const MCInstrDesc &Desc = MCII.get(MI.getOpcode());

288

289 unsigned Size = Desc.getSize();

290

291 switch (MI.getOpcode()) {

292 default:

293 break;

294 case LoongArch::PseudoVREPLI_B:

295 case LoongArch::PseudoVREPLI_H:

296 case LoongArch::PseudoVREPLI_W:

297 case LoongArch::PseudoVREPLI_D:

298 return expandToVectorLDILoongArch::VLDI(MI, CB, Fixups, STI);

299 case LoongArch::PseudoXVREPLI_B:

300 case LoongArch::PseudoXVREPLI_H:

301 case LoongArch::PseudoXVREPLI_W:

302 case LoongArch::PseudoXVREPLI_D:

303 return expandToVectorLDILoongArch::XVLDI(MI, CB, Fixups, STI);

304 case LoongArch::PseudoAddTPRel_W:

305 case LoongArch::PseudoAddTPRel_D:

306 return expandAddTPRel(MI, CB, Fixups, STI);

307 }

308

309 switch (Size) {

310 default:

312 case 4: {

313 uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);

315 break;

316 }

317 }

318}

319

322 return new LoongArchMCCodeEmitter(Ctx, MCII);

323}

324

325#include "LoongArchGenMCCodeEmitter.inc"

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

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

bool getRelaxHint() const

MCCodeEmitter - Generic instruction encoding interface.

static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)

Context object for machine code objects.

const MCRegisterInfo * getRegisterInfo() const

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

@ SymbolRef

References to labels and assigned expressions.

@ 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.

Instances of this class represent operands of the MCInst class.

MCRegister getReg() const

Returns the register number.

const MCExpr * getExpr() const

uint16_t getEncodingValue(MCRegister Reg) const

Returns the encoding for Reg.

Spec getSpecifier() const

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.

@ ADD

Simple integer binary arithmetic operators.

@ fixup_loongarch_abs64_hi12

@ fixup_loongarch_abs_hi20

@ fixup_loongarch_abs_lo12

@ fixup_loongarch_invalid

@ fixup_loongarch_abs64_lo20

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.

decltype(auto) dyn_cast(const From &Val)

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

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

Definition LoongArchMCCodeEmitter.cpp:320

static Lanai::Fixups FixupKind(const MCExpr *Expr)

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

@ FirstLiteralRelocationKind

decltype(auto) cast(const From &Val)

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