FixedPoint.h revision 344779
1//===- FixedPoint.h - Fixed point constant handling -------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10/// \file 11/// Defines the fixed point number interface. 12/// This is a class for abstracting various operations performed on fixed point 13/// types described in ISO/IEC JTC1 SC22 WG14 N1169 starting at clause 4. 14// 15//===----------------------------------------------------------------------===// 16 17#ifndef LLVM_CLANG_BASIC_FIXEDPOINT_H 18#define LLVM_CLANG_BASIC_FIXEDPOINT_H 19 20#include "llvm/ADT/APSInt.h" 21 22namespace clang { 23 24class ASTContext; 25class QualType; 26 27/// The fixed point semantics work similarly to llvm::fltSemantics. The width 28/// specifies the whole bit width of the underlying scaled integer (with padding 29/// if any). The scale represents the number of fractional bits in this type. 30/// When HasUnsignedPadding is true and this type is signed, the first bit 31/// in the value this represents is treaded as padding. 32class FixedPointSemantics { 33public: 34 FixedPointSemantics(unsigned Width, unsigned Scale, bool IsSigned, 35 bool IsSaturated, bool HasUnsignedPadding) 36 : Width(Width), Scale(Scale), IsSigned(IsSigned), 37 IsSaturated(IsSaturated), HasUnsignedPadding(HasUnsignedPadding) { 38 assert(Width >= Scale && "Not enough room for the scale"); 39 } 40 41 unsigned getWidth() const { return Width; } 42 unsigned getScale() const { return Scale; } 43 bool isSigned() const { return IsSigned; } 44 bool isSaturated() const { return IsSaturated; } 45 bool hasUnsignedPadding() const { return HasUnsignedPadding; } 46 47 void setSaturated(bool Saturated) { IsSaturated = Saturated; } 48 49 unsigned getIntegralBits() const { 50 if (IsSigned || (!IsSigned && HasUnsignedPadding)) 51 return Width - Scale - 1; 52 else 53 return Width - Scale; 54 } 55 56private: 57 unsigned Width; 58 unsigned Scale; 59 bool IsSigned; 60 bool IsSaturated; 61 bool HasUnsignedPadding; 62}; 63 64/// The APFixedPoint class works similarly to APInt/APSInt in that it is a 65/// functional replacement for a scaled integer. It is meant to replicate the 66/// fixed point types proposed in ISO/IEC JTC1 SC22 WG14 N1169. The class carries 67/// info about the fixed point type's width, sign, scale, and saturation, and 68/// provides different operations that would normally be performed on fixed point 69/// types. 70/// 71/// Semantically this does not represent any existing C type other than fixed 72/// point types and should eventually be moved to LLVM if fixed point types gain 73/// native IR support. 74class APFixedPoint { 75 public: 76 APFixedPoint(const llvm::APInt &Val, const FixedPointSemantics &Sema) 77 : Val(Val, !Sema.isSigned()), Sema(Sema) { 78 assert(Val.getBitWidth() == Sema.getWidth() && 79 "The value should have a bit width that matches the Sema width"); 80 } 81 82 APFixedPoint(uint64_t Val, const FixedPointSemantics &Sema) 83 : APFixedPoint(llvm::APInt(Sema.getWidth(), Val, Sema.isSigned()), 84 Sema) {} 85 86 llvm::APSInt getValue() const { return llvm::APSInt(Val, !Sema.isSigned()); } 87 inline unsigned getWidth() const { return Sema.getWidth(); } 88 inline unsigned getScale() const { return Sema.getScale(); } 89 inline bool isSaturated() const { return Sema.isSaturated(); } 90 inline bool isSigned() const { return Sema.isSigned(); } 91 inline bool hasPadding() const { return Sema.hasUnsignedPadding(); } 92 93 // Convert this number to match the semantics provided. 94 APFixedPoint convert(const FixedPointSemantics &DstSema) const; 95 96 APFixedPoint shr(unsigned Amt) const { 97 return APFixedPoint(Val >> Amt, Sema); 98 } 99 100 APFixedPoint shl(unsigned Amt) const { 101 return APFixedPoint(Val << Amt, Sema); 102 } 103 104 llvm::APSInt getIntPart() const { 105 if (Val < 0 && Val != -Val) // Cover the case when we have the min val 106 return -(-Val >> getScale()); 107 else 108 return Val >> getScale(); 109 } 110 111 // If LHS > RHS, return 1. If LHS == RHS, return 0. If LHS < RHS, return -1. 112 int compare(const APFixedPoint &Other) const; 113 bool operator==(const APFixedPoint &Other) const { 114 return compare(Other) == 0; 115 } 116 bool operator!=(const APFixedPoint &Other) const { 117 return compare(Other) != 0; 118 } 119 bool operator>(const APFixedPoint &Other) const { return compare(Other) > 0; } 120 bool operator<(const APFixedPoint &Other) const { return compare(Other) < 0; } 121 bool operator>=(const APFixedPoint &Other) const { 122 return compare(Other) >= 0; 123 } 124 bool operator<=(const APFixedPoint &Other) const { 125 return compare(Other) <= 0; 126 } 127 128 static APFixedPoint getMax(const FixedPointSemantics &Sema); 129 static APFixedPoint getMin(const FixedPointSemantics &Sema); 130 131private: 132 llvm::APSInt Val; 133 FixedPointSemantics Sema; 134}; 135 136} // namespace clang 137 138#endif 139