InlineAsm.cpp revision 1df9859c40492511b8aa4321eb76496005d3b75b
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" 15cc041ba03aed685400197fb938b7a583713d25afChris Lattner#include "llvm/DerivedTypes.h" 1609f0bd39b16eec73e067561c0c7546902ce97c30Jeff Cohen#include <algorithm> 173b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner#include <cctype> 18cc041ba03aed685400197fb938b7a583713d25afChris Lattnerusing namespace llvm; 19cc041ba03aed685400197fb938b7a583713d25afChris Lattner 20afba8fe662d65b25b4baf46bb26cc18e1f9cc0a5Gordon Henriksen// Implement the first virtual method in this class in this file so the 21afba8fe662d65b25b4baf46bb26cc18e1f9cc0a5Gordon Henriksen// InlineAsm vtable is emitted here. 22afba8fe662d65b25b4baf46bb26cc18e1f9cc0a5Gordon HenriksenInlineAsm::~InlineAsm() { 23afba8fe662d65b25b4baf46bb26cc18e1f9cc0a5Gordon Henriksen} 24afba8fe662d65b25b4baf46bb26cc18e1f9cc0a5Gordon Henriksen 25afba8fe662d65b25b4baf46bb26cc18e1f9cc0a5Gordon Henriksen 2680cd11561892a639a2628d19815af0695b5dbcaaChris Lattner// NOTE: when memoizing the function type, we have to be careful to handle the 2780cd11561892a639a2628d19815af0695b5dbcaaChris Lattner// case when the type gets refined. 2880cd11561892a639a2628d19815af0695b5dbcaaChris Lattner 292928c83b010f7cfdb0f819199d806f6942a7d995Daniel DunbarInlineAsm *InlineAsm::get(const FunctionType *Ty, StringRef AsmString, 302928c83b010f7cfdb0f819199d806f6942a7d995Daniel Dunbar StringRef Constraints, bool hasSideEffects, 318ba2d5befc05ca73d3bac8708819bbbe759e2cf9Dale Johannesen bool isAlignStack) { 3280cd11561892a639a2628d19815af0695b5dbcaaChris Lattner // FIXME: memoize! 338ba2d5befc05ca73d3bac8708819bbbe759e2cf9Dale Johannesen return new InlineAsm(Ty, AsmString, Constraints, hasSideEffects, 348ba2d5befc05ca73d3bac8708819bbbe759e2cf9Dale Johannesen isAlignStack); 3580cd11561892a639a2628d19815af0695b5dbcaaChris Lattner} 3680cd11561892a639a2628d19815af0695b5dbcaaChris Lattner 372928c83b010f7cfdb0f819199d806f6942a7d995Daniel DunbarInlineAsm::InlineAsm(const FunctionType *Ty, StringRef asmString, 382928c83b010f7cfdb0f819199d806f6942a7d995Daniel Dunbar StringRef constraints, bool hasSideEffects, 398ba2d5befc05ca73d3bac8708819bbbe759e2cf9Dale Johannesen bool isAlignStack) 4043ad6b3e0d6ada51e9b23aab3e061187f1f5710cChristopher Lamb : Value(PointerType::getUnqual(Ty), 4143ad6b3e0d6ada51e9b23aab3e061187f1f5710cChristopher Lamb Value::InlineAsmVal), 4243ad6b3e0d6ada51e9b23aab3e061187f1f5710cChristopher Lamb AsmString(asmString), 438ba2d5befc05ca73d3bac8708819bbbe759e2cf9Dale Johannesen Constraints(constraints), HasSideEffects(hasSideEffects), 448ba2d5befc05ca73d3bac8708819bbbe759e2cf9Dale Johannesen IsAlignStack(isAlignStack) { 45cc041ba03aed685400197fb938b7a583713d25afChris Lattner 4680cd11561892a639a2628d19815af0695b5dbcaaChris Lattner // Do various checks on the constraint string and type. 4780cd11561892a639a2628d19815af0695b5dbcaaChris Lattner assert(Verify(Ty, constraints) && "Function type not legal for constraints!"); 48cc041ba03aed685400197fb938b7a583713d25afChris Lattner} 49cc041ba03aed685400197fb938b7a583713d25afChris Lattner 50cc041ba03aed685400197fb938b7a583713d25afChris Lattnerconst FunctionType *InlineAsm::getFunctionType() const { 51cc041ba03aed685400197fb938b7a583713d25afChris Lattner return cast<FunctionType>(getType()->getElementType()); 52cc041ba03aed685400197fb938b7a583713d25afChris Lattner} 5380cd11561892a639a2628d19815af0695b5dbcaaChris Lattner 54a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner/// Parse - Analyze the specified string (e.g. "==&{eax}") and fill in the 55a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner/// fields in this structure. If the constraint string is not understood, 56a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner/// return true, otherwise return false. 572928c83b010f7cfdb0f819199d806f6942a7d995Daniel Dunbarbool InlineAsm::ConstraintInfo::Parse(StringRef Str, 582f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner std::vector<InlineAsm::ConstraintInfo> &ConstraintsSoFar) { 5992ccf70ad448eb02f9f273d2c70ae4708b3bd0f2Daniel Dunbar StringRef::iterator I = Str.begin(), E = Str.end(); 603b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner 61a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Initialize 62a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Type = isInput; 63a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner isEarlyClobber = false; 646bdcda3d3e30003fb6cef1d4e2fd3a5d5b40d3fcChris Lattner MatchingInput = -1; 65fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner isCommutative = false; 6673d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner isIndirect = false; 67a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 6873d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner // Parse prefixes. 69a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (*I == '~') { 70a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Type = isClobber; 71a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ++I; 72a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } else if (*I == '=') { 73a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ++I; 74a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Type = isOutput; 7573d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner } 7673d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner 7773d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner if (*I == '*') { 7873d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner isIndirect = true; 7973d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner ++I; 80a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 81a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 82a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (I == E) return true; // Just a prefix, like "==" or "~". 83a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 84a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Parse the modifiers. 85a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner bool DoneWithModifiers = false; 86a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner while (!DoneWithModifiers) { 87a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner switch (*I) { 88a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner default: 89a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner DoneWithModifiers = true; 90a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner break; 91fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner case '&': // Early clobber. 92a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (Type != isOutput || // Cannot early clobber anything but output. 93a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner isEarlyClobber) // Reject &&&&&& 94a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner return true; 95a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner isEarlyClobber = true; 96a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner break; 97fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner case '%': // Commutative. 98fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner if (Type == isClobber || // Cannot commute clobbers. 99fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner isCommutative) // Reject %%%%% 100fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner return true; 101fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner isCommutative = true; 102fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner break; 103fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner case '#': // Comment. 104fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner case '*': // Register preferencing. 105fe3db46fe073ecaf0e1dc4b5be899e335f4e83a8Chris Lattner return true; // Not supported. 106a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 107a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 108a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (!DoneWithModifiers) { 1093b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner ++I; 110a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (I == E) return true; // Just prefixes and modifiers! 111a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 112a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 113a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 114a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Parse the various constraints. 115a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner while (I != E) { 116a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (*I == '{') { // Physical register reference. 117a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Find the end of the register name. 11892ccf70ad448eb02f9f273d2c70ae4708b3bd0f2Daniel Dunbar StringRef::iterator ConstraintEnd = std::find(I+1, E, '}'); 119a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (ConstraintEnd == E) return true; // "{foo" 120a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Codes.push_back(std::string(I, ConstraintEnd+1)); 121a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner I = ConstraintEnd+1; 1222f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner } else if (isdigit(*I)) { // Matching Constraint 123a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Maximal munch numbers. 12492ccf70ad448eb02f9f273d2c70ae4708b3bd0f2Daniel Dunbar StringRef::iterator NumStart = I; 125a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner while (I != E && isdigit(*I)) 1263b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner ++I; 127a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Codes.push_back(std::string(NumStart, I)); 1282f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner unsigned N = atoi(Codes.back().c_str()); 1292f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner // Check that this is a valid matching constraint! 1302f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner if (N >= ConstraintsSoFar.size() || ConstraintsSoFar[N].Type != isOutput|| 1312f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner Type != isInput) 1322f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner return true; // Invalid constraint number. 1332f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner 1346bdcda3d3e30003fb6cef1d4e2fd3a5d5b40d3fcChris Lattner // If Operand N already has a matching input, reject this. An output 1356bdcda3d3e30003fb6cef1d4e2fd3a5d5b40d3fcChris Lattner // can't be constrained to the same value as multiple inputs. 1366bdcda3d3e30003fb6cef1d4e2fd3a5d5b40d3fcChris Lattner if (ConstraintsSoFar[N].hasMatchingInput()) 1376bdcda3d3e30003fb6cef1d4e2fd3a5d5b40d3fcChris Lattner return true; 1386bdcda3d3e30003fb6cef1d4e2fd3a5d5b40d3fcChris Lattner 1392f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner // Note that operand #n has a matching input. 1406bdcda3d3e30003fb6cef1d4e2fd3a5d5b40d3fcChris Lattner ConstraintsSoFar[N].MatchingInput = ConstraintsSoFar.size(); 141a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } else { 142a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Single letter constraint. 143a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Codes.push_back(std::string(I, I+1)); 144a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ++I; 1453b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner } 146a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 147a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 148a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner return false; 149a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner} 150a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 151a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattnerstd::vector<InlineAsm::ConstraintInfo> 1522928c83b010f7cfdb0f819199d806f6942a7d995Daniel DunbarInlineAsm::ParseConstraints(StringRef Constraints) { 153a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner std::vector<ConstraintInfo> Result; 154a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 155a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Scan the constraints string. 15692ccf70ad448eb02f9f273d2c70ae4708b3bd0f2Daniel Dunbar for (StringRef::iterator I = Constraints.begin(), 15792ccf70ad448eb02f9f273d2c70ae4708b3bd0f2Daniel Dunbar E = Constraints.end(); I != E; ) { 158a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ConstraintInfo Info; 159a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 160a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // Find the end of this constraint. 16192ccf70ad448eb02f9f273d2c70ae4708b3bd0f2Daniel Dunbar StringRef::iterator ConstraintEnd = std::find(I, E, ','); 162a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 163a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner if (ConstraintEnd == I || // Empty constraint like ",," 1642f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner Info.Parse(std::string(I, ConstraintEnd), Result)) { 1652f0eec6520f9c8bb5cf51251ae735846fc8f2522Chris Lattner Result.clear(); // Erroneous constraint? 166f0b415f178615714de38fb8196f49d131e54274bChris Lattner break; 167f0b415f178615714de38fb8196f49d131e54274bChris Lattner } 168a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner 169a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner Result.push_back(Info); 1703b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner 171a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // ConstraintEnd may be either the next comma or the end of the string. In 172a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner // the former case, we skip the comma. 173a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner I = ConstraintEnd; 174f0b415f178615714de38fb8196f49d131e54274bChris Lattner if (I != E) { 175f0b415f178615714de38fb8196f49d131e54274bChris Lattner ++I; 176f0b415f178615714de38fb8196f49d131e54274bChris Lattner if (I == E) { Result.clear(); break; } // don't allow "xyz," 177f0b415f178615714de38fb8196f49d131e54274bChris Lattner } 178f0b415f178615714de38fb8196f49d131e54274bChris Lattner } 179f0b415f178615714de38fb8196f49d131e54274bChris Lattner 180f0b415f178615714de38fb8196f49d131e54274bChris Lattner return Result; 181f0b415f178615714de38fb8196f49d131e54274bChris Lattner} 182f0b415f178615714de38fb8196f49d131e54274bChris Lattner 183f0b415f178615714de38fb8196f49d131e54274bChris Lattner 184f0b415f178615714de38fb8196f49d131e54274bChris Lattner/// Verify - Verify that the specified constraint string is reasonable for the 185f0b415f178615714de38fb8196f49d131e54274bChris Lattner/// specified function type, and otherwise validate the constraint string. 1862928c83b010f7cfdb0f819199d806f6942a7d995Daniel Dunbarbool InlineAsm::Verify(const FunctionType *Ty, StringRef ConstStr) { 187f0b415f178615714de38fb8196f49d131e54274bChris Lattner if (Ty->isVarArg()) return false; 188f0b415f178615714de38fb8196f49d131e54274bChris Lattner 189a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner std::vector<ConstraintInfo> Constraints = ParseConstraints(ConstStr); 190f0b415f178615714de38fb8196f49d131e54274bChris Lattner 191f0b415f178615714de38fb8196f49d131e54274bChris Lattner // Error parsing constraints. 192f0b415f178615714de38fb8196f49d131e54274bChris Lattner if (Constraints.empty() && !ConstStr.empty()) return false; 193f0b415f178615714de38fb8196f49d131e54274bChris Lattner 194f0b415f178615714de38fb8196f49d131e54274bChris Lattner unsigned NumOutputs = 0, NumInputs = 0, NumClobbers = 0; 195ea21ad49261a6a9d1614c01e631c2cdc4d554b84Chris Lattner unsigned NumIndirect = 0; 196f0b415f178615714de38fb8196f49d131e54274bChris Lattner 197f0b415f178615714de38fb8196f49d131e54274bChris Lattner for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { 198a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner switch (Constraints[i].Type) { 199a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner case InlineAsm::isOutput: 200ea21ad49261a6a9d1614c01e631c2cdc4d554b84Chris Lattner if ((NumInputs-NumIndirect) != 0 || NumClobbers != 0) 201ea21ad49261a6a9d1614c01e631c2cdc4d554b84Chris Lattner return false; // outputs before inputs and clobbers. 20273d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner if (!Constraints[i].isIndirect) { 203a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner ++NumOutputs; 204a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner break; 205a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner } 206ea21ad49261a6a9d1614c01e631c2cdc4d554b84Chris Lattner ++NumIndirect; 20773d0d0d4b8b93e8101e0a0aa283f694be341da6cChris Lattner // FALLTHROUGH for Indirect Outputs. 208a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner case InlineAsm::isInput: 2093b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner if (NumClobbers) return false; // inputs before clobbers. 2103b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner ++NumInputs; 2113b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner break; 212a55079a5ccdf0cdb4d482fb47a3fb21825f56713Chris Lattner case InlineAsm::isClobber: 2133b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner ++NumClobbers; 2143b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner break; 2153b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner } 2163b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner } 2173b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner 21896bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner switch (NumOutputs) { 21996bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner case 0: 220f012705c7e4ca8cf90b6b734ce1d5355daca5ba5Benjamin Kramer if (!Ty->getReturnType()->isVoidTy()) return false; 22196bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner break; 22296bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner case 1: 2231df9859c40492511b8aa4321eb76496005d3b75bDuncan Sands if (Ty->getReturnType()->isStructTy()) return false; 22496bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner break; 22596bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner default: 22696bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner const StructType *STy = dyn_cast<StructType>(Ty->getReturnType()); 22796bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner if (STy == 0 || STy->getNumElements() != NumOutputs) 22896bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner return false; 22996bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner break; 23096bb6226462536dc0fff4b5c0250613300abb9fbChris Lattner } 2313b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner 2323b91778659ec7d515ae1354022f0213e5de64d80Chris Lattner if (Ty->getNumParams() != NumInputs) return false; 23380cd11561892a639a2628d19815af0695b5dbcaaChris Lattner return true; 23480cd11561892a639a2628d19815af0695b5dbcaaChris Lattner} 235af303d53e6013417d189621c75179df6c7cbdcdeReid Spencer 236