cp1.c 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967
  1. /*> cp1.c <*/
  2. /* MIPS Simulator FPU (CoProcessor 1) support.
  3. Copyright (C) 2002-2022 Free Software Foundation, Inc.
  4. Originally created by Cygnus Solutions. Extensive modifications,
  5. including paired-single operation support and MIPS-3D support
  6. contributed by Ed Satterthwaite and Chris Demetriou, of Broadcom
  7. Corporation (SiByte).
  8. This file is part of GDB, the GNU debugger.
  9. This program is free software; you can redistribute it and/or modify
  10. it under the terms of the GNU General Public License as published by
  11. the Free Software Foundation; either version 3 of the License, or
  12. (at your option) any later version.
  13. This program is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. GNU General Public License for more details.
  17. You should have received a copy of the GNU General Public License
  18. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  19. /* XXX: The following notice should be removed as soon as is practical: */
  20. /* Floating Point Support for gdb MIPS simulators
  21. This file is part of the MIPS sim
  22. THIS SOFTWARE IS NOT COPYRIGHTED
  23. (by Cygnus.)
  24. Cygnus offers the following for use in the public domain. Cygnus
  25. makes no warranty with regard to the software or it's performance
  26. and the user accepts the software "AS IS" with all faults.
  27. CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
  28. THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  29. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  30. (Originally, this code was in interp.c)
  31. */
  32. /* This must come before any other includes. */
  33. #include "defs.h"
  34. #include "sim-main.h"
  35. #include <stdlib.h>
  36. /* Within cp1.c we refer to sim_cpu directly. */
  37. #define CPU cpu
  38. #define SD CPU_STATE(cpu)
  39. /*-- FPU support routines ---------------------------------------------------*/
  40. /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
  41. formats conform to ANSI/IEEE Std 754-1985.
  42. SINGLE precision floating:
  43. seeeeeeeefffffffffffffffffffffff
  44. s = 1bit = sign
  45. e = 8bits = exponent
  46. f = 23bits = fraction
  47. SINGLE precision fixed:
  48. siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
  49. s = 1bit = sign
  50. i = 31bits = integer
  51. DOUBLE precision floating:
  52. seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
  53. s = 1bit = sign
  54. e = 11bits = exponent
  55. f = 52bits = fraction
  56. DOUBLE precision fixed:
  57. siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
  58. s = 1bit = sign
  59. i = 63bits = integer
  60. PAIRED SINGLE precision floating:
  61. seeeeeeeefffffffffffffffffffffffseeeeeeeefffffffffffffffffffffff
  62. | upper || lower |
  63. s = 1bit = sign
  64. e = 8bits = exponent
  65. f = 23bits = fraction
  66. Note: upper = [63..32], lower = [31..0]
  67. */
  68. /* Extract packed single values: */
  69. #define FP_PS_upper(v) (((v) >> 32) & (unsigned)0xFFFFFFFF)
  70. #define FP_PS_lower(v) ((v) & (unsigned)0xFFFFFFFF)
  71. #define FP_PS_cat(u,l) (((uint64_t)((u) & (unsigned)0xFFFFFFFF) << 32) \
  72. | (uint64_t)((l) & 0xFFFFFFFF))
  73. /* Explicit QNaN values. */
  74. #define FPQNaN_SINGLE (0x7FBFFFFF)
  75. #define FPQNaN_WORD (0x7FFFFFFF)
  76. #define FPQNaN_DOUBLE (UNSIGNED64 (0x7FF7FFFFFFFFFFFF))
  77. #define FPQNaN_LONG (UNSIGNED64 (0x7FFFFFFFFFFFFFFF))
  78. #define FPQNaN_PS (FP_PS_cat (FPQNaN_SINGLE, FPQNaN_SINGLE))
  79. static void update_fcsr (sim_cpu *, address_word, sim_fpu_status);
  80. static const char *fpu_format_name (FP_formats fmt);
  81. #ifdef DEBUG
  82. static const char *fpu_rounding_mode_name (int rm);
  83. #endif
  84. uword64
  85. value_fpr (sim_cpu *cpu,
  86. address_word cia,
  87. int fpr,
  88. FP_formats fmt)
  89. {
  90. uword64 value = 0;
  91. int err = 0;
  92. /* Treat unused register values, as fixed-point 64bit values. */
  93. if (fmt == fmt_unknown)
  94. {
  95. #if 1
  96. /* If request to read data as "unknown", then use the current
  97. encoding: */
  98. fmt = FPR_STATE[fpr];
  99. #else
  100. fmt = fmt_long;
  101. #endif
  102. }
  103. /* For values not yet accessed, set to the desired format. */
  104. if (fmt < fmt_uninterpreted && fmt != fmt_dc32)
  105. {
  106. if (FPR_STATE[fpr] == fmt_uninterpreted)
  107. {
  108. FPR_STATE[fpr] = fmt;
  109. #ifdef DEBUG
  110. printf ("DBG: Register %d was fmt_uninterpreted. Now %s\n", fpr,
  111. fpu_format_name (fmt));
  112. #endif /* DEBUG */
  113. }
  114. else if (fmt != FPR_STATE[fpr]
  115. && !(fmt == fmt_single
  116. && FPR_STATE[fpr] == fmt_double
  117. && (FGR[fpr] == 0 || FGR[fpr] == 0xFFFFFFFF)))
  118. {
  119. sim_io_eprintf (SD, "FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",
  120. fpr, fpu_format_name (FPR_STATE[fpr]),
  121. fpu_format_name (fmt), pr_addr (cia));
  122. FPR_STATE[fpr] = fmt_unknown;
  123. }
  124. }
  125. if (FPR_STATE[fpr] == fmt_unknown)
  126. {
  127. /* Set QNaN value: */
  128. switch (fmt)
  129. {
  130. case fmt_single: value = FPQNaN_SINGLE; break;
  131. case fmt_double: value = FPQNaN_DOUBLE; break;
  132. case fmt_word: value = FPQNaN_WORD; break;
  133. case fmt_long: value = FPQNaN_LONG; break;
  134. case fmt_ps: value = FPQNaN_PS; break;
  135. default: err = -1; break;
  136. }
  137. }
  138. else if (SizeFGR () == 64)
  139. {
  140. switch (fmt)
  141. {
  142. case fmt_uninterpreted_32:
  143. case fmt_single:
  144. case fmt_word:
  145. case fmt_dc32:
  146. value = (FGR[fpr] & 0xFFFFFFFF);
  147. break;
  148. case fmt_uninterpreted_64:
  149. case fmt_uninterpreted:
  150. case fmt_double:
  151. case fmt_long:
  152. case fmt_ps:
  153. value = FGR[fpr];
  154. break;
  155. default:
  156. err = -1;
  157. break;
  158. }
  159. }
  160. else
  161. {
  162. switch (fmt)
  163. {
  164. case fmt_uninterpreted_32:
  165. case fmt_single:
  166. case fmt_word:
  167. value = (FGR[fpr] & 0xFFFFFFFF);
  168. break;
  169. case fmt_uninterpreted_64:
  170. case fmt_uninterpreted:
  171. case fmt_double:
  172. case fmt_long:
  173. if ((fpr & 1) == 0)
  174. {
  175. /* Even register numbers only. */
  176. #ifdef DEBUG
  177. printf ("DBG: ValueFPR: FGR[%d] = %s, FGR[%d] = %s\n",
  178. fpr + 1, pr_uword64 ((uword64) FGR[fpr+1]),
  179. fpr, pr_uword64 ((uword64) FGR[fpr]));
  180. #endif
  181. value = ((((uword64) FGR[fpr+1]) << 32)
  182. | (FGR[fpr] & 0xFFFFFFFF));
  183. }
  184. else
  185. {
  186. SignalException (ReservedInstruction, 0);
  187. }
  188. break;
  189. case fmt_ps:
  190. SignalException (ReservedInstruction, 0);
  191. break;
  192. default:
  193. err = -1;
  194. break;
  195. }
  196. }
  197. if (err)
  198. SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR ()");
  199. #ifdef DEBUG
  200. printf ("DBG: ValueFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d\n",
  201. fpr, fpu_format_name (fmt), pr_uword64 (value), pr_addr (cia),
  202. SizeFGR ());
  203. #endif /* DEBUG */
  204. return (value);
  205. }
  206. void
  207. store_fpr (sim_cpu *cpu,
  208. address_word cia,
  209. int fpr,
  210. FP_formats fmt,
  211. uword64 value)
  212. {
  213. int err = 0;
  214. #ifdef DEBUG
  215. printf ("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d, \n",
  216. fpr, fpu_format_name (fmt), pr_uword64 (value), pr_addr (cia),
  217. SizeFGR ());
  218. #endif /* DEBUG */
  219. if (SizeFGR () == 64)
  220. {
  221. switch (fmt)
  222. {
  223. case fmt_uninterpreted_32:
  224. fmt = fmt_uninterpreted;
  225. case fmt_single:
  226. case fmt_word:
  227. if (STATE_VERBOSE_P (SD))
  228. sim_io_eprintf (SD,
  229. "Warning: PC 0x%s: interp.c store_fpr DEADCODE\n",
  230. pr_addr (cia));
  231. FGR[fpr] = (((uword64) 0xDEADC0DE << 32) | (value & 0xFFFFFFFF));
  232. FPR_STATE[fpr] = fmt;
  233. break;
  234. case fmt_uninterpreted_64:
  235. fmt = fmt_uninterpreted;
  236. case fmt_uninterpreted:
  237. case fmt_double:
  238. case fmt_long:
  239. case fmt_ps:
  240. FGR[fpr] = value;
  241. FPR_STATE[fpr] = fmt;
  242. break;
  243. default:
  244. FPR_STATE[fpr] = fmt_unknown;
  245. err = -1;
  246. break;
  247. }
  248. }
  249. else
  250. {
  251. switch (fmt)
  252. {
  253. case fmt_uninterpreted_32:
  254. fmt = fmt_uninterpreted;
  255. case fmt_single:
  256. case fmt_word:
  257. FGR[fpr] = (value & 0xFFFFFFFF);
  258. FPR_STATE[fpr] = fmt;
  259. break;
  260. case fmt_uninterpreted_64:
  261. fmt = fmt_uninterpreted;
  262. case fmt_uninterpreted:
  263. case fmt_double:
  264. case fmt_long:
  265. if ((fpr & 1) == 0)
  266. {
  267. /* Even register numbers only. */
  268. FGR[fpr+1] = (value >> 32);
  269. FGR[fpr] = (value & 0xFFFFFFFF);
  270. FPR_STATE[fpr + 1] = fmt;
  271. FPR_STATE[fpr] = fmt;
  272. }
  273. else
  274. {
  275. FPR_STATE[fpr] = fmt_unknown;
  276. FPR_STATE[fpr ^ 1] = fmt_unknown;
  277. SignalException (ReservedInstruction, 0);
  278. }
  279. break;
  280. case fmt_ps:
  281. FPR_STATE[fpr] = fmt_unknown;
  282. SignalException (ReservedInstruction, 0);
  283. break;
  284. default:
  285. FPR_STATE[fpr] = fmt_unknown;
  286. err = -1;
  287. break;
  288. }
  289. }
  290. if (err)
  291. SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR ()");
  292. #ifdef DEBUG
  293. printf ("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",
  294. fpr, pr_uword64 (FGR[fpr]), fpu_format_name (fmt));
  295. #endif /* DEBUG */
  296. return;
  297. }
  298. /* CP1 control/status register access functions. */
  299. void
  300. test_fcsr (sim_cpu *cpu,
  301. address_word cia)
  302. {
  303. unsigned int cause;
  304. cause = (FCSR & fcsr_CAUSE_mask) >> fcsr_CAUSE_shift;
  305. if ((cause & ((FCSR & fcsr_ENABLES_mask) >> fcsr_ENABLES_shift)) != 0
  306. || (cause & (1 << UO)))
  307. {
  308. SignalExceptionFPE();
  309. }
  310. }
  311. unsigned_word
  312. value_fcr(sim_cpu *cpu,
  313. address_word cia,
  314. int fcr)
  315. {
  316. uint32_t value = 0;
  317. switch (fcr)
  318. {
  319. case 0: /* FP Implementation and Revision Register. */
  320. value = FCR0;
  321. break;
  322. case 25: /* FP Condition Codes Register (derived from FCSR). */
  323. value = (FCR31 & fcsr_FCC_mask) >> fcsr_FCC_shift;
  324. value = (value & 0x1) | (value >> 1); /* Close FCC gap. */
  325. break;
  326. case 26: /* FP Exceptions Register (derived from FCSR). */
  327. value = FCR31 & (fcsr_CAUSE_mask | fcsr_FLAGS_mask);
  328. break;
  329. case 28: /* FP Enables Register (derived from FCSR). */
  330. value = FCR31 & (fcsr_ENABLES_mask | fcsr_RM_mask);
  331. if ((FCR31 & fcsr_FS) != 0)
  332. value |= fenr_FS;
  333. break;
  334. case 31: /* FP Control/Status Register (FCSR). */
  335. value = FCR31 & ~fcsr_ZERO_mask;
  336. break;
  337. }
  338. return (EXTEND32 (value));
  339. }
  340. void
  341. store_fcr(sim_cpu *cpu,
  342. address_word cia,
  343. int fcr,
  344. unsigned_word value)
  345. {
  346. uint32_t v;
  347. v = VL4_8(value);
  348. switch (fcr)
  349. {
  350. case 25: /* FP Condition Codes Register (stored into FCSR). */
  351. v = (v << 1) | (v & 0x1); /* Adjust for FCC gap. */
  352. FCR31 &= ~fcsr_FCC_mask;
  353. FCR31 |= ((v << fcsr_FCC_shift) & fcsr_FCC_mask);
  354. break;
  355. case 26: /* FP Exceptions Register (stored into FCSR). */
  356. FCR31 &= ~(fcsr_CAUSE_mask | fcsr_FLAGS_mask);
  357. FCR31 |= (v & (fcsr_CAUSE_mask | fcsr_FLAGS_mask));
  358. test_fcsr(cpu, cia);
  359. break;
  360. case 28: /* FP Enables Register (stored into FCSR). */
  361. if ((v & fenr_FS) != 0)
  362. v |= fcsr_FS;
  363. else
  364. v &= ~fcsr_FS;
  365. FCR31 &= (fcsr_FCC_mask | fcsr_CAUSE_mask | fcsr_FLAGS_mask);
  366. FCR31 |= (v & (fcsr_FS | fcsr_ENABLES_mask | fcsr_RM_mask));
  367. test_fcsr(cpu, cia);
  368. break;
  369. case 31: /* FP Control/Status Register (FCSR). */
  370. FCR31 = v & ~fcsr_ZERO_mask;
  371. test_fcsr(cpu, cia);
  372. break;
  373. }
  374. }
  375. static void
  376. update_fcsr (sim_cpu *cpu,
  377. address_word cia,
  378. sim_fpu_status status)
  379. {
  380. FCSR &= ~fcsr_CAUSE_mask;
  381. if (status != 0)
  382. {
  383. unsigned int cause = 0;
  384. /* map between sim_fpu codes and MIPS FCSR */
  385. if (status & (sim_fpu_status_invalid_snan
  386. | sim_fpu_status_invalid_isi
  387. | sim_fpu_status_invalid_idi
  388. | sim_fpu_status_invalid_zdz
  389. | sim_fpu_status_invalid_imz
  390. | sim_fpu_status_invalid_cmp
  391. | sim_fpu_status_invalid_sqrt
  392. | sim_fpu_status_invalid_cvi))
  393. cause |= (1 << IO);
  394. if (status & sim_fpu_status_invalid_div0)
  395. cause |= (1 << DZ);
  396. if (status & sim_fpu_status_overflow)
  397. cause |= (1 << OF);
  398. if (status & sim_fpu_status_underflow)
  399. cause |= (1 << UF);
  400. if (status & sim_fpu_status_inexact)
  401. cause |= (1 << IR);
  402. #if 0 /* Not yet. */
  403. /* Implicit clearing of other bits by unimplemented done by callers. */
  404. if (status & sim_fpu_status_unimplemented)
  405. cause |= (1 << UO);
  406. #endif
  407. FCSR |= (cause << fcsr_CAUSE_shift);
  408. test_fcsr (cpu, cia);
  409. FCSR |= ((cause & ~(1 << UO)) << fcsr_FLAGS_shift);
  410. }
  411. return;
  412. }
  413. static sim_fpu_round
  414. rounding_mode(int rm)
  415. {
  416. sim_fpu_round round;
  417. switch (rm)
  418. {
  419. case FP_RM_NEAREST:
  420. /* Round result to nearest representable value. When two
  421. representable values are equally near, round to the value
  422. that has a least significant bit of zero (i.e. is even). */
  423. round = sim_fpu_round_near;
  424. break;
  425. case FP_RM_TOZERO:
  426. /* Round result to the value closest to, and not greater in
  427. magnitude than, the result. */
  428. round = sim_fpu_round_zero;
  429. break;
  430. case FP_RM_TOPINF:
  431. /* Round result to the value closest to, and not less than,
  432. the result. */
  433. round = sim_fpu_round_up;
  434. break;
  435. case FP_RM_TOMINF:
  436. /* Round result to the value closest to, and not greater than,
  437. the result. */
  438. round = sim_fpu_round_down;
  439. break;
  440. default:
  441. round = 0;
  442. fprintf (stderr, "Bad switch\n");
  443. abort ();
  444. }
  445. return round;
  446. }
  447. /* When the FS bit is set, MIPS processors return zero for
  448. denormalized results and optionally replace denormalized inputs
  449. with zero. When FS is clear, some implementation trap on input
  450. and/or output, while other perform the operation in hardware. */
  451. static sim_fpu_denorm
  452. denorm_mode(sim_cpu *cpu)
  453. {
  454. sim_fpu_denorm denorm;
  455. /* XXX: FIXME: Eventually should be CPU model dependent. */
  456. if (GETFS())
  457. denorm = sim_fpu_denorm_zero;
  458. else
  459. denorm = 0;
  460. return denorm;
  461. }
  462. /* Comparison operations. */
  463. static sim_fpu_status
  464. fp_test(uint64_t op1,
  465. uint64_t op2,
  466. FP_formats fmt,
  467. int abs,
  468. int cond,
  469. int *condition)
  470. {
  471. sim_fpu wop1;
  472. sim_fpu wop2;
  473. sim_fpu_status status = 0;
  474. int less, equal, unordered;
  475. /* The format type has already been checked: */
  476. switch (fmt)
  477. {
  478. case fmt_single:
  479. {
  480. sim_fpu_32to (&wop1, op1);
  481. sim_fpu_32to (&wop2, op2);
  482. break;
  483. }
  484. case fmt_double:
  485. {
  486. sim_fpu_64to (&wop1, op1);
  487. sim_fpu_64to (&wop2, op2);
  488. break;
  489. }
  490. default:
  491. fprintf (stderr, "Bad switch\n");
  492. abort ();
  493. }
  494. if (sim_fpu_is_nan (&wop1) || sim_fpu_is_nan (&wop2))
  495. {
  496. if ((cond & (1 << 3))
  497. || sim_fpu_is_snan (&wop1) || sim_fpu_is_snan (&wop2))
  498. status = sim_fpu_status_invalid_snan;
  499. less = 0;
  500. equal = 0;
  501. unordered = 1;
  502. }
  503. else
  504. {
  505. if (abs)
  506. {
  507. status |= sim_fpu_abs (&wop1, &wop1);
  508. status |= sim_fpu_abs (&wop2, &wop2);
  509. }
  510. equal = sim_fpu_is_eq (&wop1, &wop2);
  511. less = !equal && sim_fpu_is_lt (&wop1, &wop2);
  512. unordered = 0;
  513. }
  514. *condition = (((cond & (1 << 2)) && less)
  515. || ((cond & (1 << 1)) && equal)
  516. || ((cond & (1 << 0)) && unordered));
  517. return status;
  518. }
  519. static const int sim_fpu_class_mips_mapping[] = {
  520. FP_R6CLASS_SNAN, /* SIM_FPU_IS_SNAN = 1, Noisy not-a-number */
  521. FP_R6CLASS_QNAN, /* SIM_FPU_IS_QNAN = 2, Quiet not-a-number */
  522. FP_R6CLASS_NEGINF, /* SIM_FPU_IS_NINF = 3, -infinity */
  523. FP_R6CLASS_POSINF, /* SIM_FPU_IS_PINF = 4, +infinity */
  524. FP_R6CLASS_NEGNORM, /* SIM_FPU_IS_NNUMBER = 5, -num - [-MAX .. -MIN] */
  525. FP_R6CLASS_POSNORM, /* SIM_FPU_IS_PNUMBER = 6, +num - [+MIN .. +MAX] */
  526. FP_R6CLASS_NEGSUB, /* SIM_FPU_IS_NDENORM = 7, -denorm - (MIN .. 0) */
  527. FP_R6CLASS_POSSUB, /* SIM_FPU_IS_PDENORM = 8, +denorm - (0 .. MIN) */
  528. FP_R6CLASS_NEGZERO, /* SIM_FPU_IS_NZERO = 9, -0 */
  529. FP_R6CLASS_POSZERO /* SIM_FPU_IS_PZERO = 10, +0 */
  530. };
  531. uint64_t
  532. fp_classify (sim_cpu *cpu,
  533. address_word cia,
  534. uint64_t op,
  535. FP_formats fmt)
  536. {
  537. sim_fpu wop;
  538. switch (fmt)
  539. {
  540. case fmt_single:
  541. sim_fpu_32to (&wop, op);
  542. break;
  543. case fmt_double:
  544. sim_fpu_64to (&wop, op);
  545. break;
  546. default:
  547. sim_io_error (SD, "Bad switch\n");
  548. }
  549. return sim_fpu_class_mips_mapping[sim_fpu_classify (&wop) - 1];
  550. }
  551. int
  552. fp_rint (sim_cpu *cpu,
  553. address_word cia,
  554. uint64_t op,
  555. uint64_t *ans,
  556. FP_formats fmt)
  557. {
  558. sim_fpu wop = {0}, wtemp = {0}, wmagic = {0}, wans = {0};
  559. int64_t intermediate;
  560. int status = 0;
  561. sim_fpu_round round = rounding_mode (GETRM());
  562. switch (fmt)
  563. {
  564. case fmt_single:
  565. sim_fpu_32to (&wop, op);
  566. sim_fpu_32to (&wmagic, 0x4b000000);
  567. break;
  568. case fmt_double:
  569. sim_fpu_64to (&wop, op);
  570. sim_fpu_64to (&wmagic, 0x4330000000000000);
  571. break;
  572. default:
  573. sim_io_error (SD, "Bad switch\n");
  574. }
  575. if (sim_fpu_is_nan (&wop) || sim_fpu_is_infinity (&wop))
  576. {
  577. status = sim_fpu_status_invalid_cvi;
  578. update_fcsr (cpu, cia, status);
  579. return status;
  580. }
  581. switch (fmt)
  582. {
  583. case fmt_single:
  584. if (sim_fpu_is_ge (&wop, &wmagic))
  585. wans = wop;
  586. else
  587. {
  588. sim_fpu_add (&wtemp, &wop, &wmagic);
  589. sim_fpu_round_32 (&wtemp, round, sim_fpu_denorm_default);
  590. sim_fpu_sub (&wans, &wtemp, &wmagic);
  591. }
  592. sim_fpu_to32 ((uint32_t *) ans, &wans);
  593. break;
  594. case fmt_double:
  595. if (sim_fpu_is_ge (&wop, &wmagic))
  596. wans = wop;
  597. else
  598. {
  599. sim_fpu_add (&wtemp, &wop, &wmagic);
  600. sim_fpu_round_64 (&wtemp, round, sim_fpu_denorm_default);
  601. sim_fpu_sub (&wans, &wtemp, &wmagic);
  602. }
  603. sim_fpu_to64 (ans, &wans);
  604. break;
  605. default:
  606. sim_io_error (SD, "Bad switch\n");
  607. }
  608. if (*ans != op && status == 0)
  609. status = sim_fpu_status_inexact;
  610. update_fcsr (cpu, cia, status);
  611. return status;
  612. }
  613. void
  614. fp_cmp(sim_cpu *cpu,
  615. address_word cia,
  616. uint64_t op1,
  617. uint64_t op2,
  618. FP_formats fmt,
  619. int abs,
  620. int cond,
  621. int cc)
  622. {
  623. sim_fpu_status status = 0;
  624. /* The format type should already have been checked. The FCSR is
  625. updated before the condition codes so that any exceptions will
  626. be signalled before the condition codes are changed. */
  627. switch (fmt)
  628. {
  629. case fmt_single:
  630. case fmt_double:
  631. {
  632. int result;
  633. status = fp_test(op1, op2, fmt, abs, cond, &result);
  634. update_fcsr (cpu, cia, status);
  635. SETFCC (cc, result);
  636. break;
  637. }
  638. case fmt_ps:
  639. {
  640. int result0, result1;
  641. status = fp_test(FP_PS_lower (op1), FP_PS_lower (op2), fmt_single,
  642. abs, cond, &result0);
  643. status |= fp_test(FP_PS_upper (op1), FP_PS_upper (op2), fmt_single,
  644. abs, cond, &result1);
  645. update_fcsr (cpu, cia, status);
  646. SETFCC (cc, result0);
  647. SETFCC (cc+1, result1);
  648. break;
  649. }
  650. default:
  651. sim_io_error (SD, "Bad switch\n");
  652. }
  653. }
  654. uint64_t
  655. fp_r6_cmp (sim_cpu *cpu,
  656. address_word cia,
  657. uint64_t op1,
  658. uint64_t op2,
  659. FP_formats fmt,
  660. int cond)
  661. {
  662. sim_fpu wop1, wop2;
  663. int result = 0;
  664. int signalling = cond & 0x8;
  665. switch (fmt)
  666. {
  667. case fmt_single:
  668. sim_fpu_32to (&wop1, op1);
  669. sim_fpu_32to (&wop2, op2);
  670. break;
  671. case fmt_double:
  672. sim_fpu_64to (&wop1, op1);
  673. sim_fpu_64to (&wop2, op2);
  674. break;
  675. default:
  676. sim_io_error (SD, "Bad switch\n");
  677. }
  678. switch (cond)
  679. {
  680. case FP_R6CMP_AF:
  681. result = 0;
  682. break;
  683. case FP_R6CMP_UN:
  684. result = sim_fpu_is_un (&wop1, &wop2);
  685. break;
  686. case FP_R6CMP_OR:
  687. result = sim_fpu_is_or (&wop1, &wop2);
  688. break;
  689. case FP_R6CMP_EQ:
  690. result = sim_fpu_is_eq (&wop1, &wop2);
  691. break;
  692. case FP_R6CMP_NE:
  693. result = sim_fpu_is_ne (&wop1, &wop2);
  694. break;
  695. case FP_R6CMP_LT:
  696. result = sim_fpu_is_lt (&wop1, &wop2);
  697. break;
  698. case FP_R6CMP_LE:
  699. result = sim_fpu_is_le (&wop1, &wop2);
  700. break;
  701. case FP_R6CMP_UEQ:
  702. result = sim_fpu_is_un (&wop1, &wop2) || sim_fpu_is_eq (&wop1, &wop2);
  703. break;
  704. case FP_R6CMP_UNE:
  705. result = sim_fpu_is_un (&wop1, &wop2) || sim_fpu_is_ne (&wop1, &wop2);
  706. break;
  707. case FP_R6CMP_ULT:
  708. result = sim_fpu_is_un (&wop1, &wop2) || sim_fpu_is_lt (&wop1, &wop2);
  709. break;
  710. case FP_R6CMP_ULE:
  711. result = sim_fpu_is_un (&wop1, &wop2) || sim_fpu_is_le (&wop1, &wop2);
  712. break;
  713. default:
  714. update_fcsr (cpu, cia, sim_fpu_status_invalid_cmp);
  715. break;
  716. }
  717. if (result)
  718. {
  719. switch (fmt)
  720. {
  721. case fmt_single:
  722. return 0xFFFFFFFF;
  723. case fmt_double:
  724. return 0xFFFFFFFFFFFFFFFF;
  725. default:
  726. sim_io_error (SD, "Bad switch\n");
  727. }
  728. }
  729. else
  730. return 0;
  731. }
  732. /* Basic arithmetic operations. */
  733. static uint64_t
  734. fp_unary(sim_cpu *cpu,
  735. address_word cia,
  736. int (*sim_fpu_op)(sim_fpu *, const sim_fpu *),
  737. uint64_t op,
  738. FP_formats fmt)
  739. {
  740. sim_fpu wop = {0};
  741. sim_fpu ans;
  742. sim_fpu_round round = rounding_mode (GETRM());
  743. sim_fpu_denorm denorm = denorm_mode (cpu);
  744. sim_fpu_status status = 0;
  745. uint64_t result = 0;
  746. /* The format type has already been checked: */
  747. switch (fmt)
  748. {
  749. case fmt_single:
  750. {
  751. uint32_t res;
  752. sim_fpu_32to (&wop, op);
  753. status |= (*sim_fpu_op) (&ans, &wop);
  754. status |= sim_fpu_round_32 (&ans, round, denorm);
  755. sim_fpu_to32 (&res, &ans);
  756. result = res;
  757. break;
  758. }
  759. case fmt_double:
  760. {
  761. uint64_t res;
  762. sim_fpu_64to (&wop, op);
  763. status |= (*sim_fpu_op) (&ans, &wop);
  764. status |= sim_fpu_round_64 (&ans, round, denorm);
  765. sim_fpu_to64 (&res, &ans);
  766. result = res;
  767. break;
  768. }
  769. case fmt_ps:
  770. {
  771. int status_u = 0, status_l = 0;
  772. uint32_t res_u, res_l;
  773. sim_fpu_32to (&wop, FP_PS_upper(op));
  774. status_u |= (*sim_fpu_op) (&ans, &wop);
  775. sim_fpu_to32 (&res_u, &ans);
  776. sim_fpu_32to (&wop, FP_PS_lower(op));
  777. status_l |= (*sim_fpu_op) (&ans, &wop);
  778. sim_fpu_to32 (&res_l, &ans);
  779. result = FP_PS_cat(res_u, res_l);
  780. status = status_u | status_l;
  781. break;
  782. }
  783. default:
  784. sim_io_error (SD, "Bad switch\n");
  785. }
  786. update_fcsr (cpu, cia, status);
  787. return result;
  788. }
  789. static uint64_t
  790. fp_binary(sim_cpu *cpu,
  791. address_word cia,
  792. int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
  793. uint64_t op1,
  794. uint64_t op2,
  795. FP_formats fmt)
  796. {
  797. sim_fpu wop1 = {0};
  798. sim_fpu wop2 = {0};
  799. sim_fpu ans = {0};
  800. sim_fpu_round round = rounding_mode (GETRM());
  801. sim_fpu_denorm denorm = denorm_mode (cpu);
  802. sim_fpu_status status = 0;
  803. uint64_t result = 0;
  804. /* The format type has already been checked: */
  805. switch (fmt)
  806. {
  807. case fmt_single:
  808. {
  809. uint32_t res;
  810. sim_fpu_32to (&wop1, op1);
  811. sim_fpu_32to (&wop2, op2);
  812. status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
  813. status |= sim_fpu_round_32 (&ans, round, denorm);
  814. sim_fpu_to32 (&res, &ans);
  815. result = res;
  816. break;
  817. }
  818. case fmt_double:
  819. {
  820. uint64_t res;
  821. sim_fpu_64to (&wop1, op1);
  822. sim_fpu_64to (&wop2, op2);
  823. status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
  824. status |= sim_fpu_round_64 (&ans, round, denorm);
  825. sim_fpu_to64 (&res, &ans);
  826. result = res;
  827. break;
  828. }
  829. case fmt_ps:
  830. {
  831. int status_u = 0, status_l = 0;
  832. uint32_t res_u, res_l;
  833. sim_fpu_32to (&wop1, FP_PS_upper(op1));
  834. sim_fpu_32to (&wop2, FP_PS_upper(op2));
  835. status_u |= (*sim_fpu_op) (&ans, &wop1, &wop2);
  836. sim_fpu_to32 (&res_u, &ans);
  837. sim_fpu_32to (&wop1, FP_PS_lower(op1));
  838. sim_fpu_32to (&wop2, FP_PS_lower(op2));
  839. status_l |= (*sim_fpu_op) (&ans, &wop1, &wop2);
  840. sim_fpu_to32 (&res_l, &ans);
  841. result = FP_PS_cat(res_u, res_l);
  842. status = status_u | status_l;
  843. break;
  844. }
  845. default:
  846. sim_io_error (SD, "Bad switch\n");
  847. }
  848. update_fcsr (cpu, cia, status);
  849. return result;
  850. }
  851. /* Common MAC code for single operands (.s or .d), defers setting FCSR. */
  852. static sim_fpu_status
  853. inner_mac(int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
  854. uint64_t op1,
  855. uint64_t op2,
  856. uint64_t op3,
  857. int scale,
  858. int negate,
  859. FP_formats fmt,
  860. sim_fpu_round round,
  861. sim_fpu_denorm denorm,
  862. uint64_t *result)
  863. {
  864. sim_fpu wop1;
  865. sim_fpu wop2;
  866. sim_fpu ans;
  867. sim_fpu_status status = 0;
  868. sim_fpu_status op_status;
  869. uint64_t temp = 0;
  870. switch (fmt)
  871. {
  872. case fmt_single:
  873. {
  874. uint32_t res;
  875. sim_fpu_32to (&wop1, op1);
  876. sim_fpu_32to (&wop2, op2);
  877. status |= sim_fpu_mul (&ans, &wop1, &wop2);
  878. if (scale != 0 && sim_fpu_is_number (&ans)) /* number or denorm */
  879. ans.normal_exp += scale;
  880. status |= sim_fpu_round_32 (&ans, round, denorm);
  881. wop1 = ans;
  882. op_status = 0;
  883. sim_fpu_32to (&wop2, op3);
  884. op_status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
  885. op_status |= sim_fpu_round_32 (&ans, round, denorm);
  886. status |= op_status;
  887. if (negate)
  888. {
  889. wop1 = ans;
  890. op_status = sim_fpu_neg (&ans, &wop1);
  891. op_status |= sim_fpu_round_32 (&ans, round, denorm);
  892. status |= op_status;
  893. }
  894. sim_fpu_to32 (&res, &ans);
  895. temp = res;
  896. break;
  897. }
  898. case fmt_double:
  899. {
  900. uint64_t res;
  901. sim_fpu_64to (&wop1, op1);
  902. sim_fpu_64to (&wop2, op2);
  903. status |= sim_fpu_mul (&ans, &wop1, &wop2);
  904. if (scale != 0 && sim_fpu_is_number (&ans)) /* number or denorm */
  905. ans.normal_exp += scale;
  906. status |= sim_fpu_round_64 (&ans, round, denorm);
  907. wop1 = ans;
  908. op_status = 0;
  909. sim_fpu_64to (&wop2, op3);
  910. op_status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
  911. op_status |= sim_fpu_round_64 (&ans, round, denorm);
  912. status |= op_status;
  913. if (negate)
  914. {
  915. wop1 = ans;
  916. op_status = sim_fpu_neg (&ans, &wop1);
  917. op_status |= sim_fpu_round_64 (&ans, round, denorm);
  918. status |= op_status;
  919. }
  920. sim_fpu_to64 (&res, &ans);
  921. temp = res;
  922. break;
  923. }
  924. default:
  925. fprintf (stderr, "Bad switch\n");
  926. abort ();
  927. }
  928. *result = temp;
  929. return status;
  930. }
  931. /* Common implementation of madd, nmadd, msub, nmsub that does
  932. intermediate rounding per spec. Also used for recip2 and rsqrt2,
  933. which are transformed into equivalent nmsub operations. The scale
  934. argument is an adjustment to the exponent of the intermediate
  935. product op1*op2. It is currently non-zero for rsqrt2 (-1), which
  936. requires an effective division by 2. */
  937. static uint64_t
  938. fp_mac(sim_cpu *cpu,
  939. address_word cia,
  940. int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
  941. uint64_t op1,
  942. uint64_t op2,
  943. uint64_t op3,
  944. int scale,
  945. int negate,
  946. FP_formats fmt)
  947. {
  948. sim_fpu_round round = rounding_mode (GETRM());
  949. sim_fpu_denorm denorm = denorm_mode (cpu);
  950. sim_fpu_status status = 0;
  951. uint64_t result = 0;
  952. /* The format type has already been checked: */
  953. switch (fmt)
  954. {
  955. case fmt_single:
  956. case fmt_double:
  957. status = inner_mac(sim_fpu_op, op1, op2, op3, scale,
  958. negate, fmt, round, denorm, &result);
  959. break;
  960. case fmt_ps:
  961. {
  962. int status_u, status_l;
  963. uint64_t result_u, result_l;
  964. status_u = inner_mac(sim_fpu_op, FP_PS_upper(op1), FP_PS_upper(op2),
  965. FP_PS_upper(op3), scale, negate, fmt_single,
  966. round, denorm, &result_u);
  967. status_l = inner_mac(sim_fpu_op, FP_PS_lower(op1), FP_PS_lower(op2),
  968. FP_PS_lower(op3), scale, negate, fmt_single,
  969. round, denorm, &result_l);
  970. result = FP_PS_cat(result_u, result_l);
  971. status = status_u | status_l;
  972. break;
  973. }
  974. default:
  975. sim_io_error (SD, "Bad switch\n");
  976. }
  977. update_fcsr (cpu, cia, status);
  978. return result;
  979. }
  980. /* Common FMAC code for .s, .d. Defers setting FCSR to caller. */
  981. static sim_fpu_status
  982. inner_fmac (sim_cpu *cpu,
  983. int (*sim_fpu_op) (sim_fpu *, const sim_fpu *, const sim_fpu *),
  984. uint64_t op1,
  985. uint64_t op2,
  986. uint64_t op3,
  987. sim_fpu_round round,
  988. sim_fpu_denorm denorm,
  989. FP_formats fmt,
  990. uint64_t *result)
  991. {
  992. sim_fpu wop1, wop2, ans;
  993. sim_fpu_status status = 0;
  994. sim_fpu_status op_status;
  995. uint32_t t32 = 0;
  996. uint64_t t64 = 0;
  997. switch (fmt)
  998. {
  999. case fmt_single:
  1000. sim_fpu_32to (&wop1, op1);
  1001. sim_fpu_32to (&wop2, op2);
  1002. status |= sim_fpu_mul (&ans, &wop1, &wop2);
  1003. wop1 = ans;
  1004. op_status = 0;
  1005. sim_fpu_32to (&wop2, op3);
  1006. op_status |= (*sim_fpu_op) (&ans, &wop2, &wop1);
  1007. op_status |= sim_fpu_round_32 (&ans, round, denorm);
  1008. status |= op_status;
  1009. sim_fpu_to32 (&t32, &ans);
  1010. t64 = t32;
  1011. break;
  1012. case fmt_double:
  1013. sim_fpu_64to (&wop1, op1);
  1014. sim_fpu_64to (&wop2, op2);
  1015. status |= sim_fpu_mul (&ans, &wop1, &wop2);
  1016. wop1 = ans;
  1017. op_status = 0;
  1018. sim_fpu_64to (&wop2, op3);
  1019. op_status |= (*sim_fpu_op) (&ans, &wop2, &wop1);
  1020. op_status |= sim_fpu_round_64 (&ans, round, denorm);
  1021. status |= op_status;
  1022. sim_fpu_to64 (&t64, &ans);
  1023. break;
  1024. default:
  1025. sim_io_error (SD, "Bad switch\n");
  1026. }
  1027. *result = t64;
  1028. return status;
  1029. }
  1030. static uint64_t
  1031. fp_fmac (sim_cpu *cpu,
  1032. address_word cia,
  1033. int (*sim_fpu_op) (sim_fpu *, const sim_fpu *, const sim_fpu *),
  1034. uint64_t op1,
  1035. uint64_t op2,
  1036. uint64_t op3,
  1037. FP_formats fmt)
  1038. {
  1039. sim_fpu_round round = rounding_mode (GETRM());
  1040. sim_fpu_denorm denorm = denorm_mode (cpu);
  1041. sim_fpu_status status = 0;
  1042. uint64_t result = 0;
  1043. switch (fmt)
  1044. {
  1045. case fmt_single:
  1046. case fmt_double:
  1047. status = inner_fmac (cpu, sim_fpu_op, op1, op2, op3,
  1048. round, denorm, fmt, &result);
  1049. break;
  1050. default:
  1051. sim_io_error (SD, "Bad switch\n");
  1052. }
  1053. update_fcsr (cpu, cia, status);
  1054. return result;
  1055. }
  1056. /* Common rsqrt code for single operands (.s or .d), intermediate rounding. */
  1057. static sim_fpu_status
  1058. inner_rsqrt(uint64_t op1,
  1059. FP_formats fmt,
  1060. sim_fpu_round round,
  1061. sim_fpu_denorm denorm,
  1062. uint64_t *result)
  1063. {
  1064. sim_fpu wop1;
  1065. sim_fpu ans;
  1066. sim_fpu_status status = 0;
  1067. sim_fpu_status op_status;
  1068. uint64_t temp = 0;
  1069. switch (fmt)
  1070. {
  1071. case fmt_single:
  1072. {
  1073. uint32_t res;
  1074. sim_fpu_32to (&wop1, op1);
  1075. status |= sim_fpu_sqrt (&ans, &wop1);
  1076. status |= sim_fpu_round_32 (&ans, status, round);
  1077. wop1 = ans;
  1078. op_status = sim_fpu_inv (&ans, &wop1);
  1079. op_status |= sim_fpu_round_32 (&ans, round, denorm);
  1080. sim_fpu_to32 (&res, &ans);
  1081. temp = res;
  1082. status |= op_status;
  1083. break;
  1084. }
  1085. case fmt_double:
  1086. {
  1087. uint64_t res;
  1088. sim_fpu_64to (&wop1, op1);
  1089. status |= sim_fpu_sqrt (&ans, &wop1);
  1090. status |= sim_fpu_round_64 (&ans, round, denorm);
  1091. wop1 = ans;
  1092. op_status = sim_fpu_inv (&ans, &wop1);
  1093. op_status |= sim_fpu_round_64 (&ans, round, denorm);
  1094. sim_fpu_to64 (&res, &ans);
  1095. temp = res;
  1096. status |= op_status;
  1097. break;
  1098. }
  1099. default:
  1100. fprintf (stderr, "Bad switch\n");
  1101. abort ();
  1102. }
  1103. *result = temp;
  1104. return status;
  1105. }
  1106. static uint64_t
  1107. fp_inv_sqrt(sim_cpu *cpu,
  1108. address_word cia,
  1109. uint64_t op1,
  1110. FP_formats fmt)
  1111. {
  1112. sim_fpu_round round = rounding_mode (GETRM());
  1113. sim_fpu_round denorm = denorm_mode (cpu);
  1114. sim_fpu_status status = 0;
  1115. uint64_t result = 0;
  1116. /* The format type has already been checked: */
  1117. switch (fmt)
  1118. {
  1119. case fmt_single:
  1120. case fmt_double:
  1121. status = inner_rsqrt (op1, fmt, round, denorm, &result);
  1122. break;
  1123. case fmt_ps:
  1124. {
  1125. int status_u, status_l;
  1126. uint64_t result_u, result_l;
  1127. status_u = inner_rsqrt (FP_PS_upper(op1), fmt_single, round, denorm,
  1128. &result_u);
  1129. status_l = inner_rsqrt (FP_PS_lower(op1), fmt_single, round, denorm,
  1130. &result_l);
  1131. result = FP_PS_cat(result_u, result_l);
  1132. status = status_u | status_l;
  1133. break;
  1134. }
  1135. default:
  1136. sim_io_error (SD, "Bad switch\n");
  1137. }
  1138. update_fcsr (cpu, cia, status);
  1139. return result;
  1140. }
  1141. uint64_t
  1142. fp_abs(sim_cpu *cpu,
  1143. address_word cia,
  1144. uint64_t op,
  1145. FP_formats fmt)
  1146. {
  1147. return fp_unary(cpu, cia, &sim_fpu_abs, op, fmt);
  1148. }
  1149. uint64_t
  1150. fp_neg(sim_cpu *cpu,
  1151. address_word cia,
  1152. uint64_t op,
  1153. FP_formats fmt)
  1154. {
  1155. return fp_unary(cpu, cia, &sim_fpu_neg, op, fmt);
  1156. }
  1157. uint64_t
  1158. fp_add(sim_cpu *cpu,
  1159. address_word cia,
  1160. uint64_t op1,
  1161. uint64_t op2,
  1162. FP_formats fmt)
  1163. {
  1164. return fp_binary(cpu, cia, &sim_fpu_add, op1, op2, fmt);
  1165. }
  1166. uint64_t
  1167. fp_sub(sim_cpu *cpu,
  1168. address_word cia,
  1169. uint64_t op1,
  1170. uint64_t op2,
  1171. FP_formats fmt)
  1172. {
  1173. return fp_binary(cpu, cia, &sim_fpu_sub, op1, op2, fmt);
  1174. }
  1175. uint64_t
  1176. fp_mul(sim_cpu *cpu,
  1177. address_word cia,
  1178. uint64_t op1,
  1179. uint64_t op2,
  1180. FP_formats fmt)
  1181. {
  1182. return fp_binary(cpu, cia, &sim_fpu_mul, op1, op2, fmt);
  1183. }
  1184. uint64_t
  1185. fp_div(sim_cpu *cpu,
  1186. address_word cia,
  1187. uint64_t op1,
  1188. uint64_t op2,
  1189. FP_formats fmt)
  1190. {
  1191. return fp_binary(cpu, cia, &sim_fpu_div, op1, op2, fmt);
  1192. }
  1193. uint64_t
  1194. fp_min (sim_cpu *cpu,
  1195. address_word cia,
  1196. uint64_t op1,
  1197. uint64_t op2,
  1198. FP_formats fmt)
  1199. {
  1200. return fp_binary (cpu, cia, &sim_fpu_min, op1, op2, fmt);
  1201. }
  1202. uint64_t
  1203. fp_max (sim_cpu *cpu,
  1204. address_word cia,
  1205. uint64_t op1,
  1206. uint64_t op2,
  1207. FP_formats fmt)
  1208. {
  1209. return fp_binary (cpu, cia, &sim_fpu_max, op1, op2, fmt);
  1210. }
  1211. uint64_t
  1212. fp_mina (sim_cpu *cpu,
  1213. address_word cia,
  1214. uint64_t op1,
  1215. uint64_t op2,
  1216. FP_formats fmt)
  1217. {
  1218. uint64_t ret;
  1219. sim_fpu wop1 = {0}, wop2 = {0}, waop1, waop2, wans;
  1220. sim_fpu_status status = 0;
  1221. switch (fmt)
  1222. {
  1223. case fmt_single:
  1224. sim_fpu_32to (&wop1, op1);
  1225. sim_fpu_32to (&wop2, op2);
  1226. break;
  1227. case fmt_double:
  1228. sim_fpu_64to (&wop1, op1);
  1229. sim_fpu_64to (&wop2, op2);
  1230. break;
  1231. default:
  1232. sim_io_error (SD, "Bad switch\n");
  1233. }
  1234. status |= sim_fpu_abs (&waop1, &wop1);
  1235. status |= sim_fpu_abs (&waop2, &wop2);
  1236. status |= sim_fpu_min (&wans, &waop1, &waop2);
  1237. ret = (sim_fpu_is_eq (&wans, &waop1)) ? op1 : op2;
  1238. update_fcsr (cpu, cia, status);
  1239. return ret;
  1240. }
  1241. uint64_t
  1242. fp_maxa (sim_cpu *cpu,
  1243. address_word cia,
  1244. uint64_t op1,
  1245. uint64_t op2,
  1246. FP_formats fmt)
  1247. {
  1248. uint64_t ret;
  1249. sim_fpu wop1 = {0}, wop2 = {0}, waop1, waop2, wans;
  1250. sim_fpu_status status = 0;
  1251. switch (fmt)
  1252. {
  1253. case fmt_single:
  1254. sim_fpu_32to (&wop1, op1);
  1255. sim_fpu_32to (&wop2, op2);
  1256. break;
  1257. case fmt_double:
  1258. sim_fpu_64to (&wop1, op1);
  1259. sim_fpu_64to (&wop2, op2);
  1260. break;
  1261. default:
  1262. sim_io_error (SD, "Bad switch\n");
  1263. }
  1264. status |= sim_fpu_abs (&waop1, &wop1);
  1265. status |= sim_fpu_abs (&waop2, &wop2);
  1266. status |= sim_fpu_max (&wans, &waop1, &waop2);
  1267. ret = (sim_fpu_is_eq (&wans, &waop1)) ? op1 : op2;
  1268. update_fcsr (cpu, cia, status);
  1269. return ret;
  1270. }
  1271. uint64_t
  1272. fp_recip(sim_cpu *cpu,
  1273. address_word cia,
  1274. uint64_t op,
  1275. FP_formats fmt)
  1276. {
  1277. return fp_unary(cpu, cia, &sim_fpu_inv, op, fmt);
  1278. }
  1279. uint64_t
  1280. fp_sqrt(sim_cpu *cpu,
  1281. address_word cia,
  1282. uint64_t op,
  1283. FP_formats fmt)
  1284. {
  1285. return fp_unary(cpu, cia, &sim_fpu_sqrt, op, fmt);
  1286. }
  1287. uint64_t
  1288. fp_rsqrt(sim_cpu *cpu,
  1289. address_word cia,
  1290. uint64_t op,
  1291. FP_formats fmt)
  1292. {
  1293. return fp_inv_sqrt(cpu, cia, op, fmt);
  1294. }
  1295. uint64_t
  1296. fp_madd(sim_cpu *cpu,
  1297. address_word cia,
  1298. uint64_t op1,
  1299. uint64_t op2,
  1300. uint64_t op3,
  1301. FP_formats fmt)
  1302. {
  1303. return fp_mac(cpu, cia, &sim_fpu_add, op1, op2, op3, 0, 0, fmt);
  1304. }
  1305. uint64_t
  1306. fp_msub(sim_cpu *cpu,
  1307. address_word cia,
  1308. uint64_t op1,
  1309. uint64_t op2,
  1310. uint64_t op3,
  1311. FP_formats fmt)
  1312. {
  1313. return fp_mac(cpu, cia, &sim_fpu_sub, op1, op2, op3, 0, 0, fmt);
  1314. }
  1315. uint64_t
  1316. fp_fmadd (sim_cpu *cpu,
  1317. address_word cia,
  1318. uint64_t op1,
  1319. uint64_t op2,
  1320. uint64_t op3,
  1321. FP_formats fmt)
  1322. {
  1323. return fp_fmac (cpu, cia, &sim_fpu_add, op1, op2, op3, fmt);
  1324. }
  1325. uint64_t
  1326. fp_fmsub (sim_cpu *cpu,
  1327. address_word cia,
  1328. uint64_t op1,
  1329. uint64_t op2,
  1330. uint64_t op3,
  1331. FP_formats fmt)
  1332. {
  1333. return fp_fmac (cpu, cia, &sim_fpu_sub, op1, op2, op3, fmt);
  1334. }
  1335. uint64_t
  1336. fp_nmadd(sim_cpu *cpu,
  1337. address_word cia,
  1338. uint64_t op1,
  1339. uint64_t op2,
  1340. uint64_t op3,
  1341. FP_formats fmt)
  1342. {
  1343. return fp_mac(cpu, cia, &sim_fpu_add, op1, op2, op3, 0, 1, fmt);
  1344. }
  1345. uint64_t
  1346. fp_nmsub(sim_cpu *cpu,
  1347. address_word cia,
  1348. uint64_t op1,
  1349. uint64_t op2,
  1350. uint64_t op3,
  1351. FP_formats fmt)
  1352. {
  1353. return fp_mac(cpu, cia, &sim_fpu_sub, op1, op2, op3, 0, 1, fmt);
  1354. }
  1355. /* MIPS-3D ASE operations. */
  1356. /* Variant of fp_binary for *r.ps MIPS-3D operations. */
  1357. static uint64_t
  1358. fp_binary_r(sim_cpu *cpu,
  1359. address_word cia,
  1360. int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
  1361. uint64_t op1,
  1362. uint64_t op2)
  1363. {
  1364. sim_fpu wop1;
  1365. sim_fpu wop2;
  1366. sim_fpu ans;
  1367. sim_fpu_round round = rounding_mode (GETRM ());
  1368. sim_fpu_denorm denorm = denorm_mode (cpu);
  1369. sim_fpu_status status_u, status_l;
  1370. uint64_t result;
  1371. uint32_t res_u, res_l;
  1372. /* The format must be fmt_ps. */
  1373. status_u = 0;
  1374. sim_fpu_32to (&wop1, FP_PS_upper (op1));
  1375. sim_fpu_32to (&wop2, FP_PS_lower (op1));
  1376. status_u |= (*sim_fpu_op) (&ans, &wop1, &wop2);
  1377. status_u |= sim_fpu_round_32 (&ans, round, denorm);
  1378. sim_fpu_to32 (&res_u, &ans);
  1379. status_l = 0;
  1380. sim_fpu_32to (&wop1, FP_PS_upper (op2));
  1381. sim_fpu_32to (&wop2, FP_PS_lower (op2));
  1382. status_l |= (*sim_fpu_op) (&ans, &wop1, &wop2);
  1383. status_l |= sim_fpu_round_32 (&ans, round, denorm);
  1384. sim_fpu_to32 (&res_l, &ans);
  1385. result = FP_PS_cat (res_u, res_l);
  1386. update_fcsr (cpu, cia, status_u | status_l);
  1387. return result;
  1388. }
  1389. uint64_t
  1390. fp_add_r(sim_cpu *cpu,
  1391. address_word cia,
  1392. uint64_t op1,
  1393. uint64_t op2,
  1394. FP_formats fmt)
  1395. {
  1396. return fp_binary_r (cpu, cia, &sim_fpu_add, op1, op2);
  1397. }
  1398. uint64_t
  1399. fp_mul_r(sim_cpu *cpu,
  1400. address_word cia,
  1401. uint64_t op1,
  1402. uint64_t op2,
  1403. FP_formats fmt)
  1404. {
  1405. return fp_binary_r (cpu, cia, &sim_fpu_mul, op1, op2);
  1406. }
  1407. #define NR_FRAC_GUARD (60)
  1408. #define IMPLICIT_1 LSBIT64 (NR_FRAC_GUARD)
  1409. static int
  1410. fpu_inv1(sim_fpu *f, const sim_fpu *l)
  1411. {
  1412. static const sim_fpu sim_fpu_one = {
  1413. sim_fpu_class_number, 0, IMPLICIT_1, 0
  1414. };
  1415. int status = 0;
  1416. sim_fpu t;
  1417. if (sim_fpu_is_zero (l))
  1418. {
  1419. *f = sim_fpu_maxfp;
  1420. f->sign = l->sign;
  1421. return sim_fpu_status_invalid_div0;
  1422. }
  1423. if (sim_fpu_is_infinity (l))
  1424. {
  1425. *f = sim_fpu_zero;
  1426. f->sign = l->sign;
  1427. return status;
  1428. }
  1429. status |= sim_fpu_div (f, &sim_fpu_one, l);
  1430. return status;
  1431. }
  1432. static int
  1433. fpu_inv1_32(sim_fpu *f, const sim_fpu *l)
  1434. {
  1435. if (sim_fpu_is_zero (l))
  1436. {
  1437. *f = sim_fpu_max32;
  1438. f->sign = l->sign;
  1439. return sim_fpu_status_invalid_div0;
  1440. }
  1441. return fpu_inv1 (f, l);
  1442. }
  1443. static int
  1444. fpu_inv1_64(sim_fpu *f, const sim_fpu *l)
  1445. {
  1446. if (sim_fpu_is_zero (l))
  1447. {
  1448. *f = sim_fpu_max64;
  1449. f->sign = l->sign;
  1450. return sim_fpu_status_invalid_div0;
  1451. }
  1452. return fpu_inv1 (f, l);
  1453. }
  1454. uint64_t
  1455. fp_recip1(sim_cpu *cpu,
  1456. address_word cia,
  1457. uint64_t op,
  1458. FP_formats fmt)
  1459. {
  1460. switch (fmt)
  1461. {
  1462. case fmt_single:
  1463. case fmt_ps:
  1464. return fp_unary (cpu, cia, &fpu_inv1_32, op, fmt);
  1465. case fmt_double:
  1466. return fp_unary (cpu, cia, &fpu_inv1_64, op, fmt);
  1467. }
  1468. return 0;
  1469. }
  1470. uint64_t
  1471. fp_recip2(sim_cpu *cpu,
  1472. address_word cia,
  1473. uint64_t op1,
  1474. uint64_t op2,
  1475. FP_formats fmt)
  1476. {
  1477. static const uint64_t one_single = UNSIGNED64 (0x3F800000);
  1478. static const uint64_t one_double = UNSIGNED64 (0x3FF0000000000000);
  1479. static const uint64_t one_ps = (UNSIGNED64 (0x3F800000) << 32 | UNSIGNED64 (0x3F800000));
  1480. uint64_t one;
  1481. /* Implemented as nmsub fd, 1, fs, ft. */
  1482. switch (fmt)
  1483. {
  1484. case fmt_single: one = one_single; break;
  1485. case fmt_double: one = one_double; break;
  1486. case fmt_ps: one = one_ps; break;
  1487. default: one = 0; abort ();
  1488. }
  1489. return fp_mac (cpu, cia, &sim_fpu_sub, op1, op2, one, 0, 1, fmt);
  1490. }
  1491. static int
  1492. fpu_inv_sqrt1(sim_fpu *f, const sim_fpu *l)
  1493. {
  1494. static const sim_fpu sim_fpu_one = {
  1495. sim_fpu_class_number, 0, IMPLICIT_1, 0
  1496. };
  1497. int status = 0;
  1498. sim_fpu t;
  1499. if (sim_fpu_is_zero (l))
  1500. {
  1501. *f = sim_fpu_maxfp;
  1502. f->sign = l->sign;
  1503. return sim_fpu_status_invalid_div0;
  1504. }
  1505. if (sim_fpu_is_infinity (l))
  1506. {
  1507. if (!l->sign)
  1508. {
  1509. f->class = sim_fpu_class_zero;
  1510. f->sign = 0;
  1511. }
  1512. else
  1513. {
  1514. *f = sim_fpu_qnan;
  1515. status = sim_fpu_status_invalid_sqrt;
  1516. }
  1517. return status;
  1518. }
  1519. status |= sim_fpu_sqrt (&t, l);
  1520. status |= sim_fpu_div (f, &sim_fpu_one, &t);
  1521. return status;
  1522. }
  1523. static int
  1524. fpu_inv_sqrt1_32(sim_fpu *f, const sim_fpu *l)
  1525. {
  1526. if (sim_fpu_is_zero (l))
  1527. {
  1528. *f = sim_fpu_max32;
  1529. f->sign = l->sign;
  1530. return sim_fpu_status_invalid_div0;
  1531. }
  1532. return fpu_inv_sqrt1 (f, l);
  1533. }
  1534. static int
  1535. fpu_inv_sqrt1_64(sim_fpu *f, const sim_fpu *l)
  1536. {
  1537. if (sim_fpu_is_zero (l))
  1538. {
  1539. *f = sim_fpu_max64;
  1540. f->sign = l->sign;
  1541. return sim_fpu_status_invalid_div0;
  1542. }
  1543. return fpu_inv_sqrt1 (f, l);
  1544. }
  1545. uint64_t
  1546. fp_rsqrt1(sim_cpu *cpu,
  1547. address_word cia,
  1548. uint64_t op,
  1549. FP_formats fmt)
  1550. {
  1551. switch (fmt)
  1552. {
  1553. case fmt_single:
  1554. case fmt_ps:
  1555. return fp_unary (cpu, cia, &fpu_inv_sqrt1_32, op, fmt);
  1556. case fmt_double:
  1557. return fp_unary (cpu, cia, &fpu_inv_sqrt1_64, op, fmt);
  1558. }
  1559. return 0;
  1560. }
  1561. uint64_t
  1562. fp_rsqrt2(sim_cpu *cpu,
  1563. address_word cia,
  1564. uint64_t op1,
  1565. uint64_t op2,
  1566. FP_formats fmt)
  1567. {
  1568. static const uint64_t half_single = UNSIGNED64 (0x3F000000);
  1569. static const uint64_t half_double = UNSIGNED64 (0x3FE0000000000000);
  1570. static const uint64_t half_ps = (UNSIGNED64 (0x3F000000) << 32 | UNSIGNED64 (0x3F000000));
  1571. uint64_t half;
  1572. /* Implemented as (nmsub fd, 0.5, fs, ft)/2, where the divide is
  1573. done by scaling the exponent during multiply. */
  1574. switch (fmt)
  1575. {
  1576. case fmt_single: half = half_single; break;
  1577. case fmt_double: half = half_double; break;
  1578. case fmt_ps: half = half_ps; break;
  1579. default: half = 0; abort ();
  1580. }
  1581. return fp_mac (cpu, cia, &sim_fpu_sub, op1, op2, half, -1, 1, fmt);
  1582. }
  1583. /* Conversion operations. */
  1584. uword64
  1585. convert (sim_cpu *cpu,
  1586. address_word cia,
  1587. int rm,
  1588. uword64 op,
  1589. FP_formats from,
  1590. FP_formats to)
  1591. {
  1592. sim_fpu wop;
  1593. sim_fpu_round round = rounding_mode (rm);
  1594. sim_fpu_denorm denorm = denorm_mode (cpu);
  1595. uint32_t result32;
  1596. uint64_t result64;
  1597. sim_fpu_status status = 0;
  1598. /* Convert the input to sim_fpu internal format */
  1599. switch (from)
  1600. {
  1601. case fmt_double:
  1602. sim_fpu_64to (&wop, op);
  1603. break;
  1604. case fmt_single:
  1605. sim_fpu_32to (&wop, op);
  1606. break;
  1607. case fmt_word:
  1608. status = sim_fpu_i32to (&wop, op, round);
  1609. break;
  1610. case fmt_long:
  1611. status = sim_fpu_i64to (&wop, op, round);
  1612. break;
  1613. default:
  1614. sim_io_error (SD, "Bad switch\n");
  1615. }
  1616. /* Convert sim_fpu format into the output */
  1617. /* The value WOP is converted to the destination format, rounding
  1618. using mode RM. When the destination is a fixed-point format, then
  1619. a source value of Infinity, NaN or one which would round to an
  1620. integer outside the fixed point range then an IEEE Invalid Operation
  1621. condition is raised. Not used if destination format is PS. */
  1622. switch (to)
  1623. {
  1624. case fmt_single:
  1625. status |= sim_fpu_round_32 (&wop, round, denorm);
  1626. /* For a NaN, normalize mantissa bits (cvt.s.d can't preserve them) */
  1627. if (sim_fpu_is_qnan (&wop))
  1628. wop = sim_fpu_qnan;
  1629. sim_fpu_to32 (&result32, &wop);
  1630. result64 = result32;
  1631. break;
  1632. case fmt_double:
  1633. status |= sim_fpu_round_64 (&wop, round, denorm);
  1634. /* For a NaN, normalize mantissa bits (make cvt.d.s consistent) */
  1635. if (sim_fpu_is_qnan (&wop))
  1636. wop = sim_fpu_qnan;
  1637. sim_fpu_to64 (&result64, &wop);
  1638. break;
  1639. case fmt_word:
  1640. status |= sim_fpu_to32u (&result32, &wop, round);
  1641. result64 = result32;
  1642. break;
  1643. case fmt_long:
  1644. status |= sim_fpu_to64u (&result64, &wop, round);
  1645. break;
  1646. default:
  1647. result64 = 0;
  1648. sim_io_error (SD, "Bad switch\n");
  1649. }
  1650. update_fcsr (cpu, cia, status);
  1651. return result64;
  1652. }
  1653. uint64_t
  1654. ps_lower(sim_cpu *cpu,
  1655. address_word cia,
  1656. uint64_t op)
  1657. {
  1658. return FP_PS_lower (op);
  1659. }
  1660. uint64_t
  1661. ps_upper(sim_cpu *cpu,
  1662. address_word cia,
  1663. uint64_t op)
  1664. {
  1665. return FP_PS_upper(op);
  1666. }
  1667. uint64_t
  1668. pack_ps(sim_cpu *cpu,
  1669. address_word cia,
  1670. uint64_t op1,
  1671. uint64_t op2,
  1672. FP_formats fmt)
  1673. {
  1674. uint64_t result = 0;
  1675. /* The registers must specify FPRs valid for operands of type
  1676. "fmt". If they are not valid, the result is undefined. */
  1677. /* The format type should already have been checked: */
  1678. switch (fmt)
  1679. {
  1680. case fmt_single:
  1681. {
  1682. sim_fpu wop;
  1683. uint32_t res_u, res_l;
  1684. sim_fpu_32to (&wop, op1);
  1685. sim_fpu_to32 (&res_u, &wop);
  1686. sim_fpu_32to (&wop, op2);
  1687. sim_fpu_to32 (&res_l, &wop);
  1688. result = FP_PS_cat(res_u, res_l);
  1689. break;
  1690. }
  1691. default:
  1692. sim_io_error (SD, "Bad switch\n");
  1693. }
  1694. return result;
  1695. }
  1696. uint64_t
  1697. convert_ps (sim_cpu *cpu,
  1698. address_word cia,
  1699. int rm,
  1700. uint64_t op,
  1701. FP_formats from,
  1702. FP_formats to)
  1703. {
  1704. sim_fpu wop_u, wop_l;
  1705. sim_fpu_round round = rounding_mode (rm);
  1706. sim_fpu_denorm denorm = denorm_mode (cpu);
  1707. uint32_t res_u, res_l;
  1708. uint64_t result;
  1709. sim_fpu_status status_u = 0, status_l = 0;
  1710. /* As convert, but used only for paired values (formats PS, PW) */
  1711. /* Convert the input to sim_fpu internal format */
  1712. switch (from)
  1713. {
  1714. case fmt_word: /* fmt_pw */
  1715. sim_fpu_i32to (&wop_u, (op >> 32) & (unsigned)0xFFFFFFFF, round);
  1716. sim_fpu_i32to (&wop_l, op & (unsigned)0xFFFFFFFF, round);
  1717. break;
  1718. case fmt_ps:
  1719. sim_fpu_32to (&wop_u, FP_PS_upper(op));
  1720. sim_fpu_32to (&wop_l, FP_PS_lower(op));
  1721. break;
  1722. default:
  1723. sim_io_error (SD, "Bad switch\n");
  1724. }
  1725. /* Convert sim_fpu format into the output */
  1726. switch (to)
  1727. {
  1728. case fmt_word: /* fmt_pw */
  1729. status_u |= sim_fpu_to32u (&res_u, &wop_u, round);
  1730. status_l |= sim_fpu_to32u (&res_l, &wop_l, round);
  1731. result = (((uint64_t)res_u) << 32) | (uint64_t)res_l;
  1732. break;
  1733. case fmt_ps:
  1734. status_u |= sim_fpu_round_32 (&wop_u, 0, round);
  1735. status_l |= sim_fpu_round_32 (&wop_l, 0, round);
  1736. sim_fpu_to32 (&res_u, &wop_u);
  1737. sim_fpu_to32 (&res_l, &wop_l);
  1738. result = FP_PS_cat(res_u, res_l);
  1739. break;
  1740. default:
  1741. result = 0;
  1742. sim_io_error (SD, "Bad switch\n");
  1743. }
  1744. update_fcsr (cpu, cia, status_u | status_l);
  1745. return result;
  1746. }
  1747. static const char *
  1748. fpu_format_name (FP_formats fmt)
  1749. {
  1750. switch (fmt)
  1751. {
  1752. case fmt_single:
  1753. return "single";
  1754. case fmt_double:
  1755. return "double";
  1756. case fmt_word:
  1757. return "word";
  1758. case fmt_long:
  1759. return "long";
  1760. case fmt_ps:
  1761. return "ps";
  1762. case fmt_unknown:
  1763. return "<unknown>";
  1764. case fmt_uninterpreted:
  1765. return "<uninterpreted>";
  1766. case fmt_uninterpreted_32:
  1767. return "<uninterpreted_32>";
  1768. case fmt_uninterpreted_64:
  1769. return "<uninterpreted_64>";
  1770. default:
  1771. return "<format error>";
  1772. }
  1773. }
  1774. #ifdef DEBUG
  1775. static const char *
  1776. fpu_rounding_mode_name (int rm)
  1777. {
  1778. switch (rm)
  1779. {
  1780. case FP_RM_NEAREST:
  1781. return "Round";
  1782. case FP_RM_TOZERO:
  1783. return "Trunc";
  1784. case FP_RM_TOPINF:
  1785. return "Ceil";
  1786. case FP_RM_TOMINF:
  1787. return "Floor";
  1788. default:
  1789. return "<rounding mode error>";
  1790. }
  1791. }
  1792. #endif /* DEBUG */