1 //===- ARCMCInstLower.cpp - ARC MachineInstr to MCInst ----------*- C++ -*-===// 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 /// \file 10 /// This file contains code to lower ARC MachineInstrs to their 11 /// corresponding MCInst records. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #include "ARCMCInstLower.h" 16 #include "llvm/CodeGen/AsmPrinter.h" 17 #include "llvm/CodeGen/MachineFunction.h" 18 #include "llvm/CodeGen/MachineInstr.h" 19 #include "llvm/CodeGen/MachineOperand.h" 20 #include "llvm/MC/MCContext.h" 21 #include "llvm/MC/MCExpr.h" 22 #include "llvm/MC/MCInst.h" 23 24 using namespace llvm; 25 26 ARCMCInstLower::ARCMCInstLower(MCContext *C, AsmPrinter &AsmPrinter) 27 : Ctx(C), Printer(AsmPrinter) {} 28 29 MCOperand ARCMCInstLower::LowerSymbolOperand(const MachineOperand &MO, 30 MachineOperandType MOTy, 31 unsigned Offset) const { 32 MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None; 33 const MCSymbol *Symbol; 34 35 switch (MOTy) { 36 case MachineOperand::MO_MachineBasicBlock: 37 Symbol = MO.getMBB()->getSymbol(); 38 break; 39 case MachineOperand::MO_GlobalAddress: 40 Symbol = Printer.getSymbol(MO.getGlobal()); 41 Offset += MO.getOffset(); 42 break; 43 case MachineOperand::MO_BlockAddress: 44 Symbol = Printer.GetBlockAddressSymbol(MO.getBlockAddress()); 45 Offset += MO.getOffset(); 46 break; 47 case MachineOperand::MO_ExternalSymbol: 48 Symbol = Printer.GetExternalSymbolSymbol(MO.getSymbolName()); 49 Offset += MO.getOffset(); 50 break; 51 case MachineOperand::MO_JumpTableIndex: 52 Symbol = Printer.GetJTISymbol(MO.getIndex()); 53 break; 54 case MachineOperand::MO_ConstantPoolIndex: 55 Symbol = Printer.GetCPISymbol(MO.getIndex()); 56 Offset += MO.getOffset(); 57 break; 58 default: 59 llvm_unreachable("<unknown operand type>"); 60 } 61 62 assert(Symbol && "Symbol creation failed.\n"); 63 const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Symbol, Kind, *Ctx); 64 65 if (!Offset) 66 return MCOperand::createExpr(MCSym); 67 68 // Assume offset is never negative. 69 assert(Offset > 0); 70 71 const MCConstantExpr *OffsetExpr = MCConstantExpr::create(Offset, *Ctx); 72 const MCBinaryExpr *Add = MCBinaryExpr::createAdd(MCSym, OffsetExpr, *Ctx); 73 return MCOperand::createExpr(Add); 74 } 75 76 MCOperand ARCMCInstLower::LowerOperand(const MachineOperand &MO, 77 unsigned Offset) const { 78 MachineOperandType MOTy = MO.getType(); 79 80 switch (MOTy) { 81 default: 82 llvm_unreachable("unknown operand type"); 83 case MachineOperand::MO_Register: 84 // Ignore all implicit register operands. 85 if (MO.isImplicit()) 86 break; 87 return MCOperand::createReg(MO.getReg()); 88 case MachineOperand::MO_Immediate: 89 return MCOperand::createImm(MO.getImm() + Offset); 90 case MachineOperand::MO_MachineBasicBlock: 91 case MachineOperand::MO_GlobalAddress: 92 case MachineOperand::MO_ExternalSymbol: 93 case MachineOperand::MO_JumpTableIndex: 94 case MachineOperand::MO_ConstantPoolIndex: 95 case MachineOperand::MO_BlockAddress: 96 return LowerSymbolOperand(MO, MOTy, Offset); 97 case MachineOperand::MO_RegisterMask: 98 break; 99 } 100 101 return {}; 102 } 103 104 void ARCMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { 105 OutMI.setOpcode(MI->getOpcode()); 106 107 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 108 const MachineOperand &MO = MI->getOperand(i); 109 MCOperand MCOp = LowerOperand(MO); 110 111 if (MCOp.isValid()) 112 OutMI.addOperand(MCOp); 113 } 114 } 115