summaryrefslogtreecommitdiff
path: root/sys/src/cmd/vi/run.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/vi/run.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/vi/run.c')
-rwxr-xr-xsys/src/cmd/vi/run.c869
1 files changed, 869 insertions, 0 deletions
diff --git a/sys/src/cmd/vi/run.c b/sys/src/cmd/vi/run.c
new file mode 100755
index 000000000..bf3883679
--- /dev/null
+++ b/sys/src/cmd/vi/run.c
@@ -0,0 +1,869 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <mach.h>
+#define Extern extern
+#include "mips.h"
+
+void Iaddi(ulong);
+void Isw(ulong);
+void Ilui(ulong);
+void Iori(ulong);
+void Ixori(ulong);
+void Ilw(ulong);
+void Ijal(ulong);
+void Ispecial(ulong);
+void Ibeq(ulong);
+void Ibeql(ulong);
+void Iaddiu(ulong);
+void Ilb(ulong);
+void Iandi(ulong);
+void Ij(ulong);
+void Ibne(ulong);
+void Ibnel(ulong);
+void Isb(ulong);
+void Islti(ulong);
+void Ibcond(ulong);
+void Ibgtz(ulong);
+void Ibgtzl(ulong);
+void Ilbu(ulong);
+void Ilhu(ulong);
+void Ish(ulong);
+void Ilh(ulong);
+void Iblez(ulong);
+void Iblezl(ulong);
+void Isltiu(ulong);
+void Iswc1(ulong);
+void Ilwc1(ulong);
+void Icop1(ulong);
+void Ilwl(ulong);
+void Ilwr(ulong);
+void Ill(ulong);
+void Isc(ulong);
+
+Inst itab[] = {
+ { Ispecial, 0 },
+ { Ibcond, "bcond", Ibranch },
+ { Ij, "j", Ibranch },
+ { Ijal, "jal", Ibranch },
+ { Ibeq, "beq", Ibranch },
+ { Ibne, "bne", Ibranch },
+ { Iblez, "blez", Ibranch },
+ { Ibgtz, "bgtz", Ibranch },
+ { Iaddi, "addi", Iarith }, /* 8 */
+ { Iaddiu, "addiu", Iarith },
+ { Islti, "slti", Iarith },
+ { Isltiu, "sltiu", Iarith },
+ { Iandi, "andi", Iarith },
+ { Iori, "ori", Iarith },
+ { Ixori, "xori", Iarith },
+ { Ilui, "lui", Iload }, /* 15 */
+ { undef, "" },
+ { Icop1, "cop1", Ifloat },
+ { undef, "" },
+ { undef, "" },
+ { Ibeql, "beql" },
+ { Ibnel, "bnel" },
+ { Iblezl, "blezl" },
+ { Ibgtzl, "bgtzl" },
+ { undef, "" },
+ { undef, "" },
+ { undef, "" },
+ { undef, "" },
+ { undef, "" },
+ { undef, "" },
+ { undef, "" },
+ { undef, "" },
+ { Ilb, "lb", Iload },
+ { Ilh, "lh", Iload },
+ { Ilwl, "lwl", Iload },
+ { Ilw, "lw", Iload },
+ { Ilbu, "lbu", Iload },
+ { Ilhu, "lhu", Iload },
+ { Ilwr, "lwr", Iload },
+ { undef, "" },
+ { Isb, "sb", Istore },
+ { Ish, "sh", Istore },
+ { undef, "" },
+ { Isw, "sw", Istore }, /* 43 */
+ { undef, "" },
+ { undef, "" },
+ { undef, "" },
+ { undef, "" },
+ { Ill, "ll", Iload},
+ { Ilwc1, "lwc1", Ifloat },
+ { undef, "" },
+ { undef, "" },
+ { undef, "" },
+ { undef, "" },
+ { undef, "" },
+ { undef, "" },
+ { Isc, "sc", Istore },
+ { Iswc1, "swc1", Ifloat },
+ { undef, "" },
+ { undef, "" },
+ { undef, "" },
+ { undef, "" },
+ { undef, "" },
+ { undef, "" },
+ { 0 }
+};
+
+void
+dortrace(void)
+{
+ int i;
+
+ for(i = 0; i < 32; i++)
+ if(rtrace & (1<<i))
+ Bprint(bioout, "R%.2d %.8lux\n", i, reg.r[i]);
+}
+
+void
+run(void)
+{
+ do {
+ reg.r[0] = 0;
+ reg.ir = ifetch(reg.pc);
+ Iexec(reg.ir);
+ reg.pc += 4;
+ if(bplist)
+ brkchk(reg.pc, Instruction);
+ if(rtrace)
+ dortrace();
+Bflush(bioout);
+ }while(--count);
+}
+
+void
+undef(ulong inst)
+{
+
+/*
+ if((reg.ir>>26) == 0)
+ Bprint(bioout, "special=%d,%d table=%d\n",
+ (reg.ir>>3)&0x7, reg.ir&0x7, reg.ir&0x3f);
+ else
+ Bprint(bioout, "code=%d,%d table=%d\n",
+ reg.ir>>29, (reg.ir>>26)&0x7, reg.ir>>26);
+*/
+
+ Bprint(bioout, "Undefined Instruction Trap IR %.8lux\n", inst);
+ longjmp(errjmp, 0);
+}
+
+void
+Iaddi(ulong inst)
+{
+ int rs, rt;
+ int imm;
+
+ Getrsrt(rs, rt, inst);
+ imm = (short)(inst&0xffff);
+
+ if(trace)
+ itrace("addi\tr%d,r%d,#0x%x", rt, rs, imm);
+
+ reg.r[rt] = reg.r[rs] + imm;
+}
+
+void
+Iandi(ulong inst)
+{
+ int rs, rt;
+ int imm;
+
+ Getrsrt(rs, rt, inst);
+ imm = inst&0xffff;
+
+ if(trace)
+ itrace("andi\tr%d,r%d,#0x%x", rt, rs, imm);
+
+ reg.r[rt] = reg.r[rs] & imm;
+}
+
+void
+Isw(ulong inst)
+{
+ int rt, rb;
+ int off;
+ ulong v;
+
+ Getrbrt(rb, rt, inst);
+ off = (short)(inst&0xffff);
+
+ v = reg.r[rt];
+ if(trace)
+ itrace("sw\tr%d,0x%x(r%d) %lux=%lux",
+ rt, off, rb, reg.r[rb]+off, v);
+
+ putmem_w(reg.r[rb]+off, v);
+}
+
+void
+Isb(ulong inst)
+{
+ int rt, rb;
+ int off;
+ uchar value;
+
+ Getrbrt(rb, rt, inst);
+ off = (short)(inst&0xffff);
+
+ value = reg.r[rt];
+ if(trace)
+ itrace("sb\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, reg.r[rb]+off, value);
+
+ putmem_b(reg.r[rb]+off, value);
+}
+
+void
+Ish(ulong inst)
+{
+ int rt, rb;
+ int off;
+ ushort value;
+
+ Getrbrt(rb, rt, inst);
+ off = (short)(inst&0xffff);
+
+ value = reg.r[rt];
+ if(trace)
+ itrace("sh\tr%d,0x%x(r%d) %lux=%lux",
+ rt, off, rb, reg.r[rb]+off, value&0xffff);
+
+ putmem_h(reg.r[rb]+off, value);
+}
+
+void
+Ilui(ulong inst)
+{
+ int rs, rt;
+ int imm;
+
+ Getrsrt(rs, rt, inst);
+ USED(rs);
+ imm = inst<<16;
+
+ if(trace)
+ itrace("lui\tr%d,#0x%x", rt, imm);
+
+ reg.r[rt] = imm;
+}
+
+void
+Iori(ulong inst)
+{
+ int rs, rt;
+ int imm;
+
+ Getrsrt(rs, rt, inst);
+ imm = inst&0xffff;
+
+ if(trace)
+ itrace("ori\tr%d,r%d,#0x%x", rt, rs, imm);
+
+ reg.r[rt] = reg.r[rs] | imm;
+}
+
+void
+Ixori(ulong inst)
+{
+ int rs, rt;
+ int imm;
+
+ Getrsrt(rs, rt, inst);
+ imm = inst&0xffff;
+
+ if(trace)
+ itrace("xori\tr%d,r%d,#0x%x", rt, rs, imm);
+
+ reg.r[rt] = reg.r[rs] ^ imm;
+}
+
+void
+Ilw(ulong inst)
+{
+ int rt, rb;
+ int off;
+ ulong v, va;
+
+ Getrbrt(rb, rt, inst);
+ off = (short)(inst&0xffff);
+
+ va = reg.r[rb]+off;
+
+ if(trace) {
+ v = 0;
+ if(!badvaddr(va, 4))
+ v = getmem_w(va);
+ itrace("lw\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
+ }
+
+ reg.r[rt] = getmem_w(va);
+}
+
+void
+Ilwl(ulong inst)
+{
+ int rt, rb;
+ int off;
+ ulong v, va;
+
+ Getrbrt(rb, rt, inst);
+ off = (short)(inst&0xffff);
+
+ va = reg.r[rb]+off;
+
+ if(trace) {
+ v = 0;
+ if(!badvaddr(va, 4))
+ v = getmem_w(va & ~3) << ((va & 3) << 3);
+ itrace("lwl\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
+ }
+
+ v = getmem_w(va & ~3);
+ switch(va & 3) {
+ case 0:
+ reg.r[rt] = v;
+ break;
+ case 1:
+ reg.r[rt] = (v<<8) | (reg.r[rt] & 0xff);
+ break;
+ case 2:
+ reg.r[rt] = (v<<16) | (reg.r[rt] & 0xffff);
+ break;
+ case 3:
+ reg.r[rt] = (v<<24) | (reg.r[rt] & 0xffffff);
+ break;
+ }
+}
+
+void
+Ilwr(ulong inst)
+{
+ int rt, rb;
+ int off;
+ ulong v, va;
+
+ Getrbrt(rb, rt, inst);
+ off = (short)(inst&0xffff);
+
+ va = reg.r[rb]+off;
+
+ if(trace) {
+ v = 0;
+ if(!badvaddr(va, 4))
+ v = getmem_w(va & ~3) << ((va & 3) << 3);
+ itrace("lwr\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
+ }
+
+ v = getmem_w(va & ~3);
+ switch(va & 3) {
+ case 0:
+ break;
+ case 1:
+ reg.r[rt] = (v>>24) | (reg.r[rt] & 0xffffff00);
+ break;
+ case 2:
+ reg.r[rt] = (v>>16) | (reg.r[rt] & 0xffff0000);
+ break;
+ case 3:
+ reg.r[rt] = (v>>8) | (reg.r[rt] & 0xff000000);
+ break;
+ }
+}
+
+void
+Ilh(ulong inst)
+{
+ int rt, rb;
+ int off;
+ ulong v, va;
+
+ Getrbrt(rb, rt, inst);
+ off = (short)(inst&0xffff);
+
+ va = reg.r[rb]+off;
+
+ if(trace) {
+ v = 0;
+ if(!badvaddr(va, 2))
+ v = (short)getmem_h(va);
+ itrace("lw\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
+ }
+
+ reg.r[rt] = (short)getmem_h(va);
+}
+
+void
+Ilhu(ulong inst)
+{
+ int rt, rb;
+ int off;
+ ulong v, va;
+
+ Getrbrt(rb, rt, inst);
+ off = (short)(inst&0xffff);
+
+ va = reg.r[rb]+off;
+
+ if(trace) {
+ v = 0;
+ if(!badvaddr(va, 2))
+ v = getmem_h(va) & 0xffff;
+ itrace("lhu\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
+ }
+
+ reg.r[rt] = getmem_h(va) & 0xffff;
+}
+
+void
+Ilb(ulong inst)
+{
+ int rt, rb;
+ int off;
+ ulong v, va;
+
+ Getrbrt(rb, rt, inst);
+ off = (short)(inst&0xffff);
+
+ va = reg.r[rb]+off;
+
+ if(trace) {
+ v = 0;
+ if(!badvaddr(va, 1))
+ v = (schar)getmem_b(va);
+ itrace("lb\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
+ }
+
+ reg.r[rt] = (schar)getmem_b(va);
+}
+
+void
+Ilbu(ulong inst)
+{
+ int rt, rb;
+ int off;
+ ulong v, va;
+
+ Getrbrt(rb, rt, inst);
+ off = (short)(inst&0xffff);
+
+ va = reg.r[rb]+off;
+
+ if(trace) {
+ v = 0;
+ if(!badvaddr(va, 1))
+ v = getmem_b(va) & 0xff;
+ itrace("lbu\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
+ }
+
+ reg.r[rt] = getmem_b(va) & 0xff;
+}
+
+void
+Ijal(ulong inst)
+{
+ ulong npc;
+ Symbol s;
+
+ npc = (reg.pc&0xF0000000)|((inst&0x3FFFFFF)<<2);
+ if(trace)
+ itrace("jal\t0x%lux", npc);
+
+ reg.r[31] = reg.pc+8;
+ /* Do the delay slot */
+ reg.ir = ifetch(reg.pc+4);
+ Statbra();
+ Iexec(reg.ir);
+
+ if(calltree) {
+ findsym(npc, CTEXT, &s);
+ Bprint(bioout, "%8lux %s(", reg.pc, s.name);
+ printparams(&s, reg.r[29]);
+ Bprint(bioout, "from ");
+ printsource(reg.pc);
+ Bputc(bioout, '\n');
+ }
+
+ reg.pc = npc-4;
+}
+
+void
+Ij(ulong inst)
+{
+ ulong npc;
+
+ npc = (reg.pc&0xF0000000)|((inst&0x3FFFFFF)<<2);
+ if(trace)
+ itrace("j\t0x%lux", npc);
+
+ /* Do the delay slot */
+ reg.ir = ifetch(reg.pc+4);
+ Statbra();
+ Iexec(reg.ir);
+ reg.pc = npc-4;
+}
+
+void
+Ibeq(ulong inst)
+{
+ int rt, rs;
+ int off;
+ ulong npc;
+
+ Getrsrt(rs, rt, inst);
+ off = (short)(inst&0xffff);
+
+ npc = reg.pc + (off<<2) + 4;
+ if(trace)
+ itrace("beq\tr%d,r%d,0x%lux", rs, rt, npc);
+
+ if(reg.r[rs] == reg.r[rt]) {
+ /* Do the delay slot */
+ reg.ir = ifetch(reg.pc+4);
+ Statbra();
+ Iexec(reg.ir);
+ reg.pc = npc-4;
+ }
+}
+
+void
+Ibeql(ulong inst)
+{
+ int rt, rs;
+ int off;
+ ulong npc;
+
+ Getrsrt(rs, rt, inst);
+ off = (short)(inst&0xffff);
+
+ npc = reg.pc + (off<<2) + 4;
+ if(trace)
+ itrace("beq\tr%d,r%d,0x%lux", rs, rt, npc);
+
+ if(reg.r[rs] == reg.r[rt]) {
+ /* Do the delay slot */
+ reg.ir = ifetch(reg.pc+4);
+ Statbra();
+ Iexec(reg.ir);
+ reg.pc = npc-4;
+ } else
+ reg.pc += 4;
+}
+
+void
+Ibgtz(ulong inst)
+{
+ int rs;
+ int off;
+ ulong npc, r;
+
+ rs = (inst>>21)&0x1f;
+ off = (short)(inst&0xffff);
+
+ npc = reg.pc + (off<<2) + 4;
+ if(trace)
+ itrace("bgtz\tr%d,0x%lux", rs, npc);
+
+ r = reg.r[rs];
+ if(!(r&SIGNBIT) && r != 0) {
+ /* Do the delay slot */
+ reg.ir = ifetch(reg.pc+4);
+ Iexec(reg.ir);
+ reg.pc = npc-4;
+ }
+}
+
+void
+Ibgtzl(ulong inst)
+{
+ int rs;
+ int off;
+ ulong npc, r;
+
+ rs = (inst>>21)&0x1f;
+ off = (short)(inst&0xffff);
+
+ npc = reg.pc + (off<<2) + 4;
+ if(trace)
+ itrace("bgtz\tr%d,0x%lux", rs, npc);
+
+ r = reg.r[rs];
+ if(!(r&SIGNBIT) && r != 0) {
+ /* Do the delay slot */
+ reg.ir = ifetch(reg.pc+4);
+ Iexec(reg.ir);
+ reg.pc = npc-4;
+ } else
+ reg.pc += 4;
+}
+
+void
+Iblez(ulong inst)
+{
+ int rs;
+ int off;
+ ulong npc, r;
+
+ rs = (inst>>21)&0x1f;
+ off = (short)(inst&0xffff);
+
+ npc = reg.pc + (off<<2) + 4;
+ if(trace)
+ itrace("blez\tr%d,0x%lux", rs, npc);
+
+ r = reg.r[rs];
+ if((r&SIGNBIT) || r == 0) {
+ /* Do the delay slot */
+ reg.ir = ifetch(reg.pc+4);
+ Statbra();
+ Iexec(reg.ir);
+ reg.pc = npc-4;
+ }
+}
+
+void
+Iblezl(ulong inst)
+{
+ int rs;
+ int off;
+ ulong npc, r;
+
+ rs = (inst>>21)&0x1f;
+ off = (short)(inst&0xffff);
+
+ npc = reg.pc + (off<<2) + 4;
+ if(trace)
+ itrace("blez\tr%d,0x%lux", rs, npc);
+
+ r = reg.r[rs];
+ if((r&SIGNBIT) || r == 0) {
+ /* Do the delay slot */
+ reg.ir = ifetch(reg.pc+4);
+ Statbra();
+ Iexec(reg.ir);
+ reg.pc = npc-4;
+ } else
+ reg.pc += 4;
+}
+
+void
+Ibne(ulong inst)
+{
+ int rt, rs;
+ int off;
+ ulong npc;
+
+ Getrsrt(rs, rt, inst);
+ off = (short)(inst&0xffff);
+
+ npc = reg.pc + (off<<2) + 4;
+ if(trace)
+ itrace("bne\tr%d,r%d,0x%lux", rs, rt, npc);
+
+ if(reg.r[rs] != reg.r[rt]) {
+ /* Do the delay slot */
+ reg.ir = ifetch(reg.pc+4);
+ Statbra();
+ Iexec(reg.ir);
+ reg.pc = npc-4;
+ }
+}
+
+void
+Ibnel(ulong inst)
+{
+ int rt, rs;
+ int off;
+ ulong npc;
+
+ Getrsrt(rs, rt, inst);
+ off = (short)(inst&0xffff);
+
+ npc = reg.pc + (off<<2) + 4;
+ if(trace)
+ itrace("bne\tr%d,r%d,0x%lux", rs, rt, npc);
+
+ if(reg.r[rs] != reg.r[rt]) {
+ /* Do the delay slot */
+ reg.ir = ifetch(reg.pc+4);
+ Statbra();
+ Iexec(reg.ir);
+ reg.pc = npc-4;
+ } else
+ reg.pc += 4;
+}
+
+void
+Iaddiu(ulong inst)
+{
+ int rs, rt;
+ int imm;
+
+ Getrsrt(rs, rt, inst);
+ imm = (short)(inst&0xffff);
+
+ if(trace)
+ itrace("addiu\tr%d,r%d,#0x%x", rt, rs, imm);
+
+ reg.r[rt] = reg.r[rs]+imm;
+}
+
+void
+Islti(ulong inst)
+{
+ int rs, rt;
+ int imm;
+
+ Getrsrt(rs, rt, inst);
+ imm = (short)(inst&0xffff);
+
+ if(trace)
+ itrace("slti\tr%d,r%d,#0x%x", rt, rs, imm);
+
+ reg.r[rt] = reg.r[rs] < imm ? 1 : 0;
+}
+
+void
+Isltiu(ulong inst)
+{
+ int rs, rt;
+ int imm;
+
+ Getrsrt(rs, rt, inst);
+ imm = (short)(inst&0xffff);
+
+ if(trace)
+ itrace("sltiu\tr%d,r%d,#0x%x", rt, rs, imm);
+
+ reg.r[rt] = (ulong)reg.r[rs] < (ulong)imm ? 1 : 0;
+}
+
+/* ll and sc are implemented as lw and sw, since we simulate a uniprocessor */
+
+void
+Ill(ulong inst)
+{
+ int rt, rb;
+ int off;
+ ulong v, va;
+
+ Getrbrt(rb, rt, inst);
+ off = (short)(inst&0xffff);
+
+ va = reg.r[rb]+off;
+
+ if(trace) {
+ v = 0;
+ if(!badvaddr(va, 4))
+ v = getmem_w(va);
+ itrace("ll\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
+ }
+
+ reg.r[rt] = getmem_w(va);
+}
+
+void
+Isc(ulong inst)
+{
+ int rt, rb;
+ int off;
+ ulong v;
+
+ Getrbrt(rb, rt, inst);
+ off = (short)(inst&0xffff);
+
+ v = reg.r[rt];
+ if(trace)
+ itrace("sc\tr%d,0x%x(r%d) %lux=%lux",
+ rt, off, rb, reg.r[rb]+off, v);
+
+ putmem_w(reg.r[rb]+off, v);
+}
+
+enum
+{
+ Bltz = 0,
+ Bgez = 1,
+ Bltzal = 0x10,
+ Bgezal = 0x11,
+ Bltzl = 2,
+ Bgezl = 3,
+ Bltzall = 0x12,
+ Bgezall = 0x13,
+};
+
+static char *sbcond[] =
+{
+ [Bltz] "ltz",
+ [Bgez] "gez",
+ [Bltzal] "ltzal",
+ [Bgezal] "gezal",
+ [Bltzl] "ltzl",
+ [Bgezl] "gezl",
+ [Bltzall] "ltzall",
+ [Bgezall] "gezall",
+};
+
+void
+Ibcond(ulong inst)
+{
+ int rs, bran;
+ int off, doit, likely;
+ ulong npc;
+
+ rs = (inst>>21)&0x1f;
+ bran = (inst>>16)&0x1f;
+ off = (short)(inst&0xffff);
+ doit = 0;
+ likely = 0;
+
+ npc = reg.pc + (off<<2) + 4;
+ switch(bran) {
+ default:
+ Bprint(bioout, "bcond=%d\n", bran);
+ undef(inst);
+ case Bltzl:
+ likely = 1;
+ case Bltz:
+ if(reg.r[rs]&SIGNBIT)
+ doit = 1;
+ break;
+ case Bgezl:
+ likely = 1;
+ case Bgez:
+ if(!(reg.r[rs]&SIGNBIT))
+ doit = 1;
+ break;
+ case Bltzall:
+ likely = 1;
+ case Bltzal:
+ reg.r[31] = reg.pc+8;
+ if(reg.r[rs]&SIGNBIT)
+ doit = 1;
+ break;
+ case Bgezall:
+ likely = 1;
+ case Bgezal:
+ reg.r[31] = reg.pc+8;
+ if(!(reg.r[rs]&SIGNBIT))
+ doit = 1;
+ break;
+ }
+
+ if(trace)
+ itrace("b%s\tr%d,0x%lux", sbcond[bran], rs, npc);
+
+ if(doit) {
+ /* Do the delay slot */
+ reg.ir = ifetch(reg.pc+4);
+ Statbra();
+ Iexec(reg.ir);
+ reg.pc = npc-4;
+ } else
+ if(likely)
+ reg.pc += 4;
+
+}