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 14cc041ba03aed685400197fb938b7a583713d25afChris Lattner#include "llvm/InlineAsm.h" 15bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin#include "ConstantsContext.h" 16bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin#include "LLVMContextImpl.h" 17cc041ba03aed685400197fb938b7a583713d25afChris Lattner#include "llvm/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, 308ba2d5befc05ca73d3bac8708819bbbe759e2cf9Dale Johannesen bool isAlignStack) { 31bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin InlineAsmKeyType Key(AsmString, Constraints, hasSideEffects, isAlignStack); 32bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin LLVMContextImpl *pImpl = Ty->getContext().pImpl; 33bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin return pImpl->InlineAsms.getOrCreate(PointerType::getUnqual(Ty), Key); 3480cd11561892a639a2628d19815af0695b5dbcaaChris Lattner} 3580cd11561892a639a2628d19815af0695b5dbcaaChris Lattner 36db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris LattnerInlineAsm::InlineAsm(PointerType *Ty, const std::string &asmString, 37bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin const std::string &constraints, bool hasSideEffects, 388ba2d5befc05ca73d3bac8708819bbbe759e2cf9Dale Johannesen bool isAlignStack) 39bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin : Value(Ty, Value::InlineAsmVal), 4043ad6b3e0d6ada51e9b23aab3e061187f1f5710cChristopher Lamb AsmString(asmString), 418ba2d5befc05ca73d3bac8708819bbbe759e2cf9Dale Johannesen Constraints(constraints), HasSideEffects(hasSideEffects), 428ba2d5befc05ca73d3bac8708819bbbe759e2cf9Dale Johannesen IsAlignStack(isAlignStack) { 43cc041ba03aed685400197fb938b7a583713d25afChris Lattner 4480cd11561892a639a2628d19815af0695b5dbcaaChris Lattner // Do various checks on the constraint string and type. 45bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin assert(Verify(getFunctionType(), constraints) && 46bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin "Function type not legal for constraints!"); 47bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin} 48bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin 49bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskinvoid InlineAsm::destroyConstant() { 501afcace3a3a138b1b18e5c6270caa8dae2261ae2Chris Lattner getType()->getContext().pImpl->InlineAsms.remove(this); 51bf48a9b6db111fc14a8faef1adefbce5d807aaefJeffrey Yasskin delete this; 52cc041ba03aed685400197fb938b7a583713d25afChris Lattner} 53cc041ba03aed685400197fb938b7a583713d25afChris Lattner 54c1d414ad713406c67c19ff2a1db861046a51cea9Chris LattnerFunctionType *InlineAsm::getFunctionType() const { 55cc041ba03aed685400197fb938b7a583713d25afChris Lattner return cast<FunctionType>(getType()->getElementType()); 56cc041ba03aed685400197fb938b7a583713d25afChris Lattner} 57eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson 58eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson///Default constructor. 59eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn ThompsonInlineAsm::ConstraintInfo::ConstraintInfo() : 60eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson Type(isInput), isEarlyClobber(false), 61eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson MatchingInput(-1), isCommutative(false), 623ec73169a335cbdf1f836957e251f2f23a3b0b4cEric Christopher isIndirect(false), isMultipleAlternative(false), 633ec73169a335cbdf1f836957e251f2f23a3b0b4cEric Christopher currentAlternativeIndex(0) { 64eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson} 65eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson 66eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson/// Copy constructor. 67eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn ThompsonInlineAsm::ConstraintInfo::ConstraintInfo(const ConstraintInfo &other) : 68eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson Type(other.Type), isEarlyClobber(other.isEarlyClobber), 69eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson MatchingInput(other.MatchingInput), isCommutative(other.isCommutative), 70eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson isIndirect(other.isIndirect), Codes(other.Codes), 713ec73169a335cbdf1f836957e251f2f23a3b0b4cEric Christopher isMultipleAlternative(other.isMultipleAlternative), 72eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson multipleAlternatives(other.multipleAlternatives), 73eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson currentAlternativeIndex(other.currentAlternativeIndex) { 74eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson} 7580cd11561892a639a2628d19815af0695b5dbcaaChris Lattner 76a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner/// Parse - Analyze the specified string (e.g. "==&{eax}") and fill in the 77a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner/// fields in this structure. If the constraint string is not understood, 78a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner/// return true, otherwise return false. 792928c83b010f7cfdb0f819199d806f6942a7d995Daniel Dunbarbool InlineAsm::ConstraintInfo::Parse(StringRef Str, 8044ab89eb376af838d1123293a79975aede501464John Thompson InlineAsm::ConstraintInfoVector &ConstraintsSoFar) { 8192ccf70ad448eb02f9f273d2c70ae4708b3bd0f2Daniel Dunbar StringRef::iterator I = Str.begin(), E = Str.end(); 82eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson unsigned multipleAlternativeCount = Str.count('|') + 1; 83eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson unsigned multipleAlternativeIndex = 0; 8444ab89eb376af838d1123293a79975aede501464John Thompson ConstraintCodeVector *pCodes = &Codes; 853b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner 86a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Initialize 87eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson isMultipleAlternative = (multipleAlternativeCount > 1 ? true : false); 88eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson if (isMultipleAlternative) { 89eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson multipleAlternatives.resize(multipleAlternativeCount); 90eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson pCodes = &multipleAlternatives[0].Codes; 91eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson } 92a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Type = isInput; 93a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner isEarlyClobber = false; 946bdcda3d3e30003fb6cef1d4e2fd3a5d5b40d3fcChris Lattner MatchingInput = -1; 95fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner isCommutative = false; 9673d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner isIndirect = false; 97eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson currentAlternativeIndex = 0; 98a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 9973d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner // Parse prefixes. 100a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (*I == '~') { 101a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Type = isClobber; 102a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ++I; 103a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } else if (*I == '=') { 104a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ++I; 105a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Type = isOutput; 10673d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner } 10773d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner 10873d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner if (*I == '*') { 10973d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner isIndirect = true; 11073d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner ++I; 111a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 112a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 113a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (I == E) return true; // Just a prefix, like "==" or "~". 114a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 115a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Parse the modifiers. 116a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner bool DoneWithModifiers = false; 117a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner while (!DoneWithModifiers) { 118a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner switch (*I) { 119a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner default: 120a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner DoneWithModifiers = true; 121a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner break; 122fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner case '&': // Early clobber. 123a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (Type != isOutput || // Cannot early clobber anything but output. 124a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner isEarlyClobber) // Reject &&&&&& 125a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner return true; 126a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner isEarlyClobber = true; 127a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner break; 128fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner case '%': // Commutative. 129fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner if (Type == isClobber || // Cannot commute clobbers. 130fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner isCommutative) // Reject %%%%% 131fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner return true; 132fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner isCommutative = true; 133fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner break; 134fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner case '#': // Comment. 135fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner case '*': // Register preferencing. 136fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner return true; // Not supported. 137a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 138a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 139a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (!DoneWithModifiers) { 1403b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner ++I; 141a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (I == E) return true; // Just prefixes and modifiers! 142a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 143a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 144a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 145a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Parse the various constraints. 146a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner while (I != E) { 147a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (*I == '{') { // Physical register reference. 148a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Find the end of the register name. 14992ccf70ad448eb02f9f273d2c70ae4708b3bd0f2Daniel Dunbar StringRef::iterator ConstraintEnd = std::find(I+1, E, '}'); 150a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (ConstraintEnd == E) return true; // "{foo" 151eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson pCodes->push_back(std::string(I, ConstraintEnd+1)); 152a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner I = ConstraintEnd+1; 1532f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner } else if (isdigit(*I)) { // Matching Constraint 154a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Maximal munch numbers. 15592ccf70ad448eb02f9f273d2c70ae4708b3bd0f2Daniel Dunbar StringRef::iterator NumStart = I; 156a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner while (I != E && isdigit(*I)) 1573b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner ++I; 158eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson pCodes->push_back(std::string(NumStart, I)); 159eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson unsigned N = atoi(pCodes->back().c_str()); 1602f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner // Check that this is a valid matching constraint! 1612f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner if (N >= ConstraintsSoFar.size() || ConstraintsSoFar[N].Type != isOutput|| 1622f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner Type != isInput) 1632f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner return true; // Invalid constraint number. 1642f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner 1656bdcda3d3e30003fb6cef1d4e2fd3a5d5b40d3fcChris Lattner // If Operand N already has a matching input, reject this. An output 1666bdcda3d3e30003fb6cef1d4e2fd3a5d5b40d3fcChris Lattner // can't be constrained to the same value as multiple inputs. 167eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson if (isMultipleAlternative) { 168eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson InlineAsm::SubConstraintInfo &scInfo = 169eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson ConstraintsSoFar[N].multipleAlternatives[multipleAlternativeIndex]; 170eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson if (scInfo.MatchingInput != -1) 171eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson return true; 172eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson // Note that operand #n has a matching input. 173eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson scInfo.MatchingInput = ConstraintsSoFar.size(); 174eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson } else { 175eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson if (ConstraintsSoFar[N].hasMatchingInput()) 176eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson return true; 177eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson // Note that operand #n has a matching input. 178eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson ConstraintsSoFar[N].MatchingInput = ConstraintsSoFar.size(); 179eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson } 180eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson } else if (*I == '|') { 181eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson multipleAlternativeIndex++; 182eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson pCodes = &multipleAlternatives[multipleAlternativeIndex].Codes; 183eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson ++I; 1845fab03d54cc1e624b9c9f32a66505aff388d99daEric Christopher } else if (*I == '^') { 1855fab03d54cc1e624b9c9f32a66505aff388d99daEric Christopher // Multi-letter constraint 186ec281c8934a8400ad0da100cd4afd8abcb913d09Eric Christopher // FIXME: For now assuming these are 2-character constraints. 187ec281c8934a8400ad0da100cd4afd8abcb913d09Eric Christopher pCodes->push_back(std::string(I+1, I+3)); 188ec281c8934a8400ad0da100cd4afd8abcb913d09Eric Christopher I += 3; 189a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } else { 190a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Single letter constraint. 191eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson pCodes->push_back(std::string(I, I+1)); 192a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ++I; 1933b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner } 194a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 195a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 196a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner return false; 197a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner} 198a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 199eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson/// selectAlternative - Point this constraint to the alternative constraint 200eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson/// indicated by the index. 201eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompsonvoid InlineAsm::ConstraintInfo::selectAlternative(unsigned index) { 202eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson if (index < multipleAlternatives.size()) { 203eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson currentAlternativeIndex = index; 204eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson InlineAsm::SubConstraintInfo &scInfo = 205eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson multipleAlternatives[currentAlternativeIndex]; 206eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson MatchingInput = scInfo.MatchingInput; 207eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson Codes = scInfo.Codes; 208eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson } 209eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson} 210eac6e1d0c748afc3d1496be0753ffbe5f5a4279bJohn Thompson 21144ab89eb376af838d1123293a79975aede501464John ThompsonInlineAsm::ConstraintInfoVector 2122928c83b010f7cfdb0f819199d806f6942a7d995Daniel DunbarInlineAsm::ParseConstraints(StringRef Constraints) { 21344ab89eb376af838d1123293a79975aede501464John Thompson ConstraintInfoVector Result; 214a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 215a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Scan the constraints string. 21692ccf70ad448eb02f9f273d2c70ae4708b3bd0f2Daniel Dunbar for (StringRef::iterator I = Constraints.begin(), 21792ccf70ad448eb02f9f273d2c70ae4708b3bd0f2Daniel Dunbar E = Constraints.end(); I != E; ) { 218a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ConstraintInfo Info; 219a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 220a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Find the end of this constraint. 22192ccf70ad448eb02f9f273d2c70ae4708b3bd0f2Daniel Dunbar StringRef::iterator ConstraintEnd = std::find(I, E, ','); 222a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 223a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (ConstraintEnd == I || // Empty constraint like ",," 22482d5baec32054849e760625e2413a27edfd1a9fcBenjamin Kramer Info.Parse(StringRef(I, ConstraintEnd-I), Result)) { 2252f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner Result.clear(); // Erroneous constraint? 226f0b415f178615714de38fb8196f49d131e54274bChris Lattner break; 227f0b415f178615714de38fb8196f49d131e54274bChris Lattner } 228a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 229a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Result.push_back(Info); 2303b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner 231a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // ConstraintEnd may be either the next comma or the end of the string. In 232a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // the former case, we skip the comma. 233a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner I = ConstraintEnd; 234f0b415f178615714de38fb8196f49d131e54274bChris Lattner if (I != E) { 235f0b415f178615714de38fb8196f49d131e54274bChris Lattner ++I; 236f0b415f178615714de38fb8196f49d131e54274bChris Lattner if (I == E) { Result.clear(); break; } // don't allow "xyz," 237f0b415f178615714de38fb8196f49d131e54274bChris Lattner } 238f0b415f178615714de38fb8196f49d131e54274bChris Lattner } 239f0b415f178615714de38fb8196f49d131e54274bChris Lattner 240f0b415f178615714de38fb8196f49d131e54274bChris Lattner return Result; 241f0b415f178615714de38fb8196f49d131e54274bChris Lattner} 242f0b415f178615714de38fb8196f49d131e54274bChris Lattner 243f0b415f178615714de38fb8196f49d131e54274bChris Lattner/// Verify - Verify that the specified constraint string is reasonable for the 244f0b415f178615714de38fb8196f49d131e54274bChris Lattner/// specified function type, and otherwise validate the constraint string. 245db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool InlineAsm::Verify(FunctionType *Ty, StringRef ConstStr) { 246f0b415f178615714de38fb8196f49d131e54274bChris Lattner if (Ty->isVarArg()) return false; 247f0b415f178615714de38fb8196f49d131e54274bChris Lattner 24844ab89eb376af838d1123293a79975aede501464John Thompson ConstraintInfoVector Constraints = ParseConstraints(ConstStr); 249f0b415f178615714de38fb8196f49d131e54274bChris Lattner 250f0b415f178615714de38fb8196f49d131e54274bChris Lattner // Error parsing constraints. 251f0b415f178615714de38fb8196f49d131e54274bChris Lattner if (Constraints.empty() && !ConstStr.empty()) return false; 252f0b415f178615714de38fb8196f49d131e54274bChris Lattner 253f0b415f178615714de38fb8196f49d131e54274bChris Lattner unsigned NumOutputs = 0, NumInputs = 0, NumClobbers = 0; 254ea21ad49261a6a9d1614c01e631c2cdc4d554b84Chris Lattner unsigned NumIndirect = 0; 255f0b415f178615714de38fb8196f49d131e54274bChris Lattner 256f0b415f178615714de38fb8196f49d131e54274bChris Lattner for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { 257a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner switch (Constraints[i].Type) { 258a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner case InlineAsm::isOutput: 259ea21ad49261a6a9d1614c01e631c2cdc4d554b84Chris Lattner if ((NumInputs-NumIndirect) != 0 || NumClobbers != 0) 260ea21ad49261a6a9d1614c01e631c2cdc4d554b84Chris Lattner return false; // outputs before inputs and clobbers. 26173d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner if (!Constraints[i].isIndirect) { 262a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ++NumOutputs; 263a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner break; 264a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 265ea21ad49261a6a9d1614c01e631c2cdc4d554b84Chris Lattner ++NumIndirect; 26673d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner // FALLTHROUGH for Indirect Outputs. 267a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner case InlineAsm::isInput: 2683b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner if (NumClobbers) return false; // inputs before clobbers. 2693b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner ++NumInputs; 2703b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner break; 271a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner case InlineAsm::isClobber: 2723b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner ++NumClobbers; 2733b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner break; 2743b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner } 2753b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner } 2763b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner 27796bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner switch (NumOutputs) { 27896bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner case 0: 279f012705c7e4ca8cf90b6b734ce1d5355daca5ba5Benjamin Kramer if (!Ty->getReturnType()->isVoidTy()) return false; 28096bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner break; 28196bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner case 1: 2821df9859c40492511b8aa4321eb76496005d3b75bDuncan Sands if (Ty->getReturnType()->isStructTy()) return false; 28396bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner break; 28496bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner default: 285db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner StructType *STy = dyn_cast<StructType>(Ty->getReturnType()); 28696bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner if (STy == 0 || STy->getNumElements() != NumOutputs) 28796bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner return false; 28896bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner break; 28996bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner } 2903b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner 2913b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner if (Ty->getNumParams() != NumInputs) return false; 29280cd11561892a639a2628d19815af0695b5dbcaaChris Lattner return true; 29380cd11561892a639a2628d19815af0695b5dbcaaChris Lattner} 294af303d53e6013417d189621c75179df6c7cbdcdeReid Spencer 295