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"
21 #define YYERROR_VERBOSE 1
22 #define YYINCLUDED_STDLIB_H
25 int yylex(); // declaration" of xxx warnings.
29 static std::string CurFilename;
30 static std::ostream *O = 0;
31 std::istream* LexInput = 0;
32 unsigned SizeOfPointer = 32;
33 static uint64_t unique = 1;
35 // This bool controls whether attributes are ever added to function declarations
36 // definitions and calls.
37 static bool AddAttributes = false;
39 // This bool is used to communicate between the InstVal and Inst rules about
40 // whether or not a cast should be deleted. When the flag is set, InstVal has
41 // determined that the cast is a candidate. However, it can only be deleted if
42 // the value being casted is the same value name as the instruction. The Inst
43 // rule makes that comparison if the flag is set and comments out the
44 // instruction if they match.
45 static bool deleteUselessCastFlag = false;
46 static std::string* deleteUselessCastName = 0;
48 typedef std::vector<TypeInfo> TypeVector;
49 static TypeVector EnumeratedTypes;
50 typedef std::map<std::string,TypeInfo> TypeMap;
51 static TypeMap NamedTypes;
52 static TypeMap Globals;
54 void destroy(ValueList* VL) {
55 while (!VL->empty()) {
56 ValueInfo& VI = VL->back();
63 void UpgradeAssembly(const std::string &infile, std::istream& in,
64 std::ostream &out, bool debug, bool addAttrs)
70 AddAttributes = addAttrs;
74 std::cerr << "Parse failed.\n";
79 TypeInfo* ResolveType(TypeInfo*& Ty) {
80 if (Ty->isUnresolved()) {
81 if (Ty->getNewTy()[0] == '%' && isdigit(Ty->getNewTy()[1])) {
82 unsigned ref = atoi(&((Ty->getNewTy().c_str())[1])); // skip the %
83 if (ref < EnumeratedTypes.size()) {
84 Ty = &EnumeratedTypes[ref];
87 std::string msg("Can't resolve numbered type: ");
88 msg += Ty->getNewTy();
92 TypeMap::iterator I = NamedTypes.find(Ty->getNewTy());
93 if (I != NamedTypes.end()) {
97 std::string msg("Cannot resolve type: ");
98 msg += Ty->getNewTy();
103 // otherwise its already resolved.
107 static const char* getCastOpcode(
108 std::string& Source, const TypeInfo* SrcTy, const TypeInfo* DstTy)
110 unsigned SrcBits = SrcTy->getBitWidth();
111 unsigned DstBits = DstTy->getBitWidth();
112 const char* opcode = "bitcast";
113 // Run through the possibilities ...
114 if (DstTy->isIntegral()) { // Casting to integral
115 if (SrcTy->isIntegral()) { // Casting from integral
116 if (DstBits < SrcBits)
118 else if (DstBits > SrcBits) { // its an extension
119 if (SrcTy->isSigned())
120 opcode ="sext"; // signed -> SEXT
122 opcode = "zext"; // unsigned -> ZEXT
124 opcode = "bitcast"; // Same size, No-op cast
126 } else if (SrcTy->isFloatingPoint()) { // Casting from floating pt
127 if (DstTy->isSigned())
128 opcode = "fptosi"; // FP -> sint
130 opcode = "fptoui"; // FP -> uint
131 } else if (SrcTy->isPacked()) {
132 assert(DstBits == SrcTy->getBitWidth() &&
133 "Casting packed to integer of different width");
134 opcode = "bitcast"; // same size, no-op cast
136 assert(SrcTy->isPointer() &&
137 "Casting from a value that is not first-class type");
138 opcode = "ptrtoint"; // ptr -> int
140 } else if (DstTy->isFloatingPoint()) { // Casting to floating pt
141 if (SrcTy->isIntegral()) { // Casting from integral
142 if (SrcTy->isSigned())
143 opcode = "sitofp"; // sint -> FP
145 opcode = "uitofp"; // uint -> FP
146 } else if (SrcTy->isFloatingPoint()) { // Casting from floating pt
147 if (DstBits < SrcBits) {
148 opcode = "fptrunc"; // FP -> smaller FP
149 } else if (DstBits > SrcBits) {
150 opcode = "fpext"; // FP -> larger FP
152 opcode ="bitcast"; // same size, no-op cast
154 } else if (SrcTy->isPacked()) {
155 assert(DstBits == SrcTy->getBitWidth() &&
156 "Casting packed to floating point of different width");
157 opcode = "bitcast"; // same size, no-op cast
159 assert(0 && "Casting pointer or non-first class to float");
161 } else if (DstTy->isPacked()) {
162 if (SrcTy->isPacked()) {
163 assert(DstTy->getBitWidth() == SrcTy->getBitWidth() &&
164 "Casting packed to packed of different widths");
165 opcode = "bitcast"; // packed -> packed
166 } else if (DstTy->getBitWidth() == SrcBits) {
167 opcode = "bitcast"; // float/int -> packed
169 assert(!"Illegal cast to packed (wrong type or size)");
171 } else if (DstTy->isPointer()) {
172 if (SrcTy->isPointer()) {
173 opcode = "bitcast"; // ptr -> ptr
174 } else if (SrcTy->isIntegral()) {
175 opcode = "inttoptr"; // int -> ptr
177 assert(!"Casting invalid type to pointer");
180 assert(!"Casting to type that is not first-class");
185 static std::string getCastUpgrade(const std::string& Src, TypeInfo* SrcTy,
186 TypeInfo* DstTy, bool isConst)
189 std::string Source = Src;
190 if (SrcTy->isFloatingPoint() && DstTy->isPointer()) {
191 // fp -> ptr cast is no longer supported but we must upgrade this
192 // by doing a double cast: fp -> int -> ptr
194 Source = "i64 fptoui(" + Source + " to i64)";
196 *O << " %cast_upgrade" << unique << " = fptoui " << Source
198 Source = "i64 %cast_upgrade" + llvm::utostr(unique);
200 // Update the SrcTy for the getCastOpcode call below
202 SrcTy = new TypeInfo("i64", ULongTy);
203 } else if (DstTy->isBool()) {
204 // cast type %x to bool was previously defined as setne type %x, null
205 // The cast semantic is now to truncate, not compare so we must retain
206 // the original intent by replacing the cast with a setne
207 const char* comparator = SrcTy->isPointer() ? ", null" :
208 (SrcTy->isFloatingPoint() ? ", 0.0" :
209 (SrcTy->isBool() ? ", false" : ", 0"));
210 const char* compareOp = SrcTy->isFloatingPoint() ? "fcmp one " : "icmp ne ";
212 Result = "(" + Source + comparator + ")";
213 Result = compareOp + Result;
215 Result = compareOp + Source + comparator;
216 return Result; // skip cast processing below
220 std::string Opcode(getCastOpcode(Source, SrcTy, DstTy));
222 Result += Opcode + "( " + Source + " to " + DstTy->getNewTy() + ")";
224 Result += Opcode + " " + Source + " to " + DstTy->getNewTy();
228 const char* getDivRemOpcode(const std::string& opcode, TypeInfo* TI) {
229 const char* op = opcode.c_str();
230 const TypeInfo* Ty = ResolveType(TI);
232 Ty = Ty->getElementType();
234 if (Ty->isFloatingPoint())
236 else if (Ty->isUnsigned())
238 else if (Ty->isSigned())
241 yyerror("Invalid type for div instruction");
242 else if (opcode == "rem")
243 if (Ty->isFloatingPoint())
245 else if (Ty->isUnsigned())
247 else if (Ty->isSigned())
250 yyerror("Invalid type for rem instruction");
255 getCompareOp(const std::string& setcc, const TypeInfo* TI) {
256 assert(setcc.length() == 5);
259 assert(cc1 == 'e' || cc1 == 'n' || cc1 == 'l' || cc1 == 'g');
260 assert(cc2 == 'q' || cc2 == 'e' || cc2 == 'e' || cc2 == 't');
261 std::string result("xcmp xxx");
264 if (TI->isFloatingPoint()) {
268 result[5] = 'u'; // NE maps to unordered
270 result[5] = 'o'; // everything else maps to ordered
271 } else if (TI->isIntegral() || TI->isPointer()) {
273 if ((cc1 == 'e' && cc2 == 'q') || (cc1 == 'n' && cc2 == 'e'))
275 else if (TI->isSigned())
277 else if (TI->isUnsigned() || TI->isPointer() || TI->isBool())
280 yyerror("Invalid integral type for setcc");
285 static TypeInfo* getFunctionReturnType(TypeInfo* PFTy) {
287 if (PFTy->isPointer()) {
288 TypeInfo* ElemTy = PFTy->getElementType();
290 if (ElemTy->isFunction())
291 return ElemTy->getResultType()->clone();
292 } else if (PFTy->isFunction()) {
293 return PFTy->getResultType()->clone();
295 return PFTy->clone();
298 typedef std::vector<TypeInfo*> UpRefStack;
299 static TypeInfo* ResolveUpReference(TypeInfo* Ty, UpRefStack* stack) {
300 assert(Ty->isUpReference() && "Can't resolve a non-upreference");
301 unsigned upref = atoi(&((Ty->getNewTy().c_str())[1])); // skip the slash
302 assert(upref < stack->size() && "Invalid up reference");
303 return (*stack)[upref - stack->size() - 1];
306 static TypeInfo* getGEPIndexedType(TypeInfo* PTy, ValueList* idxs) {
307 TypeInfo* Result = ResolveType(PTy);
308 assert(PTy->isPointer() && "GEP Operand is not a pointer?");
310 for (unsigned i = 0; i < idxs->size(); ++i) {
311 if (Result->isComposite()) {
312 Result = Result->getIndexedType((*idxs)[i]);
314 stack.push_back(Result);
316 yyerror("Invalid type for index");
318 // Resolve upreferences so we can return a more natural type
319 if (Result->isPointer()) {
320 if (Result->getElementType()->isUpReference()) {
321 stack.push_back(Result);
322 Result = ResolveUpReference(Result->getElementType(), &stack);
324 } else if (Result->isUpReference()) {
325 Result = ResolveUpReference(Result->getElementType(), &stack);
327 return Result->getPointerType();
330 static std::string makeUniqueName(const std::string *Name, bool isSigned) {
331 const char *suffix = ".u";
334 if ((*Name)[Name->size()-1] == '"') {
335 std::string Result(*Name);
336 Result.insert(Name->size()-1, suffix);
339 return *Name + suffix;
342 // This function handles appending .u or .s to integer value names that
343 // were previously unsigned or signed, respectively. This avoids name
344 // collisions since the unsigned and signed type planes have collapsed
345 // into a single signless type plane.
346 static std::string getUniqueName(const std::string *Name, TypeInfo* Ty) {
347 // If its not a symbolic name, don't modify it, probably a constant val.
348 if ((*Name)[0] != '%' && (*Name)[0] != '"')
350 // If its a numeric reference, just leave it alone.
351 if (isdigit((*Name)[1]))
357 // Remove as many levels of pointer nesting that we have.
358 if (Ty->isPointer()) {
359 // Avoid infinite loops in recursive types
361 while (Ty->isPointer() && Last != Ty) {
363 Ty = Ty->getElementType();
368 // Default the result to the current name
369 std::string Result = *Name;
371 // Now deal with the underlying type
372 if (Ty->isInteger()) {
373 // If its an integer type, make the name unique
374 Result = makeUniqueName(Name, Ty->isSigned());
375 } else if (Ty->isArray() || Ty->isPacked()) {
376 Ty = Ty->getElementType();
378 Result = makeUniqueName(Name, Ty->isSigned());
379 } else if (Ty->isStruct()) {
380 // Scan the fields and count the signed and unsigned fields
382 for (unsigned i = 0; i < Ty->getNumStructElements(); ++i) {
383 TypeInfo* Tmp = Ty->getElement(i);
384 if (Tmp->isInteger())
391 Result = makeUniqueName(Name, isSigned > 0);
398 // %file-prefix="UpgradeParser"
409 %token <Type> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
410 %token <Type> FLOAT DOUBLE LABEL
411 %token <String> OPAQUE ESINT64VAL EUINT64VAL SINTVAL UINTVAL FPVAL
412 %token <String> NULL_TOK UNDEF ZEROINITIALIZER TRUETOK FALSETOK
413 %token <String> TYPE VAR_ID LABELSTR STRINGCONSTANT
414 %token <String> IMPLEMENTATION BEGINTOK ENDTOK
415 %token <String> DECLARE GLOBAL CONSTANT SECTION VOLATILE
416 %token <String> TO DOTDOTDOT CONST INTERNAL LINKONCE WEAK
417 %token <String> DLLIMPORT DLLEXPORT EXTERN_WEAK APPENDING
418 %token <String> NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG
419 %token <String> ALIGN UNINITIALIZED
420 %token <String> DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
421 %token <String> CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK
422 %token <String> X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
423 %token <String> DATALAYOUT
424 %token <String> RET BR SWITCH INVOKE EXCEPT UNWIND UNREACHABLE
425 %token <String> ADD SUB MUL DIV UDIV SDIV FDIV REM UREM SREM FREM AND OR XOR
426 %token <String> SETLE SETGE SETLT SETGT SETEQ SETNE // Binary Comparators
427 %token <String> ICMP FCMP EQ NE SLT SGT SLE SGE OEQ ONE OLT OGT OLE OGE
428 %token <String> ORD UNO UEQ UNE ULT UGT ULE UGE
429 %token <String> MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR
430 %token <String> PHI_TOK SELECT SHL SHR ASHR LSHR VAARG
431 %token <String> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
432 %token <String> CAST TRUNC ZEXT SEXT FPTRUNC FPEXT FPTOUI FPTOSI UITOFP SITOFP
433 %token <String> PTRTOINT INTTOPTR BITCAST
435 %type <String> OptAssign OptLinkage OptCallingConv OptAlign OptCAlign
436 %type <String> SectionString OptSection GlobalVarAttributes GlobalVarAttribute
437 %type <String> ConstExpr DefinitionList
438 %type <String> ConstPool TargetDefinition LibrariesDefinition LibList OptName
439 %type <String> ArgVal ArgListH ArgList FunctionHeaderH BEGIN FunctionHeader END
440 %type <String> Function FunctionProto BasicBlock
441 %type <String> InstructionList BBTerminatorInst JumpTable Inst
442 %type <String> OptTailCall OptVolatile Unwind
443 %type <String> SymbolicValueRef OptSideEffect GlobalType
444 %type <String> FnDeclareLinkage BasicBlockList BigOrLittle AsmBlock
445 %type <String> Name ConstValueRef ConstVector External
446 %type <String> ShiftOps SetCondOps LogicalOps ArithmeticOps CastOps
447 %type <String> IPredicates FPredicates
449 %type <ValList> ValueRefList ValueRefListE IndexList
450 %type <TypeVec> TypeListI ArgTypeListI
452 %type <Type> IntType SIntType UIntType FPType TypesV Types
453 %type <Type> PrimType UpRTypesV UpRTypes
455 %type <String> IntVal EInt64Val
456 %type <Const> ConstVal
458 %type <Value> ValueRef ResolvedVal InstVal PHIList MemoryInst
464 // Handle constant integer size restriction and conversion...
465 IntVal : SINTVAL | UINTVAL ;
466 EInt64Val : ESINT64VAL | EUINT64VAL;
468 // Operations that are notably excluded from this list include:
469 // RET, BR, & SWITCH because they end basic blocks and are treated specially.
470 ArithmeticOps: ADD | SUB | MUL | DIV | UDIV | SDIV | FDIV
471 | REM | UREM | SREM | FREM;
472 LogicalOps : AND | OR | XOR;
473 SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE;
474 IPredicates : EQ | NE | SLT | SGT | SLE | SGE | ULT | UGT | ULE | UGE;
475 FPredicates : OEQ | ONE | OLT | OGT | OLE | OGE | ORD | UNO | UEQ | UNE
476 | ULT | UGT | ULE | UGE | TRUETOK | FALSETOK;
477 ShiftOps : SHL | SHR | ASHR | LSHR;
478 CastOps : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | FPTOUI | FPTOSI |
479 UITOFP | SITOFP | PTRTOINT | INTTOPTR | BITCAST | CAST
482 // These are some types that allow classification if we only want a particular
483 // thing... for example, only a signed, unsigned, or integral type.
484 SIntType : LONG | INT | SHORT | SBYTE;
485 UIntType : ULONG | UINT | USHORT | UBYTE;
486 IntType : SIntType | UIntType;
487 FPType : FLOAT | DOUBLE;
489 // OptAssign - Value producing statements have an optional assignment component
490 OptAssign : Name '=' {
494 $$ = new std::string("");
498 : INTERNAL | LINKONCE | WEAK | APPENDING | DLLIMPORT | DLLEXPORT
500 | /*empty*/ { $$ = new std::string(""); } ;
503 : CCC_TOK | CSRETCC_TOK | FASTCC_TOK | COLDCC_TOK | X86_STDCALLCC_TOK
505 | CC_TOK EUINT64VAL {
510 | /*empty*/ { $$ = new std::string(""); } ;
512 // OptAlign/OptCAlign - An optional alignment, and an optional alignment with
513 // a comma before it.
515 : /*empty*/ { $$ = new std::string(); }
516 | ALIGN EUINT64VAL { *$1 += " " + *$2; delete $2; $$ = $1; };
519 : /*empty*/ { $$ = new std::string(); }
520 | ',' ALIGN EUINT64VAL {
528 : SECTION STRINGCONSTANT {
534 OptSection : /*empty*/ { $$ = new std::string(); }
538 : /* empty */ { $$ = new std::string(); }
539 | ',' GlobalVarAttribute GlobalVarAttributes {
555 //===----------------------------------------------------------------------===//
556 // Types includes all predefined types... except void, because it can only be
557 // used in specific contexts (function returning void for example). To have
558 // access to it, a user must explicitly use TypesV.
561 // TypesV includes all of 'Types', but it also includes the void type.
562 TypesV : Types | VOID ;
563 UpRTypesV : UpRTypes | VOID ;
566 // Derived types are added later...
568 PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ;
569 PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL;
572 $$ = new TypeInfo($1, OpaqueTy);
575 $$ = new TypeInfo($1, UnresolvedTy);
580 | '\\' EUINT64VAL { // Type UpReference
582 $$ = new TypeInfo($2, UpRefTy);
584 | UpRTypesV '(' ArgTypeListI ')' { // Function derived type?
585 std::string newTy( $1->getNewTy() + "(");
586 for (unsigned i = 0; i < $3->size(); ++i) {
589 if ((*$3)[i]->isVoid())
592 newTy += (*$3)[i]->getNewTy();
595 $$ = new TypeInfo(new std::string(newTy), $1, $3);
597 | '[' EUINT64VAL 'x' UpRTypes ']' { // Sized array type?
599 *$2 += " x " + $4->getNewTy() + " ]";
600 uint64_t elems = atoi($2->c_str());
601 $$ = new TypeInfo($2, ArrayTy, $4, elems);
603 | '<' EUINT64VAL 'x' UpRTypes '>' { // Packed array type?
605 *$2 += " x " + $4->getNewTy() + " >";
606 uint64_t elems = atoi($2->c_str());
607 $$ = new TypeInfo($2, PackedTy, $4, elems);
609 | '{' TypeListI '}' { // Structure type?
610 std::string newTy("{");
611 for (unsigned i = 0; i < $2->size(); ++i) {
614 newTy += (*$2)[i]->getNewTy();
617 $$ = new TypeInfo(new std::string(newTy), StructTy, $2);
619 | '{' '}' { // Empty structure type?
620 $$ = new TypeInfo(new std::string("{}"), StructTy, new TypeList());
622 | '<' '{' TypeListI '}' '>' { // Packed Structure type?
623 std::string newTy("<{");
624 for (unsigned i = 0; i < $3->size(); ++i) {
627 newTy += (*$3)[i]->getNewTy();
630 $$ = new TypeInfo(new std::string(newTy), PackedStructTy, $3);
632 | '<' '{' '}' '>' { // Empty packed structure type?
633 $$ = new TypeInfo(new std::string("<{}>"), PackedStructTy, new TypeList());
635 | UpRTypes '*' { // Pointer type?
636 $$ = $1->getPointerType();
639 // TypeList - Used for struct declarations and as a basis for function type
640 // declaration type lists
647 | TypeListI ',' UpRTypes {
652 // ArgTypeList - List of types for a function type declaration...
655 | TypeListI ',' DOTDOTDOT {
657 $$->push_back(new TypeInfo("void",VoidTy));
662 $$->push_back(new TypeInfo("void",VoidTy));
669 // ConstVal - The various declarations that go into the constant pool. This
670 // production is used ONLY to represent constants that show up AFTER a 'const',
671 // 'constant' or 'global' token at global scope. Constants that can be inlined
672 // into other expressions (such as integers and constexprs) are handled by the
673 // ResolvedVal, ValueRef and ConstValueRef productions.
675 ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
677 $$.cnst = new std::string($1->getNewTy());
678 *$$.cnst += " [ " + *$3 + " ]";
683 $$.cnst = new std::string($1->getNewTy());
686 | Types 'c' STRINGCONSTANT {
688 $$.cnst = new std::string($1->getNewTy());
689 *$$.cnst += " c" + *$3;
692 | Types '<' ConstVector '>' { // Nonempty unsized arr
694 $$.cnst = new std::string($1->getNewTy());
695 *$$.cnst += " < " + *$3 + " >";
698 | Types '{' ConstVector '}' {
700 $$.cnst = new std::string($1->getNewTy());
701 *$$.cnst += " { " + *$3 + " }";
706 $$.cnst = new std::string($1->getNewTy());
711 $$.cnst = new std::string($1->getNewTy());
712 *$$.cnst += " " + *$2;
717 $$.cnst = new std::string($1->getNewTy());
718 *$$.cnst += " " + *$2;
721 | Types SymbolicValueRef {
722 std::string Name = getUniqueName($2,$1);
724 $$.cnst = new std::string($1->getNewTy());
725 *$$.cnst += " " + Name;
730 $$.cnst = new std::string($1->getNewTy());
731 *$$.cnst += " " + *$2;
734 | Types ZEROINITIALIZER {
736 $$.cnst = new std::string($1->getNewTy());
737 *$$.cnst += " " + *$2;
740 | SIntType EInt64Val { // integral constants
742 $$.cnst = new std::string($1->getNewTy());
743 *$$.cnst += " " + *$2;
746 | UIntType EInt64Val { // integral constants
748 $$.cnst = new std::string($1->getNewTy());
749 *$$.cnst += " " + *$2;
752 | BOOL TRUETOK { // Boolean constants
754 $$.cnst = new std::string($1->getNewTy());
755 *$$.cnst += " " + *$2;
758 | BOOL FALSETOK { // Boolean constants
760 $$.cnst = new std::string($1->getNewTy());
761 *$$.cnst += " " + *$2;
764 | FPType FPVAL { // Float & Double constants
766 $$.cnst = new std::string($1->getNewTy());
767 *$$.cnst += " " + *$2;
772 ConstExpr: CastOps '(' ConstVal TO Types ')' {
773 std::string source = *$3.cnst;
774 TypeInfo* DstTy = ResolveType($5);
776 // Call getCastUpgrade to upgrade the old cast
777 $$ = new std::string(getCastUpgrade(source, $3.type, DstTy, true));
779 // Nothing to upgrade, just create the cast constant expr
780 $$ = new std::string(*$1);
781 *$$ += "( " + source + " to " + $5->getNewTy() + ")";
783 delete $1; $3.destroy(); delete $4;
785 | GETELEMENTPTR '(' ConstVal IndexList ')' {
786 *$1 += "(" + *$3.cnst;
787 for (unsigned i = 0; i < $4->size(); ++i) {
788 ValueInfo& VI = (*$4)[i];
789 *$1 += ", " + *VI.val;
797 | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
798 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
799 $3.destroy(); $5.destroy(); $7.destroy();
802 | ArithmeticOps '(' ConstVal ',' ConstVal ')' {
803 const char* op = getDivRemOpcode(*$1, $3.type);
804 $$ = new std::string(op);
805 *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
806 delete $1; $3.destroy(); $5.destroy();
808 | LogicalOps '(' ConstVal ',' ConstVal ')' {
809 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
810 $3.destroy(); $5.destroy();
813 | SetCondOps '(' ConstVal ',' ConstVal ')' {
814 *$1 = getCompareOp(*$1, $3.type);
815 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
816 $3.destroy(); $5.destroy();
819 | ICMP IPredicates '(' ConstVal ',' ConstVal ')' {
820 *$1 += "(" + *$2 + "," + *$4.cnst + "," + *$6.cnst + ")";
821 delete $2; $4.destroy(); $6.destroy();
824 | FCMP FPredicates '(' ConstVal ',' ConstVal ')' {
825 *$1 += "(" + *$2 + "," + *$4.cnst + "," + *$6.cnst + ")";
826 delete $2; $4.destroy(); $6.destroy();
829 | ShiftOps '(' ConstVal ',' ConstVal ')' {
830 const char* shiftop = $1->c_str();
832 shiftop = ($3.type->isUnsigned()) ? "lshr" : "ashr";
833 $$ = new std::string(shiftop);
834 *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
835 delete $1; $3.destroy(); $5.destroy();
837 | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' {
838 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
839 $3.destroy(); $5.destroy();
842 | INSERTELEMENT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
843 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
844 $3.destroy(); $5.destroy(); $7.destroy();
847 | SHUFFLEVECTOR '(' ConstVal ',' ConstVal ',' ConstVal ')' {
848 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
849 $3.destroy(); $5.destroy(); $7.destroy();
854 // ConstVector - A list of comma separated constants.
857 : ConstVector ',' ConstVal {
858 *$1 += ", " + *$3.cnst;
862 | ConstVal { $$ = new std::string(*$1.cnst); $1.destroy(); }
866 // GlobalType - Match either GLOBAL or CONSTANT for global declarations...
867 GlobalType : GLOBAL | CONSTANT ;
870 //===----------------------------------------------------------------------===//
871 // Rules to match Modules
872 //===----------------------------------------------------------------------===//
874 // Module rule: Capture the result of parsing the whole file into a result
877 Module : DefinitionList {
880 // DefinitionList - Top level definitions
882 DefinitionList : DefinitionList Function {
885 | DefinitionList FunctionProto {
890 | DefinitionList MODULE ASM_TOK AsmBlock {
891 *O << "module asm " << ' ' << *$4 << '\n';
894 | DefinitionList IMPLEMENTATION {
895 *O << "implementation\n";
898 | ConstPool { $$ = 0; }
900 External : EXTERNAL | UNINITIALIZED { $$ = $1; *$$ = "external"; }
902 // ConstPool - Constants with optional names assigned to them.
903 ConstPool : ConstPool OptAssign TYPE TypesV {
904 EnumeratedTypes.push_back(*$4);
906 NamedTypes[*$2] = *$4;
909 *O << "type " << $4->getNewTy() << '\n';
910 delete $2; delete $3;
913 | ConstPool FunctionProto { // Function prototypes can be in const pool
918 | ConstPool MODULE ASM_TOK AsmBlock { // Asm blocks can be in the const pool
919 *O << *$2 << ' ' << *$3 << ' ' << *$4 << '\n';
920 delete $2; delete $3; delete $4;
923 | ConstPool OptAssign OptLinkage GlobalType ConstVal GlobalVarAttributes {
925 std::string Name = getUniqueName($2,$5.type);
927 Globals[Name] = *$5.type;
929 *O << *$3 << ' ' << *$4 << ' ' << *$5.cnst << ' ' << *$6 << '\n';
930 delete $2; delete $3; delete $4; delete $6;
933 | ConstPool OptAssign External GlobalType Types GlobalVarAttributes {
935 std::string Name = getUniqueName($2,$5);
939 *O << *$3 << ' ' << *$4 << ' ' << $5->getNewTy() << ' ' << *$6 << '\n';
940 delete $2; delete $3; delete $4; delete $6;
943 | ConstPool OptAssign DLLIMPORT GlobalType Types GlobalVarAttributes {
945 std::string Name = getUniqueName($2,$5);
949 *O << *$3 << ' ' << *$4 << ' ' << $5->getNewTy() << ' ' << *$6 << '\n';
950 delete $2; delete $3; delete $4; delete $6;
953 | ConstPool OptAssign EXTERN_WEAK GlobalType Types GlobalVarAttributes {
955 std::string Name = getUniqueName($2,$5);
959 *O << *$3 << ' ' << *$4 << ' ' << $5->getNewTy() << ' ' << *$6 << '\n';
960 delete $2; delete $3; delete $4; delete $6;
963 | ConstPool TARGET TargetDefinition {
964 *O << *$2 << ' ' << *$3 << '\n';
965 delete $2; delete $3;
968 | ConstPool DEPLIBS '=' LibrariesDefinition {
969 *O << *$2 << " = " << *$4 << '\n';
970 delete $2; delete $4;
973 | /* empty: end of list */ {
978 AsmBlock : STRINGCONSTANT ;
980 BigOrLittle : BIG | LITTLE
983 : ENDIAN '=' BigOrLittle {
988 | POINTERSIZE '=' EUINT64VAL {
995 | TRIPLE '=' STRINGCONSTANT {
1000 | DATALAYOUT '=' STRINGCONSTANT {
1008 $2->insert(0, "[ ");
1014 : LibList ',' STRINGCONSTANT {
1020 | /* empty: end of list */ {
1021 $$ = new std::string();
1024 //===----------------------------------------------------------------------===//
1025 // Rules to match Function Headers
1026 //===----------------------------------------------------------------------===//
1028 Name : VAR_ID | STRINGCONSTANT;
1029 OptName : Name | /*empty*/ { $$ = new std::string(); };
1031 ArgVal : Types OptName {
1032 $$ = new std::string($1->getNewTy());
1034 std::string Name = getUniqueName($2, $1);
1040 ArgListH : ArgListH ',' ArgVal {
1048 ArgList : ArgListH {
1051 | ArgListH ',' DOTDOTDOT {
1059 | /* empty */ { $$ = new std::string(); };
1062 : OptCallingConv TypesV Name '(' ArgList ')' OptSection OptAlign {
1066 *$1 += $2->getNewTy() + " " + *$3 + "(" + *$5 + ")";
1080 BEGIN : BEGINTOK { $$ = new std::string("{"); delete $1; }
1081 | '{' { $$ = new std::string ("{"); }
1084 : OptLinkage FunctionHeaderH BEGIN {
1089 *O << *$2 << ' ' << *$3 << '\n';
1090 delete $1; delete $2; delete $3;
1095 END : ENDTOK { $$ = new std::string("}"); delete $1; }
1096 | '}' { $$ = new std::string("}"); };
1098 Function : FunctionHeader BasicBlockList END {
1101 *O << *$3 << "\n\n";
1102 delete $1; delete $2; delete $3;
1107 : /*default*/ { $$ = new std::string(); }
1113 : DECLARE FnDeclareLinkage FunctionHeaderH {
1122 //===----------------------------------------------------------------------===//
1123 // Rules to match Basic Blocks
1124 //===----------------------------------------------------------------------===//
1126 OptSideEffect : /* empty */ { $$ = new std::string(); }
1130 : ESINT64VAL | EUINT64VAL | FPVAL | TRUETOK | FALSETOK | NULL_TOK | UNDEF
1132 | '<' ConstVector '>' {
1138 | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT {
1142 *$1 += " " + *$3 + ", " + *$5;
1143 delete $2; delete $3; delete $5;
1147 SymbolicValueRef : IntVal | Name ;
1149 // ValueRef - A reference to a definition... either constant or symbolic
1151 : SymbolicValueRef {
1153 $$.constant = false;
1154 $$.type = new TypeInfo();
1159 $$.type = new TypeInfo();
1163 // ResolvedVal - a <type> <value> pair. This is used only in cases where the
1164 // type immediately preceeds the value reference, and allows complex constant
1165 // pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
1166 ResolvedVal : Types ValueRef {
1168 std::string Name = getUniqueName($2.val, $1);
1172 $$.val = new std::string($1->getNewTy() + " " + Name);
1176 BasicBlockList : BasicBlockList BasicBlock {
1179 | BasicBlock { // Do not allow functions with 0 basic blocks
1184 // Basic blocks are terminated by branching instructions:
1185 // br, br/cc, switch, ret
1187 BasicBlock : InstructionList BBTerminatorInst {
1191 InstructionList : InstructionList Inst {
1192 *O << " " << *$2 << '\n';
1205 Unwind : UNWIND | EXCEPT { $$ = $1; *$$ = "unwind"; }
1207 BBTerminatorInst : RET ResolvedVal { // Return with a result...
1208 *O << " " << *$1 << ' ' << *$2.val << '\n';
1209 delete $1; $2.destroy();
1212 | RET VOID { // Return with no result...
1213 *O << " " << *$1 << ' ' << $2->getNewTy() << '\n';
1214 delete $1; delete $2;
1217 | BR LABEL ValueRef { // Unconditional Branch...
1218 *O << " " << *$1 << ' ' << $2->getNewTy() << ' ' << *$3.val << '\n';
1219 delete $1; delete $2; $3.destroy();
1221 } // Conditional Branch...
1222 | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {
1223 std::string Name = getUniqueName($3.val, $2);
1224 *O << " " << *$1 << ' ' << $2->getNewTy() << ' ' << Name << ", "
1225 << $5->getNewTy() << ' ' << *$6.val << ", " << $8->getNewTy() << ' '
1227 delete $1; delete $2; $3.destroy(); delete $5; $6.destroy();
1228 delete $8; $9.destroy();
1231 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
1232 std::string Name = getUniqueName($3.val, $2);
1233 *O << " " << *$1 << ' ' << $2->getNewTy() << ' ' << Name << ", "
1234 << $5->getNewTy() << ' ' << *$6.val << " [" << *$8 << " ]\n";
1235 delete $1; delete $2; $3.destroy(); delete $5; $6.destroy();
1239 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' {
1240 std::string Name = getUniqueName($3.val, $2);
1241 *O << " " << *$1 << ' ' << $2->getNewTy() << ' ' << Name << ", "
1242 << $5->getNewTy() << ' ' << *$6.val << "[]\n";
1243 delete $1; delete $2; $3.destroy(); delete $5; $6.destroy();
1246 | OptAssign INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')'
1247 TO LABEL ValueRef Unwind LABEL ValueRef {
1248 TypeInfo* ResTy = getFunctionReturnType($4);
1251 std::string Name = getUniqueName($1, ResTy);
1252 *O << Name << " = ";
1254 *O << *$2 << ' ' << *$3 << ' ' << $4->getNewTy() << ' ' << *$5.val << " (";
1255 for (unsigned i = 0; i < $7->size(); ++i) {
1256 ValueInfo& VI = (*$7)[i];
1258 if (i+1 < $7->size())
1262 *O << ") " << *$9 << ' ' << $10->getNewTy() << ' ' << *$11.val << ' '
1263 << *$12 << ' ' << $13->getNewTy() << ' ' << *$14.val << '\n';
1264 delete $1; delete $2; delete $3; delete $4; $5.destroy(); delete $7;
1265 delete $9; delete $10; $11.destroy(); delete $12; delete $13;
1270 *O << " " << *$1 << '\n';
1275 *O << " " << *$1 << '\n';
1280 JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
1281 *$1 += " " + $2->getNewTy() + " " + *$3 + ", " + $5->getNewTy() + " " +
1283 delete $2; delete $3; delete $5; $6.destroy();
1286 | IntType ConstValueRef ',' LABEL ValueRef {
1287 $2->insert(0, $1->getNewTy() + " " );
1288 *$2 += ", " + $4->getNewTy() + " " + *$5.val;
1289 delete $1; delete $4; $5.destroy();
1294 : OptAssign InstVal {
1296 if (deleteUselessCastFlag && *deleteUselessCastName == *$1) {
1298 $1->insert(0, "; "); // don't actually delete it, just comment it out
1299 delete deleteUselessCastName;
1301 // Get a unique name for the name of this value, based on its type.
1302 *$1 = getUniqueName($1, $2.type) + " = ";
1307 deleteUselessCastFlag = false;
1312 : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes
1313 std::string Name = getUniqueName($3.val, $1);
1314 Name.insert(0, $1->getNewTy() + "[");
1315 Name += "," + *$5.val + "]";
1316 $$.val = new std::string(Name);
1318 $3.destroy(); $5.destroy();
1320 | PHIList ',' '[' ValueRef ',' ValueRef ']' {
1321 std::string Name = getUniqueName($4.val, $1.type);
1322 *$1.val += ", [" + Name + "," + *$6.val + "]";
1323 $4.destroy(); $6.destroy();
1330 $$ = new ValueList();
1333 | ValueRefList ',' ResolvedVal {
1338 // ValueRefListE - Just like ValueRefList, except that it may also be empty!
1340 : ValueRefList { $$ = $1; }
1341 | /*empty*/ { $$ = new ValueList(); }
1353 InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
1354 const char* op = getDivRemOpcode(*$1, $2);
1355 std::string Name1 = getUniqueName($3.val, $2);
1356 std::string Name2 = getUniqueName($5.val, $2);
1357 $$.val = new std::string(op);
1358 *$$.val += " " + $2->getNewTy() + " " + Name1 + ", " + Name2;
1360 delete $1; $3.destroy(); $5.destroy();
1362 | LogicalOps Types ValueRef ',' ValueRef {
1363 std::string Name1 = getUniqueName($3.val, $2);
1364 std::string Name2 = getUniqueName($5.val, $2);
1365 *$1 += " " + $2->getNewTy() + " " + Name1 + ", " + Name2;
1368 $3.destroy(); $5.destroy();
1370 | SetCondOps Types ValueRef ',' ValueRef {
1371 std::string Name1 = getUniqueName($3.val, $2);
1372 std::string Name2 = getUniqueName($5.val, $2);
1373 *$1 = getCompareOp(*$1, $2);
1374 *$1 += " " + $2->getNewTy() + " " + Name1 + ", " + Name2;
1376 $$.type = new TypeInfo("bool",BoolTy);
1377 $3.destroy(); $5.destroy();
1379 | ICMP IPredicates Types ValueRef ',' ValueRef {
1380 std::string Name1 = getUniqueName($4.val, $3);
1381 std::string Name2 = getUniqueName($6.val, $3);
1382 *$1 += " " + *$2 + " " + $3->getNewTy() + " " + Name1 + "," + Name2;
1384 $$.type = new TypeInfo("bool",BoolTy);
1385 delete $2; $4.destroy(); $6.destroy();
1387 | FCMP FPredicates Types ValueRef ',' ValueRef {
1388 std::string Name1 = getUniqueName($4.val, $3);
1389 std::string Name2 = getUniqueName($6.val, $3);
1390 *$1 += " " + *$2 + " " + $3->getNewTy() + " " + Name1 + "," + Name2;
1392 $$.type = new TypeInfo("bool",BoolTy);
1393 delete $2; $4.destroy(); $6.destroy();
1397 $$.val->insert(0, *$1 + " ");
1400 | ShiftOps ResolvedVal ',' ResolvedVal {
1401 const char* shiftop = $1->c_str();
1403 shiftop = ($2.type->isUnsigned()) ? "lshr" : "ashr";
1404 $$.val = new std::string(shiftop);
1405 *$$.val += " " + *$2.val + ", " + *$4.val;
1407 delete $1; delete $2.val; $4.destroy();
1409 | CastOps ResolvedVal TO Types {
1410 std::string source = *$2.val;
1411 TypeInfo* SrcTy = $2.type;
1412 TypeInfo* DstTy = ResolveType($4);
1413 $$.val = new std::string();
1414 if (*$1 == "cast") {
1415 *$$.val += getCastUpgrade(source, SrcTy, DstTy, false);
1417 *$$.val += *$1 + " " + source + " to " + DstTy->getNewTy();
1420 // Check to see if this is a useless cast of a value to the same name
1421 // and the same type. Such casts will probably cause redefinition errors
1422 // when assembled and perform no code gen action so just remove them.
1423 if (*$1 == "cast" || *$1 == "bitcast")
1424 if ($2.type->isInteger() && DstTy->isInteger() &&
1425 $2.type->getBitWidth() == DstTy->getBitWidth()) {
1426 deleteUselessCastFlag = true; // Flag the "Inst" rule
1427 deleteUselessCastName = new std::string(*$2.val); // save the name
1428 size_t pos = deleteUselessCastName->find_first_of("%\"",0);
1429 if (pos != std::string::npos) {
1430 // remove the type portion before val
1431 deleteUselessCastName->erase(0, pos);
1434 delete $1; $2.destroy();
1437 | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
1438 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1441 $2.destroy(); delete $4.val; $6.destroy();
1443 | VAARG ResolvedVal ',' Types {
1444 *$1 += " " + *$2.val + ", " + $4->getNewTy();
1449 | EXTRACTELEMENT ResolvedVal ',' ResolvedVal {
1450 *$1 += " " + *$2.val + ", " + *$4.val;
1452 ResolveType($2.type);
1453 $$.type = $2.type->getElementType();
1454 delete $2.val; $4.destroy();
1456 | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
1457 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1460 delete $2.val; $4.destroy(); $6.destroy();
1462 | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal {
1463 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1466 delete $2.val; $4.destroy(); $6.destroy();
1469 *$1 += " " + *$2.val;
1474 | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' {
1479 *$1 += $3->getNewTy() + " " + *$4.val + "(";
1480 for (unsigned i = 0; i < $6->size(); ++i) {
1481 ValueInfo& VI = (*$6)[i];
1483 if (i+1 < $6->size())
1489 $$.type = getFunctionReturnType($3);
1490 delete $2; delete $3; $4.destroy(); delete $6;
1495 // IndexList - List of indices for GEP based instructions...
1497 : ',' ValueRefList { $$ = $2; }
1498 | /* empty */ { $$ = new ValueList(); }
1503 | /* empty */ { $$ = new std::string(); }
1506 MemoryInst : MALLOC Types OptCAlign {
1507 *$1 += " " + $2->getNewTy();
1511 $$.type = $2->getPointerType();
1512 delete $2; delete $3;
1514 | MALLOC Types ',' UINT ValueRef OptCAlign {
1515 std::string Name = getUniqueName($5.val, $4);
1516 *$1 += " " + $2->getNewTy() + ", " + $4->getNewTy() + " " + Name;
1520 $$.type = $2->getPointerType();
1521 delete $2; delete $4; $5.destroy(); delete $6;
1523 | ALLOCA Types OptCAlign {
1524 *$1 += " " + $2->getNewTy();
1528 $$.type = $2->getPointerType();
1529 delete $2; delete $3;
1531 | ALLOCA Types ',' UINT ValueRef OptCAlign {
1532 std::string Name = getUniqueName($5.val, $4);
1533 *$1 += " " + $2->getNewTy() + ", " + $4->getNewTy() + " " + Name;
1537 $$.type = $2->getPointerType();
1538 delete $2; delete $4; $5.destroy(); delete $6;
1540 | FREE ResolvedVal {
1541 *$1 += " " + *$2.val;
1543 $$.type = new TypeInfo("void", VoidTy);
1546 | OptVolatile LOAD Types ValueRef {
1547 std::string Name = getUniqueName($4.val, $3);
1550 *$1 += *$2 + " " + $3->getNewTy() + " " + Name;
1552 $$.type = $3->getElementType()->clone();
1553 delete $2; delete $3; $4.destroy();
1555 | OptVolatile STORE ResolvedVal ',' Types ValueRef {
1556 std::string Name = getUniqueName($6.val, $5);
1559 *$1 += *$2 + " " + *$3.val + ", " + $5->getNewTy() + " " + Name;
1561 $$.type = new TypeInfo("void", VoidTy);
1562 delete $2; $3.destroy(); delete $5; $6.destroy();
1564 | GETELEMENTPTR Types ValueRef IndexList {
1565 std::string Name = getUniqueName($3.val, $2);
1566 // Upgrade the indices
1567 for (unsigned i = 0; i < $4->size(); ++i) {
1568 ValueInfo& VI = (*$4)[i];
1569 if (VI.type->isUnsigned() && !VI.isConstant() &&
1570 VI.type->getBitWidth() < 64) {
1571 std::string* old = VI.val;
1572 *O << " %gep_upgrade" << unique << " = zext " << *old
1574 VI.val = new std::string("i64 %gep_upgrade" + llvm::utostr(unique++));
1575 VI.type->setOldTy(ULongTy);
1578 *$1 += " " + $2->getNewTy() + " " + Name;
1579 for (unsigned i = 0; i < $4->size(); ++i) {
1580 ValueInfo& VI = (*$4)[i];
1581 *$1 += ", " + *VI.val;
1584 $$.type = getGEPIndexedType($2,$4);
1585 $3.destroy(); delete $4;
1590 int yyerror(const char *ErrorMsg) {
1592 = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
1593 + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
1594 std::string errMsg = std::string(ErrorMsg) + "\n" + where + " while reading ";
1595 if (yychar == YYEMPTY || yychar == 0)
1596 errMsg += "end-of-file.";
1598 errMsg += "token: '" + std::string(Upgradetext, Upgradeleng) + "'";
1599 std::cerr << "llvm-upgrade: " << errMsg << '\n';