LLVM 19.0.0git
MSP430AsmPrinter.cpp
Go to the documentation of this file.
1//===-- MSP430AsmPrinter.cpp - MSP430 LLVM assembly writer ----------------===//
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// This file contains a printer that converts from our internal representation
10// of machine-dependent LLVM code to the MSP430 assembly language.
11//
12//===----------------------------------------------------------------------===//
13
15#include "MSP430.h"
16#include "MSP430InstrInfo.h"
17#include "MSP430MCInstLower.h"
18#include "MSP430TargetMachine.h"
26#include "llvm/IR/Constants.h"
28#include "llvm/IR/Mangler.h"
29#include "llvm/IR/Module.h"
30#include "llvm/MC/MCAsmInfo.h"
31#include "llvm/MC/MCInst.h"
33#include "llvm/MC/MCStreamer.h"
34#include "llvm/MC/MCSymbol.h"
37using namespace llvm;
38
39#define DEBUG_TYPE "asm-printer"
40
41namespace {
42 class MSP430AsmPrinter : public AsmPrinter {
43 public:
44 MSP430AsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
45 : AsmPrinter(TM, std::move(Streamer)) {}
46
47 StringRef getPassName() const override { return "MSP430 Assembly Printer"; }
48
49 bool runOnMachineFunction(MachineFunction &MF) override;
50
51 void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override;
52 void printOperand(const MachineInstr *MI, int OpNum,
53 raw_ostream &O, const char* Modifier = nullptr);
54 void printSrcMemOperand(const MachineInstr *MI, int OpNum,
55 raw_ostream &O);
56 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
57 const char *ExtraCode, raw_ostream &O) override;
58 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
59 const char *ExtraCode, raw_ostream &O) override;
60 void emitInstruction(const MachineInstr *MI) override;
61
62 void EmitInterruptVectorSection(MachineFunction &ISR);
63 };
64} // end of anonymous namespace
65
66void MSP430AsmPrinter::PrintSymbolOperand(const MachineOperand &MO,
67 raw_ostream &O) {
69 if (Offset)
70 O << '(' << Offset << '+';
71
72 getSymbol(MO.getGlobal())->print(O, MAI);
73
74 if (Offset)
75 O << ')';
76}
77
78void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
79 raw_ostream &O, const char *Modifier) {
80 const MachineOperand &MO = MI->getOperand(OpNum);
81 switch (MO.getType()) {
82 default: llvm_unreachable("Not implemented yet!");
85 return;
87 if (!Modifier || strcmp(Modifier, "nohash"))
88 O << '#';
89 O << MO.getImm();
90 return;
92 MO.getMBB()->getSymbol()->print(O, MAI);
93 return;
95 // If the global address expression is a part of displacement field with a
96 // register base, we should not emit any prefix symbol here, e.g.
97 // mov.w glb(r1), r2
98 // Otherwise (!) msp430-as will silently miscompile the output :(
99 if (!Modifier || strcmp(Modifier, "nohash"))
100 O << '#';
101 PrintSymbolOperand(MO, O);
102 return;
103 }
104 }
105}
106
107void MSP430AsmPrinter::printSrcMemOperand(const MachineInstr *MI, int OpNum,
108 raw_ostream &O) {
109 const MachineOperand &Base = MI->getOperand(OpNum);
110 const MachineOperand &Disp = MI->getOperand(OpNum+1);
111
112 // Print displacement first
113
114 // Imm here is in fact global address - print extra modifier.
115 if (Disp.isImm() && Base.getReg() == MSP430::SR)
116 O << '&';
117 printOperand(MI, OpNum+1, O, "nohash");
118
119 // Print register base field
120 if (Base.getReg() != MSP430::SR && Base.getReg() != MSP430::PC) {
121 O << '(';
122 printOperand(MI, OpNum, O);
123 O << ')';
124 }
125}
126
127/// PrintAsmOperand - Print out an operand for an inline asm expression.
128///
129bool MSP430AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
130 const char *ExtraCode, raw_ostream &O) {
131 // Does this asm operand have a single letter operand modifier?
132 if (ExtraCode && ExtraCode[0])
133 return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
134
135 printOperand(MI, OpNo, O);
136 return false;
137}
138
139bool MSP430AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
140 unsigned OpNo,
141 const char *ExtraCode,
142 raw_ostream &O) {
143 if (ExtraCode && ExtraCode[0]) {
144 return true; // Unknown modifier.
145 }
146 printSrcMemOperand(MI, OpNo, O);
147 return false;
148}
149
150//===----------------------------------------------------------------------===//
151void MSP430AsmPrinter::emitInstruction(const MachineInstr *MI) {
152 MSP430_MC::verifyInstructionPredicates(MI->getOpcode(),
153 getSubtargetInfo().getFeatureBits());
154
155 MSP430MCInstLower MCInstLowering(OutContext, *this);
156
157 MCInst TmpInst;
158 MCInstLowering.Lower(MI, TmpInst);
159 EmitToStreamer(*OutStreamer, TmpInst);
160}
161
162void MSP430AsmPrinter::EmitInterruptVectorSection(MachineFunction &ISR) {
163 MCSection *Cur = OutStreamer->getCurrentSectionOnly();
164 const auto *F = &ISR.getFunction();
165 if (F->getCallingConv() != CallingConv::MSP430_INTR) {
166 report_fatal_error("Functions with 'interrupt' attribute must have msp430_intrcc CC");
167 }
168 StringRef IVIdx = F->getFnAttribute("interrupt").getValueAsString();
169 MCSection *IV = OutStreamer->getContext().getELFSection(
170 "__interrupt_vector_" + IVIdx,
172 OutStreamer->switchSection(IV);
173
174 const MCSymbol *FunctionSymbol = getSymbol(F);
175 OutStreamer->emitSymbolValue(FunctionSymbol, TM.getProgramPointerSize());
176 OutStreamer->switchSection(Cur);
177}
178
179bool MSP430AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
180 // Emit separate section for an interrupt vector if ISR
181 if (MF.getFunction().hasFnAttribute("interrupt")) {
182 EmitInterruptVectorSection(MF);
183 }
184
185 SetupMachineFunction(MF);
186 emitFunctionBody();
187 return false;
188}
189
190// Force static initialization.
193}
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:135
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition: MD5.cpp:55
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMSP430AsmPrinter()
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Module.h This file contains the declarations for the Module class.
const char LLVMTargetMachineRef TM
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
static const uint32_t IV[8]
Definition: blake3_impl.h:78
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:84
virtual void emitInstruction(const MachineInstr *)
Targets should implement this to emit instructions.
Definition: AsmPrinter.h:567
virtual void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &OS)
Print the MachineOperand as a symbol.
bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
Definition: AsmPrinter.h:395
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...
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.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:669
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:39
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:40
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Definition: MCSymbol.cpp:58
static const char * getRegisterName(MCRegister Reg)
MSP430MCInstLower - This class is used to lower an MachineInstr into an MCInst.
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
Definition: MachineInstr.h:68
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
int64_t getImm() const
MachineBasicBlock * getMBB() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
Register getReg() const
getReg - Returns the register number.
@ MO_Immediate
Immediate operand.
@ MO_GlobalAddress
Address of a global value.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_Register
Register operand.
int64_t getOffset() const
Return the offset from the symbol in this operand.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition: Pass.cpp:81
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:78
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ MSP430_INTR
Used for MSP430 interrupt routines.
Definition: CallingConv.h:117
@ SHF_ALLOC
Definition: ELF.h:1154
@ SHF_EXECINSTR
Definition: ELF.h:1157
@ SHT_PROGBITS
Definition: ELF.h:1062
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:456
Target & getTheMSP430Target()
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:156
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...