blob: 5f4d20854d072eedde2b0a70aee80f2818f82012 [file] [log] [blame]
Jakub Staszak88ac78c2004-04-06 19:31:31 +00001//===- SimpleInstrSelEmitter.cpp - Generate a Simple Instruction Selector ------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This tablegen backend is responsible for emitting an instruction selector
11//
12//
13//===----------------------------------------------------------------------===//
14#include "InstrInfoEmitter.h"
15#include "SimpleInstrSelEmitter.h"
16#include "CodeGenWrappers.h"
17#include "Record.h"
18#include "Support/Debug.h"
19#include "Support/StringExtras.h"
20#include <set>
21
22
23#include "Record.h"
24#include "Support/CommandLine.h"
25#include "Support/Signals.h"
26#include "Support/FileUtilities.h"
27#include "CodeEmitterGen.h"
28#include "RegisterInfoEmitter.h"
29#include "InstrInfoEmitter.h"
30#include "InstrSelectorEmitter.h"
31#include "SimpleInstrSelEmitter.h"
32#include <algorithm>
33#include <cstdio>
34#include <fstream>
35#include <vector>
36
37namespace llvm {
38
39 std::string FnDecs;
40
41// run - Emit the main instruction description records for the target...
42void SimpleInstrSelEmitter::run(std::ostream &OS) {
43
44
45 // EmitSourceFileHeader("Mark's Instruction Selector for the X86 target", OS);
46
47
48// OS << "#include \"llvm/CodeGen/MachineInstrBuilder.h\"\n";
49
50// OS << "#include \"llvm/Constants.h\"\n";
51// OS << "#include \"llvm/DerivedTypes.h\"\n";
52// OS << "#include \"llvm/Function.h\"\n";
53// OS << "#include \"llvm/Instructions.h\"\n";
54// OS << "#include \"llvm/IntrinsicLowering.h\"\n";
55// OS << "#include \"llvm/Pass.h\"\n";
56// OS << "#include \"llvm/CodeGen/MachineConstantPool.h\"\n";
57// OS << "#include \"llvm/CodeGen/MachineFrameInfo.h\"\n";
58// OS << "#include \"llvm/CodeGen/MachineFunction.h\"\n";
59// OS << "#include \"llvm/CodeGen/MachineInstrBuilder.h\"\n";
60// OS << "#include \"llvm/CodeGen/SSARegMap.h\"\n";
61// OS << "#include \"llvm/Target/MRegisterInfo.h\"\n";
62// OS << "#include \"llvm/Target/TargetMachine.h\"\n";
63// OS << "#include \"llvm/Support/InstVisitor.h\"\n";
64
65// OS << "using namespace llvm;\n\n";
66
67
68 FnDecs = "";
69
70 // for each InstrClass
71
72 std::vector<Record*> Recs = Records.getAllDerivedDefinitions("InstrClass");
73 for (unsigned i = 0, e = Recs.size(); i != e; ++i) {
74 std::string InstrClassName = Recs[i]->getName();
75 OS << "// Generate BMI instructions for " << InstrClassName << "\n\n";
76 OS << "void ISel::visit";
77 OS << Recs[i]->getValueAsString("FunctionName");
78 OS << "(" << Recs[i]->getValueAsString("InstructionName") << " &I)\n{" << "\n";
79 // for each supported InstrSubclass
80
81 OS << spacing() << "unsigned DestReg = getReg(I);\n";
82 OS << spacing() << "unsigned Op0Reg = getReg(I.getOperand(0));\n";
83 OS << spacing() << "unsigned Op1Reg = getReg(I.getOperand(1));\n";
84 OS << spacing() << "Value *Op0Val = I.getOperand(0);\n";
85 OS << spacing() << "Value *Op1Val = I.getOperand(1);\n";
86
87 OS << spacing() << "MachineBasicBlock::iterator IP = BB->end();\n";
88
89 OS << std::endl;
90
91 ListInit *SupportedSubclasses = Recs[i]->getValueAsListInit("Supports");
92
93 //OS << spacing() << InstrClassName << "Prep();" << "\n";
94 //FnDecs += "void ISel::" + InstrClassName + "Prep() {\n\n}\n\n";
95
96 std::vector<std::string> vi;
97
98 // generate subclasses nested switch statements
99 InstrSubclasses(OS, InstrClassName, InstrClassName, SupportedSubclasses, vi, 0);
100
101 //OS << spacing() << InstrClassName << "Post();\n";
102 //FnDecs += "void ISel::" + InstrClassName + "Post() {\n\n}\n\n";
103
104 OS << "}\n";
105 OS << "\n\n\n";
106
107 } // for each instrclass
108
109 // OS << "} //namespace\n";
110
111
112#if 0
113 // print out function stubs
114 OS << "\n\n\n//Functions\n\n" << FnDecs;
115
116 // print out getsubclass() definitions
117 std::vector<Record*> SubclassColRec = Records.getAllDerivedDefinitions("InstrSubclassCollection");
118 for (unsigned j=0, m=SubclassColRec.getSize(); j!=m; ++j) {
119 std::string SubclassName = SubclassColRec[j]->getName();
120 FnDecs += "unsigned ISel::get" + SubclassName + "() {\n\n";
121
122 ListInit* list = dynamic_cast<ListInit*>(SubclassColRec[j].getValueAsListInit("List"));
123
124 for (unsigned k=0; n=list.getSize(); k!=n; ++k) {
125
126 FnDecs += "}\n\n";
127 }
128#endif
129
130} //run
131
132
133
134// find instructions that match all the subclasses (only support for 1 now)
135Record* SimpleInstrSelEmitter::findInstruction(std::ostream &OS, std::string cl, std::vector<std::string>& vi) {
136 std::vector<Record*> Recs = Records.getAllDerivedDefinitions("TargInstrSet");
137
138 for (unsigned i = 0, e = Recs.size(); i != e; ++i) {
139 Record* thisClass = Recs[i]->getValueAsDef("Class");
140
141 if (thisClass->getName() == cl) {
142
143 // get the Subclasses this supports
144 ListInit* SubclassList = Recs[i]->getValueAsListInit("List");
145
146 bool Match = true;
147
148 if (SubclassList->getSize() != vi.size())
149 Match = false;
150
151 // match the instruction's supported subclasses with the subclasses we are looking for
152
153 for (unsigned j=0, f=SubclassList->getSize(); j!=f; ++j) {
154 DefInit* SubclassDef = dynamic_cast<DefInit*>(SubclassList->getElement(j));
155 Record* thisSubclass = SubclassDef->getDef();
156
157 std::string searchingFor = vi[j];
158
159 if (thisSubclass->getName() != searchingFor) {
160 Match = false;
161 }
162
163 } // for each subclass list
164
165 if (Match == true) { return Recs[i]; }
166
167 } //if instrclass matches
168
169 } // for all instructions
170
171 // if no instructions found, return NULL
172 return NULL;
173
174} //findInstruction
175
176
177
178Record* SimpleInstrSelEmitter::findRegister(std::ostream &OS, std::string regname) {
179 std::vector<Record*> Recs = Records.getAllDerivedDefinitions("Register");
180
181 for (unsigned i = 0, e = Recs.size(); i != e; ++i) {
182 Record* thisReg = Recs[i];
183
184 if (thisReg->getName() == regname) return Recs[i];
185 }
186
187 return NULL;
188
189}
190
191// handle "::" and "+" etc
192std::string SimpleInstrSelEmitter::formatRegister(std::ostream &OS, std::string regname) {
193 std::string Reg;
194 std::string suffix;
195
196 int x = std::strcspn(regname.c_str(),"+-");
197
198 // operate on text before "+" or "-", append it back at the end
199 Reg = regname.substr(0,x);
200 suffix = regname.substr(x,regname.length());
201
202 unsigned int y = std::strcspn(Reg.c_str(),":");
203
204 if (y == Reg.length()) { // does not contain "::"
205
206 Record* RegRec = findRegister(OS,Reg);
207
208 assert(RegRec && "Register not found!");
209
210 if (RegRec->getValueAsString("Namespace") != "Virtual") {
211 Reg = RegRec->getValueAsString("Namespace") + "::" + RegRec->getName();
212 } else {
213 Reg = RegRec->getName();
214 }
215 } // regular case
216
217 // append + or - at the end again (i.e. X86::EAX+1)
218 Reg = Reg + suffix;
219
220 return Reg;
221}
222
223
224// take information in the instruction class and generate the correct BMI call
225void SimpleInstrSelEmitter::generateBMIcall(std::ostream &OS, std::string MBB, std::string IP, std::string Opcode, int NumOperands, ListInit &instroperands, ListInit &operands) {
226
227 // find Destination Register
228 StringInit* DestRegStr = dynamic_cast<StringInit*>(operands.getElement(0));
229 std::string DestReg = formatRegister(OS,DestRegStr->getValue());
230
231 OS << "BuildMI(";
232 OS << MBB << ", ";
233 OS << IP << ", ";
234 OS << Opcode << ", ";
235 OS << NumOperands;
236
237 if (DestReg != "Pseudo") {
238 OS << ", " << DestReg << ")";
239 } else {
240 OS << ")";
241 }
242
243 // handle the .add stuff
244 for (unsigned i=0, e=instroperands.getSize(); i!=e; ++i) {
245 DefInit* OpDef = dynamic_cast<DefInit*>(instroperands.getElement(i));
246 StringInit* RegStr = dynamic_cast<StringInit*>(operands.getElement(i+1));
247
248 Record* Op = OpDef->getDef();
249
250 std::string opstr = Op->getValueAsString("Name");
251
252 std::string regname;
253
254 if (opstr == "Register") {
255 regname = formatRegister(OS,RegStr->getValue());
256 } else {
257 regname = RegStr->getValue();
258 }
259
260 OS << ".add" << opstr << "(" << regname << ")";
261 }
262
263 OS << ";\n";
264
265} //generateBMIcall
266
267
268 std::string SimpleInstrSelEmitter::spacing() {
269 return globalSpacing;
270 }
271
272 std::string SimpleInstrSelEmitter::addspacing() {
273 globalSpacing += " ";
274 return globalSpacing;
275 }
276
277 std::string SimpleInstrSelEmitter::remspacing() {
278 globalSpacing = globalSpacing.substr(0,globalSpacing.length()-2);
279 return globalSpacing;
280 }
281
282
283 // recursively print out the subclasses of an instruction
284 //
285 void SimpleInstrSelEmitter::InstrSubclasses(std::ostream &OS, std::string prefix, std::string InstrClassName, ListInit* SupportedSubclasses, std::vector<std::string>& vi, unsigned depth) {
286
287
288 if (depth >= SupportedSubclasses->getSize()) {
289 return;
290 }
291
292 // get the subclass collection
293
294 DefInit* InstrSubclassColl = dynamic_cast<DefInit*>(SupportedSubclasses->getElement(depth));
295
296 Record* InstrSubclassRec = InstrSubclassColl->getDef();
297
298 std::string SubclassName = InstrSubclassRec->getName();
299
300
301 if (InstrSubclassRec->getValueAsString("PreCode") != "") {
302 // OS << spacing() << prefix << "_" << Subclass->getName() << "_Prep();\n";
303 OS << spacing() << InstrSubclassRec->getValueAsString("PreCode") << "\n\n";
304 }
305
306
307 OS << spacing() << "// Looping through " << SubclassName << "\n";
308
309 OS << spacing() << "switch (" << SubclassName <<") {\n";
310 addspacing();
311
312 ListInit* SubclassList = InstrSubclassRec->getValueAsListInit("List");
313
314 for (unsigned k=0, g = SubclassList->getSize(); k!=g; ++k) {
315
316 DefInit* SubclassDef = dynamic_cast<DefInit*>(SubclassList->getElement(k));
317
318 Record* Subclass = SubclassDef->getDef();
319
320 OS << spacing() << "// " << prefix << "_" << Subclass->getName() << "\n";
321 OS << spacing() << "case " << Subclass->getName() << ":\n";
322 addspacing();
323 OS << spacing() << "{\n";
324
325
326 vi.push_back(Subclass->getName());
327
328 // go down hierarchy
329 InstrSubclasses(OS, prefix + "_" + Subclass->getName(), InstrClassName, SupportedSubclasses, vi, depth+1);
330
331 // find the record that matches this
332 Record *theInstructionSet = findInstruction(OS, InstrClassName, vi);
333
334 // only print out the assertion if this is a leaf
335 if ( (theInstructionSet == NULL) && (depth == (SupportedSubclasses->getSize() - 1)) ) {
336
337 OS << spacing() << "assert(0 && \"No instructions defined for " << InstrClassName << " instructions of subclasses " << prefix << "_" << Subclass->getName() << "!\");" << "\n";
338
339 } else if (theInstructionSet != NULL) {
340
341 if (theInstructionSet->getValueAsString("PreCode") != "") {
342 OS << spacing() << theInstructionSet->getValueAsString("PreCode") << "\n\n";
343 }
344
345 ListInit *theInstructions = theInstructionSet->getValueAsListInit("Instructions");
346
347 ListInit *registerlists = theInstructionSet->getValueAsListInit("Operands"); // not necessarily registers anymore, but the name will stay for now
348
349 for (unsigned l=0, h=theInstructions->getSize(); l!=h; ++l) {
350
351 DefInit *theInstructionDef = dynamic_cast<DefInit*>(theInstructions->getElement(l));
352 Record *theInstruction = theInstructionDef->getDef();
353
354 ListInit *operands = theInstruction->getValueAsListInit("Params");
355
356 OS << spacing();
357
358 ListInit* registers = dynamic_cast<ListInit*>(registerlists->getElement(l));
359
360 // handle virtual instructions here before going to generateBMIcall
361
362 if (theInstruction->getValueAsString("Namespace") == "Virtual") {
363
364 // create reg for different sizes
365 std::string Instr = theInstruction->getName();
366 StringInit* DestRegInit = dynamic_cast<StringInit*>(registers->getElement(0));
367 std::string DestReg = DestRegInit->getValue();
368 std::string theType;
369
370 if (Instr == "NullInstruction") { } // do nothing
371 else if (Instr == "CreateRegByte")
372 OS << "unsigned " << DestReg << " = makeAnotherReg(Type::SByteTy);\n";
373 else if (Instr == "CreateRegShort")
374 OS << "unsigned " << DestReg << " = makeAnotherReg(Type::SShortTy);\n";
375 else if (Instr == "CreateRegInt")
376 OS << "unsigned " << DestReg << " = makeAnotherReg(Type::SIntTy);\n";
377 else if (Instr == "CreateRegLong")
378 OS << "unsigned " << DestReg << " = makeAnotherReg(Type::SLongTy);\n";
379 else if (Instr == "CreateRegUByte")
380 OS << "unsigned " << DestReg << " = makeAnotherReg(Type::UByteTy);\n";
381 else if (Instr == "CreateRegUShort")
382 OS << "unsigned " << DestReg << " = makeAnotherReg(Type::UShortTy);\n";
383 else if (Instr == "CreateRegUInt")
384 OS << "unsigned " << DestReg << " = makeAnotherReg(Type::UIntTy);\n";
385 else if (Instr == "CreateRegULong")
386 OS << "unsigned " << DestReg << " = makeAnotherReg(Type::ULongTy);\n";
387 else if (Instr == "CreateRegFloat")
388 OS << "unsigned " << DestReg << " = makeAnotherReg(Type::FloatTy);\n";
389 else if (Instr == "CreateRegDouble")
390 OS << "unsigned " << DestReg << " = makeAnotherReg(Type::DoubleTy);\n";
391 else if (Instr == "CreateRegPointer")
392 OS << "unsigned " << DestReg << " = makeAnotherReg(Type::PointerTy_;\n";
393 else
394 OS << "unsigned " << DestReg << " = makeAnotherReg(Type::SByteTy);\n"; // create a byte by default
395
396
397 } else {
398 std::string InstrName;
399
400 if (theInstruction->getValueAsString("Namespace") != "Virtual") {
401 InstrName = theInstruction->getValueAsString("Namespace") + "::" + theInstruction->getValueAsString("Name");
402 } else {
403 // shouldn't ever happen, virtual instrs should be caught before this
404 InstrName = theInstruction->getValueAsString("Name");
405 }
406
407 generateBMIcall(OS, "*BB","IP",InstrName,theInstruction->getValueAsInt("NumOperands"),*operands,*registers);
408 }
409
410 }
411
412 if (theInstructionSet->getValueAsString("PostCode") != "") {
413 OS << spacing() << theInstructionSet->getValueAsString("PostCode") << "\n\n";
414 }
415
416 }
417
418
419
420 if (InstrSubclassRec->getValueAsString("PostCode") != "") {
421 //OS << spacing() << "// " << prefix << "_" << Subclass->getName() << "_Prep();\n";
422 OS << spacing() << InstrSubclassRec->getValueAsString("PostCode") << "\n\n";
423 }
424
425
426 OS << spacing() << "break;\n";
427
428 OS << spacing() << "}\n\n";
429
430 remspacing();
431
432 vi.pop_back();
433 }
434
435 // provide a default case for the switch
436
437 OS << spacing() << "default:\n";
438 OS << spacing() << " assert(0 && \"No instructions defined for " << InstrClassName << " instructions of subclasses " << prefix << "_" << SubclassName << "!\");" << "\n";
439 OS << spacing() << " break;\n\n";
440
441 remspacing();
442 OS << spacing() << "}\n";
443
444 }
445
446
447 // ret br switch invoke unwind
448 // add sub mul div rem setcc (eq ne lt gt le ge)
449 // and or xor sbl sbr
450 // malloc free alloca load store
451 // getelementptr phi cast call vanext vaarg
452
453} // End llvm namespace