LLVM: lib/Target/MSP430/MSP430AsmPrinter.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
32using namespace llvm;
33
34#define DEBUG_TYPE "asm-printer"
35
36namespace {
37 class MSP430AsmPrinter : public AsmPrinter {
38 public:
39 MSP430AsmPrinter(TargetMachine &TM, std::unique_ptr Streamer)
41
42 StringRef getPassName() const override { return "MSP430 Assembly Printer"; }
43
45
48 bool PrefixHash = true);
49 void printSrcMemOperand(const MachineInstr *MI, int OpNum,
51 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
52 const char *ExtraCode, raw_ostream &O) override;
53 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
54 const char *ExtraCode, raw_ostream &O) override;
55 void emitInstruction(const MachineInstr *MI) override;
56
58
59 static char ID;
60 };
61}
62
63void MSP430AsmPrinter::PrintSymbolOperand(const MachineOperand &MO,
68
69 getSymbol(MO.getGlobal())->print(O, MAI);
70
72 O << ')';
73}
74
75void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
76 raw_ostream &O, bool PrefixHash) {
77 const MachineOperand &MO = MI->getOperand(OpNum);
82 return;
84 if (PrefixHash)
85 O << '#';
87 return;
90 return;
92
93
94
95
96 if (PrefixHash)
97 O << '#';
98 PrintSymbolOperand(MO, O);
99 return;
100 }
101 }
102}
103
104void MSP430AsmPrinter::printSrcMemOperand(const MachineInstr *MI, int OpNum,
105 raw_ostream &O) {
106 const MachineOperand &Base = MI->getOperand(OpNum);
107 const MachineOperand &Disp = MI->getOperand(OpNum+1);
108
109
110
111
112 if (Disp.isImm() && Base.getReg() == MSP430::SR)
113 O << '&';
114 printOperand(MI, OpNum + 1, O, false);
115
116
117 if (Base.getReg() != MSP430::SR && Base.getReg() != MSP430::PC) {
118 O << '(';
120 O << ')';
121 }
122}
123
124
125
126bool MSP430AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
127 const char *ExtraCode, raw_ostream &O) {
128
129 if (ExtraCode && ExtraCode[0])
131
133 return false;
134}
135
136bool MSP430AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
137 unsigned OpNo,
138 const char *ExtraCode,
139 raw_ostream &O) {
140 if (ExtraCode && ExtraCode[0]) {
141 return true;
142 }
143 printSrcMemOperand(MI, OpNo, O);
144 return false;
145}
146
147
148void MSP430AsmPrinter::emitInstruction(const MachineInstr *MI) {
149 MSP430_MC::verifyInstructionPredicates(MI->getOpcode(),
150 getSubtargetInfo().getFeatureBits());
151
152 MSP430MCInstLower MCInstLowering(OutContext, *this);
153
154 MCInst TmpInst;
155 MCInstLowering.Lower(MI, TmpInst);
156 EmitToStreamer(*OutStreamer, TmpInst);
157}
158
159void MSP430AsmPrinter::EmitInterruptVectorSection(MachineFunction &ISR) {
160 MCSection *Cur = OutStreamer->getCurrentSectionOnly();
162 if (F->getCallingConv() != CallingConv::MSP430_INTR) {
163 report_fatal_error("Functions with 'interrupt' attribute must have msp430_intrcc CC");
164 }
166 MCSection *IV = OutStreamer->getContext().getELFSection(
167 "__interrupt_vector_" + IVIdx,
169 OutStreamer->switchSection(IV);
170
172 OutStreamer->emitSymbolValue(FunctionSymbol, TM.getProgramPointerSize());
173 OutStreamer->switchSection(Cur);
174}
175
176bool MSP430AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
177
179 EmitInterruptVectorSection(MF);
180 }
181
182 SetupMachineFunction(MF);
183 emitFunctionBody();
184 return false;
185}
186
187char MSP430AsmPrinter::ID = 0;
188
190 "MSP430 Assembly Printer", false, false)
191
192
194LLVMInitializeMSP430AsmPrinter() {
196}
#define LLVM_EXTERNAL_VISIBILITY
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static const uint32_t IV[8]
This class is intended to be used as a driving class for all asm writers.
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.
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
LLVM_ABI void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
static const char * getRegisterName(MCRegister Reg)
LLVM_ABI 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.
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() 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.
StringRef - Represent a constant reference to a string, i.e.
Primary interface to the complete machine description for the target machine.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheMSP430Target()
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...