run.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include <mach.h>
  5. #define Extern extern
  6. #include "power.h"
  7. void lfs(ulong);
  8. void lfd(ulong);
  9. void stfs(ulong);
  10. void stfd(ulong);
  11. /* indexed versions are in 31 */
  12. void addic(ulong);
  13. void addiccc(ulong);
  14. void addi(ulong);
  15. void addis(ulong);
  16. void andicc(ulong);
  17. void andiscc(ulong);
  18. void bcx(ulong);
  19. void bx(ulong);
  20. void cmpi(ulong);
  21. void cmpli(ulong);
  22. void lbz(ulong);
  23. void lha(ulong);
  24. void lhz(ulong);
  25. void lmw(ulong);
  26. void lwz(ulong);
  27. void mulli(ulong);
  28. void ori(ulong);
  29. void oris(ulong);
  30. void rlwimi(ulong);
  31. void rlwinm(ulong);
  32. void rlwnm(ulong);
  33. void sc(ulong);
  34. void stb(ulong);
  35. void sth(ulong);
  36. void stmw(ulong);
  37. void stw(ulong);
  38. void subfic(ulong);
  39. void twi(ulong);
  40. void xori(ulong);
  41. void xoris(ulong);
  42. Inst op0[] = {
  43. [3] {twi, "twi", Ibranch},
  44. [7] {mulli, "mulli", Iarith},
  45. [8] {subfic, "subfic", Iarith},
  46. [10] {cmpli, "cmpli", Iarith},
  47. [11] {cmpi, "cmpi", Iarith},
  48. [12] {addic, "addic", Iarith},
  49. [13] {addiccc, "addic.", Iarith},
  50. [14] {addi, "addi", Iarith},
  51. [15] {addis, "addis", Iarith},
  52. [16] {bcx, "bc⋯", Ibranch},
  53. [17] {sc, "sc", Isyscall},
  54. [18] {bx, "b⋯", Ibranch},
  55. /* group 19; branch unit */
  56. [20] {rlwimi, "rlwimi", Ilog},
  57. [21] {rlwinm, "rlwinm", Ilog},
  58. [23] {rlwnm, "rlwnm", Ilog},
  59. [24] {ori, "ori", Ilog},
  60. [25] {oris, "oris", Ilog},
  61. [26] {xori, "xori", Ilog},
  62. [27] {xoris, "xoris", Ilog},
  63. [28] {andicc, "andi.", Ilog},
  64. [29] {andiscc, "andis.", Ilog},
  65. /* group 31; integer & misc. */
  66. [32] {lwz, "lwz", Iload},
  67. [33] {lwz, "lwzu", Iload},
  68. [34] {lbz, "lbz", Iload},
  69. [35] {lbz, "lbzu", Iload},
  70. [36] {stw, "stw", Istore},
  71. [37] {stw, "stwu", Istore},
  72. [38] {stb, "stb", Istore},
  73. [39] {stb, "stbu", Istore},
  74. [40] {lhz, "lhz", Iload},
  75. [41] {lhz, "lhzu", Iload},
  76. [42] {lha, "lha", Iload},
  77. [43] {lha, "lhau", Iload},
  78. [44] {sth, "sth", Istore},
  79. [45] {sth, "sthu", Istore},
  80. [46] {lmw, "lmw", Iload},
  81. [47] {stmw, "stmw", Istore},
  82. [48] {lfs, "lfs", Iload},
  83. [49] {lfs, "lfsu", Iload},
  84. [50] {lfd, "lfd", Iload},
  85. [51] {lfd, "lfdu", Iload},
  86. [52] {stfs, "stfs", Istore},
  87. [53] {stfs, "stfsu", Istore},
  88. [54] {stfd, "stfd", Istore},
  89. [55] {stfd, "stfdu", Istore},
  90. /* group 59; single precision floating point */
  91. /* group 63; double precision floating point; fpscr */
  92. {0, 0, 0},
  93. };
  94. Inset ops0 = {op0, nelem(op0)-1};
  95. static char oemflag[] = {
  96. [104] 1,
  97. [10] 1,
  98. [136] 1,
  99. [138] 1,
  100. [200] 1,
  101. [202] 1,
  102. [232] 1,
  103. [234] 1,
  104. [235] 1,
  105. [266] 1,
  106. [40] 1,
  107. [459] 1,
  108. [491] 1,
  109. [8] 1,
  110. };
  111. void
  112. run(void)
  113. {
  114. int xo, f;
  115. do {
  116. reg.ir = ifetch(reg.pc);
  117. ci = 0;
  118. switch(reg.ir>>26) {
  119. default:
  120. xo = reg.ir>>26;
  121. if(xo >= nelem(op0))
  122. break;
  123. ci = &op0[xo];
  124. break;
  125. case 19:
  126. xo = getxo(reg.ir);
  127. if(xo >= ops19.nel)
  128. break;
  129. ci = &ops19.tab[xo];
  130. break;
  131. case 31:
  132. xo = getxo(reg.ir);
  133. f = xo & ~getxo(OE);
  134. if(reg.ir&OE && f < sizeof(oemflag) && oemflag[f])
  135. xo = f;
  136. if(xo >= ops31.nel)
  137. break;
  138. ci = &ops31.tab[xo];
  139. break;
  140. case 59:
  141. xo = getxo(reg.ir) & 0x1F;
  142. if(xo >= ops59.nel)
  143. break;
  144. ci = &ops59.tab[xo];
  145. break;
  146. case 63:
  147. xo = getxo(reg.ir) & 0x1F;
  148. if(xo < ops63a.nel) {
  149. ci = &ops63a.tab[xo];
  150. if(ci->func || ci->name)
  151. break;
  152. ci = 0;
  153. }
  154. xo = getxo(reg.ir);
  155. if(xo >= ops63b.nel)
  156. break;
  157. ci = &ops63b.tab[xo];
  158. break;
  159. }
  160. if(ci && ci->func){
  161. ci->count++;
  162. (*ci->func)(reg.ir);
  163. } else {
  164. if(ci && ci->name && trace)
  165. itrace("%s\t[not yet done]", ci->name);
  166. else
  167. undef(reg.ir);
  168. }
  169. reg.pc += 4;
  170. if(bplist)
  171. brkchk(reg.pc, Instruction);
  172. }while(--count);
  173. }
  174. void
  175. ilock(int)
  176. {
  177. }
  178. void
  179. undef(ulong ir)
  180. {
  181. /* Bprint(bioout, "op=%d op2=%d op3=%d\n", ir>>30, (ir>>21)&0x7, (ir>>19)&0x3f); */
  182. Bprint(bioout, "illegal_instruction IR #%.8lux (op=%ld/%ld, pc=#%.8lux)\n", ir, getop(ir), getxo(ir), reg.pc);
  183. if(ci && ci->name && ci->func==0)
  184. Bprint(bioout, "(%s not yet implemented)\n", ci->name);
  185. longjmp(errjmp, 0);
  186. }
  187. void
  188. unimp(ulong ir)
  189. {
  190. /* Bprint(bioout, "op=%d op2=%d op3=%d\n", ir>>30, (ir>>21)&0x7, (ir>>19)&0x3f); */
  191. Bprint(bioout, "illegal_instruction IR #%.8lux (op=%ld/%ld, pc=#%.8lux) %s not in MPC601\n", ir, getop(ir), getxo(ir), reg.pc, ci->name?ci->name: "-");
  192. longjmp(errjmp, 0);
  193. }