blob: f53369d6031bb258e52a96a53e8fcac92e584996 [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 Spencer996fb282006-12-06 06:30:15 +000026#define UPGRADE_SETCOND_OPS 0
Reid Spencerf0cf1322006-12-07 04:23:03 +000027#define GENERATE_FCMP_INSTS 0
Reid Spencere7c3c602006-11-30 06:36:44 +000028
29int yylex(); // declaration" of xxx warnings.
30int yyparse();
Reid Spencere77e35e2006-12-01 20:26:20 +000031extern int yydebug;
Reid Spencere7c3c602006-11-30 06:36:44 +000032
33static std::string CurFilename;
Reid Spencere7c3c602006-11-30 06:36:44 +000034static std::ostream *O = 0;
Reid Spencer96839be2006-11-30 16:50:26 +000035std::istream* LexInput = 0;
Reid Spencere77e35e2006-12-01 20:26:20 +000036unsigned SizeOfPointer = 32;
Reid Spencerf459d392006-12-02 16:19:52 +000037static uint64_t unique = 1;
Reid Spencer96839be2006-11-30 16:50:26 +000038
Reid Spencera50d5962006-12-02 04:11:07 +000039typedef std::vector<TypeInfo> TypeVector;
40static TypeVector EnumeratedTypes;
41typedef std::map<std::string,TypeInfo> TypeMap;
42static TypeMap NamedTypes;
Reid Spencerf12ee422006-12-05 19:21:25 +000043static TypeMap Globals;
Reid Spencera50d5962006-12-02 04:11:07 +000044
Reid Spencerf8483652006-12-02 15:16:01 +000045void destroy(ValueList* VL) {
46 while (!VL->empty()) {
47 ValueInfo& VI = VL->back();
48 VI.destroy();
49 VL->pop_back();
50 }
51 delete VL;
52}
53
Reid Spencer96839be2006-11-30 16:50:26 +000054void UpgradeAssembly(const std::string &infile, std::istream& in,
Reid Spencere77e35e2006-12-01 20:26:20 +000055 std::ostream &out, bool debug)
Reid Spencere7c3c602006-11-30 06:36:44 +000056{
57 Upgradelineno = 1;
58 CurFilename = infile;
Reid Spencer96839be2006-11-30 16:50:26 +000059 LexInput = &in;
Reid Spencere77e35e2006-12-01 20:26:20 +000060 yydebug = debug;
Reid Spencere7c3c602006-11-30 06:36:44 +000061 O = &out;
62
63 if (yyparse()) {
64 std::cerr << "Parse failed.\n";
65 exit(1);
66 }
67}
68
Reid Spencera50d5962006-12-02 04:11:07 +000069static void ResolveType(TypeInfo& Ty) {
70 if (Ty.oldTy == UnresolvedTy) {
71 TypeMap::iterator I = NamedTypes.find(*Ty.newTy);
Reid Spencer78720742006-12-02 20:21:22 +000072 if (I != NamedTypes.end()) {
Reid Spencera50d5962006-12-02 04:11:07 +000073 Ty.oldTy = I->second.oldTy;
Reid Spencer78720742006-12-02 20:21:22 +000074 Ty.elemTy = I->second.elemTy;
75 } else {
Reid Spencera50d5962006-12-02 04:11:07 +000076 std::string msg("Can't resolve type: ");
77 msg += *Ty.newTy;
78 yyerror(msg.c_str());
Reid Spencer280d8012006-12-01 23:40:53 +000079 }
Reid Spencera50d5962006-12-02 04:11:07 +000080 } else if (Ty.oldTy == NumericTy) {
81 unsigned ref = atoi(&((Ty.newTy->c_str())[1])); // Skip the '\\'
82 if (ref < EnumeratedTypes.size()) {
83 Ty.oldTy = EnumeratedTypes[ref].oldTy;
Reid Spencer78720742006-12-02 20:21:22 +000084 Ty.elemTy = EnumeratedTypes[ref].elemTy;
Reid Spencera50d5962006-12-02 04:11:07 +000085 } else {
86 std::string msg("Can't resolve type: ");
87 msg += *Ty.newTy;
88 yyerror(msg.c_str());
89 }
Reid Spencer280d8012006-12-01 23:40:53 +000090 }
Reid Spencera50d5962006-12-02 04:11:07 +000091 // otherwise its already resolved.
Reid Spencer280d8012006-12-01 23:40:53 +000092}
93
Reid Spencera50d5962006-12-02 04:11:07 +000094static const char* getCastOpcode(
95 std::string& Source, const TypeInfo& SrcTy, const TypeInfo& DstTy)
96{
Reid Spencere77e35e2006-12-01 20:26:20 +000097 unsigned SrcBits = SrcTy.getBitWidth();
98 unsigned DstBits = DstTy.getBitWidth();
99 const char* opcode = "bitcast";
100 // Run through the possibilities ...
101 if (DstTy.isIntegral()) { // Casting to integral
102 if (SrcTy.isIntegral()) { // Casting from integral
103 if (DstBits < SrcBits)
104 opcode = "trunc";
105 else if (DstBits > SrcBits) { // its an extension
106 if (SrcTy.isSigned())
107 opcode ="sext"; // signed -> SEXT
108 else
109 opcode = "zext"; // unsigned -> ZEXT
110 } else {
111 opcode = "bitcast"; // Same size, No-op cast
112 }
113 } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt
114 if (DstTy.isSigned())
115 opcode = "fptosi"; // FP -> sint
116 else
117 opcode = "fptoui"; // FP -> uint
118 } else if (SrcTy.isPacked()) {
119 assert(DstBits == SrcTy.getBitWidth() &&
120 "Casting packed to integer of different width");
121 opcode = "bitcast"; // same size, no-op cast
122 } else {
123 assert(SrcTy.isPointer() &&
124 "Casting from a value that is not first-class type");
125 opcode = "ptrtoint"; // ptr -> int
126 }
127 } else if (DstTy.isFloatingPoint()) { // Casting to floating pt
128 if (SrcTy.isIntegral()) { // Casting from integral
129 if (SrcTy.isSigned())
130 opcode = "sitofp"; // sint -> FP
131 else
132 opcode = "uitofp"; // uint -> FP
133 } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt
134 if (DstBits < SrcBits) {
135 opcode = "fptrunc"; // FP -> smaller FP
136 } else if (DstBits > SrcBits) {
137 opcode = "fpext"; // FP -> larger FP
138 } else {
139 opcode ="bitcast"; // same size, no-op cast
140 }
141 } else if (SrcTy.isPacked()) {
142 assert(DstBits == SrcTy.getBitWidth() &&
143 "Casting packed to floating point of different width");
144 opcode = "bitcast"; // same size, no-op cast
145 } else {
146 assert(0 && "Casting pointer or non-first class to float");
147 }
148 } else if (DstTy.isPacked()) {
149 if (SrcTy.isPacked()) {
150 assert(DstTy.getBitWidth() == SrcTy.getBitWidth() &&
151 "Casting packed to packed of different widths");
152 opcode = "bitcast"; // packed -> packed
153 } else if (DstTy.getBitWidth() == SrcBits) {
154 opcode = "bitcast"; // float/int -> packed
155 } else {
156 assert(!"Illegal cast to packed (wrong type or size)");
157 }
158 } else if (DstTy.isPointer()) {
159 if (SrcTy.isPointer()) {
160 opcode = "bitcast"; // ptr -> ptr
161 } else if (SrcTy.isIntegral()) {
162 opcode = "inttoptr"; // int -> ptr
163 } else {
Reid Spencera50d5962006-12-02 04:11:07 +0000164 assert(!"Casting invalid type to pointer");
Reid Spencere77e35e2006-12-01 20:26:20 +0000165 }
166 } else {
167 assert(!"Casting to type that is not first-class");
168 }
169 return opcode;
170}
171
Reid Spencera50d5962006-12-02 04:11:07 +0000172static std::string getCastUpgrade(
173 const std::string& Src, TypeInfo& SrcTy, TypeInfo& DstTy, bool isConst)
174{
175 std::string Result;
176 std::string Source = Src;
177 if (SrcTy.isFloatingPoint() && DstTy.isPointer()) {
178 // fp -> ptr cast is no longer supported but we must upgrade this
179 // by doing a double cast: fp -> int -> ptr
180 if (isConst)
181 Source = "ulong fptoui(" + Source + " to ulong)";
182 else {
Reid Spencerf459d392006-12-02 16:19:52 +0000183 *O << " %cast_upgrade" << unique << " = fptoui " << Source
184 << " to ulong\n";
185 Source = "ulong %cast_upgrade" + llvm::utostr(unique);
Reid Spencera50d5962006-12-02 04:11:07 +0000186 }
187 // Update the SrcTy for the getCastOpcode call below
188 SrcTy.destroy();
189 SrcTy.newTy = new std::string("ulong");
190 SrcTy.oldTy = ULongTy;
191 } else if (DstTy.oldTy == BoolTy) {
192 // cast ptr %x to bool was previously defined as setne ptr %x, null
193 // The ptrtoint semantic is to truncate, not compare so we must retain
194 // the original intent by replace the cast with a setne
195 const char* comparator = SrcTy.isPointer() ? ", null" :
196 (SrcTy.isFloatingPoint() ? ", 0.0" : ", 0");
197 if (isConst)
198 Result = "setne (" + Source + comparator + ")";
199 else
200 Result = "setne " + Source + comparator;
201 return Result; // skip cast processing below
202 }
203 ResolveType(SrcTy);
204 ResolveType(DstTy);
205 std::string Opcode(getCastOpcode(Source, SrcTy, DstTy));
206 if (isConst)
207 Result += Opcode + "( " + Source + " to " + *DstTy.newTy + ")";
208 else
209 Result += Opcode + " " + Source + " to " + *DstTy.newTy;
210 return Result;
211}
212
Reid Spencer78720742006-12-02 20:21:22 +0000213const char* getDivRemOpcode(const std::string& opcode, const TypeInfo& TI) {
214 const char* op = opcode.c_str();
215 TypeInfo Ty = TI;
216 ResolveType(Ty);
217 if (Ty.isPacked())
218 Ty.oldTy = Ty.getElementType();
219 if (opcode == "div")
220 if (Ty.isFloatingPoint())
221 op = "fdiv";
222 else if (Ty.isUnsigned())
223 op = "udiv";
224 else if (Ty.isSigned())
225 op = "sdiv";
226 else
227 yyerror("Invalid type for div instruction");
228 else if (opcode == "rem")
229 if (Ty.isFloatingPoint())
230 op = "frem";
231 else if (Ty.isUnsigned())
232 op = "urem";
233 else if (Ty.isSigned())
234 op = "srem";
235 else
236 yyerror("Invalid type for rem instruction");
237 return op;
238}
Reid Spencer229e9362006-12-02 22:14:11 +0000239
240std::string
241getCompareOp(const std::string& setcc, const TypeInfo& TI) {
242 assert(setcc.length() == 5);
243 char cc1 = setcc[3];
244 char cc2 = setcc[4];
245 assert(cc1 == 'e' || cc1 == 'n' || cc1 == 'l' || cc1 == 'g');
246 assert(cc2 == 'q' || cc2 == 'e' || cc2 == 'e' || cc2 == 't');
247 std::string result("xcmp xxx");
248 result[6] = cc1;
249 result[7] = cc2;
250 if (TI.isFloatingPoint()) {
Reid Spencerf0cf1322006-12-07 04:23:03 +0000251#if GENERATE_FCMP_INSTS
Reid Spencer229e9362006-12-02 22:14:11 +0000252 result[0] = 'f';
253 result[5] = 'o'; // FIXME: Always map to ordered comparison ?
Reid Spencerf0cf1322006-12-07 04:23:03 +0000254 if (cc1 == 'n')
255 result[5] = 'u'; // NE maps to unordered
256 else
257 result[5] = 'o'; // everything else maps to ordered
258#else
259 result = setcc;
260#endif
Reid Spencer229e9362006-12-02 22:14:11 +0000261 } else if (TI.isIntegral() || TI.isPointer()) {
262 result[0] = 'i';
263 if ((cc1 == 'e' && cc2 == 'q') || (cc1 == 'n' && cc2 == 'e'))
264 result.erase(5,1);
265 else if (TI.isSigned())
266 result[5] = 's';
Reid Spencer3e5ab8c2006-12-06 06:25:46 +0000267 else if (TI.isUnsigned() || TI.isPointer() || TI.isBool())
Reid Spencer229e9362006-12-02 22:14:11 +0000268 result[5] = 'u';
269 else
270 yyerror("Invalid integral type for setcc");
271 }
272 return result;
273}
274
Reid Spencere7c3c602006-11-30 06:36:44 +0000275%}
276
Reid Spencerf0cf1322006-12-07 04:23:03 +0000277// %file-prefix="UpgradeParser"
Reid Spencere77e35e2006-12-01 20:26:20 +0000278
279%union {
280 std::string* String;
281 TypeInfo Type;
282 ValueInfo Value;
283 ConstInfo Const;
Reid Spencerf8483652006-12-02 15:16:01 +0000284 ValueList* ValList;
Reid Spencere77e35e2006-12-01 20:26:20 +0000285}
286
Reid Spencerf2d55322006-12-01 21:52:30 +0000287%token <Type> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
Reid Spencera50d5962006-12-02 04:11:07 +0000288%token <Type> FLOAT DOUBLE LABEL
289%token <String> OPAQUE ESINT64VAL EUINT64VAL SINTVAL UINTVAL FPVAL
Reid Spencerf2d55322006-12-01 21:52:30 +0000290%token <String> NULL_TOK UNDEF ZEROINITIALIZER TRUETOK FALSETOK
Reid Spencere77e35e2006-12-01 20:26:20 +0000291%token <String> TYPE VAR_ID LABELSTR STRINGCONSTANT
292%token <String> IMPLEMENTATION BEGINTOK ENDTOK
293%token <String> DECLARE GLOBAL CONSTANT SECTION VOLATILE
294%token <String> TO DOTDOTDOT CONST INTERNAL LINKONCE WEAK
295%token <String> DLLIMPORT DLLEXPORT EXTERN_WEAK APPENDING
296%token <String> NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG
Reid Spencer78720742006-12-02 20:21:22 +0000297%token <String> ALIGN UNINITIALIZED
Reid Spencere77e35e2006-12-01 20:26:20 +0000298%token <String> DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
299%token <String> CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK
300%token <String> X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
301%token <String> DATALAYOUT
Reid Spencer78720742006-12-02 20:21:22 +0000302%token <String> RET BR SWITCH INVOKE EXCEPT UNWIND UNREACHABLE
303%token <String> ADD SUB MUL DIV UDIV SDIV FDIV REM UREM SREM FREM AND OR XOR
Reid Spencere77e35e2006-12-01 20:26:20 +0000304%token <String> SETLE SETGE SETLT SETGT SETEQ SETNE // Binary Comparators
Reid Spencer229e9362006-12-02 22:14:11 +0000305%token <String> ICMP FCMP EQ NE SLT SGT SLE SGE OEQ ONE OLT OGT OLE OGE
306%token <String> ORD UNO UEQ UNE ULT UGT ULE UGE
Reid Spencere77e35e2006-12-01 20:26:20 +0000307%token <String> MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR
Reid Spencerf7bde222006-12-01 22:26:37 +0000308%token <String> PHI_TOK SELECT SHL SHR ASHR LSHR VAARG
Reid Spencere77e35e2006-12-01 20:26:20 +0000309%token <String> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
Reid Spencerfcb5df82006-12-01 22:34:43 +0000310%token <String> CAST TRUNC ZEXT SEXT FPTRUNC FPEXT FPTOUI FPTOSI UITOFP SITOFP
311%token <String> PTRTOINT INTTOPTR BITCAST
Reid Spencere77e35e2006-12-01 20:26:20 +0000312
313%type <String> OptAssign OptLinkage OptCallingConv OptAlign OptCAlign
314%type <String> SectionString OptSection GlobalVarAttributes GlobalVarAttribute
315%type <String> ArgTypeListI ConstExpr DefinitionList
316%type <String> ConstPool TargetDefinition LibrariesDefinition LibList OptName
317%type <String> ArgVal ArgListH ArgList FunctionHeaderH BEGIN FunctionHeader END
318%type <String> Function FunctionProto BasicBlock TypeListI
319%type <String> InstructionList BBTerminatorInst JumpTable Inst PHIList
Reid Spencer78720742006-12-02 20:21:22 +0000320%type <String> OptTailCall InstVal OptVolatile Unwind
Reid Spencere77e35e2006-12-01 20:26:20 +0000321%type <String> MemoryInst SymbolicValueRef OptSideEffect GlobalType
322%type <String> FnDeclareLinkage BasicBlockList BigOrLittle AsmBlock
Reid Spencer78720742006-12-02 20:21:22 +0000323%type <String> Name ConstValueRef ConstVector External
Reid Spencer57f28f92006-12-03 07:10:26 +0000324%type <String> ShiftOps SetCondOps LogicalOps ArithmeticOps CastOps
325%type <String> IPredicates FPredicates
Reid Spencere77e35e2006-12-01 20:26:20 +0000326
Reid Spencerf8483652006-12-02 15:16:01 +0000327%type <ValList> ValueRefList ValueRefListE IndexList
Reid Spencere77e35e2006-12-01 20:26:20 +0000328
329%type <Type> IntType SIntType UIntType FPType TypesV Types
330%type <Type> PrimType UpRTypesV UpRTypes
331
Reid Spencerf2d55322006-12-01 21:52:30 +0000332%type <String> IntVal EInt64Val
333%type <Const> ConstVal
Reid Spencere77e35e2006-12-01 20:26:20 +0000334
Reid Spencerf459d392006-12-02 16:19:52 +0000335%type <Value> ValueRef ResolvedVal
Reid Spencere7c3c602006-11-30 06:36:44 +0000336
337%start Module
338
339%%
340
341// Handle constant integer size restriction and conversion...
Reid Spencerf2d55322006-12-01 21:52:30 +0000342IntVal : SINTVAL | UINTVAL ;
Reid Spencere77e35e2006-12-01 20:26:20 +0000343EInt64Val : ESINT64VAL | EUINT64VAL;
Reid Spencere7c3c602006-11-30 06:36:44 +0000344
345// Operations that are notably excluded from this list include:
346// RET, BR, & SWITCH because they end basic blocks and are treated specially.
Reid Spencer78720742006-12-02 20:21:22 +0000347ArithmeticOps: ADD | SUB | MUL | DIV | UDIV | SDIV | FDIV
348 | REM | UREM | SREM | FREM;
Reid Spencere7c3c602006-11-30 06:36:44 +0000349LogicalOps : AND | OR | XOR;
350SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE;
Reid Spencer57f28f92006-12-03 07:10:26 +0000351IPredicates : EQ | NE | SLT | SGT | SLE | SGE | ULT | UGT | ULE | UGE;
352FPredicates : OEQ | ONE | OLT | OGT | OLE | OGE | ORD | UNO | UEQ | UNE
353 | ULT | UGT | ULE | UGE | TRUETOK | FALSETOK;
Reid Spencerf7bde222006-12-01 22:26:37 +0000354ShiftOps : SHL | SHR | ASHR | LSHR;
Reid Spencerfcb5df82006-12-01 22:34:43 +0000355CastOps : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | FPTOUI | FPTOSI |
356 UITOFP | SITOFP | PTRTOINT | INTTOPTR | BITCAST | CAST
357 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000358
359// These are some types that allow classification if we only want a particular
360// thing... for example, only a signed, unsigned, or integral type.
361SIntType : LONG | INT | SHORT | SBYTE;
362UIntType : ULONG | UINT | USHORT | UBYTE;
363IntType : SIntType | UIntType;
364FPType : FLOAT | DOUBLE;
365
366// OptAssign - Value producing statements have an optional assignment component
367OptAssign : Name '=' {
Reid Spencere7c3c602006-11-30 06:36:44 +0000368 $$ = $1;
369 }
370 | /*empty*/ {
371 $$ = new std::string("");
372 };
373
374OptLinkage
375 : INTERNAL | LINKONCE | WEAK | APPENDING | DLLIMPORT | DLLEXPORT
376 | EXTERN_WEAK
377 | /*empty*/ { $$ = new std::string(""); } ;
378
379OptCallingConv
380 : CCC_TOK | CSRETCC_TOK | FASTCC_TOK | COLDCC_TOK | X86_STDCALLCC_TOK
Reid Spencer16244f42006-12-01 21:10:07 +0000381 | X86_FASTCALLCC_TOK
382 | CC_TOK EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000383 *$1 += *$2;
384 delete $2;
Reid Spencer16244f42006-12-01 21:10:07 +0000385 $$ = $1;
386 }
Reid Spencere7c3c602006-11-30 06:36:44 +0000387 | /*empty*/ { $$ = new std::string(""); } ;
388
389// OptAlign/OptCAlign - An optional alignment, and an optional alignment with
390// a comma before it.
391OptAlign
392 : /*empty*/ { $$ = new std::string(); }
Reid Spencerf2d55322006-12-01 21:52:30 +0000393 | ALIGN EUINT64VAL { *$1 += " " + *$2; delete $2; $$ = $1; };
Reid Spencerf0cf1322006-12-07 04:23:03 +0000394
Reid Spencere7c3c602006-11-30 06:36:44 +0000395OptCAlign
396 : /*empty*/ { $$ = new std::string(); }
397 | ',' ALIGN EUINT64VAL {
398 $2->insert(0, ", ");
Reid Spencerf2d55322006-12-01 21:52:30 +0000399 *$2 += " " + *$3;
400 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000401 $$ = $2;
402 };
403
404SectionString
405 : SECTION STRINGCONSTANT {
406 *$1 += " " + *$2;
407 delete $2;
408 $$ = $1;
409 };
410
411OptSection : /*empty*/ { $$ = new std::string(); }
412 | SectionString;
413
414GlobalVarAttributes
415 : /* empty */ { $$ = new std::string(); }
416 | ',' GlobalVarAttribute GlobalVarAttributes {
417 $2->insert(0, ", ");
418 if (!$3->empty())
419 *$2 += " " + *$3;
420 delete $3;
421 $$ = $2;
422 };
423
424GlobalVarAttribute
425 : SectionString
426 | ALIGN EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000427 *$1 += " " + *$2;
428 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000429 $$ = $1;
430 };
431
432//===----------------------------------------------------------------------===//
433// Types includes all predefined types... except void, because it can only be
434// used in specific contexts (function returning void for example). To have
435// access to it, a user must explicitly use TypesV.
436//
437
438// TypesV includes all of 'Types', but it also includes the void type.
439TypesV : Types | VOID ;
440UpRTypesV : UpRTypes | VOID ;
441Types : UpRTypes ;
442
443// Derived types are added later...
444//
445PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ;
Reid Spencere77e35e2006-12-01 20:26:20 +0000446PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL;
Reid Spencera50d5962006-12-02 04:11:07 +0000447UpRTypes
448 : OPAQUE {
449 $$.newTy = $1;
450 $$.oldTy = OpaqueTy;
451 }
452 | SymbolicValueRef {
453 $$.newTy = $1;
454 $$.oldTy = UnresolvedTy;
455 }
Reid Spencer78720742006-12-02 20:21:22 +0000456 | PrimType {
457 $$ = $1;
458 }
459 | '\\' EUINT64VAL { // Type UpReference
Reid Spencerf2d55322006-12-01 21:52:30 +0000460 $2->insert(0, "\\");
461 $$.newTy = $2;
Reid Spencera50d5962006-12-02 04:11:07 +0000462 $$.oldTy = NumericTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000463 }
464 | UpRTypesV '(' ArgTypeListI ')' { // Function derived type?
Reid Spencere77e35e2006-12-01 20:26:20 +0000465 *$1.newTy += "( " + *$3 + " )";
Reid Spencere7c3c602006-11-30 06:36:44 +0000466 delete $3;
Reid Spencere77e35e2006-12-01 20:26:20 +0000467 $$.newTy = $1.newTy;
468 $$.oldTy = FunctionTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000469 }
470 | '[' EUINT64VAL 'x' UpRTypes ']' { // Sized array type?
Reid Spencerf2d55322006-12-01 21:52:30 +0000471 $2->insert(0,"[ ");
472 *$2 += " x " + *$4.newTy + " ]";
Reid Spencere77e35e2006-12-01 20:26:20 +0000473 delete $4.newTy;
Reid Spencerf2d55322006-12-01 21:52:30 +0000474 $$.newTy = $2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000475 $$.oldTy = ArrayTy;
Reid Spencer78720742006-12-02 20:21:22 +0000476 $$.elemTy = $4.oldTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000477 }
478 | '<' EUINT64VAL 'x' UpRTypes '>' { // Packed array type?
Reid Spencerf2d55322006-12-01 21:52:30 +0000479 $2->insert(0,"< ");
480 *$2 += " x " + *$4.newTy + " >";
Reid Spencere77e35e2006-12-01 20:26:20 +0000481 delete $4.newTy;
Reid Spencerf2d55322006-12-01 21:52:30 +0000482 $$.newTy = $2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000483 $$.oldTy = PackedTy;
Reid Spencer78720742006-12-02 20:21:22 +0000484 $$.elemTy = $4.oldTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000485 }
486 | '{' TypeListI '}' { // Structure type?
487 $2->insert(0, "{ ");
488 *$2 += " }";
Reid Spencere77e35e2006-12-01 20:26:20 +0000489 $$.newTy = $2;
490 $$.oldTy = StructTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000491 }
492 | '{' '}' { // Empty structure type?
Reid Spencer0b7e5072006-12-01 22:42:01 +0000493 $$.newTy = new std::string("{}");
Reid Spencere77e35e2006-12-01 20:26:20 +0000494 $$.oldTy = StructTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000495 }
496 | UpRTypes '*' { // Pointer type?
Reid Spencere77e35e2006-12-01 20:26:20 +0000497 *$1.newTy += '*';
Reid Spencer78720742006-12-02 20:21:22 +0000498 $$.elemTy = $1.oldTy;
Reid Spencere77e35e2006-12-01 20:26:20 +0000499 $1.oldTy = PointerTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000500 $$ = $1;
501 };
502
503// TypeList - Used for struct declarations and as a basis for function type
504// declaration type lists
505//
Reid Spencere77e35e2006-12-01 20:26:20 +0000506TypeListI
507 : UpRTypes {
508 $$ = $1.newTy;
509 }
510 | TypeListI ',' UpRTypes {
511 *$1 += ", " + *$3.newTy;
512 delete $3.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000513 $$ = $1;
514 };
515
516// ArgTypeList - List of types for a function type declaration...
Reid Spencere77e35e2006-12-01 20:26:20 +0000517ArgTypeListI
518 : TypeListI
Reid Spencere7c3c602006-11-30 06:36:44 +0000519 | TypeListI ',' DOTDOTDOT {
520 *$1 += ", ...";
521 delete $3;
522 $$ = $1;
523 }
524 | DOTDOTDOT {
525 $$ = $1;
526 }
527 | /*empty*/ {
528 $$ = new std::string();
529 };
530
531// ConstVal - The various declarations that go into the constant pool. This
532// production is used ONLY to represent constants that show up AFTER a 'const',
533// 'constant' or 'global' token at global scope. Constants that can be inlined
534// into other expressions (such as integers and constexprs) are handled by the
535// ResolvedVal, ValueRef and ConstValueRef productions.
536//
537ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
Reid Spencere77e35e2006-12-01 20:26:20 +0000538 $$.type = $1;
539 $$.cnst = new std::string(*$1.newTy);
540 *$$.cnst += " [ " + *$3 + " ]";
Reid Spencere7c3c602006-11-30 06:36:44 +0000541 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000542 }
543 | Types '[' ']' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000544 $$.type = $1;
545 $$.cnst = new std::string(*$1.newTy);
546 *$$.cnst += "[ ]";
Reid Spencere7c3c602006-11-30 06:36:44 +0000547 }
548 | Types 'c' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000549 $$.type = $1;
550 $$.cnst = new std::string(*$1.newTy);
551 *$$.cnst += " c" + *$3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000552 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000553 }
554 | Types '<' ConstVector '>' { // Nonempty unsized arr
Reid Spencere77e35e2006-12-01 20:26:20 +0000555 $$.type = $1;
556 $$.cnst = new std::string(*$1.newTy);
557 *$$.cnst += " < " + *$3 + " >";
Reid Spencere7c3c602006-11-30 06:36:44 +0000558 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000559 }
560 | Types '{' ConstVector '}' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000561 $$.type = $1;
562 $$.cnst = new std::string(*$1.newTy);
563 *$$.cnst += " { " + *$3 + " }";
Reid Spencere7c3c602006-11-30 06:36:44 +0000564 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000565 }
566 | Types '{' '}' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000567 $$.type = $1;
568 $$.cnst = new std::string(*$1.newTy);
Reid Spencer0b7e5072006-12-01 22:42:01 +0000569 *$$.cnst += " {}";
Reid Spencere7c3c602006-11-30 06:36:44 +0000570 }
571 | Types NULL_TOK {
Reid Spencere77e35e2006-12-01 20:26:20 +0000572 $$.type = $1;
573 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000574 *$$.cnst += " " + *$2;
575 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000576 }
577 | Types UNDEF {
Reid Spencere77e35e2006-12-01 20:26:20 +0000578 $$.type = $1;
579 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000580 *$$.cnst += " " + *$2;
581 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000582 }
583 | Types SymbolicValueRef {
Reid Spencere77e35e2006-12-01 20:26:20 +0000584 $$.type = $1;
585 $$.cnst = new std::string(*$1.newTy);
586 *$$.cnst += " " + *$2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000587 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000588 }
589 | Types ConstExpr {
Reid Spencere77e35e2006-12-01 20:26:20 +0000590 $$.type = $1;
591 $$.cnst = new std::string(*$1.newTy);
592 *$$.cnst += " " + *$2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000593 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000594 }
595 | Types ZEROINITIALIZER {
Reid Spencere77e35e2006-12-01 20:26:20 +0000596 $$.type = $1;
597 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000598 *$$.cnst += " " + *$2;
599 delete $2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000600 }
601 | SIntType EInt64Val { // integral constants
602 $$.type = $1;
603 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000604 *$$.cnst += " " + *$2;
605 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000606 }
607 | UIntType EUINT64VAL { // integral constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000608 $$.type = $1;
609 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000610 *$$.cnst += " " + *$2;
611 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000612 }
613 | BOOL TRUETOK { // Boolean constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000614 $$.type = $1;
615 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000616 *$$.cnst += " " + *$2;
617 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000618 }
619 | BOOL FALSETOK { // Boolean constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000620 $$.type = $1;
621 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000622 *$$.cnst += " " + *$2;
623 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000624 }
625 | FPType FPVAL { // Float & Double constants
Reid Spencere77e35e2006-12-01 20:26:20 +0000626 $$.type = $1;
627 $$.cnst = new std::string(*$1.newTy);
Reid Spencerf2d55322006-12-01 21:52:30 +0000628 *$$.cnst += " " + *$2;
629 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000630 };
631
632
Reid Spencerfcb5df82006-12-01 22:34:43 +0000633ConstExpr: CastOps '(' ConstVal TO Types ')' {
Reid Spencer280d8012006-12-01 23:40:53 +0000634 std::string source = *$3.cnst;
Reid Spencera50d5962006-12-02 04:11:07 +0000635 TypeInfo DstTy = $5;
636 ResolveType(DstTy);
Reid Spencer280d8012006-12-01 23:40:53 +0000637 if (*$1 == "cast") {
Reid Spencera50d5962006-12-02 04:11:07 +0000638 // Call getCastUpgrade to upgrade the old cast
639 $$ = new std::string(getCastUpgrade(source, $3.type, $5, true));
640 } else {
641 // Nothing to upgrade, just create the cast constant expr
642 $$ = new std::string(*$1);
643 *$$ += "( " + source + " to " + *$5.newTy + ")";
Reid Spencer280d8012006-12-01 23:40:53 +0000644 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000645 delete $1; $3.destroy(); delete $4; $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000646 }
647 | GETELEMENTPTR '(' ConstVal IndexList ')' {
Reid Spencerf8483652006-12-02 15:16:01 +0000648 *$1 += "(" + *$3.cnst;
649 for (unsigned i = 0; i < $4->size(); ++i) {
650 ValueInfo& VI = (*$4)[i];
651 *$1 += ", " + *VI.val;
652 VI.destroy();
653 }
654 *$1 += ")";
Reid Spencere77e35e2006-12-01 20:26:20 +0000655 $$ = $1;
656 $3.destroy();
657 delete $4;
Reid Spencere7c3c602006-11-30 06:36:44 +0000658 }
659 | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000660 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
661 $3.destroy(); $5.destroy(); $7.destroy();
662 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000663 }
664 | ArithmeticOps '(' ConstVal ',' ConstVal ')' {
Reid Spencer78720742006-12-02 20:21:22 +0000665 const char* op = getDivRemOpcode(*$1, $3.type);
666 $$ = new std::string(op);
667 *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
668 delete $1; $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000669 }
670 | LogicalOps '(' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000671 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
672 $3.destroy(); $5.destroy();
673 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000674 }
675 | SetCondOps '(' ConstVal ',' ConstVal ')' {
Reid Spencer229e9362006-12-02 22:14:11 +0000676#if UPGRADE_SETCOND_OPS
677 *$1 = getCompareOp(*$1, $3.type);
678#endif
Reid Spencere77e35e2006-12-01 20:26:20 +0000679 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
680 $3.destroy(); $5.destroy();
681 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000682 }
Reid Spencer57f28f92006-12-03 07:10:26 +0000683 | ICMP IPredicates '(' ConstVal ',' ConstVal ')' {
684 *$1 += "(" + *$2 + "," + *$4.cnst + "," + *$6.cnst + ")";
685 delete $2; $4.destroy(); $6.destroy();
686 $$ = $1;
687 }
688 | FCMP FPredicates '(' ConstVal ',' ConstVal ')' {
Reid Spencer229e9362006-12-02 22:14:11 +0000689 *$1 += "(" + *$2 + "," + *$4.cnst + "," + *$6.cnst + ")";
690 delete $2; $4.destroy(); $6.destroy();
691 $$ = $1;
692 }
Reid Spencere7c3c602006-11-30 06:36:44 +0000693 | ShiftOps '(' ConstVal ',' ConstVal ')' {
Reid Spencerf7bde222006-12-01 22:26:37 +0000694 const char* shiftop = $1->c_str();
695 if (*$1 == "shr")
696 shiftop = ($3.type.isUnsigned()) ? "lshr" : "ashr";
697 $$ = new std::string(shiftop);
698 *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
699 delete $1; $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000700 }
701 | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000702 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
703 $3.destroy(); $5.destroy();
704 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000705 }
706 | INSERTELEMENT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000707 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
708 $3.destroy(); $5.destroy(); $7.destroy();
709 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000710 }
711 | SHUFFLEVECTOR '(' ConstVal ',' ConstVal ',' ConstVal ')' {
Reid Spencere77e35e2006-12-01 20:26:20 +0000712 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
713 $3.destroy(); $5.destroy(); $7.destroy();
714 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000715 };
716
717
718// ConstVector - A list of comma separated constants.
Reid Spencere77e35e2006-12-01 20:26:20 +0000719
720ConstVector
721 : ConstVector ',' ConstVal {
722 *$1 += ", " + *$3.cnst;
723 $3.destroy();
724 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000725 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000726 | ConstVal { $$ = new std::string(*$1.cnst); $1.destroy(); }
727 ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000728
729
730// GlobalType - Match either GLOBAL or CONSTANT for global declarations...
Reid Spencere77e35e2006-12-01 20:26:20 +0000731GlobalType : GLOBAL | CONSTANT ;
Reid Spencere7c3c602006-11-30 06:36:44 +0000732
733
734//===----------------------------------------------------------------------===//
735// Rules to match Modules
736//===----------------------------------------------------------------------===//
737
738// Module rule: Capture the result of parsing the whole file into a result
739// variable...
740//
741Module : DefinitionList {
742};
743
744// DefinitionList - Top level definitions
745//
746DefinitionList : DefinitionList Function {
747 $$ = 0;
748 }
749 | DefinitionList FunctionProto {
750 *O << *$2 << "\n";
751 delete $2;
752 $$ = 0;
753 }
754 | DefinitionList MODULE ASM_TOK AsmBlock {
755 *O << "module asm " << " " << *$4 << "\n";
Reid Spencerd154b572006-12-01 20:36:40 +0000756 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000757 }
758 | DefinitionList IMPLEMENTATION {
759 *O << "implementation\n";
Reid Spencerd154b572006-12-01 20:36:40 +0000760 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000761 }
Reid Spencera50d5962006-12-02 04:11:07 +0000762 | ConstPool { $$ = 0; }
Reid Spencere7c3c602006-11-30 06:36:44 +0000763
Reid Spencer78720742006-12-02 20:21:22 +0000764External : EXTERNAL | UNINITIALIZED { $$ = $1; *$$ = "external"; }
765
Reid Spencere7c3c602006-11-30 06:36:44 +0000766// ConstPool - Constants with optional names assigned to them.
767ConstPool : ConstPool OptAssign TYPE TypesV {
Reid Spencera50d5962006-12-02 04:11:07 +0000768 EnumeratedTypes.push_back($4);
769 if (!$2->empty()) {
770 NamedTypes[*$2].newTy = new std::string(*$4.newTy);
771 NamedTypes[*$2].oldTy = $4.oldTy;
Reid Spencer78720742006-12-02 20:21:22 +0000772 NamedTypes[*$2].elemTy = $4.elemTy;
Reid Spencera50d5962006-12-02 04:11:07 +0000773 *O << *$2 << " = ";
774 }
775 *O << "type " << *$4.newTy << "\n";
776 delete $2; delete $3; $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +0000777 $$ = 0;
778 }
779 | ConstPool FunctionProto { // Function prototypes can be in const pool
780 *O << *$2 << "\n";
781 delete $2;
782 $$ = 0;
783 }
784 | ConstPool MODULE ASM_TOK AsmBlock { // Asm blocks can be in the const pool
785 *O << *$2 << " " << *$3 << " " << *$4 << "\n";
786 delete $2; delete $3; delete $4;
787 $$ = 0;
788 }
789 | ConstPool OptAssign OptLinkage GlobalType ConstVal GlobalVarAttributes {
Reid Spencerf12ee422006-12-05 19:21:25 +0000790 if (!$2->empty()) {
Reid Spencera50d5962006-12-02 04:11:07 +0000791 *O << *$2 << " = ";
Reid Spencerf12ee422006-12-05 19:21:25 +0000792 Globals[*$2] = $5.type.clone();
793 }
Reid Spencera50d5962006-12-02 04:11:07 +0000794 *O << *$3 << " " << *$4 << " " << *$5.cnst << " " << *$6 << "\n";
Reid Spencere77e35e2006-12-01 20:26:20 +0000795 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +0000796 $$ = 0;
797 }
Reid Spencer78720742006-12-02 20:21:22 +0000798 | ConstPool OptAssign External GlobalType Types 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.clone();
802 }
Reid Spencera50d5962006-12-02 04:11:07 +0000803 *O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$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 }
807 | ConstPool OptAssign DLLIMPORT 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 Spencera50d5962006-12-02 04:11:07 +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 EXTERN_WEAK 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 Spencera50d5962006-12-02 04:11:07 +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 TARGET TargetDefinition {
826 *O << *$2 << " " << *$3 << "\n";
827 delete $2; delete $3;
828 $$ = 0;
829 }
830 | ConstPool DEPLIBS '=' LibrariesDefinition {
831 *O << *$2 << " = " << *$4 << "\n";
832 delete $2; delete $4;
833 $$ = 0;
834 }
835 | /* empty: end of list */ {
836 $$ = 0;
837 };
838
839
840AsmBlock : STRINGCONSTANT ;
841
842BigOrLittle : BIG | LITTLE
843
844TargetDefinition
845 : ENDIAN '=' BigOrLittle {
Reid Spencere77e35e2006-12-01 20:26:20 +0000846 *$1 += " = " + *$3;
847 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000848 $$ = $1;
849 }
850 | POINTERSIZE '=' EUINT64VAL {
Reid Spencerf2d55322006-12-01 21:52:30 +0000851 *$1 += " = " + *$3;
852 if (*$3 == "64")
Reid Spencere77e35e2006-12-01 20:26:20 +0000853 SizeOfPointer = 64;
Reid Spencerf2d55322006-12-01 21:52:30 +0000854 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000855 $$ = $1;
856 }
857 | TRIPLE '=' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000858 *$1 += " = " + *$3;
859 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000860 $$ = $1;
861 }
862 | DATALAYOUT '=' STRINGCONSTANT {
Reid Spencere77e35e2006-12-01 20:26:20 +0000863 *$1 += " = " + *$3;
864 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000865 $$ = $1;
866 };
867
868LibrariesDefinition
869 : '[' LibList ']' {
870 $2->insert(0, "[ ");
871 *$2 += " ]";
872 $$ = $2;
873 };
874
875LibList
876 : LibList ',' STRINGCONSTANT {
877 *$1 += ", " + *$3;
878 delete $3;
879 $$ = $1;
880 }
881 | STRINGCONSTANT
882 | /* empty: end of list */ {
883 $$ = new std::string();
884 };
885
886//===----------------------------------------------------------------------===//
887// Rules to match Function Headers
888//===----------------------------------------------------------------------===//
889
890Name : VAR_ID | STRINGCONSTANT;
891OptName : Name | /*empty*/ { $$ = new std::string(); };
892
893ArgVal : Types OptName {
Reid Spencere77e35e2006-12-01 20:26:20 +0000894 $$ = $1.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +0000895 if (!$2->empty())
896 *$$ += " " + *$2;
Reid Spencere77e35e2006-12-01 20:26:20 +0000897 delete $2;
Reid Spencere7c3c602006-11-30 06:36:44 +0000898};
899
900ArgListH : ArgListH ',' ArgVal {
901 *$1 += ", " + *$3;
Reid Spencere77e35e2006-12-01 20:26:20 +0000902 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000903 }
904 | ArgVal {
905 $$ = $1;
906 };
907
908ArgList : ArgListH {
909 $$ = $1;
910 }
911 | ArgListH ',' DOTDOTDOT {
912 *$1 += ", ...";
913 $$ = $1;
Reid Spencere77e35e2006-12-01 20:26:20 +0000914 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000915 }
916 | DOTDOTDOT {
917 $$ = $1;
918 }
Reid Spencerd154b572006-12-01 20:36:40 +0000919 | /* empty */ { $$ = new std::string(); };
Reid Spencere7c3c602006-11-30 06:36:44 +0000920
921FunctionHeaderH : OptCallingConv TypesV Name '(' ArgList ')'
922 OptSection OptAlign {
923 if (!$1->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000924 *$1 += " ";
Reid Spencere7c3c602006-11-30 06:36:44 +0000925 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000926 *$1 += *$2.newTy + " " + *$3 + "(" + *$5 + ")";
Reid Spencere7c3c602006-11-30 06:36:44 +0000927 if (!$7->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000928 *$1 += " " + *$7;
Reid Spencere7c3c602006-11-30 06:36:44 +0000929 }
930 if (!$8->empty()) {
Reid Spencere77e35e2006-12-01 20:26:20 +0000931 *$1 += " " + *$8;
Reid Spencere7c3c602006-11-30 06:36:44 +0000932 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000933 $2.destroy();
934 delete $3;
935 delete $5;
936 delete $7;
937 delete $8;
938 $$ = $1;
Reid Spencere7c3c602006-11-30 06:36:44 +0000939 };
940
Reid Spencer78720742006-12-02 20:21:22 +0000941BEGIN : BEGINTOK { $$ = new std::string("{"); delete $1; }
942 | '{' { $$ = new std::string ("{"); }
Reid Spencere7c3c602006-11-30 06:36:44 +0000943
944FunctionHeader : OptLinkage FunctionHeaderH BEGIN {
945 if (!$1->empty()) {
946 *O << *$1 << " ";
947 }
948 *O << *$2 << " " << *$3 << "\n";
949 delete $1; delete $2; delete $3;
950 $$ = 0;
951};
952
Reid Spencer78720742006-12-02 20:21:22 +0000953END : ENDTOK { $$ = new std::string("}"); delete $1; }
Reid Spencere7c3c602006-11-30 06:36:44 +0000954 | '}' { $$ = new std::string("}"); };
955
956Function : FunctionHeader BasicBlockList END {
957 if ($2)
958 *O << *$2;
959 *O << '\n' << *$3 << "\n";
Reid Spencere77e35e2006-12-01 20:26:20 +0000960 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +0000961};
962
Reid Spencere77e35e2006-12-01 20:26:20 +0000963FnDeclareLinkage
964 : /*default*/ { $$ = new std::string(); }
Reid Spencere7c3c602006-11-30 06:36:44 +0000965 | DLLIMPORT
966 | EXTERN_WEAK
967 ;
968
969FunctionProto
970 : DECLARE FnDeclareLinkage FunctionHeaderH {
Reid Spencere77e35e2006-12-01 20:26:20 +0000971 if (!$2->empty())
972 *$1 += " " + *$2;
973 *$1 += " " + *$3;
974 delete $2;
975 delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +0000976 $$ = $1;
977 };
978
979//===----------------------------------------------------------------------===//
980// Rules to match Basic Blocks
981//===----------------------------------------------------------------------===//
982
Reid Spencerd154b572006-12-01 20:36:40 +0000983OptSideEffect : /* empty */ { $$ = new std::string(); }
984 | SIDEEFFECT;
Reid Spencere7c3c602006-11-30 06:36:44 +0000985
Reid Spencere77e35e2006-12-01 20:26:20 +0000986ConstValueRef
Reid Spencerf2d55322006-12-01 21:52:30 +0000987 : ESINT64VAL | EUINT64VAL | FPVAL | TRUETOK | FALSETOK | NULL_TOK | UNDEF
988 | ZEROINITIALIZER
Reid Spencere7c3c602006-11-30 06:36:44 +0000989 | '<' ConstVector '>' {
990 $2->insert(0, "<");
991 *$2 += ">";
992 $$ = $2;
993 }
994 | ConstExpr
995 | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT {
996 if (!$2->empty()) {
997 *$1 += " " + *$2;
998 }
Reid Spencere77e35e2006-12-01 20:26:20 +0000999 *$1 += " " + *$3 + ", " + *$5;
1000 delete $2; delete $3; delete $5;
Reid Spencere7c3c602006-11-30 06:36:44 +00001001 $$ = $1;
1002 };
1003
Reid Spencerf2d55322006-12-01 21:52:30 +00001004SymbolicValueRef : IntVal | Name ;
Reid Spencere7c3c602006-11-30 06:36:44 +00001005
1006// ValueRef - A reference to a definition... either constant or symbolic
Reid Spencerf459d392006-12-02 16:19:52 +00001007ValueRef
1008 : SymbolicValueRef {
1009 $$.val = $1;
1010 $$.constant = false;
1011 $$.type.newTy = 0;
1012 $$.type.oldTy = UnresolvedTy;
1013 }
1014 | ConstValueRef {
1015 $$.val = $1;
1016 $$.constant = true;
1017 $$.type.newTy = 0;
1018 $$.type.oldTy = UnresolvedTy;
1019 }
1020 ;
Reid Spencere7c3c602006-11-30 06:36:44 +00001021
1022// ResolvedVal - a <type> <value> pair. This is used only in cases where the
1023// type immediately preceeds the value reference, and allows complex constant
1024// pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
1025ResolvedVal : Types ValueRef {
Reid Spencerf459d392006-12-02 16:19:52 +00001026 $$ = $2;
Reid Spencere77e35e2006-12-01 20:26:20 +00001027 $$.type = $1;
Reid Spencerf459d392006-12-02 16:19:52 +00001028 $$.val->insert(0, *$1.newTy + " ");
Reid Spencere7c3c602006-11-30 06:36:44 +00001029 };
1030
1031BasicBlockList : BasicBlockList BasicBlock {
Reid Spencerf2d55322006-12-01 21:52:30 +00001032 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +00001033 }
1034 | BasicBlock { // Do not allow functions with 0 basic blocks
Reid Spencerf2d55322006-12-01 21:52:30 +00001035 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +00001036 };
1037
1038
1039// Basic blocks are terminated by branching instructions:
1040// br, br/cc, switch, ret
1041//
Reid Spencer16244f42006-12-01 21:10:07 +00001042BasicBlock : InstructionList BBTerminatorInst {
Reid Spencerf2d55322006-12-01 21:52:30 +00001043 $$ = 0;
Reid Spencere7c3c602006-11-30 06:36:44 +00001044 };
1045
1046InstructionList : InstructionList Inst {
1047 *O << " " << *$2 << "\n";
1048 delete $2;
1049 $$ = 0;
1050 }
1051 | /* empty */ {
1052 $$ = 0;
1053 }
1054 | LABELSTR {
1055 *O << *$1 << "\n";
1056 delete $1;
1057 $$ = 0;
1058 };
1059
Reid Spencer78720742006-12-02 20:21:22 +00001060Unwind : UNWIND | EXCEPT { $$ = $1; *$$ = "unwind"; }
1061
Reid Spencere7c3c602006-11-30 06:36:44 +00001062BBTerminatorInst : RET ResolvedVal { // Return with a result...
Reid Spencere77e35e2006-12-01 20:26:20 +00001063 *O << " " << *$1 << " " << *$2.val << "\n";
1064 delete $1; $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001065 $$ = 0;
1066 }
1067 | RET VOID { // Return with no result...
Reid Spencere77e35e2006-12-01 20:26:20 +00001068 *O << " " << *$1 << " " << *$2.newTy << "\n";
1069 delete $1; $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001070 $$ = 0;
1071 }
1072 | BR LABEL ValueRef { // Unconditional Branch...
Reid Spencerf459d392006-12-02 16:19:52 +00001073 *O << " " << *$1 << " " << *$2.newTy << " " << *$3.val << "\n";
1074 delete $1; $2.destroy(); $3.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001075 $$ = 0;
1076 } // Conditional Branch...
1077 | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {
Reid Spencerf459d392006-12-02 16:19:52 +00001078 *O << " " << *$1 << " " << *$2.newTy << " " << *$3.val << ", "
1079 << *$5.newTy << " " << *$6.val << ", " << *$8.newTy << " "
1080 << *$9.val << "\n";
1081 delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy();
1082 $8.destroy(); $9.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001083 $$ = 0;
1084 }
1085 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
Reid Spencerf459d392006-12-02 16:19:52 +00001086 *O << " " << *$1 << " " << *$2.newTy << " " << *$3.val << ", "
1087 << *$5.newTy << " " << *$6.val << " [" << *$8 << " ]\n";
1088 delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy();
1089 delete $8;
Reid Spencere7c3c602006-11-30 06:36:44 +00001090 $$ = 0;
1091 }
1092 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' {
Reid Spencerf459d392006-12-02 16:19:52 +00001093 *O << " " << *$1 << " " << *$2.newTy << " " << *$3.val << ", "
1094 << *$5.newTy << " " << *$6.val << "[]\n";
1095 delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001096 $$ = 0;
1097 }
Reid Spencer16244f42006-12-01 21:10:07 +00001098 | OptAssign INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')'
Reid Spencer78720742006-12-02 20:21:22 +00001099 TO LABEL ValueRef Unwind LABEL ValueRef {
Reid Spencer16244f42006-12-01 21:10:07 +00001100 *O << " ";
1101 if (!$1->empty())
Reid Spencera50d5962006-12-02 04:11:07 +00001102 *O << *$1 << " = ";
Reid Spencerf459d392006-12-02 16:19:52 +00001103 *O << *$2 << " " << *$3 << " " << *$4.newTy << " " << *$5.val << " (";
Reid Spencerf8483652006-12-02 15:16:01 +00001104 for (unsigned i = 0; i < $7->size(); ++i) {
1105 ValueInfo& VI = (*$7)[i];
1106 *O << *VI.val;
1107 if (i+1 < $7->size())
1108 *O << ", ";
1109 VI.destroy();
1110 }
Reid Spencerf459d392006-12-02 16:19:52 +00001111 *O << ") " << *$9 << " " << *$10.newTy << " " << *$11.val << " "
1112 << *$12 << " " << *$13.newTy << " " << *$14.val << "\n";
1113 delete $1; delete $2; delete $3; $4.destroy(); $5.destroy(); delete $7;
1114 delete $9; $10.destroy(); $11.destroy(); delete $12; $13.destroy();
1115 $14.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001116 $$ = 0;
1117 }
Reid Spencer78720742006-12-02 20:21:22 +00001118 | Unwind {
Reid Spencere7c3c602006-11-30 06:36:44 +00001119 *O << " " << *$1 << "\n";
1120 delete $1;
1121 $$ = 0;
1122 }
1123 | UNREACHABLE {
1124 *O << " " << *$1 << "\n";
1125 delete $1;
1126 $$ = 0;
1127 };
1128
1129JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
Reid Spencerf459d392006-12-02 16:19:52 +00001130 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5.newTy + " " + *$6.val;
1131 $2.destroy(); delete $3; $5.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001132 $$ = $1;
1133 }
1134 | IntType ConstValueRef ',' LABEL ValueRef {
Reid Spencere77e35e2006-12-01 20:26:20 +00001135 $2->insert(0, *$1.newTy + " " );
Reid Spencerf459d392006-12-02 16:19:52 +00001136 *$2 += ", " + *$4.newTy + " " + *$5.val;
1137 $1.destroy(); $4.destroy(); $5.destroy();
Reid Spencere77e35e2006-12-01 20:26:20 +00001138 $$ = $2;
Reid Spencere7c3c602006-11-30 06:36:44 +00001139 };
1140
1141Inst
1142 : OptAssign InstVal {
Reid Spencera50d5962006-12-02 04:11:07 +00001143 if (!$1->empty())
1144 *$1 += " = ";
Reid Spencere7c3c602006-11-30 06:36:44 +00001145 *$1 += *$2;
1146 delete $2;
1147 $$ = $1;
1148 };
1149
1150PHIList
1151 : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes
Reid Spencerf459d392006-12-02 16:19:52 +00001152 $3.val->insert(0, *$1.newTy + "[");
1153 *$3.val += "," + *$5.val + "]";
1154 $1.destroy(); $5.destroy();
1155 $$ = new std::string(*$3.val);
1156 $3.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001157 }
1158 | PHIList ',' '[' ValueRef ',' ValueRef ']' {
Reid Spencerf459d392006-12-02 16:19:52 +00001159 *$1 += ", [" + *$4.val + "," + *$6.val + "]";
1160 $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001161 $$ = $1;
1162 };
1163
1164
1165ValueRefList
Reid Spencerf8483652006-12-02 15:16:01 +00001166 : ResolvedVal {
1167 $$ = new ValueList();
1168 $$->push_back($1);
1169 }
Reid Spencere7c3c602006-11-30 06:36:44 +00001170 | ValueRefList ',' ResolvedVal {
Reid Spencerf8483652006-12-02 15:16:01 +00001171 $1->push_back($3);
Reid Spencere7c3c602006-11-30 06:36:44 +00001172 $$ = $1;
1173 };
1174
1175// ValueRefListE - Just like ValueRefList, except that it may also be empty!
1176ValueRefListE
Reid Spencerf8483652006-12-02 15:16:01 +00001177 : ValueRefList { $$ = $1; }
1178 | /*empty*/ { $$ = new ValueList(); }
Reid Spencere7c3c602006-11-30 06:36:44 +00001179 ;
1180
1181OptTailCall
1182 : TAIL CALL {
1183 *$1 += " " + *$2;
1184 delete $2;
1185 $$ = $1;
1186 }
1187 | CALL
1188 ;
1189
1190InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
Reid Spencer78720742006-12-02 20:21:22 +00001191 const char* op = getDivRemOpcode(*$1, $2);
1192 $$ = new std::string(op);
1193 *$$ += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
1194 delete $1; $2.destroy(); $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001195 }
1196 | LogicalOps Types ValueRef ',' ValueRef {
Reid Spencerf459d392006-12-02 16:19:52 +00001197 *$1 += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
1198 $2.destroy(); $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001199 $$ = $1;
1200 }
1201 | SetCondOps Types ValueRef ',' ValueRef {
Reid Spencer229e9362006-12-02 22:14:11 +00001202#if UPGRADE_SETCOND_OPS
1203 *$1 = getCompareOp(*$1, $2);
1204#endif
Reid Spencerf459d392006-12-02 16:19:52 +00001205 *$1 += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
1206 $2.destroy(); $3.destroy(); $5.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001207 $$ = $1;
1208 }
Reid Spencer57f28f92006-12-03 07:10:26 +00001209 | ICMP IPredicates Types ValueRef ',' ValueRef ')' {
1210 *$1 += " " + *$2 + " " + *$4.val + "," + *$6.val + ")";
1211 delete $2; $4.destroy(); $6.destroy();
1212 $$ = $1;
1213 }
1214 | FCMP FPredicates Types ValueRef ',' ValueRef ')' {
Reid Spencer229e9362006-12-02 22:14:11 +00001215 *$1 += " " + *$2 + " " + *$4.val + "," + *$6.val + ")";
1216 delete $2; $4.destroy(); $6.destroy();
1217 $$ = $1;
1218 }
Reid Spencere7c3c602006-11-30 06:36:44 +00001219 | NOT ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001220 *$1 += " " + *$2.val;
1221 $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001222 $$ = $1;
1223 }
1224 | ShiftOps ResolvedVal ',' ResolvedVal {
Reid Spencerf7bde222006-12-01 22:26:37 +00001225 const char* shiftop = $1->c_str();
1226 if (*$1 == "shr")
1227 shiftop = ($2.type.isUnsigned()) ? "lshr" : "ashr";
1228 $$ = new std::string(shiftop);
1229 *$$ += " " + *$2.val + ", " + *$4.val;
1230 delete $1; $2.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001231 }
Reid Spencerfcb5df82006-12-01 22:34:43 +00001232 | CastOps ResolvedVal TO Types {
Reid Spencer280d8012006-12-01 23:40:53 +00001233 std::string source = *$2.val;
Reid Spencera50d5962006-12-02 04:11:07 +00001234 TypeInfo SrcTy = $2.type;
1235 TypeInfo DstTy = $4;
1236 ResolveType(DstTy);
1237 $$ = new std::string();
Reid Spencer280d8012006-12-01 23:40:53 +00001238 if (*$1 == "cast") {
Reid Spencera50d5962006-12-02 04:11:07 +00001239 *$$ += getCastUpgrade(source, SrcTy, DstTy, false);
1240 } else {
1241 *$$ += *$1 + " " + source + " to " + *DstTy.newTy;
Reid Spencer280d8012006-12-01 23:40:53 +00001242 }
Reid Spencere77e35e2006-12-01 20:26:20 +00001243 delete $1; $2.destroy();
1244 delete $3; $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001245 }
1246 | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001247 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1248 $2.destroy(); $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001249 $$ = $1;
1250 }
1251 | VAARG ResolvedVal ',' Types {
Reid Spencere77e35e2006-12-01 20:26:20 +00001252 *$1 += " " + *$2.val + ", " + *$4.newTy;
1253 $2.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001254 $$ = $1;
1255 }
1256 | EXTRACTELEMENT ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001257 *$1 += " " + *$2.val + ", " + *$4.val;
1258 $2.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001259 $$ = $1;
1260 }
1261 | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001262 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1263 $2.destroy(); $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001264 $$ = $1;
1265 }
1266 | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001267 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1268 $2.destroy(); $4.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001269 $$ = $1;
1270 }
1271 | PHI_TOK PHIList {
1272 *$1 += " " + *$2;
1273 delete $2;
1274 $$ = $1;
1275 }
1276 | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' {
1277 if (!$2->empty())
1278 *$1 += " " + *$2;
1279 if (!$1->empty())
1280 *$1 += " ";
Reid Spencerf459d392006-12-02 16:19:52 +00001281 *$1 += *$3.newTy + " " + *$4.val + "(";
Reid Spencerf8483652006-12-02 15:16:01 +00001282 for (unsigned i = 0; i < $6->size(); ++i) {
1283 ValueInfo& VI = (*$6)[i];
1284 *$1 += *VI.val;
1285 if (i+1 < $6->size())
1286 *$1 += ", ";
1287 VI.destroy();
1288 }
1289 *$1 += ")";
Reid Spencerf459d392006-12-02 16:19:52 +00001290 delete $2; $3.destroy(); $4.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001291 $$ = $1;
1292 }
1293 | MemoryInst ;
1294
1295
1296// IndexList - List of indices for GEP based instructions...
1297IndexList
Reid Spencerf8483652006-12-02 15:16:01 +00001298 : ',' ValueRefList { $$ = $2; }
1299 | /* empty */ { $$ = new ValueList(); }
Reid Spencere7c3c602006-11-30 06:36:44 +00001300 ;
1301
1302OptVolatile
1303 : VOLATILE
1304 | /* empty */ { $$ = new std::string(); }
1305 ;
1306
1307MemoryInst : MALLOC Types OptCAlign {
Reid Spencere77e35e2006-12-01 20:26:20 +00001308 *$1 += " " + *$2.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +00001309 if (!$3->empty())
1310 *$1 += " " + *$3;
Reid Spencere77e35e2006-12-01 20:26:20 +00001311 $2.destroy(); delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001312 $$ = $1;
1313 }
1314 | MALLOC Types ',' UINT ValueRef OptCAlign {
Reid Spencerf459d392006-12-02 16:19:52 +00001315 *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5.val;
Reid Spencere7c3c602006-11-30 06:36:44 +00001316 if (!$6->empty())
1317 *$1 += " " + *$6;
Reid Spencerf459d392006-12-02 16:19:52 +00001318 $2.destroy(); $4.destroy(); $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001319 $$ = $1;
1320 }
1321 | ALLOCA Types OptCAlign {
Reid Spencere77e35e2006-12-01 20:26:20 +00001322 *$1 += " " + *$2.newTy;
Reid Spencere7c3c602006-11-30 06:36:44 +00001323 if (!$3->empty())
1324 *$1 += " " + *$3;
Reid Spencere77e35e2006-12-01 20:26:20 +00001325 $2.destroy(); delete $3;
Reid Spencere7c3c602006-11-30 06:36:44 +00001326 $$ = $1;
1327 }
1328 | ALLOCA Types ',' UINT ValueRef OptCAlign {
Reid Spencerf459d392006-12-02 16:19:52 +00001329 *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5.val;
Reid Spencere7c3c602006-11-30 06:36:44 +00001330 if (!$6->empty())
1331 *$1 += " " + *$6;
Reid Spencerf459d392006-12-02 16:19:52 +00001332 $2.destroy(); $4.destroy(); $5.destroy(); delete $6;
Reid Spencere7c3c602006-11-30 06:36:44 +00001333 $$ = $1;
1334 }
1335 | FREE ResolvedVal {
Reid Spencere77e35e2006-12-01 20:26:20 +00001336 *$1 += " " + *$2.val;
1337 $2.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001338 $$ = $1;
1339 }
1340 | OptVolatile LOAD Types ValueRef {
1341 if (!$1->empty())
1342 *$1 += " ";
Reid Spencerf459d392006-12-02 16:19:52 +00001343 *$1 += *$2 + " " + *$3.newTy + " " + *$4.val;
1344 delete $2; $3.destroy(); $4.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001345 $$ = $1;
1346 }
1347 | OptVolatile STORE ResolvedVal ',' Types ValueRef {
1348 if (!$1->empty())
1349 *$1 += " ";
Reid Spencerf459d392006-12-02 16:19:52 +00001350 *$1 += *$2 + " " + *$3.val + ", " + *$5.newTy + " " + *$6.val;
1351 delete $2; $3.destroy(); $5.destroy(); $6.destroy();
Reid Spencere7c3c602006-11-30 06:36:44 +00001352 $$ = $1;
1353 }
1354 | GETELEMENTPTR Types ValueRef IndexList {
Reid Spencerf459d392006-12-02 16:19:52 +00001355 // Upgrade the indices
1356 for (unsigned i = 0; i < $4->size(); ++i) {
1357 ValueInfo& VI = (*$4)[i];
1358 if (VI.type.isUnsigned() && !VI.isConstant() &&
1359 VI.type.getBitWidth() < 64) {
1360 std::string* old = VI.val;
1361 *O << " %gep_upgrade" << unique << " = zext " << *old
1362 << " to ulong\n";
1363 VI.val = new std::string("ulong %gep_upgrade" + llvm::utostr(unique++));
1364 VI.type.oldTy = ULongTy;
1365 delete old;
1366 }
1367 }
1368 *$1 += " " + *$2.newTy + " " + *$3.val;
Reid Spencerf8483652006-12-02 15:16:01 +00001369 for (unsigned i = 0; i < $4->size(); ++i) {
1370 ValueInfo& VI = (*$4)[i];
1371 *$1 += ", " + *VI.val;
1372 VI.destroy();
1373 }
Reid Spencerf459d392006-12-02 16:19:52 +00001374 $2.destroy(); $3.destroy(); delete $4;
Reid Spencere7c3c602006-11-30 06:36:44 +00001375 $$ = $1;
1376 };
1377
1378%%
1379
1380int yyerror(const char *ErrorMsg) {
1381 std::string where
1382 = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
1383 + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
1384 std::string errMsg = std::string(ErrorMsg) + "\n" + where + " while reading ";
1385 if (yychar == YYEMPTY || yychar == 0)
1386 errMsg += "end-of-file.";
1387 else
1388 errMsg += "token: '" + std::string(Upgradetext, Upgradeleng) + "'";
1389 std::cerr << errMsg << '\n';
1390 exit(1);
1391}