Changes in directory llvm/lib/AsmParser:
Lexer.l updated: 1.78 -> 1.78.2.1 llvmAsmParser.y updated: 1.266.2.1 -> 1.266.2.2 ParserInternals.h updated: 1.45 -> 1.45.2.1 --- Log message: Add support for handling sdiv and udiv instructions while retaining backwards compatibility with the old div instruction. --- Diffs of the changes: (+69 -20) Lexer.l | 16 +++++++++++++-- ParserInternals.h | 16 +++++++++++++++ llvmAsmParser.y | 57 ++++++++++++++++++++++++++++++++++++------------------ 3 files changed, 69 insertions(+), 20 deletions(-) Index: llvm/lib/AsmParser/Lexer.l diff -u llvm/lib/AsmParser/Lexer.l:1.78 llvm/lib/AsmParser/Lexer.l:1.78.2.1 --- llvm/lib/AsmParser/Lexer.l:1.78 Tue Oct 17 21:19:55 2006 +++ llvm/lib/AsmParser/Lexer.l Thu Oct 19 14:16:00 2006 @@ -39,8 +39,18 @@ 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,9 @@ 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, UDiv, UDIV); } rem { RET_TOK(BinaryOpVal, Rem, REM); } and { RET_TOK(BinaryOpVal, And, AND); } or { RET_TOK(BinaryOpVal, Or , OR ); } Index: llvm/lib/AsmParser/llvmAsmParser.y diff -u llvm/lib/AsmParser/llvmAsmParser.y:1.266.2.1 llvm/lib/AsmParser/llvmAsmParser.y:1.266.2.2 --- llvm/lib/AsmParser/llvmAsmParser.y:1.266.2.1 Wed Oct 18 22:57:55 2006 +++ llvm/lib/AsmParser/llvmAsmParser.y Thu Oct 19 14:16:00 2006 @@ -813,6 +813,23 @@ return Ty; } +// This function is +template <class EnumKind> +static void sanitizeOpCode(OpcodeInfo<EnumKind> &OI, const PATypeHolder& Ty) { + if (OI.obsolete) { + switch (OI.opcode) { + default: + GenerateError("Invalid Obsolete OpCode"); + break; + case Instruction::UDiv: + if (Ty->isSigned()) + OI.opcode = Instruction::SDiv; + break; + } + OI.obsolete = false; + } +} + // common code from the two 'RunVMAsmParser' functions static Module* RunParser(Module * M) { @@ -1004,11 +1021,11 @@ char *StrVal; // This memory is strdup'd! 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; } %type <ModuleVal> Module FunctionList @@ -1076,8 +1093,8 @@ // Binary Operators %type <BinaryOpVal> ArithmeticOps LogicalOps SetCondOps // Binops Subcatagories -%token <BinaryOpVal> ADD SUB MUL DIV REM AND OR XOR -%token <BinaryOpVal> SETLE SETGE SETLT SETGT SETEQ SETNE // Binary Comarators +%token <BinaryOpVal> ADD SUB MUL UDIV SDIV REM AND OR XOR +%token <BinaryOpVal> SETLE SETGE SETLT SETGT SETEQ SETNE // Binary Comparators // Memory Instructions %token <MemOpVal> MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR @@ -1114,7 +1131,7 @@ // Operations that are notably excluded from this list include: // RET, BR, & SWITCH because they end basic blocks and are treated specially. // -ArithmeticOps: ADD | SUB | MUL | DIV | REM; +ArithmeticOps: ADD | SUB | MUL | UDIV | SDIV | REM ; LogicalOps : AND | OR | XOR; SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE; @@ -1642,12 +1659,14 @@ | ArithmeticOps '(' ConstVal ',' ConstVal ')' { if ($3->getType() != $5->getType()) GEN_ERROR("Binary operator types must match!"); + sanitizeOpCode($1,$3->getType()); + CHECK_FOR_ERROR; // HACK: llvm 1.3 and earlier used to emit invalid pointer constant exprs. // To retain backward compatibility with these early compilers, we emit a // cast to the appropriate integer type automatically if we are in the // broken case. See PR424 for more information. if (!isa<PointerType>($3->getType())) { - $$ = ConstantExpr::get($1, $3, $5); + $$ = ConstantExpr::get($1.opcode, $3, $5); } else { const Type *IntPtrTy = 0; switch (CurModule.CurrentModule->getPointerSize()) { @@ -1655,7 +1674,7 @@ case Module::Pointer64: IntPtrTy = Type::LongTy; break; default: GEN_ERROR("invalid pointer binary constant expr!"); } - $$ = ConstantExpr::get($1, ConstantExpr::getCast($3, IntPtrTy), + $$ = ConstantExpr::get($1.opcode, ConstantExpr::getCast($3, IntPtrTy), ConstantExpr::getCast($5, IntPtrTy)); $$ = ConstantExpr::getCast($$, $3->getType()); } @@ -1669,13 +1688,13 @@ !cast<PackedType>($3->getType())->getElementType()->isIntegral()) GEN_ERROR("Logical operator requires integral operands!"); } - $$ = ConstantExpr::get($1, $3, $5); + $$ = ConstantExpr::get($1.opcode, $3, $5); CHECK_FOR_ERROR } | SetCondOps '(' ConstVal ',' ConstVal ')' { if ($3->getType() != $5->getType()) GEN_ERROR("setcc operand types must match!"); - $$ = ConstantExpr::get($1, $3, $5); + $$ = ConstantExpr::get($1.opcode, $3, $5); CHECK_FOR_ERROR } | ShiftOps '(' ConstVal ',' ConstVal ')' { @@ -1683,7 +1702,7 @@ GEN_ERROR("Shift count for shift constant must be unsigned byte!"); if (!$3->getType()->isInteger()) GEN_ERROR("Shift constant expression requires integer operand!"); - $$ = ConstantExpr::get($1, $3, $5); + $$ = ConstantExpr::get($1.opcode, $3, $5); CHECK_FOR_ERROR } | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' { @@ -2425,13 +2444,15 @@ !isa<PackedType>((*$2).get())) GEN_ERROR( "Arithmetic operator requires integer, FP, or packed operands!"); - if (isa<PackedType>((*$2).get()) && $1 == Instruction::Rem) + if (isa<PackedType>((*$2).get()) && $1.opcode == Instruction::Rem) GEN_ERROR("Rem not supported on packed types!"); + sanitizeOpCode($1,*$2); + CHECK_FOR_ERROR; Value* val1 = getVal(*$2, $3); CHECK_FOR_ERROR Value* val2 = getVal(*$2, $5); CHECK_FOR_ERROR - $$ = BinaryOperator::create($1, val1, val2); + $$ = BinaryOperator::create($1.opcode, val1, val2); if ($$ == 0) GEN_ERROR("binary operator returned null!"); delete $2; @@ -2446,7 +2467,7 @@ CHECK_FOR_ERROR Value* tmpVal2 = getVal(*$2, $5); CHECK_FOR_ERROR - $$ = BinaryOperator::create($1, tmpVal1, tmpVal2); + $$ = BinaryOperator::create($1.opcode, tmpVal1, tmpVal2); if ($$ == 0) GEN_ERROR("binary operator returned null!"); delete $2; @@ -2460,7 +2481,7 @@ CHECK_FOR_ERROR Value* tmpVal2 = getVal(*$2, $5); CHECK_FOR_ERROR - $$ = new SetCondInst($1, tmpVal1, tmpVal2); + $$ = new SetCondInst($1.opcode, tmpVal1, tmpVal2); if ($$ == 0) GEN_ERROR("binary operator returned null!"); delete $2; @@ -2483,7 +2504,7 @@ GEN_ERROR("Shift amount must be ubyte!"); if (!$2->getType()->isInteger()) GEN_ERROR("Shift constant expression requires integer operand!"); - $$ = new ShiftInst($1, $2, $4); + $$ = new ShiftInst($1.opcode, $2, $4); CHECK_FOR_ERROR } | CAST ResolvedVal TO Types { Index: llvm/lib/AsmParser/ParserInternals.h diff -u llvm/lib/AsmParser/ParserInternals.h:1.45 llvm/lib/AsmParser/ParserInternals.h:1.45.2.1 --- llvm/lib/AsmParser/ParserInternals.h:1.45 Thu Sep 28 18:35:21 2006 +++ llvm/lib/AsmParser/ParserInternals.h Thu Oct 19 14:16:00 2006 @@ -201,4 +201,20 @@ } // 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 _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits