[llvm-commits] CVS: llvm/lib/AsmParser/llvmAsmParser.y

Reid Spencer reid at x10sys.com
Tue Feb 27 18:24:01 PST 2007



Changes in directory llvm/lib/AsmParser:

llvmAsmParser.y updated: 1.325 -> 1.326
---
Log message:

Implement support for aribrary precision integers by creating two new 
tokens: ESAPINTVAL and EUAPINTVAL and adding an APInt* as a semantic value.
This allows us to extend the definition of an integer constant to allow
arbitrary precision integer constant values.


---
Diffs of the changes:  (+41 -2)

 llvmAsmParser.y |   43 +++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 41 insertions(+), 2 deletions(-)


Index: llvm/lib/AsmParser/llvmAsmParser.y
diff -u llvm/lib/AsmParser/llvmAsmParser.y:1.325 llvm/lib/AsmParser/llvmAsmParser.y:1.326
--- llvm/lib/AsmParser/llvmAsmParser.y:1.325	Wed Feb 14 21:39:17 2007
+++ llvm/lib/AsmParser/llvmAsmParser.y	Tue Feb 27 20:23:44 2007
@@ -925,6 +925,7 @@
   llvm::GlobalValue::LinkageTypes         Linkage;
   llvm::GlobalValue::VisibilityTypes      Visibility;
   llvm::FunctionType::ParameterAttributes ParamAttrs;
+  llvm::APInt                       *APIntVal;
   int64_t                           SInt64Val;
   uint64_t                          UInt64Val;
   int                               SIntVal;
@@ -978,6 +979,12 @@
 // EUINT64VAL - A positive number within uns. long long range
 %token <UInt64Val> EUINT64VAL
 
+// ESAPINTVAL - A negative number with arbitrary precision 
+%token <APIntVal>  ESAPINTVAL
+
+// EUAPINTVAL - A positive number with arbitrary precision 
+%token <APIntVal>  EUAPINTVAL
+
 %token  <UIntVal>   LOCALVAL_ID GLOBALVAL_ID  // %123 @123
 %token  <FPVal>     FPVAL     // Float or Double constant
 
@@ -1704,13 +1711,45 @@
   | IntType ESINT64VAL {      // integral constants
     if (!ConstantInt::isValueValidForType($1, $2))
       GEN_ERROR("Constant value doesn't fit in type");
-    $$ = ConstantInt::get($1, $2);
+    APInt Val(64, $2);
+    uint32_t BitWidth = cast<IntegerType>($1)->getBitWidth();
+    if (BitWidth > 64)
+      Val.sext(BitWidth);
+    else if (BitWidth < 64)
+      Val.trunc(BitWidth);
+    $$ = ConstantInt::get($1, Val);
+    CHECK_FOR_ERROR
+  }
+  | IntType ESAPINTVAL {      // arbitrary precision integer constants
+    uint32_t BitWidth = cast<IntegerType>($1)->getBitWidth();
+    if ($2->getBitWidth() > BitWidth) {
+      GEN_ERROR("Constant value does not fit in type");
+    } else if ($2->getBitWidth() < BitWidth)
+      $2->sext(BitWidth);
+    else if ($2->getBitWidth() > BitWidth)
+      $2->trunc(BitWidth);
+    $$ = ConstantInt::get($1, *$2);
+    delete $2;
     CHECK_FOR_ERROR
   }
   | IntType EUINT64VAL {      // integral constants
     if (!ConstantInt::isValueValidForType($1, $2))
       GEN_ERROR("Constant value doesn't fit in type");
-    $$ = ConstantInt::get($1, $2);
+    uint32_t BitWidth = cast<IntegerType>($1)->getBitWidth();
+    APInt Val(BitWidth, $2);
+    $$ = ConstantInt::get($1, Val);
+    CHECK_FOR_ERROR
+  }
+  | IntType EUAPINTVAL {      // arbitrary precision integer constants
+    uint32_t BitWidth = cast<IntegerType>($1)->getBitWidth();
+    if ($2->getBitWidth() > BitWidth) {
+      GEN_ERROR("Constant value does not fit in type");
+    } else if ($2->getBitWidth() < BitWidth)
+      $2->zext(BitWidth);
+    else if ($2->getBitWidth() > BitWidth)
+      $2->trunc(BitWidth);
+    $$ = ConstantInt::get($1, *$2);
+    delete $2;
     CHECK_FOR_ERROR
   }
   | INTTYPE TRUETOK {                      // Boolean constants






More information about the llvm-commits mailing list