1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===- AsmWriterInst.h - Classes encapsulating a printable inst -----------===// 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The LLVM Compiler Infrastructure 4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details. 7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// These classes implement a parser for assembly strings. 11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "AsmWriterInst.h" 15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "CodeGenTarget.h" 16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/StringExtras.h" 1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/TableGen/Record.h" 18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm; 20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic bool isIdentChar(char C) { 22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return (C >= 'a' && C <= 'z') || 23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (C >= 'A' && C <= 'Z') || 24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (C >= '0' && C <= '9') || 25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman C == '_'; 26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstd::string AsmWriterOperand::getCode() const { 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (OperandType == isLiteralTextOperand) { 30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Str.size() == 1) 31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return "O << '" + Str + "'; "; 32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return "O << \"" + Str + "\"; "; 33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (OperandType == isLiteralStatementOperand) 36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Str; 37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::string Result = Str + "(MI"; 39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MIOpNo != ~0U) 40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result += ", " + utostr(MIOpNo); 41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result += ", O"; 42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!MiModifier.empty()) 43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result += ", \"" + MiModifier + '"'; 44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Result + "); "; 45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ParseAsmString - Parse the specified Instruction's AsmString into this 48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// AsmWriterInst. 49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanAsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, 51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Variant, 52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int FirstOperandColumn, 53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int OperandSpacing) { 54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman this->CGI = &CGI; 55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // This is the number of tabs we've seen if we're doing columnar layout. 57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned CurColumn = 0; 58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // NOTE: Any extensions to this code need to be mirrored in the 61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // AsmPrinter::printInlineAsm code that executes as compile time (assuming 62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // that inline asm strings should also get the new feature)! 6319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::string AsmString = CGI.FlattenAsmStringVariants(CGI.AsmString, Variant); 64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::string::size_type LastEmitted = 0; 65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman while (LastEmitted != AsmString.size()) { 66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::string::size_type DollarPos = 6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman AsmString.find_first_of("$\\", LastEmitted); 68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (DollarPos == std::string::npos) DollarPos = AsmString.size(); 69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Emit a constant string fragment. 71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (DollarPos != LastEmitted) { 7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (; LastEmitted != DollarPos; ++LastEmitted) 7319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch (AsmString[LastEmitted]) { 7419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case '\n': 7519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman AddLiteralString("\\n"); 7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 7719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case '\t': 7819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If the asm writer is not using a columnar layout, \t is not 7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // magic. 8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (FirstOperandColumn == -1 || OperandSpacing == -1) { 8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman AddLiteralString("\\t"); 8219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 8319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // We recognize a tab as an operand delimeter. 8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned DestColumn = FirstOperandColumn + 8519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CurColumn++ * OperandSpacing; 8619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Operands.push_back( 8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman AsmWriterOperand( 8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "O.PadToColumn(" + 8919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman utostr(DestColumn) + ");\n", 9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman AsmWriterOperand::isLiteralStatementOperand)); 9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case '"': 9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman AddLiteralString("\\\""); 9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case '\\': 9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman AddLiteralString("\\\\"); 9819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 9919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman default: 10019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman AddLiteralString(std::string(1, AsmString[LastEmitted])); 10119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 10219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (AsmString[DollarPos] == '\\') { 10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (DollarPos+1 != AsmString.size()) { 105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (AsmString[DollarPos+1] == 'n') { 106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AddLiteralString("\\n"); 107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (AsmString[DollarPos+1] == 't') { 108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the asm writer is not using a columnar layout, \t is not 109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // magic. 110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (FirstOperandColumn == -1 || OperandSpacing == -1) { 111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AddLiteralString("\\t"); 112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We recognize a tab as an operand delimeter. 116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned DestColumn = FirstOperandColumn + 117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurColumn++ * OperandSpacing; 118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Operands.push_back( 119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AsmWriterOperand("O.PadToColumn(" + utostr(DestColumn) + ");\n", 120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AsmWriterOperand::isLiteralStatementOperand)); 121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (std::string("${|}\\").find(AsmString[DollarPos+1]) 123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman != std::string::npos) { 124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AddLiteralString(std::string(1, AsmString[DollarPos+1])); 125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman throw "Non-supported escaped character found in instruction '" + 127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CGI.TheDef->getName() + "'!"; 128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LastEmitted = DollarPos+2; 130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (DollarPos+1 != AsmString.size() && 133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AsmString[DollarPos+1] == '$') { 13419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman AddLiteralString("$"); // "$$" -> $ 135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LastEmitted = DollarPos+2; 136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Get the name of the variable. 138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::string::size_type VarEnd = DollarPos+1; 139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // handle ${foo}bar as $foo by detecting whether the character following 141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the dollar sign is a curly brace. If so, advance VarEnd and DollarPos 142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // so the variable name does not contain the leading curly brace. 143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool hasCurlyBraces = false; 144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VarEnd < AsmString.size() && '{' == AsmString[VarEnd]) { 145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman hasCurlyBraces = true; 146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++DollarPos; 147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++VarEnd; 148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd])) 151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++VarEnd; 152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::string VarName(AsmString.begin()+DollarPos+1, 153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AsmString.begin()+VarEnd); 154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Modifier - Support ${foo:modifier} syntax, where "modifier" is passed 156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // into printOperand. Also support ${:feature}, which is passed into 157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // PrintSpecial. 158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::string Modifier; 159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // In order to avoid starting the next string at the terminating curly 161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // brace, advance the end position past it if we found an opening curly 162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // brace. 163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (hasCurlyBraces) { 164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VarEnd >= AsmString.size()) 165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman throw "Reached end of string before terminating curly brace in '" 166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman + CGI.TheDef->getName() + "'"; 167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Look for a modifier string. 169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (AsmString[VarEnd] == ':') { 170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++VarEnd; 171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VarEnd >= AsmString.size()) 172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman throw "Reached end of string before terminating curly brace in '" 173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman + CGI.TheDef->getName() + "'"; 174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned ModifierStart = VarEnd; 176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd])) 177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++VarEnd; 178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Modifier = std::string(AsmString.begin()+ModifierStart, 179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AsmString.begin()+VarEnd); 180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Modifier.empty()) 181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman throw "Bad operand modifier name in '"+ CGI.TheDef->getName() + "'"; 182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (AsmString[VarEnd] != '}') 185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman throw "Variable name beginning with '{' did not end with '}' in '" 186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman + CGI.TheDef->getName() + "'"; 187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++VarEnd; 188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VarName.empty() && Modifier.empty()) 190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman throw "Stray '$' in '" + CGI.TheDef->getName() + 191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "' asm string, maybe you want $$?"; 192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VarName.empty()) { 194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Just a modifier, pass this into PrintSpecial. 195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Operands.push_back(AsmWriterOperand("PrintSpecial", 196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ~0U, 197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ~0U, 198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Modifier)); 199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, normal operand. 20119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned OpNo = CGI.Operands.getOperandNamed(VarName); 20219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CGIOperandList::OperandInfo OpInfo = CGI.Operands[OpNo]; 203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 20419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned MIOp = OpInfo.MIOperandNo; 20519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName, 20619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman OpNo, MIOp, Modifier)); 207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LastEmitted = VarEnd; 209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Operands.push_back(AsmWriterOperand("return;", 213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AsmWriterOperand::isLiteralStatementOperand)); 214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// MatchesAllButOneOp - If this instruction is exactly identical to the 217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// specified instruction except for one differing operand, return the differing 218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// operand number. If more than one operand mismatches, return ~1, otherwise 219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// if the instructions are identical return ~0. 220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanunsigned AsmWriterInst::MatchesAllButOneOp(const AsmWriterInst &Other)const{ 221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Operands.size() != Other.Operands.size()) return ~1; 222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned MismatchOperand = ~0U; 224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = Operands.size(); i != e; ++i) { 225894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Operands[i] != Other.Operands[i]) { 226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MismatchOperand != ~0U) // Already have one mismatch? 227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ~1U; 228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MismatchOperand = i; 230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return MismatchOperand; 233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 234