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