float.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include <mach.h>
  5. #define Extern extern
  6. #include "mips.h"
  7. void unimp(ulong);
  8. void Ifcmp(ulong);
  9. void Ifdiv(ulong);
  10. void Ifmul(ulong);
  11. void Ifadd(ulong);
  12. void Ifsub(ulong);
  13. void Ifmov(ulong);
  14. void Icvtd(ulong);
  15. void Icvtw(ulong);
  16. void Icvts(ulong);
  17. void Ifabs(ulong);
  18. void Ifneg(ulong);
  19. Inst cop1[] = {
  20. { Ifadd, "add.f", Ifloat },
  21. { Ifsub, "sub.f", Ifloat },
  22. { Ifmul, "mul.f", Ifloat },
  23. { Ifdiv, "div.f", Ifloat },
  24. { unimp, "", },
  25. { Ifabs, "abs.f", Ifloat },
  26. { Ifmov, "mov.f", Ifloat },
  27. { Ifneg, "neg.f", Ifloat },
  28. { unimp, "", },
  29. { unimp, "", },
  30. { unimp, "", },
  31. { unimp, "", },
  32. { unimp, "", },
  33. { unimp, "", },
  34. { unimp, "", },
  35. { unimp, "", },
  36. { unimp, "", },
  37. { unimp, "", },
  38. { unimp, "", },
  39. { unimp, "", },
  40. { unimp, "", },
  41. { unimp, "", },
  42. { unimp, "", },
  43. { unimp, "", },
  44. { unimp, "", },
  45. { unimp, "", },
  46. { unimp, "", },
  47. { unimp, "", },
  48. { unimp, "", },
  49. { unimp, "", },
  50. { unimp, "", },
  51. { unimp, "", },
  52. { Icvts, "cvt.s", Ifloat },
  53. { Icvtd, "cvt.d", Ifloat },
  54. { unimp, "", },
  55. { unimp, "", },
  56. { Icvtw, "cvt.w", Ifloat },
  57. { unimp, "", },
  58. { unimp, "", },
  59. { unimp, "", },
  60. { unimp, "", },
  61. { unimp, "", },
  62. { unimp, "", },
  63. { unimp, "", },
  64. { unimp, "", },
  65. { unimp, "", },
  66. { unimp, "", },
  67. { unimp, "", },
  68. { Ifcmp, "c.f", Ifloat },
  69. { Ifcmp, "c.un", Ifloat },
  70. { Ifcmp, "c.eq", Ifloat },
  71. { Ifcmp, "c.ueq", Ifloat },
  72. { Ifcmp, "c.olt", Ifloat },
  73. { Ifcmp, "c.ult", Ifloat },
  74. { Ifcmp, "c.ole", Ifloat },
  75. { Ifcmp, "c.ule", Ifloat },
  76. { Ifcmp, "c,sf", Ifloat },
  77. { Ifcmp, "c.ngle",Ifloat },
  78. { Ifcmp, "c.seq", Ifloat },
  79. { Ifcmp, "c.ngl", Ifloat },
  80. { Ifcmp, "c.lt", Ifloat },
  81. { Ifcmp, "c.nge", Ifloat },
  82. { Ifcmp, "c.le", Ifloat },
  83. { Ifcmp, "c.ngt", Ifloat },
  84. { 0 }
  85. };
  86. void
  87. unimp(ulong inst)
  88. {
  89. print("op %ld\n", inst&0x3f);
  90. Bprint(bioout, "Unimplemented floating point Trap IR %.8lux\n", inst);
  91. longjmp(errjmp, 0);
  92. }
  93. void
  94. inval(ulong inst)
  95. {
  96. Bprint(bioout, "Invalid Operation Exception IR %.8lux\n", inst);
  97. longjmp(errjmp, 0);
  98. }
  99. void
  100. ifmt(int r)
  101. {
  102. Bprint(bioout, "Invalid Floating Data Format f%d pc 0x%lux\n", r, reg.pc);
  103. longjmp(errjmp, 0);
  104. }
  105. void
  106. floatop(int dst, int s1, int s2)
  107. {
  108. if(reg.ft[s1] == FPd && s1 != 24)
  109. ifmt(s1);
  110. if(reg.ft[s2] == FPd && s2 != 24)
  111. ifmt(s2);
  112. reg.ft[dst] = FPs;
  113. }
  114. void
  115. doubop(int dst, int s1, int s2)
  116. {
  117. ulong l;
  118. if(reg.ft[s1] != FPd) {
  119. if(reg.ft[s1] == FPs && s1 != 24)
  120. ifmt(s1);
  121. l = reg.di[s1];
  122. reg.di[s1] = reg.di[s1+1];
  123. reg.di[s1+1] = l;
  124. reg.ft[s1] = FPd;
  125. }
  126. if(reg.ft[s2] != FPd) {
  127. if(reg.ft[s2] == FPs && s2 != 24)
  128. ifmt(s2);
  129. l = reg.di[s2];
  130. reg.di[s2] = reg.di[s2+1];
  131. reg.di[s2+1] = l;
  132. reg.ft[s2] = FPd;
  133. }
  134. reg.ft[dst] = FPd;
  135. }
  136. void
  137. Iswc1(ulong inst)
  138. {
  139. int off;
  140. ulong l;
  141. int rt, rb, ert;
  142. Getrbrt(rb, rt, inst);
  143. off = (short)(inst&0xffff);
  144. if(trace)
  145. itrace("swc1\tf%d,0x%x(r%d) ea=%lux", rt, off, rb, reg.r[rb]+off);
  146. ert = rt&~1;
  147. if(reg.ft[ert] == FPd) {
  148. l = reg.di[ert];
  149. reg.di[ert] = reg.di[ert+1];
  150. reg.di[ert+1] = l;
  151. reg.ft[ert] = FPmemory;
  152. }
  153. putmem_w(reg.r[rb]+off, reg.di[rt]);
  154. }
  155. void
  156. Ifsub(ulong ir)
  157. {
  158. char fmt;
  159. int fs, ft, fd;
  160. Getf3(fs, ft, fd, ir);
  161. switch((ir>>21)&0xf) {
  162. default:
  163. unimp(ir);
  164. case 0: /* single */
  165. fmt = 's';
  166. floatop(fd, fs, ft);
  167. reg.fl[fd] = reg.fl[fs] - reg.fl[ft];
  168. break;
  169. case 1: /* double */
  170. fmt = 'd';
  171. doubop(fd, fs, ft);
  172. reg.fd[fd>>1] = reg.fd[fs>>1] - reg.fd[ft>>1];
  173. break;
  174. case 4:
  175. fmt = 'w';
  176. reg.di[fd] = reg.di[fs] - reg.di[ft];
  177. break;
  178. }
  179. if(trace)
  180. itrace("sub.%c\tf%d,f%d,f%d", fmt, fd, fs, ft);
  181. }
  182. void
  183. Ifmov(ulong ir)
  184. {
  185. char fmt;
  186. int fs, fd;
  187. Getf2(fs, fd, ir);
  188. switch((ir>>21)&0xf) {
  189. default:
  190. unimp(ir);
  191. case 0: /* single */
  192. fmt = 's';
  193. reg.fl[fd] = reg.fl[fs];
  194. reg.ft[fd] = reg.ft[fs];
  195. break;
  196. case 1: /* double */
  197. fmt = 'd';
  198. reg.fd[fd>>1] = reg.fd[fs>>1];
  199. reg.ft[fd] = reg.ft[fs];
  200. break;
  201. case 4:
  202. fmt = 'w';
  203. reg.di[fd] = reg.di[fs];
  204. reg.ft[fd] = reg.ft[fs];
  205. break;
  206. }
  207. if(trace)
  208. itrace("mov.%c\tf%d,f%d", fmt, fd, fs);
  209. }
  210. void
  211. Ifabs(ulong ir)
  212. {
  213. char fmt;
  214. int fs, fd;
  215. Getf2(fs, fd, ir);
  216. switch((ir>>21)&0xf) {
  217. default:
  218. unimp(ir);
  219. case 0: /* single */
  220. fmt = 's';
  221. floatop(fd, fs, fs);
  222. if(reg.fl[fs] < 0.0)
  223. reg.fl[fd] = -reg.fl[fs];
  224. else
  225. reg.fl[fd] = reg.fl[fs];
  226. break;
  227. case 1: /* double */
  228. fmt = 'd';
  229. doubop(fd, fs, fs);
  230. if(reg.fd[fs>>1] < 0.0)
  231. reg.fd[fd>>1] = -reg.fd[fs>>1];
  232. else
  233. reg.fd[fd>>1] = reg.fd[fs>>1];
  234. break;
  235. case 4:
  236. fmt = 'w';
  237. if((long)reg.di[fs] < 0)
  238. reg.di[fd] = -reg.di[fs];
  239. else
  240. reg.di[fd] = reg.di[fs];
  241. break;
  242. }
  243. if(trace)
  244. itrace("abs.%c\tf%d,f%d", fmt, fd, fs);
  245. }
  246. void
  247. Ifneg(ulong ir)
  248. {
  249. char fmt;
  250. int fs, fd;
  251. Getf2(fs, fd, ir);
  252. switch((ir>>21)&0xf) {
  253. default:
  254. unimp(ir);
  255. case 0: /* single */
  256. fmt = 's';
  257. floatop(fd, fs, fs);
  258. reg.fl[fd] = -reg.fl[fs];
  259. break;
  260. case 1: /* double */
  261. fmt = 'd';
  262. doubop(fd, fs, fs);
  263. reg.fd[fd>>1] = -reg.fd[fs>>1];
  264. break;
  265. case 4:
  266. fmt = 'w';
  267. reg.di[fd] = -reg.di[fs];
  268. break;
  269. }
  270. if(trace)
  271. itrace("neg.%c\tf%d,f%d", fmt, fd, fs);
  272. }
  273. void
  274. Icvtd(ulong ir)
  275. {
  276. char fmt;
  277. int fs, fd;
  278. Getf2(fs, fd, ir);
  279. switch((ir>>21)&0xf) {
  280. default:
  281. unimp(ir);
  282. case 0: /* single */
  283. fmt = 's';
  284. floatop(fs, fs, fs);
  285. reg.fd[fd>>1] = reg.fl[fs];
  286. reg.ft[fd] = FPd;
  287. break;
  288. case 1: /* double */
  289. fmt = 'd';
  290. doubop(fd, fs, fs);
  291. reg.fd[fd>>1] = reg.fd[fs>>1];
  292. break;
  293. case 4:
  294. fmt = 'w';
  295. reg.fd[fd>>1] = (long)reg.di[fs];
  296. reg.ft[fd] = FPd;
  297. break;
  298. }
  299. if(trace)
  300. itrace("cvt.d.%c\tf%d,f%d", fmt, fd, fs);
  301. }
  302. void
  303. Icvts(ulong ir)
  304. {
  305. char fmt;
  306. int fs, fd;
  307. Getf2(fs, fd, ir);
  308. switch((ir>>21)&0xf) {
  309. default:
  310. unimp(ir);
  311. case 0: /* single */
  312. fmt = 's';
  313. floatop(fd, fs, fs);
  314. reg.fl[fd] = reg.fl[fs];
  315. break;
  316. case 1: /* double */
  317. fmt = 'd';
  318. doubop(fs, fs, fs);
  319. reg.fl[fd] = reg.fd[fs>>1];
  320. reg.ft[fd] = FPs;
  321. break;
  322. case 4:
  323. fmt = 'w';
  324. reg.fl[fd] = (long)reg.di[fs];
  325. reg.ft[fd] = FPs;
  326. break;
  327. }
  328. if(trace)
  329. itrace("cvt.s.%c\tf%d,f%d", fmt, fd, fs);
  330. }
  331. void
  332. Icvtw(ulong ir)
  333. {
  334. long v;
  335. char fmt;
  336. int fs, fd;
  337. Getf2(fs, fd, ir);
  338. switch((ir>>21)&0xf) {
  339. default:
  340. unimp(ir);
  341. case 0: /* single */
  342. fmt = 's';
  343. floatop(fs, fs, fs);
  344. v = reg.fl[fs];
  345. break;
  346. case 1: /* double */
  347. fmt = 'd';
  348. doubop(fs, fs, fs);
  349. v = reg.fd[fs>>1];
  350. break;
  351. case 4:
  352. fmt = 'w';
  353. v = reg.di[fs];
  354. break;
  355. }
  356. reg.di[fd] = v;
  357. reg.ft[fd] = FPmemory;
  358. if(trace)
  359. itrace("cvt.w.%c\tf%d,f%d", fmt, fd, fs);
  360. }
  361. void
  362. Ifadd(ulong ir)
  363. {
  364. char fmt;
  365. int fs, ft, fd;
  366. Getf3(fs, ft, fd, ir);
  367. switch((ir>>21)&0xf) {
  368. default:
  369. unimp(ir);
  370. case 0: /* single */
  371. fmt = 's';
  372. floatop(fd, fs, ft);
  373. reg.fl[fd] = reg.fl[fs] + reg.fl[ft];
  374. break;
  375. case 1: /* double */
  376. fmt = 'd';
  377. doubop(fd, fs, ft);
  378. reg.fd[fd>>1] = reg.fd[fs>>1] + reg.fd[ft>>1];
  379. break;
  380. case 4:
  381. fmt = 'w';
  382. reg.di[fd] = reg.di[fs] + reg.di[ft];
  383. break;
  384. }
  385. if(trace)
  386. itrace("add.%c\tf%d,f%d,f%d", fmt, fd, fs, ft);
  387. }
  388. void
  389. Ifmul(ulong ir)
  390. {
  391. char fmt;
  392. int fs, ft, fd;
  393. Getf3(fs, ft, fd, ir);
  394. switch((ir>>21)&0xf) {
  395. default:
  396. unimp(ir);
  397. case 0: /* single */
  398. fmt = 's';
  399. floatop(fd, fs, ft);
  400. reg.fl[fd] = reg.fl[fs] * reg.fl[ft];
  401. break;
  402. case 1: /* double */
  403. fmt = 'd';
  404. doubop(fd, fs, ft);
  405. reg.fd[fd>>1] = reg.fd[fs>>1] * reg.fd[ft>>1];
  406. break;
  407. case 4:
  408. fmt = 'w';
  409. reg.di[fd] = reg.di[fs] * reg.di[ft];
  410. break;
  411. }
  412. if(trace)
  413. itrace("mul.%c\tf%d,f%d,f%d", fmt, fd, fs, ft);
  414. }
  415. void
  416. Ifdiv(ulong ir)
  417. {
  418. char fmt;
  419. int fs, ft, fd;
  420. Getf3(fs, ft, fd, ir);
  421. switch((ir>>21)&0xf) {
  422. default:
  423. unimp(ir);
  424. case 0: /* single */
  425. fmt = 's';
  426. floatop(fd, fs, ft);
  427. reg.fl[fd] = reg.fl[fs] / reg.fl[ft];
  428. break;
  429. case 1: /* double */
  430. fmt = 'd';
  431. doubop(fd, fs, ft);
  432. reg.fd[fd>>1] = reg.fd[fs>>1] / reg.fd[ft>>1];
  433. break;
  434. case 4:
  435. fmt = 'w';
  436. reg.di[fd] = reg.di[fs] / reg.di[ft];
  437. break;
  438. }
  439. if(trace)
  440. itrace("div.%c\tf%d,f%d,f%d", fmt, fd, fs, ft);
  441. }
  442. void
  443. Ilwc1(ulong inst)
  444. {
  445. int rt, rb;
  446. int off;
  447. Getrbrt(rb, rt, inst);
  448. off = (short)(inst&0xffff);
  449. if(trace)
  450. itrace("lwc1\tf%d,0x%x(r%d) ea=%lux", rt, off, rb, reg.r[rb]+off);
  451. reg.di[rt] = getmem_w(reg.r[rb]+off);
  452. reg.ft[rt] = FPmemory;
  453. }
  454. void
  455. Ibcfbct(ulong inst)
  456. {
  457. int takeit;
  458. int off;
  459. ulong npc;
  460. off = (short)(inst&0xffff);
  461. takeit = 0;
  462. npc = reg.pc + (off<<2) + 4;
  463. if(inst&(1<<16)) {
  464. if(trace)
  465. itrace("bc1t\t0x%lux", npc);
  466. if(reg.fpsr&FP_CBIT)
  467. takeit = 1;
  468. }
  469. else {
  470. if(trace)
  471. itrace("bc1f\t0x%lux", npc);
  472. if((reg.fpsr&FP_CBIT) == 0)
  473. takeit = 1;
  474. }
  475. if(takeit) {
  476. /* Do the delay slot */
  477. reg.ir = ifetch(reg.pc+4);
  478. Statbra();
  479. Iexec(reg.ir);
  480. reg.pc = npc-4;
  481. }
  482. }
  483. void
  484. Imtct(ulong ir)
  485. {
  486. int rt, fs;
  487. SpecialGetrtrd(rt, fs, ir);
  488. if(ir&(1<<22)) { /* CT */
  489. if(trace)
  490. itrace("ctc1\tr%d,f%d", rt, fs);
  491. }
  492. else { /* MT */
  493. if(trace)
  494. itrace("mtc1\tr%d,f%d", rt, fs);
  495. reg.di[fs] = reg.r[rt];
  496. reg.ft[fs] = FPmemory;
  497. }
  498. }
  499. void
  500. Imfcf(ulong ir)
  501. {
  502. int rt, fs;
  503. SpecialGetrtrd(rt, fs, ir);
  504. if(ir&(1<<22)) { /* CF */
  505. if(trace)
  506. itrace("cfc1\tr%d,f%d", rt, fs);
  507. }
  508. else { /* MF */
  509. if(trace)
  510. itrace("mfc1\tr%d,f%d", rt, fs);
  511. reg.r[rt] = reg.di[fs];
  512. }
  513. }
  514. void
  515. Icop1(ulong ir)
  516. {
  517. Inst *i;
  518. switch((ir>>23)&7) {
  519. case 0:
  520. Imfcf(ir);
  521. break;
  522. case 1:
  523. Imtct(ir);
  524. break;
  525. case 2:
  526. case 3:
  527. Ibcfbct(ir);
  528. break;
  529. case 4:
  530. case 5:
  531. case 6:
  532. case 7:
  533. i = &cop1[ir&0x3f];
  534. i->count++;
  535. (*i->func)(ir);
  536. }
  537. }
  538. void
  539. Ifcmp(ulong ir)
  540. {
  541. char fmt;
  542. int fc;
  543. int ft, fs;
  544. SpecialGetrtrd(ft, fs, ir);
  545. SET(fc);
  546. switch((ir>>21)&0xf) {
  547. default:
  548. unimp(ir);
  549. case 0: /* single */
  550. fmt = 's';
  551. floatop(fs, fs, ft);
  552. if(isNaN(reg.fl[fs]) || isNaN(reg.fl[ft])) {
  553. fc = FP_U;
  554. break;
  555. }
  556. if(reg.fl[fs] == reg.fl[ft]) {
  557. fc = FP_E;
  558. break;
  559. }
  560. if(reg.fl[fs] < reg.fl[ft]) {
  561. fc = FP_L;
  562. break;
  563. }
  564. if(reg.fl[fs] > reg.fl[ft]) {
  565. fc = FP_G;
  566. break;
  567. }
  568. print("vi: bad in fcmp");
  569. break;
  570. case 1: /* double */
  571. fmt = 'd';
  572. doubop(fs, fs, ft);
  573. if(isNaN(reg.fd[fs>>1]) || isNaN(reg.fd[ft>>1])) {
  574. fc = FP_U;
  575. break;
  576. }
  577. if(reg.fd[fs>>1] == reg.fd[ft>>1]) {
  578. fc = FP_E;
  579. break;
  580. }
  581. if(reg.fd[fs>>1] < reg.fd[ft>>1]) {
  582. fc = FP_L;
  583. break;
  584. }
  585. if(reg.fd[fs>>1] > reg.fd[ft>>1]) {
  586. fc = FP_G;
  587. break;
  588. }
  589. print("vi: bad in fcmp");
  590. break;
  591. case 4:
  592. fmt = 'w';
  593. if(reg.di[fs] == reg.di[ft]) {
  594. fc = FP_E;
  595. break;
  596. }
  597. if(reg.di[fs] < reg.di[ft]) {
  598. fc = FP_L;
  599. break;
  600. }
  601. if(reg.di[fs] > reg.di[ft]) {
  602. fc = FP_G;
  603. break;
  604. }
  605. break;
  606. }
  607. reg.fpsr &= ~FP_CBIT;
  608. switch(ir&0xf) {
  609. case 0:
  610. if(trace)
  611. itrace("c.f.%c\tf%d,f%d", fmt, fs, ft);
  612. break;
  613. case 1:
  614. if(trace)
  615. itrace("c.un.%c\tf%d,f%d", fmt, fs, ft);
  616. if(fc == FP_U)
  617. reg.fpsr |= FP_CBIT;
  618. break;
  619. case 2:
  620. if(trace)
  621. itrace("c.eq.%c\tf%d,f%d", fmt, fs, ft);
  622. if(fc == FP_E)
  623. reg.fpsr |= FP_CBIT;
  624. break;
  625. case 3:
  626. if(trace)
  627. itrace("c.ueq.%c\tf%d,f%d", fmt, fs, ft);
  628. if(fc == FP_E || fc == FP_U)
  629. reg.fpsr |= FP_CBIT;
  630. break;
  631. case 4:
  632. if(trace)
  633. itrace("c.lt.%c\tf%d,f%d", fmt, fs, ft);
  634. if(fc == FP_L)
  635. reg.fpsr |= FP_CBIT;
  636. break;
  637. case 5:
  638. if(trace)
  639. itrace("c.ult.%c\tf%d,f%d", fmt, fs, ft);
  640. if(fc == FP_L || fc == FP_U)
  641. reg.fpsr |= FP_CBIT;
  642. break;
  643. case 6:
  644. if(trace)
  645. itrace("c.le.%c\tf%d,f%d", fmt, fs, ft);
  646. if(fc == FP_E || fc == FP_L)
  647. reg.fpsr |= FP_CBIT;
  648. break;
  649. case 7:
  650. if(trace)
  651. itrace("c.ule.%c\tf%d,f%d", fmt, fs, ft);
  652. if(fc == FP_E || fc == FP_L || fc == FP_U)
  653. reg.fpsr |= FP_CBIT;
  654. break;
  655. case 8:
  656. if(trace)
  657. itrace("c.sf.%c\tf%d,f%d", fmt, fs, ft);
  658. if(fc == FP_U)
  659. inval(ir);
  660. break;
  661. case 9:
  662. if(trace)
  663. itrace("c.ngle.%c\tf%d,f%d", fmt, fs, ft);
  664. if(fc == FP_U) {
  665. reg.fpsr |= FP_CBIT;
  666. inval(ir);
  667. }
  668. break;
  669. case 10:
  670. if(trace)
  671. itrace("c.seq.%c\tf%d,f%d", fmt, fs, ft);
  672. if(fc == FP_E)
  673. reg.fpsr |= FP_CBIT;
  674. if(fc == FP_U)
  675. inval(ir);
  676. break;
  677. case 11:
  678. if(trace)
  679. itrace("c.ngl.%c\tf%d,f%d", fmt, fs, ft);
  680. if(fc == FP_E || fc == FP_U)
  681. reg.fpsr |= FP_CBIT;
  682. if(fc == FP_U)
  683. inval(ir);
  684. break;
  685. case 12:
  686. if(trace)
  687. itrace("c.lt.%c\tf%d,f%d", fmt, fs, ft);
  688. if(fc == FP_L)
  689. reg.fpsr |= FP_CBIT;
  690. if(fc == FP_U)
  691. inval(ir);
  692. break;
  693. case 13:
  694. if(trace)
  695. itrace("c.nge.%c\tf%d,f%d", fmt, fs, ft);
  696. if(fc == FP_L || fc == FP_U)
  697. reg.fpsr |= FP_CBIT;
  698. if(fc == FP_U)
  699. inval(ir);
  700. break;
  701. case 14:
  702. if(trace)
  703. itrace("c.le.%c\tf%d,f%d", fmt, fs, ft);
  704. if(fc == FP_E || fc == FP_L)
  705. reg.fpsr |= FP_CBIT;
  706. if(fc == FP_U)
  707. inval(ir);
  708. break;
  709. case 15:
  710. if(trace)
  711. itrace("c.ngt.%c\tf%d,f%d", fmt, fs, ft);
  712. if(fc == FP_E || fc == FP_L || fc == FP_U)
  713. reg.fpsr |= FP_CBIT;
  714. if(fc == FP_U)
  715. inval(ir);
  716. break;
  717. }
  718. USED(fmt);
  719. }