run.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  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 Iaddi(ulong);
  8. void Isw(ulong);
  9. void Ilui(ulong);
  10. void Iori(ulong);
  11. void Ixori(ulong);
  12. void Ilw(ulong);
  13. void Ijal(ulong);
  14. void Ispecial(ulong);
  15. void Ibeq(ulong);
  16. void Ibeql(ulong);
  17. void Iaddiu(ulong);
  18. void Ilb(ulong);
  19. void Iandi(ulong);
  20. void Ij(ulong);
  21. void Ibne(ulong);
  22. void Ibnel(ulong);
  23. void Isb(ulong);
  24. void Islti(ulong);
  25. void Ibcond(ulong);
  26. void Ibgtz(ulong);
  27. void Ibgtzl(ulong);
  28. void Ilbu(ulong);
  29. void Ilhu(ulong);
  30. void Ish(ulong);
  31. void Ilh(ulong);
  32. void Iblez(ulong);
  33. void Iblezl(ulong);
  34. void Isltiu(ulong);
  35. void Iswc1(ulong);
  36. void Ilwc1(ulong);
  37. void Icop1(ulong);
  38. void Ilwl(ulong);
  39. void Ilwr(ulong);
  40. void Ill(ulong);
  41. void Isc(ulong);
  42. Inst itab[] = {
  43. { Ispecial, 0 },
  44. { Ibcond, "bcond", Ibranch },
  45. { Ij, "j", Ibranch },
  46. { Ijal, "jal", Ibranch },
  47. { Ibeq, "beq", Ibranch },
  48. { Ibne, "bne", Ibranch },
  49. { Iblez, "blez", Ibranch },
  50. { Ibgtz, "bgtz", Ibranch },
  51. { Iaddi, "addi", Iarith }, /* 8 */
  52. { Iaddiu, "addiu", Iarith },
  53. { Islti, "slti", Iarith },
  54. { Isltiu, "sltiu", Iarith },
  55. { Iandi, "andi", Iarith },
  56. { Iori, "ori", Iarith },
  57. { Ixori, "xori", Iarith },
  58. { Ilui, "lui", Iload }, /* 15 */
  59. { undef, "" },
  60. { Icop1, "cop1", Ifloat },
  61. { undef, "" },
  62. { undef, "" },
  63. { Ibeql, "beql" },
  64. { Ibnel, "bnel" },
  65. { Iblezl, "blezl" },
  66. { Ibgtzl, "bgtzl" },
  67. { undef, "" },
  68. { undef, "" },
  69. { undef, "" },
  70. { undef, "" },
  71. { undef, "" },
  72. { undef, "" },
  73. { undef, "" },
  74. { undef, "" },
  75. { Ilb, "lb", Iload },
  76. { Ilh, "lh", Iload },
  77. { Ilwl, "lwl", Iload },
  78. { Ilw, "lw", Iload },
  79. { Ilbu, "lbu", Iload },
  80. { Ilhu, "lhu", Iload },
  81. { Ilwr, "lwr", Iload },
  82. { undef, "" },
  83. { Isb, "sb", Istore },
  84. { Ish, "sh", Istore },
  85. { undef, "" },
  86. { Isw, "sw", Istore }, /* 43 */
  87. { undef, "" },
  88. { undef, "" },
  89. { undef, "" },
  90. { undef, "" },
  91. { Ill, "ll", Iload},
  92. { Ilwc1, "lwc1", Ifloat },
  93. { undef, "" },
  94. { undef, "" },
  95. { undef, "" },
  96. { undef, "" },
  97. { undef, "" },
  98. { undef, "" },
  99. { Isc, "sc", Istore },
  100. { Iswc1, "swc1", Ifloat },
  101. { undef, "" },
  102. { undef, "" },
  103. { undef, "" },
  104. { undef, "" },
  105. { undef, "" },
  106. { undef, "" },
  107. { 0 }
  108. };
  109. void
  110. dortrace(void)
  111. {
  112. int i;
  113. for(i = 0; i < 32; i++)
  114. if(rtrace & (1<<i))
  115. Bprint(bioout, "R%.2d %.8lux\n", i, reg.r[i]);
  116. }
  117. void
  118. run(void)
  119. {
  120. do {
  121. reg.r[0] = 0;
  122. reg.ir = ifetch(reg.pc);
  123. Iexec(reg.ir);
  124. reg.pc += 4;
  125. if(bplist)
  126. brkchk(reg.pc, Instruction);
  127. if(rtrace)
  128. dortrace();
  129. Bflush(bioout);
  130. }while(--count);
  131. }
  132. void
  133. undef(ulong inst)
  134. {
  135. /*
  136. if((reg.ir>>26) == 0)
  137. Bprint(bioout, "special=%d,%d table=%d\n",
  138. (reg.ir>>3)&0x7, reg.ir&0x7, reg.ir&0x3f);
  139. else
  140. Bprint(bioout, "code=%d,%d table=%d\n",
  141. reg.ir>>29, (reg.ir>>26)&0x7, reg.ir>>26);
  142. */
  143. Bprint(bioout, "Undefined Instruction Trap IR %.8lux\n", inst);
  144. longjmp(errjmp, 0);
  145. }
  146. void
  147. Iaddi(ulong inst)
  148. {
  149. int rs, rt;
  150. int imm;
  151. Getrsrt(rs, rt, inst);
  152. imm = (short)(inst&0xffff);
  153. if(trace)
  154. itrace("addi\tr%d,r%d,#0x%x", rt, rs, imm);
  155. reg.r[rt] = reg.r[rs] + imm;
  156. }
  157. void
  158. Iandi(ulong inst)
  159. {
  160. int rs, rt;
  161. int imm;
  162. Getrsrt(rs, rt, inst);
  163. imm = inst&0xffff;
  164. if(trace)
  165. itrace("andi\tr%d,r%d,#0x%x", rt, rs, imm);
  166. reg.r[rt] = reg.r[rs] & imm;
  167. }
  168. void
  169. Isw(ulong inst)
  170. {
  171. int rt, rb;
  172. int off;
  173. ulong v;
  174. Getrbrt(rb, rt, inst);
  175. off = (short)(inst&0xffff);
  176. v = reg.r[rt];
  177. if(trace)
  178. itrace("sw\tr%d,0x%x(r%d) %lux=%lux",
  179. rt, off, rb, reg.r[rb]+off, v);
  180. putmem_w(reg.r[rb]+off, v);
  181. }
  182. void
  183. Isb(ulong inst)
  184. {
  185. int rt, rb;
  186. int off;
  187. uchar value;
  188. Getrbrt(rb, rt, inst);
  189. off = (short)(inst&0xffff);
  190. value = reg.r[rt];
  191. if(trace)
  192. itrace("sb\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, reg.r[rb]+off, value);
  193. putmem_b(reg.r[rb]+off, value);
  194. }
  195. void
  196. Ish(ulong inst)
  197. {
  198. int rt, rb;
  199. int off;
  200. ushort value;
  201. Getrbrt(rb, rt, inst);
  202. off = (short)(inst&0xffff);
  203. value = reg.r[rt];
  204. if(trace)
  205. itrace("sh\tr%d,0x%x(r%d) %lux=%lux",
  206. rt, off, rb, reg.r[rb]+off, value&0xffff);
  207. putmem_h(reg.r[rb]+off, value);
  208. }
  209. void
  210. Ilui(ulong inst)
  211. {
  212. int rs, rt;
  213. int imm;
  214. Getrsrt(rs, rt, inst);
  215. USED(rs);
  216. imm = inst<<16;
  217. if(trace)
  218. itrace("lui\tr%d,#0x%x", rt, imm);
  219. reg.r[rt] = imm;
  220. }
  221. void
  222. Iori(ulong inst)
  223. {
  224. int rs, rt;
  225. int imm;
  226. Getrsrt(rs, rt, inst);
  227. imm = inst&0xffff;
  228. if(trace)
  229. itrace("ori\tr%d,r%d,#0x%x", rt, rs, imm);
  230. reg.r[rt] = reg.r[rs] | imm;
  231. }
  232. void
  233. Ixori(ulong inst)
  234. {
  235. int rs, rt;
  236. int imm;
  237. Getrsrt(rs, rt, inst);
  238. imm = inst&0xffff;
  239. if(trace)
  240. itrace("xori\tr%d,r%d,#0x%x", rt, rs, imm);
  241. reg.r[rt] = reg.r[rs] ^ imm;
  242. }
  243. void
  244. Ilw(ulong inst)
  245. {
  246. int rt, rb;
  247. int off;
  248. ulong v, va;
  249. Getrbrt(rb, rt, inst);
  250. off = (short)(inst&0xffff);
  251. va = reg.r[rb]+off;
  252. if(trace) {
  253. v = 0;
  254. if(!badvaddr(va, 4))
  255. v = getmem_w(va);
  256. itrace("lw\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
  257. }
  258. reg.r[rt] = getmem_w(va);
  259. }
  260. void
  261. Ilwl(ulong inst)
  262. {
  263. int rt, rb;
  264. int off;
  265. ulong v, va;
  266. Getrbrt(rb, rt, inst);
  267. off = (short)(inst&0xffff);
  268. va = reg.r[rb]+off;
  269. if(trace) {
  270. v = 0;
  271. if(!badvaddr(va, 4))
  272. v = getmem_w(va & ~3) << ((va & 3) << 3);
  273. itrace("lwl\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
  274. }
  275. v = getmem_w(va & ~3);
  276. switch(va & 3) {
  277. case 0:
  278. reg.r[rt] = v;
  279. break;
  280. case 1:
  281. reg.r[rt] = (v<<8) | (reg.r[rt] & 0xff);
  282. break;
  283. case 2:
  284. reg.r[rt] = (v<<16) | (reg.r[rt] & 0xffff);
  285. break;
  286. case 3:
  287. reg.r[rt] = (v<<24) | (reg.r[rt] & 0xffffff);
  288. break;
  289. }
  290. }
  291. void
  292. Ilwr(ulong inst)
  293. {
  294. int rt, rb;
  295. int off;
  296. ulong v, va;
  297. Getrbrt(rb, rt, inst);
  298. off = (short)(inst&0xffff);
  299. va = reg.r[rb]+off;
  300. if(trace) {
  301. v = 0;
  302. if(!badvaddr(va, 4))
  303. v = getmem_w(va & ~3) << ((va & 3) << 3);
  304. itrace("lwr\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
  305. }
  306. v = getmem_w(va & ~3);
  307. switch(va & 3) {
  308. case 0:
  309. break;
  310. case 1:
  311. reg.r[rt] = (v>>24) | (reg.r[rt] & 0xffffff00);
  312. break;
  313. case 2:
  314. reg.r[rt] = (v>>16) | (reg.r[rt] & 0xffff0000);
  315. break;
  316. case 3:
  317. reg.r[rt] = (v>>8) | (reg.r[rt] & 0xff0000000);
  318. break;
  319. }
  320. }
  321. void
  322. Ilh(ulong inst)
  323. {
  324. int rt, rb;
  325. int off;
  326. ulong v, va;
  327. Getrbrt(rb, rt, inst);
  328. off = (short)(inst&0xffff);
  329. va = reg.r[rb]+off;
  330. if(trace) {
  331. v = 0;
  332. if(!badvaddr(va, 2))
  333. v = (short)getmem_h(va);
  334. itrace("lw\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
  335. }
  336. reg.r[rt] = (short)getmem_h(va);
  337. }
  338. void
  339. Ilhu(ulong inst)
  340. {
  341. int rt, rb;
  342. int off;
  343. ulong v, va;
  344. Getrbrt(rb, rt, inst);
  345. off = (short)(inst&0xffff);
  346. va = reg.r[rb]+off;
  347. if(trace) {
  348. v = 0;
  349. if(!badvaddr(va, 2))
  350. v = getmem_h(va) & 0xffff;
  351. itrace("lhu\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
  352. }
  353. reg.r[rt] = getmem_h(va) & 0xffff;
  354. }
  355. void
  356. Ilb(ulong inst)
  357. {
  358. int rt, rb;
  359. int off;
  360. ulong v, va;
  361. Getrbrt(rb, rt, inst);
  362. off = (short)(inst&0xffff);
  363. va = reg.r[rb]+off;
  364. if(trace) {
  365. v = 0;
  366. if(!badvaddr(va, 1))
  367. v = (schar)getmem_b(va);
  368. itrace("lb\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
  369. }
  370. reg.r[rt] = (schar)getmem_b(va);
  371. }
  372. void
  373. Ilbu(ulong inst)
  374. {
  375. int rt, rb;
  376. int off;
  377. ulong v, va;
  378. Getrbrt(rb, rt, inst);
  379. off = (short)(inst&0xffff);
  380. va = reg.r[rb]+off;
  381. if(trace) {
  382. v = 0;
  383. if(!badvaddr(va, 1))
  384. v = getmem_b(va) & 0xff;
  385. itrace("lbu\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
  386. }
  387. reg.r[rt] = getmem_b(va) & 0xff;
  388. }
  389. void
  390. Ijal(ulong inst)
  391. {
  392. ulong npc;
  393. Symbol s;
  394. npc = (reg.pc&0xF0000000)|((inst&0x3FFFFFF)<<2);
  395. if(trace)
  396. itrace("jal\t0x%lux", npc);
  397. reg.r[31] = reg.pc+8;
  398. /* Do the delay slot */
  399. reg.ir = ifetch(reg.pc+4);
  400. Statbra();
  401. Iexec(reg.ir);
  402. if(calltree) {
  403. findsym(npc, CTEXT, &s);
  404. Bprint(bioout, "%8lux %s(", reg.pc, s.name);
  405. printparams(&s, reg.r[29]);
  406. Bprint(bioout, "from ");
  407. printsource(reg.pc);
  408. Bputc(bioout, '\n');
  409. }
  410. reg.pc = npc-4;
  411. }
  412. void
  413. Ij(ulong inst)
  414. {
  415. ulong npc;
  416. npc = (reg.pc&0xF0000000)|((inst&0x3FFFFFF)<<2);
  417. if(trace)
  418. itrace("j\t0x%lux", npc);
  419. /* Do the delay slot */
  420. reg.ir = ifetch(reg.pc+4);
  421. Statbra();
  422. Iexec(reg.ir);
  423. reg.pc = npc-4;
  424. }
  425. void
  426. Ibeq(ulong inst)
  427. {
  428. int rt, rs;
  429. int off;
  430. ulong npc;
  431. Getrsrt(rs, rt, inst);
  432. off = (short)(inst&0xffff);
  433. npc = reg.pc + (off<<2) + 4;
  434. if(trace)
  435. itrace("beq\tr%d,r%d,0x%lux", rs, rt, npc);
  436. if(reg.r[rs] == reg.r[rt]) {
  437. /* Do the delay slot */
  438. reg.ir = ifetch(reg.pc+4);
  439. Statbra();
  440. Iexec(reg.ir);
  441. reg.pc = npc-4;
  442. }
  443. }
  444. void
  445. Ibeql(ulong inst)
  446. {
  447. int rt, rs;
  448. int off;
  449. ulong npc;
  450. Getrsrt(rs, rt, inst);
  451. off = (short)(inst&0xffff);
  452. npc = reg.pc + (off<<2) + 4;
  453. if(trace)
  454. itrace("beq\tr%d,r%d,0x%lux", rs, rt, npc);
  455. if(reg.r[rs] == reg.r[rt]) {
  456. /* Do the delay slot */
  457. reg.ir = ifetch(reg.pc+4);
  458. Statbra();
  459. Iexec(reg.ir);
  460. reg.pc = npc-4;
  461. } else
  462. reg.pc += 4;
  463. }
  464. void
  465. Ibgtz(ulong inst)
  466. {
  467. int rs;
  468. int off;
  469. ulong npc, r;
  470. rs = (inst>>21)&0x1f;
  471. off = (short)(inst&0xffff);
  472. npc = reg.pc + (off<<2) + 4;
  473. if(trace)
  474. itrace("bgtz\tr%d,0x%lux", rs, npc);
  475. r = reg.r[rs];
  476. if(!(r&SIGNBIT) && r != 0) {
  477. /* Do the delay slot */
  478. reg.ir = ifetch(reg.pc+4);
  479. Iexec(reg.ir);
  480. reg.pc = npc-4;
  481. }
  482. }
  483. void
  484. Ibgtzl(ulong inst)
  485. {
  486. int rs;
  487. int off;
  488. ulong npc, r;
  489. rs = (inst>>21)&0x1f;
  490. off = (short)(inst&0xffff);
  491. npc = reg.pc + (off<<2) + 4;
  492. if(trace)
  493. itrace("bgtz\tr%d,0x%lux", rs, npc);
  494. r = reg.r[rs];
  495. if(!(r&SIGNBIT) && r != 0) {
  496. /* Do the delay slot */
  497. reg.ir = ifetch(reg.pc+4);
  498. Iexec(reg.ir);
  499. reg.pc = npc-4;
  500. } else
  501. reg.pc += 4;
  502. }
  503. void
  504. Iblez(ulong inst)
  505. {
  506. int rs;
  507. int off;
  508. ulong npc, r;
  509. rs = (inst>>21)&0x1f;
  510. off = (short)(inst&0xffff);
  511. npc = reg.pc + (off<<2) + 4;
  512. if(trace)
  513. itrace("blez\tr%d,0x%lux", rs, npc);
  514. r = reg.r[rs];
  515. if((r&SIGNBIT) || r == 0) {
  516. /* Do the delay slot */
  517. reg.ir = ifetch(reg.pc+4);
  518. Statbra();
  519. Iexec(reg.ir);
  520. reg.pc = npc-4;
  521. }
  522. }
  523. void
  524. Iblezl(ulong inst)
  525. {
  526. int rs;
  527. int off;
  528. ulong npc, r;
  529. rs = (inst>>21)&0x1f;
  530. off = (short)(inst&0xffff);
  531. npc = reg.pc + (off<<2) + 4;
  532. if(trace)
  533. itrace("blez\tr%d,0x%lux", rs, npc);
  534. r = reg.r[rs];
  535. if((r&SIGNBIT) || r == 0) {
  536. /* Do the delay slot */
  537. reg.ir = ifetch(reg.pc+4);
  538. Statbra();
  539. Iexec(reg.ir);
  540. reg.pc = npc-4;
  541. } else
  542. reg.pc += 4;
  543. }
  544. void
  545. Ibne(ulong inst)
  546. {
  547. int rt, rs;
  548. int off;
  549. ulong npc;
  550. Getrsrt(rs, rt, inst);
  551. off = (short)(inst&0xffff);
  552. npc = reg.pc + (off<<2) + 4;
  553. if(trace)
  554. itrace("bne\tr%d,r%d,0x%lux", rs, rt, npc);
  555. if(reg.r[rs] != reg.r[rt]) {
  556. /* Do the delay slot */
  557. reg.ir = ifetch(reg.pc+4);
  558. Statbra();
  559. Iexec(reg.ir);
  560. reg.pc = npc-4;
  561. }
  562. }
  563. void
  564. Ibnel(ulong inst)
  565. {
  566. int rt, rs;
  567. int off;
  568. ulong npc;
  569. Getrsrt(rs, rt, inst);
  570. off = (short)(inst&0xffff);
  571. npc = reg.pc + (off<<2) + 4;
  572. if(trace)
  573. itrace("bne\tr%d,r%d,0x%lux", rs, rt, npc);
  574. if(reg.r[rs] != reg.r[rt]) {
  575. /* Do the delay slot */
  576. reg.ir = ifetch(reg.pc+4);
  577. Statbra();
  578. Iexec(reg.ir);
  579. reg.pc = npc-4;
  580. } else
  581. reg.pc += 4;
  582. }
  583. void
  584. Iaddiu(ulong inst)
  585. {
  586. int rs, rt;
  587. int imm;
  588. Getrsrt(rs, rt, inst);
  589. imm = (short)(inst&0xffff);
  590. if(trace)
  591. itrace("addiu\tr%d,r%d,#0x%x", rt, rs, imm);
  592. reg.r[rt] = reg.r[rs]+imm;
  593. }
  594. void
  595. Islti(ulong inst)
  596. {
  597. int rs, rt;
  598. int imm;
  599. Getrsrt(rs, rt, inst);
  600. imm = (short)(inst&0xffff);
  601. if(trace)
  602. itrace("slti\tr%d,r%d,#0x%x", rt, rs, imm);
  603. reg.r[rt] = reg.r[rs] < imm ? 1 : 0;
  604. }
  605. void
  606. Isltiu(ulong inst)
  607. {
  608. int rs, rt;
  609. int imm;
  610. Getrsrt(rs, rt, inst);
  611. imm = (short)(inst&0xffff);
  612. if(trace)
  613. itrace("sltiu\tr%d,r%d,#0x%x", rt, rs, imm);
  614. reg.r[rt] = (ulong)reg.r[rs] < (ulong)imm ? 1 : 0;
  615. }
  616. /* ll and sc are implemented as lw and sw, since we simulate a uniprocessor */
  617. void
  618. Ill(ulong inst)
  619. {
  620. int rt, rb;
  621. int off;
  622. ulong v, va;
  623. Getrbrt(rb, rt, inst);
  624. off = (short)(inst&0xffff);
  625. va = reg.r[rb]+off;
  626. if(trace) {
  627. v = 0;
  628. if(!badvaddr(va, 4))
  629. v = getmem_w(va);
  630. itrace("ll\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
  631. }
  632. reg.r[rt] = getmem_w(va);
  633. }
  634. void
  635. Isc(ulong inst)
  636. {
  637. int rt, rb;
  638. int off;
  639. ulong v;
  640. Getrbrt(rb, rt, inst);
  641. off = (short)(inst&0xffff);
  642. v = reg.r[rt];
  643. if(trace)
  644. itrace("sc\tr%d,0x%x(r%d) %lux=%lux",
  645. rt, off, rb, reg.r[rb]+off, v);
  646. putmem_w(reg.r[rb]+off, v);
  647. }
  648. enum
  649. {
  650. Bltz = 0,
  651. Bgez = 1,
  652. Bltzal = 0x10,
  653. Bgezal = 0x11,
  654. Bltzl = 2,
  655. Bgezl = 3,
  656. Bltzall = 0x12,
  657. Bgezall = 0x13,
  658. };
  659. static char *sbcond[] =
  660. {
  661. [Bltz] "ltz",
  662. [Bgez] "gez",
  663. [Bltzal] "ltzal",
  664. [Bgezal] "gezal",
  665. [Bltzl] "ltzl",
  666. [Bgezl] "gezl",
  667. [Bltzall] "ltzall",
  668. [Bgezall] "gezall",
  669. };
  670. void
  671. Ibcond(ulong inst)
  672. {
  673. int rs, bran;
  674. int off, doit, likely;
  675. ulong npc;
  676. rs = (inst>>21)&0x1f;
  677. bran = (inst>>16)&0x1f;
  678. off = (short)(inst&0xffff);
  679. doit = 0;
  680. likely = 0;
  681. npc = reg.pc + (off<<2) + 4;
  682. switch(bran) {
  683. default:
  684. Bprint(bioout, "bcond=%d\n", bran);
  685. undef(inst);
  686. case Bltzl:
  687. likely = 1;
  688. case Bltz:
  689. if(reg.r[rs]&SIGNBIT)
  690. doit = 1;
  691. break;
  692. case Bgezl:
  693. likely = 1;
  694. case Bgez:
  695. if(!(reg.r[rs]&SIGNBIT))
  696. doit = 1;
  697. break;
  698. case Bltzall:
  699. likely = 1;
  700. case Bltzal:
  701. reg.r[31] = reg.pc+8;
  702. if(reg.r[rs]&SIGNBIT)
  703. doit = 1;
  704. break;
  705. case Bgezall:
  706. likely = 1;
  707. case Bgezal:
  708. reg.r[31] = reg.pc+8;
  709. if(!(reg.r[rs]&SIGNBIT))
  710. doit = 1;
  711. break;
  712. }
  713. if(trace)
  714. itrace("b%s\tr%d,0x%lux", sbcond[bran], rs, npc);
  715. if(doit) {
  716. /* Do the delay slot */
  717. reg.ir = ifetch(reg.pc+4);
  718. Statbra();
  719. Iexec(reg.ir);
  720. reg.pc = npc-4;
  721. } else
  722. if(likely)
  723. reg.pc += 4;
  724. }