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
17 using namespace llvm;
18
19 // Return the VK_* enumeration for MachineOperand target flags Flags.
getVariantKind(unsigned Flags)20 static 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
SystemZMCInstLower(MCContext & ctx,SystemZAsmPrinter & asmprinter)32 SystemZMCInstLower::SystemZMCInstLower(MCContext &ctx,
33 SystemZAsmPrinter &asmprinter)
34 : Ctx(ctx), AsmPrinter(asmprinter) {}
35
36 const MCExpr *
getExpr(const MachineOperand & MO,MCSymbolRefExpr::VariantKind Kind) const37 SystemZMCInstLower::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
lowerOperand(const MachineOperand & MO) const80 MCOperand 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
lower(const MachineInstr * MI,MCInst & OutMI) const95 void 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