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>
23 #define YYERROR_VERBOSE 1
24 #define YYINCLUDED_STDLIB_H
27 int yylex(); // declaration" of xxx warnings.
31 static std::string CurFilename;
32 static std::ostream *O = 0;
33 std::istream* LexInput = 0;
34 unsigned SizeOfPointer = 32;
36 typedef std::vector<TypeInfo> TypeVector;
37 static TypeVector EnumeratedTypes;
38 typedef std::map<std::string,TypeInfo> TypeMap;
39 static TypeMap NamedTypes;
41 void UpgradeAssembly(const std::string &infile, std::istream& in,
42 std::ostream &out, bool debug)
51 std::cerr << "Parse failed.\n";
56 static void ResolveType(TypeInfo& Ty) {
57 if (Ty.oldTy == UnresolvedTy) {
58 TypeMap::iterator I = NamedTypes.find(*Ty.newTy);
59 if (I != NamedTypes.end())
60 Ty.oldTy = I->second.oldTy;
62 std::string msg("Can't resolve type: ");
66 } else if (Ty.oldTy == NumericTy) {
67 unsigned ref = atoi(&((Ty.newTy->c_str())[1])); // Skip the '\\'
68 if (ref < EnumeratedTypes.size()) {
69 Ty.oldTy = EnumeratedTypes[ref].oldTy;
71 std::string msg("Can't resolve type: ");
76 // otherwise its already resolved.
79 static const char* getCastOpcode(
80 std::string& Source, const TypeInfo& SrcTy, const TypeInfo& DstTy)
82 unsigned SrcBits = SrcTy.getBitWidth();
83 unsigned DstBits = DstTy.getBitWidth();
84 const char* opcode = "bitcast";
85 // Run through the possibilities ...
86 if (DstTy.isIntegral()) { // Casting to integral
87 if (SrcTy.isIntegral()) { // Casting from integral
88 if (DstBits < SrcBits)
90 else if (DstBits > SrcBits) { // its an extension
92 opcode ="sext"; // signed -> SEXT
94 opcode = "zext"; // unsigned -> ZEXT
96 opcode = "bitcast"; // Same size, No-op cast
98 } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt
100 opcode = "fptosi"; // FP -> sint
102 opcode = "fptoui"; // FP -> uint
103 } else if (SrcTy.isPacked()) {
104 assert(DstBits == SrcTy.getBitWidth() &&
105 "Casting packed to integer of different width");
106 opcode = "bitcast"; // same size, no-op cast
108 assert(SrcTy.isPointer() &&
109 "Casting from a value that is not first-class type");
110 opcode = "ptrtoint"; // ptr -> int
112 } else if (DstTy.isFloatingPoint()) { // Casting to floating pt
113 if (SrcTy.isIntegral()) { // Casting from integral
114 if (SrcTy.isSigned())
115 opcode = "sitofp"; // sint -> FP
117 opcode = "uitofp"; // uint -> FP
118 } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt
119 if (DstBits < SrcBits) {
120 opcode = "fptrunc"; // FP -> smaller FP
121 } else if (DstBits > SrcBits) {
122 opcode = "fpext"; // FP -> larger FP
124 opcode ="bitcast"; // same size, no-op cast
126 } else if (SrcTy.isPacked()) {
127 assert(DstBits == SrcTy.getBitWidth() &&
128 "Casting packed to floating point of different width");
129 opcode = "bitcast"; // same size, no-op cast
131 assert(0 && "Casting pointer or non-first class to float");
133 } else if (DstTy.isPacked()) {
134 if (SrcTy.isPacked()) {
135 assert(DstTy.getBitWidth() == SrcTy.getBitWidth() &&
136 "Casting packed to packed of different widths");
137 opcode = "bitcast"; // packed -> packed
138 } else if (DstTy.getBitWidth() == SrcBits) {
139 opcode = "bitcast"; // float/int -> packed
141 assert(!"Illegal cast to packed (wrong type or size)");
143 } else if (DstTy.isPointer()) {
144 if (SrcTy.isPointer()) {
145 opcode = "bitcast"; // ptr -> ptr
146 } else if (SrcTy.isIntegral()) {
147 opcode = "inttoptr"; // int -> ptr
149 assert(!"Casting invalid type to pointer");
152 assert(!"Casting to type that is not first-class");
157 static std::string getCastUpgrade(
158 const std::string& Src, TypeInfo& SrcTy, TypeInfo& DstTy, bool isConst)
161 std::string Source = Src;
162 if (SrcTy.isFloatingPoint() && DstTy.isPointer()) {
163 // fp -> ptr cast is no longer supported but we must upgrade this
164 // by doing a double cast: fp -> int -> ptr
166 Source = "ulong fptoui(" + Source + " to ulong)";
168 *O << " %cast_upgrade = fptoui " + Source + " to ulong\n";
169 Source = "ulong %cast_upgrade";
171 // Update the SrcTy for the getCastOpcode call below
173 SrcTy.newTy = new std::string("ulong");
174 SrcTy.oldTy = ULongTy;
175 } else if (DstTy.oldTy == BoolTy) {
176 // cast ptr %x to bool was previously defined as setne ptr %x, null
177 // The ptrtoint semantic is to truncate, not compare so we must retain
178 // the original intent by replace the cast with a setne
179 const char* comparator = SrcTy.isPointer() ? ", null" :
180 (SrcTy.isFloatingPoint() ? ", 0.0" : ", 0");
182 Result = "setne (" + Source + comparator + ")";
184 Result = "setne " + Source + comparator;
185 return Result; // skip cast processing below
189 std::string Opcode(getCastOpcode(Source, SrcTy, DstTy));
191 Result += Opcode + "( " + Source + " to " + *DstTy.newTy + ")";
193 Result += Opcode + " " + Source + " to " + *DstTy.newTy;
199 %file-prefix="UpgradeParser"
208 %token <Type> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
209 %token <Type> FLOAT DOUBLE LABEL
210 %token <String> OPAQUE ESINT64VAL EUINT64VAL SINTVAL UINTVAL FPVAL
211 %token <String> NULL_TOK UNDEF ZEROINITIALIZER TRUETOK FALSETOK
212 %token <String> TYPE VAR_ID LABELSTR STRINGCONSTANT
213 %token <String> IMPLEMENTATION BEGINTOK ENDTOK
214 %token <String> DECLARE GLOBAL CONSTANT SECTION VOLATILE
215 %token <String> TO DOTDOTDOT CONST INTERNAL LINKONCE WEAK
216 %token <String> DLLIMPORT DLLEXPORT EXTERN_WEAK APPENDING
217 %token <String> NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG
218 %token <String> ALIGN
219 %token <String> DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
220 %token <String> CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK
221 %token <String> X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
222 %token <String> DATALAYOUT
223 %token <String> RET BR SWITCH INVOKE UNWIND UNREACHABLE
224 %token <String> ADD SUB MUL UDIV SDIV FDIV UREM SREM FREM AND OR XOR
225 %token <String> SETLE SETGE SETLT SETGT SETEQ SETNE // Binary Comparators
226 %token <String> MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR
227 %token <String> PHI_TOK SELECT SHL SHR ASHR LSHR VAARG
228 %token <String> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
229 %token <String> CAST TRUNC ZEXT SEXT FPTRUNC FPEXT FPTOUI FPTOSI UITOFP SITOFP
230 %token <String> PTRTOINT INTTOPTR BITCAST
232 %type <String> OptAssign OptLinkage OptCallingConv OptAlign OptCAlign
233 %type <String> SectionString OptSection GlobalVarAttributes GlobalVarAttribute
234 %type <String> ArgTypeListI ConstExpr DefinitionList
235 %type <String> ConstPool TargetDefinition LibrariesDefinition LibList OptName
236 %type <String> ArgVal ArgListH ArgList FunctionHeaderH BEGIN FunctionHeader END
237 %type <String> Function FunctionProto BasicBlock TypeListI
238 %type <String> InstructionList BBTerminatorInst JumpTable Inst PHIList
239 %type <String> ValueRefList OptTailCall InstVal IndexList OptVolatile
240 %type <String> MemoryInst SymbolicValueRef OptSideEffect GlobalType
241 %type <String> FnDeclareLinkage BasicBlockList BigOrLittle AsmBlock
242 %type <String> Name ValueRef ValueRefListE ConstValueRef
243 %type <String> ShiftOps SetCondOps LogicalOps ArithmeticOps CastOps
245 %type <String> ConstVector
247 %type <Type> IntType SIntType UIntType FPType TypesV Types
248 %type <Type> PrimType UpRTypesV UpRTypes
250 %type <String> IntVal EInt64Val
251 %type <Const> ConstVal
253 %type <Value> ResolvedVal
259 // Handle constant integer size restriction and conversion...
260 IntVal : SINTVAL | UINTVAL ;
261 EInt64Val : ESINT64VAL | EUINT64VAL;
263 // Operations that are notably excluded from this list include:
264 // RET, BR, & SWITCH because they end basic blocks and are treated specially.
265 ArithmeticOps: ADD | SUB | MUL | UDIV | SDIV | FDIV | UREM | SREM | FREM;
266 LogicalOps : AND | OR | XOR;
267 SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE;
268 ShiftOps : SHL | SHR | ASHR | LSHR;
269 CastOps : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | FPTOUI | FPTOSI |
270 UITOFP | SITOFP | PTRTOINT | INTTOPTR | BITCAST | CAST
273 // These are some types that allow classification if we only want a particular
274 // thing... for example, only a signed, unsigned, or integral type.
275 SIntType : LONG | INT | SHORT | SBYTE;
276 UIntType : ULONG | UINT | USHORT | UBYTE;
277 IntType : SIntType | UIntType;
278 FPType : FLOAT | DOUBLE;
280 // OptAssign - Value producing statements have an optional assignment component
281 OptAssign : Name '=' {
285 $$ = new std::string("");
289 : INTERNAL | LINKONCE | WEAK | APPENDING | DLLIMPORT | DLLEXPORT
291 | /*empty*/ { $$ = new std::string(""); } ;
294 : CCC_TOK | CSRETCC_TOK | FASTCC_TOK | COLDCC_TOK | X86_STDCALLCC_TOK
296 | CC_TOK EUINT64VAL {
301 | /*empty*/ { $$ = new std::string(""); } ;
303 // OptAlign/OptCAlign - An optional alignment, and an optional alignment with
304 // a comma before it.
306 : /*empty*/ { $$ = new std::string(); }
307 | ALIGN EUINT64VAL { *$1 += " " + *$2; delete $2; $$ = $1; };
310 : /*empty*/ { $$ = new std::string(); }
311 | ',' ALIGN EUINT64VAL {
319 : SECTION STRINGCONSTANT {
325 OptSection : /*empty*/ { $$ = new std::string(); }
329 : /* empty */ { $$ = new std::string(); }
330 | ',' GlobalVarAttribute GlobalVarAttributes {
346 //===----------------------------------------------------------------------===//
347 // Types includes all predefined types... except void, because it can only be
348 // used in specific contexts (function returning void for example). To have
349 // access to it, a user must explicitly use TypesV.
352 // TypesV includes all of 'Types', but it also includes the void type.
353 TypesV : Types | VOID ;
354 UpRTypesV : UpRTypes | VOID ;
357 // Derived types are added later...
359 PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ;
360 PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL;
368 $$.oldTy = UnresolvedTy;
373 // Include derived types in the Types production.
375 UpRTypes : '\\' EUINT64VAL { // Type UpReference
378 $$.oldTy = NumericTy;
380 | UpRTypesV '(' ArgTypeListI ')' { // Function derived type?
381 *$1.newTy += "( " + *$3 + " )";
384 $$.oldTy = FunctionTy;
386 | '[' EUINT64VAL 'x' UpRTypes ']' { // Sized array type?
388 *$2 += " x " + *$4.newTy + " ]";
393 | '<' EUINT64VAL 'x' UpRTypes '>' { // Packed array type?
395 *$2 += " x " + *$4.newTy + " >";
400 | '{' TypeListI '}' { // Structure type?
406 | '{' '}' { // Empty structure type?
407 $$.newTy = new std::string("{}");
410 | UpRTypes '*' { // Pointer type?
412 $1.oldTy = PointerTy;
416 // TypeList - Used for struct declarations and as a basis for function type
417 // declaration type lists
423 | TypeListI ',' UpRTypes {
424 *$1 += ", " + *$3.newTy;
429 // ArgTypeList - List of types for a function type declaration...
432 | TypeListI ',' DOTDOTDOT {
441 $$ = new std::string();
444 // ConstVal - The various declarations that go into the constant pool. This
445 // production is used ONLY to represent constants that show up AFTER a 'const',
446 // 'constant' or 'global' token at global scope. Constants that can be inlined
447 // into other expressions (such as integers and constexprs) are handled by the
448 // ResolvedVal, ValueRef and ConstValueRef productions.
450 ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
452 $$.cnst = new std::string(*$1.newTy);
453 *$$.cnst += " [ " + *$3 + " ]";
458 $$.cnst = new std::string(*$1.newTy);
461 | Types 'c' STRINGCONSTANT {
463 $$.cnst = new std::string(*$1.newTy);
464 *$$.cnst += " c" + *$3;
467 | Types '<' ConstVector '>' { // Nonempty unsized arr
469 $$.cnst = new std::string(*$1.newTy);
470 *$$.cnst += " < " + *$3 + " >";
473 | Types '{' ConstVector '}' {
475 $$.cnst = new std::string(*$1.newTy);
476 *$$.cnst += " { " + *$3 + " }";
481 $$.cnst = new std::string(*$1.newTy);
486 $$.cnst = new std::string(*$1.newTy);
487 *$$.cnst += " " + *$2;
492 $$.cnst = new std::string(*$1.newTy);
493 *$$.cnst += " " + *$2;
496 | Types SymbolicValueRef {
498 $$.cnst = new std::string(*$1.newTy);
499 *$$.cnst += " " + *$2;
504 $$.cnst = new std::string(*$1.newTy);
505 *$$.cnst += " " + *$2;
508 | Types ZEROINITIALIZER {
510 $$.cnst = new std::string(*$1.newTy);
511 *$$.cnst += " " + *$2;
514 | SIntType EInt64Val { // integral constants
516 $$.cnst = new std::string(*$1.newTy);
517 *$$.cnst += " " + *$2;
520 | UIntType EUINT64VAL { // integral constants
522 $$.cnst = new std::string(*$1.newTy);
523 *$$.cnst += " " + *$2;
526 | BOOL TRUETOK { // Boolean constants
528 $$.cnst = new std::string(*$1.newTy);
529 *$$.cnst += " " + *$2;
532 | BOOL FALSETOK { // Boolean constants
534 $$.cnst = new std::string(*$1.newTy);
535 *$$.cnst += " " + *$2;
538 | FPType FPVAL { // Float & Double constants
540 $$.cnst = new std::string(*$1.newTy);
541 *$$.cnst += " " + *$2;
546 ConstExpr: CastOps '(' ConstVal TO Types ')' {
547 std::string source = *$3.cnst;
551 // Call getCastUpgrade to upgrade the old cast
552 $$ = new std::string(getCastUpgrade(source, $3.type, $5, true));
554 // Nothing to upgrade, just create the cast constant expr
555 $$ = new std::string(*$1);
556 *$$ += "( " + source + " to " + *$5.newTy + ")";
558 delete $1; $3.destroy(); delete $4; $5.destroy();
560 | GETELEMENTPTR '(' ConstVal IndexList ')' {
561 *$1 += "(" + *$3.cnst + " " + *$4 + ")";
566 | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
567 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
568 $3.destroy(); $5.destroy(); $7.destroy();
571 | ArithmeticOps '(' ConstVal ',' ConstVal ')' {
572 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
573 $3.destroy(); $5.destroy();
576 | LogicalOps '(' ConstVal ',' ConstVal ')' {
577 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
578 $3.destroy(); $5.destroy();
581 | SetCondOps '(' ConstVal ',' ConstVal ')' {
582 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
583 $3.destroy(); $5.destroy();
586 | ShiftOps '(' ConstVal ',' ConstVal ')' {
587 const char* shiftop = $1->c_str();
589 shiftop = ($3.type.isUnsigned()) ? "lshr" : "ashr";
590 $$ = new std::string(shiftop);
591 *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
592 delete $1; $3.destroy(); $5.destroy();
594 | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' {
595 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
596 $3.destroy(); $5.destroy();
599 | INSERTELEMENT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
600 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
601 $3.destroy(); $5.destroy(); $7.destroy();
604 | SHUFFLEVECTOR '(' ConstVal ',' ConstVal ',' ConstVal ')' {
605 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
606 $3.destroy(); $5.destroy(); $7.destroy();
611 // ConstVector - A list of comma separated constants.
614 : ConstVector ',' ConstVal {
615 *$1 += ", " + *$3.cnst;
619 | ConstVal { $$ = new std::string(*$1.cnst); $1.destroy(); }
623 // GlobalType - Match either GLOBAL or CONSTANT for global declarations...
624 GlobalType : GLOBAL | CONSTANT ;
627 //===----------------------------------------------------------------------===//
628 // Rules to match Modules
629 //===----------------------------------------------------------------------===//
631 // Module rule: Capture the result of parsing the whole file into a result
634 Module : DefinitionList {
637 // DefinitionList - Top level definitions
639 DefinitionList : DefinitionList Function {
642 | DefinitionList FunctionProto {
647 | DefinitionList MODULE ASM_TOK AsmBlock {
648 *O << "module asm " << " " << *$4 << "\n";
651 | DefinitionList IMPLEMENTATION {
652 *O << "implementation\n";
655 | ConstPool { $$ = 0; }
657 // ConstPool - Constants with optional names assigned to them.
658 ConstPool : ConstPool OptAssign TYPE TypesV {
659 EnumeratedTypes.push_back($4);
661 NamedTypes[*$2].newTy = new std::string(*$4.newTy);
662 NamedTypes[*$2].oldTy = $4.oldTy;
665 *O << "type " << *$4.newTy << "\n";
666 delete $2; delete $3; $4.destroy();
669 | ConstPool FunctionProto { // Function prototypes can be in const pool
674 | ConstPool MODULE ASM_TOK AsmBlock { // Asm blocks can be in the const pool
675 *O << *$2 << " " << *$3 << " " << *$4 << "\n";
676 delete $2; delete $3; delete $4;
679 | ConstPool OptAssign OptLinkage GlobalType ConstVal GlobalVarAttributes {
682 *O << *$3 << " " << *$4 << " " << *$5.cnst << " " << *$6 << "\n";
683 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
686 | ConstPool OptAssign EXTERNAL GlobalType Types GlobalVarAttributes {
689 *O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
690 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
693 | ConstPool OptAssign DLLIMPORT GlobalType Types GlobalVarAttributes {
696 *O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
697 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
700 | ConstPool OptAssign EXTERN_WEAK GlobalType Types GlobalVarAttributes {
703 *O << *$3 << " " << *$4 << " " << *$5.newTy << " " << *$6 << "\n";
704 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
707 | ConstPool TARGET TargetDefinition {
708 *O << *$2 << " " << *$3 << "\n";
709 delete $2; delete $3;
712 | ConstPool DEPLIBS '=' LibrariesDefinition {
713 *O << *$2 << " = " << *$4 << "\n";
714 delete $2; delete $4;
717 | /* empty: end of list */ {
722 AsmBlock : STRINGCONSTANT ;
724 BigOrLittle : BIG | LITTLE
727 : ENDIAN '=' BigOrLittle {
732 | POINTERSIZE '=' EUINT64VAL {
739 | TRIPLE '=' STRINGCONSTANT {
744 | DATALAYOUT '=' STRINGCONSTANT {
758 : LibList ',' STRINGCONSTANT {
764 | /* empty: end of list */ {
765 $$ = new std::string();
768 //===----------------------------------------------------------------------===//
769 // Rules to match Function Headers
770 //===----------------------------------------------------------------------===//
772 Name : VAR_ID | STRINGCONSTANT;
773 OptName : Name | /*empty*/ { $$ = new std::string(); };
775 ArgVal : Types OptName {
782 ArgListH : ArgListH ',' ArgVal {
793 | ArgListH ',' DOTDOTDOT {
801 | /* empty */ { $$ = new std::string(); };
803 FunctionHeaderH : OptCallingConv TypesV Name '(' ArgList ')'
804 OptSection OptAlign {
808 *$1 += *$2.newTy + " " + *$3 + "(" + *$5 + ")";
824 $$ = new std::string("begin");
827 $$ = new std::string ("{");
830 FunctionHeader : OptLinkage FunctionHeaderH BEGIN {
834 *O << *$2 << " " << *$3 << "\n";
835 delete $1; delete $2; delete $3;
839 END : ENDTOK { $$ = new std::string("end"); }
840 | '}' { $$ = new std::string("}"); };
842 Function : FunctionHeader BasicBlockList END {
845 *O << '\n' << *$3 << "\n";
850 : /*default*/ { $$ = new std::string(); }
856 : DECLARE FnDeclareLinkage FunctionHeaderH {
865 //===----------------------------------------------------------------------===//
866 // Rules to match Basic Blocks
867 //===----------------------------------------------------------------------===//
869 OptSideEffect : /* empty */ { $$ = new std::string(); }
873 : ESINT64VAL | EUINT64VAL | FPVAL | TRUETOK | FALSETOK | NULL_TOK | UNDEF
875 | '<' ConstVector '>' {
881 | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT {
885 *$1 += " " + *$3 + ", " + *$5;
886 delete $2; delete $3; delete $5;
890 SymbolicValueRef : IntVal | Name ;
892 // ValueRef - A reference to a definition... either constant or symbolic
893 ValueRef : SymbolicValueRef | ConstValueRef;
896 // ResolvedVal - a <type> <value> pair. This is used only in cases where the
897 // type immediately preceeds the value reference, and allows complex constant
898 // pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
899 ResolvedVal : Types ValueRef {
901 $$.val = new std::string(*$1.newTy + " ");
906 BasicBlockList : BasicBlockList BasicBlock {
909 | BasicBlock { // Do not allow functions with 0 basic blocks
914 // Basic blocks are terminated by branching instructions:
915 // br, br/cc, switch, ret
917 BasicBlock : InstructionList BBTerminatorInst {
921 InstructionList : InstructionList Inst {
922 *O << " " << *$2 << "\n";
935 BBTerminatorInst : RET ResolvedVal { // Return with a result...
936 *O << " " << *$1 << " " << *$2.val << "\n";
937 delete $1; $2.destroy();
940 | RET VOID { // Return with no result...
941 *O << " " << *$1 << " " << *$2.newTy << "\n";
942 delete $1; $2.destroy();
945 | BR LABEL ValueRef { // Unconditional Branch...
946 *O << " " << *$1 << " " << *$2.newTy << " " << *$3 << "\n";
947 delete $1; $2.destroy(); delete $3;
949 } // Conditional Branch...
950 | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {
951 *O << " " << *$1 << " " << *$2.newTy << " " << *$3 << ", "
952 << *$5.newTy << " " << *$6 << ", " << *$8.newTy << " " << *$9 << "\n";
953 delete $1; $2.destroy(); delete $3; $5.destroy(); delete $6;
954 $8.destroy(); delete $9;
957 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
958 *O << " " << *$1 << " " << *$2.newTy << " " << *$3 << ", " << *$5.newTy
959 << " " << *$6 << " [" << *$8 << " ]\n";
960 delete $1; $2.destroy(); delete $3; $5.destroy(); delete $6; delete $8;
963 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' {
964 *O << " " << *$1 << " " << *$2.newTy << " " << *$3 << ", "
965 << *$5.newTy << " " << *$6 << "[]\n";
966 delete $1; $2.destroy(); delete $3; $5.destroy(); delete $6;
969 | OptAssign INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')'
970 TO LABEL ValueRef UNWIND LABEL ValueRef {
974 *O << *$2 << " " << *$3 << " " << *$4.newTy << " " << *$5 << " ("
975 << *$7 << ") " << *$9 << " " << *$10.newTy << " " << *$11 << " "
976 << *$12 << " " << *$13.newTy << " " << *$14 << "\n";
977 delete $1; delete $2; delete $3; $4.destroy(); delete $5; delete $7;
978 delete $9; $10.destroy(); delete $11; delete $12; $13.destroy();
983 *O << " " << *$1 << "\n";
988 *O << " " << *$1 << "\n";
993 JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
994 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5.newTy + " " + *$6;
995 $2.destroy(); delete $3; $5.destroy(); delete $6;
998 | IntType ConstValueRef ',' LABEL ValueRef {
999 $2->insert(0, *$1.newTy + " " );
1000 *$2 += ", " + *$4.newTy + " " + *$5;
1001 $1.destroy(); $4.destroy(); delete $5;
1006 : OptAssign InstVal {
1015 : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes
1016 $3->insert(0, *$1.newTy + "[");
1017 *$3 += "," + *$5 + "]";
1018 $1.destroy(); delete $5;
1021 | PHIList ',' '[' ValueRef ',' ValueRef ']' {
1022 *$1 += ", [" + *$4 + "," + *$6 + "]";
1023 delete $4; delete $6;
1029 : ResolvedVal { $$ = new std::string(*$1.val); $1.destroy(); }
1030 | ValueRefList ',' ResolvedVal {
1031 *$1 += ", " + *$3.val;
1036 // ValueRefListE - Just like ValueRefList, except that it may also be empty!
1039 | /*empty*/ { $$ = new std::string(); }
1051 InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
1052 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5;
1053 $2.destroy(); delete $3; delete $5;
1056 | LogicalOps Types ValueRef ',' ValueRef {
1057 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5;
1058 $2.destroy(); delete $3; delete $5;
1061 | SetCondOps Types ValueRef ',' ValueRef {
1062 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5;
1063 $2.destroy(); delete $3; delete $5;
1067 *$1 += " " + *$2.val;
1071 | ShiftOps ResolvedVal ',' ResolvedVal {
1072 const char* shiftop = $1->c_str();
1074 shiftop = ($2.type.isUnsigned()) ? "lshr" : "ashr";
1075 $$ = new std::string(shiftop);
1076 *$$ += " " + *$2.val + ", " + *$4.val;
1077 delete $1; $2.destroy(); $4.destroy();
1079 | CastOps ResolvedVal TO Types {
1080 std::string source = *$2.val;
1081 TypeInfo SrcTy = $2.type;
1082 TypeInfo DstTy = $4;
1084 $$ = new std::string();
1085 if (*$1 == "cast") {
1086 *$$ += getCastUpgrade(source, SrcTy, DstTy, false);
1088 *$$ += *$1 + " " + source + " to " + *DstTy.newTy;
1090 delete $1; $2.destroy();
1091 delete $3; $4.destroy();
1093 | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
1094 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1095 $2.destroy(); $4.destroy(); $6.destroy();
1098 | VAARG ResolvedVal ',' Types {
1099 *$1 += " " + *$2.val + ", " + *$4.newTy;
1100 $2.destroy(); $4.destroy();
1103 | EXTRACTELEMENT ResolvedVal ',' ResolvedVal {
1104 *$1 += " " + *$2.val + ", " + *$4.val;
1105 $2.destroy(); $4.destroy();
1108 | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
1109 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1110 $2.destroy(); $4.destroy(); $6.destroy();
1113 | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal {
1114 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1115 $2.destroy(); $4.destroy(); $6.destroy();
1123 | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' {
1128 *$1 += *$3.newTy + " " + *$4 + "(" + *$6 + ")";
1129 delete $2; $3.destroy(); delete $4; delete $6;
1135 // IndexList - List of indices for GEP based instructions...
1137 : ',' ValueRefList {
1138 $2->insert(0, ", ");
1141 | /* empty */ { $$ = new std::string(); }
1146 | /* empty */ { $$ = new std::string(); }
1149 MemoryInst : MALLOC Types OptCAlign {
1150 *$1 += " " + *$2.newTy;
1153 $2.destroy(); delete $3;
1156 | MALLOC Types ',' UINT ValueRef OptCAlign {
1157 *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5;
1160 $2.destroy(); $4.destroy(); delete $5; delete $6;
1163 | ALLOCA Types OptCAlign {
1164 *$1 += " " + *$2.newTy;
1167 $2.destroy(); delete $3;
1170 | ALLOCA Types ',' UINT ValueRef OptCAlign {
1171 *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5;
1174 $2.destroy(); $4.destroy(); delete $5; delete $6;
1177 | FREE ResolvedVal {
1178 *$1 += " " + *$2.val;
1182 | OptVolatile LOAD Types ValueRef {
1185 *$1 += *$2 + " " + *$3.newTy + " " + *$4;
1186 delete $2; $3.destroy(); delete $4;
1189 | OptVolatile STORE ResolvedVal ',' Types ValueRef {
1192 *$1 += *$2 + " " + *$3.val + ", " + *$5.newTy + " " + *$6;
1193 delete $2; $3.destroy(); $5.destroy(); delete $6;
1196 | GETELEMENTPTR Types ValueRef IndexList {
1197 *$1 += " " + *$2.newTy + " " + *$3 + " " + *$4;
1198 $2.destroy(); delete $3; delete $4;
1204 int yyerror(const char *ErrorMsg) {
1206 = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
1207 + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
1208 std::string errMsg = std::string(ErrorMsg) + "\n" + where + " while reading ";
1209 if (yychar == YYEMPTY || yychar == 0)
1210 errMsg += "end-of-file.";
1212 errMsg += "token: '" + std::string(Upgradetext, Upgradeleng) + "'";
1213 std::cerr << errMsg << '\n';