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 8 void Iaddi(ulong); 9 void Isw(ulong); 10 void Ilui(ulong); 11 void Iori(ulong); 12 void Ixori(ulong); 13 void Ilw(ulong); 14 void Ijal(ulong); 15 void Ispecial(ulong); 16 void Ibeq(ulong); 17 void Iaddiu(ulong); 18 void Ilb(ulong); 19 void Iandi(ulong); 20 void Ij(ulong); 21 void Ibne(ulong); 22 void Isb(ulong); 23 void Islti(ulong); 24 void Ibcond(ulong); 25 void Ibgtz(ulong); 26 void Ilbu(ulong); 27 void Ilhu(ulong); 28 void Ish(ulong); 29 void Ilh(ulong); 30 void Iblez(ulong); 31 void Isltiu(ulong); 32 void Iswc1(ulong); 33 void Ilwc1(ulong); 34 void Icop1(ulong); 35 36 Inst itab[] = { 37 { Ispecial, 0 }, 38 { Ibcond, "bcond", Ibranch }, 39 { Ij, "j", Ibranch }, 40 { Ijal, "jal", Ibranch }, 41 { Ibeq, "beq", Ibranch }, 42 { Ibne, "bne", Ibranch }, 43 { Iblez, "blez", Ibranch }, 44 { Ibgtz, "bgtz", Ibranch }, 45 { Iaddi, "addi", Iarith }, /* 8 */ 46 { Iaddiu, "addiu", Iarith }, 47 { Islti, "slti", Iarith }, 48 { Isltiu, "sltiu", Iarith }, 49 { Iandi, "andi", Iarith }, 50 { Iori, "ori", Iarith }, 51 { Ixori, "xori", Iarith }, 52 { Ilui, "lui", Iload }, /* 15 */ 53 { undef, "" }, 54 { Icop1, "cop1", Ifloat }, 55 { undef, "" }, 56 { undef, "" }, 57 { undef, "" }, 58 { undef, "" }, 59 { undef, "" }, 60 { undef, "" }, 61 { undef, "" }, 62 { undef, "" }, 63 { undef, "" }, 64 { undef, "" }, 65 { undef, "" }, 66 { undef, "" }, 67 { undef, "" }, 68 { undef, "" }, 69 { Ilb, "lb", Iload }, 70 { Ilh, "lh", Iload }, 71 { undef, "" }, 72 { Ilw, "lw", Iload }, 73 { Ilbu, "lbu", Iload }, 74 { Ilhu, "lhu", Iload }, 75 { undef, "" }, 76 { undef, "" }, 77 { Isb, "sb", Istore }, 78 { Ish, "sh", Istore }, 79 { undef, "" }, 80 { Isw, "sw", Istore }, /* 43 */ 81 { undef, "" }, 82 { undef, "" }, 83 { undef, "" }, 84 { undef, "" }, 85 { undef, "" }, 86 { Ilwc1, "lwc1", Ifloat }, 87 { undef, "" }, 88 { undef, "" }, 89 { undef, "" }, 90 { undef, "" }, 91 { undef, "" }, 92 { undef, "" }, 93 { undef, "" }, 94 { Iswc1, "swc1", Ifloat }, 95 { undef, "" }, 96 { undef, "" }, 97 { undef, "" }, 98 { undef, "" }, 99 { undef, "" }, 100 { undef, "" }, 101 { 0 } 102 }; 103 104 void 105 run(void) 106 { 107 do { 108 reg.r[0] = 0; 109 reg.ir = ifetch(reg.pc); 110 Iexec(reg.ir); 111 reg.pc += 4; 112 if(bplist) 113 brkchk(reg.pc, Instruction); 114 }while(--count); 115 } 116 117 void 118 undef(ulong inst) 119 { 120 /* 121 if((reg.ir>>26) == 0) 122 Bprint(bioout, "special=%d,%d table=%d\n", 123 (reg.ir>>3)&0x7, reg.ir&0x7, reg.ir&0x3f); 124 else 125 Bprint(bioout, "code=%d,%d table=%d\n", 126 reg.ir>>29, (reg.ir>>26)&0x7, reg.ir>>26); 127 */ 128 Bprint(bioout, "Undefined Instruction Trap IR %.8lux\n", inst); 129 longjmp(errjmp, 0); 130 } 131 132 void 133 Iaddi(ulong inst) 134 { 135 int rs, rt; 136 int imm; 137 138 Getrsrt(rs, rt, inst); 139 imm = (short)(inst&0xffff); 140 141 if(trace) 142 itrace("addi\tr%d,r%d,#0x%x", rt, rs, imm); 143 144 reg.r[rt] = reg.r[rs] + imm; 145 } 146 147 void 148 Iandi(ulong inst) 149 { 150 int rs, rt; 151 int imm; 152 153 Getrsrt(rs, rt, inst); 154 imm = inst&0xffff; 155 156 if(trace) 157 itrace("andi\tr%d,r%d,#0x%x", rt, rs, imm); 158 159 reg.r[rt] = reg.r[rs] & imm; 160 } 161 162 void 163 Isw(ulong inst) 164 { 165 int rt, rb; 166 int off; 167 ulong value; 168 169 Getrbrt(rb, rt, inst); 170 off = (short)(inst&0xffff); 171 172 value = reg.r[rt]; 173 if(trace) 174 itrace("sw\tr%d,0x%x(r%d) %lux=%lux", 175 rt, off, rb, reg.r[rb]+off, value); 176 177 putmem_w(reg.r[rb]+off, value); 178 } 179 180 void 181 Isb(ulong inst) 182 { 183 int rt, rb; 184 int off; 185 uchar value; 186 187 Getrbrt(rb, rt, inst); 188 off = (short)(inst&0xffff); 189 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 194 putmem_b(reg.r[rb]+off, value); 195 } 196 197 void 198 Ish(ulong inst) 199 { 200 int rt, rb; 201 int off; 202 ushort value; 203 204 Getrbrt(rb, rt, inst); 205 off = (short)(inst&0xffff); 206 207 value = reg.r[rt]; 208 if(trace) 209 itrace("sh\tr%d,0x%x(r%d) %lux=%lux", 210 rt, off, rb, reg.r[rb]+off, value&0xffff); 211 212 putmem_h(reg.r[rb]+off, value); 213 } 214 215 void 216 Ilui(ulong inst) 217 { 218 int rs, rt; 219 int imm; 220 221 Getrsrt(rs, rt, inst); 222 USED(rs); 223 imm = inst<<16; 224 225 if(trace) 226 itrace("lui\tr%d,#0x%x", rt, imm); 227 228 reg.r[rt] = imm; 229 } 230 231 void 232 Iori(ulong inst) 233 { 234 int rs, rt; 235 int imm; 236 237 Getrsrt(rs, rt, inst); 238 imm = inst&0xffff; 239 240 if(trace) 241 itrace("ori\tr%d,r%d,#0x%x", rt, rs, imm); 242 243 reg.r[rt] = reg.r[rs] | imm; 244 } 245 246 void 247 Ixori(ulong inst) 248 { 249 int rs, rt; 250 int imm; 251 252 Getrsrt(rs, rt, inst); 253 imm = inst&0xffff; 254 255 if(trace) 256 itrace("xori\tr%d,r%d,#0x%x", rt, rs, imm); 257 258 reg.r[rt] = reg.r[rs] ^ imm; 259 } 260 261 void 262 Ilw(ulong inst) 263 { 264 int rt, rb; 265 int off; 266 267 Getrbrt(rb, rt, inst); 268 off = (short)(inst&0xffff); 269 270 if(trace) 271 itrace("lw\tr%d,0x%x(r%d) ea=%lux", rt, off, rb, reg.r[rb]+off); 272 273 reg.r[rt] = getmem_w(reg.r[rb]+off); 274 } 275 276 void 277 Ilh(ulong inst) 278 { 279 int rt, rb; 280 int off; 281 282 Getrbrt(rb, rt, inst); 283 off = (short)(inst&0xffff); 284 285 if(trace) 286 itrace("lh\tr%d,0x%x(r%d) ea=%lux", rt, off, rb, reg.r[rb]+off); 287 288 reg.r[rt] = (short)getmem_h(reg.r[rb]+off); 289 } 290 291 void 292 Ijal(ulong inst) 293 { 294 ulong npc; 295 Symbol s; 296 297 npc = (reg.pc&0xF0000000)|((inst&0x3FFFFFF)<<2); 298 if(trace) 299 itrace("jal\t0x%lux", npc); 300 301 reg.r[31] = reg.pc+8; 302 /* Do the delay slot */ 303 reg.ir = ifetch(reg.pc+4); 304 Statbra(); 305 Iexec(reg.ir); 306 307 if(calltree) { 308 findsym(npc, CTEXT, &s); 309 Bprint(bioout, "%8lux %s(", reg.pc, s.name); 310 printparams(&s, reg.r[29]); 311 Bprint(bioout, "from "); 312 printsource(reg.pc); 313 Bputc(bioout, '\n'); 314 } 315 316 reg.pc = npc-4; 317 } 318 319 void 320 Ij(ulong inst) 321 { 322 ulong npc; 323 324 npc = (reg.pc&0xF0000000)|((inst&0x3FFFFFF)<<2); 325 if(trace) 326 itrace("j\t0x%lux", npc); 327 328 /* Do the delay slot */ 329 reg.ir = ifetch(reg.pc+4); 330 Statbra(); 331 Iexec(reg.ir); 332 reg.pc = npc-4; 333 } 334 335 void 336 Ibeq(ulong inst) 337 { 338 int rt, rs; 339 int off; 340 ulong npc; 341 342 Getrsrt(rs, rt, inst); 343 off = (short)(inst&0xffff); 344 345 npc = reg.pc + (off<<2) + 4; 346 if(trace) 347 itrace("beq\tr%d,r%d,0x%lux", rs, rt, npc); 348 349 if(reg.r[rs] == reg.r[rt]) { 350 /* Do the delay slot */ 351 reg.ir = ifetch(reg.pc+4); 352 Statbra(); 353 Iexec(reg.ir); 354 reg.pc = npc-4; 355 } 356 } 357 358 void 359 Ibgtz(ulong inst) 360 { 361 int rs; 362 int off; 363 ulong npc, r; 364 365 rs = (inst>>21)&0x1f; 366 off = (short)(inst&0xffff); 367 368 npc = reg.pc + (off<<2) + 4; 369 if(trace) 370 itrace("bgtz\tr%d,0x%lux", rs, npc); 371 372 r = reg.r[rs]; 373 if(!(r&SIGNBIT) && r != 0) { 374 /* Do the delay slot */ 375 reg.ir = ifetch(reg.pc+4); 376 Iexec(reg.ir); 377 reg.pc = npc-4; 378 } 379 } 380 381 void 382 Iblez(ulong inst) 383 { 384 int rs; 385 int off; 386 ulong npc, r; 387 388 rs = (inst>>21)&0x1f; 389 off = (short)(inst&0xffff); 390 391 npc = reg.pc + (off<<2) + 4; 392 if(trace) 393 itrace("blez\tr%d,0x%lux", rs, npc); 394 395 r = reg.r[rs]; 396 if((r&SIGNBIT) || r == 0) { 397 /* Do the delay slot */ 398 reg.ir = ifetch(reg.pc+4); 399 Statbra(); 400 Iexec(reg.ir); 401 reg.pc = npc-4; 402 } 403 } 404 405 void 406 Ibne(ulong inst) 407 { 408 int rt, rs; 409 int off; 410 ulong npc; 411 412 Getrsrt(rs, rt, inst); 413 off = (short)(inst&0xffff); 414 415 npc = reg.pc + (off<<2) + 4; 416 if(trace) 417 itrace("bne\tr%d,r%d,0x%lux", rs, rt, npc); 418 419 if(reg.r[rs] != reg.r[rt]) { 420 /* Do the delay slot */ 421 reg.ir = ifetch(reg.pc+4); 422 Statbra(); 423 Iexec(reg.ir); 424 reg.pc = npc-4; 425 } 426 } 427 428 void 429 Iaddiu(ulong inst) 430 { 431 int rs, rt; 432 int imm; 433 434 Getrsrt(rs, rt, inst); 435 imm = (short)(inst&0xffff); 436 437 if(trace) 438 itrace("addiu\tr%d,r%d,#0x%x", rt, rs, imm); 439 440 reg.r[rt] = reg.r[rs]+imm; 441 } 442 443 void 444 Islti(ulong inst) 445 { 446 int rs, rt; 447 int imm; 448 449 Getrsrt(rs, rt, inst); 450 imm = (short)(inst&0xffff); 451 452 if(trace) 453 itrace("slti\tr%d,r%d,#0x%x", rt, rs, imm); 454 455 reg.r[rt] = reg.r[rs] < imm ? 1 : 0; 456 } 457 458 void 459 Isltiu(ulong inst) 460 { 461 int rs, rt; 462 int imm; 463 464 Getrsrt(rs, rt, inst); 465 imm = (short)(inst&0xffff); 466 467 if(trace) 468 itrace("sltiu\tr%d,r%d,#0x%x", rt, rs, imm); 469 470 reg.r[rt] = (ulong)reg.r[rs] < (ulong)imm ? 1 : 0; 471 } 472 473 void 474 Ilb(ulong inst) 475 { 476 int rt, rb; 477 int off; 478 479 Getrbrt(rb, rt, inst); 480 off = (short)(inst&0xffff); 481 482 if(trace) 483 itrace("lb\tr%d,0x%x(r%d) ea=%lux", rt, off, rb, reg.r[rb]+off); 484 485 reg.r[rt] = (schar)getmem_b(reg.r[rb]+off); 486 } 487 488 void 489 Ilbu(ulong inst) 490 { 491 int rt, rb; 492 int off; 493 494 Getrbrt(rb, rt, inst); 495 off = (short)(inst&0xffff); 496 497 if(trace) 498 itrace("lbu\tr%d,0x%x(r%d) ea=%lux", rt, off, rb, reg.r[rb]+off); 499 500 reg.r[rt] = getmem_b(reg.r[rb]+off) & 0xff; 501 } 502 503 void 504 Ilhu(ulong inst) 505 { 506 int rt, rb; 507 int off; 508 509 Getrbrt(rb, rt, inst); 510 off = (short)(inst&0xffff); 511 512 if(trace) 513 itrace("lhu\tr%d,0x%x(r%d) ea=%lux", rt, off, rb, reg.r[rb]+off); 514 515 reg.r[rt] = getmem_h(reg.r[rb]+off) & 0xffff; 516 } 517 518 enum 519 { 520 Bltz = 0, 521 Bgez = 1, 522 Bltzal = 0x10, 523 Bgezal = 0x11, 524 }; 525 526 static char *sbcond[] = 527 { 528 [Bltz] "ltz", 529 [Bgez] "gez", 530 [Bltzal] "ltzal", 531 [Bgezal] "gezal", 532 }; 533 534 void 535 Ibcond(ulong inst) 536 { 537 int rs, bran; 538 int off, doit; 539 ulong npc; 540 541 rs = (inst>>21)&0x1f; 542 bran = (inst>>16)&0x1f; 543 off = (short)(inst&0xffff); 544 doit = 0; 545 546 npc = reg.pc + (off<<2) + 4; 547 switch(bran) { 548 default: 549 Bprint(bioout, "bcond=%d\n", bran); 550 undef(inst); 551 case Bltz: 552 if(reg.r[rs]&SIGNBIT) 553 doit = 1; 554 break; 555 case Bgez: 556 if(!(reg.r[rs]&SIGNBIT)) 557 doit = 1; 558 break; 559 case Bltzal: 560 if(reg.r[rs]&SIGNBIT) { 561 doit = 1; 562 reg.r[31] = reg.pc+8; 563 } 564 break; 565 case Bgezal: 566 if(reg.r[rs] >= 0) { 567 doit = 1; 568 reg.r[31] = reg.pc+8; 569 } 570 break; 571 } 572 573 if(trace) 574 itrace("b%s\tr%d,0x%lux", sbcond[bran], rs, npc); 575 576 if(doit) { 577 /* Do the delay slot */ 578 reg.ir = ifetch(reg.pc+4); 579 Statbra(); 580 Iexec(reg.ir); 581 reg.pc = npc-4; 582 } 583 584 } 585