run.c 14 KB

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