blob: de8df5246a0fc2e5e7585049670ca3dc5724ee2d [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"
16#include <llvm/ADT/StringExtras.h>
Reid Spencere7c3c602006-11-30 06:36:44 +000017#include <algorithm>
Reid Spencera50d5962006-12-02 04:11:07 +000018#include <map>
Reid Spencere7c3c602006-11-30 06:36:44 +000019#include <utility>
20#include <iostream>
Reid Spencerbec0b592006-12-03 03:16:48 +000021#include <cassert>
Reid Spencere7c3c602006-11-30 06:36:44 +000022
Reid Spencere77e35e2006-12-01 20:26:20 +000023#define YYERROR_VERBOSE 1
Reid Spencer96839be2006-11-30 16:50:26 +000024#define YYINCLUDED_STDLIB_H
Reid Spencere77e35e2006-12-01 20:26:20 +000025#define YYDEBUG 1
Reid Spencere7c3c602006-11-30 06:36:44 +000026
27int yylex(); // declaration" of xxx warnings.
28int yyparse();
Reid Spencere77e35e2006-12-01 20:26:20 +000029extern int yydebug;
Reid Spencere7c3c602006-11-30 06:36:44 +000030
31static std::string CurFilename;
Reid Spencere7c3c602006-11-30 06:36:44 +000032static std::ostream *O = 0;
Reid Spencer96839be2006-11-30 16:50:26 +000033std::istream* LexInput = 0;
Reid Spencere77e35e2006-12-01 20:26:20 +000034unsigned SizeOfPointer = 32;
Reid Spencerf459d392006-12-02 16:19:52 +000035static uint64_t unique = 1;
Reid Spencer96839be2006-11-30 16:50:26 +000036
Reid Spencer71d2ec92006-12-31 06:02:26 +000037// This bool controls whether attributes are ever added to function declarations
38// definitions and calls.
39static bool AddAttributes = false;
40
Reid Spencera50d5962006-12-02 04:11:07 +000041typedef std::vector<TypeInfo> TypeVector;
42static TypeVector EnumeratedTypes;
43typedef std::map<std::string,TypeInfo> TypeMap;
44static TypeMap NamedTypes;
Reid Spencerf12ee422006-12-05 19:21:25 +000045static TypeMap Globals;
Reid Spencera50d5962006-12-02 04:11:07 +000046
Reid Spencerf8483652006-12-02 15:16:01 +000047void destroy(ValueList* VL) {
48 while (!VL->empty()) {
49 ValueInfo& VI = VL->back();
50 VI.destroy();
51 VL->pop_back();
52 }
53 delete VL;
54}
55
Reid Spencer96839be2006-11-30 16:50:26 +000056void UpgradeAssembly(const std::string &infile, std::istream& in,
Reid Spencer71d2ec92006-12-31 06:02:26 +000057 std::ostream &out, bool debug, bool addAttrs)
Reid Spencere7c3c602006-11-30 06:36:44 +000058{
59 Upgradelineno = 1;
60 CurFilename = infile;
Reid Spencer96839be2006-11-30 16:50:26 +000061 LexInput = &in;
Reid Spencere77e35e2006-12-01 20:26:20 +000062 yydebug = debug;
Reid Spencer71d2ec92006-12-31 06:02:26 +000063 AddAttributes = addAttrs;
Reid Spencere7c3c602006-11-30 06:36:44 +000064 O = &out;
65
66 if (yyparse()) {
67 std::cerr << "Parse failed.\n";
68 exit(1);
69 }
70}
71
Reid Spencera50d5962006-12-02 04:11:07 +000072static void ResolveType(TypeInfo& Ty) {
73 if (Ty.oldTy == UnresolvedTy) {
74 TypeMap::iterator I = NamedTypes.find(*Ty.newTy);
Reid Spencer78720742006-12-02 20:21:22 +000075 if (I != NamedTypes.end()) {
Reid Spencera50d5962006-12-02 04:11:07 +000076 Ty.oldTy = I->second.oldTy;
Reid Spencer78720742006-12-02 20:21:22 +000077 Ty.elemTy = I->second.elemTy;
78 } else {
Reid Spencera50d5962006-12-02 04:11:07 +000079 std::string msg("Can't resolve type: ");
80 msg += *Ty.newTy;
81 yyerror(msg.c_str());
Reid Spencer280d8012006-12-01 23:40:53 +000082 }
Reid Spencera50d5962006-12-02 04:11:07 +000083 } else if (Ty.oldTy == NumericTy) {
84 unsigned ref = atoi(&((Ty.newTy->c_str())[1])); // Skip the '\\'
85 if (ref < EnumeratedTypes.size()) {
86 Ty.oldTy = EnumeratedTypes[ref].oldTy;
Reid Spencer78720742006-12-02 20:21:22 +000087 Ty.elemTy = EnumeratedTypes[ref].elemTy;
Reid Spencera50d5962006-12-02 04:11:07 +000088 } else {
89 std::string msg("Can't resolve type: ");
90 msg += *Ty.newTy;
91 yyerror(msg.c_str());
92 }
Reid Spencer280d8012006-12-01 23:40:53 +000093 }
Reid Spencera50d5962006-12-02 04:11:07 +000094 // otherwise its already resolved.
Reid Spencer280d8012006-12-01 23:40:53 +000095}
96
Reid Spencera50d5962006-12-02 04:11:07 +000097static const char* getCastOpcode(
98 std::string& Source, const TypeInfo& SrcTy, const TypeInfo& DstTy)
99{
Reid Spencere77e35e2006-12-01 20:26:20 +0000100 unsigned SrcBits = SrcTy.getBitWidth();
101 unsigned DstBits = DstTy.getBitWidth();
102 const char* opcode = "bitcast";
103 // Run through the possibilities ...
104 if (DstTy.isIntegral()) { // Casting to integral
105 if (SrcTy.isIntegral()) { // Casting from integral
106 if (DstBits < SrcBits)
107 opcode = "trunc";
108 else if (DstBits > SrcBits) { // its an extension
109 if (SrcTy.isSigned())
110 opcode ="sext"; // signed -> SEXT
111 else
112 opcode = "zext"; // unsigned -> ZEXT
113 } else {
114 opcode = "bitcast"; // Same size, No-op cast
115 }
116 } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt
117 if (DstTy.isSigned())
118 opcode = "fptosi"; // FP -> sint
119 else
120 opcode = "fptoui"; // FP -> uint
121 } else if (SrcTy.isPacked()) {
122 assert(DstBits == SrcTy.getBitWidth() &&
123 "Casting packed to integer of different width");
124 opcode = "bitcast"; // same size, no-op cast
125 } else {
126 assert(SrcTy.isPointer() &&
127 "Casting from a value that is not first-class type");
128 opcode = "ptrtoint"; // ptr -> int
129 }
130 } else if (DstTy.isFloatingPoint()) { // Casting to floating pt
131 if (SrcTy.isIntegral()) { // Casting from integral
132 if (SrcTy.isSigned())
133 opcode = "sitofp"; // sint -> FP
134 else
135 opcode = "uitofp"; // uint -> FP
136 } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt
137 if (DstBits < SrcBits) {
138 opcode = "fptrunc"; // FP -> smaller FP
139 } else if (DstBits > SrcBits) {
140 opcode = "fpext"; // FP -> larger FP
141 } else {
142 opcode ="bitcast"; // same size, no-op cast
143 }
144 } else if (SrcTy.isPacked()) {
145 assert(DstBits == SrcTy.getBitWidth() &&
146 "Casting packed to floating point of different width");
147 opcode = "bitcast"; // same size, no-op cast
148 } else {
149 assert(0 && "Casting pointer or non-first class to float");
150 }
151 } else if (DstTy.isPacked()) {
152 if (SrcTy.isPacked()) {
153 assert(DstTy.getBitWidth() == SrcTy.getBitWidth() &&
154 "Casting packed to packed of different widths");
155 opcode = "bitcast"; // packed -> packed
156 } else if (DstTy.getBitWidth() == SrcBits) {
157 opcode = "bitcast"; // float/int -> packed
158 } else {
159 assert(!"Illegal cast to packed (wrong type or size)");
160 }
161 } else if (DstTy.isPointer()) {
162 if (SrcTy.isPointer()) {
163 opcode = "bitcast"; // ptr -> ptr
164 } else if (SrcTy.isIntegral()) {
165 opcode = "inttoptr"; // int -> ptr
166 } else {
Reid Spencera50d5962006-12-02 04:11:07 +0000167 assert(!"Casting invalid type to pointer");
Reid Spencere77e35e2006-12-01 20:26:20 +0000168 }
169 } else {
170 assert(!"Casting to type that is not first-class");
171 }
172 return opcode;
173}
174
Reid Spencera50d5962006-12-02 04:11:07 +0000175static std::string getCastUpgrade(
176 const std::string& Src, TypeInfo& SrcTy, TypeInfo& DstTy, bool isConst)
177{
178 std::string Result;
179 std::string Source = Src;
180 if (SrcTy.isFloatingPoint() && DstTy.isPointer()) {
181 // fp -> ptr cast is no longer supported but we must upgrade this
182 // by doing a double cast: fp -> int -> ptr
183 if (isConst)
Reid Spencer71d2ec92006-12-31 06:02:26 +0000184 Source = "i64 fptoui(" + Source + " to i64)";
Reid Spencera50d5962006-12-02 04:11:07 +0000185 else {
Reid Spencerf459d392006-12-02 16:19:52 +0000186 *O << " %cast_upgrade" << unique << " = fptoui " << Source
Reid Spencer71d2ec92006-12-31 06:02:26 +0000187 << " to i64\n";
188 Source = "i64 %cast_upgrade" + llvm::utostr(unique);
Reid Spencera50d5962006-12-02 04:11:07 +0000189 }
190 // Update the SrcTy for the getCastOpcode call below
191 SrcTy.destroy();
Reid Spencer71d2ec92006-12-31 06:02:26 +0000192 SrcTy.newTy = new std::string("i64");
Reid Spencera50d5962006-12-02 04:11:07 +0000193 SrcTy.oldTy = ULongTy;
Reid Spencer5fe27e72006-12-09 19:41:25 +0000194 } else if (DstTy.oldTy == BoolTy && SrcTy.oldTy != BoolTy) {
Reid Spencera50d5962006-12-02 04:11:07 +0000195 // cast ptr %x to bool was previously defined as setne ptr %x, null
196 // The ptrtoint semantic is to truncate, not compare so we must retain
197 // the original intent by replace the cast with a setne
198 const char* comparator = SrcTy.isPointer() ? ", null" :
199 (SrcTy.isFloatingPoint() ? ", 0.0" : ", 0");
Reid Spencere4d87aa2006-12-23 06:05:41 +0000200 const char* compareOp = SrcTy.isFloatingPoint() ? "fcmp one " : "icmp ne ";
Reid Spencer187ccf82006-12-09 16:57:22 +0000201 if (isConst) {
202 Result = "(" + Source + comparator + ")";
203 Result = compareOp + Result;
204 } else
205 Result = compareOp + Source + comparator;
Reid Spencera50d5962006-12-02 04:11:07 +0000206 return Result; // skip cast processing below
207 }
208 ResolveType(SrcTy);
209 ResolveType(DstTy);
210 std::string Opcode(getCastOpcode(Source, SrcTy, DstTy));
211 if (isConst)
212 Result += Opcode + "( " + Source + " to " + *DstTy.newTy + ")";
213 else
214 Result += Opcode + " " + Source + " to " + *DstTy.newTy;
215 return Result;
216}
217
Reid Spencer78720742006-12-02 20:21:22 +0000218const char* getDivRemOpcode(const std::string& opcode, const TypeInfo& TI) {
219 const char* op = opcode.c_str();
220 TypeInfo Ty = TI;
221 ResolveType(Ty);
222 if (Ty.isPacked())
223 Ty.oldTy = Ty.getElementType();
224 if (opcode == "div")
225 if (Ty.isFloatingPoint())
226 op = "fdiv";
227 else if (Ty.isUnsigned())
228 op = "udiv";
229 else if (Ty.isSigned())
230 op = "sdiv";
231 else
232 yyerror("Invalid type for div instruction");
233 else if (opcode == "rem")
234 if (Ty.isFloatingPoint())
235 op = "frem";
236 else if (Ty.isUnsigned())
237 op = "urem";
238 else if (Ty.isSigned())
239 op = "srem";
240 else
241 yyerror("Invalid type for rem instruction");
242 return op;
243}
Reid Spencer229e9362006-12-02 22:14:11 +0000244
245std::string
246getCompareOp(const std::string& setcc, const TypeInfo& TI) {
247 assert(setcc.length() == 5);
248 char cc1 = setcc[3];
249 char cc2 = setcc[4];
250 assert(cc1 == 'e' || cc1 == 'n' || cc1 == 'l' || cc1 == 'g');
251 assert(cc2 == 'q' || cc2 == 'e' || cc2 == 'e' || cc2 == 't');
252 std::string result("xcmp xxx");
253 result[6] = cc1;
254 result[7] = cc2;
255 if (TI.isFloatingPoint()) {
256 result[0] = 'f';
Reid Spencere4d87aa2006-12-23 06:05:41 +0000257 result[5] = 'o';
Reid Spencerf0cf1322006-12-07 04:23:03 +0000258 if (cc1 == 'n')
259 result[5] = 'u'; // NE maps to unordered
260 else
261 result[5] = 'o'; // everything else maps to ordered
Reid Spencer229e9362006-12-02 22:14:11 +0000262 } else if (TI.isIntegral() || TI.isPointer()) {
263 result[0] = 'i';
264 if ((cc1 == 'e' && cc2 == 'q') || (cc1 == 'n' && cc2 == 'e'))
265 result.erase(5,1);
266 else if (TI.isSigned())
267 result[5] = 's';
Reid Spencer3e5ab8c2006-12-06 06:25:46 +0000268 else if (TI.isUnsigned() || TI.isPointer() || TI.isBool())
Reid Spencer229e9362006-12-02 22:14:11 +0000269 result[5] = 'u';
270 else
271 yyerror("Invalid integral type for setcc");
272 }
273 return result;
274}
275
Reid Spencere7c3c602006-11-30 06:36:44 +0000276%}
277
Reid Spencerf0cf1322006-12-07 04:23:03 +0000278// %file-prefix="UpgradeParser"
Reid Spencere77e35e2006-12-01 20:26:20 +0000279
280%union {
281 std::string* String;
282 TypeInfo Type;
283 ValueInfo Value;
284 ConstInfo Const;
Reid Spencerf8483652006-12-02 15:16:01 +0000285 ValueList* ValList;
Reid Spencere77e35e2006-12-01 20:26:20 +0000286}
287
Reid Spencerf2d55322006-12-01 21:52:30 +0000288%token <Type> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
Reid Spencera50d5962006-12-02 04:11:07 +0000289%token <Type> FLOAT DOUBLE LABEL
290%token <String> OPAQUE ESINT64VAL EUINT64VAL SINTVAL UINTVAL FPVAL
Reid Spencerf2d55322006-12-01 21:52:30 +0000291%token <String> NULL_TOK UNDEF ZEROINITIALIZER TRUETOK FALSETOK
Reid Spencere77e35e2006-12-01 20:26:20 +0000292%token <String> TYPE VAR_ID LABELSTR STRINGCONSTANT
293%token <String> IMPLEMENTATION BEGINTOK ENDTOK
Reid Spencer71d2ec92006-12-31 06:02:26 +0000294%token <String> DECLARE GLOBAL CONSTANT SECTION VOLATILE
Reid Spencere77e35e2006-12-01 20:26:20 +0000295%token <String> TO DOTDOTDOT CONST INTERNAL LINKONCE WEAK
296%token <String> DLLIMPORT DLLEXPORT EXTERN_WEAK APPENDING
297%token <String> NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG
Reid Spencer78720742006-12-02 20:21:22 +0000298%token <String> ALIGN UNINITIALIZED
Reid Spencere77e35e2006-12-01 20:26:20 +0000299%token <String> DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
300%token <String> CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK
301%token <String> X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
302%token <String> DATALAYOUT
Reid Spencer78720742006-12-02 20:21:22 +0000303%token <String> RET BR SWITCH INVOKE EXCEPT UNWIND UNREACHABLE
304%token <String> ADD SUB MUL DIV UDIV SDIV FDIV REM UREM SREM FREM AND OR XOR
Reid Spencere77e35e2006-12-01 20:26:20 +0000305%token <String> SETLE SETGE SETLT SETGT SETEQ SETNE // Binary Comparators
Reid Spencer229e9362006-12-02 22:14:11 +0000306%token <String> ICMP FCMP EQ NE SLT SGT SLE SGE OEQ ONE OLT OGT OLE OGE
307%token <String> ORD UNO UEQ UNE ULT UGT ULE UGE
Reid Spencere77e35e2006-12-01 20:26:20 +0000308%token <String> MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR
Reid Spencerf7bde222006-12-01 22:26:37 +0000309%token <String> PHI_TOK SELECT SHL SHR ASHR LSHR VAARG
Reid Spencere77e35e2006-12-01 20:26:20 +0000310%token <String> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
Reid Spencerfcb5df82006-12-01 22:34:43 +0000311%token <String> CAST TRUNC ZEXT SEXT FPTRUNC FPEXT FPTOUI FPTOSI UITOFP SITOFP
312%token <String> PTRTOINT INTTOPTR BITCAST
Reid Spencere77e35e2006-12-01 20:26:20 +0000313
314%type <String> OptAssign OptLinkage OptCallingConv OptAlign OptCAlign
315%type <String> SectionString OptSection GlobalVarAttributes GlobalVarAttribute
316%type <String> ArgTypeListI ConstExpr DefinitionList
317%type <String> ConstPool TargetDefinition LibrariesDefinition LibList OptName
318%type <String> ArgVal ArgListH ArgList FunctionHeaderH BEGIN FunctionHeader END
319%type <String> Function FunctionProto BasicBlock TypeListI
320%type <String> InstructionList BBTerminatorInst JumpTable Inst PHIList
Reid Spencer78720742006-12-02 20:21:22 +0000321%type <String> OptTailCall InstVal OptVolatile Unwind
Reid Spencere77e35e2006-12-01 20:26:20 +0000322%type <String> MemoryInst SymbolicValueRef OptSideEffect GlobalType
323%type <String> FnDeclareLinkage BasicBlockList BigOrLittle AsmBlock
Reid Spencer78720742006-12-02 20:21:22 +0000324%type <String> Name ConstValueRef ConstVector External
Reid Spencer57f28f92006-12-03 07:10:26 +0000325%type <String> ShiftOps SetCondOps LogicalOps ArithmeticOps CastOps
326%type <String> IPredicates FPredicates
Reid Spencere77e35e2006-12-01 20:26:20 +0000327
Reid Spencerf8483652006-12-02 15:16:01 +0000328%type <ValList> ValueRefList ValueRefListE IndexList
Reid Spencere77e35e2006-12-01 20:26:20 +0000329
330%type <Type> IntType SIntType UIntType FPType TypesV Types
331%type <Type> PrimType UpRTypesV UpRTypes
332
Reid Spencerf2d55322006-12-01 21:52:30 +0000333%type <String> IntVal EInt64Val
334%type <Const> ConstVal
Reid Spencere77e35e2006-12-01 20:26:20 +0000335
Reid Spencerf459d392006-12-02 16:19:52 +0000336%type <Value> ValueRef ResolvedVal
Reid Spencere7c3c602006-11-30 06:36:44 +0000337
338%start Module
339
340%%
341
342// Handle constant integer size restriction and conversion...
Reid Spencerf2d55322006-12-01 21:52:30 +0000343IntVal : SINTVAL | UINTVAL ;
Reid Spencere77e35e2006-12-01 20:26:20 +0000344EInt64Val : ESINT64VAL | EUINT64VAL;
Reid Spencere7c3c602006-11-30 06:36:44 +0000345
346// Operations that are notably excluded from this list include:
347// RET, BR, & SWITCH because they end basic blocks and are treated specially.
Reid Spencer78720742006-12-02 20:21:22 +0000348ArithmeticOps: ADD | SUB | MUL | DIV | UDIV | SDIV | FDIV
349 | REM | UREM | SREM | FREM;
Reid Spencere7c3c602006-11-30 06:36:44 +0000350LogicalOps : AND | OR | XOR;
351SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE;
Reid Spencer57f28f92006-12-03 07:10:26 +0000352IPredicates : EQ | NE | SLT | SGT | SLE | SGE | ULT | UGT | ULE | UGE;
353FPredicates : OEQ | ONE | OLT | OGT | OLE | OGE | ORD | UNO | UEQ | UNE
354 | ULT | UGT | ULE | UGE | TRUETOK | FALSETOK;
Reid Spencerf7bde222006-12-01 22:26:37 +0000355ShiftOps : SHL | SHR | ASHR | LSHR;
Reid Spencerfcb5df82006-12-01 22:34:43 +0000356CastOps : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | FPTOUI | FPTOSI |
357 UITOFP | SITOFP | PTRTOINT | INTTOPTR | BITCAST | CAST
358 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000359
360// These are some types that allow classification if we only want a particular
361// thing... for example, only a signed, unsigned, or integral type.
362SIntType : LONG | INT | SHORT | SBYTE;
363UIntType : ULONG | UINT | USHORT | UBYTE;
364IntType : SIntType | UIntType;
365FPType : FLOAT | DOUBLE;
366
367// OptAssign - Value producing statements have an optional assignment component
368OptAssign : Name '=' {
Reid Spencere7c3c602006-11-30 06:36:44 +0000369 $$ = $1;
370 }
371 | /*empty*/ {
372 $$ = new std::string("");
373 };
374
375OptLinkage
376 : INTERNAL | LINKONCE | WEAK | APPENDING | DLLIMPORT | DLLEXPORT
377 | EXTERN_WEAK
378 | /*empty*/ { $$ = new std::string(""); } ;
379
380OptCallingConv
381 : CCC_TOK | CSRETCC_TOK | FASTCC_TOK | COLDCC_TOK | X86_STDCALLCC_TOK
Reid Spencer16244f42006-12-01 21:10:07 +0000382 | X86_FASTCALLCC_TOK
383 | CC_TOK EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000384 *$1 += *$2;
385 delete $2;
Reid Spencer16244f42006-12-01 21:10:07 +0000386 $$ = $1;
387 }
Reid Spencere7c3c602006-11-30 06:36:44 +0000388 | /*empty*/ { $$ = new std::string(""); } ;
389
390// OptAlign/OptCAlign - An optional alignment, and an optional alignment with
391// a comma before it.
392OptAlign
393 : /*empty*/ { $$ = new std::string(); }
Reid Spencerf2d55322006-12-01 21:52:30 +0000394 | ALIGN EUINT64VAL { *$1 += " " + *$2; delete $2; $$ = $1; };
Reid Spencerf0cf1322006-12-07 04:23:03 +0000395
Reid Spencere7c3c602006-11-30 06:36:44 +0000396OptCAlign
397 : /*empty*/ { $$ = new std::string(); }
398 | ',' ALIGN EUINT64VAL {
399 $2->insert(0, ", ");
Reid Spencerf2d55322006-12-01 21:52:30 +0000400 *$2 += " " + *$3;
401 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000402 $$ = $2;
403 };
404
405SectionString
406 : SECTION STRINGCONSTANT {
407 *$1 += " " + *$2;
408 delete $2;
409 $$ = $1;
410 };
411
412OptSection : /*empty*/ { $$ = new std::string(); }
413 | SectionString;
414
415GlobalVarAttributes
416 : /* empty */ { $$ = new std::string(); }
417 | ',' GlobalVarAttribute GlobalVarAttributes {
418 $2->insert(0, ", ");
419 if (!$3->empty())
420 *$2 += " " + *$3;
421 delete $3;
422 $$ = $2;
423 };
424
425GlobalVarAttribute
426 : SectionString
427 | ALIGN EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000428 *$1 += " " + *$2;
429 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000430 $$ = $1;
431 };
432
433//===----------------------------------------------------------------------===//
434// Types includes all predefined types... except void, because it can only be
435// used in specific contexts (function returning void for example). To have
436// access to it, a user must explicitly use TypesV.
437//
438
439// TypesV includes all of 'Types', but it also includes the void type.
440TypesV : Types | VOID ;
441UpRTypesV : UpRTypes | VOID ;
442Types : UpRTypes ;
443
444// Derived types are added later...
445//
446PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ;
Reid Spencere77e35e2006-12-01 20:26:20 +0000447PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL;
Reid Spencera50d5962006-12-02 04:11:07 +0000448UpRTypes
449 : OPAQUE {
450 $$.newTy = $1;
451 $$.oldTy = OpaqueTy;
452 }
453 | SymbolicValueRef {
454 $$.newTy = $1;
455 $$.oldTy = UnresolvedTy;
456 }
Reid Spencer78720742006-12-02 20:21:22 +0000457 | PrimType {
458 $$ = $1;
459 }
460 | '\\' EUINT64VAL { // Type UpReference
Reid Spencerf2d55322006-12-01 21:52:30 +0000461 $2->insert(0, "\\");
462 $$.newTy = $2;
Reid Spencera50d5962006-12-02 04:11:07 +0000463 $$.oldTy = NumericTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000464 }
465 | UpRTypesV '(' ArgTypeListI ')' { // Function derived type?
Reid Spencere77e35e2006-12-01 20:26:20 +0000466 *$1.newTy += "( " + *$3 + " )";
Reid Spencere7c3c602006-11-30 06:36:44 +0000467 delete $3;
Reid Spencere77e35e2006-12-01 20:26:20 +0000468 $$.newTy = $1.newTy;
469 $$.oldTy = FunctionTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000470 }
471 | '[' EUINT64VAL 'x' UpRTypes ']' { // Sized array type?
Reid Spencerf2d55322006-12-01 21:52:30 +0000472 $2->insert(0,"[ ");
473 *$2 += " x " + *$4.newTy + " ]";
Reid Spencere77e35e2006-12-01 20:26:20 +0000474 delete $4.newTy;
Reid Spencerf2d55322006-12-01 21:52:30 +0000475 $$.newTy = $2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000476 $$.oldTy = ArrayTy;
Reid Spencer78720742006-12-02 20:21:22 +0000477 $$.elemTy = $4.oldTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000478 }
479 | '<' EUINT64VAL 'x' UpRTypes '>' { // Packed array type?
Reid Spencerf2d55322006-12-01 21:52:30 +0000480 $2->insert(0,"< ");
481 *$2 += " x " + *$4.newTy + " >";
Reid Spencere77e35e2006-12-01 20:26:20 +0000482 delete $4.newTy;
Reid Spencerf2d55322006-12-01 21:52:30 +0000483 $$.newTy = $2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000484 $$.oldTy = PackedTy;
Reid Spencer78720742006-12-02 20:21:22 +0000485 $$.elemTy = $4.oldTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000486 }
487 | '{' TypeListI '}' { // Structure type?
488 $2->insert(0, "{ ");
489 *$2 += " }";
Reid Spencere77e35e2006-12-01 20:26:20 +0000490 $$.newTy = $2;
491 $$.oldTy = StructTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000492 }
493 | '{' '}' { // Empty structure type?
Reid Spencer0b7e5072006-12-01 22:42:01 +0000494 $$.newTy = new std::string("{}");
Reid Spencere77e35e2006-12-01 20:26:20 +0000495 $$.oldTy = StructTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000496 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000497 | '<' '{' TypeListI '}' '>' { // Packed Structure type?
498 $3->insert(0, "<{ ");
499 *$3 += " }>";
500 $$.newTy = $3;
501 $$.oldTy = StructTy;
502 }
503 | '<' '{' '}' '>' { // Empty packed structure type?
504 $$.newTy = new std::string("<{}>");
505 $$.oldTy = StructTy;
506 }
Reid Spencere7c3c602006-11-30 06:36:44 +0000507 | UpRTypes '*' { // Pointer type?
Reid Spencere77e35e2006-12-01 20:26:20 +0000508 *$1.newTy += '*';
Reid Spencer78720742006-12-02 20:21:22 +0000509 $$.elemTy = $1.oldTy;
Reid Spencere77e35e2006-12-01 20:26:20 +0000510 $1.oldTy = PointerTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000511 $$ = $1;
512 };
513
514// TypeList - Used for struct declarations and as a basis for function type
515// declaration type lists
516//
Reid Spencere77e35e2006-12-01 20:26:20 +0000517TypeListI
518 : UpRTypes {
519 $$ = $1.newTy;
520 }
521 | TypeListI ',' UpRTypes {
522 *$1 += ", " + *$3.newTy;
523 delete $3.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000524 $$ = $1;
525 };
526
527// ArgTypeList - List of types for a function type declaration...
Reid Spencere77e35e2006-12-01 20:26:20 +0000528ArgTypeListI
529 : TypeListI
Reid Spencere7c3c602006-11-30 06:36:44 +0000530 | TypeListI ',' DOTDOTDOT {
531 *$1 += ", ...";
532 delete $3;
533 $$ = $1;
534 }
535 | DOTDOTDOT {
536 $$ = $1;
537 }
538 | /*empty*/ {
539 $$ = new std::string();
540 };
541
542// ConstVal - The various declarations that go into the constant pool. This
543// production is used ONLY to represent constants that show up AFTER a 'const',
544// 'constant' or 'global' token at global scope. Constants that can be inlined
545// into other expressions (such as integers and constexprs) are handled by the
546// ResolvedVal, ValueRef and ConstValueRef productions.
547//
548ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
Reid Spencere77e35e2006-12-01 20:26:20 +0000549 $$.type = $1;
550 $$.cnst = new std::string(*$1.newTy);
551 *$$.cnst += " [ " + *$3 + " ]";
Reid Spencere7c3c602006-11-30 06:36:44 +0000552 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000553 }
554 | Types '[' ']' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000555 $$.type = $1;
556 $$.cnst = new std::string(*$1.newTy);
557 *$$.cnst += "[ ]";
Reid Spencere7c3c602006-11-30 06:36:44 +0000558 }
559 | Types 'c' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000560 $$.type = $1;
561 $$.cnst = new std::string(*$1.newTy);
562 *$$.cnst += " c" + *$3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000563 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000564 }
565 | Types '<' ConstVector '>' { // Nonempty unsized arr
Reid Spencere77e35e2006-12-01 20:26:20 +0000566 $$.type = $1;
567 $$.cnst = new std::string(*$1.newTy);
568 *$$.cnst += " < " + *$3 + " >";
Reid Spencere7c3c602006-11-30 06:36:44 +0000569 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000570 }
571 | Types '{' ConstVector '}' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000572 $$.type = $1;
573 $$.cnst = new std::string(*$1.newTy);
574 *$$.cnst += " { " + *$3 + " }";
Reid Spencere7c3c602006-11-30 06:36:44 +0000575 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000576 }
577 | Types '{' '}' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000578 $$.type = $1;
579 $$.cnst = new std::string(*$1.newTy);
Reid Spencer0b7e5072006-12-01 22:42:01 +0000580 *$$.cnst += " {}";
Reid Spencere7c3c602006-11-30 06:36:44 +0000581 }
582 | Types NULL_TOK {
Reid Spencere77e35e2006-12-01 20:26:20 +0000583 $$.type = $1;
584 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000585 *$$.cnst += " " + *$2;
586 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000587 }
588 | Types UNDEF {
Reid Spencere77e35e2006-12-01 20:26:20 +0000589 $$.type = $1;
590 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000591 *$$.cnst += " " + *$2;
592 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000593 }
594 | Types SymbolicValueRef {
Reid Spencere77e35e2006-12-01 20:26:20 +0000595 $$.type = $1;
596 $$.cnst = new std::string(*$1.newTy);
597 *$$.cnst += " " + *$2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000598 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000599 }
600 | Types ConstExpr {
Reid Spencere77e35e2006-12-01 20:26:20 +0000601 $$.type = $1;
602 $$.cnst = new std::string(*$1.newTy);
603 *$$.cnst += " " + *$2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000604 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000605 }
606 | Types ZEROINITIALIZER {
Reid Spencere77e35e2006-12-01 20:26:20 +0000607 $$.type = $1;
608 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000609 *$$.cnst += " " + *$2;
610 delete $2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000611 }
612 | SIntType EInt64Val { // integral constants
613 $$.type = $1;
614 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000615 *$$.cnst += " " + *$2;
616 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000617 }
618 | UIntType EUINT64VAL { // integral constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000619 $$.type = $1;
620 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000621 *$$.cnst += " " + *$2;
622 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000623 }
624 | BOOL TRUETOK { // Boolean constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000625 $$.type = $1;
626 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000627 *$$.cnst += " " + *$2;
628 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000629 }
630 | BOOL FALSETOK { // Boolean constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000631 $$.type = $1;
632 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000633 *$$.cnst += " " + *$2;
634 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000635 }
636 | FPType FPVAL { // Float & Double constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000637 $$.type = $1;
638 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000639 *$$.cnst += " " + *$2;
640 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000641 };
642
643
Reid Spencerfcb5df82006-12-01 22:34:43 +0000644ConstExpr: CastOps '(' ConstVal TO Types ')' {
Reid Spencer280d8012006-12-01 23:40:53 +0000645 std::string source = *$3.cnst;
Reid Spencera50d5962006-12-02 04:11:07 +0000646 TypeInfo DstTy = $5;
647 ResolveType(DstTy);
Reid Spencer280d8012006-12-01 23:40:53 +0000648 if (*$1 == "cast") {
Reid Spencera50d5962006-12-02 04:11:07 +0000649 // Call getCastUpgrade to upgrade the old cast
650 $$ = new std::string(getCastUpgrade(source, $3.type, $5, true));
651 } else {
652 // Nothing to upgrade, just create the cast constant expr
653 $$ = new std::string(*$1);
654 *$$ += "( " + source + " to " + *$5.newTy + ")";
Reid Spencer280d8012006-12-01 23:40:53 +0000655 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000656 delete $1; $3.destroy(); delete $4; $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000657 }
658 | GETELEMENTPTR '(' ConstVal IndexList ')' {
Reid Spencerf8483652006-12-02 15:16:01 +0000659 *$1 += "(" + *$3.cnst;
660 for (unsigned i = 0; i < $4->size(); ++i) {
661 ValueInfo& VI = (*$4)[i];
662 *$1 += ", " + *VI.val;
663 VI.destroy();
664 }
665 *$1 += ")";
Reid Spencere77e35e2006-12-01 20:26:20 +0000666 $$ = $1;
667 $3.destroy();
668 delete $4;
Reid Spencere7c3c602006-11-30 06:36:44 +0000669 }
670 | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000671 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
672 $3.destroy(); $5.destroy(); $7.destroy();
673 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000674 }
675 | ArithmeticOps '(' ConstVal ',' ConstVal ')' {
Reid Spencer78720742006-12-02 20:21:22 +0000676 const char* op = getDivRemOpcode(*$1, $3.type);
677 $$ = new std::string(op);
678 *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
679 delete $1; $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000680 }
681 | LogicalOps '(' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000682 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
683 $3.destroy(); $5.destroy();
684 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000685 }
686 | SetCondOps '(' ConstVal ',' ConstVal ')' {
Reid Spencer229e9362006-12-02 22:14:11 +0000687 *$1 = getCompareOp(*$1, $3.type);
Reid Spencere77e35e2006-12-01 20:26:20 +0000688 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
689 $3.destroy(); $5.destroy();
690 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000691 }
Reid Spencer57f28f92006-12-03 07:10:26 +0000692 | ICMP IPredicates '(' ConstVal ',' ConstVal ')' {
693 *$1 += "(" + *$2 + "," + *$4.cnst + "," + *$6.cnst + ")";
694 delete $2; $4.destroy(); $6.destroy();
695 $$ = $1;
696 }
697 | FCMP FPredicates '(' ConstVal ',' ConstVal ')' {
Reid Spencer229e9362006-12-02 22:14:11 +0000698 *$1 += "(" + *$2 + "," + *$4.cnst + "," + *$6.cnst + ")";
699 delete $2; $4.destroy(); $6.destroy();
700 $$ = $1;
701 }
Reid Spencere7c3c602006-11-30 06:36:44 +0000702 | ShiftOps '(' ConstVal ',' ConstVal ')' {
Reid Spencerf7bde222006-12-01 22:26:37 +0000703 const char* shiftop = $1->c_str();
704 if (*$1 == "shr")
705 shiftop = ($3.type.isUnsigned()) ? "lshr" : "ashr";
706 $$ = new std::string(shiftop);
707 *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
708 delete $1; $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000709 }
710 | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000711 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
712 $3.destroy(); $5.destroy();
713 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000714 }
715 | INSERTELEMENT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000716 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
717 $3.destroy(); $5.destroy(); $7.destroy();
718 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000719 }
720 | SHUFFLEVECTOR '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000721 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
722 $3.destroy(); $5.destroy(); $7.destroy();
723 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000724 };
725
726
727// ConstVector - A list of comma separated constants.
Reid Spencere77e35e2006-12-01 20:26:20 +0000728
729ConstVector
730 : ConstVector ',' ConstVal {
731 *$1 += ", " + *$3.cnst;
732 $3.destroy();
733 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000734 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000735 | ConstVal { $$ = new std::string(*$1.cnst); $1.destroy(); }
736 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000737
738
739// GlobalType - Match either GLOBAL or CONSTANT for global declarations...
Reid Spencere77e35e2006-12-01 20:26:20 +0000740GlobalType : GLOBAL | CONSTANT ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000741
742
743//===----------------------------------------------------------------------===//
744// Rules to match Modules
745//===----------------------------------------------------------------------===//
746
747// Module rule: Capture the result of parsing the whole file into a result
748// variable...
749//
750Module : DefinitionList {
751};
752
753// DefinitionList - Top level definitions
754//
755DefinitionList : DefinitionList Function {
756 $$ = 0;
757 }
758 | DefinitionList FunctionProto {
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000759 *O << *$2 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +0000760 delete $2;
761 $$ = 0;
762 }
763 | DefinitionList MODULE ASM_TOK AsmBlock {
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000764 *O << "module asm " << ' ' << *$4 << '\n';
Reid Spencerd154b572006-12-01 20:36:40 +0000765 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000766 }
767 | DefinitionList IMPLEMENTATION {
768 *O << "implementation\n";
Reid Spencerd154b572006-12-01 20:36:40 +0000769 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000770 }
Reid Spencera50d5962006-12-02 04:11:07 +0000771 | ConstPool { $$ = 0; }
Reid Spencere7c3c602006-11-30 06:36:44 +0000772
Reid Spencer78720742006-12-02 20:21:22 +0000773External : EXTERNAL | UNINITIALIZED { $$ = $1; *$$ = "external"; }
774
Reid Spencere7c3c602006-11-30 06:36:44 +0000775// ConstPool - Constants with optional names assigned to them.
776ConstPool : ConstPool OptAssign TYPE TypesV {
Reid Spencera50d5962006-12-02 04:11:07 +0000777 EnumeratedTypes.push_back($4);
778 if (!$2->empty()) {
779 NamedTypes[*$2].newTy = new std::string(*$4.newTy);
780 NamedTypes[*$2].oldTy = $4.oldTy;
Reid Spencer78720742006-12-02 20:21:22 +0000781 NamedTypes[*$2].elemTy = $4.elemTy;
Reid Spencera50d5962006-12-02 04:11:07 +0000782 *O << *$2 << " = ";
783 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000784 *O << "type " << *$4.newTy << '\n';
Reid Spencera50d5962006-12-02 04:11:07 +0000785 delete $2; delete $3; $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000786 $$ = 0;
787 }
788 | ConstPool FunctionProto { // Function prototypes can be in const pool
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000789 *O << *$2 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +0000790 delete $2;
791 $$ = 0;
792 }
793 | ConstPool MODULE ASM_TOK AsmBlock { // Asm blocks can be in the const pool
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000794 *O << *$2 << ' ' << *$3 << ' ' << *$4 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +0000795 delete $2; delete $3; delete $4;
796 $$ = 0;
797 }
798 | ConstPool OptAssign OptLinkage GlobalType ConstVal GlobalVarAttributes {
Reid Spencerf12ee422006-12-05 19:21:25 +0000799 if (!$2->empty()) {
Reid Spencera50d5962006-12-02 04:11:07 +0000800 *O << *$2 << " = ";
Reid Spencerf12ee422006-12-05 19:21:25 +0000801 Globals[*$2] = $5.type.clone();
802 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000803 *O << *$3 << ' ' << *$4 << ' ' << *$5.cnst << ' ' << *$6 << '\n';
Reid Spencere77e35e2006-12-01 20:26:20 +0000804 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000805 $$ = 0;
806 }
Reid Spencer78720742006-12-02 20:21:22 +0000807 | ConstPool OptAssign External GlobalType Types GlobalVarAttributes {
Reid Spencerf12ee422006-12-05 19:21:25 +0000808 if (!$2->empty()) {
Reid Spencera50d5962006-12-02 04:11:07 +0000809 *O << *$2 << " = ";
Reid Spencerf12ee422006-12-05 19:21:25 +0000810 Globals[*$2] = $5.clone();
811 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000812 *O << *$3 << ' ' << *$4 << ' ' << *$5.newTy << ' ' << *$6 << '\n';
Reid Spencere77e35e2006-12-01 20:26:20 +0000813 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000814 $$ = 0;
815 }
816 | ConstPool OptAssign DLLIMPORT GlobalType Types GlobalVarAttributes {
Reid Spencerf12ee422006-12-05 19:21:25 +0000817 if (!$2->empty()) {
Reid Spencera50d5962006-12-02 04:11:07 +0000818 *O << *$2 << " = ";
Reid Spencerf12ee422006-12-05 19:21:25 +0000819 Globals[*$2] = $5.clone();
820 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000821 *O << *$3 << ' ' << *$4 << ' ' << *$5.newTy << ' ' << *$6 << '\n';
Reid Spencere77e35e2006-12-01 20:26:20 +0000822 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000823 $$ = 0;
824 }
825 | ConstPool OptAssign EXTERN_WEAK GlobalType Types GlobalVarAttributes {
Reid Spencerf12ee422006-12-05 19:21:25 +0000826 if (!$2->empty()) {
Reid Spencera50d5962006-12-02 04:11:07 +0000827 *O << *$2 << " = ";
Reid Spencerf12ee422006-12-05 19:21:25 +0000828 Globals[*$2] = $5.clone();
829 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000830 *O << *$3 << ' ' << *$4 << ' ' << *$5.newTy << ' ' << *$6 << '\n';
Reid Spencere77e35e2006-12-01 20:26:20 +0000831 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000832 $$ = 0;
833 }
834 | ConstPool TARGET TargetDefinition {
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000835 *O << *$2 << ' ' << *$3 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +0000836 delete $2; delete $3;
837 $$ = 0;
838 }
839 | ConstPool DEPLIBS '=' LibrariesDefinition {
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000840 *O << *$2 << " = " << *$4 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +0000841 delete $2; delete $4;
842 $$ = 0;
843 }
844 | /* empty: end of list */ {
845 $$ = 0;
846 };
847
848
849AsmBlock : STRINGCONSTANT ;
850
851BigOrLittle : BIG | LITTLE
852
853TargetDefinition
854 : ENDIAN '=' BigOrLittle {
Reid Spencere77e35e2006-12-01 20:26:20 +0000855 *$1 += " = " + *$3;
856 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000857 $$ = $1;
858 }
859 | POINTERSIZE '=' EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000860 *$1 += " = " + *$3;
861 if (*$3 == "64")
Reid Spencere77e35e2006-12-01 20:26:20 +0000862 SizeOfPointer = 64;
Reid Spencerf2d55322006-12-01 21:52:30 +0000863 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000864 $$ = $1;
865 }
866 | TRIPLE '=' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000867 *$1 += " = " + *$3;
868 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000869 $$ = $1;
870 }
871 | DATALAYOUT '=' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000872 *$1 += " = " + *$3;
873 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000874 $$ = $1;
875 };
876
877LibrariesDefinition
878 : '[' LibList ']' {
879 $2->insert(0, "[ ");
880 *$2 += " ]";
881 $$ = $2;
882 };
883
884LibList
885 : LibList ',' STRINGCONSTANT {
886 *$1 += ", " + *$3;
887 delete $3;
888 $$ = $1;
889 }
890 | STRINGCONSTANT
891 | /* empty: end of list */ {
892 $$ = new std::string();
893 };
894
895//===----------------------------------------------------------------------===//
896// Rules to match Function Headers
897//===----------------------------------------------------------------------===//
898
899Name : VAR_ID | STRINGCONSTANT;
900OptName : Name | /*empty*/ { $$ = new std::string(); };
901
902ArgVal : Types OptName {
Reid Spencere77e35e2006-12-01 20:26:20 +0000903 $$ = $1.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000904 if (!$2->empty())
905 *$$ += " " + *$2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000906 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000907};
908
909ArgListH : ArgListH ',' ArgVal {
910 *$1 += ", " + *$3;
Reid Spencere77e35e2006-12-01 20:26:20 +0000911 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000912 }
913 | ArgVal {
914 $$ = $1;
915 };
916
917ArgList : ArgListH {
918 $$ = $1;
919 }
920 | ArgListH ',' DOTDOTDOT {
921 *$1 += ", ...";
922 $$ = $1;
Reid Spencere77e35e2006-12-01 20:26:20 +0000923 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000924 }
925 | DOTDOTDOT {
926 $$ = $1;
927 }
Reid Spencerd154b572006-12-01 20:36:40 +0000928 | /* empty */ { $$ = new std::string(); };
Reid Spencere7c3c602006-11-30 06:36:44 +0000929
Reid Spencer71d2ec92006-12-31 06:02:26 +0000930FunctionHeaderH
931 : OptCallingConv TypesV Name '(' ArgList ')' OptSection OptAlign {
Reid Spencere7c3c602006-11-30 06:36:44 +0000932 if (!$1->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000933 *$1 += " ";
Reid Spencere7c3c602006-11-30 06:36:44 +0000934 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000935 *$1 += *$2.newTy + " " + *$3 + "(" + *$5 + ")";
Reid Spencere7c3c602006-11-30 06:36:44 +0000936 if (!$7->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000937 *$1 += " " + *$7;
Reid Spencere7c3c602006-11-30 06:36:44 +0000938 }
939 if (!$8->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000940 *$1 += " " + *$8;
Reid Spencere7c3c602006-11-30 06:36:44 +0000941 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000942 $2.destroy();
943 delete $3;
944 delete $5;
945 delete $7;
946 delete $8;
947 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000948 };
949
Reid Spencer78720742006-12-02 20:21:22 +0000950BEGIN : BEGINTOK { $$ = new std::string("{"); delete $1; }
951 | '{' { $$ = new std::string ("{"); }
Reid Spencere7c3c602006-11-30 06:36:44 +0000952
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000953FunctionHeader
954 : OptLinkage FunctionHeaderH BEGIN {
955 *O << "define ";
956 if (!$1->empty()) {
957 *O << *$1 << ' ';
958 }
959 *O << *$2 << ' ' << *$3 << '\n';
960 delete $1; delete $2; delete $3;
961 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000962 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +0000963 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000964
Reid Spencer78720742006-12-02 20:21:22 +0000965END : ENDTOK { $$ = new std::string("}"); delete $1; }
Reid Spencere7c3c602006-11-30 06:36:44 +0000966 | '}' { $$ = new std::string("}"); };
967
968Function : FunctionHeader BasicBlockList END {
969 if ($2)
970 *O << *$2;
Reid Spencer71d2ec92006-12-31 06:02:26 +0000971 *O << *$3 << "\n\n";
Reid Spencere77e35e2006-12-01 20:26:20 +0000972 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000973};
974
Reid Spencere77e35e2006-12-01 20:26:20 +0000975FnDeclareLinkage
976 : /*default*/ { $$ = new std::string(); }
Reid Spencere7c3c602006-11-30 06:36:44 +0000977 | DLLIMPORT
978 | EXTERN_WEAK
979 ;
980
981FunctionProto
982 : DECLARE FnDeclareLinkage FunctionHeaderH {
Reid Spencere77e35e2006-12-01 20:26:20 +0000983 if (!$2->empty())
984 *$1 += " " + *$2;
985 *$1 += " " + *$3;
986 delete $2;
987 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000988 $$ = $1;
989 };
990
991//===----------------------------------------------------------------------===//
992// Rules to match Basic Blocks
993//===----------------------------------------------------------------------===//
994
Reid Spencerd154b572006-12-01 20:36:40 +0000995OptSideEffect : /* empty */ { $$ = new std::string(); }
996 | SIDEEFFECT;
Reid Spencere7c3c602006-11-30 06:36:44 +0000997
Reid Spencere77e35e2006-12-01 20:26:20 +0000998ConstValueRef
Reid Spencerf2d55322006-12-01 21:52:30 +0000999 : ESINT64VAL | EUINT64VAL | FPVAL | TRUETOK | FALSETOK | NULL_TOK | UNDEF
1000 | ZEROINITIALIZER
Reid Spencere7c3c602006-11-30 06:36:44 +00001001 | '<' ConstVector '>' {
1002 $2->insert(0, "<");
1003 *$2 += ">";
1004 $$ = $2;
1005 }
1006 | ConstExpr
1007 | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT {
1008 if (!$2->empty()) {
1009 *$1 += " " + *$2;
1010 }
Reid Spencere77e35e2006-12-01 20:26:20 +00001011 *$1 += " " + *$3 + ", " + *$5;
1012 delete $2; delete $3; delete $5;
Reid Spencere7c3c602006-11-30 06:36:44 +00001013 $$ = $1;
1014 };
1015
Reid Spencerf2d55322006-12-01 21:52:30 +00001016SymbolicValueRef : IntVal | Name ;
Reid Spencere7c3c602006-11-30 06:36:44 +00001017
1018// ValueRef - A reference to a definition... either constant or symbolic
Reid Spencerf459d392006-12-02 16:19:52 +00001019ValueRef
1020 : SymbolicValueRef {
1021 $$.val = $1;
1022 $$.constant = false;
1023 $$.type.newTy = 0;
1024 $$.type.oldTy = UnresolvedTy;
1025 }
1026 | ConstValueRef {
1027 $$.val = $1;
1028 $$.constant = true;
1029 $$.type.newTy = 0;
1030 $$.type.oldTy = UnresolvedTy;
1031 }
1032 ;
Reid Spencere7c3c602006-11-30 06:36:44 +00001033
1034// ResolvedVal - a <type> <value> pair. This is used only in cases where the
1035// type immediately preceeds the value reference, and allows complex constant
1036// pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
1037ResolvedVal : Types ValueRef {
Reid Spencerf459d392006-12-02 16:19:52 +00001038 $$ = $2;
Reid Spencere77e35e2006-12-01 20:26:20 +00001039 $$.type = $1;
Reid Spencerf459d392006-12-02 16:19:52 +00001040 $$.val->insert(0, *$1.newTy + " ");
Reid Spencere7c3c602006-11-30 06:36:44 +00001041 };
1042
1043BasicBlockList : BasicBlockList BasicBlock {
Reid Spencerf2d55322006-12-01 21:52:30 +00001044 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +00001045 }
1046 | BasicBlock { // Do not allow functions with 0 basic blocks
Reid Spencerf2d55322006-12-01 21:52:30 +00001047 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +00001048 };
1049
1050
1051// Basic blocks are terminated by branching instructions:
1052// br, br/cc, switch, ret
1053//
Reid Spencer16244f42006-12-01 21:10:07 +00001054BasicBlock : InstructionList BBTerminatorInst {
Reid Spencerf2d55322006-12-01 21:52:30 +00001055 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +00001056 };
1057
1058InstructionList : InstructionList Inst {
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001059 *O << " " << *$2 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +00001060 delete $2;
1061 $$ = 0;
1062 }
1063 | /* empty */ {
1064 $$ = 0;
1065 }
1066 | LABELSTR {
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001067 *O << *$1 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +00001068 delete $1;
1069 $$ = 0;
1070 };
1071
Reid Spencer78720742006-12-02 20:21:22 +00001072Unwind : UNWIND | EXCEPT { $$ = $1; *$$ = "unwind"; }
1073
Reid Spencere7c3c602006-11-30 06:36:44 +00001074BBTerminatorInst : RET ResolvedVal { // Return with a result...
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001075 *O << " " << *$1 << ' ' << *$2.val << '\n';
Reid Spencere77e35e2006-12-01 20:26:20 +00001076 delete $1; $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001077 $$ = 0;
1078 }
1079 | RET VOID { // Return with no result...
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001080 *O << " " << *$1 << ' ' << *$2.newTy << '\n';
Reid Spencere77e35e2006-12-01 20:26:20 +00001081 delete $1; $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001082 $$ = 0;
1083 }
1084 | BR LABEL ValueRef { // Unconditional Branch...
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001085 *O << " " << *$1 << ' ' << *$2.newTy << ' ' << *$3.val << '\n';
Reid Spencerf459d392006-12-02 16:19:52 +00001086 delete $1; $2.destroy(); $3.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001087 $$ = 0;
1088 } // Conditional Branch...
1089 | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001090 *O << " " << *$1 << ' ' << *$2.newTy << ' ' << *$3.val << ", "
1091 << *$5.newTy << ' ' << *$6.val << ", " << *$8.newTy << ' '
1092 << *$9.val << '\n';
Reid Spencerf459d392006-12-02 16:19:52 +00001093 delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy();
1094 $8.destroy(); $9.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001095 $$ = 0;
1096 }
1097 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001098 *O << " " << *$1 << ' ' << *$2.newTy << ' ' << *$3.val << ", "
1099 << *$5.newTy << ' ' << *$6.val << " [" << *$8 << " ]\n";
Reid Spencerf459d392006-12-02 16:19:52 +00001100 delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy();
1101 delete $8;
Reid Spencere7c3c602006-11-30 06:36:44 +00001102 $$ = 0;
1103 }
1104 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' {
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001105 *O << " " << *$1 << ' ' << *$2.newTy << ' ' << *$3.val << ", "
1106 << *$5.newTy << ' ' << *$6.val << "[]\n";
Reid Spencerf459d392006-12-02 16:19:52 +00001107 delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001108 $$ = 0;
1109 }
Reid Spencer16244f42006-12-01 21:10:07 +00001110 | OptAssign INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')'
Reid Spencer78720742006-12-02 20:21:22 +00001111 TO LABEL ValueRef Unwind LABEL ValueRef {
Reid Spencer16244f42006-12-01 21:10:07 +00001112 *O << " ";
1113 if (!$1->empty())
Reid Spencera50d5962006-12-02 04:11:07 +00001114 *O << *$1 << " = ";
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001115 *O << *$2 << ' ' << *$3 << ' ' << *$4.newTy << ' ' << *$5.val << " (";
Reid Spencerf8483652006-12-02 15:16:01 +00001116 for (unsigned i = 0; i < $7->size(); ++i) {
1117 ValueInfo& VI = (*$7)[i];
1118 *O << *VI.val;
1119 if (i+1 < $7->size())
1120 *O << ", ";
1121 VI.destroy();
1122 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001123 *O << ") " << *$9 << ' ' << *$10.newTy << ' ' << *$11.val << ' '
1124 << *$12 << ' ' << *$13.newTy << ' ' << *$14.val << '\n';
Reid Spencerf459d392006-12-02 16:19:52 +00001125 delete $1; delete $2; delete $3; $4.destroy(); $5.destroy(); delete $7;
1126 delete $9; $10.destroy(); $11.destroy(); delete $12; $13.destroy();
1127 $14.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001128 $$ = 0;
1129 }
Reid Spencer78720742006-12-02 20:21:22 +00001130 | Unwind {
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001131 *O << " " << *$1 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +00001132 delete $1;
1133 $$ = 0;
1134 }
1135 | UNREACHABLE {
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001136 *O << " " << *$1 << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +00001137 delete $1;
1138 $$ = 0;
1139 };
1140
1141JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
Reid Spencerf459d392006-12-02 16:19:52 +00001142 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5.newTy + " " + *$6.val;
1143 $2.destroy(); delete $3; $5.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001144 $$ = $1;
1145 }
1146 | IntType ConstValueRef ',' LABEL ValueRef {
Reid Spencere77e35e2006-12-01 20:26:20 +00001147 $2->insert(0, *$1.newTy + " " );
Reid Spencerf459d392006-12-02 16:19:52 +00001148 *$2 += ", " + *$4.newTy + " " + *$5.val;
1149 $1.destroy(); $4.destroy(); $5.destroy();
Reid Spencere77e35e2006-12-01 20:26:20 +00001150 $$ = $2;
Reid Spencere7c3c602006-11-30 06:36:44 +00001151 };
1152
1153Inst
1154 : OptAssign InstVal {
Reid Spencera50d5962006-12-02 04:11:07 +00001155 if (!$1->empty())
1156 *$1 += " = ";
Reid Spencere7c3c602006-11-30 06:36:44 +00001157 *$1 += *$2;
1158 delete $2;
1159 $$ = $1;
1160 };
1161
1162PHIList
1163 : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes
Reid Spencerf459d392006-12-02 16:19:52 +00001164 $3.val->insert(0, *$1.newTy + "[");
1165 *$3.val += "," + *$5.val + "]";
1166 $1.destroy(); $5.destroy();
1167 $$ = new std::string(*$3.val);
1168 $3.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001169 }
1170 | PHIList ',' '[' ValueRef ',' ValueRef ']' {
Reid Spencerf459d392006-12-02 16:19:52 +00001171 *$1 += ", [" + *$4.val + "," + *$6.val + "]";
1172 $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001173 $$ = $1;
1174 };
1175
1176
1177ValueRefList
Reid Spencerf8483652006-12-02 15:16:01 +00001178 : ResolvedVal {
1179 $$ = new ValueList();
1180 $$->push_back($1);
1181 }
Reid Spencere7c3c602006-11-30 06:36:44 +00001182 | ValueRefList ',' ResolvedVal {
Reid Spencerf8483652006-12-02 15:16:01 +00001183 $1->push_back($3);
Reid Spencere7c3c602006-11-30 06:36:44 +00001184 $$ = $1;
1185 };
1186
1187// ValueRefListE - Just like ValueRefList, except that it may also be empty!
1188ValueRefListE
Reid Spencerf8483652006-12-02 15:16:01 +00001189 : ValueRefList { $$ = $1; }
1190 | /*empty*/ { $$ = new ValueList(); }
Reid Spencere7c3c602006-11-30 06:36:44 +00001191 ;
1192
1193OptTailCall
1194 : TAIL CALL {
1195 *$1 += " " + *$2;
1196 delete $2;
1197 $$ = $1;
1198 }
1199 | CALL
1200 ;
1201
1202InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
Reid Spencer78720742006-12-02 20:21:22 +00001203 const char* op = getDivRemOpcode(*$1, $2);
1204 $$ = new std::string(op);
1205 *$$ += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
1206 delete $1; $2.destroy(); $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001207 }
1208 | LogicalOps Types ValueRef ',' ValueRef {
Reid Spencerf459d392006-12-02 16:19:52 +00001209 *$1 += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
1210 $2.destroy(); $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001211 $$ = $1;
1212 }
1213 | SetCondOps Types ValueRef ',' ValueRef {
Reid Spencer229e9362006-12-02 22:14:11 +00001214 *$1 = getCompareOp(*$1, $2);
Reid Spencerf459d392006-12-02 16:19:52 +00001215 *$1 += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
1216 $2.destroy(); $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001217 $$ = $1;
1218 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001219 | ICMP IPredicates Types ValueRef ',' ValueRef {
1220 *$1 += " " + *$2 + " " + *$3.newTy + " " + *$4.val + "," + *$6.val;
Reid Spencer57f28f92006-12-03 07:10:26 +00001221 delete $2; $4.destroy(); $6.destroy();
1222 $$ = $1;
1223 }
Reid Spencer6fd36ab2006-12-29 20:35:03 +00001224 | FCMP FPredicates Types ValueRef ',' ValueRef {
1225 *$1 += " " + *$2 + " " + *$3.newTy + " " + *$4.val + "," + *$6.val;
Reid Spencer229e9362006-12-02 22:14:11 +00001226 delete $2; $4.destroy(); $6.destroy();
1227 $$ = $1;
1228 }
Reid Spencere7c3c602006-11-30 06:36:44 +00001229 | NOT ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001230 *$1 += " " + *$2.val;
1231 $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001232 $$ = $1;
1233 }
1234 | ShiftOps ResolvedVal ',' ResolvedVal {
Reid Spencerf7bde222006-12-01 22:26:37 +00001235 const char* shiftop = $1->c_str();
1236 if (*$1 == "shr")
1237 shiftop = ($2.type.isUnsigned()) ? "lshr" : "ashr";
1238 $$ = new std::string(shiftop);
1239 *$$ += " " + *$2.val + ", " + *$4.val;
1240 delete $1; $2.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001241 }
Reid Spencerfcb5df82006-12-01 22:34:43 +00001242 | CastOps ResolvedVal TO Types {
Reid Spencer280d8012006-12-01 23:40:53 +00001243 std::string source = *$2.val;
Reid Spencera50d5962006-12-02 04:11:07 +00001244 TypeInfo SrcTy = $2.type;
1245 TypeInfo DstTy = $4;
1246 ResolveType(DstTy);
1247 $$ = new std::string();
Reid Spencer280d8012006-12-01 23:40:53 +00001248 if (*$1 == "cast") {
Reid Spencera50d5962006-12-02 04:11:07 +00001249 *$$ += getCastUpgrade(source, SrcTy, DstTy, false);
1250 } else {
1251 *$$ += *$1 + " " + source + " to " + *DstTy.newTy;
Reid Spencer280d8012006-12-01 23:40:53 +00001252 }
Reid Spencere77e35e2006-12-01 20:26:20 +00001253 delete $1; $2.destroy();
1254 delete $3; $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001255 }
1256 | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001257 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1258 $2.destroy(); $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001259 $$ = $1;
1260 }
1261 | VAARG ResolvedVal ',' Types {
Reid Spencere77e35e2006-12-01 20:26:20 +00001262 *$1 += " " + *$2.val + ", " + *$4.newTy;
1263 $2.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001264 $$ = $1;
1265 }
1266 | EXTRACTELEMENT ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001267 *$1 += " " + *$2.val + ", " + *$4.val;
1268 $2.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001269 $$ = $1;
1270 }
1271 | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001272 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1273 $2.destroy(); $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001274 $$ = $1;
1275 }
1276 | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001277 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1278 $2.destroy(); $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001279 $$ = $1;
1280 }
1281 | PHI_TOK PHIList {
1282 *$1 += " " + *$2;
1283 delete $2;
1284 $$ = $1;
1285 }
1286 | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' {
1287 if (!$2->empty())
1288 *$1 += " " + *$2;
1289 if (!$1->empty())
1290 *$1 += " ";
Reid Spencerf459d392006-12-02 16:19:52 +00001291 *$1 += *$3.newTy + " " + *$4.val + "(";
Reid Spencerf8483652006-12-02 15:16:01 +00001292 for (unsigned i = 0; i < $6->size(); ++i) {
1293 ValueInfo& VI = (*$6)[i];
1294 *$1 += *VI.val;
1295 if (i+1 < $6->size())
1296 *$1 += ", ";
1297 VI.destroy();
1298 }
1299 *$1 += ")";
Reid Spencerf459d392006-12-02 16:19:52 +00001300 delete $2; $3.destroy(); $4.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001301 $$ = $1;
1302 }
1303 | MemoryInst ;
1304
1305
1306// IndexList - List of indices for GEP based instructions...
1307IndexList
Reid Spencerf8483652006-12-02 15:16:01 +00001308 : ',' ValueRefList { $$ = $2; }
1309 | /* empty */ { $$ = new ValueList(); }
Reid Spencere7c3c602006-11-30 06:36:44 +00001310 ;
1311
1312OptVolatile
1313 : VOLATILE
1314 | /* empty */ { $$ = new std::string(); }
1315 ;
1316
1317MemoryInst : MALLOC Types OptCAlign {
Reid Spencere77e35e2006-12-01 20:26:20 +00001318 *$1 += " " + *$2.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +00001319 if (!$3->empty())
1320 *$1 += " " + *$3;
Reid Spencere77e35e2006-12-01 20:26:20 +00001321 $2.destroy(); delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001322 $$ = $1;
1323 }
1324 | MALLOC Types ',' UINT ValueRef OptCAlign {
Reid Spencerf459d392006-12-02 16:19:52 +00001325 *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5.val;
Reid Spencere7c3c602006-11-30 06:36:44 +00001326 if (!$6->empty())
1327 *$1 += " " + *$6;
Reid Spencerf459d392006-12-02 16:19:52 +00001328 $2.destroy(); $4.destroy(); $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001329 $$ = $1;
1330 }
1331 | ALLOCA Types OptCAlign {
Reid Spencere77e35e2006-12-01 20:26:20 +00001332 *$1 += " " + *$2.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +00001333 if (!$3->empty())
1334 *$1 += " " + *$3;
Reid Spencere77e35e2006-12-01 20:26:20 +00001335 $2.destroy(); delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001336 $$ = $1;
1337 }
1338 | ALLOCA Types ',' UINT ValueRef OptCAlign {
Reid Spencerf459d392006-12-02 16:19:52 +00001339 *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5.val;
Reid Spencere7c3c602006-11-30 06:36:44 +00001340 if (!$6->empty())
1341 *$1 += " " + *$6;
Reid Spencerf459d392006-12-02 16:19:52 +00001342 $2.destroy(); $4.destroy(); $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001343 $$ = $1;
1344 }
1345 | FREE ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001346 *$1 += " " + *$2.val;
1347 $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001348 $$ = $1;
1349 }
1350 | OptVolatile LOAD Types ValueRef {
1351 if (!$1->empty())
1352 *$1 += " ";
Reid Spencerf459d392006-12-02 16:19:52 +00001353 *$1 += *$2 + " " + *$3.newTy + " " + *$4.val;
1354 delete $2; $3.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001355 $$ = $1;
1356 }
1357 | OptVolatile STORE ResolvedVal ',' Types ValueRef {
1358 if (!$1->empty())
1359 *$1 += " ";
Reid Spencerf459d392006-12-02 16:19:52 +00001360 *$1 += *$2 + " " + *$3.val + ", " + *$5.newTy + " " + *$6.val;
1361 delete $2; $3.destroy(); $5.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001362 $$ = $1;
1363 }
1364 | GETELEMENTPTR Types ValueRef IndexList {
Reid Spencerf459d392006-12-02 16:19:52 +00001365 // Upgrade the indices
1366 for (unsigned i = 0; i < $4->size(); ++i) {
1367 ValueInfo& VI = (*$4)[i];
1368 if (VI.type.isUnsigned() && !VI.isConstant() &&
1369 VI.type.getBitWidth() < 64) {
1370 std::string* old = VI.val;
1371 *O << " %gep_upgrade" << unique << " = zext " << *old
Reid Spencer71d2ec92006-12-31 06:02:26 +00001372 << " to i64\n";
1373 VI.val = new std::string("i64 %gep_upgrade" + llvm::utostr(unique++));
Reid Spencerf459d392006-12-02 16:19:52 +00001374 VI.type.oldTy = ULongTy;
1375 delete old;
1376 }
1377 }
1378 *$1 += " " + *$2.newTy + " " + *$3.val;
Reid Spencerf8483652006-12-02 15:16:01 +00001379 for (unsigned i = 0; i < $4->size(); ++i) {
1380 ValueInfo& VI = (*$4)[i];
1381 *$1 += ", " + *VI.val;
1382 VI.destroy();
1383 }
Reid Spencerf459d392006-12-02 16:19:52 +00001384 $2.destroy(); $3.destroy(); delete $4;
Reid Spencere7c3c602006-11-30 06:36:44 +00001385 $$ = $1;
1386 };
1387
1388%%
1389
1390int yyerror(const char *ErrorMsg) {
1391 std::string where
1392 = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
1393 + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
1394 std::string errMsg = std::string(ErrorMsg) + "\n" + where + " while reading ";
1395 if (yychar == YYEMPTY || yychar == 0)
1396 errMsg += "end-of-file.";
1397 else
1398 errMsg += "token: '" + std::string(Upgradetext, Upgradeleng) + "'";
Reid Spencer71d2ec92006-12-31 06:02:26 +00001399 std::cerr << "llvm-upgrade: " << errMsg << '\n';
Reid Spencere7c3c602006-11-30 06:36:44 +00001400 exit(1);
1401}