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