[llvm-commits] [SignlessTypes] CVS: llvm/lib/AsmParser/Lexer.l llvmAsmParser.y ParserInternals.h

Reid Spencer reid at x10sys.com
Thu Oct 19 12:16:14 PDT 2006



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






More information about the llvm-commits mailing list