Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4338 lines
136 KiB

  1. /******************************
  2. Intel Confidential
  3. ******************************/
  4. // MACH
  5. #include "ki.h"
  6. #ifndef WIN32_OR_WIN64
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <memory.h>
  10. #endif
  11. #include "fepublic.h"
  12. #include "fehelper.h"
  13. #include "festate.h"
  14. // MACH #ifdef WIN32_OR_WIN64
  15. // MACH #include <process.h>
  16. // MACH #endif
  17. // *************************************************************
  18. // The functions fp_reg_read_hi() and fp_reg_read_lo()
  19. // Take a packed floating-point register,
  20. // Reads the hi (or lo) part
  21. // Returns a register-biased number with implicit made explicit.
  22. // *************************************************************
  23. EM_uint64_t
  24. fp_concatenate(EM_uint_t hi_val, EM_uint_t lo_val) {
  25. return( ((EM_uint64_t)hi_val <<32)
  26. | ((EM_uint64_t)lo_val & CONST_FORMAT(0x00000000FFFFFFFF )) );
  27. }
  28. EM_uint_t
  29. fp_extract_bits(
  30. EM_uint64_t input_value,
  31. unsigned int hi_bound,
  32. unsigned int lo_bound)
  33. {
  34. EM_uint64_t value;
  35. if(lo_bound >63) return(0x00000000);
  36. value = (input_value >> lo_bound) &
  37. ~(CONST_FORMAT(0xFFFFFFFFFFFFFFFF) << (hi_bound - lo_bound + 1));
  38. return((EM_uint_t)value);
  39. }
  40. INLINE EM_fp_reg_type
  41. fp_reg_read_hi(EM_uint_t freg)
  42. {
  43. EM_fp_reg_type tmp_freg = FR[freg];
  44. EM_memory_type mem;
  45. if (freg == 0)
  46. return (FP_ZERO);
  47. else if (freg == 1) {
  48. return (FP_NEG_ZERO);
  49. }
  50. else {
  51. mem.uint_32.uvalue = (EM_uint_t)(tmp_freg.significand >> 32);
  52. tmp_freg = fp_mem_to_fr_format(mem, 4, 0);
  53. return (tmp_freg);
  54. }
  55. }
  56. INLINE EM_fp_reg_type
  57. fp_reg_read_lo(EM_uint_t freg)
  58. {
  59. EM_fp_reg_type tmp_freg = FR[freg];
  60. EM_memory_type mem;
  61. EM_uint64_t tmp_val;
  62. EM_uint_t tmp32_val;
  63. if (freg == 0)
  64. return (FP_ZERO);
  65. else if (freg == 1) {
  66. return (FP_ZERO);
  67. }
  68. else {
  69. tmp_val = (tmp_freg.significand & CONST_FORMAT(0x00000000ffffffff));
  70. tmp32_val = (EM_uint_t)tmp_val;
  71. mem.uint_32.uvalue = tmp32_val;
  72. tmp_freg = fp_mem_to_fr_format(mem, 4, 0);
  73. return (tmp_freg);
  74. }
  75. }
  76. #undef fp_reg_read_hi
  77. #undef fp_reg_read_lo
  78. #define fp_reg_read_hi(f2) fp82_reg_read_hi(ps,f2)
  79. #define fp_reg_read_lo(f3) fp82_reg_read_lo(ps,f3)
  80. // ***********************************************************
  81. // fp_fr_to_mem_format()
  82. // ************************************************************
  83. EM_memory_type
  84. fp_fr_to_mem_format(
  85. EM_fp_reg_type freg,
  86. EM_uint_t size,
  87. EM_uint_t integer_form)
  88. {
  89. EM_memory_type tmp_mem;
  90. EM_uint64_t tmp_significand;
  91. switch(size) {
  92. case 4:
  93. tmp_mem.fp_single.sign = freg.sign;
  94. if (freg.exponent == 0)
  95. tmp_mem.fp_single.exponent = 0;
  96. else if ((freg.significand>>63) == 0)
  97. tmp_mem.fp_single.exponent = 0;
  98. else if (freg.exponent == FP_REG_EXP_ONES)
  99. tmp_mem.fp_single.exponent = FP_SGL_EXP_ONES;
  100. else
  101. tmp_mem.fp_single.exponent =
  102. ((freg.exponent
  103. >> (FP_REG_EXP_WIDTH-1) & 1)
  104. << (FP_SGL_EXP_WIDTH-1))
  105. |( freg.exponent & FP_SGL_BIAS);
  106. tmp_mem.fp_single.significand =
  107. (EM_uint_t)((freg.significand <<1) >>(63-22));
  108. break;
  109. case 8: /* double */
  110. if (integer_form)
  111. tmp_mem.uint_64.uvalue = freg.significand;
  112. else { /* !integer_form */
  113. tmp_mem.fp_double.sign = freg.sign;
  114. if (freg.exponent == 0)
  115. tmp_mem.fp_double.exponent = 0;
  116. else if ((freg.significand>>63) == 0)
  117. tmp_mem.fp_double.exponent = 0;
  118. else if (freg.exponent == FP_REG_EXP_ONES)
  119. tmp_mem.fp_double.exponent = FP_DBL_EXP_ONES;
  120. else
  121. tmp_mem.fp_double.exponent =
  122. ((freg.exponent
  123. >> (FP_REG_EXP_WIDTH-1) & 1)
  124. << (FP_DBL_EXP_WIDTH-1))
  125. |( freg.exponent & FP_DBL_BIAS);
  126. tmp_significand =
  127. (freg.significand <<1) >> (63-51);
  128. tmp_mem.fp_double.significand_hi =
  129. (EM_uint_t)((tmp_significand >> 32) & CONST_FORMAT( 0x00000000ffffffff));
  130. tmp_mem.fp_double.significand_lo =
  131. (EM_uint_t)(tmp_significand & CONST_FORMAT( 0x00000000ffffffff));
  132. }
  133. break;
  134. case 10: /* double extended */
  135. tmp_mem.fp_double_extended.sign = freg.sign;
  136. if (freg.exponent == 0) {
  137. /* Zero or (Pseudo-)Denormal */
  138. tmp_mem.fp_double_extended.exponent = 0;
  139. } else if (freg.exponent == FP_REG_EXP_ONES) {
  140. /* Inf/NaN/NatVAL */
  141. tmp_mem.fp_double_extended.exponent = FP_EXT_EXP_ONES;
  142. } else {
  143. /* Normal or Unnormal */
  144. tmp_mem.fp_double_extended.exponent =
  145. ((freg.exponent
  146. >> (FP_REG_EXP_WIDTH-1) & 1)
  147. << (FP_EXT_EXP_WIDTH-1))
  148. |( freg.exponent & FP_EXT_BIAS);
  149. }
  150. memcpy(tmp_mem.fp_double_extended.significand,
  151. &freg.significand, 8);
  152. break;
  153. case 16: /* spill */
  154. tmp_mem.fp_spill_fill.reserved1 = 0;
  155. tmp_mem.fp_spill_fill.reserved2 = 0;
  156. tmp_mem.fp_spill_fill.sign = freg.sign;
  157. tmp_mem.fp_spill_fill.exponent = freg.exponent;
  158. tmp_mem.fp_spill_fill.significand = freg.significand;
  159. break;
  160. }
  161. return (tmp_mem);
  162. }
  163. INLINE EM_memory_type
  164. fr_to_mem4_bias_adjust(EM_fp_reg_type freg)
  165. {
  166. EM_memory_type tmp_mem;
  167. tmp_mem.fp_single.sign = freg.sign;
  168. if (freg.exponent == 0)
  169. tmp_mem.fp_single.exponent = 0;
  170. else if (freg.exponent == FP_REG_EXP_ONES)
  171. tmp_mem.fp_single.exponent = FP_SGL_EXP_ONES;
  172. else if ((freg.significand>>63) == 0)
  173. tmp_mem.fp_single.exponent = (EM_uint_t)
  174. (((EM_int_t)freg.exponent)
  175. - FP_REG_BIAS + FP_SGL_BIAS - 1);
  176. else
  177. tmp_mem.fp_single.exponent = (EM_uint_t)
  178. (((EM_int_t)freg.exponent)
  179. - FP_REG_BIAS + FP_SGL_BIAS);
  180. tmp_mem.fp_single.significand = (EM_uint_t) (
  181. (freg.significand<<(64-62-1))>>(40+64-62-1));
  182. return (tmp_mem);
  183. }
  184. // *****************************************************
  185. // helper functions definitions
  186. // *****************************************************
  187. INLINE EM_boolean_t
  188. fp_equal(EM_fp_reg_type fr1, EM_fp_reg_type fr2)
  189. {
  190. EM_fp_dp_type fp_dp1;
  191. EM_fp_dp_type fp_dp2;
  192. if ( fp_is_nan(fr1) || fp_is_nan(fr2)
  193. || fp_is_unsupported(fr1) || fp_is_unsupported(fr2) )
  194. return (0);
  195. fp_dp1 = fp_fr_to_dp(fr1);
  196. fp_dp2 = fp_fr_to_dp(fr2);
  197. if ( (fp_dp1.sign == fp_dp2.sign )
  198. && (fp_dp1.exponent == fp_dp2.exponent )
  199. && (fp_dp1.significand.hi == fp_dp2.significand.hi)
  200. && (fp_dp1.significand.lo == fp_dp2.significand.lo) )
  201. return (1);
  202. else if ( fp_is_zero_dp(fp_dp1) && fp_is_zero_dp(fp_dp2) )
  203. return (1);
  204. else
  205. return (0);
  206. }
  207. INLINE EM_boolean_t
  208. fp_less_than(
  209. EM_fp_reg_type fr1,
  210. EM_fp_reg_type fr2)
  211. {
  212. EM_fp_dp_type fp_dp1;
  213. EM_fp_dp_type fp_dp2;
  214. if ( fp_is_nan(fr1) || fp_is_nan(fr2)
  215. || fp_is_unsupported(fr1) || fp_is_unsupported(fr2) )
  216. return (0);
  217. fp_dp1 = fp_fr_to_dp(fr1);
  218. fp_dp2 = fp_fr_to_dp(fr2);
  219. if (fp_is_neg_dp(fp_dp1) && fp_is_pos_dp(fp_dp2)) {
  220. if (!fp_is_zero_dp(fp_dp1) || !fp_is_zero_dp(fp_dp2) )
  221. return (1); /* for non-zero's neg is lt pos */
  222. else
  223. return (0); /* zeros are equal */
  224. } else if (fp_is_pos_dp(fp_dp1) && fp_is_neg_dp(fp_dp2)) {
  225. return (0); /* pos is not lt neg */
  226. } else if (fp_is_neg_dp(fp_dp1) && fp_is_neg_dp(fp_dp2)) {
  227. if (fp_dp1.exponent > fp_dp2.exponent)
  228. return (1); /* fp_dp1 much less than fp_dp2 */
  229. else if ((fp_dp1.exponent == fp_dp2.exponent)
  230. && (fp_U128_gt(fp_dp1.significand, fp_dp2.significand)))
  231. return (1); /* fp_dp1 just less than fp_dp2 */
  232. else
  233. return (0);
  234. } else if (fp_is_pos_dp(fp_dp1) && fp_is_pos_dp(fp_dp2)) {
  235. if (fp_dp1.exponent < fp_dp2.exponent)
  236. return (1); /* fp_dp1 much less than fp_dp2 */
  237. else if ((fp_dp1.exponent == fp_dp2.exponent)
  238. && (fp_U128_lt(fp_dp1.significand, fp_dp2.significand)))
  239. return (1); /* fp_dp1 just less than fp_dp2 */
  240. else
  241. return (0);
  242. } else {
  243. return (0); // MACH ADDED
  244. }
  245. }
  246. INLINE EM_boolean_t
  247. fp_lesser_or_equal(EM_fp_reg_type fr1, EM_fp_reg_type fr2)
  248. {
  249. EM_fp_dp_type fp_dp1;
  250. EM_fp_dp_type fp_dp2;
  251. if ( fp_is_nan(fr1) || fp_is_nan(fr2)
  252. || fp_is_unsupported(fr1) || fp_is_unsupported(fr2) )
  253. return (0);
  254. fp_dp1 = fp_fr_to_dp(fr1);
  255. fp_dp2 = fp_fr_to_dp(fr2);
  256. if (fp_is_neg_dp(fp_dp1) && fp_is_pos_dp(fp_dp2)) {
  257. return (1); /* for non-zero's and zeros's neg is le pos */
  258. } else if (fp_is_pos_dp(fp_dp1) && fp_is_neg_dp(fp_dp2)) {
  259. if (fp_is_zero_dp(fp_dp1) && fp_is_zero_dp(fp_dp2))
  260. return (1); /* zero's are le */
  261. else
  262. return (0); /* pos is not lt neg */
  263. } else if (fp_is_neg_dp(fp_dp1) && fp_is_neg_dp(fp_dp2)) {
  264. if (fp_dp1.exponent > fp_dp2.exponent)
  265. return (1); /* fp_dp1 much less than fp_dp2 */
  266. else if ((fp_dp1.exponent == fp_dp2.exponent)
  267. && (fp_U128_ge(fp_dp1.significand, fp_dp2.significand)))
  268. return (1); /* fp_dp1 just less than or equal fp_dp2 */
  269. else
  270. return (0);
  271. } else if (fp_is_pos_dp(fp_dp1) && fp_is_pos_dp(fp_dp2)) {
  272. if (fp_dp1.exponent < fp_dp2.exponent)
  273. return (1); /* fp_dp1 much less than fp_dp2 */
  274. else if ((fp_dp1.exponent == fp_dp2.exponent)
  275. && (fp_U128_le(fp_dp1.significand, fp_dp2.significand)))
  276. return (1); /* fp_dp1 just less than or equal fp_dp2 */
  277. else
  278. return (0);
  279. } else {
  280. return (0); // MACH ADDED
  281. }
  282. }
  283. INLINE EM_boolean_t
  284. fp_unordered(EM_fp_reg_type fr1, EM_fp_reg_type fr2)
  285. {
  286. if ( fp_is_nan(fr1) || fp_is_nan(fr2)
  287. || fp_is_unsupported(fr1) || fp_is_unsupported(fr2) )
  288. return (1);
  289. else
  290. return (0);
  291. }
  292. EM_uint_t
  293. fp82_fp_decode_fault(EM_tmp_fp_env_type tmp_fp_env)
  294. {
  295. EM_uint_t tmp_ret = 0;
  296. if (!tmp_fp_env.simd) { // MACH ADDED
  297. if (tmp_fp_env.em_faults.swa)
  298. return (8);
  299. else if (tmp_fp_env.em_faults.v)
  300. return (1);
  301. else if (tmp_fp_env.em_faults.z)
  302. return (4);
  303. else if (tmp_fp_env.em_faults.d)
  304. return (2);
  305. else {
  306. tmp_ret = 0;
  307. return (0); // MACH ADDED
  308. }
  309. } else {
  310. // ****************************************************
  311. // hi_faults are recorded in the low four bits of temp_ret.
  312. // lo_faults are recorded in the high four bits of temp_ret.
  313. // ****************************************************
  314. if (tmp_fp_env.hi_faults.swa)
  315. tmp_ret = 8;
  316. else if (tmp_fp_env.hi_faults.v)
  317. tmp_ret = 1;
  318. else if (tmp_fp_env.hi_faults.z)
  319. tmp_ret = 4;
  320. else if (tmp_fp_env.hi_faults.d)
  321. tmp_ret = 2;
  322. if (tmp_fp_env.lo_faults.swa)
  323. tmp_ret |= 8<<4;
  324. else if (tmp_fp_env.lo_faults.v)
  325. tmp_ret |= 1<<4;
  326. else if (tmp_fp_env.lo_faults.z)
  327. tmp_ret |= 4<<4;
  328. else if (tmp_fp_env.lo_faults.d)
  329. tmp_ret |= 2<<4;
  330. return (tmp_ret);
  331. }
  332. }
  333. EM_uint_t
  334. fp82_fp_decode_trap(EM_tmp_fp_env_type tmp_fp_env)
  335. {
  336. EM_uint_t tmp_ret;
  337. if (!tmp_fp_env.simd) {
  338. tmp_ret = (tmp_fp_env.ebc <<15
  339. | tmp_fp_env.fpa <<14
  340. | tmp_fp_env.em_traps.i<<13
  341. | tmp_fp_env.em_traps.un<<12
  342. | tmp_fp_env.em_traps.o<<11 ); // MACH
  343. }
  344. else {
  345. tmp_ret = 0;
  346. if(tmp_fp_env.hi_traps.i ||
  347. tmp_fp_env.hi_traps.un ||
  348. tmp_fp_env.hi_traps.o ) { // MACH
  349. tmp_ret = tmp_fp_env.hi_fpa <<14
  350. | tmp_fp_env.hi_traps.i<<13
  351. | tmp_fp_env.hi_flags.i<<13
  352. | tmp_fp_env.hi_traps.un<<12
  353. | tmp_fp_env.hi_traps.o<<11; // MACH
  354. }
  355. if(tmp_fp_env.lo_traps.i ||
  356. tmp_fp_env.lo_traps.un ||
  357. tmp_fp_env.lo_traps.o ) { // MACH
  358. tmp_ret |= tmp_fp_env.lo_fpa <<10
  359. | tmp_fp_env.lo_traps.i<<9
  360. | tmp_fp_env.lo_flags.i<<9
  361. | tmp_fp_env.lo_traps.un<<8
  362. | tmp_fp_env.lo_traps.o<<7; // MACH
  363. }
  364. }
  365. return (tmp_ret);
  366. }
  367. void
  368. fp_decode_environment(
  369. EM_opcode_pc_type pc,
  370. EM_opcode_sf_type sf,
  371. EM_tmp_fp_env_type *tmp_fp_env)
  372. {
  373. EM_sf_type tmp_sf;
  374. if (sf == sfS0) {
  375. tmp_sf.controls.ftz = FPSR.sf0_controls_ftz;
  376. tmp_sf.controls.wre = FPSR.sf0_controls_wre;
  377. tmp_sf.controls.pc = FPSR.sf0_controls_pc;
  378. tmp_sf.controls.rc = FPSR.sf0_controls_rc;
  379. tmp_sf.controls.td = FPSR.sf0_controls_td;
  380. } else if (sf == sfS1) {
  381. tmp_sf.controls.ftz = FPSR.sf1_controls_ftz;
  382. tmp_sf.controls.wre = FPSR.sf1_controls_wre;
  383. tmp_sf.controls.pc = FPSR.sf1_controls_pc;
  384. tmp_sf.controls.rc = FPSR.sf1_controls_rc;
  385. tmp_sf.controls.td = FPSR.sf1_controls_td;
  386. } else if (sf == sfS2) {
  387. tmp_sf.controls.ftz = FPSR.sf2_controls_ftz;
  388. tmp_sf.controls.wre = FPSR.sf2_controls_wre;
  389. tmp_sf.controls.pc = FPSR.sf2_controls_pc;
  390. tmp_sf.controls.rc = FPSR.sf2_controls_rc;
  391. tmp_sf.controls.td = FPSR.sf2_controls_td;
  392. } else if (sf == sfS3) {
  393. tmp_sf.controls.ftz = FPSR.sf3_controls_ftz;
  394. tmp_sf.controls.wre = FPSR.sf3_controls_wre;
  395. tmp_sf.controls.pc = FPSR.sf3_controls_pc;
  396. tmp_sf.controls.rc = FPSR.sf3_controls_rc;
  397. tmp_sf.controls.td = FPSR.sf3_controls_td;
  398. } else {
  399. tmp_sf.controls.ftz = 0;
  400. tmp_sf.controls.wre = 1;
  401. tmp_sf.controls.pc = sf_double_extended;
  402. tmp_sf.controls.rc = rc_rn;
  403. tmp_sf.controls.td = 1;
  404. }
  405. if (sf == sf_none) {
  406. tmp_fp_env->controls.vd = 0;
  407. tmp_fp_env->controls.dd = 0;
  408. tmp_fp_env->controls.zd = 0;
  409. tmp_fp_env->controls.od = 0;
  410. tmp_fp_env->controls.ud = 0;
  411. tmp_fp_env->controls.id = 0;
  412. } else if (tmp_sf.controls.td ) {
  413. tmp_fp_env->controls.vd = 1;
  414. tmp_fp_env->controls.dd = 1;
  415. tmp_fp_env->controls.zd = 1;
  416. tmp_fp_env->controls.od = 1;
  417. tmp_fp_env->controls.ud = 1;
  418. tmp_fp_env->controls.id = 1;
  419. } else {
  420. tmp_fp_env->controls.vd = FPSR.traps_vd;
  421. tmp_fp_env->controls.dd = FPSR.traps_dd;
  422. tmp_fp_env->controls.zd = FPSR.traps_zd;
  423. tmp_fp_env->controls.od = FPSR.traps_od;
  424. tmp_fp_env->controls.ud = FPSR.traps_ud;
  425. tmp_fp_env->controls.id = FPSR.traps_id;
  426. }
  427. if (pc == pc_none) {
  428. tmp_fp_env->ss = ss_double_extended_64;
  429. tmp_fp_env->es = es_seventeen_bits;
  430. tmp_fp_env->simd = 0;
  431. } else if (pc == pc_simd) {
  432. tmp_fp_env->ss = ss_single_24;
  433. tmp_fp_env->es = es_eight_bits;
  434. tmp_fp_env->simd = 1;
  435. if (tmp_sf.controls.wre)
  436. tmp_sf.controls.wre = 0;
  437. tmp_fp_env->hi_flags.v = 0;
  438. tmp_fp_env->hi_flags.d = 0;
  439. tmp_fp_env->hi_flags.z = 0;
  440. tmp_fp_env->hi_flags.o = 0;
  441. tmp_fp_env->hi_flags.un = 0;
  442. tmp_fp_env->hi_flags.i = 0;
  443. tmp_fp_env->lo_flags.v = 0;
  444. tmp_fp_env->lo_flags.d = 0;
  445. tmp_fp_env->lo_flags.z = 0;
  446. tmp_fp_env->lo_flags.o = 0;
  447. tmp_fp_env->lo_flags.un = 0;
  448. tmp_fp_env->lo_flags.i = 0;
  449. } else if (pc == pc_s) {
  450. tmp_fp_env->ss = ss_single_24;
  451. tmp_fp_env->simd = 0;
  452. if (tmp_sf.controls.wre)
  453. tmp_fp_env->es = es_seventeen_bits;
  454. else
  455. tmp_fp_env->es = es_eight_bits;
  456. } else if (pc == pc_d) {
  457. tmp_fp_env->ss = ss_double_53;
  458. tmp_fp_env->simd = 0;
  459. if (tmp_sf.controls.wre)
  460. tmp_fp_env->es = es_seventeen_bits;
  461. else
  462. tmp_fp_env->es = es_eleven_bits;
  463. } else if (pc == pc_sf) {
  464. tmp_fp_env->simd = 0;
  465. if (tmp_sf.controls.pc == sf_single)
  466. tmp_fp_env->ss = ss_single_24;
  467. else if (tmp_sf.controls.pc == sf_double)
  468. tmp_fp_env->ss = ss_double_53;
  469. else if (tmp_sf.controls.pc == sf_double_extended)
  470. tmp_fp_env->ss = ss_double_extended_64;
  471. if (tmp_sf.controls.wre)
  472. tmp_fp_env->es = es_seventeen_bits;
  473. else
  474. tmp_fp_env->es = es_fifteen_bits;
  475. }
  476. if (sf == sf_none) {
  477. tmp_fp_env->rc = rc_rz;
  478. tmp_fp_env->ftz = 0;
  479. } else {
  480. tmp_fp_env->rc = tmp_sf.controls.rc;
  481. tmp_fp_env->ftz = tmp_sf.controls.ftz && tmp_fp_env->controls.ud;
  482. }
  483. tmp_fp_env->flags.v = 0;
  484. tmp_fp_env->flags.d = 0;
  485. tmp_fp_env->flags.z = 0;
  486. tmp_fp_env->flags.o = 0;
  487. tmp_fp_env->flags.un = 0;
  488. tmp_fp_env->flags.i = 0;
  489. tmp_fp_env->ebc = 0;
  490. tmp_fp_env->mdl = 0;
  491. tmp_fp_env->mdh = 0;
  492. tmp_fp_env->em_faults.v = 0;
  493. tmp_fp_env->em_faults.d = 0;
  494. tmp_fp_env->em_faults.z = 0;
  495. tmp_fp_env->em_faults.swa = 0;
  496. tmp_fp_env->em_traps.i = 0;
  497. tmp_fp_env->em_traps.o = 0;
  498. tmp_fp_env->em_traps.un = 0;
  499. tmp_fp_env->fpa = 0;
  500. tmp_fp_env->hi_faults.v = 0;
  501. tmp_fp_env->hi_faults.d = 0;
  502. tmp_fp_env->hi_faults.z = 0;
  503. tmp_fp_env->hi_faults.swa = 0;
  504. tmp_fp_env->hi_traps.i = 0;
  505. tmp_fp_env->hi_traps.o = 0;
  506. tmp_fp_env->hi_traps.un = 0;
  507. tmp_fp_env->hi_fpa = 0;
  508. tmp_fp_env->lo_faults.v = 0;
  509. tmp_fp_env->lo_faults.d = 0;
  510. tmp_fp_env->lo_faults.z = 0;
  511. tmp_fp_env->lo_faults.swa = 0;
  512. tmp_fp_env->lo_traps.i = 0;
  513. tmp_fp_env->lo_traps.o = 0;
  514. tmp_fp_env->lo_traps.un = 0;
  515. tmp_fp_env->lo_fpa = 0;
  516. return;
  517. }
  518. #undef fp_decode_environment
  519. #define fp_decode_environment(arg1, arg2, arg3) \
  520. fp82_fp_decode_environment(ps, arg1, arg2, arg3)
  521. // ****************************************************
  522. // Returns
  523. // 1: if a specified register is <= disabled limit and dfl is 1
  524. // 0: if a specified register is > disabled limit and dfh is 1
  525. // The disabled limit is 31 after ACR106.
  526. // *****************************************************
  527. EM_uint_t
  528. fp_reg_disabled(
  529. EM_uint_t f1,
  530. EM_uint_t f2,
  531. EM_uint_t f3,
  532. EM_uint_t f4)
  533. {
  534. EM_uint_t tmp_ret;
  535. EM_uint_t disabled_limit;
  536. tmp_ret=0;
  537. disabled_limit = 31;
  538. if ( ((f1 >= 2) && (f1 <=disabled_limit) && (PSR.dfl))
  539. || ((f2 >= 2) && (f2 <=disabled_limit) && (PSR.dfl))
  540. || ((f3 >= 2) && (f3 <=disabled_limit) && (PSR.dfl))
  541. || ((f4 >= 2) && (f4 <=disabled_limit) && (PSR.dfl))
  542. )
  543. tmp_ret |= (1<<0);
  544. if ( ((f1 > disabled_limit) && (f1 <= 127) && (PSR.dfh))
  545. || ((f2 > disabled_limit) && (f2 <= 127) && (PSR.dfh))
  546. || ((f3 > disabled_limit) && (f3 <= 127) && (PSR.dfh))
  547. || ((f4 > disabled_limit) && (f4 <= 127) && (PSR.dfh))
  548. )
  549. tmp_ret |= (1<<1);
  550. return(tmp_ret);
  551. }
  552. INLINE EM_boolean_t
  553. fp_is_nan_or_inf(EM_fp_reg_type tmp_res)
  554. {
  555. if (fp_is_nan(tmp_res) || fp_is_inf(tmp_res))
  556. return (1);
  557. else
  558. return (0);
  559. }
  560. INLINE EM_fp_reg_type
  561. fp_dp_to_fr(EM_fp_dp_type tmp_res)
  562. {
  563. EM_fp_reg_type tmp_ret;
  564. /* MACH FIX CMPLR BUG tmp_ret.sign = tmp_res.sign; */
  565. if (tmp_res.exponent == FP_DP_EXP_ONES)
  566. tmp_ret.exponent = FP_REG_EXP_ONES;
  567. else if (tmp_res.exponent == 0)
  568. tmp_ret.exponent = 0;
  569. else
  570. tmp_ret.exponent = (EM_uint_t)(((EM_int_t)tmp_res.exponent)
  571. - FP_DP_BIAS + FP_REG_BIAS);
  572. tmp_ret.sign = tmp_res.sign; /* MACH FIX CMPLR BUG */
  573. tmp_ret.significand = tmp_res.significand.hi;
  574. return (tmp_ret);
  575. }
  576. // ***************************************************************
  577. // fp_add()
  578. // Adds a dp value to an freg value
  579. // Returns a dp value
  580. // ***************************************************************
  581. INLINE EM_fp_dp_type
  582. fp_add(EM_fp_dp_type fp_dp, EM_fp_reg_type fr2, EM_tmp_fp_env_type tmp_fp_env)
  583. // fp_dp has been normalized and fr2 may not be normalized
  584. {
  585. EM_fp_dp_type tmp_res;
  586. EM_uint256_t tmp_a, tmp_b, tmp_c;
  587. EM_int_t exp_diff;
  588. EM_uint_t normalize_count;
  589. // all cases which might have faulted have been screened out
  590. // we still may trap on overflow, underflow and/or inexact later
  591. if (fp_is_zero_dp(fp_dp) && (fp_is_zero(fr2) || fp_is_pseudo_zero(fr2))) {
  592. /* correctly signed zero */
  593. tmp_res = fp_fr_to_dp(FP_ZERO);
  594. if (fp_dp.sign == fr2.sign) {
  595. tmp_res.sign = fr2.sign;
  596. } else if (tmp_fp_env.rc == rc_rm) {
  597. tmp_res.sign = 1;
  598. } else {
  599. tmp_res.sign = 0;
  600. }
  601. return(tmp_res);
  602. } else if (fp_is_inf_dp(fp_dp)) {
  603. /* correctly signed infinity */
  604. return(fp_dp);
  605. } else if (fp_is_inf(fr2)) {
  606. /* correctly signed infinity */
  607. return(fp_fr_to_dp(fr2));
  608. } else if( fp_is_zero_dp(fp_dp)) {
  609. return(fp_fr_to_dp(fr2));
  610. } else if( fp_is_zero(fr2) || fp_is_pseudo_zero(fr2) ) {
  611. return(fp_dp);
  612. } else {
  613. /* we have non-all-zeros and non-all-ones exponents in both operands */
  614. exp_diff = (((EM_int_t)fp_dp.exponent) - FP_DP_BIAS )
  615. - (((EM_int_t)fr2.exponent) - FP_REG_BIAS);
  616. tmp_res.sign = fp_dp.sign;
  617. tmp_a = fp_U128_to_U256(fp_dp.significand);
  618. tmp_a = fp_U256_lsh(tmp_a,64);
  619. tmp_b = fp_U64_to_U256(fr2.significand);
  620. tmp_b = fp_U256_lsh(tmp_b,128);
  621. if (exp_diff >= 0) {
  622. tmp_res.exponent = fp_dp.exponent;
  623. tmp_c = fp_U256_rsh(tmp_b,exp_diff);
  624. tmp_res.sticky = !fp_U256_eq(tmp_b,fp_U256_lsh(tmp_c,exp_diff));
  625. tmp_b = tmp_c;
  626. if(fp_dp.sign != fr2.sign) {
  627. /* add sticky */
  628. if (tmp_res.sticky)
  629. tmp_b = fp_U256_inc(tmp_b);
  630. if (fp_dp.sign)
  631. tmp_a = fp_U256_neg(tmp_a);
  632. if (fr2.sign)
  633. tmp_b = fp_U256_neg(tmp_b);
  634. }
  635. } else {
  636. tmp_res.exponent = fp_dp.exponent - exp_diff;
  637. tmp_c = fp_U256_rsh(tmp_a,-exp_diff);
  638. tmp_res.sticky = !fp_U256_eq(tmp_a,fp_U256_lsh(tmp_c,-exp_diff));
  639. tmp_a = tmp_c;
  640. if(fp_dp.sign != fr2.sign) {
  641. /* add sticky */
  642. if (tmp_res.sticky)
  643. tmp_a = fp_U256_inc(tmp_a);
  644. if (fp_dp.sign)
  645. tmp_a = fp_U256_neg(tmp_a);
  646. if (fr2.sign)
  647. tmp_b = fp_U256_neg(tmp_b);
  648. }
  649. }
  650. tmp_c = fp_U256_add(tmp_a, tmp_b);
  651. if (fp_dp.sign != fr2.sign) {
  652. if (tmp_c.hh != 0) {
  653. tmp_res.sign = 1;
  654. tmp_c = fp_U256_neg(tmp_c);
  655. } else {
  656. tmp_res.sign = 0;
  657. }
  658. }
  659. if (!fp_U256_eq(tmp_c,U256_0)) {
  660. normalize_count = fp_U256_lead0(tmp_c);
  661. tmp_res.exponent -= (normalize_count - 64);
  662. tmp_res.significand = fp_U256_to_U128(
  663. fp_U256_rsh(
  664. fp_U256_lsh(tmp_c, normalize_count),
  665. 128
  666. )
  667. );
  668. if(normalize_count > 128) {
  669. tmp_res.sticky |= !fp_U256_eq(
  670. fp_U256_rsh(
  671. fp_U128_to_U256(tmp_res.significand),
  672. normalize_count-128
  673. ),
  674. tmp_c
  675. );
  676. } else {
  677. tmp_res.sticky |= !fp_U256_eq(
  678. fp_U256_lsh(
  679. fp_U128_to_U256(tmp_res.significand),
  680. 128-normalize_count
  681. ),
  682. tmp_c
  683. );
  684. }
  685. } else {
  686. if (fp_dp.sign == fr2.sign)
  687. tmp_res.sign = fp_dp.sign;
  688. else if (tmp_fp_env.rc == rc_rm)
  689. tmp_res.sign = 1;
  690. else
  691. tmp_res.sign = 0;
  692. tmp_res.exponent = 0;
  693. tmp_res.significand = U128_0;
  694. }
  695. return(tmp_res);
  696. }
  697. }
  698. // *******************************************************************
  699. // IEEE rounds
  700. // *******************************************************************
  701. INLINE EM_uint_t
  702. fp_single(EM_fp_reg_type freg)
  703. {
  704. EM_memory_type tmp_mem;
  705. tmp_mem = fp_fr_to_mem_format(freg, 4, 0);
  706. return (tmp_mem.uint_32.uvalue);
  707. }
  708. INLINE void
  709. fp_ieee_to_hilo(
  710. EM_simd_hilo hilo,
  711. EM_tmp_fp_env_type *tmp_fp_env)
  712. {
  713. if(hilo == high) {
  714. tmp_fp_env->hi_flags.o = tmp_fp_env->flags.o;
  715. tmp_fp_env->flags.o = 0;
  716. tmp_fp_env->hi_flags.un = tmp_fp_env->flags.un; // MACH
  717. tmp_fp_env->flags.un = 0; // MACH
  718. tmp_fp_env->hi_flags.i = tmp_fp_env->flags.i;
  719. tmp_fp_env->flags.i = 0;
  720. tmp_fp_env->hi_traps.o = tmp_fp_env->em_traps.o;
  721. tmp_fp_env->em_traps.o = 0;
  722. tmp_fp_env->hi_traps.un = tmp_fp_env->em_traps.un; // MACH
  723. tmp_fp_env->em_traps.un = 0; // MACH
  724. tmp_fp_env->hi_traps.i = tmp_fp_env->em_traps.i;
  725. tmp_fp_env->em_traps.i = 0;
  726. tmp_fp_env->hi_faults.d = tmp_fp_env->em_faults.d;
  727. tmp_fp_env->em_faults.d = 0;
  728. tmp_fp_env->hi_faults.z = tmp_fp_env->em_faults.z;
  729. tmp_fp_env->em_faults.z = 0;
  730. tmp_fp_env->hi_faults.v = tmp_fp_env->em_faults.v;
  731. tmp_fp_env->em_faults.v = 0;
  732. tmp_fp_env->hi_fpa = tmp_fp_env->fpa;
  733. tmp_fp_env->fpa = 0;
  734. } else {
  735. tmp_fp_env->lo_flags.o = tmp_fp_env->flags.o;
  736. tmp_fp_env->flags.o = 0;
  737. tmp_fp_env->lo_flags.un = tmp_fp_env->flags.un; // MACH
  738. tmp_fp_env->flags.un = 0; // MACH
  739. tmp_fp_env->lo_flags.i = tmp_fp_env->flags.i;
  740. tmp_fp_env->flags.i = 0;
  741. tmp_fp_env->lo_traps.o = tmp_fp_env->em_traps.o;
  742. tmp_fp_env->em_traps.o = 0;
  743. tmp_fp_env->lo_traps.un = tmp_fp_env->em_traps.un; // MACH
  744. tmp_fp_env->em_traps.un = 0; // MACH
  745. tmp_fp_env->lo_traps.i = tmp_fp_env->em_traps.i;
  746. tmp_fp_env->em_traps.i = 0;
  747. tmp_fp_env->lo_faults.d = tmp_fp_env->em_faults.d;
  748. tmp_fp_env->em_faults.d = 0;
  749. tmp_fp_env->lo_faults.z = tmp_fp_env->em_faults.z;
  750. tmp_fp_env->em_faults.z = 0;
  751. tmp_fp_env->lo_faults.v = tmp_fp_env->em_faults.v;
  752. tmp_fp_env->em_faults.v = 0;
  753. tmp_fp_env->lo_fpa = tmp_fp_env->fpa;
  754. tmp_fp_env->fpa = 0;
  755. }
  756. }
  757. EM_fp_reg_type
  758. fp_ieee_round(
  759. EM_fp_dp_type fp_dp,
  760. EM_tmp_fp_env_type *tmp_fp_env)
  761. {
  762. const EM_uint_t FPA[64] = {
  763. 0,0,0,1,
  764. 0,0,1,1,
  765. 0,0,0,1,
  766. 0,0,1,1, /* Nearest */
  767. 0,0,0,0,
  768. 0,0,0,0,
  769. 0,1,1,1,
  770. 0,1,1,1, /* -inf */
  771. 0,1,1,1,
  772. 0,1,1,1,
  773. 0,0,0,0,
  774. 0,0,0,0, /* +inf */
  775. 0,0,0,0,
  776. 0,0,0,0,
  777. 0,0,0,0,
  778. 0,0,0,0, /* Zero */
  779. };
  780. EM_fp_reg_type tmp_rtn;
  781. EM_fp_dp_type tmp_res, tmp_unbounded_round;
  782. EM_int_t cnt, tmp_shift;
  783. EM_uint_t e_max, e_min,
  784. tmp_unbounded_ebc = 0, tmp_unbounded_fpa = 0;
  785. EM_uint128_t significand_mask;
  786. EM_uint128_t significand_even;
  787. EM_uint128_t significand_round;
  788. EM_uint128_t significand_not_mask;
  789. EM_uint128_t significand_sticky;
  790. /************************************************
  791. SETUP
  792. set e_max, e_min
  793. Note that the exponents are still dp-biased.
  794. *************************************************/
  795. if (tmp_fp_env->es == es_eight_bits) {
  796. e_max = FP_DP_BIAS + FP_SGL_BIAS;
  797. e_min = FP_DP_BIAS - FP_SGL_BIAS + 1;
  798. } else if (tmp_fp_env->es == es_eleven_bits) {
  799. e_max = FP_DP_BIAS + FP_DBL_BIAS;
  800. e_min = FP_DP_BIAS - FP_DBL_BIAS + 1;
  801. } else if (tmp_fp_env->es == es_fifteen_bits) {
  802. e_max = FP_DP_BIAS + FP_EXT_BIAS;
  803. e_min = FP_DP_BIAS - FP_EXT_BIAS + 1;
  804. } else if (tmp_fp_env->es == es_seventeen_bits) {
  805. e_max = FP_DP_BIAS + FP_REG_BIAS;
  806. e_min = FP_DP_BIAS - FP_REG_BIAS + 1;
  807. }
  808. /************************************************
  809. SETUP
  810. set significand_mask, significand_even, significand_round
  811. significand_not_mask, significand_sticky
  812. *************************************************/
  813. if( tmp_fp_env->ss == ss_single_24) {
  814. significand_mask = U128_0xFFFFFF00000000000000000000000000;
  815. significand_even = U128_0x00000100000000000000000000000000;
  816. significand_round = U128_0x00000080000000000000000000000000;
  817. significand_not_mask = U128_0x000000FFFFFFFFFFFFFFFFFFFFFFFFFF;
  818. significand_sticky = U128_0x0000007FFFFFFFFFFFFFFFFFFFFFFFFF;
  819. } else if( tmp_fp_env->ss == ss_double_53) {
  820. significand_mask = U128_0xFFFFFFFFFFFFF8000000000000000000;
  821. significand_even = U128_0x00000000000008000000000000000000;
  822. significand_round = U128_0x00000000000004000000000000000000;
  823. significand_not_mask = U128_0x00000000000007FFFFFFFFFFFFFFFFFF;
  824. significand_sticky = U128_0x00000000000003FFFFFFFFFFFFFFFFFF;
  825. } else if( tmp_fp_env->ss == ss_double_extended_64) {
  826. significand_mask = U128_0xFFFFFFFFFFFFFFFF0000000000000000;
  827. significand_even = U128_0x00000000000000010000000000000000;
  828. significand_round = U128_0x00000000000000008000000000000000;
  829. significand_not_mask = U128_0x0000000000000000FFFFFFFFFFFFFFFF;
  830. significand_sticky = U128_0x00000000000000007FFFFFFFFFFFFFFF;
  831. }
  832. /***************************************************
  833. INPUT CHECK
  834. Inf?
  835. ****************************************************/
  836. if ( fp_is_inf_dp(fp_dp) ) {
  837. tmp_res = fp_dp;
  838. tmp_res.significand = fp_U128_band(tmp_res.significand,
  839. significand_mask);
  840. tmp_rtn = fp_dp_to_fr(tmp_res);
  841. return(tmp_rtn);
  842. /***************************************************
  843. INPUT CHECK
  844. Nan?
  845. ****************************************************/
  846. } else if ( fp_is_nan_dp(fp_dp) ) {
  847. tmp_res = fp_dp;
  848. tmp_res.significand = fp_U128_band(tmp_res.significand,
  849. significand_mask);
  850. tmp_rtn = fp_dp_to_fr(tmp_res);
  851. return(tmp_rtn);
  852. /***************************************************
  853. INPUT CHECK
  854. Zero?
  855. ****************************************************/
  856. } else if ( fp_is_zero_dp(fp_dp) ) {
  857. if ( (fp_dp.sticky) && (tmp_fp_env->rc == rc_rm) )
  858. tmp_rtn.sign = 1;
  859. else if ( (fp_dp.sticky) && (tmp_fp_env->rc != rc_rm) )
  860. tmp_rtn.sign = 0;
  861. else
  862. tmp_rtn.sign = fp_dp.sign;
  863. tmp_rtn.exponent = fp_dp.exponent;
  864. tmp_rtn.significand = 0;
  865. return(tmp_rtn);
  866. /******************************************************
  867. INPUT CHECK
  868. Answer is finite and non-zero.
  869. *******************************************************/
  870. } else {
  871. tmp_res.sign = fp_dp.sign;
  872. tmp_res.exponent = fp_dp.exponent;
  873. tmp_res.sticky = fp_dp.sticky;
  874. /******************************************************
  875. UNBOUNDED SETUP
  876. Set cnt -- depends on rounding control, +/-, even/odd, round?, sticky?
  877. Set sticky to be either round or sticky
  878. *******************************************************/
  879. cnt = (tmp_fp_env->rc<<4) | (fp_dp.sign<<3);
  880. cnt |= !fp_U128_eq(U128_0, fp_U128_band(fp_dp.significand,
  881. /* even */ significand_even)) << 2;
  882. cnt |= !fp_U128_eq(U128_0, fp_U128_band(fp_dp.significand,
  883. /* round */ significand_round)) << 1;
  884. tmp_res.sticky |= !fp_U128_eq(U128_0, fp_U128_band(fp_dp.significand,
  885. /* sticky */ significand_sticky));
  886. cnt |= tmp_res.sticky;
  887. tmp_res.sticky |= ((cnt&2) != 0); /* round and sticky */
  888. /*************************************************************************
  889. UNBOUNDED ROUNDING
  890. If necessary, round the significand
  891. This is the FIRST (or UNBOUNDED) rounding
  892. If rounding the significand results in a carry out of
  893. the significand, inc exponent and set significand to 10..0
  894. else
  895. mask out lower bits of significand
  896. **************************************************************************/
  897. if (FPA[cnt]) {
  898. tmp_res.significand = fp_U128_bor(fp_dp.significand,
  899. significand_not_mask);
  900. tmp_res.significand = fp_U128_inc(tmp_res.significand);
  901. if ( fp_U128_eq(tmp_res.significand, U128_0) ) { /* carry out */
  902. tmp_res.exponent++;
  903. tmp_res.significand = U128_0x80000000000000000000000000000000;
  904. }
  905. } else {
  906. tmp_res.significand = fp_U128_band(fp_dp.significand,
  907. significand_mask);
  908. }
  909. /*************************************************************************
  910. UNBOUNDED ROUNDING
  911. If significand = 0, set exponent to 0.
  912. CAN THIS EVER HAPPEN IF tmp_res IS NORMALIZED?
  913. **************************************************************************/
  914. if ( fp_U128_eq(tmp_res.significand, U128_0) ) { /* underflow -> zero */
  915. tmp_res.exponent = 0;
  916. }
  917. /*************************************************************************
  918. UNBOUNDED
  919. Save the result of the FIRST ROUNDING in tmp_unbounded_round.
  920. Then, set i flag.
  921. **************************************************************************/
  922. tmp_unbounded_round.sign = tmp_res.sign;
  923. tmp_unbounded_round.significand = tmp_res.significand;
  924. tmp_unbounded_round.exponent = tmp_res.exponent;
  925. tmp_unbounded_round.sticky = tmp_res.sticky;
  926. tmp_unbounded_fpa = FPA[cnt];
  927. if ( ((tmp_unbounded_round.exponent>>17)&1)
  928. ^ ((tmp_unbounded_round.exponent>>16)&1)
  929. )
  930. tmp_unbounded_ebc = 1;
  931. tmp_fp_env->flags.i = tmp_res.sticky;
  932. /************************************************************
  933. HUGE
  934. if HUGE, set o_flag;
  935. if o traps enabled, also set o_trap, ebc, fpa
  936. then if i_flag set, set i_trap and
  937. return tmp_unbounded_round with mod17 exponent;
  938. the fp_dp_to_fr() mods the exponent.
  939. (sometimes inappropriately called the wrapped value)
  940. else set set tmp_res to max or inf, set i_flag
  941. if i traps enabled, set i_trap, fpa
  942. return tmp_res
  943. *************************************************************/
  944. if ( tmp_res.exponent > e_max ) { /* huge */
  945. tmp_fp_env->flags.o = 1;
  946. if ( !tmp_fp_env->controls.od) {
  947. tmp_fp_env->ebc = tmp_unbounded_ebc;
  948. tmp_fp_env->fpa = tmp_unbounded_fpa;
  949. tmp_fp_env->em_traps.o = 1;
  950. if(tmp_fp_env->flags.i) {
  951. tmp_fp_env->em_traps.i = 1;
  952. }
  953. return(fp_dp_to_fr(tmp_unbounded_round));
  954. } else {
  955. tmp_res = fp_max_or_infinity(fp_dp.sign, tmp_fp_env,
  956. e_max, significand_mask);
  957. tmp_fp_env->flags.i = 1;
  958. /****************************************************************
  959. The IEEE standard specifies (7.5) that if you overflow without enabling
  960. O traps, then inexact is always set. Hence, the above assignment.
  961. *****************************************************************/
  962. if ( !tmp_fp_env->controls.id ) {
  963. tmp_fp_env->em_traps.i = 1;
  964. tmp_fp_env->fpa = fp_is_inf_dp(tmp_res);
  965. tmp_fp_env->ebc = 0;
  966. }
  967. return(fp_dp_to_fr(tmp_res));
  968. }
  969. /************************************************************
  970. TINY
  971. If MERCED_RTL, return unbounded, rounded result with mod17 exponent
  972. *************************************************************/
  973. } else if ( tmp_res.exponent < e_min ) { /* tiny */
  974. /************************************************************
  975. TINY
  976. Undo the rounding.
  977. *************************************************************/
  978. tmp_res.sign = fp_dp.sign;
  979. tmp_res.exponent = fp_dp.exponent;
  980. tmp_res.sticky = fp_dp.sticky;
  981. /************************************************************
  982. TINY
  983. Calculate the shift to bring exponent to e_min
  984. if shift >=128 and significand is not zero,
  985. set sticky and clear significand
  986. else
  987. do the shift and set sticky if lost bits from significand
  988. *************************************************************/
  989. tmp_shift = ((EM_int_t)e_min) - ((EM_int_t)fp_dp.exponent);
  990. tmp_res.exponent += tmp_shift;
  991. if (tmp_shift >= 128) {
  992. tmp_res.sticky |= !fp_U128_eq( fp_dp.significand, U128_0);
  993. tmp_res.significand = U128_0;
  994. } else {
  995. tmp_res.sticky |= !fp_U128_eq( U128_0,
  996. fp_U128_lsh(
  997. fp_dp.significand,
  998. (128-tmp_shift)));
  999. tmp_res.significand = fp_U128_rsh(fp_dp.significand,
  1000. tmp_shift);
  1001. }
  1002. /******************************************************
  1003. TINY SETUP
  1004. Set cnt -- depends on rounding control, +/-, even/odd, round?, sticky?
  1005. Set sticky to be either round or sticky
  1006. *******************************************************/
  1007. cnt = (tmp_fp_env->rc<<4) | (tmp_res.sign<<3);
  1008. /* even */
  1009. cnt |= !fp_U128_eq(U128_0, fp_U128_band(tmp_res.significand,
  1010. significand_even)) << 2;
  1011. /* round */
  1012. cnt |= !fp_U128_eq(U128_0, fp_U128_band(tmp_res.significand,
  1013. significand_round)) << 1;
  1014. /* sticky */
  1015. tmp_res.sticky |= !fp_U128_eq(U128_0, fp_U128_band(tmp_res.significand,
  1016. significand_sticky));
  1017. cnt |= tmp_res.sticky;
  1018. tmp_res.sticky |= ((cnt&2) != 0); /* round and sticky */
  1019. /*************************************************************************
  1020. TINY ROUNDING -- answer is in tmp_res
  1021. If necessary, round the significand
  1022. This is the SECOND (as opposed to the FIRST or UNBOUNDED) rounding
  1023. If rounding the significand results in a carry out of
  1024. the significand, inc exponent and set significand to 10..0
  1025. else
  1026. mask out lower bits of significand
  1027. **************************************************************************/
  1028. if (FPA[cnt]) {
  1029. tmp_res.significand = fp_U128_bor(tmp_res.significand,
  1030. significand_not_mask);
  1031. tmp_res.significand = fp_U128_inc(tmp_res.significand);
  1032. if ( fp_U128_eq(tmp_res.significand, U128_0) ) { /* carry out */
  1033. tmp_res.exponent++;
  1034. tmp_res.significand =
  1035. U128_0x80000000000000000000000000000000;
  1036. }
  1037. } else {
  1038. tmp_res.significand = fp_U128_band(tmp_res.significand,
  1039. significand_mask);
  1040. }
  1041. /******************************************************
  1042. TINY ROUNDING
  1043. If significand = 0, set exponent to 0.
  1044. Then, or in new sticky to the i flag
  1045. *******************************************************/
  1046. if ( fp_U128_eq(tmp_res.significand, U128_0) ) { /* underflow to 0 */
  1047. tmp_res.exponent = 0;
  1048. }
  1049. tmp_fp_env->flags.i |= tmp_res.sticky;
  1050. /******************************************************
  1051. TINY
  1052. Set underflow, if inexact.
  1053. *******************************************************/
  1054. if( tmp_fp_env->flags.i )
  1055. tmp_fp_env->flags.un = 1; /* tiny and inexact */ // MACH
  1056. /******************************************************
  1057. TINY
  1058. If u traps enabled,
  1059. set u_flag, u_trap, ebc, fpa, and possibly i_trap
  1060. return unbounded result with mod17 exponent;
  1061. the fp_dp_to_fr() mods the exponent.
  1062. else
  1063. if ftz
  1064. set i_flag, set u_flag, clear ebc, clear fpa
  1065. if inexact set i_trap
  1066. else
  1067. if inexact trap and inexact
  1068. set fpa, set i_trap
  1069. set tmp_rtn (freg) to tmp_res (fp_dp).
  1070. tmp_rtn now has the result of the SECOND rounding.
  1071. Do not return tmp_res yet, because we may have to
  1072. make a canonical double_ext denormal.
  1073. *******************************************************/
  1074. tmp_fp_env->fpa = FPA[cnt];
  1075. if (!tmp_fp_env->controls.ud) {
  1076. tmp_fp_env->flags.un = 1; // MACH
  1077. tmp_fp_env->em_traps.un = 1; // MACH
  1078. tmp_fp_env->ebc = tmp_unbounded_ebc;
  1079. tmp_fp_env->fpa = tmp_unbounded_fpa;
  1080. tmp_fp_env->flags.i = tmp_unbounded_round.sticky;
  1081. if(tmp_fp_env->flags.i) {
  1082. tmp_fp_env->em_traps.i = 1;
  1083. }
  1084. return(fp_dp_to_fr(tmp_unbounded_round));
  1085. }
  1086. else {
  1087. if (tmp_fp_env->ftz) {
  1088. tmp_res.exponent = 0;
  1089. tmp_res.significand = U128_0;
  1090. tmp_res.sticky = 1;
  1091. tmp_fp_env->flags.i = 1;
  1092. tmp_fp_env->flags.un = 1; // MACH
  1093. tmp_fp_env->ebc = 0;
  1094. tmp_fp_env->fpa = 0;
  1095. if (!tmp_fp_env->controls.id) {
  1096. tmp_fp_env->em_traps.i = 1;
  1097. }
  1098. }
  1099. else {
  1100. if (!tmp_fp_env->controls.id && tmp_fp_env->flags.i) {
  1101. tmp_fp_env->fpa = FPA[cnt];
  1102. tmp_fp_env->em_traps.i = 1;
  1103. }
  1104. }
  1105. }
  1106. tmp_rtn = fp_dp_to_fr(tmp_res);
  1107. /******************************************************
  1108. TINY
  1109. if double_extended, set tmp_rtn to canonical denormal
  1110. return result of SECOND ROUNDING
  1111. *******************************************************/
  1112. if ( (tmp_fp_env->es == es_fifteen_bits)
  1113. && (tmp_rtn.exponent == 0x0C001)
  1114. &&((tmp_rtn.significand & U64_0x8000000000000000) == 0) ) {
  1115. /* canonical double-extended denormal */
  1116. tmp_rtn.exponent = 0x00000;
  1117. }
  1118. return(tmp_rtn);
  1119. /******************************************************
  1120. NOT HUGE, NOT TINY
  1121. if i traps enabled and i flag, set i_trap
  1122. set fpa
  1123. *******************************************************/
  1124. } else {
  1125. if (!tmp_fp_env->controls.id && tmp_fp_env->flags.i) {
  1126. tmp_fp_env->fpa = tmp_unbounded_fpa;
  1127. tmp_fp_env->em_traps.i = 1;
  1128. }
  1129. tmp_rtn = fp_dp_to_fr(tmp_unbounded_round);
  1130. /******************************************************
  1131. NOT HUGE, NOT TINY
  1132. if double_extended, set tmp_rtn to canonical denormal
  1133. return result of FIRST rounding
  1134. *******************************************************/
  1135. if ( (tmp_fp_env->es == es_fifteen_bits)
  1136. && (tmp_rtn.exponent == 0x0C001)
  1137. &&((tmp_rtn.significand & U64_0x8000000000000000) == 0) ) {
  1138. /* canonical double-extended denormal */
  1139. tmp_rtn.exponent = 0x00000;
  1140. }
  1141. return(tmp_rtn);
  1142. } /* end of not huge, not tiny */
  1143. } /* end of infinitely precise and nonzero */
  1144. }
  1145. #undef fp_ieee_round
  1146. #define fp_ieee_round(arg1, arg2) fp82_fp_ieee_round(ps, arg1, arg2)
  1147. // *******************************************************************
  1148. // fp_ieee_round_sp()
  1149. // Takes a dp register value (which is the hi or lo of a simd)
  1150. // Rounds to single precision, setting flags
  1151. // Returns the value as a single-precision memory format value
  1152. // ********************************************************************
  1153. EM_uint_t
  1154. fp_ieee_round_sp(
  1155. EM_fp_dp_type fp_dp,
  1156. EM_simd_hilo hilo,
  1157. EM_tmp_fp_env_type *tmp_fp_env)
  1158. {
  1159. EM_fp_reg_type fp_reg;
  1160. EM_memory_type tmp_mem;
  1161. fp_reg = fp_ieee_round( fp_dp, tmp_fp_env);
  1162. fp_ieee_to_hilo(hilo, tmp_fp_env);
  1163. if( tmp_fp_env->hi_traps.un || tmp_fp_env->hi_traps.o ||
  1164. tmp_fp_env->lo_traps.un || tmp_fp_env->lo_traps.o ) { // MACH
  1165. tmp_mem = fr_to_mem4_bias_adjust(fp_reg);
  1166. return (tmp_mem.uint_32.uvalue);
  1167. }
  1168. else {
  1169. return (fp_single(fp_reg));
  1170. }
  1171. }
  1172. #undef fp_ieee_round_sp
  1173. #define fp_ieee_round_sp(arg1, arg2, arg3) \
  1174. fp82_fp_ieee_round_sp(ps, arg1, arg2, arg3)
  1175. EM_fp_reg_type
  1176. fp_ieee_rnd_to_int(
  1177. EM_fp_reg_type fr1,
  1178. EM_tmp_fp_env_type *tmp_fp_env)
  1179. {
  1180. EM_fp_dp_type tmp_res;
  1181. EM_tmp_fp_env_type tmp_fp_env_local;
  1182. tmp_res = fp_fr_to_dp(fr1);
  1183. memcpy ((char *)(&tmp_fp_env_local), (char *)tmp_fp_env,
  1184. sizeof (EM_tmp_fp_env_type));
  1185. if (tmp_res.exponent < FP_DP_INTEGER_EXP) {
  1186. if (tmp_res.sign) {
  1187. tmp_res = fp_add(tmp_res, FP_NEG_2_TO_63, *tmp_fp_env);
  1188. tmp_res = fp_fr_to_dp(fp_ieee_round( tmp_res, tmp_fp_env));
  1189. tmp_res = fp_add(tmp_res, FP_POS_2_TO_63, *tmp_fp_env);
  1190. return(fp_ieee_round( tmp_res, &tmp_fp_env_local));
  1191. } else {
  1192. tmp_res = fp_add(tmp_res, FP_POS_2_TO_63, *tmp_fp_env);
  1193. tmp_res = fp_fr_to_dp(fp_ieee_round( tmp_res, tmp_fp_env));
  1194. tmp_res = fp_add(tmp_res, FP_NEG_2_TO_63, *tmp_fp_env);
  1195. return(fp_ieee_round( tmp_res, &tmp_fp_env_local));
  1196. }
  1197. } else
  1198. return (fr1);
  1199. }
  1200. #undef fp_ieee_rnd_to_int
  1201. #define fp_ieee_rnd_to_int(arg1,arg2) \
  1202. fp82_fp_ieee_rnd_to_int(ps, arg1, arg2)
  1203. EM_fp_reg_type
  1204. fp_ieee_rnd_to_int_sp(
  1205. EM_fp_reg_type fr1,
  1206. EM_simd_hilo hilo,
  1207. EM_tmp_fp_env_type *tmp_fp_env)
  1208. {
  1209. EM_fp_reg_type tmp_fix;
  1210. EM_tmp_fp_env_type tmp_fp_env_save;
  1211. tmp_fp_env_save = *tmp_fp_env;
  1212. tmp_fp_env->ss = ss_double_extended_64;
  1213. tmp_fp_env->es = es_seventeen_bits;
  1214. tmp_fix = fp_ieee_rnd_to_int(fr1, tmp_fp_env);
  1215. fp_ieee_to_hilo(hilo, tmp_fp_env);
  1216. tmp_fp_env->ss = tmp_fp_env_save.ss;
  1217. tmp_fp_env->es = tmp_fp_env_save.es;
  1218. return(tmp_fix);
  1219. }
  1220. // ***************************************************************
  1221. // Exception fault checks
  1222. // *****************************************************************
  1223. // ****************************************************************
  1224. // fcmp_exception_fault_check()
  1225. // *****************************************************************
  1226. INLINE void
  1227. fcmp_exception_fault_check(
  1228. EM_fp_reg_specifier f2,
  1229. EM_fp_reg_specifier f3,
  1230. EM_opcode_frel_type frel,
  1231. EM_opcode_sf_type sf,
  1232. EM_tmp_fp_env_type *tmp_fp_env)
  1233. {
  1234. EM_fp_reg_type fr2, fr3;
  1235. fr2 = FR[f2];
  1236. fr3 = FR[f3];
  1237. fp_decode_environment( pc_none, sf, tmp_fp_env );
  1238. if (fp_software_assistance_required(ps, op_fcmp, fr2, fr3)) {
  1239. tmp_fp_env->em_faults.swa = 1;
  1240. }
  1241. if (fp_is_unsupported(fr2) || fp_is_unsupported(fr3)) {
  1242. tmp_fp_env->flags.v = 1;
  1243. if (!tmp_fp_env->controls.vd) {
  1244. tmp_fp_env->em_faults.v = 1;
  1245. }
  1246. } else if (fp_is_nan(fr2) || fp_is_nan(fr3)) {
  1247. if (fp_is_snan(fr2) || fp_is_snan(fr3) ||
  1248. (frel == frelLT) || (frel == frelNLT) ||
  1249. (frel == frelLE) || (frel == frelNLE)) {
  1250. tmp_fp_env->flags.v = 1;
  1251. if (!tmp_fp_env->controls.vd) {
  1252. tmp_fp_env->em_faults.v = 1;
  1253. }
  1254. }
  1255. } else if (fp_is_unorm(fr2) || fp_is_unorm(fr3)) {
  1256. tmp_fp_env->flags.d = 1;
  1257. if(!tmp_fp_env->controls.dd)
  1258. tmp_fp_env->em_faults.d = 1;
  1259. }
  1260. }
  1261. // ****************************************************************
  1262. // fpcmp_exception_fault_check()
  1263. // *****************************************************************
  1264. INLINE void
  1265. fpcmp_exception_fault_check(
  1266. EM_fp_reg_specifier f2,
  1267. EM_fp_reg_specifier f3,
  1268. EM_opcode_frel_type frel,
  1269. EM_opcode_sf_type sf,
  1270. EM_tmp_fp_env_type *tmp_fp_env)
  1271. {
  1272. EM_fp_reg_type tmp_fr2 = FR[f2], tmp_fr3 = FR[f3];
  1273. fp_decode_environment( pc_simd, sf, tmp_fp_env );
  1274. // ***********
  1275. // high
  1276. // ************
  1277. tmp_fr2 = fp_reg_read_hi(f2);
  1278. tmp_fr3 = fp_reg_read_hi(f3);
  1279. if (fp_software_assistance_required(ps, op_fpcmp, tmp_fr2, tmp_fr3)) {
  1280. tmp_fp_env->hi_faults.swa = 1;
  1281. } else if (fp_is_nan(tmp_fr2) || fp_is_nan(tmp_fr3)) {
  1282. if ((fp_is_snan(tmp_fr2) || fp_is_snan(tmp_fr3) ||
  1283. (frel == frelLT) || (frel == frelNLT) ||
  1284. (frel == frelLE) || (frel == frelNLE))) {
  1285. tmp_fp_env->hi_flags.v = 1;
  1286. if (!tmp_fp_env->controls.vd) {
  1287. tmp_fp_env->hi_faults.v = 1;
  1288. }
  1289. }
  1290. } else if (fp_is_unorm(tmp_fr2) || fp_is_unorm(tmp_fr3)) {
  1291. tmp_fp_env->hi_flags.d = 1;
  1292. if (!tmp_fp_env->controls.dd)
  1293. tmp_fp_env->hi_faults.d = 1;
  1294. }
  1295. // ***********
  1296. // low
  1297. // ************
  1298. tmp_fr2 = fp_reg_read_lo(f2);
  1299. tmp_fr3 = fp_reg_read_lo(f3);
  1300. if (fp_software_assistance_required(ps, op_fpcmp, tmp_fr2, tmp_fr3)) {
  1301. tmp_fp_env->lo_faults.swa = 1;
  1302. } else if (fp_is_nan(tmp_fr2) || fp_is_nan(tmp_fr3)) {
  1303. if ((fp_is_snan(tmp_fr2) || fp_is_snan(tmp_fr3) ||
  1304. (frel == frelLT) || (frel == frelNLT) ||
  1305. (frel == frelLE) || (frel == frelNLE))) {
  1306. tmp_fp_env->lo_flags.v = 1;
  1307. if (!tmp_fp_env->controls.vd) {
  1308. tmp_fp_env->lo_faults.v = 1;
  1309. }
  1310. }
  1311. } else if (fp_is_unorm(tmp_fr2) || fp_is_unorm(tmp_fr3)) {
  1312. tmp_fp_env->lo_flags.d = 1;
  1313. if (!tmp_fp_env->controls.dd)
  1314. tmp_fp_env->lo_faults.d = 1;
  1315. }
  1316. return;
  1317. }
  1318. // *******************************************************************
  1319. // fcvt_exception_fault_check()
  1320. // ********************************************************************
  1321. INLINE EM_fp_reg_type
  1322. fcvt_exception_fault_check(
  1323. EM_fp_reg_specifier f2,
  1324. EM_opcode_sf_type sf,
  1325. EM_boolean_t signed_form,
  1326. EM_boolean_t trunc_form,
  1327. EM_tmp_fp_env_type *tmp_fp_env)
  1328. {
  1329. EM_fp_reg_type tmp_res, fr2;
  1330. EM_tmp_fp_env_type tmp_fp_env_local;
  1331. fr2 = FR[f2];
  1332. fp_decode_environment( pc_none, sf, tmp_fp_env );
  1333. if (trunc_form)
  1334. tmp_fp_env->rc = rc_rz;
  1335. tmp_res = fp_reg_read(fr2);
  1336. memcpy ((char *)(&tmp_fp_env_local), (char *)tmp_fp_env,
  1337. sizeof (EM_tmp_fp_env_type));
  1338. tmp_res = fp_ieee_rnd_to_int( tmp_res, &tmp_fp_env_local);
  1339. if( signed_form && fp_software_assistance_required(ps, op_fcvt_fx, fr2)) {
  1340. tmp_fp_env->em_faults.swa = 1;
  1341. return (FP_ZERO);
  1342. } else if( !signed_form && fp_software_assistance_required(ps, op_fcvt_fxu, fr2)) {
  1343. tmp_fp_env->em_faults.swa = 1;
  1344. return (FP_ZERO);
  1345. }
  1346. if (fp_is_unsupported(fr2)) {
  1347. tmp_fp_env->flags.v = 1;
  1348. tmp_res = FP_QNAN;
  1349. if (!tmp_fp_env->controls.vd) {
  1350. tmp_fp_env->em_faults.v = 1;
  1351. }
  1352. } else if (fp_is_nan(fr2)) {
  1353. tmp_fp_env->flags.v = 1;
  1354. if (!tmp_fp_env->controls.vd) {
  1355. tmp_fp_env->em_faults.v = 1;
  1356. }
  1357. tmp_res = fp_is_snan(fr2)?fp_make_quiet_nan(fr2):fr2;
  1358. } else if ( signed_form &&
  1359. (!fp_lesser_or_equal(FP_NEG_2_TO_63, tmp_res) ||
  1360. !fp_less_than(tmp_res,FP_POS_2_TO_63)) ) {
  1361. tmp_fp_env->flags.v = 1;
  1362. tmp_res = FP_QNAN;
  1363. if (!tmp_fp_env->controls.vd)
  1364. tmp_fp_env->em_faults.v = 1;
  1365. } else if ( !signed_form &&
  1366. (!fp_lesser_or_equal(FP_ZERO, tmp_res) ||
  1367. !fp_less_than(tmp_res,FP_POS_2_TO_64)) ) {
  1368. tmp_fp_env->flags.v = 1;
  1369. if (!tmp_fp_env->controls.vd)
  1370. tmp_fp_env->em_faults.v = 1;
  1371. tmp_res = FP_QNAN;
  1372. } else if (fp_is_unorm(fr2)) {
  1373. tmp_fp_env->flags.d = 1;
  1374. if( !tmp_fp_env->controls.dd)
  1375. tmp_fp_env->em_faults.d = 1;
  1376. }
  1377. return (tmp_res);
  1378. }
  1379. // *******************************************************************
  1380. // fpcvt_exception_fault_check()
  1381. // ********************************************************************
  1382. EM_pair_fp_reg_type
  1383. fpcvt_exception_fault_check(
  1384. EM_fp_reg_specifier f2,
  1385. EM_opcode_sf_type sf,
  1386. EM_boolean_t signed_form,
  1387. EM_boolean_t trunc_form,
  1388. EM_tmp_fp_env_type *tmp_fp_env)
  1389. {
  1390. EM_tmp_fp_env_type tmp_fp_env_local;
  1391. EM_pair_fp_reg_type tmp_reg_pair;
  1392. EM_fp_reg_type tmp_fr2 = FR[f2];
  1393. fp_decode_environment( pc_simd, sf, tmp_fp_env );
  1394. tmp_reg_pair.hi = FP_ZERO;
  1395. tmp_reg_pair.lo = FP_ZERO;
  1396. if (trunc_form)
  1397. tmp_fp_env->rc = rc_rz;
  1398. // *************
  1399. // high
  1400. // **************
  1401. tmp_fr2 = fp_reg_read_hi(f2);
  1402. tmp_fp_env_local = *tmp_fp_env;
  1403. tmp_fp_env_local.ss = ss_double_extended_64;
  1404. tmp_fp_env_local.es = es_seventeen_bits;
  1405. tmp_reg_pair.hi = fp_ieee_rnd_to_int( tmp_fr2, &tmp_fp_env_local);
  1406. if ( signed_form &&
  1407. fp_software_assistance_required(ps, op_fpcvt_fx, tmp_fr2)) {
  1408. tmp_fp_env->hi_faults.swa = 1;
  1409. } else if( !signed_form &&
  1410. fp_software_assistance_required(ps, op_fpcvt_fxu, tmp_fr2)) {
  1411. tmp_fp_env->hi_faults.swa = 1;
  1412. } else if (fp_is_nan(tmp_fr2)) {
  1413. tmp_fp_env->hi_flags.v = 1;
  1414. tmp_reg_pair.hi = fp_is_snan(tmp_fr2)?fp_make_quiet_nan(tmp_fr2):tmp_fr2;
  1415. if (!tmp_fp_env->controls.vd)
  1416. tmp_fp_env->hi_faults.v = 1;
  1417. } else if (signed_form &&
  1418. (!fp_lesser_or_equal(FP_NEG_2_TO_31, tmp_reg_pair.hi) ||
  1419. !fp_less_than(tmp_reg_pair.hi,FP_POS_2_TO_31)) ) {
  1420. tmp_fp_env->hi_flags.v = 1;
  1421. tmp_reg_pair.hi = FP_QNAN;
  1422. if (!tmp_fp_env->controls.vd)
  1423. tmp_fp_env->hi_faults.v = 1;
  1424. } else if (!signed_form &&
  1425. (!fp_lesser_or_equal(FP_ZERO, tmp_reg_pair.hi) ||
  1426. !fp_less_than(tmp_reg_pair.hi,FP_POS_2_TO_32)) ) {
  1427. tmp_fp_env->hi_flags.v = 1;
  1428. tmp_reg_pair.hi = FP_QNAN;
  1429. if (!tmp_fp_env->controls.vd)
  1430. tmp_fp_env->hi_faults.v = 1;
  1431. } else if (fp_is_unorm(tmp_fr2)) {
  1432. tmp_fp_env->hi_flags.d = 1;
  1433. if (!tmp_fp_env->controls.dd)
  1434. tmp_fp_env->hi_faults.d = 1;
  1435. }
  1436. // *************
  1437. // low
  1438. // **************
  1439. tmp_fr2 = fp_reg_read_lo(f2);
  1440. tmp_fp_env_local = *tmp_fp_env;
  1441. tmp_fp_env_local.ss = ss_double_extended_64;
  1442. tmp_fp_env_local.es = es_seventeen_bits;
  1443. tmp_reg_pair.lo = fp_ieee_rnd_to_int( tmp_fr2, &tmp_fp_env_local);
  1444. if ( signed_form &&
  1445. fp_software_assistance_required(ps, op_fpcvt_fx, tmp_fr2)) {
  1446. tmp_fp_env->lo_faults.swa = 1;
  1447. } else if( !signed_form &&
  1448. fp_software_assistance_required(ps, op_fpcvt_fxu, tmp_fr2)) {
  1449. tmp_fp_env->lo_faults.swa = 1;
  1450. } else if (fp_is_nan(tmp_fr2)) {
  1451. tmp_fp_env->lo_flags.v = 1;
  1452. tmp_reg_pair.lo = fp_is_snan(tmp_fr2)?fp_make_quiet_nan(tmp_fr2):tmp_fr2;
  1453. if (!tmp_fp_env->controls.vd)
  1454. tmp_fp_env->lo_faults.v = 1;
  1455. } else if (signed_form &&
  1456. (!fp_lesser_or_equal(FP_NEG_2_TO_31, tmp_reg_pair.lo) ||
  1457. !fp_less_than(tmp_reg_pair.lo,FP_POS_2_TO_31)) ) {
  1458. tmp_fp_env->lo_flags.v = 1;
  1459. tmp_reg_pair.lo = FP_QNAN;
  1460. if (!tmp_fp_env->controls.vd)
  1461. tmp_fp_env->lo_faults.v = 1;
  1462. } else if (!signed_form &&
  1463. (!fp_lesser_or_equal(FP_ZERO, tmp_reg_pair.lo) ||
  1464. !fp_less_than(tmp_reg_pair.lo,FP_POS_2_TO_32)) ) {
  1465. tmp_fp_env->lo_flags.v = 1;
  1466. tmp_reg_pair.lo = FP_QNAN;
  1467. if (!tmp_fp_env->controls.vd)
  1468. tmp_fp_env->lo_faults.v = 1;
  1469. } else if (fp_is_unorm(tmp_fr2)) {
  1470. tmp_fp_env->lo_flags.d = 1;
  1471. if (!tmp_fp_env->controls.dd)
  1472. tmp_fp_env->lo_faults.d = 1;
  1473. }
  1474. return (tmp_reg_pair);
  1475. }
  1476. // *******************************************************************
  1477. // fma_exception_fault_check()
  1478. // ********************************************************************
  1479. EM_fp_reg_type
  1480. fma_exception_fault_check(
  1481. EM_fp_reg_specifier f2,
  1482. EM_fp_reg_specifier f3,
  1483. EM_fp_reg_specifier f4,
  1484. EM_opcode_pc_type pc,
  1485. EM_opcode_sf_type sf,
  1486. EM_tmp_fp_env_type *tmp_fp_env)
  1487. {
  1488. EM_fp_reg_type tmp_res;
  1489. EM_fp_reg_type fr2, fr3, fr4;
  1490. // printf ("MACH DEBUG: BEGIN fma_exception_fault_check\n");
  1491. fr2 = FR[f2];
  1492. fr3 = FR[f3];
  1493. fr4 = FR[f4];
  1494. // printf ("MACH DEBUG: FR2 = %x %x "LX"\n", fr2.sign, fr2.exponent, fr2.significand);
  1495. // printf ("MACH DEBUG: FR3 = %x %x "LX"\n", fr3.sign, fr3.exponent, fr3.significand);
  1496. // printf ("MACH DEBUG: FR4 = %x %x "LX"\n", fr4.sign, fr4.exponent, fr4.significand);
  1497. fp_decode_environment( pc, sf, tmp_fp_env );
  1498. if(f4==1 && f2==0) {
  1499. if (fp_software_assistance_required(ps, op_fnorm, fr3, *tmp_fp_env)) {
  1500. tmp_fp_env->em_faults.swa = 1;
  1501. return (FP_ZERO);
  1502. }
  1503. } else {
  1504. if (fp_software_assistance_required(ps, op_fma, fr2, fr3, fr4)) {
  1505. tmp_fp_env->em_faults.swa = 1;
  1506. return (FP_ZERO);
  1507. }
  1508. }
  1509. tmp_res = FP_ZERO;
  1510. if (fp_is_unsupported(fr2) || fp_is_unsupported(fr3) || fp_is_unsupported(fr4)) {
  1511. tmp_fp_env->flags.v = 1;
  1512. tmp_res = FP_QNAN;
  1513. if (!tmp_fp_env->controls.vd) {
  1514. tmp_fp_env->em_faults.v = 1;
  1515. return (tmp_res);
  1516. }
  1517. } else if (fp_is_nan(fr2) || fp_is_nan(fr3) || fp_is_nan(fr4)) {
  1518. if (fp_is_snan(fr2) || fp_is_snan(fr3) || fp_is_snan(fr4)) {
  1519. tmp_fp_env->flags.v = 1;
  1520. if (!tmp_fp_env->controls.vd)
  1521. tmp_fp_env->em_faults.v = 1;
  1522. }
  1523. if (fp_is_nan(fr4))
  1524. tmp_res = fp_is_snan(fr4)?fp_make_quiet_nan(fr4):fr4;
  1525. else if (fp_is_nan(fr2))
  1526. tmp_res = fp_is_snan(fr2)?fp_make_quiet_nan(fr2):fr2;
  1527. else if (fp_is_nan(fr3))
  1528. tmp_res = fp_is_snan(fr3)?fp_make_quiet_nan(fr3):fr3;
  1529. } else if (( fp_is_pos_inf(fr3) && fp_is_pos_non_zero(fr4) && fp_is_neg_inf(fr2) )
  1530. || ( fp_is_pos_inf(fr3) && fp_is_neg_non_zero(fr4) && fp_is_pos_inf(fr2) )
  1531. || ( fp_is_neg_inf(fr3) && fp_is_pos_non_zero(fr4) && fp_is_pos_inf(fr2) )
  1532. || ( fp_is_neg_inf(fr3) && fp_is_neg_non_zero(fr4) && fp_is_neg_inf(fr2) )
  1533. || ( fp_is_pos_non_zero(fr3) && fp_is_pos_inf(fr4) && fp_is_neg_inf(fr2) )
  1534. || ( fp_is_pos_non_zero(fr3) && fp_is_neg_inf(fr4) && fp_is_pos_inf(fr2) )
  1535. || ( fp_is_neg_non_zero(fr3) && fp_is_pos_inf(fr4) && fp_is_pos_inf(fr2) )
  1536. || ( fp_is_neg_non_zero(fr3) && fp_is_neg_inf(fr4) && fp_is_neg_inf(fr2) )) {
  1537. tmp_fp_env->flags.v = 1;
  1538. tmp_res = FP_QNAN;
  1539. if (!tmp_fp_env->controls.vd) {
  1540. tmp_fp_env->em_faults.v = 1;
  1541. return (tmp_res);
  1542. }
  1543. } else if ((fp_is_inf(fr3) && fp_is_zero(fr4)) || (fp_is_zero(fr3) && fp_is_inf(fr4))) {
  1544. tmp_fp_env->flags.v = 1;
  1545. tmp_res = FP_QNAN;
  1546. if (!tmp_fp_env->controls.vd) {
  1547. tmp_fp_env->em_faults.v = 1;
  1548. return (tmp_res);
  1549. }
  1550. } else if (fp_is_unorm(fr2) || fp_is_unorm(fr3) || fp_is_unorm(fr4)) {
  1551. // printf ("MACH DEBUG: setting the D flag in fma_exception_fault_check\n");
  1552. tmp_fp_env->flags.d = 1;
  1553. if(!tmp_fp_env->controls.dd) { // MACH DEBUG
  1554. // printf ("MACH DEBUG: setting the D fault in fma_exception_fault_check\n");
  1555. tmp_fp_env->em_faults.d = 1;
  1556. } // MACH DEBUG
  1557. }
  1558. return (tmp_res);
  1559. }
  1560. // *******************************************************************
  1561. // fpma_exception_fault_check()
  1562. // ********************************************************************
  1563. EM_pair_fp_reg_type
  1564. fpma_exception_fault_check(
  1565. EM_fp_reg_specifier f2,
  1566. EM_fp_reg_specifier f3,
  1567. EM_fp_reg_specifier f4,
  1568. EM_opcode_sf_type sf,
  1569. EM_tmp_fp_env_type *tmp_fp_env)
  1570. {
  1571. EM_pair_fp_reg_type tmp_reg_pair;
  1572. EM_fp_reg_type tmp_fr2 = FR[f2], tmp_fr3 = FR[f3], tmp_fr4 = FR[f4];
  1573. fp_decode_environment( pc_simd, sf, tmp_fp_env );
  1574. tmp_reg_pair.hi = FP_ZERO;
  1575. tmp_reg_pair.lo = FP_ZERO;
  1576. // *********
  1577. // high
  1578. // *********
  1579. tmp_fr2 = fp_reg_read_hi(f2);
  1580. tmp_fr3 = fp_reg_read_hi(f3);
  1581. tmp_fr4 = fp_reg_read_hi(f4);
  1582. if (fp_software_assistance_required(ps, op_fpma, tmp_fr2, tmp_fr3, tmp_fr4)) {
  1583. tmp_fp_env->hi_faults.swa = 1;
  1584. } else if (fp_is_nan(tmp_fr2) || fp_is_nan(tmp_fr3) || fp_is_nan(tmp_fr4)) {
  1585. if (fp_is_snan(tmp_fr2) || fp_is_snan(tmp_fr3) || fp_is_snan(tmp_fr4)) {
  1586. tmp_fp_env->hi_flags.v = 1;
  1587. if (!tmp_fp_env->controls.vd)
  1588. tmp_fp_env->hi_faults.v = 1;
  1589. }
  1590. if (fp_is_nan(tmp_fr4))
  1591. tmp_reg_pair.hi = fp_is_snan(tmp_fr4)?fp_make_quiet_nan(tmp_fr4):tmp_fr4;
  1592. else if (fp_is_nan(tmp_fr2))
  1593. tmp_reg_pair.hi = fp_is_snan(tmp_fr2)?fp_make_quiet_nan(tmp_fr2):tmp_fr2;
  1594. else if (fp_is_nan(tmp_fr3))
  1595. tmp_reg_pair.hi = fp_is_snan(tmp_fr3)?fp_make_quiet_nan(tmp_fr3):tmp_fr3;
  1596. } else if (( fp_is_pos_inf(tmp_fr3) && fp_is_pos_non_zero(tmp_fr4)
  1597. && fp_is_neg_inf(tmp_fr2) )
  1598. || ( fp_is_pos_inf(tmp_fr3) && fp_is_neg_non_zero(tmp_fr4)
  1599. && fp_is_pos_inf(tmp_fr2) )
  1600. || ( fp_is_neg_inf(tmp_fr3) && fp_is_pos_non_zero(tmp_fr4)
  1601. && fp_is_pos_inf(tmp_fr2) )
  1602. || ( fp_is_neg_inf(tmp_fr3) && fp_is_neg_non_zero(tmp_fr4)
  1603. && fp_is_neg_inf(tmp_fr2) )
  1604. || ( fp_is_pos_non_zero(tmp_fr3) && fp_is_pos_inf(tmp_fr4)
  1605. && fp_is_neg_inf(tmp_fr2) )
  1606. || ( fp_is_pos_non_zero(tmp_fr3) && fp_is_neg_inf(tmp_fr4)
  1607. && fp_is_pos_inf(tmp_fr2) )
  1608. || ( fp_is_neg_non_zero(tmp_fr3) && fp_is_pos_inf(tmp_fr4)
  1609. && fp_is_pos_inf(tmp_fr2) )
  1610. || ( fp_is_neg_non_zero(tmp_fr3) && fp_is_neg_inf(tmp_fr4)
  1611. && fp_is_neg_inf(tmp_fr2) )) {
  1612. tmp_fp_env->hi_flags.v = 1;
  1613. tmp_reg_pair.hi = FP_QNAN;
  1614. if (!tmp_fp_env->controls.vd)
  1615. tmp_fp_env->hi_faults.v = 1;
  1616. } else if ((fp_is_inf(tmp_fr3) && fp_is_zero(tmp_fr4))
  1617. || (fp_is_zero(tmp_fr3) && fp_is_inf(tmp_fr4))) {
  1618. tmp_fp_env->hi_flags.v = 1;
  1619. tmp_reg_pair.hi = FP_QNAN;
  1620. if (!tmp_fp_env->controls.vd)
  1621. tmp_fp_env->hi_faults.v = 1;
  1622. } else if (fp_is_unorm(tmp_fr2) || fp_is_unorm(tmp_fr3) || fp_is_unorm(tmp_fr4)) {
  1623. tmp_fp_env->hi_flags.d = 1;
  1624. if (!tmp_fp_env->controls.dd)
  1625. tmp_fp_env->hi_faults.d = 1;
  1626. }
  1627. // *********
  1628. // low
  1629. // **********
  1630. tmp_fr2 = fp_reg_read_lo(f2);
  1631. tmp_fr3 = fp_reg_read_lo(f3);
  1632. tmp_fr4 = fp_reg_read_lo(f4);
  1633. if (fp_software_assistance_required(ps, op_fpma, tmp_fr2, tmp_fr3, tmp_fr4)) {
  1634. tmp_fp_env->lo_faults.swa = 1;
  1635. }
  1636. if (fp_is_nan(tmp_fr2) || fp_is_nan(tmp_fr3) || fp_is_nan(tmp_fr4)) {
  1637. if (fp_is_snan(tmp_fr2) || fp_is_snan(tmp_fr3) || fp_is_snan(tmp_fr4)) {
  1638. tmp_fp_env->lo_flags.v = 1;
  1639. if (!tmp_fp_env->controls.vd)
  1640. tmp_fp_env->lo_faults.v = 1;
  1641. }
  1642. if (fp_is_nan(tmp_fr4))
  1643. tmp_reg_pair.lo = fp_is_snan(tmp_fr4)?fp_make_quiet_nan(tmp_fr4):tmp_fr4;
  1644. else if (fp_is_nan(tmp_fr2))
  1645. tmp_reg_pair.lo = fp_is_snan(tmp_fr2)?fp_make_quiet_nan(tmp_fr2):tmp_fr2;
  1646. else if (fp_is_nan(tmp_fr3))
  1647. tmp_reg_pair.lo = fp_is_snan(tmp_fr3)?fp_make_quiet_nan(tmp_fr3):tmp_fr3;
  1648. } else if (( fp_is_pos_inf(tmp_fr3) && fp_is_pos_non_zero(tmp_fr4)
  1649. && fp_is_neg_inf(tmp_fr2) )
  1650. || ( fp_is_pos_inf(tmp_fr3) && fp_is_neg_non_zero(tmp_fr4)
  1651. && fp_is_pos_inf(tmp_fr2) )
  1652. || ( fp_is_neg_inf(tmp_fr3) && fp_is_pos_non_zero(tmp_fr4)
  1653. && fp_is_pos_inf(tmp_fr2) )
  1654. || ( fp_is_neg_inf(tmp_fr3) && fp_is_neg_non_zero(tmp_fr4)
  1655. && fp_is_neg_inf(tmp_fr2) )
  1656. || ( fp_is_pos_non_zero(tmp_fr3) && fp_is_pos_inf(tmp_fr4)
  1657. && fp_is_neg_inf(tmp_fr2) )
  1658. || ( fp_is_pos_non_zero(tmp_fr3) && fp_is_neg_inf(tmp_fr4)
  1659. && fp_is_pos_inf(tmp_fr2) )
  1660. || ( fp_is_neg_non_zero(tmp_fr3) && fp_is_pos_inf(tmp_fr4)
  1661. && fp_is_pos_inf(tmp_fr2) )
  1662. || ( fp_is_neg_non_zero(tmp_fr3) && fp_is_neg_inf(tmp_fr4)
  1663. && fp_is_neg_inf(tmp_fr2) )) {
  1664. tmp_fp_env->lo_flags.v = 1;
  1665. tmp_reg_pair.lo = FP_QNAN;
  1666. if (!tmp_fp_env->controls.vd)
  1667. tmp_fp_env->lo_faults.v = 1;
  1668. } else if ((fp_is_inf(tmp_fr3) && fp_is_zero(tmp_fr4))
  1669. || (fp_is_zero(tmp_fr3) && fp_is_inf(tmp_fr4))) {
  1670. tmp_fp_env->lo_flags.v = 1;
  1671. tmp_reg_pair.lo = FP_QNAN;
  1672. if (!tmp_fp_env->controls.vd)
  1673. tmp_fp_env->lo_faults.v = 1;
  1674. } else if (fp_is_unorm(tmp_fr2) || fp_is_unorm(tmp_fr3) || fp_is_unorm(tmp_fr4)) {
  1675. tmp_fp_env->lo_flags.d = 1;
  1676. if (!tmp_fp_env->controls.dd)
  1677. tmp_fp_env->lo_faults.d = 1;
  1678. }
  1679. return (tmp_reg_pair);
  1680. }
  1681. // *******************************************************************
  1682. // fpminmax_exception_fault_check()
  1683. // No return value
  1684. // If input contains a NATVAL, just return.
  1685. // Otherwise set flags appropriately so that fpsr will
  1686. // be correct or a fault taken in caller.
  1687. // ********************************************************************
  1688. INLINE void
  1689. fpminmax_exception_fault_check(
  1690. EM_uint_t f2,
  1691. EM_uint_t f3,
  1692. EM_opcode_sf_type sf,
  1693. EM_tmp_fp_env_type *tmp_fp_env)
  1694. {
  1695. EM_fp_reg_type tmp_fr2 = FR[f2], tmp_fr3 = FR[f3];
  1696. // MACH
  1697. fp_decode_environment( pc_simd, sf, tmp_fp_env );
  1698. // ************
  1699. // high
  1700. // ************
  1701. tmp_fr2 = fp_reg_read_hi(f2);
  1702. tmp_fr3 = fp_reg_read_hi(f3);
  1703. if (fp_software_assistance_required(ps, op_fpminmax, tmp_fr2, tmp_fr3)) {
  1704. tmp_fp_env->hi_faults.swa = 1;
  1705. } else if (fp_is_nan(tmp_fr2) || fp_is_nan(tmp_fr3)) {
  1706. tmp_fp_env->hi_flags.v = 1;
  1707. if (!tmp_fp_env->controls.vd) {
  1708. tmp_fp_env->hi_faults.v = 1;
  1709. }
  1710. } else if (fp_is_unorm(tmp_fr2) || fp_is_unorm(tmp_fr3)) {
  1711. tmp_fp_env->hi_flags.d = 1;
  1712. if (!tmp_fp_env->controls.dd) {
  1713. tmp_fp_env->hi_faults.d = 1;
  1714. }
  1715. }
  1716. // ************
  1717. // low
  1718. // ************
  1719. tmp_fr2 = fp_reg_read_lo(f2);
  1720. tmp_fr3 = fp_reg_read_lo(f3);
  1721. if (fp_software_assistance_required(ps, op_fpminmax, tmp_fr2, tmp_fr3)) {
  1722. tmp_fp_env->lo_faults.swa = 1;
  1723. } else if (fp_is_nan(tmp_fr2) || fp_is_nan(tmp_fr3)) {
  1724. tmp_fp_env->lo_flags.v = 1;
  1725. if (!tmp_fp_env->controls.vd) {
  1726. tmp_fp_env->lo_faults.v = 1;
  1727. }
  1728. } else if (fp_is_unorm(tmp_fr2) || fp_is_unorm(tmp_fr3)) {
  1729. tmp_fp_env->lo_flags.d = 1;
  1730. if (!tmp_fp_env->controls.dd)
  1731. tmp_fp_env->lo_faults.d = 1;
  1732. }
  1733. return;
  1734. }
  1735. // *******************************************************************
  1736. // fminmax_exception_fault_check()
  1737. // *******************************************************************
  1738. INLINE void
  1739. fminmax_exception_fault_check(
  1740. EM_fp_reg_specifier f2,
  1741. EM_fp_reg_specifier f3,
  1742. EM_opcode_sf_type sf,
  1743. EM_tmp_fp_env_type *tmp_fp_env)
  1744. {
  1745. EM_fp_reg_type fr2, fr3;
  1746. fr2 = FR[f2];
  1747. fr3 = FR[f3];
  1748. fp_decode_environment( pc_none, sf, tmp_fp_env );
  1749. if (fp_software_assistance_required(ps, op_fminmax, fr2, fr3)) {
  1750. tmp_fp_env->em_faults.swa = 1;
  1751. }
  1752. if (fp_is_unsupported(fr2) || fp_is_unsupported(fr3)) {
  1753. tmp_fp_env->flags.v = 1;
  1754. if (!tmp_fp_env->controls.vd) {
  1755. tmp_fp_env->em_faults.v = 1;
  1756. }
  1757. } else if (fp_is_nan(fr2) || fp_is_nan(fr3)) {
  1758. tmp_fp_env->flags.v = 1;
  1759. if (!tmp_fp_env->controls.vd) {
  1760. tmp_fp_env->em_faults.v = 1;
  1761. }
  1762. } else if (fp_is_unorm(fr2) || fp_is_unorm(fr3)) {
  1763. tmp_fp_env->flags.d = 1;
  1764. if (!tmp_fp_env->controls.dd)
  1765. tmp_fp_env->em_faults.d = 1;
  1766. }
  1767. }
  1768. // *******************************************************************
  1769. // fms_fnma_()
  1770. // *******************************************************************
  1771. EM_fp_reg_type
  1772. fms_fnma_exception_fault_check(
  1773. EM_fp_reg_specifier f2,
  1774. EM_fp_reg_specifier f3,
  1775. EM_fp_reg_specifier f4,
  1776. EM_opcode_pc_type pc,
  1777. EM_opcode_sf_type sf,
  1778. EM_tmp_fp_env_type *tmp_fp_env)
  1779. {
  1780. EM_fp_reg_type fr2, fr3, fr4;
  1781. EM_fp_reg_type tmp_res;
  1782. fr2 = FR[f2];
  1783. fr3 = FR[f3];
  1784. fr4 = FR[f4];
  1785. fp_decode_environment( pc, sf, tmp_fp_env );
  1786. if (fp_software_assistance_required(ps, op_fms_fnma, fr2, fr3, fr4)) {
  1787. tmp_fp_env->em_faults.swa = 1;
  1788. return (FP_ZERO);
  1789. }
  1790. tmp_res = FP_ZERO;
  1791. if (fp_is_unsupported(fr2) || fp_is_unsupported(fr3) || fp_is_unsupported(fr4)) {
  1792. tmp_fp_env->flags.v = 1;
  1793. tmp_res = FP_QNAN;
  1794. if (!tmp_fp_env->controls.vd) {
  1795. tmp_fp_env->em_faults.v = 1;
  1796. return (tmp_res);
  1797. }
  1798. } else if (fp_is_nan(fr2) || fp_is_nan(fr3) || fp_is_nan(fr4)) {
  1799. if (fp_is_snan(fr2) || fp_is_snan(fr3) || fp_is_snan(fr4)) {
  1800. tmp_fp_env->flags.v = 1;
  1801. if (!tmp_fp_env->controls.vd)
  1802. tmp_fp_env->em_faults.v = 1;
  1803. }
  1804. if (fp_is_nan(fr4))
  1805. tmp_res = fp_is_snan(fr4)?fp_make_quiet_nan(fr4):fr4;
  1806. else if (fp_is_nan(fr2))
  1807. tmp_res = fp_is_snan(fr2)?fp_make_quiet_nan(fr2):fr2;
  1808. else if (fp_is_nan(fr3))
  1809. tmp_res = fp_is_snan(fr3)?fp_make_quiet_nan(fr3):fr3;
  1810. } else if (( fp_is_pos_inf(fr3) && fp_is_pos_non_zero(fr4) && fp_is_pos_inf(fr2) )
  1811. || ( fp_is_pos_inf(fr3) && fp_is_neg_non_zero(fr4) && fp_is_neg_inf(fr2) )
  1812. || ( fp_is_neg_inf(fr3) && fp_is_pos_non_zero(fr4) && fp_is_neg_inf(fr2) )
  1813. || ( fp_is_neg_inf(fr3) && fp_is_neg_non_zero(fr4) && fp_is_pos_inf(fr2) )
  1814. || ( fp_is_pos_non_zero(fr3) && fp_is_pos_inf(fr4) && fp_is_pos_inf(fr2) )
  1815. || ( fp_is_pos_non_zero(fr3) && fp_is_neg_inf(fr4) && fp_is_neg_inf(fr2) )
  1816. || ( fp_is_neg_non_zero(fr3) && fp_is_pos_inf(fr4) && fp_is_neg_inf(fr2) )
  1817. || ( fp_is_neg_non_zero(fr3) && fp_is_neg_inf(fr4) && fp_is_pos_inf(fr2) )) {
  1818. tmp_fp_env->flags.v = 1;
  1819. tmp_res = FP_QNAN;
  1820. if (!tmp_fp_env->controls.vd) {
  1821. tmp_fp_env->em_faults.v = 1;
  1822. return (tmp_res);
  1823. }
  1824. } else if ((fp_is_inf(fr3) && fp_is_zero(fr4)) || (fp_is_zero(fr3) && fp_is_inf(fr4))) {
  1825. tmp_fp_env->flags.v = 1;
  1826. tmp_res = FP_QNAN;
  1827. if (!tmp_fp_env->controls.vd) {
  1828. tmp_fp_env->em_faults.v = 1;
  1829. return (tmp_res);
  1830. }
  1831. } else if (fp_is_unorm(fr2) || fp_is_unorm(fr3) || fp_is_unorm(fr4)) {
  1832. tmp_fp_env->flags.d = 1;
  1833. if (!tmp_fp_env->controls.dd)
  1834. tmp_fp_env->em_faults.d = 1;
  1835. }
  1836. return (tmp_res);
  1837. }
  1838. // *******************************************************************
  1839. // fpms_fpnma_exception_fault_check()
  1840. // ********************************************************************
  1841. EM_pair_fp_reg_type
  1842. fpms_fpnma_exception_fault_check(
  1843. EM_fp_reg_specifier f2,
  1844. EM_fp_reg_specifier f3,
  1845. EM_fp_reg_specifier f4,
  1846. EM_opcode_sf_type sf,
  1847. EM_tmp_fp_env_type *tmp_fp_env)
  1848. {
  1849. EM_pair_fp_reg_type tmp_reg_pair;
  1850. EM_fp_reg_type tmp_fr2 = FR[f2], tmp_fr3 = FR[f3], tmp_fr4 = FR[f4];
  1851. fp_decode_environment( pc_simd, sf, tmp_fp_env );
  1852. tmp_reg_pair.hi = FP_ZERO;
  1853. tmp_reg_pair.lo = FP_ZERO;
  1854. // ***************
  1855. // high
  1856. // ***************
  1857. tmp_fr2 = fp_reg_read_hi(f2);
  1858. tmp_fr3 = fp_reg_read_hi(f3);
  1859. tmp_fr4 = fp_reg_read_hi(f4);
  1860. if (fp_software_assistance_required(ps, op_fpms_fpnma, tmp_fr2, tmp_fr3, tmp_fr4)) {
  1861. tmp_fp_env->hi_faults.swa = 1;
  1862. } else if (fp_is_unsupported(tmp_fr2) || fp_is_unsupported(tmp_fr3) || fp_is_unsupported(tmp_fr4)) {
  1863. tmp_fp_env->hi_flags.v = 1;
  1864. tmp_reg_pair.hi = FP_QNAN;
  1865. if (!tmp_fp_env->controls.vd)
  1866. tmp_fp_env->hi_faults.v = 1;
  1867. } else if (fp_is_nan(tmp_fr2) || fp_is_nan(tmp_fr3) || fp_is_nan(tmp_fr4)) {
  1868. if (fp_is_snan(tmp_fr2) || fp_is_snan(tmp_fr3) || fp_is_snan(tmp_fr4)) {
  1869. tmp_fp_env->hi_flags.v = 1;
  1870. if (!tmp_fp_env->controls.vd)
  1871. tmp_fp_env->hi_faults.v = 1;
  1872. }
  1873. if (fp_is_nan(tmp_fr4))
  1874. tmp_reg_pair.hi = fp_is_snan(tmp_fr4)?fp_make_quiet_nan(tmp_fr4):tmp_fr4;
  1875. else if (fp_is_nan(tmp_fr2))
  1876. tmp_reg_pair.hi = fp_is_snan(tmp_fr2)?fp_make_quiet_nan(tmp_fr2):tmp_fr2;
  1877. else if (fp_is_nan(tmp_fr3))
  1878. tmp_reg_pair.hi = fp_is_snan(tmp_fr3)?fp_make_quiet_nan(tmp_fr3):tmp_fr3;
  1879. } else if (( fp_is_pos_inf(tmp_fr3) && fp_is_pos_non_zero(tmp_fr4)
  1880. && fp_is_pos_inf(tmp_fr2) )
  1881. || ( fp_is_pos_inf(tmp_fr3) && fp_is_neg_non_zero(tmp_fr4)
  1882. && fp_is_neg_inf(tmp_fr2) )
  1883. || ( fp_is_neg_inf(tmp_fr3) && fp_is_pos_non_zero(tmp_fr4)
  1884. && fp_is_neg_inf(tmp_fr2) )
  1885. || ( fp_is_neg_inf(tmp_fr3) && fp_is_neg_non_zero(tmp_fr4)
  1886. && fp_is_pos_inf(tmp_fr2) )
  1887. || ( fp_is_pos_non_zero(tmp_fr3) && fp_is_pos_inf(tmp_fr4)
  1888. && fp_is_pos_inf(tmp_fr2) )
  1889. || ( fp_is_pos_non_zero(tmp_fr3) && fp_is_neg_inf(tmp_fr4)
  1890. && fp_is_neg_inf(tmp_fr2) )
  1891. || ( fp_is_neg_non_zero(tmp_fr3) && fp_is_pos_inf(tmp_fr4)
  1892. && fp_is_neg_inf(tmp_fr2) )
  1893. || ( fp_is_neg_non_zero(tmp_fr3) && fp_is_neg_inf(tmp_fr4)
  1894. && fp_is_pos_inf(tmp_fr2) )) {
  1895. tmp_fp_env->hi_flags.v = 1;
  1896. tmp_reg_pair.hi = FP_QNAN;
  1897. if (!tmp_fp_env->controls.vd)
  1898. tmp_fp_env->hi_faults.v = 1;
  1899. } else if ((fp_is_inf(tmp_fr3) && fp_is_zero(tmp_fr4))
  1900. || (fp_is_zero(tmp_fr3) && fp_is_inf(tmp_fr4))) {
  1901. tmp_fp_env->hi_flags.v = 1;
  1902. tmp_reg_pair.hi = FP_QNAN;
  1903. if (!tmp_fp_env->controls.vd)
  1904. tmp_fp_env->hi_faults.v = 1;
  1905. } else if (fp_is_unorm(tmp_fr2) || fp_is_unorm(tmp_fr3) || fp_is_unorm(tmp_fr4)) {
  1906. tmp_fp_env->hi_flags.d = 1;
  1907. if (!tmp_fp_env->controls.dd)
  1908. tmp_fp_env->hi_faults.d = 1;
  1909. }
  1910. // ***************
  1911. // low
  1912. // ***************
  1913. tmp_fr2 = fp_reg_read_lo(f2);
  1914. tmp_fr3 = fp_reg_read_lo(f3);
  1915. tmp_fr4 = fp_reg_read_lo(f4);
  1916. if (fp_software_assistance_required(ps, op_fpms_fpnma, tmp_fr2, tmp_fr3, tmp_fr4)) {
  1917. tmp_fp_env->lo_faults.swa = 1;
  1918. } else if (fp_is_unsupported(tmp_fr2) || fp_is_unsupported(tmp_fr3) || fp_is_unsupported(tmp_fr4)) {
  1919. tmp_fp_env->lo_flags.v = 1;
  1920. tmp_reg_pair.lo = FP_QNAN;
  1921. if (!tmp_fp_env->controls.vd)
  1922. tmp_fp_env->lo_faults.v = 1;
  1923. } else if (fp_is_nan(tmp_fr2) || fp_is_nan(tmp_fr3) || fp_is_nan(tmp_fr4)) {
  1924. if (fp_is_snan(tmp_fr2) || fp_is_snan(tmp_fr3) || fp_is_snan(tmp_fr4)) {
  1925. tmp_fp_env->lo_flags.v = 1;
  1926. if (!tmp_fp_env->controls.vd)
  1927. tmp_fp_env->lo_faults.v = 1;
  1928. }
  1929. if (fp_is_nan(tmp_fr4))
  1930. tmp_reg_pair.lo = fp_is_snan(tmp_fr4)?fp_make_quiet_nan(tmp_fr4):tmp_fr4;
  1931. else if (fp_is_nan(tmp_fr2))
  1932. tmp_reg_pair.lo = fp_is_snan(tmp_fr2)?fp_make_quiet_nan(tmp_fr2):tmp_fr2;
  1933. else if (fp_is_nan(tmp_fr3))
  1934. tmp_reg_pair.lo = fp_is_snan(tmp_fr3)?fp_make_quiet_nan(tmp_fr3):tmp_fr3;
  1935. } else if (( fp_is_pos_inf(tmp_fr3) && fp_is_pos_non_zero(tmp_fr4)
  1936. && fp_is_pos_inf(tmp_fr2) )
  1937. || ( fp_is_pos_inf(tmp_fr3) && fp_is_neg_non_zero(tmp_fr4)
  1938. && fp_is_neg_inf(tmp_fr2) )
  1939. || ( fp_is_neg_inf(tmp_fr3) && fp_is_pos_non_zero(tmp_fr4)
  1940. && fp_is_neg_inf(tmp_fr2) )
  1941. || ( fp_is_neg_inf(tmp_fr3) && fp_is_neg_non_zero(tmp_fr4)
  1942. && fp_is_pos_inf(tmp_fr2) )
  1943. || ( fp_is_pos_non_zero(tmp_fr3) && fp_is_pos_inf(tmp_fr4)
  1944. && fp_is_pos_inf(tmp_fr2) )
  1945. || ( fp_is_pos_non_zero(tmp_fr3) && fp_is_neg_inf(tmp_fr4)
  1946. && fp_is_neg_inf(tmp_fr2) )
  1947. || ( fp_is_neg_non_zero(tmp_fr3) && fp_is_pos_inf(tmp_fr4)
  1948. && fp_is_neg_inf(tmp_fr2) )
  1949. || ( fp_is_neg_non_zero(tmp_fr3) && fp_is_neg_inf(tmp_fr4)
  1950. && fp_is_pos_inf(tmp_fr2) )) {
  1951. tmp_fp_env->lo_flags.v = 1;
  1952. tmp_reg_pair.lo = FP_QNAN;
  1953. if (!tmp_fp_env->controls.vd)
  1954. tmp_fp_env->lo_faults.v = 1;
  1955. } else if ((fp_is_inf(tmp_fr3) && fp_is_zero(tmp_fr4))
  1956. || (fp_is_zero(tmp_fr3) && fp_is_inf(tmp_fr4))) {
  1957. tmp_fp_env->lo_flags.v = 1;
  1958. tmp_reg_pair.lo = FP_QNAN;
  1959. if (!tmp_fp_env->controls.vd)
  1960. tmp_fp_env->lo_faults.v = 1;
  1961. } else if (fp_is_unorm(tmp_fr2) || fp_is_unorm(tmp_fr3) || fp_is_unorm(tmp_fr4)) {
  1962. tmp_fp_env->lo_flags.d = 1;
  1963. if (!tmp_fp_env->controls.dd)
  1964. tmp_fp_env->lo_faults.d = 1;
  1965. }
  1966. return (tmp_reg_pair);
  1967. }
  1968. INLINE EM_fp_dp_type
  1969. fp_max_or_infinity(EM_uint_t sign, EM_tmp_fp_env_type *tmp_fp_env,
  1970. EM_uint_t e_max, EM_uint128_t max_significand)
  1971. {
  1972. EM_fp_dp_type tmp_res;
  1973. tmp_res.sign = sign;
  1974. if (tmp_fp_env->rc == rc_rm) {
  1975. if (tmp_res.sign) {
  1976. tmp_res.exponent = FP_DP_EXP_ONES;
  1977. tmp_res.significand = U128_0x80000000000000000000000000000000;
  1978. }else {
  1979. tmp_res.exponent = e_max;
  1980. tmp_res.significand = max_significand;
  1981. }
  1982. } else if (tmp_fp_env->rc == rc_rz) {
  1983. tmp_res.exponent = e_max;
  1984. tmp_res.significand = max_significand;
  1985. } else if (tmp_fp_env->rc == rc_rp) {
  1986. if (tmp_res.sign) {
  1987. tmp_res.exponent = e_max;
  1988. tmp_res.significand = max_significand;
  1989. }else {
  1990. tmp_res.exponent = FP_DP_EXP_ONES;
  1991. tmp_res.significand = U128_0x80000000000000000000000000000000;
  1992. }
  1993. } else {
  1994. tmp_res.exponent = FP_DP_EXP_ONES;
  1995. tmp_res.significand = U128_0x80000000000000000000000000000000;
  1996. }
  1997. return(tmp_res);
  1998. }
  1999. INLINE EM_fp_dp_type
  2000. fp_mul(EM_fp_reg_type fr3, EM_fp_reg_type fr4)
  2001. {
  2002. EM_fp_dp_type tmp_res;
  2003. EM_int_t normalize_count;
  2004. // all cases which might have faulted have been screened out
  2005. // we still may trap on overflow, underflow and/or inexact later
  2006. if (fp_is_zero(fr3) || fp_is_zero(fr4)) {
  2007. /* correctly signed zero */
  2008. tmp_res = fp_fr_to_dp(FP_ZERO);
  2009. tmp_res.sign = fr3.sign ^ fr4.sign;
  2010. } else if (fp_is_inf(fr3) || fp_is_inf(fr4)) {
  2011. /* correctly signed inf*/
  2012. tmp_res = fp_fr_to_dp(FP_INFINITY);
  2013. tmp_res.sign = fr3.sign ^ fr4.sign;
  2014. } else if (fp_is_pseudo_zero(fr3) || fp_is_pseudo_zero(fr4)) {
  2015. /* pseudo zero if one operand is a pseudo-zero, return real zero.
  2016. pz * NaN = Nan, but we already tested for Nan */
  2017. tmp_res = fp_fr_to_dp(FP_ZERO);
  2018. tmp_res.sign = fr3.sign ^ fr4.sign;
  2019. } else {
  2020. /* (un)normal * (un)normal */
  2021. tmp_res.sign = fr3.sign ^ fr4.sign;
  2022. tmp_res.exponent = (EM_uint_t)(
  2023. (((EM_int_t)fr3.exponent)-FP_REG_BIAS)
  2024. + (((EM_int_t)fr4.exponent)-FP_REG_BIAS)
  2025. + FP_DP_BIAS);
  2026. /* x.xxx (64-bits) * y.yyy (64-bits)
  2027. => zz.zzzzzz (128-bits) */
  2028. tmp_res.significand = fp_U64_x_U64_to_U128(fr3.significand,
  2029. fr4.significand);
  2030. if (fp_U128_lead0(tmp_res.significand) == 0) {
  2031. /* 1.xxx (64-bits) * 1.yyy (64-bits)
  2032. => 1z.zzzzzz (128-bits) */
  2033. tmp_res.exponent += 1;
  2034. /* 1z.zzzzzz
  2035. => 1.zzzzzzz (128-bits) */
  2036. } else if (fp_U128_lead0(tmp_res.significand) == 1) {
  2037. /* 1.xxx (64-bits) * 1.yyy (64-bits)
  2038. => 0z.zzzzzz (128-bits) */
  2039. tmp_res.significand = fp_U128_lsh(tmp_res.significand,1);
  2040. /* 0z.zzzzzz => z.zzzzzz0 (128-bits) */
  2041. } else {
  2042. /* 0.xxx (64-bits) * 0.yyy (64-bits)
  2043. => 00.zzzzzz (128-bits) all unsigned int's */
  2044. normalize_count = fp_U128_lead0(tmp_res.significand);
  2045. tmp_res.exponent -= normalize_count-1;
  2046. tmp_res.significand = fp_U128_lsh(tmp_res.significand,
  2047. normalize_count);
  2048. }
  2049. }
  2050. tmp_res.sticky = 0;
  2051. return(tmp_res);
  2052. }
  2053. INLINE EM_fp_reg_type
  2054. fp_normalize(EM_fp_reg_type freg)
  2055. {
  2056. EM_int_t tmp_normalize_count;
  2057. if (fp_is_nan(freg) || fp_is_inf(freg) || fp_is_normal(freg)
  2058. || fp_is_unsupported(freg) || fp_is_zero(freg) || fp_is_natval(freg))
  2059. return (freg);
  2060. tmp_normalize_count = fp_U64_lead0(freg.significand);
  2061. if (tmp_normalize_count == 64) { /* ftz pseudo-zero */
  2062. if(freg.exponent)
  2063. freg.exponent = 0;
  2064. return (freg);
  2065. } else if(freg.exponent == 1) {
  2066. return(freg);
  2067. } else if ((((EM_int_t)freg.exponent) - tmp_normalize_count) <= 0) {
  2068. tmp_normalize_count = freg.exponent -1;
  2069. freg.exponent = 1;
  2070. freg.significand <<= tmp_normalize_count;
  2071. return (freg);
  2072. } else { /* normalize */
  2073. freg.exponent -= tmp_normalize_count;
  2074. freg.significand <<= tmp_normalize_count;
  2075. return(freg);
  2076. }
  2077. }
  2078. INLINE EM_fp_dp_type
  2079. fp_normalize_dp(EM_fp_dp_type fp_dp)
  2080. {
  2081. EM_int_t tmp_normalize_count;
  2082. if (fp_is_nan_dp(fp_dp) || fp_is_inf_dp(fp_dp) || fp_is_normal_dp(fp_dp)
  2083. || fp_is_zero_dp(fp_dp))
  2084. return (fp_dp);
  2085. else if (fp_is_unsupported_dp(fp_dp)) /* unsupported are turned into nans */
  2086. return (fp_fr_to_dp(FP_QNAN));
  2087. tmp_normalize_count = fp_U128_lead0(fp_dp.significand);
  2088. if (tmp_normalize_count == 128) { /* ftz pseudo-zero */
  2089. if (fp_dp.exponent)
  2090. fp_dp.exponent = 0;
  2091. return (fp_dp);
  2092. } else if ((((EM_int_t)fp_dp.exponent) - tmp_normalize_count) <= 0) {
  2093. /* ftz register file format (pseudo-)denormals */
  2094. fp_dp.exponent = 0;
  2095. fp_dp.significand = U128_0;
  2096. return (fp_dp);
  2097. } else { /* normalize */
  2098. fp_dp.exponent -= tmp_normalize_count;
  2099. fp_dp.significand = fp_U128_lsh(fp_dp.significand,
  2100. tmp_normalize_count);
  2101. return(fp_dp);
  2102. }
  2103. }
  2104. EM_fp_dp_type
  2105. fp82_fp_fr_to_dp(EM_fp_reg_type fr1)
  2106. {
  2107. EM_fp_dp_type tmp_res;
  2108. tmp_res.sign = fr1.sign;
  2109. if (fr1.exponent == 0)
  2110. tmp_res.exponent = 0;
  2111. else if (fr1.exponent == FP_REG_EXP_ONES)
  2112. tmp_res.exponent = FP_DP_EXP_ONES;
  2113. else
  2114. tmp_res.exponent = (EM_uint_t)(((EM_int_t)fr1.exponent)
  2115. - FP_REG_BIAS + FP_DP_BIAS);
  2116. tmp_res.significand.hi = fr1.significand;
  2117. tmp_res.significand.lo = U64_0;
  2118. tmp_res.sticky = 0;
  2119. return(fp_normalize_dp(tmp_res));
  2120. }
  2121. // *******************************************************************
  2122. // frcpa_exception_fault_check()
  2123. // *******************************************************************
  2124. EM_fp_reg_type
  2125. frcpa_exception_fault_check(
  2126. EM_fp_reg_specifier f2,
  2127. EM_fp_reg_specifier f3,
  2128. EM_opcode_sf_type sf,
  2129. EM_tmp_fp_env_type *tmp_fp_env)
  2130. {
  2131. EM_fp_reg_type fr2, fr3;
  2132. EM_fp_reg_type tmp_res;
  2133. EM_int_t estimated_exponent;
  2134. fr2 = FR[f2];
  2135. fr3 = FR[f3];
  2136. fp_decode_environment( pc_none, sf, tmp_fp_env );
  2137. if (fp_software_assistance_required(ps, op_frcpa, fr2, fr3) ) {
  2138. tmp_fp_env->em_faults.swa = 1;
  2139. return (FP_ZERO);
  2140. }
  2141. tmp_res = FP_ZERO;
  2142. if (fp_is_unsupported(fr2) || fp_is_unsupported(fr3)) {
  2143. tmp_fp_env->flags.v = 1;
  2144. tmp_res = FP_QNAN;
  2145. if (!tmp_fp_env->controls.vd) {
  2146. tmp_fp_env->em_faults.v = 1;
  2147. }
  2148. } else if (fp_is_nan(fr2) || fp_is_nan(fr3)) {
  2149. if (fp_is_snan(fr2) || fp_is_snan(fr3)) {
  2150. tmp_fp_env->flags.v = 1;
  2151. if (!tmp_fp_env->controls.vd) {
  2152. tmp_fp_env->em_faults.v = 1;
  2153. }
  2154. }
  2155. if (fp_is_nan(fr2)) {
  2156. tmp_res = fp_is_snan(fr2)?fp_make_quiet_nan(fr2):fr2;
  2157. } else if (fp_is_nan(fr3)) {
  2158. tmp_res = fp_is_snan(fr3)?fp_make_quiet_nan(fr3):fr3;
  2159. }
  2160. } else if ( (fp_is_inf(fr2) && fp_is_inf(fr3))
  2161. || ( (fp_is_zero(fr2) || fp_is_pseudo_zero(fr2))
  2162. && (fp_is_zero(fr3) || fp_is_pseudo_zero(fr3)) ) ) {
  2163. tmp_fp_env->flags.v = 1;
  2164. tmp_res = FP_QNAN;
  2165. if (!tmp_fp_env->controls.vd) {
  2166. tmp_fp_env->em_faults.v = 1;
  2167. }
  2168. } else if ( ( ( fp_is_normal(fr2) && !fp_is_zero(fr2) )
  2169. || ( fp_is_unorm(fr2) && !fp_is_pseudo_zero(fr2) ) )
  2170. && ( fp_is_zero(fr3) || fp_is_pseudo_zero(fr3) ) ) {
  2171. tmp_fp_env->flags.z = 1;
  2172. tmp_res = FP_INFINITY;
  2173. tmp_res.sign = fr2.sign ^ fr3.sign;
  2174. if (!tmp_fp_env->controls.zd) {
  2175. tmp_fp_env->em_faults.z = 1;
  2176. }
  2177. } else if (fp_is_unorm(fr2) || fp_is_unorm(fr3)) {
  2178. tmp_fp_env->flags.d = 1;
  2179. if (!tmp_fp_env->controls.dd) {
  2180. tmp_fp_env->em_faults.d = 1;
  2181. }
  2182. }
  2183. /************************************************************
  2184. This is the architecturally mandated swa fault check.
  2185. The precision of the working type is 17-bit exponent.
  2186. fp_normalize() will normalize except in the case of a register denormal.
  2187. In this context, fp_is_unorm() returns 1 if integer bit is 0
  2188. and that occurs when fr3.exponent < emin.
  2189. Note that the estimated exponent is unbiased, because the bias
  2190. is subtracted out.
  2191. *************************************************************/
  2192. if ( !fp_is_zero(fr2) && fp_is_finite(fr2) && !fp_is_pseudo_zero(fr2)
  2193. && !fp_is_zero(fr3) && fp_is_finite(fr3) && !fp_is_pseudo_zero(fr3)
  2194. ) {
  2195. fr2 = fp_normalize(fp_reg_read(fr2));
  2196. fr3 = fp_normalize(fp_reg_read(fr3));
  2197. estimated_exponent = (EM_int_t)(fr2.exponent)
  2198. - (EM_int_t)(fr3.exponent);
  2199. if ( fp_is_unorm(fr3)
  2200. || ( fr3.exponent >= (FP_REG_BIAS+FP_REG_BIAS-2) )
  2201. || ( estimated_exponent >= ((EM_int_t)(FP_REG_BIAS)) )
  2202. || ( estimated_exponent <= (2 - (EM_int_t)FP_REG_BIAS) )
  2203. || ( fr2.exponent <= (ss_double_extended_64) )
  2204. ) {
  2205. tmp_fp_env->em_faults.swa = 1;
  2206. }
  2207. }
  2208. return (tmp_res);
  2209. }
  2210. // *******************************************************************
  2211. // fprcpa_exception_fault_check()
  2212. // *******************************************************************
  2213. EM_pair_fp_reg_type
  2214. fprcpa_exception_fault_check(
  2215. EM_fp_reg_specifier f2,
  2216. EM_fp_reg_specifier f3,
  2217. EM_opcode_sf_type sf,
  2218. EM_tmp_fp_env_type *tmp_fp_env,
  2219. EM_limits_check_fprcpa *limits_check)
  2220. {
  2221. EM_pair_fp_reg_type tmp_reg_pair;
  2222. EM_fp_reg_type tmp_fr2 = FR[f2], tmp_fr3 = FR[f3];
  2223. EM_int_t estimated_exponent;
  2224. fp_decode_environment( pc_simd, sf, tmp_fp_env );
  2225. tmp_reg_pair.hi = FP_ZERO;
  2226. tmp_reg_pair.lo = FP_ZERO;
  2227. // ************
  2228. // high
  2229. // ************
  2230. tmp_fr2 = fp_reg_read_hi(f2);
  2231. tmp_fr3 = fp_reg_read_hi(f3);
  2232. if (fp_software_assistance_required(ps, op_fprcpa, tmp_fr2, tmp_fr3)) {
  2233. tmp_fp_env->hi_faults.swa = 1;
  2234. } else if (fp_is_nan(tmp_fr2) || fp_is_nan(tmp_fr3)) {
  2235. if (fp_is_snan(tmp_fr2) || fp_is_snan(tmp_fr3)) {
  2236. tmp_fp_env->hi_flags.v = 1;
  2237. if (!tmp_fp_env->controls.vd) {
  2238. tmp_fp_env->hi_faults.v = 1;
  2239. }
  2240. }
  2241. if (fp_is_nan(tmp_fr2)) {
  2242. tmp_reg_pair.hi = fp_is_snan(tmp_fr2)
  2243. ? fp_make_quiet_nan(tmp_fr2) : tmp_fr2;
  2244. } else if (fp_is_nan(tmp_fr3)) {
  2245. tmp_reg_pair.hi = fp_is_snan(tmp_fr3)
  2246. ? fp_make_quiet_nan(tmp_fr3) : tmp_fr3;
  2247. }
  2248. /*******************************************************************************
  2249. (f2 and f3 are inf) or (f2 and f3 are 0); returns qnan
  2250. ********************************************************************************/
  2251. } else if ( (fp_is_inf(tmp_fr2) && fp_is_inf(tmp_fr3) )
  2252. || (fp_is_zero(tmp_fr2) && fp_is_zero(tmp_fr3) ) ) {
  2253. tmp_fp_env->hi_flags.v = 1;
  2254. tmp_reg_pair.hi = FP_QNAN;
  2255. if (!tmp_fp_env->controls.vd) {
  2256. tmp_fp_env->hi_faults.v = 1;
  2257. }
  2258. /*******************************************************************************
  2259. (f2 is non-zero (normal or denormal but not inf) and f3 is zero; returns inf
  2260. The reason for the "but not inf" is because inf/0 shoudl not set the
  2261. divide-by-zero flag.
  2262. ********************************************************************************/
  2263. } else if ( !fp_is_inf(tmp_fr2) && !fp_is_zero(tmp_fr2) && fp_is_zero(tmp_fr3) ) {
  2264. tmp_fp_env->hi_flags.z = 1;
  2265. tmp_reg_pair.hi = FP_INFINITY;
  2266. tmp_reg_pair.hi.sign = tmp_fr2.sign ^ tmp_fr3.sign;
  2267. if (!tmp_fp_env->controls.zd) {
  2268. tmp_fp_env->hi_faults.z = 1;
  2269. }
  2270. } else if (fp_is_unorm(tmp_fr2) || fp_is_unorm(tmp_fr3)) {
  2271. tmp_fp_env->hi_flags.d = 1;
  2272. if (!tmp_fp_env->controls.dd) {
  2273. tmp_fp_env->hi_faults.d = 1;
  2274. }
  2275. }
  2276. if ( !fp_is_zero(tmp_fr2) && fp_is_finite(tmp_fr2)
  2277. && !fp_is_zero(tmp_fr3) && fp_is_finite(tmp_fr3) ) {
  2278. tmp_fr2 = fp_normalize(tmp_fr2);
  2279. if ( fp_is_unorm(tmp_fr3) ) {
  2280. limits_check->hi_fr3 = 1; /* recip(fr3_hi) not rep. */
  2281. tmp_reg_pair.hi = FP_INFINITY;
  2282. tmp_reg_pair.hi.sign = tmp_fr3.sign;
  2283. tmp_fr3 = fp_normalize(tmp_fr3);
  2284. } else if ( tmp_fr3.exponent >= (FP_REG_BIAS+FP_SGL_BIAS-2) ) {
  2285. limits_check->hi_fr3 = 1; /* recip(fr3_hi) not rep. */
  2286. tmp_reg_pair.hi = FP_ZERO;
  2287. tmp_reg_pair.hi.sign = tmp_fr3.sign;
  2288. }
  2289. estimated_exponent = (EM_int_t)tmp_fr2.exponent
  2290. - (EM_int_t)tmp_fr3.exponent;
  2291. if ( (estimated_exponent >= (((EM_int_t)(FP_SGL_BIAS))) )
  2292. || (estimated_exponent <= (2-((EM_int_t)FP_SGL_BIAS)) )
  2293. || (tmp_fr2.exponent <= (ss_single_24+FP_REG_BIAS-FP_SGL_BIAS) )
  2294. ) {
  2295. limits_check->hi_fr2_or_quot = 1; /* hi est. quot. or fr2_hi */
  2296. }
  2297. }
  2298. // ************
  2299. // low
  2300. // ************
  2301. tmp_fr2 = fp_reg_read_lo(f2);
  2302. tmp_fr3 = fp_reg_read_lo(f3);
  2303. if (fp_software_assistance_required(ps, op_fprcpa, tmp_fr2, tmp_fr3)) {
  2304. tmp_fp_env->lo_faults.swa = 1;
  2305. } else if (fp_is_nan(tmp_fr2) || fp_is_nan(tmp_fr3)) {
  2306. if (fp_is_snan(tmp_fr2) || fp_is_snan(tmp_fr3)) {
  2307. tmp_fp_env->lo_flags.v = 1;
  2308. if (!tmp_fp_env->controls.vd) {
  2309. tmp_fp_env->lo_faults.v = 1;
  2310. }
  2311. }
  2312. if (fp_is_nan(tmp_fr2)) {
  2313. tmp_reg_pair.lo = fp_is_snan(tmp_fr2)
  2314. ? fp_make_quiet_nan(tmp_fr2) : tmp_fr2;
  2315. } else if (fp_is_nan(tmp_fr3)) {
  2316. tmp_reg_pair.lo = fp_is_snan(tmp_fr3)
  2317. ? fp_make_quiet_nan(tmp_fr3) : tmp_fr3;
  2318. }
  2319. /*******************************************************************************
  2320. (f2 and f3 are inf) or (f2 and f3 are 0); returns qnan
  2321. ********************************************************************************/
  2322. } else if ( ( fp_is_inf(tmp_fr2) && fp_is_inf(tmp_fr3) )
  2323. || ( fp_is_zero(tmp_fr2) && fp_is_zero(tmp_fr3) ) ) {
  2324. tmp_fp_env->lo_flags.v = 1;
  2325. tmp_reg_pair.lo = FP_QNAN;
  2326. if (!tmp_fp_env->controls.vd) {
  2327. tmp_fp_env->lo_faults.v = 1;
  2328. }
  2329. /*******************************************************************************
  2330. (f2 is non-zero (normal or denormal but not inf) and f3 is zero; returns inf
  2331. The reason for the "but not inf" is because inf/0 should not set the
  2332. divide-by-zero flag.
  2333. ********************************************************************************/
  2334. } else if ( !fp_is_inf(tmp_fr2) && !fp_is_zero(tmp_fr2) && fp_is_zero(tmp_fr3) ) {
  2335. tmp_fp_env->lo_flags.z = 1;
  2336. tmp_reg_pair.lo = FP_INFINITY;
  2337. tmp_reg_pair.lo.sign = tmp_fr2.sign ^ tmp_fr3.sign;
  2338. if (!tmp_fp_env->controls.zd) {
  2339. tmp_fp_env->lo_faults.z = 1;
  2340. }
  2341. } else if (fp_is_unorm(tmp_fr2) || fp_is_unorm(tmp_fr3)) {
  2342. tmp_fp_env->lo_flags.d = 1;
  2343. if (!tmp_fp_env->controls.dd) {
  2344. tmp_fp_env->lo_faults.d = 1;
  2345. }
  2346. }
  2347. if ( !fp_is_zero(tmp_fr2) && fp_is_finite(tmp_fr2)
  2348. && !fp_is_zero(tmp_fr3) && fp_is_finite(tmp_fr3) ) {
  2349. tmp_fr2 = fp_normalize(tmp_fr2);
  2350. if ( fp_is_unorm(tmp_fr3) ) {
  2351. limits_check->lo_fr3 = 1; /* recip(fr3_lo) not rep. */
  2352. tmp_reg_pair.lo = FP_INFINITY;
  2353. tmp_reg_pair.lo.sign = tmp_fr3.sign;
  2354. tmp_fr3 = fp_normalize(tmp_fr3);
  2355. } else if ( tmp_fr3.exponent >= (FP_REG_BIAS+FP_SGL_BIAS-2) ) {
  2356. limits_check->lo_fr3 = 1; /* recip(fr3_lo) not rep. */
  2357. tmp_reg_pair.lo = FP_ZERO;
  2358. tmp_reg_pair.lo.sign = tmp_fr3.sign;
  2359. }
  2360. estimated_exponent = (EM_int_t)tmp_fr2.exponent
  2361. - (EM_int_t)tmp_fr3.exponent;
  2362. if ( (estimated_exponent >= (((EM_int_t)(FP_SGL_BIAS))) )
  2363. || (estimated_exponent <= (2-((EM_int_t)FP_SGL_BIAS)) )
  2364. || (tmp_fr2.exponent <= (ss_single_24+FP_REG_BIAS-FP_SGL_BIAS) )
  2365. ) {
  2366. limits_check->lo_fr2_or_quot = 1; /* lo est. quot. or fr2_lo */
  2367. }
  2368. }
  2369. return (tmp_reg_pair);
  2370. }
  2371. // *******************************************************************
  2372. // frsqrta_exception_fault_check()
  2373. // *******************************************************************
  2374. EM_fp_reg_type
  2375. frsqrta_exception_fault_check(
  2376. EM_fp_reg_specifier f3,
  2377. EM_opcode_sf_type sf,
  2378. EM_tmp_fp_env_type *tmp_fp_env)
  2379. {
  2380. EM_fp_reg_type tmp_res, fr3;
  2381. fr3 = FR[f3];
  2382. fp_decode_environment( pc_none, sf, tmp_fp_env );
  2383. if (fp_software_assistance_required(ps, op_frsqrta, fr3)) {
  2384. tmp_fp_env->em_faults.swa = 1;
  2385. return (FP_ZERO);
  2386. }
  2387. tmp_res = FP_ZERO;
  2388. if (fp_is_unsupported(fr3)) {
  2389. tmp_fp_env->flags.v = 1;
  2390. tmp_res = FP_QNAN;
  2391. if (!tmp_fp_env->controls.vd) {
  2392. tmp_fp_env->em_faults.v = 1;
  2393. }
  2394. } else if (fp_is_nan(fr3)) {
  2395. if(fp_is_snan(fr3)){
  2396. tmp_fp_env->flags.v = 1;
  2397. if (!tmp_fp_env->controls.vd) {
  2398. tmp_fp_env->em_faults.v = 1;
  2399. }
  2400. }
  2401. tmp_res = fp_is_snan(fr3)
  2402. ? fp_make_quiet_nan(fr3) : fr3;
  2403. } else if (fp_is_neg_inf(fr3)) {
  2404. tmp_fp_env->flags.v = 1;
  2405. tmp_res = FP_QNAN;
  2406. if (!tmp_fp_env->controls.vd) {
  2407. tmp_fp_env->em_faults.v = 1;
  2408. }
  2409. } else if ( fp_is_neg_non_zero(fr3) && !fp_is_pseudo_zero(fr3)) {
  2410. tmp_fp_env->flags.v = 1;
  2411. tmp_res = FP_QNAN;
  2412. if (!tmp_fp_env->controls.vd) {
  2413. tmp_fp_env->em_faults.v = 1;
  2414. }
  2415. } else if (fp_is_unorm(fr3)) {
  2416. tmp_fp_env->flags.d = 1;
  2417. if( !tmp_fp_env->controls.dd) {
  2418. tmp_fp_env->em_faults.d = 1;
  2419. }
  2420. }
  2421. if( (fp_is_pos_non_zero(fr3) && !fp_is_pseudo_zero(fr3) )&& fp_is_finite(fr3)) {
  2422. fr3 = fp_normalize(fp_reg_read(fr3));
  2423. if(fr3.exponent <= ss_double_extended_64) {
  2424. tmp_fp_env->em_faults.swa = 1;
  2425. }
  2426. }
  2427. return (tmp_res);
  2428. }
  2429. // *******************************************************************
  2430. // fprsqrta_exception_fault_check()
  2431. // *******************************************************************
  2432. EM_pair_fp_reg_type
  2433. fprsqrta_exception_fault_check(
  2434. EM_fp_reg_specifier f3,
  2435. EM_opcode_sf_type sf,
  2436. EM_tmp_fp_env_type *tmp_fp_env,
  2437. EM_limits_check_fprsqrta *limits_check)
  2438. {
  2439. EM_pair_fp_reg_type tmp_reg_pair;
  2440. EM_fp_reg_type tmp_fr3 = FR[f3];
  2441. fp_decode_environment( pc_simd, sf, tmp_fp_env );
  2442. tmp_reg_pair.hi = FP_ZERO;
  2443. tmp_reg_pair.lo = FP_ZERO;
  2444. // ********
  2445. // high
  2446. // ********
  2447. tmp_fr3 = fp_reg_read_hi(f3);
  2448. if (fp_software_assistance_required(ps, op_fprsqrta, tmp_fr3)) {
  2449. tmp_fp_env->hi_faults.swa = 1;
  2450. } else if (fp_is_nan(tmp_fr3)) {
  2451. if (fp_is_snan(tmp_fr3)) {
  2452. tmp_fp_env->hi_flags.v = 1;
  2453. if (!tmp_fp_env->controls.vd) {
  2454. tmp_fp_env->hi_faults.v = 1;
  2455. }
  2456. }
  2457. tmp_reg_pair.hi = fp_is_snan(tmp_fr3)
  2458. ? fp_make_quiet_nan(tmp_fr3) : tmp_fr3;
  2459. } else if (fp_is_neg_inf(tmp_fr3)) {
  2460. tmp_fp_env->hi_flags.v = 1;
  2461. tmp_reg_pair.hi = FP_QNAN;
  2462. if (!tmp_fp_env->controls.vd) {
  2463. tmp_fp_env->hi_faults.v = 1;
  2464. }
  2465. } else if (fp_is_neg_non_zero(tmp_fr3)) {
  2466. tmp_fp_env->hi_flags.v = 1;
  2467. tmp_reg_pair.hi = FP_QNAN;
  2468. if (!tmp_fp_env->controls.vd) {
  2469. tmp_fp_env->hi_faults.v = 1;
  2470. }
  2471. } else if (fp_is_unorm(tmp_fr3)) {
  2472. tmp_fp_env->hi_flags.d = 1;
  2473. if (!tmp_fp_env->controls.dd) {
  2474. tmp_fp_env->hi_faults.d = 1;
  2475. }
  2476. }
  2477. if(fp_is_pos_non_zero(tmp_fr3) && fp_is_finite(tmp_fr3)) {
  2478. tmp_fr3 = fp_normalize(tmp_fr3);
  2479. if (tmp_fr3.exponent <= (FP_REG_BIAS - FP_SGL_BIAS + ss_single_24)) {
  2480. limits_check->hi = 1;
  2481. } else {
  2482. limits_check->hi = 0;
  2483. }
  2484. }
  2485. // ********
  2486. // low
  2487. // ********
  2488. tmp_fr3 = fp_reg_read_lo(f3);
  2489. if (fp_software_assistance_required(ps, op_fprsqrta, tmp_fr3)) {
  2490. tmp_fp_env->lo_faults.swa = 1;
  2491. } else if (fp_is_nan(tmp_fr3)) {
  2492. if (fp_is_snan(tmp_fr3)) {
  2493. tmp_fp_env->lo_flags.v = 1;
  2494. if (!tmp_fp_env->controls.vd) {
  2495. tmp_fp_env->lo_faults.v = 1;
  2496. }
  2497. }
  2498. tmp_reg_pair.lo = fp_is_snan(tmp_fr3)
  2499. ? fp_make_quiet_nan(tmp_fr3) : tmp_fr3;
  2500. } else if (fp_is_neg_inf(tmp_fr3)) {
  2501. tmp_fp_env->lo_flags.v = 1;
  2502. tmp_reg_pair.lo = FP_QNAN;
  2503. if (!tmp_fp_env->controls.vd) {
  2504. tmp_fp_env->lo_faults.v = 1;
  2505. }
  2506. } else if (fp_is_neg_non_zero(tmp_fr3)) {
  2507. tmp_fp_env->lo_flags.v = 1;
  2508. tmp_reg_pair.lo = FP_QNAN;
  2509. if (!tmp_fp_env->controls.vd) {
  2510. tmp_fp_env->lo_faults.v = 1;
  2511. }
  2512. } else if (fp_is_unorm(tmp_fr3)) {
  2513. tmp_fp_env->lo_flags.d = 1;
  2514. if (!tmp_fp_env->controls.dd) {
  2515. tmp_fp_env->lo_faults.d = 1;
  2516. }
  2517. }
  2518. if(fp_is_pos_non_zero(tmp_fr3) && fp_is_finite(tmp_fr3)) {
  2519. tmp_fr3 = fp_normalize(tmp_fr3);
  2520. if (tmp_fr3.exponent <= (FP_REG_BIAS - FP_SGL_BIAS + ss_single_24)) {
  2521. limits_check->lo = 1;
  2522. } else {
  2523. limits_check->lo = 0;
  2524. }
  2525. }
  2526. return (tmp_reg_pair);
  2527. }
  2528. INLINE EM_boolean_t
  2529. fp_is_finite(EM_fp_reg_type freg)
  2530. {
  2531. if ( fp_is_inf(freg) || fp_is_nan(freg) || fp_is_unsupported(freg) ) {
  2532. return(0);
  2533. } else {
  2534. return(1);
  2535. }
  2536. }
  2537. INLINE EM_boolean_t
  2538. fp_is_inf(EM_fp_reg_type freg)
  2539. {
  2540. if ( (freg.exponent == FP_REG_EXP_ONES)
  2541. &&(freg.significand == U64_0x8000000000000000) ) {
  2542. return(1);
  2543. } else {
  2544. return(0);
  2545. }
  2546. }
  2547. INLINE EM_boolean_t
  2548. fp_is_inf_dp(EM_fp_dp_type tmp_res)
  2549. {
  2550. if ( (tmp_res.exponent == FP_DP_EXP_ONES)
  2551. && fp_U128_eq(tmp_res.significand,
  2552. U128_0x80000000000000000000000000000000) ) {
  2553. return(1);
  2554. } else {
  2555. return(0);
  2556. }
  2557. }
  2558. INLINE EM_boolean_t
  2559. fp_is_nan(EM_fp_reg_type freg)
  2560. {
  2561. if ( (freg.exponent == FP_REG_EXP_ONES)
  2562. && ((freg.significand & U64_0x8000000000000000) != 0)
  2563. && ((freg.significand & U64_0x7FFFFFFFFFFFFFFF) != 0) ) {
  2564. return(1);
  2565. } else {
  2566. return(0);
  2567. }
  2568. }
  2569. INLINE EM_boolean_t
  2570. fp_is_nan_dp(EM_fp_dp_type tmp_res)
  2571. {
  2572. if ( (tmp_res.exponent == FP_DP_EXP_ONES)
  2573. && fp_U128_eq(U128_0x80000000000000000000000000000000,
  2574. fp_U128_band(tmp_res.significand,
  2575. U128_0x80000000000000000000000000000000))
  2576. && !fp_U128_eq(U128_0,
  2577. fp_U128_band(tmp_res.significand,
  2578. U128_0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))
  2579. ) {
  2580. return (1);
  2581. } else {
  2582. return (0);
  2583. }
  2584. }
  2585. INLINE EM_boolean_t
  2586. fp_is_natval(EM_fp_reg_type freg)
  2587. {
  2588. if ( (freg.sign == 0)
  2589. && (freg.exponent == 0x1FFFE)
  2590. && (freg.significand == U64_0) ) {
  2591. return(1);
  2592. } else {
  2593. return(0);
  2594. }
  2595. }
  2596. INLINE EM_boolean_t
  2597. fp_is_neg_dp(EM_fp_dp_type tmp_res)
  2598. {
  2599. if (tmp_res.sign) {
  2600. return(1);
  2601. } else {
  2602. return(0);
  2603. }
  2604. }
  2605. INLINE EM_boolean_t
  2606. fp_is_neg_inf(EM_fp_reg_type freg)
  2607. {
  2608. if ( (freg.sign == 1)
  2609. && (freg.exponent == FP_REG_EXP_ONES)
  2610. && (freg.significand == U64_0x8000000000000000) ) {
  2611. return(1);
  2612. } else {
  2613. return(0);
  2614. }
  2615. }
  2616. INLINE EM_boolean_t
  2617. fp_is_neg_non_zero(EM_fp_reg_type freg)
  2618. {
  2619. if ( (freg.sign == 1) && !fp_is_zero(freg) ) {
  2620. return(1);
  2621. } else {
  2622. return(0);
  2623. }
  2624. }
  2625. INLINE EM_boolean_t
  2626. fp_is_normal(EM_fp_reg_type freg)
  2627. {
  2628. if ( (freg.exponent != 0)
  2629. && (freg.exponent != FP_REG_EXP_ONES)
  2630. && ((freg.significand & U64_0x8000000000000000) != 0) ) {
  2631. return(1);
  2632. } else {
  2633. return(0);
  2634. }
  2635. }
  2636. INLINE EM_boolean_t
  2637. fp_is_normal_dp(EM_fp_dp_type tmp_res)
  2638. {
  2639. if ( (tmp_res.exponent != 0)
  2640. && (tmp_res.exponent != FP_DP_EXP_ONES)
  2641. && fp_U128_eq(U128_0x80000000000000000000000000000000,
  2642. fp_U128_band(tmp_res.significand,
  2643. U128_0x80000000000000000000000000000000))
  2644. ) {
  2645. return(1);
  2646. } else {
  2647. return(0);
  2648. }
  2649. }
  2650. INLINE EM_boolean_t
  2651. fp_is_pos_dp(EM_fp_dp_type tmp_res)
  2652. {
  2653. if (!tmp_res.sign) {
  2654. return(1);
  2655. } else {
  2656. return(0);
  2657. }
  2658. }
  2659. INLINE EM_boolean_t
  2660. fp_is_pos_inf(EM_fp_reg_type freg)
  2661. {
  2662. if ( (freg.sign == 0)
  2663. && (freg.exponent == FP_REG_EXP_ONES)
  2664. && (freg.significand == U64_0x8000000000000000) ) {
  2665. return(1);
  2666. } else {
  2667. return(0);
  2668. }
  2669. }
  2670. INLINE EM_boolean_t
  2671. fp_is_pos_non_zero(EM_fp_reg_type freg)
  2672. {
  2673. if ( (freg.sign == 0) && !fp_is_zero(freg) ) {
  2674. return(1);
  2675. } else {
  2676. return(0);
  2677. }
  2678. }
  2679. INLINE EM_boolean_t
  2680. fp_is_pseudo_zero(EM_fp_reg_type freg)
  2681. {
  2682. if ( (freg.exponent != 0)
  2683. && (freg.exponent != FP_REG_EXP_ONES)
  2684. && (freg.significand == U64_0 && !fp_is_natval (freg)) ) {
  2685. return(1);
  2686. } else {
  2687. return(0);
  2688. }
  2689. }
  2690. INLINE EM_boolean_t
  2691. fp_is_qnan(EM_fp_reg_type freg)
  2692. {
  2693. if ( (freg.exponent == FP_REG_EXP_ONES)
  2694. &&((freg.significand & U64_0xC000000000000000) == U64_0xC000000000000000) ) {
  2695. return(1);
  2696. } else {
  2697. return(0);
  2698. }
  2699. }
  2700. INLINE EM_boolean_t
  2701. fp_is_snan(EM_fp_reg_type freg)
  2702. {
  2703. if ( (freg.exponent == FP_REG_EXP_ONES)
  2704. &&((freg.significand & U64_0xC000000000000000) == U64_0x8000000000000000)
  2705. &&((freg.significand & U64_0x3FFFFFFFFFFFFFFF) != 0) ) {
  2706. return(1);
  2707. } else {
  2708. return(0);
  2709. }
  2710. }
  2711. INLINE EM_boolean_t
  2712. fp_is_unorm(EM_fp_reg_type freg)
  2713. {
  2714. if ( ( (freg.exponent != 0)
  2715. && (freg.exponent != FP_REG_EXP_ONES)
  2716. &&((freg.significand & U64_0x8000000000000000) == 0) )
  2717. /* double-extended pseudo-denormal or double-extended denormal */
  2718. || ( (freg.exponent == 0) && (freg.significand != 0) ) ) {
  2719. return(1);
  2720. } else {
  2721. return(0);
  2722. }
  2723. }
  2724. INLINE EM_boolean_t
  2725. fp_is_unorm_dp(EM_fp_dp_type tmp_res)
  2726. {
  2727. if ( (tmp_res.exponent != 0)
  2728. && (tmp_res.exponent != FP_DP_EXP_ONES)
  2729. &&((tmp_res.significand.hi & U64_0x8000000000000000) == 0) ) {
  2730. return(1);
  2731. } else {
  2732. return(0);
  2733. }
  2734. }
  2735. INLINE EM_boolean_t
  2736. fp_is_unsupported(EM_fp_reg_type freg)
  2737. {
  2738. if ( fp_is_natval(freg) || fp_is_nan(freg) || fp_is_inf(freg)
  2739. || fp_is_normal(freg) || fp_is_unorm(freg) || fp_is_zero(freg) ) {
  2740. return(0);
  2741. } else {
  2742. return(1);
  2743. }
  2744. }
  2745. INLINE EM_boolean_t
  2746. fp_is_unsupported_dp(EM_fp_dp_type tmp_res)
  2747. {
  2748. if ( fp_is_nan_dp(tmp_res) || fp_is_inf_dp(tmp_res)
  2749. || fp_is_normal_dp(tmp_res) || fp_is_unorm_dp(tmp_res)
  2750. || fp_is_zero_dp(tmp_res) ) {
  2751. return(0);
  2752. } else {
  2753. return(1);
  2754. }
  2755. }
  2756. INLINE EM_boolean_t
  2757. fp_is_zero(EM_fp_reg_type freg)
  2758. {
  2759. if ( (freg.exponent == 0) && (freg.significand == U64_0) ) {
  2760. return(1);
  2761. } else {
  2762. return(0);
  2763. }
  2764. }
  2765. INLINE EM_boolean_t
  2766. fp_is_zero_dp(EM_fp_dp_type tmp_res)
  2767. {
  2768. if ( (tmp_res.exponent == 0) && fp_U128_eq(tmp_res.significand, U128_0) ) {
  2769. return(1);
  2770. } else {
  2771. return(0);
  2772. }
  2773. }
  2774. EM_int_t
  2775. fp82_fp_U64_lead0(EM_uint64_t value)
  2776. {
  2777. EM_int_t tmp_i, offset=0;
  2778. EM_uint64_t tmp_mask;
  2779. if( value == U64_0)
  2780. return(64);
  2781. tmp_mask = U64_0x8000000000000000;
  2782. if( (value & U64_0xFFFFFFFF00000000) != U64_0) {
  2783. if( (value & U64_0xFFFF000000000000) != U64_0) {
  2784. if( (value & U64_0xFF00000000000000) != U64_0) {
  2785. for (tmp_i=0; tmp_i<8; tmp_i++, tmp_mask>>=1) {
  2786. if ( (value & tmp_mask) != U64_0 ) {
  2787. return(tmp_i);
  2788. }
  2789. }
  2790. }
  2791. else { /* 0x00FF000000000000 */
  2792. value <<= 8;
  2793. offset += 8;
  2794. for (tmp_i=0; tmp_i<8; tmp_i++, tmp_mask>>=1) {
  2795. if ( (value & tmp_mask) != U64_0 ) {
  2796. return(tmp_i + offset);
  2797. }
  2798. }
  2799. }
  2800. }
  2801. else { /* 0x0000FFFF00000000 */
  2802. value <<= 16;
  2803. offset += 16;
  2804. if( (value & U64_0xFF00000000000000) != U64_0) {
  2805. for (tmp_i=0; tmp_i<8; tmp_i++, tmp_mask>>=1) {
  2806. if ( (value & tmp_mask) != U64_0 ) {
  2807. return(tmp_i + offset);
  2808. }
  2809. }
  2810. }
  2811. else {
  2812. value <<= 8;
  2813. offset += 8;
  2814. for (tmp_i=0; tmp_i<8; tmp_i++, tmp_mask>>=1) {
  2815. if ( (value & tmp_mask) != U64_0 ) {
  2816. return(tmp_i + offset);
  2817. }
  2818. }
  2819. }
  2820. }
  2821. }
  2822. else { /* 0x00000000 FFFFFFFF */
  2823. value <<= 32;
  2824. offset += 32;
  2825. if( (value & U64_0xFFFF000000000000) != U64_0) {
  2826. if( (value & U64_0xFF00000000000000) != U64_0) {
  2827. for (tmp_i=0; tmp_i<8; tmp_i++, tmp_mask>>=1) {
  2828. if ( (value & tmp_mask) != U64_0 ) {
  2829. return(tmp_i + offset);
  2830. }
  2831. }
  2832. }
  2833. else { /* 0x00000000 00FF0000 */
  2834. value <<= 8;
  2835. offset += 8;
  2836. for (tmp_i=0; tmp_i<8; tmp_i++, tmp_mask>>=1) {
  2837. if ( (value & tmp_mask) != U64_0 ) {
  2838. return(tmp_i + offset);
  2839. }
  2840. }
  2841. }
  2842. }
  2843. else { /* 0x00000000 0000FFFF */
  2844. value <<= 16;
  2845. offset += 16;
  2846. if( (value & U64_0xFF00000000000000) != U64_0) {
  2847. for (tmp_i=0; tmp_i<8; tmp_i++, tmp_mask>>=1) {
  2848. if ( (value & tmp_mask) != U64_0 ) {
  2849. return(tmp_i + offset);
  2850. }
  2851. }
  2852. }
  2853. else {
  2854. value <<= 8;
  2855. offset += 8;
  2856. for (tmp_i=0; tmp_i<8; tmp_i++, tmp_mask>>=1) {
  2857. if ( (value & tmp_mask) != U64_0 ) {
  2858. return(tmp_i + offset);
  2859. }
  2860. }
  2861. }
  2862. }
  2863. }
  2864. return(64); // MACH ADDED
  2865. }
  2866. EM_int_t
  2867. fp_U128_lead0(EM_uint128_t value)
  2868. {
  2869. EM_int_t tmp_i;
  2870. tmp_i = fp_U64_lead0(value.hi);
  2871. if (tmp_i == 64) {
  2872. tmp_i += fp_U64_lead0(value.lo);
  2873. }
  2874. return(tmp_i);
  2875. }
  2876. EM_int_t
  2877. fp82_fp_U256_lead0(EM_uint256_t value)
  2878. {
  2879. EM_int_t tmp_i;
  2880. tmp_i = fp_U64_lead0(value.hh);
  2881. if (tmp_i == 64) {
  2882. tmp_i += fp_U64_lead0(value.hl);
  2883. if (tmp_i == 128) {
  2884. tmp_i += fp_U64_lead0(value.lh);
  2885. if (tmp_i == 192) {
  2886. tmp_i += fp_U64_lead0(value.ll);
  2887. }
  2888. }
  2889. }
  2890. return(tmp_i);
  2891. }
  2892. // *******************************************************************
  2893. // fp_mem_to_fr_format()
  2894. // *******************************************************************
  2895. EM_fp_reg_type
  2896. fp_mem_to_fr_format(
  2897. EM_memory_type mem,
  2898. EM_uint_t size,
  2899. EM_uint_t integer_form)
  2900. {
  2901. /******************************************************
  2902. integer_form = 0 floating point
  2903. integer_form = 1 simd, integer
  2904. *******************************************************/
  2905. EM_fp_reg_type tmp_freg;
  2906. EM_uint64_t tmp_significand, tmp_significand_hi, tmp_significand_lo;
  2907. switch (size) {
  2908. case 4:/* single */
  2909. tmp_freg.sign = mem.fp_single.sign;
  2910. if ( (mem.fp_single.exponent == 0)
  2911. && (mem.fp_single.significand == 0) ) { /* zero */
  2912. tmp_freg.exponent = 0;
  2913. } else if (mem.fp_single.exponent == 0) { /* denormal */
  2914. tmp_freg.exponent = (EM_uint_t)(FP_REG_BIAS - FP_SGL_BIAS + 1);
  2915. } else if (mem.fp_single.exponent == FP_SGL_EXP_ONES) { /* Inf, NaN, NaTVal */
  2916. tmp_freg.exponent = FP_REG_EXP_ONES;
  2917. } else {
  2918. tmp_freg.exponent = (EM_uint_t)
  2919. (((EM_int_t)mem.fp_single.exponent)
  2920. - FP_SGL_BIAS + FP_REG_BIAS);
  2921. }
  2922. tmp_freg.significand =
  2923. (((EM_uint64_t)mem.fp_single.significand)<<40)
  2924. #ifdef HPC_BUGS
  2925. | (((mem.fp_single.exponent != U64_0)?U64_1:U64_0)<<63);
  2926. #else
  2927. | (((mem.fp_single.exponent != 0)?U64_1:U64_0)<<63);
  2928. #endif
  2929. break;
  2930. case 8: /* double */
  2931. if (integer_form) {
  2932. tmp_freg.sign = 0;
  2933. tmp_freg.significand = mem.uint_64.uvalue;
  2934. tmp_freg.exponent = FP_INTEGER_EXP;
  2935. } else {
  2936. tmp_freg.sign = mem.fp_double.sign;
  2937. if ( (mem.fp_double.exponent == 0)
  2938. && (mem.fp_double.significand_hi == 0)
  2939. && (mem.fp_double.significand_lo == 0) ){ /* zero */
  2940. tmp_freg.exponent = 0;
  2941. } else if (mem.fp_double.exponent == 0) { /* denormal */
  2942. tmp_freg.exponent = (EM_uint_t)(FP_REG_BIAS - FP_DBL_BIAS + 1);
  2943. } else if (mem.fp_double.exponent == FP_DBL_EXP_ONES) { /* Inf, NaN, NaTVal */
  2944. tmp_freg.exponent = FP_REG_EXP_ONES;
  2945. } else {
  2946. tmp_freg.exponent = (EM_uint_t)
  2947. (((EM_int_t)mem.fp_double.exponent)
  2948. - FP_DBL_BIAS + FP_REG_BIAS);
  2949. }
  2950. tmp_significand_lo = ((EM_uint64_t)(mem.fp_double.significand_lo)) ;
  2951. tmp_significand_hi = (((EM_uint64_t)(mem.fp_double.significand_hi)) << 32);
  2952. tmp_significand = tmp_significand_lo | tmp_significand_hi;
  2953. tmp_freg.significand =
  2954. (tmp_significand<<11)
  2955. #ifdef HPC_BUGS
  2956. | (((mem.fp_double.exponent != U64_0)?U64_1:U64_0)<<63);
  2957. #else
  2958. | (((mem.fp_double.exponent != 0)?U64_1:U64_0)<<63);
  2959. #endif
  2960. }
  2961. break;
  2962. case 10: /* double extended */
  2963. tmp_freg.sign = mem.fp_double_extended.sign;
  2964. if (mem.fp_double_extended.exponent == 0) {
  2965. /* Zero or (Pseudo-)Denormal */
  2966. tmp_freg.exponent = 0;
  2967. } else if (mem.fp_double_extended.exponent == FP_EXT_EXP_ONES) {
  2968. /* Inf, NaN, NaTVal */
  2969. tmp_freg.exponent = FP_REG_EXP_ONES;
  2970. } else { /* Normal */
  2971. tmp_freg.exponent = (EM_uint_t)
  2972. (((EM_int_t)mem.fp_double_extended.exponent)
  2973. - FP_EXT_BIAS + FP_REG_BIAS);
  2974. }
  2975. memcpy(&tmp_freg.significand,
  2976. mem.fp_double_extended.significand, 8);
  2977. break;
  2978. case 16: /* fill */
  2979. tmp_freg.sign = mem.fp_spill_fill.sign;
  2980. tmp_freg.exponent = mem.fp_spill_fill.exponent;
  2981. tmp_freg.significand = mem.fp_spill_fill.significand;
  2982. break;
  2983. }
  2984. return (tmp_freg);
  2985. }
  2986. INLINE EM_fp_reg_type
  2987. fp_make_quiet_nan(EM_fp_reg_type freg)
  2988. {
  2989. freg.significand |= U64_0x4000000000000000;
  2990. return (freg);
  2991. }
  2992. EM_boolean_t
  2993. fp82_fp_raise_fault(EM_tmp_fp_env_type tmp_fp_env)
  2994. {
  2995. if(tmp_fp_env.simd == 1) {
  2996. if (tmp_fp_env.lo_faults.swa || tmp_fp_env.lo_faults.v
  2997. || tmp_fp_env.lo_faults.d || tmp_fp_env.lo_faults.z
  2998. || tmp_fp_env.hi_faults.swa || tmp_fp_env.hi_faults.v
  2999. || tmp_fp_env.hi_faults.d || tmp_fp_env.hi_faults.z )
  3000. return(1);
  3001. } else if ( tmp_fp_env.em_faults.swa || tmp_fp_env.em_faults.v
  3002. || tmp_fp_env.em_faults.d || tmp_fp_env.em_faults.z )
  3003. return (1);
  3004. return (0);
  3005. }
  3006. EM_boolean_t
  3007. fp82_fp_raise_traps(EM_tmp_fp_env_type tmp_fp_env)
  3008. {
  3009. if(tmp_fp_env.simd == 1) {
  3010. if (tmp_fp_env.hi_traps.o || tmp_fp_env.hi_traps.un || tmp_fp_env.hi_traps.i
  3011. || tmp_fp_env.lo_traps.o || tmp_fp_env.lo_traps.un || tmp_fp_env.lo_traps.i) // MACH
  3012. return (1);
  3013. } else if (tmp_fp_env.em_traps.o || tmp_fp_env.em_traps.un || tmp_fp_env.em_traps.i) // MACH
  3014. return (1);
  3015. return (0);
  3016. }
  3017. INLINE EM_fp_reg_type
  3018. fp_reg_read(EM_fp_reg_type freg)
  3019. {
  3020. EM_fp_reg_type tmp_freg;
  3021. tmp_freg = freg;
  3022. /* insert true register file exponent for double-extended (pseudo-)denormal */
  3023. if ((tmp_freg.exponent == 0) && (tmp_freg.significand != U64_0))
  3024. tmp_freg.exponent=0x0C001;
  3025. return (tmp_freg);
  3026. }
  3027. // *******************************************************************
  3028. // fp_update_fpsr()
  3029. // *******************************************************************
  3030. INLINE void
  3031. fp_update_fpsr(
  3032. EM_opcode_sf_type sf,
  3033. EM_tmp_fp_env_type tmp_fp_env )
  3034. {
  3035. if (sf == sf_none) {
  3036. return;
  3037. }
  3038. else if (sf == sfS0) {
  3039. /*******************************************************************
  3040. SF0
  3041. *******************************************************************/
  3042. if(tmp_fp_env.simd == 1) {
  3043. /* SF0 simd fault: if either hi or low is set, set the s0 flag */
  3044. if (tmp_fp_env.hi_flags.v || tmp_fp_env.lo_flags.v) {
  3045. SET_STATUS_FLAG(FPSR.sf0_flags_v);
  3046. }
  3047. if (tmp_fp_env.hi_flags.d || tmp_fp_env.lo_flags.d) {
  3048. SET_STATUS_FLAG(FPSR.sf0_flags_d);
  3049. }
  3050. if (tmp_fp_env.hi_flags.z || tmp_fp_env.lo_flags.z) {
  3051. SET_STATUS_FLAG(FPSR.sf0_flags_z);
  3052. }
  3053. /* SF0 simd trap: if either hi or low is set, set the s0 flag
  3054. if the flag is over or underflow, also set inexact */
  3055. if (tmp_fp_env.hi_flags.o || tmp_fp_env.lo_flags.o) {
  3056. SET_STATUS_FLAG(FPSR.sf0_flags_o);
  3057. }
  3058. if (tmp_fp_env.hi_flags.un || tmp_fp_env.lo_flags.un) { // MACH
  3059. SET_STATUS_FLAG(FPSR.sf0_flags_u);
  3060. }
  3061. if (tmp_fp_env.hi_flags.i || tmp_fp_env.lo_flags.i) {
  3062. SET_STATUS_FLAG(FPSR.sf0_flags_i);
  3063. }
  3064. } /* end of simd */
  3065. else { /* not simd */
  3066. /* SF0 non-simd fault: if tmp flag is set and s0 flag is not, set the flag */
  3067. if (tmp_fp_env.flags.v) {
  3068. SET_STATUS_FLAG(FPSR.sf0_flags_v);
  3069. }
  3070. if (tmp_fp_env.flags.d) {
  3071. // printf ("MACH DEBUG: setting the D flag in update_fpsr ()\n");
  3072. SET_STATUS_FLAG(FPSR.sf0_flags_d);
  3073. }
  3074. if (tmp_fp_env.flags.z) {
  3075. SET_STATUS_FLAG(FPSR.sf0_flags_z);
  3076. }
  3077. /* SF0 non-simd trap: if tmp flag is set, set the flag.
  3078. if the flag is over or underflow, also check inexact */
  3079. if (tmp_fp_env.flags.o) {
  3080. SET_STATUS_FLAG(FPSR.sf0_flags_o);
  3081. if ( tmp_fp_env.flags.i) {
  3082. SET_STATUS_FLAG(FPSR.sf0_flags_i);
  3083. }
  3084. }
  3085. else if (tmp_fp_env.flags.un) { // MACH
  3086. SET_STATUS_FLAG(FPSR.sf0_flags_u);
  3087. if ( tmp_fp_env.flags.i ) {
  3088. SET_STATUS_FLAG(FPSR.sf0_flags_i);
  3089. }
  3090. }
  3091. else if (tmp_fp_env.flags.i) {
  3092. SET_STATUS_FLAG(FPSR.sf0_flags_i);
  3093. }
  3094. } /* end of not simd */
  3095. } /* end of SF0 */
  3096. /*******************************************************************
  3097. SF1
  3098. *******************************************************************/
  3099. else if (sf == sfS1) {
  3100. if(tmp_fp_env.simd == 1) {
  3101. /* SF1 simd fault: if either hi or low is set, set the s1 flag
  3102. */
  3103. if (tmp_fp_env.hi_flags.v || tmp_fp_env.lo_flags.v) {
  3104. SET_STATUS_FLAG(FPSR.sf1_flags_v);
  3105. }
  3106. if (tmp_fp_env.hi_flags.d || tmp_fp_env.lo_flags.d) {
  3107. SET_STATUS_FLAG(FPSR.sf1_flags_d);
  3108. }
  3109. if (tmp_fp_env.hi_flags.z || tmp_fp_env.lo_flags.z) {
  3110. SET_STATUS_FLAG(FPSR.sf1_flags_z);
  3111. }
  3112. /* SF1 simd trap: if either hi or low is set and the s1 flag is not, set the s1 flag
  3113. If the flag is over or underflow, also check inexact */
  3114. if (tmp_fp_env.hi_flags.o || tmp_fp_env.lo_flags.o) {
  3115. SET_STATUS_FLAG(FPSR.sf1_flags_o);
  3116. }
  3117. if (tmp_fp_env.hi_flags.un || tmp_fp_env.lo_flags.un) { // MACH
  3118. SET_STATUS_FLAG(FPSR.sf1_flags_u);
  3119. }
  3120. if (tmp_fp_env.hi_flags.i || tmp_fp_env.lo_flags.i) {
  3121. SET_STATUS_FLAG(FPSR.sf1_flags_i);
  3122. }
  3123. } /* end of simd SF1 */
  3124. else { /* not simd SF1 */
  3125. /* SF1 non-simd fault: if tmp flag is set and s1 flag is not, set the flag
  3126. */
  3127. if (tmp_fp_env.flags.v ) {
  3128. SET_STATUS_FLAG(FPSR.sf1_flags_v);
  3129. }
  3130. if (tmp_fp_env.flags.d ) {
  3131. SET_STATUS_FLAG(FPSR.sf1_flags_d);
  3132. }
  3133. if (tmp_fp_env.flags.z ) {
  3134. SET_STATUS_FLAG(FPSR.sf1_flags_z);
  3135. }
  3136. /* SF1 non-simd traps: if tmp flag is set and s1 flag is not, set the flag.
  3137. if the flag is over or underflow, also check inexact */
  3138. if ( tmp_fp_env.flags.o ) {
  3139. SET_STATUS_FLAG(FPSR.sf1_flags_o);
  3140. if ( tmp_fp_env.flags.i ) {
  3141. SET_STATUS_FLAG(FPSR.sf1_flags_i);
  3142. }
  3143. }
  3144. else if (tmp_fp_env.flags.un ) { // MACH
  3145. SET_STATUS_FLAG(FPSR.sf1_flags_u);
  3146. if ( tmp_fp_env.flags.i ) {
  3147. SET_STATUS_FLAG(FPSR.sf1_flags_i);
  3148. }
  3149. }
  3150. else if (tmp_fp_env.flags.i ) {
  3151. SET_STATUS_FLAG(FPSR.sf1_flags_i);
  3152. }
  3153. } /*end of not simd SF1 */
  3154. } /* end of SF1 */
  3155. /*******************************************************************
  3156. SF2
  3157. *******************************************************************/
  3158. else if (sf == sfS2) {
  3159. if(tmp_fp_env.simd == 1) {
  3160. /* SF2 simd fault: if either hi or low is set and the s2 flag is not, set the s2 flag
  3161. */
  3162. if (tmp_fp_env.hi_flags.v || tmp_fp_env.lo_flags.v) {
  3163. SET_STATUS_FLAG(FPSR.sf2_flags_v);
  3164. }
  3165. if (tmp_fp_env.hi_flags.d || tmp_fp_env.lo_flags.d) {
  3166. SET_STATUS_FLAG(FPSR.sf2_flags_d);
  3167. }
  3168. if (tmp_fp_env.hi_flags.z || tmp_fp_env.lo_flags.z) {
  3169. SET_STATUS_FLAG(FPSR.sf2_flags_z);
  3170. }
  3171. /* SF2 simd trap: if either hi or low is set and the s2 flag is not, set the s2 flag
  3172. If the flag is over or underflow, also check inexact */
  3173. if (tmp_fp_env.hi_flags.o || tmp_fp_env.lo_flags.o) {
  3174. SET_STATUS_FLAG(FPSR.sf2_flags_o);
  3175. }
  3176. if (tmp_fp_env.hi_flags.un || tmp_fp_env.lo_flags.un) { // MACH
  3177. SET_STATUS_FLAG(FPSR.sf2_flags_u);
  3178. }
  3179. if (tmp_fp_env.hi_flags.i || tmp_fp_env.lo_flags.i) {
  3180. SET_STATUS_FLAG(FPSR.sf2_flags_i);
  3181. }
  3182. } /* end of simd SF2 */
  3183. else { /* not simd SF2 */
  3184. /* SF2 non-simd fault: if tmp flag is set and s2 flag is not, set the flag
  3185. */
  3186. if (tmp_fp_env.flags.v ) {
  3187. SET_STATUS_FLAG(FPSR.sf2_flags_v);
  3188. }
  3189. if (tmp_fp_env.flags.d ) {
  3190. SET_STATUS_FLAG(FPSR.sf2_flags_d);
  3191. }
  3192. if (tmp_fp_env.flags.z ) {
  3193. SET_STATUS_FLAG(FPSR.sf2_flags_z);
  3194. }
  3195. /* SF2 non-simd traps: if tmp flag is set and s2 flag is not, set the flag.
  3196. if the flag is over or underflow, also check inexact */
  3197. if ( tmp_fp_env.flags.o ) {
  3198. SET_STATUS_FLAG(FPSR.sf2_flags_o);
  3199. if ( tmp_fp_env.flags.i ) {
  3200. SET_STATUS_FLAG(FPSR.sf2_flags_i);
  3201. }
  3202. }
  3203. else if (tmp_fp_env.flags.un ) { // MACH
  3204. SET_STATUS_FLAG(FPSR.sf2_flags_u);
  3205. if ( tmp_fp_env.flags.i ) {
  3206. SET_STATUS_FLAG(FPSR.sf2_flags_i);
  3207. }
  3208. }
  3209. else if (tmp_fp_env.flags.i ) {
  3210. SET_STATUS_FLAG(FPSR.sf2_flags_i);
  3211. }
  3212. } /* end of not simd SF2 */
  3213. } /* end of SF2 */
  3214. /*******************************************************************
  3215. SF3
  3216. *******************************************************************/
  3217. else if (sf == sfS3) {
  3218. if(tmp_fp_env.simd == 1) {
  3219. /* SF3 simd fault: if either hi or low is set and the s3 flag is not, set the s3 flag
  3220. */
  3221. if (tmp_fp_env.hi_flags.v || tmp_fp_env.lo_flags.v) {
  3222. SET_STATUS_FLAG(FPSR.sf3_flags_v);
  3223. }
  3224. if (tmp_fp_env.hi_flags.d || tmp_fp_env.lo_flags.d) {
  3225. SET_STATUS_FLAG(FPSR.sf3_flags_d);
  3226. }
  3227. if (tmp_fp_env.hi_flags.z || tmp_fp_env.lo_flags.z) {
  3228. SET_STATUS_FLAG(FPSR.sf3_flags_z);
  3229. }
  3230. /* SF3 simd trap: if either hi or low is set and the s3 flag is not, set the s3 flag
  3231. If the flag is over or underflow, also check inexact */
  3232. if (tmp_fp_env.hi_flags.o || tmp_fp_env.lo_flags.o) {
  3233. SET_STATUS_FLAG(FPSR.sf3_flags_o);
  3234. }
  3235. if (tmp_fp_env.hi_flags.un || tmp_fp_env.lo_flags.un) { // MACH
  3236. SET_STATUS_FLAG(FPSR.sf3_flags_u);
  3237. }
  3238. if (tmp_fp_env.hi_flags.i || tmp_fp_env.lo_flags.i) {
  3239. SET_STATUS_FLAG(FPSR.sf3_flags_i);
  3240. }
  3241. } /* end of simd SF3 */
  3242. else { /* not simd SF3 */
  3243. /* SF3 non-simd fault: if tmp flag is set and s3 flag is not, set the flag
  3244. */
  3245. if (tmp_fp_env.flags.v ) {
  3246. SET_STATUS_FLAG(FPSR.sf3_flags_v);
  3247. }
  3248. if (tmp_fp_env.flags.d ) {
  3249. SET_STATUS_FLAG(FPSR.sf3_flags_d);
  3250. }
  3251. if (tmp_fp_env.flags.z ) {
  3252. SET_STATUS_FLAG(FPSR.sf3_flags_z);
  3253. }
  3254. /* SF3 non-simd traps: if tmp flag is set and s3 flag is not, set the flag.
  3255. if the flag is over or underflow, also check inexact */
  3256. if ( tmp_fp_env.flags.o ) {
  3257. SET_STATUS_FLAG(FPSR.sf3_flags_o);
  3258. if ( tmp_fp_env.flags.i ) {
  3259. SET_STATUS_FLAG(FPSR.sf3_flags_i);
  3260. }
  3261. }
  3262. else if (tmp_fp_env.flags.un ) { // MACH
  3263. SET_STATUS_FLAG(FPSR.sf3_flags_u);
  3264. if ( tmp_fp_env.flags.i ) {
  3265. SET_STATUS_FLAG(FPSR.sf3_flags_i);
  3266. }
  3267. }
  3268. else if (tmp_fp_env.flags.i ) {
  3269. SET_STATUS_FLAG(FPSR.sf3_flags_i);
  3270. }
  3271. } /* end of not simd SF3 */
  3272. } /* end of SF3 */
  3273. } /* end of fp_update_fpsr */
  3274. INLINE void
  3275. fp_update_psr(EM_uint_t dest_freg)
  3276. {
  3277. EM_uint_t disabled_limit = 31;
  3278. if ( (dest_freg >= 2) && (dest_freg <= disabled_limit) ){
  3279. SET_STATUS_FLAG(PSR.mfl);
  3280. }
  3281. else if ( (dest_freg > disabled_limit) ) {
  3282. SET_STATUS_FLAG(PSR.mfh);
  3283. }
  3284. }
  3285. /* EM_int64_t, EM_uint64_t, EM_uint128_t and EM_uint256_t support routines */
  3286. /* 128-bit unsigned int support routines */
  3287. EM_boolean_t
  3288. fp82_fp_U128_eq(EM_uint128_t value1, EM_uint128_t value2)
  3289. {
  3290. if ( (value1.hi == value2.hi)
  3291. && (value1.lo == value2.lo) )
  3292. return (1);
  3293. else
  3294. return (0);
  3295. }
  3296. static INLINE EM_boolean_t
  3297. fp_U128_ge(EM_uint128_t value1, EM_uint128_t value2)
  3298. {
  3299. if (value1.hi > value2.hi)
  3300. return (1);
  3301. else if ( (value1.hi == value2.hi)
  3302. && (value1.lo >= value2.lo) )
  3303. return (1);
  3304. else
  3305. return (0);
  3306. }
  3307. static INLINE EM_boolean_t
  3308. fp_U128_gt(EM_uint128_t value1, EM_uint128_t value2)
  3309. {
  3310. if (value1.hi > value2.hi)
  3311. return (1);
  3312. else if ( (value1.hi == value2.hi)
  3313. && (value1.lo > value2.lo) )
  3314. return (1);
  3315. else
  3316. return (0);
  3317. }
  3318. static INLINE EM_boolean_t
  3319. fp_U128_le(EM_uint128_t value1, EM_uint128_t value2)
  3320. {
  3321. if (value1.hi < value2.hi)
  3322. return (1);
  3323. else if ( (value1.hi == value2.hi)
  3324. && (value1.lo <= value2.lo) )
  3325. return (1);
  3326. else
  3327. return (0);
  3328. }
  3329. EM_boolean_t
  3330. fp82_fp_U128_lt(EM_uint128_t value1, EM_uint128_t value2)
  3331. {
  3332. if (value1.hi < value2.hi)
  3333. return (1);
  3334. else if ( (value1.hi == value2.hi)
  3335. && (value1.lo < value2.lo) )
  3336. return (1);
  3337. else
  3338. return (0);
  3339. }
  3340. EM_uint128_t
  3341. fp82_fp_U128_lsh(EM_uint128_t value, EM_uint_t count)
  3342. {
  3343. EM_uint128_t tmp;
  3344. if (count == 0) {
  3345. return(value);
  3346. } else if (count >= 128) {
  3347. return (U128_0);
  3348. } else if (count > 64) {
  3349. tmp.lo = U64_0;
  3350. tmp.hi = (value.lo<<(count-64));
  3351. return (tmp);
  3352. } else if (count == 64) {
  3353. tmp.lo = U64_0;
  3354. tmp.hi = value.lo;
  3355. return (tmp);
  3356. } else if (count > 0) {
  3357. tmp.lo = (value.lo<<count);
  3358. tmp.hi = (value.hi<<count) | (value.lo>>(64-count)) ;
  3359. return (tmp);
  3360. }
  3361. return(value); // MACH ADDED
  3362. }
  3363. EM_uint128_t
  3364. fp82_fp_U128_rsh(EM_uint128_t value, EM_uint_t count)
  3365. {
  3366. EM_uint128_t tmp;
  3367. if (count == 0) {
  3368. return (value);
  3369. } else if (count >= 128) {
  3370. return (U128_0);
  3371. } else if (count > 64) {
  3372. tmp.lo = (value.hi>>(count-64));
  3373. tmp.hi = U64_0;
  3374. return (tmp);
  3375. } else if (count == 64) {
  3376. tmp.lo = value.hi;
  3377. tmp.hi = U64_0;
  3378. return (tmp);
  3379. } else if (count > 0) {
  3380. tmp.lo = (value.lo>>count) | (value.hi<<(64-count));
  3381. tmp.hi = (value.hi>>count);
  3382. return (tmp);
  3383. }
  3384. return(U128_0); // MACH ADDED
  3385. }
  3386. EM_uint128_t
  3387. fp82_fp_U64_x_U64_to_U128(EM_uint64_t value1, EM_uint64_t value2)
  3388. {
  3389. EM_uint128_t tmp_res;
  3390. EM_uint64_t r0, s0, t0;
  3391. EM_uint64_t r1, s1, t1;
  3392. s0 = (value1<<32)>>32;
  3393. s1 = (value1>>32);
  3394. t0 = (value2<<32)>>32;
  3395. t1 = (value2>>32);
  3396. #ifdef HPC_BUGS
  3397. s0 = ((EM_uint64_t)( ( ( ((EM_int64_t)s0) << 32 ) >> 32 ) ));
  3398. s1 = ((EM_uint64_t)( ( ( ((EM_int64_t)s1) << 32 ) >> 32 ) ));
  3399. t0 = ((EM_uint64_t)( ( ( ((EM_int64_t)t0) << 32 ) >> 32 ) ));
  3400. t1 = ((EM_uint64_t)( ( ( ((EM_int64_t)t1) << 32 ) >> 32 ) ));
  3401. #endif
  3402. tmp_res.lo = s0 * t0;
  3403. #ifdef HPC_BUGS
  3404. if(s0 & U64_0x0000000080000000)
  3405. tmp_res.lo += t0<<32;
  3406. if(t0 & U64_0x0000000080000000)
  3407. tmp_res.lo += s0<<32;
  3408. #endif
  3409. r0 = s0 * t1;
  3410. #ifdef HPC_BUGS
  3411. if(s0 & U64_0x0000000080000000)
  3412. r0 += t1<<32;
  3413. if(t1 & U64_0x0000000080000000)
  3414. r0 += s0<<32;
  3415. #endif
  3416. r1 = s1 * t0;
  3417. #ifdef HPC_BUGS
  3418. if(s1 & U64_0x0000000080000000)
  3419. r1 += t0<<32;
  3420. if(t0 & U64_0x0000000080000000)
  3421. r1 += s1<<32;
  3422. #endif
  3423. tmp_res.hi = s1 * t1;
  3424. #ifdef HPC_BUGS
  3425. if(s1 & U64_0x0000000080000000)
  3426. tmp_res.hi += t1<<32;
  3427. if(t1 & U64_0x0000000080000000)
  3428. tmp_res.hi += s1<<32;
  3429. #endif
  3430. if ( (tmp_res.lo + (r0<<32)) < tmp_res.lo)
  3431. tmp_res.hi++;
  3432. tmp_res.lo += (r0<<32);
  3433. if ( (tmp_res.lo + (r1<<32)) < tmp_res.lo)
  3434. tmp_res.hi++;
  3435. tmp_res.lo += (r1<<32);
  3436. tmp_res.hi += (r0>>32);
  3437. tmp_res.hi += (r1>>32);
  3438. return (tmp_res);
  3439. }
  3440. INLINE EM_uint128_t
  3441. fp_I64_x_I64_to_I128(EM_uint64_t value1, EM_uint64_t value2)
  3442. {
  3443. EM_uint128_t tmp_res;
  3444. EM_uint128_t scratch;
  3445. tmp_res = fp_U64_x_U64_to_U128(value1, value2);
  3446. if (value1 & U64_0x8000000000000000) {
  3447. scratch = fp_U64_to_U128(value2);
  3448. scratch = fp_U128_lsh(scratch,64);
  3449. scratch = fp_U128_neg(scratch);
  3450. tmp_res = fp_U128_add(scratch, tmp_res);
  3451. }
  3452. if (value2 & U64_0x8000000000000000) {
  3453. scratch = fp_U64_to_U128(value1);
  3454. scratch = fp_U128_lsh(scratch,64);
  3455. scratch = fp_U128_neg(scratch);
  3456. tmp_res = fp_U128_add(scratch, tmp_res);
  3457. }
  3458. return (tmp_res);
  3459. }
  3460. EM_uint128_t
  3461. fp82_fp_U128_inc(EM_uint128_t value)
  3462. {
  3463. EM_uint128_t tmp;
  3464. /* add one */
  3465. tmp.lo = value.lo + 1;
  3466. tmp.hi = value.hi + (tmp.lo < value.lo);
  3467. return (tmp);
  3468. }
  3469. static INLINE EM_uint128_t
  3470. fp_U128_neg(EM_uint128_t value)
  3471. {
  3472. EM_uint128_t tmp;
  3473. /* complement */
  3474. value.lo = ~value.lo;
  3475. value.hi = ~value.hi;
  3476. /* add one */
  3477. tmp.lo = value.lo + 1;
  3478. tmp.hi = value.hi + (tmp.lo < value.lo);
  3479. return (tmp);
  3480. }
  3481. EM_uint128_t
  3482. fp82_fp_U128_add(EM_uint128_t value1,
  3483. EM_uint128_t value2)
  3484. {
  3485. EM_uint128_t tmp;
  3486. /* sum */
  3487. value2.lo = value1.lo + value2.lo;
  3488. value2.hi = value1.hi + value2.hi;
  3489. /* carry */
  3490. tmp.lo = 0;
  3491. tmp.hi = (value2.lo < value1.lo);
  3492. /* carry propagate adder */
  3493. tmp.lo = value2.lo;
  3494. tmp.hi += value2.hi;
  3495. return (tmp);
  3496. }
  3497. EM_uint128_t
  3498. fp82_fp_U128_bor(EM_uint128_t value1, EM_uint128_t value2)
  3499. {
  3500. EM_uint128_t tmp_res;
  3501. tmp_res.lo = value1.lo | value2.lo;
  3502. tmp_res.hi = value1.hi | value2.hi;
  3503. return (tmp_res);
  3504. }
  3505. EM_uint128_t
  3506. fp82_fp_U128_band(EM_uint128_t value1, EM_uint128_t value2)
  3507. {
  3508. EM_uint128_t tmp_res;
  3509. tmp_res.lo = value1.lo & value2.lo;
  3510. tmp_res.hi = value1.hi & value2.hi;
  3511. return (tmp_res);
  3512. }
  3513. /* 256-bit unsigned int support routines */
  3514. EM_boolean_t
  3515. fp82_fp_U256_eq(EM_uint256_t value1, EM_uint256_t value2)
  3516. {
  3517. if ( (value1.hh == value2.hh)
  3518. && (value1.hl == value2.hl )
  3519. && (value1.lh == value2.lh )
  3520. && (value1.ll == value2.ll ) )
  3521. return (1);
  3522. else
  3523. return (0);
  3524. }
  3525. EM_uint256_t
  3526. fp82_fp_U256_lsh(EM_uint256_t value, EM_uint_t count)
  3527. {
  3528. EM_uint256_t tmp;
  3529. if (count == 0) {
  3530. return (value);
  3531. } else if (count >= 256) {
  3532. return (U256_0);
  3533. } else if (count > 192) {
  3534. tmp.ll = U64_0;
  3535. tmp.lh = U64_0;
  3536. tmp.hl = U64_0;
  3537. tmp.hh = (value.ll<<(count-192));
  3538. return (tmp);
  3539. } else if (count == 192) {
  3540. tmp.ll = U64_0;
  3541. tmp.lh = U64_0;
  3542. tmp.hl = U64_0;
  3543. tmp.hh = value.ll;
  3544. return (tmp);
  3545. } else if (count > 128) {
  3546. tmp.ll = U64_0;
  3547. tmp.lh = U64_0;
  3548. tmp.hl = (value.ll<<(count-128));
  3549. tmp.hh = (value.lh<<(count-128)) | (value.ll>>(192-count));
  3550. return (tmp);
  3551. } else if (count == 128) {
  3552. tmp.ll = U64_0;
  3553. tmp.lh = U64_0;
  3554. tmp.hl = value.ll;
  3555. tmp.hh = value.lh;
  3556. return (tmp);
  3557. } else if (count > 64) {
  3558. tmp.ll = U64_0;
  3559. tmp.lh = (value.ll<<(count-64));
  3560. tmp.hl = (value.lh<<(count-64)) | (value.ll>>(128-count)) ;
  3561. tmp.hh = (value.hl<<(count-64)) | (value.lh>>(128-count)) ;
  3562. return (tmp);
  3563. } else if (count == 64) {
  3564. tmp.ll = 0;
  3565. tmp.lh = value.ll;
  3566. tmp.hl = value.lh;
  3567. tmp.hh = value.hl;
  3568. return (tmp);
  3569. } else if (count > 0) {
  3570. tmp.ll = (value.ll<<count);
  3571. tmp.lh = (value.lh<<count) | (value.ll>>(64-count)) ;
  3572. tmp.hl = (value.hl<<count) | (value.lh>>(64-count)) ;
  3573. tmp.hh = (value.hh<<(count)) | (value.hl>>(64-count)) ;
  3574. return (tmp);
  3575. }
  3576. return(U256_0); // MACH ADDED
  3577. }
  3578. EM_uint256_t
  3579. fp82_fp_U256_rsh(EM_uint256_t value, EM_uint_t count)
  3580. {
  3581. EM_uint256_t tmp;
  3582. if (count == 0) {
  3583. return (value);
  3584. } else if (count >= 256) {
  3585. return (U256_0);
  3586. } else if (count > 192) {
  3587. tmp.ll = (value.hh>>(count-192));
  3588. tmp.lh = U64_0;
  3589. tmp.hl = U64_0;
  3590. tmp.hh = U64_0;
  3591. return (tmp);
  3592. } else if (count == 192) {
  3593. tmp.ll = value.hh;
  3594. tmp.lh = U64_0;
  3595. tmp.hl = U64_0;
  3596. tmp.hh = U64_0;
  3597. return (tmp);
  3598. } else if (count > 128) {
  3599. tmp.ll = (value.hl>>(count-128)) | (value.hh<<(192-count));
  3600. tmp.lh = (value.hh>>(count-128));
  3601. tmp.hl = U64_0;
  3602. tmp.hh = U64_0;
  3603. return (tmp);
  3604. } else if (count == 128) {
  3605. tmp.ll = value.hl;
  3606. tmp.lh = value.hh;
  3607. tmp.hl = U64_0;
  3608. tmp.hh = U64_0;
  3609. return (tmp);
  3610. } else if (count > 64) {
  3611. tmp.ll = (value.lh>>(count-64)) | (value.hl<<(128-count));
  3612. tmp.lh = (value.hl>>(count-64)) | (value.hh<<(128-count));
  3613. tmp.hl = (value.hh>>(count-64));
  3614. tmp.hh = U64_0;
  3615. return (tmp);
  3616. } else if (count == 64) {
  3617. tmp.ll = value.lh;
  3618. tmp.lh = value.hl;
  3619. tmp.hl = value.hh;
  3620. tmp.hh = U64_0;
  3621. return (tmp);
  3622. } else if (count > 0) {
  3623. tmp.ll = (value.ll>>count) | (value.lh<<(64-count));
  3624. tmp.lh = (value.lh>>count) | (value.hl<<(64-count));
  3625. tmp.hl = (value.hl>>count) | (value.hh<<(64-count));
  3626. tmp.hh = (value.hh>>count);
  3627. return (tmp);
  3628. }
  3629. return(U256_0); // MACH ADDED
  3630. }
  3631. EM_uint256_t
  3632. fp82_fp_U256_inc(EM_uint256_t value)
  3633. {
  3634. EM_uint256_t tmp;
  3635. /* add one */
  3636. tmp.ll = value.ll + 1;
  3637. tmp.lh = value.lh + (tmp.ll < value.ll);
  3638. tmp.hl = value.hl + (tmp.lh < value.lh);
  3639. tmp.hh = value.hh + (tmp.hl < value.hl);
  3640. return (tmp);
  3641. }
  3642. static INLINE EM_uint256_t
  3643. fp_U256_neg(EM_uint256_t value)
  3644. {
  3645. EM_uint256_t tmp;
  3646. /* complement */
  3647. value.ll = ~value.ll;
  3648. value.lh = ~value.lh;
  3649. value.hl = ~value.hl;
  3650. value.hh = ~value.hh;
  3651. /* add one */
  3652. tmp.ll = value.ll + 1;
  3653. tmp.lh = value.lh + (tmp.ll < value.ll);
  3654. tmp.hl = value.hl + (tmp.lh < value.lh);
  3655. tmp.hh = value.hh + (tmp.hl < value.hl);
  3656. return (tmp);
  3657. }
  3658. static INLINE EM_uint256_t
  3659. fp_U256_add(EM_uint256_t value1, EM_uint256_t value2)
  3660. {
  3661. EM_uint256_t tmp;
  3662. /* sum */
  3663. value2.ll = value1.ll + value2.ll;
  3664. value2.lh = value1.lh + value2.lh;
  3665. value2.hl = value1.hl + value2.hl;
  3666. value2.hh = value1.hh + value2.hh;
  3667. /* carry */
  3668. tmp.ll = 0;
  3669. tmp.lh = (value2.ll < value1.ll);
  3670. tmp.hl = (value2.lh < value1.lh);
  3671. tmp.hh = (value2.hl < value1.hl);
  3672. /* c_out = (value2.hh < value1.hh); */
  3673. /* carry propagate adder */
  3674. tmp.ll = value2.ll;
  3675. tmp.lh += value2.lh;
  3676. tmp.hl += value2.hl + (tmp.lh < value2.lh);
  3677. tmp.hh += value2.hh + (tmp.hl < value2.hl);
  3678. /* c_out += (tmp.hh < value2.hh); */
  3679. return (tmp);
  3680. }
  3681. /* Basic Conversion Routines */
  3682. INLINE EM_uint128_t
  3683. fp_U64_to_U128(EM_uint64_t value)
  3684. {
  3685. EM_uint128_t tmp;
  3686. tmp.lo = value;
  3687. tmp.hi = U64_0;
  3688. return (tmp);
  3689. }
  3690. INLINE EM_uint64_t
  3691. fp_U128_to_U64(EM_uint128_t value)
  3692. {
  3693. EM_uint64_t tmp;
  3694. tmp = value.lo;
  3695. return (tmp);
  3696. }
  3697. static INLINE EM_uint256_t
  3698. fp_U64_to_U256(EM_uint64_t value)
  3699. {
  3700. EM_uint256_t tmp;
  3701. tmp.ll = value;
  3702. tmp.lh = U64_0;
  3703. tmp.hl = U64_0;
  3704. tmp.hh = U64_0;
  3705. return (tmp);
  3706. }
  3707. static INLINE EM_uint64_t
  3708. fp_U256_to_U64(EM_uint256_t value)
  3709. {
  3710. EM_uint64_t tmp;
  3711. tmp = value.ll;
  3712. return (tmp);
  3713. }
  3714. EM_uint256_t
  3715. fp82_fp_U128_to_U256(EM_uint128_t value)
  3716. {
  3717. EM_uint256_t tmp;
  3718. tmp.ll = value.lo;
  3719. tmp.lh = value.hi;
  3720. tmp.hl = U64_0;
  3721. tmp.hh = U64_0;
  3722. return (tmp);
  3723. }
  3724. static INLINE EM_uint128_t
  3725. fp_U256_to_U128(EM_uint256_t value)
  3726. {
  3727. EM_uint128_t tmp;
  3728. tmp.lo = value.ll;
  3729. tmp.hi = value.lh;
  3730. return (tmp);
  3731. }