X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FAsmWriterEmitter.cpp;h=6d2fa5578c9c7e99f40744ae7955d632e5e574ab;hb=249e1e4e2742977a4e3a5ba336b83168a4af43c0;hp=2ea74494f24a14600358d92f4a533825156d0cf3;hpb=2926869b4a083fc951484de03a9867eabf81e880;p=oota-llvm.git diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp index 2ea74494f24..6d2fa5578c9 100644 --- a/utils/TableGen/AsmWriterEmitter.cpp +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -19,7 +19,6 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" #include -#include using namespace llvm; static bool isIdentChar(char C) { @@ -29,7 +28,8 @@ static bool isIdentChar(char C) { C == '_'; } -namespace { +// This should be an anon namespace, this works around a GCC warning. +namespace llvm { struct AsmWriterOperand { enum { isLiteralTextOperand, isMachineInstrOperand } OperandType; @@ -45,7 +45,10 @@ namespace { /// an operand, specified with syntax like ${opname:modifier}. std::string MiModifier; - AsmWriterOperand(const std::string &LitStr) + // To make VS STL happy + AsmWriterOperand():OperandType(isLiteralTextOperand) {} + + explicit AsmWriterOperand(const std::string &LitStr) : OperandType(isLiteralTextOperand), Str(LitStr) {} AsmWriterOperand(const std::string &Printer, unsigned OpNo, @@ -69,7 +72,8 @@ namespace { } namespace llvm { - struct AsmWriterInst { + class AsmWriterInst { + public: std::vector Operands; const CodeGenInstruction *CGI; @@ -98,7 +102,9 @@ std::string AsmWriterOperand::getCode() const { if (OperandType == isLiteralTextOperand) return "O << \"" + Str + "\"; "; - std::string Result = Str + "(MI, " + utostr(MIOpNo); + std::string Result = Str + "(MI"; + if (MIOpNo != ~0U) + Result += ", " + utostr(MIOpNo); if (!MiModifier.empty()) Result += ", \"" + MiModifier + '"'; return Result + "); "; @@ -119,7 +125,7 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, unsigned Variant) { std::string::size_type LastEmitted = 0; while (LastEmitted != AsmString.size()) { std::string::size_type DollarPos = - AsmString.find_first_of("${|}", LastEmitted); + AsmString.find_first_of("${|}\\", LastEmitted); if (DollarPos == std::string::npos) DollarPos = AsmString.size(); // Emit a constant string fragment. @@ -129,6 +135,23 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, unsigned Variant) { AddLiteralString(std::string(AsmString.begin()+LastEmitted, AsmString.begin()+DollarPos)); LastEmitted = DollarPos; + } else if (AsmString[DollarPos] == '\\') { + if (DollarPos+1 != AsmString.size() && + (CurVariant == Variant || CurVariant == ~0U)) { + if (AsmString[DollarPos+1] == 'n') { + AddLiteralString("\\n"); + } else if (AsmString[DollarPos+1] == 't') { + AddLiteralString("\\t"); + } else if (std::string("${|}\\").find(AsmString[DollarPos+1]) + != std::string::npos) { + AddLiteralString(std::string(1, AsmString[DollarPos+1])); + } else { + throw "Non-supported escaped character found in instruction '" + + CGI.TheDef->getName() + "'!"; + } + LastEmitted = DollarPos+2; + continue; + } } else if (AsmString[DollarPos] == '{') { if (CurVariant != ~0U) throw "Nested variants found for instruction '" + @@ -172,7 +195,8 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, unsigned Variant) { AsmString.begin()+VarEnd); // Modifier - Support ${foo:modifier} syntax, where "modifier" is passed - // into printOperand. + // into printOperand. Also support ${:feature}, which is passed into + // PrintSpecial. std::string Modifier; // In order to avoid starting the next string at the terminating curly @@ -204,23 +228,24 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, unsigned Variant) { + CGI.TheDef->getName() + "'"; ++VarEnd; } - if (VarName.empty()) + if (VarName.empty() && Modifier.empty()) throw "Stray '$' in '" + CGI.TheDef->getName() + "' asm string, maybe you want $$?"; - unsigned OpNo = CGI.getOperandNamed(VarName); - CodeGenInstruction::OperandInfo OpInfo = CGI.OperandList[OpNo]; - - // If this is a two-address instruction, verify the second operand isn't - // used. - unsigned MIOp = OpInfo.MIOperandNo; - if (CGI.isTwoAddress && MIOp == 1) - throw "Should refer to operand #0 instead of #1 for two-address" - " instruction '" + CGI.TheDef->getName() + "'!"; - - if (CurVariant == Variant || CurVariant == ~0U) - Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName, MIOp, - Modifier)); + if (VarName.empty()) { + // Just a modifier, pass this into PrintSpecial. + Operands.push_back(AsmWriterOperand("PrintSpecial", ~0U, Modifier)); + } else { + // Otherwise, normal operand. + unsigned OpNo = CGI.getOperandNamed(VarName); + CodeGenInstruction::OperandInfo OpInfo = CGI.OperandList[OpNo]; + + if (CurVariant == Variant || CurVariant == ~0U) { + unsigned MIOp = OpInfo.MIOperandNo; + Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName, MIOp, + Modifier)); + } + } LastEmitted = VarEnd; } } @@ -237,11 +262,12 @@ unsigned AsmWriterInst::MatchesAllButOneOp(const AsmWriterInst &Other)const{ unsigned MismatchOperand = ~0U; for (unsigned i = 0, e = Operands.size(); i != e; ++i) { - if (Operands[i] != Other.Operands[i]) + if (Operands[i] != Other.Operands[i]) { if (MismatchOperand != ~0U) // Already have one mismatch? return ~1U; else MismatchOperand = i; + } } return MismatchOperand; } @@ -340,7 +366,7 @@ FindUniqueOperandCommands(std::vector &UniqueOperandCommands, for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { const AsmWriterInst *Inst = getAsmWriterInstByID(i); - if (Inst == 0) continue; // PHI, INLINEASM, etc. + if (Inst == 0) continue; // PHI, INLINEASM, DBG_LABEL, etc. std::string Command; if (Inst->Operands.empty()) @@ -475,9 +501,10 @@ void AsmWriterEmitter::run(std::ostream &O) { // Build an aggregate string, and build a table of offsets into it. std::map StringOffset; std::string AggregateString; - AggregateString += "\0\0"; + AggregateString.push_back(0); // "\0" + AggregateString.push_back(0); // "\0" - /// OpcodeInfo - Theis encodes the index of the string to use for the first + /// OpcodeInfo - This encodes the index of the string to use for the first /// chunk of the output as well as indices used for operand printing. std::vector OpcodeInfo; @@ -512,7 +539,7 @@ void AsmWriterEmitter::run(std::ostream &O) { } // Figure out how many bits we used for the string index. - unsigned AsmStrBits = Log2_32_Ceil(MaxStringIdx); + unsigned AsmStrBits = Log2_32_Ceil(MaxStringIdx+1); // To reduce code size, we compactify common instructions into a few bits // in the opcode-indexed table. @@ -545,8 +572,8 @@ void AsmWriterEmitter::run(std::ostream &O) { // If we don't have enough bits for this operand, don't include it. if (NumBits > BitsLeft) { - DEBUG(std::cerr << "Not enough bits to densely encode " << NumBits - << " more bits\n"); + DOUT << "Not enough bits to densely encode " << NumBits + << " more bits\n"; break; } @@ -613,11 +640,34 @@ void AsmWriterEmitter::run(std::ostream &O) { } O << "\";\n\n"; + O << " if (TAI->doesSupportDebugInformation()) {\n" + << " const MachineFunction *MF = MI->getParent()->getParent();\n" + << " static DebugLoc PrevDL = DebugLoc::getUnknownLoc();\n" + << " DebugLoc CurDL = MI->getDebugLoc();\n\n" + << " if (!CurDL.isUnknown() && PrevDL != CurDL) {\n" + << " DebugLocTuple DLT = MF->getDebugLocTuple(CurDL);\n" + << " printLabel(DW->RecordSourceLine(DLT.Line, DLT.Col, DLT.Src));\n" + << " }\n\n" + << " PrevDL = CurDL;\n" + << " }\n\n"; + O << " if (MI->getOpcode() == TargetInstrInfo::INLINEASM) {\n" + << " O << \"\\t\";\n" << " printInlineAsm(MI);\n" << " return true;\n" + << " } else if (MI->isLabel()) {\n" + << " printLabel(MI);\n" + << " return true;\n" + << " } else if (MI->getOpcode() == TargetInstrInfo::DECLARE) {\n" + << " printDeclare(MI);\n" + << " return true;\n" + << " } else if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) {\n" + << " printImplicitDef(MI);\n" + << " return true;\n" << " }\n\n"; + O << " O << \"\\t\";\n\n"; + O << " // Emit the opcode for the instruction.\n" << " unsigned Bits = OpInfo[MI->getOpcode()];\n" << " if (Bits == 0) return false;\n"