diff options
32 files changed, 3002 insertions, 1860 deletions
diff --git a/docs/LangRef.html b/docs/LangRef.html index de19222c52..0ed371a749 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -77,7 +77,9 @@ <li><a href="#i_add">'<tt>add</tt>' Instruction</a></li> <li><a href="#i_sub">'<tt>sub</tt>' Instruction</a></li> <li><a href="#i_mul">'<tt>mul</tt>' Instruction</a></li> - <li><a href="#i_div">'<tt>div</tt>' Instruction</a></li> + <li><a href="#i_udiv">'<tt>udiv</tt>' Instruction</a></li> + <li><a href="#i_sdiv">'<tt>sdiv</tt>' Instruction</a></li> + <li><a href="#i_fdiv">'<tt>fdiv</tt>' Instruction</a></li> <li><a href="#i_rem">'<tt>rem</tt>' Instruction</a></li> <li><a href="#i_setcc">'<tt>set<i>cc</i></tt>' Instructions</a></li> </ol> @@ -1630,26 +1632,70 @@ action is taken based on the type of the operand.</p> </pre> </div> <!-- _______________________________________________________________________ --> -<div class="doc_subsubsection"> <a name="i_div">'<tt>div</tt>' +<div class="doc_subsubsection"> <a name="i_udiv">'<tt>udiv</tt>' Instruction +</a></div> +<div class="doc_text"> +<h5>Syntax:</h5> +<pre> <result> = udiv <ty> <var1>, <var2> <i>; yields {ty}:result</i> +</pre> +<h5>Overview:</h5> +<p>The '<tt>udiv</tt>' instruction returns the quotient of its two +operands.</p> +<h5>Arguments:</h5> +<p>The two arguments to the '<tt>udiv</tt>' instruction must be +<a href="#t_integer">integer</a> values. Both arguments must have identical +types. This instruction can also take <a href="#t_packed">packed</a> versions +of the values in which case the elements must be integers.</p> +<h5>Semantics:</h5> +<p>The value produced is the unsigned integer quotient of the two operands. This +instruction always performs an unsigned division operation, regardless of +whether the arguments are unsigned or not.</p> +<h5>Example:</h5> +<pre> <result> = udiv uint 4, %var <i>; yields {uint}:result = 4 / %var</i> +</pre> +</div> +<!-- _______________________________________________________________________ --> +<div class="doc_subsubsection"> <a name="i_sdiv">'<tt>sdiv</tt>' Instruction +</a> </div> +<div class="doc_text"> +<h5>Syntax:</h5> +<pre> <result> = sdiv <ty> <var1>, <var2> <i>; yields {ty}:result</i> +</pre> +<h5>Overview:</h5> +<p>The '<tt>sdiv</tt>' instruction returns the quotient of its two +operands.</p> +<h5>Arguments:</h5> +<p>The two arguments to the '<tt>sdiv</tt>' instruction must be +<a href="#t_integer">integer</a> values. Both arguments must have identical +types. This instruction can also take <a href="#t_packed">packed</a> versions +of the values in which case the elements must be integers.</p> +<h5>Semantics:</h5> +<p>The value produced is the signed integer quotient of the two operands. This +instruction always performs a signed division operation, regardless of whether +the arguments are signed or not.</p> +<h5>Example:</h5> +<pre> <result> = sdiv int 4, %var <i>; yields {int}:result = 4 / %var</i> +</pre> +</div> +<!-- _______________________________________________________________________ --> +<div class="doc_subsubsection"> <a name="i_fdiv">'<tt>fdiv</tt>' Instruction</a> </div> <div class="doc_text"> <h5>Syntax:</h5> -<pre> <result> = div <ty> <var1>, <var2> <i>; yields {ty}:result</i> +<pre> <result> = fdiv <ty> <var1>, <var2> <i>; yields {ty}:result</i> </pre> <h5>Overview:</h5> -<p>The '<tt>div</tt>' instruction returns the quotient of its two +<p>The '<tt>fdiv</tt>' instruction returns the quotient of its two operands.</p> <h5>Arguments:</h5> -<p>The two arguments to the '<tt>div</tt>' instruction must be either <a - href="#t_integer">integer</a> or <a href="#t_floating">floating point</a> -values. -This instruction can also take <a href="#t_packed">packed</a> versions of the values. -Both arguments must have identical types.</p> +<p>The two arguments to the '<tt>div</tt>' instruction must be +<a href="#t_floating">floating point</a> values. Both arguments must have +identical types. This instruction can also take <a href="#t_packed">packed</a> +versions of the values in which case the elements must be floating point.</p> <h5>Semantics:</h5> -<p>The value produced is the integer or floating point quotient of the -two operands.</p> +<p>The value produced is the floating point quotient of the two operands.</p> <h5>Example:</h5> -<pre> <result> = div int 4, %var <i>; yields {int}:result = 4 / %var</i> +<pre> <result> = fdiv float 4.0, %var <i>; yields {float}:result = 4.0 / %var</i> </pre> </div> <!-- _______________________________________________________________________ --> diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h index 3673112069..391c12b2ba 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -140,7 +140,7 @@ namespace llvm { const Type *Ty = S->getType(); Value *LHS = expandInTy(S->getLHS(), Ty); Value *RHS = expandInTy(S->getRHS(), Ty); - return BinaryOperator::createDiv(LHS, RHS, "tmp.", InsertPt); + return BinaryOperator::createSDiv(LHS, RHS, "tmp.", InsertPt); } Value *visitAddRecExpr(SCEVAddRecExpr *S); diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h index 2a546c3482..ba1b6d4fec 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpressions.h +++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h @@ -293,7 +293,7 @@ namespace llvm { //===--------------------------------------------------------------------===// - /// SCEVSDivExpr - This class represents a binary unsigned division operation. + /// SCEVSDivExpr - This class represents a binary signed division operation. /// class SCEVSDivExpr : public SCEV { SCEVHandle LHS, RHS; diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index 8c244356d4..3bf935bb5b 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -543,7 +543,9 @@ public: static Constant *getAdd(Constant *C1, Constant *C2); static Constant *getSub(Constant *C1, Constant *C2); static Constant *getMul(Constant *C1, Constant *C2); - static Constant *getDiv(Constant *C1, Constant *C2); + static Constant *getUDiv(Constant *C1, Constant *C2); + static Constant *getSDiv(Constant *C1, Constant *C2); + static Constant *getFDiv(Constant *C1, Constant *C2); static Constant *getRem(Constant *C1, Constant *C2); static Constant *getAnd(Constant *C1, Constant *C2); static Constant *getOr(Constant *C1, Constant *C2); diff --git a/include/llvm/Instruction.def b/include/llvm/Instruction.def index e298aa4fbb..91a467cf59 100644 --- a/include/llvm/Instruction.def +++ b/include/llvm/Instruction.def @@ -93,45 +93,43 @@ HANDLE_TERM_INST ( 6, Unreachable, UnreachableInst) HANDLE_BINARY_INST( 7, Add , BinaryOperator) HANDLE_BINARY_INST( 8, Sub , BinaryOperator) HANDLE_BINARY_INST( 9, Mul , BinaryOperator) -HANDLE_BINARY_INST(10, Div , BinaryOperator) -HANDLE_BINARY_INST(11, Rem , BinaryOperator) +HANDLE_BINARY_INST(10, UDiv , BinaryOperator) +HANDLE_BINARY_INST(11, SDiv , BinaryOperator) +HANDLE_BINARY_INST(12, FDiv , BinaryOperator) +HANDLE_BINARY_INST(13, Rem , BinaryOperator) // Logical operators... -HANDLE_BINARY_INST(12, And , BinaryOperator) -HANDLE_BINARY_INST(13, Or , BinaryOperator) -HANDLE_BINARY_INST(14, Xor , BinaryOperator) +HANDLE_BINARY_INST(14, And , BinaryOperator) +HANDLE_BINARY_INST(15, Or , BinaryOperator) +HANDLE_BINARY_INST(16, Xor , BinaryOperator) // Binary comparison operators... -HANDLE_BINARY_INST(15, SetEQ , SetCondInst) -HANDLE_BINARY_INST(16, SetNE , SetCondInst) -HANDLE_BINARY_INST(17, SetLE , SetCondInst) -HANDLE_BINARY_INST(18, SetGE , SetCondInst) -HANDLE_BINARY_INST(19, SetLT , SetCondInst) -HANDLE_BINARY_INST(20, SetGT , SetCondInst) - LAST_BINARY_INST(20) +HANDLE_BINARY_INST(17, SetEQ , SetCondInst) +HANDLE_BINARY_INST(18, SetNE , SetCondInst) +HANDLE_BINARY_INST(19, SetLE , SetCondInst) +HANDLE_BINARY_INST(20, SetGE , SetCondInst) +HANDLE_BINARY_INST(21, SetLT , SetCondInst) +HANDLE_BINARY_INST(22, SetGT , SetCondInst) + LAST_BINARY_INST(22) // Memory operators... - FIRST_MEMORY_INST(21) -HANDLE_MEMORY_INST(21, Malloc, MallocInst) // Heap management instructions -HANDLE_MEMORY_INST(22, Free , FreeInst ) -HANDLE_MEMORY_INST(23, Alloca, AllocaInst) // Stack management -HANDLE_MEMORY_INST(24, Load , LoadInst ) // Memory manipulation instrs -HANDLE_MEMORY_INST(25, Store , StoreInst ) -HANDLE_MEMORY_INST(26, GetElementPtr, GetElementPtrInst) - LAST_MEMORY_INST(26) + FIRST_MEMORY_INST(23) +HANDLE_MEMORY_INST(23, Malloc, MallocInst) // Heap management instructions +HANDLE_MEMORY_INST(24, Free , FreeInst ) +HANDLE_MEMORY_INST(25, Alloca, AllocaInst) // Stack management +HANDLE_MEMORY_INST(26, Load , LoadInst ) // Memory manipulation instrs +HANDLE_MEMORY_INST(27, Store , StoreInst ) +HANDLE_MEMORY_INST(28, GetElementPtr, GetElementPtrInst) + LAST_MEMORY_INST(28) // Other operators... - FIRST_OTHER_INST(27) -HANDLE_OTHER_INST(27, PHI , PHINode ) // PHI node instruction -HANDLE_OTHER_INST(28, Cast , CastInst ) // Type cast -HANDLE_OTHER_INST(29, Call , CallInst ) // Call a function - -HANDLE_OTHER_INST(30, Shl , ShiftInst ) // Shift operations -HANDLE_OTHER_INST(31, Shr , ShiftInst ) -// 32 -> Empty slot used to be used for vanext in llvm 1.5 and before. -// 33 -> Empty slot used to be used for vaarg in llvm 1.5 and before. + FIRST_OTHER_INST(29) +HANDLE_OTHER_INST(29, PHI , PHINode ) // PHI node instruction +HANDLE_OTHER_INST(30, Cast , CastInst ) // Type cast +HANDLE_OTHER_INST(31, Call , CallInst ) // Call a function +HANDLE_OTHER_INST(32, Shl , ShiftInst ) // Shift operations +HANDLE_OTHER_INST(33, Shr , ShiftInst ) HANDLE_OTHER_INST(34, Select , SelectInst ) // select instruction - HANDLE_OTHER_INST(35, UserOp1, Instruction) // May be used internally in a pass HANDLE_OTHER_INST(36, UserOp2, Instruction) HANDLE_OTHER_INST(37, VAArg , VAArgInst ) // vaarg instruction diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h index 4d745d6c2e..f4c9ad5098 100644 --- a/include/llvm/Support/PatternMatch.h +++ b/include/llvm/Support/PatternMatch.h @@ -112,9 +112,21 @@ inline BinaryOp_match<LHS, RHS, Instruction::Mul> m_Mul(const LHS &L, } template<typename LHS, typename RHS> -inline BinaryOp_match<LHS, RHS, Instruction::Div> m_Div(const LHS &L, +inline BinaryOp_match<LHS, RHS, Instruction::UDiv> m_UDiv(const LHS &L, const RHS &R) { - return BinaryOp_match<LHS, RHS, Instruction::Div>(L, R); + return BinaryOp_match<LHS, RHS, Instruction::UDiv>(L, R); +} + +template<typename LHS, typename RHS> +inline BinaryOp_match<LHS, RHS, Instruction::SDiv> m_SDiv(const LHS &L, + const RHS &R) { + return BinaryOp_match<LHS, RHS, Instruction::SDiv>(L, R); +} + +template<typename LHS, typename RHS> +inline BinaryOp_match<LHS, RHS, Instruction::FDiv> m_FDiv(const LHS &L, + const RHS &R) { + return BinaryOp_match<LHS, RHS, Instruction::FDiv>(L, R); } template<typename LHS, typename RHS> diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index a992e51e0f..20e3859b63 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -989,9 +989,9 @@ SCEVHandle SCEVMulExpr::get(std::vector<SCEVHandle> &Ops) { SCEVHandle SCEVSDivExpr::get(const SCEVHandle &LHS, const SCEVHandle &RHS) { if (SCEVConstant *RHSC = dyn_cast<SCEVConstant>(RHS)) { if (RHSC->getValue()->equalsInt(1)) - return LHS; // X /s 1 --> x + return LHS; // X sdiv 1 --> x if (RHSC->getValue()->isAllOnesValue()) - return SCEV::getNegativeSCEV(LHS); // X /s -1 --> -x + return SCEV::getNegativeSCEV(LHS); // X sdiv -1 --> -x if (SCEVConstant *LHSC = dyn_cast<SCEVConstant>(LHS)) { Constant *LHSCV = LHSC->getValue(); @@ -1001,7 +1001,7 @@ SCEVHandle SCEVSDivExpr::get(const SCEVHandle &LHS, const SCEVHandle &RHS) { LHSCV->getType()->getSignedVersion()); if (RHSCV->getType()->isUnsigned()) RHSCV = ConstantExpr::getCast(RHSCV, LHSCV->getType()); - return SCEVUnknown::get(ConstantExpr::getDiv(LHSCV, RHSCV)); + return SCEVUnknown::get(ConstantExpr::getSDiv(LHSCV, RHSCV)); } } @@ -1384,10 +1384,9 @@ SCEVHandle ScalarEvolutionsImpl::createSCEV(Value *V) { case Instruction::Mul: return SCEVMulExpr::get(getSCEV(I->getOperand(0)), getSCEV(I->getOperand(1))); - case Instruction::Div: - if (V->getType()->isInteger() && V->getType()->isSigned()) - return SCEVSDivExpr::get(getSCEV(I->getOperand(0)), - getSCEV(I->getOperand(1))); + case Instruction::SDiv: + return SCEVSDivExpr::get(getSCEV(I->getOperand(0)), + getSCEV(I->getOperand(1))); break; case Instruction::Sub: @@ -2058,16 +2057,16 @@ SolveQuadraticEquation(const SCEVAddRecExpr *AddRec) { return std::make_pair(CNC, CNC); } - Constant *Two = ConstantInt::get(L->getValue()->getType(), 2); + Constant *C = L->getValue(); + Constant *Two = ConstantInt::get(C->getType(), 2); // Convert from chrec coefficients to polynomial coefficients AX^2+BX+C - Constant *C = L->getValue(); // The B coefficient is M-N/2 Constant *B = ConstantExpr::getSub(M->getValue(), - ConstantExpr::getDiv(N->getValue(), + ConstantExpr::getSDiv(N->getValue(), Two)); // The A coefficient is N/2 - Constant *A = ConstantExpr::getDiv(N->getValue(), Two); + Constant *A = ConstantExpr::getSDiv(N->getValue(), Two); // Compute the B^2-4ac term. Constant *SqrtTerm = @@ -2102,9 +2101,9 @@ SolveQuadraticEquation(const SCEVAddRecExpr *AddRec) { SqrtTerm = ConstantExpr::getCast(SqrtTerm, SignedTy); Constant *Solution1 = - ConstantExpr::getDiv(ConstantExpr::getAdd(NegB, SqrtTerm), TwoA); + ConstantExpr::getSDiv(ConstantExpr::getAdd(NegB, SqrtTerm), TwoA); Constant *Solution2 = - ConstantExpr::getDiv(ConstantExpr::getSub(NegB, SqrtTerm), TwoA); + ConstantExpr::getSDiv(ConstantExpr::getSub(NegB, SqrtTerm), TwoA); return std::make_pair(SCEVUnknown::get(Solution1), SCEVUnknown::get(Solution2)); } @@ -2150,7 +2149,7 @@ SCEVHandle ScalarEvolutionsImpl::HowFarToZero(SCEV *V, const Loop *L) { Constant *StartNegC = ConstantExpr::getNeg(StartCC); Constant *Rem = ConstantExpr::getRem(StartNegC, StepC->getValue()); if (Rem->isNullValue()) { - Constant *Result =ConstantExpr::getDiv(StartNegC,StepC->getValue()); + Constant *Result =ConstantExpr::getSDiv(StartNegC,StepC->getValue()); return SCEVUnknown::get(Result); } } @@ -2352,7 +2351,7 @@ SCEVHandle SCEVAddRecExpr::getNumIterationsInRange(ConstantRange Range) const { Constant *ExitValue = Upper; if (A != One) { ExitValue = ConstantExpr::getSub(ConstantExpr::getAdd(Upper, A), One); - ExitValue = ConstantExpr::getDiv(ExitValue, A); + ExitValue = ConstantExpr::getSDiv(ExitValue, A); } assert(isa<ConstantInt>(ExitValue) && "Constant folding of integers not implemented?"); diff --git a/lib/AsmParser/Lexer.l b/lib/AsmParser/Lexer.l index 08a70e04d8..96804bb75b 100644 --- a/lib/AsmParser/Lexer.l +++ b/lib/AsmParser/Lexer.l @@ -39,8 +39,18 @@ void set_scan_string (const char * str) { yy_scan_string (str); } +// Construct a token value for a non-obsolete token #define RET_TOK(type, Enum, sym) \ - llvmAsmlval.type = Instruction::Enum; return sym + llvmAsmlval.type.opcode = Instruction::Enum; \ + llvmAsmlval.type.obsolete = false; \ + return sym + +// Construct a token value for an obsolete token +#define RET_TOK_OBSOLETE(type, Enum, sym) \ + llvmAsmlval.type.opcode = Instruction::Enum; \ + llvmAsmlval.type.obsolete = true; \ + return sym + namespace llvm { @@ -247,7 +257,10 @@ opaque { return OPAQUE; } add { RET_TOK(BinaryOpVal, Add, ADD); } sub { RET_TOK(BinaryOpVal, Sub, SUB); } mul { RET_TOK(BinaryOpVal, Mul, MUL); } -div { RET_TOK(BinaryOpVal, Div, DIV); } +div { RET_TOK_OBSOLETE(BinaryOpVal, UDiv, UDIV); } +udiv { RET_TOK(BinaryOpVal, UDiv, UDIV); } +sdiv { RET_TOK(BinaryOpVal, SDiv, SDIV); } +fdiv { RET_TOK(BinaryOpVal, FDiv, FDIV); } rem { RET_TOK(BinaryOpVal, Rem, REM); } and { RET_TOK(BinaryOpVal, And, AND); } or { RET_TOK(BinaryOpVal, Or , OR ); } diff --git a/lib/AsmParser/ParserInternals.h b/lib/AsmParser/ParserInternals.h index 79e367fe1f..9c94505bf8 100644 --- a/lib/AsmParser/ParserInternals.h +++ b/lib/AsmParser/ParserInternals.h @@ -201,4 +201,20 @@ struct ValID { } // End llvm namespace +// This structure is used to keep track of obsolete opcodes. The lexer will +// retain the ability to parse obsolete opcode mnemonics. In this case it will +// set "obsolete" to true and the opcode will be the replacement opcode. For +// example if "rem" is encountered then opcode will be set to "urem" and the +// "obsolete" flag will be true. If the opcode is not obsolete then "obsolete" +// will be false. +template <class Enum> +struct OpcodeInfo { + Enum opcode; + bool obsolete; +}; +typedef OpcodeInfo<llvm::Instruction::BinaryOps> BinaryOpInfo; +typedef OpcodeInfo<llvm::Instruction::TermOps> TermOpInfo; +typedef OpcodeInfo<llvm::Instruction::MemoryOps> MemOpInfo; +typedef OpcodeInfo<llvm::Instruction::OtherOps> OtherOpInfo; + #endif diff --git a/lib/AsmParser/llvmAsmParser.cpp.cvs b/lib/AsmParser/llvmAsmParser.cpp.cvs index 2a873eeba5..6837528d6c 100644 --- a/lib/AsmParser/llvmAsmParser.cpp.cvs +++ b/lib/AsmParser/llvmAsmParser.cpp.cvs @@ -142,34 +142,36 @@ ADD = 333, SUB = 334, MUL = 335, - DIV = 336, - REM = 337, - AND = 338, - OR = 339, - XOR = 340, - SETLE = 341, - SETGE = 342, - SETLT = 343, - SETGT = 344, - SETEQ = 345, - SETNE = 346, - MALLOC = 347, - ALLOCA = 348, - FREE = 349, - LOAD = 350, - STORE = 351, - GETELEMENTPTR = 352, - PHI_TOK = 353, - CAST = 354, - SELECT = 355, - SHL = 356, - SHR = 357, - VAARG = 358, - EXTRACTELEMENT = 359, - INSERTELEMENT = 360, - SHUFFLEVECTOR = 361, - VAARG_old = 362, - VANEXT_old = 363 + UDIV = 336, + SDIV = 337, + FDIV = 338, + REM = 339, + AND = 340, + OR = 341, + XOR = 342, + SETLE = 343, + SETGE = 344, + SETLT = 345, + SETGT = 346, + SETEQ = 347, + SETNE = 348, + MALLOC = 349, + ALLOCA = 350, + FREE = 351, + LOAD = 352, + STORE = 353, + GETELEMENTPTR = 354, + PHI_TOK = 355, + CAST = 356, + SELECT = 357, + SHL = 358, + SHR = 359, + VAARG = 360, + EXTRACTELEMENT = 361, + INSERTELEMENT = 362, + SHUFFLEVECTOR = 363, + VAARG_old = 364, + VANEXT_old = 365 }; #endif /* Tokens. */ @@ -251,40 +253,42 @@ #define ADD 333 #define SUB 334 #define MUL 335 -#define DIV 336 -#define REM 337 -#define AND 338 -#define OR 339 -#define XOR 340 -#define SETLE 341 -#define SETGE 342 -#define SETLT 343 -#define SETGT 344 -#define SETEQ 345 -#define SETNE 346 -#define MALLOC 347 -#define ALLOCA 348 -#define FREE 349 -#define LOAD 350 -#define STORE 351 -#define GETELEMENTPTR 352 -#define PHI_TOK 353 -#define CAST 354 -#define SELECT 355 -#define SHL 356 -#define SHR 357 -#define VAARG 358 -#define EXTRACTELEMENT 359 -#define INSERTELEMENT 360 -#define SHUFFLEVECTOR 361 -#define VAARG_old 362 -#define VANEXT_old 363 +#define UDIV 336 +#define SDIV 337 +#define FDIV 338 +#define REM 339 +#define AND 340 +#define OR 341 +#define XOR 342 +#define SETLE 343 +#define SETGE 344 +#define SETLT 345 +#define SETGT 346 +#define SETEQ 347 +#define SETNE 348 +#define MALLOC 349 +#define ALLOCA 350 +#define FREE 351 +#define LOAD 352 +#define STORE 353 +#define GETELEMENTPTR 354 +#define PHI_TOK 355 +#define CAST 356 +#define SELECT 357 +#define SHL 358 +#define SHR 359 +#define VAARG 360 +#define EXTRACTELEMENT 361 +#define INSERTELEMENT 362 +#define SHUFFLEVECTOR 363 +#define VAARG_old 364 +#define VANEXT_old 365 /* Copy the first part of user declarations. */ -#line 14 "/proj/llvm/llvm_nc/lib/AsmParser/llvmAsmParser.y" +#line 14 "/proj/llvm/llvm/lib/AsmParser/llvmAsmParser.y" #include "ParserInternals.h" #include "llvm/CallingConv.h" @@ -1087,6 +1091,43 @@ static PATypeHolder HandleUpRefs(const Type *ty) { return Ty; } +/// This function is used to obtain the correct opcode for an instruction when +/// an obsolete opcode is encountered. The OI parameter (OpcodeInfo) has both +/// an opcode and an "obsolete" flag. These are generated by the lexer and +/// the "obsolete" member will be true when the lexer encounters the token for +/// an obsolete opcode. For example, "div" was replaced by [usf]div but we need +/// to maintain backwards compatibility for asm files that still have the "div" +/// instruction. This function handles converting div -> [usf]div appropriately. +/// @brief Convert obsolete opcodes to new values +static void +sanitizeOpCode(OpcodeInfo<Instruction::BinaryOps> &OI, const PATypeHolder& PATy) +{ + // If its not obsolete, don't do anything + if (!OI.obsolete) + return; + + // If its a packed type we want to use the element type + const Type* Ty = PATy; + if (const PackedType* PTy = dyn_cast<PackedType>(Ty)) + Ty = PTy->getElementType(); + + // Depending on the opcode .. + switch (OI.opcode) { + default: + GenerateError("Invalid Obsolete OpCode"); + break; + case Instruction::UDiv: + // Handle cases where the opcode needs to change + if (Ty->isFloatingPoint()) + OI.opcode = Instruction::FDiv; + else if (Ty->isSigned()) + OI.opcode = Instruction::SDiv; + break; + } + // Its not obsolete any more, we fixed it. + OI.obsolete = false; +} + // common code from the two 'RunVMAsmParser' functions static Module* RunParser(Module * M) { @@ -1264,7 +1305,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { #endif #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -#line 974 "/proj/llvm/llvm_nc/lib/AsmParser/llvmAsmParser.y" +#line 1011 "/proj/llvm/llvm/lib/AsmParser/llvmAsmParser.y" typedef union YYSTYPE { llvm::Module *ModuleVal; llvm::Function *FunctionVal; @@ -1296,16 +1337,16 @@ typedef union YYSTYPE { bool BoolVal; char *StrVal; // This memory is strdup'd! - llvm::ValID ValIDVal; // strdup'd memory maybe! + llvm::ValID ValIDVal; // strdup'd memory maybe! - llvm::Instruction::BinaryOps BinaryOpVal; - llvm::Instruction::TermOps TermOpVal; - llvm::Instruction::MemoryOps MemOpVal; - llvm::Instruction::OtherOps OtherOpVal; - llvm::Module::Endianness Endianness; + BinaryOpInfo BinaryOpVal; + TermOpInfo TermOpVal; + MemOpInfo MemOpVal; + OtherOpInfo OtherOpVal; + llvm::Module::Endianness Endianness; } YYSTYPE; /* Line 196 of yacc.c. */ -#line 1309 "llvmAsmParser.tab.c" +#line 1350 "llvmAsmParser.tab.c" # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 @@ -1317,7 +1358,7 @@ typedef union YYSTYPE { /* Line 219 of yacc.c. */ -#line 1321 "llvmAsmParser.tab.c" +#line 1362 "llvmAsmParser.tab.c" #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) # define YYSIZE_T __SIZE_TYPE__ @@ -1468,20 +1509,20 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 4 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 1339 +#define YYLAST 1288 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 123 +#define YYNTOKENS 125 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 75 /* YYNRULES -- Number of rules. */ -#define YYNRULES 252 +#define YYNRULES 254 /* YYNRULES -- Number of states. */ -#define YYNSTATES 517 +#define YYNSTATES 519 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 363 +#define YYMAXUTOK 365 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -1493,15 +1534,15 @@ static const unsigned char yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 112, 113, 121, 2, 110, 2, 2, 2, 2, 2, + 114, 115, 123, 2, 112, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 117, 109, 118, 2, 2, 2, 2, 2, 2, 2, + 119, 111, 120, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 114, 111, 116, 2, 2, 2, 2, 2, 122, + 2, 116, 113, 118, 2, 2, 2, 2, 2, 124, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 115, 2, 2, 119, 2, 120, 2, 2, 2, 2, + 117, 2, 2, 121, 2, 122, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -1525,7 +1566,7 @@ static const unsigned char yytranslate[] = 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108 + 105, 106, 107, 108, 109, 110 }; #if YYDEBUG |