clang  8.0.0
FixedPoint.cpp
Go to the documentation of this file.
1 //===- FixedPoint.cpp - 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 implementation for the fixed point number interface.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "clang/Basic/FixedPoint.h"
16 
17 namespace clang {
18 
20  llvm::APSInt NewVal = Val;
21  unsigned DstWidth = DstSema.getWidth();
22  unsigned DstScale = DstSema.getScale();
23  bool Upscaling = DstScale > getScale();
24 
25  if (Upscaling) {
26  NewVal = NewVal.extend(NewVal.getBitWidth() + DstScale - getScale());
27  NewVal <<= (DstScale - getScale());
28  } else {
29  NewVal >>= (getScale() - DstScale);
30  }
31 
32  if (DstSema.isSaturated()) {
33  auto Mask = llvm::APInt::getBitsSetFrom(
34  NewVal.getBitWidth(),
35  std::min(DstScale + DstSema.getIntegralBits(), NewVal.getBitWidth()));
36  llvm::APInt Masked(NewVal & Mask);
37 
38  // Change in the bits above the sign
39  if (!(Masked == Mask || Masked == 0))
40  NewVal = NewVal.isNegative() ? Mask : ~Mask;
41 
42  if (!DstSema.isSigned() && NewVal.isNegative())
43  NewVal = 0;
44  }
45 
46  NewVal = NewVal.extOrTrunc(DstWidth);
47  NewVal.setIsSigned(DstSema.isSigned());
48  return APFixedPoint(NewVal, DstSema);
49 }
50 
51 int APFixedPoint::compare(const APFixedPoint &Other) const {
52  llvm::APSInt ThisVal = getValue();
53  llvm::APSInt OtherVal = Other.getValue();
54  bool ThisSigned = Val.isSigned();
55  bool OtherSigned = OtherVal.isSigned();
56  unsigned OtherScale = Other.getScale();
57  unsigned OtherWidth = OtherVal.getBitWidth();
58 
59  unsigned CommonWidth = std::max(Val.getBitWidth(), OtherWidth);
60 
61  // Prevent overflow in the event the widths are the same but the scales differ
62  CommonWidth += getScale() >= OtherScale ? getScale() - OtherScale
63  : OtherScale - getScale();
64 
65  ThisVal = ThisVal.extOrTrunc(CommonWidth);
66  OtherVal = OtherVal.extOrTrunc(CommonWidth);
67 
68  unsigned CommonScale = std::max(getScale(), OtherScale);
69  ThisVal = ThisVal.shl(CommonScale - getScale());
70  OtherVal = OtherVal.shl(CommonScale - OtherScale);
71 
72  if (ThisSigned && OtherSigned) {
73  if (ThisVal.sgt(OtherVal))
74  return 1;
75  else if (ThisVal.slt(OtherVal))
76  return -1;
77  } else if (!ThisSigned && !OtherSigned) {
78  if (ThisVal.ugt(OtherVal))
79  return 1;
80  else if (ThisVal.ult(OtherVal))
81  return -1;
82  } else if (ThisSigned && !OtherSigned) {
83  if (ThisVal.isSignBitSet())
84  return -1;
85  else if (ThisVal.ugt(OtherVal))
86  return 1;
87  else if (ThisVal.ult(OtherVal))
88  return -1;
89  } else {
90  // !ThisSigned && OtherSigned
91  if (OtherVal.isSignBitSet())
92  return 1;
93  else if (ThisVal.ugt(OtherVal))
94  return 1;
95  else if (ThisVal.ult(OtherVal))
96  return -1;
97  }
98 
99  return 0;
100 }
101 
103  bool IsUnsigned = !Sema.isSigned();
104  auto Val = llvm::APSInt::getMaxValue(Sema.getWidth(), IsUnsigned);
105  if (IsUnsigned && Sema.hasUnsignedPadding())
106  Val = Val.lshr(1);
107  return APFixedPoint(Val, Sema);
108 }
109 
111  auto Val = llvm::APSInt::getMinValue(Sema.getWidth(), !Sema.isSigned());
112  return APFixedPoint(Val, Sema);
113 }
114 
115 } // namespace clang
static APFixedPoint getMax(const FixedPointSemantics &Sema)
Definition: FixedPoint.cpp:102
llvm::APSInt getValue() const
Definition: FixedPoint.h:86
APFixedPoint convert(const FixedPointSemantics &DstSema) const
Definition: FixedPoint.cpp:19
The fixed point semantics work similarly to llvm::fltSemantics.
Definition: FixedPoint.h:32
unsigned getScale() const
Definition: FixedPoint.h:88
int compare(const APFixedPoint &Other) const
Definition: FixedPoint.cpp:51
unsigned getIntegralBits() const
Definition: FixedPoint.h:49
static APFixedPoint getMin(const FixedPointSemantics &Sema)
Definition: FixedPoint.cpp:110
unsigned getScale() const
Definition: FixedPoint.h:42
The APFixedPoint class works similarly to APInt/APSInt in that it is a functional replacement for a s...
Definition: FixedPoint.h:74
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:278
bool hasUnsignedPadding() const
Definition: FixedPoint.h:45
bool isSaturated() const
Definition: FixedPoint.h:44
Defines the fixed point number interface.
Dataflow Directional Tag Classes.
unsigned getWidth() const
Definition: FixedPoint.h:41
APFixedPoint(const llvm::APInt &Val, const FixedPointSemantics &Sema)
Definition: FixedPoint.h:76
__DEVICE__ int max(int __a, int __b)
__DEVICE__ int min(int __a, int __b)