Path: blob/main/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.cpp
35294 views
//===-- CSKYMCCodeEmitter.cpp - CSKY Code Emitter interface ---------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements the CSKYMCCodeEmitter class.9//10//===----------------------------------------------------------------------===//1112#include "CSKYMCCodeEmitter.h"13#include "CSKYMCExpr.h"14#include "MCTargetDesc/CSKYMCTargetDesc.h"15#include "llvm/ADT/Statistic.h"16#include "llvm/MC/MCInstBuilder.h"17#include "llvm/MC/MCInstrInfo.h"18#include "llvm/MC/MCRegisterInfo.h"19#include "llvm/MC/MCSubtargetInfo.h"20#include "llvm/Support/Casting.h"21#include "llvm/Support/EndianStream.h"2223using namespace llvm;2425#define DEBUG_TYPE "csky-mccode-emitter"2627STATISTIC(MCNumEmitted, "Number of MC instructions emitted");2829unsigned CSKYMCCodeEmitter::getOImmOpValue(const MCInst &MI, unsigned Idx,30SmallVectorImpl<MCFixup> &Fixups,31const MCSubtargetInfo &STI) const {32const MCOperand &MO = MI.getOperand(Idx);33assert(MO.isImm() && "Unexpected MO type.");34return MO.getImm() - 1;35}3637unsigned38CSKYMCCodeEmitter::getImmOpValueIDLY(const MCInst &MI, unsigned Idx,39SmallVectorImpl<MCFixup> &Fixups,40const MCSubtargetInfo &STI) const {41const MCOperand &MO = MI.getOperand(Idx);42assert(MO.isImm() && "Unexpected MO type.");4344auto V = (MO.getImm() <= 3) ? 4 : MO.getImm();45return V - 1;46}4748unsigned49CSKYMCCodeEmitter::getImmOpValueMSBSize(const MCInst &MI, unsigned Idx,50SmallVectorImpl<MCFixup> &Fixups,51const MCSubtargetInfo &STI) const {52const MCOperand &MSB = MI.getOperand(Idx);53const MCOperand &LSB = MI.getOperand(Idx + 1);54assert(MSB.isImm() && LSB.isImm() && "Unexpected MO type.");5556return MSB.getImm() - LSB.getImm();57}5859static void writeData(uint32_t Bin, unsigned Size, SmallVectorImpl<char> &CB) {60if (Size == 4)61support::endian::write(CB, static_cast<uint16_t>(Bin >> 16),62llvm::endianness::little);63support::endian::write(CB, static_cast<uint16_t>(Bin),64llvm::endianness::little);65}6667void CSKYMCCodeEmitter::expandJBTF(const MCInst &MI, SmallVectorImpl<char> &CB,68SmallVectorImpl<MCFixup> &Fixups,69const MCSubtargetInfo &STI) const {7071MCInst TmpInst;7273uint32_t Binary;7475TmpInst =76MCInstBuilder(MI.getOpcode() == CSKY::JBT_E ? CSKY::BF16 : CSKY::BT16)77.addOperand(MI.getOperand(0))78.addImm(6);79Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);80writeData(Binary, 2, CB);8182if (!STI.hasFeature(CSKY::Has2E3))83TmpInst = MCInstBuilder(CSKY::BR32)84.addOperand(MI.getOperand(1))85.addOperand(MI.getOperand(2));86else87TmpInst = MCInstBuilder(CSKY::JMPI32).addOperand(MI.getOperand(2));88Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);89Fixups[Fixups.size() - 1].setOffset(2);90writeData(Binary, 4, CB);91}9293void CSKYMCCodeEmitter::expandNEG(const MCInst &MI, SmallVectorImpl<char> &CB,94SmallVectorImpl<MCFixup> &Fixups,95const MCSubtargetInfo &STI) const {9697MCInst TmpInst;98uint32_t Binary;99unsigned Size = MI.getOpcode() == CSKY::NEG32 ? 4 : 2;100101TmpInst = MCInstBuilder(Size == 4 ? CSKY::NOT32 : CSKY::NOT16)102.addOperand(MI.getOperand(0))103.addOperand(MI.getOperand(1));104Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);105writeData(Binary, Size, CB);106107TmpInst = MCInstBuilder(Size == 4 ? CSKY::ADDI32 : CSKY::ADDI16)108.addOperand(MI.getOperand(0))109.addOperand(MI.getOperand(0))110.addImm(1);111Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);112writeData(Binary, Size, CB);113}114115void CSKYMCCodeEmitter::expandRSUBI(const MCInst &MI, SmallVectorImpl<char> &CB,116SmallVectorImpl<MCFixup> &Fixups,117const MCSubtargetInfo &STI) const {118119MCInst TmpInst;120uint32_t Binary;121unsigned Size = MI.getOpcode() == CSKY::RSUBI32 ? 4 : 2;122123TmpInst = MCInstBuilder(Size == 4 ? CSKY::NOT32 : CSKY::NOT16)124.addOperand(MI.getOperand(0))125.addOperand(MI.getOperand(1));126Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);127writeData(Binary, Size, CB);128129TmpInst = MCInstBuilder(Size == 4 ? CSKY::ADDI32 : CSKY::ADDI16)130.addOperand(MI.getOperand(0))131.addOperand(MI.getOperand(0))132.addImm(MI.getOperand(2).getImm() + 1);133Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);134writeData(Binary, Size, CB);135}136137void CSKYMCCodeEmitter::encodeInstruction(const MCInst &MI,138SmallVectorImpl<char> &CB,139SmallVectorImpl<MCFixup> &Fixups,140const MCSubtargetInfo &STI) const {141const MCInstrDesc &Desc = MII.get(MI.getOpcode());142unsigned Size = Desc.getSize();143144MCInst TmpInst;145146switch (MI.getOpcode()) {147default:148TmpInst = MI;149break;150case CSKY::JBT_E:151case CSKY::JBF_E:152expandJBTF(MI, CB, Fixups, STI);153MCNumEmitted += 2;154return;155case CSKY::NEG32:156case CSKY::NEG16:157expandNEG(MI, CB, Fixups, STI);158MCNumEmitted += 2;159return;160case CSKY::RSUBI32:161case CSKY::RSUBI16:162expandRSUBI(MI, CB, Fixups, STI);163MCNumEmitted += 2;164return;165case CSKY::JBSR32:166TmpInst = MCInstBuilder(CSKY::BSR32).addOperand(MI.getOperand(0));167break;168case CSKY::JBR16:169TmpInst = MCInstBuilder(CSKY::BR16).addOperand(MI.getOperand(0));170break;171case CSKY::JBR32:172TmpInst = MCInstBuilder(CSKY::BR32).addOperand(MI.getOperand(0));173break;174case CSKY::JBT16:175TmpInst = MCInstBuilder(CSKY::BT16)176.addOperand(MI.getOperand(0))177.addOperand(MI.getOperand(1));178break;179case CSKY::JBT32:180TmpInst = MCInstBuilder(CSKY::BT32)181.addOperand(MI.getOperand(0))182.addOperand(MI.getOperand(1));183break;184case CSKY::JBF16:185TmpInst = MCInstBuilder(CSKY::BF16)186.addOperand(MI.getOperand(0))187.addOperand(MI.getOperand(1));188break;189case CSKY::JBF32:190TmpInst = MCInstBuilder(CSKY::BF32)191.addOperand(MI.getOperand(0))192.addOperand(MI.getOperand(1));193break;194case CSKY::LRW32_Gen:195TmpInst = MCInstBuilder(CSKY::LRW32)196.addOperand(MI.getOperand(0))197.addOperand(MI.getOperand(2));198break;199case CSKY::LRW16_Gen:200TmpInst = MCInstBuilder(CSKY::LRW16)201.addOperand(MI.getOperand(0))202.addOperand(MI.getOperand(2));203break;204case CSKY::CMPLEI32:205TmpInst = MCInstBuilder(CSKY::CMPLTI32)206.addOperand(MI.getOperand(0))207.addOperand(MI.getOperand(1))208.addImm(MI.getOperand(2).getImm() + 1);209break;210case CSKY::CMPLEI16:211TmpInst = MCInstBuilder(CSKY::CMPLTI16)212.addOperand(MI.getOperand(0))213.addOperand(MI.getOperand(1))214.addImm(MI.getOperand(2).getImm() + 1);215break;216case CSKY::ROTRI32:217TmpInst = MCInstBuilder(CSKY::ROTLI32)218.addOperand(MI.getOperand(0))219.addOperand(MI.getOperand(1))220.addImm(32 - MI.getOperand(2).getImm());221break;222case CSKY::BGENI:223auto V = 1 << MI.getOperand(1).getImm();224TmpInst =225MCInstBuilder(CSKY::MOVI32).addOperand(MI.getOperand(0)).addImm(V);226break;227}228229++MCNumEmitted;230writeData(getBinaryCodeForInstr(TmpInst, Fixups, STI), Size, CB);231}232233unsigned234CSKYMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,235SmallVectorImpl<MCFixup> &Fixups,236const MCSubtargetInfo &STI) const {237if (MO.isReg())238return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());239240if (MO.isImm())241return static_cast<unsigned>(MO.getImm());242243llvm_unreachable("Unhandled expression!");244return 0;245}246247unsigned248CSKYMCCodeEmitter::getRegSeqImmOpValue(const MCInst &MI, unsigned Idx,249SmallVectorImpl<MCFixup> &Fixups,250const MCSubtargetInfo &STI) const {251assert(MI.getOperand(Idx).isReg() && "Unexpected MO type.");252assert(MI.getOperand(Idx + 1).isImm() && "Unexpected MO type.");253254unsigned Ry = MI.getOperand(Idx).getReg();255unsigned Rz = MI.getOperand(Idx + 1).getImm();256257unsigned Imm = Ctx.getRegisterInfo()->getEncodingValue(Rz) -258Ctx.getRegisterInfo()->getEncodingValue(Ry);259260return ((Ctx.getRegisterInfo()->getEncodingValue(Ry) << 5) | Imm);261}262263unsigned264CSKYMCCodeEmitter::getRegisterSeqOpValue(const MCInst &MI, unsigned Op,265SmallVectorImpl<MCFixup> &Fixups,266const MCSubtargetInfo &STI) const {267unsigned Reg1 =268Ctx.getRegisterInfo()->getEncodingValue(MI.getOperand(Op).getReg());269unsigned Reg2 =270Ctx.getRegisterInfo()->getEncodingValue(MI.getOperand(Op + 1).getReg());271272unsigned Binary = ((Reg1 & 0x1f) << 5) | (Reg2 - Reg1);273274return Binary;275}276277unsigned CSKYMCCodeEmitter::getImmJMPIX(const MCInst &MI, unsigned Idx,278SmallVectorImpl<MCFixup> &Fixups,279const MCSubtargetInfo &STI) const {280if (MI.getOperand(Idx).getImm() == 16)281return 0;282else if (MI.getOperand(Idx).getImm() == 24)283return 1;284else if (MI.getOperand(Idx).getImm() == 32)285return 2;286else if (MI.getOperand(Idx).getImm() == 40)287return 3;288else289assert(0);290}291292MCFixupKind CSKYMCCodeEmitter::getTargetFixup(const MCExpr *Expr) const {293const CSKYMCExpr *CSKYExpr = cast<CSKYMCExpr>(Expr);294295switch (CSKYExpr->getKind()) {296default:297llvm_unreachable("Unhandled fixup kind!");298case CSKYMCExpr::VK_CSKY_ADDR:299return MCFixupKind(CSKY::fixup_csky_addr32);300case CSKYMCExpr::VK_CSKY_ADDR_HI16:301return MCFixupKind(CSKY::fixup_csky_addr_hi16);302case CSKYMCExpr::VK_CSKY_ADDR_LO16:303return MCFixupKind(CSKY::fixup_csky_addr_lo16);304case CSKYMCExpr::VK_CSKY_GOT:305return MCFixupKind(CSKY::fixup_csky_got32);306case CSKYMCExpr::VK_CSKY_GOTPC:307return MCFixupKind(CSKY::fixup_csky_gotpc);308case CSKYMCExpr::VK_CSKY_GOTOFF:309return MCFixupKind(CSKY::fixup_csky_gotoff);310case CSKYMCExpr::VK_CSKY_PLT:311return MCFixupKind(CSKY::fixup_csky_plt32);312case CSKYMCExpr::VK_CSKY_PLT_IMM18_BY4:313return MCFixupKind(CSKY::fixup_csky_plt_imm18_scale4);314case CSKYMCExpr::VK_CSKY_GOT_IMM18_BY4:315return MCFixupKind(CSKY::fixup_csky_got_imm18_scale4);316}317}318319MCCodeEmitter *llvm::createCSKYMCCodeEmitter(const MCInstrInfo &MCII,320MCContext &Ctx) {321return new CSKYMCCodeEmitter(Ctx, MCII);322}323324#include "CSKYGenMCCodeEmitter.inc"325326327