InlineAsm.cpp revision 2f0eec6520f9c8bb5cf51251ae735846fc8f2522
1cc041ba03aed685400197fb938b7a583713d25afChris Lattner//===-- InlineAsm.cpp - Implement the InlineAsm class ---------------------===// 2cc041ba03aed685400197fb938b7a583713d25afChris Lattner// 3cc041ba03aed685400197fb938b7a583713d25afChris Lattner// The LLVM Compiler Infrastructure 4cc041ba03aed685400197fb938b7a583713d25afChris Lattner// 5cc041ba03aed685400197fb938b7a583713d25afChris Lattner// This file was developed by Chris Lattner and is distributed under the 6cc041ba03aed685400197fb938b7a583713d25afChris Lattner// University of Illinois Open Source 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" 15cc041ba03aed685400197fb938b7a583713d25afChris Lattner#include "llvm/DerivedTypes.h" 1609f0bd39b16eec73e067561c0c7546902ce97c30Jeff Cohen#include <algorithm> 173b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner#include <cctype> 18cc041ba03aed685400197fb938b7a583713d25afChris Lattnerusing namespace llvm; 19cc041ba03aed685400197fb938b7a583713d25afChris Lattner 2080cd11561892a639a2628d19815af0695b5dbcaaChris Lattner// NOTE: when memoizing the function type, we have to be careful to handle the 2180cd11561892a639a2628d19815af0695b5dbcaaChris Lattner// case when the type gets refined. 2280cd11561892a639a2628d19815af0695b5dbcaaChris Lattner 2380cd11561892a639a2628d19815af0695b5dbcaaChris LattnerInlineAsm *InlineAsm::get(const FunctionType *Ty, const std::string &AsmString, 2480cd11561892a639a2628d19815af0695b5dbcaaChris Lattner const std::string &Constraints, bool hasSideEffects) { 2580cd11561892a639a2628d19815af0695b5dbcaaChris Lattner // FIXME: memoize! 2680cd11561892a639a2628d19815af0695b5dbcaaChris Lattner return new InlineAsm(Ty, AsmString, Constraints, hasSideEffects); 2780cd11561892a639a2628d19815af0695b5dbcaaChris Lattner} 2880cd11561892a639a2628d19815af0695b5dbcaaChris Lattner 29cc041ba03aed685400197fb938b7a583713d25afChris LattnerInlineAsm::InlineAsm(const FunctionType *Ty, const std::string &asmString, 30863517aea0b06770c809396be985c1c4cc50d3c4Chris Lattner const std::string &constraints, bool hasSideEffects) 31863517aea0b06770c809396be985c1c4cc50d3c4Chris Lattner : Value(PointerType::get(Ty), Value::InlineAsmVal), AsmString(asmString), 32863517aea0b06770c809396be985c1c4cc50d3c4Chris Lattner Constraints(constraints), HasSideEffects(hasSideEffects) { 33cc041ba03aed685400197fb938b7a583713d25afChris Lattner 3480cd11561892a639a2628d19815af0695b5dbcaaChris Lattner // Do various checks on the constraint string and type. 3580cd11561892a639a2628d19815af0695b5dbcaaChris Lattner assert(Verify(Ty, constraints) && "Function type not legal for constraints!"); 36cc041ba03aed685400197fb938b7a583713d25afChris Lattner} 37cc041ba03aed685400197fb938b7a583713d25afChris Lattner 38cc041ba03aed685400197fb938b7a583713d25afChris Lattnerconst FunctionType *InlineAsm::getFunctionType() const { 39cc041ba03aed685400197fb938b7a583713d25afChris Lattner return cast<FunctionType>(getType()->getElementType()); 40cc041ba03aed685400197fb938b7a583713d25afChris Lattner} 4180cd11561892a639a2628d19815af0695b5dbcaaChris Lattner 42a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner/// Parse - Analyze the specified string (e.g. "==&{eax}") and fill in the 43a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner/// fields in this structure. If the constraint string is not understood, 44a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner/// return true, otherwise return false. 452f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattnerbool InlineAsm::ConstraintInfo::Parse(const std::string &Str, 462f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner std::vector<InlineAsm::ConstraintInfo> &ConstraintsSoFar) { 47a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner std::string::const_iterator I = Str.begin(), E = Str.end(); 483b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner 49a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Initialize 50a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Type = isInput; 51a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner isEarlyClobber = false; 522f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner isIndirectOutput = false; 532f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner hasMatchingInput = false; 54a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 55a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Parse the prefix. 56a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (*I == '~') { 57a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Type = isClobber; 58a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ++I; 59a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } else if (*I == '=') { 60a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ++I; 61a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Type = isOutput; 62a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (I != E && *I == '=') { 63a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner isIndirectOutput = true; 643b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner ++I; 65a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 66a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 67a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 68a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (I == E) return true; // Just a prefix, like "==" or "~". 69a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 70a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Parse the modifiers. 71a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner bool DoneWithModifiers = false; 72a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner while (!DoneWithModifiers) { 73a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner switch (*I) { 74a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner default: 75a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner DoneWithModifiers = true; 76a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner break; 77a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner case '&': 78a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (Type != isOutput || // Cannot early clobber anything but output. 79a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner isEarlyClobber) // Reject &&&&&& 80a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner return true; 81a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner isEarlyClobber = true; 82a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner break; 83a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 84a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 85a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (!DoneWithModifiers) { 863b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner ++I; 87a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (I == E) return true; // Just prefixes and modifiers! 88a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 89a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 90a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 91a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Parse the various constraints. 92a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner while (I != E) { 93a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (*I == '{') { // Physical register reference. 94a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Find the end of the register name. 95a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner std::string::const_iterator ConstraintEnd = std::find(I+1, E, '}'); 96a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (ConstraintEnd == E) return true; // "{foo" 97a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Codes.push_back(std::string(I, ConstraintEnd+1)); 98a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner I = ConstraintEnd+1; 992f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner } else if (isdigit(*I)) { // Matching Constraint 100a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Maximal munch numbers. 101a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner std::string::const_iterator NumStart = I; 102a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner while (I != E && isdigit(*I)) 1033b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner ++I; 104a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Codes.push_back(std::string(NumStart, I)); 1052f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner unsigned N = atoi(Codes.back().c_str()); 1062f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner // Check that this is a valid matching constraint! 1072f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner if (N >= ConstraintsSoFar.size() || ConstraintsSoFar[N].Type != isOutput|| 1082f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner Type != isInput) 1092f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner return true; // Invalid constraint number. 1102f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner 1112f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner // Note that operand #n has a matching input. 1122f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner ConstraintsSoFar[N].hasMatchingInput = true; 113a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } else { 114a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Single letter constraint. 115a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Codes.push_back(std::string(I, I+1)); 116a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ++I; 1173b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner } 118a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 119a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 120a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner return false; 121a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner} 122a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 123a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattnerstd::vector<InlineAsm::ConstraintInfo> 124a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris LattnerInlineAsm::ParseConstraints(const std::string &Constraints) { 125a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner std::vector<ConstraintInfo> Result; 126a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 127a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Scan the constraints string. 128a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner for (std::string::const_iterator I = Constraints.begin(), 129a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner E = Constraints.end(); I != E; ) { 130a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ConstraintInfo Info; 131a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 132a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Find the end of this constraint. 133a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner std::string::const_iterator ConstraintEnd = std::find(I, E, ','); 134a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 135a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (ConstraintEnd == I || // Empty constraint like ",," 1362f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner Info.Parse(std::string(I, ConstraintEnd), Result)) { 1372f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner Result.clear(); // Erroneous constraint? 138f0b415f178615714de38fb8196f49d131e54274bChris Lattner break; 139f0b415f178615714de38fb8196f49d131e54274bChris Lattner } 140a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 141a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Result.push_back(Info); 1423b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner 143a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // ConstraintEnd may be either the next comma or the end of the string. In 144a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // the former case, we skip the comma. 145a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner I = ConstraintEnd; 146f0b415f178615714de38fb8196f49d131e54274bChris Lattner if (I != E) { 147f0b415f178615714de38fb8196f49d131e54274bChris Lattner ++I; 148f0b415f178615714de38fb8196f49d131e54274bChris Lattner if (I == E) { Result.clear(); break; } // don't allow "xyz," 149f0b415f178615714de38fb8196f49d131e54274bChris Lattner } 150f0b415f178615714de38fb8196f49d131e54274bChris Lattner } 151f0b415f178615714de38fb8196f49d131e54274bChris Lattner 152f0b415f178615714de38fb8196f49d131e54274bChris Lattner return Result; 153f0b415f178615714de38fb8196f49d131e54274bChris Lattner} 154f0b415f178615714de38fb8196f49d131e54274bChris Lattner 155f0b415f178615714de38fb8196f49d131e54274bChris Lattner 156f0b415f178615714de38fb8196f49d131e54274bChris Lattner/// Verify - Verify that the specified constraint string is reasonable for the 157f0b415f178615714de38fb8196f49d131e54274bChris Lattner/// specified function type, and otherwise validate the constraint string. 158f0b415f178615714de38fb8196f49d131e54274bChris Lattnerbool InlineAsm::Verify(const FunctionType *Ty, const std::string &ConstStr) { 159f0b415f178615714de38fb8196f49d131e54274bChris Lattner if (Ty->isVarArg()) return false; 160f0b415f178615714de38fb8196f49d131e54274bChris Lattner 161a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner std::vector<ConstraintInfo> Constraints = ParseConstraints(ConstStr); 162f0b415f178615714de38fb8196f49d131e54274bChris Lattner 163f0b415f178615714de38fb8196f49d131e54274bChris Lattner // Error parsing constraints. 164f0b415f178615714de38fb8196f49d131e54274bChris Lattner if (Constraints.empty() && !ConstStr.empty()) return false; 165f0b415f178615714de38fb8196f49d131e54274bChris Lattner 166f0b415f178615714de38fb8196f49d131e54274bChris Lattner unsigned NumOutputs = 0, NumInputs = 0, NumClobbers = 0; 167f0b415f178615714de38fb8196f49d131e54274bChris Lattner 168f0b415f178615714de38fb8196f49d131e54274bChris Lattner for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { 169a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner switch (Constraints[i].Type) { 170a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner case InlineAsm::isOutput: 171a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (!Constraints[i].isIndirectOutput) { 172a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (NumInputs || NumClobbers) return false; // outputs come first. 173a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ++NumOutputs; 174a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner break; 175a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 176a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // FALLTHROUGH for IndirectOutputs. 177a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner case InlineAsm::isInput: 1783b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner if (NumClobbers) return false; // inputs before clobbers. 1793b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner ++NumInputs; 1803b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner break; 181a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner case InlineAsm::isClobber: 1823b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner ++NumClobbers; 1833b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner break; 1843b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner } 1853b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner } 186f0b415f178615714de38fb8196f49d131e54274bChris Lattner 187f0b415f178615714de38fb8196f49d131e54274bChris Lattner if (NumOutputs > 1) return false; // Only one result allowed so far. 1883b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner 1893b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner if ((Ty->getReturnType() != Type::VoidTy) != NumOutputs) 1903b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner return false; // NumOutputs = 1 iff has a result type. 1913b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner 1923b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner if (Ty->getNumParams() != NumInputs) return false; 19380cd11561892a639a2628d19815af0695b5dbcaaChris Lattner return true; 19480cd11561892a639a2628d19815af0695b5dbcaaChris Lattner} 195