3ccd8aca7ebf993759f9bbf8868b5ce9a0ff7aac
[oota-llvm.git] / lib / VMCore / InlineAsm.cpp
1 //===-- InlineAsm.cpp - Implement the InlineAsm class ---------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Chris Lattner and is distributed under the
6 // University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the InlineAsm class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/InlineAsm.h"
15 #include "llvm/DerivedTypes.h"
16 #include <cctype>
17 using namespace llvm;
18
19 // NOTE: when memoizing the function type, we have to be careful to handle the
20 // case when the type gets refined.
21
22 InlineAsm *InlineAsm::get(const FunctionType *Ty, const std::string &AsmString,
23                           const std::string &Constraints, bool hasSideEffects) {
24   // FIXME: memoize!
25   return new InlineAsm(Ty, AsmString, Constraints, hasSideEffects);  
26 }
27
28 InlineAsm::InlineAsm(const FunctionType *Ty, const std::string &asmString,
29                      const std::string &constraints, bool hasSideEffects)
30   : Value(PointerType::get(Ty), Value::InlineAsmVal), AsmString(asmString), 
31     Constraints(constraints), HasSideEffects(hasSideEffects) {
32
33   // Do various checks on the constraint string and type.
34   assert(Verify(Ty, constraints) && "Function type not legal for constraints!");
35 }
36
37 const FunctionType *InlineAsm::getFunctionType() const {
38   return cast<FunctionType>(getType()->getElementType());
39 }
40
41 /// Verify - Verify that the specified constraint string is reasonable for the
42 /// specified function type, and otherwise validate the constraint string.
43 bool InlineAsm::Verify(const FunctionType *Ty, const std::string &Constraints) {
44   if (Ty->isVarArg()) return false;
45   
46   unsigned NumOutputs = 0, NumInputs = 0, NumClobbers = 0;
47   
48   // Scan the constraints string.
49   for (std::string::const_iterator I = Constraints.begin(), 
50          E = Constraints.end(); I != E; ) {
51     if (*I == ',') return false;  // Empty constraint like ",,"
52     
53     // Parse the prefix.
54     enum {
55       isInput,            // 'x'
56       isOutput,           // '=x'
57       isIndirectOutput,   // '==x'
58       isClobber,          // '~x'
59     } ConstraintType = isInput;
60     
61     if (*I == '~') {
62       ConstraintType = isClobber;
63       ++I;
64     } else if (*I == '=') {
65       ++I;
66       if (I != E && *I == '=') {
67         ConstraintType = isIndirectOutput;
68         ++I;
69       } else {
70         ConstraintType = isOutput;
71       }
72     }
73     
74     if (I == E) return false;   // Just a prefix, like "==" or "~".
75     
76     switch (ConstraintType) {
77     case isOutput:
78       if (NumInputs || NumClobbers) return false;  // outputs come first.
79       ++NumOutputs;
80       break;
81     case isInput:
82     case isIndirectOutput:
83       if (NumClobbers) return false;               // inputs before clobbers.
84       ++NumInputs;
85       break;
86     case isClobber:
87       ++NumClobbers;
88       break;
89     }
90     
91     // Parse the id.  We accept [a-zA-Z0-9] currently.
92     while (I != E && isalnum(*I)) ++I;
93     
94     // If we reached the end of the ID, we must have the end of the string or a
95     // comma, which we skip now.
96     if (I != E) {
97       if (*I != ',') return false;
98       ++I;
99       if (I == E) return false;    // don't allow "xyz,"
100     }
101   }
102   
103   if (NumOutputs > 1) return false;  // Only one result allowed.
104   
105   if ((Ty->getReturnType() != Type::VoidTy) != NumOutputs)
106     return false;   // NumOutputs = 1 iff has a result type.
107   
108   if (Ty->getNumParams() != NumInputs) return false;
109   return true;
110 }