xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Lanai/MCTargetDesc/LanaiMCCodeEmitter.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
10b57cec5SDimitry Andric //===-- LanaiMCCodeEmitter.cpp - Convert Lanai code to machine code -------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the LanaiMCCodeEmitter class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "LanaiAluCode.h"
140b57cec5SDimitry Andric #include "MCTargetDesc/LanaiBaseInfo.h"
150b57cec5SDimitry Andric #include "MCTargetDesc/LanaiFixupKinds.h"
160b57cec5SDimitry Andric #include "MCTargetDesc/LanaiMCExpr.h"
170b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
180b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCCodeEmitter.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCFixup.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
230b57cec5SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
240b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
250b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
260b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
2706c3fb27SDimitry Andric #include "llvm/Support/EndianStream.h"
280b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
290b57cec5SDimitry Andric #include <cassert>
300b57cec5SDimitry Andric #include <cstdint>
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric #define DEBUG_TYPE "mccodeemitter"
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric namespace llvm {
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric namespace {
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric class LanaiMCCodeEmitter : public MCCodeEmitter {
410b57cec5SDimitry Andric public:
420b57cec5SDimitry Andric   LanaiMCCodeEmitter(const MCInstrInfo &MCII, MCContext &C) {}
430b57cec5SDimitry Andric   LanaiMCCodeEmitter(const LanaiMCCodeEmitter &) = delete;
440b57cec5SDimitry Andric   void operator=(const LanaiMCCodeEmitter &) = delete;
450b57cec5SDimitry Andric   ~LanaiMCCodeEmitter() override = default;
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric   // The functions below are called by TableGen generated functions for getting
480b57cec5SDimitry Andric   // the binary encoding of instructions/opereands.
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric   // getBinaryCodeForInstr - TableGen'erated function for getting the
510b57cec5SDimitry Andric   // binary encoding for an instruction.
520b57cec5SDimitry Andric   uint64_t getBinaryCodeForInstr(const MCInst &Inst,
530b57cec5SDimitry Andric                                  SmallVectorImpl<MCFixup> &Fixups,
540b57cec5SDimitry Andric                                  const MCSubtargetInfo &SubtargetInfo) const;
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric   // getMachineOpValue - Return binary encoding of operand. If the machine
570b57cec5SDimitry Andric   // operand requires relocation, record the relocation and return zero.
580b57cec5SDimitry Andric   unsigned getMachineOpValue(const MCInst &Inst, const MCOperand &MCOp,
590b57cec5SDimitry Andric                              SmallVectorImpl<MCFixup> &Fixups,
600b57cec5SDimitry Andric                              const MCSubtargetInfo &SubtargetInfo) const;
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric   unsigned getRiMemoryOpValue(const MCInst &Inst, unsigned OpNo,
630b57cec5SDimitry Andric                               SmallVectorImpl<MCFixup> &Fixups,
640b57cec5SDimitry Andric                               const MCSubtargetInfo &SubtargetInfo) const;
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric   unsigned getRrMemoryOpValue(const MCInst &Inst, unsigned OpNo,
670b57cec5SDimitry Andric                               SmallVectorImpl<MCFixup> &Fixups,
680b57cec5SDimitry Andric                               const MCSubtargetInfo &SubtargetInfo) const;
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric   unsigned getSplsOpValue(const MCInst &Inst, unsigned OpNo,
710b57cec5SDimitry Andric                           SmallVectorImpl<MCFixup> &Fixups,
720b57cec5SDimitry Andric                           const MCSubtargetInfo &SubtargetInfo) const;
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric   unsigned getBranchTargetOpValue(const MCInst &Inst, unsigned OpNo,
750b57cec5SDimitry Andric                                   SmallVectorImpl<MCFixup> &Fixups,
760b57cec5SDimitry Andric                                   const MCSubtargetInfo &SubtargetInfo) const;
770b57cec5SDimitry Andric 
7806c3fb27SDimitry Andric   void encodeInstruction(const MCInst &Inst, SmallVectorImpl<char> &CB,
790b57cec5SDimitry Andric                          SmallVectorImpl<MCFixup> &Fixups,
800b57cec5SDimitry Andric                          const MCSubtargetInfo &SubtargetInfo) const override;
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   unsigned adjustPqBitsRmAndRrm(const MCInst &Inst, unsigned Value,
830b57cec5SDimitry Andric                                 const MCSubtargetInfo &STI) const;
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   unsigned adjustPqBitsSpls(const MCInst &Inst, unsigned Value,
860b57cec5SDimitry Andric                             const MCSubtargetInfo &STI) const;
870b57cec5SDimitry Andric };
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric } // end anonymous namespace
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric static Lanai::Fixups FixupKind(const MCExpr *Expr) {
920b57cec5SDimitry Andric   if (isa<MCSymbolRefExpr>(Expr))
930b57cec5SDimitry Andric     return Lanai::FIXUP_LANAI_21;
940b57cec5SDimitry Andric   if (const LanaiMCExpr *McExpr = dyn_cast<LanaiMCExpr>(Expr)) {
950b57cec5SDimitry Andric     LanaiMCExpr::VariantKind ExprKind = McExpr->getKind();
960b57cec5SDimitry Andric     switch (ExprKind) {
970b57cec5SDimitry Andric     case LanaiMCExpr::VK_Lanai_None:
980b57cec5SDimitry Andric       return Lanai::FIXUP_LANAI_21;
990b57cec5SDimitry Andric     case LanaiMCExpr::VK_Lanai_ABS_HI:
1000b57cec5SDimitry Andric       return Lanai::FIXUP_LANAI_HI16;
1010b57cec5SDimitry Andric     case LanaiMCExpr::VK_Lanai_ABS_LO:
1020b57cec5SDimitry Andric       return Lanai::FIXUP_LANAI_LO16;
1030b57cec5SDimitry Andric     }
1040b57cec5SDimitry Andric   }
1050b57cec5SDimitry Andric   return Lanai::Fixups(0);
1060b57cec5SDimitry Andric }
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric // getMachineOpValue - Return binary encoding of operand. If the machine
1090b57cec5SDimitry Andric // operand requires relocation, record the relocation and return zero.
1100b57cec5SDimitry Andric unsigned LanaiMCCodeEmitter::getMachineOpValue(
1110b57cec5SDimitry Andric     const MCInst &Inst, const MCOperand &MCOp, SmallVectorImpl<MCFixup> &Fixups,
1120b57cec5SDimitry Andric     const MCSubtargetInfo &SubtargetInfo) const {
1130b57cec5SDimitry Andric   if (MCOp.isReg())
1140b57cec5SDimitry Andric     return getLanaiRegisterNumbering(MCOp.getReg());
1150b57cec5SDimitry Andric   if (MCOp.isImm())
1160b57cec5SDimitry Andric     return static_cast<unsigned>(MCOp.getImm());
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric   // MCOp must be an expression
1190b57cec5SDimitry Andric   assert(MCOp.isExpr());
1200b57cec5SDimitry Andric   const MCExpr *Expr = MCOp.getExpr();
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric   // Extract the symbolic reference side of a binary expression.
1230b57cec5SDimitry Andric   if (Expr->getKind() == MCExpr::Binary) {
1240b57cec5SDimitry Andric     const MCBinaryExpr *BinaryExpr = static_cast<const MCBinaryExpr *>(Expr);
1250b57cec5SDimitry Andric     Expr = BinaryExpr->getLHS();
1260b57cec5SDimitry Andric   }
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric   assert(isa<LanaiMCExpr>(Expr) || Expr->getKind() == MCExpr::SymbolRef);
1290b57cec5SDimitry Andric   // Push fixup (all info is contained within)
1300b57cec5SDimitry Andric   Fixups.push_back(
1310b57cec5SDimitry Andric       MCFixup::create(0, MCOp.getExpr(), MCFixupKind(FixupKind(Expr))));
1320b57cec5SDimitry Andric   return 0;
1330b57cec5SDimitry Andric }
1340b57cec5SDimitry Andric 
1350b57cec5SDimitry Andric // Helper function to adjust P and Q bits on load and store instructions.
1360b57cec5SDimitry Andric static unsigned adjustPqBits(const MCInst &Inst, unsigned Value,
1370b57cec5SDimitry Andric                              unsigned PBitShift, unsigned QBitShift) {
1380b57cec5SDimitry Andric   const MCOperand AluOp = Inst.getOperand(3);
1390b57cec5SDimitry Andric   unsigned AluCode = AluOp.getImm();
1400b57cec5SDimitry Andric 
1410b57cec5SDimitry Andric   // Set the P bit to one iff the immediate is nonzero and not a post-op
1420b57cec5SDimitry Andric   // instruction.
1430b57cec5SDimitry Andric   const MCOperand Op2 = Inst.getOperand(2);
1440b57cec5SDimitry Andric   Value &= ~(1 << PBitShift);
1450b57cec5SDimitry Andric   if (!LPAC::isPostOp(AluCode) &&
1460b57cec5SDimitry Andric       ((Op2.isImm() && Op2.getImm() != 0) ||
1470b57cec5SDimitry Andric        (Op2.isReg() && Op2.getReg() != Lanai::R0) || (Op2.isExpr())))
1480b57cec5SDimitry Andric     Value |= (1 << PBitShift);
1490b57cec5SDimitry Andric 
1500b57cec5SDimitry Andric   // Set the Q bit to one iff it is a post- or pre-op instruction.
1510b57cec5SDimitry Andric   assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
1520b57cec5SDimitry Andric          "Expected register operand.");
1530b57cec5SDimitry Andric   Value &= ~(1 << QBitShift);
1540b57cec5SDimitry Andric   if (LPAC::modifiesOp(AluCode) && ((Op2.isImm() && Op2.getImm() != 0) ||
1550b57cec5SDimitry Andric                                     (Op2.isReg() && Op2.getReg() != Lanai::R0)))
1560b57cec5SDimitry Andric     Value |= (1 << QBitShift);
1570b57cec5SDimitry Andric 
1580b57cec5SDimitry Andric   return Value;
1590b57cec5SDimitry Andric }
1600b57cec5SDimitry Andric 
1610b57cec5SDimitry Andric unsigned
1620b57cec5SDimitry Andric LanaiMCCodeEmitter::adjustPqBitsRmAndRrm(const MCInst &Inst, unsigned Value,
1630b57cec5SDimitry Andric                                          const MCSubtargetInfo &STI) const {
1640b57cec5SDimitry Andric   return adjustPqBits(Inst, Value, 17, 16);
1650b57cec5SDimitry Andric }
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric unsigned
1680b57cec5SDimitry Andric LanaiMCCodeEmitter::adjustPqBitsSpls(const MCInst &Inst, unsigned Value,
1690b57cec5SDimitry Andric                                      const MCSubtargetInfo &STI) const {
1700b57cec5SDimitry Andric   return adjustPqBits(Inst, Value, 11, 10);
1710b57cec5SDimitry Andric }
1720b57cec5SDimitry Andric 
1730b57cec5SDimitry Andric void LanaiMCCodeEmitter::encodeInstruction(
17406c3fb27SDimitry Andric     const MCInst &Inst, SmallVectorImpl<char> &CB,
17506c3fb27SDimitry Andric     SmallVectorImpl<MCFixup> &Fixups,
1760b57cec5SDimitry Andric     const MCSubtargetInfo &SubtargetInfo) const {
1770b57cec5SDimitry Andric   // Get instruction encoding and emit it
1780b57cec5SDimitry Andric   unsigned Value = getBinaryCodeForInstr(Inst, Fixups, SubtargetInfo);
1790b57cec5SDimitry Andric   ++MCNumEmitted; // Keep track of the number of emitted insns.
1800b57cec5SDimitry Andric 
181*5f757f3fSDimitry Andric   support::endian::write<uint32_t>(CB, Value, llvm::endianness::big);
1820b57cec5SDimitry Andric }
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric // Encode Lanai Memory Operand
1850b57cec5SDimitry Andric unsigned LanaiMCCodeEmitter::getRiMemoryOpValue(
1860b57cec5SDimitry Andric     const MCInst &Inst, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
1870b57cec5SDimitry Andric     const MCSubtargetInfo &SubtargetInfo) const {
1880b57cec5SDimitry Andric   unsigned Encoding;
1890b57cec5SDimitry Andric   const MCOperand Op1 = Inst.getOperand(OpNo + 0);
1900b57cec5SDimitry Andric   const MCOperand Op2 = Inst.getOperand(OpNo + 1);
1910b57cec5SDimitry Andric   const MCOperand AluOp = Inst.getOperand(OpNo + 2);
1920b57cec5SDimitry Andric 
1930b57cec5SDimitry Andric   assert(Op1.isReg() && "First operand is not register.");
1940b57cec5SDimitry Andric   assert((Op2.isImm() || Op2.isExpr()) &&
1950b57cec5SDimitry Andric          "Second operand is neither an immediate nor an expression.");
1960b57cec5SDimitry Andric   assert((LPAC::getAluOp(AluOp.getImm()) == LPAC::ADD) &&
1970b57cec5SDimitry Andric          "Register immediate only supports addition operator");
1980b57cec5SDimitry Andric 
1990b57cec5SDimitry Andric   Encoding = (getLanaiRegisterNumbering(Op1.getReg()) << 18);
2000b57cec5SDimitry Andric   if (Op2.isImm()) {
2010b57cec5SDimitry Andric     assert(isInt<16>(Op2.getImm()) &&
2020b57cec5SDimitry Andric            "Constant value truncated (limited to 16-bit)");
2030b57cec5SDimitry Andric 
2040b57cec5SDimitry Andric     Encoding |= (Op2.getImm() & 0xffff);
2050b57cec5SDimitry Andric     if (Op2.getImm() != 0) {
2060b57cec5SDimitry Andric       if (LPAC::isPreOp(AluOp.getImm()))
2070b57cec5SDimitry Andric         Encoding |= (0x3 << 16);
2080b57cec5SDimitry Andric       if (LPAC::isPostOp(AluOp.getImm()))
2090b57cec5SDimitry Andric         Encoding |= (0x1 << 16);
2100b57cec5SDimitry Andric     }
2110b57cec5SDimitry Andric   } else
2120b57cec5SDimitry Andric     getMachineOpValue(Inst, Op2, Fixups, SubtargetInfo);
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric   return Encoding;
2150b57cec5SDimitry Andric }
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric unsigned LanaiMCCodeEmitter::getRrMemoryOpValue(
2180b57cec5SDimitry Andric     const MCInst &Inst, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
2190b57cec5SDimitry Andric     const MCSubtargetInfo &SubtargetInfo) const {
2200b57cec5SDimitry Andric   unsigned Encoding;
2210b57cec5SDimitry Andric   const MCOperand Op1 = Inst.getOperand(OpNo + 0);
2220b57cec5SDimitry Andric   const MCOperand Op2 = Inst.getOperand(OpNo + 1);
2230b57cec5SDimitry Andric   const MCOperand AluMCOp = Inst.getOperand(OpNo + 2);
2240b57cec5SDimitry Andric 
2250b57cec5SDimitry Andric   assert(Op1.isReg() && "First operand is not register.");
2260b57cec5SDimitry Andric   Encoding = (getLanaiRegisterNumbering(Op1.getReg()) << 15);
2270b57cec5SDimitry Andric   assert(Op2.isReg() && "Second operand is not register.");
2280b57cec5SDimitry Andric   Encoding |= (getLanaiRegisterNumbering(Op2.getReg()) << 10);
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric   assert(AluMCOp.isImm() && "Third operator is not immediate.");
2310b57cec5SDimitry Andric   // Set BBB
2320b57cec5SDimitry Andric   unsigned AluOp = AluMCOp.getImm();
2330b57cec5SDimitry Andric   Encoding |= LPAC::encodeLanaiAluCode(AluOp) << 5;
2340b57cec5SDimitry Andric   // Set P and Q
2350b57cec5SDimitry Andric   if (LPAC::isPreOp(AluOp))
2360b57cec5SDimitry Andric     Encoding |= (0x3 << 8);
2370b57cec5SDimitry Andric   if (LPAC::isPostOp(AluOp))
2380b57cec5SDimitry Andric     Encoding |= (0x1 << 8);
2390b57cec5SDimitry Andric   // Set JJJJ
2400b57cec5SDimitry Andric   switch (LPAC::getAluOp(AluOp)) {
2410b57cec5SDimitry Andric   case LPAC::SHL:
2420b57cec5SDimitry Andric   case LPAC::SRL:
2430b57cec5SDimitry Andric     Encoding |= 0x10;
2440b57cec5SDimitry Andric     break;
2450b57cec5SDimitry Andric   case LPAC::SRA:
2460b57cec5SDimitry Andric     Encoding |= 0x18;
2470b57cec5SDimitry Andric     break;
2480b57cec5SDimitry Andric   default:
2490b57cec5SDimitry Andric     break;
2500b57cec5SDimitry Andric   }
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric   return Encoding;
2530b57cec5SDimitry Andric }
2540b57cec5SDimitry Andric 
2550b57cec5SDimitry Andric unsigned
2560b57cec5SDimitry Andric LanaiMCCodeEmitter::getSplsOpValue(const MCInst &Inst, unsigned OpNo,
2570b57cec5SDimitry Andric                                    SmallVectorImpl<MCFixup> &Fixups,
2580b57cec5SDimitry Andric                                    const MCSubtargetInfo &SubtargetInfo) const {
2590b57cec5SDimitry Andric   unsigned Encoding;
2600b57cec5SDimitry Andric   const MCOperand Op1 = Inst.getOperand(OpNo + 0);
2610b57cec5SDimitry Andric   const MCOperand Op2 = Inst.getOperand(OpNo + 1);
2620b57cec5SDimitry Andric   const MCOperand AluOp = Inst.getOperand(OpNo + 2);
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric   assert(Op1.isReg() && "First operand is not register.");
2650b57cec5SDimitry Andric   assert((Op2.isImm() || Op2.isExpr()) &&
2660b57cec5SDimitry Andric          "Second operand is neither an immediate nor an expression.");
2670b57cec5SDimitry Andric   assert((LPAC::getAluOp(AluOp.getImm()) == LPAC::ADD) &&
2680b57cec5SDimitry Andric          "Register immediate only supports addition operator");
2690b57cec5SDimitry Andric 
2700b57cec5SDimitry Andric   Encoding = (getLanaiRegisterNumbering(Op1.getReg()) << 12);
2710b57cec5SDimitry Andric   if (Op2.isImm()) {
2720b57cec5SDimitry Andric     assert(isInt<10>(Op2.getImm()) &&
2730b57cec5SDimitry Andric            "Constant value truncated (limited to 10-bit)");
2740b57cec5SDimitry Andric 
2750b57cec5SDimitry Andric     Encoding |= (Op2.getImm() & 0x3ff);
2760b57cec5SDimitry Andric     if (Op2.getImm() != 0) {
2770b57cec5SDimitry Andric       if (LPAC::isPreOp(AluOp.getImm()))
2780b57cec5SDimitry Andric         Encoding |= (0x3 << 10);
2790b57cec5SDimitry Andric       if (LPAC::isPostOp(AluOp.getImm()))
2800b57cec5SDimitry Andric         Encoding |= (0x1 << 10);
2810b57cec5SDimitry Andric     }
2820b57cec5SDimitry Andric   } else
2830b57cec5SDimitry Andric     getMachineOpValue(Inst, Op2, Fixups, SubtargetInfo);
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric   return Encoding;
2860b57cec5SDimitry Andric }
2870b57cec5SDimitry Andric 
2880b57cec5SDimitry Andric unsigned LanaiMCCodeEmitter::getBranchTargetOpValue(
2890b57cec5SDimitry Andric     const MCInst &Inst, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
2900b57cec5SDimitry Andric     const MCSubtargetInfo &SubtargetInfo) const {
2910b57cec5SDimitry Andric   const MCOperand &MCOp = Inst.getOperand(OpNo);
2920b57cec5SDimitry Andric   if (MCOp.isReg() || MCOp.isImm())
2930b57cec5SDimitry Andric     return getMachineOpValue(Inst, MCOp, Fixups, SubtargetInfo);
2940b57cec5SDimitry Andric 
2950b57cec5SDimitry Andric   Fixups.push_back(MCFixup::create(
2960b57cec5SDimitry Andric       0, MCOp.getExpr(), static_cast<MCFixupKind>(Lanai::FIXUP_LANAI_25)));
2970b57cec5SDimitry Andric 
2980b57cec5SDimitry Andric   return 0;
2990b57cec5SDimitry Andric }
3000b57cec5SDimitry Andric 
3010b57cec5SDimitry Andric #include "LanaiGenMCCodeEmitter.inc"
3020b57cec5SDimitry Andric 
3030b57cec5SDimitry Andric } // end namespace llvm
3040b57cec5SDimitry Andric 
3050b57cec5SDimitry Andric llvm::MCCodeEmitter *
3060b57cec5SDimitry Andric llvm::createLanaiMCCodeEmitter(const MCInstrInfo &InstrInfo,
3070b57cec5SDimitry Andric                                MCContext &context) {
3080b57cec5SDimitry Andric   return new LanaiMCCodeEmitter(InstrInfo, context);
3090b57cec5SDimitry Andric }
310