101 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "SystemZMCInstLower.h"10#include "MCTargetDesc/SystemZMCAsmInfo.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 S_* enumeration for MachineOperand target flags Flags.20static SystemZ::Specifier getSpecifierForTFlags(unsigned Flags) {21 switch (Flags & SystemZII::MO_SYMBOL_MODIFIER) {22 case 0:23 return SystemZ::S_None;24 case SystemZII::MO_GOT:25 return SystemZ::S_GOT;26 case SystemZII::MO_INDNTPOFF:27 return SystemZ::S_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 *SystemZMCInstLower::getExpr(const MachineOperand &MO,37 SystemZ::Specifier Spec) 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, Spec, 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 79MCOperand 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 auto Kind = getSpecifierForTFlags(MO.getTargetFlags());89 return MCOperand::createExpr(getExpr(MO, Kind));90 }91 }92}93 94void SystemZMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const {95 OutMI.setOpcode(MI->getOpcode());96 for (const MachineOperand &MO : MI->operands())97 // Ignore all implicit register operands.98 if (!MO.isReg() || !MO.isImplicit())99 OutMI.addOperand(lowerOperand(MO));100}101