diff options
author | Reid Spencer <rspencer@reidspencer.com> | 2007-02-28 02:23:44 +0000 |
---|---|---|
committer | Reid Spencer <rspencer@reidspencer.com> | 2007-02-28 02:23:44 +0000 |
commit | f231004a1c9f2b064c1daeb04a2d3db800c1b1c9 (patch) | |
tree | 70658db5d1b9f596b24dc0e4e2b9aaf85be4b4f4 | |
parent | 84b4eeccc70b39f975a82ad098413d129d38a7d3 (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.y | 43 |
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 |