00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "config.h"
00022 #include "system.h"
00023 #include "coretypes.h"
00024 #include "tm.h"
00025 #include "tree.h"
00026
00027
00028
00029 static inline double_int
00030 double_int_mask (unsigned prec)
00031 {
00032 unsigned HOST_WIDE_INT m;
00033 double_int mask;
00034
00035 if (prec > HOST_BITS_PER_WIDE_INT)
00036 {
00037 prec -= HOST_BITS_PER_WIDE_INT;
00038 m = ((unsigned HOST_WIDE_INT) 2 << (prec - 1)) - 1;
00039 mask.high = (HOST_WIDE_INT) m;
00040 mask.low = ALL_ONES;
00041 }
00042 else
00043 {
00044 mask.high = 0;
00045 mask.low = ((unsigned HOST_WIDE_INT) 2 << (prec - 1)) - 1;
00046 }
00047
00048 return mask;
00049 }
00050
00051
00052
00053
00054
00055
00056
00057
00058 double_int
00059 double_int_ext (double_int cst, unsigned prec, bool uns)
00060 {
00061 if (uns)
00062 return double_int_zext (cst, prec);
00063 else
00064 return double_int_sext (cst, prec);
00065 }
00066
00067
00068
00069 double_int
00070 double_int_zext (double_int cst, unsigned prec)
00071 {
00072 double_int mask = double_int_mask (prec);
00073 double_int r;
00074
00075 r.low = cst.low & mask.low;
00076 r.high = cst.high & mask.high;
00077
00078 return r;
00079 }
00080
00081
00082
00083 double_int
00084 double_int_sext (double_int cst, unsigned prec)
00085 {
00086 double_int mask = double_int_mask (prec);
00087 double_int r;
00088 unsigned HOST_WIDE_INT snum;
00089
00090 if (prec <= HOST_BITS_PER_WIDE_INT)
00091 snum = cst.low;
00092 else
00093 {
00094 prec -= HOST_BITS_PER_WIDE_INT;
00095 snum = (unsigned HOST_WIDE_INT) cst.high;
00096 }
00097 if (((snum >> (prec - 1)) & 1) == 1)
00098 {
00099 r.low = cst.low | ~mask.low;
00100 r.high = cst.high | ~mask.high;
00101 }
00102 else
00103 {
00104 r.low = cst.low & mask.low;
00105 r.high = cst.high & mask.high;
00106 }
00107
00108 return r;
00109 }
00110
00111
00112
00113
00114
00115 double_int
00116 tree_to_double_int (tree cst)
00117 {
00118
00119
00120 return TREE_INT_CST (cst);
00121 }
00122
00123
00124
00125 bool
00126 double_int_fits_in_uhwi_p (double_int cst)
00127 {
00128 return cst.high == 0;
00129 }
00130
00131
00132
00133 bool
00134 double_int_fits_in_shwi_p (double_int cst)
00135 {
00136 if (cst.high == 0)
00137 return (HOST_WIDE_INT) cst.low >= 0;
00138 else if (cst.high == -1)
00139 return (HOST_WIDE_INT) cst.low < 0;
00140 else
00141 return false;
00142 }
00143
00144
00145
00146
00147 bool
00148 double_int_fits_in_hwi_p (double_int cst, bool uns)
00149 {
00150 if (uns)
00151 return double_int_fits_in_uhwi_p (cst);
00152 else
00153 return double_int_fits_in_shwi_p (cst);
00154 }
00155
00156
00157
00158
00159 HOST_WIDE_INT
00160 double_int_to_shwi (double_int cst)
00161 {
00162 return (HOST_WIDE_INT) cst.low;
00163 }
00164
00165
00166
00167
00168 unsigned HOST_WIDE_INT
00169 double_int_to_uhwi (double_int cst)
00170 {
00171 return cst.low;
00172 }
00173
00174
00175
00176 double_int
00177 double_int_mul (double_int a, double_int b)
00178 {
00179 double_int ret;
00180 mul_double (a.low, a.high, b.low, b.high, &ret.low, &ret.high);
00181 return ret;
00182 }
00183
00184
00185
00186 double_int
00187 double_int_add (double_int a, double_int b)
00188 {
00189 double_int ret;
00190 add_double (a.low, a.high, b.low, b.high, &ret.low, &ret.high);
00191 return ret;
00192 }
00193
00194
00195
00196 double_int
00197 double_int_neg (double_int a)
00198 {
00199 double_int ret;
00200 neg_double (a.low, a.high, &ret.low, &ret.high);
00201 return ret;
00202 }
00203
00204
00205
00206
00207
00208
00209 double_int
00210 double_int_divmod (double_int a, double_int b, bool uns, unsigned code,
00211 double_int *mod)
00212 {
00213 double_int ret;
00214
00215 div_and_round_double (code, uns, a.low, a.high, b.low, b.high,
00216 &ret.low, &ret.high, &mod->low, &mod->high);
00217 return ret;
00218 }
00219
00220
00221
00222 double_int
00223 double_int_sdivmod (double_int a, double_int b, unsigned code, double_int *mod)
00224 {
00225 return double_int_divmod (a, b, false, code, mod);
00226 }
00227
00228
00229
00230 double_int
00231 double_int_udivmod (double_int a, double_int b, unsigned code, double_int *mod)
00232 {
00233 return double_int_divmod (a, b, true, code, mod);
00234 }
00235
00236
00237
00238
00239
00240 double_int
00241 double_int_div (double_int a, double_int b, bool uns, unsigned code)
00242 {
00243 double_int mod;
00244
00245 return double_int_divmod (a, b, uns, code, &mod);
00246 }
00247
00248
00249
00250 double_int
00251 double_int_sdiv (double_int a, double_int b, unsigned code)
00252 {
00253 return double_int_div (a, b, false, code);
00254 }
00255
00256
00257
00258 double_int
00259 double_int_udiv (double_int a, double_int b, unsigned code)
00260 {
00261 return double_int_div (a, b, true, code);
00262 }
00263
00264
00265
00266
00267
00268 double_int
00269 double_int_mod (double_int a, double_int b, bool uns, unsigned code)
00270 {
00271 double_int mod;
00272
00273 double_int_divmod (a, b, uns, code, &mod);
00274 return mod;
00275 }
00276
00277
00278
00279 double_int
00280 double_int_smod (double_int a, double_int b, unsigned code)
00281 {
00282 return double_int_mod (a, b, false, code);
00283 }
00284
00285
00286
00287 double_int
00288 double_int_umod (double_int a, double_int b, unsigned code)
00289 {
00290 return double_int_mod (a, b, true, code);
00291 }
00292
00293
00294
00295 tree
00296 double_int_to_tree (tree type, double_int cst)
00297 {
00298 cst = double_int_ext (cst, TYPE_PRECISION (type), TYPE_UNSIGNED (type));
00299
00300 return build_int_cst_wide (type, cst.low, cst.high);
00301 }
00302
00303
00304
00305
00306 bool
00307 double_int_negative_p (double_int cst)
00308 {
00309 return cst.high < 0;
00310 }
00311
00312
00313
00314
00315 int
00316 double_int_cmp (double_int a, double_int b, bool uns)
00317 {
00318 if (uns)
00319 return double_int_ucmp (a, b);
00320 else
00321 return double_int_scmp (a, b);
00322 }
00323
00324
00325
00326
00327 int
00328 double_int_ucmp (double_int a, double_int b)
00329 {
00330 if ((unsigned HOST_WIDE_INT) a.high < (unsigned HOST_WIDE_INT) b.high)
00331 return -1;
00332 if ((unsigned HOST_WIDE_INT) a.high > (unsigned HOST_WIDE_INT) b.high)
00333 return 1;
00334 if (a.low < b.low)
00335 return -1;
00336 if (a.low > b.low)
00337 return 1;
00338
00339 return 0;
00340 }
00341
00342
00343
00344
00345 int
00346 double_int_scmp (double_int a, double_int b)
00347 {
00348 if (a.high < b.high)
00349 return -1;
00350 if (a.high > b.high)
00351 return 1;
00352 if ((HOST_WIDE_INT) a.low < (HOST_WIDE_INT) b.low)
00353 return -1;
00354 if ((HOST_WIDE_INT) a.low > (HOST_WIDE_INT) b.low)
00355 return 1;
00356
00357 return 0;
00358 }
00359
00360
00361
00362 static unsigned
00363 double_int_split_digit (double_int *cst, unsigned base)
00364 {
00365 unsigned HOST_WIDE_INT resl, reml;
00366 HOST_WIDE_INT resh, remh;
00367
00368 div_and_round_double (FLOOR_DIV_EXPR, true, cst->low, cst->high, base, 0,
00369 &resl, &resh, &reml, &remh);
00370 cst->high = resh;
00371 cst->low = resl;
00372
00373 return reml;
00374 }
00375
00376
00377
00378
00379 void
00380 dump_double_int (FILE *file, double_int cst, bool uns)
00381 {
00382 unsigned digits[100], n;
00383 int i;
00384
00385 if (double_int_zero_p (cst))
00386 {
00387 fprintf (file, "0");
00388 return;
00389 }
00390
00391 if (!uns && double_int_negative_p (cst))
00392 {
00393 fprintf (file, "-");
00394 cst = double_int_neg (cst);
00395 }
00396
00397 for (n = 0; !double_int_zero_p (cst); n++)
00398 digits[n] = double_int_split_digit (&cst, 10);
00399 for (i = n - 1; i >= 0; i--)
00400 fprintf (file, "%u", digits[i]);
00401 }