181ad6265SDimitry Andric //=- LoongArchMCCodeEmitter.cpp - Convert LoongArch code to machine code --===// 281ad6265SDimitry Andric // 381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 681ad6265SDimitry Andric // 781ad6265SDimitry Andric //===----------------------------------------------------------------------===// 881ad6265SDimitry Andric // 981ad6265SDimitry Andric // This file implements the LoongArchMCCodeEmitter class. 1081ad6265SDimitry Andric // 1181ad6265SDimitry Andric //===----------------------------------------------------------------------===// 1281ad6265SDimitry Andric 13bdd1243dSDimitry Andric #include "LoongArchFixupKinds.h" 1481ad6265SDimitry Andric #include "MCTargetDesc/LoongArchBaseInfo.h" 15bdd1243dSDimitry Andric #include "MCTargetDesc/LoongArchMCExpr.h" 1681ad6265SDimitry Andric #include "MCTargetDesc/LoongArchMCTargetDesc.h" 1781ad6265SDimitry Andric #include "llvm/MC/MCCodeEmitter.h" 1881ad6265SDimitry Andric #include "llvm/MC/MCContext.h" 1981ad6265SDimitry Andric #include "llvm/MC/MCInstBuilder.h" 2081ad6265SDimitry Andric #include "llvm/MC/MCInstrInfo.h" 2181ad6265SDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 22647cbc5dSDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 23bdd1243dSDimitry Andric #include "llvm/Support/Casting.h" 2481ad6265SDimitry Andric #include "llvm/Support/EndianStream.h" 2581ad6265SDimitry Andric 2681ad6265SDimitry Andric using namespace llvm; 2781ad6265SDimitry Andric 2881ad6265SDimitry Andric #define DEBUG_TYPE "mccodeemitter" 2981ad6265SDimitry Andric 3081ad6265SDimitry Andric namespace { 3181ad6265SDimitry Andric class LoongArchMCCodeEmitter : public MCCodeEmitter { 3281ad6265SDimitry Andric LoongArchMCCodeEmitter(const LoongArchMCCodeEmitter &) = delete; 3381ad6265SDimitry Andric void operator=(const LoongArchMCCodeEmitter &) = delete; 3481ad6265SDimitry Andric MCContext &Ctx; 3581ad6265SDimitry Andric MCInstrInfo const &MCII; 3681ad6265SDimitry Andric 3781ad6265SDimitry Andric public: 3881ad6265SDimitry Andric LoongArchMCCodeEmitter(MCContext &ctx, MCInstrInfo const &MCII) 3981ad6265SDimitry Andric : Ctx(ctx), MCII(MCII) {} 4081ad6265SDimitry Andric 4181ad6265SDimitry Andric ~LoongArchMCCodeEmitter() override {} 4281ad6265SDimitry Andric 4306c3fb27SDimitry Andric void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB, 4481ad6265SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 4581ad6265SDimitry Andric const MCSubtargetInfo &STI) const override; 4681ad6265SDimitry Andric 4706c3fb27SDimitry Andric template <unsigned Opc> 4806c3fb27SDimitry Andric void expandToVectorLDI(const MCInst &MI, SmallVectorImpl<char> &CB, 4906c3fb27SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 5006c3fb27SDimitry Andric const MCSubtargetInfo &STI) const; 5106c3fb27SDimitry Andric 5281ad6265SDimitry Andric /// TableGen'erated function for getting the binary encoding for an 5381ad6265SDimitry Andric /// instruction. 5481ad6265SDimitry Andric uint64_t getBinaryCodeForInstr(const MCInst &MI, 5581ad6265SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 5681ad6265SDimitry Andric const MCSubtargetInfo &STI) const; 5781ad6265SDimitry Andric 5881ad6265SDimitry Andric /// Return binary encoding of operand. If the machine operand requires 5981ad6265SDimitry Andric /// relocation, record the relocation and return zero. 6081ad6265SDimitry Andric unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, 6181ad6265SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 6281ad6265SDimitry Andric const MCSubtargetInfo &STI) const; 6381ad6265SDimitry Andric 6481ad6265SDimitry Andric /// Return binary encoding of an immediate operand specified by OpNo. 6581ad6265SDimitry Andric /// The value returned is the value of the immediate minus 1. 6681ad6265SDimitry Andric /// Note that this function is dedicated to specific immediate types, 6781ad6265SDimitry Andric /// e.g. uimm2_plus1. 6881ad6265SDimitry Andric unsigned getImmOpValueSub1(const MCInst &MI, unsigned OpNo, 6981ad6265SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 7081ad6265SDimitry Andric const MCSubtargetInfo &STI) const; 7181ad6265SDimitry Andric 7281ad6265SDimitry Andric /// Return binary encoding of an immediate operand specified by OpNo. 7381ad6265SDimitry Andric /// The value returned is the value of the immediate shifted right 7406c3fb27SDimitry Andric // arithmetically by N. 7581ad6265SDimitry Andric /// Note that this function is dedicated to specific immediate types, 7681ad6265SDimitry Andric /// e.g. simm14_lsl2, simm16_lsl2, simm21_lsl2 and simm26_lsl2. 7706c3fb27SDimitry Andric template <unsigned N> 7806c3fb27SDimitry Andric unsigned getImmOpValueAsr(const MCInst &MI, unsigned OpNo, 7981ad6265SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 8006c3fb27SDimitry Andric const MCSubtargetInfo &STI) const { 8106c3fb27SDimitry Andric const MCOperand &MO = MI.getOperand(OpNo); 8206c3fb27SDimitry Andric if (MO.isImm()) { 8306c3fb27SDimitry Andric unsigned Res = MI.getOperand(OpNo).getImm(); 8406c3fb27SDimitry Andric assert((Res & ((1U << N) - 1U)) == 0 && "lowest N bits are non-zero"); 8506c3fb27SDimitry Andric return Res >> N; 8606c3fb27SDimitry Andric } 8706c3fb27SDimitry Andric return getExprOpValue(MI, MO, Fixups, STI); 8806c3fb27SDimitry Andric } 89bdd1243dSDimitry Andric 90bdd1243dSDimitry Andric unsigned getExprOpValue(const MCInst &MI, const MCOperand &MO, 91bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 92bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const; 9381ad6265SDimitry Andric }; 94972a253aSDimitry Andric } // end namespace 9581ad6265SDimitry Andric 9681ad6265SDimitry Andric unsigned 9781ad6265SDimitry Andric LoongArchMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO, 9881ad6265SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 9981ad6265SDimitry Andric const MCSubtargetInfo &STI) const { 10081ad6265SDimitry Andric 10181ad6265SDimitry Andric if (MO.isReg()) 10281ad6265SDimitry Andric return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); 10381ad6265SDimitry Andric 10481ad6265SDimitry Andric if (MO.isImm()) 10581ad6265SDimitry Andric return static_cast<unsigned>(MO.getImm()); 10681ad6265SDimitry Andric 107bdd1243dSDimitry Andric // MO must be an Expr. 108bdd1243dSDimitry Andric assert(MO.isExpr()); 109bdd1243dSDimitry Andric return getExprOpValue(MI, MO, Fixups, STI); 11081ad6265SDimitry Andric } 11181ad6265SDimitry Andric 11281ad6265SDimitry Andric unsigned 11381ad6265SDimitry Andric LoongArchMCCodeEmitter::getImmOpValueSub1(const MCInst &MI, unsigned OpNo, 11481ad6265SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 11581ad6265SDimitry Andric const MCSubtargetInfo &STI) const { 11681ad6265SDimitry Andric return MI.getOperand(OpNo).getImm() - 1; 11781ad6265SDimitry Andric } 11881ad6265SDimitry Andric 11981ad6265SDimitry Andric unsigned 120bdd1243dSDimitry Andric LoongArchMCCodeEmitter::getExprOpValue(const MCInst &MI, const MCOperand &MO, 121bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups, 122bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const { 123bdd1243dSDimitry Andric assert(MO.isExpr() && "getExprOpValue expects only expressions"); 124647cbc5dSDimitry Andric bool RelaxCandidate = false; 125647cbc5dSDimitry Andric bool EnableRelax = STI.hasFeature(LoongArch::FeatureRelax); 126bdd1243dSDimitry Andric const MCExpr *Expr = MO.getExpr(); 127bdd1243dSDimitry Andric MCExpr::ExprKind Kind = Expr->getKind(); 128bdd1243dSDimitry Andric LoongArch::Fixups FixupKind = LoongArch::fixup_loongarch_invalid; 129bdd1243dSDimitry Andric if (Kind == MCExpr::Target) { 130bdd1243dSDimitry Andric const LoongArchMCExpr *LAExpr = cast<LoongArchMCExpr>(Expr); 131bdd1243dSDimitry Andric 132647cbc5dSDimitry Andric RelaxCandidate = LAExpr->getRelaxHint(); 133bdd1243dSDimitry Andric switch (LAExpr->getKind()) { 134bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_None: 135bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_Invalid: 136bdd1243dSDimitry Andric llvm_unreachable("Unhandled fixup kind!"); 137bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_B16: 138bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_b16; 139bdd1243dSDimitry Andric break; 140bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_B21: 141bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_b21; 142bdd1243dSDimitry Andric break; 143bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_B26: 144bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_CALL: 145bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_CALL_PLT: 146bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_b26; 147bdd1243dSDimitry Andric break; 148bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_ABS_HI20: 149bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_abs_hi20; 150bdd1243dSDimitry Andric break; 151bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_ABS_LO12: 152bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_abs_lo12; 153bdd1243dSDimitry Andric break; 154bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_ABS64_LO20: 155bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_abs64_lo20; 156bdd1243dSDimitry Andric break; 157bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_ABS64_HI12: 158bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_abs64_hi12; 159bdd1243dSDimitry Andric break; 160bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_PCALA_HI20: 161bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_pcala_hi20; 162bdd1243dSDimitry Andric break; 163bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_PCALA_LO12: 164bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_pcala_lo12; 165bdd1243dSDimitry Andric break; 166bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_PCALA64_LO20: 167bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_pcala64_lo20; 168bdd1243dSDimitry Andric break; 169bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_PCALA64_HI12: 170bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_pcala64_hi12; 171bdd1243dSDimitry Andric break; 172bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_GOT_PC_HI20: 173bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_got_pc_hi20; 174bdd1243dSDimitry Andric break; 175bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_GOT_PC_LO12: 176bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_got_pc_lo12; 177bdd1243dSDimitry Andric break; 178bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_GOT64_PC_LO20: 179bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_got64_pc_lo20; 180bdd1243dSDimitry Andric break; 181bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_GOT64_PC_HI12: 182bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_got64_pc_hi12; 183bdd1243dSDimitry Andric break; 184bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_GOT_HI20: 185bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_got_hi20; 186bdd1243dSDimitry Andric break; 187bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_GOT_LO12: 188bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_got_lo12; 189bdd1243dSDimitry Andric break; 190bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_GOT64_LO20: 191bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_got64_lo20; 192bdd1243dSDimitry Andric break; 193bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_GOT64_HI12: 194bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_got64_hi12; 195bdd1243dSDimitry Andric break; 196bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_TLS_LE_HI20: 197bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_tls_le_hi20; 198bdd1243dSDimitry Andric break; 199bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_TLS_LE_LO12: 200bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_tls_le_lo12; 201bdd1243dSDimitry Andric break; 202bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_TLS_LE64_LO20: 203bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_tls_le64_lo20; 204bdd1243dSDimitry Andric break; 205bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_TLS_LE64_HI12: 206bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_tls_le64_hi12; 207bdd1243dSDimitry Andric break; 208bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_TLS_IE_PC_HI20: 209bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_tls_ie_pc_hi20; 210bdd1243dSDimitry Andric break; 211bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_TLS_IE_PC_LO12: 212bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_tls_ie_pc_lo12; 213bdd1243dSDimitry Andric break; 214bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_TLS_IE64_PC_LO20: 215bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_tls_ie64_pc_lo20; 216bdd1243dSDimitry Andric break; 217bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_TLS_IE64_PC_HI12: 218bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_tls_ie64_pc_hi12; 219bdd1243dSDimitry Andric break; 220bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_TLS_IE_HI20: 221bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_tls_ie_hi20; 222bdd1243dSDimitry Andric break; 223bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_TLS_IE_LO12: 224bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_tls_ie_lo12; 225bdd1243dSDimitry Andric break; 226bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_TLS_IE64_LO20: 227bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_tls_ie64_lo20; 228bdd1243dSDimitry Andric break; 229bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_TLS_IE64_HI12: 230bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_tls_ie64_hi12; 231bdd1243dSDimitry Andric break; 232bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_TLS_LD_PC_HI20: 233bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_tls_ld_pc_hi20; 234bdd1243dSDimitry Andric break; 235bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_TLS_LD_HI20: 236bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_tls_ld_hi20; 237bdd1243dSDimitry Andric break; 238bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_TLS_GD_PC_HI20: 239bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_tls_gd_pc_hi20; 240bdd1243dSDimitry Andric break; 241bdd1243dSDimitry Andric case LoongArchMCExpr::VK_LoongArch_TLS_GD_HI20: 242bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_tls_gd_hi20; 243bdd1243dSDimitry Andric break; 244*1db9f3b2SDimitry Andric case LoongArchMCExpr::VK_LoongArch_CALL36: 245*1db9f3b2SDimitry Andric FixupKind = LoongArch::fixup_loongarch_call36; 246*1db9f3b2SDimitry Andric break; 247bdd1243dSDimitry Andric } 248bdd1243dSDimitry Andric } else if (Kind == MCExpr::SymbolRef && 249bdd1243dSDimitry Andric cast<MCSymbolRefExpr>(Expr)->getKind() == 250bdd1243dSDimitry Andric MCSymbolRefExpr::VK_None) { 251bdd1243dSDimitry Andric switch (MI.getOpcode()) { 252bdd1243dSDimitry Andric default: 253bdd1243dSDimitry Andric break; 254bdd1243dSDimitry Andric case LoongArch::BEQ: 255bdd1243dSDimitry Andric case LoongArch::BNE: 256bdd1243dSDimitry Andric case LoongArch::BLT: 257bdd1243dSDimitry Andric case LoongArch::BGE: 258bdd1243dSDimitry Andric case LoongArch::BLTU: 259bdd1243dSDimitry Andric case LoongArch::BGEU: 260bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_b16; 261bdd1243dSDimitry Andric break; 262bdd1243dSDimitry Andric case LoongArch::BEQZ: 263bdd1243dSDimitry Andric case LoongArch::BNEZ: 264bdd1243dSDimitry Andric case LoongArch::BCEQZ: 265bdd1243dSDimitry Andric case LoongArch::BCNEZ: 266bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_b21; 267bdd1243dSDimitry Andric break; 268bdd1243dSDimitry Andric case LoongArch::B: 2695f757f3fSDimitry Andric case LoongArch::BL: 270bdd1243dSDimitry Andric FixupKind = LoongArch::fixup_loongarch_b26; 271bdd1243dSDimitry Andric break; 272bdd1243dSDimitry Andric } 273bdd1243dSDimitry Andric } 274bdd1243dSDimitry Andric 275bdd1243dSDimitry Andric assert(FixupKind != LoongArch::fixup_loongarch_invalid && 276bdd1243dSDimitry Andric "Unhandled expression!"); 277bdd1243dSDimitry Andric 278bdd1243dSDimitry Andric Fixups.push_back( 279bdd1243dSDimitry Andric MCFixup::create(0, Expr, MCFixupKind(FixupKind), MI.getLoc())); 280647cbc5dSDimitry Andric 281647cbc5dSDimitry Andric // Emit an R_LARCH_RELAX if linker relaxation is enabled and LAExpr has relax 282647cbc5dSDimitry Andric // hint. 283647cbc5dSDimitry Andric if (EnableRelax && RelaxCandidate) { 284647cbc5dSDimitry Andric const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx); 285647cbc5dSDimitry Andric Fixups.push_back(MCFixup::create( 286647cbc5dSDimitry Andric 0, Dummy, MCFixupKind(LoongArch::fixup_loongarch_relax), MI.getLoc())); 287647cbc5dSDimitry Andric } 288647cbc5dSDimitry Andric 289bdd1243dSDimitry Andric return 0; 290bdd1243dSDimitry Andric } 291bdd1243dSDimitry Andric 29206c3fb27SDimitry Andric template <unsigned Opc> 29306c3fb27SDimitry Andric void LoongArchMCCodeEmitter::expandToVectorLDI( 29406c3fb27SDimitry Andric const MCInst &MI, SmallVectorImpl<char> &CB, 29506c3fb27SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const { 29606c3fb27SDimitry Andric int64_t Imm = MI.getOperand(1).getImm() & 0x3FF; 29706c3fb27SDimitry Andric switch (MI.getOpcode()) { 29806c3fb27SDimitry Andric case LoongArch::PseudoVREPLI_B: 29906c3fb27SDimitry Andric case LoongArch::PseudoXVREPLI_B: 30006c3fb27SDimitry Andric break; 30106c3fb27SDimitry Andric case LoongArch::PseudoVREPLI_H: 30206c3fb27SDimitry Andric case LoongArch::PseudoXVREPLI_H: 30306c3fb27SDimitry Andric Imm |= 0x400; 30406c3fb27SDimitry Andric break; 30506c3fb27SDimitry Andric case LoongArch::PseudoVREPLI_W: 30606c3fb27SDimitry Andric case LoongArch::PseudoXVREPLI_W: 30706c3fb27SDimitry Andric Imm |= 0x800; 30806c3fb27SDimitry Andric break; 30906c3fb27SDimitry Andric case LoongArch::PseudoVREPLI_D: 31006c3fb27SDimitry Andric case LoongArch::PseudoXVREPLI_D: 31106c3fb27SDimitry Andric Imm |= 0xC00; 31206c3fb27SDimitry Andric break; 31306c3fb27SDimitry Andric } 31406c3fb27SDimitry Andric MCInst TmpInst = MCInstBuilder(Opc).addOperand(MI.getOperand(0)).addImm(Imm); 31506c3fb27SDimitry Andric uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 3165f757f3fSDimitry Andric support::endian::write(CB, Binary, llvm::endianness::little); 31706c3fb27SDimitry Andric } 31806c3fb27SDimitry Andric 31981ad6265SDimitry Andric void LoongArchMCCodeEmitter::encodeInstruction( 32006c3fb27SDimitry Andric const MCInst &MI, SmallVectorImpl<char> &CB, 32106c3fb27SDimitry Andric SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const { 32281ad6265SDimitry Andric const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); 32381ad6265SDimitry Andric // Get byte count of instruction. 32481ad6265SDimitry Andric unsigned Size = Desc.getSize(); 32581ad6265SDimitry Andric 32606c3fb27SDimitry Andric switch (MI.getOpcode()) { 32706c3fb27SDimitry Andric default: 32806c3fb27SDimitry Andric break; 32906c3fb27SDimitry Andric case LoongArch::PseudoVREPLI_B: 33006c3fb27SDimitry Andric case LoongArch::PseudoVREPLI_H: 33106c3fb27SDimitry Andric case LoongArch::PseudoVREPLI_W: 33206c3fb27SDimitry Andric case LoongArch::PseudoVREPLI_D: 33306c3fb27SDimitry Andric return expandToVectorLDI<LoongArch::VLDI>(MI, CB, Fixups, STI); 33406c3fb27SDimitry Andric case LoongArch::PseudoXVREPLI_B: 33506c3fb27SDimitry Andric case LoongArch::PseudoXVREPLI_H: 33606c3fb27SDimitry Andric case LoongArch::PseudoXVREPLI_W: 33706c3fb27SDimitry Andric case LoongArch::PseudoXVREPLI_D: 33806c3fb27SDimitry Andric return expandToVectorLDI<LoongArch::XVLDI>(MI, CB, Fixups, STI); 33906c3fb27SDimitry Andric } 34006c3fb27SDimitry Andric 34181ad6265SDimitry Andric switch (Size) { 34281ad6265SDimitry Andric default: 34381ad6265SDimitry Andric llvm_unreachable("Unhandled encodeInstruction length!"); 34481ad6265SDimitry Andric case 4: { 34581ad6265SDimitry Andric uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); 3465f757f3fSDimitry Andric support::endian::write(CB, Bits, llvm::endianness::little); 34781ad6265SDimitry Andric break; 34881ad6265SDimitry Andric } 34981ad6265SDimitry Andric } 35081ad6265SDimitry Andric } 35181ad6265SDimitry Andric 35281ad6265SDimitry Andric MCCodeEmitter *llvm::createLoongArchMCCodeEmitter(const MCInstrInfo &MCII, 35381ad6265SDimitry Andric MCContext &Ctx) { 35481ad6265SDimitry Andric return new LoongArchMCCodeEmitter(Ctx, MCII); 35581ad6265SDimitry Andric } 35681ad6265SDimitry Andric 35781ad6265SDimitry Andric #include "LoongArchGenMCCodeEmitter.inc" 358