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";
75 out << "llvm-upgrade parse failed.\n";
80 TypeInfo* ResolveType(TypeInfo*& Ty) {
81 if (Ty->isUnresolved()) {
82 if (Ty->getNewTy()[0] == '%' && isdigit(Ty->getNewTy()[1])) {
83 unsigned ref = atoi(&((Ty->getNewTy().c_str())[1])); // skip the %
84 if (ref < EnumeratedTypes.size()) {
85 Ty = &EnumeratedTypes[ref];
88 std::string msg("Can't resolve numbered type: ");
89 msg += Ty->getNewTy();
93 TypeMap::iterator I = NamedTypes.find(Ty->getNewTy());
94 if (I != NamedTypes.end()) {
98 std::string msg("Cannot resolve type: ");
99 msg += Ty->getNewTy();
100 yyerror(msg.c_str());
104 // otherwise its already resolved.
108 static const char* getCastOpcode(
109 std::string& Source, const TypeInfo* SrcTy, const TypeInfo* DstTy)
111 unsigned SrcBits = SrcTy->getBitWidth();
112 unsigned DstBits = DstTy->getBitWidth();
113 const char* opcode = "bitcast";
114 // Run through the possibilities ...
115 if (DstTy->isIntegral()) { // Casting to integral
116 if (SrcTy->isIntegral()) { // Casting from integral
117 if (DstBits < SrcBits)
119 else if (DstBits > SrcBits) { // its an extension
120 if (SrcTy->isSigned())
121 opcode ="sext"; // signed -> SEXT
123 opcode = "zext"; // unsigned -> ZEXT
125 opcode = "bitcast"; // Same size, No-op cast
127 } else if (SrcTy->isFloatingPoint()) { // Casting from floating pt
128 if (DstTy->isSigned())
129 opcode = "fptosi"; // FP -> sint
131 opcode = "fptoui"; // FP -> uint
132 } else if (SrcTy->isPacked()) {
133 assert(DstBits == SrcTy->getBitWidth() &&
134 "Casting packed to integer of different width");
135 opcode = "bitcast"; // same size, no-op cast
137 assert(SrcTy->isPointer() &&
138 "Casting from a value that is not first-class type");
139 opcode = "ptrtoint"; // ptr -> int
141 } else if (DstTy->isFloatingPoint()) { // Casting to floating pt
142 if (SrcTy->isIntegral()) { // Casting from integral
143 if (SrcTy->isSigned())
144 opcode = "sitofp"; // sint -> FP
146 opcode = "uitofp"; // uint -> FP
147 } else if (SrcTy->isFloatingPoint()) { // Casting from floating pt
148 if (DstBits < SrcBits) {
149 opcode = "fptrunc"; // FP -> smaller FP
150 } else if (DstBits > SrcBits) {
151 opcode = "fpext"; // FP -> larger FP
153 opcode ="bitcast"; // same size, no-op cast
155 } else if (SrcTy->isPacked()) {
156 assert(DstBits == SrcTy->getBitWidth() &&
157 "Casting packed to floating point of different width");
158 opcode = "bitcast"; // same size, no-op cast
160 assert(0 && "Casting pointer or non-first class to float");
162 } else if (DstTy->isPacked()) {
163 if (SrcTy->isPacked()) {
164 assert(DstTy->getBitWidth() == SrcTy->getBitWidth() &&
165 "Casting packed to packed of different widths");
166 opcode = "bitcast"; // packed -> packed
167 } else if (DstTy->getBitWidth() == SrcBits) {
168 opcode = "bitcast"; // float/int -> packed
170 assert(!"Illegal cast to packed (wrong type or size)");
172 } else if (DstTy->isPointer()) {
173 if (SrcTy->isPointer()) {
174 opcode = "bitcast"; // ptr -> ptr
175 } else if (SrcTy->isIntegral()) {
176 opcode = "inttoptr"; // int -> ptr
178 assert(!"Casting invalid type to pointer");
181 assert(!"Casting to type that is not first-class");
186 static std::string getCastUpgrade(const std::string& Src, TypeInfo* SrcTy,
187 TypeInfo* DstTy, bool isConst)
190 std::string Source = Src;
191 if (SrcTy->isFloatingPoint() && DstTy->isPointer()) {
192 // fp -> ptr cast is no longer supported but we must upgrade this
193 // by doing a double cast: fp -> int -> ptr
195 Source = "i64 fptoui(" + Source + " to i64)";
197 *O << " %cast_upgrade" << unique << " = fptoui " << Source
199 Source = "i64 %cast_upgrade" + llvm::utostr(unique);
201 // Update the SrcTy for the getCastOpcode call below
203 SrcTy = new TypeInfo("i64", ULongTy);
204 } else if (DstTy->isBool()) {
205 // cast type %x to bool was previously defined as setne type %x, null
206 // The cast semantic is now to truncate, not compare so we must retain
207 // the original intent by replacing the cast with a setne
208 const char* comparator = SrcTy->isPointer() ? ", null" :
209 (SrcTy->isFloatingPoint() ? ", 0.0" :
210 (SrcTy->isBool() ? ", false" : ", 0"));
211 const char* compareOp = SrcTy->isFloatingPoint() ? "fcmp one " : "icmp ne ";
213 Result = "(" + Source + comparator + ")";
214 Result = compareOp + Result;
216 Result = compareOp + Source + comparator;
217 return Result; // skip cast processing below
221 std::string Opcode(getCastOpcode(Source, SrcTy, DstTy));
223 Result += Opcode + "( " + Source + " to " + DstTy->getNewTy() + ")";
225 Result += Opcode + " " + Source + " to " + DstTy->getNewTy();
229 const char* getDivRemOpcode(const std::string& opcode, TypeInfo* TI) {
230 const char* op = opcode.c_str();
231 const TypeInfo* Ty = ResolveType(TI);
233 Ty = Ty->getElementType();
235 if (Ty->isFloatingPoint())
237 else if (Ty->isUnsigned())
239 else if (Ty->isSigned())
242 yyerror("Invalid type for div instruction");
243 else if (opcode == "rem")
244 if (Ty->isFloatingPoint())
246 else if (Ty->isUnsigned())
248 else if (Ty->isSigned())
251 yyerror("Invalid type for rem instruction");
256 getCompareOp(const std::string& setcc, const TypeInfo* TI) {
257 assert(setcc.length() == 5);
260 assert(cc1 == 'e' || cc1 == 'n' || cc1 == 'l' || cc1 == 'g');
261 assert(cc2 == 'q' || cc2 == 'e' || cc2 == 'e' || cc2 == 't');
262 std::string result("xcmp xxx");
265 if (TI->isFloatingPoint()) {
269 result[5] = 'u'; // NE maps to unordered
271 result[5] = 'o'; // everything else maps to ordered
272 } else if (TI->isIntegral() || TI->isPointer()) {
274 if ((cc1 == 'e' && cc2 == 'q') || (cc1 == 'n' && cc2 == 'e'))
276 else if (TI->isSigned())
278 else if (TI->isUnsigned() || TI->isPointer() || TI->isBool())
281 yyerror("Invalid integral type for setcc");
286 static TypeInfo* getFunctionReturnType(TypeInfo* PFTy) {
288 if (PFTy->isPointer()) {
289 TypeInfo* ElemTy = PFTy->getElementType();
291 if (ElemTy->isFunction())
292 return ElemTy->getResultType()->clone();
293 } else if (PFTy->isFunction()) {
294 return PFTy->getResultType()->clone();
296 return PFTy->clone();
299 typedef std::vector<TypeInfo*> UpRefStack;
300 static TypeInfo* ResolveUpReference(TypeInfo* Ty, UpRefStack* stack) {
301 assert(Ty->isUpReference() && "Can't resolve a non-upreference");
302 unsigned upref = atoi(&((Ty->getNewTy().c_str())[1])); // skip the slash
303 assert(upref < stack->size() && "Invalid up reference");
304 return (*stack)[upref - stack->size() - 1];
307 static TypeInfo* getGEPIndexedType(TypeInfo* PTy, ValueList* idxs) {
308 TypeInfo* Result = ResolveType(PTy);
309 assert(PTy->isPointer() && "GEP Operand is not a pointer?");
311 for (unsigned i = 0; i < idxs->size(); ++i) {
312 if (Result->isComposite()) {
313 Result = Result->getIndexedType((*idxs)[i]);
315 stack.push_back(Result);
317 yyerror("Invalid type for index");
319 // Resolve upreferences so we can return a more natural type
320 if (Result->isPointer()) {
321 if (Result->getElementType()->isUpReference()) {
322 stack.push_back(Result);
323 Result = ResolveUpReference(Result->getElementType(), &stack);
325 } else if (Result->isUpReference()) {
326 Result = ResolveUpReference(Result->getElementType(), &stack);
328 return Result->getPointerType();
331 static std::string makeUniqueName(const std::string *Name, bool isSigned) {
332 const char *suffix = ".u";
335 if ((*Name)[Name->size()-1] == '"') {
336 std::string Result(*Name);
337 Result.insert(Name->size()-1, suffix);
340 return *Name + suffix;
343 // This function handles appending .u or .s to integer value names that
344 // were previously unsigned or signed, respectively. This avoids name
345 // collisions since the unsigned and signed type planes have collapsed
346 // into a single signless type plane.
347 static std::string getUniqueName(const std::string *Name, TypeInfo* Ty) {
348 // If its not a symbolic name, don't modify it, probably a constant val.
349 if ((*Name)[0] != '%' && (*Name)[0] != '"')
351 // If its a numeric reference, just leave it alone.
352 if (isdigit((*Name)[1]))
358 // Remove as many levels of pointer nesting that we have.
359 if (Ty->isPointer()) {
360 // Avoid infinite loops in recursive types
362 while (Ty->isPointer() && Last != Ty) {
364 Ty = Ty->getElementType();
369 // Default the result to the current name
370 std::string Result = *Name;
372 // Now deal with the underlying type
373 if (Ty->isInteger()) {
374 // If its an integer type, make the name unique
375 Result = makeUniqueName(Name, Ty->isSigned());
376 } else if (Ty->isArray() || Ty->isPacked()) {
377 Ty = Ty->getElementType();
379 Result = makeUniqueName(Name, Ty->isSigned());
380 } else if (Ty->isStruct()) {
381 // Scan the fields and count the signed and unsigned fields
383 for (unsigned i = 0; i < Ty->getNumStructElements(); ++i) {
384 TypeInfo* Tmp = Ty->getElement(i);
385 if (Tmp->isInteger())
392 Result = makeUniqueName(Name, isSigned > 0);
399 // %file-prefix="UpgradeParser"
410 %token <Type> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
411 %token <Type> FLOAT DOUBLE LABEL
412 %token <String> OPAQUE ESINT64VAL EUINT64VAL SINTVAL UINTVAL FPVAL
413 %token <String> NULL_TOK UNDEF ZEROINITIALIZER TRUETOK FALSETOK
414 %token <String> TYPE VAR_ID LABELSTR STRINGCONSTANT
415 %token <String> IMPLEMENTATION BEGINTOK ENDTOK
416 %token <String> DECLARE GLOBAL CONSTANT SECTION VOLATILE
417 %token <String> TO DOTDOTDOT CONST INTERNAL LINKONCE WEAK
418 %token <String> DLLIMPORT DLLEXPORT EXTERN_WEAK APPENDING
419 %token <String> NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG
420 %token <String> ALIGN UNINITIALIZED
421 %token <String> DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
422 %token <String> CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK
423 %token <String> X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
424 %token <String> DATALAYOUT
425 %token <String> RET BR SWITCH INVOKE EXCEPT UNWIND UNREACHABLE
426 %token <String> ADD SUB MUL DIV UDIV SDIV FDIV REM UREM SREM FREM AND OR XOR
427 %token <String> SETLE SETGE SETLT SETGT SETEQ SETNE // Binary Comparators
428 %token <String> ICMP FCMP EQ NE SLT SGT SLE SGE OEQ ONE OLT OGT OLE OGE
429 %token <String> ORD UNO UEQ UNE ULT UGT ULE UGE
430 %token <String> MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR
431 %token <String> PHI_TOK SELECT SHL SHR ASHR LSHR VAARG
432 %token <String> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
433 %token <String> CAST TRUNC ZEXT SEXT FPTRUNC FPEXT FPTOUI FPTOSI UITOFP SITOFP
434 %token <String> PTRTOINT INTTOPTR BITCAST
436 %type <String> OptAssign OptLinkage OptCallingConv OptAlign OptCAlign
437 %type <String> SectionString OptSection GlobalVarAttributes GlobalVarAttribute
438 %type <String> ConstExpr DefinitionList
439 %type <String> ConstPool TargetDefinition LibrariesDefinition LibList OptName
440 %type <String> ArgVal ArgListH ArgList FunctionHeaderH BEGIN FunctionHeader END
441 %type <String> Function FunctionProto BasicBlock
442 %type <String> InstructionList BBTerminatorInst JumpTable Inst
443 %type <String> OptTailCall OptVolatile Unwind
444 %type <String> SymbolicValueRef OptSideEffect GlobalType
445 %type <String> FnDeclareLinkage BasicBlockList BigOrLittle AsmBlock
446 %type <String> Name ConstValueRef ConstVector External
447 %type <String> ShiftOps SetCondOps LogicalOps ArithmeticOps CastOps
448 %type <String> IPredicates FPredicates
450 %type <ValList> ValueRefList ValueRefListE IndexList
451 %type <TypeVec> TypeListI ArgTypeListI
453 %type <Type> IntType SIntType UIntType FPType TypesV Types
454 %type <Type> PrimType UpRTypesV UpRTypes
456 %type <String> IntVal EInt64Val
457 %type <Const> ConstVal
459 %type <Value> ValueRef ResolvedVal InstVal PHIList MemoryInst
465 // Handle constant integer size restriction and conversion...
466 IntVal : SINTVAL | UINTVAL ;
467 EInt64Val : ESINT64VAL | EUINT64VAL;
469 // Operations that are notably excluded from this list include:
470 // RET, BR, & SWITCH because they end basic blocks and are treated specially.
471 ArithmeticOps: ADD | SUB | MUL | DIV | UDIV | SDIV | FDIV
472 | REM | UREM | SREM | FREM;
473 LogicalOps : AND | OR | XOR;
474 SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE;
475 IPredicates : EQ | NE | SLT | SGT | SLE | SGE | ULT | UGT | ULE | UGE;
476 FPredicates : OEQ | ONE | OLT | OGT | OLE | OGE | ORD | UNO | UEQ | UNE
477 | ULT | UGT | ULE | UGE | TRUETOK | FALSETOK;
478 ShiftOps : SHL | SHR | ASHR | LSHR;
479 CastOps : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | FPTOUI | FPTOSI |
480 UITOFP | SITOFP | PTRTOINT | INTTOPTR | BITCAST | CAST
483 // These are some types that allow classification if we only want a particular
484 // thing... for example, only a signed, unsigned, or integral type.
485 SIntType : LONG | INT | SHORT | SBYTE;
486 UIntType : ULONG | UINT | USHORT | UBYTE;
487 IntType : SIntType | UIntType;
488 FPType : FLOAT | DOUBLE;
490 // OptAssign - Value producing statements have an optional assignment component
491 OptAssign : Name '=' {
495 $$ = new std::string("");
499 : INTERNAL | LINKONCE | WEAK | APPENDING | DLLIMPORT | DLLEXPORT
501 | /*empty*/ { $$ = new std::string(""); } ;
504 : CCC_TOK | CSRETCC_TOK | FASTCC_TOK | COLDCC_TOK | X86_STDCALLCC_TOK
506 | CC_TOK EUINT64VAL {
511 | /*empty*/ { $$ = new std::string(""); } ;
513 // OptAlign/OptCAlign - An optional alignment, and an optional alignment with
514 // a comma before it.
516 : /*empty*/ { $$ = new std::string(); }
517 | ALIGN EUINT64VAL { *$1 += " " + *$2; delete $2; $$ = $1; };
520 : /*empty*/ { $$ = new std::string(); }
521 | ',' ALIGN EUINT64VAL {
529 : SECTION STRINGCONSTANT {
535 OptSection : /*empty*/ { $$ = new std::string(); }
539 : /* empty */ { $$ = new std::string(); }
540 | ',' GlobalVarAttribute GlobalVarAttributes {
556 //===----------------------------------------------------------------------===//
557 // Types includes all predefined types... except void, because it can only be
558 // used in specific contexts (function returning void for example). To have
559 // access to it, a user must explicitly use TypesV.
562 // TypesV includes all of 'Types', but it also includes the void type.
563 TypesV : Types | VOID ;
564 UpRTypesV : UpRTypes | VOID ;
567 // Derived types are added later...
569 PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ;
570 PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL;
573 $$ = new TypeInfo($1, OpaqueTy);
576 $$ = new TypeInfo($1, UnresolvedTy);
581 | '\\' EUINT64VAL { // Type UpReference
583 $$ = new TypeInfo($2, UpRefTy);
585 | UpRTypesV '(' ArgTypeListI ')' { // Function derived type?
586 std::string newTy( $1->getNewTy() + "(");
587 for (unsigned i = 0; i < $3->size(); ++i) {
590 if ((*$3)[i]->isVoid())
593 newTy += (*$3)[i]->getNewTy();
596 $$ = new TypeInfo(new std::string(newTy), $1, $3);
598 | '[' EUINT64VAL 'x' UpRTypes ']' { // Sized array type?
600 *$2 += " x " + $4->getNewTy() + " ]";
601 uint64_t elems = atoi($2->c_str());
602 $$ = new TypeInfo($2, ArrayTy, $4, elems);
604 | '<' EUINT64VAL 'x' UpRTypes '>' { // Packed array type?
606 *$2 += " x " + $4->getNewTy() + " >";
607 uint64_t elems = atoi($2->c_str());
608 $$ = new TypeInfo($2, PackedTy, $4, elems);
610 | '{' TypeListI '}' { // Structure type?
611 std::string newTy("{");
612 for (unsigned i = 0; i < $2->size(); ++i) {
615 newTy += (*$2)[i]->getNewTy();
618 $$ = new TypeInfo(new std::string(newTy), StructTy, $2);
620 | '{' '}' { // Empty structure type?
621 $$ = new TypeInfo(new std::string("{}"), StructTy, new TypeList());
623 | '<' '{' TypeListI '}' '>' { // Packed Structure type?
624 std::string newTy("<{");
625 for (unsigned i = 0; i < $3->size(); ++i) {
628 newTy += (*$3)[i]->getNewTy();
631 $$ = new TypeInfo(new std::string(newTy), PackedStructTy, $3);
633 | '<' '{' '}' '>' { // Empty packed structure type?
634 $$ = new TypeInfo(new std::string("<{}>"), PackedStructTy, new TypeList());
636 | UpRTypes '*' { // Pointer type?
637 $$ = $1->getPointerType();
640 // TypeList - Used for struct declarations and as a basis for function type
641 // declaration type lists
648 | TypeListI ',' UpRTypes {
653 // ArgTypeList - List of types for a function type declaration...
656 | TypeListI ',' DOTDOTDOT {
658 $$->push_back(new TypeInfo("void",VoidTy));
663 $$->push_back(new TypeInfo("void",VoidTy));
670 // ConstVal - The various declarations that go into the constant pool. This
671 // production is used ONLY to represent constants that show up AFTER a 'const',
672 // 'constant' or 'global' token at global scope. Constants that can be inlined
673 // into other expressions (such as integers and constexprs) are handled by the
674 // ResolvedVal, ValueRef and ConstValueRef productions.
676 ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
678 $$.cnst = new std::string($1->getNewTy());
679 *$$.cnst += " [ " + *$3 + " ]";
684 $$.cnst = new std::string($1->getNewTy());
687 | Types 'c' STRINGCONSTANT {
689 $$.cnst = new std::string($1->getNewTy());
690 *$$.cnst += " c" + *$3;
693 | Types '<' ConstVector '>' { // Nonempty unsized arr
695 $$.cnst = new std::string($1->getNewTy());
696 *$$.cnst += " < " + *$3 + " >";
699 | Types '{' ConstVector '}' {
701 $$.cnst = new std::string($1->getNewTy());
702 *$$.cnst += " { " + *$3 + " }";
707 $$.cnst = new std::string($1->getNewTy());
712 $$.cnst = new std::string($1->getNewTy());
713 *$$.cnst += " " + *$2;
718 $$.cnst = new std::string($1->getNewTy());
719 *$$.cnst += " " + *$2;
722 | Types SymbolicValueRef {
723 std::string Name = getUniqueName($2,$1);
725 $$.cnst = new std::string($1->getNewTy());
726 *$$.cnst += " " + Name;
731 $$.cnst = new std::string($1->getNewTy());
732 *$$.cnst += " " + *$2;
735 | Types ZEROINITIALIZER {
737 $$.cnst = new std::string($1->getNewTy());
738 *$$.cnst += " " + *$2;
741 | SIntType EInt64Val { // integral constants
743 $$.cnst = new std::string($1->getNewTy());
744 *$$.cnst += " " + *$2;
747 | UIntType EInt64Val { // integral constants
749 $$.cnst = new std::string($1->getNewTy());
750 *$$.cnst += " " + *$2;
753 | BOOL TRUETOK { // Boolean constants
755 $$.cnst = new std::string($1->getNewTy());
756 *$$.cnst += " " + *$2;
759 | BOOL FALSETOK { // Boolean constants
761 $$.cnst = new std::string($1->getNewTy());
762 *$$.cnst += " " + *$2;
765 | FPType FPVAL { // Float & Double constants
767 $$.cnst = new std::string($1->getNewTy());
768 *$$.cnst += " " + *$2;
773 ConstExpr: CastOps '(' ConstVal TO Types ')' {
774 std::string source = *$3.cnst;
775 TypeInfo* DstTy = ResolveType($5);
777 // Call getCastUpgrade to upgrade the old cast
778 $$ = new std::string(getCastUpgrade(source, $3.type, DstTy, true));
780 // Nothing to upgrade, just create the cast constant expr
781 $$ = new std::string(*$1);
782 *$$ += "( " + source + " to " + $5->getNewTy() + ")";
784 delete $1; $3.destroy(); delete $4;
786 | GETELEMENTPTR '(' ConstVal IndexList ')' {
787 *$1 += "(" + *$3.cnst;
788 for (unsigned i = 0; i < $4->size(); ++i) {
789 ValueInfo& VI = (*$4)[i];
790 *$1 += ", " + *VI.val;
798 | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
799 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
800 $3.destroy(); $5.destroy(); $7.destroy();
803 | ArithmeticOps '(' ConstVal ',' ConstVal ')' {
804 const char* op = getDivRemOpcode(*$1, $3.type);
805 $$ = new std::string(op);
806 *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
807 delete $1; $3.destroy(); $5.destroy();
809 | LogicalOps '(' ConstVal ',' ConstVal ')' {
810 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
811 $3.destroy(); $5.destroy();
814 | SetCondOps '(' ConstVal ',' ConstVal ')' {
815 *$1 = getCompareOp(*$1, $3.type);
816 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
817 $3.destroy(); $5.destroy();
820 | ICMP IPredicates '(' ConstVal ',' ConstVal ')' {
821 *$1 += "(" + *$2 + "," + *$4.cnst + "," + *$6.cnst + ")";
822 delete $2; $4.destroy(); $6.destroy();
825 | FCMP FPredicates '(' ConstVal ',' ConstVal ')' {
826 *$1 += "(" + *$2 + "," + *$4.cnst + "," + *$6.cnst + ")";
827 delete $2; $4.destroy(); $6.destroy();
830 | ShiftOps '(' ConstVal ',' ConstVal ')' {
831 const char* shiftop = $1->c_str();
833 shiftop = ($3.type->isUnsigned()) ? "lshr" : "ashr";
834 $$ = new std::string(shiftop);
835 *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")";
836 delete $1; $3.destroy(); $5.destroy();
838 | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' {
839 *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")";
840 $3.destroy(); $5.destroy();
843 | INSERTELEMENT '(' ConstVal ',' ConstVal ',' ConstVal ')' {
844 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
845 $3.destroy(); $5.destroy(); $7.destroy();
848 | SHUFFLEVECTOR '(' ConstVal ',' ConstVal ',' ConstVal ')' {
849 *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")";
850 $3.destroy(); $5.destroy(); $7.destroy();
855 // ConstVector - A list of comma separated constants.
858 : ConstVector ',' ConstVal {
859 *$1 += ", " + *$3.cnst;
863 | ConstVal { $$ = new std::string(*$1.cnst); $1.destroy(); }
867 // GlobalType - Match either GLOBAL or CONSTANT for global declarations...
868 GlobalType : GLOBAL | CONSTANT ;
871 //===----------------------------------------------------------------------===//
872 // Rules to match Modules
873 //===----------------------------------------------------------------------===//
875 // Module rule: Capture the result of parsing the whole file into a result
878 Module : DefinitionList {
881 // DefinitionList - Top level definitions
883 DefinitionList : DefinitionList Function {
886 | DefinitionList FunctionProto {
891 | DefinitionList MODULE ASM_TOK AsmBlock {
892 *O << "module asm " << ' ' << *$4 << '\n';
895 | DefinitionList IMPLEMENTATION {
896 *O << "implementation\n";
899 | ConstPool { $$ = 0; }
901 External : EXTERNAL | UNINITIALIZED { $$ = $1; *$$ = "external"; }
903 // ConstPool - Constants with optional names assigned to them.
904 ConstPool : ConstPool OptAssign TYPE TypesV {
905 EnumeratedTypes.push_back(*$4);
907 NamedTypes[*$2] = *$4;
910 *O << "type " << $4->getNewTy() << '\n';
911 delete $2; delete $3;
914 | ConstPool FunctionProto { // Function prototypes can be in const pool
919 | ConstPool MODULE ASM_TOK AsmBlock { // Asm blocks can be in the const pool
920 *O << *$2 << ' ' << *$3 << ' ' << *$4 << '\n';
921 delete $2; delete $3; delete $4;
924 | ConstPool OptAssign OptLinkage GlobalType ConstVal GlobalVarAttributes {
926 std::string Name = getUniqueName($2,$5.type);
928 Globals[Name] = *$5.type;
930 *O << *$3 << ' ' << *$4 << ' ' << *$5.cnst << ' ' << *$6 << '\n';
931 delete $2; delete $3; delete $4; delete $6;
934 | ConstPool OptAssign External GlobalType Types GlobalVarAttributes {
936 std::string Name = getUniqueName($2,$5);
940 *O << *$3 << ' ' << *$4 << ' ' << $5->getNewTy() << ' ' << *$6 << '\n';
941 delete $2; delete $3; delete $4; delete $6;
944 | ConstPool OptAssign DLLIMPORT GlobalType Types GlobalVarAttributes {
946 std::string Name = getUniqueName($2,$5);
950 *O << *$3 << ' ' << *$4 << ' ' << $5->getNewTy() << ' ' << *$6 << '\n';
951 delete $2; delete $3; delete $4; delete $6;
954 | ConstPool OptAssign EXTERN_WEAK GlobalType Types GlobalVarAttributes {
956 std::string Name = getUniqueName($2,$5);
960 *O << *$3 << ' ' << *$4 << ' ' << $5->getNewTy() << ' ' << *$6 << '\n';
961 delete $2; delete $3; delete $4; delete $6;
964 | ConstPool TARGET TargetDefinition {
965 *O << *$2 << ' ' << *$3 << '\n';
966 delete $2; delete $3;
969 | ConstPool DEPLIBS '=' LibrariesDefinition {
970 *O << *$2 << " = " << *$4 << '\n';
971 delete $2; delete $4;
974 | /* empty: end of list */ {
979 AsmBlock : STRINGCONSTANT ;
981 BigOrLittle : BIG | LITTLE
984 : ENDIAN '=' BigOrLittle {
989 | POINTERSIZE '=' EUINT64VAL {
996 | TRIPLE '=' STRINGCONSTANT {
1001 | DATALAYOUT '=' STRINGCONSTANT {
1009 $2->insert(0, "[ ");
1015 : LibList ',' STRINGCONSTANT {
1021 | /* empty: end of list */ {
1022 $$ = new std::string();
1025 //===----------------------------------------------------------------------===//
1026 // Rules to match Function Headers
1027 //===----------------------------------------------------------------------===//
1029 Name : VAR_ID | STRINGCONSTANT;
1030 OptName : Name | /*empty*/ { $$ = new std::string(); };
1032 ArgVal : Types OptName {
1033 $$ = new std::string($1->getNewTy());
1035 std::string Name = getUniqueName($2, $1);
1041 ArgListH : ArgListH ',' ArgVal {
1049 ArgList : ArgListH {
1052 | ArgListH ',' DOTDOTDOT {
1060 | /* empty */ { $$ = new std::string(); };
1063 : OptCallingConv TypesV Name '(' ArgList ')' OptSection OptAlign {
1067 *$1 += $2->getNewTy() + " " + *$3 + "(" + *$5 + ")";
1081 BEGIN : BEGINTOK { $$ = new std::string("{"); delete $1; }
1082 | '{' { $$ = new std::string ("{"); }
1085 : OptLinkage FunctionHeaderH BEGIN {
1090 *O << *$2 << ' ' << *$3 << '\n';
1091 delete $1; delete $2; delete $3;
1096 END : ENDTOK { $$ = new std::string("}"); delete $1; }
1097 | '}' { $$ = new std::string("}"); };
1099 Function : FunctionHeader BasicBlockList END {
1102 *O << *$3 << "\n\n";
1103 delete $1; delete $2; delete $3;
1108 : /*default*/ { $$ = new std::string(); }
1114 : DECLARE FnDeclareLinkage FunctionHeaderH {
1123 //===----------------------------------------------------------------------===//
1124 // Rules to match Basic Blocks
1125 //===----------------------------------------------------------------------===//
1127 OptSideEffect : /* empty */ { $$ = new std::string(); }
1131 : ESINT64VAL | EUINT64VAL | FPVAL | TRUETOK | FALSETOK | NULL_TOK | UNDEF
1133 | '<' ConstVector '>' {
1139 | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT {
1143 *$1 += " " + *$3 + ", " + *$5;
1144 delete $2; delete $3; delete $5;
1148 SymbolicValueRef : IntVal | Name ;
1150 // ValueRef - A reference to a definition... either constant or symbolic
1152 : SymbolicValueRef {
1154 $$.constant = false;
1155 $$.type = new TypeInfo();
1160 $$.type = new TypeInfo();
1164 // ResolvedVal - a <type> <value> pair. This is used only in cases where the
1165 // type immediately preceeds the value reference, and allows complex constant
1166 // pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
1167 ResolvedVal : Types ValueRef {
1169 std::string Name = getUniqueName($2.val, $1);
1173 $$.val = new std::string($1->getNewTy() + " " + Name);
1177 BasicBlockList : BasicBlockList BasicBlock {
1180 | BasicBlock { // Do not allow functions with 0 basic blocks
1185 // Basic blocks are terminated by branching instructions:
1186 // br, br/cc, switch, ret
1188 BasicBlock : InstructionList BBTerminatorInst {
1192 InstructionList : InstructionList Inst {
1193 *O << " " << *$2 << '\n';
1206 Unwind : UNWIND | EXCEPT { $$ = $1; *$$ = "unwind"; }
1208 BBTerminatorInst : RET ResolvedVal { // Return with a result...
1209 *O << " " << *$1 << ' ' << *$2.val << '\n';
1210 delete $1; $2.destroy();
1213 | RET VOID { // Return with no result...
1214 *O << " " << *$1 << ' ' << $2->getNewTy() << '\n';
1215 delete $1; delete $2;
1218 | BR LABEL ValueRef { // Unconditional Branch...
1219 *O << " " << *$1 << ' ' << $2->getNewTy() << ' ' << *$3.val << '\n';
1220 delete $1; delete $2; $3.destroy();
1222 } // Conditional Branch...
1223 | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {
1224 std::string Name = getUniqueName($3.val, $2);
1225 *O << " " << *$1 << ' ' << $2->getNewTy() << ' ' << Name << ", "
1226 << $5->getNewTy() << ' ' << *$6.val << ", " << $8->getNewTy() << ' '
1228 delete $1; delete $2; $3.destroy(); delete $5; $6.destroy();
1229 delete $8; $9.destroy();
1232 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
1233 std::string Name = getUniqueName($3.val, $2);
1234 *O << " " << *$1 << ' ' << $2->getNewTy() << ' ' << Name << ", "
1235 << $5->getNewTy() << ' ' << *$6.val << " [" << *$8 << " ]\n";
1236 delete $1; delete $2; $3.destroy(); delete $5; $6.destroy();
1240 | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' {
1241 std::string Name = getUniqueName($3.val, $2);
1242 *O << " " << *$1 << ' ' << $2->getNewTy() << ' ' << Name << ", "
1243 << $5->getNewTy() << ' ' << *$6.val << "[]\n";
1244 delete $1; delete $2; $3.destroy(); delete $5; $6.destroy();
1247 | OptAssign INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')'
1248 TO LABEL ValueRef Unwind LABEL ValueRef {
1249 TypeInfo* ResTy = getFunctionReturnType($4);
1252 std::string Name = getUniqueName($1, ResTy);
1253 *O << Name << " = ";
1255 *O << *$2 << ' ' << *$3 << ' ' << $4->getNewTy() << ' ' << *$5.val << " (";
1256 for (unsigned i = 0; i < $7->size(); ++i) {
1257 ValueInfo& VI = (*$7)[i];
1259 if (i+1 < $7->size())
1263 *O << ") " << *$9 << ' ' << $10->getNewTy() << ' ' << *$11.val << ' '
1264 << *$12 << ' ' << $13->getNewTy() << ' ' << *$14.val << '\n';
1265 delete $1; delete $2; delete $3; delete $4; $5.destroy(); delete $7;
1266 delete $9; delete $10; $11.destroy(); delete $12; delete $13;
1271 *O << " " << *$1 << '\n';
1276 *O << " " << *$1 << '\n';
1281 JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
1282 *$1 += " " + $2->getNewTy() + " " + *$3 + ", " + $5->getNewTy() + " " +
1284 delete $2; delete $3; delete $5; $6.destroy();
1287 | IntType ConstValueRef ',' LABEL ValueRef {
1288 $2->insert(0, $1->getNewTy() + " " );
1289 *$2 += ", " + $4->getNewTy() + " " + *$5.val;
1290 delete $1; delete $4; $5.destroy();
1295 : OptAssign InstVal {
1297 if (deleteUselessCastFlag && *deleteUselessCastName == *$1) {
1299 $1->insert(0, "; "); // don't actually delete it, just comment it out
1300 delete deleteUselessCastName;
1302 // Get a unique name for the name of this value, based on its type.
1303 *$1 = getUniqueName($1, $2.type) + " = ";
1308 deleteUselessCastFlag = false;
1313 : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes
1314 std::string Name = getUniqueName($3.val, $1);
1315 Name.insert(0, $1->getNewTy() + "[");
1316 Name += "," + *$5.val + "]";
1317 $$.val = new std::string(Name);
1319 $3.destroy(); $5.destroy();
1321 | PHIList ',' '[' ValueRef ',' ValueRef ']' {
1322 std::string Name = getUniqueName($4.val, $1.type);
1323 *$1.val += ", [" + Name + "," + *$6.val + "]";
1324 $4.destroy(); $6.destroy();
1331 $$ = new ValueList();
1334 | ValueRefList ',' ResolvedVal {
1339 // ValueRefListE - Just like ValueRefList, except that it may also be empty!
1341 : ValueRefList { $$ = $1; }
1342 | /*empty*/ { $$ = new ValueList(); }
1354 InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
1355 const char* op = getDivRemOpcode(*$1, $2);
1356 std::string Name1 = getUniqueName($3.val, $2);
1357 std::string Name2 = getUniqueName($5.val, $2);
1358 $$.val = new std::string(op);
1359 *$$.val += " " + $2->getNewTy() + " " + Name1 + ", " + Name2;
1361 delete $1; $3.destroy(); $5.destroy();
1363 | LogicalOps Types ValueRef ',' ValueRef {
1364 std::string Name1 = getUniqueName($3.val, $2);
1365 std::string Name2 = getUniqueName($5.val, $2);
1366 *$1 += " " + $2->getNewTy() + " " + Name1 + ", " + Name2;
1369 $3.destroy(); $5.destroy();
1371 | SetCondOps Types ValueRef ',' ValueRef {
1372 std::string Name1 = getUniqueName($3.val, $2);
1373 std::string Name2 = getUniqueName($5.val, $2);
1374 *$1 = getCompareOp(*$1, $2);
1375 *$1 += " " + $2->getNewTy() + " " + Name1 + ", " + Name2;
1377 $$.type = new TypeInfo("bool",BoolTy);
1378 $3.destroy(); $5.destroy();
1380 | ICMP IPredicates Types ValueRef ',' ValueRef {
1381 std::string Name1 = getUniqueName($4.val, $3);
1382 std::string Name2 = getUniqueName($6.val, $3);
1383 *$1 += " " + *$2 + " " + $3->getNewTy() + " " + Name1 + "," + Name2;
1385 $$.type = new TypeInfo("bool",BoolTy);
1386 delete $2; $4.destroy(); $6.destroy();
1388 | FCMP FPredicates Types ValueRef ',' ValueRef {
1389 std::string Name1 = getUniqueName($4.val, $3);
1390 std::string Name2 = getUniqueName($6.val, $3);
1391 *$1 += " " + *$2 + " " + $3->getNewTy() + " " + Name1 + "," + Name2;
1393 $$.type = new TypeInfo("bool",BoolTy);
1394 delete $2; $4.destroy(); $6.destroy();
1398 $$.val->insert(0, *$1 + " ");
1401 | ShiftOps ResolvedVal ',' ResolvedVal {
1402 const char* shiftop = $1->c_str();
1404 shiftop = ($2.type->isUnsigned()) ? "lshr" : "ashr";
1405 $$.val = new std::string(shiftop);
1406 *$$.val += " " + *$2.val + ", " + *$4.val;
1408 delete $1; delete $2.val; $4.destroy();
1410 | CastOps ResolvedVal TO Types {
1411 std::string source = *$2.val;
1412 TypeInfo* SrcTy = $2.type;
1413 TypeInfo* DstTy = ResolveType($4);
1414 $$.val = new std::string();
1415 if (*$1 == "cast") {
1416 *$$.val += getCastUpgrade(source, SrcTy, DstTy, false);
1418 *$$.val += *$1 + " " + source + " to " + DstTy->getNewTy();
1421 // Check to see if this is a useless cast of a value to the same name
1422 // and the same type. Such casts will probably cause redefinition errors
1423 // when assembled and perform no code gen action so just remove them.
1424 if (*$1 == "cast" || *$1 == "bitcast")
1425 if ($2.type->isInteger() && DstTy->isInteger() &&
1426 $2.type->getBitWidth() == DstTy->getBitWidth()) {
1427 deleteUselessCastFlag = true; // Flag the "Inst" rule
1428 deleteUselessCastName = new std::string(*$2.val); // save the name
1429 size_t pos = deleteUselessCastName->find_first_of("%\"",0);
1430 if (pos != std::string::npos) {
1431 // remove the type portion before val
1432 deleteUselessCastName->erase(0, pos);
1435 delete $1; $2.destroy();
1438 | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
1439 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1442 $2.destroy(); delete $4.val; $6.destroy();
1444 | VAARG ResolvedVal ',' Types {
1445 *$1 += " " + *$2.val + ", " + $4->getNewTy();
1450 | EXTRACTELEMENT ResolvedVal ',' ResolvedVal {
1451 *$1 += " " + *$2.val + ", " + *$4.val;
1453 ResolveType($2.type);
1454 $$.type = $2.type->getElementType();
1455 delete $2.val; $4.destroy();
1457 | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
1458 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1461 delete $2.val; $4.destroy(); $6.destroy();
1463 | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal {
1464 *$1 += " " + *$2.val + ", " + *$4.val + ", " + *$6.val;
1467 delete $2.val; $4.destroy(); $6.destroy();
1470 *$1 += " " + *$2.val;
1475 | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' {
1480 *$1 += $3->getNewTy() + " " + *$4.val + "(";
1481 for (unsigned i = 0; i < $6->size(); ++i) {
1482 ValueInfo& VI = (*$6)[i];
1484 if (i+1 < $6->size())
1490 $$.type = getFunctionReturnType($3);
1491 delete $2; delete $3; $4.destroy(); delete $6;
1496 // IndexList - List of indices for GEP based instructions...
1498 : ',' ValueRefList { $$ = $2; }
1499 | /* empty */ { $$ = new ValueList(); }
1504 | /* empty */ { $$ = new std::string(); }
1507 MemoryInst : MALLOC Types OptCAlign {
1508 *$1 += " " + $2->getNewTy();
1512 $$.type = $2->getPointerType();
1513 delete $2; delete $3;
1515 | MALLOC Types ',' UINT ValueRef OptCAlign {
1516 std::string Name = getUniqueName($5.val, $4);
1517 *$1 += " " + $2->getNewTy() + ", " + $4->getNewTy() + " " + Name;
1521 $$.type = $2->getPointerType();
1522 delete $2; delete $4; $5.destroy(); delete $6;
1524 | ALLOCA Types OptCAlign {
1525 *$1 += " " + $2->getNewTy();
1529 $$.type = $2->getPointerType();
1530 delete $2; delete $3;
1532 | ALLOCA Types ',' UINT ValueRef OptCAlign {
1533 std::string Name = getUniqueName($5.val, $4);
1534 *$1 += " " + $2->getNewTy() + ", " + $4->getNewTy() + " " + Name;
1538 $$.type = $2->getPointerType();
1539 delete $2; delete $4; $5.destroy(); delete $6;
1541 | FREE ResolvedVal {
1542 *$1 += " " + *$2.val;
1544 $$.type = new TypeInfo("void", VoidTy);
1547 | OptVolatile LOAD Types ValueRef {
1548 std::string Name = getUniqueName($4.val, $3);
1551 *$1 += *$2 + " " + $3->getNewTy() + " " + Name;
1553 $$.type = $3->getElementType()->clone();
1554 delete $2; delete $3; $4.destroy();
1556 | OptVolatile STORE ResolvedVal ',' Types ValueRef {
1557 std::string Name = getUniqueName($6.val, $5);
1560 *$1 += *$2 + " " + *$3.val + ", " + $5->getNewTy() + " " + Name;
1562 $$.type = new TypeInfo("void", VoidTy);
1563 delete $2; $3.destroy(); delete $5; $6.destroy();
1565 | GETELEMENTPTR Types ValueRef IndexList {
1566 std::string Name = getUniqueName($3.val, $2);
1567 // Upgrade the indices
1568 for (unsigned i = 0; i < $4->size(); ++i) {
1569 ValueInfo& VI = (*$4)[i];
1570 if (VI.type->isUnsigned() && !VI.isConstant() &&
1571 VI.type->getBitWidth() < 64) {
1572 std::string* old = VI.val;
1573 *O << " %gep_upgrade" << unique << " = zext " << *old
1575 VI.val = new std::string("i64 %gep_upgrade" + llvm::utostr(unique++));
1576 VI.type->setOldTy(ULongTy);
1579 *$1 += " " + $2->getNewTy() + " " + Name;
1580 for (unsigned i = 0; i < $4->size(); ++i) {
1581 ValueInfo& VI = (*$4)[i];
1582 *$1 += ", " + *VI.val;
1585 $$.type = getGEPIndexedType($2,$4);
1586 $3.destroy(); delete $4;
1591 int yyerror(const char *ErrorMsg) {
1593 = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
1594 + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
1595 std::string errMsg = std::string(ErrorMsg) + "\n" + where + " while reading ";
1596 if (yychar == YYEMPTY || yychar == 0)
1597 errMsg += "end-of-file.";
1599 errMsg += "token: '" + std::string(Upgradetext, Upgradeleng) + "'";
1600 std::cerr << "llvm-upgrade: " << errMsg << '\n';
1601 *O << "llvm-upgrade parse failed.\n";