fixed-bit.c 28 KB

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