llvm.org GIT mirror llvm / 7e844f1
Implement APInt <-> APFloat conversion for IEEE 128-bit floats. This fixes PR2555 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@79677 91177308-0d34-0410-b5e6-96231b3b80d8 Anton Korobeynikov 11 years ago
2 changed file(s) with 85 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
321321
322322 APInt convertFloatAPFloatToAPInt() const;
323323 APInt convertDoubleAPFloatToAPInt() const;
324 APInt convertQuadrupleAPFloatToAPInt() const;
324325 APInt convertF80LongDoubleAPFloatToAPInt() const;
325326 APInt convertPPCDoubleDoubleAPFloatToAPInt() const;
326327 void initFromAPInt(const APInt& api, bool isIEEE = false);
327328 void initFromFloatAPInt(const APInt& api);
328329 void initFromDoubleAPInt(const APInt& api);
330 void initFromQuadrupleAPInt(const APInt &api);
329331 void initFromF80LongDoubleAPInt(const APInt& api);
330332 void initFromPPCDoubleDoubleAPInt(const APInt& api);
331333
27092709 }
27102710
27112711 APInt
2712 APFloat::convertQuadrupleAPFloatToAPInt() const
2713 {
2714 assert(semantics == (const llvm::fltSemantics*)&IEEEquad);
2715 assert (partCount()==2);
2716
2717 uint64_t myexponent, mysignificand, mysignificand2;
2718
2719 if (category==fcNormal) {
2720 myexponent = exponent+16383; //bias
2721 mysignificand = significandParts()[0];
2722 mysignificand2 = significandParts()[1];
2723 if (myexponent==1 && !(mysignificand2 & 0x1000000000000LL))
2724 myexponent = 0; // denormal
2725 } else if (category==fcZero) {
2726 myexponent = 0;
2727 mysignificand = mysignificand2 = 0;
2728 } else if (category==fcInfinity) {
2729 myexponent = 0x7fff;
2730 mysignificand = mysignificand2 = 0;
2731 } else {
2732 assert(category == fcNaN && "Unknown category!");
2733 myexponent = 0x7fff;
2734 mysignificand = significandParts()[0];
2735 mysignificand2 = significandParts()[1];
2736 }
2737
2738 uint64_t words[2];
2739 words[0] = mysignificand;
2740 words[1] = ((uint64_t)(sign & 1) << 63) |
2741 ((myexponent & 0x7fff) << 48) |
2742 (mysignificand & 0xffffffffffffLL);
2743
2744 return APInt(128, 2, words);
2745 }
2746
2747 APInt
27122748 APFloat::convertDoubleAPFloatToAPInt() const
27132749 {
27142750 assert(semantics == (const llvm::fltSemantics*)&IEEEdouble);
27762812 {
27772813 if (semantics == (const llvm::fltSemantics*)&IEEEsingle)
27782814 return convertFloatAPFloatToAPInt();
2779
2815
27802816 if (semantics == (const llvm::fltSemantics*)&IEEEdouble)
27812817 return convertDoubleAPFloatToAPInt();
2818
2819 if (semantics == (const llvm::fltSemantics*)&IEEEquad)
2820 return convertQuadrupleAPFloatToAPInt();
27822821
27832822 if (semantics == (const llvm::fltSemantics*)&PPCDoubleDouble)
27842823 return convertPPCDoubleDoubleAPFloatToAPInt();
28962935 }
28972936
28982937 void
2938 APFloat::initFromQuadrupleAPInt(const APInt &api)
2939 {
2940 assert(api.getBitWidth()==128);
2941 uint64_t i1 = api.getRawData()[0];
2942 uint64_t i2 = api.getRawData()[1];
2943 uint64_t myexponent = (i2 >> 48) & 0x7fff;
2944 uint64_t mysignificand = i1;
2945 uint64_t mysignificand2 = i2 & 0xffffffffffffLL;
2946
2947 initialize(&APFloat::IEEEquad);
2948 assert(partCount()==2);
2949
2950 sign = static_cast(i2>>63);
2951 if (myexponent==0 &&
2952 (mysignificand==0 && mysignificand2==0)) {
2953 // exponent, significand meaningless
2954 category = fcZero;
2955 } else if (myexponent==0x7fff &&
2956 (mysignificand==0 && mysignificand2==0)) {
2957 // exponent, significand meaningless
2958 category = fcInfinity;
2959 } else if (myexponent==0x7fff &&
2960 (mysignificand!=0 || mysignificand2 !=0)) {
2961 // exponent meaningless
2962 category = fcNaN;
2963 significandParts()[0] = mysignificand;
2964 significandParts()[1] = mysignificand2;
2965 } else {
2966 category = fcNormal;
2967 exponent = myexponent - 16383;
2968 significandParts()[0] = mysignificand;
2969 significandParts()[1] = mysignificand2;
2970 if (myexponent==0) // denormal
2971 exponent = -16382;
2972 else
2973 significandParts()[1] |= 0x1000000000000LL; // integer bit
2974 }
2975 }
2976
2977 void
28992978 APFloat::initFromDoubleAPInt(const APInt &api)
29002979 {
29012980 assert(api.getBitWidth()==64);
29743053 return initFromDoubleAPInt(api);
29753054 else if (api.getBitWidth()==80)
29763055 return initFromF80LongDoubleAPInt(api);
2977 else if (api.getBitWidth()==128 && !isIEEE)
2978 return initFromPPCDoubleDoubleAPInt(api);
3056 else if (api.getBitWidth()==128)
3057 return (isIEEE ?
3058 initFromQuadrupleAPInt(api) : initFromPPCDoubleDoubleAPInt(api));
29793059 else
29803060 llvm_unreachable(0);
29813061 }