diff options
Diffstat (limited to 'llvm/lib/AsmParser')
| -rw-r--r-- | llvm/lib/AsmParser/Lexer.l | 60 | ||||
| -rw-r--r-- | llvm/lib/AsmParser/llvmAsmParser.y | 13 |
2 files changed, 64 insertions, 9 deletions
diff --git a/llvm/lib/AsmParser/Lexer.l b/llvm/lib/AsmParser/Lexer.l index 390544d8c3d..5acbbacf60f 100644 --- a/llvm/lib/AsmParser/Lexer.l +++ b/llvm/lib/AsmParser/Lexer.l @@ -91,14 +91,40 @@ static uint64_t HexIntToVal(const char *Buffer) { return Result; } - -// HexToFP - Convert the ascii string in hexidecimal format to the floating +// HexToFP - Convert the ascii string in hexadecimal format to the floating // point representation of it. // static double HexToFP(const char *Buffer) { return BitsToDouble(HexIntToVal(Buffer)); // Cast Hex constant to double } +static void HexToIntPair(const char *Buffer, uint64_t Pair[2]) { + Pair[0] = 0; + for (int i=0; i<16; i++, Buffer++) { + assert(*Buffer); + Pair[0] *= 16; + char C = *Buffer; + if (C >= '0' && C <= '9') + Pair[0] += C-'0'; + else if (C >= 'A' && C <= 'F') + Pair[0] += C-'A'+10; + else if (C >= 'a' && C <= 'f') + Pair[0] += C-'a'+10; + } + Pair[1] = 0; + for (int i=0; i<16 && *Buffer; i++, Buffer++) { + Pair[1] *= 16; + char C = *Buffer; + if (C >= '0' && C <= '9') + Pair[1] += C-'0'; + else if (C >= 'A' && C <= 'F') + Pair[1] += C-'A'+10; + else if (C >= 'a' && C <= 'f') + Pair[1] += C-'a'+10; + } + if (*Buffer) + GenerateError("constant bigger than 128 bits detected!"); +} // UnEscapeLexed - Run through the specified buffer and change \xx codes to the // appropriate character. @@ -163,15 +189,28 @@ IntegerType i[0-9]+ PInteger [0-9]+ NInteger -[0-9]+ -/* FPConstant - A Floating point constant. +/* FPConstant - A Floating point constant. Float and double only. */ FPConstant [-+]?[0-9]+[.][0-9]*([eE][-+]?[0-9]+)? /* HexFPConstant - Floating point constant represented in IEEE format as a * hexadecimal number for when exponential notation is not precise enough. + * Float and double only. */ HexFPConstant 0x[0-9A-Fa-f]+ +/* F80HexFPConstant - x87 long double in hexadecimal format (10 bytes) + */ +HexFP80Constant 0xK[0-9A-Fa-f]+ + +/* F128HexFPConstant - IEEE 128-bit in hexadecimal format (16 bytes) + */ +HexFP128Constant 0xL[0-9A-Fa-f]+ + +/* PPC128HexFPConstant - PowerPC 128-bit in hexadecimal format (16 bytes) + */ +HexPPC128Constant 0xM[0-9A-Fa-f]+ + /* HexIntConstant - Hexadecimal constant generated by the CFE to avoid forcing * it to deal with 64 bit numbers. */ @@ -441,6 +480,21 @@ shufflevector { RET_TOK(OtherOpVal, ShuffleVector, SHUFFLEVECTOR); } {HexFPConstant} { llvmAsmlval.FPVal = new APFloat(HexToFP(yytext)); return FPVAL; } +{HexFP80Constant} { uint64_t Pair[2]; + HexToIntPair(yytext, Pair); + llvmAsmlval.FPVal = new APFloat(APInt(80, 2, Pair)); + return FPVAL; + } +{HexFP128Constant} { uint64_t Pair[2]; + HexToIntPair(yytext, Pair); + llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair)); + return FPVAL; + } +{HexPPC128Constant} { uint64_t Pair[2]; + HexToIntPair(yytext, Pair); + llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair)); + return FPVAL; + } <<EOF>> { /* Make sure to free the internal buffers for flex when we are diff --git a/llvm/lib/AsmParser/llvmAsmParser.y b/llvm/lib/AsmParser/llvmAsmParser.y index 6364b29bcd7..c0374daf3f1 100644 --- a/llvm/lib/AsmParser/llvmAsmParser.y +++ b/llvm/lib/AsmParser/llvmAsmParser.y @@ -416,9 +416,10 @@ static Value *getExistingVal(const Type *Ty, const ValID &D) { GenerateError("FP constant invalid for type"); return 0; } - // Lexer has no type info, so builds all FP constants as double. - // Fix this here. - if (Ty==Type::FloatTy) + // Lexer has no type info, so builds all float and double FP constants + // as double. Fix this here. Long double does not need this. + if (&D.ConstPoolFP->getSemantics() == &APFloat::IEEEdouble && + Ty==Type::FloatTy) D.ConstPoolFP->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven); return ConstantFP::get(Ty, *D.ConstPoolFP); @@ -1868,9 +1869,9 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr | FPType FPVAL { // Float & Double constants if (!ConstantFP::isValueValidForType($1, *$2)) GEN_ERROR("Floating point constant invalid for type"); - // Lexer has no type info, so builds all FP constants as double. - // Fix this here. - if ($1==Type::FloatTy) + // Lexer has no type info, so builds all float and double FP constants + // as double. Fix this here. Long double is done right. + if (&$2->getSemantics()==&APFloat::IEEEdouble && $1==Type::FloatTy) $2->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven); $$ = ConstantFP::get($1, *$2); delete $2; |

