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