blob: 2b3315d8f18ff97f098e1438b8848b00d3952e3c [file] [log] [blame]
Reid Spencer96839be2006-11-30 16:50:26 +00001//===-- UpgradeParser.y - Upgrade parser for llvm assmbly -------*- C++ -*-===//
Reid Spencere7c3c602006-11-30 06:36:44 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Reid Spencer and is distributed under the
6// University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Reid Spencer96839be2006-11-30 16:50:26 +000010// This file implements the bison parser for LLVM 1.9 assembly language.
Reid Spencere7c3c602006-11-30 06:36:44 +000011//
12//===----------------------------------------------------------------------===//
13
14%{
Reid Spencere7c3c602006-11-30 06:36:44 +000015#include "ParserInternals.h"
Reid Spencere7c3c602006-11-30 06:36:44 +000016#include <algorithm>
Reid Spencera50d5962006-12-02 04:11:07 +000017#include <map>
Reid Spencere7c3c602006-11-30 06:36:44 +000018#include <utility>
19#include <iostream>
20
Reid Spencere77e35e2006-12-01 20:26:20 +000021#define YYERROR_VERBOSE 1
Reid Spencer96839be2006-11-30 16:50:26 +000022#define YYINCLUDED_STDLIB_H
Reid Spencere77e35e2006-12-01 20:26:20 +000023#define YYDEBUG 1
Reid Spencere7c3c602006-11-30 06:36:44 +000024
25int yylex(); // declaration" of xxx warnings.
26int yyparse();
Reid Spencere77e35e2006-12-01 20:26:20 +000027extern int yydebug;
Reid Spencere7c3c602006-11-30 06:36:44 +000028
29static std::string CurFilename;
Reid Spencere7c3c602006-11-30 06:36:44 +000030static std::ostream *O = 0;
Reid Spencer96839be2006-11-30 16:50:26 +000031std::istream* LexInput = 0;
Reid Spencere77e35e2006-12-01 20:26:20 +000032unsigned SizeOfPointer = 32;
Reid Spencerf459d392006-12-02 16:19:52 +000033static uint64_t unique = 1;
Reid Spencer96839be2006-11-30 16:50:26 +000034
Reid Spencer71d2ec92006-12-31 06:02:26 +000035// This bool controls whether attributes are ever added to function declarations
36// definitions and calls.
37static bool AddAttributes = false;
38
Reid Spencerf5626a32007-01-01 01:20:41 +000039// This bool is used to communicate between the InstVal and Inst rules about
40// whether or not a cast should be deleted. When the flag is set, InstVal has
41// determined that the cast is a candidate. However, it can only be deleted if
42// the value being casted is the same value name as the instruction. The Inst
43// rule makes that comparison if the flag is set and comments out the
44// instruction if they match.
45static bool deleteUselessCastFlag = false;
46static std::string* deleteUselessCastName = 0;
47
Reid Spencera50d5962006-12-02 04:11:07 +000048typedef std::vector<TypeInfo> TypeVector;
49static TypeVector EnumeratedTypes;
50typedef std::map<std::string,TypeInfo> TypeMap;
51static TypeMap NamedTypes;
Reid Spencerf12ee422006-12-05 19:21:25 +000052static TypeMap Globals;
Reid Spencera50d5962006-12-02 04:11:07 +000053
Reid Spencerf8483652006-12-02 15:16:01 +000054void destroy(ValueList* VL) {
55 while (!VL->empty()) {
56 ValueInfo& VI = VL->back();
57 VI.destroy();
58 VL->pop_back();
59 }
60 delete VL;
61}
62
Reid Spencer96839be2006-11-30 16:50:26 +000063void UpgradeAssembly(const std::string &infile, std::istream& in,
Reid Spencer71d2ec92006-12-31 06:02:26 +000064 std::ostream &out, bool debug, bool addAttrs)
Reid Spencere7c3c602006-11-30 06:36:44 +000065{
66 Upgradelineno = 1;
67 CurFilename = infile;
Reid Spencer96839be2006-11-30 16:50:26 +000068 LexInput = &in;
Reid Spencere77e35e2006-12-01 20:26:20 +000069 yydebug = debug;
Reid Spencer71d2ec92006-12-31 06:02:26 +000070 AddAttributes = addAttrs;
Reid Spencere7c3c602006-11-30 06:36:44 +000071 O = &out;
72
73 if (yyparse()) {
74 std::cerr << "Parse failed.\n";
Chris Lattner37e01c52007-01-04 18:46:42 +000075 out << "llvm-upgrade parse failed.\n";
Reid Spencere7c3c602006-11-30 06:36:44 +000076 exit(1);
77 }
78}
79
Reid Spencer52402b02007-01-02 05:45:11 +000080TypeInfo* ResolveType(TypeInfo*& Ty) {
81 if (Ty->isUnresolved()) {
Reid Spencereff838e2007-01-03 23:45:42 +000082 if (Ty->getNewTy()[0] == '%' && isdigit(Ty->getNewTy()[1])) {
83 unsigned ref = atoi(&((Ty->getNewTy().c_str())[1])); // skip the %
84 if (ref < EnumeratedTypes.size()) {
85 Ty = &EnumeratedTypes[ref];
86 return Ty;
87 } else {
88 std::string msg("Can't resolve numbered type: ");
89 msg += Ty->getNewTy();
90 yyerror(msg.c_str());
91 }
Reid Spencer78720742006-12-02 20:21:22 +000092 } else {
Reid Spencereff838e2007-01-03 23:45:42 +000093 TypeMap::iterator I = NamedTypes.find(Ty->getNewTy());
94 if (I != NamedTypes.end()) {
95 Ty = &I->second;
96 return Ty;
97 } else {
98 std::string msg("Cannot resolve type: ");
99 msg += Ty->getNewTy();
100 yyerror(msg.c_str());
101 }
Reid Spencera50d5962006-12-02 04:11:07 +0000102 }
Reid Spencer280d8012006-12-01 23:40:53 +0000103 }
Reid Spencera50d5962006-12-02 04:11:07 +0000104 // otherwise its already resolved.
Reid Spencer52402b02007-01-02 05:45:11 +0000105 return Ty;
Reid Spencer280d8012006-12-01 23:40:53 +0000106}
107
Reid Spencera50d5962006-12-02 04:11:07 +0000108static const char* getCastOpcode(
Reid Spencer52402b02007-01-02 05:45:11 +0000109 std::string& Source, const TypeInfo* SrcTy, const TypeInfo* DstTy)
Reid Spencera50d5962006-12-02 04:11:07 +0000110{
Reid Spencer52402b02007-01-02 05:45:11 +0000111 unsigned SrcBits = SrcTy->getBitWidth();
112 unsigned DstBits = DstTy->getBitWidth();
Reid Spencere77e35e2006-12-01 20:26:20 +0000113 const char* opcode = "bitcast";
114 // Run through the possibilities ...
Reid Spencer52402b02007-01-02 05:45:11 +0000115 if (DstTy->isIntegral()) { // Casting to integral
116 if (SrcTy->isIntegral()) { // Casting from integral
Reid Spencere77e35e2006-12-01 20:26:20 +0000117 if (DstBits < SrcBits)
118 opcode = "trunc";
119 else if (DstBits > SrcBits) { // its an extension
Reid Spencer52402b02007-01-02 05:45:11 +0000120 if (SrcTy->isSigned())
Reid Spencere77e35e2006-12-01 20:26:20 +0000121 opcode ="sext"; // signed -> SEXT
122 else
123 opcode = "zext"; // unsigned -> ZEXT
124 } else {
125 opcode = "bitcast"; // Same size, No-op cast
126 }
Reid Spencer52402b02007-01-02 05:45:11 +0000127 } else if (SrcTy->isFloatingPoint()) { // Casting from floating pt
128 if (DstTy->isSigned())
Reid Spencere77e35e2006-12-01 20:26:20 +0000129 opcode = "fptosi"; // FP -> sint
130 else
131 opcode = "fptoui"; // FP -> uint
Reid Spencer52402b02007-01-02 05:45:11 +0000132 } else if (SrcTy->isPacked()) {
133 assert(DstBits == SrcTy->getBitWidth() &&
Reid Spencere77e35e2006-12-01 20:26:20 +0000134 "Casting packed to integer of different width");
135 opcode = "bitcast"; // same size, no-op cast
136 } else {
Reid Spencer52402b02007-01-02 05:45:11 +0000137 assert(SrcTy->isPointer() &&
Reid Spencere77e35e2006-12-01 20:26:20 +0000138 "Casting from a value that is not first-class type");
139 opcode = "ptrtoint"; // ptr -> int
140 }
Reid Spencer52402b02007-01-02 05:45:11 +0000141 } else if (DstTy->isFloatingPoint()) { // Casting to floating pt
142 if (SrcTy->isIntegral()) { // Casting from integral
143 if (SrcTy->isSigned())
Reid Spencere77e35e2006-12-01 20:26:20 +0000144 opcode = "sitofp"; // sint -> FP
145 else
146 opcode = "uitofp"; // uint -> FP
Reid Spencer52402b02007-01-02 05:45:11 +0000147 } else if (SrcTy->isFloatingPoint()) { // Casting from floating pt
Reid Spencere77e35e2006-12-01 20:26:20 +0000148 if (DstBits < SrcBits) {
149 opcode = "fptrunc"; // FP -> smaller FP
150 } else if (DstBits > SrcBits) {
151 opcode = "fpext"; // FP -> larger FP
152 } else {
153 opcode ="bitcast"; // same size, no-op cast
154 }
Reid Spencer52402b02007-01-02 05:45:11 +0000155 } else if (SrcTy->isPacked()) {
156 assert(DstBits == SrcTy->getBitWidth() &&
Reid Spencere77e35e2006-12-01 20:26:20 +0000157 "Casting packed to floating point of different width");
158 opcode = "bitcast"; // same size, no-op cast
159 } else {
160 assert(0 && "Casting pointer or non-first class to float");
161 }
Reid Spencer52402b02007-01-02 05:45:11 +0000162 } else if (DstTy->isPacked()) {
163 if (SrcTy->isPacked()) {
164 assert(DstTy->getBitWidth() == SrcTy->getBitWidth() &&
Reid Spencere77e35e2006-12-01 20:26:20 +0000165 "Casting packed to packed of different widths");
166 opcode = "bitcast"; // packed -> packed
Reid Spencer52402b02007-01-02 05:45:11 +0000167 } else if (DstTy->getBitWidth() == SrcBits) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000168 opcode = "bitcast"; // float/int -> packed
169 } else {
170 assert(!"Illegal cast to packed (wrong type or size)");
171 }
Reid Spencer52402b02007-01-02 05:45:11 +0000172 } else if (DstTy->isPointer()) {
173 if (SrcTy->isPointer()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000174 opcode = "bitcast"; // ptr -> ptr
Reid Spencer52402b02007-01-02 05:45:11 +0000175 } else if (SrcTy->isIntegral()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000176 opcode = "inttoptr"; // int -> ptr
177 } else {
Reid Spencera50d5962006-12-02 04:11:07 +0000178 assert(!"Casting invalid type to pointer");
Reid Spencere77e35e2006-12-01 20:26:20 +0000179 }
180 } else {
181 assert(!"Casting to type that is not first-class");
182 }
183 return opcode;
184}
185
Reid Spencer52402b02007-01-02 05:45:11 +0000186static std::string getCastUpgrade(const std::string& Src, TypeInfo* SrcTy,
187 TypeInfo* DstTy, bool isConst)
Reid Spencera50d5962006-12-02 04:11:07 +0000188{
189 std::string Result;
190 std::string Source = Src;
Reid Spencer52402b02007-01-02 05:45:11 +0000191 if (SrcTy->isFloatingPoint() && DstTy->isPointer()) {
Reid Spencera50d5962006-12-02 04:11:07 +0000192 // fp -> ptr cast is no longer supported but we must upgrade this
193 // by doing a double cast: fp -> int -> ptr
194 if (isConst)
Reid Spencer71d2ec92006-12-31 06:02:26 +0000195 Source = "i64 fptoui(" + Source + " to i64)";
Reid Spencera50d5962006-12-02 04:11:07 +0000196 else {
Reid Spencerf459d392006-12-02 16:19:52 +0000197 *O << " %cast_upgrade" << unique << " = fptoui " << Source
Reid Spencer71d2ec92006-12-31 06:02:26 +0000198 << " to i64\n";
199 Source = "i64 %cast_upgrade" + llvm::utostr(unique);
Reid Spencera50d5962006-12-02 04:11:07 +0000200 }
201 // Update the SrcTy for the getCastOpcode call below
Reid Spencer52402b02007-01-02 05:45:11 +0000202 delete SrcTy;
203 SrcTy = new TypeInfo("i64", ULongTy);
204 } else if (DstTy->isBool()) {
205 // cast type %x to bool was previously defined as setne type %x, null
206 // The cast semantic is now to truncate, not compare so we must retain
207 // the original intent by replacing the cast with a setne
208 const char* comparator = SrcTy->isPointer() ? ", null" :
209 (SrcTy->isFloatingPoint() ? ", 0.0" :
210 (SrcTy->isBool() ? ", false" : ", 0"));
211 const char* compareOp = SrcTy->isFloatingPoint() ? "fcmp one " : "icmp ne ";
Reid Spencer187ccf82006-12-09 16:57:22 +0000212 if (isConst) {
213 Result = "(" + Source + comparator + ")";
214 Result = compareOp + Result;
215 } else
216 Result = compareOp + Source + comparator;
Reid Spencera50d5962006-12-02 04:11:07 +0000217 return Result; // skip cast processing below
218 }
219 ResolveType(SrcTy);
220 ResolveType(DstTy);
221 std::string Opcode(getCastOpcode(Source, SrcTy, DstTy));
222 if (isConst)
Reid Spencer52402b02007-01-02 05:45:11 +0000223 Result += Opcode + "( " + Source + " to " + DstTy->getNewTy() + ")";
Reid Spencera50d5962006-12-02 04:11:07 +0000224 else
Reid Spencer52402b02007-01-02 05:45:11 +0000225 Result += Opcode + " " + Source + " to " + DstTy->getNewTy();
Reid Spencera50d5962006-12-02 04:11:07 +0000226 return Result;
227}
228
Reid Spencer52402b02007-01-02 05:45:11 +0000229const char* getDivRemOpcode(const std::string& opcode, TypeInfo* TI) {
Reid Spencer78720742006-12-02 20:21:22 +0000230 const char* op = opcode.c_str();
Reid Spencer52402b02007-01-02 05:45:11 +0000231 const TypeInfo* Ty = ResolveType(TI);
232 if (Ty->isPacked())
233 Ty = Ty->getElementType();
Reid Spencer78720742006-12-02 20:21:22 +0000234 if (opcode == "div")
Reid Spencer52402b02007-01-02 05:45:11 +0000235 if (Ty->isFloatingPoint())
Reid Spencer78720742006-12-02 20:21:22 +0000236 op = "fdiv";
Reid Spencer52402b02007-01-02 05:45:11 +0000237 else if (Ty->isUnsigned())
Reid Spencer78720742006-12-02 20:21:22 +0000238 op = "udiv";
Reid Spencer52402b02007-01-02 05:45:11 +0000239 else if (Ty->isSigned())
Reid Spencer78720742006-12-02 20:21:22 +0000240 op = "sdiv";
241 else
242 yyerror("Invalid type for div instruction");
243 else if (opcode == "rem")
Reid Spencer52402b02007-01-02 05:45:11 +0000244 if (Ty->isFloatingPoint())
Reid Spencer78720742006-12-02 20:21:22 +0000245 op = "frem";
Reid Spencer52402b02007-01-02 05:45:11 +0000246 else if (Ty->isUnsigned())
Reid Spencer78720742006-12-02 20:21:22 +0000247 op = "urem";
Reid Spencer52402b02007-01-02 05:45:11 +0000248 else if (Ty->isSigned())
Reid Spencer78720742006-12-02 20:21:22 +0000249 op = "srem";
250 else
251 yyerror("Invalid type for rem instruction");
252 return op;
253}
Reid Spencer229e9362006-12-02 22:14:11 +0000254
255std::string
Reid Spencer52402b02007-01-02 05:45:11 +0000256getCompareOp(const std::string& setcc, const TypeInfo* TI) {
Reid Spencer229e9362006-12-02 22:14:11 +0000257 assert(setcc.length() == 5);
258 char cc1 = setcc[3];
259 char cc2 = setcc[4];
260 assert(cc1 == 'e' || cc1 == 'n' || cc1 == 'l' || cc1 == 'g');
261 assert(cc2 == 'q' || cc2 == 'e' || cc2 == 'e' || cc2 == 't');
262 std::string result("xcmp xxx");
263 result[6] = cc1;
264 result[7] = cc2;
Reid Spencer52402b02007-01-02 05:45:11 +0000265 if (TI->isFloatingPoint()) {
Reid Spencer229e9362006-12-02 22:14:11 +0000266 result[0] = 'f';
Reid Spencere4d87aa2006-12-23 06:05:41 +0000267 result[5] = 'o';
Reid Spencerf0cf1322006-12-07 04:23:03 +0000268 if (cc1 == 'n')
269 result[5] = 'u'; // NE maps to unordered
270 else
271 result[5] = 'o'; // everything else maps to ordered
Reid Spencer52402b02007-01-02 05:45:11 +0000272 } else if (TI->isIntegral() || TI->isPointer()) {
Reid Spencer229e9362006-12-02 22:14:11 +0000273 result[0] = 'i';
274 if ((cc1 == 'e' && cc2 == 'q') || (cc1 == 'n' && cc2 == 'e'))
275 result.erase(5,1);
Reid Spencer52402b02007-01-02 05:45:11 +0000276 else if (TI->isSigned())
Reid Spencer229e9362006-12-02 22:14:11 +0000277 result[5] = 's';
Reid Spencer52402b02007-01-02 05:45:11 +0000278 else if (TI->isUnsigned() || TI->isPointer() || TI->isBool())
Reid Spencer229e9362006-12-02 22:14:11 +0000279 result[5] = 'u';
280 else
281 yyerror("Invalid integral type for setcc");
282 }
283 return result;
284}
285
Reid Spencer52402b02007-01-02 05:45:11 +0000286static TypeInfo* getFunctionReturnType(TypeInfo* PFTy) {
287 ResolveType(PFTy);
288 if (PFTy->isPointer()) {
289 TypeInfo* ElemTy = PFTy->getElementType();
290 ResolveType(ElemTy);
291 if (ElemTy->isFunction())
292 return ElemTy->getResultType()->clone();
293 } else if (PFTy->isFunction()) {
294 return PFTy->getResultType()->clone();
295 }
296 return PFTy->clone();
297}
298
Reid Spencereff838e2007-01-03 23:45:42 +0000299typedef std::vector<TypeInfo*> UpRefStack;
300static TypeInfo* ResolveUpReference(TypeInfo* Ty, UpRefStack* stack) {
301 assert(Ty->isUpReference() && "Can't resolve a non-upreference");
302 unsigned upref = atoi(&((Ty->getNewTy().c_str())[1])); // skip the slash
303 assert(upref < stack->size() && "Invalid up reference");
304 return (*stack)[upref - stack->size() - 1];
305}
306
Reid Spencer52402b02007-01-02 05:45:11 +0000307static TypeInfo* getGEPIndexedType(TypeInfo* PTy, ValueList* idxs) {
Reid Spencereff838e2007-01-03 23:45:42 +0000308 TypeInfo* Result = ResolveType(PTy);
Reid Spencer52402b02007-01-02 05:45:11 +0000309 assert(PTy->isPointer() && "GEP Operand is not a pointer?");
Reid Spencereff838e2007-01-03 23:45:42 +0000310 UpRefStack stack;
311 for (unsigned i = 0; i < idxs->size(); ++i) {
Reid Spencer52402b02007-01-02 05:45:11 +0000312 if (Result->isComposite()) {
313 Result = Result->getIndexedType((*idxs)[i]);
314 ResolveType(Result);
Reid Spencereff838e2007-01-03 23:45:42 +0000315 stack.push_back(Result);
Reid Spencer52402b02007-01-02 05:45:11 +0000316 } else
317 yyerror("Invalid type for index");
318 }
Reid Spencereff838e2007-01-03 23:45:42 +0000319 // Resolve upreferences so we can return a more natural type
320 if (Result->isPointer()) {
321 if (Result->getElementType()->isUpReference()) {
322 stack.push_back(Result);
323 Result = ResolveUpReference(Result->getElementType(), &stack);
324 }
325 } else if (Result->isUpReference()) {
326 Result = ResolveUpReference(Result->getElementType(), &stack);
327 }
Reid Spencer52402b02007-01-02 05:45:11 +0000328 return Result->getPointerType();
329}
330
331static std::string makeUniqueName(const std::string *Name, bool isSigned) {
332 const char *suffix = ".u";
333 if (isSigned)
334 suffix = ".s";
335 if ((*Name)[Name->size()-1] == '"') {
336 std::string Result(*Name);
337 Result.insert(Name->size()-1, suffix);
338 return Result;
339 }
340 return *Name + suffix;
341}
342
343// This function handles appending .u or .s to integer value names that
344// were previously unsigned or signed, respectively. This avoids name
345// collisions since the unsigned and signed type planes have collapsed
346// into a single signless type plane.
347static std::string getUniqueName(const std::string *Name, TypeInfo* Ty) {
348 // If its not a symbolic name, don't modify it, probably a constant val.
349 if ((*Name)[0] != '%' && (*Name)[0] != '"')
350 return *Name;
351 // If its a numeric reference, just leave it alone.
352 if (isdigit((*Name)[1]))
353 return *Name;
354
355 // Resolve the type
356 ResolveType(Ty);
357
Reid Spencereff838e2007-01-03 23:45:42 +0000358 // Remove as many levels of pointer nesting that we have.
359 if (Ty->isPointer()) {
360 // Avoid infinite loops in recursive types
361 TypeInfo* Last = 0;
362 while (Ty->isPointer() && Last != Ty) {
363 Last = Ty;
364 Ty = Ty->getElementType();
365 ResolveType(Ty);
366 }
367 }
368
Reid Spencer52402b02007-01-02 05:45:11 +0000369 // Default the result to the current name
370 std::string Result = *Name;
371
Reid Spencereff838e2007-01-03 23:45:42 +0000372 // Now deal with the underlying type
Reid Spencer52402b02007-01-02 05:45:11 +0000373 if (Ty->isInteger()) {
374 // If its an integer type, make the name unique
375 Result = makeUniqueName(Name, Ty->isSigned());
Reid Spencereff838e2007-01-03 23:45:42 +0000376 } else if (Ty->isArray() || Ty->isPacked()) {
377 Ty = Ty->getElementType();
Reid Spencer52402b02007-01-02 05:45:11 +0000378 if (Ty->isInteger())
379 Result = makeUniqueName(Name, Ty->isSigned());
Reid Spencereff838e2007-01-03 23:45:42 +0000380 } else if (Ty->isStruct()) {
381 // Scan the fields and count the signed and unsigned fields
382 int isSigned = 0;
383 for (unsigned i = 0; i < Ty->getNumStructElements(); ++i) {
384 TypeInfo* Tmp = Ty->getElement(i);
385 if (Tmp->isInteger())
386 if (Tmp->isSigned())
387 isSigned++;
388 else
389 isSigned--;
390 }
391 if (isSigned != 0)
392 Result = makeUniqueName(Name, isSigned > 0);
Reid Spencer52402b02007-01-02 05:45:11 +0000393 }
394 return Result;
395}
396
Reid Spencere7c3c602006-11-30 06:36:44 +0000397%}
398
Reid Spencerf0cf1322006-12-07 04:23:03 +0000399// %file-prefix="UpgradeParser"
Reid Spencere77e35e2006-12-01 20:26:20 +0000400
401%union {
402 std::string* String;
Reid Spencer52402b02007-01-02 05:45:11 +0000403 TypeInfo* Type;
Reid Spencere77e35e2006-12-01 20:26:20 +0000404 ValueInfo Value;
405 ConstInfo Const;
Reid Spencerf8483652006-12-02 15:16:01 +0000406 ValueList* ValList;
Reid Spencer52402b02007-01-02 05:45:11 +0000407 TypeList* TypeVec;
Reid Spencere77e35e2006-12-01 20:26:20 +0000408}
409
Reid Spencerf2d55322006-12-01 21:52:30 +0000410%token <Type> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
Reid Spencera50d5962006-12-02 04:11:07 +0000411%token <Type> FLOAT DOUBLE LABEL
412%token <String> OPAQUE ESINT64VAL EUINT64VAL SINTVAL UINTVAL FPVAL
Reid Spencerf2d55322006-12-01 21:52:30 +0000413%token <String> NULL_TOK UNDEF ZEROINITIALIZER TRUETOK FALSETOK
Reid Spencere77e35e2006-12-01 20:26:20 +0000414%token <String> TYPE VAR_ID LABELSTR STRINGCONSTANT
415%token <String> IMPLEMENTATION BEGINTOK ENDTOK
Reid Spencer71d2ec92006-12-31 06:02:26 +0000416%token <String> DECLARE GLOBAL CONSTANT SECTION VOLATILE
Reid Spencere77e35e2006-12-01 20:26:20 +0000417%token <String> TO DOTDOTDOT CONST INTERNAL LINKONCE WEAK
418%token <String> DLLIMPORT DLLEXPORT EXTERN_WEAK APPENDING
419%token <String> NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG
Reid Spencer78720742006-12-02 20:21:22 +0000420%token <String> ALIGN UNINITIALIZED
Reid Spencere77e35e2006-12-01 20:26:20 +0000421%token <String> DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
422%token <String> CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK
423%token <String> X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
424%token <String> DATALAYOUT
Reid Spencer78720742006-12-02 20:21:22 +0000425%token <String> RET BR SWITCH INVOKE EXCEPT UNWIND UNREACHABLE
426%token <String> ADD SUB MUL DIV UDIV SDIV FDIV REM UREM SREM FREM AND OR XOR
Reid Spencere77e35e2006-12-01 20:26:20 +0000427%token <String> SETLE SETGE SETLT SETGT SETEQ SETNE // Binary Comparators
Reid Spencer229e9362006-12-02 22:14:11 +0000428%token <String> ICMP FCMP EQ NE SLT SGT SLE SGE OEQ ONE OLT OGT OLE OGE
429%token <String> ORD UNO UEQ UNE ULT UGT ULE UGE
Reid Spencere77e35e2006-12-01 20:26:20 +0000430%token <String> MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR
Reid Spencerf7bde222006-12-01 22:26:37 +0000431%token <String> PHI_TOK SELECT SHL SHR ASHR LSHR VAARG
Reid Spencere77e35e2006-12-01 20:26:20 +0000432%token <String> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
Reid Spencerfcb5df82006-12-01 22:34:43 +0000433%token <String> CAST TRUNC ZEXT SEXT FPTRUNC FPEXT FPTOUI FPTOSI UITOFP SITOFP
434%token <String> PTRTOINT INTTOPTR BITCAST
Reid Spencere77e35e2006-12-01 20:26:20 +0000435
436%type <String> OptAssign OptLinkage OptCallingConv OptAlign OptCAlign
437%type <String> SectionString OptSection GlobalVarAttributes GlobalVarAttribute
Reid Spencer52402b02007-01-02 05:45:11 +0000438%type <String> ConstExpr DefinitionList
Reid Spencere77e35e2006-12-01 20:26:20 +0000439%type <String> ConstPool TargetDefinition LibrariesDefinition LibList OptName
440%type <String> ArgVal ArgListH ArgList FunctionHeaderH BEGIN FunctionHeader END
Reid Spencer52402b02007-01-02 05:45:11 +0000441%type <String> Function FunctionProto BasicBlock
442%type <String> InstructionList BBTerminatorInst JumpTable Inst
443%type <String> OptTailCall OptVolatile Unwind
444%type <String> SymbolicValueRef OptSideEffect GlobalType
Reid Spencere77e35e2006-12-01 20:26:20 +0000445%type <String> FnDeclareLinkage BasicBlockList BigOrLittle AsmBlock
Reid Spencer78720742006-12-02 20:21:22 +0000446%type <String> Name ConstValueRef ConstVector External
Reid Spencer57f28f92006-12-03 07:10:26 +0000447%type <String> ShiftOps SetCondOps LogicalOps ArithmeticOps CastOps
448%type <String> IPredicates FPredicates
Reid Spencere77e35e2006-12-01 20:26:20 +0000449
Reid Spencerf8483652006-12-02 15:16:01 +0000450%type <ValList> ValueRefList ValueRefListE IndexList
Reid Spencer52402b02007-01-02 05:45:11 +0000451%type <TypeVec> TypeListI ArgTypeListI
Reid Spencere77e35e2006-12-01 20:26:20 +0000452
453%type <Type> IntType SIntType UIntType FPType TypesV Types
454%type <Type> PrimType UpRTypesV UpRTypes
455
Reid Spencerf2d55322006-12-01 21:52:30 +0000456%type <String> IntVal EInt64Val
457%type <Const> ConstVal
Reid Spencere77e35e2006-12-01 20:26:20 +0000458
Reid Spencer52402b02007-01-02 05:45:11 +0000459%type <Value> ValueRef ResolvedVal InstVal PHIList MemoryInst
Reid Spencere7c3c602006-11-30 06:36:44 +0000460
461%start Module
462
463%%
464
465// Handle constant integer size restriction and conversion...
Reid Spencerf2d55322006-12-01 21:52:30 +0000466IntVal : SINTVAL | UINTVAL ;
Reid Spencere77e35e2006-12-01 20:26:20 +0000467EInt64Val : ESINT64VAL | EUINT64VAL;
Reid Spencere7c3c602006-11-30 06:36:44 +0000468
469// Operations that are notably excluded from this list include:
470// RET, BR, & SWITCH because they end basic blocks and are treated specially.
Reid Spencer78720742006-12-02 20:21:22 +0000471ArithmeticOps: ADD | SUB | MUL | DIV | UDIV | SDIV | FDIV
472 | REM | UREM | SREM | FREM;
Reid Spencere7c3c602006-11-30 06:36:44 +0000473LogicalOps : AND | OR | XOR;
474SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE;
Reid Spencer57f28f92006-12-03 07:10:26 +0000475IPredicates : EQ | NE | SLT | SGT | SLE | SGE | ULT | UGT | ULE | UGE;
476FPredicates : OEQ | ONE | OLT | OGT | OLE | OGE | ORD | UNO | UEQ | UNE
477 | ULT | UGT | ULE | UGE | TRUETOK | FALSETOK;
Reid Spencerf7bde222006-12-01 22:26:37 +0000478ShiftOps : SHL | SHR | ASHR | LSHR;
Reid Spencerfcb5df82006-12-01 22:34:43 +0000479CastOps : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | FPTOUI | FPTOSI |
480 UITOFP | SITOFP | PTRTOINT | INTTOPTR | BITCAST | CAST
481 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000482
483// These are some types that allow classification if we only want a particular
484// thing... for example, only a signed, unsigned, or integral type.
485SIntType : LONG | INT | SHORT | SBYTE;
486UIntType : ULONG | UINT | USHORT | UBYTE;
487IntType : SIntType | UIntType;
488FPType : FLOAT | DOUBLE;
489
490// OptAssign - Value producing statements have an optional assignment component
491OptAssign : Name '=' {
Reid Spencere7c3c602006-11-30 06:36:44 +0000492 $$ = $1;
493 }
494 | /*empty*/ {
495 $$ = new std::string("");
496 };
497
498OptLinkage
499 : INTERNAL | LINKONCE | WEAK | APPENDING | DLLIMPORT | DLLEXPORT
500 | EXTERN_WEAK
501 | /*empty*/ { $$ = new std::string(""); } ;
502
503OptCallingConv
504 : CCC_TOK | CSRETCC_TOK | FASTCC_TOK | COLDCC_TOK | X86_STDCALLCC_TOK
Reid Spencer16244f42006-12-01 21:10:07 +0000505 | X86_FASTCALLCC_TOK
506 | CC_TOK EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000507 *$1 += *$2;
508 delete $2;
Reid Spencer16244f42006-12-01 21:10:07 +0000509 $$ = $1;
510 }
Reid Spencere7c3c602006-11-30 06:36:44 +0000511 | /*empty*/ { $$ = new std::string(""); } ;
512
513// OptAlign/OptCAlign - An optional alignment, and an optional alignment with
514// a comma before it.
515OptAlign
516 : /*empty*/ { $$ = new std::string(); }
Reid Spencerf2d55322006-12-01 21:52:30 +0000517 | ALIGN EUINT64VAL { *$1 += " " + *$2; delete $2; $$ = $1; };
Reid Spencerf0cf1322006-12-07 04:23:03 +0000518
Reid Spencere7c3c602006-11-30 06:36:44 +0000519OptCAlign
520 : /*empty*/ { $$ = new std::string(); }
521 | ',' ALIGN EUINT64VAL {
522 $2->insert(0, ", ");
Reid Spencerf2d55322006-12-01 21:52:30 +0000523 *$2 += " " + *$3;
524 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000525 $$ = $2;
526 };
527
528SectionString
529 : SECTION STRINGCONSTANT {
530 *$1 += " " + *$2;
531 delete $2;
532 $$ = $1;
533 };
534
535OptSection : /*empty*/ { $$ = new std::string(); }
536 | SectionString;
537
538GlobalVarAttributes
539 : /* empty */ { $$ = new std::string(); }
540 | ',' GlobalVarAttribute GlobalVarAttributes {
541 $2->insert(0, ", ");
542 if (!$3->empty())
543 *$2 += " " + *$3;
544 delete $3;
545 $$ = $2;
546 };
547
548GlobalVarAttribute
549 : SectionString
550 | ALIGN EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000551 *$1 += " " + *$2;
552 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000553 $$ = $1;
554 };
555
556//===----------------------------------------------------------------------===//
557// Types includes all predefined types... except void, because it can only be
558// used in specific contexts (function returning void for example). To have
559// access to it, a user must explicitly use TypesV.
560//
561
562// TypesV includes all of 'Types', but it also includes the void type.
563TypesV : Types | VOID ;
564UpRTypesV : UpRTypes | VOID ;
565Types : UpRTypes ;
566
567// Derived types are added later...
568//
569PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ;
Reid Spencere77e35e2006-12-01 20:26:20 +0000570PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL;
Reid Spencera50d5962006-12-02 04:11:07 +0000571UpRTypes
572 : OPAQUE {
Reid Spencer52402b02007-01-02 05:45:11 +0000573 $$ = new TypeInfo($1, OpaqueTy);
Reid Spencera50d5962006-12-02 04:11:07 +0000574 }
575 | SymbolicValueRef {
Reid Spencer52402b02007-01-02 05:45:11 +0000576 $$ = new TypeInfo($1, UnresolvedTy);
Reid Spencera50d5962006-12-02 04:11:07 +0000577 }
Reid Spencer78720742006-12-02 20:21:22 +0000578 | PrimType {
579 $$ = $1;
580 }
581 | '\\' EUINT64VAL { // Type UpReference
Reid Spencerf2d55322006-12-01 21:52:30 +0000582 $2->insert(0, "\\");
Reid Spencereff838e2007-01-03 23:45:42 +0000583 $$ = new TypeInfo($2, UpRefTy);
Reid Spencere7c3c602006-11-30 06:36:44 +0000584 }
585 | UpRTypesV '(' ArgTypeListI ')' { // Function derived type?
Reid Spencer52402b02007-01-02 05:45:11 +0000586 std::string newTy( $1->getNewTy() + "(");
587 for (unsigned i = 0; i < $3->size(); ++i) {
588 if (i != 0)
589 newTy += ", ";
590 if ((*$3)[i]->isVoid())
591 newTy += "...";
592 else
593 newTy += (*$3)[i]->getNewTy();
594 }
595 newTy += ")";
596 $$ = new TypeInfo(new std::string(newTy), $1, $3);
Reid Spencere7c3c602006-11-30 06:36:44 +0000597 }
598 | '[' EUINT64VAL 'x' UpRTypes ']' { // Sized array type?
Reid Spencerf2d55322006-12-01 21:52:30 +0000599 $2->insert(0,"[ ");
Reid Spencer52402b02007-01-02 05:45:11 +0000600 *$2 += " x " + $4->getNewTy() + " ]";
601 uint64_t elems = atoi($2->c_str());
602 $$ = new TypeInfo($2, ArrayTy, $4, elems);
Reid Spencere7c3c602006-11-30 06:36:44 +0000603 }
604 | '<' EUINT64VAL 'x' UpRTypes '>' { // Packed array type?
Reid Spencerf2d55322006-12-01 21:52:30 +0000605 $2->insert(0,"< ");
Reid Spencer52402b02007-01-02 05:45:11 +0000606 *$2 += " x " + $4->getNewTy() + " >";
607 uint64_t elems = atoi($2->c_str());
608 $$ = new TypeInfo($2, PackedTy, $4, elems);
Reid Spencere7c3c602006-11-30 06:36:44 +0000609 }
610 | '{' TypeListI '}' { // Structure type?
Reid Spencer52402b02007-01-02 05:45:11 +0000611 std::string newTy("{");
612 for (unsigned i = 0; i < $2->size(); ++i) {
613 if (i != 0)
614 newTy += ", ";
615 newTy += (*$2)[i]->getNewTy();
616 }
617 newTy += "}";
618 $$ = new TypeInfo(new std::string(newTy), StructTy, $2);
Reid Spencere7c3c602006-11-30 06:36:44 +0000619 }
620 | '{' '}' { // Empty structure type?
Reid Spencer52402b02007-01-02 05:45:11 +0000621 $$ = new TypeInfo(new std::string("{}"), StructTy, new TypeList());
Reid Spencere7c3c602006-11-30 06:36:44 +0000622 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000623 | '<' '{' TypeListI '}' '>' { // Packed Structure type?
Reid Spencer52402b02007-01-02 05:45:11 +0000624 std::string newTy("<{");
625 for (unsigned i = 0; i < $3->size(); ++i) {
626 if (i != 0)
627 newTy += ", ";
628 newTy += (*$3)[i]->getNewTy();
629 }
630 newTy += "}>";
631 $$ = new TypeInfo(new std::string(newTy), PackedStructTy, $3);
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000632 }
633 | '<' '{' '}' '>' { // Empty packed structure type?
Reid Spencer52402b02007-01-02 05:45:11 +0000634 $$ = new TypeInfo(new std::string("<{}>"), PackedStructTy, new TypeList());
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000635 }
Reid Spencere7c3c602006-11-30 06:36:44 +0000636 | UpRTypes '*' { // Pointer type?
Reid Spencer52402b02007-01-02 05:45:11 +0000637 $$ = $1->getPointerType();
Reid Spencere7c3c602006-11-30 06:36:44 +0000638 };
639
640// TypeList - Used for struct declarations and as a basis for function type
641// declaration type lists
642//
Reid Spencere77e35e2006-12-01 20:26:20 +0000643TypeListI
644 : UpRTypes {
Reid Spencer52402b02007-01-02 05:45:11 +0000645 $$ = new TypeList();
646 $$->push_back($1);
Reid Spencere77e35e2006-12-01 20:26:20 +0000647 }
648 | TypeListI ',' UpRTypes {
Reid Spencere7c3c602006-11-30 06:36:44 +0000649 $$ = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000650 $$->push_back($3);
Reid Spencere7c3c602006-11-30 06:36:44 +0000651 };
652
653// ArgTypeList - List of types for a function type declaration...
Reid Spencere77e35e2006-12-01 20:26:20 +0000654ArgTypeListI
655 : TypeListI
Reid Spencere7c3c602006-11-30 06:36:44 +0000656 | TypeListI ',' DOTDOTDOT {
Reid Spencere7c3c602006-11-30 06:36:44 +0000657 $$ = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000658 $$->push_back(new TypeInfo("void",VoidTy));
659 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000660 }
661 | DOTDOTDOT {
Reid Spencer52402b02007-01-02 05:45:11 +0000662 $$ = new TypeList();
663 $$->push_back(new TypeInfo("void",VoidTy));
664 delete $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000665 }
666 | /*empty*/ {
Reid Spencer52402b02007-01-02 05:45:11 +0000667 $$ = new TypeList();
Reid Spencere7c3c602006-11-30 06:36:44 +0000668 };
669
670// ConstVal - The various declarations that go into the constant pool. This
671// production is used ONLY to represent constants that show up AFTER a 'const',
672// 'constant' or 'global' token at global scope. Constants that can be inlined
673// into other expressions (such as integers and constexprs) are handled by the
674// ResolvedVal, ValueRef and ConstValueRef productions.
675//
676ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
Reid Spencere77e35e2006-12-01 20:26:20 +0000677 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000678 $$.cnst = new std::string($1->getNewTy());
Reid Spencere77e35e2006-12-01 20:26:20 +0000679 *$$.cnst += " [ " + *$3 + " ]";
Reid Spencere7c3c602006-11-30 06:36:44 +0000680 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000681 }
682 | Types '[' ']' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000683 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000684 $$.cnst = new std::string($1->getNewTy());
Reid Spencere77e35e2006-12-01 20:26:20 +0000685 *$$.cnst += "[ ]";
Reid Spencere7c3c602006-11-30 06:36:44 +0000686 }
687 | Types 'c' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000688 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000689 $$.cnst = new std::string($1->getNewTy());
Reid Spencere77e35e2006-12-01 20:26:20 +0000690 *$$.cnst += " c" + *$3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000691 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000692 }
693 | Types '<' ConstVector '>' { // Nonempty unsized arr
Reid Spencere77e35e2006-12-01 20:26:20 +0000694 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000695 $$.cnst = new std::string($1->getNewTy());
Reid Spencere77e35e2006-12-01 20:26:20 +0000696 *$$.cnst += " < " + *$3 + " >";
Reid Spencere7c3c602006-11-30 06:36:44 +0000697 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000698 }
699 | Types '{' ConstVector '}' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000700 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000701 $$.cnst = new std::string($1->getNewTy());
Reid Spencere77e35e2006-12-01 20:26:20 +0000702 *$$.cnst += " { " + *$3 + " }";
Reid Spencere7c3c602006-11-30 06:36:44 +0000703 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000704 }
705 | Types '{' '}' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000706 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000707 $$.cnst = new std::string($1->getNewTy());
Reid Spencer0b7e5072006-12-01 22:42:01 +0000708 *$$.cnst += " {}";
Reid Spencere7c3c602006-11-30 06:36:44 +0000709 }
710 | Types NULL_TOK {
Reid Spencere77e35e2006-12-01 20:26:20 +0000711 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000712 $$.cnst = new std::string($1->getNewTy());
Reid Spencerf2d55322006-12-01 21:52:30 +0000713 *$$.cnst += " " + *$2;
714 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000715 }
716 | Types UNDEF {
Reid Spencere77e35e2006-12-01 20:26:20 +0000717 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000718 $$.cnst = new std::string($1->getNewTy());
Reid Spencerf2d55322006-12-01 21:52:30 +0000719 *$$.cnst += " " + *$2;
720 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000721 }
722 | Types SymbolicValueRef {
Reid Spencer52402b02007-01-02 05:45:11 +0000723 std::string Name = getUniqueName($2,$1);
Reid Spencere77e35e2006-12-01 20:26:20 +0000724 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000725 $$.cnst = new std::string($1->getNewTy());
726 *$$.cnst += " " + Name;
Reid Spencere7c3c602006-11-30 06:36:44 +0000727 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000728 }
729 | Types ConstExpr {
Reid Spencere77e35e2006-12-01 20:26:20 +0000730 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000731 $$.cnst = new std::string($1->getNewTy());
Reid Spencere77e35e2006-12-01 20:26:20 +0000732 *$$.cnst += " " + *$2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000733 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000734 }
735 | Types ZEROINITIALIZER {
Reid Spencere77e35e2006-12-01 20:26:20 +0000736 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000737 $$.cnst = new std::string($1->getNewTy());
Reid Spencerf2d55322006-12-01 21:52:30 +0000738 *$$.cnst += " " + *$2;
739 delete $2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000740 }
741 | SIntType EInt64Val { // integral constants
742 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000743 $$.cnst = new std::string($1->getNewTy());
Reid Spencerf2d55322006-12-01 21:52:30 +0000744 *$$.cnst += " " + *$2;
745 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000746 }
Reid Spencer7356ae42007-01-02 06:34:08 +0000747 | UIntType EInt64Val { // integral constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000748 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000749 $$.cnst = new std::string($1->getNewTy());
Reid Spencerf2d55322006-12-01 21:52:30 +0000750 *$$.cnst += " " + *$2;
751 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000752 }
753 | BOOL TRUETOK { // Boolean constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000754 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000755 $$.cnst = new std::string($1->getNewTy());
Reid Spencerf2d55322006-12-01 21:52:30 +0000756 *$$.cnst += " " + *$2;
757 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000758 }
759 | BOOL FALSETOK { // Boolean constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000760 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000761 $$.cnst = new std::string($1->getNewTy());
Reid Spencerf2d55322006-12-01 21:52:30 +0000762 *$$.cnst += " " + *$2;
763 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000764 }
765 | FPType FPVAL { // Float & Double constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000766 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000767 $$.cnst = new std::string($1->getNewTy());
Reid Spencerf2d55322006-12-01 21:52:30 +0000768 *$$.cnst += " " + *$2;
769 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000770 };
771
772
Reid Spencerfcb5df82006-12-01 22:34:43 +0000773ConstExpr: CastOps '(' ConstVal TO Types ')' {
Reid Spencer280d8012006-12-01 23:40:53 +0000774 std::string source = *$3.cnst;
Reid Spencer52402b02007-01-02 05:45:11 +0000775 TypeInfo* DstTy = ResolveType($5);
Reid Spencer280d8012006-12-01 23:40:53 +0000776 if (*$1 == "cast") {
Reid Spencera50d5962006-12-02 04:11:07 +0000777 // Call getCastUpgrade to upgrade the old cast
Reid Spencer52402b02007-01-02 05:45:11 +0000778 $$ = new std::string(getCastUpgrade(source, $3.type, DstTy, true));
Reid Spencera50d5962006-12-02 04:11:07 +0000779 } else {
780 // Nothing to upgrade, just create the cast constant expr
781 $$ = new std::string(*$1);
Reid Spencer52402b02007-01-02 05:45:11 +0000782 *$$ += "( " + source + " to " + $5->getNewTy() + ")";
Reid Spencer280d8012006-12-01 23:40:53 +0000783 }
Reid Spencereff838e2007-01-03 23:45:42 +0000784 delete $1; $3.destroy(); delete $4;
Reid Spencere7c3c602006-11-30 06:36:44 +0000785 }
786 | GETELEMENTPTR '(' ConstVal IndexList ')' {
Reid Spencerf8483652006-12-02 15:16:01 +0000787 *$1 += "(" + *$3.cnst;
788 for (unsigned i = 0; i < $4->size(); ++i) {
789 ValueInfo& VI = (*$4)[i];
790 *$1 += ", " + *VI.val;
791 VI.destroy();
792 }
793 *$1 += ")";
Reid Spencere77e35e2006-12-01 20:26:20 +0000794 $$ = $1;
795 $3.destroy();
796 delete $4;
Reid Spencere7c3c602006-11-30 06:36:44 +0000797 }
798 | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000799 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
800 $3.destroy(); $5.destroy(); $7.destroy();
801 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000802 }
803 | ArithmeticOps '(' ConstVal ',' ConstVal ')' {
Reid Spencer78720742006-12-02 20:21:22 +0000804 const char* op = getDivRemOpcode(*$1, $3.type);
805 $$ = new std::string(op);
806 *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
807 delete $1; $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000808 }
809 | LogicalOps '(' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000810 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
811 $3.destroy(); $5.destroy();
812 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000813 }
814 | SetCondOps '(' ConstVal ',' ConstVal ')' {
Reid Spencer229e9362006-12-02 22:14:11 +0000815 *$1 = getCompareOp(*$1, $3.type);
Reid Spencere77e35e2006-12-01 20:26:20 +0000816 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
817 $3.destroy(); $5.destroy();
818 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000819 }
Reid Spencer57f28f92006-12-03 07:10:26 +0000820 | ICMP IPredicates '(' ConstVal ',' ConstVal ')' {
821 *$1 += "(" + *$2 + "," + *$4.cnst + "," + *$6.cnst + ")";
822 delete $2; $4.destroy(); $6.destroy();
823 $$ = $1;
824 }
825 | FCMP FPredicates '(' ConstVal ',' ConstVal ')' {
Reid Spencer229e9362006-12-02 22:14:11 +0000826 *$1 += "(" + *$2 + "," + *$4.cnst + "," + *$6.cnst + ")";
827 delete $2; $4.destroy(); $6.destroy();
828 $$ = $1;
829 }
Reid Spencere7c3c602006-11-30 06:36:44 +0000830 | ShiftOps '(' ConstVal ',' ConstVal ')' {
Reid Spencerf7bde222006-12-01 22:26:37 +0000831 const char* shiftop = $1->c_str();
832 if (*$1 == "shr")
Reid Spencer52402b02007-01-02 05:45:11 +0000833 shiftop = ($3.type->isUnsigned()) ? "lshr" : "ashr";
Reid Spencerf7bde222006-12-01 22:26:37 +0000834 $$ = new std::string(shiftop);
835 *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
836 delete $1; $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000837 }
838 | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000839 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
840 $3.destroy(); $5.destroy();
841 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000842 }
843 | INSERTELEMENT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000844 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
845 $3.destroy(); $5.destroy(); $7.destroy();
846 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000847 }
848 | SHUFFLEVECTOR '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000849 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
850 $3.destroy(); $5.destroy(); $7.destroy();
851 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000852 };
853
854
855// ConstVector - A list of comma separated constants.
Reid Spencere77e35e2006-12-01 20:26:20 +0000856
857ConstVector
858 : ConstVector ',' ConstVal {
859 *$1 += ", " + *$3.cnst;
860 $3.destroy();
861 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000862 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000863 | ConstVal { $$ = new std::string(*$1.cnst); $1.destroy(); }
864 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000865
866
867// GlobalType - Match either GLOBAL or CONSTANT for global declarations...
Reid Spencere77e35e2006-12-01 20:26:20 +0000868GlobalType : GLOBAL | CONSTANT ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000869
870
871//===----------------------------------------------------------------------===//
872// Rules to match Modules
873//===----------------------------------------------------------------------===//
874
875// Module rule: Capture the result of parsing the whole file into a result
876// variable...
877//
878Module : DefinitionList {
879};
880
881// DefinitionList - Top level definitions
882//
883DefinitionList : DefinitionList Function {
884 $$ = 0;
885 }
886 | DefinitionList FunctionProto {
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000887 *O << *$2 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +0000888 delete $2;
889 $$ = 0;
890 }
891 | DefinitionList MODULE ASM_TOK AsmBlock {
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000892 *O << "module asm " << ' ' << *$4 << '\n';
Reid Spencerd154b572006-12-01 20:36:40 +0000893 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000894 }
895 | DefinitionList IMPLEMENTATION {
896 *O << "implementation\n";
Reid Spencerd154b572006-12-01 20:36:40 +0000897 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000898 }
Reid Spencera50d5962006-12-02 04:11:07 +0000899 | ConstPool { $$ = 0; }
Reid Spencere7c3c602006-11-30 06:36:44 +0000900
Reid Spencer78720742006-12-02 20:21:22 +0000901External : EXTERNAL | UNINITIALIZED { $$ = $1; *$$ = "external"; }
902
Reid Spencere7c3c602006-11-30 06:36:44 +0000903// ConstPool - Constants with optional names assigned to them.
904ConstPool : ConstPool OptAssign TYPE TypesV {
Reid Spencer52402b02007-01-02 05:45:11 +0000905 EnumeratedTypes.push_back(*$4);
Reid Spencera50d5962006-12-02 04:11:07 +0000906 if (!$2->empty()) {
Reid Spencer52402b02007-01-02 05:45:11 +0000907 NamedTypes[*$2] = *$4;
Reid Spencera50d5962006-12-02 04:11:07 +0000908 *O << *$2 << " = ";
909 }
Reid Spencer52402b02007-01-02 05:45:11 +0000910 *O << "type " << $4->getNewTy() << '\n';
911 delete $2; delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000912 $$ = 0;
913 }
914 | ConstPool FunctionProto { // Function prototypes can be in const pool
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000915 *O << *$2 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +0000916 delete $2;
917 $$ = 0;
918 }
919 | ConstPool MODULE ASM_TOK AsmBlock { // Asm blocks can be in the const pool
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000920 *O << *$2 << ' ' << *$3 << ' ' << *$4 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +0000921 delete $2; delete $3; delete $4;
922 $$ = 0;
923 }
924 | ConstPool OptAssign OptLinkage GlobalType ConstVal GlobalVarAttributes {
Reid Spencerf12ee422006-12-05 19:21:25 +0000925 if (!$2->empty()) {
Reid Spencer52402b02007-01-02 05:45:11 +0000926 std::string Name = getUniqueName($2,$5.type);
927 *O << Name << " = ";
928 Globals[Name] = *$5.type;
Reid Spencerf12ee422006-12-05 19:21:25 +0000929 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000930 *O << *$3 << ' ' << *$4 << ' ' << *$5.cnst << ' ' << *$6 << '\n';
Reid Spencer52402b02007-01-02 05:45:11 +0000931 delete $2; delete $3; delete $4; delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000932 $$ = 0;
933 }
Reid Spencer78720742006-12-02 20:21:22 +0000934 | ConstPool OptAssign External GlobalType Types GlobalVarAttributes {
Reid Spencerf12ee422006-12-05 19:21:25 +0000935 if (!$2->empty()) {
Reid Spencer52402b02007-01-02 05:45:11 +0000936 std::string Name = getUniqueName($2,$5);
937 *O << Name << " = ";
938 Globals[Name] = *$5;
Reid Spencerf12ee422006-12-05 19:21:25 +0000939 }
Reid Spencer52402b02007-01-02 05:45:11 +0000940 *O << *$3 << ' ' << *$4 << ' ' << $5->getNewTy() << ' ' << *$6 << '\n';
941 delete $2; delete $3; delete $4; delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000942 $$ = 0;
943 }
944 | ConstPool OptAssign DLLIMPORT GlobalType Types GlobalVarAttributes {
Reid Spencerf12ee422006-12-05 19:21:25 +0000945 if (!$2->empty()) {
Reid Spencer52402b02007-01-02 05:45:11 +0000946 std::string Name = getUniqueName($2,$5);
947 *O << Name << " = ";
948 Globals[Name] = *$5;
Reid Spencerf12ee422006-12-05 19:21:25 +0000949 }
Reid Spencer52402b02007-01-02 05:45:11 +0000950 *O << *$3 << ' ' << *$4 << ' ' << $5->getNewTy() << ' ' << *$6 << '\n';
951 delete $2; delete $3; delete $4; delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000952 $$ = 0;
953 }
954 | ConstPool OptAssign EXTERN_WEAK GlobalType Types GlobalVarAttributes {
Reid Spencerf12ee422006-12-05 19:21:25 +0000955 if (!$2->empty()) {
Reid Spencer52402b02007-01-02 05:45:11 +0000956 std::string Name = getUniqueName($2,$5);
957 *O << Name << " = ";
958 Globals[Name] = *$5;
Reid Spencerf12ee422006-12-05 19:21:25 +0000959 }
Reid Spencer52402b02007-01-02 05:45:11 +0000960 *O << *$3 << ' ' << *$4 << ' ' << $5->getNewTy() << ' ' << *$6 << '\n';
961 delete $2; delete $3; delete $4; delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000962 $$ = 0;
963 }
964 | ConstPool TARGET TargetDefinition {
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000965 *O << *$2 << ' ' << *$3 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +0000966 delete $2; delete $3;
967 $$ = 0;
968 }
969 | ConstPool DEPLIBS '=' LibrariesDefinition {
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000970 *O << *$2 << " = " << *$4 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +0000971 delete $2; delete $4;
972 $$ = 0;
973 }
974 | /* empty: end of list */ {
975 $$ = 0;
976 };
977
978
979AsmBlock : STRINGCONSTANT ;
980
981BigOrLittle : BIG | LITTLE
982
983TargetDefinition
984 : ENDIAN '=' BigOrLittle {
Reid Spencere77e35e2006-12-01 20:26:20 +0000985 *$1 += " = " + *$3;
986 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000987 $$ = $1;
988 }
989 | POINTERSIZE '=' EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000990 *$1 += " = " + *$3;
991 if (*$3 == "64")
Reid Spencere77e35e2006-12-01 20:26:20 +0000992 SizeOfPointer = 64;
Reid Spencerf2d55322006-12-01 21:52:30 +0000993 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000994 $$ = $1;
995 }
996 | TRIPLE '=' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000997 *$1 += " = " + *$3;
998 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000999 $$ = $1;
1000 }
1001 | DATALAYOUT '=' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +00001002 *$1 += " = " + *$3;
1003 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001004 $$ = $1;
1005 };
1006
1007LibrariesDefinition
1008 : '[' LibList ']' {
1009 $2->insert(0, "[ ");
1010 *$2 += " ]";
1011 $$ = $2;
1012 };
1013
1014LibList
1015 : LibList ',' STRINGCONSTANT {
1016 *$1 += ", " + *$3;
1017 delete $3;
1018 $$ = $1;
1019 }
1020 | STRINGCONSTANT
1021 | /* empty: end of list */ {
1022 $$ = new std::string();
1023 };
1024
1025//===----------------------------------------------------------------------===//
1026// Rules to match Function Headers
1027//===----------------------------------------------------------------------===//
1028
1029Name : VAR_ID | STRINGCONSTANT;
1030OptName : Name | /*empty*/ { $$ = new std::string(); };
1031
1032ArgVal : Types OptName {
Reid Spencer52402b02007-01-02 05:45:11 +00001033 $$ = new std::string($1->getNewTy());
1034 if (!$2->empty()) {
1035 std::string Name = getUniqueName($2, $1);
1036 *$$ += " " + Name;
1037 }
Reid Spencere77e35e2006-12-01 20:26:20 +00001038 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +00001039};
1040
1041ArgListH : ArgListH ',' ArgVal {
1042 *$1 += ", " + *$3;
Reid Spencere77e35e2006-12-01 20:26:20 +00001043 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001044 }
1045 | ArgVal {
1046 $$ = $1;
1047 };
1048
1049ArgList : ArgListH {
1050 $$ = $1;
1051 }
1052 | ArgListH ',' DOTDOTDOT {
1053 *$1 += ", ...";
1054 $$ = $1;
Reid Spencere77e35e2006-12-01 20:26:20 +00001055 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001056 }
1057 | DOTDOTDOT {
1058 $$ = $1;
1059 }
Reid Spencerd154b572006-12-01 20:36:40 +00001060 | /* empty */ { $$ = new std::string(); };
Reid Spencere7c3c602006-11-30 06:36:44 +00001061
Reid Spencer71d2ec92006-12-31 06:02:26 +00001062FunctionHeaderH
1063 : OptCallingConv TypesV Name '(' ArgList ')' OptSection OptAlign {
Reid Spencere7c3c602006-11-30 06:36:44 +00001064 if (!$1->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +00001065 *$1 += " ";
Reid Spencere7c3c602006-11-30 06:36:44 +00001066 }
Reid Spencer52402b02007-01-02 05:45:11 +00001067 *$1 += $2->getNewTy() + " " + *$3 + "(" + *$5 + ")";
Reid Spencere7c3c602006-11-30 06:36:44 +00001068 if (!$7->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +00001069 *$1 += " " + *$7;
Reid Spencere7c3c602006-11-30 06:36:44 +00001070 }
1071 if (!$8->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +00001072 *$1 += " " + *$8;
Reid Spencere7c3c602006-11-30 06:36:44 +00001073 }
Reid Spencere77e35e2006-12-01 20:26:20 +00001074 delete $3;
1075 delete $5;
1076 delete $7;
1077 delete $8;
1078 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +00001079 };
1080
Reid Spencer78720742006-12-02 20:21:22 +00001081BEGIN : BEGINTOK { $$ = new std::string("{"); delete $1; }
1082 | '{' { $$ = new std::string ("{"); }
Reid Spencere7c3c602006-11-30 06:36:44 +00001083
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001084FunctionHeader
1085 : OptLinkage FunctionHeaderH BEGIN {
1086 *O << "define ";
1087 if (!$1->empty()) {
1088 *O << *$1 << ' ';
1089 }
1090 *O << *$2 << ' ' << *$3 << '\n';
1091 delete $1; delete $2; delete $3;
1092 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +00001093 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001094 ;
Reid Spencere7c3c602006-11-30 06:36:44 +00001095
Reid Spencer78720742006-12-02 20:21:22 +00001096END : ENDTOK { $$ = new std::string("}"); delete $1; }
Reid Spencere7c3c602006-11-30 06:36:44 +00001097 | '}' { $$ = new std::string("}"); };
1098
1099Function : FunctionHeader BasicBlockList END {
1100 if ($2)
1101 *O << *$2;
Reid Spencer71d2ec92006-12-31 06:02:26 +00001102 *O << *$3 << "\n\n";
Reid Spencer52402b02007-01-02 05:45:11 +00001103 delete $1; delete $2; delete $3;
Reid Spencere77e35e2006-12-01 20:26:20 +00001104 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +00001105};
1106
Reid Spencere77e35e2006-12-01 20:26:20 +00001107FnDeclareLinkage
1108 : /*default*/ { $$ = new std::string(); }
Reid Spencere7c3c602006-11-30 06:36:44 +00001109 | DLLIMPORT
1110 | EXTERN_WEAK
1111 ;
1112
1113FunctionProto
1114 : DECLARE FnDeclareLinkage FunctionHeaderH {
Reid Spencere77e35e2006-12-01 20:26:20 +00001115 if (!$2->empty())
1116 *$1 += " " + *$2;
1117 *$1 += " " + *$3;
1118 delete $2;
1119 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001120 $$ = $1;
1121 };
1122
1123//===----------------------------------------------------------------------===//
1124// Rules to match Basic Blocks
1125//===----------------------------------------------------------------------===//
1126
Reid Spencerd154b572006-12-01 20:36:40 +00001127OptSideEffect : /* empty */ { $$ = new std::string(); }
1128 | SIDEEFFECT;
Reid Spencere7c3c602006-11-30 06:36:44 +00001129
Reid Spencere77e35e2006-12-01 20:26:20 +00001130ConstValueRef
Reid Spencerf2d55322006-12-01 21:52:30 +00001131 : ESINT64VAL | EUINT64VAL | FPVAL | TRUETOK | FALSETOK | NULL_TOK | UNDEF
1132 | ZEROINITIALIZER
Reid Spencere7c3c602006-11-30 06:36:44 +00001133 | '<' ConstVector '>' {
1134 $2->insert(0, "<");
1135 *$2 += ">";
1136 $$ = $2;
1137 }
1138 | ConstExpr
1139 | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT {
1140 if (!$2->empty()) {
1141 *$1 += " " + *$2;
1142 }
Reid Spencere77e35e2006-12-01 20:26:20 +00001143 *$1 += " " + *$3 + ", " + *$5;
1144 delete $2; delete $3; delete $5;
Reid Spencere7c3c602006-11-30 06:36:44 +00001145 $$ = $1;
1146 };
1147
Reid Spencerf2d55322006-12-01 21:52:30 +00001148SymbolicValueRef : IntVal | Name ;
Reid Spencere7c3c602006-11-30 06:36:44 +00001149
1150// ValueRef - A reference to a definition... either constant or symbolic
Reid Spencerf459d392006-12-02 16:19:52 +00001151ValueRef
1152 : SymbolicValueRef {
1153 $$.val = $1;
1154 $$.constant = false;
Reid Spencer52402b02007-01-02 05:45:11 +00001155 $$.type = new TypeInfo();
Reid Spencerf459d392006-12-02 16:19:52 +00001156 }
1157 | ConstValueRef {
1158 $$.val = $1;
1159 $$.constant = true;
Reid Spencer52402b02007-01-02 05:45:11 +00001160 $$.type = new TypeInfo();
Reid Spencerf459d392006-12-02 16:19:52 +00001161 }
1162 ;
Reid Spencere7c3c602006-11-30 06:36:44 +00001163
1164// ResolvedVal - a <type> <value> pair. This is used only in cases where the
1165// type immediately preceeds the value reference, and allows complex constant
1166// pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
1167ResolvedVal : Types ValueRef {
Reid Spencereff838e2007-01-03 23:45:42 +00001168 ResolveType($1);
Reid Spencer52402b02007-01-02 05:45:11 +00001169 std::string Name = getUniqueName($2.val, $1);
Reid Spencerf459d392006-12-02 16:19:52 +00001170 $$ = $2;
Reid Spencer52402b02007-01-02 05:45:11 +00001171 delete $$.val;
1172 delete $$.type;
1173 $$.val = new std::string($1->getNewTy() + " " + Name);
Reid Spencere77e35e2006-12-01 20:26:20 +00001174 $$.type = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +00001175 };
1176
1177BasicBlockList : BasicBlockList BasicBlock {
Reid Spencerf2d55322006-12-01 21:52:30 +00001178 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +00001179 }
1180 | BasicBlock { // Do not allow functions with 0 basic blocks
Reid Spencerf2d55322006-12-01 21:52:30 +00001181 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +00001182 };
1183
1184
1185// Basic blocks are terminated by branching instructions:
1186// br, br/cc, switch, ret
1187//
Reid Spencer16244f42006-12-01 21:10:07 +00001188BasicBlock : InstructionList BBTerminatorInst {
Reid Spencerf2d55322006-12-01 21:52:30 +00001189 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +00001190 };
1191
1192InstructionList : InstructionList Inst {
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001193 *O << " " << *$2 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +00001194 delete $2;
1195 $$ = 0;
1196 }
1197 | /* empty */ {
1198 $$ = 0;
1199 }
1200 | LABELSTR {
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001201 *O << *$1 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +00001202 delete $1;
1203 $$ = 0;
1204 };
1205
Reid Spencer78720742006-12-02 20:21:22 +00001206Unwind : UNWIND | EXCEPT { $$ = $1; *$$ = "unwind"; }
1207
Reid Spencere7c3c602006-11-30 06:36:44 +00001208BBTerminatorInst : RET ResolvedVal { // Return with a result...
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001209 *O << " " << *$1 << ' ' << *$2.val << '\n';
Reid Spencere77e35e2006-12-01 20:26:20 +00001210 delete $1; $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001211 $$ = 0;
1212 }
1213 | RET VOID { // Return with no result...
Reid Spencer52402b02007-01-02 05:45:11 +00001214 *O << " " << *$1 << ' ' << $2->getNewTy() << '\n';
1215 delete $1; delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +00001216 $$ = 0;
1217 }
1218 | BR LABEL ValueRef { // Unconditional Branch...
Reid Spencer52402b02007-01-02 05:45:11 +00001219 *O << " " << *$1 << ' ' << $2->getNewTy() << ' ' << *$3.val << '\n';
1220 delete $1; delete $2; $3.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001221 $$ = 0;
1222 } // Conditional Branch...
1223 | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {
Reid Spencer52402b02007-01-02 05:45:11 +00001224 std::string Name = getUniqueName($3.val, $2);
1225 *O << " " << *$1 << ' ' << $2->getNewTy() << ' ' << Name << ", "
1226 << $5->getNewTy() << ' ' << *$6.val << ", " << $8->getNewTy() << ' '
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001227 << *$9.val << '\n';
Reid Spencer52402b02007-01-02 05:45:11 +00001228 delete $1; delete $2; $3.destroy(); delete $5; $6.destroy();
1229 delete $8; $9.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001230 $$ = 0;
1231 }
1232 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
Reid Spencer52402b02007-01-02 05:45:11 +00001233 std::string Name = getUniqueName($3.val, $2);
1234 *O << " " << *$1 << ' ' << $2->getNewTy() << ' ' << Name << ", "
1235 << $5->getNewTy() << ' ' << *$6.val << " [" << *$8 << " ]\n";
1236 delete $1; delete $2; $3.destroy(); delete $5; $6.destroy();
Reid Spencerf459d392006-12-02 16:19:52 +00001237 delete $8;
Reid Spencere7c3c602006-11-30 06:36:44 +00001238 $$ = 0;
1239 }
1240 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' {
Reid Spencer52402b02007-01-02 05:45:11 +00001241 std::string Name = getUniqueName($3.val, $2);
1242 *O << " " << *$1 << ' ' << $2->getNewTy() << ' ' << Name << ", "
1243 << $5->getNewTy() << ' ' << *$6.val << "[]\n";
1244 delete $1; delete $2; $3.destroy(); delete $5; $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001245 $$ = 0;
1246 }
Reid Spencer16244f42006-12-01 21:10:07 +00001247 | OptAssign INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')'
Reid Spencer78720742006-12-02 20:21:22 +00001248 TO LABEL ValueRef Unwind LABEL ValueRef {
Reid Spencer52402b02007-01-02 05:45:11 +00001249 TypeInfo* ResTy = getFunctionReturnType($4);
Reid Spencer16244f42006-12-01 21:10:07 +00001250 *O << " ";
Reid Spencer52402b02007-01-02 05:45:11 +00001251 if (!$1->empty()) {
1252 std::string Name = getUniqueName($1, ResTy);
1253 *O << Name << " = ";
1254 }
1255 *O << *$2 << ' ' << *$3 << ' ' << $4->getNewTy() << ' ' << *$5.val << " (";
Reid Spencerf8483652006-12-02 15:16:01 +00001256 for (unsigned i = 0; i < $7->size(); ++i) {
1257 ValueInfo& VI = (*$7)[i];
1258 *O << *VI.val;
1259 if (i+1 < $7->size())
1260 *O << ", ";
1261 VI.destroy();
1262 }
Reid Spencer52402b02007-01-02 05:45:11 +00001263 *O << ") " << *$9 << ' ' << $10->getNewTy() << ' ' << *$11.val << ' '
1264 << *$12 << ' ' << $13->getNewTy() << ' ' << *$14.val << '\n';
1265 delete $1; delete $2; delete $3; delete $4; $5.destroy(); delete $7;
1266 delete $9; delete $10; $11.destroy(); delete $12; delete $13;
Reid Spencerf459d392006-12-02 16:19:52 +00001267 $14.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001268 $$ = 0;
1269 }
Reid Spencer78720742006-12-02 20:21:22 +00001270 | Unwind {
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001271 *O << " " << *$1 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +00001272 delete $1;
1273 $$ = 0;
1274 }
1275 | UNREACHABLE {
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001276 *O << " " << *$1 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +00001277 delete $1;
1278 $$ = 0;
1279 };
1280
1281JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
Reid Spencer52402b02007-01-02 05:45:11 +00001282 *$1 += " " + $2->getNewTy() + " " + *$3 + ", " + $5->getNewTy() + " " +
1283 *$6.val;
1284 delete $2; delete $3; delete $5; $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001285 $$ = $1;
1286 }
1287 | IntType ConstValueRef ',' LABEL ValueRef {
Reid Spencer52402b02007-01-02 05:45:11 +00001288 $2->insert(0, $1->getNewTy() + " " );
1289 *$2 += ", " + $4->getNewTy() + " " + *$5.val;
1290 delete $1; delete $4; $5.destroy();
Reid Spencere77e35e2006-12-01 20:26:20 +00001291 $$ = $2;
Reid Spencere7c3c602006-11-30 06:36:44 +00001292 };
1293
1294Inst
1295 : OptAssign InstVal {
Reid Spencerf5626a32007-01-01 01:20:41 +00001296 if (!$1->empty()) {
1297 if (deleteUselessCastFlag && *deleteUselessCastName == *$1) {
1298 *$1 += " = ";
1299 $1->insert(0, "; "); // don't actually delete it, just comment it out
1300 delete deleteUselessCastName;
1301 } else {
Reid Spencer52402b02007-01-02 05:45:11 +00001302 // Get a unique name for the name of this value, based on its type.
1303 *$1 = getUniqueName($1, $2.type) + " = ";
Reid Spencerf5626a32007-01-01 01:20:41 +00001304 }
1305 }
Reid Spencer52402b02007-01-02 05:45:11 +00001306 *$1 += *$2.val;
1307 $2.destroy();
Reid Spencerf5626a32007-01-01 01:20:41 +00001308 deleteUselessCastFlag = false;
Reid Spencere7c3c602006-11-30 06:36:44 +00001309 $$ = $1;
1310 };
1311
1312PHIList
1313 : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes
Reid Spencer52402b02007-01-02 05:45:11 +00001314 std::string Name = getUniqueName($3.val, $1);
1315 Name.insert(0, $1->getNewTy() + "[");
1316 Name += "," + *$5.val + "]";
1317 $$.val = new std::string(Name);
1318 $$.type = $1;
1319 $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001320 }
1321 | PHIList ',' '[' ValueRef ',' ValueRef ']' {
Reid Spencer52402b02007-01-02 05:45:11 +00001322 std::string Name = getUniqueName($4.val, $1.type);
1323 *$1.val += ", [" + Name + "," + *$6.val + "]";
Reid Spencerf459d392006-12-02 16:19:52 +00001324 $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001325 $$ = $1;
1326 };
1327
1328
1329ValueRefList
Reid Spencer52402b02007-01-02 05:45:11 +00001330 : ResolvedVal {
Reid Spencerf8483652006-12-02 15:16:01 +00001331 $$ = new ValueList();
1332 $$->push_back($1);
1333 }
Reid Spencere7c3c602006-11-30 06:36:44 +00001334 | ValueRefList ',' ResolvedVal {
Reid Spencere7c3c602006-11-30 06:36:44 +00001335 $$ = $1;
Reid Spencer52402b02007-01-02 05:45:11 +00001336 $$->push_back($3);
Reid Spencere7c3c602006-11-30 06:36:44 +00001337 };
1338
1339// ValueRefListE - Just like ValueRefList, except that it may also be empty!
1340ValueRefListE
Reid Spencerf8483652006-12-02 15:16:01 +00001341 : ValueRefList { $$ = $1; }
1342 | /*empty*/ { $$ = new ValueList(); }
Reid Spencere7c3c602006-11-30 06:36:44 +00001343 ;
1344
1345OptTailCall
1346 : TAIL CALL {
1347 *$1 += " " + *$2;
1348 delete $2;
1349 $$ = $1;
1350 }
1351 | CALL
1352 ;
1353
1354InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
Reid Spencer78720742006-12-02 20:21:22 +00001355 const char* op = getDivRemOpcode(*$1, $2);
Reid Spencer52402b02007-01-02 05:45:11 +00001356 std::string Name1 = getUniqueName($3.val, $2);
1357 std::string Name2 = getUniqueName($5.val, $2);
1358 $$.val = new std::string(op);
1359 *$$.val += " " + $2->getNewTy() + " " + Name1 + ", " + Name2;
1360 $$.type = $2;
1361 delete $1; $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001362 }
1363 | LogicalOps Types ValueRef ',' ValueRef {
Reid Spencer52402b02007-01-02 05:45:11 +00001364 std::string Name1 = getUniqueName($3.val, $2);
1365 std::string Name2 = getUniqueName($5.val, $2);
1366 *$1 += " " + $2->getNewTy() + " " + Name1 + ", " + Name2;
1367 $$.val = $1;
1368 $$.type = $2;
1369 $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001370 }
1371 | SetCondOps Types ValueRef ',' ValueRef {
Reid Spencer52402b02007-01-02 05:45:11 +00001372 std::string Name1 = getUniqueName($3.val, $2);
1373 std::string Name2 = getUniqueName($5.val, $2);
Reid Spencer229e9362006-12-02 22:14:11 +00001374 *$1 = getCompareOp(*$1, $2);
Reid Spencer52402b02007-01-02 05:45:11 +00001375 *$1 += " " + $2->getNewTy() + " " + Name1 + ", " + Name2;
1376 $$.val = $1;
1377 $$.type = new TypeInfo("bool",BoolTy);
1378 $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001379 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001380 | ICMP IPredicates Types ValueRef ',' ValueRef {
Reid Spencer52402b02007-01-02 05:45:11 +00001381 std::string Name1 = getUniqueName($4.val, $3);
1382 std::string Name2 = getUniqueName($6.val, $3);
1383 *$1 += " " + *$2 + " " + $3->getNewTy() + " " + Name1 + "," + Name2;
1384 $$.val = $1;
1385 $$.type = new TypeInfo("bool",BoolTy);
Reid Spencer57f28f92006-12-03 07:10:26 +00001386 delete $2; $4.destroy(); $6.destroy();
Reid Spencer57f28f92006-12-03 07:10:26 +00001387 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001388 | FCMP FPredicates Types ValueRef ',' ValueRef {
Reid Spencer52402b02007-01-02 05:45:11 +00001389 std::string Name1 = getUniqueName($4.val, $3);
1390 std::string Name2 = getUniqueName($6.val, $3);
1391 *$1 += " " + *$2 + " " + $3->getNewTy() + " " + Name1 + "," + Name2;
1392 $$.val = $1;
1393 $$.type = new TypeInfo("bool",BoolTy);
Reid Spencer229e9362006-12-02 22:14:11 +00001394 delete $2; $4.destroy(); $6.destroy();
Reid Spencer229e9362006-12-02 22:14:11 +00001395 }
Reid Spencere7c3c602006-11-30 06:36:44 +00001396 | NOT ResolvedVal {
Reid Spencer52402b02007-01-02 05:45:11 +00001397 $$ = $2;
1398 $$.val->insert(0, *$1 + " ");
1399 delete $1;
Reid Spencere7c3c602006-11-30 06:36:44 +00001400 }
1401 | ShiftOps ResolvedVal ',' ResolvedVal {
Reid Spencerf7bde222006-12-01 22:26:37 +00001402 const char* shiftop = $1->c_str();
1403 if (*$1 == "shr")
Reid Spencer52402b02007-01-02 05:45:11 +00001404 shiftop = ($2.type->isUnsigned()) ? "lshr" : "ashr";
1405 $$.val = new std::string(shiftop);
1406 *$$.val += " " + *$2.val + ", " + *$4.val;
1407 $$.type = $2.type;
1408 delete $1; delete $2.val; $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001409 }
Reid Spencerfcb5df82006-12-01 22:34:43 +00001410 | CastOps ResolvedVal TO Types {
Reid Spencer280d8012006-12-01 23:40:53 +00001411 std::string source = *$2.val;
Reid Spencer52402b02007-01-02 05:45:11 +00001412 TypeInfo* SrcTy = $2.type;
1413 TypeInfo* DstTy = ResolveType($4);
1414 $$.val = new std::string();
Reid Spencer280d8012006-12-01 23:40:53 +00001415 if (*$1 == "cast") {
Reid Spencer52402b02007-01-02 05:45:11 +00001416 *$$.val += getCastUpgrade(source, SrcTy, DstTy, false);
Reid Spencera50d5962006-12-02 04:11:07 +00001417 } else {
Reid Spencer52402b02007-01-02 05:45:11 +00001418 *$$.val += *$1 + " " + source + " to " + DstTy->getNewTy();
Reid Spencer280d8012006-12-01 23:40:53 +00001419 }
Reid Spencer52402b02007-01-02 05:45:11 +00001420 $$.type = $4;
Reid Spencerf5626a32007-01-01 01:20:41 +00001421 // Check to see if this is a useless cast of a value to the same name
1422 // and the same type. Such casts will probably cause redefinition errors
1423 // when assembled and perform no code gen action so just remove them.
1424 if (*$1 == "cast" || *$1 == "bitcast")
Reid Spencer52402b02007-01-02 05:45:11 +00001425 if ($2.type->isInteger() && DstTy->isInteger() &&
1426 $2.type->getBitWidth() == DstTy->getBitWidth()) {
Reid Spencerf5626a32007-01-01 01:20:41 +00001427 deleteUselessCastFlag = true; // Flag the "Inst" rule
1428 deleteUselessCastName = new std::string(*$2.val); // save the name
1429 size_t pos = deleteUselessCastName->find_first_of("%\"",0);
1430 if (pos != std::string::npos) {
1431 // remove the type portion before val
1432 deleteUselessCastName->erase(0, pos);
1433 }
1434 }
Reid Spencere77e35e2006-12-01 20:26:20 +00001435 delete $1; $2.destroy();
Reid Spencer52402b02007-01-02 05:45:11 +00001436 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001437 }
1438 | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001439 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
Reid Spencer52402b02007-01-02 05:45:11 +00001440 $$.val = $1;
1441 $$.type = $4.type;
1442 $2.destroy(); delete $4.val; $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001443 }
1444 | VAARG ResolvedVal ',' Types {
Reid Spencer52402b02007-01-02 05:45:11 +00001445 *$1 += " " + *$2.val + ", " + $4->getNewTy();
1446 $$.val = $1;
1447 $$.type = $4;
1448 $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001449 }
1450 | EXTRACTELEMENT ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001451 *$1 += " " + *$2.val + ", " + *$4.val;
Reid Spencer52402b02007-01-02 05:45:11 +00001452 $$.val = $1;
1453 ResolveType($2.type);
Reid Spencereff838e2007-01-03 23:45:42 +00001454 $$.type = $2.type->getElementType();
Reid Spencer52402b02007-01-02 05:45:11 +00001455 delete $2.val; $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001456 }
1457 | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001458 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
Reid Spencer52402b02007-01-02 05:45:11 +00001459 $$.val = $1;
1460 $$.type = $2.type;
1461 delete $2.val; $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001462 }
1463 | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001464 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
Reid Spencer52402b02007-01-02 05:45:11 +00001465 $$.val = $1;
1466 $$.type = $2.type;
1467 delete $2.val; $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001468 }
1469 | PHI_TOK PHIList {
Reid Spencer52402b02007-01-02 05:45:11 +00001470 *$1 += " " + *$2.val;
1471 $$.val = $1;
1472 $$.type = $2.type;
1473 delete $2.val;
Reid Spencere7c3c602006-11-30 06:36:44 +00001474 }
1475 | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' {
1476 if (!$2->empty())
1477 *$1 += " " + *$2;
1478 if (!$1->empty())
1479 *$1 += " ";
Reid Spencer52402b02007-01-02 05:45:11 +00001480 *$1 += $3->getNewTy() + " " + *$4.val + "(";
Reid Spencerf8483652006-12-02 15:16:01 +00001481 for (unsigned i = 0; i < $6->size(); ++i) {
1482 ValueInfo& VI = (*$6)[i];
1483 *$1 += *VI.val;
1484 if (i+1 < $6->size())
1485 *$1 += ", ";
1486 VI.destroy();
1487 }
1488 *$1 += ")";
Reid Spencer52402b02007-01-02 05:45:11 +00001489 $$.val = $1;
1490 $$.type = getFunctionReturnType($3);
1491 delete $2; delete $3; $4.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001492 }
1493 | MemoryInst ;
1494
1495
1496// IndexList - List of indices for GEP based instructions...
1497IndexList
Reid Spencerf8483652006-12-02 15:16:01 +00001498 : ',' ValueRefList { $$ = $2; }
1499 | /* empty */ { $$ = new ValueList(); }
Reid Spencere7c3c602006-11-30 06:36:44 +00001500 ;
1501
1502OptVolatile
1503 : VOLATILE
1504 | /* empty */ { $$ = new std::string(); }
1505 ;
1506
1507MemoryInst : MALLOC Types OptCAlign {
Reid Spencer52402b02007-01-02 05:45:11 +00001508 *$1 += " " + $2->getNewTy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001509 if (!$3->empty())
1510 *$1 += " " + *$3;
Reid Spencer52402b02007-01-02 05:45:11 +00001511 $$.val = $1;
1512 $$.type = $2->getPointerType();
1513 delete $2; delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001514 }
1515 | MALLOC Types ',' UINT ValueRef OptCAlign {
Reid Spencer52402b02007-01-02 05:45:11 +00001516 std::string Name = getUniqueName($5.val, $4);
1517 *$1 += " " + $2->getNewTy() + ", " + $4->getNewTy() + " " + Name;
Reid Spencere7c3c602006-11-30 06:36:44 +00001518 if (!$6->empty())
1519 *$1 += " " + *$6;
Reid Spencer52402b02007-01-02 05:45:11 +00001520 $$.val = $1;
1521 $$.type = $2->getPointerType();
1522 delete $2; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001523 }
1524 | ALLOCA Types OptCAlign {
Reid Spencer52402b02007-01-02 05:45:11 +00001525 *$1 += " " + $2->getNewTy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001526 if (!$3->empty())
1527 *$1 += " " + *$3;
Reid Spencer52402b02007-01-02 05:45:11 +00001528 $$.val = $1;
1529 $$.type = $2->getPointerType();
1530 delete $2; delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001531 }
1532 | ALLOCA Types ',' UINT ValueRef OptCAlign {
Reid Spencer52402b02007-01-02 05:45:11 +00001533 std::string Name = getUniqueName($5.val, $4);
1534 *$1 += " " + $2->getNewTy() + ", " + $4->getNewTy() + " " + Name;
Reid Spencere7c3c602006-11-30 06:36:44 +00001535 if (!$6->empty())
1536 *$1 += " " + *$6;
Reid Spencer52402b02007-01-02 05:45:11 +00001537 $$.val = $1;
1538 $$.type = $2->getPointerType();
1539 delete $2; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001540 }
1541 | FREE ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001542 *$1 += " " + *$2.val;
Reid Spencer52402b02007-01-02 05:45:11 +00001543 $$.val = $1;
1544 $$.type = new TypeInfo("void", VoidTy);
Reid Spencere77e35e2006-12-01 20:26:20 +00001545 $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001546 }
1547 | OptVolatile LOAD Types ValueRef {
Reid Spencer52402b02007-01-02 05:45:11 +00001548 std::string Name = getUniqueName($4.val, $3);
Reid Spencere7c3c602006-11-30 06:36:44 +00001549 if (!$1->empty())
1550 *$1 += " ";
Reid Spencer52402b02007-01-02 05:45:11 +00001551 *$1 += *$2 + " " + $3->getNewTy() + " " + Name;
1552 $$.val = $1;
1553 $$.type = $3->getElementType()->clone();
1554 delete $2; delete $3; $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001555 }
1556 | OptVolatile STORE ResolvedVal ',' Types ValueRef {
Reid Spencer52402b02007-01-02 05:45:11 +00001557 std::string Name = getUniqueName($6.val, $5);
Reid Spencere7c3c602006-11-30 06:36:44 +00001558 if (!$1->empty())
1559 *$1 += " ";
Reid Spencer52402b02007-01-02 05:45:11 +00001560 *$1 += *$2 + " " + *$3.val + ", " + $5->getNewTy() + " " + Name;
1561 $$.val = $1;
1562 $$.type = new TypeInfo("void", VoidTy);
1563 delete $2; $3.destroy(); delete $5; $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001564 }
1565 | GETELEMENTPTR Types ValueRef IndexList {
Reid Spencer52402b02007-01-02 05:45:11 +00001566 std::string Name = getUniqueName($3.val, $2);
Reid Spencerf459d392006-12-02 16:19:52 +00001567 // Upgrade the indices
1568 for (unsigned i = 0; i < $4->size(); ++i) {
1569 ValueInfo& VI = (*$4)[i];
Reid Spencer52402b02007-01-02 05:45:11 +00001570 if (VI.type->isUnsigned() && !VI.isConstant() &&
1571 VI.type->getBitWidth() < 64) {
Reid Spencerf459d392006-12-02 16:19:52 +00001572 std::string* old = VI.val;
1573 *O << " %gep_upgrade" << unique << " = zext " << *old
Reid Spencer71d2ec92006-12-31 06:02:26 +00001574 << " to i64\n";
1575 VI.val = new std::string("i64 %gep_upgrade" + llvm::utostr(unique++));
Reid Spencer52402b02007-01-02 05:45:11 +00001576 VI.type->setOldTy(ULongTy);
Reid Spencerf459d392006-12-02 16:19:52 +00001577 }
1578 }
Reid Spencer52402b02007-01-02 05:45:11 +00001579 *$1 += " " + $2->getNewTy() + " " + Name;
Reid Spencerf8483652006-12-02 15:16:01 +00001580 for (unsigned i = 0; i < $4->size(); ++i) {
1581 ValueInfo& VI = (*$4)[i];
1582 *$1 += ", " + *VI.val;
Reid Spencerf8483652006-12-02 15:16:01 +00001583 }
Reid Spencer52402b02007-01-02 05:45:11 +00001584 $$.val = $1;
1585 $$.type = getGEPIndexedType($2,$4);
1586 $3.destroy(); delete $4;
Reid Spencere7c3c602006-11-30 06:36:44 +00001587 };
1588
1589%%
1590
1591int yyerror(const char *ErrorMsg) {
1592 std::string where
1593 = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
1594 + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
1595 std::string errMsg = std::string(ErrorMsg) + "\n" + where + " while reading ";
1596 if (yychar == YYEMPTY || yychar == 0)
1597 errMsg += "end-of-file.";
1598 else
1599 errMsg += "token: '" + std::string(Upgradetext, Upgradeleng) + "'";
Reid Spencer71d2ec92006-12-31 06:02:26 +00001600 std::cerr << "llvm-upgrade: " << errMsg << '\n';
Chris Lattner37e01c52007-01-04 18:46:42 +00001601 *O << "llvm-upgrade parse failed.\n";
Reid Spencere7c3c602006-11-30 06:36:44 +00001602 exit(1);
1603}