InlineAsm.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. //===-- InlineAsm.cpp - Implement the InlineAsm class ---------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file implements the InlineAsm class.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "llvm/IR/InlineAsm.h"
  14. #include "ConstantsContext.h"
  15. #include "LLVMContextImpl.h"
  16. #include "llvm/IR/DerivedTypes.h"
  17. #include <algorithm>
  18. #include <cctype>
  19. using namespace llvm;
  20. // Implement the first virtual method in this class in this file so the
  21. // InlineAsm vtable is emitted here.
  22. InlineAsm::~InlineAsm() {
  23. }
  24. InlineAsm *InlineAsm::get(FunctionType *Ty, StringRef AsmString,
  25. StringRef Constraints, bool hasSideEffects,
  26. bool isAlignStack, AsmDialect asmDialect) {
  27. InlineAsmKeyType Key(AsmString, Constraints, hasSideEffects, isAlignStack,
  28. asmDialect);
  29. LLVMContextImpl *pImpl = Ty->getContext().pImpl;
  30. return pImpl->InlineAsms.getOrCreate(PointerType::getUnqual(Ty), Key);
  31. }
  32. InlineAsm::InlineAsm(PointerType *Ty, const std::string &asmString,
  33. const std::string &constraints, bool hasSideEffects,
  34. bool isAlignStack, AsmDialect asmDialect)
  35. : Value(Ty, Value::InlineAsmVal),
  36. AsmString(asmString), Constraints(constraints),
  37. HasSideEffects(hasSideEffects), IsAlignStack(isAlignStack),
  38. Dialect(asmDialect) {
  39. // Do various checks on the constraint string and type.
  40. assert(Verify(getFunctionType(), constraints) &&
  41. "Function type not legal for constraints!");
  42. }
  43. void InlineAsm::destroyConstant() {
  44. getType()->getContext().pImpl->InlineAsms.remove(this);
  45. delete this;
  46. }
  47. FunctionType *InlineAsm::getFunctionType() const {
  48. return cast<FunctionType>(getType()->getElementType());
  49. }
  50. ///Default constructor.
  51. InlineAsm::ConstraintInfo::ConstraintInfo() :
  52. Type(isInput), isEarlyClobber(false),
  53. MatchingInput(-1), isCommutative(false),
  54. isIndirect(false), isMultipleAlternative(false),
  55. currentAlternativeIndex(0) {
  56. }
  57. /// Parse - Analyze the specified string (e.g. "==&{eax}") and fill in the
  58. /// fields in this structure. If the constraint string is not understood,
  59. /// return true, otherwise return false.
  60. bool InlineAsm::ConstraintInfo::Parse(StringRef Str,
  61. InlineAsm::ConstraintInfoVector &ConstraintsSoFar) {
  62. StringRef::iterator I = Str.begin(), E = Str.end();
  63. unsigned multipleAlternativeCount = Str.count('|') + 1;
  64. unsigned multipleAlternativeIndex = 0;
  65. ConstraintCodeVector *pCodes = &Codes;
  66. // Initialize
  67. isMultipleAlternative = multipleAlternativeCount > 1;
  68. if (isMultipleAlternative) {
  69. multipleAlternatives.resize(multipleAlternativeCount);
  70. pCodes = &multipleAlternatives[0].Codes;
  71. }
  72. Type = isInput;
  73. isEarlyClobber = false;
  74. MatchingInput = -1;
  75. isCommutative = false;
  76. isIndirect = false;
  77. currentAlternativeIndex = 0;
  78. // Parse prefixes.
  79. if (*I == '~') {
  80. Type = isClobber;
  81. ++I;
  82. // '{' must immediately follow '~'.
  83. if (I != E && *I != '{')
  84. return true;
  85. } else if (*I == '=') {
  86. ++I;
  87. Type = isOutput;
  88. }
  89. if (*I == '*') {
  90. isIndirect = true;
  91. ++I;
  92. }
  93. if (I == E) return true; // Just a prefix, like "==" or "~".
  94. // Parse the modifiers.
  95. bool DoneWithModifiers = false;
  96. while (!DoneWithModifiers) {
  97. switch (*I) {
  98. default:
  99. DoneWithModifiers = true;
  100. break;
  101. case '&': // Early clobber.
  102. if (Type != isOutput || // Cannot early clobber anything but output.
  103. isEarlyClobber) // Reject &&&&&&
  104. return true;
  105. isEarlyClobber = true;
  106. break;
  107. case '%': // Commutative.
  108. if (Type == isClobber || // Cannot commute clobbers.
  109. isCommutative) // Reject %%%%%
  110. return true;
  111. isCommutative = true;
  112. break;
  113. case '#': // Comment.
  114. case '*': // Register preferencing.
  115. return true; // Not supported.
  116. }
  117. if (!DoneWithModifiers) {
  118. ++I;
  119. if (I == E) return true; // Just prefixes and modifiers!
  120. }
  121. }
  122. // Parse the various constraints.
  123. while (I != E) {
  124. if (*I == '{') { // Physical register reference.
  125. // Find the end of the register name.
  126. StringRef::iterator ConstraintEnd = std::find(I+1, E, '}');
  127. if (ConstraintEnd == E) return true; // "{foo"
  128. pCodes->push_back(std::string(I, ConstraintEnd+1));
  129. I = ConstraintEnd+1;
  130. } else if (isdigit(static_cast<unsigned char>(*I))) { // Matching Constraint
  131. // Maximal munch numbers.
  132. StringRef::iterator NumStart = I;
  133. while (I != E && isdigit(static_cast<unsigned char>(*I)))
  134. ++I;
  135. pCodes->push_back(std::string(NumStart, I));
  136. unsigned N = atoi(pCodes->back().c_str());
  137. // Check that this is a valid matching constraint!
  138. if (N >= ConstraintsSoFar.size() || ConstraintsSoFar[N].Type != isOutput||
  139. Type != isInput)
  140. return true; // Invalid constraint number.
  141. // If Operand N already has a matching input, reject this. An output
  142. // can't be constrained to the same value as multiple inputs.
  143. if (isMultipleAlternative) {
  144. InlineAsm::SubConstraintInfo &scInfo =
  145. ConstraintsSoFar[N].multipleAlternatives[multipleAlternativeIndex];
  146. if (scInfo.MatchingInput != -1)
  147. return true;
  148. // Note that operand #n has a matching input.
  149. scInfo.MatchingInput = ConstraintsSoFar.size();
  150. } else {
  151. if (ConstraintsSoFar[N].hasMatchingInput() &&
  152. (size_t)ConstraintsSoFar[N].MatchingInput !=
  153. ConstraintsSoFar.size())
  154. return true;
  155. // Note that operand #n has a matching input.
  156. ConstraintsSoFar[N].MatchingInput = ConstraintsSoFar.size();
  157. }
  158. } else if (*I == '|') {
  159. multipleAlternativeIndex++;
  160. pCodes = &multipleAlternatives[multipleAlternativeIndex].Codes;
  161. ++I;
  162. } else if (*I == '^') {
  163. // Multi-letter constraint
  164. // FIXME: For now assuming these are 2-character constraints.
  165. pCodes->push_back(std::string(I+1, I+3));
  166. I += 3;
  167. } else {
  168. // Single letter constraint.
  169. pCodes->push_back(std::string(I, I+1));
  170. ++I;
  171. }
  172. }
  173. return false;
  174. }
  175. /// selectAlternative - Point this constraint to the alternative constraint
  176. /// indicated by the index.
  177. void InlineAsm::ConstraintInfo::selectAlternative(unsigned index) {
  178. if (index < multipleAlternatives.size()) {
  179. currentAlternativeIndex = index;
  180. InlineAsm::SubConstraintInfo &scInfo =
  181. multipleAlternatives[currentAlternativeIndex];
  182. MatchingInput = scInfo.MatchingInput;
  183. Codes = scInfo.Codes;
  184. }
  185. }
  186. InlineAsm::ConstraintInfoVector
  187. InlineAsm::ParseConstraints(StringRef Constraints) {
  188. ConstraintInfoVector Result;
  189. // Scan the constraints string.
  190. for (StringRef::iterator I = Constraints.begin(),
  191. E = Constraints.end(); I != E; ) {
  192. ConstraintInfo Info;
  193. // Find the end of this constraint.
  194. StringRef::iterator ConstraintEnd = std::find(I, E, ',');
  195. if (ConstraintEnd == I || // Empty constraint like ",,"
  196. Info.Parse(StringRef(I, ConstraintEnd-I), Result)) {
  197. Result.clear(); // Erroneous constraint?
  198. break;
  199. }
  200. Result.push_back(Info);
  201. // ConstraintEnd may be either the next comma or the end of the string. In
  202. // the former case, we skip the comma.
  203. I = ConstraintEnd;
  204. if (I != E) {
  205. ++I;
  206. if (I == E) {
  207. Result.clear();
  208. break;
  209. } // don't allow "xyz,"
  210. }
  211. }
  212. return Result;
  213. }
  214. /// Verify - Verify that the specified constraint string is reasonable for the
  215. /// specified function type, and otherwise validate the constraint string.
  216. bool InlineAsm::Verify(FunctionType *Ty, StringRef ConstStr) {
  217. if (Ty->isVarArg()) return false;
  218. ConstraintInfoVector Constraints = ParseConstraints(ConstStr);
  219. // Error parsing constraints.
  220. if (Constraints.empty() && !ConstStr.empty()) return false;
  221. unsigned NumOutputs = 0, NumInputs = 0, NumClobbers = 0;
  222. unsigned NumIndirect = 0;
  223. for (unsigned i = 0, e = Constraints.size(); i != e; ++i) {
  224. switch (Constraints[i].Type) {
  225. case InlineAsm::isOutput:
  226. if ((NumInputs-NumIndirect) != 0 || NumClobbers != 0)
  227. return false; // outputs before inputs and clobbers.
  228. if (!Constraints[i].isIndirect) {
  229. ++NumOutputs;
  230. break;
  231. }
  232. ++NumIndirect;
  233. // FALLTHROUGH for Indirect Outputs.
  234. case InlineAsm::isInput:
  235. if (NumClobbers) return false; // inputs before clobbers.
  236. ++NumInputs;
  237. break;
  238. case InlineAsm::isClobber:
  239. ++NumClobbers;
  240. break;
  241. }
  242. }
  243. switch (NumOutputs) {
  244. case 0:
  245. if (!Ty->getReturnType()->isVoidTy()) return false;
  246. break;
  247. case 1:
  248. if (Ty->getReturnType()->isStructTy()) return false;
  249. break;
  250. default:
  251. StructType *STy = dyn_cast<StructType>(Ty->getReturnType());
  252. if (!STy || STy->getNumElements() != NumOutputs)
  253. return false;
  254. break;
  255. }
  256. if (Ty->getNumParams() != NumInputs) return false;
  257. return true;
  258. }