1 //===-- Nios2AsmPrinter.cpp - Nios2 LLVM Assembly Printer -----------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains a printer that converts from our internal representation
11 // of machine-dependent LLVM code to GAS-format NIOS2 assembly language.
13 //===----------------------------------------------------------------------===//
15 #include "InstPrinter/Nios2InstPrinter.h"
16 #include "MCTargetDesc/Nios2BaseInfo.h"
18 #include "Nios2TargetMachine.h"
19 #include "llvm/CodeGen/AsmPrinter.h"
20 #include "llvm/MC/MCStreamer.h"
21 #include "llvm/Support/TargetRegistry.h"
25 #define DEBUG_TYPE "nios2-asm-printer"
29 class Nios2AsmPrinter
: public AsmPrinter
{
32 explicit Nios2AsmPrinter(TargetMachine
&TM
,
33 std::unique_ptr
<MCStreamer
> Streamer
)
34 : AsmPrinter(TM
, std::move(Streamer
)) {}
36 StringRef
getPassName() const override
{ return "Nios2 Assembly Printer"; }
38 //- EmitInstruction() must exists or will have run time error.
39 void EmitInstruction(const MachineInstr
*MI
) override
;
40 bool PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
41 unsigned AsmVariant
, const char *ExtraCode
,
42 raw_ostream
&O
) override
;
43 bool PrintAsmMemoryOperand(const MachineInstr
*MI
, unsigned OpNum
,
44 unsigned AsmVariant
, const char *ExtraCode
,
45 raw_ostream
&O
) override
;
46 void printOperand(const MachineInstr
*MI
, int opNum
, raw_ostream
&O
);
47 void EmitFunctionEntryLabel() override
;
51 //- EmitInstruction() must exists or will have run time error.
52 void Nios2AsmPrinter::EmitInstruction(const MachineInstr
*MI
) {
54 // Print out both ordinary instruction and boudle instruction
55 MachineBasicBlock::const_instr_iterator I
= MI
->getIterator();
56 MachineBasicBlock::const_instr_iterator E
= MI
->getParent()->instr_end();
61 llvm_unreachable("Pseudo opcode found in EmitInstruction()");
65 LowerNios2MachineInstToMCInst(&*I
, TmpInst0
, *this);
66 EmitToStreamer(*OutStreamer
, TmpInst0
);
67 } while ((++I
!= E
) && I
->isInsideBundle()); // Delay slot check
70 // .type main,@function
71 //-> .ent main # @main
73 void Nios2AsmPrinter::EmitFunctionEntryLabel() {
74 OutStreamer
->EmitLabel(CurrentFnSym
);
77 // Print out an operand for an inline asm expression.
78 bool Nios2AsmPrinter::PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNum
,
80 const char *ExtraCode
, raw_ostream
&O
) {
81 printOperand(MI
, OpNum
, O
);
85 bool Nios2AsmPrinter::PrintAsmMemoryOperand(const MachineInstr
*MI
,
86 unsigned OpNum
, unsigned AsmVariant
,
87 const char *ExtraCode
,
89 if (ExtraCode
&& ExtraCode
[0])
90 return true; // Unknown modifier
92 const MachineOperand
&MO
= MI
->getOperand(OpNum
);
93 assert(MO
.isReg() && "unexpected inline asm memory operand");
94 O
<< "($" << Nios2InstPrinter::getRegisterName(MO
.getReg()) << ")";
99 void Nios2AsmPrinter::printOperand(const MachineInstr
*MI
, int opNum
,
101 const MachineOperand
&MO
= MI
->getOperand(opNum
);
104 if (MO
.getTargetFlags())
107 switch (MO
.getTargetFlags()) {
108 case Nios2FG::MO_ABS_HI
:
111 case Nios2FG::MO_ABS_LO
:
116 switch (MO
.getType()) {
117 case MachineOperand::MO_Register
:
119 << StringRef(Nios2InstPrinter::getRegisterName(MO
.getReg())).lower();
122 case MachineOperand::MO_Immediate
:
126 case MachineOperand::MO_MachineBasicBlock
:
127 MO
.getMBB()->getSymbol()->print(O
, MAI
);
130 case MachineOperand::MO_GlobalAddress
:
131 getSymbol(MO
.getGlobal())->print(O
, MAI
);
134 case MachineOperand::MO_BlockAddress
:
135 O
<< GetBlockAddressSymbol(MO
.getBlockAddress())->getName();
138 case MachineOperand::MO_ExternalSymbol
:
139 O
<< MO
.getSymbolName();
143 llvm_unreachable("<unknown operand type>");
150 // Force static initialization.
151 extern "C" void LLVMInitializeNios2AsmPrinter() {
152 RegisterAsmPrinter
<Nios2AsmPrinter
> X(getTheNios2Target());