1 | /* Operations with very long integers. -*- C++ -*- |
---|---|

2 | Copyright (C) 2012-2017 Free Software Foundation, Inc. |

3 | |

4 | This file is part of GCC. |

5 | |

6 | GCC is free software; you can redistribute it and/or modify it |

7 | under the terms of the GNU General Public License as published by the |

8 | Free Software Foundation; either version 3, or (at your option) any |

9 | later version. |

10 | |

11 | GCC is distributed in the hope that it will be useful, but WITHOUT |

12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |

13 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |

14 | for more details. |

15 | |

16 | You should have received a copy of the GNU General Public License |

17 | along with GCC; see the file COPYING3. If not see |

18 | <http://www.gnu.org/licenses/>. */ |

19 | |

20 | #ifndef WIDE_INT_H |

21 | #define WIDE_INT_H |

22 | |

23 | /* wide-int.[cc|h] implements a class that efficiently performs |

24 | mathematical operations on finite precision integers. wide_ints |

25 | are designed to be transient - they are not for long term storage |

26 | of values. There is tight integration between wide_ints and the |

27 | other longer storage GCC representations (rtl and tree). |

28 | |

29 | The actual precision of a wide_int depends on the flavor. There |

30 | are three predefined flavors: |

31 | |

32 | 1) wide_int (the default). This flavor does the math in the |

33 | precision of its input arguments. It is assumed (and checked) |

34 | that the precisions of the operands and results are consistent. |

35 | This is the most efficient flavor. It is not possible to examine |

36 | bits above the precision that has been specified. Because of |

37 | this, the default flavor has semantics that are simple to |

38 | understand and in general model the underlying hardware that the |

39 | compiler is targetted for. |

40 | |

41 | This flavor must be used at the RTL level of gcc because there |

42 | is, in general, not enough information in the RTL representation |

43 | to extend a value beyond the precision specified in the mode. |

44 | |

45 | This flavor should also be used at the TREE and GIMPLE levels of |

46 | the compiler except for the circumstances described in the |

47 | descriptions of the other two flavors. |

48 | |

49 | The default wide_int representation does not contain any |

50 | information inherent about signedness of the represented value, |

51 | so it can be used to represent both signed and unsigned numbers. |

52 | For operations where the results depend on signedness (full width |

53 | multiply, division, shifts, comparisons, and operations that need |

54 | overflow detected), the signedness must be specified separately. |

55 | |

56 | 2) offset_int. This is a fixed-precision integer that can hold |

57 | any address offset, measured in either bits or bytes, with at |

58 | least one extra sign bit. At the moment the maximum address |

59 | size GCC supports is 64 bits. With 8-bit bytes and an extra |

60 | sign bit, offset_int therefore needs to have at least 68 bits |

61 | of precision. We round this up to 128 bits for efficiency. |

62 | Values of type T are converted to this precision by sign- or |

63 | zero-extending them based on the signedness of T. |

64 | |

65 | The extra sign bit means that offset_int is effectively a signed |

66 | 128-bit integer, i.e. it behaves like int128_t. |

67 | |

68 | Since the values are logically signed, there is no need to |

69 | distinguish between signed and unsigned operations. Sign-sensitive |

70 | comparison operators <, <=, > and >= are therefore supported. |

71 | Shift operators << and >> are also supported, with >> being |

72 | an _arithmetic_ right shift. |

73 | |

74 | [ Note that, even though offset_int is effectively int128_t, |

75 | it can still be useful to use unsigned comparisons like |

76 | wi::leu_p (a, b) as a more efficient short-hand for |

77 | "a >= 0 && a <= b". ] |

78 | |

79 | 3) widest_int. This representation is an approximation of |

80 | infinite precision math. However, it is not really infinite |

81 | precision math as in the GMP library. It is really finite |

82 | precision math where the precision is 4 times the size of the |

83 | largest integer that the target port can represent. |

84 | |

85 | Like offset_int, widest_int is wider than all the values that |

86 | it needs to represent, so the integers are logically signed. |

87 | Sign-sensitive comparison operators <, <=, > and >= are supported, |

88 | as are << and >>. |

89 | |

90 | There are several places in the GCC where this should/must be used: |

91 | |

92 | * Code that does induction variable optimizations. This code |

93 | works with induction variables of many different types at the |

94 | same time. Because of this, it ends up doing many different |

95 | calculations where the operands are not compatible types. The |

96 | widest_int makes this easy, because it provides a field where |

97 | nothing is lost when converting from any variable, |

98 | |

99 | * There are a small number of passes that currently use the |

100 | widest_int that should use the default. These should be |

101 | changed. |

102 | |

103 | There are surprising features of offset_int and widest_int |

104 | that the users should be careful about: |

105 | |

106 | 1) Shifts and rotations are just weird. You have to specify a |

107 | precision in which the shift or rotate is to happen in. The bits |

108 | above this precision are zeroed. While this is what you |

109 | want, it is clearly non obvious. |

110 | |

111 | 2) Larger precision math sometimes does not produce the same |

112 | answer as would be expected for doing the math at the proper |

113 | precision. In particular, a multiply followed by a divide will |

114 | produce a different answer if the first product is larger than |

115 | what can be represented in the input precision. |

116 | |

117 | The offset_int and the widest_int flavors are more expensive |

118 | than the default wide int, so in addition to the caveats with these |

119 | two, the default is the prefered representation. |

120 | |

121 | All three flavors of wide_int are represented as a vector of |

122 | HOST_WIDE_INTs. The default and widest_int vectors contain enough elements |

123 | to hold a value of MAX_BITSIZE_MODE_ANY_INT bits. offset_int contains only |

124 | enough elements to hold ADDR_MAX_PRECISION bits. The values are stored |

125 | in the vector with the least significant HOST_BITS_PER_WIDE_INT bits |

126 | in element 0. |

127 | |

128 | The default wide_int contains three fields: the vector (VAL), |

129 | the precision and a length (LEN). The length is the number of HWIs |

130 | needed to represent the value. widest_int and offset_int have a |

131 | constant precision that cannot be changed, so they only store the |

132 | VAL and LEN fields. |

133 | |

134 | Since most integers used in a compiler are small values, it is |

135 | generally profitable to use a representation of the value that is |

136 | as small as possible. LEN is used to indicate the number of |

137 | elements of the vector that are in use. The numbers are stored as |

138 | sign extended numbers as a means of compression. Leading |

139 | HOST_WIDE_INTs that contain strings of either -1 or 0 are removed |

140 | as long as they can be reconstructed from the top bit that is being |

141 | represented. |

142 | |

143 | The precision and length of a wide_int are always greater than 0. |

144 | Any bits in a wide_int above the precision are sign-extended from the |

145 | most significant bit. For example, a 4-bit value 0x8 is represented as |

146 | VAL = { 0xf...fff8 }. However, as an optimization, we allow other integer |

147 | constants to be represented with undefined bits above the precision. |

148 | This allows INTEGER_CSTs to be pre-extended according to TYPE_SIGN, |

149 | so that the INTEGER_CST representation can be used both in TYPE_PRECISION |

150 | and in wider precisions. |

151 | |

152 | There are constructors to create the various forms of wide_int from |

153 | trees, rtl and constants. For trees the options are: |

154 | |

155 | tree t = ...; |

156 | wi::to_wide (t) // Treat T as a wide_int |

157 | wi::to_offset (t) // Treat T as an offset_int |

158 | wi::to_widest (t) // Treat T as a widest_int |

159 | |

160 | All three are light-weight accessors that should have no overhead |

161 | in release builds. If it is useful for readability reasons to |

162 | store the result in a temporary variable, the preferred method is: |

163 | |

164 | wi::tree_to_wide_ref twide = wi::to_wide (t); |

165 | wi::tree_to_offset_ref toffset = wi::to_offset (t); |

166 | wi::tree_to_widest_ref twidest = wi::to_widest (t); |

167 | |

168 | To make an rtx into a wide_int, you have to pair it with a mode. |

169 | The canonical way to do this is with rtx_mode_t as in: |

170 | |

171 | rtx r = ... |

172 | wide_int x = rtx_mode_t (r, mode); |

173 | |

174 | Similarly, a wide_int can only be constructed from a host value if |

175 | the target precision is given explicitly, such as in: |

176 | |

177 | wide_int x = wi::shwi (c, prec); // sign-extend C if necessary |

178 | wide_int y = wi::uhwi (c, prec); // zero-extend C if necessary |

179 | |

180 | However, offset_int and widest_int have an inherent precision and so |

181 | can be initialized directly from a host value: |

182 | |

183 | offset_int x = (int) c; // sign-extend C |

184 | widest_int x = (unsigned int) c; // zero-extend C |

185 | |

186 | It is also possible to do arithmetic directly on rtx_mode_ts and |

187 | constants. For example: |

188 | |

189 | wi::add (r1, r2); // add equal-sized rtx_mode_ts r1 and r2 |

190 | wi::add (r1, 1); // add 1 to rtx_mode_t r1 |

191 | wi::lshift (1, 100); // 1 << 100 as a widest_int |

192 | |

193 | Many binary operations place restrictions on the combinations of inputs, |

194 | using the following rules: |

195 | |

196 | - {rtx, wide_int} op {rtx, wide_int} -> wide_int |

197 | The inputs must be the same precision. The result is a wide_int |

198 | of the same precision |

199 | |

200 | - {rtx, wide_int} op (un)signed HOST_WIDE_INT -> wide_int |

201 | (un)signed HOST_WIDE_INT op {rtx, wide_int} -> wide_int |

202 | The HOST_WIDE_INT is extended or truncated to the precision of |

203 | the other input. The result is a wide_int of the same precision |

204 | as that input. |

205 | |

206 | - (un)signed HOST_WIDE_INT op (un)signed HOST_WIDE_INT -> widest_int |

207 | The inputs are extended to widest_int precision and produce a |

208 | widest_int result. |

209 | |

210 | - offset_int op offset_int -> offset_int |

211 | offset_int op (un)signed HOST_WIDE_INT -> offset_int |

212 | (un)signed HOST_WIDE_INT op offset_int -> offset_int |

213 | |

214 | - widest_int op widest_int -> widest_int |

215 | widest_int op (un)signed HOST_WIDE_INT -> widest_int |

216 | (un)signed HOST_WIDE_INT op widest_int -> widest_int |

217 | |

218 | Other combinations like: |

219 | |

220 | - widest_int op offset_int and |

221 | - wide_int op offset_int |

222 | |

223 | are not allowed. The inputs should instead be extended or truncated |

224 | so that they match. |

225 | |

226 | The inputs to comparison functions like wi::eq_p and wi::lts_p |

227 | follow the same compatibility rules, although their return types |

228 | are different. Unary functions on X produce the same result as |

229 | a binary operation X + X. Shift functions X op Y also produce |

230 | the same result as X + X; the precision of the shift amount Y |

231 | can be arbitrarily different from X. */ |

232 | |

233 | /* The MAX_BITSIZE_MODE_ANY_INT is automatically generated by a very |

234 | early examination of the target's mode file. The WIDE_INT_MAX_ELTS |

235 | can accomodate at least 1 more bit so that unsigned numbers of that |

236 | mode can be represented as a signed value. Note that it is still |

237 | possible to create fixed_wide_ints that have precisions greater than |

238 | MAX_BITSIZE_MODE_ANY_INT. This can be useful when representing a |

239 | double-width multiplication result, for example. */ |

240 | #define WIDE_INT_MAX_ELTS \ |

241 | ((MAX_BITSIZE_MODE_ANY_INT + HOST_BITS_PER_WIDE_INT) / HOST_BITS_PER_WIDE_INT) |

242 | |

243 | #define WIDE_INT_MAX_PRECISION (WIDE_INT_MAX_ELTS * HOST_BITS_PER_WIDE_INT) |

244 | |

245 | /* This is the max size of any pointer on any machine. It does not |

246 | seem to be as easy to sniff this out of the machine description as |

247 | it is for MAX_BITSIZE_MODE_ANY_INT since targets may support |

248 | multiple address sizes and may have different address sizes for |

249 | different address spaces. However, currently the largest pointer |

250 | on any platform is 64 bits. When that changes, then it is likely |

251 | that a target hook should be defined so that targets can make this |

252 | value larger for those targets. */ |

253 | #define ADDR_MAX_BITSIZE 64 |

254 | |

255 | /* This is the internal precision used when doing any address |

256 | arithmetic. The '4' is really 3 + 1. Three of the bits are for |

257 | the number of extra bits needed to do bit addresses and the other bit |

258 | is to allow everything to be signed without loosing any precision. |

259 | Then everything is rounded up to the next HWI for efficiency. */ |

260 | #define ADDR_MAX_PRECISION \ |

261 | ((ADDR_MAX_BITSIZE + 4 + HOST_BITS_PER_WIDE_INT - 1) \ |

262 | & ~(HOST_BITS_PER_WIDE_INT - 1)) |

263 | |

264 | /* The number of HWIs needed to store an offset_int. */ |

265 | #define OFFSET_INT_ELTS (ADDR_MAX_PRECISION / HOST_BITS_PER_WIDE_INT) |

266 | |

267 | /* The type of result produced by a binary operation on types T1 and T2. |

268 | Defined purely for brevity. */ |

269 | #define WI_BINARY_RESULT(T1, T2) \ |

270 | typename wi::binary_traits <T1, T2>::result_type |

271 | |

272 | /* Likewise for binary operators, which excludes the case in which neither |

273 | T1 nor T2 is a wide-int-based type. */ |

274 | #define WI_BINARY_OPERATOR_RESULT(T1, T2) \ |

275 | typename wi::binary_traits <T1, T2>::operator_result |

276 | |

277 | /* The type of result produced by T1 << T2. Leads to substitution failure |

278 | if the operation isn't supported. Defined purely for brevity. */ |

279 | #define WI_SIGNED_SHIFT_RESULT(T1, T2) \ |

280 | typename wi::binary_traits <T1, T2>::signed_shift_result_type |

281 | |

282 | /* The type of result produced by a sign-agnostic binary predicate on |

283 | types T1 and T2. This is bool if wide-int operations make sense for |

284 | T1 and T2 and leads to substitution failure otherwise. */ |

285 | #define WI_BINARY_PREDICATE_RESULT(T1, T2) \ |

286 | typename wi::binary_traits <T1, T2>::predicate_result |

287 | |

288 | /* The type of result produced by a signed binary predicate on types T1 and T2. |

289 | This is bool if signed comparisons make sense for T1 and T2 and leads to |

290 | substitution failure otherwise. */ |

291 | #define WI_SIGNED_BINARY_PREDICATE_RESULT(T1, T2) \ |

292 | typename wi::binary_traits <T1, T2>::signed_predicate_result |

293 | |

294 | /* The type of result produced by a unary operation on type T. */ |

295 | #define WI_UNARY_RESULT(T) \ |

296 | typename wi::unary_traits <T>::result_type |

297 | |

298 | /* Define a variable RESULT to hold the result of a binary operation on |

299 | X and Y, which have types T1 and T2 respectively. Define VAL to |

300 | point to the blocks of RESULT. Once the user of the macro has |

301 | filled in VAL, it should call RESULT.set_len to set the number |

302 | of initialized blocks. */ |

303 | #define WI_BINARY_RESULT_VAR(RESULT, VAL, T1, X, T2, Y) \ |

304 | WI_BINARY_RESULT (T1, T2) RESULT = \ |

305 | wi::int_traits <WI_BINARY_RESULT (T1, T2)>::get_binary_result (X, Y); \ |

306 | HOST_WIDE_INT *VAL = RESULT.write_val () |

307 | |

308 | /* Similar for the result of a unary operation on X, which has type T. */ |

309 | #define WI_UNARY_RESULT_VAR(RESULT, VAL, T, X) \ |

310 | WI_UNARY_RESULT (T) RESULT = \ |

311 | wi::int_traits <WI_UNARY_RESULT (T)>::get_binary_result (X, X); \ |

312 | HOST_WIDE_INT *VAL = RESULT.write_val () |

313 | |

314 | template <typename T> class generic_wide_int; |

315 | template <int N> class fixed_wide_int_storage; |

316 | class wide_int_storage; |

317 | |

318 | /* An N-bit integer. Until we can use typedef templates, use this instead. */ |

319 | #define FIXED_WIDE_INT(N) \ |

320 | generic_wide_int < fixed_wide_int_storage <N> > |

321 | |

322 | typedef generic_wide_int <wide_int_storage> wide_int; |

323 | typedef FIXED_WIDE_INT (ADDR_MAX_PRECISION) offset_int; |

324 | typedef FIXED_WIDE_INT (WIDE_INT_MAX_PRECISION) widest_int; |

325 | |

326 | /* wi::storage_ref can be a reference to a primitive type, |

327 | so this is the conservatively-correct setting. */ |

328 | template <bool SE, bool HDP = true> |

329 | struct wide_int_ref_storage; |

330 | |

331 | typedef generic_wide_int <wide_int_ref_storage <false> > wide_int_ref; |

332 | |

333 | /* This can be used instead of wide_int_ref if the referenced value is |

334 | known to have type T. It carries across properties of T's representation, |

335 | such as whether excess upper bits in a HWI are defined, and can therefore |

336 | help avoid redundant work. |

337 | |

338 | The macro could be replaced with a template typedef, once we're able |

339 | to use those. */ |

340 | #define WIDE_INT_REF_FOR(T) \ |

341 | generic_wide_int \ |

342 | <wide_int_ref_storage <wi::int_traits <T>::is_sign_extended, \ |

343 | wi::int_traits <T>::host_dependent_precision> > |

344 | |

345 | namespace wi |

346 | { |

347 | /* Classifies an integer based on its precision. */ |

348 | enum precision_type { |

349 | /* The integer has both a precision and defined signedness. This allows |

350 | the integer to be converted to any width, since we know whether to fill |

351 | any extra bits with zeros or signs. */ |

352 | FLEXIBLE_PRECISION, |

353 | |

354 | /* The integer has a variable precision but no defined signedness. */ |

355 | VAR_PRECISION, |

356 | |

357 | /* The integer has a constant precision (known at GCC compile time) |

358 | and is signed. */ |

359 | CONST_PRECISION |

360 | }; |

361 | |

362 | /* This class, which has no default implementation, is expected to |

363 | provide the following members: |

364 | |

365 | static const enum precision_type precision_type; |

366 | Classifies the type of T. |

367 | |

368 | static const unsigned int precision; |

369 | Only defined if precision_type == CONST_PRECISION. Specifies the |

370 | precision of all integers of type T. |

371 | |

372 | static const bool host_dependent_precision; |

373 | True if the precision of T depends (or can depend) on the host. |

374 | |

375 | static unsigned int get_precision (const T &x) |

376 | Return the number of bits in X. |

377 | |

378 | static wi::storage_ref *decompose (HOST_WIDE_INT *scratch, |

379 | unsigned int precision, const T &x) |

380 | Decompose X as a PRECISION-bit integer, returning the associated |

381 | wi::storage_ref. SCRATCH is available as scratch space if needed. |

382 | The routine should assert that PRECISION is acceptable. */ |

383 | template <typename T> struct int_traits; |

384 | |

385 | /* This class provides a single type, result_type, which specifies the |

386 | type of integer produced by a binary operation whose inputs have |

387 | types T1 and T2. The definition should be symmetric. */ |

388 | template <typename T1, typename T2, |

389 | enum precision_type P1 = int_traits <T1>::precision_type, |

390 | enum precision_type P2 = int_traits <T2>::precision_type> |

391 | struct binary_traits; |

392 | |

393 | /* The result of a unary operation on T is the same as the result of |

394 | a binary operation on two values of type T. */ |

395 | template <typename T> |

396 | struct unary_traits : public binary_traits <T, T> {}; |

397 | |

398 | /* Specify the result type for each supported combination of binary |

399 | inputs. Note that CONST_PRECISION and VAR_PRECISION cannot be |

400 | mixed, in order to give stronger type checking. When both inputs |

401 | are CONST_PRECISION, they must have the same precision. */ |

402 | template <typename T1, typename T2> |

403 | struct binary_traits <T1, T2, FLEXIBLE_PRECISION, FLEXIBLE_PRECISION> |

404 | { |

405 | typedef widest_int result_type; |

406 | /* Don't define operators for this combination. */ |

407 | }; |

408 | |

409 | template <typename T1, typename T2> |

410 | struct binary_traits <T1, T2, FLEXIBLE_PRECISION, VAR_PRECISION> |

411 | { |

412 | typedef wide_int result_type; |

413 | typedef result_type operator_result; |

414 | typedef bool predicate_result; |

415 | }; |

416 | |

417 | template <typename T1, typename T2> |

418 | struct binary_traits <T1, T2, FLEXIBLE_PRECISION, CONST_PRECISION> |

419 | { |

420 | /* Spelled out explicitly (rather than through FIXED_WIDE_INT) |

421 | so as not to confuse gengtype. */ |

422 | typedef generic_wide_int < fixed_wide_int_storage |

423 | <int_traits <T2>::precision> > result_type; |

424 | typedef result_type operator_result; |

425 | typedef bool predicate_result; |

426 | typedef bool signed_predicate_result; |

427 | }; |

428 | |

429 | template <typename T1, typename T2> |

430 | struct binary_traits <T1, T2, VAR_PRECISION, FLEXIBLE_PRECISION> |

431 | { |

432 | typedef wide_int result_type; |

433 | typedef result_type operator_result; |

434 | typedef bool predicate_result; |

435 | }; |

436 | |

437 | template <typename T1, typename T2> |

438 | struct binary_traits <T1, T2, CONST_PRECISION, FLEXIBLE_PRECISION> |

439 | { |

440 | /* Spelled out explicitly (rather than through FIXED_WIDE_INT) |

441 | so as not to confuse gengtype. */ |

442 | typedef generic_wide_int < fixed_wide_int_storage |

443 | <int_traits <T1>::precision> > result_type; |

444 | typedef result_type operator_result; |

445 | typedef bool predicate_result; |

446 | typedef result_type signed_shift_result_type; |

447 | typedef bool signed_predicate_result; |

448 | }; |

449 | |

450 | template <typename T1, typename T2> |

451 | struct binary_traits <T1, T2, CONST_PRECISION, CONST_PRECISION> |

452 | { |

453 | STATIC_ASSERT (int_traits <T1>::precision == int_traits <T2>::precision); |

454 | /* Spelled out explicitly (rather than through FIXED_WIDE_INT) |

455 | so as not to confuse gengtype. */ |

456 | typedef generic_wide_int < fixed_wide_int_storage |

457 | <int_traits <T1>::precision> > result_type; |

458 | typedef result_type operator_result; |

459 | typedef bool predicate_result; |

460 | typedef result_type signed_shift_result_type; |

461 | typedef bool signed_predicate_result; |

462 | }; |

463 | |

464 | template <typename T1, typename T2> |

465 | struct binary_traits <T1, T2, VAR_PRECISION, VAR_PRECISION> |

466 | { |

467 | typedef wide_int result_type; |

468 | typedef result_type operator_result; |

469 | typedef bool predicate_result; |

470 | }; |

471 | } |

472 | |

473 | /* Public functions for querying and operating on integers. */ |

474 | namespace wi |

475 | { |

476 | template <typename T> |

477 | unsigned int get_precision (const T &); |

478 | |

479 | template <typename T1, typename T2> |

480 | unsigned int get_binary_precision (const T1 &, const T2 &); |

481 | |

482 | template <typename T1, typename T2> |

483 | void copy (T1 &, const T2 &); |

484 | |

485 | #define UNARY_PREDICATE \ |

486 | template <typename T> bool |

487 | #define UNARY_FUNCTION \ |

488 | template <typename T> WI_UNARY_RESULT (T) |

489 | #define BINARY_PREDICATE \ |

490 | template <typename T1, typename T2> bool |

491 | #define BINARY_FUNCTION \ |

492 | template <typename T1, typename T2> WI_BINARY_RESULT (T1, T2) |

493 | #define SHIFT_FUNCTION \ |

494 | template <typename T1, typename T2> WI_UNARY_RESULT (T1) |

495 | |

496 | UNARY_PREDICATE fits_shwi_p (const T &); |

497 | UNARY_PREDICATE fits_uhwi_p (const T &); |

498 | UNARY_PREDICATE neg_p (const T &, signop = SIGNED); |

499 | |

500 | template <typename T> |

501 | HOST_WIDE_INT sign_mask (const T &); |

502 | |

503 | BINARY_PREDICATE eq_p (const T1 &, const T2 &); |

504 | BINARY_PREDICATE ne_p (const T1 &, const T2 &); |

505 | BINARY_PREDICATE lt_p (const T1 &, const T2 &, signop); |

506 | BINARY_PREDICATE lts_p (const T1 &, const T2 &); |

507 | BINARY_PREDICATE ltu_p (const T1 &, const T2 &); |

508 | BINARY_PREDICATE le_p (const T1 &, const T2 &, signop); |

509 | BINARY_PREDICATE les_p (const T1 &, const T2 &); |

510 | BINARY_PREDICATE leu_p (const T1 &, const T2 &); |

511 | BINARY_PREDICATE gt_p (const T1 &, const T2 &, signop); |

512 | BINARY_PREDICATE gts_p (const T1 &, const T2 &); |

513 | BINARY_PREDICATE gtu_p (const T1 &, const T2 &); |

514 | BINARY_PREDICATE ge_p (const T1 &, const T2 &, signop); |

515 | BINARY_PREDICATE ges_p (const T1 &, const T2 &); |

516 | BINARY_PREDICATE geu_p (const T1 &, const T2 &); |

517 | |

518 | template <typename T1, typename T2> |

519 | int cmp (const T1 &, const T2 &, signop); |

520 | |

521 | template <typename T1, typename T2> |

522 | int cmps (const T1 &, const T2 &); |

523 | |

524 | template <typename T1, typename T2> |

525 | int cmpu (const T1 &, const T2 &); |

526 | |

527 | UNARY_FUNCTION bit_not (const T &); |

528 | UNARY_FUNCTION neg (const T &); |

529 | UNARY_FUNCTION neg (const T &, bool *); |

530 | UNARY_FUNCTION abs (const T &); |

531 | UNARY_FUNCTION ext (const T &, unsigned int, signop); |

532 | UNARY_FUNCTION sext (const T &, unsigned int); |

533 | UNARY_FUNCTION zext (const T &, unsigned int); |

534 | UNARY_FUNCTION set_bit (const T &, unsigned int); |

535 | |

536 | BINARY_FUNCTION min (const T1 &, const T2 &, signop); |

537 | BINARY_FUNCTION smin (const T1 &, const T2 &); |

538 | BINARY_FUNCTION umin (const T1 &, const T2 &); |

539 | BINARY_FUNCTION max (const T1 &, const T2 &, signop); |

540 | BINARY_FUNCTION smax (const T1 &, const T2 &); |

541 | BINARY_FUNCTION umax (const T1 &, const T2 &); |

542 | |

543 | BINARY_FUNCTION bit_and (const T1 &, const T2 &); |

544 | BINARY_FUNCTION bit_and_not (const T1 &, const T2 &); |

545 | BINARY_FUNCTION bit_or (const T1 &, const T2 &); |

546 | BINARY_FUNCTION bit_or_not (const T1 &, const T2 &); |

547 | BINARY_FUNCTION bit_xor (const T1 &, const T2 &); |

548 | BINARY_FUNCTION add (const T1 &, const T2 &); |

549 | BINARY_FUNCTION add (const T1 &, const T2 &, signop, bool *); |

550 | BINARY_FUNCTION sub (const T1 &, const T2 &); |

551 | BINARY_FUNCTION sub (const T1 &, const T2 &, signop, bool *); |

552 | BINARY_FUNCTION mul (const T1 &, const T2 &); |

553 | BINARY_FUNCTION mul (const T1 &, const T2 &, signop, bool *); |

554 | BINARY_FUNCTION smul (const T1 &, const T2 &, bool *); |

555 | BINARY_FUNCTION umul (const T1 &, const T2 &, bool *); |

556 | BINARY_FUNCTION mul_high (const T1 &, const T2 &, signop); |

557 | BINARY_FUNCTION div_trunc (const T1 &, const T2 &, signop, bool * = 0); |

558 | BINARY_FUNCTION sdiv_trunc (const T1 &, const T2 &); |

559 | BINARY_FUNCTION udiv_trunc (const T1 &, const T2 &); |

560 | BINARY_FUNCTION div_floor (const T1 &, const T2 &, signop, bool * = 0); |

561 | BINARY_FUNCTION udiv_floor (const T1 &, const T2 &); |

562 | BINARY_FUNCTION sdiv_floor (const T1 &, const T2 &); |

563 | BINARY_FUNCTION div_ceil (const T1 &, const T2 &, signop, bool * = 0); |

564 | BINARY_FUNCTION div_round (const T1 &, const T2 &, signop, bool * = 0); |

565 | BINARY_FUNCTION divmod_trunc (const T1 &, const T2 &, signop, |

566 | WI_BINARY_RESULT (T1, T2) *); |

567 | BINARY_FUNCTION gcd (const T1 &, const T2 &, signop = UNSIGNED); |

568 | BINARY_FUNCTION mod_trunc (const T1 &, const T2 &, signop, bool * = 0); |

569 | BINARY_FUNCTION smod_trunc (const T1 &, const T2 &); |

570 | BINARY_FUNCTION umod_trunc (const T1 &, const T2 &); |

571 | BINARY_FUNCTION mod_floor (const T1 &, const T2 &, signop, bool * = 0); |

572 | BINARY_FUNCTION umod_floor (const T1 &, const T2 &); |

573 | BINARY_FUNCTION mod_ceil (const T1 &, const T2 &, signop, bool * = 0); |

574 | BINARY_FUNCTION mod_round (const T1 &, const T2 &, signop, bool * = 0); |

575 | |

576 | template <typename T1, typename T2> |

577 | bool multiple_of_p (const T1 &, const T2 &, signop); |

578 | |

579 | template <typename T1, typename T2> |

580 | bool multiple_of_p (const T1 &, const T2 &, signop, |

581 | WI_BINARY_RESULT (T1, T2) *); |

582 | |

583 | SHIFT_FUNCTION lshift (const T1 &, const T2 &); |

584 | SHIFT_FUNCTION lrshift (const T1 &, const T2 &); |

585 | SHIFT_FUNCTION arshift (const T1 &, const T2 &); |

586 | SHIFT_FUNCTION rshift (const T1 &, const T2 &, signop sgn); |

587 | SHIFT_FUNCTION lrotate (const T1 &, const T2 &, unsigned int = 0); |

588 | SHIFT_FUNCTION rrotate (const T1 &, const T2 &, unsigned int = 0); |

589 | |

590 | #undef SHIFT_FUNCTION |

591 | #undef BINARY_PREDICATE |

592 | #undef BINARY_FUNCTION |

593 | #undef UNARY_PREDICATE |

594 | #undef UNARY_FUNCTION |

595 | |

596 | bool only_sign_bit_p (const wide_int_ref &, unsigned int); |

597 | bool only_sign_bit_p (const wide_int_ref &); |

598 | int clz (const wide_int_ref &); |

599 | int clrsb (const wide_int_ref &); |

600 | int ctz (const wide_int_ref &); |

601 | int exact_log2 (const wide_int_ref &); |

602 | int floor_log2 (const wide_int_ref &); |

603 | int ffs (const wide_int_ref &); |

604 | int popcount (const wide_int_ref &); |

605 | int parity (const wide_int_ref &); |

606 | |

607 | template <typename T> |

608 | unsigned HOST_WIDE_INT extract_uhwi (const T &, unsigned int, unsigned int); |

609 | |

610 | template <typename T> |

611 | unsigned int min_precision (const T &, signop); |

612 | } |

613 | |

614 | namespace wi |

615 | { |

616 | /* Contains the components of a decomposed integer for easy, direct |

617 | access. */ |

618 | struct storage_ref |

619 | { |

620 | storage_ref (const HOST_WIDE_INT *, unsigned int, unsigned int); |

621 | |

622 | const HOST_WIDE_INT *val; |

623 | unsigned int len; |

624 | unsigned int precision; |

625 | |

626 | /* Provide enough trappings for this class to act as storage for |

627 | generic_wide_int. */ |

628 | unsigned int get_len () const; |

629 | unsigned int get_precision () const; |

630 | const HOST_WIDE_INT *get_val () const; |

631 | }; |

632 | } |

633 | |

634 | inline::wi::storage_ref::storage_ref (const HOST_WIDE_INT *val_in, |

635 | unsigned int len_in, |

636 | unsigned int precision_in) |

637 | : val (val_in), len (len_in), precision (precision_in) |

638 | { |

639 | } |

640 | |

641 | inline unsigned int |

642 | wi::storage_ref::get_len () const |

643 | { |

644 | return len; |

645 | } |

646 | |

647 | inline unsigned int |

648 | wi::storage_ref::get_precision () const |

649 | { |

650 | return precision; |

651 | } |

652 | |

653 | inline const HOST_WIDE_INT * |

654 | wi::storage_ref::get_val () const |

655 | { |

656 | return val; |

657 | } |

658 | |

659 | /* This class defines an integer type using the storage provided by the |

660 | template argument. The storage class must provide the following |

661 | functions: |

662 | |

663 | unsigned int get_precision () const |

664 | Return the number of bits in the integer. |

665 | |

666 | HOST_WIDE_INT *get_val () const |

667 | Return a pointer to the array of blocks that encodes the integer. |

668 | |

669 | unsigned int get_len () const |

670 | Return the number of blocks in get_val (). If this is smaller |

671 | than the number of blocks implied by get_precision (), the |

672 | remaining blocks are sign extensions of block get_len () - 1. |

673 | |

674 | Although not required by generic_wide_int itself, writable storage |

675 | classes can also provide the following functions: |

676 | |

677 | HOST_WIDE_INT *write_val () |

678 | Get a modifiable version of get_val () |

679 | |

680 | unsigned int set_len (unsigned int len) |

681 | Set the value returned by get_len () to LEN. */ |

682 | template <typename storage> |

683 | class GTY(()) generic_wide_int : public storage |

684 | { |

685 | public: |

686 | generic_wide_int (); |

687 | |

688 | template <typename T> |

689 | generic_wide_int (const T &); |

690 | |

691 | template <typename T> |

692 | generic_wide_int (const T &, unsigned int); |

693 | |

694 | /* Conversions. */ |

695 | HOST_WIDE_INT to_shwi (unsigned int) const; |

696 | HOST_WIDE_INT to_shwi () const; |

697 | unsigned HOST_WIDE_INT to_uhwi (unsigned int) const; |

698 | unsigned HOST_WIDE_INT to_uhwi () const; |

699 | HOST_WIDE_INT to_short_addr () const; |

700 | |

701 | /* Public accessors for the interior of a wide int. */ |

702 | HOST_WIDE_INT sign_mask () const; |

703 | HOST_WIDE_INT elt (unsigned int) const; |

704 | unsigned HOST_WIDE_INT ulow () const; |

705 | unsigned HOST_WIDE_INT uhigh () const; |

706 | HOST_WIDE_INT slow () const; |

707 | HOST_WIDE_INT shigh () const; |

708 | |

709 | template <typename T> |

710 | generic_wide_int &operator = (const T &); |

711 | |

712 | #define ASSIGNMENT_OPERATOR(OP, F) \ |

713 | template <typename T> \ |

714 | generic_wide_int &OP (const T &c) { return (*this = wi::F (*this, c)); } |

715 | |

716 | /* Restrict these to cases where the shift operator is defined. */ |

717 | #define SHIFT_ASSIGNMENT_OPERATOR(OP, OP2) \ |

718 | template <typename T> \ |

719 | generic_wide_int &OP (const T &c) { return (*this = *this OP2 c); } |

720 | |

721 | #define INCDEC_OPERATOR(OP, DELTA) \ |

722 | generic_wide_int &OP () { *this += DELTA; return *this; } |

723 | |

724 | ASSIGNMENT_OPERATOR (operator &=, bit_and) |

725 | ASSIGNMENT_OPERATOR (operator |=, bit_or) |

726 | ASSIGNMENT_OPERATOR (operator ^=, bit_xor) |

727 | ASSIGNMENT_OPERATOR (operator +=, add) |

728 | ASSIGNMENT_OPERATOR (operator -=, sub) |

729 | ASSIGNMENT_OPERATOR (operator *=, mul) |

730 | SHIFT_ASSIGNMENT_OPERATOR (operator <<=, <<) |

731 | SHIFT_ASSIGNMENT_OPERATOR (operator >>=, >>) |

732 | INCDEC_OPERATOR (operator ++, 1) |

733 | INCDEC_OPERATOR (operator --, -1) |

734 | |

735 | #undef SHIFT_ASSIGNMENT_OPERATOR |

736 | #undef ASSIGNMENT_OPERATOR |

737 | #undef INCDEC_OPERATOR |

738 | |

739 | /* Debugging functions. */ |

740 | void dump () const; |

741 | |

742 | static const bool is_sign_extended |

743 | = wi::int_traits <generic_wide_int <storage> >::is_sign_extended; |

744 | }; |

745 | |

746 | template <typename storage> |

747 | inline generic_wide_int <storage>::generic_wide_int () {} |

748 | |

749 | template <typename storage> |

750 | template <typename T> |

751 | inline generic_wide_int <storage>::generic_wide_int (const T &x) |

752 | : storage (x) |

753 | { |

754 | } |

755 | |

756 | template <typename storage> |

757 | template <typename T> |

758 | inline generic_wide_int <storage>::generic_wide_int (const T &x, |

759 | unsigned int precision) |

760 | : storage (x, precision) |

761 | { |

762 | } |

763 | |

764 | /* Return THIS as a signed HOST_WIDE_INT, sign-extending from PRECISION. |

765 | If THIS does not fit in PRECISION, the information is lost. */ |

766 | template <typename storage> |

767 | inline HOST_WIDE_INT |

768 | generic_wide_int <storage>::to_shwi (unsigned int precision) const |

769 | { |

770 | if (precision < HOST_BITS_PER_WIDE_INT) |

771 | return sext_hwi (this->get_val ()[0], precision); |

772 | else |

773 | return this->get_val ()[0]; |

774 | } |

775 | |

776 | /* Return THIS as a signed HOST_WIDE_INT, in its natural precision. */ |

777 | template <typename storage> |

778 | inline HOST_WIDE_INT |

779 | generic_wide_int <storage>::to_shwi () const |

780 | { |

781 | if (is_sign_extended) |

782 | return this->get_val ()[0]; |

783 | else |

784 | return to_shwi (this->get_precision ()); |

785 | } |

786 | |

787 | /* Return THIS as an unsigned HOST_WIDE_INT, zero-extending from |

788 | PRECISION. If THIS does not fit in PRECISION, the information |

789 | is lost. */ |

790 | template <typename storage> |

791 | inline unsigned HOST_WIDE_INT |

792 | generic_wide_int <storage>::to_uhwi (unsigned int precision) const |

793 | { |

794 | if (precision < HOST_BITS_PER_WIDE_INT) |

795 | return zext_hwi (this->get_val ()[0], precision); |

796 | else |

797 | return this->get_val ()[0]; |

798 | } |

799 | |

800 | /* Return THIS as an signed HOST_WIDE_INT, in its natural precision. */ |

801 | template <typename storage> |

802 | inline unsigned HOST_WIDE_INT |

803 | generic_wide_int <storage>::to_uhwi () const |

804 | { |

805 | return to_uhwi (this->get_precision ()); |

806 | } |

807 | |

808 | /* TODO: The compiler is half converted from using HOST_WIDE_INT to |

809 | represent addresses to using offset_int to represent addresses. |

810 | We use to_short_addr at the interface from new code to old, |

811 | unconverted code. */ |

812 | template <typename storage> |

813 | inline HOST_WIDE_INT |

814 | generic_wide_int <storage>::to_short_addr () const |

815 | { |

816 | return this->get_val ()[0]; |

817 | } |

818 | |

819 | /* Return the implicit value of blocks above get_len (). */ |

820 | template <typename storage> |

821 | inline HOST_WIDE_INT |

822 | generic_wide_int <storage>::sign_mask () const |

823 | { |

824 | unsigned int len = this->get_len (); |

825 | unsigned HOST_WIDE_INT high = this->get_val ()[len - 1]; |

826 | if (!is_sign_extended) |

827 | { |

828 | unsigned int precision = this->get_precision (); |

829 | int excess = len * HOST_BITS_PER_WIDE_INT - precision; |

830 | if (excess > 0) |

831 | high <<= excess; |

832 | } |

833 | return (HOST_WIDE_INT) (high) < 0 ? -1 : 0; |

834 | } |

835 | |

836 | /* Return the signed value of the least-significant explicitly-encoded |

837 | block. */ |

838 | template <typename storage> |

839 | inline HOST_WIDE_INT |

840 | generic_wide_int <storage>::slow () const |

841 | { |

842 | return this->get_val ()[0]; |

843 | } |

844 | |

845 | /* Return the signed value of the most-significant explicitly-encoded |

846 | block. */ |

847 | template <typename storage> |

848 | inline HOST_WIDE_INT |

849 | generic_wide_int <storage>::shigh () const |

850 | { |

851 | return this->get_val ()[this->get_len () - 1]; |

852 | } |

853 | |

854 | /* Return the unsigned value of the least-significant |

855 | explicitly-encoded block. */ |

856 | template <typename storage> |

857 | inline unsigned HOST_WIDE_INT |

858 | generic_wide_int <storage>::ulow () const |

859 | { |

860 | return this->get_val ()[0]; |

861 | } |

862 | |

863 | /* Return the unsigned value of the most-significant |

864 | explicitly-encoded block. */ |

865 | template <typename storage> |

866 | inline unsigned HOST_WIDE_INT |

867 | generic_wide_int <storage>::uhigh () const |

868 | { |

869 | return this->get_val ()[this->get_len () - 1]; |

870 | } |

871 | |

872 | /* Return block I, which might be implicitly or explicit encoded. */ |

873 | template <typename storage> |

874 | inline HOST_WIDE_INT |

875 | generic_wide_int <storage>::elt (unsigned int i) const |

876 | { |

877 | if (i >= this->get_len ()) |

878 | return sign_mask (); |

879 | else |

880 | return this->get_val ()[i]; |

881 | } |

882 | |

883 | template <typename storage> |

884 | template <typename T> |

885 | inline generic_wide_int <storage> & |

886 | generic_wide_int <storage>::operator = (const T &x) |

887 | { |

888 | storage::operator = (x); |

889 | return *this; |

890 | } |

891 | |

892 | /* Dump the contents of the integer to stderr, for debugging. */ |

893 | template <typename storage> |

894 | void |

895 | generic_wide_int <storage>::dump () const |

896 | { |

897 | unsigned int len = this->get_len (); |

898 | const HOST_WIDE_INT *val = this->get_val (); |

899 | unsigned int precision = this->get_precision (); |

900 | fprintf (stderr, "["); |

901 | if (len * HOST_BITS_PER_WIDE_INT < precision) |

902 | fprintf (stderr, "...,"); |

903 | for (unsigned int i = 0; i < len - 1; ++i) |

904 | fprintf (stderr, HOST_WIDE_INT_PRINT_HEX ",", val[len - 1 - i]); |

905 | fprintf (stderr, HOST_WIDE_INT_PRINT_HEX "], precision = %d\n", |

906 | val[0], precision); |

907 | } |

908 | |

909 | namespace wi |

910 | { |

911 | template <typename storage> |

912 | struct int_traits < generic_wide_int <storage> > |

913 | : public wi::int_traits <storage> |

914 | { |

915 | static unsigned int get_precision (const generic_wide_int <storage> &); |

916 | static wi::storage_ref decompose (HOST_WIDE_INT *, unsigned int, |

917 | const generic_wide_int <storage> &); |

918 | }; |

919 | } |

920 | |

921 | template <typename storage> |

922 | inline unsigned int |

923 | wi::int_traits < generic_wide_int <storage> >:: |

924 | get_precision (const generic_wide_int <storage> &x) |

925 | { |

926 | return x.get_precision (); |

927 | } |

928 | |

929 | template <typename storage> |

930 | inline wi::storage_ref |

931 | wi::int_traits < generic_wide_int <storage> >:: |

932 | decompose (HOST_WIDE_INT *, unsigned int precision, |

933 | const generic_wide_int <storage> &x) |

934 | { |

935 | gcc_checking_assert (precision == x.get_precision ()); |

936 | return wi::storage_ref (x.get_val (), x.get_len (), precision); |

937 | } |

938 | |

939 | /* Provide the storage for a wide_int_ref. This acts like a read-only |

940 | wide_int, with the optimization that VAL is normally a pointer to |

941 | another integer's storage, so that no array copy is needed. */ |

942 | template <bool SE, bool HDP> |

943 | struct wide_int_ref_storage : public wi::storage_ref |

944 | { |

945 | private: |

946 | /* Scratch space that can be used when decomposing the original integer. |

947 | It must live as long as this object. */ |

948 | HOST_WIDE_INT scratch[2]; |

949 | |

950 | public: |

951 | wide_int_ref_storage (const wi::storage_ref &); |

952 | |

953 | template <typename T> |

954 | wide_int_ref_storage (const T &); |

955 | |

956 | template <typename T> |

957 | wide_int_ref_storage (const T &, unsigned int); |

958 | }; |

959 | |

960 | /* Create a reference from an existing reference. */ |

961 | template <bool SE, bool HDP> |

962 | inline wide_int_ref_storage <SE, HDP>:: |

963 | wide_int_ref_storage (const wi::storage_ref &x) |

964 | : storage_ref (x) |

965 | {} |

966 | |

967 | /* Create a reference to integer X in its natural precision. Note |

968 | that the natural precision is host-dependent for primitive |

969 | types. */ |

970 | template <bool SE, bool HDP> |

971 | template <typename T> |

972 | inline wide_int_ref_storage <SE, HDP>::wide_int_ref_storage (const T &x) |

973 | : storage_ref (wi::int_traits <T>::decompose (scratch, |

974 | wi::get_precision (x), x)) |

975 | { |

976 | } |

977 | |

978 | /* Create a reference to integer X in precision PRECISION. */ |

979 | template <bool SE, bool HDP> |

980 | template <typename T> |

981 | inline wide_int_ref_storage <SE, HDP>:: |

982 | wide_int_ref_storage (const T &x, unsigned int precision) |

983 | : storage_ref (wi::int_traits <T>::decompose (scratch, precision, x)) |

984 | { |

985 | } |

986 | |

987 | namespace wi |

988 | { |

989 | template <bool SE, bool HDP> |

990 | struct int_traits <wide_int_ref_storage <SE, HDP> > |

991 | { |

992 | static const enum precision_type precision_type = VAR_PRECISION; |

993 | static const bool host_dependent_precision = HDP; |

994 | static const bool is_sign_extended = SE; |

995 | }; |

996 | } |

997 | |

998 | namespace wi |

999 | { |

1000 | unsigned int force_to_size (HOST_WIDE_INT *, const HOST_WIDE_INT *, |

1001 | unsigned int, unsigned int, unsigned int, |

1002 | signop sgn); |

1003 | unsigned int from_array (HOST_WIDE_INT *, const HOST_WIDE_INT *, |

1004 | unsigned int, unsigned int, bool = true); |

1005 | } |

1006 | |

1007 | /* The storage used by wide_int. */ |

1008 | class GTY(()) wide_int_storage |

1009 | { |

1010 | private: |

1011 | HOST_WIDE_INT val[WIDE_INT_MAX_ELTS]; |

1012 | unsigned int len; |

1013 | unsigned int precision; |

1014 | |

1015 | public: |

1016 | wide_int_storage (); |

1017 | template <typename T> |

1018 | wide_int_storage (const T &); |

1019 | |

1020 | /* The standard generic_wide_int storage methods. */ |

1021 | unsigned int get_precision () const; |

1022 | const HOST_WIDE_INT *get_val () const; |

1023 | unsigned int get_len () const; |

1024 | HOST_WIDE_INT *write_val (); |

1025 | void set_len (unsigned int, bool = false); |

1026 | |

1027 | template <typename T> |

1028 | wide_int_storage &operator = (const T &); |

1029 | |

1030 | static wide_int from (const wide_int_ref &, unsigned int, signop); |

1031 | static wide_int from_array (const HOST_WIDE_INT *, unsigned int, |

1032 | unsigned int, bool = true); |

1033 | static wide_int create (unsigned int); |

1034 | |

1035 | /* FIXME: target-dependent, so should disappear. */ |

1036 | wide_int bswap () const; |

1037 | }; |

1038 | |

1039 | namespace wi |

1040 | { |

1041 | template <> |

1042 | struct int_traits <wide_int_storage> |

1043 | { |

1044 | static const enum precision_type precision_type = VAR_PRECISION; |

1045 | /* Guaranteed by a static assert in the wide_int_storage constructor. */ |

1046 | static const bool host_dependent_precision = false; |

1047 | static const bool is_sign_extended = true; |

1048 | template <typename T1, typename T2> |

1049 | static wide_int get_binary_result (const T1 &, const T2 &); |

1050 | }; |

1051 | } |

1052 | |

1053 | inline wide_int_storage::wide_int_storage () {} |

1054 | |

1055 | /* Initialize the storage from integer X, in its natural precision. |

1056 | Note that we do not allow integers with host-dependent precision |

1057 | to become wide_ints; wide_ints must always be logically independent |

1058 | of the host. */ |

1059 | template <typename T> |

1060 | inline wide_int_storage::wide_int_storage (const T &x) |

1061 | { |

1062 | { STATIC_ASSERT (!wi::int_traits<T>::host_dependent_precision); } |

1063 | { STATIC_ASSERT (wi::int_traits<T>::precision_type != wi::CONST_PRECISION); } |

1064 | WIDE_INT_REF_FOR (T) xi (x); |

1065 | precision = xi.precision; |

1066 | wi::copy (*this, xi); |

1067 | } |

1068 | |

1069 | template <typename T> |

1070 | inline wide_int_storage& |

1071 | wide_int_storage::operator = (const T &x) |

1072 | { |

1073 | { STATIC_ASSERT (!wi::int_traits<T>::host_dependent_precision); } |

1074 | { STATIC_ASSERT (wi::int_traits<T>::precision_type != wi::CONST_PRECISION); } |

1075 | WIDE_INT_REF_FOR (T) xi (x); |

1076 | precision = xi.precision; |

1077 | wi::copy (*this, xi); |

1078 | return *this; |

1079 | } |

1080 | |

1081 | inline unsigned int |

1082 | wide_int_storage::get_precision () const |

1083 | { |

1084 | return precision; |

1085 | } |

1086 | |

1087 | inline const HOST_WIDE_INT * |

1088 | wide_int_storage::get_val () const |

1089 | { |

1090 | return val; |

1091 | } |

1092 | |

1093 | inline unsigned int |

1094 | wide_int_storage::get_len () const |

1095 | { |

1096 | return len; |

1097 | } |

1098 | |

1099 | inline HOST_WIDE_INT * |

1100 | wide_int_storage::write_val () |

1101 | { |

1102 | return val; |

1103 | } |

1104 | |

1105 | inline void |

1106 | wide_int_storage::set_len (unsigned int l, bool is_sign_extended) |

1107 | { |

1108 | len = l; |

1109 | if (!is_sign_extended && len * HOST_BITS_PER_WIDE_INT > precision) |

1110 | val[len - 1] = sext_hwi (val[len - 1], |

1111 | precision % HOST_BITS_PER_WIDE_INT); |

1112 | } |

1113 | |

1114 | /* Treat X as having signedness SGN and convert it to a PRECISION-bit |

1115 | number. */ |

1116 | inline wide_int |

1117 | wide_int_storage::from (const wide_int_ref &x, unsigned int precision, |

1118 | signop sgn) |

1119 | { |

1120 | wide_int result = wide_int::create (precision); |

1121 | result.set_len (wi::force_to_size (result.write_val (), x.val, x.len, |

1122 | x.precision, precision, sgn)); |

1123 | return result; |

1124 | } |

1125 | |

1126 | /* Create a wide_int from the explicit block encoding given by VAL and |

1127 | LEN. PRECISION is the precision of the integer. NEED_CANON_P is |

1128 | true if the encoding may have redundant trailing blocks. */ |

1129 | inline wide_int |

1130 | wide_int_storage::from_array (const HOST_WIDE_INT *val, unsigned int len, |

1131 | unsigned int precision, bool need_canon_p) |

1132 | { |

1133 | wide_int result = wide_int::create (precision); |

1134 | result.set_len (wi::from_array (result.write_val (), val, len, precision, |

1135 | need_canon_p)); |

1136 | return result; |

1137 | } |

1138 | |

1139 | /* Return an uninitialized wide_int with precision PRECISION. */ |

1140 | inline wide_int |

1141 | wide_int_storage::create (unsigned int precision) |

1142 | { |

1143 | wide_int x; |

1144 | x.precision = precision; |

1145 | return x; |

1146 | } |

1147 | |

1148 | template <typename T1, typename T2> |

1149 | inline wide_int |

1150 | wi::int_traits <wide_int_storage>::get_binary_result (const T1 &x, const T2 &y) |

1151 | { |

1152 | /* This shouldn't be used for two flexible-precision inputs. */ |

1153 | STATIC_ASSERT (wi::int_traits <T1>::precision_type != FLEXIBLE_PRECISION |

1154 | || wi::int_traits <T2>::precision_type != FLEXIBLE_PRECISION); |

1155 | if (wi::int_traits <T1>::precision_type == FLEXIBLE_PRECISION) |

1156 | return wide_int::create (wi::get_precision (y)); |

1157 | else |

1158 | return wide_int::create (wi::get_precision (x)); |

1159 | } |

1160 | |

1161 | /* The storage used by FIXED_WIDE_INT (N). */ |

1162 | template <int N> |

1163 | class GTY(()) fixed_wide_int_storage |

1164 | { |

1165 | private: |

1166 | HOST_WIDE_INT val[(N + HOST_BITS_PER_WIDE_INT + 1) / HOST_BITS_PER_WIDE_INT]; |

1167 | unsigned int len; |

1168 | |

1169 | public: |

1170 | fixed_wide_int_storage (); |

1171 | template <typename T> |

1172 | fixed_wide_int_storage (const T &); |

1173 | |

1174 | /* The standard generic_wide_int storage methods. */ |

1175 | unsigned int get_precision () const; |

1176 | const HOST_WIDE_INT *get_val () const; |

1177 | unsigned int get_len () const; |

1178 | HOST_WIDE_INT *write_val (); |

1179 | void set_len (unsigned int, bool = false); |

1180 | |

1181 | static FIXED_WIDE_INT (N) from (const wide_int_ref &, signop); |

1182 | static FIXED_WIDE_INT (N) from_array (const HOST_WIDE_INT *, unsigned int, |

1183 | bool = true); |

1184 | }; |

1185 | |

1186 | namespace wi |

1187 | { |

1188 | template <int N> |

1189 | struct int_traits < fixed_wide_int_storage <N> > |

1190 | { |

1191 | static const enum precision_type precision_type = CONST_PRECISION; |

1192 | static const bool host_dependent_precision = false; |

1193 | static const bool is_sign_extended = true; |

1194 | static const unsigned int precision = N; |

1195 | template <typename T1, typename T2> |

1196 | static FIXED_WIDE_INT (N) get_binary_result (const T1 &, const T2 &); |

1197 | }; |

1198 | } |

1199 | |

1200 | template <int N> |

1201 | inline fixed_wide_int_storage <N>::fixed_wide_int_storage () {} |

1202 | |

1203 | /* Initialize the storage from integer X, in precision N. */ |

1204 | template <int N> |

1205 | template <typename T> |

1206 | inline fixed_wide_int_storage <N>::fixed_wide_int_storage (const T &x) |

1207 | { |

1208 | /* Check for type compatibility. We don't want to initialize a |

1209 | fixed-width integer from something like a wide_int. */ |

1210 | WI_BINARY_RESULT (T, FIXED_WIDE_INT (N)) *assertion ATTRIBUTE_UNUSED; |

1211 | wi::copy (*this, WIDE_INT_REF_FOR (T) (x, N)); |

1212 | } |

1213 | |

1214 | template <int N> |

1215 | inline unsigned int |

1216 | fixed_wide_int_storage <N>::get_precision () const |

1217 | { |

1218 | return N; |

1219 | } |

1220 | |

1221 | template <int N> |

1222 | inline const HOST_WIDE_INT * |

1223 | fixed_wide_int_storage <N>::get_val () const |

1224 | { |

1225 | return val; |

1226 | } |

1227 | |

1228 | template <int N> |

1229 | inline unsigned int |

1230 | fixed_wide_int_storage <N>::get_len () const |

1231 | { |

1232 | return len; |

1233 | } |

1234 | |

1235 | template <int N> |

1236 | inline HOST_WIDE_INT * |

1237 | fixed_wide_int_storage <N>::write_val () |

1238 | { |

1239 | return val; |

1240 | } |

1241 | |

1242 | template <int N> |

1243 | inline void |

1244 | fixed_wide_int_storage <N>::set_len (unsigned int l, bool) |

1245 | { |

1246 | len = l; |

1247 | /* There are no excess bits in val[len - 1]. */ |

1248 | STATIC_ASSERT (N % HOST_BITS_PER_WIDE_INT == 0); |

1249 | } |

1250 | |

1251 | /* Treat X as having signedness SGN and convert it to an N-bit number. */ |

1252 | template <int N> |

1253 | inline FIXED_WIDE_INT (N) |

1254 | fixed_wide_int_storage <N>::from (const wide_int_ref &x, signop sgn) |

1255 | { |

1256 | FIXED_WIDE_INT (N) result; |

1257 | result.set_len (wi::force_to_size (result.write_val (), x.val, x.len, |

1258 | x.precision, N, sgn)); |

1259 | return result; |

1260 | } |

1261 | |

1262 | /* Create a FIXED_WIDE_INT (N) from the explicit block encoding given by |

1263 | VAL and LEN. NEED_CANON_P is true if the encoding may have redundant |

1264 | trailing blocks. */ |

1265 | template <int N> |

1266 | inline FIXED_WIDE_INT (N) |

1267 | fixed_wide_int_storage <N>::from_array (const HOST_WIDE_INT *val, |

1268 | unsigned int len, |

1269 | bool need_canon_p) |

1270 | { |

1271 | FIXED_WIDE_INT (N) result; |

1272 | result.set_len (wi::from_array (result.write_val (), val, len, |

1273 | N, need_canon_p)); |

1274 | return result; |

1275 | } |

1276 | |

1277 | template <int N> |

1278 | template <typename T1, typename T2> |

1279 | inline FIXED_WIDE_INT (N) |

1280 | wi::int_traits < fixed_wide_int_storage <N> >:: |

1281 | get_binary_result (const T1 &, const T2 &) |

1282 | { |

1283 | return FIXED_WIDE_INT (N) (); |

1284 | } |

1285 | |

1286 | /* A reference to one element of a trailing_wide_ints structure. */ |

1287 | class trailing_wide_int_storage |

1288 | { |

1289 | private: |

1290 | /* The precision of the integer, which is a fixed property of the |

1291 | parent trailing_wide_ints. */ |

1292 | unsigned int m_precision; |

1293 | |

1294 | /* A pointer to the length field. */ |

1295 | unsigned char *m_len; |

1296 | |

1297 | /* A pointer to the HWI array. There are enough elements to hold all |

1298 | values of precision M_PRECISION. */ |

1299 | HOST_WIDE_INT *m_val; |

1300 | |

1301 | public: |

1302 | trailing_wide_int_storage (unsigned int, unsigned char *, HOST_WIDE_INT *); |

1303 | |

1304 | /* The standard generic_wide_int storage methods. */ |

1305 | unsigned int get_len () const; |

1306 | unsigned int get_precision () const; |

1307 | const HOST_WIDE_INT *get_val () const; |

1308 | HOST_WIDE_INT *write_val (); |

1309 | void set_len (unsigned int, bool = false); |

1310 | |

1311 | template <typename T> |

1312 | trailing_wide_int_storage &operator = (const T &); |

1313 | }; |

1314 | |

1315 | typedef generic_wide_int <trailing_wide_int_storage> trailing_wide_int; |

1316 | |

1317 | /* trailing_wide_int behaves like a wide_int. */ |

1318 | namespace wi |

1319 | { |

1320 | template <> |

1321 | struct int_traits <trailing_wide_int_storage> |

1322 | : public int_traits <wide_int_storage> {}; |

1323 | } |

1324 | |

1325 | /* An array of N wide_int-like objects that can be put at the end of |

1326 | a variable-sized structure. Use extra_size to calculate how many |

1327 | bytes beyond the sizeof need to be allocated. Use set_precision |

1328 | to initialize the structure. */ |

1329 | template <int N> |

1330 | class GTY(()) trailing_wide_ints |

1331 | { |

1332 | private: |

1333 | /* The shared precision of each number. */ |

1334 | unsigned short m_precision; |

1335 | |

1336 | /* The shared maximum length of each number. */ |

1337 | unsigned char m_max_len; |

1338 | |

1339 | /* The current length of each number. */ |

1340 | unsigned char m_len[N]; |

1341 | |

1342 | /* The variable-length part of the structure, which always contains |

1343 | at least one HWI. Element I starts at index I * M_MAX_LEN. */ |

1344 | HOST_WIDE_INT m_val[1]; |

1345 | |

1346 | public: |

1347 | void set_precision (unsigned int); |

1348 | trailing_wide_int operator [] (unsigned int); |

1349 | static size_t extra_size (unsigned int); |

1350 | }; |

1351 | |

1352 | inline trailing_wide_int_storage:: |

1353 | trailing_wide_int_storage (unsigned int precision, unsigned char *len, |

1354 | HOST_WIDE_INT *val) |

1355 | : m_precision (precision), m_len (len), m_val (val) |

1356 | { |

1357 | } |

1358 | |

1359 | inline unsigned int |

1360 | trailing_wide_int_storage::get_len () const |

1361 | { |

1362 | return *m_len; |

1363 | } |

1364 | |

1365 | inline unsigned int |

1366 | trailing_wide_int_storage::get_precision () const |

1367 | { |

1368 | return m_precision; |

1369 | } |

1370 | |

1371 | inline const HOST_WIDE_INT * |

1372 | trailing_wide_int_storage::get_val () const |

1373 | { |

1374 | return m_val; |

1375 | } |

1376 | |

1377 | inline HOST_WIDE_INT * |

1378 | trailing_wide_int_storage::write_val () |

1379 | { |

1380 | return m_val; |

1381 | } |

1382 | |

1383 | inline void |

1384 | trailing_wide_int_storage::set_len (unsigned int len, bool is_sign_extended) |

1385 | { |

1386 | *m_len = len; |

1387 | if (!is_sign_extended && len * HOST_BITS_PER_WIDE_INT > m_precision) |

1388 | m_val[len - 1] = sext_hwi (m_val[len - 1], |

1389 | m_precision % HOST_BITS_PER_WIDE_INT); |

1390 | } |

1391 | |

1392 | template <typename T> |

1393 | inline trailing_wide_int_storage & |

1394 | trailing_wide_int_storage::operator = (const T &x) |

1395 | { |

1396 | WIDE_INT_REF_FOR (T) xi (x, m_precision); |

1397 | wi::copy (*this, xi); |

1398 | return *this; |

1399 | } |

1400 | |

1401 | /* Initialize the structure and record that all elements have precision |

1402 | PRECISION. */ |

1403 | template <int N> |

1404 | inline void |

1405 | trailing_wide_ints <N>::set_precision (unsigned int precision) |

1406 | { |

1407 | m_precision = precision; |

1408 | m_max_len = ((precision + HOST_BITS_PER_WIDE_INT - 1) |

1409 | / HOST_BITS_PER_WIDE_INT); |

1410 | } |

1411 | |

1412 | /* Return a reference to element INDEX. */ |

1413 | template <int N> |

1414 | inline trailing_wide_int |

1415 | trailing_wide_ints <N>::operator [] (unsigned int index) |

1416 | { |

1417 | return trailing_wide_int_storage (m_precision, &m_len[index], |

1418 | &m_val[index * m_max_len]); |

1419 | } |

1420 | |

1421 | /* Return how many extra bytes need to be added to the end of the structure |

1422 | in order to handle N wide_ints of precision PRECISION. */ |

1423 | template <int N> |

1424 | inline size_t |

1425 | trailing_wide_ints <N>::extra_size (unsigned int precision) |

1426 | { |

1427 | unsigned int max_len = ((precision + HOST_BITS_PER_WIDE_INT - 1) |

1428 | / HOST_BITS_PER_WIDE_INT); |

1429 | return (N * max_len - 1) * sizeof (HOST_WIDE_INT); |

1430 | } |

1431 | |

1432 | /* This macro is used in structures that end with a trailing_wide_ints field |

1433 | called FIELD. It declares get_NAME() and set_NAME() methods to access |

1434 | element I of FIELD. */ |

1435 | #define TRAILING_WIDE_INT_ACCESSOR(NAME, FIELD, I) \ |

1436 | trailing_wide_int get_##NAME () { return FIELD[I]; } \ |

1437 | template <typename T> void set_##NAME (const T &x) { FIELD[I] = x; } |

1438 | |

1439 | namespace wi |

1440 | { |

1441 | /* Implementation of int_traits for primitive integer types like "int". */ |

1442 | template <typename T, bool signed_p> |

1443 | struct primitive_int_traits |

1444 | { |

1445 | static const enum precision_type precision_type = FLEXIBLE_PRECISION; |

1446 | static const bool host_dependent_precision = true; |

1447 | static const bool is_sign_extended = true; |

1448 | static unsigned int get_precision (T); |

1449 | static wi::storage_ref decompose (HOST_WIDE_INT *, unsigned int, T); |

1450 | }; |

1451 | } |

1452 | |

1453 | template <typename T, bool signed_p> |

1454 | inline unsigned int |

1455 | wi::primitive_int_traits <T, signed_p>::get_precision (T) |

1456 | { |

1457 | return sizeof (T) * CHAR_BIT; |

1458 | } |

1459 | |

1460 | template <typename T, bool signed_p> |

1461 | inline wi::storage_ref |

1462 | wi::primitive_int_traits <T, signed_p>::decompose (HOST_WIDE_INT *scratch, |

1463 | unsigned int precision, T x) |

1464 | { |

1465 | scratch[0] = x; |

1466 | if (signed_p || scratch[0] >= 0 || precision <= HOST_BITS_PER_WIDE_INT) |

1467 | return wi::storage_ref (scratch, 1, precision); |

1468 | scratch[1] = 0; |

1469 | return wi::storage_ref (scratch, 2, precision); |

1470 | } |

1471 | |

1472 | /* Allow primitive C types to be used in wi:: routines. */ |

1473 | namespace wi |

1474 | { |

1475 | template <> |

1476 | struct int_traits <unsigned char> |

1477 | : public primitive_int_traits <unsigned char, false> {}; |

1478 | |

1479 | template <> |

1480 | struct int_traits <unsigned short> |

1481 | : public primitive_int_traits <unsigned short, false> {}; |

1482 | |

1483 | template <> |

1484 | struct int_traits <int> |

1485 | : public primitive_int_traits <int, true> {}; |

1486 | |

1487 | template <> |

1488 | struct int_traits <unsigned int> |

1489 | : public primitive_int_traits <unsigned int, false> {}; |

1490 | |

1491 | template <> |

1492 | struct int_traits <long> |

1493 | : public primitive_int_traits <long, true> {}; |

1494 | |

1495 | template <> |

1496 | struct int_traits <unsigned long> |

1497 | : public primitive_int_traits <unsigned long, false> {}; |

1498 | |

1499 | #if defined HAVE_LONG_LONG |

1500 | template <> |

1501 | struct int_traits <long long> |

1502 | : public primitive_int_traits <long long, true> {}; |

1503 | |

1504 | template <> |

1505 | struct int_traits <unsigned long long> |

1506 | : public primitive_int_traits <unsigned long long, false> {}; |

1507 | #endif |

1508 | } |

1509 | |

1510 | namespace wi |

1511 | { |

1512 | /* Stores HWI-sized integer VAL, treating it as having signedness SGN |

1513 | and precision PRECISION. */ |

1514 | struct hwi_with_prec |

1515 | { |

1516 | hwi_with_prec (HOST_WIDE_INT, unsigned int, signop); |

1517 | HOST_WIDE_INT val; |

1518 | unsigned int precision; |

1519 | signop sgn; |

1520 | }; |

1521 | |

1522 | hwi_with_prec shwi (HOST_WIDE_INT, unsigned int); |

1523 | hwi_with_prec uhwi (unsigned HOST_WIDE_INT, unsigned int); |

1524 | |

1525 | hwi_with_prec minus_one (unsigned int); |

1526 | hwi_with_prec zero (unsigned int); |

1527 | hwi_with_prec one (unsigned int); |

1528 | hwi_with_prec two (unsigned int); |

1529 | } |

1530 | |

1531 | inline wi::hwi_with_prec::hwi_with_prec (HOST_WIDE_INT v, unsigned int p, |

1532 | signop s) |

1533 | : precision (p), sgn (s) |

1534 | { |

1535 | if (precision < HOST_BITS_PER_WIDE_INT) |

1536 | val = sext_hwi (v, precision); |

1537 | else |

1538 | val = v; |

1539 | } |

1540 | |

1541 | /* Return a signed integer that has value VAL and precision PRECISION. */ |

1542 | inline wi::hwi_with_prec |

1543 | wi::shwi (HOST_WIDE_INT val, unsigned int precision) |

1544 | { |

1545 | return hwi_with_prec (val, precision, SIGNED); |

1546 | } |

1547 | |

1548 | /* Return an unsigned integer that has value VAL and precision PRECISION. */ |

1549 | inline wi::hwi_with_prec |

1550 | wi::uhwi (unsigned HOST_WIDE_INT val, unsigned int precision) |

1551 | { |

1552 | return hwi_with_prec (val, precision, UNSIGNED); |

1553 | } |

1554 | |

1555 | /* Return a wide int of -1 with precision PRECISION. */ |

1556 | inline wi::hwi_with_prec |

1557 | wi::minus_one (unsigned int precision) |

1558 | { |

1559 | return wi::shwi (-1, precision); |

1560 | } |

1561 | |

1562 | /* Return a wide int of 0 with precision PRECISION. */ |

1563 | inline wi::hwi_with_prec |

1564 | wi::zero (unsigned int precision) |

1565 | { |

1566 | return wi::shwi (0, precision); |

1567 | } |

1568 | |

1569 | /* Return a wide int of 1 with precision PRECISION. */ |

1570 | inline wi::hwi_with_prec |

1571 | wi::one (unsigned int precision) |

1572 | { |

1573 | return wi::shwi (1, precision); |

1574 | } |

1575 | |

1576 | /* Return a wide int of 2 with precision PRECISION. */ |

1577 | inline wi::hwi_with_prec |

1578 | wi::two (unsigned int precision) |

1579 | { |

1580 | return wi::shwi (2, precision); |

1581 | } |

1582 | |

1583 | namespace wi |

1584 | { |

1585 | template <> |

1586 | struct int_traits <wi::hwi_with_prec> |

1587 | { |

1588 | static const enum precision_type precision_type = VAR_PRECISION; |

1589 | /* hwi_with_prec has an explicitly-given precision, rather than the |

1590 | precision of HOST_WIDE_INT. */ |

1591 | static const bool host_dependent_precision = false; |

1592 | static const bool is_sign_extended = true; |

1593 | static unsigned int get_precision (const wi::hwi_with_prec &); |

1594 | static wi::storage_ref decompose (HOST_WIDE_INT *, unsigned int, |

1595 | const wi::hwi_with_prec &); |

1596 | }; |

1597 | } |

1598 | |

1599 | inline unsigned int |

1600 | wi::int_traits <wi::hwi_with_prec>::get_precision (const wi::hwi_with_prec &x) |

1601 | { |

1602 | return x.precision; |

1603 | } |

1604 | |

1605 | inline wi::storage_ref |

1606 | wi::int_traits <wi::hwi_with_prec>:: |

1607 | decompose (HOST_WIDE_INT *scratch, unsigned int precision, |

1608 | const wi::hwi_with_prec &x) |

1609 | { |

1610 | gcc_checking_assert (precision == x.precision); |

1611 | scratch[0] = x.val; |

1612 | if (x.sgn == SIGNED || x.val >= 0 || precision <= HOST_BITS_PER_WIDE_INT) |

1613 | return wi::storage_ref (scratch, 1, precision); |

1614 | scratch[1] = 0; |

1615 | return wi::storage_ref (scratch, 2, precision); |

1616 | } |

1617 | |

1618 | /* Private functions for handling large cases out of line. They take |

1619 | individual length and array parameters because that is cheaper for |

1620 | the inline caller than constructing an object on the stack and |

1621 | passing a reference to it. (Although many callers use wide_int_refs, |

1622 | we generally want those to be removed by SRA.) */ |

1623 | namespace wi |

1624 | { |

1625 | bool eq_p_large (const HOST_WIDE_INT *, unsigned int, |

1626 | const HOST_WIDE_INT *, unsigned int, unsigned int); |

1627 | bool lts_p_large (const HOST_WIDE_INT *, unsigned int, unsigned int, |

1628 | const HOST_WIDE_INT *, unsigned int); |

1629 | bool ltu_p_large (const HOST_WIDE_INT *, unsigned int, unsigned int, |

1630 | const HOST_WIDE_INT *, unsigned int); |

1631 | int cmps_large (const HOST_WIDE_INT *, unsigned int, unsigned int, |

1632 | const HOST_WIDE_INT *, unsigned int); |

1633 | int cmpu_large (const HOST_WIDE_INT *, unsigned int, unsigned int, |

1634 | const HOST_WIDE_INT *, unsigned int); |

1635 | unsigned int sext_large (HOST_WIDE_INT *, const HOST_WIDE_INT *, |

1636 | unsigned int, |

1637 | unsigned int, unsigned int); |

1638 | unsigned int zext_large (HOST_WIDE_INT *, const HOST_WIDE_INT *, |

1639 | unsigned int, |

1640 | unsigned int, unsigned int); |

1641 | unsigned int set_bit_large (HOST_WIDE_INT *, const HOST_WIDE_INT *, |

1642 | unsigned int, unsigned int, unsigned int); |

1643 | unsigned int lshift_large (HOST_WIDE_INT *, const HOST_WIDE_INT *, |

1644 | unsigned int, unsigned int, unsigned int); |

1645 | unsigned int lrshift_large (HOST_WIDE_INT *, const HOST_WIDE_INT *, |

1646 | unsigned int, unsigned int, unsigned int, |

1647 | unsigned int); |

1648 | unsigned int arshift_large (HOST_WIDE_INT *, const HOST_WIDE_INT *, |

1649 | unsigned int, unsigned int, unsigned int, |

1650 | unsigned int); |

1651 | unsigned int and_large (HOST_WIDE_INT *, const HOST_WIDE_INT *, unsigned int, |

1652 | const HOST_WIDE_INT *, unsigned int, unsigned int); |

1653 | unsigned int and_not_large (HOST_WIDE_INT *, const HOST_WIDE_INT *, |

1654 | unsigned int, const HOST_WIDE_INT *, |

1655 | unsigned int, unsigned int); |

1656 | unsigned int or_large (HOST_WIDE_INT *, const HOST_WIDE_INT *, unsigned int, |

1657 | const HOST_WIDE_INT *, unsigned int, unsigned int); |

1658 | unsigned int or_not_large (HOST_WIDE_INT *, const HOST_WIDE_INT *, |

1659 | unsigned int, const HOST_WIDE_INT *, |

1660 | unsigned int, unsigned int); |

1661 | unsigned int xor_large (HOST_WIDE_INT *, const HOST_WIDE_INT *, unsigned int, |

1662 | const HOST_WIDE_INT *, unsigned int, unsigned int); |

1663 | unsigned int add_large (HOST_WIDE_INT *, const HOST_WIDE_INT *, unsigned int, |

1664 | const HOST_WIDE_INT *, unsigned int, unsigned int, |

1665 | signop, bool *); |

1666 | unsigned int sub_large (HOST_WIDE_INT *, const HOST_WIDE_INT *, unsigned int, |

1667 | const HOST_WIDE_INT *, unsigned int, unsigned int, |

1668 | signop, bool *); |

1669 | unsigned int mul_internal (HOST_WIDE_INT *, const HOST_WIDE_INT *, |

1670 | unsigned int, const HOST_WIDE_INT *, |

1671 | unsigned int, unsigned int, signop, bool *, |

1672 | bool); |

1673 | unsigned int divmod_internal (HOST_WIDE_INT *, unsigned int *, |

1674 | HOST_WIDE_INT *, const HOST_WIDE_INT *, |

1675 | unsigned int, unsigned int, |

1676 | const HOST_WIDE_INT *, |

1677 | unsigned int, unsigned int, |

1678 | signop, bool *); |

1679 | } |

1680 | |

1681 | /* Return the number of bits that integer X can hold. */ |

1682 | template <typename T> |

1683 | inline unsigned int |

1684 | wi::get_precision (const T &x) |

1685 | { |

1686 | return wi::int_traits <T>::get_precision (x); |

1687 | } |

1688 | |

1689 | /* Return the number of bits that the result of a binary operation can |

1690 | hold when the input operands are X and Y. */ |

1691 | template <typename T1, typename T2> |

1692 | inline unsigned int |

1693 | wi::get_binary_precision (const T1 &x, const T2 &y) |

1694 | { |

1695 | return get_precision (wi::int_traits <WI_BINARY_RESULT (T1, T2)>:: |

1696 | get_binary_result (x, y)); |

1697 | } |

1698 | |

1699 | /* Copy the contents of Y to X, but keeping X's current precision. */ |

1700 | template <typename T1, typename T2> |

1701 | inline void |

1702 | wi::copy (T1 &x, const T2 &y) |

1703 | { |

1704 | HOST_WIDE_INT *xval = x.write_val (); |

1705 | const HOST_WIDE_INT *yval = y.get_val (); |

1706 | unsigned int len = y.get_len (); |

1707 | unsigned int i = 0; |

1708 | do |

1709 | xval[i] = yval[i]; |

1710 | while (++i < len); |

1711 | x.set_len (len, y.is_sign_extended); |

1712 | } |

1713 | |

1714 | /* Return true if X fits in a HOST_WIDE_INT with no loss of precision. */ |

1715 | template <typename T> |

1716 | inline bool |

1717 | wi::fits_shwi_p (const T &x) |

1718 | { |

1719 | WIDE_INT_REF_FOR (T) xi (x); |

1720 | return xi.len == 1; |

1721 | } |

1722 | |

1723 | /* Return true if X fits in an unsigned HOST_WIDE_INT with no loss of |

1724 | precision. */ |

1725 | template <typename T> |

1726 | inline bool |

1727 | wi::fits_uhwi_p (const T &x) |

1728 | { |

1729 | WIDE_INT_REF_FOR (T) xi (x); |

1730 | if (xi.precision <= HOST_BITS_PER_WIDE_INT) |

1731 | return true; |

1732 | if (xi.len == 1) |

1733 | return xi.slow () >= 0; |

1734 | return xi.len == 2 && xi.uhigh () == 0; |

1735 | } |

1736 | |

1737 | /* Return true if X is negative based on the interpretation of SGN. |

1738 | For UNSIGNED, this is always false. */ |

1739 | template <typename T> |

1740 | inline bool |

1741 | wi::neg_p (const T &x, signop sgn) |

1742 | { |

1743 | WIDE_INT_REF_FOR (T) xi (x); |

1744 | if (sgn == UNSIGNED) |

1745 | return false; |

1746 | return xi.sign_mask () < 0; |

1747 | } |

1748 | |

1749 | /* Return -1 if the top bit of X is set and 0 if the top bit is clear. */ |

1750 | template <typename T> |

1751 | inline HOST_WIDE_INT |

1752 | wi::sign_mask (const T &x) |

1753 | { |

1754 | WIDE_INT_REF_FOR (T) xi (x); |

1755 | return xi.sign_mask (); |

1756 | } |

1757 | |

1758 | /* Return true if X == Y. X and Y must be binary-compatible. */ |

1759 | template <typename T1, typename T2> |

1760 | inline bool |

1761 | wi::eq_p (const T1 &x, const T2 &y) |

1762 | { |

1763 | unsigned int precision = get_binary_precision (x, y); |

1764 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

1765 | WIDE_INT_REF_FOR (T2) yi (y, precision); |

1766 | if (xi.is_sign_extended && yi.is_sign_extended) |

1767 | { |

1768 | /* This case reduces to array equality. */ |

1769 | if (xi.len != yi.len) |

1770 | return false; |

1771 | unsigned int i = 0; |

1772 | do |

1773 | if (xi.val[i] != yi.val[i]) |

1774 | return false; |

1775 | while (++i != xi.len); |

1776 | return true; |

1777 | } |

1778 | if (__builtin_expect (yi.len == 1, true)) |

1779 | { |

1780 | /* XI is only equal to YI if it too has a single HWI. */ |

1781 | if (xi.len != 1) |

1782 | return false; |

1783 | /* Excess bits in xi.val[0] will be signs or zeros, so comparisons |

1784 | with 0 are simple. */ |

1785 | if (STATIC_CONSTANT_P (yi.val[0] == 0)) |

1786 | return xi.val[0] == 0; |

1787 | /* Otherwise flush out any excess bits first. */ |

1788 | unsigned HOST_WIDE_INT diff = xi.val[0] ^ yi.val[0]; |

1789 | int excess = HOST_BITS_PER_WIDE_INT - precision; |

1790 | if (excess > 0) |

1791 | diff <<= excess; |

1792 | return diff == 0; |

1793 | } |

1794 | return eq_p_large (xi.val, xi.len, yi.val, yi.len, precision); |

1795 | } |

1796 | |

1797 | /* Return true if X != Y. X and Y must be binary-compatible. */ |

1798 | template <typename T1, typename T2> |

1799 | inline bool |

1800 | wi::ne_p (const T1 &x, const T2 &y) |

1801 | { |

1802 | return !eq_p (x, y); |

1803 | } |

1804 | |

1805 | /* Return true if X < Y when both are treated as signed values. */ |

1806 | template <typename T1, typename T2> |

1807 | inline bool |

1808 | wi::lts_p (const T1 &x, const T2 &y) |

1809 | { |

1810 | unsigned int precision = get_binary_precision (x, y); |

1811 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

1812 | WIDE_INT_REF_FOR (T2) yi (y, precision); |

1813 | /* We optimize x < y, where y is 64 or fewer bits. */ |

1814 | if (wi::fits_shwi_p (yi)) |

1815 | { |

1816 | /* Make lts_p (x, 0) as efficient as wi::neg_p (x). */ |

1817 | if (STATIC_CONSTANT_P (yi.val[0] == 0)) |

1818 | return neg_p (xi); |

1819 | /* If x fits directly into a shwi, we can compare directly. */ |

1820 | if (wi::fits_shwi_p (xi)) |

1821 | return xi.to_shwi () < yi.to_shwi (); |

1822 | /* If x doesn't fit and is negative, then it must be more |

1823 | negative than any value in y, and hence smaller than y. */ |

1824 | if (neg_p (xi)) |

1825 | return true; |

1826 | /* If x is positive, then it must be larger than any value in y, |

1827 | and hence greater than y. */ |

1828 | return false; |

1829 | } |

1830 | /* Optimize the opposite case, if it can be detected at compile time. */ |

1831 | if (STATIC_CONSTANT_P (xi.len == 1)) |

1832 | /* If YI is negative it is lower than the least HWI. |

1833 | If YI is positive it is greater than the greatest HWI. */ |

1834 | return !neg_p (yi); |

1835 | return lts_p_large (xi.val, xi.len, precision, yi.val, yi.len); |

1836 | } |

1837 | |

1838 | /* Return true if X < Y when both are treated as unsigned values. */ |

1839 | template <typename T1, typename T2> |

1840 | inline bool |

1841 | wi::ltu_p (const T1 &x, const T2 &y) |

1842 | { |

1843 | unsigned int precision = get_binary_precision (x, y); |

1844 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

1845 | WIDE_INT_REF_FOR (T2) yi (y, precision); |

1846 | /* Optimize comparisons with constants. */ |

1847 | if (STATIC_CONSTANT_P (yi.len == 1 && yi.val[0] >= 0)) |

1848 | return xi.len == 1 && xi.to_uhwi () < (unsigned HOST_WIDE_INT) yi.val[0]; |

1849 | if (STATIC_CONSTANT_P (xi.len == 1 && xi.val[0] >= 0)) |

1850 | return yi.len != 1 || yi.to_uhwi () > (unsigned HOST_WIDE_INT) xi.val[0]; |

1851 | /* Optimize the case of two HWIs. The HWIs are implicitly sign-extended |

1852 | for precisions greater than HOST_BITS_WIDE_INT, but sign-extending both |

1853 | values does not change the result. */ |

1854 | if (__builtin_expect (xi.len + yi.len == 2, true)) |

1855 | { |

1856 | unsigned HOST_WIDE_INT xl = xi.to_uhwi (); |

1857 | unsigned HOST_WIDE_INT yl = yi.to_uhwi (); |

1858 | return xl < yl; |

1859 | } |

1860 | return ltu_p_large (xi.val, xi.len, precision, yi.val, yi.len); |

1861 | } |

1862 | |

1863 | /* Return true if X < Y. Signedness of X and Y is indicated by SGN. */ |

1864 | template <typename T1, typename T2> |

1865 | inline bool |

1866 | wi::lt_p (const T1 &x, const T2 &y, signop sgn) |

1867 | { |

1868 | if (sgn == SIGNED) |

1869 | return lts_p (x, y); |

1870 | else |

1871 | return ltu_p (x, y); |

1872 | } |

1873 | |

1874 | /* Return true if X <= Y when both are treated as signed values. */ |

1875 | template <typename T1, typename T2> |

1876 | inline bool |

1877 | wi::les_p (const T1 &x, const T2 &y) |

1878 | { |

1879 | return !lts_p (y, x); |

1880 | } |

1881 | |

1882 | /* Return true if X <= Y when both are treated as unsigned values. */ |

1883 | template <typename T1, typename T2> |

1884 | inline bool |

1885 | wi::leu_p (const T1 &x, const T2 &y) |

1886 | { |

1887 | return !ltu_p (y, x); |

1888 | } |

1889 | |

1890 | /* Return true if X <= Y. Signedness of X and Y is indicated by SGN. */ |

1891 | template <typename T1, typename T2> |

1892 | inline bool |

1893 | wi::le_p (const T1 &x, const T2 &y, signop sgn) |

1894 | { |

1895 | if (sgn == SIGNED) |

1896 | return les_p (x, y); |

1897 | else |

1898 | return leu_p (x, y); |

1899 | } |

1900 | |

1901 | /* Return true if X > Y when both are treated as signed values. */ |

1902 | template <typename T1, typename T2> |

1903 | inline bool |

1904 | wi::gts_p (const T1 &x, const T2 &y) |

1905 | { |

1906 | return lts_p (y, x); |

1907 | } |

1908 | |

1909 | /* Return true if X > Y when both are treated as unsigned values. */ |

1910 | template <typename T1, typename T2> |

1911 | inline bool |

1912 | wi::gtu_p (const T1 &x, const T2 &y) |

1913 | { |

1914 | return ltu_p (y, x); |

1915 | } |

1916 | |

1917 | /* Return true if X > Y. Signedness of X and Y is indicated by SGN. */ |

1918 | template <typename T1, typename T2> |

1919 | inline bool |

1920 | wi::gt_p (const T1 &x, const T2 &y, signop sgn) |

1921 | { |

1922 | if (sgn == SIGNED) |

1923 | return gts_p (x, y); |

1924 | else |

1925 | return gtu_p (x, y); |

1926 | } |

1927 | |

1928 | /* Return true if X >= Y when both are treated as signed values. */ |

1929 | template <typename T1, typename T2> |

1930 | inline bool |

1931 | wi::ges_p (const T1 &x, const T2 &y) |

1932 | { |

1933 | return !lts_p (x, y); |

1934 | } |

1935 | |

1936 | /* Return true if X >= Y when both are treated as unsigned values. */ |

1937 | template <typename T1, typename T2> |

1938 | inline bool |

1939 | wi::geu_p (const T1 &x, const T2 &y) |

1940 | { |

1941 | return !ltu_p (x, y); |

1942 | } |

1943 | |

1944 | /* Return true if X >= Y. Signedness of X and Y is indicated by SGN. */ |

1945 | template <typename T1, typename T2> |

1946 | inline bool |

1947 | wi::ge_p (const T1 &x, const T2 &y, signop sgn) |

1948 | { |

1949 | if (sgn == SIGNED) |

1950 | return ges_p (x, y); |

1951 | else |

1952 | return geu_p (x, y); |

1953 | } |

1954 | |

1955 | /* Return -1 if X < Y, 0 if X == Y and 1 if X > Y. Treat both X and Y |

1956 | as signed values. */ |

1957 | template <typename T1, typename T2> |

1958 | inline int |

1959 | wi::cmps (const T1 &x, const T2 &y) |

1960 | { |

1961 | unsigned int precision = get_binary_precision (x, y); |

1962 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

1963 | WIDE_INT_REF_FOR (T2) yi (y, precision); |

1964 | if (wi::fits_shwi_p (yi)) |

1965 | { |

1966 | /* Special case for comparisons with 0. */ |

1967 | if (STATIC_CONSTANT_P (yi.val[0] == 0)) |

1968 | return neg_p (xi) ? -1 : !(xi.len == 1 && xi.val[0] == 0); |

1969 | /* If x fits into a signed HWI, we can compare directly. */ |

1970 | if (wi::fits_shwi_p (xi)) |

1971 | { |

1972 | HOST_WIDE_INT xl = xi.to_shwi (); |

1973 | HOST_WIDE_INT yl = yi.to_shwi (); |

1974 | return xl < yl ? -1 : xl > yl; |

1975 | } |

1976 | /* If x doesn't fit and is negative, then it must be more |

1977 | negative than any signed HWI, and hence smaller than y. */ |

1978 | if (neg_p (xi)) |

1979 | return -1; |

1980 | /* If x is positive, then it must be larger than any signed HWI, |

1981 | and hence greater than y. */ |

1982 | return 1; |

1983 | } |

1984 | /* Optimize the opposite case, if it can be detected at compile time. */ |

1985 | if (STATIC_CONSTANT_P (xi.len == 1)) |

1986 | /* If YI is negative it is lower than the least HWI. |

1987 | If YI is positive it is greater than the greatest HWI. */ |

1988 | return neg_p (yi) ? 1 : -1; |

1989 | return cmps_large (xi.val, xi.len, precision, yi.val, yi.len); |

1990 | } |

1991 | |

1992 | /* Return -1 if X < Y, 0 if X == Y and 1 if X > Y. Treat both X and Y |

1993 | as unsigned values. */ |

1994 | template <typename T1, typename T2> |

1995 | inline int |

1996 | wi::cmpu (const T1 &x, const T2 &y) |

1997 | { |

1998 | unsigned int precision = get_binary_precision (x, y); |

1999 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

2000 | WIDE_INT_REF_FOR (T2) yi (y, precision); |

2001 | /* Optimize comparisons with constants. */ |

2002 | if (STATIC_CONSTANT_P (yi.len == 1 && yi.val[0] >= 0)) |

2003 | { |

2004 | /* If XI doesn't fit in a HWI then it must be larger than YI. */ |

2005 | if (xi.len != 1) |

2006 | return 1; |

2007 | /* Otherwise compare directly. */ |

2008 | unsigned HOST_WIDE_INT xl = xi.to_uhwi (); |

2009 | unsigned HOST_WIDE_INT yl = yi.val[0]; |

2010 | return xl < yl ? -1 : xl > yl; |

2011 | } |

2012 | if (STATIC_CONSTANT_P (xi.len == 1 && xi.val[0] >= 0)) |

2013 | { |

2014 | /* If YI doesn't fit in a HWI then it must be larger than XI. */ |

2015 | if (yi.len != 1) |

2016 | return -1; |

2017 | /* Otherwise compare directly. */ |

2018 | unsigned HOST_WIDE_INT xl = xi.val[0]; |

2019 | unsigned HOST_WIDE_INT yl = yi.to_uhwi (); |

2020 | return xl < yl ? -1 : xl > yl; |

2021 | } |

2022 | /* Optimize the case of two HWIs. The HWIs are implicitly sign-extended |

2023 | for precisions greater than HOST_BITS_WIDE_INT, but sign-extending both |

2024 | values does not change the result. */ |

2025 | if (__builtin_expect (xi.len + yi.len == 2, true)) |

2026 | { |

2027 | unsigned HOST_WIDE_INT xl = xi.to_uhwi (); |

2028 | unsigned HOST_WIDE_INT yl = yi.to_uhwi (); |

2029 | return xl < yl ? -1 : xl > yl; |

2030 | } |

2031 | return cmpu_large (xi.val, xi.len, precision, yi.val, yi.len); |

2032 | } |

2033 | |

2034 | /* Return -1 if X < Y, 0 if X == Y and 1 if X > Y. Signedness of |

2035 | X and Y indicated by SGN. */ |

2036 | template <typename T1, typename T2> |

2037 | inline int |

2038 | wi::cmp (const T1 &x, const T2 &y, signop sgn) |

2039 | { |

2040 | if (sgn == SIGNED) |

2041 | return cmps (x, y); |

2042 | else |

2043 | return cmpu (x, y); |

2044 | } |

2045 | |

2046 | /* Return ~x. */ |

2047 | template <typename T> |

2048 | inline WI_UNARY_RESULT (T) |

2049 | wi::bit_not (const T &x) |

2050 | { |

2051 | WI_UNARY_RESULT_VAR (result, val, T, x); |

2052 | WIDE_INT_REF_FOR (T) xi (x, get_precision (result)); |

2053 | for (unsigned int i = 0; i < xi.len; ++i) |

2054 | val[i] = ~xi.val[i]; |

2055 | result.set_len (xi.len); |

2056 | return result; |

2057 | } |

2058 | |

2059 | /* Return -x. */ |

2060 | template <typename T> |

2061 | inline WI_UNARY_RESULT (T) |

2062 | wi::neg (const T &x) |

2063 | { |

2064 | return sub (0, x); |

2065 | } |

2066 | |

2067 | /* Return -x. Indicate in *OVERFLOW if X is the minimum signed value. */ |

2068 | template <typename T> |

2069 | inline WI_UNARY_RESULT (T) |

2070 | wi::neg (const T &x, bool *overflow) |

2071 | { |

2072 | *overflow = only_sign_bit_p (x); |

2073 | return sub (0, x); |

2074 | } |

2075 | |

2076 | /* Return the absolute value of x. */ |

2077 | template <typename T> |

2078 | inline WI_UNARY_RESULT (T) |

2079 | wi::abs (const T &x) |

2080 | { |

2081 | return neg_p (x) ? neg (x) : WI_UNARY_RESULT (T) (x); |

2082 | } |

2083 | |

2084 | /* Return the result of sign-extending the low OFFSET bits of X. */ |

2085 | template <typename T> |

2086 | inline WI_UNARY_RESULT (T) |

2087 | wi::sext (const T &x, unsigned int offset) |

2088 | { |

2089 | WI_UNARY_RESULT_VAR (result, val, T, x); |

2090 | unsigned int precision = get_precision (result); |

2091 | WIDE_INT_REF_FOR (T) xi (x, precision); |

2092 | |

2093 | if (offset <= HOST_BITS_PER_WIDE_INT) |

2094 | { |

2095 | val[0] = sext_hwi (xi.ulow (), offset); |

2096 | result.set_len (1, true); |

2097 | } |

2098 | else |

2099 | result.set_len (sext_large (val, xi.val, xi.len, precision, offset)); |

2100 | return result; |

2101 | } |

2102 | |

2103 | /* Return the result of zero-extending the low OFFSET bits of X. */ |

2104 | template <typename T> |

2105 | inline WI_UNARY_RESULT (T) |

2106 | wi::zext (const T &x, unsigned int offset) |

2107 | { |

2108 | WI_UNARY_RESULT_VAR (result, val, T, x); |

2109 | unsigned int precision = get_precision (result); |

2110 | WIDE_INT_REF_FOR (T) xi (x, precision); |

2111 | |

2112 | /* This is not just an optimization, it is actually required to |

2113 | maintain canonization. */ |

2114 | if (offset >= precision) |

2115 | { |

2116 | wi::copy (result, xi); |

2117 | return result; |

2118 | } |

2119 | |

2120 | /* In these cases we know that at least the top bit will be clear, |

2121 | so no sign extension is necessary. */ |

2122 | if (offset < HOST_BITS_PER_WIDE_INT) |

2123 | { |

2124 | val[0] = zext_hwi (xi.ulow (), offset); |

2125 | result.set_len (1, true); |

2126 | } |

2127 | else |

2128 | result.set_len (zext_large (val, xi.val, xi.len, precision, offset), true); |

2129 | return result; |

2130 | } |

2131 | |

2132 | /* Return the result of extending the low OFFSET bits of X according to |

2133 | signedness SGN. */ |

2134 | template <typename T> |

2135 | inline WI_UNARY_RESULT (T) |

2136 | wi::ext (const T &x, unsigned int offset, signop sgn) |

2137 | { |

2138 | return sgn == SIGNED ? sext (x, offset) : zext (x, offset); |

2139 | } |

2140 | |

2141 | /* Return an integer that represents X | (1 << bit). */ |

2142 | template <typename T> |

2143 | inline WI_UNARY_RESULT (T) |

2144 | wi::set_bit (const T &x, unsigned int bit) |

2145 | { |

2146 | WI_UNARY_RESULT_VAR (result, val, T, x); |

2147 | unsigned int precision = get_precision (result); |

2148 | WIDE_INT_REF_FOR (T) xi (x, precision); |

2149 | if (precision <= HOST_BITS_PER_WIDE_INT) |

2150 | { |

2151 | val[0] = xi.ulow () | (HOST_WIDE_INT_1U << bit); |

2152 | result.set_len (1); |

2153 | } |

2154 | else |

2155 | result.set_len (set_bit_large (val, xi.val, xi.len, precision, bit)); |

2156 | return result; |

2157 | } |

2158 | |

2159 | /* Return the mininum of X and Y, treating them both as having |

2160 | signedness SGN. */ |

2161 | template <typename T1, typename T2> |

2162 | inline WI_BINARY_RESULT (T1, T2) |

2163 | wi::min (const T1 &x, const T2 &y, signop sgn) |

2164 | { |

2165 | WI_BINARY_RESULT_VAR (result, val ATTRIBUTE_UNUSED, T1, x, T2, y); |

2166 | unsigned int precision = get_precision (result); |

2167 | if (wi::le_p (x, y, sgn)) |

2168 | wi::copy (result, WIDE_INT_REF_FOR (T1) (x, precision)); |

2169 | else |

2170 | wi::copy (result, WIDE_INT_REF_FOR (T2) (y, precision)); |

2171 | return result; |

2172 | } |

2173 | |

2174 | /* Return the minimum of X and Y, treating both as signed values. */ |

2175 | template <typename T1, typename T2> |

2176 | inline WI_BINARY_RESULT (T1, T2) |

2177 | wi::smin (const T1 &x, const T2 &y) |

2178 | { |

2179 | return wi::min (x, y, SIGNED); |

2180 | } |

2181 | |

2182 | /* Return the minimum of X and Y, treating both as unsigned values. */ |

2183 | template <typename T1, typename T2> |

2184 | inline WI_BINARY_RESULT (T1, T2) |

2185 | wi::umin (const T1 &x, const T2 &y) |

2186 | { |

2187 | return wi::min (x, y, UNSIGNED); |

2188 | } |

2189 | |

2190 | /* Return the maxinum of X and Y, treating them both as having |

2191 | signedness SGN. */ |

2192 | template <typename T1, typename T2> |

2193 | inline WI_BINARY_RESULT (T1, T2) |

2194 | wi::max (const T1 &x, const T2 &y, signop sgn) |

2195 | { |

2196 | WI_BINARY_RESULT_VAR (result, val ATTRIBUTE_UNUSED, T1, x, T2, y); |

2197 | unsigned int precision = get_precision (result); |

2198 | if (wi::ge_p (x, y, sgn)) |

2199 | wi::copy (result, WIDE_INT_REF_FOR (T1) (x, precision)); |

2200 | else |

2201 | wi::copy (result, WIDE_INT_REF_FOR (T2) (y, precision)); |

2202 | return result; |

2203 | } |

2204 | |

2205 | /* Return the maximum of X and Y, treating both as signed values. */ |

2206 | template <typename T1, typename T2> |

2207 | inline WI_BINARY_RESULT (T1, T2) |

2208 | wi::smax (const T1 &x, const T2 &y) |

2209 | { |

2210 | return wi::max (x, y, SIGNED); |

2211 | } |

2212 | |

2213 | /* Return the maximum of X and Y, treating both as unsigned values. */ |

2214 | template <typename T1, typename T2> |

2215 | inline WI_BINARY_RESULT (T1, T2) |

2216 | wi::umax (const T1 &x, const T2 &y) |

2217 | { |

2218 | return wi::max (x, y, UNSIGNED); |

2219 | } |

2220 | |

2221 | /* Return X & Y. */ |

2222 | template <typename T1, typename T2> |

2223 | inline WI_BINARY_RESULT (T1, T2) |

2224 | wi::bit_and (const T1 &x, const T2 &y) |

2225 | { |

2226 | WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y); |

2227 | unsigned int precision = get_precision (result); |

2228 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

2229 | WIDE_INT_REF_FOR (T2) yi (y, precision); |

2230 | bool is_sign_extended = xi.is_sign_extended && yi.is_sign_extended; |

2231 | if (__builtin_expect (xi.len + yi.len == 2, true)) |

2232 | { |

2233 | val[0] = xi.ulow () & yi.ulow (); |

2234 | result.set_len (1, is_sign_extended); |

2235 | } |

2236 | else |

2237 | result.set_len (and_large (val, xi.val, xi.len, yi.val, yi.len, |

2238 | precision), is_sign_extended); |

2239 | return result; |

2240 | } |

2241 | |

2242 | /* Return X & ~Y. */ |

2243 | template <typename T1, typename T2> |

2244 | inline WI_BINARY_RESULT (T1, T2) |

2245 | wi::bit_and_not (const T1 &x, const T2 &y) |

2246 | { |

2247 | WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y); |

2248 | unsigned int precision = get_precision (result); |

2249 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

2250 | WIDE_INT_REF_FOR (T2) yi (y, precision); |

2251 | bool is_sign_extended = xi.is_sign_extended && yi.is_sign_extended; |

2252 | if (__builtin_expect (xi.len + yi.len == 2, true)) |

2253 | { |

2254 | val[0] = xi.ulow () & ~yi.ulow (); |

2255 | result.set_len (1, is_sign_extended); |

2256 | } |

2257 | else |

2258 | result.set_len (and_not_large (val, xi.val, xi.len, yi.val, yi.len, |

2259 | precision), is_sign_extended); |

2260 | return result; |

2261 | } |

2262 | |

2263 | /* Return X | Y. */ |

2264 | template <typename T1, typename T2> |

2265 | inline WI_BINARY_RESULT (T1, T2) |

2266 | wi::bit_or (const T1 &x, const T2 &y) |

2267 | { |

2268 | WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y); |

2269 | unsigned int precision = get_precision (result); |

2270 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

2271 | WIDE_INT_REF_FOR (T2) yi (y, precision); |

2272 | bool is_sign_extended = xi.is_sign_extended && yi.is_sign_extended; |

2273 | if (__builtin_expect (xi.len + yi.len == 2, true)) |

2274 | { |

2275 | val[0] = xi.ulow () | yi.ulow (); |

2276 | result.set_len (1, is_sign_extended); |

2277 | } |

2278 | else |

2279 | result.set_len (or_large (val, xi.val, xi.len, |

2280 | yi.val, yi.len, precision), is_sign_extended); |

2281 | return result; |

2282 | } |

2283 | |

2284 | /* Return X | ~Y. */ |

2285 | template <typename T1, typename T2> |

2286 | inline WI_BINARY_RESULT (T1, T2) |

2287 | wi::bit_or_not (const T1 &x, const T2 &y) |

2288 | { |

2289 | WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y); |

2290 | unsigned int precision = get_precision (result); |

2291 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

2292 | WIDE_INT_REF_FOR (T2) yi (y, precision); |

2293 | bool is_sign_extended = xi.is_sign_extended && yi.is_sign_extended; |

2294 | if (__builtin_expect (xi.len + yi.len == 2, true)) |

2295 | { |

2296 | val[0] = xi.ulow () | ~yi.ulow (); |

2297 | result.set_len (1, is_sign_extended); |

2298 | } |

2299 | else |

2300 | result.set_len (or_not_large (val, xi.val, xi.len, yi.val, yi.len, |

2301 | precision), is_sign_extended); |

2302 | return result; |

2303 | } |

2304 | |

2305 | /* Return X ^ Y. */ |

2306 | template <typename T1, typename T2> |

2307 | inline WI_BINARY_RESULT (T1, T2) |

2308 | wi::bit_xor (const T1 &x, const T2 &y) |

2309 | { |

2310 | WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y); |

2311 | unsigned int precision = get_precision (result); |

2312 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

2313 | WIDE_INT_REF_FOR (T2) yi (y, precision); |

2314 | bool is_sign_extended = xi.is_sign_extended && yi.is_sign_extended; |

2315 | if (__builtin_expect (xi.len + yi.len == 2, true)) |

2316 | { |

2317 | val[0] = xi.ulow () ^ yi.ulow (); |

2318 | result.set_len (1, is_sign_extended); |

2319 | } |

2320 | else |

2321 | result.set_len (xor_large (val, xi.val, xi.len, |

2322 | yi.val, yi.len, precision), is_sign_extended); |

2323 | return result; |

2324 | } |

2325 | |

2326 | /* Return X + Y. */ |

2327 | template <typename T1, typename T2> |

2328 | inline WI_BINARY_RESULT (T1, T2) |

2329 | wi::add (const T1 &x, const T2 &y) |

2330 | { |

2331 | WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y); |

2332 | unsigned int precision = get_precision (result); |

2333 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

2334 | WIDE_INT_REF_FOR (T2) yi (y, precision); |

2335 | if (precision <= HOST_BITS_PER_WIDE_INT) |

2336 | { |

2337 | val[0] = xi.ulow () + yi.ulow (); |

2338 | result.set_len (1); |

2339 | } |

2340 | /* If the precision is known at compile time to be greater than |

2341 | HOST_BITS_PER_WIDE_INT, we can optimize the single-HWI case |

2342 | knowing that (a) all bits in those HWIs are significant and |

2343 | (b) the result has room for at least two HWIs. This provides |

2344 | a fast path for things like offset_int and widest_int. |

2345 | |

2346 | The STATIC_CONSTANT_P test prevents this path from being |

2347 | used for wide_ints. wide_ints with precisions greater than |

2348 | HOST_BITS_PER_WIDE_INT are relatively rare and there's not much |

2349 | point handling them inline. */ |

2350 | else if (STATIC_CONSTANT_P (precision > HOST_BITS_PER_WIDE_INT) |

2351 | && __builtin_expect (xi.len + yi.len == 2, true)) |

2352 | { |

2353 | unsigned HOST_WIDE_INT xl = xi.ulow (); |

2354 | unsigned HOST_WIDE_INT yl = yi.ulow (); |

2355 | unsigned HOST_WIDE_INT resultl = xl + yl; |

2356 | val[0] = resultl; |

2357 | val[1] = (HOST_WIDE_INT) resultl < 0 ? 0 : -1; |

2358 | result.set_len (1 + (((resultl ^ xl) & (resultl ^ yl)) |

2359 | >> (HOST_BITS_PER_WIDE_INT - 1))); |

2360 | } |

2361 | else |

2362 | result.set_len (add_large (val, xi.val, xi.len, |

2363 | yi.val, yi.len, precision, |

2364 | UNSIGNED, 0)); |

2365 | return result; |

2366 | } |

2367 | |

2368 | /* Return X + Y. Treat X and Y as having the signednes given by SGN |

2369 | and indicate in *OVERFLOW whether the operation overflowed. */ |

2370 | template <typename T1, typename T2> |

2371 | inline WI_BINARY_RESULT (T1, T2) |

2372 | wi::add (const T1 &x, const T2 &y, signop sgn, bool *overflow) |

2373 | { |

2374 | WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y); |

2375 | unsigned int precision = get_precision (result); |

2376 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

2377 | WIDE_INT_REF_FOR (T2) yi (y, precision); |

2378 | if (precision <= HOST_BITS_PER_WIDE_INT) |

2379 | { |

2380 | unsigned HOST_WIDE_INT xl = xi.ulow (); |

2381 | unsigned HOST_WIDE_INT yl = yi.ulow (); |

2382 | unsigned HOST_WIDE_INT resultl = xl + yl; |

2383 | if (sgn == SIGNED) |

2384 | *overflow = (((resultl ^ xl) & (resultl ^ yl)) |

2385 | >> (precision - 1)) & 1; |

2386 | else |

2387 | *overflow = ((resultl << (HOST_BITS_PER_WIDE_INT - precision)) |

2388 | < (xl << (HOST_BITS_PER_WIDE_INT - precision))); |

2389 | val[0] = resultl; |

2390 | result.set_len (1); |

2391 | } |

2392 | else |

2393 | result.set_len (add_large (val, xi.val, xi.len, |

2394 | yi.val, yi.len, precision, |

2395 | sgn, overflow)); |

2396 | return result; |

2397 | } |

2398 | |

2399 | /* Return X - Y. */ |

2400 | template <typename T1, typename T2> |

2401 | inline WI_BINARY_RESULT (T1, T2) |

2402 | wi::sub (const T1 &x, const T2 &y) |

2403 | { |

2404 | WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y); |

2405 | unsigned int precision = get_precision (result); |

2406 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

2407 | WIDE_INT_REF_FOR (T2) yi (y, precision); |

2408 | if (precision <= HOST_BITS_PER_WIDE_INT) |

2409 | { |

2410 | val[0] = xi.ulow () - yi.ulow (); |

2411 | result.set_len (1); |

2412 | } |

2413 | /* If the precision is known at compile time to be greater than |

2414 | HOST_BITS_PER_WIDE_INT, we can optimize the single-HWI case |

2415 | knowing that (a) all bits in those HWIs are significant and |

2416 | (b) the result has room for at least two HWIs. This provides |

2417 | a fast path for things like offset_int and widest_int. |

2418 | |

2419 | The STATIC_CONSTANT_P test prevents this path from being |

2420 | used for wide_ints. wide_ints with precisions greater than |

2421 | HOST_BITS_PER_WIDE_INT are relatively rare and there's not much |

2422 | point handling them inline. */ |

2423 | else if (STATIC_CONSTANT_P (precision > HOST_BITS_PER_WIDE_INT) |

2424 | && __builtin_expect (xi.len + yi.len == 2, true)) |

2425 | { |

2426 | unsigned HOST_WIDE_INT xl = xi.ulow (); |

2427 | unsigned HOST_WIDE_INT yl = yi.ulow (); |

2428 | unsigned HOST_WIDE_INT resultl = xl - yl; |

2429 | val[0] = resultl; |

2430 | val[1] = (HOST_WIDE_INT) resultl < 0 ? 0 : -1; |

2431 | result.set_len (1 + (((resultl ^ xl) & (xl ^ yl)) |

2432 | >> (HOST_BITS_PER_WIDE_INT - 1))); |

2433 | } |

2434 | else |

2435 | result.set_len (sub_large (val, xi.val, xi.len, |

2436 | yi.val, yi.len, precision, |

2437 | UNSIGNED, 0)); |

2438 | return result; |

2439 | } |

2440 | |

2441 | /* Return X - Y. Treat X and Y as having the signednes given by SGN |

2442 | and indicate in *OVERFLOW whether the operation overflowed. */ |

2443 | template <typename T1, typename T2> |

2444 | inline WI_BINARY_RESULT (T1, T2) |

2445 | wi::sub (const T1 &x, const T2 &y, signop sgn, bool *overflow) |

2446 | { |

2447 | WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y); |

2448 | unsigned int precision = get_precision (result); |

2449 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

2450 | WIDE_INT_REF_FOR (T2) yi (y, precision); |

2451 | if (precision <= HOST_BITS_PER_WIDE_INT) |

2452 | { |

2453 | unsigned HOST_WIDE_INT xl = xi.ulow (); |

2454 | unsigned HOST_WIDE_INT yl = yi.ulow (); |

2455 | unsigned HOST_WIDE_INT resultl = xl - yl; |

2456 | if (sgn == SIGNED) |

2457 | *overflow = (((xl ^ yl) & (resultl ^ xl)) >> (precision - 1)) & 1; |

2458 | else |

2459 | *overflow = ((resultl << (HOST_BITS_PER_WIDE_INT - precision)) |

2460 | > (xl << (HOST_BITS_PER_WIDE_INT - precision))); |

2461 | val[0] = resultl; |

2462 | result.set_len (1); |

2463 | } |

2464 | else |

2465 | result.set_len (sub_large (val, xi.val, xi.len, |

2466 | yi.val, yi.len, precision, |

2467 | sgn, overflow)); |

2468 | return result; |

2469 | } |

2470 | |

2471 | /* Return X * Y. */ |

2472 | template <typename T1, typename T2> |

2473 | inline WI_BINARY_RESULT (T1, T2) |

2474 | wi::mul (const T1 &x, const T2 &y) |

2475 | { |

2476 | WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y); |

2477 | unsigned int precision = get_precision (result); |

2478 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

2479 | WIDE_INT_REF_FOR (T2) yi (y, precision); |

2480 | if (precision <= HOST_BITS_PER_WIDE_INT) |

2481 | { |

2482 | val[0] = xi.ulow () * yi.ulow (); |

2483 | result.set_len (1); |

2484 | } |

2485 | else |

2486 | result.set_len (mul_internal (val, xi.val, xi.len, yi.val, yi.len, |

2487 | precision, UNSIGNED, 0, false)); |

2488 | return result; |

2489 | } |

2490 | |

2491 | /* Return X * Y. Treat X and Y as having the signednes given by SGN |

2492 | and indicate in *OVERFLOW whether the operation overflowed. */ |

2493 | template <typename T1, typename T2> |

2494 | inline WI_BINARY_RESULT (T1, T2) |

2495 | wi::mul (const T1 &x, const T2 &y, signop sgn, bool *overflow) |

2496 | { |

2497 | WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y); |

2498 | unsigned int precision = get_precision (result); |

2499 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

2500 | WIDE_INT_REF_FOR (T2) yi (y, precision); |

2501 | result.set_len (mul_internal (val, xi.val, xi.len, |

2502 | yi.val, yi.len, precision, |

2503 | sgn, overflow, false)); |

2504 | return result; |

2505 | } |

2506 | |

2507 | /* Return X * Y, treating both X and Y as signed values. Indicate in |

2508 | *OVERFLOW whether the operation overflowed. */ |

2509 | template <typename T1, typename T2> |

2510 | inline WI_BINARY_RESULT (T1, T2) |

2511 | wi::smul (const T1 &x, const T2 &y, bool *overflow) |

2512 | { |

2513 | return mul (x, y, SIGNED, overflow); |

2514 | } |

2515 | |

2516 | /* Return X * Y, treating both X and Y as unsigned values. Indicate in |

2517 | *OVERFLOW whether the operation overflowed. */ |

2518 | template <typename T1, typename T2> |

2519 | inline WI_BINARY_RESULT (T1, T2) |

2520 | wi::umul (const T1 &x, const T2 &y, bool *overflow) |

2521 | { |

2522 | return mul (x, y, UNSIGNED, overflow); |

2523 | } |

2524 | |

2525 | /* Perform a widening multiplication of X and Y, extending the values |

2526 | according to SGN, and return the high part of the result. */ |

2527 | template <typename T1, typename T2> |

2528 | inline WI_BINARY_RESULT (T1, T2) |

2529 | wi::mul_high (const T1 &x, const T2 &y, signop sgn) |

2530 | { |

2531 | WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y); |

2532 | unsigned int precision = get_precision (result); |

2533 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

2534 | WIDE_INT_REF_FOR (T2) yi (y, precision); |

2535 | result.set_len (mul_internal (val, xi.val, xi.len, |

2536 | yi.val, yi.len, precision, |

2537 | sgn, 0, true)); |

2538 | return result; |

2539 | } |

2540 | |

2541 | /* Return X / Y, rouding towards 0. Treat X and Y as having the |

2542 | signedness given by SGN. Indicate in *OVERFLOW if the result |

2543 | overflows. */ |

2544 | template <typename T1, typename T2> |

2545 | inline WI_BINARY_RESULT (T1, T2) |

2546 | wi::div_trunc (const T1 &x, const T2 &y, signop sgn, bool *overflow) |

2547 | { |

2548 | WI_BINARY_RESULT_VAR (quotient, quotient_val, T1, x, T2, y); |

2549 | unsigned int precision = get_precision (quotient); |

2550 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

2551 | WIDE_INT_REF_FOR (T2) yi (y); |

2552 | |

2553 | quotient.set_len (divmod_internal (quotient_val, 0, 0, xi.val, xi.len, |

2554 | precision, |

2555 | yi.val, yi.len, yi.precision, |

2556 | sgn, overflow)); |

2557 | return quotient; |

2558 | } |

2559 | |

2560 | /* Return X / Y, rouding towards 0. Treat X and Y as signed values. */ |

2561 | template <typename T1, typename T2> |

2562 | inline WI_BINARY_RESULT (T1, T2) |

2563 | wi::sdiv_trunc (const T1 &x, const T2 &y) |

2564 | { |

2565 | return div_trunc (x, y, SIGNED); |

2566 | } |

2567 | |

2568 | /* Return X / Y, rouding towards 0. Treat X and Y as unsigned values. */ |

2569 | template <typename T1, typename T2> |

2570 | inline WI_BINARY_RESULT (T1, T2) |

2571 | wi::udiv_trunc (const T1 &x, const T2 &y) |

2572 | { |

2573 | return div_trunc (x, y, UNSIGNED); |

2574 | } |

2575 | |

2576 | /* Return X / Y, rouding towards -inf. Treat X and Y as having the |

2577 | signedness given by SGN. Indicate in *OVERFLOW if the result |

2578 | overflows. */ |

2579 | template <typename T1, typename T2> |

2580 | inline WI_BINARY_RESULT (T1, T2) |

2581 | wi::div_floor (const T1 &x, const T2 &y, signop sgn, bool *overflow) |

2582 | { |

2583 | WI_BINARY_RESULT_VAR (quotient, quotient_val, T1, x, T2, y); |

2584 | WI_BINARY_RESULT_VAR (remainder, remainder_val, T1, x, T2, y); |

2585 | unsigned int precision = get_precision (quotient); |

2586 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

2587 | WIDE_INT_REF_FOR (T2) yi (y); |

2588 | |

2589 | unsigned int remainder_len; |

2590 | quotient.set_len (divmod_internal (quotient_val, |

2591 | &remainder_len, remainder_val, |

2592 | xi.val, xi.len, precision, |

2593 | yi.val, yi.len, yi.precision, sgn, |

2594 | overflow)); |

2595 | remainder.set_len (remainder_len); |

2596 | if (wi::neg_p (x, sgn) != wi::neg_p (y, sgn) && remainder != 0) |

2597 | return quotient - 1; |

2598 | return quotient; |

2599 | } |

2600 | |

2601 | /* Return X / Y, rouding towards -inf. Treat X and Y as signed values. */ |

2602 | template <typename T1, typename T2> |

2603 | inline WI_BINARY_RESULT (T1, T2) |

2604 | wi::sdiv_floor (const T1 &x, const T2 &y) |

2605 | { |

2606 | return div_floor (x, y, SIGNED); |

2607 | } |

2608 | |

2609 | /* Return X / Y, rouding towards -inf. Treat X and Y as unsigned values. */ |

2610 | /* ??? Why do we have both this and udiv_trunc. Aren't they the same? */ |

2611 | template <typename T1, typename T2> |

2612 | inline WI_BINARY_RESULT (T1, T2) |

2613 | wi::udiv_floor (const T1 &x, const T2 &y) |

2614 | { |

2615 | return div_floor (x, y, UNSIGNED); |

2616 | } |

2617 | |

2618 | /* Return X / Y, rouding towards +inf. Treat X and Y as having the |

2619 | signedness given by SGN. Indicate in *OVERFLOW if the result |

2620 | overflows. */ |

2621 | template <typename T1, typename T2> |

2622 | inline WI_BINARY_RESULT (T1, T2) |

2623 | wi::div_ceil (const T1 &x, const T2 &y, signop sgn, bool *overflow) |

2624 | { |

2625 | WI_BINARY_RESULT_VAR (quotient, quotient_val, T1, x, T2, y); |

2626 | WI_BINARY_RESULT_VAR (remainder, remainder_val, T1, x, T2, y); |

2627 | unsigned int precision = get_precision (quotient); |

2628 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

2629 | WIDE_INT_REF_FOR (T2) yi (y); |

2630 | |

2631 | unsigned int remainder_len; |

2632 | quotient.set_len (divmod_internal (quotient_val, |

2633 | &remainder_len, remainder_val, |

2634 | xi.val, xi.len, precision, |

2635 | yi.val, yi.len, yi.precision, sgn, |

2636 | overflow)); |

2637 | remainder.set_len (remainder_len); |

2638 | if (wi::neg_p (x, sgn) == wi::neg_p (y, sgn) && remainder != 0) |

2639 | return quotient + 1; |

2640 | return quotient; |

2641 | } |

2642 | |

2643 | /* Return X / Y, rouding towards nearest with ties away from zero. |

2644 | Treat X and Y as having the signedness given by SGN. Indicate |

2645 | in *OVERFLOW if the result overflows. */ |

2646 | template <typename T1, typename T2> |

2647 | inline WI_BINARY_RESULT (T1, T2) |

2648 | wi::div_round (const T1 &x, const T2 &y, signop sgn, bool *overflow) |

2649 | { |

2650 | WI_BINARY_RESULT_VAR (quotient, quotient_val, T1, x, T2, y); |

2651 | WI_BINARY_RESULT_VAR (remainder, remainder_val, T1, x, T2, y); |

2652 | unsigned int precision = get_precision (quotient); |

2653 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

2654 | WIDE_INT_REF_FOR (T2) yi (y); |

2655 | |

2656 | unsigned int remainder_len; |

2657 | quotient.set_len (divmod_internal (quotient_val, |

2658 | &remainder_len, remainder_val, |

2659 | xi.val, xi.len, precision, |

2660 | yi.val, yi.len, yi.precision, sgn, |

2661 | overflow)); |

2662 | remainder.set_len (remainder_len); |

2663 | |

2664 | if (remainder != 0) |

2665 | { |

2666 | if (sgn == SIGNED) |

2667 | { |

2668 | WI_BINARY_RESULT (T1, T2) abs_remainder = wi::abs (remainder); |

2669 | if (wi::geu_p (abs_remainder, wi::sub (wi::abs (y), abs_remainder))) |

2670 | { |

2671 | if (wi::neg_p (x, sgn) != wi::neg_p (y, sgn)) |

2672 | return quotient - 1; |

2673 | else |

2674 | return quotient + 1; |

2675 | } |

2676 | } |

2677 | else |

2678 | { |

2679 | if (wi::geu_p (remainder, wi::sub (y, remainder))) |

2680 | return quotient + 1; |

2681 | } |

2682 | } |

2683 | return quotient; |

2684 | } |

2685 | |

2686 | /* Return X / Y, rouding towards 0. Treat X and Y as having the |

2687 | signedness given by SGN. Store the remainder in *REMAINDER_PTR. */ |

2688 | template <typename T1, typename T2> |

2689 | inline WI_BINARY_RESULT (T1, T2) |

2690 | wi::divmod_trunc (const T1 &x, const T2 &y, signop sgn, |

2691 | WI_BINARY_RESULT (T1, T2) *remainder_ptr) |

2692 | { |

2693 | WI_BINARY_RESULT_VAR (quotient, quotient_val, T1, x, T2, y); |

2694 | WI_BINARY_RESULT_VAR (remainder, remainder_val, T1, x, T2, y); |

2695 | unsigned int precision = get_precision (quotient); |

2696 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

2697 | WIDE_INT_REF_FOR (T2) yi (y); |

2698 | |

2699 | unsigned int remainder_len; |

2700 | quotient.set_len (divmod_internal (quotient_val, |

2701 | &remainder_len, remainder_val, |

2702 | xi.val, xi.len, precision, |

2703 | yi.val, yi.len, yi.precision, sgn, 0)); |

2704 | remainder.set_len (remainder_len); |

2705 | |

2706 | *remainder_ptr = remainder; |

2707 | return quotient; |

2708 | } |

2709 | |

2710 | /* Compute the greatest common divisor of two numbers A and B using |

2711 | Euclid's algorithm. */ |

2712 | template <typename T1, typename T2> |

2713 | inline WI_BINARY_RESULT (T1, T2) |

2714 | wi::gcd (const T1 &a, const T2 &b, signop sgn) |

2715 | { |

2716 | T1 x, y, z; |

2717 | |

2718 | x = wi::abs (a); |

2719 | y = wi::abs (b); |

2720 | |

2721 | while (gt_p (x, 0, sgn)) |

2722 | { |

2723 | z = mod_trunc (y, x, sgn); |

2724 | y = x; |

2725 | x = z; |

2726 | } |

2727 | |

2728 | return y; |

2729 | } |

2730 | |

2731 | /* Compute X / Y, rouding towards 0, and return the remainder. |

2732 | Treat X and Y as having the signedness given by SGN. Indicate |

2733 | in *OVERFLOW if the division overflows. */ |

2734 | template <typename T1, typename T2> |

2735 | inline WI_BINARY_RESULT (T1, T2) |

2736 | wi::mod_trunc (const T1 &x, const T2 &y, signop sgn, bool *overflow) |

2737 | { |

2738 | WI_BINARY_RESULT_VAR (remainder, remainder_val, T1, x, T2, y); |

2739 | unsigned int precision = get_precision (remainder); |

2740 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

2741 | WIDE_INT_REF_FOR (T2) yi (y); |

2742 | |

2743 | unsigned int remainder_len; |

2744 | divmod_internal (0, &remainder_len, remainder_val, |

2745 | xi.val, xi.len, precision, |

2746 | yi.val, yi.len, yi.precision, sgn, overflow); |

2747 | remainder.set_len (remainder_len); |

2748 | |

2749 | return remainder; |

2750 | } |

2751 | |

2752 | /* Compute X / Y, rouding towards 0, and return the remainder. |

2753 | Treat X and Y as signed values. */ |

2754 | template <typename T1, typename T2> |

2755 | inline WI_BINARY_RESULT (T1, T2) |

2756 | wi::smod_trunc (const T1 &x, const T2 &y) |

2757 | { |

2758 | return mod_trunc (x, y, SIGNED); |

2759 | } |

2760 | |

2761 | /* Compute X / Y, rouding towards 0, and return the remainder. |

2762 | Treat X and Y as unsigned values. */ |

2763 | template <typename T1, typename T2> |

2764 | inline WI_BINARY_RESULT (T1, T2) |

2765 | wi::umod_trunc (const T1 &x, const T2 &y) |

2766 | { |

2767 | return mod_trunc (x, y, UNSIGNED); |

2768 | } |

2769 | |

2770 | /* Compute X / Y, rouding towards -inf, and return the remainder. |

2771 | Treat X and Y as having the signedness given by SGN. Indicate |

2772 | in *OVERFLOW if the division overflows. */ |

2773 | template <typename T1, typename T2> |

2774 | inline WI_BINARY_RESULT (T1, T2) |

2775 | wi::mod_floor (const T1 &x, const T2 &y, signop sgn, bool *overflow) |

2776 | { |

2777 | WI_BINARY_RESULT_VAR (quotient, quotient_val, T1, x, T2, y); |

2778 | WI_BINARY_RESULT_VAR (remainder, remainder_val, T1, x, T2, y); |

2779 | unsigned int precision = get_precision (quotient); |

2780 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

2781 | WIDE_INT_REF_FOR (T2) yi (y); |

2782 | |

2783 | unsigned int remainder_len; |

2784 | quotient.set_len (divmod_internal (quotient_val, |

2785 | &remainder_len, remainder_val, |

2786 | xi.val, xi.len, precision, |

2787 | yi.val, yi.len, yi.precision, sgn, |

2788 | overflow)); |

2789 | remainder.set_len (remainder_len); |

2790 | |

2791 | if (wi::neg_p (x, sgn) != wi::neg_p (y, sgn) && remainder != 0) |

2792 | return remainder + y; |

2793 | return remainder; |

2794 | } |

2795 | |

2796 | /* Compute X / Y, rouding towards -inf, and return the remainder. |

2797 | Treat X and Y as unsigned values. */ |

2798 | /* ??? Why do we have both this and umod_trunc. Aren't they the same? */ |

2799 | template <typename T1, typename T2> |

2800 | inline WI_BINARY_RESULT (T1, T2) |

2801 | wi::umod_floor (const T1 &x, const T2 &y) |

2802 | { |

2803 | return mod_floor (x, y, UNSIGNED); |

2804 | } |

2805 | |

2806 | /* Compute X / Y, rouding towards +inf, and return the remainder. |

2807 | Treat X and Y as having the signedness given by SGN. Indicate |

2808 | in *OVERFLOW if the division overflows. */ |

2809 | template <typename T1, typename T2> |

2810 | inline WI_BINARY_RESULT (T1, T2) |

2811 | wi::mod_ceil (const T1 &x, const T2 &y, signop sgn, bool *overflow) |

2812 | { |

2813 | WI_BINARY_RESULT_VAR (quotient, quotient_val, T1, x, T2, y); |

2814 | WI_BINARY_RESULT_VAR (remainder, remainder_val, T1, x, T2, y); |

2815 | unsigned int precision = get_precision (quotient); |

2816 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

2817 | WIDE_INT_REF_FOR (T2) yi (y); |

2818 | |

2819 | unsigned int remainder_len; |

2820 | quotient.set_len (divmod_internal (quotient_val, |

2821 | &remainder_len, remainder_val, |

2822 | xi.val, xi.len, precision, |

2823 | yi.val, yi.len, yi.precision, sgn, |

2824 | overflow)); |

2825 | remainder.set_len (remainder_len); |

2826 | |

2827 | if (wi::neg_p (x, sgn) == wi::neg_p (y, sgn) && remainder != 0) |

2828 | return remainder - y; |

2829 | return remainder; |

2830 | } |

2831 | |

2832 | /* Compute X / Y, rouding towards nearest with ties away from zero, |

2833 | and return the remainder. Treat X and Y as having the signedness |

2834 | given by SGN. Indicate in *OVERFLOW if the division overflows. */ |

2835 | template <typename T1, typename T2> |

2836 | inline WI_BINARY_RESULT (T1, T2) |

2837 | wi::mod_round (const T1 &x, const T2 &y, signop sgn, bool *overflow) |

2838 | { |

2839 | WI_BINARY_RESULT_VAR (quotient, quotient_val, T1, x, T2, y); |

2840 | WI_BINARY_RESULT_VAR (remainder, remainder_val, T1, x, T2, y); |

2841 | unsigned int precision = get_precision (quotient); |

2842 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

2843 | WIDE_INT_REF_FOR (T2) yi (y); |

2844 | |

2845 | unsigned int remainder_len; |

2846 | quotient.set_len (divmod_internal (quotient_val, |

2847 | &remainder_len, remainder_val, |

2848 | xi.val, xi.len, precision, |

2849 | yi.val, yi.len, yi.precision, sgn, |

2850 | overflow)); |

2851 | remainder.set_len (remainder_len); |

2852 | |

2853 | if (remainder != 0) |

2854 | { |

2855 | if (sgn == SIGNED) |

2856 | { |

2857 | WI_BINARY_RESULT (T1, T2) abs_remainder = wi::abs (remainder); |

2858 | if (wi::geu_p (abs_remainder, wi::sub (wi::abs (y), abs_remainder))) |

2859 | { |

2860 | if (wi::neg_p (x, sgn) != wi::neg_p (y, sgn)) |

2861 | return remainder + y; |

2862 | else |

2863 | return remainder - y; |

2864 | } |

2865 | } |

2866 | else |

2867 | { |

2868 | if (wi::geu_p (remainder, wi::sub (y, remainder))) |

2869 | return remainder - y; |

2870 | } |

2871 | } |

2872 | return remainder; |

2873 | } |

2874 | |

2875 | /* Return true if X is a multiple of Y. Treat X and Y as having the |

2876 | signedness given by SGN. */ |

2877 | template <typename T1, typename T2> |

2878 | inline bool |

2879 | wi::multiple_of_p (const T1 &x, const T2 &y, signop sgn) |

2880 | { |

2881 | return wi::mod_trunc (x, y, sgn) == 0; |

2882 | } |

2883 | |

2884 | /* Return true if X is a multiple of Y, storing X / Y in *RES if so. |

2885 | Treat X and Y as having the signedness given by SGN. */ |

2886 | template <typename T1, typename T2> |

2887 | inline bool |

2888 | wi::multiple_of_p (const T1 &x, const T2 &y, signop sgn, |

2889 | WI_BINARY_RESULT (T1, T2) *res) |

2890 | { |

2891 | WI_BINARY_RESULT (T1, T2) remainder; |

2892 | WI_BINARY_RESULT (T1, T2) quotient |

2893 | = divmod_trunc (x, y, sgn, &remainder); |

2894 | if (remainder == 0) |

2895 | { |

2896 | *res = quotient; |

2897 | return true; |

2898 | } |

2899 | return false; |

2900 | } |

2901 | |

2902 | /* Return X << Y. Return 0 if Y is greater than or equal to |

2903 | the precision of X. */ |

2904 | template <typename T1, typename T2> |

2905 | inline WI_UNARY_RESULT (T1) |

2906 | wi::lshift (const T1 &x, const T2 &y) |

2907 | { |

2908 | WI_UNARY_RESULT_VAR (result, val, T1, x); |

2909 | unsigned int precision = get_precision (result); |

2910 | WIDE_INT_REF_FOR (T1) xi (x, precision); |

2911 | WIDE_INT_REF_FOR (T2) yi (y); |

2912 | /* Handle the simple cases quickly. */ |

2913 | if (geu_p (yi, precision)) |

2914 | { |

2915 | val[0] = 0; |

2916 | result.set_len (1); |

2917 | } |

2918 | else |

2919 | { |

2920 | unsigned int shift = yi.to_uhwi (); |

2921 | /* For fixed-precision integers like offset_int and widest_int, |

2922 | handle the case where the shift value is constant and the |

2923 | result is a single nonnegative HWI (meaning that we don't |

2924 | need to worry about val[1]). This is particularly common |

2925 | for converting a byte count to a bit count. |

2926 | |

2927 | For variable-precision integers like wide_int, handle HWI |

2928 | and sub-HWI integers inline. */ |

2929 | if (STATIC_CONSTANT_P (xi.precision > HOST_BITS_PER_WIDE_INT) |

2930 | ? (STATIC_CONSTANT_P (shift < HOST_BITS_PER_WIDE_INT - 1) |

2931 | && xi.len == 1 |

2932 | && xi.val[0] <= (HOST_WIDE_INT) ((unsigned HOST_WIDE_INT) |

2933 | HOST_WIDE_INT_MAX >> shift)) |

2934 | : precision <= HOST_BITS_PER_WIDE_INT) |

2935 | { |

2936 | val[0] = xi.ulow () << shift; |

2937 | result.set_len (1); |

2938 | } |

2939 | else |

2940 | result.set_len (lshift_large (val, xi.val, xi.len, |

2941 | precision, shift)); |

2942 | } |

2943 | return result; |

2944 | } |

2945 | |

2946 | /* Return X >> Y, using a logical shift. Return 0 if Y is greater than |

2947 | or equal to the precision of X. */ |

2948 | template <typename T1, typename T2> |

2949 | inline WI_UNARY_RESULT (T1) |

2950 | wi::lrshift (const T1 &x, const T2 &y) |

2951 | { |

2952 | WI_UNARY_RESULT_VAR (result, val, T1, x); |

2953 | /* Do things in the precision of the input rather than the output, |

2954 | since the result can be no larger than that. */ |

2955 | WIDE_INT_REF_FOR (T1) xi (x); |

2956 | WIDE_INT_REF_FOR (T2) yi (y); |

2957 | /* Handle the simple cases quickly. */ |

2958 | if (geu_p (yi, xi.precision)) |

2959 | { |

2960 | val[0] = 0; |

2961 | result.set_len (1); |

2962 | } |

2963 | else |

2964 | { |

2965 | unsigned int shift = yi.to_uhwi (); |

2966 | /* For fixed-precision integers like offset_int and widest_int, |

2967 | handle the case where the shift value is constant and the |

2968 | shifted value is a single nonnegative HWI (meaning that all |

2969 | bits above the HWI are zero). This is particularly common |

2970 | for converting a bit count to a byte count. |

2971 | |

2972 | For variable-precision integers like wide_int, handle HWI |

2973 | and sub-HWI integers inline. */ |

2974 | if (STATIC_CONSTANT_P (xi.precision > HOST_BITS_PER_WIDE_INT) |

2975 | ? (shift < HOST_BITS_PER_WIDE_INT |

2976 | && xi.len == 1 |

2977 | && xi.val[0] >= 0) |

2978 | : xi.precision <= HOST_BITS_PER_WIDE_INT) |

2979 | { |

2980 | val[0] = xi.to_uhwi () >> shift; |

2981 | result.set_len (1); |

2982 | } |

2983 | else |

2984 | result.set_len (lrshift_large (val, xi.val, xi.len, xi.precision, |

2985 | get_precision (result), shift)); |

2986 | } |

2987 | return result; |

2988 | } |

2989 | |

2990 | /* Return X >> Y, using an arithmetic shift. Return a sign mask if |

2991 | Y is greater than or equal to the precision of X. */ |

2992 | template <typename T1, typename T2> |

2993 | inline WI_UNARY_RESULT (T1) |

2994 | wi::arshift (const T1 &x, const T2 &y) |

2995 | { |

2996 | WI_UNARY_RESULT_VAR (result, val, T1, x); |

2997 | /* Do things in the precision of the input rather than the output, |

2998 | since the result can be no larger than that. */ |

2999 | WIDE_INT_REF_FOR (T1) xi (x); |

3000 | WIDE_INT_REF_FOR (T2) yi (y); |

3001 | /* Handle the simple cases quickly. */ |

3002 | if (geu_p (yi, xi.precision)) |

3003 | { |

3004 | val[0] = sign_mask (x); |

3005 | result.set_len (1); |

3006 | } |

3007 | else |

3008 | { |

3009 | unsigned int shift = yi.to_uhwi (); |

3010 | if (xi.precision <= HOST_BITS_PER_WIDE_INT) |

3011 | { |

3012 | val[0] = sext_hwi (xi.ulow () >> shift, xi.precision - shift); |

3013 | result.set_len (1, true); |

3014 | } |

3015 | else |

3016 | result.set_len (arshift_large (val, xi.val, xi.len, xi.precision, |

3017 | get_precision (result), shift)); |

3018 | } |

3019 | return result; |

3020 | } |

3021 | |

3022 | /* Return X >> Y, using an arithmetic shift if SGN is SIGNED and a |

3023 | logical shift otherwise. */ |

3024 | template <typename T1, typename T2> |

3025 | inline WI_UNARY_RESULT (T1) |

3026 | wi::rshift (const T1 &x, const T2 &y, signop sgn) |

3027 | { |

3028 | if (sgn == UNSIGNED) |

3029 | return lrshift (x, y); |

3030 | else |

3031 | return arshift (x, y); |

3032 | } |

3033 | |

3034 | /* Return the result of rotating the low WIDTH bits of X left by Y |

3035 | bits and zero-extending the result. Use a full-width rotate if |

3036 | WIDTH is zero. */ |

3037 | template <typename T1, typename T2> |

3038 | WI_UNARY_RESULT (T1) |

3039 | wi::lrotate (const T1 &x, const T2 &y, unsigned int width) |

3040 | { |

3041 | unsigned int precision = get_binary_precision (x, x); |

3042 | if (width == 0) |

3043 | width = precision; |

3044 | WI_UNARY_RESULT (T2) ymod = umod_trunc (y, width); |

3045 | WI_UNARY_RESULT (T1) left = wi::lshift (x, ymod); |

3046 | WI_UNARY_RESULT (T1) right = wi::lrshift (x, wi::sub (width, ymod)); |

3047 | if (width != precision) |

3048 | return wi::zext (left, width) | wi::zext (right, width); |

3049 | return left | right; |

3050 | } |

3051 | |

3052 | /* Return the result of rotating the low WIDTH bits of X right by Y |

3053 | bits and zero-extending the result. Use a full-width rotate if |

3054 | WIDTH is zero. */ |

3055 | template <typename T1, typename T2> |

3056 | WI_UNARY_RESULT (T1) |

3057 | wi::rrotate (const T1 &x, const T2 &y, unsigned int width) |

3058 | { |

3059 | unsigned int precision = get_binary_precision (x, x); |

3060 | if (width == 0) |

3061 | width = precision; |

3062 | WI_UNARY_RESULT (T2) ymod = umod_trunc (y, width); |

3063 | WI_UNARY_RESULT (T1) right = wi::lrshift (x, ymod); |

3064 | WI_UNARY_RESULT (T1) left = wi::lshift (x, wi::sub (width, ymod)); |

3065 | if (width != precision) |

3066 | return wi::zext (left, width) | wi::zext (right, width); |

3067 | return left | right; |

3068 | } |

3069 | |

3070 | /* Return 0 if the number of 1s in X is even and 1 if the number of 1s |

3071 | is odd. */ |

3072 | inline int |

3073 | wi::parity (const wide_int_ref &x) |

3074 | { |

3075 | return popcount (x) & 1; |

3076 | } |

3077 | |

3078 | /* Extract WIDTH bits from X, starting at BITPOS. */ |

3079 | template <typename T> |

3080 | inline unsigned HOST_WIDE_INT |

3081 | wi::extract_uhwi (const T &x, unsigned int bitpos, unsigned int width) |

3082 | { |

3083 | unsigned precision = get_precision (x); |

3084 | if (precision < bitpos + width) |

3085 | precision = bitpos + width; |

3086 | WIDE_INT_REF_FOR (T) xi (x, precision); |

3087 | |

3088 | /* Handle this rare case after the above, so that we assert about |

3089 | bogus BITPOS values. */ |

3090 | if (width == 0) |

3091 | return 0; |

3092 | |

3093 | unsigned int start = bitpos / HOST_BITS_PER_WIDE_INT; |

3094 | unsigned int shift = bitpos % HOST_BITS_PER_WIDE_INT; |

3095 | unsigned HOST_WIDE_INT res = xi.elt (start); |

3096 | res >>= shift; |

3097 | if (shift + width > HOST_BITS_PER_WIDE_INT) |

3098 | { |

3099 | unsigned HOST_WIDE_INT upper = xi.elt (start + 1); |

3100 | res |= upper << (-shift % HOST_BITS_PER_WIDE_INT); |

3101 | } |

3102 | return zext_hwi (res, width); |

3103 | } |

3104 | |

3105 | /* Return the minimum precision needed to store X with sign SGN. */ |

3106 | template <typename T> |

3107 | inline unsigned int |

3108 | wi::min_precision (const T &x, signop sgn) |

3109 | { |

3110 | if (sgn == SIGNED) |

3111 | return get_precision (x) - clrsb (x); |

3112 | else |

3113 | return get_precision (x) - clz (x); |

3114 | } |

3115 | |

3116 | #define SIGNED_BINARY_PREDICATE(OP, F) \ |

3117 | template <typename T1, typename T2> \ |

3118 | inline WI_SIGNED_BINARY_PREDICATE_RESULT (T1, T2) \ |

3119 | OP (const T1 &x, const T2 &y) \ |

3120 | { \ |

3121 | return wi::F (x, y); \ |

3122 | } |

3123 | |

3124 | SIGNED_BINARY_PREDICATE (operator <, lts_p) |

3125 | SIGNED_BINARY_PREDICATE (operator <=, les_p) |

3126 | SIGNED_BINARY_PREDICATE (operator >, gts_p) |

3127 | SIGNED_BINARY_PREDICATE (operator >=, ges_p) |

3128 | |

3129 | #undef SIGNED_BINARY_PREDICATE |

3130 | |

3131 | #define UNARY_OPERATOR(OP, F) \ |

3132 | template<typename T> \ |

3133 | WI_UNARY_RESULT (generic_wide_int<T>) \ |

3134 | OP (const generic_wide_int<T> &x) \ |

3135 | { \ |

3136 | return wi::F (x); \ |

3137 | } |

3138 | |

3139 | #define BINARY_PREDICATE(OP, F) \ |

3140 | template<typename T1, typename T2> \ |

3141 | WI_BINARY_PREDICATE_RESULT (T1, T2) \ |

3142 | OP (const T1 &x, const T2 &y) \ |

3143 | { \ |

3144 | return wi::F (x, y); \ |

3145 | } |

3146 | |

3147 | #define BINARY_OPERATOR(OP, F) \ |

3148 | template<typename T1, typename T2> \ |

3149 | WI_BINARY_OPERATOR_RESULT (T1, T2) \ |

3150 | OP (const T1 &x, const T2 &y) \ |

3151 | { \ |

3152 | return wi::F (x, y); \ |

3153 | } |

3154 | |

3155 | UNARY_OPERATOR (operator ~, bit_not) |

3156 | UNARY_OPERATOR (operator -, neg) |

3157 | BINARY_PREDICATE (operator ==, eq_p) |

3158 | BINARY_PREDICATE (operator !=, ne_p) |

3159 | BINARY_OPERATOR (operator &, bit_and) |

3160 | BINARY_OPERATOR (operator |, bit_or) |

3161 | BINARY_OPERATOR (operator ^, bit_xor) |

3162 | BINARY_OPERATOR (operator +, add) |

3163 | BINARY_OPERATOR (operator -, sub) |

3164 | BINARY_OPERATOR (operator *, mul) |

3165 | |

3166 | #undef UNARY_OPERATOR |

3167 | #undef BINARY_PREDICATE |

3168 | #undef BINARY_OPERATOR |

3169 | |

3170 | template <typename T1, typename T2> |

3171 | inline WI_SIGNED_SHIFT_RESULT (T1, T2) |

3172 | operator << (const T1 &x, const T2 &y) |

3173 | { |

3174 | return wi::lshift (x, y); |

3175 | } |

3176 | |

3177 | template <typename T1, typename T2> |

3178 | inline WI_SIGNED_SHIFT_RESULT (T1, T2) |

3179 | operator >> (const T1 &x, const T2 &y) |

3180 | { |

3181 | return wi::arshift (x, y); |

3182 | } |

3183 | |

3184 | template<typename T> |

3185 | void |

3186 | gt_ggc_mx (generic_wide_int <T> *) |

3187 | { |

3188 | } |

3189 | |

3190 | template<typename T> |

3191 | void |

3192 | gt_pch_nx (generic_wide_int <T> *) |

3193 | { |

3194 | } |

3195 | |

3196 | template<typename T> |

3197 | void |

3198 | gt_pch_nx (generic_wide_int <T> *, void (*) (void *, void *), void *) |

3199 | { |

3200 | } |

3201 | |

3202 | template<int N> |

3203 | void |

3204 | gt_ggc_mx (trailing_wide_ints <N> *) |

3205 | { |

3206 | } |

3207 | |

3208 | template<int N> |

3209 | void |

3210 | gt_pch_nx (trailing_wide_ints <N> *) |

3211 | { |

3212 | } |

3213 | |

3214 | template<int N> |

3215 | void |

3216 | gt_pch_nx (trailing_wide_ints <N> *, void (*) (void *, void *), void *) |

3217 | { |

3218 | } |

3219 | |

3220 | namespace wi |

3221 | { |

3222 | /* Used for overloaded functions in which the only other acceptable |

3223 | scalar type is a pointer. It stops a plain 0 from being treated |

3224 | as a null pointer. */ |

3225 | struct never_used1 {}; |

3226 | struct never_used2 {}; |

3227 | |

3228 | wide_int min_value (unsigned int, signop); |

3229 | wide_int min_value (never_used1 *); |

3230 | wide_int min_value (never_used2 *); |

3231 | wide_int max_value (unsigned int, signop); |

3232 | wide_int max_value (never_used1 *); |

3233 | wide_int max_value (never_used2 *); |

3234 | |

3235 | /* FIXME: this is target dependent, so should be elsewhere. |

3236 | It also seems to assume that CHAR_BIT == BITS_PER_UNIT. */ |

3237 | wide_int from_buffer (const unsigned char *, unsigned int); |

3238 | |

3239 | #ifndef GENERATOR_FILE |

3240 | void to_mpz (const wide_int_ref &, mpz_t, signop); |

3241 | #endif |

3242 | |

3243 | wide_int mask (unsigned int, bool, unsigned int); |

3244 | wide_int shifted_mask (unsigned int, unsigned int, bool, unsigned int); |

3245 | wide_int set_bit_in_zero (unsigned int, unsigned int); |

3246 | wide_int insert (const wide_int &x, const wide_int &y, unsigned int, |

3247 | unsigned int); |

3248 | |

3249 | template <typename T> |

3250 | T mask (unsigned int, bool); |

3251 | |

3252 | template <typename T> |

3253 | T shifted_mask (unsigned int, unsigned int, bool); |

3254 | |

3255 | template <typename T> |

3256 | T set_bit_in_zero (unsigned int); |

3257 | |

3258 | unsigned int mask (HOST_WIDE_INT *, unsigned int, bool, unsigned int); |

3259 | unsigned int shifted_mask (HOST_WIDE_INT *, unsigned int, unsigned int, |

3260 | bool, unsigned int); |

3261 | unsigned int from_array (HOST_WIDE_INT *, const HOST_WIDE_INT *, |

3262 | unsigned int, unsigned int, bool); |

3263 | } |

3264 | |

3265 | /* Return a PRECISION-bit integer in which the low WIDTH bits are set |

3266 | and the other bits are clear, or the inverse if NEGATE_P. */ |

3267 | inline wide_int |

3268 | wi::mask (unsigned int width, bool negate_p, unsigned int precision) |

3269 | { |

3270 | wide_int result = wide_int::create (precision); |

3271 | result.set_len (mask (result.write_val (), width, negate_p, precision)); |

3272 | return result; |

3273 | } |

3274 | |

3275 | /* Return a PRECISION-bit integer in which the low START bits are clear, |

3276 | the next WIDTH bits are set, and the other bits are clear, |

3277 | or the inverse if NEGATE_P. */ |

3278 | inline wide_int |

3279 | wi::shifted_mask (unsigned int start, unsigned int width, bool negate_p, |

3280 | unsigned int precision) |

3281 | { |

3282 | wide_int result = wide_int::create (precision); |

3283 | result.set_len (shifted_mask (result.write_val (), start, width, negate_p, |

3284 | precision)); |

3285 | return result; |

3286 | } |

3287 | |

3288 | /* Return a PRECISION-bit integer in which bit BIT is set and all the |

3289 | others are clear. */ |

3290 | inline wide_int |

3291 | wi::set_bit_in_zero (unsigned int bit, unsigned int precision) |

3292 | { |

3293 | return shifted_mask (bit, 1, false, precision); |

3294 | } |

3295 | |

3296 | /* Return an integer of type T in which the low WIDTH bits are set |

3297 | and the other bits are clear, or the inverse if NEGATE_P. */ |

3298 | template <typename T> |

3299 | inline T |

3300 | wi::mask (unsigned int width, bool negate_p) |

3301 | { |

3302 | STATIC_ASSERT (wi::int_traits<T>::precision); |

3303 | T result; |

3304 | result.set_len (mask (result.write_val (), width, negate_p, |

3305 | wi::int_traits <T>::precision)); |

3306 | return result; |

3307 | } |

3308 | |

3309 | /* Return an integer of type T in which the low START bits are clear, |

3310 | the next WIDTH bits are set, and the other bits are clear, or the |

3311 | inverse if NEGATE_P. */ |

3312 | template <typename T> |

3313 | inline T |

3314 | wi::shifted_mask (unsigned int start, unsigned int width, bool negate_p) |

3315 | { |

3316 | STATIC_ASSERT (wi::int_traits<T>::precision); |

3317 | T result; |

3318 | result.set_len (shifted_mask (result.write_val (), start, width, |

3319 | negate_p, |

3320 | wi::int_traits <T>::precision)); |

3321 | return result; |

3322 | } |

3323 | |

3324 | /* Return an integer of type T in which bit BIT is set and all the |

3325 | others are clear. */ |

3326 | template <typename T> |

3327 | inline T |

3328 | wi::set_bit_in_zero (unsigned int bit) |

3329 | { |

3330 | return shifted_mask <T> (bit, 1, false); |

3331 | } |

3332 | |

3333 | #endif /* WIDE_INT_H */ |

3334 |