Fixed some bugs.
[llvm/zpu.git] / lib / Target / ZPU / AsmPrinter / ZPUAsmPrinter.cpp
blob4c869b0b2bb8f605ec7c0cc033b313509a2500e5
1 //===-- ZPUAsmPrinter.cpp - ZPU LLVM assembly writer --------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
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"
16 #include "ZPU.h"
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"
39 using namespace llvm;
41 namespace {
42 class ZPUAsmPrinter : public AsmPrinter {
43 public:
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,
55 raw_ostream &O);
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) {
70 SmallString<128> Str;
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,
81 raw_ostream &O);
82 virtual void EmitFunctionEntryLabel();
83 void EmitStartOfAsmFile(Module &M);
85 } // end of anonymous namespace
87 #include "ZPUGenAsmWriter.inc"
89 //===----------------------------------------------------------------------===//
91 // ZPU Asm Directives
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:
106 // .frame $fp,48,$ra
107 // .mask 0xc0000000,-8
108 // addiu $sp, $sp, -48
109 // sw $ra, 40($sp)
110 // sw $fp, 36($sp)
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 //===----------------------------------------------------------------------===//
121 // Mask directives
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) {
127 O << "asm 3";
130 // Print a 32 bit hex number with all numbers.
131 void ZPUAsmPrinter::printHex32(unsigned Value, raw_ostream &O) {
132 O << "asm 4";
135 //===----------------------------------------------------------------------===//
136 // Frame and Set directives
137 //===----------------------------------------------------------------------===//
139 /// Frame Directive
140 void ZPUAsmPrinter::emitFrameDirective() {
143 /// Emit Set directives.
144 const char *ZPUAsmPrinter::getCurrentABIString() const {
145 return NULL;
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)
166 const {
167 return false;
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,
173 raw_ostream &O) {
174 O << "asm 9";
175 return false;
178 void ZPUAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
179 raw_ostream &O) {
181 if( opNum >= MI->getNumOperands())
183 printf("WARNING! Buggy code for now, trying to print opcode %d, count is %d \n",opNum,MI->getNumOperands());
184 return;
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()));
191 break;
193 case MachineOperand::MO_Immediate:
194 O << (int)MO.getImm();
195 break;
196 case MachineOperand::MO_MachineBasicBlock:
197 O << *MO.getMBB()->getSymbol();
198 return;
199 case MachineOperand::MO_GlobalAddress:
200 O << *Mang->getSymbol(MO.getGlobal());
201 break;
202 case MachineOperand::MO_ExternalSymbol:
203 O << MO.getSymbolName();
204 break;
205 default:
206 llvm_unreachable("<unknown operand type>");
208 if (CloseParen) O << ")";
212 void ZPUAsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum,
213 raw_ostream &O) {
214 O << "asm 11";
217 void ZPUAsmPrinter::
218 printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
219 const char *Modifier) {
221 //if(opNum+1 < MI->getNumOperands())
222 //{
223 // printOperand(MI, opNum+1, O);
225 O << ", ";
226 printOperand(MI, opNum, O);
229 void ZPUAsmPrinter::
230 printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
231 const char *Modifier) {
232 O << "asm 1";
235 void ZPUAsmPrinter::EmitStartOfAsmFile(Module &M) {
238 void ZPUAsmPrinter::printSrcMemOperand(const MachineInstr *MI, unsigned OpNo,
239 raw_ostream &O) {
240 O << "asm 15";
244 // Force static initialization.
245 extern "C" void LLVMInitializeZPUAsmPrinter() {
246 RegisterAsmPrinter<ZPUAsmPrinter> X(TheZPUTarget);