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