llvm.org GIT mirror llvm / a4e8200
Added support for Mips specific GAS directives Fixed print immediate Fixed Identation on MipsISelDAGToDAG.cpp git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@39764 91177308-0d34-0410-b5e6-96231b3b80d8 Bruno Cardoso Lopes 13 years ago
2 changed file(s) with 159 addition(s) and 20 deletion(s). Raw diff Collapse all Expand all
1616 #include "Mips.h"
1717 #include "MipsInstrInfo.h"
1818 #include "MipsTargetMachine.h"
19 #include "MipsMachineFunction.h"
1920 #include "llvm/Constants.h"
2021 #include "llvm/DerivedTypes.h"
2122 #include "llvm/Module.h"
2223 #include "llvm/CodeGen/AsmPrinter.h"
2324 #include "llvm/CodeGen/MachineFunctionPass.h"
2425 #include "llvm/CodeGen/MachineConstantPool.h"
26 #include "llvm/CodeGen/MachineFrameInfo.h"
2527 #include "llvm/CodeGen/MachineInstr.h"
2628 #include "llvm/Target/TargetAsmInfo.h"
2729 #include "llvm/Target/TargetData.h"
2931 #include "llvm/Support/Mangler.h"
3032 #include "llvm/ADT/Statistic.h"
3133 #include "llvm/ADT/StringExtras.h"
34 #include "llvm/Support/Debug.h"
3235 #include "llvm/Support/CommandLine.h"
3336 #include "llvm/Support/MathExtras.h"
3437 #include
4750 return "Mips Assembly Printer";
4851 }
4952
53 enum SetDirectiveFlags {
54 REORDER, // enables instruction reordering.
55 NOREORDER, // disables instruction reordering.
56 MACRO, // enables GAS macros.
57 NOMACRO // disables GAS macros.
58 };
59
5060 void printOperand(const MachineInstr *MI, int opNum);
5161 void printMemOperand(const MachineInstr *MI, int opNum,
5262 const char *Modifier = 0);
63
64 void printHex32(unsigned int Value);
65 void emitFunctionStart(MachineFunction &MF);
66 void emitFunctionEnd();
67 void emitFrameDirective(MachineFunction &MF);
68 void emitMaskDirective(MachineFunction &MF);
69 void emitFMaskDirective();
70 void emitSetDirective(SetDirectiveFlags Flag);
5371
5472 bool printInstruction(const MachineInstr *MI); // autogenerated.
5573 bool runOnMachineFunction(MachineFunction &F);
7088 return new MipsAsmPrinter(o, tm, tm.getTargetAsmInfo());
7189 }
7290
91 /// This pattern will be emitted :
92 /// .frame reg1, size, reg2
93 /// It describes the stack frame.
94 /// reg1 - stack pointer
95 /// size - stack size allocated for the function
96 /// reg2 - return address register
97 void MipsAsmPrinter::
98 emitFrameDirective(MachineFunction &MF)
99 {
100 const MRegisterInfo &RI = *TM.getRegisterInfo();
101
102 unsigned stackReg = RI.getFrameRegister(MF);
103 unsigned returnReg = RI.getRARegister();
104 unsigned stackSize = MF.getFrameInfo()->getStackSize();
105
106
107 O << "\t.frame\t" << "$" << LowercaseString(RI.get(stackReg).Name)
108 << "," << stackSize << ","
109 << "$" << LowercaseString(RI.get(returnReg).Name)
110 << "\n";
111 }
112
113 /// This pattern will be emitted :
114 /// .mask bitmask, offset
115 /// Tells the assembler (and possibly linker) which registers are saved and where.
116 /// bitmask - mask of all GPRs (little endian)
117 /// offset - negative value. offset+stackSize should give where on the stack
118 /// the first GPR is saved.
119 /// TODO: consider calle saved GPR regs here, not hardcode register numbers.
120 void MipsAsmPrinter::
121 emitMaskDirective(MachineFunction &MF)
122 {
123 const MRegisterInfo &RI = *TM.getRegisterInfo();
124 MipsFunctionInfo *MipsFI = MF.getInfo();
125
126 bool hasFP = RI.hasFP(MF);
127 bool saveRA = MF.getFrameInfo()->hasCalls();
128
129 int offset;
130
131 if (!MipsFI->getTopSavedRegOffset())
132 offset = 0;
133 else
134 offset = -(MF.getFrameInfo()->getStackSize()
135 -MipsFI->getTopSavedRegOffset());
136
137 #ifndef NDEBUG
138 DOUT << "<--ASM PRINTER--emitMaskDirective-->" << "\n";
139 DOUT << "StackSize : " << MF.getFrameInfo()->getStackSize() << "\n";
140 DOUT << "getTopSavedRegOffset() : " << MipsFI->getTopSavedRegOffset() << "\n";
141 DOUT << "offset : " << offset << "\n\n";
142 #endif
143
144 unsigned int bitmask = 0;
145
146 if (hasFP)
147 bitmask |= (1 << 30);
148
149 if (saveRA)
150 bitmask |= (1 << 31);
151
152 O << "\t.mask\t";
153 printHex32(bitmask);
154 O << "," << offset << "\n";
155 }
156
157 /// This pattern will be emitted :
158 /// .fmask bitmask, offset
159 /// Tells the assembler (and possibly linker) which float registers are saved.
160 /// bitmask - mask of all Float Point registers (little endian)
161 /// offset - negative value. offset+stackSize should give where on the stack
162 /// the first Float Point register is saved.
163 /// TODO: implement this, dummy for now
164 void MipsAsmPrinter::
165 emitFMaskDirective()
166 {
167 O << "\t.fmask\t0x00000000,0" << "\n";
168 }
169
170 /// Print a 32 bit hex number filling with 0's on the left.
171 /// TODO: make this setfill and setw
172 void MipsAsmPrinter::
173 printHex32(unsigned int Value) {
174 O << "0x" << std::hex << Value << std::dec;
175 }
176
177 /// Emit Set directives.
178 void MipsAsmPrinter::
179 emitSetDirective(SetDirectiveFlags Flag) {
180
181 O << "\t.set\t";
182 switch(Flag) {
183 case REORDER: O << "reorder" << "\n"; break;
184 case NOREORDER: O << "noreorder" << "\n"; break;
185 case MACRO: O << "macro" << "\n"; break;
186 case NOMACRO: O << "nomacro" << "\n"; break;
187 default: break;
188 }
189 }
190
191 /// Emit the directives used by GAS on the start of functions
192 void MipsAsmPrinter::
193 emitFunctionStart(MachineFunction &MF)
194 {
195 // Print out the label for the function.
196 const Function *F = MF.getFunction();
197 SwitchToTextSection(getSectionForFunction(*F).c_str(), F);
198
199 // On Mips GAS, if .align #n is present, #n means the number of bits
200 // to be cleared. So, if we want 4 byte alignment, we must have .align 2
201 EmitAlignment(1, F);
202
203 O << "\t.globl\t" << CurrentFnName << "\n";
204 O << "\t.ent\t" << CurrentFnName << "\n";
205 O << "\t.type\t" << CurrentFnName << ", @function\n";
206 O << CurrentFnName << ":\n";
207
208 emitFrameDirective(MF);
209 emitMaskDirective(MF);
210 emitFMaskDirective();
211
212 emitSetDirective(NOREORDER);
213 emitSetDirective(NOMACRO);
214 }
215
216 /// Emit the directives used by GAS on the end of functions
217 void MipsAsmPrinter::
218 emitFunctionEnd() {
219 emitSetDirective(MACRO);
220 emitSetDirective(REORDER);
221 O << "\t.end\t" << CurrentFnName << "\n";
222 }
223
73224 /// runOnMachineFunction - This uses the printMachineInstruction()
74225 /// method to print assembly for each instruction.
75226 bool MipsAsmPrinter::
85236 // What's my mangled name?
86237 CurrentFnName = Mang->getValueName(MF.getFunction());
87238
88 // Print out the label for the function.
89 const Function *F = MF.getFunction();
90 SwitchToTextSection(getSectionForFunction(*F).c_str(), F);
91
92 // On Mips GAS if .align #n is present, #n means the number of bits
93 // to be cleared to align. So, if we want 4 byte alignment, we must
94 // have .align 2
95 // TODO:
96 // add gas ".mask" and ".fmask"
97 EmitAlignment(1, F);
98 O << "\t.globl\t" << CurrentFnName << "\n";
99 O << "\t.ent\t" << CurrentFnName << "\n";
100 O << "\t.type\t" << CurrentFnName << ", @function\n";
101 O << CurrentFnName << ":\n";
239 // Emit the function start directives
240 emitFunctionStart(MF);
102241
103242 // Print out code for the function.
104243 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
119258 }
120259 }
121260
122 // close function with asm directive
123 O << "\t.end\t" << CurrentFnName << "\n";
261 // Emit function end directives
262 emitFunctionEnd();
124263
125264 // We didn't modify anything.
126265 return false;
155294
156295 case MachineOperand::MO_Immediate:
157296 if ((MI->getOpcode() == Mips::SLTiu) || (MI->getOpcode() == Mips::ORi) ||
158 (MI->getOpcode() == Mips::LUi) || (MI->getOpcode() == Mips::ANDi))
159 O << (unsigned int)MO.getImmedValue();
297 (MI->getOpcode() == Mips::LUi) || (MI->getOpcode() == Mips::ANDi))
298 O << (unsigned short int)MO.getImmedValue();
160299 else
161 O << (int)MO.getImmedValue();
300 O << (short int)MO.getImmedValue();
162301 break;
163302
164303 case MachineOperand::MO_MachineBasicBlock:
162162 }
163163 }
164164
165 Base = Addr;
165 Base = Addr;
166166 Offset = CurDAG->getTargetConstant(0, MVT::i32);
167167 return true;
168168 }