float.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <bio.h>
  12. #include <mach.h>
  13. #define Extern extern
  14. #include "sparc.h"
  15. void
  16. ldf(uint32_t ir)
  17. {
  18. uint32_t ea;
  19. int rd, rs1, rs2;
  20. getrop23(ir);
  21. if(ir&IMMBIT) {
  22. ximm(ea, ir);
  23. if(trace)
  24. itrace("ldf\tf%d,0x%lux(r%d) ea=%lux",rd, ea, rs1, ea+reg.r[rs1]);
  25. ea += reg.r[rs1];
  26. }
  27. else {
  28. ea = reg.r[rs1] + reg.r[rs2];
  29. if(trace)
  30. itrace("ldf\tf%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
  31. }
  32. reg.di[rd] = getmem_w(ea);
  33. }
  34. void
  35. lddf(uint32_t ir)
  36. {
  37. uint32_t ea;
  38. int rd, rs1, rs2;
  39. getrop23(ir);
  40. if(ir&IMMBIT) {
  41. ximm(ea, ir);
  42. if(trace)
  43. itrace("lddf\tf%d,0x%lux(r%d) ea=%lux",
  44. rd, ea, rs1, ea+reg.r[rs1]);
  45. ea += reg.r[rs1];
  46. }
  47. else {
  48. ea = reg.r[rs1] + reg.r[rs2];
  49. if(trace)
  50. itrace("lddf\tf%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
  51. }
  52. if(ea&7) {
  53. Bprint(bioout, "mem_address_not_aligned [load addr %.8lux]\n", ea);
  54. longjmp(errjmp, 0);
  55. }
  56. if(rd&1)
  57. undef(ir);
  58. reg.di[rd] = getmem_w(ea);
  59. reg.di[rd+1] = getmem_w(ea+4);
  60. }
  61. void
  62. stf(uint32_t ir)
  63. {
  64. uint32_t ea;
  65. int rd, rs1, rs2;
  66. getrop23(ir);
  67. if(ir&IMMBIT) {
  68. ximm(ea, ir);
  69. if(trace)
  70. itrace("stf\tf%d,0x%lux(r%d) %lux=%g",
  71. rd, ea, rs1, ea+reg.r[rs1], reg.fl[rd]);
  72. ea += reg.r[rs1];
  73. }
  74. else {
  75. ea = reg.r[rs1] + reg.r[rs2];
  76. if(trace)
  77. itrace("stf\tf%d,[r%d+r%d] %lux=%lux",
  78. rd, rs1, rs2, ea, reg.r[rd]);
  79. }
  80. putmem_w(ea, reg.di[rd]);
  81. }
  82. void
  83. stdf(uint32_t ir)
  84. {
  85. uint32_t ea;
  86. int rd, rs1, rs2;
  87. getrop23(ir);
  88. if(ir&IMMBIT) {
  89. ximm(ea, ir);
  90. if(trace)
  91. itrace("stdf\tf%d,0x%lux(r%d) %lux=%g",
  92. rd, ea, rs1, ea+reg.r[rs1], reg.fl[rd]);
  93. ea += reg.r[rs1];
  94. }
  95. else {
  96. ea = reg.r[rs1] + reg.r[rs2];
  97. if(trace)
  98. itrace("stdf\tf%d,[r%d+r%d] %lux=%lux",
  99. rd, rs1, rs2, ea, reg.r[rd]);
  100. }
  101. if(ea&7) {
  102. Bprint(bioout, "mem_address_not_aligned [store addr %.8lux]\n", ea);
  103. longjmp(errjmp, 0);
  104. }
  105. if(rd&1)
  106. undef(ir);
  107. putmem_w(ea, reg.di[rd]);
  108. putmem_w(ea+4, reg.di[rd+1]);
  109. }
  110. void
  111. fcmp(uint32_t ir)
  112. {
  113. int fc, rd, rs1, rs2;
  114. getrop23(ir);
  115. USED(rd);
  116. SET(fc);
  117. switch((ir>>5)&0x1FF) {
  118. default:
  119. undef(ir);
  120. case 0x51: /* fcmps */
  121. if(trace)
  122. itrace("fcmps\tf%d,f%d", rs1, rs2);
  123. if(isNaN(reg.fl[rs1]) || isNaN(reg.fl[rs2])) {
  124. fc = 3;
  125. break;
  126. }
  127. if(reg.fl[rs1] == reg.fl[rs2]) {
  128. fc = 0;
  129. break;
  130. }
  131. if(reg.fl[rs1] < reg.fl[rs2]) {
  132. fc = 1;
  133. break;
  134. }
  135. if(reg.fl[rs1] > reg.fl[rs2]) {
  136. fc = 2;
  137. break;
  138. }
  139. print("ki: fcmp error\n");
  140. break;
  141. case 0x52:
  142. if(trace)
  143. itrace("fcmpd\tf%d,f%d", rs1, rs2);
  144. rs1 >>= 1;
  145. rs2 >>= 1;
  146. if(isNaN(reg.fd[rs1]) || isNaN(reg.fd[rs2])) {
  147. fc = 3;
  148. break;
  149. }
  150. if(reg.fd[rs1] == reg.fd[rs2]) {
  151. fc = 0;
  152. break;
  153. }
  154. if(reg.fd[rs1] < reg.fd[rs2]) {
  155. fc = 1;
  156. break;
  157. }
  158. if(reg.fd[rs1] > reg.fd[rs2]) {
  159. fc = 2;
  160. break;
  161. }
  162. print("ki: fcmp error\n");
  163. break;
  164. case 0x55: /* fcmpes */
  165. if(trace)
  166. itrace("fcmpes\tf%d,f%d", rs1, rs2);
  167. rs1 >>= 1;
  168. rs2 >>= 2;
  169. if(isNaN(reg.fl[rs1]) || isNaN(reg.fl[rs2])) {
  170. Bprint(bioout, "invalid_fp_register\n");
  171. longjmp(errjmp, 0);
  172. }
  173. if(reg.fl[rs1] == reg.fl[rs2]) {
  174. fc = 0;
  175. break;
  176. }
  177. if(reg.fl[rs1] < reg.fl[rs2]) {
  178. fc = 1;
  179. break;
  180. }
  181. if(reg.fl[rs1] > reg.fl[rs2]) {
  182. fc = 2;
  183. break;
  184. }
  185. print("ki: fcmp error\n");
  186. break;
  187. case 0x56:
  188. if(trace)
  189. itrace("fcmped\tf%d,f%d", rs1, rs2);
  190. if(isNaN(reg.fd[rs1]) || isNaN(reg.fd[rs2])) {
  191. Bprint(bioout, "invalid_fp_register\n");
  192. longjmp(errjmp, 0);
  193. }
  194. if(reg.fd[rs1] == reg.fd[rs2]) {
  195. fc = 0;
  196. break;
  197. }
  198. if(reg.fd[rs1] < reg.fd[rs2]) {
  199. fc = 1;
  200. break;
  201. }
  202. if(reg.fd[rs1] > reg.fd[rs2]) {
  203. fc = 2;
  204. break;
  205. }
  206. print("ki: fcmp error\n");
  207. break;
  208. }
  209. reg.fpsr = (reg.fpsr&~(0x3<<10)) | (fc<<10);
  210. }
  211. void
  212. fbcc(uint32_t ir)
  213. {
  214. char *op;
  215. uint32_t npc;
  216. int takeit, fc, ba, anul;
  217. fc = (reg.fpsr>>10)&3;
  218. ba = 0;
  219. SET(op, takeit);
  220. switch((ir>>25)&0x0F) {
  221. case 0:
  222. op = "fbn";
  223. takeit = 0;
  224. break;
  225. case 1:
  226. op = "fbne";
  227. takeit = fc == FP_L || fc == FP_G || fc == FP_U;
  228. break;
  229. case 2:
  230. op = "fblg";
  231. takeit = fc == FP_L || fc == FP_G;
  232. break;
  233. case 3:
  234. op = "fbul";
  235. takeit = fc == FP_L || fc == FP_U;
  236. break;
  237. case 4:
  238. op = "fbl";
  239. takeit = fc == FP_L;
  240. break;
  241. case 5:
  242. op = "fbug";
  243. takeit = fc == FP_U || fc == FP_G;
  244. break;
  245. case 6:
  246. op = "fbg";
  247. takeit = fc == FP_G;
  248. break;
  249. case 7:
  250. op = "fbu";
  251. takeit = fc == FP_U;
  252. break;
  253. case 8:
  254. op = "fba";
  255. ba = 1;
  256. takeit = 1;
  257. break;
  258. case 9:
  259. op = "fbe";
  260. takeit = fc == FP_E;
  261. break;
  262. case 10:
  263. op = "fbue";
  264. takeit = fc == FP_E || fc == FP_U;
  265. break;
  266. case 11:
  267. op = "fbge";
  268. takeit = fc == FP_E || fc == FP_G;
  269. break;
  270. case 12:
  271. op = "fbuge";
  272. takeit = fc == FP_E || fc == FP_G || fc == FP_U;
  273. break;
  274. case 13:
  275. op = "fble";
  276. takeit = fc == FP_E || fc == FP_L;
  277. break;
  278. case 14:
  279. op = "fbule";
  280. takeit = fc == FP_E || fc == FP_L || fc == FP_U;
  281. break;
  282. case 15:
  283. op = "fbo";
  284. takeit = fc == FP_E || fc == FP_L || fc == FP_G;
  285. break;
  286. }
  287. npc = ir & 0x3FFFFF;
  288. if(npc & (1<<21))
  289. npc |= ~((1<<22)-1);
  290. npc = (npc<<2) + reg.pc;
  291. anul = ir&ANUL;
  292. if(trace) {
  293. if(anul)
  294. itrace("%s,a\t%lux", op, npc);
  295. else
  296. itrace("%s\t%lux", op, npc);
  297. }
  298. if(takeit == 0) {
  299. reg.pc += 4;
  300. if(anul == 0) {
  301. reg.ir = ifetch(reg.pc);
  302. delay(reg.pc+4);
  303. }
  304. else
  305. anulled++;
  306. return;
  307. }
  308. ci->taken++;
  309. if(ba && anul) {
  310. reg.pc = npc-4;
  311. anulled++;
  312. return;
  313. }
  314. reg.ir = ifetch(reg.pc+4);
  315. delay(npc);
  316. reg.pc = npc-4;
  317. }
  318. void
  319. farith(uint32_t ir)
  320. {
  321. char *op;
  322. int32_t v;
  323. int rd, rs1, rs2, fmt;
  324. fmt = 0;
  325. getrop23(ir);
  326. switch((ir>>5)&0x1FF) {
  327. default:
  328. undef(ir);
  329. case 0x41:
  330. reg.fl[rd] = reg.fl[rs1] + reg.fl[rs2];
  331. op = "fadds";
  332. break;
  333. case 0x42:
  334. reg.fd[rd>>1] = reg.fd[rs1>>1] + reg.fd[rs2>>1];
  335. op = "faddd";
  336. break;
  337. case 0x45:
  338. reg.fl[rd] = reg.fl[rs1] - reg.fl[rs2];
  339. op = "fsubs";
  340. break;
  341. case 0x46:
  342. reg.fd[rd>>1] = reg.fd[rs1>>1] - reg.fd[rs2>>1];
  343. op = "fsubd";
  344. break;
  345. case 0x4d:
  346. if(reg.fl[rs2] == 0.0) {
  347. Bprint(bioout, "fp_exception DZ\n");
  348. longjmp(errjmp, 0);
  349. }
  350. reg.fl[rd] = reg.fl[rs1] / reg.fl[rs2];
  351. op = "fdivs";
  352. break;
  353. case 0x4e:
  354. if(reg.fd[rs2>>1] == 0.0) {
  355. Bprint(bioout, "fp_exception DZ\n");
  356. longjmp(errjmp, 0);
  357. }
  358. reg.fd[rd>>1] = reg.fd[rs1>>1] / reg.fd[rs2>>1];
  359. op = "fdivd";
  360. break;
  361. case 0x49:
  362. reg.fl[rd] = reg.fl[rs1] * reg.fl[rs2];
  363. op = "fmuls";
  364. break;
  365. case 0x4a:
  366. reg.fd[rd>>1] = reg.fd[rs1>>1] * reg.fd[rs2>>1];
  367. op = "fmuld";
  368. break;
  369. case 0xc4:
  370. reg.fl[rd] = (int32_t)reg.di[rs2];
  371. fmt = 1;
  372. op = "fitos";
  373. break;
  374. case 0xc8:
  375. reg.fd[rd>>1] = (int32_t)reg.di[rs2];
  376. fmt = 1;
  377. op = "fitod";
  378. break;
  379. case 0xd1:
  380. v = reg.fl[rs2];
  381. reg.di[rd] = v;
  382. fmt = 1;
  383. op = "fstoi";
  384. break;
  385. case 0xd2:
  386. v = reg.fd[rs2>>1];
  387. reg.di[rd] = v;
  388. fmt = 1;
  389. op = "fdtoi";
  390. break;
  391. case 0x01:
  392. reg.di[rd] = reg.di[rs2];
  393. fmt = 1;
  394. op = "fmovs";
  395. break;
  396. case 0x05:
  397. reg.fl[rd] = -reg.fl[rs2];
  398. fmt = 1;
  399. op = "fnegs";
  400. break;
  401. case 0x09:
  402. reg.fl[rd] = fabs(reg.fl[rs2]);
  403. fmt = 1;
  404. op = "fabss";
  405. break;
  406. case 0xc9:
  407. reg.fd[rd>>1] = reg.fl[rs2];
  408. fmt = 1;
  409. op = "fstod";
  410. break;
  411. case 0xc6:
  412. reg.fl[rd] = reg.fd[rs2>>1];
  413. fmt = 1;
  414. op = "fdtos";
  415. break;
  416. }
  417. if(trace) {
  418. switch(fmt) {
  419. case 0:
  420. itrace("%s\tf%d,f%d,f%d", op, rs1, rs2, rd);
  421. break;
  422. case 1:
  423. itrace("%s\tf%d,f%d", op, rs2, rd);
  424. break;
  425. }
  426. }
  427. }