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