1 //===-- ZPUAsmPrinter.cpp - ZPU LLVM assembly writer --------------------===//
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 ZPU assembly language.
13 //===----------------------------------------------------------------------===//
15 #define DEBUG_TYPE "ZPU-asm-printer"
17 #include "ZPUInstrInfo.h"
18 #include "ZPUTargetMachine.h"
19 #include "llvm/BasicBlock.h"
20 #include "llvm/Instructions.h"
21 #include "llvm/CodeGen/AsmPrinter.h"
22 #include "llvm/CodeGen/MachineFunctionPass.h"
23 #include "llvm/CodeGen/MachineConstantPool.h"
24 #include "llvm/CodeGen/MachineFrameInfo.h"
25 #include "llvm/CodeGen/MachineInstr.h"
26 #include "llvm/MC/MCStreamer.h"
27 #include "llvm/MC/MCAsmInfo.h"
28 #include "llvm/MC/MCSymbol.h"
29 #include "llvm/Target/Mangler.h"
30 #include "llvm/Target/TargetData.h"
31 #include "llvm/Target/TargetLoweringObjectFile.h"
32 #include "llvm/Target/TargetMachine.h"
33 #include "llvm/Target/TargetOptions.h"
34 #include "llvm/Target/TargetRegistry.h"
35 #include "llvm/ADT/SmallString.h"
36 #include "llvm/ADT/StringExtras.h"
37 #include "llvm/ADT/Twine.h"
38 #include "llvm/Support/raw_ostream.h"
42 class ZPUAsmPrinter
: public AsmPrinter
{
44 explicit ZPUAsmPrinter(TargetMachine
&TM
, MCStreamer
&Streamer
)
45 : AsmPrinter(TM
, Streamer
) {
49 virtual const char *getPassName() const {
50 return "ZPU Assembly Printer";
53 bool PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
54 unsigned AsmVariant
, const char *ExtraCode
,
56 void printOperand(const MachineInstr
*MI
, int opNum
, raw_ostream
&O
);
57 void printUnsignedImm(const MachineInstr
*MI
, int opNum
, raw_ostream
&O
);
58 void printMemOperand(const MachineInstr
*MI
, int opNum
, raw_ostream
&O
,
59 const char *Modifier
= 0);
60 void printFCCOperand(const MachineInstr
*MI
, int opNum
, raw_ostream
&O
,
61 const char *Modifier
= 0);
62 void printSavedRegsBitmask(raw_ostream
&O
);
63 void printHex32(unsigned int Value
, raw_ostream
&O
);
65 const char *getCurrentABIString() const;
66 void emitFrameDirective();
68 void printInstruction(const MachineInstr
*MI
, raw_ostream
&O
); // autogen'd.
69 void EmitInstruction(const MachineInstr
*MI
) {
71 raw_svector_ostream
OS(Str
);
72 printInstruction(MI
, OS
);
73 OutStreamer
.EmitRawText(OS
.str());
75 virtual void EmitFunctionBodyStart();
76 virtual void EmitFunctionBodyEnd();
77 virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock
*MBB
) const;
78 static const char *getRegisterName(unsigned RegNo
);
80 void printSrcMemOperand(const MachineInstr
*MI
, unsigned OpNo
,
82 virtual void EmitFunctionEntryLabel();
83 void EmitStartOfAsmFile(Module
&M
);
85 } // end of anonymous namespace
87 #include "ZPUGenAsmWriter.inc"
89 //===----------------------------------------------------------------------===//
93 // -- Frame directive "frame Stackpointer, Stacksize, RARegister"
94 // Describe the stack frame.
96 // -- Mask directives "(f)mask bitmask, offset"
97 // Tells the assembler which registers are saved and where.
98 // bitmask - contain a little endian bitset indicating which registers are
99 // saved on function prologue (e.g. with a 0x80000000 mask, the
100 // assembler knows the register 31 (RA) is saved at prologue.
101 // offset - the position before stack pointer subtraction indicating where
102 // the first saved register on prologue is located. (e.g. with a
104 // Consider the following function prologue:
107 // .mask 0xc0000000,-8
108 // addiu $sp, $sp, -48
112 // With a 0xc0000000 mask, the assembler knows the register 31 (RA) and
113 // 30 (FP) are saved at prologue. As the save order on prologue is from
114 // left to right, RA is saved first. A -8 offset means that after the
115 // stack pointer subtration, the first register in the mask (RA) will be
116 // saved at address 48-8=40.
118 //===----------------------------------------------------------------------===//
120 //===----------------------------------------------------------------------===//
122 //===----------------------------------------------------------------------===//
124 // Create a bitmask with all callee saved registers for CPU or Floating Point
125 // registers. For CPU registers consider RA, GP and FP for saving if necessary.
126 void ZPUAsmPrinter::printSavedRegsBitmask(raw_ostream
&O
) {
130 // Print a 32 bit hex number with all numbers.
131 void ZPUAsmPrinter::printHex32(unsigned Value
, raw_ostream
&O
) {
135 //===----------------------------------------------------------------------===//
136 // Frame and Set directives
137 //===----------------------------------------------------------------------===//
140 void ZPUAsmPrinter::emitFrameDirective() {
143 /// Emit Set directives.
144 const char *ZPUAsmPrinter::getCurrentABIString() const {
148 void ZPUAsmPrinter::EmitFunctionEntryLabel() {
151 /// EmitFunctionBodyStart - Targets can override this to emit stuff before
152 /// the first basic block in the function.
153 void ZPUAsmPrinter::EmitFunctionBodyStart() {
156 /// EmitFunctionBodyEnd - Targets can override this to emit stuff after
157 /// the last basic block in the function.
158 void ZPUAsmPrinter::EmitFunctionBodyEnd() {
162 /// isBlockOnlyReachableByFallthough - Return true if the basic block has
163 /// exactly one predecessor and the control transfer mechanism between
164 /// the predecessor and this block is a fall-through.
165 bool ZPUAsmPrinter::isBlockOnlyReachableByFallthrough(const MachineBasicBlock
*MBB
)
170 // Print out an operand for an inline asm expression.
171 bool ZPUAsmPrinter::PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
172 unsigned AsmVariant
,const char *ExtraCode
,
178 void ZPUAsmPrinter::printOperand(const MachineInstr
*MI
, int opNum
,
181 if( opNum
>= MI
->getNumOperands())
183 printf("WARNING! Buggy code for now, trying to print opcode %d, count is %d \n",opNum
,MI
->getNumOperands());
186 const MachineOperand
&MO
= MI
->getOperand (opNum
);
187 bool CloseParen
= false;
188 switch (MO
.getType()) {
189 case MachineOperand::MO_Register
:
190 O
<< "; %" << LowercaseString(getRegisterName(MO
.getReg()));
193 case MachineOperand::MO_Immediate
:
194 O
<< (int)MO
.getImm();
196 case MachineOperand::MO_MachineBasicBlock
:
197 O
<< *MO
.getMBB()->getSymbol();
199 case MachineOperand::MO_GlobalAddress
:
200 O
<< *Mang
->getSymbol(MO
.getGlobal());
202 case MachineOperand::MO_ExternalSymbol
:
203 O
<< MO
.getSymbolName();
206 llvm_unreachable("<unknown operand type>");
208 if (CloseParen
) O
<< ")";
212 void ZPUAsmPrinter::printUnsignedImm(const MachineInstr
*MI
, int opNum
,
218 printMemOperand(const MachineInstr
*MI
, int opNum
, raw_ostream
&O
,
219 const char *Modifier
) {
221 //if(opNum+1 < MI->getNumOperands())
223 // printOperand(MI, opNum+1, O);
226 printOperand(MI
, opNum
, O
);
230 printFCCOperand(const MachineInstr
*MI
, int opNum
, raw_ostream
&O
,
231 const char *Modifier
) {
235 void ZPUAsmPrinter::EmitStartOfAsmFile(Module
&M
) {
238 void ZPUAsmPrinter::printSrcMemOperand(const MachineInstr
*MI
, unsigned OpNo
,
244 // Force static initialization.
245 extern "C" void LLVMInitializeZPUAsmPrinter() {
246 RegisterAsmPrinter
<ZPUAsmPrinter
> X(TheZPUTarget
);