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