LLVM API Documentation
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 }