aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReid Spencer <rspencer@reidspencer.com>2007-02-28 02:23:44 +0000
committerReid Spencer <rspencer@reidspencer.com>2007-02-28 02:23:44 +0000
commitf231004a1c9f2b064c1daeb04a2d3db800c1b1c9 (patch)
tree70658db5d1b9f596b24dc0e4e2b9aaf85be4b4f4
parent84b4eeccc70b39f975a82ad098413d129d38a7d3 (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34714 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/AsmParser/llvmAsmParser.y43
1 files changed, 41 insertions, 2 deletions
diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y
index 3038a79fef..e70f25a7cf 100644
--- a/lib/AsmParser/llvmAsmParser.y
+++ b/lib/AsmParser/llvmAsmParser.y
@@ -925,6 +925,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
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 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
// 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 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
| 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