LLVM: lib/Support/ScaledNumber.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

18

19using namespace llvm;

21

24

25 auto getU = [](uint64_t N) { return N >> 32; };

26 auto getL = [](uint64_t N) { return N & UINT32_MAX; };

27 uint64_t UL = getU(LHS), LL = getL(LHS), UR = getU(RHS), LR = getL(RHS);

28

29

30 uint64_t P1 = UL * UR, P2 = UL * LR, P3 = LL * UR, P4 = LL * LR;

31

32

34 auto addWithCarry = [&](uint64_t N) {

38 };

39 addWithCarry(P2);

40 addWithCarry(P3);

41

42

44 return {Lower, 0};

45

46

48 int Shift = 64 - LeadingZeros;

49 if (LeadingZeros)

52 Shift && (Lower & UINT64_C(1) << (Shift - 1)));

53}

54

56

59 assert(Dividend && "expected non-zero dividend");

60 assert(Divisor && "expected non-zero divisor");

61

62

63 uint64_t Dividend64 = Dividend;

64 int Shift = 0;

66 Shift -= Zeros;

67 Dividend64 <<= Zeros;

68 }

69 uint64_t Quotient = Dividend64 / Divisor;

70 uint64_t Remainder = Dividend64 % Divisor;

71

72

73 if (Quotient > UINT32_MAX)

75

76

78}

79

82 assert(Dividend && "expected non-zero dividend");

83 assert(Divisor && "expected non-zero divisor");

84

85

86 int Shift = 0;

88 Shift -= Zeros;

89 Divisor >>= Zeros;

90 }

91

92

93 if (Divisor == 1)

94 return {Dividend, Shift};

95

96

98 Shift -= Zeros;

99 Dividend <<= Zeros;

100 }

101

102

103 uint64_t Quotient = Dividend / Divisor;

104 Dividend %= Divisor;

105

106

107 while (!(Quotient >> 63) && Dividend) {

108

109 bool IsOverflow = Dividend >> 63;

110 Dividend <<= 1;

111 --Shift;

112

113

114 Quotient <<= 1;

115 if (IsOverflow || Divisor <= Dividend) {

116 Quotient |= 1;

117 Dividend -= Divisor;

118 }

119 }

120

121 return getRounded(Quotient, Shift, Dividend >= getHalf(Divisor));

122}

123

125 assert(ScaleDiff >= 0 && "wrong argument order");

126 assert(ScaleDiff < 64 && "numbers too far apart");

127

128 uint64_t L_adjusted = L >> ScaleDiff;

129 if (L_adjusted < R)

130 return -1;

131 if (L_adjusted > R)

132 return 1;

133

134 return L > L_adjusted << ScaleDiff ? 1 : 0;

135}

136

139 Str += '0' + D % 10;

140}

141

143 while (N) {

145 N /= 10;

146 }

147}

148

150 switch (Digit) {

151 case '5':

152 case '6':

153 case '7':

154 case '8':

155 case '9':

156 return true;

157 default:

158 return false;

159 }

160}

161

165

166

169 int Shift = 63 - (NewE - E);

170 assert(Shift <= LeadingZeros);

172 assert(Shift >= 0 && Shift < 64 && "undefined behavior");

173 D <<= Shift;

174 E = NewE;

175

176

177 unsigned AdjustedE = E + 16383;

178 if (!(D >> 63)) {

180 AdjustedE = 0;

181 }

182

183

184 uint64_t RawBits[2] = {D, AdjustedE};

187 Float.toString(Chars, Precision, 0);

188 return std::string(Chars.begin(), Chars.end());

189}

190

192 size_t NonZero = Float.find_last_not_of('0');

193 assert(NonZero != std:🧵:npos && "no . in floating point string");

194

195 if (Float[NonZero] == '.')

196 ++NonZero;

197

198 return Float.substr(0, NonZero + 1);

199}

200

202 unsigned Precision) {

203 if (D)

204 return "0.0";

205

206

210 int ExtraShift = 0;

211 if (E == 0) {

212 Above0 = D;

213 } else if (E > 0) {

215 D <<= Shift;

216 E -= Shift;

217

218 if (!E)

219 Above0 = D;

220 }

221 } else if (E > -64) {

222 Above0 = D >> -E;

223 Below0 = D << (64 + E);

224 } else if (E == -64) {

225

226 Below0 = D;

227 } else if (E > -120) {

228 Below0 = D >> (-E - 64);

229 Extra = D << (128 + E);

230 ExtraShift = -64 - E;

231 }

232

233

234 if (!Above0 && !Below0)

236

237

238 std::string Str;

239 size_t DigitsOut = 0;

240 if (Above0) {

242 DigitsOut = Str.size();

243 } else {

245 }

246 std::reverse(Str.begin(), Str.end());

247

248

249 if (!Below0)

250 return Str + ".0";

251

252

253 Str += '.';

255

256

257

258 Extra = (Below0 & 0xf) << 56 | (Extra >> 8);

259 Below0 >>= 4;

260 size_t SinceDot = 0;

261 size_t AfterDot = Str.size();

262 do {

263 if (ExtraShift) {

264 --ExtraShift;

266 } else {

268 }

269

270 Below0 *= 10;

271 Extra *= 10;

272 Below0 += (Extra >> 60);

276 if (DigitsOut || Str.back() != '0')

277 ++DigitsOut;

278 ++SinceDot;

279 } while (Error && (Below0 << 4 | Extra >> 60) >= Error / 2 &&

280 (!Precision || DigitsOut <= Precision || SinceDot < 2));

281

282

283 if (!Precision || DigitsOut <= Precision)

285

286

287 size_t Truncate =

288 std::max(Str.size() - (DigitsOut - Precision), AfterDot + 1);

289

290

291 if (Truncate >= Str.size())

293

295 if (!Carry)

297

298

299 for (std:🧵:reverse_iterator I(Str.begin() + Truncate), E = Str.rend();

300 I != E; ++I) {

301 if (*I == '.')

302 continue;

303 if (*I == '9') {

304 *I = '0';

305 continue;

306 }

307

308 ++*I;

309 Carry = false;

310 break;

311 }

312

313

314 return stripTrailingZeros(std::string(Carry, '1') + Str.substr(0, Truncate));

315}

316

318 int Width, unsigned Precision) {

319 return OS << toString(D, E, Width, Precision);

320}

321

323 print(dbgs(), D, E, Width, 0) << "[" << Width << ":" << D << "*2^" << E

324 << "]";

325}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

This file declares a class to represent arbitrary precision floating point values and provide a varie...

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static uint64_t getHalf(uint64_t N)

Definition ScaledNumber.cpp:55

static bool doesRoundUp(char Digit)

Definition ScaledNumber.cpp:149

static std::string toStringAPFloat(uint64_t D, int E, unsigned Precision)

Definition ScaledNumber.cpp:162

static void appendDigit(std::string &Str, unsigned D)

Definition ScaledNumber.cpp:137

static std::string stripTrailingZeros(const std::string &Float)

Definition ScaledNumber.cpp:191

static void appendNumber(std::string &Str, uint64_t N)

Definition ScaledNumber.cpp:142

static const fltSemantics & x87DoubleExtended()

Class for arbitrary precision integers.

Lightweight error class with error context and mandatory checking.

static int countLeadingZeros64(uint64_t N)

static LLVM_ABI raw_ostream & print(raw_ostream &OS, uint64_t D, int16_t E, int Width, unsigned Precision)

Definition ScaledNumber.cpp:317

static LLVM_ABI std::string toString(uint64_t D, int16_t E, int Width, unsigned Precision)

Definition ScaledNumber.cpp:201

static LLVM_ABI void dump(uint64_t D, int16_t E, int Width)

Definition ScaledNumber.cpp:322

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

This class implements an extremely fast bulk output stream that can only output to a stream.

LLVM_ABI std::pair< uint64_t, int16_t > divide64(uint64_t Dividend, uint64_t Divisor)

Divide two 64-bit integers to create a 64-bit scaled number.

Definition ScaledNumber.cpp:80

LLVM_ABI std::pair< uint64_t, int16_t > multiply64(uint64_t LHS, uint64_t RHS)

Multiply two 64-bit integers to create a 64-bit scaled number.

Definition ScaledNumber.cpp:22

const int32_t MinScale

Maximum scale; same as APFloat for easy debug printing.

std::pair< DigitsT, int16_t > getAdjusted(uint64_t Digits, int16_t Scale=0)

Adjust a 64-bit scaled number down to the appropriate width.

std::pair< DigitsT, int16_t > getRounded(DigitsT Digits, int16_t Scale, bool ShouldRound)

Conditionally round up a scaled number.

LLVM_ABI std::pair< uint32_t, int16_t > divide32(uint32_t Dividend, uint32_t Divisor)

Divide two 32-bit integers to create a 32-bit scaled number.

Definition ScaledNumber.cpp:57

const int32_t MaxScale

Maximum scale; same as APFloat for easy debug printing.

LLVM_ABI int compareImpl(uint64_t L, uint64_t R, int ScaleDiff)

Implementation for comparing scaled numbers.

Definition ScaledNumber.cpp:124

This is an optimization pass for GlobalISel generic memory operations.

int countr_zero(T Val)

Count number of 0's from the least significant bit to the most stopping at the first 1.

int countl_zero(T Val)

Count number of 0's from the most significant bit to the least stopping at the first 1.

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.