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/CSKYMCAsmInfo.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 CSKY::Specifier Spec; 40 MCContext &Ctx = Printer.OutContext; 41 42 switch (MO.getTargetFlags()) { 43 default: 44 llvm_unreachable("Unknown target flag."); 45 case CSKYII::MO_None: 46 Spec = CSKY::S_None; 47 break; 48 case CSKYII::MO_GOT32: 49 Spec = CSKY::S_GOT; 50 break; 51 case CSKYII::MO_GOTOFF: 52 Spec = CSKY::S_GOTOFF; 53 break; 54 case CSKYII::MO_ADDR32: 55 Spec = CSKY::S_ADDR; 56 break; 57 case CSKYII::MO_PLT32: 58 Spec = CSKY::S_PLT; 59 break; 60 case CSKYII::MO_ADDR_HI16: 61 Spec = CSKY::S_ADDR_HI16; 62 break; 63 case CSKYII::MO_ADDR_LO16: 64 Spec = CSKY::S_ADDR_LO16; 65 break; 66 } 67 const MCExpr *ME = MCSymbolRefExpr::create(Sym, Ctx); 68 69 if (Spec != CSKY::S_None) 70 ME = MCSpecifierExpr::create(ME, Spec, Ctx); 71 72 return MCOperand::createExpr(ME); 73 } 74 75 bool CSKYMCInstLower::lowerOperand(const MachineOperand &MO, 76 MCOperand &MCOp) const { 77 switch (MO.getType()) { 78 default: 79 llvm_unreachable("unknown operand type"); 80 case MachineOperand::MO_RegisterMask: 81 break; 82 case MachineOperand::MO_Immediate: 83 MCOp = MCOperand::createImm(MO.getImm()); 84 break; 85 case MachineOperand::MO_Register: 86 if (MO.isImplicit()) 87 return false; 88 MCOp = MCOperand::createReg(MO.getReg()); 89 break; 90 case MachineOperand::MO_MachineBasicBlock: 91 MCOp = MCOperand::createExpr( 92 MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx)); 93 break; 94 case MachineOperand::MO_GlobalAddress: 95 MCOp = lowerSymbolOperand(MO, Printer.getSymbol(MO.getGlobal())); 96 break; 97 case MachineOperand::MO_BlockAddress: 98 MCOp = lowerSymbolOperand( 99 MO, Printer.GetBlockAddressSymbol(MO.getBlockAddress())); 100 break; 101 case MachineOperand::MO_ExternalSymbol: 102 MCOp = lowerSymbolOperand( 103 MO, Printer.GetExternalSymbolSymbol(MO.getSymbolName())); 104 break; 105 case MachineOperand::MO_ConstantPoolIndex: 106 MCOp = lowerSymbolOperand(MO, Printer.GetCPISymbol(MO.getIndex())); 107 break; 108 case MachineOperand::MO_JumpTableIndex: 109 MCOp = lowerSymbolOperand(MO, Printer.GetJTISymbol(MO.getIndex())); 110 break; 111 case MachineOperand::MO_MCSymbol: 112 MCOp = lowerSymbolOperand(MO, MO.getMCSymbol()); 113 break; 114 } 115 return true; 116 } 117