LLVM  14.0.0git
LanaiMCCodeEmitter.cpp
Go to the documentation of this file.
1 //===-- LanaiMCCodeEmitter.cpp - Convert Lanai code to machine code -------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the LanaiMCCodeEmitter class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "LanaiAluCode.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/Statistic.h"
19 #include "llvm/MC/MCCodeEmitter.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCFixup.h"
22 #include "llvm/MC/MCInst.h"
23 #include "llvm/MC/MCInstrInfo.h"
24 #include "llvm/MC/MCRegisterInfo.h"
26 #include "llvm/Support/Casting.h"
28 #include <cassert>
29 #include <cstdint>
30 
31 #define DEBUG_TYPE "mccodeemitter"
32 
33 STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
34 
35 namespace llvm {
36 
37 namespace {
38 
39 class LanaiMCCodeEmitter : public MCCodeEmitter {
40 public:
41  LanaiMCCodeEmitter(const MCInstrInfo &MCII, MCContext &C) {}
42  LanaiMCCodeEmitter(const LanaiMCCodeEmitter &) = delete;
43  void operator=(const LanaiMCCodeEmitter &) = delete;
44  ~LanaiMCCodeEmitter() override = default;
45 
46  // The functions below are called by TableGen generated functions for getting
47  // the binary encoding of instructions/opereands.
48 
49  // getBinaryCodeForInstr - TableGen'erated function for getting the
50  // binary encoding for an instruction.
51  uint64_t getBinaryCodeForInstr(const MCInst &Inst,
52  SmallVectorImpl<MCFixup> &Fixups,
53  const MCSubtargetInfo &SubtargetInfo) const;
54 
55  // getMachineOpValue - Return binary encoding of operand. If the machine
56  // operand requires relocation, record the relocation and return zero.
57  unsigned getMachineOpValue(const MCInst &Inst, const MCOperand &MCOp,
58  SmallVectorImpl<MCFixup> &Fixups,
59  const MCSubtargetInfo &SubtargetInfo) const;
60 
61  unsigned getRiMemoryOpValue(const MCInst &Inst, unsigned OpNo,
62  SmallVectorImpl<MCFixup> &Fixups,
63  const MCSubtargetInfo &SubtargetInfo) const;
64 
65  unsigned getRrMemoryOpValue(const MCInst &Inst, unsigned OpNo,
66  SmallVectorImpl<MCFixup> &Fixups,
67  const MCSubtargetInfo &SubtargetInfo) const;
68 
69  unsigned getSplsOpValue(const MCInst &Inst, unsigned OpNo,
70  SmallVectorImpl<MCFixup> &Fixups,
71  const MCSubtargetInfo &SubtargetInfo) const;
72 
73  unsigned getBranchTargetOpValue(const MCInst &Inst, unsigned OpNo,
74  SmallVectorImpl<MCFixup> &Fixups,
75  const MCSubtargetInfo &SubtargetInfo) const;
76 
77  void encodeInstruction(const MCInst &Inst, raw_ostream &Ostream,
78  SmallVectorImpl<MCFixup> &Fixups,
79  const MCSubtargetInfo &SubtargetInfo) const override;
80 
81  unsigned adjustPqBitsRmAndRrm(const MCInst &Inst, unsigned Value,
82  const MCSubtargetInfo &STI) const;
83 
84  unsigned adjustPqBitsSpls(const MCInst &Inst, unsigned Value,
85  const MCSubtargetInfo &STI) const;
86 };
87 
88 } // end anonymous namespace
89 
90 static Lanai::Fixups FixupKind(const MCExpr *Expr) {
91  if (isa<MCSymbolRefExpr>(Expr))
92  return Lanai::FIXUP_LANAI_21;
93  if (const LanaiMCExpr *McExpr = dyn_cast<LanaiMCExpr>(Expr)) {
94  LanaiMCExpr::VariantKind ExprKind = McExpr->getKind();
95  switch (ExprKind) {
97  return Lanai::FIXUP_LANAI_21;
102  }
103  }
104  return Lanai::Fixups(0);
105 }
106 
107 // getMachineOpValue - Return binary encoding of operand. If the machine
108 // operand requires relocation, record the relocation and return zero.
109 unsigned LanaiMCCodeEmitter::getMachineOpValue(
110  const MCInst &Inst, const MCOperand &MCOp, SmallVectorImpl<MCFixup> &Fixups,
111  const MCSubtargetInfo &SubtargetInfo) const {
112  if (MCOp.isReg())
113  return getLanaiRegisterNumbering(MCOp.getReg());
114  if (MCOp.isImm())
115  return static_cast<unsigned>(MCOp.getImm());
116 
117  // MCOp must be an expression
118  assert(MCOp.isExpr());
119  const MCExpr *Expr = MCOp.getExpr();
120 
121  // Extract the symbolic reference side of a binary expression.
122  if (Expr->getKind() == MCExpr::Binary) {
123  const MCBinaryExpr *BinaryExpr = static_cast<const MCBinaryExpr *>(Expr);
124  Expr = BinaryExpr->getLHS();
125  }
126 
127  assert(isa<LanaiMCExpr>(Expr) || Expr->getKind() == MCExpr::SymbolRef);
128  // Push fixup (all info is contained within)
129  Fixups.push_back(
130  MCFixup::create(0, MCOp.getExpr(), MCFixupKind(FixupKind(Expr))));
131  return 0;
132 }
133 
134 // Helper function to adjust P and Q bits on load and store instructions.
135 static unsigned adjustPqBits(const MCInst &Inst, unsigned Value,
136  unsigned PBitShift, unsigned QBitShift) {
137  const MCOperand AluOp = Inst.getOperand(3);
138  unsigned AluCode = AluOp.getImm();
139 
140  // Set the P bit to one iff the immediate is nonzero and not a post-op
141  // instruction.
142  const MCOperand Op2 = Inst.getOperand(2);
143  Value &= ~(1 << PBitShift);
144  if (!LPAC::isPostOp(AluCode) &&
145  ((Op2.isImm() && Op2.getImm() != 0) ||
146  (Op2.isReg() && Op2.getReg() != Lanai::R0) || (Op2.isExpr())))
147  Value |= (1 << PBitShift);
148 
149  // Set the Q bit to one iff it is a post- or pre-op instruction.
150  assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
151  "Expected register operand.");
152  Value &= ~(1 << QBitShift);
153  if (LPAC::modifiesOp(AluCode) && ((Op2.isImm() && Op2.getImm() != 0) ||
154  (Op2.isReg() && Op2.getReg() != Lanai::R0)))
155  Value |= (1 << QBitShift);
156 
157  return Value;
158 }
159 
160 unsigned
161 LanaiMCCodeEmitter::adjustPqBitsRmAndRrm(const MCInst &Inst, unsigned Value,
162  const MCSubtargetInfo &STI) const {
163  return adjustPqBits(Inst, Value, 17, 16);
164 }
165 
166 unsigned
167 LanaiMCCodeEmitter::adjustPqBitsSpls(const MCInst &Inst, unsigned Value,
168  const MCSubtargetInfo &STI) const {
169  return adjustPqBits(Inst, Value, 11, 10);
170 }
171 
172 void LanaiMCCodeEmitter::encodeInstruction(
173  const MCInst &Inst, raw_ostream &Ostream, SmallVectorImpl<MCFixup> &Fixups,
174  const MCSubtargetInfo &SubtargetInfo) const {
175  // Get instruction encoding and emit it
176  unsigned Value = getBinaryCodeForInstr(Inst, Fixups, SubtargetInfo);
177  ++MCNumEmitted; // Keep track of the number of emitted insns.
178 
179  // Emit bytes in big-endian
180  for (int i = (4 - 1) * 8; i >= 0; i -= 8)
181  Ostream << static_cast<char>((Value >> i) & 0xff);
182 }
183 
184 // Encode Lanai Memory Operand
185 unsigned LanaiMCCodeEmitter::getRiMemoryOpValue(
186  const MCInst &Inst, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
187  const MCSubtargetInfo &SubtargetInfo) const {
188  unsigned Encoding;
189  const MCOperand Op1 = Inst.getOperand(OpNo + 0);
190  const MCOperand Op2 = Inst.getOperand(OpNo + 1);
191  const MCOperand AluOp = Inst.getOperand(OpNo + 2);
192 
193  assert(Op1.isReg() && "First operand is not register.");
194  assert((Op2.isImm() || Op2.isExpr()) &&
195  "Second operand is neither an immediate nor an expression.");
196  assert((LPAC::getAluOp(AluOp.getImm()) == LPAC::ADD) &&
197  "Register immediate only supports addition operator");
198 
199  Encoding = (getLanaiRegisterNumbering(Op1.getReg()) << 18);
200  if (Op2.isImm()) {
201  assert(isInt<16>(Op2.getImm()) &&
202  "Constant value truncated (limited to 16-bit)");
203 
204  Encoding |= (Op2.getImm() & 0xffff);
205  if (Op2.getImm() != 0) {
206  if (LPAC::isPreOp(AluOp.getImm()))
207  Encoding |= (0x3 << 16);
208  if (LPAC::isPostOp(AluOp.getImm()))
209  Encoding |= (0x1 << 16);
210  }
211  } else
212  getMachineOpValue(Inst, Op2, Fixups, SubtargetInfo);
213 
214  return Encoding;
215 }
216 
217 unsigned LanaiMCCodeEmitter::getRrMemoryOpValue(
218  const MCInst &Inst, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
219  const MCSubtargetInfo &SubtargetInfo) const {
220  unsigned Encoding;
221  const MCOperand Op1 = Inst.getOperand(OpNo + 0);
222  const MCOperand Op2 = Inst.getOperand(OpNo + 1);
223  const MCOperand AluMCOp = Inst.getOperand(OpNo + 2);
224 
225  assert(Op1.isReg() && "First operand is not register.");
226  Encoding = (getLanaiRegisterNumbering(Op1.getReg()) << 15);
227  assert(Op2.isReg() && "Second operand is not register.");
228  Encoding |= (getLanaiRegisterNumbering(Op2.getReg()) << 10);
229 
230  assert(AluMCOp.isImm() && "Third operator is not immediate.");
231  // Set BBB
232  unsigned AluOp = AluMCOp.getImm();
233  Encoding |= LPAC::encodeLanaiAluCode(AluOp) << 5;
234  // Set P and Q
235  if (LPAC::isPreOp(AluOp))
236  Encoding |= (0x3 << 8);
237  if (LPAC::isPostOp(AluOp))
238  Encoding |= (0x1 << 8);
239  // Set JJJJ
240  switch (LPAC::getAluOp(AluOp)) {
241  case LPAC::SHL:
242  case LPAC::SRL:
243  Encoding |= 0x10;
244  break;
245  case LPAC::SRA:
246  Encoding |= 0x18;
247  break;
248  default:
249  break;
250  }
251 
252  return Encoding;
253 }
254 
255 unsigned
256 LanaiMCCodeEmitter::getSplsOpValue(const MCInst &Inst, unsigned OpNo,
257  SmallVectorImpl<MCFixup> &Fixups,
258  const MCSubtargetInfo &SubtargetInfo) const {
259  unsigned Encoding;
260  const MCOperand Op1 = Inst.getOperand(OpNo + 0);
261  const MCOperand Op2 = Inst.getOperand(OpNo + 1);
262  const MCOperand AluOp = Inst.getOperand(OpNo + 2);
263 
264  assert(Op1.isReg() && "First operand is not register.");
265  assert((Op2.isImm() || Op2.isExpr()) &&
266  "Second operand is neither an immediate nor an expression.");
267  assert((LPAC::getAluOp(AluOp.getImm()) == LPAC::ADD) &&
268  "Register immediate only supports addition operator");
269 
270  Encoding = (getLanaiRegisterNumbering(Op1.getReg()) << 12);
271  if (Op2.isImm()) {
272  assert(isInt<10>(Op2.getImm()) &&
273  "Constant value truncated (limited to 10-bit)");
274 
275  Encoding |= (Op2.getImm() & 0x3ff);
276  if (Op2.getImm() != 0) {
277  if (LPAC::isPreOp(AluOp.getImm()))
278  Encoding |= (0x3 << 10);
279  if (LPAC::isPostOp(AluOp.getImm()))
280  Encoding |= (0x1 << 10);
281  }
282  } else
283  getMachineOpValue(Inst, Op2, Fixups, SubtargetInfo);
284 
285  return Encoding;
286 }
287 
289  const MCInst &Inst, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
290  const MCSubtargetInfo &SubtargetInfo) const {
291  const MCOperand &MCOp = Inst.getOperand(OpNo);
292  if (MCOp.isReg() || MCOp.isImm())
293  return getMachineOpValue(Inst, MCOp, Fixups, SubtargetInfo);
294 
295  Fixups.push_back(MCFixup::create(
296  0, MCOp.getExpr(), static_cast<MCFixupKind>(Lanai::FIXUP_LANAI_25)));
297 
298  return 0;
299 }
300 
301 #include "LanaiGenMCCodeEmitter.inc"
302 
303 } // end namespace llvm
304 
307  const MCRegisterInfo & /*MRI*/,
308  MCContext &context) {
309  return new LanaiMCCodeEmitter(InstrInfo, context);
310 }
i
i
Definition: README.txt:29
llvm::LPAC::ADD
@ ADD
Definition: LanaiAluCode.h:23
LanaiAluCode.h
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
llvm::LPAC::AluCode
AluCode
Definition: LanaiAluCode.h:22
llvm::FixupKind
static Lanai::Fixups FixupKind(const MCExpr *Expr)
Definition: LanaiMCCodeEmitter.cpp:90
llvm::LPAC::isPostOp
static bool isPostOp(unsigned AluOp)
Definition: LanaiAluCode.h:60
llvm::MCOperand::isReg
bool isReg() const
Definition: MCInst.h:61
llvm::MCContext
Context object for machine code objects.
Definition: MCContext.h:72
MCCodeEmitter.h
llvm::LanaiMCExpr
Definition: LanaiMCExpr.h:17
Statistic.h
LanaiBaseInfo.h
llvm::LPAC::modifiesOp
static bool modifiesOp(unsigned AluOp)
Definition: LanaiAluCode.h:72
llvm::MCFixup::create
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Definition: MCFixup.h:87
llvm::LPAC::SRA
@ SRA
Definition: LanaiAluCode.h:37
llvm::LPAC::SHL
@ SHL
Definition: LanaiAluCode.h:35
llvm::Lanai::FIXUP_LANAI_HI16
@ FIXUP_LANAI_HI16
Definition: LanaiFixupKinds.h:32
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
llvm::Lanai::FIXUP_LANAI_25
@ FIXUP_LANAI_25
Definition: LanaiFixupKinds.h:30
x3
In x86 we generate this spiffy xmm0 xmm0 ret in x86 we generate this which could be xmm1 movss xmm1 xmm0 ret In sse4 we could use insertps to make both better Here s another testcase that could use x3
Definition: README-SSE.txt:547
llvm::LPAC::SRL
@ SRL
Definition: LanaiAluCode.h:36
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::LanaiMCExpr::VK_Lanai_ABS_HI
@ VK_Lanai_ABS_HI
Definition: LanaiMCExpr.h:19
MCInstrInfo.h
llvm::MCOperand::getImm
int64_t getImm() const
Definition: MCInst.h:80
MCInst.h
llvm::AArch64::Fixups
Fixups
Definition: AArch64FixupKinds.h:17
MCSubtargetInfo.h
getBranchTargetOpValue
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...
Definition: ARMMCCodeEmitter.cpp:620
llvm::Lanai::FIXUP_LANAI_21
@ FIXUP_LANAI_21
Definition: LanaiFixupKinds.h:28
LanaiFixupKinds.h
llvm::MCExpr::Binary
@ Binary
Binary expressions.
Definition: MCExpr.h:38
llvm::MCOperand::isImm
bool isImm() const
Definition: MCInst.h:62
uint64_t
llvm::adjustPqBits
static unsigned adjustPqBits(const MCInst &Inst, unsigned Value, unsigned PBitShift, unsigned QBitShift)
Definition: LanaiMCCodeEmitter.cpp:135
llvm::LPAC::isPreOp
static bool isPreOp(unsigned AluOp)
Definition: LanaiAluCode.h:58
STATISTIC
STATISTIC(MCNumEmitted, "Number of MC instructions emitted")
MCRegisterInfo.h
llvm::getLanaiRegisterNumbering
static unsigned getLanaiRegisterNumbering(unsigned Reg)
Definition: LanaiBaseInfo.h:40
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
BinaryExpr
Definition: ItaniumDemangle.h:1698
llvm::LPAC::getAluOp
static unsigned getAluOp(unsigned AluOp)
Definition: LanaiAluCode.h:53
MCFixup.h
llvm::Lanai::FIXUP_LANAI_LO16
@ FIXUP_LANAI_LO16
Definition: LanaiFixupKinds.h:33
llvm::MCRegisterInfo
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Definition: MCRegisterInfo.h:135
llvm::isInt< 16 >
constexpr bool isInt< 16 >(int64_t x)
Definition: MathExtras.h:370
llvm::LanaiMCExpr::VariantKind
VariantKind
Definition: LanaiMCExpr.h:19
llvm::MCInstrInfo
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:25
llvm::MCCodeEmitter
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:21
llvm::LanaiMCExpr::VK_Lanai_None
@ VK_Lanai_None
Definition: LanaiMCExpr.h:19
Casting.h
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::MCOperand::isExpr
bool isExpr() const
Definition: MCInst.h:65
llvm::MCFixupKind
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:21
SmallVector.h
llvm::MCExpr::SymbolRef
@ SymbolRef
References to labels and assigned expressions.
Definition: MCExpr.h:40
llvm::MCInst::getOperand
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:206
LanaiMCExpr.h
llvm::Lanai::Fixups
Fixups
Definition: LanaiFixupKinds.h:24
llvm::MCOperand
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
llvm::createLanaiMCCodeEmitter
MCCodeEmitter * createLanaiMCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, MCContext &Ctx)
Definition: LanaiMCCodeEmitter.cpp:306
raw_ostream.h
MCExpr.h
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::MCExpr
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
llvm::LanaiMCExpr::VK_Lanai_ABS_LO
@ VK_Lanai_ABS_LO
Definition: LanaiMCExpr.h:19
llvm::LPAC::encodeLanaiAluCode
static unsigned encodeLanaiAluCode(unsigned AluOp)
Definition: LanaiAluCode.h:48
llvm::MCOperand::getReg
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:69