blob: f5e119da491a973884fd3ac4e2378453b773c6d4 [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";
75 exit(1);
76 }
77}
78
Reid Spencer52402b02007-01-02 05:45:11 +000079TypeInfo* ResolveType(TypeInfo*& Ty) {
80 if (Ty->isUnresolved()) {
Reid Spencereff838e2007-01-03 23:45:42 +000081 if (Ty->getNewTy()[0] == '%' && isdigit(Ty->getNewTy()[1])) {
82 unsigned ref = atoi(&((Ty->getNewTy().c_str())[1])); // skip the %
83 if (ref < EnumeratedTypes.size()) {
84 Ty = &EnumeratedTypes[ref];
85 return Ty;
86 } else {
87 std::string msg("Can't resolve numbered type: ");
88 msg += Ty->getNewTy();
89 yyerror(msg.c_str());
90 }
Reid Spencer78720742006-12-02 20:21:22 +000091 } else {
Reid Spencereff838e2007-01-03 23:45:42 +000092 TypeMap::iterator I = NamedTypes.find(Ty->getNewTy());
93 if (I != NamedTypes.end()) {
94 Ty = &I->second;
95 return Ty;
96 } else {
97 std::string msg("Cannot resolve type: ");
98 msg += Ty->getNewTy();
99 yyerror(msg.c_str());
100 }
Reid Spencera50d5962006-12-02 04:11:07 +0000101 }
Reid Spencer280d8012006-12-01 23:40:53 +0000102 }
Reid Spencera50d5962006-12-02 04:11:07 +0000103 // otherwise its already resolved.
Reid Spencer52402b02007-01-02 05:45:11 +0000104 return Ty;
Reid Spencer280d8012006-12-01 23:40:53 +0000105}
106
Reid Spencera50d5962006-12-02 04:11:07 +0000107static const char* getCastOpcode(
Reid Spencer52402b02007-01-02 05:45:11 +0000108 std::string& Source, const TypeInfo* SrcTy, const TypeInfo* DstTy)
Reid Spencera50d5962006-12-02 04:11:07 +0000109{
Reid Spencer52402b02007-01-02 05:45:11 +0000110 unsigned SrcBits = SrcTy->getBitWidth();
111 unsigned DstBits = DstTy->getBitWidth();
Reid Spencere77e35e2006-12-01 20:26:20 +0000112 const char* opcode = "bitcast";
113 // Run through the possibilities ...
Reid Spencer52402b02007-01-02 05:45:11 +0000114 if (DstTy->isIntegral()) { // Casting to integral
115 if (SrcTy->isIntegral()) { // Casting from integral
Reid Spencere77e35e2006-12-01 20:26:20 +0000116 if (DstBits < SrcBits)
117 opcode = "trunc";
118 else if (DstBits > SrcBits) { // its an extension
Reid Spencer52402b02007-01-02 05:45:11 +0000119 if (SrcTy->isSigned())
Reid Spencere77e35e2006-12-01 20:26:20 +0000120 opcode ="sext"; // signed -> SEXT
121 else
122 opcode = "zext"; // unsigned -> ZEXT
123 } else {
124 opcode = "bitcast"; // Same size, No-op cast
125 }
Reid Spencer52402b02007-01-02 05:45:11 +0000126 } else if (SrcTy->isFloatingPoint()) { // Casting from floating pt
127 if (DstTy->isSigned())
Reid Spencere77e35e2006-12-01 20:26:20 +0000128 opcode = "fptosi"; // FP -> sint
129 else
130 opcode = "fptoui"; // FP -> uint
Reid Spencer52402b02007-01-02 05:45:11 +0000131 } else if (SrcTy->isPacked()) {
132 assert(DstBits == SrcTy->getBitWidth() &&
Reid Spencere77e35e2006-12-01 20:26:20 +0000133 "Casting packed to integer of different width");
134 opcode = "bitcast"; // same size, no-op cast
135 } else {
Reid Spencer52402b02007-01-02 05:45:11 +0000136 assert(SrcTy->isPointer() &&
Reid Spencere77e35e2006-12-01 20:26:20 +0000137 "Casting from a value that is not first-class type");
138 opcode = "ptrtoint"; // ptr -> int
139 }
Reid Spencer52402b02007-01-02 05:45:11 +0000140 } else if (DstTy->isFloatingPoint()) { // Casting to floating pt
141 if (SrcTy->isIntegral()) { // Casting from integral
142 if (SrcTy->isSigned())
Reid Spencere77e35e2006-12-01 20:26:20 +0000143 opcode = "sitofp"; // sint -> FP
144 else
145 opcode = "uitofp"; // uint -> FP
Reid Spencer52402b02007-01-02 05:45:11 +0000146 } else if (SrcTy->isFloatingPoint()) { // Casting from floating pt
Reid Spencere77e35e2006-12-01 20:26:20 +0000147 if (DstBits < SrcBits) {
148 opcode = "fptrunc"; // FP -> smaller FP
149 } else if (DstBits > SrcBits) {
150 opcode = "fpext"; // FP -> larger FP
151 } else {
152 opcode ="bitcast"; // same size, no-op cast
153 }
Reid Spencer52402b02007-01-02 05:45:11 +0000154 } else if (SrcTy->isPacked()) {
155 assert(DstBits == SrcTy->getBitWidth() &&
Reid Spencere77e35e2006-12-01 20:26:20 +0000156 "Casting packed to floating point of different width");
157 opcode = "bitcast"; // same size, no-op cast
158 } else {
159 assert(0 && "Casting pointer or non-first class to float");
160 }
Reid Spencer52402b02007-01-02 05:45:11 +0000161 } else if (DstTy->isPacked()) {
162 if (SrcTy->isPacked()) {
163 assert(DstTy->getBitWidth() == SrcTy->getBitWidth() &&
Reid Spencere77e35e2006-12-01 20:26:20 +0000164 "Casting packed to packed of different widths");
165 opcode = "bitcast"; // packed -> packed
Reid Spencer52402b02007-01-02 05:45:11 +0000166 } else if (DstTy->getBitWidth() == SrcBits) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000167 opcode = "bitcast"; // float/int -> packed
168 } else {
169 assert(!"Illegal cast to packed (wrong type or size)");
170 }
Reid Spencer52402b02007-01-02 05:45:11 +0000171 } else if (DstTy->isPointer()) {
172 if (SrcTy->isPointer()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000173 opcode = "bitcast"; // ptr -> ptr
Reid Spencer52402b02007-01-02 05:45:11 +0000174 } else if (SrcTy->isIntegral()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000175 opcode = "inttoptr"; // int -> ptr
176 } else {
Reid Spencera50d5962006-12-02 04:11:07 +0000177 assert(!"Casting invalid type to pointer");
Reid Spencere77e35e2006-12-01 20:26:20 +0000178 }
179 } else {
180 assert(!"Casting to type that is not first-class");
181 }
182 return opcode;
183}
184
Reid Spencer52402b02007-01-02 05:45:11 +0000185static std::string getCastUpgrade(const std::string& Src, TypeInfo* SrcTy,
186 TypeInfo* DstTy, bool isConst)
Reid Spencera50d5962006-12-02 04:11:07 +0000187{
188 std::string Result;
189 std::string Source = Src;
Reid Spencer52402b02007-01-02 05:45:11 +0000190 if (SrcTy->isFloatingPoint() && DstTy->isPointer()) {
Reid Spencera50d5962006-12-02 04:11:07 +0000191 // fp -> ptr cast is no longer supported but we must upgrade this
192 // by doing a double cast: fp -> int -> ptr
193 if (isConst)
Reid Spencer71d2ec92006-12-31 06:02:26 +0000194 Source = "i64 fptoui(" + Source + " to i64)";
Reid Spencera50d5962006-12-02 04:11:07 +0000195 else {
Reid Spencerf459d392006-12-02 16:19:52 +0000196 *O << " %cast_upgrade" << unique << " = fptoui " << Source
Reid Spencer71d2ec92006-12-31 06:02:26 +0000197 << " to i64\n";
198 Source = "i64 %cast_upgrade" + llvm::utostr(unique);
Reid Spencera50d5962006-12-02 04:11:07 +0000199 }
200 // Update the SrcTy for the getCastOpcode call below
Reid Spencer52402b02007-01-02 05:45:11 +0000201 delete SrcTy;
202 SrcTy = new TypeInfo("i64", ULongTy);
203 } else if (DstTy->isBool()) {
204 // cast type %x to bool was previously defined as setne type %x, null
205 // The cast semantic is now to truncate, not compare so we must retain
206 // the original intent by replacing the cast with a setne
207 const char* comparator = SrcTy->isPointer() ? ", null" :
208 (SrcTy->isFloatingPoint() ? ", 0.0" :
209 (SrcTy->isBool() ? ", false" : ", 0"));
210 const char* compareOp = SrcTy->isFloatingPoint() ? "fcmp one " : "icmp ne ";
Reid Spencer187ccf82006-12-09 16:57:22 +0000211 if (isConst) {
212 Result = "(" + Source + comparator + ")";
213 Result = compareOp + Result;
214 } else
215 Result = compareOp + Source + comparator;
Reid Spencera50d5962006-12-02 04:11:07 +0000216 return Result; // skip cast processing below
217 }
218 ResolveType(SrcTy);
219 ResolveType(DstTy);
220 std::string Opcode(getCastOpcode(Source, SrcTy, DstTy));
221 if (isConst)
Reid Spencer52402b02007-01-02 05:45:11 +0000222 Result += Opcode + "( " + Source + " to " + DstTy->getNewTy() + ")";
Reid Spencera50d5962006-12-02 04:11:07 +0000223 else
Reid Spencer52402b02007-01-02 05:45:11 +0000224 Result += Opcode + " " + Source + " to " + DstTy->getNewTy();
Reid Spencera50d5962006-12-02 04:11:07 +0000225 return Result;
226}
227
Reid Spencer52402b02007-01-02 05:45:11 +0000228const char* getDivRemOpcode(const std::string& opcode, TypeInfo* TI) {
Reid Spencer78720742006-12-02 20:21:22 +0000229 const char* op = opcode.c_str();
Reid Spencer52402b02007-01-02 05:45:11 +0000230 const TypeInfo* Ty = ResolveType(TI);
231 if (Ty->isPacked())
232 Ty = Ty->getElementType();
Reid Spencer78720742006-12-02 20:21:22 +0000233 if (opcode == "div")
Reid Spencer52402b02007-01-02 05:45:11 +0000234 if (Ty->isFloatingPoint())
Reid Spencer78720742006-12-02 20:21:22 +0000235 op = "fdiv";
Reid Spencer52402b02007-01-02 05:45:11 +0000236 else if (Ty->isUnsigned())
Reid Spencer78720742006-12-02 20:21:22 +0000237 op = "udiv";
Reid Spencer52402b02007-01-02 05:45:11 +0000238 else if (Ty->isSigned())
Reid Spencer78720742006-12-02 20:21:22 +0000239 op = "sdiv";
240 else
241 yyerror("Invalid type for div instruction");
242 else if (opcode == "rem")
Reid Spencer52402b02007-01-02 05:45:11 +0000243 if (Ty->isFloatingPoint())
Reid Spencer78720742006-12-02 20:21:22 +0000244 op = "frem";
Reid Spencer52402b02007-01-02 05:45:11 +0000245 else if (Ty->isUnsigned())
Reid Spencer78720742006-12-02 20:21:22 +0000246 op = "urem";
Reid Spencer52402b02007-01-02 05:45:11 +0000247 else if (Ty->isSigned())
Reid Spencer78720742006-12-02 20:21:22 +0000248 op = "srem";
249 else
250 yyerror("Invalid type for rem instruction");
251 return op;
252}
Reid Spencer229e9362006-12-02 22:14:11 +0000253
254std::string
Reid Spencer52402b02007-01-02 05:45:11 +0000255getCompareOp(const std::string& setcc, const TypeInfo* TI) {
Reid Spencer229e9362006-12-02 22:14:11 +0000256 assert(setcc.length() == 5);
257 char cc1 = setcc[3];
258 char cc2 = setcc[4];
259 assert(cc1 == 'e' || cc1 == 'n' || cc1 == 'l' || cc1 == 'g');
260 assert(cc2 == 'q' || cc2 == 'e' || cc2 == 'e' || cc2 == 't');
261 std::string result("xcmp xxx");
262 result[6] = cc1;
263 result[7] = cc2;
Reid Spencer52402b02007-01-02 05:45:11 +0000264 if (TI->isFloatingPoint()) {
Reid Spencer229e9362006-12-02 22:14:11 +0000265 result[0] = 'f';
Reid Spencere4d87aa2006-12-23 06:05:41 +0000266 result[5] = 'o';
Reid Spencerf0cf1322006-12-07 04:23:03 +0000267 if (cc1 == 'n')
268 result[5] = 'u'; // NE maps to unordered
269 else
270 result[5] = 'o'; // everything else maps to ordered
Reid Spencer52402b02007-01-02 05:45:11 +0000271 } else if (TI->isIntegral() || TI->isPointer()) {
Reid Spencer229e9362006-12-02 22:14:11 +0000272 result[0] = 'i';
273 if ((cc1 == 'e' && cc2 == 'q') || (cc1 == 'n' && cc2 == 'e'))
274 result.erase(5,1);
Reid Spencer52402b02007-01-02 05:45:11 +0000275 else if (TI->isSigned())
Reid Spencer229e9362006-12-02 22:14:11 +0000276 result[5] = 's';
Reid Spencer52402b02007-01-02 05:45:11 +0000277 else if (TI->isUnsigned() || TI->isPointer() || TI->isBool())
Reid Spencer229e9362006-12-02 22:14:11 +0000278 result[5] = 'u';
279 else
280 yyerror("Invalid integral type for setcc");
281 }
282 return result;
283}
284
Reid Spencer52402b02007-01-02 05:45:11 +0000285static TypeInfo* getFunctionReturnType(TypeInfo* PFTy) {
286 ResolveType(PFTy);
287 if (PFTy->isPointer()) {
288 TypeInfo* ElemTy = PFTy->getElementType();
289 ResolveType(ElemTy);
290 if (ElemTy->isFunction())
291 return ElemTy->getResultType()->clone();
292 } else if (PFTy->isFunction()) {
293 return PFTy->getResultType()->clone();
294 }
295 return PFTy->clone();
296}
297
Reid Spencereff838e2007-01-03 23:45:42 +0000298typedef std::vector<TypeInfo*> UpRefStack;
299static TypeInfo* ResolveUpReference(TypeInfo* Ty, UpRefStack* stack) {
300 assert(Ty->isUpReference() && "Can't resolve a non-upreference");
301 unsigned upref = atoi(&((Ty->getNewTy().c_str())[1])); // skip the slash
302 assert(upref < stack->size() && "Invalid up reference");
303 return (*stack)[upref - stack->size() - 1];
304}
305
Reid Spencer52402b02007-01-02 05:45:11 +0000306static TypeInfo* getGEPIndexedType(TypeInfo* PTy, ValueList* idxs) {
Reid Spencereff838e2007-01-03 23:45:42 +0000307 TypeInfo* Result = ResolveType(PTy);
Reid Spencer52402b02007-01-02 05:45:11 +0000308 assert(PTy->isPointer() && "GEP Operand is not a pointer?");
Reid Spencereff838e2007-01-03 23:45:42 +0000309 UpRefStack stack;
310 for (unsigned i = 0; i < idxs->size(); ++i) {
Reid Spencer52402b02007-01-02 05:45:11 +0000311 if (Result->isComposite()) {
312 Result = Result->getIndexedType((*idxs)[i]);
313 ResolveType(Result);
Reid Spencereff838e2007-01-03 23:45:42 +0000314 stack.push_back(Result);
Reid Spencer52402b02007-01-02 05:45:11 +0000315 } else
316 yyerror("Invalid type for index");
317 }
Reid Spencereff838e2007-01-03 23:45:42 +0000318 // Resolve upreferences so we can return a more natural type
319 if (Result->isPointer()) {
320 if (Result->getElementType()->isUpReference()) {
321 stack.push_back(Result);
322 Result = ResolveUpReference(Result->getElementType(), &stack);
323 }
324 } else if (Result->isUpReference()) {
325 Result = ResolveUpReference(Result->getElementType(), &stack);
326 }
Reid Spencer52402b02007-01-02 05:45:11 +0000327 return Result->getPointerType();
328}
329
330static std::string makeUniqueName(const std::string *Name, bool isSigned) {
331 const char *suffix = ".u";
332 if (isSigned)
333 suffix = ".s";
334 if ((*Name)[Name->size()-1] == '"') {
335 std::string Result(*Name);
336 Result.insert(Name->size()-1, suffix);
337 return Result;
338 }
339 return *Name + suffix;
340}
341
342// This function handles appending .u or .s to integer value names that
343// were previously unsigned or signed, respectively. This avoids name
344// collisions since the unsigned and signed type planes have collapsed
345// into a single signless type plane.
346static std::string getUniqueName(const std::string *Name, TypeInfo* Ty) {
347 // If its not a symbolic name, don't modify it, probably a constant val.
348 if ((*Name)[0] != '%' && (*Name)[0] != '"')
349 return *Name;
350 // If its a numeric reference, just leave it alone.
351 if (isdigit((*Name)[1]))
352 return *Name;
353
354 // Resolve the type
355 ResolveType(Ty);
356
Reid Spencereff838e2007-01-03 23:45:42 +0000357 // Remove as many levels of pointer nesting that we have.
358 if (Ty->isPointer()) {
359 // Avoid infinite loops in recursive types
360 TypeInfo* Last = 0;
361 while (Ty->isPointer() && Last != Ty) {
362 Last = Ty;
363 Ty = Ty->getElementType();
364 ResolveType(Ty);
365 }
366 }
367
Reid Spencer52402b02007-01-02 05:45:11 +0000368 // Default the result to the current name
369 std::string Result = *Name;
370
Reid Spencereff838e2007-01-03 23:45:42 +0000371 // Now deal with the underlying type
Reid Spencer52402b02007-01-02 05:45:11 +0000372 if (Ty->isInteger()) {
373 // If its an integer type, make the name unique
374 Result = makeUniqueName(Name, Ty->isSigned());
Reid Spencereff838e2007-01-03 23:45:42 +0000375 } else if (Ty->isArray() || Ty->isPacked()) {
376 Ty = Ty->getElementType();
Reid Spencer52402b02007-01-02 05:45:11 +0000377 if (Ty->isInteger())
378 Result = makeUniqueName(Name, Ty->isSigned());
Reid Spencereff838e2007-01-03 23:45:42 +0000379 } else if (Ty->isStruct()) {
380 // Scan the fields and count the signed and unsigned fields
381 int isSigned = 0;
382 for (unsigned i = 0; i < Ty->getNumStructElements(); ++i) {
383 TypeInfo* Tmp = Ty->getElement(i);
384 if (Tmp->isInteger())
385 if (Tmp->isSigned())
386 isSigned++;
387 else
388 isSigned--;
389 }
390 if (isSigned != 0)
391 Result = makeUniqueName(Name, isSigned > 0);
Reid Spencer52402b02007-01-02 05:45:11 +0000392 }
393 return Result;
394}
395
Reid Spencere7c3c602006-11-30 06:36:44 +0000396%}
397
Reid Spencerf0cf1322006-12-07 04:23:03 +0000398// %file-prefix="UpgradeParser"
Reid Spencere77e35e2006-12-01 20:26:20 +0000399
400%union {
401 std::string* String;
Reid Spencer52402b02007-01-02 05:45:11 +0000402 TypeInfo* Type;
Reid Spencere77e35e2006-12-01 20:26:20 +0000403 ValueInfo Value;
404 ConstInfo Const;
Reid Spencerf8483652006-12-02 15:16:01 +0000405 ValueList* ValList;
Reid Spencer52402b02007-01-02 05:45:11 +0000406 TypeList* TypeVec;
Reid Spencere77e35e2006-12-01 20:26:20 +0000407}
408
Reid Spencerf2d55322006-12-01 21:52:30 +0000409%token <Type> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
Reid Spencera50d5962006-12-02 04:11:07 +0000410%token <Type> FLOAT DOUBLE LABEL
411%token <String> OPAQUE ESINT64VAL EUINT64VAL SINTVAL UINTVAL FPVAL
Reid Spencerf2d55322006-12-01 21:52:30 +0000412%token <String> NULL_TOK UNDEF ZEROINITIALIZER TRUETOK FALSETOK
Reid Spencere77e35e2006-12-01 20:26:20 +0000413%token <String> TYPE VAR_ID LABELSTR STRINGCONSTANT
414%token <String> IMPLEMENTATION BEGINTOK ENDTOK
Reid Spencer71d2ec92006-12-31 06:02:26 +0000415%token <String> DECLARE GLOBAL CONSTANT SECTION VOLATILE
Reid Spencere77e35e2006-12-01 20:26:20 +0000416%token <String> TO DOTDOTDOT CONST INTERNAL LINKONCE WEAK
417%token <String> DLLIMPORT DLLEXPORT EXTERN_WEAK APPENDING
418%token <String> NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG
Reid Spencer78720742006-12-02 20:21:22 +0000419%token <String> ALIGN UNINITIALIZED
Reid Spencere77e35e2006-12-01 20:26:20 +0000420%token <String> DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
421%token <String> CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK
422%token <String> X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
423%token <String> DATALAYOUT
Reid Spencer78720742006-12-02 20:21:22 +0000424%token <String> RET BR SWITCH INVOKE EXCEPT UNWIND UNREACHABLE
425%token <String> ADD SUB MUL DIV UDIV SDIV FDIV REM UREM SREM FREM AND OR XOR
Reid Spencere77e35e2006-12-01 20:26:20 +0000426%token <String> SETLE SETGE SETLT SETGT SETEQ SETNE // Binary Comparators
Reid Spencer229e9362006-12-02 22:14:11 +0000427%token <String> ICMP FCMP EQ NE SLT SGT SLE SGE OEQ ONE OLT OGT OLE OGE
428%token <String> ORD UNO UEQ UNE ULT UGT ULE UGE
Reid Spencere77e35e2006-12-01 20:26:20 +0000429%token <String> MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR
Reid Spencerf7bde222006-12-01 22:26:37 +0000430%token <String> PHI_TOK SELECT SHL SHR ASHR LSHR VAARG
Reid Spencere77e35e2006-12-01 20:26:20 +0000431%token <String> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
Reid Spencerfcb5df82006-12-01 22:34:43 +0000432%token <String> CAST TRUNC ZEXT SEXT FPTRUNC FPEXT FPTOUI FPTOSI UITOFP SITOFP
433%token <String> PTRTOINT INTTOPTR BITCAST
Reid Spencere77e35e2006-12-01 20:26:20 +0000434
435%type <String> OptAssign OptLinkage OptCallingConv OptAlign OptCAlign
436%type <String> SectionString OptSection GlobalVarAttributes GlobalVarAttribute
Reid Spencer52402b02007-01-02 05:45:11 +0000437%type <String> ConstExpr DefinitionList
Reid Spencere77e35e2006-12-01 20:26:20 +0000438%type <String> ConstPool TargetDefinition LibrariesDefinition LibList OptName
439%type <String> ArgVal ArgListH ArgList FunctionHeaderH BEGIN FunctionHeader END
Reid Spencer52402b02007-01-02 05:45:11 +0000440%type <String> Function FunctionProto BasicBlock
441%type <String> InstructionList BBTerminatorInst JumpTable Inst
442%type <String> OptTailCall OptVolatile Unwind
443%type <String> SymbolicValueRef OptSideEffect GlobalType
Reid Spencere77e35e2006-12-01 20:26:20 +0000444%type <String> FnDeclareLinkage BasicBlockList BigOrLittle AsmBlock
Reid Spencer78720742006-12-02 20:21:22 +0000445%type <String> Name ConstValueRef ConstVector External
Reid Spencer57f28f92006-12-03 07:10:26 +0000446%type <String> ShiftOps SetCondOps LogicalOps ArithmeticOps CastOps
447%type <String> IPredicates FPredicates
Reid Spencere77e35e2006-12-01 20:26:20 +0000448
Reid Spencerf8483652006-12-02 15:16:01 +0000449%type <ValList> ValueRefList ValueRefListE IndexList
Reid Spencer52402b02007-01-02 05:45:11 +0000450%type <TypeVec> TypeListI ArgTypeListI
Reid Spencere77e35e2006-12-01 20:26:20 +0000451
452%type <Type> IntType SIntType UIntType FPType TypesV Types
453%type <Type> PrimType UpRTypesV UpRTypes
454
Reid Spencerf2d55322006-12-01 21:52:30 +0000455%type <String> IntVal EInt64Val
456%type <Const> ConstVal
Reid Spencere77e35e2006-12-01 20:26:20 +0000457
Reid Spencer52402b02007-01-02 05:45:11 +0000458%type <Value> ValueRef ResolvedVal InstVal PHIList MemoryInst
Reid Spencere7c3c602006-11-30 06:36:44 +0000459
460%start Module
461
462%%
463
464// Handle constant integer size restriction and conversion...
Reid Spencerf2d55322006-12-01 21:52:30 +0000465IntVal : SINTVAL | UINTVAL ;
Reid Spencere77e35e2006-12-01 20:26:20 +0000466EInt64Val : ESINT64VAL | EUINT64VAL;
Reid Spencere7c3c602006-11-30 06:36:44 +0000467
468// Operations that are notably excluded from this list include:
469// RET, BR, & SWITCH because they end basic blocks and are treated specially.
Reid Spencer78720742006-12-02 20:21:22 +0000470ArithmeticOps: ADD | SUB | MUL | DIV | UDIV | SDIV | FDIV
471 | REM | UREM | SREM | FREM;
Reid Spencere7c3c602006-11-30 06:36:44 +0000472LogicalOps : AND | OR | XOR;
473SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE;
Reid Spencer57f28f92006-12-03 07:10:26 +0000474IPredicates : EQ | NE | SLT | SGT | SLE | SGE | ULT | UGT | ULE | UGE;
475FPredicates : OEQ | ONE | OLT | OGT | OLE | OGE | ORD | UNO | UEQ | UNE
476 | ULT | UGT | ULE | UGE | TRUETOK | FALSETOK;
Reid Spencerf7bde222006-12-01 22:26:37 +0000477ShiftOps : SHL | SHR | ASHR | LSHR;
Reid Spencerfcb5df82006-12-01 22:34:43 +0000478CastOps : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | FPTOUI | FPTOSI |
479 UITOFP | SITOFP | PTRTOINT | INTTOPTR | BITCAST | CAST
480 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000481
482// These are some types that allow classification if we only want a particular
483// thing... for example, only a signed, unsigned, or integral type.
484SIntType : LONG | INT | SHORT | SBYTE;
485UIntType : ULONG | UINT | USHORT | UBYTE;
486IntType : SIntType | UIntType;
487FPType : FLOAT | DOUBLE;
488
489// OptAssign - Value producing statements have an optional assignment component
490OptAssign : Name '=' {
Reid Spencere7c3c602006-11-30 06:36:44 +0000491 $$ = $1;
492 }
493 | /*empty*/ {
494 $$ = new std::string("");
495 };
496
497OptLinkage
498 : INTERNAL | LINKONCE | WEAK | APPENDING | DLLIMPORT | DLLEXPORT
499 | EXTERN_WEAK
500 | /*empty*/ { $$ = new std::string(""); } ;
501
502OptCallingConv
503 : CCC_TOK | CSRETCC_TOK | FASTCC_TOK | COLDCC_TOK | X86_STDCALLCC_TOK
Reid Spencer16244f42006-12-01 21:10:07 +0000504 | X86_FASTCALLCC_TOK
505 | CC_TOK EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000506 *$1 += *$2;
507 delete $2;
Reid Spencer16244f42006-12-01 21:10:07 +0000508 $$ = $1;
509 }
Reid Spencere7c3c602006-11-30 06:36:44 +0000510 | /*empty*/ { $$ = new std::string(""); } ;
511
512// OptAlign/OptCAlign - An optional alignment, and an optional alignment with
513// a comma before it.
514OptAlign
515 : /*empty*/ { $$ = new std::string(); }
Reid Spencerf2d55322006-12-01 21:52:30 +0000516 | ALIGN EUINT64VAL { *$1 += " " + *$2; delete $2; $$ = $1; };
Reid Spencerf0cf1322006-12-07 04:23:03 +0000517
Reid Spencere7c3c602006-11-30 06:36:44 +0000518OptCAlign
519 : /*empty*/ { $$ = new std::string(); }
520 | ',' ALIGN EUINT64VAL {
521 $2->insert(0, ", ");
Reid Spencerf2d55322006-12-01 21:52:30 +0000522 *$2 += " " + *$3;
523 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000524 $$ = $2;
525 };
526
527SectionString
528 : SECTION STRINGCONSTANT {
529 *$1 += " " + *$2;
530 delete $2;
531 $$ = $1;
532 };
533
534OptSection : /*empty*/ { $$ = new std::string(); }
535 | SectionString;
536
537GlobalVarAttributes
538 : /* empty */ { $$ = new std::string(); }
539 | ',' GlobalVarAttribute GlobalVarAttributes {
540 $2->insert(0, ", ");
541 if (!$3->empty())
542 *$2 += " " + *$3;
543 delete $3;
544 $$ = $2;
545 };
546
547GlobalVarAttribute
548 : SectionString
549 | ALIGN EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000550 *$1 += " " + *$2;
551 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000552 $$ = $1;
553 };
554
555//===----------------------------------------------------------------------===//
556// Types includes all predefined types... except void, because it can only be
557// used in specific contexts (function returning void for example). To have
558// access to it, a user must explicitly use TypesV.
559//
560
561// TypesV includes all of 'Types', but it also includes the void type.
562TypesV : Types | VOID ;
563UpRTypesV : UpRTypes | VOID ;
564Types : UpRTypes ;
565
566// Derived types are added later...
567//
568PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ;
Reid Spencere77e35e2006-12-01 20:26:20 +0000569PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL;
Reid Spencera50d5962006-12-02 04:11:07 +0000570UpRTypes
571 : OPAQUE {
Reid Spencer52402b02007-01-02 05:45:11 +0000572 $$ = new TypeInfo($1, OpaqueTy);
Reid Spencera50d5962006-12-02 04:11:07 +0000573 }
574 | SymbolicValueRef {
Reid Spencer52402b02007-01-02 05:45:11 +0000575 $$ = new TypeInfo($1, UnresolvedTy);
Reid Spencera50d5962006-12-02 04:11:07 +0000576 }
Reid Spencer78720742006-12-02 20:21:22 +0000577 | PrimType {
578 $$ = $1;
579 }
580 | '\\' EUINT64VAL { // Type UpReference
Reid Spencerf2d55322006-12-01 21:52:30 +0000581 $2->insert(0, "\\");
Reid Spencereff838e2007-01-03 23:45:42 +0000582 $$ = new TypeInfo($2, UpRefTy);
Reid Spencere7c3c602006-11-30 06:36:44 +0000583 }
584 | UpRTypesV '(' ArgTypeListI ')' { // Function derived type?
Reid Spencer52402b02007-01-02 05:45:11 +0000585 std::string newTy( $1->getNewTy() + "(");
586 for (unsigned i = 0; i < $3->size(); ++i) {
587 if (i != 0)
588 newTy += ", ";
589 if ((*$3)[i]->isVoid())
590 newTy += "...";
591 else
592 newTy += (*$3)[i]->getNewTy();
593 }
594 newTy += ")";
595 $$ = new TypeInfo(new std::string(newTy), $1, $3);
Reid Spencere7c3c602006-11-30 06:36:44 +0000596 }
597 | '[' EUINT64VAL 'x' UpRTypes ']' { // Sized array type?
Reid Spencerf2d55322006-12-01 21:52:30 +0000598 $2->insert(0,"[ ");
Reid Spencer52402b02007-01-02 05:45:11 +0000599 *$2 += " x " + $4->getNewTy() + " ]";
600 uint64_t elems = atoi($2->c_str());
601 $$ = new TypeInfo($2, ArrayTy, $4, elems);
Reid Spencere7c3c602006-11-30 06:36:44 +0000602 }
603 | '<' EUINT64VAL 'x' UpRTypes '>' { // Packed array type?
Reid Spencerf2d55322006-12-01 21:52:30 +0000604 $2->insert(0,"< ");
Reid Spencer52402b02007-01-02 05:45:11 +0000605 *$2 += " x " + $4->getNewTy() + " >";
606 uint64_t elems = atoi($2->c_str());
607 $$ = new TypeInfo($2, PackedTy, $4, elems);
Reid Spencere7c3c602006-11-30 06:36:44 +0000608 }
609 | '{' TypeListI '}' { // Structure type?
Reid Spencer52402b02007-01-02 05:45:11 +0000610 std::string newTy("{");
611 for (unsigned i = 0; i < $2->size(); ++i) {
612 if (i != 0)
613 newTy += ", ";
614 newTy += (*$2)[i]->getNewTy();
615 }
616 newTy += "}";
617 $$ = new TypeInfo(new std::string(newTy), StructTy, $2);
Reid Spencere7c3c602006-11-30 06:36:44 +0000618 }
619 | '{' '}' { // Empty structure type?
Reid Spencer52402b02007-01-02 05:45:11 +0000620 $$ = new TypeInfo(new std::string("{}"), StructTy, new TypeList());
Reid Spencere7c3c602006-11-30 06:36:44 +0000621 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000622 | '<' '{' TypeListI '}' '>' { // Packed Structure type?
Reid Spencer52402b02007-01-02 05:45:11 +0000623 std::string newTy("<{");
624 for (unsigned i = 0; i < $3->size(); ++i) {
625 if (i != 0)
626 newTy += ", ";
627 newTy += (*$3)[i]->getNewTy();
628 }
629 newTy += "}>";
630 $$ = new TypeInfo(new std::string(newTy), PackedStructTy, $3);
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000631 }
632 | '<' '{' '}' '>' { // Empty packed structure type?
Reid Spencer52402b02007-01-02 05:45:11 +0000633 $$ = new TypeInfo(new std::string("<{}>"), PackedStructTy, new TypeList());
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000634 }
Reid Spencere7c3c602006-11-30 06:36:44 +0000635 | UpRTypes '*' { // Pointer type?
Reid Spencer52402b02007-01-02 05:45:11 +0000636 $$ = $1->getPointerType();
Reid Spencere7c3c602006-11-30 06:36:44 +0000637 };
638
639// TypeList - Used for struct declarations and as a basis for function type
640// declaration type lists
641//
Reid Spencere77e35e2006-12-01 20:26:20 +0000642TypeListI
643 : UpRTypes {
Reid Spencer52402b02007-01-02 05:45:11 +0000644 $$ = new TypeList();
645 $$->push_back($1);
Reid Spencere77e35e2006-12-01 20:26:20 +0000646 }
647 | TypeListI ',' UpRTypes {
Reid Spencere7c3c602006-11-30 06:36:44 +0000648 $$ = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000649 $$->push_back($3);
Reid Spencere7c3c602006-11-30 06:36:44 +0000650 };
651
652// ArgTypeList - List of types for a function type declaration...
Reid Spencere77e35e2006-12-01 20:26:20 +0000653ArgTypeListI
654 : TypeListI
Reid Spencere7c3c602006-11-30 06:36:44 +0000655 | TypeListI ',' DOTDOTDOT {
Reid Spencere7c3c602006-11-30 06:36:44 +0000656 $$ = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000657 $$->push_back(new TypeInfo("void",VoidTy));
658 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000659 }
660 | DOTDOTDOT {
Reid Spencer52402b02007-01-02 05:45:11 +0000661 $$ = new TypeList();
662 $$->push_back(new TypeInfo("void",VoidTy));
663 delete $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000664 }
665 | /*empty*/ {
Reid Spencer52402b02007-01-02 05:45:11 +0000666 $$ = new TypeList();
Reid Spencere7c3c602006-11-30 06:36:44 +0000667 };
668
669// ConstVal - The various declarations that go into the constant pool. This
670// production is used ONLY to represent constants that show up AFTER a 'const',
671// 'constant' or 'global' token at global scope. Constants that can be inlined
672// into other expressions (such as integers and constexprs) are handled by the
673// ResolvedVal, ValueRef and ConstValueRef productions.
674//
675ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
Reid Spencere77e35e2006-12-01 20:26:20 +0000676 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000677 $$.cnst = new std::string($1->getNewTy());
Reid Spencere77e35e2006-12-01 20:26:20 +0000678 *$$.cnst += " [ " + *$3 + " ]";
Reid Spencere7c3c602006-11-30 06:36:44 +0000679 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000680 }
681 | Types '[' ']' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000682 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000683 $$.cnst = new std::string($1->getNewTy());
Reid Spencere77e35e2006-12-01 20:26:20 +0000684 *$$.cnst += "[ ]";
Reid Spencere7c3c602006-11-30 06:36:44 +0000685 }
686 | Types 'c' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000687 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000688 $$.cnst = new std::string($1->getNewTy());
Reid Spencere77e35e2006-12-01 20:26:20 +0000689 *$$.cnst += " c" + *$3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000690 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000691 }
692 | Types '<' ConstVector '>' { // Nonempty unsized arr
Reid Spencere77e35e2006-12-01 20:26:20 +0000693 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000694 $$.cnst = new std::string($1->getNewTy());
Reid Spencere77e35e2006-12-01 20:26:20 +0000695 *$$.cnst += " < " + *$3 + " >";
Reid Spencere7c3c602006-11-30 06:36:44 +0000696 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000697 }
698 | Types '{' ConstVector '}' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000699 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000700 $$.cnst = new std::string($1->getNewTy());
Reid Spencere77e35e2006-12-01 20:26:20 +0000701 *$$.cnst += " { " + *$3 + " }";
Reid Spencere7c3c602006-11-30 06:36:44 +0000702 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000703 }
704 | Types '{' '}' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000705 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000706 $$.cnst = new std::string($1->getNewTy());
Reid Spencer0b7e5072006-12-01 22:42:01 +0000707 *$$.cnst += " {}";
Reid Spencere7c3c602006-11-30 06:36:44 +0000708 }
709 | Types NULL_TOK {
Reid Spencere77e35e2006-12-01 20:26:20 +0000710 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000711 $$.cnst = new std::string($1->getNewTy());
Reid Spencerf2d55322006-12-01 21:52:30 +0000712 *$$.cnst += " " + *$2;
713 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000714 }
715 | Types UNDEF {
Reid Spencere77e35e2006-12-01 20:26:20 +0000716 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000717 $$.cnst = new std::string($1->getNewTy());
Reid Spencerf2d55322006-12-01 21:52:30 +0000718 *$$.cnst += " " + *$2;
719 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000720 }
721 | Types SymbolicValueRef {
Reid Spencer52402b02007-01-02 05:45:11 +0000722 std::string Name = getUniqueName($2,$1);
Reid Spencere77e35e2006-12-01 20:26:20 +0000723 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000724 $$.cnst = new std::string($1->getNewTy());
725 *$$.cnst += " " + Name;
Reid Spencere7c3c602006-11-30 06:36:44 +0000726 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000727 }
728 | Types ConstExpr {
Reid Spencere77e35e2006-12-01 20:26:20 +0000729 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000730 $$.cnst = new std::string($1->getNewTy());
Reid Spencere77e35e2006-12-01 20:26:20 +0000731 *$$.cnst += " " + *$2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000732 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000733 }
734 | Types ZEROINITIALIZER {
Reid Spencere77e35e2006-12-01 20:26:20 +0000735 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000736 $$.cnst = new std::string($1->getNewTy());
Reid Spencerf2d55322006-12-01 21:52:30 +0000737 *$$.cnst += " " + *$2;
738 delete $2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000739 }
740 | SIntType EInt64Val { // integral constants
741 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000742 $$.cnst = new std::string($1->getNewTy());
Reid Spencerf2d55322006-12-01 21:52:30 +0000743 *$$.cnst += " " + *$2;
744 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000745 }
Reid Spencer7356ae42007-01-02 06:34:08 +0000746 | UIntType EInt64Val { // integral constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000747 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000748 $$.cnst = new std::string($1->getNewTy());
Reid Spencerf2d55322006-12-01 21:52:30 +0000749 *$$.cnst += " " + *$2;
750 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000751 }
752 | BOOL TRUETOK { // Boolean constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000753 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000754 $$.cnst = new std::string($1->getNewTy());
Reid Spencerf2d55322006-12-01 21:52:30 +0000755 *$$.cnst += " " + *$2;
756 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000757 }
758 | BOOL FALSETOK { // Boolean constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000759 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000760 $$.cnst = new std::string($1->getNewTy());
Reid Spencerf2d55322006-12-01 21:52:30 +0000761 *$$.cnst += " " + *$2;
762 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000763 }
764 | FPType FPVAL { // Float & Double constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000765 $$.type = $1;
Reid Spencer52402b02007-01-02 05:45:11 +0000766 $$.cnst = new std::string($1->getNewTy());
Reid Spencerf2d55322006-12-01 21:52:30 +0000767 *$$.cnst += " " + *$2;
768 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000769 };
770
771
Reid Spencerfcb5df82006-12-01 22:34:43 +0000772ConstExpr: CastOps '(' ConstVal TO Types ')' {
Reid Spencer280d8012006-12-01 23:40:53 +0000773 std::string source = *$3.cnst;
Reid Spencer52402b02007-01-02 05:45:11 +0000774 TypeInfo* DstTy = ResolveType($5);
Reid Spencer280d8012006-12-01 23:40:53 +0000775 if (*$1 == "cast") {
Reid Spencera50d5962006-12-02 04:11:07 +0000776 // Call getCastUpgrade to upgrade the old cast
Reid Spencer52402b02007-01-02 05:45:11 +0000777 $$ = new std::string(getCastUpgrade(source, $3.type, DstTy, true));
Reid Spencera50d5962006-12-02 04:11:07 +0000778 } else {
779 // Nothing to upgrade, just create the cast constant expr
780 $$ = new std::string(*$1);
Reid Spencer52402b02007-01-02 05:45:11 +0000781 *$$ += "( " + source + " to " + $5->getNewTy() + ")";
Reid Spencer280d8012006-12-01 23:40:53 +0000782 }
Reid Spencereff838e2007-01-03 23:45:42 +0000783 delete $1; $3.destroy(); delete $4;
Reid Spencere7c3c602006-11-30 06:36:44 +0000784 }
785 | GETELEMENTPTR '(' ConstVal IndexList ')' {
Reid Spencerf8483652006-12-02 15:16:01 +0000786 *$1 += "(" + *$3.cnst;
787 for (unsigned i = 0; i < $4->size(); ++i) {
788 ValueInfo& VI = (*$4)[i];
789 *$1 += ", " + *VI.val;
790 VI.destroy();
791 }
792 *$1 += ")";
Reid Spencere77e35e2006-12-01 20:26:20 +0000793 $$ = $1;
794 $3.destroy();
795 delete $4;
Reid Spencere7c3c602006-11-30 06:36:44 +0000796 }
797 | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000798 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
799 $3.destroy(); $5.destroy(); $7.destroy();
800 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000801 }
802 | ArithmeticOps '(' ConstVal ',' ConstVal ')' {
Reid Spencer78720742006-12-02 20:21:22 +0000803 const char* op = getDivRemOpcode(*$1, $3.type);
804 $$ = new std::string(op);
805 *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
806 delete $1; $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000807 }
808 | LogicalOps '(' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000809 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
810 $3.destroy(); $5.destroy();
811 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000812 }
813 | SetCondOps '(' ConstVal ',' ConstVal ')' {
Reid Spencer229e9362006-12-02 22:14:11 +0000814 *$1 = getCompareOp(*$1, $3.type);
Reid Spencere77e35e2006-12-01 20:26:20 +0000815 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
816 $3.destroy(); $5.destroy();
817 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000818 }
Reid Spencer57f28f92006-12-03 07:10:26 +0000819 | ICMP IPredicates '(' ConstVal ',' ConstVal ')' {
820 *$1 += "(" + *$2 + "," + *$4.cnst + "," + *$6.cnst + ")";
821 delete $2; $4.destroy(); $6.destroy();
822 $$ = $1;
823 }
824 | FCMP FPredicates '(' ConstVal ',' ConstVal ')' {
Reid Spencer229e9362006-12-02 22:14:11 +0000825 *$1 += "(" + *$2 + "," + *$4.cnst + "," + *$6.cnst + ")";
826 delete $2; $4.destroy(); $6.destroy();
827 $$ = $1;
828 }
Reid Spencere7c3c602006-11-30 06:36:44 +0000829 | ShiftOps '(' ConstVal ',' ConstVal ')' {
Reid Spencerf7bde222006-12-01 22:26:37 +0000830 const char* shiftop = $1->c_str();
831 if (*$1 == "shr")
Reid Spencer52402b02007-01-02 05:45:11 +0000832 shiftop = ($3.type->isUnsigned()) ? "lshr" : "ashr";
Reid Spencerf7bde222006-12-01 22:26:37 +0000833 $$ = new std::string(shiftop);
834 *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
835 delete $1; $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000836 }
837 | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000838 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
839 $3.destroy(); $5.destroy();
840 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000841 }
842 | INSERTELEMENT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000843 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
844 $3.destroy(); $5.destroy(); $7.destroy();
845 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000846 }
847 | SHUFFLEVECTOR '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000848 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
849 $3.destroy(); $5.destroy(); $7.destroy();
850 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000851 };
852
853
854// ConstVector - A list of comma separated constants.
Reid Spencere77e35e2006-12-01 20:26:20 +0000855
856ConstVector
857 : ConstVector ',' ConstVal {
858 *$1 += ", " + *$3.cnst;
859 $3.destroy();
860 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000861 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000862 | ConstVal { $$ = new std::string(*$1.cnst); $1.destroy(); }
863 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000864
865
866// GlobalType - Match either GLOBAL or CONSTANT for global declarations...
Reid Spencere77e35e2006-12-01 20:26:20 +0000867GlobalType : GLOBAL | CONSTANT ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000868
869
870//===----------------------------------------------------------------------===//
871// Rules to match Modules
872//===----------------------------------------------------------------------===//
873
874// Module rule: Capture the result of parsing the whole file into a result
875// variable...
876//
877Module : DefinitionList {
878};
879
880// DefinitionList - Top level definitions
881//
882DefinitionList : DefinitionList Function {
883 $$ = 0;
884 }
885 | DefinitionList FunctionProto {
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000886 *O << *$2 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +0000887 delete $2;
888 $$ = 0;
889 }
890 | DefinitionList MODULE ASM_TOK AsmBlock {
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000891 *O << "module asm " << ' ' << *$4 << '\n';
Reid Spencerd154b572006-12-01 20:36:40 +0000892 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000893 }
894 | DefinitionList IMPLEMENTATION {
895 *O << "implementation\n";
Reid Spencerd154b572006-12-01 20:36:40 +0000896 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000897 }
Reid Spencera50d5962006-12-02 04:11:07 +0000898 | ConstPool { $$ = 0; }
Reid Spencere7c3c602006-11-30 06:36:44 +0000899
Reid Spencer78720742006-12-02 20:21:22 +0000900External : EXTERNAL | UNINITIALIZED { $$ = $1; *$$ = "external"; }
901
Reid Spencere7c3c602006-11-30 06:36:44 +0000902// ConstPool - Constants with optional names assigned to them.
903ConstPool : ConstPool OptAssign TYPE TypesV {
Reid Spencer52402b02007-01-02 05:45:11 +0000904 EnumeratedTypes.push_back(*$4);
Reid Spencera50d5962006-12-02 04:11:07 +0000905 if (!$2->empty()) {
Reid Spencer52402b02007-01-02 05:45:11 +0000906 NamedTypes[*$2] = *$4;
Reid Spencera50d5962006-12-02 04:11:07 +0000907 *O << *$2 << " = ";
908 }
Reid Spencer52402b02007-01-02 05:45:11 +0000909 *O << "type " << $4->getNewTy() << '\n';
910 delete $2; delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000911 $$ = 0;
912 }
913 | ConstPool FunctionProto { // Function prototypes can be in const pool
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000914 *O << *$2 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +0000915 delete $2;
916 $$ = 0;
917 }
918 | ConstPool MODULE ASM_TOK AsmBlock { // Asm blocks can be in the const pool
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000919 *O << *$2 << ' ' << *$3 << ' ' << *$4 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +0000920 delete $2; delete $3; delete $4;
921 $$ = 0;
922 }
923 | ConstPool OptAssign OptLinkage GlobalType ConstVal GlobalVarAttributes {
Reid Spencerf12ee422006-12-05 19:21:25 +0000924 if (!$2->empty()) {
Reid Spencer52402b02007-01-02 05:45:11 +0000925 std::string Name = getUniqueName($2,$5.type);
926 *O << Name << " = ";
927 Globals[Name] = *$5.type;
Reid Spencerf12ee422006-12-05 19:21:25 +0000928 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000929 *O << *$3 << ' ' << *$4 << ' ' << *$5.cnst << ' ' << *$6 << '\n';
Reid Spencer52402b02007-01-02 05:45:11 +0000930 delete $2; delete $3; delete $4; delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000931 $$ = 0;
932 }
Reid Spencer78720742006-12-02 20:21:22 +0000933 | ConstPool OptAssign External GlobalType Types GlobalVarAttributes {
Reid Spencerf12ee422006-12-05 19:21:25 +0000934 if (!$2->empty()) {
Reid Spencer52402b02007-01-02 05:45:11 +0000935 std::string Name = getUniqueName($2,$5);
936 *O << Name << " = ";
937 Globals[Name] = *$5;
Reid Spencerf12ee422006-12-05 19:21:25 +0000938 }
Reid Spencer52402b02007-01-02 05:45:11 +0000939 *O << *$3 << ' ' << *$4 << ' ' << $5->getNewTy() << ' ' << *$6 << '\n';
940 delete $2; delete $3; delete $4; delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000941 $$ = 0;
942 }
943 | ConstPool OptAssign DLLIMPORT GlobalType Types GlobalVarAttributes {
Reid Spencerf12ee422006-12-05 19:21:25 +0000944 if (!$2->empty()) {
Reid Spencer52402b02007-01-02 05:45:11 +0000945 std::string Name = getUniqueName($2,$5);
946 *O << Name << " = ";
947 Globals[Name] = *$5;
Reid Spencerf12ee422006-12-05 19:21:25 +0000948 }
Reid Spencer52402b02007-01-02 05:45:11 +0000949 *O << *$3 << ' ' << *$4 << ' ' << $5->getNewTy() << ' ' << *$6 << '\n';
950 delete $2; delete $3; delete $4; delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000951 $$ = 0;
952 }
953 | ConstPool OptAssign EXTERN_WEAK GlobalType Types GlobalVarAttributes {
Reid Spencerf12ee422006-12-05 19:21:25 +0000954 if (!$2->empty()) {
Reid Spencer52402b02007-01-02 05:45:11 +0000955 std::string Name = getUniqueName($2,$5);
956 *O << Name << " = ";
957 Globals[Name] = *$5;
Reid Spencerf12ee422006-12-05 19:21:25 +0000958 }
Reid Spencer52402b02007-01-02 05:45:11 +0000959 *O << *$3 << ' ' << *$4 << ' ' << $5->getNewTy() << ' ' << *$6 << '\n';
960 delete $2; delete $3; delete $4; delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000961 $$ = 0;
962 }
963 | ConstPool TARGET TargetDefinition {
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000964 *O << *$2 << ' ' << *$3 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +0000965 delete $2; delete $3;
966 $$ = 0;
967 }
968 | ConstPool DEPLIBS '=' LibrariesDefinition {
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000969 *O << *$2 << " = " << *$4 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +0000970 delete $2; delete $4;
971 $$ = 0;
972 }
973 | /* empty: end of list */ {
974 $$ = 0;
975 };
976
977
978AsmBlock : STRINGCONSTANT ;
979
980BigOrLittle : BIG | LITTLE
981
982TargetDefinition
983 : ENDIAN '=' BigOrLittle {
Reid Spencere77e35e2006-12-01 20:26:20 +0000984 *$1 += " = " + *$3;
985 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000986 $$ = $1;
987 }
988 | POINTERSIZE '=' EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000989 *$1 += " = " + *$3;
990 if (*$3 == "64")
Reid Spencere77e35e2006-12-01 20:26:20 +0000991 SizeOfPointer = 64;
Reid Spencerf2d55322006-12-01 21:52:30 +0000992 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000993 $$ = $1;
994 }
995 | TRIPLE '=' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000996 *$1 += " = " + *$3;
997 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000998 $$ = $1;
999 }
1000 | DATALAYOUT '=' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +00001001 *$1 += " = " + *$3;
1002 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001003 $$ = $1;
1004 };
1005
1006LibrariesDefinition
1007 : '[' LibList ']' {
1008 $2->insert(0, "[ ");
1009 *$2 += " ]";
1010 $$ = $2;
1011 };
1012
1013LibList
1014 : LibList ',' STRINGCONSTANT {
1015 *$1 += ", " + *$3;
1016 delete $3;
1017 $$ = $1;
1018 }
1019 | STRINGCONSTANT
1020 | /* empty: end of list */ {
1021 $$ = new std::string();
1022 };
1023
1024//===----------------------------------------------------------------------===//
1025// Rules to match Function Headers
1026//===----------------------------------------------------------------------===//
1027
1028Name : VAR_ID | STRINGCONSTANT;
1029OptName : Name | /*empty*/ { $$ = new std::string(); };
1030
1031ArgVal : Types OptName {
Reid Spencer52402b02007-01-02 05:45:11 +00001032 $$ = new std::string($1->getNewTy());
1033 if (!$2->empty()) {
1034 std::string Name = getUniqueName($2, $1);
1035 *$$ += " " + Name;
1036 }
Reid Spencere77e35e2006-12-01 20:26:20 +00001037 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +00001038};
1039
1040ArgListH : ArgListH ',' ArgVal {
1041 *$1 += ", " + *$3;
Reid Spencere77e35e2006-12-01 20:26:20 +00001042 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001043 }
1044 | ArgVal {
1045 $$ = $1;
1046 };
1047
1048ArgList : ArgListH {
1049 $$ = $1;
1050 }
1051 | ArgListH ',' DOTDOTDOT {
1052 *$1 += ", ...";
1053 $$ = $1;
Reid Spencere77e35e2006-12-01 20:26:20 +00001054 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001055 }
1056 | DOTDOTDOT {
1057 $$ = $1;
1058 }
Reid Spencerd154b572006-12-01 20:36:40 +00001059 | /* empty */ { $$ = new std::string(); };
Reid Spencere7c3c602006-11-30 06:36:44 +00001060
Reid Spencer71d2ec92006-12-31 06:02:26 +00001061FunctionHeaderH
1062 : OptCallingConv TypesV Name '(' ArgList ')' OptSection OptAlign {
Reid Spencere7c3c602006-11-30 06:36:44 +00001063 if (!$1->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +00001064 *$1 += " ";
Reid Spencere7c3c602006-11-30 06:36:44 +00001065 }
Reid Spencer52402b02007-01-02 05:45:11 +00001066 *$1 += $2->getNewTy() + " " + *$3 + "(" + *$5 + ")";
Reid Spencere7c3c602006-11-30 06:36:44 +00001067 if (!$7->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +00001068 *$1 += " " + *$7;
Reid Spencere7c3c602006-11-30 06:36:44 +00001069 }
1070 if (!$8->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +00001071 *$1 += " " + *$8;
Reid Spencere7c3c602006-11-30 06:36:44 +00001072 }
Reid Spencere77e35e2006-12-01 20:26:20 +00001073 delete $3;
1074 delete $5;
1075 delete $7;
1076 delete $8;
1077 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +00001078 };
1079
Reid Spencer78720742006-12-02 20:21:22 +00001080BEGIN : BEGINTOK { $$ = new std::string("{"); delete $1; }
1081 | '{' { $$ = new std::string ("{"); }
Reid Spencere7c3c602006-11-30 06:36:44 +00001082
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001083FunctionHeader
1084 : OptLinkage FunctionHeaderH BEGIN {
1085 *O << "define ";
1086 if (!$1->empty()) {
1087 *O << *$1 << ' ';
1088 }
1089 *O << *$2 << ' ' << *$3 << '\n';
1090 delete $1; delete $2; delete $3;
1091 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +00001092 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001093 ;
Reid Spencere7c3c602006-11-30 06:36:44 +00001094
Reid Spencer78720742006-12-02 20:21:22 +00001095END : ENDTOK { $$ = new std::string("}"); delete $1; }
Reid Spencere7c3c602006-11-30 06:36:44 +00001096 | '}' { $$ = new std::string("}"); };
1097
1098Function : FunctionHeader BasicBlockList END {
1099 if ($2)
1100 *O << *$2;
Reid Spencer71d2ec92006-12-31 06:02:26 +00001101 *O << *$3 << "\n\n";
Reid Spencer52402b02007-01-02 05:45:11 +00001102 delete $1; delete $2; delete $3;
Reid Spencere77e35e2006-12-01 20:26:20 +00001103 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +00001104};
1105
Reid Spencere77e35e2006-12-01 20:26:20 +00001106FnDeclareLinkage
1107 : /*default*/ { $$ = new std::string(); }
Reid Spencere7c3c602006-11-30 06:36:44 +00001108 | DLLIMPORT
1109 | EXTERN_WEAK
1110 ;
1111
1112FunctionProto
1113 : DECLARE FnDeclareLinkage FunctionHeaderH {
Reid Spencere77e35e2006-12-01 20:26:20 +00001114 if (!$2->empty())
1115 *$1 += " " + *$2;
1116 *$1 += " " + *$3;
1117 delete $2;
1118 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001119 $$ = $1;
1120 };
1121
1122//===----------------------------------------------------------------------===//
1123// Rules to match Basic Blocks
1124//===----------------------------------------------------------------------===//
1125
Reid Spencerd154b572006-12-01 20:36:40 +00001126OptSideEffect : /* empty */ { $$ = new std::string(); }
1127 | SIDEEFFECT;
Reid Spencere7c3c602006-11-30 06:36:44 +00001128
Reid Spencere77e35e2006-12-01 20:26:20 +00001129ConstValueRef
Reid Spencerf2d55322006-12-01 21:52:30 +00001130 : ESINT64VAL | EUINT64VAL | FPVAL | TRUETOK | FALSETOK | NULL_TOK | UNDEF
1131 | ZEROINITIALIZER
Reid Spencere7c3c602006-11-30 06:36:44 +00001132 | '<' ConstVector '>' {
1133 $2->insert(0, "<");
1134 *$2 += ">";
1135 $$ = $2;
1136 }
1137 | ConstExpr
1138 | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT {
1139 if (!$2->empty()) {
1140 *$1 += " " + *$2;
1141 }
Reid Spencere77e35e2006-12-01 20:26:20 +00001142 *$1 += " " + *$3 + ", " + *$5;
1143 delete $2; delete $3; delete $5;
Reid Spencere7c3c602006-11-30 06:36:44 +00001144 $$ = $1;
1145 };
1146
Reid Spencerf2d55322006-12-01 21:52:30 +00001147SymbolicValueRef : IntVal | Name ;
Reid Spencere7c3c602006-11-30 06:36:44 +00001148
1149// ValueRef - A reference to a definition... either constant or symbolic
Reid Spencerf459d392006-12-02 16:19:52 +00001150ValueRef
1151 : SymbolicValueRef {
1152 $$.val = $1;
1153 $$.constant = false;
Reid Spencer52402b02007-01-02 05:45:11 +00001154 $$.type = new TypeInfo();
Reid Spencerf459d392006-12-02 16:19:52 +00001155 }
1156 | ConstValueRef {
1157 $$.val = $1;
1158 $$.constant = true;
Reid Spencer52402b02007-01-02 05:45:11 +00001159 $$.type = new TypeInfo();
Reid Spencerf459d392006-12-02 16:19:52 +00001160 }
1161 ;
Reid Spencere7c3c602006-11-30 06:36:44 +00001162
1163// ResolvedVal - a <type> <value> pair. This is used only in cases where the
1164// type immediately preceeds the value reference, and allows complex constant
1165// pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
1166ResolvedVal : Types ValueRef {
Reid Spencereff838e2007-01-03 23:45:42 +00001167 ResolveType($1);
Reid Spencer52402b02007-01-02 05:45:11 +00001168 std::string Name = getUniqueName($2.val, $1);
Reid Spencerf459d392006-12-02 16:19:52 +00001169 $$ = $2;
Reid Spencer52402b02007-01-02 05:45:11 +00001170 delete $$.val;
1171 delete $$.type;
1172 $$.val = new std::string($1->getNewTy() + " " + Name);
Reid Spencere77e35e2006-12-01 20:26:20 +00001173 $$.type = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +00001174 };
1175
1176BasicBlockList : BasicBlockList BasicBlock {
Reid Spencerf2d55322006-12-01 21:52:30 +00001177 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +00001178 }
1179 | BasicBlock { // Do not allow functions with 0 basic blocks
Reid Spencerf2d55322006-12-01 21:52:30 +00001180 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +00001181 };
1182
1183
1184// Basic blocks are terminated by branching instructions:
1185// br, br/cc, switch, ret
1186//
Reid Spencer16244f42006-12-01 21:10:07 +00001187BasicBlock : InstructionList BBTerminatorInst {
Reid Spencerf2d55322006-12-01 21:52:30 +00001188 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +00001189 };
1190
1191InstructionList : InstructionList Inst {
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001192 *O << " " << *$2 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +00001193 delete $2;
1194 $$ = 0;
1195 }
1196 | /* empty */ {
1197 $$ = 0;
1198 }
1199 | LABELSTR {
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001200 *O << *$1 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +00001201 delete $1;
1202 $$ = 0;
1203 };
1204
Reid Spencer78720742006-12-02 20:21:22 +00001205Unwind : UNWIND | EXCEPT { $$ = $1; *$$ = "unwind"; }
1206
Reid Spencere7c3c602006-11-30 06:36:44 +00001207BBTerminatorInst : RET ResolvedVal { // Return with a result...
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001208 *O << " " << *$1 << ' ' << *$2.val << '\n';
Reid Spencere77e35e2006-12-01 20:26:20 +00001209 delete $1; $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001210 $$ = 0;
1211 }
1212 | RET VOID { // Return with no result...
Reid Spencer52402b02007-01-02 05:45:11 +00001213 *O << " " << *$1 << ' ' << $2->getNewTy() << '\n';
1214 delete $1; delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +00001215 $$ = 0;
1216 }
1217 | BR LABEL ValueRef { // Unconditional Branch...
Reid Spencer52402b02007-01-02 05:45:11 +00001218 *O << " " << *$1 << ' ' << $2->getNewTy() << ' ' << *$3.val << '\n';
1219 delete $1; delete $2; $3.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001220 $$ = 0;
1221 } // Conditional Branch...
1222 | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {
Reid Spencer52402b02007-01-02 05:45:11 +00001223 std::string Name = getUniqueName($3.val, $2);
1224 *O << " " << *$1 << ' ' << $2->getNewTy() << ' ' << Name << ", "
1225 << $5->getNewTy() << ' ' << *$6.val << ", " << $8->getNewTy() << ' '
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001226 << *$9.val << '\n';
Reid Spencer52402b02007-01-02 05:45:11 +00001227 delete $1; delete $2; $3.destroy(); delete $5; $6.destroy();
1228 delete $8; $9.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001229 $$ = 0;
1230 }
1231 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
Reid Spencer52402b02007-01-02 05:45:11 +00001232 std::string Name = getUniqueName($3.val, $2);
1233 *O << " " << *$1 << ' ' << $2->getNewTy() << ' ' << Name << ", "
1234 << $5->getNewTy() << ' ' << *$6.val << " [" << *$8 << " ]\n";
1235 delete $1; delete $2; $3.destroy(); delete $5; $6.destroy();
Reid Spencerf459d392006-12-02 16:19:52 +00001236 delete $8;
Reid Spencere7c3c602006-11-30 06:36:44 +00001237 $$ = 0;
1238 }
1239 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' {
Reid Spencer52402b02007-01-02 05:45:11 +00001240 std::string Name = getUniqueName($3.val, $2);
1241 *O << " " << *$1 << ' ' << $2->getNewTy() << ' ' << Name << ", "
1242 << $5->getNewTy() << ' ' << *$6.val << "[]\n";
1243 delete $1; delete $2; $3.destroy(); delete $5; $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001244 $$ = 0;
1245 }
Reid Spencer16244f42006-12-01 21:10:07 +00001246 | OptAssign INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')'
Reid Spencer78720742006-12-02 20:21:22 +00001247 TO LABEL ValueRef Unwind LABEL ValueRef {
Reid Spencer52402b02007-01-02 05:45:11 +00001248 TypeInfo* ResTy = getFunctionReturnType($4);
Reid Spencer16244f42006-12-01 21:10:07 +00001249 *O << " ";
Reid Spencer52402b02007-01-02 05:45:11 +00001250 if (!$1->empty()) {
1251 std::string Name = getUniqueName($1, ResTy);
1252 *O << Name << " = ";
1253 }
1254 *O << *$2 << ' ' << *$3 << ' ' << $4->getNewTy() << ' ' << *$5.val << " (";
Reid Spencerf8483652006-12-02 15:16:01 +00001255 for (unsigned i = 0; i < $7->size(); ++i) {
1256 ValueInfo& VI = (*$7)[i];
1257 *O << *VI.val;
1258 if (i+1 < $7->size())
1259 *O << ", ";
1260 VI.destroy();
1261 }
Reid Spencer52402b02007-01-02 05:45:11 +00001262 *O << ") " << *$9 << ' ' << $10->getNewTy() << ' ' << *$11.val << ' '
1263 << *$12 << ' ' << $13->getNewTy() << ' ' << *$14.val << '\n';
1264 delete $1; delete $2; delete $3; delete $4; $5.destroy(); delete $7;
1265 delete $9; delete $10; $11.destroy(); delete $12; delete $13;
Reid Spencerf459d392006-12-02 16:19:52 +00001266 $14.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001267 $$ = 0;
1268 }
Reid Spencer78720742006-12-02 20:21:22 +00001269 | Unwind {
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001270 *O << " " << *$1 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +00001271 delete $1;
1272 $$ = 0;
1273 }
1274 | UNREACHABLE {
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001275 *O << " " << *$1 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +00001276 delete $1;
1277 $$ = 0;
1278 };
1279
1280JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
Reid Spencer52402b02007-01-02 05:45:11 +00001281 *$1 += " " + $2->getNewTy() + " " + *$3 + ", " + $5->getNewTy() + " " +
1282 *$6.val;
1283 delete $2; delete $3; delete $5; $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001284 $$ = $1;
1285 }
1286 | IntType ConstValueRef ',' LABEL ValueRef {
Reid Spencer52402b02007-01-02 05:45:11 +00001287 $2->insert(0, $1->getNewTy() + " " );
1288 *$2 += ", " + $4->getNewTy() + " " + *$5.val;
1289 delete $1; delete $4; $5.destroy();
Reid Spencere77e35e2006-12-01 20:26:20 +00001290 $$ = $2;
Reid Spencere7c3c602006-11-30 06:36:44 +00001291 };
1292
1293Inst
1294 : OptAssign InstVal {
Reid Spencerf5626a32007-01-01 01:20:41 +00001295 if (!$1->empty()) {
1296 if (deleteUselessCastFlag && *deleteUselessCastName == *$1) {
1297 *$1 += " = ";
1298 $1->insert(0, "; "); // don't actually delete it, just comment it out
1299 delete deleteUselessCastName;
1300 } else {
Reid Spencer52402b02007-01-02 05:45:11 +00001301 // Get a unique name for the name of this value, based on its type.
1302 *$1 = getUniqueName($1, $2.type) + " = ";
Reid Spencerf5626a32007-01-01 01:20:41 +00001303 }
1304 }
Reid Spencer52402b02007-01-02 05:45:11 +00001305 *$1 += *$2.val;
1306 $2.destroy();
Reid Spencerf5626a32007-01-01 01:20:41 +00001307 deleteUselessCastFlag = false;
Reid Spencere7c3c602006-11-30 06:36:44 +00001308 $$ = $1;
1309 };
1310
1311PHIList
1312 : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes
Reid Spencer52402b02007-01-02 05:45:11 +00001313 std::string Name = getUniqueName($3.val, $1);
1314 Name.insert(0, $1->getNewTy() + "[");
1315 Name += "," + *$5.val + "]";
1316 $$.val = new std::string(Name);
1317 $$.type = $1;
1318 $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001319 }
1320 | PHIList ',' '[' ValueRef ',' ValueRef ']' {
Reid Spencer52402b02007-01-02 05:45:11 +00001321 std::string Name = getUniqueName($4.val, $1.type);
1322 *$1.val += ", [" + Name + "," + *$6.val + "]";
Reid Spencerf459d392006-12-02 16:19:52 +00001323 $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001324 $$ = $1;
1325 };
1326
1327
1328ValueRefList
Reid Spencer52402b02007-01-02 05:45:11 +00001329 : ResolvedVal {
Reid Spencerf8483652006-12-02 15:16:01 +00001330 $$ = new ValueList();
1331 $$->push_back($1);
1332 }
Reid Spencere7c3c602006-11-30 06:36:44 +00001333 | ValueRefList ',' ResolvedVal {
Reid Spencere7c3c602006-11-30 06:36:44 +00001334 $$ = $1;
Reid Spencer52402b02007-01-02 05:45:11 +00001335 $$->push_back($3);
Reid Spencere7c3c602006-11-30 06:36:44 +00001336 };
1337
1338// ValueRefListE - Just like ValueRefList, except that it may also be empty!
1339ValueRefListE
Reid Spencerf8483652006-12-02 15:16:01 +00001340 : ValueRefList { $$ = $1; }
1341 | /*empty*/ { $$ = new ValueList(); }
Reid Spencere7c3c602006-11-30 06:36:44 +00001342 ;
1343
1344OptTailCall
1345 : TAIL CALL {
1346 *$1 += " " + *$2;
1347 delete $2;
1348 $$ = $1;
1349 }
1350 | CALL
1351 ;
1352
1353InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
Reid Spencer78720742006-12-02 20:21:22 +00001354 const char* op = getDivRemOpcode(*$1, $2);
Reid Spencer52402b02007-01-02 05:45:11 +00001355 std::string Name1 = getUniqueName($3.val, $2);
1356 std::string Name2 = getUniqueName($5.val, $2);
1357 $$.val = new std::string(op);
1358 *$$.val += " " + $2->getNewTy() + " " + Name1 + ", " + Name2;
1359 $$.type = $2;
1360 delete $1; $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001361 }
1362 | LogicalOps Types ValueRef ',' ValueRef {
Reid Spencer52402b02007-01-02 05:45:11 +00001363 std::string Name1 = getUniqueName($3.val, $2);
1364 std::string Name2 = getUniqueName($5.val, $2);
1365 *$1 += " " + $2->getNewTy() + " " + Name1 + ", " + Name2;
1366 $$.val = $1;
1367 $$.type = $2;
1368 $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001369 }
1370 | SetCondOps Types ValueRef ',' ValueRef {
Reid Spencer52402b02007-01-02 05:45:11 +00001371 std::string Name1 = getUniqueName($3.val, $2);
1372 std::string Name2 = getUniqueName($5.val, $2);
Reid Spencer229e9362006-12-02 22:14:11 +00001373 *$1 = getCompareOp(*$1, $2);
Reid Spencer52402b02007-01-02 05:45:11 +00001374 *$1 += " " + $2->getNewTy() + " " + Name1 + ", " + Name2;
1375 $$.val = $1;
1376 $$.type = new TypeInfo("bool",BoolTy);
1377 $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001378 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001379 | ICMP IPredicates Types ValueRef ',' ValueRef {
Reid Spencer52402b02007-01-02 05:45:11 +00001380 std::string Name1 = getUniqueName($4.val, $3);
1381 std::string Name2 = getUniqueName($6.val, $3);
1382 *$1 += " " + *$2 + " " + $3->getNewTy() + " " + Name1 + "," + Name2;
1383 $$.val = $1;
1384 $$.type = new TypeInfo("bool",BoolTy);
Reid Spencer57f28f92006-12-03 07:10:26 +00001385 delete $2; $4.destroy(); $6.destroy();
Reid Spencer57f28f92006-12-03 07:10:26 +00001386 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001387 | FCMP FPredicates Types ValueRef ',' ValueRef {
Reid Spencer52402b02007-01-02 05:45:11 +00001388 std::string Name1 = getUniqueName($4.val, $3);
1389 std::string Name2 = getUniqueName($6.val, $3);
1390 *$1 += " " + *$2 + " " + $3->getNewTy() + " " + Name1 + "," + Name2;
1391 $$.val = $1;
1392 $$.type = new TypeInfo("bool",BoolTy);
Reid Spencer229e9362006-12-02 22:14:11 +00001393 delete $2; $4.destroy(); $6.destroy();
Reid Spencer229e9362006-12-02 22:14:11 +00001394 }
Reid Spencere7c3c602006-11-30 06:36:44 +00001395 | NOT ResolvedVal {
Reid Spencer52402b02007-01-02 05:45:11 +00001396 $$ = $2;
1397 $$.val->insert(0, *$1 + " ");
1398 delete $1;
Reid Spencere7c3c602006-11-30 06:36:44 +00001399 }
1400 | ShiftOps ResolvedVal ',' ResolvedVal {
Reid Spencerf7bde222006-12-01 22:26:37 +00001401 const char* shiftop = $1->c_str();
1402 if (*$1 == "shr")
Reid Spencer52402b02007-01-02 05:45:11 +00001403 shiftop = ($2.type->isUnsigned()) ? "lshr" : "ashr";
1404 $$.val = new std::string(shiftop);
1405 *$$.val += " " + *$2.val + ", " + *$4.val;
1406 $$.type = $2.type;
1407 delete $1; delete $2.val; $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001408 }
Reid Spencerfcb5df82006-12-01 22:34:43 +00001409 | CastOps ResolvedVal TO Types {
Reid Spencer280d8012006-12-01 23:40:53 +00001410 std::string source = *$2.val;
Reid Spencer52402b02007-01-02 05:45:11 +00001411 TypeInfo* SrcTy = $2.type;
1412 TypeInfo* DstTy = ResolveType($4);
1413 $$.val = new std::string();
Reid Spencer280d8012006-12-01 23:40:53 +00001414 if (*$1 == "cast") {
Reid Spencer52402b02007-01-02 05:45:11 +00001415 *$$.val += getCastUpgrade(source, SrcTy, DstTy, false);
Reid Spencera50d5962006-12-02 04:11:07 +00001416 } else {
Reid Spencer52402b02007-01-02 05:45:11 +00001417 *$$.val += *$1 + " " + source + " to " + DstTy->getNewTy();
Reid Spencer280d8012006-12-01 23:40:53 +00001418 }
Reid Spencer52402b02007-01-02 05:45:11 +00001419 $$.type = $4;
Reid Spencerf5626a32007-01-01 01:20:41 +00001420 // Check to see if this is a useless cast of a value to the same name
1421 // and the same type. Such casts will probably cause redefinition errors
1422 // when assembled and perform no code gen action so just remove them.
1423 if (*$1 == "cast" || *$1 == "bitcast")
Reid Spencer52402b02007-01-02 05:45:11 +00001424 if ($2.type->isInteger() && DstTy->isInteger() &&
1425 $2.type->getBitWidth() == DstTy->getBitWidth()) {
Reid Spencerf5626a32007-01-01 01:20:41 +00001426 deleteUselessCastFlag = true; // Flag the "Inst" rule
1427 deleteUselessCastName = new std::string(*$2.val); // save the name
1428 size_t pos = deleteUselessCastName->find_first_of("%\"",0);
1429 if (pos != std::string::npos) {
1430 // remove the type portion before val
1431 deleteUselessCastName->erase(0, pos);
1432 }
1433 }
Reid Spencere77e35e2006-12-01 20:26:20 +00001434 delete $1; $2.destroy();
Reid Spencer52402b02007-01-02 05:45:11 +00001435 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001436 }
1437 | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001438 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
Reid Spencer52402b02007-01-02 05:45:11 +00001439 $$.val = $1;
1440 $$.type = $4.type;
1441 $2.destroy(); delete $4.val; $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001442 }
1443 | VAARG ResolvedVal ',' Types {
Reid Spencer52402b02007-01-02 05:45:11 +00001444 *$1 += " " + *$2.val + ", " + $4->getNewTy();
1445 $$.val = $1;
1446 $$.type = $4;
1447 $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001448 }
1449 | EXTRACTELEMENT ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001450 *$1 += " " + *$2.val + ", " + *$4.val;
Reid Spencer52402b02007-01-02 05:45:11 +00001451 $$.val = $1;
1452 ResolveType($2.type);
Reid Spencereff838e2007-01-03 23:45:42 +00001453 $$.type = $2.type->getElementType();
Reid Spencer52402b02007-01-02 05:45:11 +00001454 delete $2.val; $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001455 }
1456 | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001457 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
Reid Spencer52402b02007-01-02 05:45:11 +00001458 $$.val = $1;
1459 $$.type = $2.type;
1460 delete $2.val; $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001461 }
1462 | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001463 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
Reid Spencer52402b02007-01-02 05:45:11 +00001464 $$.val = $1;
1465 $$.type = $2.type;
1466 delete $2.val; $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001467 }
1468 | PHI_TOK PHIList {
Reid Spencer52402b02007-01-02 05:45:11 +00001469 *$1 += " " + *$2.val;
1470 $$.val = $1;
1471 $$.type = $2.type;
1472 delete $2.val;
Reid Spencere7c3c602006-11-30 06:36:44 +00001473 }
1474 | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' {
1475 if (!$2->empty())
1476 *$1 += " " + *$2;
1477 if (!$1->empty())
1478 *$1 += " ";
Reid Spencer52402b02007-01-02 05:45:11 +00001479 *$1 += $3->getNewTy() + " " + *$4.val + "(";
Reid Spencerf8483652006-12-02 15:16:01 +00001480 for (unsigned i = 0; i < $6->size(); ++i) {
1481 ValueInfo& VI = (*$6)[i];
1482 *$1 += *VI.val;
1483 if (i+1 < $6->size())
1484 *$1 += ", ";
1485 VI.destroy();
1486 }
1487 *$1 += ")";
Reid Spencer52402b02007-01-02 05:45:11 +00001488 $$.val = $1;
1489 $$.type = getFunctionReturnType($3);
1490 delete $2; delete $3; $4.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001491 }
1492 | MemoryInst ;
1493
1494
1495// IndexList - List of indices for GEP based instructions...
1496IndexList
Reid Spencerf8483652006-12-02 15:16:01 +00001497 : ',' ValueRefList { $$ = $2; }
1498 | /* empty */ { $$ = new ValueList(); }
Reid Spencere7c3c602006-11-30 06:36:44 +00001499 ;
1500
1501OptVolatile
1502 : VOLATILE
1503 | /* empty */ { $$ = new std::string(); }
1504 ;
1505
1506MemoryInst : MALLOC Types OptCAlign {
Reid Spencer52402b02007-01-02 05:45:11 +00001507 *$1 += " " + $2->getNewTy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001508 if (!$3->empty())
1509 *$1 += " " + *$3;
Reid Spencer52402b02007-01-02 05:45:11 +00001510 $$.val = $1;
1511 $$.type = $2->getPointerType();
1512 delete $2; delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001513 }
1514 | MALLOC Types ',' UINT ValueRef OptCAlign {
Reid Spencer52402b02007-01-02 05:45:11 +00001515 std::string Name = getUniqueName($5.val, $4);
1516 *$1 += " " + $2->getNewTy() + ", " + $4->getNewTy() + " " + Name;
Reid Spencere7c3c602006-11-30 06:36:44 +00001517 if (!$6->empty())
1518 *$1 += " " + *$6;
Reid Spencer52402b02007-01-02 05:45:11 +00001519 $$.val = $1;
1520 $$.type = $2->getPointerType();
1521 delete $2; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001522 }
1523 | ALLOCA Types OptCAlign {
Reid Spencer52402b02007-01-02 05:45:11 +00001524 *$1 += " " + $2->getNewTy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001525 if (!$3->empty())
1526 *$1 += " " + *$3;
Reid Spencer52402b02007-01-02 05:45:11 +00001527 $$.val = $1;
1528 $$.type = $2->getPointerType();
1529 delete $2; delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001530 }
1531 | ALLOCA Types ',' UINT ValueRef OptCAlign {
Reid Spencer52402b02007-01-02 05:45:11 +00001532 std::string Name = getUniqueName($5.val, $4);
1533 *$1 += " " + $2->getNewTy() + ", " + $4->getNewTy() + " " + Name;
Reid Spencere7c3c602006-11-30 06:36:44 +00001534 if (!$6->empty())
1535 *$1 += " " + *$6;
Reid Spencer52402b02007-01-02 05:45:11 +00001536 $$.val = $1;
1537 $$.type = $2->getPointerType();
1538 delete $2; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001539 }
1540 | FREE ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001541 *$1 += " " + *$2.val;
Reid Spencer52402b02007-01-02 05:45:11 +00001542 $$.val = $1;
1543 $$.type = new TypeInfo("void", VoidTy);
Reid Spencere77e35e2006-12-01 20:26:20 +00001544 $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001545 }
1546 | OptVolatile LOAD Types ValueRef {
Reid Spencer52402b02007-01-02 05:45:11 +00001547 std::string Name = getUniqueName($4.val, $3);
Reid Spencere7c3c602006-11-30 06:36:44 +00001548 if (!$1->empty())
1549 *$1 += " ";
Reid Spencer52402b02007-01-02 05:45:11 +00001550 *$1 += *$2 + " " + $3->getNewTy() + " " + Name;
1551 $$.val = $1;
1552 $$.type = $3->getElementType()->clone();
1553 delete $2; delete $3; $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001554 }
1555 | OptVolatile STORE ResolvedVal ',' Types ValueRef {
Reid Spencer52402b02007-01-02 05:45:11 +00001556 std::string Name = getUniqueName($6.val, $5);
Reid Spencere7c3c602006-11-30 06:36:44 +00001557 if (!$1->empty())
1558 *$1 += " ";
Reid Spencer52402b02007-01-02 05:45:11 +00001559 *$1 += *$2 + " " + *$3.val + ", " + $5->getNewTy() + " " + Name;
1560 $$.val = $1;
1561 $$.type = new TypeInfo("void", VoidTy);
1562 delete $2; $3.destroy(); delete $5; $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001563 }
1564 | GETELEMENTPTR Types ValueRef IndexList {
Reid Spencer52402b02007-01-02 05:45:11 +00001565 std::string Name = getUniqueName($3.val, $2);
Reid Spencerf459d392006-12-02 16:19:52 +00001566 // Upgrade the indices
1567 for (unsigned i = 0; i < $4->size(); ++i) {
1568 ValueInfo& VI = (*$4)[i];
Reid Spencer52402b02007-01-02 05:45:11 +00001569 if (VI.type->isUnsigned() && !VI.isConstant() &&
1570 VI.type->getBitWidth() < 64) {
Reid Spencerf459d392006-12-02 16:19:52 +00001571 std::string* old = VI.val;
1572 *O << " %gep_upgrade" << unique << " = zext " << *old
Reid Spencer71d2ec92006-12-31 06:02:26 +00001573 << " to i64\n";
1574 VI.val = new std::string("i64 %gep_upgrade" + llvm::utostr(unique++));
Reid Spencer52402b02007-01-02 05:45:11 +00001575 VI.type->setOldTy(ULongTy);
Reid Spencerf459d392006-12-02 16:19:52 +00001576 }
1577 }
Reid Spencer52402b02007-01-02 05:45:11 +00001578 *$1 += " " + $2->getNewTy() + " " + Name;
Reid Spencerf8483652006-12-02 15:16:01 +00001579 for (unsigned i = 0; i < $4->size(); ++i) {
1580 ValueInfo& VI = (*$4)[i];
1581 *$1 += ", " + *VI.val;
Reid Spencerf8483652006-12-02 15:16:01 +00001582 }
Reid Spencer52402b02007-01-02 05:45:11 +00001583 $$.val = $1;
1584 $$.type = getGEPIndexedType($2,$4);
1585 $3.destroy(); delete $4;
Reid Spencere7c3c602006-11-30 06:36:44 +00001586 };
1587
1588%%
1589
1590int yyerror(const char *ErrorMsg) {
1591 std::string where
1592 = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
1593 + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
1594 std::string errMsg = std::string(ErrorMsg) + "\n" + where + " while reading ";
1595 if (yychar == YYEMPTY || yychar == 0)
1596 errMsg += "end-of-file.";
1597 else
1598 errMsg += "token: '" + std::string(Upgradetext, Upgradeleng) + "'";
Reid Spencer71d2ec92006-12-31 06:02:26 +00001599 std::cerr << "llvm-upgrade: " << errMsg << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +00001600 exit(1);
1601}