1 //===-- SystemZMCInstLower.cpp - Lower MachineInstr to MCInst -------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "SystemZMCInstLower.h" 10 #include "SystemZAsmPrinter.h" 11 #include "llvm/IR/Mangler.h" 12 #include "llvm/MC/MCExpr.h" 13 #include "llvm/MC/MCInst.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 case SystemZII::MO_INDNTPOFF: 26 return MCSymbolRefExpr::VK_INDNTPOFF; 27 } 28 llvm_unreachable("Unrecognised MO_ACCESS_MODEL"); 29 } 30 31 SystemZMCInstLower::SystemZMCInstLower(MCContext &ctx, 32 SystemZAsmPrinter &asmprinter) 33 : Ctx(ctx), AsmPrinter(asmprinter) {} 34 35 const MCExpr * 36 SystemZMCInstLower::getExpr(const MachineOperand &MO, 37 MCSymbolRefExpr::VariantKind Kind) const { 38 const MCSymbol *Symbol; 39 bool HasOffset = true; 40 switch (MO.getType()) { 41 case MachineOperand::MO_MachineBasicBlock: 42 Symbol = MO.getMBB()->getSymbol(); 43 HasOffset = false; 44 break; 45 46 case MachineOperand::MO_GlobalAddress: 47 Symbol = AsmPrinter.getSymbol(MO.getGlobal()); 48 break; 49 50 case MachineOperand::MO_ExternalSymbol: 51 Symbol = AsmPrinter.GetExternalSymbolSymbol(MO.getSymbolName()); 52 break; 53 54 case MachineOperand::MO_JumpTableIndex: 55 Symbol = AsmPrinter.GetJTISymbol(MO.getIndex()); 56 HasOffset = false; 57 break; 58 59 case MachineOperand::MO_ConstantPoolIndex: 60 Symbol = AsmPrinter.GetCPISymbol(MO.getIndex()); 61 break; 62 63 case MachineOperand::MO_BlockAddress: 64 Symbol = AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress()); 65 break; 66 67 default: 68 llvm_unreachable("unknown operand type"); 69 } 70 const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, Kind, Ctx); 71 if (HasOffset) 72 if (int64_t Offset = MO.getOffset()) { 73 const MCExpr *OffsetExpr = MCConstantExpr::create(Offset, Ctx); 74 Expr = MCBinaryExpr::createAdd(Expr, OffsetExpr, Ctx); 75 } 76 return Expr; 77 } 78 79 MCOperand SystemZMCInstLower::lowerOperand(const MachineOperand &MO) const { 80 switch (MO.getType()) { 81 case MachineOperand::MO_Register: 82 return MCOperand::createReg(MO.getReg()); 83 84 case MachineOperand::MO_Immediate: 85 return MCOperand::createImm(MO.getImm()); 86 87 default: { 88 MCSymbolRefExpr::VariantKind Kind = getVariantKind(MO.getTargetFlags()); 89 return MCOperand::createExpr(getExpr(MO, Kind)); 90 } 91 } 92 } 93 94 void SystemZMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const { 95 OutMI.setOpcode(MI->getOpcode()); 96 for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) { 97 const MachineOperand &MO = MI->getOperand(I); 98 // Ignore all implicit register operands. 99 if (!MO.isReg() || !MO.isImplicit()) 100 OutMI.addOperand(lowerOperand(MO)); 101 } 102 } 103