1//===-- SystemZMCInstLower.cpp - Lower 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#include "SystemZMCInstLower.h" 11#include "SystemZAsmPrinter.h" 12#include "llvm/IR/Mangler.h" 13#include "llvm/MC/MCExpr.h" 14#include "llvm/MC/MCInst.h" 15#include "llvm/MC/MCStreamer.h" 16 17using namespace llvm; 18 19// Return the VK_* enumeration for MachineOperand target flags Flags. 20static MCSymbolRefExpr::VariantKind getVariantKind(unsigned Flags) { 21 switch (Flags & SystemZII::MO_SYMBOL_MODIFIER) { 22 case 0: 23 return MCSymbolRefExpr::VK_None; 24 case SystemZII::MO_GOT: 25 return MCSymbolRefExpr::VK_GOT; 26 case SystemZII::MO_INDNTPOFF: 27 return MCSymbolRefExpr::VK_INDNTPOFF; 28 } 29 llvm_unreachable("Unrecognised MO_ACCESS_MODEL"); 30} 31 32SystemZMCInstLower::SystemZMCInstLower(MCContext &ctx, 33 SystemZAsmPrinter &asmprinter) 34 : Ctx(ctx), AsmPrinter(asmprinter) {} 35 36const MCExpr * 37SystemZMCInstLower::getExpr(const MachineOperand &MO, 38 MCSymbolRefExpr::VariantKind Kind) const { 39 const MCSymbol *Symbol; 40 bool HasOffset = true; 41 switch (MO.getType()) { 42 case MachineOperand::MO_MachineBasicBlock: 43 Symbol = MO.getMBB()->getSymbol(); 44 HasOffset = false; 45 break; 46 47 case MachineOperand::MO_GlobalAddress: 48 Symbol = AsmPrinter.getSymbol(MO.getGlobal()); 49 break; 50 51 case MachineOperand::MO_ExternalSymbol: 52 Symbol = AsmPrinter.GetExternalSymbolSymbol(MO.getSymbolName()); 53 break; 54 55 case MachineOperand::MO_JumpTableIndex: 56 Symbol = AsmPrinter.GetJTISymbol(MO.getIndex()); 57 HasOffset = false; 58 break; 59 60 case MachineOperand::MO_ConstantPoolIndex: 61 Symbol = AsmPrinter.GetCPISymbol(MO.getIndex()); 62 break; 63 64 case MachineOperand::MO_BlockAddress: 65 Symbol = AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress()); 66 break; 67 68 default: 69 llvm_unreachable("unknown operand type"); 70 } 71 const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, Kind, Ctx); 72 if (HasOffset) 73 if (int64_t Offset = MO.getOffset()) { 74 const MCExpr *OffsetExpr = MCConstantExpr::create(Offset, Ctx); 75 Expr = MCBinaryExpr::createAdd(Expr, OffsetExpr, Ctx); 76 } 77 return Expr; 78} 79 80MCOperand SystemZMCInstLower::lowerOperand(const MachineOperand &MO) const { 81 switch (MO.getType()) { 82 case MachineOperand::MO_Register: 83 return MCOperand::createReg(MO.getReg()); 84 85 case MachineOperand::MO_Immediate: 86 return MCOperand::createImm(MO.getImm()); 87 88 default: { 89 MCSymbolRefExpr::VariantKind Kind = getVariantKind(MO.getTargetFlags()); 90 return MCOperand::createExpr(getExpr(MO, Kind)); 91 } 92 } 93} 94 95void SystemZMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const { 96 OutMI.setOpcode(MI->getOpcode()); 97 for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) { 98 const MachineOperand &MO = MI->getOperand(I); 99 // Ignore all implicit register operands. 100 if (!MO.isReg() || !MO.isImplicit()) 101 OutMI.addOperand(lowerOperand(MO)); 102 } 103} 104