Fix XCoreTargetLowering::isLegalAddressingMode() to handle VoidTy.
[oota-llvm.git] / lib / VMCore / InlineAsm.cpp
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
14 #include "llvm/InlineAsm.h"
15 #include "llvm/DerivedTypes.h"
16 #include <algorithm>
17 #include <cctype>
18 using namespace llvm;
19
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
25
26 // NOTE: when memoizing the function type, we have to be careful to handle the
27 // case when the type gets refined.
28
29 InlineAsm *InlineAsm::get(const FunctionType *Ty, StringRef AsmString,
30                           StringRef Constraints, bool hasSideEffects,
31                           bool isAlignStack) {
32   // FIXME: memoize!
33   return new InlineAsm(Ty, AsmString, Constraints, hasSideEffects, 
34                        isAlignStack);
35 }
36
37 InlineAsm::InlineAsm(const FunctionType *Ty, StringRef asmString,
38                      StringRef constraints, bool hasSideEffects,
39                      bool isAlignStack)
40   : Value(PointerType::getUnqual(Ty), 
41           Value::InlineAsmVal), 
42     AsmString(asmString), 
43     Constraints(constraints), HasSideEffects(hasSideEffects), 
44     IsAlignStack(isAlignStack) {
45
46   // Do various checks on the constraint string and type.
47   assert(Verify(Ty, constraints) && "Function type not legal for constraints!");
48 }
49
50 const FunctionType *InlineAsm::getFunctionType() const {
51   return cast<FunctionType>(getType()->getElementType());
52 }
53
54 /// Parse - Analyze the specified string (e.g. "==&{eax}") and fill in the
55 /// fields in this structure.  If the constraint string is not understood,
56 /// return true, otherwise return false.
57 bool InlineAsm::ConstraintInfo::Parse(StringRef Str,
58                      std::vector<InlineAsm::ConstraintInfo> &ConstraintsSoFar) {
59   StringRef::iterator I = Str.begin(), E = Str.end();
60   
61   // Initialize
62   Type = isInput;
63   isEarlyClobber = false;
64   MatchingInput = -1;
65   isCommutative = false;
66   isIndirect = false;
67   
68   // Parse prefixes.
69   if (*I == '~') {
70     Type = isClobber;
71     ++I;
72   } else if (*I == '=') {
73     ++I;
74     Type = isOutput;
75   }
76   
77   if (*I == '*') {
78     isIndirect = true;
79     ++I;
80   }
81   
82   if (I == E) return true;  // Just a prefix, like "==" or "~".
83   
84   // Parse the modifiers.
85   bool DoneWithModifiers = false;
86   while (!DoneWithModifiers) {
87     switch (*I) {
88     default:
89       DoneWithModifiers = true;
90       break;
91     case '&':     // Early clobber.
92       if (Type != isOutput ||      // Cannot early clobber anything but output.
93           isEarlyClobber)          // Reject &&&&&&
94         return true;
95       isEarlyClobber = true;
96       break;
97     case '%':     // Commutative.
98       if (Type == isClobber ||     // Cannot commute clobbers.
99           isCommutative)           // Reject %%%%%
100         return true;
101       isCommutative = true;
102       break;
103     case '#':     // Comment.
104     case '*':     // Register preferencing.
105       return true;     // Not supported.
106     }
107     
108     if (!DoneWithModifiers) {
109       ++I;
110       if (I == E) return true;   // Just prefixes and modifiers!
111     }
112   }
113   
114   // Parse the various constraints.
115   while (I != E) {
116     if (*I == '{') {   // Physical register reference.
117       // Find the end of the register name.
118       StringRef::iterator ConstraintEnd = std::find(I+1, E, '}');
119       if (ConstraintEnd == E) return true;  // "{foo"
120       Codes.push_back(std::string(I, ConstraintEnd+1));
121       I = ConstraintEnd+1;
122     } else if (isdigit(*I)) {     // Matching Constraint
123       // Maximal munch numbers.
124       StringRef::iterator NumStart = I;
125       while (I != E && isdigit(*I))
126         ++I;
127       Codes.push_back(std::string(NumStart, I));
128       unsigned N = atoi(Codes.back().c_str());
129       // Check that this is a valid matching constraint!
130       if (N >= ConstraintsSoFar.size() || ConstraintsSoFar[N].Type != isOutput||
131           Type != isInput)
132         return true;  // Invalid constraint number.
133       
134       // If Operand N already has a matching input, reject this.  An output
135       // can't be constrained to the same value as multiple inputs.
136       if (ConstraintsSoFar[N].hasMatchingInput())
137         return true;
138       
139       // Note that operand #n has a matching input.
140       ConstraintsSoFar[N].MatchingInput = ConstraintsSoFar.size();
141     } else {
142       // Single letter constraint.
143       Codes.push_back(std::string(I, I+1));
144       ++I;
145     }
146   }
147
148   return false;
149 }
150
151 std::vector<InlineAsm::ConstraintInfo>
152 InlineAsm::ParseConstraints(StringRef Constraints) {
153   std::vector<ConstraintInfo> Result;
154   
155   // Scan the constraints string.
156   for (StringRef::iterator I = Constraints.begin(),
157          E = Constraints.end(); I != E; ) {
158     ConstraintInfo Info;
159
160     // Find the end of this constraint.
161     StringRef::iterator ConstraintEnd = std::find(I, E, ',');
162
163     if (ConstraintEnd == I ||  // Empty constraint like ",,"
164         Info.Parse(std::string(I, ConstraintEnd), Result)) {
165       Result.clear();          // Erroneous constraint?
166       break;
167     }
168
169     Result.push_back(Info);
170     
171     // ConstraintEnd may be either the next comma or the end of the string.  In
172     // the former case, we skip the comma.
173     I = ConstraintEnd;
174     if (I != E) {
175       ++I;
176       if (I == E) { Result.clear(); break; }    // don't allow "xyz,"
177     }
178   }
179   
180   return Result;
181 }
182
183
184 /// Verify - Verify that the specified constraint string is reasonable for the
185 /// specified function type, and otherwise validate the constraint string.
186 bool InlineAsm::Verify(const FunctionType *Ty, StringRef ConstStr) {
187   if (Ty->isVarArg()) return false;
188   
189   std::vector<ConstraintInfo> Constraints = ParseConstraints(ConstStr);
190   
191   // Error parsing constraints.
192   if (Constraints.empty() && !ConstStr.empty()) return false;
193   
194   unsigned NumOutputs = 0, NumInputs = 0, NumClobbers = 0;
195   unsigned NumIndirect = 0;
196   
197   for (unsigned i = 0, e = Constraints.size(); i != e; ++i) {
198     switch (Constraints[i].Type) {
199     case InlineAsm::isOutput:
200       if ((NumInputs-NumIndirect) != 0 || NumClobbers != 0)
201         return false;  // outputs before inputs and clobbers.
202       if (!Constraints[i].isIndirect) {
203         ++NumOutputs;
204         break;
205       }
206       ++NumIndirect;
207       // FALLTHROUGH for Indirect Outputs.
208     case InlineAsm::isInput:
209       if (NumClobbers) return false;               // inputs before clobbers.
210       ++NumInputs;
211       break;
212     case InlineAsm::isClobber:
213       ++NumClobbers;
214       break;
215     }
216   }
217   
218   switch (NumOutputs) {
219   case 0:
220     if (!Ty->getReturnType()->isVoidTy()) return false;
221     break;
222   case 1:
223     if (Ty->getReturnType()->isStructTy()) return false;
224     break;
225   default:
226     const StructType *STy = dyn_cast<StructType>(Ty->getReturnType());
227     if (STy == 0 || STy->getNumElements() != NumOutputs)
228       return false;
229     break;
230   }      
231   
232   if (Ty->getNumParams() != NumInputs) return false;
233   return true;
234 }
235