LLVM 23.0.0git
M68kAsmPrinter.cpp
Go to the documentation of this file.
1//===-- M68kAsmPrinter.cpp - M68k LLVM Assembly Printer ---------*- 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 a printer that converts from our internal representation
11/// of machine-dependent LLVM code to GAS-format M68k assembly language.
12///
13//===----------------------------------------------------------------------===//
14
15// TODO Conform to Motorola ASM syntax
16
17#include "M68kAsmPrinter.h"
18
19#include "M68k.h"
20#include "M68kMachineFunction.h"
23
25
26using namespace llvm;
27
28#define DEBUG_TYPE "m68k-asm-printer"
29
31 MMFI = MF.getInfo<M68kMachineFunctionInfo>();
32 MCInstLowering = std::make_unique<M68kMCInstLower>(MF, *this);
34 return true;
35}
36
37void M68kAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
38 raw_ostream &OS) {
39 const MachineOperand &MO = MI->getOperand(OpNum);
40 switch (MO.getType()) {
42 Register Reg = MO.getReg();
43 if (Reg.isValid())
44 OS << "%" << M68kInstPrinter::getRegisterName(Reg);
45 break;
46 }
48 OS << '#' << MO.getImm();
49 break;
51 MO.getMBB()->getSymbol()->print(OS, MAI);
52 break;
54 PrintSymbolOperand(MO, OS);
55 break;
58 break;
60 const DataLayout &DL = getDataLayout();
61 OS << DL.getInternalSymbolPrefix() << "CPI" << getFunctionNumber() << '_'
62 << MO.getIndex();
63 break;
64 }
65 default:
66 llvm_unreachable("not implemented");
67 }
68}
69
71 const char *ExtraCode, raw_ostream &OS) {
72 // Print the operand if there is no operand modifier.
73 if (!ExtraCode || !ExtraCode[0]) {
74 printOperand(MI, OpNo, OS);
75 return false;
76 }
77
78 // Fallback to the default implementation.
79 return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS);
80}
81
82void M68kAsmPrinter::printDisp(const MachineInstr *MI, unsigned opNum,
83 raw_ostream &O) {
84 // Print immediate displacement without the '#' predix
85 const MachineOperand &Op = MI->getOperand(opNum);
86 if (Op.isImm()) {
87 O << Op.getImm();
88 return;
89 }
90 // Displacement is relocatable, so we're pretty permissive about what
91 // can be put here.
92 printOperand(MI, opNum, O);
93}
94
95void M68kAsmPrinter::printScale(const MachineInstr *MI, unsigned opNum,
96 raw_ostream &O) {
97 const MachineOperand &Op = MI->getOperand(opNum);
98 // Scale has to be an immediate.
99 unsigned Scale = Op.getImm();
100 // We only print it out when it's larger than 1
101 if (Scale > 1)
102 O << "*" << Scale;
103}
104
105void M68kAsmPrinter::printAbsMem(const MachineInstr *MI, unsigned OpNum,
106 raw_ostream &O) {
107 const MachineOperand &MO = MI->getOperand(OpNum);
108 if (MO.isImm())
109 O << format("$%0" PRIx64, (uint64_t)MO.getImm());
110 else
111 PrintAsmMemoryOperand(MI, OpNum, nullptr, O);
112}
113
115 unsigned OpNo, const char *ExtraCode,
116 raw_ostream &OS) {
117 const MachineOperand &MO = MI->getOperand(OpNo);
118 switch (MO.getType()) {
120 // Immediate value that goes here is the addressing mode kind we set
121 // in M68kDAGToDAGISel::SelectInlineAsmMemoryOperand.
122 using namespace M68k;
123 // Skip the addressing mode kind operand.
124 ++OpNo;
125 // Decode MemAddrModeKind.
126 switch (static_cast<MemAddrModeKind>(MO.getImm())) {
127 case MemAddrModeKind::j:
128 printARIMem(MI, OpNo, OS);
129 break;
130 case MemAddrModeKind::o:
131 printARIPIMem(MI, OpNo, OS);
132 break;
133 case MemAddrModeKind::e:
134 printARIPDMem(MI, OpNo, OS);
135 break;
136 case MemAddrModeKind::p:
137 printARIDMem(MI, OpNo, OS);
138 break;
139 case MemAddrModeKind::f:
140 case MemAddrModeKind::F:
141 printARIIMem(MI, OpNo, OS);
142 break;
143 case MemAddrModeKind::k:
144 printPCIMem(MI, 0, OpNo, OS);
145 break;
146 case MemAddrModeKind::q:
147 printPCDMem(MI, 0, OpNo, OS);
148 break;
149 case MemAddrModeKind::b:
150 printAbsMem(MI, OpNo, OS);
151 break;
152 default:
153 llvm_unreachable("Unrecognized memory addressing mode");
154 }
155 return false;
157 PrintSymbolOperand(MO, OS);
158 return false;
161 return false;
163 // This is a special case where it is treated as a memory reference, with
164 // the register holding the address value. Thus, we print it as ARI here.
166 printARIMem(MI, OpNo, OS);
167 return false;
168 }
169 break;
170 default:
171 break;
172 }
173 return AsmPrinter::PrintAsmMemoryOperand(MI, OpNo, ExtraCode, OS);
174}
175
177 M68k_MC::verifyInstructionPredicates(MI->getOpcode(),
178 getSubtargetInfo().getFeatureBits());
179
180 switch (MI->getOpcode()) {
181 default: {
182 if (MI->isPseudo()) {
183 LLVM_DEBUG(dbgs() << "Pseudo opcode(" << MI->getOpcode()
184 << ") found in EmitInstruction()\n");
185 llvm_unreachable("Cannot proceed");
186 }
187 break;
188 }
189 case M68k::TAILJMPj:
190 case M68k::TAILJMPq:
191 // Lower these as normal, but add some comments.
192 OutStreamer->AddComment("TAILCALL");
193 break;
194 }
195
196 MCInst TmpInst0;
197 MCInstLowering->Lower(MI, TmpInst0);
198 OutStreamer->emitInstruction(TmpInst0, getSubtargetInfo());
199}
200
202
204
206
207char M68kAsmPrinter::ID = 0;
208
209INITIALIZE_PASS(M68kAsmPrinter, "m68k-asm-printer", "M68k Assembly Printer",
210 false, false)
211
212extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeM68kAsmPrinter() {
214}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define X(NUM, ENUM, NAME)
Definition ELF.h:853
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
IRTranslator LLVM IR MI
This file contains M68k assembler printer declarations.
This file contains declarations for an M68k MCInst printer.
This file declares the M68k specific subclass of MachineFunctionInfo.
This file contains the entry points for global functions defined in the M68k target library,...
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
#define LLVM_DEBUG(...)
Definition Debug.h:119
virtual void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &OS)
Print the MachineOperand as a symbol.
MachineFunction * MF
The current machine function.
Definition AsmPrinter.h:109
unsigned getFunctionNumber() const
Return a unique ID for the current function.
bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
Definition AsmPrinter.h:453
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition AsmPrinter.h:106
const MCAsmInfo & MAI
Target Asm Printer information.
Definition AsmPrinter.h:97
virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const
Return the MCSymbol used to satisfy BlockAddress uses of the specified basic block.
const DataLayout & getDataLayout() const
Return information about data layout.
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
void emitFunctionBodyStart() override
Targets can override this to emit stuff before the first basic block in the function.
virtual bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
void emitInstruction(const MachineInstr *MI) override
Targets should implement this to emit instructions.
void emitEndOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the end of their file...
std::unique_ptr< M68kMCInstLower > MCInstLowering
void emitFunctionBodyEnd() override
Targets can override this to emit stuff after the last basic block in the function.
const M68kMachineFunctionInfo * MMFI
static const char * getRegisterName(MCRegister Reg)
void printARIDMem(const MachineInstr *MI, unsigned OpNum, raw_ostream &O)
void printPCDMem(const MachineInstr *MI, uint64_t Address, unsigned OpNum, raw_ostream &O)
void printPCIMem(const MachineInstr *MI, uint64_t Address, unsigned OpNum, raw_ostream &O)
void printARIPDMem(const MachineInstr *MI, unsigned OpNum, raw_ostream &O)
void printARIPIMem(const MachineInstr *MI, unsigned OpNum, raw_ostream &O)
void printARIIMem(const MachineInstr *MI, unsigned OpNum, raw_ostream &O)
void printARIMem(const MachineInstr *MI, unsigned OpNum, raw_ostream &O)
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
LLVM_ABI void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Definition MCSymbol.cpp:59
LLVM_ABI MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
int64_t getImm() const
MachineBasicBlock * getMBB() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
const BlockAddress * getBlockAddress() const
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
Register getReg() const
getReg - Returns the register number.
@ MO_Immediate
Immediate operand.
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
@ MO_GlobalAddress
Address of a global value.
@ MO_BlockAddress
Address of a basic block.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_Register
Register operand.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
Wrapper class representing virtual and physical registers.
Definition Register.h:20
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static bool isAddressRegister(unsigned RegNo)
Define some predicates that are used for node matching.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition Format.h:129
DWARFExpression::Operation Op
Target & getTheM68kTarget()
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...