LLVM: lib/Target/Lanai/MCTargetDesc/LanaiMCCodeEmitter.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

27#include

28#include

29

30#define DEBUG_TYPE "mccodeemitter"

31

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

33

34namespace llvm {

35

36namespace {

37

38class LanaiMCCodeEmitter : public MCCodeEmitter {

39public:

40 LanaiMCCodeEmitter(const MCInstrInfo &MCII, MCContext &C) {}

41 LanaiMCCodeEmitter(const LanaiMCCodeEmitter &) = delete;

42 void operator=(const LanaiMCCodeEmitter &) = delete;

43 ~LanaiMCCodeEmitter() override = default;

44

45

46

47

48

49

50 uint64_t getBinaryCodeForInstr(const MCInst &Inst,

51 SmallVectorImpl &Fixups,

52 const MCSubtargetInfo &SubtargetInfo) const;

53

54

55

56 unsigned getMachineOpValue(const MCInst &Inst, const MCOperand &MCOp,

57 SmallVectorImpl &Fixups,

58 const MCSubtargetInfo &SubtargetInfo) const;

59

60 unsigned getRiMemoryOpValue(const MCInst &Inst, unsigned OpNo,

61 SmallVectorImpl &Fixups,

62 const MCSubtargetInfo &SubtargetInfo) const;

63

64 unsigned getRrMemoryOpValue(const MCInst &Inst, unsigned OpNo,

65 SmallVectorImpl &Fixups,

66 const MCSubtargetInfo &SubtargetInfo) const;

67

68 unsigned getSplsOpValue(const MCInst &Inst, unsigned OpNo,

69 SmallVectorImpl &Fixups,

70 const MCSubtargetInfo &SubtargetInfo) const;

71

73 SmallVectorImpl &Fixups,

74 const MCSubtargetInfo &SubtargetInfo) const;

75

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

77 SmallVectorImpl &Fixups,

78 const MCSubtargetInfo &SubtargetInfo) const override;

79

80 unsigned adjustPqBitsRmAndRrm(const MCInst &Inst, unsigned Value,

81 const MCSubtargetInfo &STI) const;

82

83 unsigned adjustPqBitsSpls(const MCInst &Inst, unsigned Value,

84 const MCSubtargetInfo &STI) const;

85};

86

87}

88

94 switch (ExprKind) {

101 }

102 }

104}

105

106

107

108unsigned LanaiMCCodeEmitter::getMachineOpValue(

109 const MCInst &Inst, const MCOperand &MCOp, SmallVectorImpl &Fixups,

110 const MCSubtargetInfo &SubtargetInfo) const {

111 if (MCOp.isReg())

112 return getLanaiRegisterNumbering(MCOp.getReg());

113 if (MCOp.isImm())

114 return static_cast<unsigned>(MCOp.getImm());

115

116

117 assert(MCOp.isExpr());

118 const MCExpr *Expr = MCOp.getExpr();

119

120

121 if (Expr->getKind() == MCExpr::Binary) {

122 const MCBinaryExpr *BinaryExpr = static_cast<const MCBinaryExpr *>(Expr);

124 }

125

126 assert(isa(Expr) || Expr->getKind() == MCExpr::SymbolRef);

127

130 return 0;

131}

132

133

135 unsigned PBitShift, unsigned QBitShift) {

137 unsigned AluCode = AluOp.getImm();

138

139

140

142 Value &= ~(1 << PBitShift);

146 Value |= (1 << PBitShift);

147

148

150 "Expected register operand.");

151 Value &= ~(1 << QBitShift);

153 (Op2.isReg() && Op2.getReg() != Lanai::R0)))

154 Value |= (1 << QBitShift);

155

157}

158

159unsigned

160LanaiMCCodeEmitter::adjustPqBitsRmAndRrm(const MCInst &Inst, unsigned Value,

161 const MCSubtargetInfo &STI) const {

162 return adjustPqBits(Inst, Value, 17, 16);

163}

164

165unsigned

166LanaiMCCodeEmitter::adjustPqBitsSpls(const MCInst &Inst, unsigned Value,

167 const MCSubtargetInfo &STI) const {

169}

170

171void LanaiMCCodeEmitter::encodeInstruction(

172 const MCInst &Inst, SmallVectorImpl &CB,

173 SmallVectorImpl &Fixups,

174 const MCSubtargetInfo &SubtargetInfo) const {

175

176 unsigned Value = getBinaryCodeForInstr(Inst, Fixups, SubtargetInfo);

177 ++MCNumEmitted;

178

180}

181

182

183unsigned LanaiMCCodeEmitter::getRiMemoryOpValue(

184 const MCInst &Inst, unsigned OpNo, SmallVectorImpl &Fixups,

185 const MCSubtargetInfo &SubtargetInfo) const {

186 unsigned Encoding;

187 const MCOperand Op1 = Inst.getOperand(OpNo + 0);

188 const MCOperand Op2 = Inst.getOperand(OpNo + 1);

189 const MCOperand AluOp = Inst.getOperand(OpNo + 2);

190

191 assert(Op1.isReg() && "First operand is not register.");

192 assert((Op2.isImm() || Op2.isExpr()) &&

193 "Second operand is neither an immediate nor an expression.");

194 assert((LPAC::getAluOp(AluOp.getImm()) == LPAC::ADD) &&

195 "Register immediate only supports addition operator");

196

197 Encoding = (getLanaiRegisterNumbering(Op1.getReg()) << 18);

198 if (Op2.isImm()) {

199 assert(isInt<16>(Op2.getImm()) &&

200 "Constant value truncated (limited to 16-bit)");

201

202 Encoding |= (Op2.getImm() & 0xffff);

203 if (Op2.getImm() != 0) {

204 if (LPAC::isPreOp(AluOp.getImm()))

205 Encoding |= (0x3 << 16);

206 if (LPAC::isPostOp(AluOp.getImm()))

207 Encoding |= (0x1 << 16);

208 }

209 } else

210 getMachineOpValue(Inst, Op2, Fixups, SubtargetInfo);

211

212 return Encoding;

213}

214

215unsigned LanaiMCCodeEmitter::getRrMemoryOpValue(

216 const MCInst &Inst, unsigned OpNo, SmallVectorImpl &Fixups,

217 const MCSubtargetInfo &SubtargetInfo) const {

218 unsigned Encoding;

219 const MCOperand Op1 = Inst.getOperand(OpNo + 0);

220 const MCOperand Op2 = Inst.getOperand(OpNo + 1);

221 const MCOperand AluMCOp = Inst.getOperand(OpNo + 2);

222

223 assert(Op1.isReg() && "First operand is not register.");

224 Encoding = (getLanaiRegisterNumbering(Op1.getReg()) << 15);

225 assert(Op2.isReg() && "Second operand is not register.");

226 Encoding |= (getLanaiRegisterNumbering(Op2.getReg()) << 10);

227

228 assert(AluMCOp.isImm() && "Third operator is not immediate.");

229

230 unsigned AluOp = AluMCOp.getImm();

231 Encoding |= LPAC::encodeLanaiAluCode(AluOp) << 5;

232

233 if (LPAC::isPreOp(AluOp))

234 Encoding |= (0x3 << 8);

235 if (LPAC::isPostOp(AluOp))

236 Encoding |= (0x1 << 8);

237

238 switch (LPAC::getAluOp(AluOp)) {

239 case LPAC::SHL:

240 case LPAC::SRL:

241 Encoding |= 0x10;

242 break;

243 case LPAC::SRA:

244 Encoding |= 0x18;

245 break;

246 default:

247 break;

248 }

249

250 return Encoding;

251}

252

253unsigned

254LanaiMCCodeEmitter::getSplsOpValue(const MCInst &Inst, unsigned OpNo,

255 SmallVectorImpl &Fixups,

256 const MCSubtargetInfo &SubtargetInfo) const {

257 unsigned Encoding;

258 const MCOperand Op1 = Inst.getOperand(OpNo + 0);

259 const MCOperand Op2 = Inst.getOperand(OpNo + 1);

260 const MCOperand AluOp = Inst.getOperand(OpNo + 2);

261

262 assert(Op1.isReg() && "First operand is not register.");

263 assert((Op2.isImm() || Op2.isExpr()) &&

264 "Second operand is neither an immediate nor an expression.");

265 assert((LPAC::getAluOp(AluOp.getImm()) == LPAC::ADD) &&

266 "Register immediate only supports addition operator");

267

268 Encoding = (getLanaiRegisterNumbering(Op1.getReg()) << 12);

269 if (Op2.isImm()) {

270 assert(isInt<10>(Op2.getImm()) &&

271 "Constant value truncated (limited to 10-bit)");

272

273 Encoding |= (Op2.getImm() & 0x3ff);

274 if (Op2.getImm() != 0) {

275 if (LPAC::isPreOp(AluOp.getImm()))

276 Encoding |= (0x3 << 10);

277 if (LPAC::isPostOp(AluOp.getImm()))

278 Encoding |= (0x1 << 10);

279 }

280 } else

281 getMachineOpValue(Inst, Op2, Fixups, SubtargetInfo);

282

283 return Encoding;

284}

285

286unsigned LanaiMCCodeEmitter::getBranchTargetOpValue(

287 const MCInst &Inst, unsigned OpNo, SmallVectorImpl &Fixups,

288 const MCSubtargetInfo &SubtargetInfo) const {

289 const MCOperand &MCOp = Inst.getOperand(OpNo);

290 if (MCOp.isReg() || MCOp.isImm())

291 return getMachineOpValue(Inst, MCOp, Fixups, SubtargetInfo);

292

293 Fixups.push_back(MCFixup::create(0, MCOp.getExpr(), Lanai::FIXUP_LANAI_25));

294

295 return 0;

296}

297

298#include "LanaiGenMCCodeEmitter.inc"

299

300}

301

305 return new LanaiMCCodeEmitter(InstrInfo, context);

306}

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

static uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, unsigned FixupKind, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI)

getBranchTargetOpValue - Helper function to get the branch target operand, which is either an immedia...

static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")

This file defines the SmallVector class.

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.

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

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

const MCOperand & getOperand(unsigned i) const

Interface to description of machine instruction set.

Instances of this class represent operands of the MCInst class.

MCRegister getReg() const

Returns the register number.

Extension point for target-specific MCExpr subclasses with a relocation specifier,...

LLVM Value Representation.

static bool isPostOp(unsigned AluOp)

static bool modifiesOp(unsigned AluOp)

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

decltype(auto) dyn_cast(const From &Val)

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

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

Definition LanaiMCCodeEmitter.cpp:303

uint16_t MCFixupKind

Extensible enumeration to represent the type of a fixup.

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

Definition LanaiMCCodeEmitter.cpp:89

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

static unsigned adjustPqBits(const MCInst &Inst, unsigned Value, unsigned PBitShift, unsigned QBitShift)

Definition LanaiMCCodeEmitter.cpp:134