LLVM API Documentation

SystemZMCInstLower.cpp
Go to the documentation of this file.
00001 //===-- SystemZMCInstLower.cpp - Lower 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 #include "SystemZMCInstLower.h"
00011 #include "SystemZAsmPrinter.h"
00012 #include "llvm/IR/Mangler.h"
00013 #include "llvm/MC/MCExpr.h"
00014 #include "llvm/MC/MCStreamer.h"
00015 
00016 using namespace llvm;
00017 
00018 // Return the VK_* enumeration for MachineOperand target flags Flags.
00019 static MCSymbolRefExpr::VariantKind getVariantKind(unsigned Flags) {
00020   switch (Flags & SystemZII::MO_SYMBOL_MODIFIER) {
00021     case 0:
00022       return MCSymbolRefExpr::VK_None;
00023     case SystemZII::MO_GOT:
00024       return MCSymbolRefExpr::VK_GOT;
00025   }
00026   llvm_unreachable("Unrecognised MO_ACCESS_MODEL");
00027 }
00028 
00029 SystemZMCInstLower::SystemZMCInstLower(MCContext &ctx,
00030                                        SystemZAsmPrinter &asmprinter)
00031   : Ctx(ctx), AsmPrinter(asmprinter) {}
00032 
00033 const MCExpr *
00034 SystemZMCInstLower::getExpr(const MachineOperand &MO,
00035                             MCSymbolRefExpr::VariantKind Kind) const {
00036   const MCSymbol *Symbol;
00037   bool HasOffset = true;
00038   switch (MO.getType()) {
00039   case MachineOperand::MO_MachineBasicBlock:
00040     Symbol = MO.getMBB()->getSymbol();
00041     HasOffset = false;
00042     break;
00043 
00044   case MachineOperand::MO_GlobalAddress:
00045     Symbol = AsmPrinter.getSymbol(MO.getGlobal());
00046     break;
00047 
00048   case MachineOperand::MO_ExternalSymbol:
00049     Symbol = AsmPrinter.GetExternalSymbolSymbol(MO.getSymbolName());
00050     break;
00051 
00052   case MachineOperand::MO_JumpTableIndex:
00053     Symbol = AsmPrinter.GetJTISymbol(MO.getIndex());
00054     HasOffset = false;
00055     break;
00056 
00057   case MachineOperand::MO_ConstantPoolIndex:
00058     Symbol = AsmPrinter.GetCPISymbol(MO.getIndex());
00059     break;
00060 
00061   case MachineOperand::MO_BlockAddress:
00062     Symbol = AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress());
00063     break;
00064 
00065   default:
00066     llvm_unreachable("unknown operand type");
00067   }
00068   const MCExpr *Expr = MCSymbolRefExpr::Create(Symbol, Kind, Ctx);
00069   if (HasOffset)
00070     if (int64_t Offset = MO.getOffset()) {
00071       const MCExpr *OffsetExpr = MCConstantExpr::Create(Offset, Ctx);
00072       Expr = MCBinaryExpr::CreateAdd(Expr, OffsetExpr, Ctx);
00073     }
00074   return Expr;
00075 }
00076 
00077 MCOperand SystemZMCInstLower::lowerOperand(const MachineOperand &MO) const {
00078   switch (MO.getType()) {
00079   case MachineOperand::MO_Register:
00080     return MCOperand::CreateReg(MO.getReg());
00081 
00082   case MachineOperand::MO_Immediate:
00083     return MCOperand::CreateImm(MO.getImm());
00084 
00085   default: {
00086     MCSymbolRefExpr::VariantKind Kind = getVariantKind(MO.getTargetFlags());
00087     return MCOperand::CreateExpr(getExpr(MO, Kind));
00088   }
00089   }
00090 }
00091 
00092 void SystemZMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const {
00093   OutMI.setOpcode(MI->getOpcode());
00094   for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) {
00095     const MachineOperand &MO = MI->getOperand(I);
00096     // Ignore all implicit register operands.
00097     if (!MO.isReg() || !MO.isImplicit())
00098       OutMI.addOperand(lowerOperand(MO));
00099   }
00100 }