1 //===- AsmWriterEmitter.cpp - Generate an 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 tablegen backend is emits an assembly printer for the current target.
11 // Note that this is currently fairly skeletal, but will grow over time.
13 //===----------------------------------------------------------------------===//
15 #include "AsmWriterEmitter.h"
16 #include "AsmWriterInst.h"
18 #include "CodeGenTarget.h"
20 #include "StringToOffsetTable.h"
21 #include "llvm/ADT/Twine.h"
22 #include "llvm/Support/Debug.h"
23 #include "llvm/Support/MathExtras.h"
27 static void PrintCases(std::vector
<std::pair
<std::string
,
28 AsmWriterOperand
> > &OpsToPrint
, raw_ostream
&O
) {
29 O
<< " case " << OpsToPrint
.back().first
<< ": ";
30 AsmWriterOperand TheOp
= OpsToPrint
.back().second
;
31 OpsToPrint
.pop_back();
33 // Check to see if any other operands are identical in this list, and if so,
34 // emit a case label for them.
35 for (unsigned i
= OpsToPrint
.size(); i
!= 0; --i
)
36 if (OpsToPrint
[i
-1].second
== TheOp
) {
37 O
<< "\n case " << OpsToPrint
[i
-1].first
<< ": ";
38 OpsToPrint
.erase(OpsToPrint
.begin()+i
-1);
41 // Finally, emit the code.
47 /// EmitInstructions - Emit the last instruction in the vector and any other
48 /// instructions that are suitably similar to it.
49 static void EmitInstructions(std::vector
<AsmWriterInst
> &Insts
,
51 AsmWriterInst FirstInst
= Insts
.back();
54 std::vector
<AsmWriterInst
> SimilarInsts
;
55 unsigned DifferingOperand
= ~0;
56 for (unsigned i
= Insts
.size(); i
!= 0; --i
) {
57 unsigned DiffOp
= Insts
[i
-1].MatchesAllButOneOp(FirstInst
);
59 if (DifferingOperand
== ~0U) // First match!
60 DifferingOperand
= DiffOp
;
62 // If this differs in the same operand as the rest of the instructions in
63 // this class, move it to the SimilarInsts list.
64 if (DifferingOperand
== DiffOp
|| DiffOp
== ~0U) {
65 SimilarInsts
.push_back(Insts
[i
-1]);
66 Insts
.erase(Insts
.begin()+i
-1);
71 O
<< " case " << FirstInst
.CGI
->Namespace
<< "::"
72 << FirstInst
.CGI
->TheDef
->getName() << ":\n";
73 for (unsigned i
= 0, e
= SimilarInsts
.size(); i
!= e
; ++i
)
74 O
<< " case " << SimilarInsts
[i
].CGI
->Namespace
<< "::"
75 << SimilarInsts
[i
].CGI
->TheDef
->getName() << ":\n";
76 for (unsigned i
= 0, e
= FirstInst
.Operands
.size(); i
!= e
; ++i
) {
77 if (i
!= DifferingOperand
) {
78 // If the operand is the same for all instructions, just print it.
79 O
<< " " << FirstInst
.Operands
[i
].getCode();
81 // If this is the operand that varies between all of the instructions,
82 // emit a switch for just this operand now.
83 O
<< " switch (MI->getOpcode()) {\n";
84 std::vector
<std::pair
<std::string
, AsmWriterOperand
> > OpsToPrint
;
85 OpsToPrint
.push_back(std::make_pair(FirstInst
.CGI
->Namespace
+ "::" +
86 FirstInst
.CGI
->TheDef
->getName(),
87 FirstInst
.Operands
[i
]));
89 for (unsigned si
= 0, e
= SimilarInsts
.size(); si
!= e
; ++si
) {
90 AsmWriterInst
&AWI
= SimilarInsts
[si
];
91 OpsToPrint
.push_back(std::make_pair(AWI
.CGI
->Namespace
+"::"+
92 AWI
.CGI
->TheDef
->getName(),
95 std::reverse(OpsToPrint
.begin(), OpsToPrint
.end());
96 while (!OpsToPrint
.empty())
97 PrintCases(OpsToPrint
, O
);
105 void AsmWriterEmitter::
106 FindUniqueOperandCommands(std::vector
<std::string
> &UniqueOperandCommands
,
107 std::vector
<unsigned> &InstIdxs
,
108 std::vector
<unsigned> &InstOpsUsed
) const {
109 InstIdxs
.assign(NumberedInstructions
.size(), ~0U);
111 // This vector parallels UniqueOperandCommands, keeping track of which
112 // instructions each case are used for. It is a comma separated string of
114 std::vector
<std::string
> InstrsForCase
;
115 InstrsForCase
.resize(UniqueOperandCommands
.size());
116 InstOpsUsed
.assign(UniqueOperandCommands
.size(), 0);
118 for (unsigned i
= 0, e
= NumberedInstructions
.size(); i
!= e
; ++i
) {
119 const AsmWriterInst
*Inst
= getAsmWriterInstByID(i
);
120 if (Inst
== 0) continue; // PHI, INLINEASM, PROLOG_LABEL, etc.
123 if (Inst
->Operands
.empty())
124 continue; // Instruction already done.
126 Command
= " " + Inst
->Operands
[0].getCode() + "\n";
128 // Check to see if we already have 'Command' in UniqueOperandCommands.
130 bool FoundIt
= false;
131 for (unsigned idx
= 0, e
= UniqueOperandCommands
.size(); idx
!= e
; ++idx
)
132 if (UniqueOperandCommands
[idx
] == Command
) {
134 InstrsForCase
[idx
] += ", ";
135 InstrsForCase
[idx
] += Inst
->CGI
->TheDef
->getName();
140 InstIdxs
[i
] = UniqueOperandCommands
.size();
141 UniqueOperandCommands
.push_back(Command
);
142 InstrsForCase
.push_back(Inst
->CGI
->TheDef
->getName());
144 // This command matches one operand so far.
145 InstOpsUsed
.push_back(1);
149 // For each entry of UniqueOperandCommands, there is a set of instructions
150 // that uses it. If the next command of all instructions in the set are
151 // identical, fold it into the command.
152 for (unsigned CommandIdx
= 0, e
= UniqueOperandCommands
.size();
153 CommandIdx
!= e
; ++CommandIdx
) {
155 for (unsigned Op
= 1; ; ++Op
) {
156 // Scan for the first instruction in the set.
157 std::vector
<unsigned>::iterator NIT
=
158 std::find(InstIdxs
.begin(), InstIdxs
.end(), CommandIdx
);
159 if (NIT
== InstIdxs
.end()) break; // No commonality.
161 // If this instruction has no more operands, we isn't anything to merge
162 // into this command.
163 const AsmWriterInst
*FirstInst
=
164 getAsmWriterInstByID(NIT
-InstIdxs
.begin());
165 if (!FirstInst
|| FirstInst
->Operands
.size() == Op
)
168 // Otherwise, scan to see if all of the other instructions in this command
169 // set share the operand.
171 // Keep track of the maximum, number of operands or any
172 // instruction we see in the group.
173 size_t MaxSize
= FirstInst
->Operands
.size();
175 for (NIT
= std::find(NIT
+1, InstIdxs
.end(), CommandIdx
);
176 NIT
!= InstIdxs
.end();
177 NIT
= std::find(NIT
+1, InstIdxs
.end(), CommandIdx
)) {
178 // Okay, found another instruction in this command set. If the operand
179 // matches, we're ok, otherwise bail out.
180 const AsmWriterInst
*OtherInst
=
181 getAsmWriterInstByID(NIT
-InstIdxs
.begin());
184 OtherInst
->Operands
.size() > FirstInst
->Operands
.size())
185 MaxSize
= std::max(MaxSize
, OtherInst
->Operands
.size());
187 if (!OtherInst
|| OtherInst
->Operands
.size() == Op
||
188 OtherInst
->Operands
[Op
] != FirstInst
->Operands
[Op
]) {
195 // Okay, everything in this command set has the same next operand. Add it
196 // to UniqueOperandCommands and remember that it was consumed.
197 std::string Command
= " " + FirstInst
->Operands
[Op
].getCode() + "\n";
199 UniqueOperandCommands
[CommandIdx
] += Command
;
200 InstOpsUsed
[CommandIdx
]++;
204 // Prepend some of the instructions each case is used for onto the case val.
205 for (unsigned i
= 0, e
= InstrsForCase
.size(); i
!= e
; ++i
) {
206 std::string Instrs
= InstrsForCase
[i
];
207 if (Instrs
.size() > 70) {
208 Instrs
.erase(Instrs
.begin()+70, Instrs
.end());
213 UniqueOperandCommands
[i
] = " // " + Instrs
+ "\n" +
214 UniqueOperandCommands
[i
];
219 static void UnescapeString(std::string
&Str
) {
220 for (unsigned i
= 0; i
!= Str
.size(); ++i
) {
221 if (Str
[i
] == '\\' && i
!= Str
.size()-1) {
223 default: continue; // Don't execute the code after the switch.
224 case 'a': Str
[i
] = '\a'; break;
225 case 'b': Str
[i
] = '\b'; break;
226 case 'e': Str
[i
] = 27; break;
227 case 'f': Str
[i
] = '\f'; break;
228 case 'n': Str
[i
] = '\n'; break;
229 case 'r': Str
[i
] = '\r'; break;
230 case 't': Str
[i
] = '\t'; break;
231 case 'v': Str
[i
] = '\v'; break;
232 case '"': Str
[i
] = '\"'; break;
233 case '\'': Str
[i
] = '\''; break;
234 case '\\': Str
[i
] = '\\'; break;
236 // Nuke the second character.
237 Str
.erase(Str
.begin()+i
+1);
242 /// EmitPrintInstruction - Generate the code for the "printInstruction" method
244 void AsmWriterEmitter::EmitPrintInstruction(raw_ostream
&O
) {
245 CodeGenTarget
Target(Records
);
246 Record
*AsmWriter
= Target
.getAsmWriter();
247 std::string ClassName
= AsmWriter
->getValueAsString("AsmWriterClassName");
248 bool isMC
= AsmWriter
->getValueAsBit("isMCAsmWriter");
249 const char *MachineInstrClassName
= isMC
? "MCInst" : "MachineInstr";
252 "/// printInstruction - This method is automatically generated by tablegen\n"
253 "/// from the instruction set description.\n"
254 "void " << Target
.getName() << ClassName
255 << "::printInstruction(const " << MachineInstrClassName
256 << " *MI, raw_ostream &O) {\n";
258 std::vector
<AsmWriterInst
> Instructions
;
260 for (CodeGenTarget::inst_iterator I
= Target
.inst_begin(),
261 E
= Target
.inst_end(); I
!= E
; ++I
)
262 if (!(*I
)->AsmString
.empty() &&
263 (*I
)->TheDef
->getName() != "PHI")
264 Instructions
.push_back(
266 AsmWriter
->getValueAsInt("Variant"),
267 AsmWriter
->getValueAsInt("FirstOperandColumn"),
268 AsmWriter
->getValueAsInt("OperandSpacing")));
270 // Get the instruction numbering.
271 NumberedInstructions
= Target
.getInstructionsByEnumValue();
273 // Compute the CodeGenInstruction -> AsmWriterInst mapping. Note that not
274 // all machine instructions are necessarily being printed, so there may be
275 // target instructions not in this map.
276 for (unsigned i
= 0, e
= Instructions
.size(); i
!= e
; ++i
)
277 CGIAWIMap
.insert(std::make_pair(Instructions
[i
].CGI
, &Instructions
[i
]));
279 // Build an aggregate string, and build a table of offsets into it.
280 StringToOffsetTable StringTable
;
282 /// OpcodeInfo - This encodes the index of the string to use for the first
283 /// chunk of the output as well as indices used for operand printing.
284 std::vector
<unsigned> OpcodeInfo
;
286 unsigned MaxStringIdx
= 0;
287 for (unsigned i
= 0, e
= NumberedInstructions
.size(); i
!= e
; ++i
) {
288 AsmWriterInst
*AWI
= CGIAWIMap
[NumberedInstructions
[i
]];
291 // Something not handled by the asmwriter printer.
293 } else if (AWI
->Operands
[0].OperandType
!=
294 AsmWriterOperand::isLiteralTextOperand
||
295 AWI
->Operands
[0].Str
.empty()) {
296 // Something handled by the asmwriter printer, but with no leading string.
297 Idx
= StringTable
.GetOrAddStringOffset("");
299 std::string Str
= AWI
->Operands
[0].Str
;
301 Idx
= StringTable
.GetOrAddStringOffset(Str
);
302 MaxStringIdx
= std::max(MaxStringIdx
, Idx
);
304 // Nuke the string from the operand list. It is now handled!
305 AWI
->Operands
.erase(AWI
->Operands
.begin());
308 // Bias offset by one since we want 0 as a sentinel.
309 OpcodeInfo
.push_back(Idx
+1);
312 // Figure out how many bits we used for the string index.
313 unsigned AsmStrBits
= Log2_32_Ceil(MaxStringIdx
+2);
315 // To reduce code size, we compactify common instructions into a few bits
316 // in the opcode-indexed table.
317 unsigned BitsLeft
= 32-AsmStrBits
;
319 std::vector
<std::vector
<std::string
> > TableDrivenOperandPrinters
;
322 std::vector
<std::string
> UniqueOperandCommands
;
323 std::vector
<unsigned> InstIdxs
;
324 std::vector
<unsigned> NumInstOpsHandled
;
325 FindUniqueOperandCommands(UniqueOperandCommands
, InstIdxs
,
328 // If we ran out of operands to print, we're done.
329 if (UniqueOperandCommands
.empty()) break;
331 // Compute the number of bits we need to represent these cases, this is
332 // ceil(log2(numentries)).
333 unsigned NumBits
= Log2_32_Ceil(UniqueOperandCommands
.size());
335 // If we don't have enough bits for this operand, don't include it.
336 if (NumBits
> BitsLeft
) {
337 DEBUG(errs() << "Not enough bits to densely encode " << NumBits
342 // Otherwise, we can include this in the initial lookup table. Add it in.
344 for (unsigned i
= 0, e
= InstIdxs
.size(); i
!= e
; ++i
)
345 if (InstIdxs
[i
] != ~0U)
346 OpcodeInfo
[i
] |= InstIdxs
[i
] << (BitsLeft
+AsmStrBits
);
348 // Remove the info about this operand.
349 for (unsigned i
= 0, e
= NumberedInstructions
.size(); i
!= e
; ++i
) {
350 if (AsmWriterInst
*Inst
= getAsmWriterInstByID(i
))
351 if (!Inst
->Operands
.empty()) {
352 unsigned NumOps
= NumInstOpsHandled
[InstIdxs
[i
]];
353 assert(NumOps
<= Inst
->Operands
.size() &&
354 "Can't remove this many ops!");
355 Inst
->Operands
.erase(Inst
->Operands
.begin(),
356 Inst
->Operands
.begin()+NumOps
);
360 // Remember the handlers for this set of operands.
361 TableDrivenOperandPrinters
.push_back(UniqueOperandCommands
);
366 O
<<" static const unsigned OpInfo[] = {\n";
367 for (unsigned i
= 0, e
= NumberedInstructions
.size(); i
!= e
; ++i
) {
368 O
<< " " << OpcodeInfo
[i
] << "U,\t// "
369 << NumberedInstructions
[i
]->TheDef
->getName() << "\n";
371 // Add a dummy entry so the array init doesn't end with a comma.
375 // Emit the string itself.
376 O
<< " const char *AsmStrs = \n";
377 StringTable
.EmitString(O
);
380 O
<< " O << \"\\t\";\n\n";
382 O
<< " // Emit the opcode for the instruction.\n"
383 << " unsigned Bits = OpInfo[MI->getOpcode()];\n"
384 << " assert(Bits != 0 && \"Cannot print this instruction.\");\n"
385 << " O << AsmStrs+(Bits & " << (1 << AsmStrBits
)-1 << ")-1;\n\n";
387 // Output the table driven operand information.
388 BitsLeft
= 32-AsmStrBits
;
389 for (unsigned i
= 0, e
= TableDrivenOperandPrinters
.size(); i
!= e
; ++i
) {
390 std::vector
<std::string
> &Commands
= TableDrivenOperandPrinters
[i
];
392 // Compute the number of bits we need to represent these cases, this is
393 // ceil(log2(numentries)).
394 unsigned NumBits
= Log2_32_Ceil(Commands
.size());
395 assert(NumBits
<= BitsLeft
&& "consistency error");
397 // Emit code to extract this field from Bits.
400 O
<< "\n // Fragment " << i
<< " encoded into " << NumBits
401 << " bits for " << Commands
.size() << " unique commands.\n";
403 if (Commands
.size() == 2) {
404 // Emit two possibilitys with if/else.
405 O
<< " if ((Bits >> " << (BitsLeft
+AsmStrBits
) << ") & "
406 << ((1 << NumBits
)-1) << ") {\n"
411 } else if (Commands
.size() == 1) {
412 // Emit a single possibility.
413 O
<< Commands
[0] << "\n\n";
415 O
<< " switch ((Bits >> " << (BitsLeft
+AsmStrBits
) << ") & "
416 << ((1 << NumBits
)-1) << ") {\n"
417 << " default: // unreachable.\n";
419 // Print out all the cases.
420 for (unsigned i
= 0, e
= Commands
.size(); i
!= e
; ++i
) {
421 O
<< " case " << i
<< ":\n";
429 // Okay, delete instructions with no operand info left.
430 for (unsigned i
= 0, e
= Instructions
.size(); i
!= e
; ++i
) {
431 // Entire instruction has been emitted?
432 AsmWriterInst
&Inst
= Instructions
[i
];
433 if (Inst
.Operands
.empty()) {
434 Instructions
.erase(Instructions
.begin()+i
);
440 // Because this is a vector, we want to emit from the end. Reverse all of the
441 // elements in the vector.
442 std::reverse(Instructions
.begin(), Instructions
.end());
445 // Now that we've emitted all of the operand info that fit into 32 bits, emit
446 // information for those instructions that are left. This is a less dense
447 // encoding, but we expect the main 32-bit table to handle the majority of
449 if (!Instructions
.empty()) {
450 // Find the opcode # of inline asm.
451 O
<< " switch (MI->getOpcode()) {\n";
452 while (!Instructions
.empty())
453 EmitInstructions(Instructions
, O
);
463 emitRegisterNameString(raw_ostream
&O
, StringRef AltName
,
464 const std::vector
<CodeGenRegister
*> &Registers
) {
465 StringToOffsetTable StringTable
;
466 O
<< " static const unsigned RegAsmOffset" << AltName
<< "[] = {\n ";
467 for (unsigned i
= 0, e
= Registers
.size(); i
!= e
; ++i
) {
468 const CodeGenRegister
&Reg
= *Registers
[i
];
471 // "NoRegAltName" is special. We don't need to do a lookup for that,
472 // as it's just a reference to the default register name.
473 if (AltName
== "" || AltName
== "NoRegAltName") {
474 AsmName
= Reg
.TheDef
->getValueAsString("AsmName");
476 AsmName
= Reg
.getName();
478 // Make sure the register has an alternate name for this index.
479 std::vector
<Record
*> AltNameList
=
480 Reg
.TheDef
->getValueAsListOfDefs("RegAltNameIndices");
482 for (e
= AltNameList
.size();
483 Idx
< e
&& (AltNameList
[Idx
]->getName() != AltName
);
486 // If the register has an alternate name for this index, use it.
487 // Otherwise, leave it empty as an error flag.
489 std::vector
<std::string
> AltNames
=
490 Reg
.TheDef
->getValueAsListOfStrings("AltNames");
491 if (AltNames
.size() <= Idx
)
492 throw TGError(Reg
.TheDef
->getLoc(),
493 (Twine("Register definition missing alt name for '") +
494 AltName
+ "'.").str());
495 AsmName
= AltNames
[Idx
];
499 O
<< StringTable
.GetOrAddStringOffset(AsmName
);
500 if (((i
+ 1) % 14) == 0)
510 O
<< " const char *AsmStrs" << AltName
<< " =\n";
511 StringTable
.EmitString(O
);
515 void AsmWriterEmitter::EmitGetRegisterName(raw_ostream
&O
) {
516 CodeGenTarget
Target(Records
);
517 Record
*AsmWriter
= Target
.getAsmWriter();
518 std::string ClassName
= AsmWriter
->getValueAsString("AsmWriterClassName");
519 const std::vector
<CodeGenRegister
*> &Registers
=
520 Target
.getRegBank().getRegisters();
521 std::vector
<Record
*> AltNameIndices
= Target
.getRegAltNameIndices();
522 bool hasAltNames
= AltNameIndices
.size() > 1;
525 "\n\n/// getRegisterName - This method is automatically generated by tblgen\n"
526 "/// from the register set description. This returns the assembler name\n"
527 "/// for the specified register.\n"
528 "const char *" << Target
.getName() << ClassName
<< "::";
530 O
<< "\ngetRegisterName(unsigned RegNo, unsigned AltIdx) {\n";
532 O
<< "getRegisterName(unsigned RegNo) {\n";
533 O
<< " assert(RegNo && RegNo < " << (Registers
.size()+1)
534 << " && \"Invalid register number!\");\n"
538 for (unsigned i
= 0, e
= AltNameIndices
.size(); i
< e
; ++i
)
539 emitRegisterNameString(O
, AltNameIndices
[i
]->getName(), Registers
);
541 emitRegisterNameString(O
, "", Registers
);
544 O
<< " const unsigned *RegAsmOffset;\n"
545 << " const char *AsmStrs;\n"
546 << " switch(AltIdx) {\n"
547 << " default: assert(0 && \"Invalid register alt name index!\");\n";
548 for (unsigned i
= 0, e
= AltNameIndices
.size(); i
< e
; ++i
) {
549 StringRef Namespace
= AltNameIndices
[1]->getValueAsString("Namespace");
550 StringRef
AltName(AltNameIndices
[i
]->getName());
551 O
<< " case " << Namespace
<< "::" << AltName
553 << " AsmStrs = AsmStrs" << AltName
<< ";\n"
554 << " RegAsmOffset = RegAsmOffset" << AltName
<< ";\n"
560 O
<< " assert (*(AsmStrs+RegAsmOffset[RegNo-1]) &&\n"
561 << " \"Invalid alt name index for register!\");\n"
562 << " return AsmStrs+RegAsmOffset[RegNo-1];\n"
566 void AsmWriterEmitter::EmitGetInstructionName(raw_ostream
&O
) {
567 CodeGenTarget
Target(Records
);
568 Record
*AsmWriter
= Target
.getAsmWriter();
569 std::string ClassName
= AsmWriter
->getValueAsString("AsmWriterClassName");
571 const std::vector
<const CodeGenInstruction
*> &NumberedInstructions
=
572 Target
.getInstructionsByEnumValue();
574 StringToOffsetTable StringTable
;
576 "\n\n#ifdef GET_INSTRUCTION_NAME\n"
577 "#undef GET_INSTRUCTION_NAME\n\n"
578 "/// getInstructionName: This method is automatically generated by tblgen\n"
579 "/// from the instruction set description. This returns the enum name of the\n"
580 "/// specified instruction.\n"
581 "const char *" << Target
.getName() << ClassName
582 << "::getInstructionName(unsigned Opcode) {\n"
583 << " assert(Opcode < " << NumberedInstructions
.size()
584 << " && \"Invalid instruction number!\");\n"
586 << " static const unsigned InstAsmOffset[] = {";
587 for (unsigned i
= 0, e
= NumberedInstructions
.size(); i
!= e
; ++i
) {
588 const CodeGenInstruction
&Inst
= *NumberedInstructions
[i
];
590 std::string AsmName
= Inst
.TheDef
->getName();
594 O
<< StringTable
.GetOrAddStringOffset(AsmName
) << ", ";
600 O
<< " const char *Strs =\n";
601 StringTable
.EmitString(O
);
604 O
<< " return Strs+InstAsmOffset[Opcode];\n"
609 // IAPrinter - Holds information about an InstAlias. Two InstAliases match if
610 // they both have the same conditionals. In which case, we cannot print out the
611 // alias for that pattern.
613 std::vector
<std::string
> Conds
;
614 std::map
<StringRef
, unsigned> OpMap
;
616 std::string AsmString
;
617 std::vector
<Record
*> ReqFeatures
;
619 IAPrinter(std::string R
, std::string AS
)
620 : Result(R
), AsmString(AS
) {}
622 void addCond(const std::string
&C
) { Conds
.push_back(C
); }
624 void addOperand(StringRef Op
, unsigned Idx
) { OpMap
[Op
] = Idx
; }
625 unsigned getOpIndex(StringRef Op
) { return OpMap
[Op
]; }
626 bool isOpMapped(StringRef Op
) { return OpMap
.find(Op
) != OpMap
.end(); }
628 void print(raw_ostream
&O
) {
629 if (Conds
.empty() && ReqFeatures
.empty()) {
630 O
.indent(6) << "return true;\n";
636 for (std::vector
<std::string
>::iterator
637 I
= Conds
.begin(), E
= Conds
.end(); I
!= E
; ++I
) {
638 if (I
!= Conds
.begin()) {
647 O
.indent(6) << "// " << Result
<< "\n";
648 O
.indent(6) << "AsmString = \"" << AsmString
<< "\";\n";
650 for (std::map
<StringRef
, unsigned>::iterator
651 I
= OpMap
.begin(), E
= OpMap
.end(); I
!= E
; ++I
)
652 O
.indent(6) << "OpMap.push_back(std::make_pair(\"" << I
->first
<< "\", "
653 << I
->second
<< "));\n";
655 O
.indent(6) << "break;\n";
659 bool operator==(const IAPrinter
&RHS
) {
660 if (Conds
.size() != RHS
.Conds
.size())
664 for (std::vector
<std::string
>::iterator
665 I
= Conds
.begin(), E
= Conds
.end(); I
!= E
; ++I
)
666 if (*I
!= RHS
.Conds
[Idx
++])
672 bool operator()(const IAPrinter
&RHS
) {
673 if (Conds
.size() < RHS
.Conds
.size())
677 for (std::vector
<std::string
>::iterator
678 I
= Conds
.begin(), E
= Conds
.end(); I
!= E
; ++I
)
679 if (*I
!= RHS
.Conds
[Idx
++])
680 return *I
< RHS
.Conds
[Idx
++];
686 } // end anonymous namespace
688 static void EmitGetMapOperandNumber(raw_ostream
&O
) {
689 O
<< "static unsigned getMapOperandNumber("
690 << "const SmallVectorImpl<std::pair<StringRef, unsigned> > &OpMap,\n";
691 O
<< " StringRef Name) {\n";
692 O
<< " for (SmallVectorImpl<std::pair<StringRef, unsigned> >::"
693 << "const_iterator\n";
694 O
<< " I = OpMap.begin(), E = OpMap.end(); I != E; ++I)\n";
695 O
<< " if (I->first == Name)\n";
696 O
<< " return I->second;\n";
697 O
<< " assert(false && \"Operand not in map!\");\n";
702 void AsmWriterEmitter::EmitRegIsInRegClass(raw_ostream
&O
) {
703 CodeGenTarget
Target(Records
);
705 // Enumerate the register classes.
706 const std::vector
<CodeGenRegisterClass
> &RegisterClasses
=
707 Target
.getRegisterClasses();
709 O
<< "namespace { // Register classes\n";
710 O
<< " enum RegClass {\n";
712 // Emit the register enum value for each RegisterClass.
713 for (unsigned I
= 0, E
= RegisterClasses
.size(); I
!= E
; ++I
) {
714 if (I
!= 0) O
<< ",\n";
715 O
<< " RC_" << RegisterClasses
[I
].TheDef
->getName();
719 O
<< "} // end anonymous namespace\n\n";
721 // Emit a function that returns 'true' if a regsiter is part of a particular
722 // register class. I.e., RAX is part of GR64 on X86.
723 O
<< "static bool regIsInRegisterClass"
724 << "(unsigned RegClass, unsigned Reg) {\n";
726 // Emit the switch that checks if a register belongs to a particular register
728 O
<< " switch (RegClass) {\n";
729 O
<< " default: break;\n";
731 for (unsigned I
= 0, E
= RegisterClasses
.size(); I
!= E
; ++I
) {
732 const CodeGenRegisterClass
&RC
= RegisterClasses
[I
];
734 // Give the register class a legal C name if it's anonymous.
735 std::string Name
= RC
.TheDef
->getName();
736 O
<< " case RC_" << Name
<< ":\n";
738 // Emit the register list now.
739 unsigned IE
= RC
.getOrder().size();
741 O
<< " if (Reg == " << getQualifiedName(RC
.getOrder()[0]) << ")\n";
742 O
<< " return true;\n";
744 O
<< " switch (Reg) {\n";
745 O
<< " default: break;\n";
747 for (unsigned II
= 0; II
!= IE
; ++II
) {
748 Record
*Reg
= RC
.getOrder()[II
];
749 O
<< " case " << getQualifiedName(Reg
) << ":\n";
752 O
<< " return true;\n";
760 O
<< " return false;\n";
764 static unsigned CountNumOperands(StringRef AsmString
) {
766 std::pair
<StringRef
, StringRef
> ASM
= AsmString
.split(' ');
768 while (!ASM
.second
.empty()) {
770 ASM
= ASM
.second
.split(' ');
776 static unsigned CountResultNumOperands(StringRef AsmString
) {
778 std::pair
<StringRef
, StringRef
> ASM
= AsmString
.split('\t');
780 if (!ASM
.second
.empty()) {
781 size_t I
= ASM
.second
.find('{');
782 StringRef Str
= ASM
.second
;
783 if (I
!= StringRef::npos
)
784 Str
= ASM
.second
.substr(I
, ASM
.second
.find('|', I
));
786 ASM
= Str
.split(' ');
790 ASM
= ASM
.second
.split(' ');
791 } while (!ASM
.second
.empty());
797 void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream
&O
) {
798 CodeGenTarget
Target(Records
);
799 Record
*AsmWriter
= Target
.getAsmWriter();
801 if (!AsmWriter
->getValueAsBit("isMCAsmWriter"))
804 O
<< "\n#ifdef PRINT_ALIAS_INSTR\n";
805 O
<< "#undef PRINT_ALIAS_INSTR\n\n";
807 EmitRegIsInRegClass(O
);
809 // Emit the method that prints the alias instruction.
810 std::string ClassName
= AsmWriter
->getValueAsString("AsmWriterClassName");
812 std::vector
<Record
*> AllInstAliases
=
813 Records
.getAllDerivedDefinitions("InstAlias");
815 // Create a map from the qualified name to a list of potential matches.
816 std::map
<std::string
, std::vector
<CodeGenInstAlias
*> > AliasMap
;
817 for (std::vector
<Record
*>::iterator
818 I
= AllInstAliases
.begin(), E
= AllInstAliases
.end(); I
!= E
; ++I
) {
819 CodeGenInstAlias
*Alias
= new CodeGenInstAlias(*I
, Target
);
820 const Record
*R
= *I
;
821 if (!R
->getValueAsBit("EmitAlias"))
822 continue; // We were told not to emit the alias, but to emit the aliasee.
823 const DagInit
*DI
= R
->getValueAsDag("ResultInst");
824 const DefInit
*Op
= dynamic_cast<const DefInit
*>(DI
->getOperator());
825 AliasMap
[getQualifiedName(Op
->getDef())].push_back(Alias
);
828 // A map of which conditions need to be met for each instruction operand
829 // before it can be matched to the mnemonic.
830 std::map
<std::string
, std::vector
<IAPrinter
*> > IAPrinterMap
;
832 for (std::map
<std::string
, std::vector
<CodeGenInstAlias
*> >::iterator
833 I
= AliasMap
.begin(), E
= AliasMap
.end(); I
!= E
; ++I
) {
834 std::vector
<CodeGenInstAlias
*> &Aliases
= I
->second
;
836 for (std::vector
<CodeGenInstAlias
*>::iterator
837 II
= Aliases
.begin(), IE
= Aliases
.end(); II
!= IE
; ++II
) {
838 const CodeGenInstAlias
*CGA
= *II
;
839 unsigned LastOpNo
= CGA
->ResultInstOperandIndex
.size();
840 unsigned NumResultOps
=
841 CountResultNumOperands(CGA
->ResultInst
->AsmString
);
843 // Don't emit the alias if it has more operands than what it's aliasing.
844 if (NumResultOps
< CountNumOperands(CGA
->AsmString
))
847 IAPrinter
*IAP
= new IAPrinter(CGA
->Result
->getAsString(),
851 Cond
= std::string("MI->getNumOperands() == ") + llvm::utostr(LastOpNo
);
854 std::map
<StringRef
, unsigned> OpMap
;
855 bool CantHandle
= false;
857 for (unsigned i
= 0, e
= LastOpNo
; i
!= e
; ++i
) {
858 const CodeGenInstAlias::ResultOperand
&RO
= CGA
->ResultOperands
[i
];
861 default: assert(0 && "unexpected InstAlias operand kind");
862 case CodeGenInstAlias::ResultOperand::K_Record
: {
863 const Record
*Rec
= RO
.getRecord();
864 StringRef ROName
= RO
.getName();
867 if (Rec
->isSubClassOf("RegisterOperand"))
868 Rec
= Rec
->getValueAsDef("RegClass");
869 if (Rec
->isSubClassOf("RegisterClass")) {
870 Cond
= std::string("MI->getOperand(")+llvm::utostr(i
)+").isReg()";
873 if (!IAP
->isOpMapped(ROName
)) {
874 IAP
->addOperand(ROName
, i
);
875 Cond
= std::string("regIsInRegisterClass(RC_") +
876 CGA
->ResultOperands
[i
].getRecord()->getName() +
877 ", MI->getOperand(" + llvm::utostr(i
) + ").getReg())";
880 Cond
= std::string("MI->getOperand(") +
881 llvm::utostr(i
) + ").getReg() == MI->getOperand(" +
882 llvm::utostr(IAP
->getOpIndex(ROName
)) + ").getReg()";
886 assert(Rec
->isSubClassOf("Operand") && "Unexpected operand!");
887 // FIXME: We may need to handle these situations.
896 case CodeGenInstAlias::ResultOperand::K_Imm
:
897 Cond
= std::string("MI->getOperand(") +
898 llvm::utostr(i
) + ").getImm() == " +
899 llvm::utostr(CGA
->ResultOperands
[i
].getImm());
902 case CodeGenInstAlias::ResultOperand::K_Reg
:
903 Cond
= std::string("MI->getOperand(") +
904 llvm::utostr(i
) + ").getReg() == " + Target
.getName() +
905 "::" + CGA
->ResultOperands
[i
].getRegister()->getName();
913 if (CantHandle
) continue;
914 IAPrinterMap
[I
->first
].push_back(IAP
);
919 raw_string_ostream
HeaderO(Header
);
921 HeaderO
<< "bool " << Target
.getName() << ClassName
922 << "::printAliasInstr(const MCInst"
923 << " *MI, raw_ostream &OS) {\n";
926 raw_string_ostream
CasesO(Cases
);
928 for (std::map
<std::string
, std::vector
<IAPrinter
*> >::iterator
929 I
= IAPrinterMap
.begin(), E
= IAPrinterMap
.end(); I
!= E
; ++I
) {
930 std::vector
<IAPrinter
*> &IAPs
= I
->second
;
931 std::vector
<IAPrinter
*> UniqueIAPs
;
933 for (std::vector
<IAPrinter
*>::iterator
934 II
= IAPs
.begin(), IE
= IAPs
.end(); II
!= IE
; ++II
) {
935 IAPrinter
*LHS
= *II
;
937 for (std::vector
<IAPrinter
*>::iterator
938 III
= IAPs
.begin(), IIE
= IAPs
.end(); III
!= IIE
; ++III
) {
939 IAPrinter
*RHS
= *III
;
940 if (LHS
!= RHS
&& *LHS
== *RHS
) {
946 if (!IsDup
) UniqueIAPs
.push_back(LHS
);
949 if (UniqueIAPs
.empty()) continue;
951 CasesO
.indent(2) << "case " << I
->first
<< ":\n";
953 for (std::vector
<IAPrinter
*>::iterator
954 II
= UniqueIAPs
.begin(), IE
= UniqueIAPs
.end(); II
!= IE
; ++II
) {
955 IAPrinter
*IAP
= *II
;
961 CasesO
.indent(4) << "return false;\n";
964 if (CasesO
.str().empty()) {
966 O
<< " return false;\n";
968 O
<< "#endif // PRINT_ALIAS_INSTR\n";
972 EmitGetMapOperandNumber(O
);
975 O
.indent(2) << "StringRef AsmString;\n";
976 O
.indent(2) << "SmallVector<std::pair<StringRef, unsigned>, 4> OpMap;\n";
977 O
.indent(2) << "switch (MI->getOpcode()) {\n";
978 O
.indent(2) << "default: return false;\n";
980 O
.indent(2) << "}\n\n";
982 // Code that prints the alias, replacing the operands with the ones from the
984 O
<< " std::pair<StringRef, StringRef> ASM = AsmString.split(' ');\n";
985 O
<< " OS << '\\t' << ASM.first;\n";
987 O
<< " if (!ASM.second.empty()) {\n";
988 O
<< " OS << '\\t';\n";
989 O
<< " for (StringRef::iterator\n";
990 O
<< " I = ASM.second.begin(), E = ASM.second.end(); I != E; ) {\n";
991 O
<< " if (*I == '$') {\n";
992 O
<< " StringRef::iterator Start = ++I;\n";
993 O
<< " while (I != E &&\n";
994 O
<< " ((*I >= 'a' && *I <= 'z') ||\n";
995 O
<< " (*I >= 'A' && *I <= 'Z') ||\n";
996 O
<< " (*I >= '0' && *I <= '9') ||\n";
997 O
<< " *I == '_'))\n";
999 O
<< " StringRef Name(Start, I - Start);\n";
1000 O
<< " printOperand(MI, getMapOperandNumber(OpMap, Name), OS);\n";
1002 O
<< " OS << *I++;\n";
1007 O
<< " return true;\n";
1010 O
<< "#endif // PRINT_ALIAS_INSTR\n";
1013 void AsmWriterEmitter::run(raw_ostream
&O
) {
1014 EmitSourceFileHeader("Assembly Writer Source Fragment", O
);
1016 EmitPrintInstruction(O
);
1017 EmitGetRegisterName(O
);
1018 EmitGetInstructionName(O
);
1019 EmitPrintAliasInstruction(O
);