1*349cc55cSDimitry Andric //===-- CSKYMCInstLower.cpp - Convert CSKY MachineInstr to an MCInst --------=// 2*349cc55cSDimitry Andric // 3*349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*349cc55cSDimitry Andric // 7*349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 8*349cc55cSDimitry Andric // 9*349cc55cSDimitry Andric // This file contains code to lower CSKY MachineInstrs to their corresponding 10*349cc55cSDimitry Andric // MCInst records. 11*349cc55cSDimitry Andric // 12*349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 13*349cc55cSDimitry Andric 14*349cc55cSDimitry Andric #include "CSKYMCInstLower.h" 15*349cc55cSDimitry Andric #include "MCTargetDesc/CSKYBaseInfo.h" 16*349cc55cSDimitry Andric #include "MCTargetDesc/CSKYMCExpr.h" 17*349cc55cSDimitry Andric #include "llvm/CodeGen/AsmPrinter.h" 18*349cc55cSDimitry Andric #include "llvm/MC/MCExpr.h" 19*349cc55cSDimitry Andric 20*349cc55cSDimitry Andric #define DEBUG_TYPE "csky-mcinst-lower" 21*349cc55cSDimitry Andric 22*349cc55cSDimitry Andric using namespace llvm; 23*349cc55cSDimitry Andric 24*349cc55cSDimitry Andric CSKYMCInstLower::CSKYMCInstLower(MCContext &Ctx, AsmPrinter &Printer) 25*349cc55cSDimitry Andric : Ctx(Ctx), Printer(Printer) {} 26*349cc55cSDimitry Andric 27*349cc55cSDimitry Andric void CSKYMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { 28*349cc55cSDimitry Andric OutMI.setOpcode(MI->getOpcode()); 29*349cc55cSDimitry Andric 30*349cc55cSDimitry Andric for (const MachineOperand &MO : MI->operands()) { 31*349cc55cSDimitry Andric MCOperand MCOp; 32*349cc55cSDimitry Andric if (lowerOperand(MO, MCOp)) 33*349cc55cSDimitry Andric OutMI.addOperand(MCOp); 34*349cc55cSDimitry Andric } 35*349cc55cSDimitry Andric } 36*349cc55cSDimitry Andric 37*349cc55cSDimitry Andric MCOperand CSKYMCInstLower::lowerSymbolOperand(const MachineOperand &MO, 38*349cc55cSDimitry Andric MCSymbol *Sym) const { 39*349cc55cSDimitry Andric CSKYMCExpr::VariantKind Kind; 40*349cc55cSDimitry Andric MCContext &Ctx = Printer.OutContext; 41*349cc55cSDimitry Andric 42*349cc55cSDimitry Andric switch (MO.getTargetFlags()) { 43*349cc55cSDimitry Andric default: 44*349cc55cSDimitry Andric llvm_unreachable("Unknown target flag."); 45*349cc55cSDimitry Andric case CSKYII::MO_None: 46*349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_None; 47*349cc55cSDimitry Andric break; 48*349cc55cSDimitry Andric case CSKYII::MO_GOT32: 49*349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOT; 50*349cc55cSDimitry Andric break; 51*349cc55cSDimitry Andric case CSKYII::MO_GOTOFF: 52*349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOTOFF; 53*349cc55cSDimitry Andric break; 54*349cc55cSDimitry Andric case CSKYII::MO_ADDR32: 55*349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_ADDR; 56*349cc55cSDimitry Andric break; 57*349cc55cSDimitry Andric case CSKYII::MO_PLT32: 58*349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_PLT; 59*349cc55cSDimitry Andric break; 60*349cc55cSDimitry Andric case CSKYII::MO_ADDR_HI16: 61*349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_ADDR_HI16; 62*349cc55cSDimitry Andric break; 63*349cc55cSDimitry Andric case CSKYII::MO_ADDR_LO16: 64*349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_ADDR_LO16; 65*349cc55cSDimitry Andric break; 66*349cc55cSDimitry Andric } 67*349cc55cSDimitry Andric const MCExpr *ME = 68*349cc55cSDimitry Andric MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx); 69*349cc55cSDimitry Andric 70*349cc55cSDimitry Andric if (Kind != CSKYMCExpr::VK_CSKY_None) 71*349cc55cSDimitry Andric ME = CSKYMCExpr::create(ME, Kind, Ctx); 72*349cc55cSDimitry Andric 73*349cc55cSDimitry Andric return MCOperand::createExpr(ME); 74*349cc55cSDimitry Andric } 75*349cc55cSDimitry Andric 76*349cc55cSDimitry Andric bool CSKYMCInstLower::lowerOperand(const MachineOperand &MO, 77*349cc55cSDimitry Andric MCOperand &MCOp) const { 78*349cc55cSDimitry Andric switch (MO.getType()) { 79*349cc55cSDimitry Andric default: 80*349cc55cSDimitry Andric llvm_unreachable("unknown operand type"); 81*349cc55cSDimitry Andric case MachineOperand::MO_RegisterMask: 82*349cc55cSDimitry Andric break; 83*349cc55cSDimitry Andric case MachineOperand::MO_Immediate: 84*349cc55cSDimitry Andric MCOp = MCOperand::createImm(MO.getImm()); 85*349cc55cSDimitry Andric break; 86*349cc55cSDimitry Andric case MachineOperand::MO_Register: 87*349cc55cSDimitry Andric if (MO.isImplicit()) 88*349cc55cSDimitry Andric return false; 89*349cc55cSDimitry Andric MCOp = MCOperand::createReg(MO.getReg()); 90*349cc55cSDimitry Andric break; 91*349cc55cSDimitry Andric case MachineOperand::MO_MachineBasicBlock: 92*349cc55cSDimitry Andric MCOp = MCOperand::createExpr( 93*349cc55cSDimitry Andric MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx)); 94*349cc55cSDimitry Andric break; 95*349cc55cSDimitry Andric case MachineOperand::MO_GlobalAddress: 96*349cc55cSDimitry Andric MCOp = lowerSymbolOperand(MO, Printer.getSymbol(MO.getGlobal())); 97*349cc55cSDimitry Andric break; 98*349cc55cSDimitry Andric case MachineOperand::MO_BlockAddress: 99*349cc55cSDimitry Andric MCOp = lowerSymbolOperand( 100*349cc55cSDimitry Andric MO, Printer.GetBlockAddressSymbol(MO.getBlockAddress())); 101*349cc55cSDimitry Andric break; 102*349cc55cSDimitry Andric case MachineOperand::MO_ExternalSymbol: 103*349cc55cSDimitry Andric MCOp = lowerSymbolOperand( 104*349cc55cSDimitry Andric MO, Printer.GetExternalSymbolSymbol(MO.getSymbolName())); 105*349cc55cSDimitry Andric break; 106*349cc55cSDimitry Andric case MachineOperand::MO_ConstantPoolIndex: 107*349cc55cSDimitry Andric MCOp = lowerSymbolOperand(MO, Printer.GetCPISymbol(MO.getIndex())); 108*349cc55cSDimitry Andric break; 109*349cc55cSDimitry Andric case MachineOperand::MO_JumpTableIndex: 110*349cc55cSDimitry Andric MCOp = lowerSymbolOperand(MO, Printer.GetJTISymbol(MO.getIndex())); 111*349cc55cSDimitry Andric break; 112*349cc55cSDimitry Andric case MachineOperand::MO_MCSymbol: 113*349cc55cSDimitry Andric MCOp = lowerSymbolOperand(MO, MO.getMCSymbol()); 114*349cc55cSDimitry Andric break; 115*349cc55cSDimitry Andric } 116*349cc55cSDimitry Andric return true; 117*349cc55cSDimitry Andric }