1 1.1 mrg /* This is a software fixed-point library. 2 1.1.1.11 mrg Copyright (C) 2007-2024 Free Software Foundation, Inc. 3 1.1 mrg 4 1.1 mrg This file is part of GCC. 5 1.1 mrg 6 1.1 mrg GCC is free software; you can redistribute it and/or modify it under 7 1.1 mrg the terms of the GNU General Public License as published by the Free 8 1.1 mrg Software Foundation; either version 3, or (at your option) any later 9 1.1 mrg version. 10 1.1 mrg 11 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY 12 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 1.1 mrg for more details. 15 1.1 mrg 16 1.1 mrg Under Section 7 of GPL version 3, you are granted additional 17 1.1 mrg permissions described in the GCC Runtime Library Exception, version 18 1.1 mrg 3.1, as published by the Free Software Foundation. 19 1.1 mrg 20 1.1 mrg You should have received a copy of the GNU General Public License and 21 1.1 mrg a copy of the GCC Runtime Library Exception along with this program; 22 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 1.1 mrg <http://www.gnu.org/licenses/>. */ 24 1.1 mrg 25 1.1 mrg /* This implements fixed-point arithmetic. 26 1.1 mrg 27 1.1 mrg Contributed by Chao-ying Fu <fu (at) mips.com>. */ 28 1.1 mrg 29 1.1 mrg /* To use this file, we need to define one of the following: 30 1.1 mrg QQ_MODE, UQQ_MODE, HQ_MODE, UHQ_MODE, SQ_MODE, USQ_MODE, DQ_MODE, UDQ_MODE, 31 1.1 mrg TQ_MODE, UTQ_MODE, HA_MODE, UHA_MODE, SA_MODE, USA_MODE, DA_MODE, UDA_MODE, 32 1.1 mrg TA_MODE, UTA_MODE. 33 1.1 mrg Then, all operators for this machine mode will be created. 34 1.1 mrg 35 1.1 mrg Or, we need to define FROM_* TO_* for conversions from one mode to another 36 1.1 mrg mode. The mode could be one of the following: 37 1.1 mrg Fract: QQ, UQQ, HQ, UHQ, SQ, USQ, DQ, UDQ, TQ, UTQ 38 1.1 mrg Accum: HA, UHA, SA, USA, DA, UDA, TA, UTA 39 1.1 mrg Signed integer: QI, HI, SI, DI, TI 40 1.1 mrg Unsigned integer: UQI, UHI, USI, UDI, UTI 41 1.1 mrg Floating-point: SF, DF 42 1.1 mrg Ex: If we define FROM_QQ and TO_SI, the conversion from QQ to SI is 43 1.1 mrg generated. */ 44 1.1 mrg 45 1.1 mrg #include "tconfig.h" 46 1.1 mrg #include "tsystem.h" 47 1.1 mrg #include "coretypes.h" 48 1.1 mrg #include "tm.h" 49 1.1 mrg #include "libgcc_tm.h" 50 1.1 mrg 51 1.1 mrg #ifndef MIN_UNITS_PER_WORD 52 1.1 mrg #define MIN_UNITS_PER_WORD UNITS_PER_WORD 53 1.1 mrg #endif 54 1.1 mrg 55 1.1 mrg #include "fixed-bit.h" 56 1.1 mrg 57 1.1 mrg #if defined(FIXED_ADD) && defined(L_add) 58 1.1 mrg FIXED_C_TYPE 59 1.1 mrg FIXED_ADD (FIXED_C_TYPE a, FIXED_C_TYPE b) 60 1.1 mrg { 61 1.1 mrg FIXED_C_TYPE c; 62 1.1 mrg INT_C_TYPE x, y, z; 63 1.1 mrg memcpy (&x, &a, FIXED_SIZE); 64 1.1 mrg memcpy (&y, &b, FIXED_SIZE); 65 1.1 mrg z = x + y; 66 1.1 mrg #if HAVE_PADDING_BITS 67 1.1 mrg z = z << PADDING_BITS; 68 1.1 mrg z = z >> PADDING_BITS; 69 1.1 mrg #endif 70 1.1 mrg memcpy (&c, &z, FIXED_SIZE); 71 1.1 mrg return c; 72 1.1 mrg } 73 1.1 mrg #endif /* FIXED_ADD */ 74 1.1 mrg 75 1.1 mrg #if defined(FIXED_SSADD) && defined(L_ssadd) 76 1.1 mrg FIXED_C_TYPE 77 1.1 mrg FIXED_SSADD (FIXED_C_TYPE a, FIXED_C_TYPE b) 78 1.1 mrg { 79 1.1 mrg FIXED_C_TYPE c; 80 1.1 mrg INT_C_TYPE x, y, z; 81 1.1 mrg memcpy (&x, &a, FIXED_SIZE); 82 1.1 mrg memcpy (&y, &b, FIXED_SIZE); 83 1.1 mrg z = x + (UINT_C_TYPE) y; 84 1.1 mrg if ((((x ^ y) >> I_F_BITS) & 1) == 0) 85 1.1 mrg { 86 1.1 mrg if (((z ^ x) >> I_F_BITS) & 1) 87 1.1 mrg { 88 1.1 mrg z = ((UINT_C_TYPE) 1) << I_F_BITS; 89 1.1 mrg if (x >= 0) 90 1.1 mrg z -= (UINT_C_TYPE) 1; 91 1.1 mrg } 92 1.1 mrg } 93 1.1 mrg #if HAVE_PADDING_BITS 94 1.1 mrg z = z << PADDING_BITS; 95 1.1 mrg z = z >> PADDING_BITS; 96 1.1 mrg #endif 97 1.1 mrg memcpy (&c, &z, FIXED_SIZE); 98 1.1 mrg return c; 99 1.1 mrg } 100 1.1 mrg #endif /* FIXED_SSADD */ 101 1.1 mrg 102 1.1 mrg #if defined(FIXED_USADD) && defined(L_usadd) 103 1.1 mrg FIXED_C_TYPE 104 1.1 mrg FIXED_USADD (FIXED_C_TYPE a, FIXED_C_TYPE b) 105 1.1 mrg { 106 1.1 mrg FIXED_C_TYPE c; 107 1.1 mrg INT_C_TYPE x, y, z; 108 1.1 mrg memcpy (&x, &a, FIXED_SIZE); 109 1.1 mrg memcpy (&y, &b, FIXED_SIZE); 110 1.1 mrg z = x + y; 111 1.1 mrg #if HAVE_PADDING_BITS 112 1.1 mrg z = z << PADDING_BITS; 113 1.1 mrg z = z >> PADDING_BITS; 114 1.1 mrg #endif 115 1.1 mrg if (z < x || z < y) /* max */ 116 1.1 mrg { 117 1.1 mrg z = -1; 118 1.1 mrg #if HAVE_PADDING_BITS 119 1.1 mrg z = z << PADDING_BITS; 120 1.1 mrg z = z >> PADDING_BITS; 121 1.1 mrg #endif 122 1.1 mrg } 123 1.1 mrg memcpy (&c, &z, FIXED_SIZE); 124 1.1 mrg return c; 125 1.1 mrg } 126 1.1 mrg #endif /* FIXED_USADD */ 127 1.1 mrg 128 1.1 mrg #if defined(FIXED_SUB) && defined(L_sub) 129 1.1 mrg FIXED_C_TYPE 130 1.1 mrg FIXED_SUB (FIXED_C_TYPE a, FIXED_C_TYPE b) 131 1.1 mrg { 132 1.1 mrg FIXED_C_TYPE c; 133 1.1 mrg INT_C_TYPE x, y, z; 134 1.1 mrg memcpy (&x, &a, FIXED_SIZE); 135 1.1 mrg memcpy (&y, &b, FIXED_SIZE); 136 1.1 mrg z = x - y; 137 1.1 mrg #if HAVE_PADDING_BITS 138 1.1 mrg z = z << PADDING_BITS; 139 1.1 mrg z = z >> PADDING_BITS; 140 1.1 mrg #endif 141 1.1 mrg memcpy (&c, &z, FIXED_SIZE); 142 1.1 mrg return c; 143 1.1 mrg } 144 1.1 mrg #endif /* FIXED_SUB */ 145 1.1 mrg 146 1.1 mrg #if defined(FIXED_SSSUB) && defined(L_sssub) 147 1.1 mrg FIXED_C_TYPE 148 1.1 mrg FIXED_SSSUB (FIXED_C_TYPE a, FIXED_C_TYPE b) 149 1.1 mrg { 150 1.1 mrg FIXED_C_TYPE c; 151 1.1 mrg INT_C_TYPE x, y, z; 152 1.1 mrg memcpy (&x, &a, FIXED_SIZE); 153 1.1 mrg memcpy (&y, &b, FIXED_SIZE); 154 1.1 mrg z = x - (UINT_C_TYPE) y; 155 1.1 mrg if (((x ^ y) >> I_F_BITS) & 1) 156 1.1 mrg { 157 1.1 mrg if (((z ^ x) >> I_F_BITS) & 1) 158 1.1 mrg { 159 1.1 mrg z = ((UINT_C_TYPE) 1) << I_F_BITS; 160 1.1 mrg if (x >= 0) 161 1.1 mrg z -= (UINT_C_TYPE) 1; 162 1.1 mrg } 163 1.1 mrg } 164 1.1 mrg #if HAVE_PADDING_BITS 165 1.1 mrg z = z << PADDING_BITS; 166 1.1 mrg z = z >> PADDING_BITS; 167 1.1 mrg #endif 168 1.1 mrg memcpy (&c, &z, FIXED_SIZE); 169 1.1 mrg return c; 170 1.1 mrg } 171 1.1 mrg #endif /* FIXED_SSSUB */ 172 1.1 mrg 173 1.1 mrg #if defined(FIXED_USSUB) && defined(L_ussub) 174 1.1 mrg FIXED_C_TYPE 175 1.1 mrg FIXED_USSUB (FIXED_C_TYPE a, FIXED_C_TYPE b) 176 1.1 mrg { 177 1.1 mrg FIXED_C_TYPE c; 178 1.1 mrg INT_C_TYPE x, y, z; 179 1.1 mrg memcpy (&x, &a, FIXED_SIZE); 180 1.1 mrg memcpy (&y, &b, FIXED_SIZE); 181 1.1 mrg z = x - y; 182 1.1 mrg if (x < y) 183 1.1 mrg z = 0; 184 1.1 mrg #if HAVE_PADDING_BITS 185 1.1 mrg z = z << PADDING_BITS; 186 1.1 mrg z = z >> PADDING_BITS; 187 1.1 mrg #endif 188 1.1 mrg memcpy (&c, &z, FIXED_SIZE); 189 1.1 mrg return c; 190 1.1 mrg } 191 1.1 mrg #endif /* FIXED_USSUB */ 192 1.1 mrg 193 1.1 mrg #if defined(FIXED_SATURATE1) && defined(L_saturate1) 194 1.1 mrg void 195 1.1 mrg FIXED_SATURATE1 (DINT_C_TYPE *a) 196 1.1 mrg { 197 1.1 mrg DINT_C_TYPE max, min; 198 1.1 mrg max = (DINT_C_TYPE)1 << I_F_BITS; 199 1.1 mrg max = max - 1; 200 1.1 mrg #if MODE_UNSIGNED == 0 201 1.1 mrg min = (DINT_C_TYPE)1 << (2 * FIXED_WIDTH - 1); 202 1.1 mrg min = min >> (2 * FIXED_WIDTH - 1 - I_F_BITS); 203 1.1 mrg #else 204 1.1 mrg min = 0; 205 1.1 mrg #endif 206 1.1 mrg if (*a > max) 207 1.1 mrg *a = max; 208 1.1 mrg else if (*a < min) 209 1.1 mrg *a = min; 210 1.1 mrg } 211 1.1 mrg #endif /* FIXED_SATURATE1 */ 212 1.1 mrg 213 1.1 mrg #if defined(FIXED_SATURATE2) && defined(L_saturate2) 214 1.1 mrg void 215 1.1 mrg FIXED_SATURATE2 (INT_C_TYPE *high, INT_C_TYPE *low) 216 1.1 mrg { 217 1.1 mrg INT_C_TYPE r_max, s_max, r_min, s_min; 218 1.1 mrg r_max = 0; 219 1.1 mrg #if (MODE_UNSIGNED == 0) || HAVE_PADDING_BITS 220 1.1 mrg s_max = (INT_C_TYPE)1 << I_F_BITS; 221 1.1 mrg s_max = s_max - 1; 222 1.1 mrg #else 223 1.1 mrg s_max = -1; 224 1.1 mrg #endif 225 1.1 mrg #if MODE_UNSIGNED == 0 226 1.1 mrg r_min = -1; 227 1.1 mrg s_min = (INT_C_TYPE)1 << (FIXED_WIDTH - 1); 228 1.1 mrg s_min = s_min >> (FIXED_WIDTH - 1 - I_F_BITS); 229 1.1 mrg #else 230 1.1 mrg r_min = 0; 231 1.1 mrg s_min = 0; 232 1.1 mrg #endif 233 1.1 mrg 234 1.1 mrg if (*high > r_max 235 1.1 mrg || (*high == r_max && (UINT_C_TYPE)(*low) > (UINT_C_TYPE)s_max)) 236 1.1 mrg { 237 1.1 mrg *high = r_max; 238 1.1 mrg *low = s_max; 239 1.1 mrg } 240 1.1 mrg else if (*high < r_min || 241 1.1 mrg (*high == r_min && (UINT_C_TYPE)(*low) < (UINT_C_TYPE)s_min)) 242 1.1 mrg { 243 1.1 mrg *high = r_min; 244 1.1 mrg *low = s_min; 245 1.1 mrg } 246 1.1 mrg } 247 1.1 mrg #endif /* FIXED_SATURATE2 */ 248 1.1 mrg 249 1.1 mrg #if defined(FIXED_MULHELPER) && defined(L_mulhelper) 250 1.1 mrg FIXED_C_TYPE 251 1.1 mrg FIXED_MULHELPER (FIXED_C_TYPE a, FIXED_C_TYPE b, word_type satp) 252 1.1 mrg { 253 1.1 mrg FIXED_C_TYPE c; 254 1.1 mrg INT_C_TYPE x, y; 255 1.1 mrg 256 1.1 mrg #if defined (DINT_C_TYPE) 257 1.1 mrg INT_C_TYPE z; 258 1.1 mrg DINT_C_TYPE dx, dy, dz; 259 1.1 mrg memcpy (&x, &a, FIXED_SIZE); 260 1.1 mrg memcpy (&y, &b, FIXED_SIZE); 261 1.1 mrg dx = (DINT_C_TYPE) x; 262 1.1 mrg dy = (DINT_C_TYPE) y; 263 1.1 mrg dz = dx * dy; 264 1.1 mrg /* Round the result by adding (1 << (FBITS -1)). */ 265 1.1 mrg dz += ((DINT_C_TYPE) 1 << (FBITS - 1)); 266 1.1 mrg dz = dz >> FBITS; 267 1.1 mrg if (satp) 268 1.1 mrg FIXED_SATURATE1 (&dz); 269 1.1 mrg 270 1.1 mrg z = (INT_C_TYPE) dz; 271 1.1 mrg #if HAVE_PADDING_BITS 272 1.1 mrg z = z << PADDING_BITS; 273 1.1 mrg z = z >> PADDING_BITS; 274 1.1 mrg #endif 275 1.1 mrg memcpy (&c, &z, FIXED_SIZE); 276 1.1 mrg return c; 277 1.1 mrg 278 1.1 mrg #else /* No DINT_C_TYPE */ 279 1.1 mrg /* The result of multiplication expands to two INT_C_TYPE. */ 280 1.1 mrg INTunion aa, bb; 281 1.1 mrg INTunion a_high, a_low, b_high, b_low; 282 1.1 mrg INTunion high_high, high_low, low_high, low_low; 283 1.1 mrg INTunion r, s, temp1, temp2; 284 1.1 mrg INT_C_TYPE carry = 0; 285 1.1 mrg INT_C_TYPE z; 286 1.1 mrg 287 1.1 mrg memcpy (&x, &a, FIXED_SIZE); 288 1.1 mrg memcpy (&y, &b, FIXED_SIZE); 289 1.1 mrg 290 1.1 mrg /* Decompose a and b. */ 291 1.1 mrg aa.ll = x; 292 1.1 mrg bb.ll = y; 293 1.1 mrg 294 1.1 mrg a_high.s.low = aa.s.high; 295 1.1 mrg a_high.s.high = 0; 296 1.1 mrg a_low.s.low = aa.s.low; 297 1.1 mrg a_low.s.high = 0; 298 1.1 mrg b_high.s.low = bb.s.high; 299 1.1 mrg b_high.s.high = 0; 300 1.1 mrg b_low.s.low = bb.s.low; 301 1.1 mrg b_low.s.high = 0; 302 1.1 mrg 303 1.1 mrg /* Perform four multiplications. */ 304 1.1 mrg low_low.ll = a_low.ll * b_low.ll; 305 1.1 mrg low_high.ll = a_low.ll * b_high.ll; 306 1.1 mrg high_low.ll = a_high.ll * b_low.ll; 307 1.1 mrg high_high.ll = a_high.ll * b_high.ll; 308 1.1 mrg 309 1.1 mrg /* Accumulate four results to {r, s}. */ 310 1.1 mrg temp1.s.high = high_low.s.low; 311 1.1 mrg temp1.s.low = 0; 312 1.1 mrg s.ll = low_low.ll + temp1.ll; 313 1.1 mrg if ((UINT_C_TYPE) s.ll < (UINT_C_TYPE) low_low.ll 314 1.1 mrg || (UINT_C_TYPE) s.ll < (UINT_C_TYPE) temp1.ll) 315 1.1 mrg carry ++; /* Carry. */ 316 1.1 mrg temp1.ll = s.ll; 317 1.1 mrg temp2.s.high = low_high.s.low; 318 1.1 mrg temp2.s.low = 0; 319 1.1 mrg s.ll = temp1.ll + temp2.ll; 320 1.1 mrg if ((UINT_C_TYPE) s.ll < (UINT_C_TYPE) temp1.ll 321 1.1 mrg || (UINT_C_TYPE) s.ll < (UINT_C_TYPE) temp2.ll) 322 1.1 mrg carry ++; /* Carry. */ 323 1.1 mrg 324 1.1 mrg temp1.s.low = high_low.s.high; 325 1.1 mrg temp1.s.high = 0; 326 1.1 mrg r.ll = high_high.ll + temp1.ll; 327 1.1 mrg temp1.s.low = low_high.s.high; 328 1.1 mrg temp1.s.high = 0; 329 1.1 mrg r.ll = r.ll + temp1.ll + carry; 330 1.1 mrg 331 1.1 mrg #if MODE_UNSIGNED == 0 332 1.1 mrg /* For signed types, we need to add neg(y) to r, if x < 0. */ 333 1.1 mrg if (x < 0) 334 1.1 mrg r.ll = r.ll - y; 335 1.1 mrg /* We need to add neg(x) to r, if y < 0. */ 336 1.1 mrg if (y < 0) 337 1.1 mrg r.ll = r.ll - x; 338 1.1 mrg #endif 339 1.1 mrg 340 1.1 mrg /* Round the result by adding (1 << (FBITS -1)). */ 341 1.1 mrg temp1.ll = s.ll; 342 1.1 mrg s.ll += ((INT_C_TYPE) 1 << (FBITS -1)); 343 1.1 mrg if ((UINT_C_TYPE) s.ll < (UINT_C_TYPE) temp1.ll 344 1.1 mrg || (UINT_C_TYPE) s.ll < (UINT_C_TYPE) ((INT_C_TYPE) 1 << (FBITS -1))) 345 1.1 mrg r.ll += 1; 346 1.1 mrg 347 1.1 mrg /* Shift right the result by FBITS. */ 348 1.1 mrg #if FBITS == FIXED_WIDTH 349 1.1 mrg /* This happens only for unsigned types without any padding bits. 350 1.1 mrg So, it is safe to set r.ll to 0 as it is logically shifted right. */ 351 1.1 mrg s.ll = r.ll; 352 1.1 mrg r.ll = 0; 353 1.1 mrg #else 354 1.1 mrg s.ll = ((UINT_C_TYPE)s.ll) >> FBITS; 355 1.1 mrg temp1.ll = r.ll << (FIXED_WIDTH - FBITS); 356 1.1 mrg s.ll = s.ll | temp1.ll; 357 1.1 mrg r.ll = r.ll >> FBITS; 358 1.1 mrg #endif 359 1.1 mrg 360 1.1 mrg if (satp) 361 1.1 mrg FIXED_SATURATE2 (&r.ll, &s.ll); 362 1.1 mrg 363 1.1 mrg z = (INT_C_TYPE) s.ll; 364 1.1 mrg #if HAVE_PADDING_BITS 365 1.1 mrg z = z << PADDING_BITS; 366 1.1 mrg z = z >> PADDING_BITS; 367 1.1 mrg #endif 368 1.1 mrg memcpy (&c, &z, FIXED_SIZE); 369 1.1 mrg return c; 370 1.1 mrg #endif 371 1.1 mrg } 372 1.1 mrg #endif /* FIXED_MULHELPER */ 373 1.1 mrg 374 1.1 mrg #if defined(FIXED_MUL) && defined(L_mul) 375 1.1 mrg FIXED_C_TYPE 376 1.1 mrg FIXED_MUL (FIXED_C_TYPE a, FIXED_C_TYPE b) 377 1.1 mrg { 378 1.1 mrg return FIXED_MULHELPER (a, b, 0); 379 1.1 mrg } 380 1.1 mrg #endif /* FIXED_MUL */ 381 1.1 mrg 382 1.1 mrg #if defined(FIXED_SSMUL) && defined(L_ssmul) 383 1.1 mrg FIXED_C_TYPE 384 1.1 mrg FIXED_SSMUL (FIXED_C_TYPE a, FIXED_C_TYPE b) 385 1.1 mrg { 386 1.1 mrg return FIXED_MULHELPER (a, b, 1); 387 1.1 mrg } 388 1.1 mrg #endif /* FIXED_SSMUL */ 389 1.1 mrg 390 1.1 mrg #if defined(FIXED_USMUL) && defined(L_usmul) 391 1.1 mrg FIXED_C_TYPE 392 1.1 mrg FIXED_USMUL (FIXED_C_TYPE a, FIXED_C_TYPE b) 393 1.1 mrg { 394 1.1 mrg return FIXED_MULHELPER (a, b, 1); 395 1.1 mrg } 396 1.1 mrg #endif /* FIXED_USMUL */ 397 1.1 mrg 398 1.1 mrg #if defined(FIXED_DIVHELPER) && defined(L_divhelper) 399 1.1 mrg FIXED_C_TYPE 400 1.1 mrg FIXED_DIVHELPER (FIXED_C_TYPE a, FIXED_C_TYPE b, word_type satp) 401 1.1 mrg { 402 1.1 mrg FIXED_C_TYPE c; 403 1.1 mrg INT_C_TYPE x, y; 404 1.1 mrg INT_C_TYPE z; 405 1.1 mrg 406 1.1 mrg #if defined (DINT_C_TYPE) 407 1.1 mrg DINT_C_TYPE dx, dy, dz; 408 1.1 mrg memcpy (&x, &a, FIXED_SIZE); 409 1.1 mrg memcpy (&y, &b, FIXED_SIZE); 410 1.1 mrg dx = (DINT_C_TYPE) x; 411 1.1 mrg dy = (DINT_C_TYPE) y; 412 1.1 mrg dx = dx << FBITS; 413 1.1 mrg dz = dx / dy; 414 1.1 mrg if (satp) 415 1.1 mrg FIXED_SATURATE1 (&dz); 416 1.1 mrg z = (INT_C_TYPE) dz; 417 1.1 mrg #if HAVE_PADDING_BITS 418 1.1 mrg z = z << PADDING_BITS; 419 1.1 mrg z = z >> PADDING_BITS; 420 1.1 mrg #endif 421 1.1 mrg memcpy (&c, &z, FIXED_SIZE); 422 1.1 mrg return c; 423 1.1 mrg 424 1.1 mrg #else /* No DINT_C_TYPE */ 425 1.1 mrg INT_C_TYPE pos_a, pos_b, r, s; 426 1.1 mrg INT_C_TYPE quo_r, quo_s, mod, temp; 427 1.1 mrg word_type i; 428 1.1 mrg #if MODE_UNSIGNED == 0 429 1.1 mrg word_type num_of_neg = 0; 430 1.1 mrg #endif 431 1.1 mrg 432 1.1 mrg memcpy (&x, &a, FIXED_SIZE); 433 1.1 mrg memcpy (&y, &b, FIXED_SIZE); 434 1.1 mrg pos_a = x; 435 1.1 mrg pos_b = y; 436 1.1 mrg 437 1.1 mrg #if MODE_UNSIGNED == 0 438 1.1 mrg /* If a < 0, negate a. */ 439 1.1 mrg if (pos_a < 0) 440 1.1 mrg { 441 1.1 mrg pos_a = -pos_a; 442 1.1 mrg num_of_neg ++; 443 1.1 mrg } 444 1.1 mrg /* If b < 0, negate b. */ 445 1.1 mrg if (pos_b < 0) 446 1.1 mrg { 447 1.1 mrg pos_b = -pos_b; 448 1.1 mrg num_of_neg ++; 449 1.1 mrg } 450 1.1 mrg #endif 451 1.1 mrg 452 1.1 mrg /* Left shift pos_a to {r, s} by FBITS. */ 453 1.1 mrg #if FBITS == FIXED_WIDTH 454 1.1 mrg /* This happens only for unsigned types without any padding bits. */ 455 1.1 mrg r = pos_a; 456 1.1 mrg s = 0; 457 1.1 mrg #else 458 1.1 mrg s = pos_a << FBITS; 459 1.1 mrg r = pos_a >> (FIXED_WIDTH - FBITS); 460 1.1 mrg #endif 461 1.1 mrg 462 1.1 mrg /* Unsigned divide r by pos_b to quo_r. The remainder is in mod. */ 463 1.1 mrg quo_r = (UINT_C_TYPE)r / (UINT_C_TYPE)pos_b; 464 1.1 mrg mod = (UINT_C_TYPE)r % (UINT_C_TYPE)pos_b; 465 1.1 mrg quo_s = 0; 466 1.1 mrg 467 1.1 mrg for (i = 0; i < FIXED_WIDTH; i++) 468 1.1 mrg { 469 1.1 mrg /* Record the leftmost bit of mod. */ 470 1.1 mrg word_type leftmost_mode = (mod >> (FIXED_WIDTH - 1)) & 1; 471 1.1 mrg /* Shift left mod by 1 bit. */ 472 1.1 mrg mod = mod << 1; 473 1.1 mrg /* Test the leftmost bit of s to add to mod. */ 474 1.1 mrg if ((s >> (FIXED_WIDTH - 1)) & 1) 475 1.1 mrg mod ++; 476 1.1 mrg /* Shift left quo_s by 1 bit. */ 477 1.1 mrg quo_s = quo_s << 1; 478 1.1 mrg /* Try to calculate (mod - pos_b). */ 479 1.1 mrg temp = mod - pos_b; 480 1.1 mrg if (leftmost_mode || (UINT_C_TYPE)mod >= (UINT_C_TYPE)pos_b) 481 1.1 mrg { 482 1.1 mrg quo_s ++; 483 1.1 mrg mod = temp; 484 1.1 mrg } 485 1.1 mrg /* Shift left s by 1 bit. */ 486 1.1 mrg s = s << 1; 487 1.1 mrg } 488 1.1 mrg 489 1.1 mrg #if MODE_UNSIGNED == 0 490 1.1 mrg if (num_of_neg == 1) 491 1.1 mrg { 492 1.1 mrg quo_s = -quo_s; 493 1.1 mrg if (quo_s == 0) 494 1.1 mrg quo_r = -quo_r; 495 1.1 mrg else 496 1.1 mrg quo_r = ~quo_r; 497 1.1 mrg } 498 1.1 mrg #endif 499 1.1 mrg if (satp) 500 1.1 mrg FIXED_SATURATE2 (&quo_r, &quo_s); 501 1.1 mrg z = quo_s; 502 1.1 mrg #if HAVE_PADDING_BITS 503 1.1 mrg z = z << PADDING_BITS; 504 1.1 mrg z = z >> PADDING_BITS; 505 1.1 mrg #endif 506 1.1 mrg memcpy (&c, &z, FIXED_SIZE); 507 1.1 mrg return c; 508 1.1 mrg #endif 509 1.1 mrg } 510 1.1 mrg #endif /* FIXED_DIVHELPER */ 511 1.1 mrg 512 1.1 mrg #if defined(FIXED_DIV) && defined(L_div) 513 1.1 mrg FIXED_C_TYPE 514 1.1 mrg FIXED_DIV (FIXED_C_TYPE a, FIXED_C_TYPE b) 515 1.1 mrg { 516 1.1 mrg return FIXED_DIVHELPER (a, b, 0); 517 1.1 mrg } 518 1.1 mrg #endif /* FIXED_DIV */ 519 1.1 mrg 520 1.1 mrg 521 1.1 mrg #if defined(FIXED_UDIV) && defined(L_udiv) 522 1.1 mrg FIXED_C_TYPE 523 1.1 mrg FIXED_UDIV (FIXED_C_TYPE a, FIXED_C_TYPE b) 524 1.1 mrg { 525 1.1 mrg return FIXED_DIVHELPER (a, b, 0); 526 1.1 mrg } 527 1.1 mrg #endif /* FIXED_UDIV */ 528 1.1 mrg 529 1.1 mrg #if defined(FIXED_SSDIV) && defined(L_ssdiv) 530 1.1 mrg FIXED_C_TYPE 531 1.1 mrg FIXED_SSDIV (FIXED_C_TYPE a, FIXED_C_TYPE b) 532 1.1 mrg { 533 1.1 mrg return FIXED_DIVHELPER (a, b, 1); 534 1.1 mrg } 535 1.1 mrg #endif /* FIXED_SSDIV */ 536 1.1 mrg 537 1.1 mrg #if defined(FIXED_USDIV) && defined(L_usdiv) 538 1.1 mrg FIXED_C_TYPE 539 1.1 mrg FIXED_USDIV (FIXED_C_TYPE a, FIXED_C_TYPE b) 540 1.1 mrg { 541 1.1 mrg return FIXED_DIVHELPER (a, b, 1); 542 1.1 mrg } 543 1.1 mrg #endif /* FIXED_USDIV */ 544 1.1 mrg 545 1.1 mrg #if defined(FIXED_NEG) && defined(L_neg) 546 1.1 mrg FIXED_C_TYPE 547 1.1 mrg FIXED_NEG (FIXED_C_TYPE a) 548 1.1 mrg { 549 1.1 mrg FIXED_C_TYPE c; 550 1.1 mrg INT_C_TYPE x, z; 551 1.1 mrg memcpy (&x, &a, FIXED_SIZE); 552 1.1 mrg z = -x; 553 1.1 mrg #if HAVE_PADDING_BITS 554 1.1 mrg z = z << PADDING_BITS; 555 1.1 mrg z = z >> PADDING_BITS; 556 1.1 mrg #endif 557 1.1 mrg memcpy (&c, &z, FIXED_SIZE); 558 1.1 mrg return c; 559 1.1 mrg } 560 1.1 mrg #endif /* FIXED_NEG */ 561 1.1 mrg 562 1.1 mrg #if defined(FIXED_SSNEG) && defined(L_ssneg) 563 1.1 mrg FIXED_C_TYPE 564 1.1 mrg FIXED_SSNEG (FIXED_C_TYPE a) 565 1.1 mrg { 566 1.1 mrg FIXED_C_TYPE c; 567 1.1 mrg INT_C_TYPE x, y, z; 568 1.1 mrg memcpy (&y, &a, FIXED_SIZE); 569 1.1 mrg x = 0; 570 1.1 mrg z = x - (UINT_C_TYPE) y; 571 1.1 mrg if (((x ^ y) >> I_F_BITS) & 1) 572 1.1 mrg { 573 1.1 mrg if (((z ^ x) >> I_F_BITS) & 1) 574 1.1 mrg z = (((UINT_C_TYPE) 1) << I_F_BITS) - 1; 575 1.1 mrg } 576 1.1 mrg #if HAVE_PADDING_BITS 577 1.1 mrg z = z << PADDING_BITS; 578 1.1 mrg z = z >> PADDING_BITS; 579 1.1 mrg #endif 580 1.1 mrg memcpy (&c, &z, FIXED_SIZE); 581 1.1 mrg return c; 582 1.1 mrg } 583 1.1 mrg #endif /* FIXED_SSNEG */ 584 1.1 mrg 585 1.1 mrg #if defined(FIXED_USNEG) && defined(L_usneg) 586 1.1 mrg FIXED_C_TYPE 587 1.1 mrg FIXED_USNEG (FIXED_C_TYPE a __attribute__ ((__unused__))) 588 1.1 mrg { 589 1.1 mrg FIXED_C_TYPE c; 590 1.1 mrg INT_C_TYPE z; 591 1.1 mrg z = 0; 592 1.1 mrg memcpy (&c, &z, FIXED_SIZE); 593 1.1 mrg return c; 594 1.1 mrg } 595 1.1 mrg #endif /* FIXED_USNEG */ 596 1.1 mrg 597 1.1 mrg #if defined(FIXED_ASHLHELPER) && defined(L_ashlhelper) 598 1.1 mrg FIXED_C_TYPE 599 1.1 mrg FIXED_ASHLHELPER (FIXED_C_TYPE a, word_type b, word_type satp) 600 1.1 mrg { 601 1.1 mrg FIXED_C_TYPE c; 602 1.1 mrg INT_C_TYPE x, z; 603 1.1 mrg 604 1.1 mrg #if defined (DINT_C_TYPE) 605 1.1 mrg DINT_C_TYPE dx, dz; 606 1.1 mrg memcpy (&x, &a, FIXED_SIZE); 607 1.1 mrg dx = (DINT_C_TYPE) x; 608 1.1 mrg if (b >= FIXED_WIDTH) 609 1.1 mrg dz = dx << FIXED_WIDTH; 610 1.1 mrg else 611 1.1 mrg dz = dx << b; 612 1.1 mrg if (satp) 613 1.1 mrg FIXED_SATURATE1 (&dz); 614 1.1 mrg z = (INT_C_TYPE) dz; 615 1.1 mrg #if HAVE_PADDING_BITS 616 1.1 mrg z = z << PADDING_BITS; 617 1.1 mrg z = z >> PADDING_BITS; 618 1.1 mrg #endif 619 1.1 mrg memcpy (&c, &z, FIXED_SIZE); 620 1.1 mrg return c; 621 1.1 mrg 622 1.1 mrg #else /* No DINT_C_TYPE */ 623 1.1 mrg INT_C_TYPE r, s; 624 1.1 mrg memcpy (&x, &a, FIXED_SIZE); 625 1.1 mrg /* We need to shift left x by b bits to {r, s}. */ 626 1.1 mrg if (b >= FIXED_WIDTH) 627 1.1 mrg { 628 1.1 mrg r = b; 629 1.1 mrg s = 0; 630 1.1 mrg } 631 1.1 mrg else 632 1.1 mrg { 633 1.1 mrg s = x << b; 634 1.1 mrg r = x >> (FIXED_WIDTH - b); 635 1.1 mrg } 636 1.1 mrg if (satp) 637 1.1 mrg FIXED_SATURATE2 (&r, &s); 638 1.1 mrg z = s; 639 1.1 mrg #if HAVE_PADDING_BITS 640 1.1 mrg z = z << PADDING_BITS; 641 1.1 mrg z = z >> PADDING_BITS; 642 1.1 mrg #endif 643 1.1 mrg memcpy (&c, &z, FIXED_SIZE); 644 1.1 mrg return c; 645 1.1 mrg #endif 646 1.1 mrg } 647 1.1 mrg #endif /* FIXED_ASHLHELPER */ 648 1.1 mrg 649 1.1 mrg #if defined(FIXED_ASHL) && defined(L_ashl) 650 1.1 mrg FIXED_C_TYPE 651 1.1 mrg FIXED_ASHL (FIXED_C_TYPE a, word_type b) 652 1.1 mrg { 653 1.1 mrg return FIXED_ASHLHELPER (a, b, 0); 654 1.1 mrg } 655 1.1 mrg #endif /* FIXED_ASHL */ 656 1.1 mrg 657 1.1 mrg #if defined(FIXED_ASHR) && defined(L_ashr) 658 1.1 mrg FIXED_C_TYPE 659 1.1 mrg FIXED_ASHR (FIXED_C_TYPE a, word_type b) 660 1.1 mrg { 661 1.1 mrg FIXED_C_TYPE c; 662 1.1 mrg INT_C_TYPE x, z; 663 1.1 mrg memcpy (&x, &a, FIXED_SIZE); 664 1.1 mrg z = x >> b; 665 1.1 mrg #if HAVE_PADDING_BITS 666 1.1 mrg z = z << PADDING_BITS; 667 1.1 mrg z = z >> PADDING_BITS; 668 1.1 mrg #endif 669 1.1 mrg memcpy (&c, &z, FIXED_SIZE); 670 1.1 mrg return c; 671 1.1 mrg } 672 1.1 mrg #endif /* FIXED_ASHR */ 673 1.1 mrg 674 1.1 mrg #if defined(FIXED_LSHR) && defined(L_lshr) 675 1.1 mrg FIXED_C_TYPE 676 1.1 mrg FIXED_LSHR (FIXED_C_TYPE a, word_type b) 677 1.1 mrg { 678 1.1 mrg FIXED_C_TYPE c; 679 1.1 mrg INT_C_TYPE x, z; 680 1.1 mrg memcpy (&x, &a, FIXED_SIZE); 681 1.1 mrg z = x >> b; 682 1.1 mrg #if HAVE_PADDING_BITS 683 1.1 mrg z = z << PADDING_BITS; 684 1.1 mrg z = z >> PADDING_BITS; 685 1.1 mrg #endif 686 1.1 mrg memcpy (&c, &z, FIXED_SIZE); 687 1.1 mrg return c; 688 1.1 mrg } 689 1.1 mrg #endif /* FIXED_LSHR */ 690 1.1 mrg 691 1.1 mrg #if defined(FIXED_SSASHL) && defined(L_ssashl) 692 1.1 mrg FIXED_C_TYPE 693 1.1 mrg FIXED_SSASHL (FIXED_C_TYPE a, word_type b) 694 1.1 mrg { 695 1.1 mrg return FIXED_ASHLHELPER (a, b, 1); 696 1.1 mrg } 697 1.1 mrg #endif /* FIXED_SSASHL */ 698 1.1 mrg 699 1.1 mrg #if defined(FIXED_USASHL) && defined(L_usashl) 700 1.1 mrg FIXED_C_TYPE 701 1.1 mrg FIXED_USASHL (FIXED_C_TYPE a, word_type b) 702 1.1 mrg { 703 1.1 mrg return FIXED_ASHLHELPER (a, b, 1); 704 1.1 mrg } 705 1.1 mrg #endif /* FIXED_USASHL */ 706 1.1 mrg 707 1.1 mrg #if defined(FIXED_CMP) && defined(L_cmp) 708 1.1 mrg word_type 709 1.1 mrg FIXED_CMP (FIXED_C_TYPE a, FIXED_C_TYPE b) 710 1.1 mrg { 711 1.1 mrg INT_C_TYPE x, y; 712 1.1 mrg memcpy (&x, &a, FIXED_SIZE); 713 1.1 mrg memcpy (&y, &b, FIXED_SIZE); 714 1.1 mrg 715 1.1 mrg if (x < y) 716 1.1 mrg return 0; 717 1.1 mrg else if (x > y) 718 1.1 mrg return 2; 719 1.1 mrg 720 1.1 mrg return 1; 721 1.1 mrg } 722 1.1 mrg #endif /* FIXED_CMP */ 723 1.1 mrg 724 1.1 mrg /* Fixed -> Fixed. */ 725 1.1 mrg #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 4 726 1.1 mrg TO_FIXED_C_TYPE 727 1.1 mrg FRACT (FROM_FIXED_C_TYPE a) 728 1.1 mrg { 729 1.1 mrg TO_FIXED_C_TYPE c; 730 1.1 mrg FROM_INT_C_TYPE x; 731 1.1 mrg TO_INT_C_TYPE z; 732 1.1 mrg int shift_amount; 733 1.1 mrg memcpy (&x, &a, FROM_FIXED_SIZE); 734 1.1 mrg #if TO_FBITS > FROM_FBITS /* Need left shift. */ 735 1.1 mrg shift_amount = TO_FBITS - FROM_FBITS; 736 1.1 mrg z = (TO_INT_C_TYPE) x; 737 1.1 mrg z = z << shift_amount; 738 1.1 mrg #else /* TO_FBITS <= FROM_FBITS. Need right Shift. */ 739 1.1 mrg shift_amount = FROM_FBITS - TO_FBITS; 740 1.1 mrg x = x >> shift_amount; 741 1.1 mrg z = (TO_INT_C_TYPE) x; 742 1.1 mrg #endif /* TO_FBITS > FROM_FBITS */ 743 1.1 mrg 744 1.1 mrg #if TO_HAVE_PADDING_BITS 745 1.1 mrg z = z << TO_PADDING_BITS; 746 1.1 mrg z = z >> TO_PADDING_BITS; 747 1.1 mrg #endif 748 1.1 mrg memcpy (&c, &z, TO_FIXED_SIZE); 749 1.1 mrg return c; 750 1.1 mrg } 751 1.1 mrg #endif /* FRACT && FROM_TYPE == 4 && TO_TYPE == 4 */ 752 1.1 mrg 753 1.1 mrg /* Fixed -> Fixed with saturation. */ 754 1.1 mrg #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 4 && TO_TYPE == 4 755 1.1 mrg TO_FIXED_C_TYPE 756 1.1 mrg SATFRACT (FROM_FIXED_C_TYPE a) 757 1.1 mrg { 758 1.1 mrg TO_FIXED_C_TYPE c; 759 1.1 mrg TO_INT_C_TYPE z; 760 1.1 mrg FROM_INT_C_TYPE x; 761 1.1 mrg #if FROM_MODE_UNSIGNED == 0 762 1.1 mrg BIG_SINT_C_TYPE high, low; 763 1.1 mrg BIG_SINT_C_TYPE max_high, max_low; 764 1.1 mrg #if TO_MODE_UNSIGNED == 0 765 1.1 mrg BIG_SINT_C_TYPE min_high, min_low; 766 1.1 mrg #endif 767 1.1 mrg #else 768 1.1 mrg BIG_UINT_C_TYPE high, low; 769 1.1 mrg BIG_UINT_C_TYPE max_high, max_low; 770 1.1 mrg #endif 771 1.1 mrg #if TO_FBITS > FROM_FBITS 772 1.1 mrg BIG_UINT_C_TYPE utemp; 773 1.1 mrg #endif 774 1.1 mrg #if TO_MODE_UNSIGNED == 0 775 1.1 mrg BIG_SINT_C_TYPE stemp; 776 1.1 mrg #endif 777 1.1 mrg #if TO_FBITS != FROM_FBITS 778 1.1 mrg int shift_amount; 779 1.1 mrg #endif 780 1.1 mrg memcpy (&x, &a, FROM_FIXED_SIZE); 781 1.1 mrg 782 1.1 mrg /* Step 1. We need to store x to {high, low}. */ 783 1.1 mrg #if FROM_MODE_UNSIGNED == 0 784 1.1 mrg low = (BIG_SINT_C_TYPE) x; 785 1.1 mrg if (x < 0) 786 1.1 mrg high = -1; 787 1.1 mrg else 788 1.1 mrg high = 0; 789 1.1 mrg #else 790 1.1 mrg low = (BIG_UINT_C_TYPE) x; 791 1.1 mrg high = 0; 792 1.1 mrg #endif 793 1.1 mrg 794 1.1 mrg /* Step 2. We need to shift {high, low}. */ 795 1.1 mrg #if TO_FBITS > FROM_FBITS /* Left shift. */ 796 1.1 mrg shift_amount = TO_FBITS - FROM_FBITS; 797 1.1 mrg utemp = (BIG_UINT_C_TYPE) low; 798 1.1 mrg utemp = utemp >> (BIG_WIDTH - shift_amount); 799 1.1 mrg high = ((BIG_UINT_C_TYPE)(high << shift_amount)) | utemp; 800 1.1 mrg low = low << shift_amount; 801 1.1 mrg #elif TO_FBITS < FROM_FBITS /* Right shift. */ 802 1.1 mrg shift_amount = FROM_FBITS - TO_FBITS; 803 1.1 mrg low = low >> shift_amount; 804 1.1 mrg #endif 805 1.1 mrg 806 1.1 mrg /* Step 3. Compare {high, low} with max and min of TO_FIXED_C_TYPE. */ 807 1.1 mrg max_high = 0; 808 1.1 mrg #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS 809 1.1 mrg max_low = (BIG_UINT_C_TYPE)1 << TO_I_F_BITS; 810 1.1 mrg max_low = max_low - 1; 811 1.1 mrg #else 812 1.1 mrg max_low = -1; 813 1.1 mrg #endif 814 1.1 mrg 815 1.1 mrg #if TO_MODE_UNSIGNED == 0 816 1.1 mrg stemp = (BIG_SINT_C_TYPE)1 << (BIG_WIDTH - 1); 817 1.1 mrg stemp = stemp >> (BIG_WIDTH - 1 - TO_I_F_BITS); 818 1.1 mrg #if FROM_MODE_UNSIGNED == 0 819 1.1 mrg min_high = -1; 820 1.1 mrg min_low = stemp; 821 1.1 mrg #endif 822 1.1 mrg #endif 823 1.1 mrg 824 1.1 mrg #if FROM_MODE_UNSIGNED == 0 && TO_MODE_UNSIGNED == 0 825 1.1 mrg /* Signed -> Signed. */ 826 1.1 mrg if ((BIG_SINT_C_TYPE) high > (BIG_SINT_C_TYPE) max_high 827 1.1 mrg || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) max_high 828 1.1 mrg && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low)) 829 1.1 mrg low = max_low; /* Maximum. */ 830 1.1 mrg else if ((BIG_SINT_C_TYPE) high < (BIG_SINT_C_TYPE) min_high 831 1.1 mrg || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) min_high 832 1.1 mrg && (BIG_UINT_C_TYPE) low < (BIG_UINT_C_TYPE) min_low)) 833 1.1 mrg low = min_low; /* Minimum. */ 834 1.1 mrg #elif FROM_MODE_UNSIGNED == 1 && TO_MODE_UNSIGNED == 1 835 1.1 mrg /* Unigned -> Unsigned. */ 836 1.1 mrg if ((BIG_UINT_C_TYPE) high > (BIG_UINT_C_TYPE) max_high 837 1.1 mrg || ((BIG_UINT_C_TYPE) high == (BIG_UINT_C_TYPE) max_high 838 1.1 mrg && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low)) 839 1.1 mrg low = max_low; /* Maximum. */ 840 1.1 mrg #elif FROM_MODE_UNSIGNED == 0 && TO_MODE_UNSIGNED == 1 841 1.1 mrg /* Signed -> Unsigned. */ 842 1.1 mrg if (x < 0) 843 1.1 mrg low = 0; /* Minimum. */ 844 1.1 mrg else if ((BIG_UINT_C_TYPE) high > (BIG_UINT_C_TYPE) max_high 845 1.1 mrg || ((BIG_UINT_C_TYPE) high == (BIG_UINT_C_TYPE) max_high 846 1.1 mrg && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low)) 847 1.1 mrg low = max_low; /* Maximum. */ 848 1.1 mrg #elif FROM_MODE_UNSIGNED == 1 && TO_MODE_UNSIGNED == 0 849 1.1 mrg /* Unsigned -> Signed. */ 850 1.1 mrg if ((BIG_SINT_C_TYPE) high < 0) 851 1.1 mrg low = max_low; /* Maximum. */ 852 1.1 mrg else if ((BIG_SINT_C_TYPE) high > (BIG_SINT_C_TYPE) max_high 853 1.1 mrg || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) max_high 854 1.1 mrg && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low)) 855 1.1 mrg low = max_low; /* Maximum. */ 856 1.1 mrg #endif 857 1.1 mrg 858 1.1 mrg /* Step 4. Store the result. */ 859 1.1 mrg z = (TO_INT_C_TYPE) low; 860 1.1 mrg #if TO_HAVE_PADDING_BITS 861 1.1 mrg z = z << TO_PADDING_BITS; 862 1.1 mrg z = z >> TO_PADDING_BITS; 863 1.1 mrg #endif 864 1.1 mrg memcpy (&c, &z, TO_FIXED_SIZE); 865 1.1 mrg return c; 866 1.1 mrg } 867 1.1 mrg #endif /* defined(SATFRACT) && FROM_TYPE == 4 && TO_TYPE == 4 */ 868 1.1 mrg 869 1.1 mrg /* Fixed -> Int. */ 870 1.1 mrg #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 1 871 1.1 mrg TO_INT_C_TYPE 872 1.1 mrg FRACT (FROM_FIXED_C_TYPE a) 873 1.1 mrg { 874 1.1 mrg FROM_INT_C_TYPE x; 875 1.1 mrg TO_INT_C_TYPE z; 876 1.1 mrg FROM_INT_C_TYPE i = 0; 877 1.1 mrg memcpy (&x, &a, FROM_FIXED_SIZE); 878 1.1 mrg 879 1.1 mrg #if FROM_MODE_UNSIGNED == 0 880 1.1 mrg if (x < 0) 881 1.1 mrg { 882 1.1 mrg #if FROM_FIXED_WIDTH == FROM_FBITS 883 1.1 mrg if (x != 0) 884 1.1 mrg i = 1; 885 1.1 mrg #else 886 1.1 mrg if (((FROM_INT_C_TYPE)(x << (FROM_FIXED_WIDTH - FROM_FBITS))) != 0) 887 1.1 mrg i = 1; 888 1.1 mrg #endif 889 1.1 mrg } 890 1.1 mrg #endif 891 1.1 mrg 892 1.1 mrg #if FROM_FIXED_WIDTH == FROM_FBITS 893 1.1 mrg x = 0; 894 1.1 mrg #else 895 1.1 mrg x = x >> FROM_FBITS; 896 1.1 mrg #endif 897 1.1 mrg x = x + i; 898 1.1 mrg z = (TO_INT_C_TYPE) x; 899 1.1 mrg return z; 900 1.1 mrg } 901 1.1 mrg #endif /* defined(FRACT) && FROM_TYPE == 4 && TO_TYPE == 1 */ 902 1.1 mrg 903 1.1 mrg /* Fixed -> Unsigned int. */ 904 1.1 mrg #if defined(FRACTUNS) && defined(L_fractuns) && FROM_TYPE == 4 && TO_TYPE == 2 905 1.1 mrg TO_INT_C_TYPE 906 1.1 mrg FRACTUNS (FROM_FIXED_C_TYPE a) 907 1.1 mrg { 908 1.1 mrg FROM_INT_C_TYPE x; 909 1.1 mrg TO_INT_C_TYPE z; 910 1.1 mrg FROM_INT_C_TYPE i = 0; 911 1.1 mrg memcpy (&x, &a, FROM_FIXED_SIZE); 912 1.1 mrg 913 1.1 mrg #if FROM_MODE_UNSIGNED == 0 914 1.1 mrg if (x < 0) 915 1.1 mrg { 916 1.1 mrg #if FROM_FIXED_WIDTH == FROM_FBITS 917 1.1 mrg if (x != 0) 918 1.1 mrg i = 1; 919 1.1 mrg #else 920 1.1 mrg if (((FROM_INT_C_TYPE)(x << (FROM_FIXED_WIDTH - FROM_FBITS))) != 0) 921 1.1 mrg i = 1; 922 1.1 mrg #endif 923 1.1 mrg } 924 1.1 mrg #endif 925 1.1 mrg 926 1.1 mrg #if FROM_FIXED_WIDTH == FROM_FBITS 927 1.1 mrg x = 0; 928 1.1 mrg #else 929 1.1 mrg x = x >> FROM_FBITS; 930 1.1 mrg #endif 931 1.1 mrg x = x + i; 932 1.1 mrg z = (TO_INT_C_TYPE) x; 933 1.1 mrg return z; 934 1.1 mrg } 935 1.1 mrg #endif /* defined(FRACTUNS) && FROM_TYPE == 4 && TO_TYPE == 2 */ 936 1.1 mrg 937 1.1 mrg /* Int -> Fixed. */ 938 1.1 mrg #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 1 && TO_TYPE == 4 939 1.1 mrg TO_FIXED_C_TYPE 940 1.1 mrg FRACT (FROM_INT_C_TYPE a) 941 1.1 mrg { 942 1.1 mrg TO_FIXED_C_TYPE c; 943 1.1 mrg TO_INT_C_TYPE z; 944 1.1 mrg z = (TO_INT_C_TYPE) a; 945 1.1 mrg #if TO_FIXED_WIDTH == TO_FBITS 946 1.1 mrg z = 0; 947 1.1 mrg #else 948 1.1 mrg z = z << TO_FBITS; 949 1.1 mrg #endif 950 1.1 mrg #if TO_HAVE_PADDING_BITS 951 1.1 mrg z = z << TO_PADDING_BITS; 952 1.1 mrg z = z >> TO_PADDING_BITS; 953 1.1 mrg #endif 954 1.1 mrg memcpy (&c, &z, TO_FIXED_SIZE); 955 1.1 mrg return c; 956 1.1 mrg } 957 1.1 mrg #endif /* defined(FRACT) && FROM_TYPE == 1 && TO_TYPE == 4 */ 958 1.1 mrg 959 1.1 mrg /* Signed int -> Fixed with saturation. */ 960 1.1 mrg #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 1 && TO_TYPE == 4 961 1.1 mrg TO_FIXED_C_TYPE 962 1.1 mrg SATFRACT (FROM_INT_C_TYPE a) 963 1.1 mrg { 964 1.1 mrg TO_FIXED_C_TYPE c; 965 1.1 mrg TO_INT_C_TYPE z; 966 1.1 mrg FROM_INT_C_TYPE x = a; 967 1.1 mrg BIG_SINT_C_TYPE high, low; 968 1.1 mrg BIG_SINT_C_TYPE max_high, max_low; 969 1.1 mrg #if TO_MODE_UNSIGNED == 0 970 1.1 mrg BIG_SINT_C_TYPE min_high, min_low; 971 1.1 mrg BIG_SINT_C_TYPE stemp; 972 1.1 mrg #endif 973 1.1 mrg #if BIG_WIDTH != TO_FBITS 974 1.1 mrg BIG_UINT_C_TYPE utemp; 975 1.1 mrg int shift_amount; 976 1.1 mrg #endif 977 1.1 mrg 978 1.1 mrg /* Step 1. We need to store x to {high, low}. */ 979 1.1 mrg low = (BIG_SINT_C_TYPE) x; 980 1.1 mrg if (x < 0) 981 1.1 mrg high = -1; 982 1.1 mrg else 983 1.1 mrg high = 0; 984 1.1 mrg 985 1.1 mrg /* Step 2. We need to left shift {high, low}. */ 986 1.1 mrg #if BIG_WIDTH == TO_FBITS 987 1.1 mrg high = low; 988 1.1 mrg low = 0; 989 1.1 mrg #else 990 1.1 mrg shift_amount = TO_FBITS; 991 1.1 mrg utemp = (BIG_UINT_C_TYPE) low; 992 1.1 mrg utemp = utemp >> (BIG_WIDTH - shift_amount); 993 1.1 mrg high = ((BIG_UINT_C_TYPE)(high << shift_amount)) | utemp; 994 1.1 mrg low = low << shift_amount; 995 1.1 mrg #endif 996 1.1 mrg 997 1.1 mrg /* Step 3. Compare {high, low} with max and min of TO_FIXED_C_TYPE. */ 998 1.1 mrg max_high = 0; 999 1.1 mrg #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS 1000 1.1 mrg max_low = (BIG_UINT_C_TYPE)1 << TO_I_F_BITS; 1001 1.1 mrg max_low = max_low - 1; 1002 1.1 mrg #else 1003 1.1 mrg max_low = -1; 1004 1.1 mrg #endif 1005 1.1 mrg 1006 1.1 mrg #if TO_MODE_UNSIGNED == 0 1007 1.1 mrg min_high = -1; 1008 1.1 mrg stemp = (BIG_SINT_C_TYPE)1 << (BIG_WIDTH - 1); 1009 1.1 mrg stemp = stemp >> (BIG_WIDTH - 1 - TO_I_F_BITS); 1010 1.1 mrg min_low = stemp; 1011 1.1 mrg 1012 1.1 mrg /* Signed -> Signed. */ 1013 1.1 mrg if ((BIG_SINT_C_TYPE) high > (BIG_SINT_C_TYPE) max_high 1014 1.1 mrg || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) max_high 1015 1.1 mrg && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low)) 1016 1.1 mrg low = max_low; /* Maximum. */ 1017 1.1 mrg else if ((BIG_SINT_C_TYPE) high < (BIG_SINT_C_TYPE) min_high 1018 1.1 mrg || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) min_high 1019 1.1 mrg && (BIG_UINT_C_TYPE) low < (BIG_UINT_C_TYPE) min_low)) 1020 1.1 mrg low = min_low; /* Minimum. */ 1021 1.1 mrg #else 1022 1.1 mrg /* Signed -> Unsigned. */ 1023 1.1 mrg if (x < 0) 1024 1.1 mrg low = 0; /* Minimum. */ 1025 1.1 mrg else if ((BIG_UINT_C_TYPE) high > (BIG_UINT_C_TYPE) max_high 1026 1.1 mrg || ((BIG_UINT_C_TYPE) high == (BIG_UINT_C_TYPE) max_high 1027 1.1 mrg && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low)) 1028 1.1 mrg low = max_low; /* Maximum. */ 1029 1.1 mrg #endif 1030 1.1 mrg 1031 1.1 mrg /* Step 4. Store the result. */ 1032 1.1 mrg z = (TO_INT_C_TYPE) low; 1033 1.1 mrg #if TO_HAVE_PADDING_BITS 1034 1.1 mrg z = z << TO_PADDING_BITS; 1035 1.1 mrg z = z >> TO_PADDING_BITS; 1036 1.1 mrg #endif 1037 1.1 mrg memcpy (&c, &z, TO_FIXED_SIZE); 1038 1.1 mrg return c; 1039 1.1 mrg } 1040 1.1 mrg #endif /* defined(SATFRACT) && FROM_TYPE == 1 && TO_TYPE == 4 */ 1041 1.1 mrg 1042 1.1 mrg /* Unsigned int -> Fixed. */ 1043 1.1 mrg #if defined(FRACTUNS) && defined(L_fractuns) &&FROM_TYPE == 2 && TO_TYPE == 4 1044 1.1 mrg TO_FIXED_C_TYPE 1045 1.1 mrg FRACTUNS (FROM_INT_C_TYPE a) 1046 1.1 mrg { 1047 1.1 mrg TO_FIXED_C_TYPE c; 1048 1.1 mrg TO_INT_C_TYPE z; 1049 1.1 mrg z = (TO_INT_C_TYPE) a; 1050 1.1 mrg #if TO_FIXED_WIDTH == TO_FBITS 1051 1.1 mrg z = 0; 1052 1.1 mrg #else 1053 1.1 mrg z = z << TO_FBITS; 1054 1.1 mrg #endif 1055 1.1 mrg #if TO_HAVE_PADDING_BITS 1056 1.1 mrg z = z << TO_PADDING_BITS; 1057 1.1 mrg z = z >> TO_PADDING_BITS; 1058 1.1 mrg #endif 1059 1.1 mrg memcpy (&c, &z, TO_FIXED_SIZE); 1060 1.1 mrg return c; 1061 1.1 mrg } 1062 1.1 mrg #endif /* defined(FRACTUNS) && FROM_TYPE == 2 && TO_TYPE == 4 */ 1063 1.1 mrg 1064 1.1 mrg /* Unsigned int -> Fixed with saturation. */ 1065 1.1 mrg #if defined(SATFRACTUNS) && defined(L_satfractuns) && FROM_TYPE == 2 && TO_TYPE == 4 1066 1.1 mrg TO_FIXED_C_TYPE 1067 1.1 mrg SATFRACTUNS (FROM_INT_C_TYPE a) 1068 1.1 mrg { 1069 1.1 mrg TO_FIXED_C_TYPE c; 1070 1.1 mrg TO_INT_C_TYPE z; 1071 1.1 mrg FROM_INT_C_TYPE x = a; 1072 1.1 mrg BIG_UINT_C_TYPE high, low; 1073 1.1 mrg BIG_UINT_C_TYPE max_high, max_low; 1074 1.1 mrg #if BIG_WIDTH != TO_FBITS 1075 1.1 mrg BIG_UINT_C_TYPE utemp; 1076 1.1 mrg int shift_amount; 1077 1.1 mrg #endif 1078 1.1 mrg 1079 1.1 mrg /* Step 1. We need to store x to {high, low}. */ 1080 1.1 mrg low = (BIG_UINT_C_TYPE) x; 1081 1.1 mrg high = 0; 1082 1.1 mrg 1083 1.1 mrg /* Step 2. We need to left shift {high, low}. */ 1084 1.1 mrg #if BIG_WIDTH == TO_FBITS 1085 1.1 mrg high = low; 1086 1.1 mrg low = 0; 1087 1.1 mrg #else 1088 1.1 mrg shift_amount = TO_FBITS; 1089 1.1 mrg utemp = (BIG_UINT_C_TYPE) low; 1090 1.1 mrg utemp = utemp >> (BIG_WIDTH - shift_amount); 1091 1.1 mrg high = ((BIG_UINT_C_TYPE)(high << shift_amount)) | utemp; 1092 1.1 mrg low = low << shift_amount; 1093 1.1 mrg #endif 1094 1.1 mrg 1095 1.1 mrg /* Step 3. Compare {high, low} with max and min of TO_FIXED_C_TYPE. */ 1096 1.1 mrg max_high = 0; 1097 1.1 mrg #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS 1098 1.1 mrg max_low = (BIG_UINT_C_TYPE)1 << TO_I_F_BITS; 1099 1.1 mrg max_low = max_low - 1; 1100 1.1 mrg #else 1101 1.1 mrg max_low = -1; 1102 1.1 mrg #endif 1103 1.1 mrg 1104 1.1 mrg #if TO_MODE_UNSIGNED == 1 1105 1.1 mrg /* Unigned -> Unsigned. */ 1106 1.1 mrg if ((BIG_UINT_C_TYPE) high > (BIG_UINT_C_TYPE) max_high 1107 1.1 mrg || ((BIG_UINT_C_TYPE) high == (BIG_UINT_C_TYPE) max_high 1108 1.1 mrg && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low)) 1109 1.1 mrg low = max_low; /* Maximum. */ 1110 1.1 mrg #else 1111 1.1 mrg /* Unsigned -> Signed. */ 1112 1.1 mrg if ((BIG_SINT_C_TYPE) high < 0) 1113 1.1 mrg low = max_low; /* Maximum. */ 1114 1.1 mrg else if ((BIG_SINT_C_TYPE) high > (BIG_SINT_C_TYPE) max_high 1115 1.1 mrg || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) max_high 1116 1.1 mrg && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low)) 1117 1.1 mrg low = max_low; /* Maximum. */ 1118 1.1 mrg #endif 1119 1.1 mrg 1120 1.1 mrg /* Step 4. Store the result. */ 1121 1.1 mrg z = (TO_INT_C_TYPE) low; 1122 1.1 mrg #if TO_HAVE_PADDING_BITS 1123 1.1 mrg z = z << TO_PADDING_BITS; 1124 1.1 mrg z = z >> TO_PADDING_BITS; 1125 1.1 mrg #endif 1126 1.1 mrg memcpy (&c, &z, TO_FIXED_SIZE); 1127 1.1 mrg return c; 1128 1.1 mrg } 1129 1.1 mrg #endif /* defined(SATFRACTUNS) && FROM_TYPE == 2 && TO_TYPE == 4 */ 1130 1.1 mrg 1131 1.1 mrg /* Fixed -> Float. */ 1132 1.1 mrg #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 3 1133 1.1 mrg TO_FLOAT_C_TYPE 1134 1.1 mrg FRACT (FROM_FIXED_C_TYPE a) 1135 1.1 mrg { 1136 1.1 mrg FROM_INT_C_TYPE x; 1137 1.1 mrg TO_FLOAT_C_TYPE z; 1138 1.1 mrg memcpy (&x, &a, FROM_FIXED_SIZE); 1139 1.1 mrg z = (TO_FLOAT_C_TYPE) x; 1140 1.1 mrg z = z / BASE; 1141 1.1 mrg return z; 1142 1.1 mrg } 1143 1.1 mrg #endif /* defined(FRACT) && FROM_TYPE == 4 && TO_TYPE == 3 */ 1144 1.1 mrg 1145 1.1 mrg /* Float -> Fixed. */ 1146 1.1 mrg #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 3 && TO_TYPE == 4 1147 1.1 mrg TO_FIXED_C_TYPE 1148 1.1 mrg FRACT (FROM_FLOAT_C_TYPE a) 1149 1.1 mrg { 1150 1.1 mrg FROM_FLOAT_C_TYPE temp; 1151 1.1 mrg TO_INT_C_TYPE z; 1152 1.1 mrg TO_FIXED_C_TYPE c; 1153 1.1 mrg 1154 1.1 mrg temp = a * BASE; 1155 1.1 mrg z = (TO_INT_C_TYPE) temp; 1156 1.1 mrg #if TO_HAVE_PADDING_BITS 1157 1.1 mrg z = z << TO_PADDING_BITS; 1158 1.1 mrg z = z >> TO_PADDING_BITS; 1159 1.1 mrg #endif 1160 1.1 mrg memcpy (&c, &z, TO_FIXED_SIZE); 1161 1.1 mrg return c; 1162 1.1 mrg } 1163 1.1 mrg #endif /* defined(FRACT) && FROM_TYPE == 3 && TO_TYPE == 4 */ 1164 1.1 mrg 1165 1.1 mrg /* Float -> Fixed with saturation. */ 1166 1.1 mrg #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 3 && TO_TYPE == 4 1167 1.1 mrg TO_FIXED_C_TYPE 1168 1.1 mrg SATFRACT (FROM_FLOAT_C_TYPE a) 1169 1.1 mrg { 1170 1.1 mrg FROM_FLOAT_C_TYPE temp; 1171 1.1 mrg TO_INT_C_TYPE z; 1172 1.1 mrg TO_FIXED_C_TYPE c; 1173 1.1 mrg 1174 1.1 mrg if (a >= FIXED_MAX) 1175 1.1 mrg { 1176 1.1 mrg #if TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS 1177 1.1 mrg z = (TO_INT_C_TYPE)1 << TO_I_F_BITS; 1178 1.1 mrg z = z - 1; 1179 1.1 mrg #else 1180 1.1 mrg z = -1; 1181 1.1 mrg #endif 1182 1.1 mrg } 1183 1.1 mrg else if (a <= FIXED_MIN) 1184 1.1 mrg { 1185 1.1 mrg #if TO_MODE_UNSIGNED == 0 1186 1.1 mrg z = (TO_INT_C_TYPE)1 << TO_I_F_BITS; 1187 1.1 mrg #else 1188 1.1 mrg z = 0; 1189 1.1 mrg #endif 1190 1.1 mrg } 1191 1.1 mrg else 1192 1.1 mrg { 1193 1.1 mrg temp = a * BASE; 1194 1.1 mrg z = (TO_INT_C_TYPE) temp; 1195 1.1 mrg } 1196 1.1 mrg 1197 1.1 mrg #if TO_HAVE_PADDING_BITS 1198 1.1 mrg z = z << TO_PADDING_BITS; 1199 1.1 mrg z = z >> TO_PADDING_BITS; 1200 1.1 mrg #endif 1201 1.1 mrg memcpy (&c, &z, TO_FIXED_SIZE); 1202 1.1 mrg return c; 1203 1.1 mrg } 1204 1.1 mrg #endif /* defined(SATFRACT) && FROM_TYPE == 3 && TO_TYPE == 4 */ 1205 1.1 mrg 1206