1cc041ba03aed685400197fb938b7a583713d25afChris Lattner//===-- InlineAsm.cpp - Implement the InlineAsm class ---------------------===// 2cc041ba03aed685400197fb938b7a583713d25afChris Lattner// 3cc041ba03aed685400197fb938b7a583713d25afChris Lattner// The LLVM Compiler Infrastructure 4cc041ba03aed685400197fb938b7a583713d25afChris Lattner// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7cc041ba03aed685400197fb938b7a583713d25afChris Lattner// 8cc041ba03aed685400197fb938b7a583713d25afChris Lattner//===----------------------------------------------------------------------===// 9cc041ba03aed685400197fb938b7a583713d25afChris Lattner// 10cc041ba03aed685400197fb938b7a583713d25afChris Lattner// This file implements the InlineAsm class. 11cc041ba03aed685400197fb938b7a583713d25afChris Lattner// 12cc041ba03aed685400197fb938b7a583713d25afChris Lattner//===----------------------------------------------------------------------===// 13cc041ba03aed685400197fb938b7a583713d25afChris Lattner 140b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/InlineAsm.h" 15bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin#include "ConstantsContext.h" 16bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin#include "LLVMContextImpl.h" 170b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h" 1809f0bd39b16eec73e067561c0c7546902ce97c30Jeff Cohen#include <algorithm> 193b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner#include <cctype> 20cc041ba03aed685400197fb938b7a583713d25afChris Lattnerusing namespace llvm; 21cc041ba03aed685400197fb938b7a583713d25afChris Lattner 22afba8fe662d65b25b4baf46bb26cc18e1f9cc0a5Gordon Henriksen// Implement the first virtual method in this class in this file so the 23afba8fe662d65b25b4baf46bb26cc18e1f9cc0a5Gordon Henriksen// InlineAsm vtable is emitted here. 24afba8fe662d65b25b4baf46bb26cc18e1f9cc0a5Gordon HenriksenInlineAsm::~InlineAsm() { 25afba8fe662d65b25b4baf46bb26cc18e1f9cc0a5Gordon Henriksen} 26afba8fe662d65b25b4baf46bb26cc18e1f9cc0a5Gordon Henriksen 27afba8fe662d65b25b4baf46bb26cc18e1f9cc0a5Gordon Henriksen 28db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris LattnerInlineAsm *InlineAsm::get(FunctionType *Ty, StringRef AsmString, 292928c83b010f7cfdb0f819199d806f6942a7d995Daniel Dunbar StringRef Constraints, bool hasSideEffects, 30581600bfc3060ee13afb278cd87e25da5b5f7db2Chad Rosier bool isAlignStack, AsmDialect asmDialect) { 3103fe8f6ab6977e0a07b17b84e9b33939d2f23025Chad Rosier InlineAsmKeyType Key(AsmString, Constraints, hasSideEffects, isAlignStack, 3203fe8f6ab6977e0a07b17b84e9b33939d2f23025Chad Rosier asmDialect); 33bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin LLVMContextImpl *pImpl = Ty->getContext().pImpl; 34bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin return pImpl->InlineAsms.getOrCreate(PointerType::getUnqual(Ty), Key); 3580cd11561892a639a2628d19815af0695b5dbcaaChris Lattner} 3680cd11561892a639a2628d19815af0695b5dbcaaChris Lattner 37db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris LattnerInlineAsm::InlineAsm(PointerType *Ty, const std::string &asmString, 38bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin const std::string &constraints, bool hasSideEffects, 39581600bfc3060ee13afb278cd87e25da5b5f7db2Chad Rosier bool isAlignStack, AsmDialect asmDialect) 40bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin : Value(Ty, Value::InlineAsmVal), 4103fe8f6ab6977e0a07b17b84e9b33939d2f23025Chad Rosier AsmString(asmString), Constraints(constraints), 4203fe8f6ab6977e0a07b17b84e9b33939d2f23025Chad Rosier HasSideEffects(hasSideEffects), IsAlignStack(isAlignStack), 43581600bfc3060ee13afb278cd87e25da5b5f7db2Chad Rosier Dialect(asmDialect) { 44cc041ba03aed685400197fb938b7a583713d25afChris Lattner 4580cd11561892a639a2628d19815af0695b5dbcaaChris Lattner // Do various checks on the constraint string and type. 46bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin assert(Verify(getFunctionType(), constraints) && 47bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin "Function type not legal for constraints!"); 48bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin} 49bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin 50bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskinvoid InlineAsm::destroyConstant() { 511afcace3a3a138b1b18e5c6270caa8dae2261ae2Chris Lattner getType()->getContext().pImpl->InlineAsms.remove(this); 52bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin delete this; 53cc041ba03aed685400197fb938b7a583713d25afChris Lattner} 54cc041ba03aed685400197fb938b7a583713d25afChris Lattner 55c1d414ad713406c67c19ff2a1db861046a51cea9Chris LattnerFunctionType *InlineAsm::getFunctionType() const { 56cc041ba03aed685400197fb938b7a583713d25afChris Lattner return cast<FunctionType>(getType()->getElementType()); 57cc041ba03aed685400197fb938b7a583713d25afChris Lattner} 58eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson 59eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson///Default constructor. 60eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn ThompsonInlineAsm::ConstraintInfo::ConstraintInfo() : 61eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson Type(isInput), isEarlyClobber(false), 62eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson MatchingInput(-1), isCommutative(false), 633ec73169a335cbdf1f836957e251f2f23a3b0b4cEric Christopher isIndirect(false), isMultipleAlternative(false), 643ec73169a335cbdf1f836957e251f2f23a3b0b4cEric Christopher currentAlternativeIndex(0) { 65eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson} 66eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson 67eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson/// Copy constructor. 68eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn ThompsonInlineAsm::ConstraintInfo::ConstraintInfo(const ConstraintInfo &other) : 69eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson Type(other.Type), isEarlyClobber(other.isEarlyClobber), 70eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson MatchingInput(other.MatchingInput), isCommutative(other.isCommutative), 71eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson isIndirect(other.isIndirect), Codes(other.Codes), 723ec73169a335cbdf1f836957e251f2f23a3b0b4cEric Christopher isMultipleAlternative(other.isMultipleAlternative), 73eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson multipleAlternatives(other.multipleAlternatives), 74eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson currentAlternativeIndex(other.currentAlternativeIndex) { 75eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson} 7680cd11561892a639a2628d19815af0695b5dbcaaChris Lattner 77a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner/// Parse - Analyze the specified string (e.g. "==&{eax}") and fill in the 78a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner/// fields in this structure. If the constraint string is not understood, 79a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner/// return true, otherwise return false. 802928c83b010f7cfdb0f819199d806f6942a7d995Daniel Dunbarbool InlineAsm::ConstraintInfo::Parse(StringRef Str, 8144ab89eb376af838d1123293a79975aede501464John Thompson InlineAsm::ConstraintInfoVector &ConstraintsSoFar) { 8292ccf70ad448eb02f9f273d2c70ae4708b3bd0f2Daniel Dunbar StringRef::iterator I = Str.begin(), E = Str.end(); 83eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson unsigned multipleAlternativeCount = Str.count('|') + 1; 84eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson unsigned multipleAlternativeIndex = 0; 8544ab89eb376af838d1123293a79975aede501464John Thompson ConstraintCodeVector *pCodes = &Codes; 863b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner 87a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Initialize 88eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson isMultipleAlternative = (multipleAlternativeCount > 1 ? true : false); 89eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson if (isMultipleAlternative) { 90eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson multipleAlternatives.resize(multipleAlternativeCount); 91eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson pCodes = &multipleAlternatives[0].Codes; 92eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson } 93a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Type = isInput; 94a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner isEarlyClobber = false; 956bdcda3d3e30003fb6cef1d4e2fd3a5d5b40d3fcChris Lattner MatchingInput = -1; 96fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner isCommutative = false; 9773d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner isIndirect = false; 98eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson currentAlternativeIndex = 0; 99a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 10073d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner // Parse prefixes. 101a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (*I == '~') { 102a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Type = isClobber; 103a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ++I; 104a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } else if (*I == '=') { 105a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ++I; 106a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Type = isOutput; 10773d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner } 10873d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner 10973d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner if (*I == '*') { 11073d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner isIndirect = true; 11173d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner ++I; 112a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 113a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 114a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (I == E) return true; // Just a prefix, like "==" or "~". 115a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 116a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Parse the modifiers. 117a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner bool DoneWithModifiers = false; 118a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner while (!DoneWithModifiers) { 119a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner switch (*I) { 120a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner default: 121a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner DoneWithModifiers = true; 122a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner break; 123fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner case '&': // Early clobber. 124a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (Type != isOutput || // Cannot early clobber anything but output. 125a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner isEarlyClobber) // Reject &&&&&& 126a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner return true; 127a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner isEarlyClobber = true; 128a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner break; 129fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner case '%': // Commutative. 130fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner if (Type == isClobber || // Cannot commute clobbers. 131fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner isCommutative) // Reject %%%%% 132fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner return true; 133fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner isCommutative = true; 134fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner break; 135fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner case '#': // Comment. 136fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner case '*': // Register preferencing. 137fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner return true; // Not supported. 138a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 139a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 140a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (!DoneWithModifiers) { 1413b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner ++I; 142a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (I == E) return true; // Just prefixes and modifiers! 143a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 144a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 145a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 146a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Parse the various constraints. 147a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner while (I != E) { 148a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (*I == '{') { // Physical register reference. 149a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Find the end of the register name. 15092ccf70ad448eb02f9f273d2c70ae4708b3bd0f2Daniel Dunbar StringRef::iterator ConstraintEnd = std::find(I+1, E, '}'); 151a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (ConstraintEnd == E) return true; // "{foo" 152eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson pCodes->push_back(std::string(I, ConstraintEnd+1)); 153a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner I = ConstraintEnd+1; 15487d0b9ed1462705dd9bf1cb7f67d0bf03af776c8Guy Benyei } else if (isdigit(static_cast<unsigned char>(*I))) { // Matching Constraint 155a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Maximal munch numbers. 15692ccf70ad448eb02f9f273d2c70ae4708b3bd0f2Daniel Dunbar StringRef::iterator NumStart = I; 15787d0b9ed1462705dd9bf1cb7f67d0bf03af776c8Guy Benyei while (I != E && isdigit(static_cast<unsigned char>(*I))) 1583b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner ++I; 159eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson pCodes->push_back(std::string(NumStart, I)); 160eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson unsigned N = atoi(pCodes->back().c_str()); 1612f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner // Check that this is a valid matching constraint! 1622f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner if (N >= ConstraintsSoFar.size() || ConstraintsSoFar[N].Type != isOutput|| 1632f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner Type != isInput) 1642f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner return true; // Invalid constraint number. 1652f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner 1666bdcda3d3e30003fb6cef1d4e2fd3a5d5b40d3fcChris Lattner // If Operand N already has a matching input, reject this. An output 1676bdcda3d3e30003fb6cef1d4e2fd3a5d5b40d3fcChris Lattner // can't be constrained to the same value as multiple inputs. 168eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson if (isMultipleAlternative) { 169eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson InlineAsm::SubConstraintInfo &scInfo = 170eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson ConstraintsSoFar[N].multipleAlternatives[multipleAlternativeIndex]; 171eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson if (scInfo.MatchingInput != -1) 172eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson return true; 173eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson // Note that operand #n has a matching input. 174eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson scInfo.MatchingInput = ConstraintsSoFar.size(); 175eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson } else { 176eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson if (ConstraintsSoFar[N].hasMatchingInput()) 177eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson return true; 178eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson // Note that operand #n has a matching input. 179eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson ConstraintsSoFar[N].MatchingInput = ConstraintsSoFar.size(); 180eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson } 181eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson } else if (*I == '|') { 182eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson multipleAlternativeIndex++; 183eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson pCodes = &multipleAlternatives[multipleAlternativeIndex].Codes; 184eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson ++I; 1855fab03d54cc1e624b9c9f32a66505aff388d99daEric Christopher } else if (*I == '^') { 1865fab03d54cc1e624b9c9f32a66505aff388d99daEric Christopher // Multi-letter constraint 187ec281c8934a8400ad0da100cd4afd8abcb913d09Eric Christopher // FIXME: For now assuming these are 2-character constraints. 188ec281c8934a8400ad0da100cd4afd8abcb913d09Eric Christopher pCodes->push_back(std::string(I+1, I+3)); 189ec281c8934a8400ad0da100cd4afd8abcb913d09Eric Christopher I += 3; 190a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } else { 191a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Single letter constraint. 192eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson pCodes->push_back(std::string(I, I+1)); 193a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ++I; 1943b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner } 195a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 196a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 197a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner return false; 198a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner} 199a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 200eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson/// selectAlternative - Point this constraint to the alternative constraint 201eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson/// indicated by the index. 202eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompsonvoid InlineAsm::ConstraintInfo::selectAlternative(unsigned index) { 203eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson if (index < multipleAlternatives.size()) { 204eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson currentAlternativeIndex = index; 205eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson InlineAsm::SubConstraintInfo &scInfo = 206eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson multipleAlternatives[currentAlternativeIndex]; 207eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson MatchingInput = scInfo.MatchingInput; 208eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson Codes = scInfo.Codes; 209eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson } 210eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson} 211eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson 21244ab89eb376af838d1123293a79975aede501464John ThompsonInlineAsm::ConstraintInfoVector 2132928c83b010f7cfdb0f819199d806f6942a7d995Daniel DunbarInlineAsm::ParseConstraints(StringRef Constraints) { 21444ab89eb376af838d1123293a79975aede501464John Thompson ConstraintInfoVector Result; 215a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 216a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Scan the constraints string. 21792ccf70ad448eb02f9f273d2c70ae4708b3bd0f2Daniel Dunbar for (StringRef::iterator I = Constraints.begin(), 21892ccf70ad448eb02f9f273d2c70ae4708b3bd0f2Daniel Dunbar E = Constraints.end(); I != E; ) { 219a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ConstraintInfo Info; 220a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 221a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Find the end of this constraint. 22292ccf70ad448eb02f9f273d2c70ae4708b3bd0f2Daniel Dunbar StringRef::iterator ConstraintEnd = std::find(I, E, ','); 223a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 224a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (ConstraintEnd == I || // Empty constraint like ",," 22582d5baec32054849e760625e2413a27edfd1a9fcBenjamin Kramer Info.Parse(StringRef(I, ConstraintEnd-I), Result)) { 2262f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner Result.clear(); // Erroneous constraint? 227f0b415f178615714de38fb8196f49d131e54274bChris Lattner break; 228f0b415f178615714de38fb8196f49d131e54274bChris Lattner } 229a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 230a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Result.push_back(Info); 2313b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner 232a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // ConstraintEnd may be either the next comma or the end of the string. In 233a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // the former case, we skip the comma. 234a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner I = ConstraintEnd; 235f0b415f178615714de38fb8196f49d131e54274bChris Lattner if (I != E) { 236f0b415f178615714de38fb8196f49d131e54274bChris Lattner ++I; 237f0b415f178615714de38fb8196f49d131e54274bChris Lattner if (I == E) { Result.clear(); break; } // don't allow "xyz," 238f0b415f178615714de38fb8196f49d131e54274bChris Lattner } 239f0b415f178615714de38fb8196f49d131e54274bChris Lattner } 240f0b415f178615714de38fb8196f49d131e54274bChris Lattner 241f0b415f178615714de38fb8196f49d131e54274bChris Lattner return Result; 242f0b415f178615714de38fb8196f49d131e54274bChris Lattner} 243f0b415f178615714de38fb8196f49d131e54274bChris Lattner 244f0b415f178615714de38fb8196f49d131e54274bChris Lattner/// Verify - Verify that the specified constraint string is reasonable for the 245f0b415f178615714de38fb8196f49d131e54274bChris Lattner/// specified function type, and otherwise validate the constraint string. 246db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool InlineAsm::Verify(FunctionType *Ty, StringRef ConstStr) { 247f0b415f178615714de38fb8196f49d131e54274bChris Lattner if (Ty->isVarArg()) return false; 248f0b415f178615714de38fb8196f49d131e54274bChris Lattner 24944ab89eb376af838d1123293a79975aede501464John Thompson ConstraintInfoVector Constraints = ParseConstraints(ConstStr); 250f0b415f178615714de38fb8196f49d131e54274bChris Lattner 251f0b415f178615714de38fb8196f49d131e54274bChris Lattner // Error parsing constraints. 252f0b415f178615714de38fb8196f49d131e54274bChris Lattner if (Constraints.empty() && !ConstStr.empty()) return false; 253f0b415f178615714de38fb8196f49d131e54274bChris Lattner 254f0b415f178615714de38fb8196f49d131e54274bChris Lattner unsigned NumOutputs = 0, NumInputs = 0, NumClobbers = 0; 255ea21ad49261a6a9d1614c01e631c2cdc4d554b84Chris Lattner unsigned NumIndirect = 0; 256f0b415f178615714de38fb8196f49d131e54274bChris Lattner 257f0b415f178615714de38fb8196f49d131e54274bChris Lattner for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { 258a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner switch (Constraints[i].Type) { 259a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner case InlineAsm::isOutput: 260ea21ad49261a6a9d1614c01e631c2cdc4d554b84Chris Lattner if ((NumInputs-NumIndirect) != 0 || NumClobbers != 0) 261ea21ad49261a6a9d1614c01e631c2cdc4d554b84Chris Lattner return false; // outputs before inputs and clobbers. 26273d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner if (!Constraints[i].isIndirect) { 263a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ++NumOutputs; 264a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner break; 265a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 266ea21ad49261a6a9d1614c01e631c2cdc4d554b84Chris Lattner ++NumIndirect; 26773d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner // FALLTHROUGH for Indirect Outputs. 268a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner case InlineAsm::isInput: 2693b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner if (NumClobbers) return false; // inputs before clobbers. 2703b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner ++NumInputs; 2713b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner break; 272a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner case InlineAsm::isClobber: 2733b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner ++NumClobbers; 2743b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner break; 2753b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner } 2763b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner } 2773b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner 27896bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner switch (NumOutputs) { 27996bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner case 0: 280f012705c7e4ca8cf90b6b734ce1d5355daca5ba5Benjamin Kramer if (!Ty->getReturnType()->isVoidTy()) return false; 28196bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner break; 28296bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner case 1: 2831df9859c40492511b8aa4321eb76496005d3b75bDuncan Sands if (Ty->getReturnType()->isStructTy()) return false; 28496bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner break; 28596bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner default: 286db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner StructType *STy = dyn_cast<StructType>(Ty->getReturnType()); 28796bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner if (STy == 0 || STy->getNumElements() != NumOutputs) 28896bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner return false; 28996bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner break; 29096bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner } 2913b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner 2923b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner if (Ty->getNumParams() != NumInputs) return false; 29380cd11561892a639a2628d19815af0695b5dbcaaChris Lattner return true; 29480cd11561892a639a2628d19815af0695b5dbcaaChris Lattner} 295af303d53e6013417d189621c75179df6c7cbdcdeReid Spencer 296