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 25 using namespace llvm; 26 27 XCoreMCInstLower::XCoreMCInstLower(class AsmPrinter &asmprinter) 28 : Printer(asmprinter) {} 29 30 void XCoreMCInstLower::Initialize(Mangler *M, MCContext *C) { 31 Mang = M; 32 Ctx = C; 33 } 34 35 MCOperand 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 81 MCOperand 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 107 void 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