| //===-- CSKYMCInstLower.cpp - Convert CSKY MachineInstr to an MCInst --------=// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file contains code to lower CSKY MachineInstrs to their corresponding |
| // MCInst records. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "CSKYMCInstLower.h" |
| #include "MCTargetDesc/CSKYBaseInfo.h" |
| #include "MCTargetDesc/CSKYMCExpr.h" |
| #include "llvm/CodeGen/AsmPrinter.h" |
| #include "llvm/MC/MCExpr.h" |
| |
| #define DEBUG_TYPE "csky-mcinst-lower" |
| |
| using namespace llvm; |
| |
| CSKYMCInstLower::CSKYMCInstLower(MCContext &Ctx, AsmPrinter &Printer) |
| : Ctx(Ctx), Printer(Printer) {} |
| |
| void CSKYMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { |
| OutMI.setOpcode(MI->getOpcode()); |
| |
| for (const MachineOperand &MO : MI->operands()) { |
| MCOperand MCOp; |
| if (lowerOperand(MO, MCOp)) |
| OutMI.addOperand(MCOp); |
| } |
| } |
| |
| MCOperand CSKYMCInstLower::lowerSymbolOperand(const MachineOperand &MO, |
| MCSymbol *Sym) const { |
| CSKYMCExpr::VariantKind Kind; |
| MCContext &Ctx = Printer.OutContext; |
| |
| switch (MO.getTargetFlags()) { |
| default: |
| llvm_unreachable("Unknown target flag."); |
| case CSKYII::MO_None: |
| Kind = CSKYMCExpr::VK_CSKY_None; |
| break; |
| case CSKYII::MO_GOT32: |
| Kind = CSKYMCExpr::VK_CSKY_GOT; |
| break; |
| case CSKYII::MO_GOTOFF: |
| Kind = CSKYMCExpr::VK_CSKY_GOTOFF; |
| break; |
| case CSKYII::MO_ADDR32: |
| Kind = CSKYMCExpr::VK_CSKY_ADDR; |
| break; |
| case CSKYII::MO_PLT32: |
| Kind = CSKYMCExpr::VK_CSKY_PLT; |
| break; |
| case CSKYII::MO_ADDR_HI16: |
| Kind = CSKYMCExpr::VK_CSKY_ADDR_HI16; |
| break; |
| case CSKYII::MO_ADDR_LO16: |
| Kind = CSKYMCExpr::VK_CSKY_ADDR_LO16; |
| break; |
| } |
| const MCExpr *ME = |
| MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx); |
| |
| if (Kind != CSKYMCExpr::VK_CSKY_None) |
| ME = CSKYMCExpr::create(ME, Kind, Ctx); |
| |
| return MCOperand::createExpr(ME); |
| } |
| |
| bool CSKYMCInstLower::lowerOperand(const MachineOperand &MO, |
| MCOperand &MCOp) const { |
| switch (MO.getType()) { |
| default: |
| llvm_unreachable("unknown operand type"); |
| case MachineOperand::MO_RegisterMask: |
| break; |
| case MachineOperand::MO_Immediate: |
| MCOp = MCOperand::createImm(MO.getImm()); |
| break; |
| case MachineOperand::MO_Register: |
| if (MO.isImplicit()) |
| return false; |
| MCOp = MCOperand::createReg(MO.getReg()); |
| break; |
| case MachineOperand::MO_MachineBasicBlock: |
| MCOp = MCOperand::createExpr( |
| MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx)); |
| break; |
| case MachineOperand::MO_GlobalAddress: |
| MCOp = lowerSymbolOperand(MO, Printer.getSymbol(MO.getGlobal())); |
| break; |
| case MachineOperand::MO_BlockAddress: |
| MCOp = lowerSymbolOperand( |
| MO, Printer.GetBlockAddressSymbol(MO.getBlockAddress())); |
| break; |
| case MachineOperand::MO_ExternalSymbol: |
| MCOp = lowerSymbolOperand( |
| MO, Printer.GetExternalSymbolSymbol(MO.getSymbolName())); |
| break; |
| case MachineOperand::MO_ConstantPoolIndex: |
| MCOp = lowerSymbolOperand(MO, Printer.GetCPISymbol(MO.getIndex())); |
| break; |
| case MachineOperand::MO_JumpTableIndex: |
| MCOp = lowerSymbolOperand(MO, Printer.GetJTISymbol(MO.getIndex())); |
| break; |
| case MachineOperand::MO_MCSymbol: |
| MCOp = lowerSymbolOperand(MO, MO.getMCSymbol()); |
| break; |
| } |
| return true; |
| } |