LLVM API Documentation

XCoreMCInstLower.cpp
Go to the documentation of this file.
00001 //===-- XCoreMCInstLower.cpp - Convert XCore MachineInstr to MCInst -------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 ///
00010 /// \file
00011 /// \brief This file contains code to lower XCore MachineInstrs to their
00012 /// corresponding MCInst records.
00013 ///
00014 //===----------------------------------------------------------------------===//
00015 #include "XCoreMCInstLower.h"
00016 #include "llvm/CodeGen/AsmPrinter.h"
00017 #include "llvm/CodeGen/MachineFunction.h"
00018 #include "llvm/CodeGen/MachineInstr.h"
00019 #include "llvm/CodeGen/MachineOperand.h"
00020 #include "llvm/IR/Mangler.h"
00021 #include "llvm/MC/MCContext.h"
00022 #include "llvm/MC/MCExpr.h"
00023 #include "llvm/MC/MCInst.h"
00024 
00025 using namespace llvm;
00026 
00027 XCoreMCInstLower::XCoreMCInstLower(class AsmPrinter &asmprinter)
00028 : Printer(asmprinter) {}
00029 
00030 void XCoreMCInstLower::Initialize(Mangler *M, MCContext *C) {
00031   Mang = M;
00032   Ctx = C;
00033 }
00034 
00035 MCOperand XCoreMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
00036                                                MachineOperandType MOTy,
00037                                                unsigned Offset) const {
00038   MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
00039   const MCSymbol *Symbol;
00040 
00041   switch (MOTy) {
00042     case MachineOperand::MO_MachineBasicBlock:
00043       Symbol = MO.getMBB()->getSymbol();
00044       break;
00045     case MachineOperand::MO_GlobalAddress:
00046       Symbol = Printer.getSymbol(MO.getGlobal());
00047       Offset += MO.getOffset();
00048       break;
00049     case MachineOperand::MO_BlockAddress:
00050       Symbol = Printer.GetBlockAddressSymbol(MO.getBlockAddress());
00051       Offset += MO.getOffset();
00052       break;
00053     case MachineOperand::MO_ExternalSymbol:
00054       Symbol = Printer.GetExternalSymbolSymbol(MO.getSymbolName());
00055       Offset += MO.getOffset();
00056       break;
00057     case MachineOperand::MO_JumpTableIndex:
00058       Symbol = Printer.GetJTISymbol(MO.getIndex());
00059       break;
00060     case MachineOperand::MO_ConstantPoolIndex:
00061       Symbol = Printer.GetCPISymbol(MO.getIndex());
00062       Offset += MO.getOffset();
00063       break;
00064     default:
00065       llvm_unreachable("<unknown operand type>");
00066   }
00067 
00068   const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Symbol, Kind, *Ctx);
00069 
00070   if (!Offset)
00071     return MCOperand::CreateExpr(MCSym);
00072 
00073   // Assume offset is never negative.
00074   assert(Offset > 0);
00075 
00076   const MCConstantExpr *OffsetExpr =  MCConstantExpr::Create(Offset, *Ctx);
00077   const MCBinaryExpr *Add = MCBinaryExpr::CreateAdd(MCSym, OffsetExpr, *Ctx);
00078   return MCOperand::CreateExpr(Add);
00079 }
00080 
00081 MCOperand XCoreMCInstLower::LowerOperand(const MachineOperand &MO,
00082                                          unsigned offset) const {
00083   MachineOperandType MOTy = MO.getType();
00084 
00085   switch (MOTy) {
00086     default: llvm_unreachable("unknown operand type");
00087     case MachineOperand::MO_Register:
00088       // Ignore all implicit register operands.
00089       if (MO.isImplicit()) break;
00090       return MCOperand::CreateReg(MO.getReg());
00091     case MachineOperand::MO_Immediate:
00092       return MCOperand::CreateImm(MO.getImm() + offset);
00093     case MachineOperand::MO_MachineBasicBlock:
00094     case MachineOperand::MO_GlobalAddress:
00095     case MachineOperand::MO_ExternalSymbol:
00096     case MachineOperand::MO_JumpTableIndex:
00097     case MachineOperand::MO_ConstantPoolIndex:
00098     case MachineOperand::MO_BlockAddress:
00099       return LowerSymbolOperand(MO, MOTy, offset);
00100     case MachineOperand::MO_RegisterMask:
00101       break;
00102   }
00103 
00104   return MCOperand();
00105 }
00106 
00107 void XCoreMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
00108   OutMI.setOpcode(MI->getOpcode());
00109 
00110   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
00111     const MachineOperand &MO = MI->getOperand(i);
00112     MCOperand MCOp = LowerOperand(MO);
00113 
00114     if (MCOp.isValid())
00115       OutMI.addOperand(MCOp);
00116   }
00117 }