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;
35 void UpgradeAssembly(const std::string &infile, std::istream& in,
36 std::ostream &out, bool debug)
45 std::cerr << "Parse failed.\n";
50 std::string getCastUpgrade(std::string& Source, TypeInfo& SrcTy,
51 TypeInfo&DstTy, bool isConst = false)
54 if (SrcTy.isFloatingPoint() && DstTy.isPointer()) {
56 Source = "ulong fptoui(" + Source + " to ulong)";
58 Result = "%cast_upgrade = fptoui " + Source + " to ulong";
59 Source = "ulong %cast_upgrade";
62 SrcTy.newTy = new std::string("ulong");
63 SrcTy.oldTy = ULongTy;
68 const char* getCastOpcode(std::string& Source, TypeInfo& SrcTy,
70 unsigned SrcBits = SrcTy.getBitWidth();
71 unsigned DstBits = DstTy.getBitWidth();
72 const char* opcode = "bitcast";
73 // Run through the possibilities ...
74 if (DstTy.isIntegral()) { // Casting to integral
75 if (SrcTy.isIntegral()) { // Casting from integral
76 if (DstBits < SrcBits)
78 else if (DstBits > SrcBits) { // its an extension
80 opcode ="sext"; // signed -> SEXT
82 opcode = "zext"; // unsigned -> ZEXT
84 opcode = "bitcast"; // Same size, No-op cast
86 } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt
88 opcode = "fptosi"; // FP -> sint
90 opcode = "fptoui"; // FP -> uint
91 } else if (SrcTy.isPacked()) {
92 assert(DstBits == SrcTy.getBitWidth() &&
93 "Casting packed to integer of different width");
94 opcode = "bitcast"; // same size, no-op cast
96 assert(SrcTy.isPointer() &&
97 "Casting from a value that is not first-class type");
98 opcode = "ptrtoint"; // ptr -> int
100 } else if (DstTy.isFloatingPoint()) { // Casting to floating pt
101 if (SrcTy.isIntegral()) { // Casting from integral
102 if (SrcTy.isSigned())
103 opcode = "sitofp"; // sint -> FP
105 opcode = "uitofp"; // uint -> FP
106 } else if (SrcTy.isFloatingPoint()) { // Casting from floating pt
107 if (DstBits < SrcBits) {
108 opcode = "fptrunc"; // FP -> smaller FP
109 } else if (DstBits > SrcBits) {
110 opcode = "fpext"; // FP -> larger FP
112 opcode ="bitcast"; // same size, no-op cast
114 } else if (SrcTy.isPacked()) {
115 assert(DstBits == SrcTy.getBitWidth() &&
116 "Casting packed to floating point of different width");
117 opcode = "bitcast"; // same size, no-op cast
119 assert(0 && "Casting pointer or non-first class to float");
121 } else if (DstTy.isPacked()) {
122 if (SrcTy.isPacked()) {
123 assert(DstTy.getBitWidth() == SrcTy.getBitWidth() &&
124 "Casting packed to packed of different widths");
125 opcode = "bitcast"; // packed -> packed
126 } else if (DstTy.getBitWidth() == SrcBits) {
127 opcode = "bitcast"; // float/int -> packed
129 assert(!"Illegal cast to packed (wrong type or size)");
131 } else if (DstTy.isPointer()) {
132 if (SrcTy.isPointer()) {
133 opcode = "bitcast"; // ptr -> ptr
134 } else if (SrcTy.isIntegral()) {
135 opcode = "inttoptr"; // int -> ptr
136 } else if (SrcTy.isFloatingPoint()) { // float/double -> ptr
138 *O << " %upgrade_cast = fptoui " << Source << " to ulong\n";
140 Source = "ulong %upgrade_cast";
142 assert(!"Casting pointer to other than pointer or int");
145 assert(!"Casting to type that is not first-class");
152 %file-prefix="UpgradeParser"
161 %token <Type> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
162 %token <Type> FLOAT DOUBLE LABEL OPAQUE
163 %token <String> ESINT64VAL EUINT64VAL SINTVAL UINTVAL FPVAL
164 %token <String> NULL_TOK UNDEF ZEROINITIALIZER TRUETOK FALSETOK
165 %token <String> TYPE VAR_ID LABELSTR STRINGCONSTANT
166 %token <String> IMPLEMENTATION BEGINTOK ENDTOK
167 %token <String> DECLARE GLOBAL CONSTANT SECTION VOLATILE
168 %token <String> TO DOTDOTDOT CONST INTERNAL LINKONCE WEAK
169 %token <String> DLLIMPORT DLLEXPORT EXTERN_WEAK APPENDING
170 %token <String> NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG
171 %token <String> ALIGN
172 %token <String> DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
173 %token <String> CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK
174 %token <String> X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
175 %token <String> DATALAYOUT
176 %token <String> RET BR SWITCH INVOKE UNWIND UNREACHABLE
177 %token <String> ADD SUB MUL UDIV SDIV FDIV UREM SREM FREM AND OR XOR
178 %token <String> SETLE SETGE SETLT SETGT SETEQ SETNE // Binary Comparators
179 %token <String> MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR
180 %token <String> PHI_TOK SELECT SHL SHR ASHR LSHR VAARG
181 %token <String> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
182 %token <String> CAST TRUNC ZEXT SEXT FPTRUNC FPEXT FPTOUI FPTOSI UITOFP SITOFP
183 %token <String> PTRTOINT INTTOPTR BITCAST
185 %type <String> OptAssign OptLinkage OptCallingConv OptAlign OptCAlign
186 %type <String> SectionString OptSection GlobalVarAttributes GlobalVarAttribute
187 %type <String> ArgTypeListI ConstExpr DefinitionList
188 %type <String> ConstPool TargetDefinition LibrariesDefinition LibList OptName
189 %type <String> ArgVal ArgListH ArgList FunctionHeaderH BEGIN FunctionHeader END
190 %type <String> Function FunctionProto BasicBlock TypeListI
191 %type <String> InstructionList BBTerminatorInst JumpTable Inst PHIList
192 %type <String> ValueRefList OptTailCall InstVal IndexList OptVolatile
193 %type <String> MemoryInst SymbolicValueRef OptSideEffect GlobalType
194 %type <String> FnDeclareLinkage BasicBlockList BigOrLittle AsmBlock
195 %type <String> Name ValueRef ValueRefListE ConstValueRef
196 %type <String> ShiftOps SetCondOps LogicalOps ArithmeticOps CastOps
198 %type <String> ConstVector
200 %type <Type> IntType SIntType UIntType FPType TypesV Types
201 %type <Type> PrimType UpRTypesV UpRTypes
203 %type <String> IntVal EInt64Val
204 %type <Const> ConstVal
206 %type <Value> ResolvedVal
212 // Handle constant integer size restriction and conversion...
213 IntVal : SINTVAL | UINTVAL ;
214 EInt64Val : ESINT64VAL | EUINT64VAL;
216 // Operations that are notably excluded from this list include:
217 // RET, BR, & SWITCH because they end basic blocks and are treated specially.
218 ArithmeticOps: ADD | SUB | MUL | UDIV | SDIV | FDIV | UREM | SREM | FREM;
219 LogicalOps : AND | OR | XOR;
220 SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE;
221 ShiftOps : SHL | SHR | ASHR | LSHR;
222 CastOps : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | FPTOUI | FPTOSI |
223 UITOFP | SITOFP | PTRTOINT | INTTOPTR | BITCAST | CAST
226 // These are some types that allow classification if we only want a particular
227 // thing... for example, only a signed, unsigned, or integral type.
228 SIntType : LONG | INT | SHORT | SBYTE;
229 UIntType : ULONG | UINT | USHORT | UBYTE;
230 IntType : SIntType | UIntType;
231 FPType : FLOAT | DOUBLE;
233 // OptAssign - Value producing statements have an optional assignment component
234 OptAssign : Name '=' {
239 $$ = new std::string("");
243 : INTERNAL | LINKONCE | WEAK | APPENDING | DLLIMPORT | DLLEXPORT
245 | /*empty*/ { $$ = new std::string(""); } ;
248 : CCC_TOK | CSRETCC_TOK | FASTCC_TOK | COLDCC_TOK | X86_STDCALLCC_TOK
250 | CC_TOK EUINT64VAL {
255 | /*empty*/ { $$ = new std::string(""); } ;
257 // OptAlign/OptCAlign - An optional alignment, and an optional alignment with
258 // a comma before it.
260 : /*empty*/ { $$ = new std::string(); }
261 | ALIGN EUINT64VAL { *$1 += " " + *$2; delete $2; $$ = $1; };
264 : /*empty*/ { $$ = new std::string(); }
265 | ',' ALIGN EUINT64VAL {
273 : SECTION STRINGCONSTANT {
279 OptSection : /*empty*/ { $$ = new std::string(); }
283 : /* empty */ { $$ = new std::string(); }
284 | ',' GlobalVarAttribute GlobalVarAttributes {
300 //===----------------------------------------------------------------------===//
301 // Types includes all predefined types... except void, because it can only be
302 // used in specific contexts (function returning void for example). To have
303 // access to it, a user must explicitly use TypesV.
306 // TypesV includes all of 'Types', but it also includes the void type.
307 TypesV : Types | VOID ;
308 UpRTypesV : UpRTypes | VOID ;
311 // Derived types are added later...
313 PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ;
314 PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL;
315 UpRTypes : OPAQUE | PrimType
317 $$.newTy = $1; $$.oldTy = OpaqueTy;
320 // Include derived types in the Types production.
322 UpRTypes : '\\' EUINT64VAL { // Type UpReference
327 | UpRTypesV '(' ArgTypeListI ')' { // Function derived type?
328 *$1.newTy += "( " + *$3 + " )";
331 $$.oldTy = FunctionTy;
333 | '[' EUINT64VAL 'x' UpRTypes ']' { // Sized array type?
335 *$2 += " x " + *$4.newTy + " ]";
340 | '<' EUINT64VAL 'x' UpRTypes '>' { // Packed array type?
342 *$2 += " x " + *$4.newTy + " >";
347 | '{' TypeListI '}' { // Structure type?
353 | '{' '}' { // Empty structure type?
354 $$.newTy = new std::string("{}");
357 | UpRTypes '*' { // Pointer type?
359 $1.oldTy = PointerTy;
363 // TypeList - Used for struct declarations and as a basis for function type
364 // declaration type lists
370 | TypeListI ',' UpRTypes {
371 *$1 += ", " + *$3.newTy;
376 // ArgTypeList - List of types for a function type declaration...
379 | TypeListI ',' DOTDOTDOT {
388 $$ = new std::string();
391 // ConstVal - The various declarations that go into the constant pool. This
392 // production is used ONLY to represent constants that show up AFTER a 'const',
393 // 'constant' or 'global' token at global scope. Constants that can be inlined
394 // into other expressions (such as integers and constexprs) are handled by the
395 // ResolvedVal, ValueRef and ConstValueRef productions.
397 ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
399 $$.cnst = new std::string(*$1.newTy);
400 *$$.cnst += " [ " + *$3 + " ]";
405 $$.cnst = new std::string(*$1.newTy);
408 | Types 'c' STRINGCONSTANT {
410 $$.cnst = new std::string(*$1.newTy);
411 *$$.cnst += " c" + *$3;
414 | Types '<' ConstVector '>' { // Nonempty unsized arr
416 $$.cnst = new std::string(*$1.newTy);
417 *$$.cnst += " < " + *$3 + " >";
420 | Types '{' ConstVector '}' {
422 $$.cnst = new std::string(*$1.newTy);
423 *$$.cnst += " { " + *$3 + " }";
428 $$.cnst = new std::string(*$1.newTy);
433 $$.cnst = new std::string(*$1.newTy);
434 *$$.cnst += " " + *$2;
439 $$.cnst = new std::string(*$1.newTy);
440 *$$.cnst += " " + *$2;
443 | Types SymbolicValueRef {
445 $$.cnst = new std::string(*$1.newTy);
446 *$$.cnst += " " + *$2;
451 $$.cnst = new std::string(*$1.newTy);
452 *$$.cnst += " " + *$2;
455 | Types ZEROINITIALIZER {
457 $$.cnst = new std::string(*$1.newTy);
458 *$$.cnst += " " + *$2;
461 | SIntType EInt64Val { // integral constants
463 $$.cnst = new std::string(*$1.newTy);
464 *$$.cnst += " " + *$2;
467 | UIntType EUINT64VAL { // integral constants
469 $$.cnst = new std::string(*$1.newTy);
470 *$$.cnst += " " + *$2;
473 | BOOL TRUETOK { // Boolean constants
475 $$.cnst = new std::string(*$1.newTy);
476 *$$.cnst += " " + *$2;
479 | BOOL FALSETOK { // Boolean constants
481 $$.cnst = new std::string(*$1.newTy);
482 *$$.cnst += " " + *$2;
485 | FPType FPVAL { // Float & Double constants
487 $$.cnst = new std::string(*$1.newTy);
488 *$$.cnst += " " + *$2;
493 ConstExpr: CastOps '(' ConstVal TO Types ')' {
494 // We must infer the cast opcode from the types of the operands.
495 const char *opcode = $1->c_str();
496 std::string source = *$3.cnst;
498 std::string upgrade = getCastUpgrade(source, $3.type, $5, true);
499 opcode = getCastOpcode(source, $3.type, $5);
500 if (!upgrade.empty())
503 $$ = new std::string(opcode);
504 *$$ += "( " + source + " " + *$4 + " " + *$5.newTy + ")";
505 delete $1; $3.destroy(); delete $4; $5.destroy();
507 | GETELEMENTPTR '(' ConstVal IndexList ')' {
508 *$1 += "(" + *$3.cnst + " " + *$4 + ")";
513 | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
514 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
515 $3.destroy(); $5.destroy(); $7.destroy();
518 | ArithmeticOps '(' ConstVal ',' ConstVal ')' {
519 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
520 $3.destroy(); $5.destroy();
523 | LogicalOps '(' ConstVal ',' ConstVal ')' {
524 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
525 $3.destroy(); $5.destroy();
528 | SetCondOps '(' ConstVal ',' ConstVal ')' {
529 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
530 $3.destroy(); $5.destroy();
533 | ShiftOps '(' ConstVal ',' ConstVal ')' {
534 const char* shiftop = $1->c_str();
536 shiftop = ($3.type.isUnsigned()) ? "lshr" : "ashr";
537 $$ = new std::string(shiftop);
538 *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
539 delete $1; $3.destroy(); $5.destroy();
541 | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' {
542 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
543 $3.destroy(); $5.destroy();
546 | INSERTELEMENT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
547 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
548 $3.destroy(); $5.destroy(); $7.destroy();
551 | SHUFFLEVECTOR '(' ConstVal ',' ConstVal ',' ConstVal ')' {
552 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
553 $3.destroy(); $5.destroy(); $7.destroy();
558 // ConstVector - A list of comma separated constants.
561 : ConstVector ',' ConstVal {
562 *$1 += ", " + *$3.cnst;
566 | ConstVal { $$ = new std::string(*$1.cnst); $1.destroy(); }
570 // GlobalType - Match either GLOBAL or CONSTANT for global declarations...
571 GlobalType : GLOBAL | CONSTANT ;
574 //===----------------------------------------------------------------------===//
575 // Rules to match Modules
576 //===----------------------------------------------------------------------===//
578 // Module rule: Capture the result of parsing the whole file into a result
581 Module : DefinitionList {
584 // DefinitionList - Top level definitions
586 DefinitionList : DefinitionList Function {
589 | DefinitionList FunctionProto {
594 | DefinitionList MODULE ASM_TOK AsmBlock {
595 *O << "module asm " << " " << *$4 << "\n";
598 | DefinitionList IMPLEMENTATION {
599 *O << "implementation\n";
604 // ConstPool - Constants with optional names assigned to them.
605 ConstPool : ConstPool OptAssign TYPE TypesV {
606 *O << *$2 << " " << *$3 << " " << *$4.newTy << "\n";
607 // delete $2; delete $3; $4.destroy();
610 | ConstPool FunctionProto { // Function prototypes can be in const pool
615 | ConstPool MODULE ASM_TOK AsmBlock { // Asm blocks can be in the const pool
616 *O << *$2 << " " << *$3 << " " << *$4 << "\n";
617 delete $2; delete $3; delete $4;
620 | ConstPool OptAssign OptLinkage GlobalType ConstVal GlobalVarAttributes {
621 *O << *$2 << " " << *$3 << " " << *$4 << " " << *$5.cnst << " "
623 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
626 | ConstPool OptAssign EXTERNAL GlobalType Types GlobalVarAttributes {
627 *O << *$2 << " " << *$3 << " " << *$4 << " " << *$5.newTy
628 << " " << *$6 << "\n";
629 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
632 | ConstPool OptAssign DLLIMPORT GlobalType Types GlobalVarAttributes {
633 *O << *$2 << " " << *$3 << " " << *$4 << " " << *$5.newTy
634 << " " << *$6 << "\n";
635 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
638 | ConstPool OptAssign EXTERN_WEAK GlobalType Types GlobalVarAttributes {
639 *O << *$2 << " " << *$3 << " " << *$4 << " " << *$5.newTy
640 << " " << *$6 << "\n";
641 delete $2; delete $3; delete $4; $5.destroy(); delete $6;
644 | ConstPool TARGET TargetDefinition {
645 *O << *$2 << " " << *$3 << "\n";
646 delete $2; delete $3;
649 | ConstPool DEPLIBS '=' LibrariesDefinition {
650 *O << *$2 << " = " << *$4 << "\n";
651 delete $2; delete $4;
654 | /* empty: end of list */ {
659 AsmBlock : STRINGCONSTANT ;
661 BigOrLittle : BIG | LITTLE
664 : ENDIAN '=' BigOrLittle {
669 | POINTERSIZE '=' EUINT64VAL {
676 | TRIPLE '=' STRINGCONSTANT {
681 | DATALAYOUT '=' STRINGCONSTANT {
695 : LibList ',' STRINGCONSTANT {
701 | /* empty: end of list */ {
702 $$ = new std::string();
705 //===----------------------------------------------------------------------===//
706 // Rules to match Function Headers
707 //===----------------------------------------------------------------------===//
709 Name : VAR_ID | STRINGCONSTANT;
710 OptName : Name | /*empty*/ { $$ = new std::string(); };
712 ArgVal : Types OptName {
719 ArgListH : ArgListH ',' ArgVal {
730 | ArgListH ',' DOTDOTDOT {
738 | /* empty */ { $$ = new std::string(); };
740 FunctionHeaderH : OptCallingConv TypesV Name '(' ArgList ')'
741 OptSection OptAlign {
745 *$1 += *$2.newTy + " " + *$3 + "(" + *$5 + ")";
761 $$ = new std::string("begin");
764 $$ = new std::string ("{");
767 FunctionHeader : OptLinkage FunctionHeaderH BEGIN {
771 *O << *$2 << " " << *$3 << "\n";
772 delete $1; delete $2; delete $3;
776 END : ENDTOK { $$ = new std::string("end"); }
777 | '}' { $$ = new std::string("}"); };
779 Function : FunctionHeader BasicBlockList END {
782 *O << '\n' << *$3 << "\n";
787 : /*default*/ { $$ = new std::string(); }
793 : DECLARE FnDeclareLinkage FunctionHeaderH {
802 //===----------------------------------------------------------------------===//
803 // Rules to match Basic Blocks
804 //===----------------------------------------------------------------------===//
806 OptSideEffect : /* empty */ { $$ = new std::string(); }
810 : ESINT64VAL | EUINT64VAL | FPVAL | TRUETOK | FALSETOK | NULL_TOK | UNDEF
812 | '<' ConstVector '>' {
818 | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT {
822 *$1 += " " + *$3 + ", " + *$5;
823 delete $2; delete $3; delete $5;
827 SymbolicValueRef : IntVal | Name ;
829 // ValueRef - A reference to a definition... either constant or symbolic
830 ValueRef : SymbolicValueRef | ConstValueRef;
833 // ResolvedVal - a <type> <value> pair. This is used only in cases where the
834 // type immediately preceeds the value reference, and allows complex constant
835 // pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
836 ResolvedVal : Types ValueRef {
838 $$.val = new std::string(*$1.newTy + " ");
843 BasicBlockList : BasicBlockList BasicBlock {
846 | BasicBlock { // Do not allow functions with 0 basic blocks
851 // Basic blocks are terminated by branching instructions:
852 // br, br/cc, switch, ret
854 BasicBlock : InstructionList BBTerminatorInst {
858 InstructionList : InstructionList Inst {
859 *O << " " << *$2 << "\n";
872 BBTerminatorInst : RET ResolvedVal { // Return with a result...
873 *O << " " << *$1 << " " << *$2.val << "\n";
874 delete $1; $2.destroy();
877 | RET VOID { // Return with no result...
878 *O << " " << *$1 << " " << *$2.newTy << "\n";
879 delete $1; $2.destroy();
882 | BR LABEL ValueRef { // Unconditional Branch...
883 *O << " " << *$1 << " " << *$2.newTy << " " << *$3 << "\n";
884 delete $1; $2.destroy(); delete $3;
886 } // Conditional Branch...
887 | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {
888 *O << " " << *$1 << " " << *$2.newTy << " " << *$3 << ", "
889 << *$5.newTy << " " << *$6 << ", " << *$8.newTy << " " << *$9 << "\n";
890 delete $1; $2.destroy(); delete $3; $5.destroy(); delete $6;
891 $8.destroy(); delete $9;
894 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
895 *O << " " << *$1 << " " << *$2.newTy << " " << *$3 << ", " << *$5.newTy
896 << " " << *$6 << " [" << *$8 << " ]\n";
897 delete $1; $2.destroy(); delete $3; $5.destroy(); delete $6; delete $8;
900 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' {
901 *O << " " << *$1 << " " << *$2.newTy << " " << *$3 << ", "
902 << *$5.newTy << " " << *$6 << "[]\n";
903 delete $1; $2.destroy(); delete $3; $5.destroy(); delete $6;
906 | OptAssign INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')'
907 TO LABEL ValueRef UNWIND LABEL ValueRef {
911 *O << *$2 << " " << *$3 << " " << *$4.newTy << " " << *$5 << " ("
912 << *$7 << ") " << *$9 << " " << *$10.newTy << " " << *$11 << " "
913 << *$12 << " " << *$13.newTy << " " << *$14 << "\n";
914 delete $1; delete $2; delete $3; $4.destroy(); delete $5; delete $7;
915 delete $9; $10.destroy(); delete $11; delete $12; $13.destroy();
920 *O << " " << *$1 << "\n";
925 *O << " " << *$1 << "\n";
930 JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
931 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5.newTy + " " + *$6;
932 $2.destroy(); delete $3; $5.destroy(); delete $6;
935 | IntType ConstValueRef ',' LABEL ValueRef {
936 $2->insert(0, *$1.newTy + " " );
937 *$2 += ", " + *$4.newTy + " " + *$5;
938 $1.destroy(); $4.destroy(); delete $5;
943 : OptAssign InstVal {
950 : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes
951 $3->insert(0, *$1.newTy + "[");
952 *$3 += "," + *$5 + "]";
953 $1.destroy(); delete $5;
956 | PHIList ',' '[' ValueRef ',' ValueRef ']' {
957 *$1 += ", [" + *$4 + "," + *$6 + "]";
958 delete $4; delete $6;
964 : ResolvedVal { $$ = new std::string(*$1.val); $1.destroy(); }
965 | ValueRefList ',' ResolvedVal {
966 *$1 += ", " + *$3.val;
971 // ValueRefListE - Just like ValueRefList, except that it may also be empty!
974 | /*empty*/ { $$ = new std::string(); }
986 InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
987 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5;
988 $2.destroy(); delete $3; delete $5;
991 | LogicalOps Types ValueRef ',' ValueRef {
992 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5;
993 $2.destroy(); delete $3; delete $5;
996 | SetCondOps Types ValueRef ',' ValueRef {
997 *$1 += " " + *$2.newTy + " " + *$3 + ", " + *$5;
998 $2.destroy(); delete $3; delete $5;
1002 *$1 += " " + *$2.val;
1006 | ShiftOps ResolvedVal ',' ResolvedVal {
1007 const char* shiftop = $1->c_str();
1009 shiftop = ($2.type.isUnsigned()) ? "lshr" : "ashr";
1010 $$ = new std::string(shiftop);
1011 *$$ += " " + *$2.val + ", " + *$4.val;
1012 delete $1; $2.destroy(); $4.destroy();
1014 | CastOps ResolvedVal TO Types {
1015 const char *opcode = $1->c_str();
1016 std::string source = *$2.val;
1017 if (*$1 == "cast") {
1018 std::string upgrade = getCastUpgrade(source, $2.type, $4, false);
1019 if (!upgrade.empty())
1020 *O << " " << upgrade << "\n";
1021 opcode = getCastOpcode(source, $2.type, $4);
1023 $$ = new std::string(opcode);
1024 *$$ += " " + source + " " + *$3 + " " + *$4.newTy;
1025 delete $1; $2.destroy();
1026 delete $3; $4.destroy();
1028 | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
1029 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1030 $2.destroy(); $4.destroy(); $6.destroy();
1033 | VAARG ResolvedVal ',' Types {
1034 *$1 += " " + *$2.val + ", " + *$4.newTy;
1035 $2.destroy(); $4.destroy();
1038 | EXTRACTELEMENT ResolvedVal ',' ResolvedVal {
1039 *$1 += " " + *$2.val + ", " + *$4.val;
1040 $2.destroy(); $4.destroy();
1043 | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
1044 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1045 $2.destroy(); $4.destroy(); $6.destroy();
1048 | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal {
1049 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1050 $2.destroy(); $4.destroy(); $6.destroy();
1058 | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' {
1063 *$1 += *$3.newTy + " " + *$4 + "(" + *$6 + ")";
1064 delete $2; $3.destroy(); delete $4; delete $6;
1070 // IndexList - List of indices for GEP based instructions...
1072 : ',' ValueRefList {
1073 $2->insert(0, ", ");
1076 | /* empty */ { $$ = new std::string(); }
1081 | /* empty */ { $$ = new std::string(); }
1084 MemoryInst : MALLOC Types OptCAlign {
1085 *$1 += " " + *$2.newTy;
1088 $2.destroy(); delete $3;
1091 | MALLOC Types ',' UINT ValueRef OptCAlign {
1092 *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5;
1095 $2.destroy(); $4.destroy(); delete $5; delete $6;
1098 | ALLOCA Types OptCAlign {
1099 *$1 += " " + *$2.newTy;
1102 $2.destroy(); delete $3;
1105 | ALLOCA Types ',' UINT ValueRef OptCAlign {
1106 *$1 += " " + *$2.newTy + ", " + *$4.newTy + " " + *$5;
1109 $2.destroy(); $4.destroy(); delete $5; delete $6;
1112 | FREE ResolvedVal {
1113 *$1 += " " + *$2.val;
1117 | OptVolatile LOAD Types ValueRef {
1120 *$1 += *$2 + " " + *$3.newTy + " " + *$4;
1121 delete $2; $3.destroy(); delete $4;
1124 | OptVolatile STORE ResolvedVal ',' Types ValueRef {
1127 *$1 += *$2 + " " + *$3.val + ", " + *$5.newTy + " " + *$6;
1128 delete $2; $3.destroy(); $5.destroy(); delete $6;
1131 | GETELEMENTPTR Types ValueRef IndexList {
1132 *$1 += *$2.newTy + " " + *$3 + " " + *$4;
1133 $2.destroy(); delete $3; delete $4;
1139 int yyerror(const char *ErrorMsg) {
1141 = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
1142 + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
1143 std::string errMsg = std::string(ErrorMsg) + "\n" + where + " while reading ";
1144 if (yychar == YYEMPTY || yychar == 0)
1145 errMsg += "end-of-file.";
1147 errMsg += "token: '" + std::string(Upgradetext, Upgradeleng) + "'";
1148 std::cerr << errMsg << '\n';