1 //===-- UpgradeParser.y - Upgrade parser for llvm assmbly -------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
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.
8 //===----------------------------------------------------------------------===//
10 // This file implements the bison parser for LLVM 1.9 assembly language.
12 //===----------------------------------------------------------------------===//
15 #include "ParserInternals.h"
16 #include <llvm/ADT/StringExtras.h>
22 #define YYERROR_VERBOSE 1
23 #define YYINCLUDED_STDLIB_H
26 int yylex(); // declaration" of xxx warnings.
30 static std::string CurFilename;
31 static std::ostream *O = 0;
32 std::istream* LexInput = 0;
33 unsigned SizeOfPointer = 32;
34 static uint64_t unique = 1;
36 typedef std::vector<TypeInfo> TypeVector;
37 static TypeVector EnumeratedTypes;
38 typedef std::map<std::string,TypeInfo> TypeMap;
39 static TypeMap NamedTypes;
41 void destroy(ValueList* VL) {
42 while (!VL->empty()) {
43 ValueInfo& VI = VL->back();
50 void UpgradeAssembly(const std::string &infile, std::istream& in,
51 std::ostream &out, bool debug)
60 std::cerr << "Parse failed.\n";
65 static void ResolveType(TypeInfo& Ty) {
66 if (Ty.oldTy == UnresolvedTy) {
67 TypeMap::iterator I = NamedTypes.find(*Ty.newTy);
68 if (I != NamedTypes.end())
69 Ty.oldTy = I->second.oldTy;
71 std::string msg("Can't resolve type: ");
75 } else if (Ty.oldTy == NumericTy) {
76 unsigned ref = atoi(&((Ty.newTy->c_str())[1])); // Skip the '\\'
77 if (ref < EnumeratedTypes.size()) {
78 Ty.oldTy = EnumeratedTypes[ref].oldTy;
80 std::string msg("Can't resolve type: ");
85 // otherwise its already resolved.
88 static const char* getCastOpcode(
89 std::string& Source, const TypeInfo& SrcTy, const TypeInfo& DstTy)
91 unsigned SrcBits = SrcTy.getBitWidth();
92 unsigned DstBits = DstTy.getBitWidth();
93 const char* opcode = "bitcast";
94 // Run through the possibilities ...
95 if (DstTy.isIntegral()) { // Casting to integral
96 if (SrcTy.isIntegral()) { // Casting from integral
97 if (DstBits < SrcBits)
99 else if (DstBits > SrcBits) { // its an extension
100 if (SrcTy.isSigned())
101 opcode ="sext"; // signed -> SEXT
103 opcode = "zext"; // unsigned -> ZEXT
105 opcode = "bitcast"; // Same size, No-op cast
107 } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt
108 if (DstTy.isSigned())
109 opcode = "fptosi"; // FP -> sint
111 opcode = "fptoui"; // FP -> uint
112 } else if (SrcTy.isPacked()) {
113 assert(DstBits == SrcTy.getBitWidth() &&
114 "Casting packed to integer of different width");
115 opcode = "bitcast"; // same size, no-op cast
117 assert(SrcTy.isPointer() &&
118 "Casting from a value that is not first-class type");
119 opcode = "ptrtoint"; // ptr -> int
121 } else if (DstTy.isFloatingPoint()) { // Casting to floating pt
122 if (SrcTy.isIntegral()) { // Casting from integral
123 if (SrcTy.isSigned())
124 opcode = "sitofp"; // sint -> FP
126 opcode = "uitofp"; // uint -> FP
127 } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt
128 if (DstBits < SrcBits) {
129 opcode = "fptrunc"; // FP -> smaller FP
130 } else if (DstBits > SrcBits) {
131 opcode = "fpext"; // FP -> larger FP
133 opcode ="bitcast"; // same size, no-op cast
135 } else if (SrcTy.isPacked()) {
136 assert(DstBits == SrcTy.getBitWidth() &&
137 "Casting packed to floating point of different width");
138 opcode = "bitcast"; // same size, no-op cast
140 assert(0 && "Casting pointer or non-first class to float");
142 } else if (DstTy.isPacked()) {
143 if (SrcTy.isPacked()) {
144 assert(DstTy.getBitWidth() == SrcTy.getBitWidth() &&
145 "Casting packed to packed of different widths");
146 opcode = "bitcast"; // packed -> packed
147 } else if (DstTy.getBitWidth() == SrcBits) {
148 opcode = "bitcast"; // float/int -> packed
150 assert(!"Illegal cast to packed (wrong type or size)");
152 } else if (DstTy.isPointer()) {
153 if (SrcTy.isPointer()) {
154 opcode = "bitcast"; // ptr -> ptr
155 } else if (SrcTy.isIntegral()) {
156 opcode = "inttoptr"; // int -> ptr
158 assert(!"Casting invalid type to pointer");
161 assert(!"Casting to type that is not first-class");
166 static std::string getCastUpgrade(
167 const std::string& Src, TypeInfo& SrcTy, TypeInfo& DstTy, bool isConst)
170 std::string Source = Src;
171 if (SrcTy.isFloatingPoint() && DstTy.isPointer()) {
172 // fp -> ptr cast is no longer supported but we must upgrade this
173 // by doing a double cast: fp -> int -> ptr
175 Source = "ulong fptoui(" + Source + " to ulong)";
177 *O << " %cast_upgrade" << unique << " = fptoui " << Source
179 Source = "ulong %cast_upgrade" + llvm::utostr(unique);
181 // Update the SrcTy for the getCastOpcode call below
183 SrcTy.newTy = new std::string("ulong");
184 SrcTy.oldTy = ULongTy;
185 } else if (DstTy.oldTy == BoolTy) {
186 // cast ptr %x to bool was previously defined as setne ptr %x, null
187 // The ptrtoint semantic is to truncate, not compare so we must retain
188 // the original intent by replace the cast with a setne
189 const char* comparator = SrcTy.isPointer() ? ", null" :
190 (SrcTy.isFloatingPoint() ? ", 0.0" : ", 0");
192 Result = "setne (" + Source + comparator + ")";
194 Result = "setne " + Source + comparator;
195 return Result; // skip cast processing below
199 std::string Opcode(getCastOpcode(Source, SrcTy, DstTy));
201 Result += Opcode + "( " + Source + " to " + *DstTy.newTy + ")";
203 Result += Opcode + " " + Source + " to " + *DstTy.newTy;
209 %file-prefix="UpgradeParser"
219 %token <Type> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
220 %token <Type> FLOAT DOUBLE LABEL
221 %token <String> OPAQUE ESINT64VAL EUINT64VAL SINTVAL UINTVAL FPVAL
222 %token <String> NULL_TOK UNDEF ZEROINITIALIZER TRUETOK FALSETOK
223 %token <String> TYPE VAR_ID LABELSTR STRINGCONSTANT
224 %token <String> IMPLEMENTATION BEGINTOK ENDTOK
225 %token <String> DECLARE GLOBAL CONSTANT SECTION VOLATILE
226 %token <String> TO DOTDOTDOT CONST INTERNAL LINKONCE WEAK
227 %token <String> DLLIMPORT DLLEXPORT EXTERN_WEAK APPENDING
228 %token <String> NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG
229 %token <String> ALIGN
230 %token <String> DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
231 %token <String> CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK
232 %token <String> X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
233 %token <String> DATALAYOUT
234 %token <String> RET BR SWITCH INVOKE UNWIND UNREACHABLE
235 %token <String> ADD SUB MUL UDIV SDIV FDIV UREM SREM FREM AND OR XOR
236 %token <String> SETLE SETGE SETLT SETGT SETEQ SETNE // Binary Comparators
237 %token <String> MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR
238 %token <String> PHI_TOK SELECT SHL SHR ASHR LSHR VAARG
239 %token <String> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
240 %token <String> CAST TRUNC ZEXT SEXT FPTRUNC FPEXT FPTOUI FPTOSI UITOFP SITOFP
241 %token <String> PTRTOINT INTTOPTR BITCAST
243 %type <String> OptAssign OptLinkage OptCallingConv OptAlign OptCAlign
244 %type <String> SectionString OptSection GlobalVarAttributes GlobalVarAttribute
245 %type <String> ArgTypeListI ConstExpr DefinitionList
246 %type <String> ConstPool TargetDefinition LibrariesDefinition LibList OptName
247 %type <String> ArgVal ArgListH ArgList FunctionHeaderH BEGIN FunctionHeader END
248 %type <String> Function FunctionProto BasicBlock TypeListI
249 %type <String> InstructionList BBTerminatorInst JumpTable Inst PHIList
250 %type <String> OptTailCall InstVal OptVolatile
251 %type <String> MemoryInst SymbolicValueRef OptSideEffect GlobalType
252 %type <String> FnDeclareLinkage BasicBlockList BigOrLittle AsmBlock
253 %type <String> Name ConstValueRef ConstVector
254 %type <String> ShiftOps SetCondOps LogicalOps ArithmeticOps CastOps
256 %type <ValList> ValueRefList ValueRefListE IndexList
258 %type <Type> IntType SIntType UIntType FPType TypesV Types
259 %type <Type> PrimType UpRTypesV UpRTypes
261 %type <String> IntVal EInt64Val
262 %type <Const> ConstVal
264 %type <Value> ValueRef ResolvedVal
270 // Handle constant integer size restriction and conversion...
271 IntVal : SINTVAL | UINTVAL ;
272 EInt64Val : ESINT64VAL | EUINT64VAL;
274 // Operations that are notably excluded from this list include:
275 // RET, BR, & SWITCH because they end basic blocks and are treated specially.
276 ArithmeticOps: ADD | SUB | MUL | UDIV | SDIV | FDIV | UREM | SREM | FREM;
277 LogicalOps : AND | OR | XOR;
278 SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE;
279 ShiftOps : SHL | SHR | ASHR | LSHR;
280 CastOps : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | FPTOUI | FPTOSI |
281 UITOFP | SITOFP | PTRTOINT | INTTOPTR | BITCAST | CAST
284 // These are some types that allow classification if we only want a particular
285 // thing... for example, only a signed, unsigned, or integral type.
286 SIntType : LONG | INT | SHORT | SBYTE;
287 UIntType : ULONG | UINT | USHORT | UBYTE;
288 IntType : SIntType | UIntType;
289 FPType : FLOAT | DOUBLE;
291 // OptAssign - Value producing statements have an optional assignment component
292 OptAssign : Name '=' {
296 $$ = new std::string("");
300 : INTERNAL | LINKONCE | WEAK | APPENDING | DLLIMPORT | DLLEXPORT
302 | /*empty*/ { $$ = new std::string(""); } ;
305 : CCC_TOK | CSRETCC_TOK | FASTCC_TOK | COLDCC_TOK | X86_STDCALLCC_TOK
307 | CC_TOK EUINT64VAL {
312 | /*empty*/ { $$ = new std::string(""); } ;
314 // OptAlign/OptCAlign - An optional alignment, and an optional alignment with
315 // a comma before it.
317 : /*empty*/ { $$ = new std::string(); }
318 | ALIGN EUINT64VAL { *$1 += " " + *$2; delete $2; $$ = $1; };
321 : /*empty*/ { $$ = new std::string(); }
322 | ',' ALIGN EUINT64VAL {
330 : SECTION STRINGCONSTANT {
336 OptSection : /*empty*/ { $$ = new std::string(); }
340 : /* empty */ { $$ = new std::string(); }
341 | ',' GlobalVarAttribute GlobalVarAttributes {
357 //===----------------------------------------------------------------------===//
358 // Types includes all predefined types... except void, because it can only be
359 // used in specific contexts (function returning void for example). To have
360 // access to it, a user must explicitly use TypesV.
363 // TypesV includes all of 'Types', but it also includes the void type.
364 TypesV : Types | VOID ;
365 UpRTypesV : UpRTypes | VOID ;
368 // Derived types are added later...
370 PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ;
371 PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL;
379 $$.oldTy = UnresolvedTy;
384 // Include derived types in the Types production.
386 UpRTypes : '\\' EUINT64VAL { // Type UpReference
389 $$.oldTy = NumericTy;
391 | UpRTypesV '(' ArgTypeListI ')' { // Function derived type?
392 *$1.newTy += "( " + *$3 + " )";
395 $$.oldTy = FunctionTy;
397 | '[' EUINT64VAL 'x' UpRTypes ']' { // Sized array type?
399 *$2 += " x " + *$4.newTy + " ]";
404 | '<' EUINT64VAL 'x' UpRTypes '>' { // Packed array type?
406 *$2 += " x " + *$4.newTy + " >";
411 | '{' TypeListI '}' { // Structure type?
417 | '{' '}' { // Empty structure type?
418 $$.newTy = new std::string("{}");
421 | UpRTypes '*' { // Pointer type?
423 $1.oldTy = PointerTy;
427 // TypeList - Used for struct declarations and as a basis for function type
428 // declaration type lists
434 | TypeListI ',' UpRTypes {
435 *$1 += ", " + *$3.newTy;
440 // ArgTypeList - List of types for a function type declaration...
443 | TypeListI ',' DOTDOTDOT {
452 $$ = new std::string();
455 // ConstVal - The various declarations that go into the constant pool. This
456 // production is used ONLY to represent constants that show up AFTER a 'const',
457 // 'constant' or 'global' token at global scope. Constants that can be inlined
458 // into other expressions (such as integers and constexprs) are handled by the
459 // ResolvedVal, ValueRef and ConstValueRef productions.
461 ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
463 $$.cnst = new std::string(*$1.newTy);
464 *$$.cnst += " [ " + *$3 + " ]";
469 $$.cnst = new std::string(*$1.newTy);
472 | Types 'c' STRINGCONSTANT {
474 $$.cnst = new std::string(*$1.newTy);
475 *$$.cnst += " c" + *$3;
478 | Types '<' ConstVector '>' { // Nonempty unsized arr
480 $$.cnst = new std::string(*$1.newTy);
481 *$$.cnst += " < " + *$3 + " >";
484 | Types '{' ConstVector '}' {
486 $$.cnst = new std::string(*$1.newTy);
487 *$$.cnst += " { " + *$3 + " }";
492 $$.cnst = new std::string(*$1.newTy);
497 $$.cnst = new std::string(*$1.newTy);
498 *$$.cnst += " " + *$2;
503 $$.cnst = new std::string(*$1.newTy);
504 *$$.cnst += " " + *$2;
507 | Types SymbolicValueRef {
509 $$.cnst = new std::string(*$1.newTy);
510 *$$.cnst += " " + *$2;
515 $$.cnst = new std::string(*$1.newTy);
516 *$$.cnst += " " + *$2;
519 | Types ZEROINITIALIZER {
521 $$.cnst = new std::string(*$1.newTy);
522 *$$.cnst += " " + *$2;
525 | SIntType EInt64Val { // integral constants
527 $$.cnst = new std::string(*$1.newTy);
528 *$$.cnst += " " + *$2;
531 | UIntType EUINT64VAL { // integral constants
533 $$.cnst = new std::string(*$1.newTy);
534 *$$.cnst += " " + *$2;
537 | BOOL TRUETOK { // Boolean constants
539 $$.cnst = new std::string(*$1.newTy);
540 *$$.cnst += " " + *$2;
543 | BOOL FALSETOK { // Boolean constants
545 $$.cnst = new std::string(*$1.newTy);
546 *$$.cnst += " " + *$2;
549 | FPType FPVAL { // Float & Double constants
551 $$.cnst = new std::string(*$1.newTy);
552 *$$.cnst += " " + *$2;
557 ConstExpr: CastOps '(' ConstVal TO Types ')' {
558 std::string source = *$3.cnst;
562 // Call getCastUpgrade to upgrade the old cast
563 $$ = new std::string(getCastUpgrade(source, $3.type, $5, true));
565 // Nothing to upgrade, just create the cast constant expr
566 $$ = new std::string(*$1);
567 *$$ += "( " + source + " to " + *$5.newTy + ")";
569 delete $1; $3.destroy(); delete $4; $5.destroy();
571 | GETELEMENTPTR '(' ConstVal IndexList ')' {
572 *$1 += "(" + *$3.cnst;
573 for (unsigned i = 0; i < $4->size(); ++i) {
574 ValueInfo& VI = (*$4)[i];
575 *$1 += ", " + *VI.val;
583 | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
584 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
585 $3.destroy(); $5.destroy(); $7.destroy();
588 | ArithmeticOps '(' ConstVal ',' ConstVal ')' {
589 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
590 $3.destroy(); $5.destroy();
593 | LogicalOps '(' ConstVal ',' ConstVal ')' {
594 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
595 $3.destroy(); $5.destroy();
598 | SetCondOps '(' ConstVal ',' ConstVal ')' {
599 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
600 $3.destroy(); $5.destroy();
603 | ShiftOps '(' ConstVal ',' ConstVal ')' {
604 const char* shiftop = $1->c_str();
606 shiftop = ($3.type.isUnsigned()) ? "lshr" : "ashr";
607 $$ = new std::string(shiftop);
608 *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
609 delete $1; $3.destroy(); $5.destroy();
611 | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' {
612 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
613 $3.destroy(); $5.destroy();
616 | INSERTELEMENT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
617 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
618 $3.destroy(); $5.destroy(); $7.destroy();
621 | SHUFFLEVECTOR '(' ConstVal ',' ConstVal ',' ConstVal ')' {
622 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
623 $3.destroy(); $5.destroy(); $7.destroy();
628 // ConstVector - A list of comma separated constants.
631 : ConstVector ',' ConstVal {
632 *$1 += ", " + *$3.cnst;
636 | ConstVal { $$ = new std::string(*$1.cnst); $1.destroy(); }
640 // GlobalType - Match either GLOBAL or CONSTANT for global declarations...
641 GlobalType : GLOBAL | CONSTANT ;
644 //===----------------------------------------------------------------------===//
645 // Rules to match Modules
646 //===----------------------------------------------------------------------===//
648 // Module rule: Capture the result of parsing the whole file into a result
651 Module : DefinitionList {
654 // DefinitionList - Top level definitions
656 DefinitionList : DefinitionList Function {
659 | DefinitionList FunctionProto {
664 | DefinitionList MODULE ASM_TOK AsmBlock {
665 *O << "module asm " << " " << *$4 << "\n";
668 | DefinitionList IMPLEMENTATION {
669 *O << "implementation\n";
672 | ConstPool { $$ = 0; }
674 // ConstPool - Constants with optional names assigned to them.
675 ConstPool : ConstPool OptAssign TYPE TypesV {
676 EnumeratedTypes.push_back($4);
678 NamedTypes[*$2].newTy = new std::string(*$4.newTy);
679 NamedTypes[*$2].oldTy = $4.oldTy;
682 *O << "type " << *$4.newTy << "\n";
683 delete $2; delete $3; $4.destroy();
686 | ConstPool FunctionProto { // Function prototypes can be in const pool
691 | ConstPool MODULE ASM_TOK AsmBlock { // Asm blocks can be in the const pool
692 *O << *$2 << " " << *$3 << " " << *$4 << "\n";
693 delete $2; delete $3; delete $4;
696 | ConstPool OptAssign OptLinkage GlobalType ConstVal GlobalVarAttributes {
699 *O << *$3 << " " << *$4 << " " << *$5.cnst << " " << *$6 << "\n";
700 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
703 | ConstPool OptAssign EXTERNAL GlobalType Types GlobalVarAttributes {
706 *O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
707 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
710 | ConstPool OptAssign DLLIMPORT GlobalType Types GlobalVarAttributes {
713 *O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
714 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
717 | ConstPool OptAssign EXTERN_WEAK GlobalType Types GlobalVarAttributes {
720 *O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
721 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
724 | ConstPool TARGET TargetDefinition {
725 *O << *$2 << " " << *$3 << "\n";
726 delete $2; delete $3;
729 | ConstPool DEPLIBS '=' LibrariesDefinition {
730 *O << *$2 << " = " << *$4 << "\n";
731 delete $2; delete $4;
734 | /* empty: end of list */ {
739 AsmBlock : STRINGCONSTANT ;
741 BigOrLittle : BIG | LITTLE
744 : ENDIAN '=' BigOrLittle {
749 | POINTERSIZE '=' EUINT64VAL {
756 | TRIPLE '=' STRINGCONSTANT {
761 | DATALAYOUT '=' STRINGCONSTANT {
775 : LibList ',' STRINGCONSTANT {
781 | /* empty: end of list */ {
782 $$ = new std::string();
785 //===----------------------------------------------------------------------===//
786 // Rules to match Function Headers
787 //===----------------------------------------------------------------------===//
789 Name : VAR_ID | STRINGCONSTANT;
790 OptName : Name | /*empty*/ { $$ = new std::string(); };
792 ArgVal : Types OptName {
799 ArgListH : ArgListH ',' ArgVal {
810 | ArgListH ',' DOTDOTDOT {
818 | /* empty */ { $$ = new std::string(); };
820 FunctionHeaderH : OptCallingConv TypesV Name '(' ArgList ')'
821 OptSection OptAlign {
825 *$1 += *$2.newTy + " " + *$3 + "(" + *$5 + ")";
841 $$ = new std::string("begin");
844 $$ = new std::string ("{");
847 FunctionHeader : OptLinkage FunctionHeaderH BEGIN {
851 *O << *$2 << " " << *$3 << "\n";
852 delete $1; delete $2; delete $3;
856 END : ENDTOK { $$ = new std::string("end"); }
857 | '}' { $$ = new std::string("}"); };
859 Function : FunctionHeader BasicBlockList END {
862 *O << '\n' << *$3 << "\n";
867 : /*default*/ { $$ = new std::string(); }
873 : DECLARE FnDeclareLinkage FunctionHeaderH {
882 //===----------------------------------------------------------------------===//
883 // Rules to match Basic Blocks
884 //===----------------------------------------------------------------------===//
886 OptSideEffect : /* empty */ { $$ = new std::string(); }
890 : ESINT64VAL | EUINT64VAL | FPVAL | TRUETOK | FALSETOK | NULL_TOK | UNDEF
892 | '<' ConstVector '>' {
898 | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT {
902 *$1 += " " + *$3 + ", " + *$5;
903 delete $2; delete $3; delete $5;
907 SymbolicValueRef : IntVal | Name ;
909 // ValueRef - A reference to a definition... either constant or symbolic
915 $$.type.oldTy = UnresolvedTy;
921 $$.type.oldTy = UnresolvedTy;
925 // ResolvedVal - a <type> <value> pair. This is used only in cases where the
926 // type immediately preceeds the value reference, and allows complex constant
927 // pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
928 ResolvedVal : Types ValueRef {
931 $$.val->insert(0, *$1.newTy + " ");
934 BasicBlockList : BasicBlockList BasicBlock {
937 | BasicBlock { // Do not allow functions with 0 basic blocks
942 // Basic blocks are terminated by branching instructions:
943 // br, br/cc, switch, ret
945 BasicBlock : InstructionList BBTerminatorInst {
949 InstructionList : InstructionList Inst {
950 *O << " " << *$2 << "\n";
963 BBTerminatorInst : RET ResolvedVal { // Return with a result...
964 *O << " " << *$1 << " " << *$2.val << "\n";
965 delete $1; $2.destroy();
968 | RET VOID { // Return with no result...
969 *O << " " << *$1 << " " << *$2.newTy << "\n";
970 delete $1; $2.destroy();
973 | BR LABEL ValueRef { // Unconditional Branch...
974 *O << " " << *$1 << " " << *$2.newTy << " " << *$3.val << "\n";
975 delete $1; $2.destroy(); $3.destroy();
977 } // Conditional Branch...
978 | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {
979 *O << " " << *$1 << " " << *$2.newTy << " " << *$3.val << ", "
980 << *$5.newTy << " " << *$6.val << ", " << *$8.newTy << " "
982 delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy();
983 $8.destroy(); $9.destroy();
986 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
987 *O << " " << *$1 << " " << *$2.newTy << " " << *$3.val << ", "
988 << *$5.newTy << " " << *$6.val << " [" << *$8 << " ]\n";
989 delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy();
993 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' {
994 *O << " " << *$1 << " " << *$2.newTy << " " << *$3.val << ", "
995 << *$5.newTy << " " << *$6.val << "[]\n";
996 delete $1; $2.destroy(); $3.destroy(); $5.destroy(); $6.destroy();
999 | OptAssign INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')'
1000 TO LABEL ValueRef UNWIND LABEL ValueRef {
1004 *O << *$2 << " " << *$3 << " " << *$4.newTy << " " << *$5.val << " (";
1005 for (unsigned i = 0; i < $7->size(); ++i) {
1006 ValueInfo& VI = (*$7)[i];
1008 if (i+1 < $7->size())
1012 *O << ") " << *$9 << " " << *$10.newTy << " " << *$11.val << " "
1013 << *$12 << " " << *$13.newTy << " " << *$14.val << "\n";
1014 delete $1; delete $2; delete $3; $4.destroy(); $5.destroy(); delete $7;
1015 delete $9; $10.destroy(); $11.destroy(); delete $12; $13.destroy();
1020 *O << " " << *$1 << "\n";
1025 *O << " " << *$1 << "\n";
1030 JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
1031 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5.newTy + " " + *$6.val;
1032 $2.destroy(); delete $3; $5.destroy(); $6.destroy();
1035 | IntType ConstValueRef ',' LABEL ValueRef {
1036 $2->insert(0, *$1.newTy + " " );
1037 *$2 += ", " + *$4.newTy + " " + *$5.val;
1038 $1.destroy(); $4.destroy(); $5.destroy();
1043 : OptAssign InstVal {
1052 : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes
1053 $3.val->insert(0, *$1.newTy + "[");
1054 *$3.val += "," + *$5.val + "]";
1055 $1.destroy(); $5.destroy();
1056 $$ = new std::string(*$3.val);
1059 | PHIList ',' '[' ValueRef ',' ValueRef ']' {
1060 *$1 += ", [" + *$4.val + "," + *$6.val + "]";
1061 $4.destroy(); $6.destroy();
1068 $$ = new ValueList();
1071 | ValueRefList ',' ResolvedVal {
1076 // ValueRefListE - Just like ValueRefList, except that it may also be empty!
1078 : ValueRefList { $$ = $1; }
1079 | /*empty*/ { $$ = new ValueList(); }
1091 InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
1092 *$1 += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
1093 $2.destroy(); $3.destroy(); $5.destroy();
1096 | LogicalOps Types ValueRef ',' ValueRef {
1097 *$1 += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
1098 $2.destroy(); $3.destroy(); $5.destroy();
1101 | SetCondOps Types ValueRef ',' ValueRef {
1102 *$1 += " " + *$2.newTy + " " + *$3.val + ", " + *$5.val;
1103 $2.destroy(); $3.destroy(); $5.destroy();
1107 *$1 += " " + *$2.val;
1111 | ShiftOps ResolvedVal ',' ResolvedVal {
1112 const char* shiftop = $1->c_str();
1114 shiftop = ($2.type.isUnsigned()) ? "lshr" : "ashr";
1115 $$ = new std::string(shiftop);
1116 *$$ += " " + *$2.val + ", " + *$4.val;
1117 delete $1; $2.destroy(); $4.destroy();
1119 | CastOps ResolvedVal TO Types {
1120 std::string source = *$2.val;
1121 TypeInfo SrcTy = $2.type;
1122 TypeInfo DstTy = $4;
1124 $$ = new std::string();
1125 if (*$1 == "cast") {
1126 *$$ += getCastUpgrade(source, SrcTy, DstTy, false);
1128 *$$ += *$1 + " " + source + " to " + *DstTy.newTy;
1130 delete $1; $2.destroy();
1131 delete $3; $4.destroy();
1133 | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
1134 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1135 $2.destroy(); $4.destroy(); $6.destroy();
1138 | VAARG ResolvedVal ',' Types {
1139 *$1 += " " + *$2.val + ", " + *$4.newTy;
1140 $2.destroy(); $4.destroy();
1143 | EXTRACTELEMENT ResolvedVal ',' ResolvedVal {
1144 *$1 += " " + *$2.val + ", " + *$4.val;
1145 $2.destroy(); $4.destroy();
1148 | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
1149 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1150 $2.destroy(); $4.destroy(); $6.destroy();
1153 | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal {
1154 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1155 $2.destroy(); $4.destroy(); $6.destroy();
1163 | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' {
1168 *$1 += *$3.newTy + " " + *$4.val + "(";
1169 for (unsigned i = 0; i < $6->size(); ++i) {
1170 ValueInfo& VI = (*$6)[i];
1172 if (i+1 < $6->size())
1177 delete $2; $3.destroy(); $4.destroy(); delete $6;
1183 // IndexList - List of indices for GEP based instructions...
1185 : ',' ValueRefList { $$ = $2; }
1186 | /* empty */ { $$ = new ValueList(); }
1191 | /* empty */ { $$ = new std::string(); }
1194 MemoryInst : MALLOC Types OptCAlign {
1195 *$1 += " " + *$2.newTy;
1198 $2.destroy(); delete $3;
1201 | MALLOC Types ',' UINT ValueRef OptCAlign {
1202 *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5.val;
1205 $2.destroy(); $4.destroy(); $5.destroy(); delete $6;
1208 | ALLOCA Types OptCAlign {
1209 *$1 += " " + *$2.newTy;
1212 $2.destroy(); delete $3;
1215 | ALLOCA Types ',' UINT ValueRef OptCAlign {
1216 *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5.val;
1219 $2.destroy(); $4.destroy(); $5.destroy(); delete $6;
1222 | FREE ResolvedVal {
1223 *$1 += " " + *$2.val;
1227 | OptVolatile LOAD Types ValueRef {
1230 *$1 += *$2 + " " + *$3.newTy + " " + *$4.val;
1231 delete $2; $3.destroy(); $4.destroy();
1234 | OptVolatile STORE ResolvedVal ',' Types ValueRef {
1237 *$1 += *$2 + " " + *$3.val + ", " + *$5.newTy + " " + *$6.val;
1238 delete $2; $3.destroy(); $5.destroy(); $6.destroy();
1241 | GETELEMENTPTR Types ValueRef IndexList {
1242 // Upgrade the indices
1243 for (unsigned i = 0; i < $4->size(); ++i) {
1244 ValueInfo& VI = (*$4)[i];
1245 if (VI.type.isUnsigned() && !VI.isConstant() &&
1246 VI.type.getBitWidth() < 64) {
1247 std::string* old = VI.val;
1248 *O << " %gep_upgrade" << unique << " = zext " << *old
1250 VI.val = new std::string("ulong %gep_upgrade" + llvm::utostr(unique++));
1251 VI.type.oldTy = ULongTy;
1255 *$1 += " " + *$2.newTy + " " + *$3.val;
1256 for (unsigned i = 0; i < $4->size(); ++i) {
1257 ValueInfo& VI = (*$4)[i];
1258 *$1 += ", " + *VI.val;
1261 $2.destroy(); $3.destroy(); delete $4;
1267 int yyerror(const char *ErrorMsg) {
1269 = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
1270 + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
1271 std::string errMsg = std::string(ErrorMsg) + "\n" + where + " while reading ";
1272 if (yychar == YYEMPTY || yychar == 0)
1273 errMsg += "end-of-file.";
1275 errMsg += "token: '" + std::string(Upgradetext, Upgradeleng) + "'";
1276 std::cerr << errMsg << '\n';