1 //===-- RISCVMCInstLower.cpp - Convert RISCV MachineInstr to an MCInst ------=// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains code to lower RISCV MachineInstrs to their corresponding 11 // MCInst records. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "RISCV.h" 16 #include "MCTargetDesc/RISCVMCExpr.h" 17 #include "llvm/CodeGen/AsmPrinter.h" 18 #include "llvm/CodeGen/MachineBasicBlock.h" 19 #include "llvm/CodeGen/MachineInstr.h" 20 #include "llvm/MC/MCAsmInfo.h" 21 #include "llvm/MC/MCContext.h" 22 #include "llvm/MC/MCExpr.h" 23 #include "llvm/MC/MCInst.h" 24 #include "llvm/Support/ErrorHandling.h" 25 #include "llvm/Support/raw_ostream.h" 26 27 using namespace llvm; 28 29 static MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym, 30 const AsmPrinter &AP) { 31 MCContext &Ctx = AP.OutContext; 32 RISCVMCExpr::VariantKind Kind; 33 34 switch (MO.getTargetFlags()) { 35 default: 36 llvm_unreachable("Unknown target flag on GV operand"); 37 case RISCVII::MO_None: 38 Kind = RISCVMCExpr::VK_RISCV_None; 39 break; 40 case RISCVII::MO_LO: 41 Kind = RISCVMCExpr::VK_RISCV_LO; 42 break; 43 case RISCVII::MO_HI: 44 Kind = RISCVMCExpr::VK_RISCV_HI; 45 break; 46 } 47 48 const MCExpr *ME = 49 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx); 50 51 if (!MO.isJTI() && !MO.isMBB() && MO.getOffset()) 52 ME = MCBinaryExpr::createAdd( 53 ME, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx); 54 55 if (Kind != RISCVMCExpr::VK_RISCV_None) 56 ME = RISCVMCExpr::create(ME, Kind, Ctx); 57 return MCOperand::createExpr(ME); 58 } 59 60 bool llvm::LowerRISCVMachineOperandToMCOperand(const MachineOperand &MO, 61 MCOperand &MCOp, 62 const AsmPrinter &AP) { 63 switch (MO.getType()) { 64 default: 65 report_fatal_error("LowerRISCVMachineInstrToMCInst: unknown operand type"); 66 case MachineOperand::MO_Register: 67 // Ignore all implicit register operands. 68 if (MO.isImplicit()) 69 return false; 70 MCOp = MCOperand::createReg(MO.getReg()); 71 break; 72 case MachineOperand::MO_RegisterMask: 73 // Regmasks are like implicit defs. 74 return false; 75 case MachineOperand::MO_Immediate: 76 MCOp = MCOperand::createImm(MO.getImm()); 77 break; 78 case MachineOperand::MO_MachineBasicBlock: 79 MCOp = lowerSymbolOperand(MO, MO.getMBB()->getSymbol(), AP); 80 break; 81 case MachineOperand::MO_GlobalAddress: 82 MCOp = lowerSymbolOperand(MO, AP.getSymbol(MO.getGlobal()), AP); 83 break; 84 case MachineOperand::MO_BlockAddress: 85 MCOp = lowerSymbolOperand( 86 MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()), AP); 87 break; 88 case MachineOperand::MO_ExternalSymbol: 89 MCOp = lowerSymbolOperand( 90 MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()), AP); 91 break; 92 case MachineOperand::MO_ConstantPoolIndex: 93 MCOp = lowerSymbolOperand(MO, AP.GetCPISymbol(MO.getIndex()), AP); 94 break; 95 } 96 return true; 97 } 98 99 void llvm::LowerRISCVMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, 100 const AsmPrinter &AP) { 101 OutMI.setOpcode(MI->getOpcode()); 102 103 for (const MachineOperand &MO : MI->operands()) { 104 MCOperand MCOp; 105 if (LowerRISCVMachineOperandToMCOperand(MO, MCOp, AP)) 106 OutMI.addOperand(MCOp); 107 } 108 } 109