1 //===-- SystemZMCInstLower.cpp - Lower MachineInstr to MCInst -------------===//
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
7 //===----------------------------------------------------------------------===//
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"
18 // Return the VK_* enumeration for MachineOperand target flags Flags.
19 static MCSymbolRefExpr::VariantKind
getVariantKind(unsigned Flags
) {
20 switch (Flags
& SystemZII::MO_SYMBOL_MODIFIER
) {
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
;
28 llvm_unreachable("Unrecognised MO_ACCESS_MODEL");
31 SystemZMCInstLower::SystemZMCInstLower(MCContext
&ctx
,
32 SystemZAsmPrinter
&asmprinter
)
33 : Ctx(ctx
), AsmPrinter(asmprinter
) {}
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();
46 case MachineOperand::MO_GlobalAddress
:
47 Symbol
= AsmPrinter
.getSymbol(MO
.getGlobal());
50 case MachineOperand::MO_ExternalSymbol
:
51 Symbol
= AsmPrinter
.GetExternalSymbolSymbol(MO
.getSymbolName());
54 case MachineOperand::MO_JumpTableIndex
:
55 Symbol
= AsmPrinter
.GetJTISymbol(MO
.getIndex());
59 case MachineOperand::MO_ConstantPoolIndex
:
60 Symbol
= AsmPrinter
.GetCPISymbol(MO
.getIndex());
63 case MachineOperand::MO_BlockAddress
:
64 Symbol
= AsmPrinter
.GetBlockAddressSymbol(MO
.getBlockAddress());
68 llvm_unreachable("unknown operand type");
70 const MCExpr
*Expr
= MCSymbolRefExpr::create(Symbol
, Kind
, Ctx
);
72 if (int64_t Offset
= MO
.getOffset()) {
73 const MCExpr
*OffsetExpr
= MCConstantExpr::create(Offset
, Ctx
);
74 Expr
= MCBinaryExpr::createAdd(Expr
, OffsetExpr
, Ctx
);
79 MCOperand
SystemZMCInstLower::lowerOperand(const MachineOperand
&MO
) const {
80 switch (MO
.getType()) {
81 case MachineOperand::MO_Register
:
82 return MCOperand::createReg(MO
.getReg());
84 case MachineOperand::MO_Immediate
:
85 return MCOperand::createImm(MO
.getImm());
88 MCSymbolRefExpr::VariantKind Kind
= getVariantKind(MO
.getTargetFlags());
89 return MCOperand::createExpr(getExpr(MO
, Kind
));
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
));