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 const MCSymbol *Symbol; 33 34 switch (MOTy) { 35 case MachineOperand::MO_MachineBasicBlock: 36 Symbol = MO.getMBB()->getSymbol(); 37 break; 38 case MachineOperand::MO_GlobalAddress: 39 Symbol = Printer.getSymbol(MO.getGlobal()); 40 Offset += MO.getOffset(); 41 break; 42 case MachineOperand::MO_BlockAddress: 43 Symbol = Printer.GetBlockAddressSymbol(MO.getBlockAddress()); 44 Offset += MO.getOffset(); 45 break; 46 case MachineOperand::MO_ExternalSymbol: 47 Symbol = Printer.GetExternalSymbolSymbol(MO.getSymbolName()); 48 Offset += MO.getOffset(); 49 break; 50 case MachineOperand::MO_JumpTableIndex: 51 Symbol = Printer.GetJTISymbol(MO.getIndex()); 52 break; 53 case MachineOperand::MO_ConstantPoolIndex: 54 Symbol = Printer.GetCPISymbol(MO.getIndex()); 55 Offset += MO.getOffset(); 56 break; 57 default: 58 llvm_unreachable("<unknown operand type>"); 59 } 60 61 assert(Symbol && "Symbol creation failed.\n"); 62 const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Symbol, *Ctx); 63 64 if (!Offset) 65 return MCOperand::createExpr(MCSym); 66 67 // Assume offset is never negative. 68 assert(Offset > 0); 69 70 const MCConstantExpr *OffsetExpr = MCConstantExpr::create(Offset, *Ctx); 71 const MCBinaryExpr *Add = MCBinaryExpr::createAdd(MCSym, OffsetExpr, *Ctx); 72 return MCOperand::createExpr(Add); 73 } 74 75 MCOperand ARCMCInstLower::LowerOperand(const MachineOperand &MO, 76 unsigned Offset) const { 77 MachineOperandType MOTy = MO.getType(); 78 79 switch (MOTy) { 80 default: 81 llvm_unreachable("unknown operand type"); 82 case MachineOperand::MO_Register: 83 // Ignore all implicit register operands. 84 if (MO.isImplicit()) 85 break; 86 return MCOperand::createReg(MO.getReg()); 87 case MachineOperand::MO_Immediate: 88 return MCOperand::createImm(MO.getImm() + Offset); 89 case MachineOperand::MO_MachineBasicBlock: 90 case MachineOperand::MO_GlobalAddress: 91 case MachineOperand::MO_ExternalSymbol: 92 case MachineOperand::MO_JumpTableIndex: 93 case MachineOperand::MO_ConstantPoolIndex: 94 case MachineOperand::MO_BlockAddress: 95 return LowerSymbolOperand(MO, MOTy, Offset); 96 case MachineOperand::MO_RegisterMask: 97 break; 98 } 99 100 return {}; 101 } 102 103 void ARCMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { 104 OutMI.setOpcode(MI->getOpcode()); 105 106 for (const MachineOperand &MO : MI->operands()) { 107 MCOperand MCOp = LowerOperand(MO); 108 109 if (MCOp.isValid()) 110 OutMI.addOperand(MCOp); 111 } 112 } 113