[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / lib / Target / M68k / M68kMCInstLower.cpp
blobf14361559b13ccebe6a595247fab75d5d9f13e86
1 //===-- M68kMCInstLower.cpp - M68k MachineInstr to MCInst ---*- C++ -*-===//
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 /// \file
10 /// This file contains code to lower M68k MachineInstrs to their
11 /// corresponding MCInst records.
12 ///
13 //===----------------------------------------------------------------------===//
15 #include "M68kMCInstLower.h"
17 #include "M68kAsmPrinter.h"
18 #include "M68kInstrInfo.h"
20 #include "MCTargetDesc/M68kBaseInfo.h"
22 #include "llvm/CodeGen/MachineFunction.h"
23 #include "llvm/CodeGen/MachineInstr.h"
24 #include "llvm/CodeGen/MachineOperand.h"
25 #include "llvm/IR/Mangler.h"
26 #include "llvm/MC/MCContext.h"
27 #include "llvm/MC/MCExpr.h"
28 #include "llvm/MC/MCInst.h"
30 using namespace llvm;
32 #define DEBUG_TYPE "m68k-mc-inst-lower"
34 M68kMCInstLower::M68kMCInstLower(MachineFunction &MF, M68kAsmPrinter &AP)
35 : Ctx(MF.getContext()), MF(MF), TM(MF.getTarget()), MAI(*TM.getMCAsmInfo()),
36 AsmPrinter(AP) {}
38 MCSymbol *
39 M68kMCInstLower::GetSymbolFromOperand(const MachineOperand &MO) const {
40 assert((MO.isGlobal() || MO.isSymbol() || MO.isMBB()) &&
41 "Isn't a symbol reference");
43 const auto &TT = TM.getTargetTriple();
44 if (MO.isGlobal() && TT.isOSBinFormatELF())
45 return AsmPrinter.getSymbolPreferLocal(*MO.getGlobal());
47 const DataLayout &DL = MF.getDataLayout();
49 MCSymbol *Sym = nullptr;
50 SmallString<128> Name;
51 StringRef Suffix;
53 if (!Suffix.empty())
54 Name += DL.getPrivateGlobalPrefix();
56 if (MO.isGlobal()) {
57 const GlobalValue *GV = MO.getGlobal();
58 AsmPrinter.getNameWithPrefix(Name, GV);
59 } else if (MO.isSymbol()) {
60 Mangler::getNameWithPrefix(Name, MO.getSymbolName(), DL);
61 } else if (MO.isMBB()) {
62 assert(Suffix.empty());
63 Sym = MO.getMBB()->getSymbol();
66 Name += Suffix;
67 if (!Sym)
68 Sym = Ctx.getOrCreateSymbol(Name);
70 return Sym;
73 MCOperand M68kMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
74 MCSymbol *Sym) const {
75 // FIXME We would like an efficient form for this, so we don't have to do a
76 // lot of extra uniquing. This fixme is originally from X86
77 const MCExpr *Expr = nullptr;
78 MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None;
80 switch (MO.getTargetFlags()) {
81 default:
82 llvm_unreachable("Unknown target flag on GV operand");
83 case M68kII::MO_NO_FLAG:
84 case M68kII::MO_ABSOLUTE_ADDRESS:
85 case M68kII::MO_PC_RELATIVE_ADDRESS:
86 break;
87 case M68kII::MO_GOTPCREL:
88 RefKind = MCSymbolRefExpr::VK_GOTPCREL;
89 break;
90 case M68kII::MO_GOT:
91 RefKind = MCSymbolRefExpr::VK_GOT;
92 break;
93 case M68kII::MO_GOTOFF:
94 RefKind = MCSymbolRefExpr::VK_GOTOFF;
95 break;
96 case M68kII::MO_PLT:
97 RefKind = MCSymbolRefExpr::VK_PLT;
98 break;
101 if (!Expr) {
102 Expr = MCSymbolRefExpr::create(Sym, RefKind, Ctx);
105 if (!MO.isJTI() && !MO.isMBB() && MO.getOffset()) {
106 Expr = MCBinaryExpr::createAdd(
107 Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
110 return MCOperand::createExpr(Expr);
113 Optional<MCOperand>
114 M68kMCInstLower::LowerOperand(const MachineInstr *MI,
115 const MachineOperand &MO) const {
116 switch (MO.getType()) {
117 default:
118 llvm_unreachable("unknown operand type");
119 case MachineOperand::MO_Register:
120 // Ignore all implicit register operands.
121 if (MO.isImplicit())
122 return None;
123 return MCOperand::createReg(MO.getReg());
124 case MachineOperand::MO_Immediate:
125 return MCOperand::createImm(MO.getImm());
126 case MachineOperand::MO_MachineBasicBlock:
127 case MachineOperand::MO_GlobalAddress:
128 case MachineOperand::MO_ExternalSymbol:
129 return LowerSymbolOperand(MO, GetSymbolFromOperand(MO));
130 case MachineOperand::MO_MCSymbol:
131 return LowerSymbolOperand(MO, MO.getMCSymbol());
132 case MachineOperand::MO_JumpTableIndex:
133 return LowerSymbolOperand(MO, AsmPrinter.GetJTISymbol(MO.getIndex()));
134 case MachineOperand::MO_ConstantPoolIndex:
135 return LowerSymbolOperand(MO, AsmPrinter.GetCPISymbol(MO.getIndex()));
136 case MachineOperand::MO_BlockAddress:
137 return LowerSymbolOperand(
138 MO, AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress()));
139 case MachineOperand::MO_RegisterMask:
140 // Ignore call clobbers.
141 return None;
145 void M68kMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
146 unsigned Opcode = MI->getOpcode();
147 OutMI.setOpcode(Opcode);
149 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
150 const MachineOperand &MO = MI->getOperand(i);
151 Optional<MCOperand> MCOp = LowerOperand(MI, MO);
153 if (MCOp.hasValue() && MCOp.getValue().isValid())
154 OutMI.addOperand(MCOp.getValue());
157 // TAILJMPj, TAILJMPq - Lower to the correct jump instructions.
158 if (Opcode == M68k::TAILJMPj || Opcode == M68k::TAILJMPq) {
159 assert(OutMI.getNumOperands() == 1 && "Unexpected number of operands");
160 switch (Opcode) {
161 case M68k::TAILJMPj:
162 Opcode = M68k::JMP32j;
163 break;
164 case M68k::TAILJMPq:
165 Opcode = M68k::BRA8;
166 break;
168 OutMI.setOpcode(Opcode);